From f5d9368f00e9a18a09d48829cf6e86ec45fbea9f Mon Sep 17 00:00:00 2001 From: Grant Linville Date: Thu, 1 Aug 2024 12:37:02 -0400 Subject: [PATCH 1/6] docs: document more features Signed-off-by: Grant Linville --- docs/docs/03-tools/08-workspace.md | 36 +++++ docs/docs/03-tools/09-code-tool-guidelines.md | 130 ++++++++++++++++++ docs/docs/09-faqs.md | 35 ++--- 3 files changed, 181 insertions(+), 20 deletions(-) create mode 100644 docs/docs/03-tools/08-workspace.md create mode 100644 docs/docs/03-tools/09-code-tool-guidelines.md diff --git a/docs/docs/03-tools/08-workspace.md b/docs/docs/03-tools/08-workspace.md new file mode 100644 index 00000000..34c681d9 --- /dev/null +++ b/docs/docs/03-tools/08-workspace.md @@ -0,0 +1,36 @@ +# Workspace + +One concept in GPTScript is the workspace directory. +This is a directory meant to be used by tools that need to write their own files. +By default, the workspace directory is a one-off temporary directory. +The workspace directory can be set with the `--workspace` argument when running GPTScript, like this: + +```bash +gptscript --workspace . my-script.gpt +``` + +In the above example, the user’s current directory (denoted by `.`) will be set as the workspace. +Both absolute and relative paths are supported. + +Regardless of whether it is set implicitly or explicitly, the workspace is then made available to the script execution as the `GPTSCRIPT_WORKSPACE_DIR` environment variable. + +:::info +GPTScript does not force scripts or tools to write to, read from, or otherwise use the workspace. +The tools must decide to make use of the workspace environment variable. +::: + +## The Workspace Context Tool + +To make prompt-based tools aware of the workspace, you can reference the workspace context tool: + +``` +Context: github.com/gptscript-ai/context/workspace +``` + +This tells the LLM (by way of a [system message](https://platform.openai.com/docs/guides/text-generation/chat-completions-api)) what the workspace directory is, +what its initial contents are, and that if it decides to create a file or directory, it should do so in the workspace directory. +This will not, however, have any impact on code-based tools (i.e. Python, Bash, or Go tools). +Such tools will have the `GPTSCRIPT_WORKSPACE_DIR` environment variable available to them, but they must be written in such a way that they make use of it. + +This context tool also automatically shares the `sys.ls`, `sys.read`, and `sys.write` tools with the tool that is using it as a context. +This is because if a tool intends to interact with the workspace, it minimally needs these tools. diff --git a/docs/docs/03-tools/09-code-tool-guidelines.md b/docs/docs/03-tools/09-code-tool-guidelines.md new file mode 100644 index 00000000..07fda4e8 --- /dev/null +++ b/docs/docs/03-tools/09-code-tool-guidelines.md @@ -0,0 +1,130 @@ +# Code Tool Guidelines + +GPTScript can handle the packaging and distribution of code-based tools via GitHub repos. +For more information on how this works, see the [authoring guide](02-authoring.md#sharing-tools). + +This guide provides guidelines for setting up GitHub repos for proper tool distribution. + +## Common Guidelines + +### `tool.gpt` or `agent.gpt` file + +Every repo should have a `tool.gpt` or `agent.gpt` file. This is the main logic of the tool. +Your repo can have other `.gpt` files that are referenced by the main file, but there must be a `tool.gpt` or `agent.gpt` file present. + +Under most circumstances, this file should live in the root of the repo. +If you are using a single repo for the distribution of multiple tools (see [gptscript-ai/context](https://github.com/gptscript-ai/context) for an example), +then you can have the `tool.gpt`/`agent.gpt` file in a subdirectory, and the tool will now be able to be referenced as `github.com///`. + +### Name and Description directives + +We recommend including a `Name` and `Description` directive for your tool. +This is useful for both people and LLMs to understand what the tool will do and when to use it. + +### Parameters + +Any parameters specified in the tool will be available as environment variables in your code. +We recommend handling parameters that way, rather than using command-line arguments. + +## Python Guidelines + +### Calling Python in the tool body + +The body of the `tool.gpt`/`agent.gpt` file needs to call Python. This can be done as an inline script like this: + +``` +Name: my-python-tool + +#!python3 + +print('hello world') +``` + +An inline script like this is only recommended for simple use cases that don't need external dependencies. + +If your use case is more complex or requires external dependencies, you can reference a Python script in your repo, like this: + +``` +Name: my-python-tool + +#!/usr/bin/env python3 ${GPTSCRIPT_TOOL_DIR}/tool.py +``` + +(This example assumes that your entrypoint to your Python program is in a file called `tool.py`. You can call it what you want.) + +### `requirements.txt` file + +If your Python program needs any external dependencies, you can create a `requirements.txt` file at the same level as +your `tool.gpt`/`agent.gpt` file. GPTScript will handle downloading the dependencies before it runs the tool. + +The file structure should look something like this: + +``` +. +├── requirements.txt +├── tool.py +└── tool.gpt +``` + +## JavaScript (Node.js) Guidelines + +### Calling Node.js in the tool body + +The body of the `tool.gpt`/`agent.gpt` file needs to call Node. This can be done as an inline script like this: + +``` +Name: my-node-tool + +#!node + +console.log('hello world') +``` + +An inline script like this is only recommended for simple use cases that don't need external dependencies. + +If your use case is more complex or requires external dependencies, you can reference a Node script in your repo, like this: + +``` +Name: my-node-tool + +#!/usr/bin/env node ${GPTSCRIPT_TOOL_DIR}/tool.js +``` + +(This example assumes that your entrypoint to your Node program is in a file called `tool.js`. You can call it what you want.) + +### `package.json` file + +If your Node program needs any external dependencies, you can create a `package.json` file at the same level as +your `tool.gpt`/`agent.gpt` file. GPTScript will handle downloading the dependencies before it runs the tool. + +The file structure should look something like this: + +``` +. +├── package.json +├── tool.js +└── tool.gpt +``` + +## Go Guidelines + +GPTScript does not support inline code for Go, so you must call to an external program from the tool body like this: + +``` +Name: my-go-tool + +#!${GPTSCRIPT_TOOL_DIR}/bin/gptscript-go-tool +``` + +GPTScript will build the Go program located at `./main.go` to a file called `./bin/gptscript-go-tool` before running the tool. +All of your dependencies need to be properly specified in a `go.mod` file. + +The file structure should look something like this: + +``` +. +├── go.mod +├── go.sum +├── main.go +└── tool.gpt +``` diff --git a/docs/docs/09-faqs.md b/docs/docs/09-faqs.md index e8e15cb5..20196011 100644 --- a/docs/docs/09-faqs.md +++ b/docs/docs/09-faqs.md @@ -54,26 +54,7 @@ By default, this directory is a one-off temp directory, but you can override thi gptscript --workspace . my-script.gpt ``` -In the above example, the user's current directory (denoted by `.`) will be set as the workspace. Both absolute and relative paths are supported. - -Regardless of whether it is set implicitly or explicitly, the workspace is then made available to the script execution as the `GPTSCRIPT_WORKSPACE_DIR` environment variable. - -:::info -GPTScript does not force scripts or tools to write to, read from, or otherwise use the workspace. The tools must decide to make use of the workspace environment variable. -::: - -To make prompt-based tools workspace aware, you can reference our workspace context tool, like so: - -``` -Context: github.com/gptscript-ai/context/workspace -``` - -This tells the LLM (by way of a [system message](https://platform.openai.com/docs/guides/text-generation/chat-completions-api)) what the workspace directory is, what its initial contents are, and that if it decides to create a file or directory, it should do so in the workspace directory. -This will not, however, have any impact on code-based tools (ie python, bash, or go tools). -Such tools will have the `GPTSCRIPT_WORKSPACE_DIR` environment variable available to them, but they must be written in such a way that they make use of it. - -This context also automatically shares the `sys.ls`, `sys.read`, and `sys.write` tools with the tool that is using it as a context. -This is because if a tool intends to interact with the workspace, it minimally needs these tools. +For more info, see the [Workspace](03-tools/08-workspace.md) page. ### I'm hitting GitHub's rate limit for unauthenticated requests when using GPTScript. @@ -85,3 +66,17 @@ If you're already authenticated with the `gh` CLI, you can use its token by runn ```bash export GITHUB_AUTH_TOKEN="$(gh auth token)" ``` + +### Can I save my chat and resume it later? + +Yes! When you run GPTScript, be sure to specify the `--save-chat-state-file` argument like this: + +```bash +gptscript --save-chat-state-file chat-state.json my-script.gpt +``` + +Then, when you want to resume your chat, you can use the `--chat-state` argument to specify the file you saved: + +```bash +gptscript --chat-state chat-state.json my-script.gpt +``` From 9584d33ac9993a1bee864e086152d2c61a7c3465 Mon Sep 17 00:00:00 2001 From: Grant Linville Date: Thu, 1 Aug 2024 21:05:54 -0400 Subject: [PATCH 2/6] document daemon tools Signed-off-by: Grant Linville --- docs/docs/03-tools/10-daemon.md | 99 +++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 docs/docs/03-tools/10-daemon.md diff --git a/docs/docs/03-tools/10-daemon.md b/docs/docs/03-tools/10-daemon.md new file mode 100644 index 00000000..2adf59dc --- /dev/null +++ b/docs/docs/03-tools/10-daemon.md @@ -0,0 +1,99 @@ +# Daemon Tools (Advanced) + +One advanced use case that GPTScript supports is daemon tools. +A daemon tool is a tool that starts a long-running HTTP server in the background, that will continue running until GPTScript is done executing. +Other tools can easily send HTTP POST requests to the daemon tool. + +## Example + +Here is an example of a daemon tool with a simple echo server written in an inline Node.js script: + +``` +Tools: my-daemon +Param: first: the first parameter +Param: second: the second parameter + +#!http://my-daemon.daemon.gptscript.local/myPath + +--- +Name: my-daemon + +#!sys.daemon node + +const http = require('http'); + +const server = http.createServer((req, res) => { + if (req.method === 'GET' || req.method === 'POST') { + // Extract the path from the request URL + const path = req.url; + + let body = ''; + + req.on('data', chunk => { + body += chunk.toString(); + }) + + // Respond with the path and body + req.on('end', () => { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.write(`Body: ${body}\n`); + res.end(`Path: ${path}`); + }) + } else { + res.writeHead(405, { 'Content-Type': 'text/plain' }); + res.end('Method Not Allowed'); + } +}); + +const PORT = process.env.PORT || 3000; +server.listen(PORT, () => { + console.log(`Server is listening on port ${PORT}`); +}); +``` + +Let's talk about the daemon tool, called `my-daemon`, first. + +### The Daemon Tool + +The body of this tool begins with `#!sys.daemon`. This tells GPTScript to take the rest of the body as a command to be +run in the background that will listen for HTTP requests. GPTScript will run this command (in this case, a Node script). +GPTScript will assign a port number for the server and set the `PORT` environment variable to that number, so the +server needs to check that variable and listen on the proper port. The server is required to respond to a GET request at +`/` with 200 OK, so that GPTScript can make sure it is running properly before continuing execution. + +### The Entrypoint Tool + +The entrypoint tool at the top of this script sends an HTTP request to the daemon tool. +There are a few important things to note here: + +- The `Tools: my-daemon` directive is needed to show that this tool requires the `my-daemon` tool to already be running. + - When the entrypoint tool runs, GPTScript will check if `my-daemon` is already running. If it is not, GPTScript will start it. +- The `#!http://my-daemon.daemon.gptscript.local/myPath` in the body tells GPTScript to send an HTTP request to the daemon tool. + - The request will be a POST request, with the body of the request being a JSON string of the parameters passed to the entrypoint tool. + - For example, if the script is run like `gptscript script.gpt '{"first":"hello","second":"world"}'`, then the body of the request will be `{"first":"hello","second":"world"}`. + - The path of the request will be `/myPath`. + - The hostname is `my-daemon.daemon.gptscript.local`. When sending a request to a daemon tool, the hostname must always start with the daemon tool's name, followed by `.daemon.gptscript.local`. + - GPTScript recognizes this hostname and determines the correct port number to send the request to, on localhost. + +### Running the Example + +Now let's try running it: + +```bash +gptscript script.gpt '{"first":"hello","second":"world"}' +``` + +``` +OUTPUT: + +Body: {"first":"hello","second":"world"} +Path: /myPath +``` + +This is exactly what we expected. This is a silly, small example just to demonstrate how this feature works. +A real-world situation would involve several different tools sending different HTTP requests to the daemon tool, +likely with an LLM determining when to call which tool. + +### Real-World Example + +To see a real-world example of a daemon tool, check out the [GPTScript Browser tool](https://github.com/gptscript-ai/browser). From 4cb5403b480aef97bac286a6bdc95d79113c52d1 Mon Sep 17 00:00:00 2001 From: Grant Linville Date: Thu, 1 Aug 2024 21:20:50 -0400 Subject: [PATCH 3/6] formatting Signed-off-by: Grant Linville --- docs/docs/03-tools/10-daemon.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/03-tools/10-daemon.md b/docs/docs/03-tools/10-daemon.md index 2adf59dc..7901102e 100644 --- a/docs/docs/03-tools/10-daemon.md +++ b/docs/docs/03-tools/10-daemon.md @@ -94,6 +94,6 @@ This is exactly what we expected. This is a silly, small example just to demonst A real-world situation would involve several different tools sending different HTTP requests to the daemon tool, likely with an LLM determining when to call which tool. -### Real-World Example +## Real-World Example To see a real-world example of a daemon tool, check out the [GPTScript Browser tool](https://github.com/gptscript-ai/browser). From 742dcb40404466bfd203bd6bcc916bff2fe9f043 Mon Sep 17 00:00:00 2001 From: Grant Linville Date: Fri, 2 Aug 2024 10:44:54 -0400 Subject: [PATCH 4/6] Update docs/docs/03-tools/08-workspace.md Co-authored-by: Donnie Adams Signed-off-by: Grant Linville --- docs/docs/03-tools/08-workspace.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/03-tools/08-workspace.md b/docs/docs/03-tools/08-workspace.md index 34c681d9..a140debc 100644 --- a/docs/docs/03-tools/08-workspace.md +++ b/docs/docs/03-tools/08-workspace.md @@ -1,7 +1,7 @@ # Workspace One concept in GPTScript is the workspace directory. -This is a directory meant to be used by tools that need to write their own files. +This is a directory meant to be used by tools that need to interact with the local file system. By default, the workspace directory is a one-off temporary directory. The workspace directory can be set with the `--workspace` argument when running GPTScript, like this: From 15f7c5e0307477d9b5690128a0b26e44aaf7739d Mon Sep 17 00:00:00 2001 From: Grant Linville Date: Fri, 2 Aug 2024 10:53:09 -0400 Subject: [PATCH 5/6] PR feedback Signed-off-by: Grant Linville --- docs/docs/03-tools/08-workspace.md | 3 ++- docs/docs/03-tools/09-code-tool-guidelines.md | 5 +++++ docs/docs/03-tools/10-daemon.md | 13 +++++++++++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/docs/docs/03-tools/08-workspace.md b/docs/docs/03-tools/08-workspace.md index a140debc..8756cb2a 100644 --- a/docs/docs/03-tools/08-workspace.md +++ b/docs/docs/03-tools/08-workspace.md @@ -10,6 +10,7 @@ gptscript --workspace . my-script.gpt ``` In the above example, the user’s current directory (denoted by `.`) will be set as the workspace. +The workspace directory is no longer temporary if it is explicitly set, and everything in it will persist after the script has finished running. Both absolute and relative paths are supported. Regardless of whether it is set implicitly or explicitly, the workspace is then made available to the script execution as the `GPTSCRIPT_WORKSPACE_DIR` environment variable. @@ -21,7 +22,7 @@ The tools must decide to make use of the workspace environment variable. ## The Workspace Context Tool -To make prompt-based tools aware of the workspace, you can reference the workspace context tool: +To make a non-code tool that uses the LLM aware of the workspace, you can reference the workspace context tool: ``` Context: github.com/gptscript-ai/context/workspace diff --git a/docs/docs/03-tools/09-code-tool-guidelines.md b/docs/docs/03-tools/09-code-tool-guidelines.md index 07fda4e8..80bbabdf 100644 --- a/docs/docs/03-tools/09-code-tool-guidelines.md +++ b/docs/docs/03-tools/09-code-tool-guidelines.md @@ -10,6 +10,7 @@ This guide provides guidelines for setting up GitHub repos for proper tool distr ### `tool.gpt` or `agent.gpt` file Every repo should have a `tool.gpt` or `agent.gpt` file. This is the main logic of the tool. +If both files exist, GPTScript will use the `agent.gpt` file and ignore the `tool.gpt` file. Your repo can have other `.gpt` files that are referenced by the main file, but there must be a `tool.gpt` or `agent.gpt` file present. Under most circumstances, this file should live in the root of the repo. @@ -116,6 +117,10 @@ Name: my-go-tool #!${GPTSCRIPT_TOOL_DIR}/bin/gptscript-go-tool ``` +:::important +Unlike the Python and Node cases above where you can name the file you are going to run anything you want, Go tools must be `#!${GPTSCRIPT_TOOL_DIR}/bin/gptscript-go-tool`. +::: + GPTScript will build the Go program located at `./main.go` to a file called `./bin/gptscript-go-tool` before running the tool. All of your dependencies need to be properly specified in a `go.mod` file. diff --git a/docs/docs/03-tools/10-daemon.md b/docs/docs/03-tools/10-daemon.md index 7901102e..128c161a 100644 --- a/docs/docs/03-tools/10-daemon.md +++ b/docs/docs/03-tools/10-daemon.md @@ -58,8 +58,17 @@ Let's talk about the daemon tool, called `my-daemon`, first. The body of this tool begins with `#!sys.daemon`. This tells GPTScript to take the rest of the body as a command to be run in the background that will listen for HTTP requests. GPTScript will run this command (in this case, a Node script). GPTScript will assign a port number for the server and set the `PORT` environment variable to that number, so the -server needs to check that variable and listen on the proper port. The server is required to respond to a GET request at -`/` with 200 OK, so that GPTScript can make sure it is running properly before continuing execution. +server needs to check that variable and listen on the proper port. + +After GPTScript runs the daemon, it will send it an HTTP GET request to make sure that it is running properly. +The daemon needs to respond with a 200 OK to this request. +By default, the request goes to `/`, but this can be configured with the following syntax: + +``` +#!sys.daemon (path=/api/ready) node + +// (node script here) +``` ### The Entrypoint Tool From d0420bbb04ec052e4e7634731d0839b79735806d Mon Sep 17 00:00:00 2001 From: Grant Linville Date: Sat, 3 Aug 2024 10:44:19 -0400 Subject: [PATCH 6/6] fix wording Signed-off-by: Grant Linville --- docs/docs/03-tools/09-code-tool-guidelines.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/03-tools/09-code-tool-guidelines.md b/docs/docs/03-tools/09-code-tool-guidelines.md index 80bbabdf..0f13ac7f 100644 --- a/docs/docs/03-tools/09-code-tool-guidelines.md +++ b/docs/docs/03-tools/09-code-tool-guidelines.md @@ -118,7 +118,7 @@ Name: my-go-tool ``` :::important -Unlike the Python and Node cases above where you can name the file you are going to run anything you want, Go tools must be `#!${GPTSCRIPT_TOOL_DIR}/bin/gptscript-go-tool`. +Unlike the Python and Node cases above where you can name the file anything you want, Go tools must be `#!${GPTSCRIPT_TOOL_DIR}/bin/gptscript-go-tool`. ::: GPTScript will build the Go program located at `./main.go` to a file called `./bin/gptscript-go-tool` before running the tool.