UNPKG

agentfootprint

Version:

The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.

87 lines (86 loc) • 4.68 kB
/** * nativeOutputFormat — the ONE builder of the JSON Schema that * `.outputSchema(parser, { strategy: 'native' })` sends as the provider's * structured-output format (Anthropic's `output_config.format`). * * Pattern: pure transform over plain JSON, run once at build * (`AgentBuilder · resolveOutputEnforcement`); no scope, no I/O. * Role: core/ agent leaf. Its input is the SAME schema the `'tool-forced'` * strategy puts on its synthetic tool (`outputEnforcement.ts · * resolveJsonSchema`: the `jsonSchema` option, else the parser's own * `toJsonSchema()`), and the SAME parser judges every answer after — * so the wire copy may be looser than the contract, never different * from it. * * THE RULES, from Anthropic's structured-outputs page ("JSON Schema * limitations", fetched 2026-10-14 — * https://platform.claude.com/docs/en/build-with-claude/structured-outputs), * and the shape of the SDK's own transform (`@anthropic-ai/sdk` · * `transformJSONSchema`, which moves what the API does not take into the * description): * - KEPT: `type`, `properties`, `required`, `items`, `anyOf`, `allOf`, * local `$ref` with `$defs` / `definitions`, `enum` and `const` of * scalars, `default`, `description`, `title`, the ten supported string * `format`s, `minItems` of 0 or 1, and a `pattern` with no backreference, * lookaround or word boundary. `oneOf` is sent as `anyOf`. * - CLOSED: every object gets `additionalProperties: false` — the only value * the API takes. * - MOVED INTO THE DESCRIPTION, on the wire copy only: every constraint the * API does not take (`minimum`, `maximum`, `multipleOf`, `minLength`, * `maxLength`, `minItems` above 1 — sent as 1 —, `maxItems`, an * unsupported `format` or `pattern`, …). The model still reads them; the * parser still enforces them. * - REFUSED BY NAME (`NativeOutputSchemaError`): what the API cannot express * — a recursive schema, an external or dangling `$ref` (checked on the * source AND on the wire copy, whose renamed paths a reference could * miss), an `enum` or `const` holding an object or array, `allOf` beside * a `$ref`, a node with no type (an open `unknown` value), and an object * with open keys (`additionalProperties` given a schema, `true` or `{}` * on an object naming no properties, a bare `{ type: 'object' }`, or * `patternProperties`: closing it would make every map empty while the * parser accepted it), and object intersections through `allOf` (closing * each branch can make the intersection impossible). * - DROPPED: the meta keys `$schema`, `$id`, `$comment`, `$anchor`. * * THE RESERVED `_findings` KEY. With `.findings()` armed, the instruction tells * the model it may carry its standings on a JSON answer as a top-level * `_findings.previous`. Under `additionalProperties: false` a key the schema * does not name cannot be written at all, so the answer standings would stop * without a sound. Armed, the root gains the optional `_findings` property * the served contract allows (`findings/reserved.ts · findingsAnswerSchema`) — * unless the author's schema names its own `_findings`, which wins; a root * that is not an object cannot carry it and is refused. Unarmed, the schema * is the author's alone. * * @example * nativeOutputFormat( * { type: 'object', properties: { n: { type: 'integer', minimum: 1 } }, required: ['n'] }, * { findings: false }, * ); * // { type: 'json_schema', schema: { type: 'object', * // properties: { n: { type: 'integer', description: '{minimum: 1}' } }, * // required: ['n'], additionalProperties: false } } */ type Json = Readonly<Record<string, unknown>>; /** What `LLMRequest.outputFormat` carries. */ export interface NativeOutputFormat { readonly type: 'json_schema'; readonly schema: Json; } /** A schema the provider's structured output cannot express, named. */ export declare class NativeOutputSchemaError extends Error { /** JSON-pointer-like path of the node refused (`'#'` is the root). */ readonly path: string; constructor(path: string, reason: string); } /** * The structured-output format for `jsonSchema`, made API-compatible as the * file header lists, with the reserved `_findings` property when the findings * ledger is armed. Deep-frozen; the input is never edited. * * @throws NativeOutputSchemaError naming the node the API cannot express. */ export declare function nativeOutputFormat(jsonSchema: Json, arms: { readonly findings: boolean; }): NativeOutputFormat; export {};