Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: openapi revamp (draft) #670

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 126 additions & 0 deletions docs/docs/03-tools/031-openapi-experimental.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# OpenAPI Tools (Experimental)

GPTScript can treat OpenAPI v2 and v3 definition files as though they were tool files.
GPTScript will automatically and internally generate a set of three tools that the large language model can use
to interact with the API defined in the OpenAPI file.
The three tools are as follows:
- List: a tool that the LLM will call first in order to list out the available API operations available to it
- Get Schema: a tool that will provide a JSONSchema for the arguments of an operation, given an operation name provided by the LLM
- Run: a tool that will make an HTTP request to the API using the operation name and arguments provided by the LLM

Here is an example that uses the OpenAPI [Petstore Example](https://github.com/OAI/OpenAPI-Specification/blob/main/examples/v3.0/petstore.yaml):

```yaml
Tools: https://petstore.gptscript-demos.ai/openapi

List all the pets. What are the names of the dogs?
```

You can also use a local file path instead of a URL.

## OpenAPI Document Requirements

### Title

The OpenAPI document must have a Title. This title will be used within the three generated tools, in order to
communicate to the LLM about the API it has access to.

### Servers

GPTScript will look at the top-level `servers` array in the file and choose the first HTTPS server it finds.
If no HTTPS server exists, it will choose the first HTTP server. Other protocols (such as WSS) are not yet supported.

GPTScript will also handle path- and operation-level server overrides, following the same logic of choosing the first HTTPS server it finds,
or the first HTTP server if no HTTPS server exists in the array.

If no servers are defined in the definition, and the definition was downloaded from a URL, GPTScript will use the host
in the URL as the server value. This is the case with the Petstore example above.

#### Server Variables

Additionally, GPTScript can handle variables in the server name. For example, this:

```yaml
servers:
- url: '{server}/v1'
variables:
server:
default: https://api.example.com
```

Will be resolved as `https://api.example.com/v1`.

### Authentication

:::warning
All authentication options will be completely ignored if the server uses HTTP and not HTTPS.
This is to protect users from accidentally sending credentials in plain text.
:::

#### 1. Security Schemes

GPTScript will read the defined [security schemes](https://swagger.io/docs/specification/authentication/) in the OpenAPI definition. The currently supported types are `apiKey` and `http`.
OAuth and OIDC schemes will be ignored.

GPTScript will look at the `security` defined on the operation (or defined globally, if it is not defined on the operation) before it makes the request.
It will set the necessary headers, cookies, or query parameters based on the corresponding security scheme.

When internally generating the tool for the operation with a supported security scheme, GPTScript will include a credential tool.
This tool will prompt the user to enter their credentials. This will make the key available to GPTScript during the tool's execution.

##### Example

To explain this better, let's use this example:

```yaml
servers:
- url: https://api.example.com/v1
components:
securitySchemes:
MyBasic:
type: http
scheme: basic

MyAPIKey:
type: apiKey
in: header
name: X-API-Key
security:
- MyBasic: []
- MyAPIKey: []
# The rest of the document defines paths, etc.
```

In this example, we have two security schemes, and both are defined as the defaults on the global level.
They are separate entries in the global `security` array, so they are treated as a logical OR, and GPTScript will prompt
the user to enter the credential for the first one (basic auth).

When put into the same entry, they would be a logical AND, and both would be required.
It would look like this:

```yaml
security:
- MyBasic: []
MyAPIKey: []
```

In this case, GPTScript will prompt the user for both the basic auth credentials and the API key.

#### 2. Bearer token for server

GPTScript can also use a bearer token for all requests to a particular server that don't already have an `Authorization` header.
To do this, set the environment variable `GPTSCRIPT_<HOSTNAME>_BEARER_TOKEN`.
If a request to the server already has an `Authorization` header, the bearer token will not be added.

This can be useful in cases of unsupported auth types. For example, GPTScript does not have built-in support for OAuth,
but you can go through an OAuth flow, get the access token, and set it to the environment variable as a bearer token
for the server and use it that way.

### MIME Types and Request Bodies

In OpenAPI definitions, request bodies are described with a MIME type. Currently, GPTScript supports these MIME types:
- `application/json`
- `text/plain`
- `multipart/form-data`

GPTScript will ignore any operations that have a request body without a supported MIME type.