UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

47 lines (46 loc) • 3.52 kB
/** * The HTTP credentials a protocol declaration carries — its static `headers` and the per-task principal * header (`principalHeader`) — and the one rule they obey, for MCP and A2A alike: they travel only to the * endpoints the declaration names, and every header name has exactly one owner, compared the way HTTP * compares names (case-insensitively). The principal header's owner is the engine: it sends the task's * principal under that name, or nothing under it when the task has none. A static header the credential vocabulary * reads as a credential is one the engine holds from the moment it resolves it: no child spawned on this host inherits * a variable whose value equals it (`holdOwnCredentialValues`, src/core/secret-env.ts). * * A declaration that breaks the rule is that peer's defect: the resolver throws inside the peer's own dial, * so the peer is skipped with a coded warning and its siblings still mount. The MCP transport binds its * endpoint by dialing only the declared URL with redirects not followed (`declaredEndpointFetch`); the A2A * peer, whose card may name another endpoint, is bound by {@link assertEndpointBound} and by * {@link redirectPolicy}. */ import type { ProtocolId } from "./protocol-table.js"; /** The per-peer HTTP auth declaration every protocol spec carries in the same two fields. */ export interface ProtocolHttpAuth { headers?: Record<string, string>; principalHeader?: string; } /** The first header name (any case) the declaration gives two owners, with both spellings. */ export declare function headerOwnershipCollision(t: ProtocolHttpAuth): { readonly first: string; readonly second: string; } | undefined; /** * Resolve the HTTP request headers for one remote peer of `protocol`: the static headers, plus the * principal under `principalHeader` when both are present. Throws `config.protocol_header_collision` when * one header name has two owners (two static spellings, or a static entry under the principal header's * name — which would otherwise be sent merged beside the principal, or alone when the task has none), and * on a principal carrying CR/LF. Callers invoke it INSIDE their per-peer boundary. */ export declare function resolveProtocolHttpHeaders(protocol: ProtocolId, t: ProtocolHttpAuth, principal?: string): Readonly<Record<string, string>> | undefined; /** The engine's default request headers under the declared ones: a declared name, in any case, owns that header * (the default of the same name is not sent beside it). */ export declare function underDeclaredHeaders(defaults: Readonly<Record<string, string>>, declared: Record<string, string> | undefined): Record<string, string>; /** Whether a resolved header set carries anything the declaration bound to its endpoints. */ export declare function carriesDeclaredHeaders(headers: Record<string, string> | undefined): boolean; /** A request carrying declared headers does not follow a redirect (the next hop is not a declared endpoint). */ export declare function redirectPolicy(headers: Record<string, string> | undefined): "manual" | "follow"; /** * Refuse an endpoint a peer advertised (an A2A card's interface URL) when it lies outside every origin the * declaration names and the peer's requests carry declared headers: `config.protocol_endpoint_unbound`. */ export declare function assertEndpointBound(protocol: ProtocolId, peer: string, endpoint: string, declared: readonly string[], headers: Record<string, string> | undefined): void;