agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
111 lines • 5.63 kB
TypeScript
/**
* adapters/hosting/a2aWire — the A2A protocol, as an `HttpWire`.
*
* ── What this is ─────────────────────────────────────────────────────────────
* **A2A** (agent-to-agent) is an open protocol for one agent calling another:
* JSON-RPC 2.0 over HTTP, a `message/send` method carrying text parts, a result
* carrying artifacts, and a discovery document — the **agent card** — that says
* what the agent is and what it can do. It is nobody's product; several
* runtimes speak it, so it lives here on its own and the runtimes that host it
* configure this rather than reimplement it.
*
* ── The subset, stated plainly ───────────────────────────────────────────────
* One method: `message/send`, text parts only. Deliberately NOT carried:
* `message/stream` and the rest of the task lifecycle (`tasks/get`,
* `tasks/cancel`, push notifications), non-text parts, and multi-turn task
* state. An agent card built here therefore declares `streaming: false` by
* default — advertising a capability this wire cannot honour is how a caller
* finds out by hanging.
*
* ── Why it fits `httpHost` without changing it ───────────────────────────────
* JSON-RPC's one hard requirement on a reply is that it ECHOES the request's
* `id`. That is possible here only because `HttpWire`'s body methods receive
* the request that produced them — a seam added for a different protocol
* entirely, and the reason this one needed no new machinery.
*
* @example A2A on paths of your own choosing
* httpHost({
* name: 'myA2AHost',
* wire: a2aWire({ card: { name: 'triage', description: '…', version: '1.0.0' } }),
* invokePath: '/',
* healthPath: '/health',
* });
*/
import type { HttpWire } from '../../hosting/httpHost.js';
/** The A2A protocol revision this wire's documents declare. */
export declare const A2A_PROTOCOL_VERSION = "0.3.0";
/** Where the A2A specification puts an agent's discovery document. */
export declare const A2A_AGENT_CARD_PATH = "/.well-known/agent-card.json";
/** The one method this wire carries. */
export declare const A2A_SEND_METHOD = "message/send";
/**
* JSON-RPC's own reserved codes, the two this wire can raise.
*
* `-32601` is "method not found" and `-32602` is "invalid params" — both from
* the JSON-RPC specification rather than from A2A or any runtime, which is why
* they are the only numbers this neutral file knows. A runtime's own error
* codes belong to that runtime's adapter.
*/
export declare const JSONRPC_METHOD_NOT_FOUND = -32601;
export declare const JSONRPC_INVALID_PARAMS = -32602;
export declare const JSONRPC_INTERNAL_ERROR = -32603;
/** One skill an agent card advertises. */
export interface A2ASkill {
readonly id: string;
readonly name: string;
readonly description: string;
readonly tags?: readonly string[];
}
/** The agent card this wire serves — what another agent reads to decide to call yours. */
export interface A2AAgentCard {
readonly name: string;
readonly description: string;
readonly version: string;
/** Where callers reach this agent. A runtime that mounts the agent behind its
* own URL fills this in; left out, the card simply omits it. */
readonly url?: string;
/** Default `false` — see the module note on why this wire does not claim it. */
readonly streaming?: boolean;
readonly defaultInputModes?: readonly string[];
readonly defaultOutputModes?: readonly string[];
readonly skills?: readonly A2ASkill[];
}
export interface A2AWireOptions {
/** The agent card. Required: A2A discovery is not optional in the protocol. */
readonly card: A2AAgentCard;
/** Body for the health probe. Default `{ status: 'ok' }`. */
readonly health?: unknown;
/**
* Map a refusal's stable code onto the numeric JSON-RPC code this deployment
* reports. Absent, everything that is not a malformed request is
* `-32603` (internal error) — the JSON-RPC catch-all.
*
* A runtime with its own published code table passes one; that table is the
* runtime's, and this file does not carry anybody's.
*/
readonly errorCodeFor?: (code: string | undefined) => number;
/** Name used in refusal messages. Default `'a2aWire'`. */
readonly name?: string;
}
type JsonObject = Readonly<Record<string, unknown>>;
/**
* The text of one A2A message — every part concatenated, refusing what is not text.
*
* A non-text part is refused rather than skipped for the reason every dialect
* in this library refuses rather than skips: an answer produced from the parts
* that happened to be understood is a wrong answer delivered confidently.
*/
export declare function readA2AMessageText(message: unknown): string;
/**
* The agent card document, as the protocol prints it.
*
* Exported on its own because a deployment often has to serve the card from
* somewhere this wire does not own — a CDN, a route in a framework, a runtime's
* own discovery API — and the document should be built once, here, rather than
* hand-copied into each of those places.
*/
export declare function a2aAgentCardDocument(card: A2AAgentCard): JsonObject;
/** An `HttpWire` speaking A2A's `message/send`. */
export declare function a2aWire(options: A2AWireOptions): HttpWire;
export {};
//# sourceMappingURL=a2aWire.d.ts.map