Skip to content

Commit 5a7ebe0

Browse files
Add find and exec
1 parent 86387ed commit 5a7ebe0

File tree

3 files changed

+121
-80
lines changed

3 files changed

+121
-80
lines changed

README.md

Lines changed: 39 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,55 @@
1-
# README for GPT File Syntax
1+
# README.md for GPTscript Project
22

3-
## Overview
4-
GPT files found in this project use a custom syntax to describe various shell tools and their respective functionalities. Each file contains definitions for tools including their names, descriptions, arguments, and executable code. Below is an explanation of the syntax based on the contents of the GPT files reviewed (`./describe.gpt`, `./summarize-syntax.gpt`, `./tables.gpt`).
3+
## Project Description
54

6-
## Syntax Description
5+
This project utilizes `GPTscript`, a powerful scripting tool that leverages OpenAI's GPT plugins to execute tasks specified in `.gpt` files. These scripts can combine traditional scripting with GPT's AI capabilities to automate complex workflows, parse information, and more.
76

8-
### General Format
9-
GPT files follow a structured format that includes a preamble (indicating available tools), followed by metadata (descriptions of each tool), and Bash script examples for the tool's operation.
7+
## Usage
108

11-
Here's the general layout of a GPT file definition:
12-
```
13-
Tools: <tool_list>
14-
<empty_line>
15-
--- (3 hyphens to separate each tool definition)
16-
name: <tool_name>
17-
description: <description_of_tool>
18-
arg: <argument_description> (Optional and re-occurring)
19-
<empty_line>
20-
<executable_code_block>
21-
```
9+
The primary command used to run GPT scripts is `gptscript`, which can be invoked with various flags to control the script execution. A typical usage pattern looks like this:
2210

23-
### Tool Definition Header
24-
A tool definition always starts with three hyphens (`---`). This is a separator used to distinguish between different tool descriptions within the file.
11+
```bash
12+
gptscript [flags] PROGRAM_FILE [INPUT...]
13+
```
2514

26-
### Name
27-
The `name` field defines the name of the tool. It is used to invoke a specific functionality.
15+
Where `PROGRAM_FILE` is the script to be executed, optionally followed by `INPUT` arguments to pass into the script.
2816

29-
### Description
30-
The `description` field provides a concise explanation of what the tool does.
17+
## GPT File Syntax
3118

32-
### Arguments
33-
The `arg` fields describe the arguments that the tool accepts. Each argument is paired with a brief description. Argument definitions are optional and can be repeated if a tool accepts multiple arguments.
19+
GPT script files (`*.gpt`) follow a syntax which allows for defining tools, their descriptions, arguments, and embedded traditional scripting codes. Here's a breakdown of the syntax:
3420

35-
### Executable Code Block
36-
Following the metadata, an executable code block is provided. It is written in Bash and contains the script to execute the tool's functionality.
21+
- `tools:` Followed by the tool names to be used.
22+
- `name:` Defines the tool's name.
23+
- `description:` Describes what the tool does.
24+
- `args:` Lists arguments the tool accepts, describing the expected input.
25+
- `tools:` Below the main tool definition, you can specify other tools used by this tool.
26+
- A line containing `---` signifies the separation between tool metadata and the script code itself.
3727

38-
### Examples
39-
Here are examples extracted from the GPT files which follow the syntax described:
28+
## Example `.gpt` Files and Their Syntax
4029

41-
#### From `./describe.gpt`
42-
```
43-
---
44-
name: ls
45-
description: Recursively lists all go files
30+
The repository contains several example `.gpt` files, such as:
4631

47-
#!/bin/bash
48-
49-
find . -name '*.go'
50-
```
51-
#### From `./summarize-syntax.gpt`
52-
```
53-
---
54-
name: cat
55-
description: Reads the contents of a file
56-
arg: file: The filename to read
32+
- `describe.gpt`: Provides functionalities for working with Go files, with tools like `ls`, `count`, `summarize`, and `compare`.
33+
- `echo.gpt`: A simple script that echoes the provided input.
34+
- `fib.gpt`: An example demonstrating a recursive function `myfunction`.
35+
- `git-commit.gpt`: Automates the creation of a well-formed git commit message.
36+
- `helloworld.gpt`: A basic script outputs the traditional "hello world" message.
37+
- `summarize-syntax.gpt`: Meta-script for generating documentation based on `.gpt` files in a directory.
38+
- `tables.gpt`: Using SQLite, identifies the table in a database with the most rows.
5739

58-
#!/bin/bash
59-
60-
cat ${FILE} </dev/null
61-
```
62-
#### From `./tables.gpt`
63-
```
64-
---
65-
Name: sqlite
66-
Description: The sqlite command line program ... to run sqlite command or SQL statements against a database.
67-
Arg: databaseFile: The filename of the database to open
68-
Arg: cmd: The sqlite command or sql statement to run.
69-
70-
#!/bin/bash
71-
72-
sqlite3 ${DATABASEFILE} -cmd "${CMD}" </dev/null
73-
```
40+
## gptscript Command Help
7441

75-
## Additional Observations
76-
- The fields and code block are separated by a new line.
77-
- The arguments are indicated as `arg: argument_name: argument_description`.
78-
- The executable code is introduced with a `#!/bin/bash` shebang line and is expected to replace the argument placeholders (`${NAME}`) with actual values during execution.
42+
The help output for `gptscript` provides vital information on how to use the command along with the available flags. Here's an abbreviated listing of the flags:
7943

