Skip to content

Http

An HTTP API as a tool source. Each tool is one operation: a request with places in it for what the model gives, which the definition of the tool describes. An operation is data, so a catalog can store it, and OpenApi makes the operations of an API from its specification.

The source sends requests to one base URL, over an HTTP client the caller has already given the credentials the API asks for, so no credential enters this package. What the model gives never decides where a request goes: it fills the places the operation has for it, as the segments of the path, the parameters of the query, the headers, and the body, which is JSON.

Since v0.1.0

Makes a source of the operations of an HTTP API. A call answered 401 or 403 fails with AuthenticationError, 408, 429, or 5xx with UnavailableError, and any other 4xx with CallFailedError, holding the API’s own words cut to 500 characters. A success is the body as JSON, as text, or null without one. A call that takes longer than timeout fails as UnavailableError, and an answer longer than maxAnswerLength as CallFailedError.

Example (A source of an API, from an operation written by hand)

import { Http } from "@amends-dev/toolkit"
import { Effect } from "effect"
import { FetchHttpClient, HttpClient } from "effect/http"
const listIssues: Http.Operation = {
definition: {
name: "list_issues",
description: "Lists the open issues of a repository",
inputSchema: {
type: "object",
properties: {
owner: { type: "string" },
repo: { type: "string" },
labels: { type: "string", description: "Labels the issues must have, separated by commas" }
},
required: ["owner", "repo"]
},
annotations: { readOnly: true }
},
request: {
method: "GET",
path: "/repos/{owner}/{repo}/issues",
parameters: [
{ in: "path", name: "owner", property: "owner" },
{ in: "path", name: "repo", property: "repo" },
{ in: "query", name: "labels", property: "labels" }
]
}
}
const program = Effect.gen(function* () {
const client = yield* HttpClient.HttpClient
const github = yield* Http.make({
name: "github",
baseUrl: "https://api.github.com",
client,
operations: [listIssues]
})
// Sends GET /repos/amends-dev/amends/issues?labels=bug, and answers with the body as JSON.
return yield* github.call("list_issues", { owner: "amends-dev", repo: "amends", labels: "bug" })
}).pipe(Effect.provide(FetchHttpClient.layer))

Signature

declare const make: (options: Options) => Effect.Effect<ToolSource.ToolSource, never, never>

Source

Since v0.1.0

What make takes: the source’s name, where its requests go, the client that sends them with the API’s credentials, and its operations.

Signature

export interface Options {
/** Names the source, as `ToolSource.name` says. */
readonly name: string
/** Where the requests go, which the operations' paths follow. */
readonly baseUrl: string
/** Sends the requests, with the credentials the API asks for set on every one of them. */
readonly client: HttpClient.HttpClient
/** The tools of the source, which must have distinct names. */
readonly operations: ReadonlyArray<Operation>
/**
* How long a call may take, from sending its request to reading the answer. A call that takes
* longer fails as `UnavailableError`. 30 seconds by default.
*/
readonly timeout?: Duration.Input
/**
* The most characters an answer may have, which is what the model reads. A longer answer fails
* the call as `CallFailedError`, telling the model to ask for less. 200,000 by default.
*/
readonly maxAnswerLength?: number
}

Source

Since v0.1.0

The HTTP methods an operation’s request may use.

Signature

declare const Method: Schema.Literals<readonly ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]>

Source

Since v0.1.0

Signature

type Method = typeof Method.Type

Source

Since v0.1.0

A tool that is one HTTP request: the definition the model is shown, and the request a call fills in and sends. It is data, so a catalog can store it, and OpenApi.readOperations reads the operations of an API from its document.

Signature

declare const Operation: Schema.Struct<{
readonly definition: Schema.Struct<{
readonly name: Schema.NonEmptyString
readonly description: Schema.optionalKey<Schema.String>
readonly inputSchema: Schema.Codec<ToolJson, ToolJson, never, never>
readonly annotations: Schema.Struct<{
readonly title: Schema.optionalKey<Schema.String>
readonly readOnly: Schema.optionalKey<Schema.Boolean>
readonly destructive: Schema.optionalKey<Schema.Boolean>
readonly idempotent: Schema.optionalKey<Schema.Boolean>
readonly openWorld: Schema.optionalKey<Schema.Boolean>
}>
}>
readonly request: Schema.Struct<{
readonly method: Schema.Literals<readonly ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]>
readonly path: Schema.String
readonly parameters: Schema.$Array<
Schema.Struct<{
readonly in: Schema.Literals<readonly ["path", "query", "header"]>
readonly name: Schema.NonEmptyString
readonly property: Schema.NonEmptyString
}>
>
readonly body: Schema.optionalKey<Schema.NonEmptyString>
}>
}>

Source

Since v0.1.0

Signature

export interface Operation extends Schema.Schema.Type<typeof Operation> {}

Source

Since v0.1.0

A place in a request for a property of the tool’s input.

Signature

declare const Parameter: Schema.Struct<{
readonly in: Schema.Literals<readonly ["path", "query", "header"]>
readonly name: Schema.NonEmptyString
readonly property: Schema.NonEmptyString
}>

Source

Since v0.1.0

Signature

export interface Parameter extends Schema.Schema.Type<typeof Parameter> {}

Source

Since v0.1.0

The request an operation sends, with places in it for what the model gives: its method, its path, where each property of the input goes, and the property that holds the JSON body.

Signature

declare const RequestTemplate: Schema.Struct<{
readonly method: Schema.Literals<readonly ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]>
readonly path: Schema.String
readonly parameters: Schema.$Array<
Schema.Struct<{
readonly in: Schema.Literals<readonly ["path", "query", "header"]>
readonly name: Schema.NonEmptyString
readonly property: Schema.NonEmptyString
}>
>
readonly body: Schema.optionalKey<Schema.NonEmptyString>
}>

Source

Since v0.1.0

Signature

export interface RequestTemplate extends Schema.Schema.Type<typeof RequestTemplate> {}

Source

Since v0.1.0