UNPKG

agents

Version:

A home for your AI agents

302 lines (301 loc) • 12.2 kB
//#region src/web/fetch/contract.d.ts /** * The `web_fetch` tool contract: its name, what it tells the model, what the * model passes in, what comes back, and how a page is rendered for the * model. Shared by every executor of the tool — the harness-executed * adapters in `agents/webfetch/*`, and a gateway-executed variant once AI * Gateway server tools ship — so a `web_fetch` call looks the same in a * transcript whoever ran it. */ /** * The tool's name, as the model calls it and as it appears in transcripts. * `web_fetch` is the name models know from Anthropic's built-in fetch tool. */ declare const WEB_FETCH_TOOL_NAME = "web_fetch"; /** How many characters of content the model sees per call. */ declare const DEFAULT_WEB_FETCH_PAGE_CHARS = 20000; /** The most response body bytes one fetch reads, streamed. */ declare const DEFAULT_WEB_FETCH_MAX_BYTES = 5000000; /** How long one fetch may take, in milliseconds, redirects and conversion included. */ declare const DEFAULT_WEB_FETCH_TIMEOUT_MS = 30000; /** How many redirects one fetch follows unless the host sets `maxRedirects`. */ declare const DEFAULT_WEB_FETCH_MAX_REDIRECTS = 5; /** The longest URL accepted, in characters. */ declare const MAX_WEB_FETCH_URL_LENGTH = 2000; /** * How to represent the body. `auto` converts to the most readable text * (Markdown for HTML and documents, pretty-printed JSON); `raw` returns * textual bodies exactly as served. */ type WebFetchFormat = "auto" | "raw"; /** What the model says when it wants a page. */ type WebFetchToolInput = { /** The http(s) URL to read. */ url: string /** Character offset into the content for continuing a long page. Default 0. */; offset?: number /** "auto" (default) converts to the most readable form; "raw" returns the body as served. */; format?: WebFetchFormat; }; /** How the content of a {@link WebFetchPage} was produced. */ type WebFetchVia = | /** The server answered `text/markdown` (Markdown for Agents). */ "markdown-negotiated" /** Converted to Markdown by Workers AI (`env.AI.toMarkdown`). */ | "converted" /** JSON, pretty-printed. */ | "json" /** Text passed through as served. */ | "text" /** `format: "raw"`: the body as served. */ | "raw" /** * Rendered in a browser first (Browser Run). Reserved: nothing produces * it yet. It is in the union now so adding a browser source later doesn't * break hosts' exhaustive switches. */ | "rendered"; /** * One fetched page, whole: what a `WebFetchSource` and `fetchWeb()` * return. The model never sees this directly; the tool stores one window of * it as a {@link WebFetchToolOutput}. */ type WebFetchPage = { /** The URL as requested, trimmed. */ url: string /** The URL after redirects. */; finalUrl: string /** The final response's HTTP status. */; status: number /** The media type only, lowercased, without parameters. */; contentType: string; via: WebFetchVia /** The full converted content. */; content: string /** `content.length`. */; totalChars: number /** The page title, when the page has one. */; title?: string; /** * Selected response headers, lowercased: content-type, content-length, * last-modified, etag, x-markdown-tokens, cf-mitigated. */ headers: Record<string, string> /** Body bytes read. */; bytes: number /** The URLs that redirected, in order; `finalUrl` is not included. */; redirects: string[]; }; /** * What one `web_fetch` run stores for the host, and what * {@link renderWebFetchPage} formats for the model: the page's metadata and * the one window the model read. Bounded by the host's `pageChars`, however * large the page, so it is safe to persist in chat history. */ type WebFetchToolOutput = Omit<WebFetchPage, "content"> & { /** The window of content the model read: at most `pageChars` characters. */ content: string /** Where the window starts in the page; may be past the end. */; offset: number /** Where the next window starts, or `null` when the window reached the end. */; nextOffset: number | null; }; declare const WEB_FETCH_TOOL_DESCRIPTION: string; interface WindowWebFetchPageOptions { /** Where the window starts. Defaults to 0. */ offset?: number; /** Window size in characters. Defaults to {@link DEFAULT_WEB_FETCH_PAGE_CHARS}. */ pageChars?: number; } /** * Cut one window out of a page: the {@link WebFetchToolOutput} the tool * stores for a call at `offset`. Use it to show a page fetched with * `fetchWeb()` to a model one window at a time, exactly as the tool would. * * The window is `pageChars` characters from `offset`, ending at the last * newline in it unless that would drop more than a fifth of it, and never * between the halves of a surrogate pair. An offset past the end is kept * as given, with empty content, so rendering can say so. */ declare function windowWebFetchPage( page: WebFetchPage, options?: WindowWebFetchPageOptions ): WebFetchToolOutput; /** * Render a stored window as the text the model reads: a header line, then * the window inside `<untrusted_web_content>`. Formats what's stored; it * never re-slices, so a re-rendered history entry reads as it did. * * ``` * web_fetch: https://final.url · 200 · text/html → markdown · chars 0–20000 of 81200 · continue with offset=20000 * <untrusted_web_content> * …window… * </untrusted_web_content> * ``` */ declare function renderWebFetchPage(output: WebFetchToolOutput): string; //#endregion //#region src/web/fetch/source.d.ts /** One fetch request as a source receives it. */ interface WebFetchRequest { /** The http(s) URL to read. */ url: string; /** Defaults to `"auto"`. */ format?: WebFetchFormat; } /** Per-call options a source receives alongside the request. */ interface WebFetchCallOptions { /** Abort the fetch. A source should reject with the signal's reason. */ signal?: AbortSignal; } /** * Runs fetches. The tool core calls `fetch` and stores one window of the * page that comes back. A source validates the request (`url`, `format`), * throwing `invalid_web_fetch_input` for a malformed one, and returns the * whole page. */ interface WebFetchSource { fetch( request: WebFetchRequest, options?: WebFetchCallOptions ): Promise<WebFetchPage>; } /** Options for {@link createDirectWebFetch}. */ interface DirectWebFetchOptions { /** * The Workers AI binding, for converting HTML and documents to Markdown. * Requires `"ai": { "binding": "AI" }` in wrangler.jsonc; pass `env.AI`. */ binding: Ai; /** Override for tests. Defaults to the global `fetch`. */ fetch?: typeof fetch; /** Defaults to `Cloudflare-Agents (+https://github.com/cloudflare/agents)`. */ userAgent?: string; /** Stop reading the body past this many bytes. A positive integer; defaults to 5 MB. */ maxBytes?: number; /** Follow at most this many redirects. An integer from 0 to 20; defaults to 5. */ maxRedirects?: number; /** * Host patterns URLs must match, when non-empty: `example.com` or * `*.example.com`. Empty or omitted: any public host. */ allowedHosts?: string[]; /** Host patterns never fetched, in the same syntax. */ blockedHosts?: string[]; /** * Allow loopback, private, link-local, and local-only hosts. Off by * default; turn on for local development against `localhost`. */ allowPrivateHosts?: boolean; } /** * Fetch pages directly with `fetch`: GET only, redirects followed by hand * and every hop re-checked against the URL policy (an https → http * downgrade is refused), the body streamed up to * `maxBytes`, and the content converted per the content-type table. A * 4xx/5xx response with a textual body is returned like any page, with its * status; one without becomes a `web_fetch_http_error`. */ declare function createDirectWebFetch( options: DirectWebFetchOptions ): WebFetchSource; /** * Error codes a {@link WebFetchError} carries, so every failure has a code * to branch on. */ type WebFetchErrorCode = | /** The URL or format was malformed or too long. */ "invalid_web_fetch_input" /** The URL's scheme, credentials, or host isn't allowed here. */ | "web_fetch_disallowed_url" /** A redirect pointed at a URL that isn't allowed here, or from https to http. */ | "web_fetch_disallowed_redirect" /** More redirects than allowed, or a redirect loop. */ | "web_fetch_too_many_redirects" /** The fetch took longer than the tool's `timeoutMs` (on the error as `timeoutMs`). */ | "web_fetch_timeout" /** The body is larger than `maxBytes`. */ | "web_fetch_too_large" /** The body is binary, or a document requested with `format: "raw"`. */ | "web_fetch_unsupported_content_type" /** A 4xx/5xx response with an empty or non-textual body. */ | "web_fetch_http_error" /** The site answered with a bot challenge instead of the page. */ | "web_fetch_blocked" /** Workers AI could not convert the body to Markdown. */ | "web_fetch_conversion_failed" /** The network failed: before a response (DNS, TLS, connection) or while reading the body. */ | "web_fetch_unavailable"; /** Why a fetch failed. */ declare class WebFetchError extends Error { readonly name = "WebFetchError"; /** * The HTTP status of the response the failure is about, when there was * one; otherwise 400 (bad input), 403 (disallowed URL), 502 (unavailable), * or 504 (timeout). */ readonly status: number; readonly code: WebFetchErrorCode; /** Whether retrying the same fetch might succeed. */ readonly retryable: boolean; /** The URL the failure is about: the requested URL, or the redirecting hop. */ readonly url?: string; /** The response's media type, when a response was read. */ readonly contentType?: string; /** The deadline that expired, in milliseconds, for `web_fetch_timeout`. */ readonly timeoutMs?: number; constructor( message: string, details: { status: number; code: WebFetchErrorCode; retryable?: boolean; url?: string; contentType?: string; timeoutMs?: number; cause?: unknown; } ); } //#endregion //#region src/web/fetch/tool.d.ts /** * Fetch directly with `fetch`, converting through the Workers AI binding; * the tool builds the source with {@link createDirectWebFetch}. */ type WebFetchToolDirectOptions = DirectWebFetchOptions & { source?: never; }; /** * Fetch through a source you built. Limits, URL policy, and the user agent * belong to the source, so the direct-fetch options are not accepted here. */ type WebFetchToolSourceOptions = { /** Where fetches run, instead of a direct `fetch`. */ source: WebFetchSource; binding?: never; fetch?: never; userAgent?: never; maxBytes?: never; maxRedirects?: never; allowedHosts?: never; blockedHosts?: never; allowPrivateHosts?: never; }; /** * Options every `web_fetch` tool adapter accepts. Invalid values throw a * `RangeError` when the tool is created. */ type WebFetchToolOptions = ( | WebFetchToolDirectOptions | WebFetchToolSourceOptions ) & { /** * How many characters of content the model reads per call; it continues * with `offset`. A positive integer; defaults to 20,000. */ pageChars?: number; /** * Give up on a fetch after this many milliseconds, as a retryable * `web_fetch_timeout` failure. A positive integer; defaults to 30 seconds. */ timeoutMs?: number /** Replaces the default tool description. */; description?: string; }; //#endregion export { WindowWebFetchPageOptions as C, WebFetchVia as S, windowWebFetchPage as T, WEB_FETCH_TOOL_NAME as _, WebFetchCallOptions as a, WebFetchToolInput as b, WebFetchRequest as c, DEFAULT_WEB_FETCH_MAX_BYTES as d, DEFAULT_WEB_FETCH_MAX_REDIRECTS as f, WEB_FETCH_TOOL_DESCRIPTION as g, MAX_WEB_FETCH_URL_LENGTH as h, DirectWebFetchOptions as i, WebFetchSource as l, DEFAULT_WEB_FETCH_TIMEOUT_MS as m, WebFetchToolOptions as n, WebFetchError as o, DEFAULT_WEB_FETCH_PAGE_CHARS as p, WebFetchToolSourceOptions as r, WebFetchErrorCode as s, WebFetchToolDirectOptions as t, createDirectWebFetch as u, WebFetchFormat as v, renderWebFetchPage as w, WebFetchToolOutput as x, WebFetchPage as y }; //# sourceMappingURL=tool-DoVberpN.d.ts.map