80-
Please note that this description of the syntax is based on the provided examples and may not cover variations which are not included in those files. Additional GPT files may include diverse structures and should be reviewed to check for consistency with this syntax.
44+
- `--assemble`: Assemble tool to a single artifact, with output specified by `--output`.
45+
- `--cache`, `--cache-dir`: Controls caching behavior and cache directory location.
46+
- `--debug`: Enable debug logging.
47+
- `--help`: Displays help information for `gptscript`.
48+
- `--input`: Specify an input file or stdin.
49+
- `--list-models`, `--list-tools`: Lists available models or built-in tools.
50+
- `--openai-api-key`: Specifies the OpenAI API key to use.
51+
- `--output`: Saves output to a specified file.
52+
- `--quiet`: Suppresses output logging.
53+
- `--sub-tool`: Selects a specific sub-tool to use from the `.gpt` file.
8154

55+
For a detailed description and more options, refer to the `gptscript --help` command.

examples/summarize-syntax.gpt

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,9 @@
1-
tools: ls, sys.read, help
1+
tools: sys.find, sys.read, sys.exec
22

33
Write a README.md for this github repo that describes this project, it's usage, and a description of the
4-
GPT file syntax. Example GPT files can be found by listing and read them. Also document the help of the
5-
gptscript command.
4+
GPT file syntax.
65

7-
---
8-
name: ls
9-
description: list all gpt files
6+
Example GPT files can be found by looking for all *.gpt files in the current directory. Analyze
7+
the contents of those files to discover the syntax and then describe how the syntax works.
108

11-
#!/bin/bash
12-
13-
find . -name '*.gpt'
14-
15-
---
16-
name: help
17-
description: Get the help output of gptscript
18-
19-
#!gptscript --help
9+
Also document the help of the gptscript command which can be obtained from running "gptscript --help".

pkg/builtin/builtin.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ import (
55
"encoding/json"
66
"fmt"
77
"io"
8+
"io/fs"
89
"net/http"
910
"os"
11+
"os/exec"
12+
"path/filepath"
1013
"sort"
1114
"strings"
1215

@@ -48,6 +51,22 @@ var Tools = map[string]types.Tool{
4851
"contentType", "The \"content type\" of the content such as application/json or text/plain"),
4952
BuiltinFunc: SysHTTPPost,
5053
},
54+
"sys.find": {
55+
Description: "Traverse a directory looking for files that match a pattern in the style of the unix find command",
56+
Arguments: types.ObjectSchema(
57+
"pattern", "The file pattern to look for. The pattern is a traditional unix glob format with * matching any character and ? matching a single character",
58+
"directory", "The directory to search in. The current directory \".\" will be used as the default if no argument is passed",
59+
),
60+
BuiltinFunc: SysFind,
61+
},
62+
"sys.exec": {
63+
Description: "Execute a command and get the output of the command",
64+
Arguments: types.ObjectSchema(
65+
"command", "The command to run including all applicable arguments",
66+
"directory", "The directory to use as the current working directory of the command. The current directory \".\" will be used if no argument is passed",
67+
),
68+
BuiltinFunc: SysExec,
69+
},
5170
}
5271

5372
func ListTools() (result []types.Tool) {
@@ -73,6 +92,64 @@ func Builtin(name string) (types.Tool, bool) {
7392
return t, ok
7493
}
7594

95+
func SysFind(ctx context.Context, env []string, input string) (string, error) {
96+
var result []string
97+
var params struct {
98+
Pattern string `json:"pattern,omitempty"`
99+
Directory string `json:"directory,omitempty"`
100+
}
101+
if err := json.Unmarshal([]byte(input), &params); err != nil {
102+
return "", err
103+
}
104+
105+
if params.Directory == "" {
106+
params.Directory = "."
107+
}
108+
109+
log.Debugf("Finding files %s in %s", params.Pattern, params.Directory)
110+
err := fs.WalkDir(os.DirFS(params.Directory), params.Directory, func(pathname string, d fs.DirEntry, err error) error {
111+
if err != nil {
112+
return err
113+
}
114+
if d.IsDir() {
115+
return nil
116+
}
117+
if ok, err := filepath.Match(params.Pattern, d.Name()); err != nil {
118+
return err
119+
} else if ok {
120+
result = append(result, filepath.Join(pathname))
121+
}
122+
return nil
123+
})
124+
if err != nil {
125+
return "", nil
126+
}
127+
sort.Strings(result)
128+
return strings.Join(result, "\n"), nil
129+
}
130+
131+
func SysExec(ctx context.Context, env []string, input string) (string, error) {
132+
var params struct {
133+
Command string `json:"command,omitempty"`
134+
Directory string `json:"directory,omitempty"`
135+
}
136+
if err := json.Unmarshal([]byte(input), &params); err != nil {
137+
return "", err
138+
}
139+
140+
if params.Directory == "" {
141+
params.Directory = "."
142+
}
143+
144+
log.Debugf("Running %s in %s", params.Command, params.Directory)
145+
146+
cmd := exec.Command("/bin/sh", "-c", params.Command)
147+
cmd.Env = env
148+
cmd.Dir = params.Directory
149+
out, err := cmd.CombinedOutput()
150+
return string(out), err
151+
}
152+
76153
func SysRead(ctx context.Context, env []string, input string) (string, error) {
77154
var params struct {
78155
Filename string `json:"filename,omitempty"`

0 commit comments

Comments
 (0)