/** * Anthropic LLM transport — full Wave 1c implementation. * * Absorbs ALL behavior from `backends/anthropic.ts`: prompt-caching breakpoints, * assistant-prefill guard, structured output (Zod schema injection + JSON repair), * extended-thinking (`thinkingBudgetTokens`), tool-choice mapping, and streaming. * * Construction: `new AnthropicTransport({ apiKey, baseUrl?, defaultHeaders? })` * where `defaultHeaders` carries OAuth `Authorization: Bearer …` headers when * the credential was resolved as `authType: 'oauth'`. * * @module llm/transports/anthropic * @task T9263 * @task T9282 (W0c — stub stream() + apiMode) * @task T9285 (W1c — full stream() + backend behavior absorption) * @epic T-LLM-CRED-CENTRALIZATION */ import type { NormalizedDelta, TransportContext } from '@cleocode/contracts/llm/interfaces.js'; import type { LlmTransport, NormalizedResponse, TransportRequest } from '@cleocode/contracts/llm/normalized-response.js'; import type { ApiMode } from '@cleocode/contracts/llm/provider-id.js'; import type { PromptCachingStrategy } from '../prompt-caching.js'; /** * Options accepted by {@link AnthropicTransport}. * * `baseUrl` is used to route requests through proxy providers or internal * gateways. `defaultHeaders` carries extra HTTP headers — typically the * `Authorization: Bearer …` header when using OAuth credentials and the * `anthropic-beta` header for extended-thinking enablement. */ export interface AnthropicTransportOptions { /** * API key (sent as `x-api-key`). * * Use this for legacy API-key auth. For OAuth bearer auth (Claude Code * tokens, `kimi-code` OAuth, etc.) pass {@link authToken} instead — the * Anthropic SDK routes `authToken` to `Authorization: Bearer …` and skips * the `x-api-key` header, which is what the OAuth gateways require. */ apiKey?: string; /** * OAuth bearer token (sent as `Authorization: Bearer …`). * * Mutually exclusive with {@link apiKey} at the wire level — the Anthropic * SDK uses `authToken` when both are set, but callers SHOULD pass only one * to avoid confusion. */ authToken?: string; /** Override base URL (e.g. for proxies or on-prem deployments). */ baseUrl?: string; /** Extra headers merged into every SDK request. */ defaultHeaders?: Record; /** * Prompt-caching injection strategy applied to every request. * Defaults to `'system_and_3'` to keep the same default as `AnthropicBackend`. */ promptCaching?: PromptCachingStrategy; } /** * Real Anthropic transport — full Wave 1c implementation. * * Wraps `@anthropic-ai/sdk` and normalizes requests/responses to/from the * provider-neutral {@link LlmTransport} interface. Supports both API-key and * OAuth credentials via `defaultHeaders`. * * Absorbs all behavior from `AnthropicBackend`: * - Prompt-caching breakpoints (`injectCacheBreakpoints`) * - Assistant-prefill guard (claude-4-class models reject prefill) * - Structured output via Zod schema injection + JSON repair * - Extended-thinking via `thinkingBudgetTokens` * - Tool-choice mapping to Anthropic API format * - Full streaming with reasoning/thinking block routing * * @example * ```ts * const transport = new AnthropicTransport({ apiKey: process.env.ANTHROPIC_API_KEY! }); * const response = await transport.complete({ * model: 'claude-sonnet-4-6', * messages: [{ role: 'user', content: 'Hello' }], * maxTokens: 1024, * }); * ``` */ export declare class AnthropicTransport implements LlmTransport { /** Provider identifier — always `'anthropic'`. */ readonly provider: "anthropic"; /** * Wire protocol spoken by this transport — always `'anthropic_messages'`. * * @see ADR-072 §Type lock-in */ readonly apiMode: ApiMode; private readonly _client; private readonly _defaultPromptCaching; /** * Create an `AnthropicTransport`. * * @param options - API key, optional base URL, optional extra headers, and * optional default prompt-caching strategy (defaults to `'system_and_3'`). */ constructor(options: AnthropicTransportOptions); /** * R2 CRITICAL: Claude 4-class models reject assistant-prefill. * * @invariant _supportsAssistantPrefill guard — returns false for * `claude-opus-4*`, `claude-sonnet-4*`, `claude-haiku-4*`. CLEO's * primary model `claude-sonnet-4-6` MUST use the non-prefill JSON schema * injection path. Correctness bug if this guard is omitted or bypassed. * * @param model - Model identifier to test. * @returns `false` when the model is a Claude 4-class model that rejects prefill. */ static _supportsAssistantPrefill(model: string): boolean; /** * Execute a single completion call against the Anthropic Messages API. * * Supports: prompt caching, extended thinking, structured output (Zod), * assistant prefill, tool-choice mapping, stop sequences. * * @param request - Provider-neutral request parameters. Extended fields * (`thinkingBudgetTokens`, `responseFormat`, `stop`, `toolChoice`, * `extraParams`, `promptCaching`) are read via intersection cast so the * LlmTransport interface remains stable. * @param _ctx - Transport context (unused by this transport currently). * @returns Normalized response including content, tool calls, usage, and raw SDK object. */ complete(request: TransportRequest, _ctx?: TransportContext): Promise; /** * Stream a completion against the Anthropic Messages API. * * Yields text, reasoning, and tool-call argument deltas as they arrive. * Thinking/reasoning blocks are routed to `delta.reasoning`; visible text * goes to `delta.text`. Tool-use content blocks emit incremental * `toolCallDelta` chunks so consumers can accumulate argument JSON in real * time without waiting for the final message. * * Tool-call streaming sequence per tool-use block: * 1. `content_block_start` (type=tool_use) → yields delta with `toolCallDelta` * carrying `{ index, name, argumentsChunk: '' }` (start marker). * 2. `content_block_delta` (type=input_json_delta) → yields delta with * `toolCallDelta` carrying `{ index, argumentsChunk }` (incremental JSON). * 3. `content_block_stop` → yields delta with `toolCallDelta` carrying * `{ index, argumentsChunk: '' }` and `stopReason: null` (end marker, no name). * * Consumers accumulate `argumentsChunk` fragments in index order to * reconstruct the full arguments JSON string before invoking tool handlers. * * @invariant thinkingBudgetTokens vs useJsonPrefill MUTEX in stream() — same * mutex as complete(): when `thinkingBudgetTokens` is set, `useJsonPrefill` * is forced false regardless of `responseFormat`. * * @param request - Provider-neutral request parameters. * @param _ctx - Transport context (unused by this transport currently). * @returns An async iterable of normalized delta chunks. */ stream(request: TransportRequest, _ctx: TransportContext): AsyncIterable; /** * Extract system-role messages and structuredClone the remaining messages. * * @invariant structuredClone() protection — caller arrays are cloned BEFORE * `injectCacheBreakpoints` mutates message content. This prevents callers * from observing `cache_control` markers injected into their own message * objects across multiple calls. * * @param messages - Provider-neutral message array. * @returns Split `{ requestMessages, systemMessages }`. */ private _extractSystem; /** * Normalize a raw Anthropic SDK `Message` into a {@link NormalizedResponse}. * * When `responseFormat` is provided, attempts JSON parse + Zod validation, * then falls back to `repairResponseModelJson` on parse failures. */ private _normalizeResponse; } //# sourceMappingURL=anthropic.d.ts.map