/** * Anthropic Messages API (/v1/messages) — wire types and provider implementation. */ import type { ChatMessageDto, ChatStreamPieceDto, ChatResponseDto, ProviderResponseDto, ProviderStreamEventDto } from '../protocol.js'; import { AIProvider, type ChatRequestOpts } from '../aiProvider.js'; export interface AnthropicTextContent { type: 'text'; text: string; } export interface AnthropicThinkingContent { type: 'thinking'; thinking: string; } export interface AnthropicNonStreamingResponseDto extends ProviderResponseDto { type: 'message'; content: Array; } export interface AnthropicErrorResponseDto { type: 'error'; error: { type: string; message: string; }; } export interface AnthropicContentBlockDeltaDto { type: 'content_block_delta'; index: number; delta: { type: 'text_delta'; text: string; } | { type: 'thinking_delta'; thinking: string; }; } export interface AnthropicContentBlockStartDto { type: 'content_block_start'; index: number; content_block: { type: 'text'; text: string; }; } export interface AnthropicContentBlockStopDto { type: 'content_block_stop'; index: number; } export interface AnthropicMessageStartDto { type: 'message_start'; message: Record; } export interface AnthropicMessageDeltaDto { type: 'message_delta'; delta: Record; usage?: Record; } export interface AnthropicMessageStopDto { type: 'message_stop'; } export interface AnthropicPingDto { type: 'ping'; } export type AnthropicSseEventDto = AnthropicContentBlockDeltaDto | AnthropicContentBlockStartDto | AnthropicContentBlockStopDto | AnthropicMessageStartDto | AnthropicMessageDeltaDto | AnthropicMessageStopDto | AnthropicPingDto | AnthropicErrorResponseDto; /** Anthropic thinking (extended reasoning) */ type AnthropicThinkingConfig = { type: 'enabled'; budget_tokens: number; } | { type: 'adaptive'; display?: 'summarized' | 'omitted'; } | { type: 'disabled'; }; /** Anthropic web search tool definition */ interface AnthropicWebSearchTool { type: 'web_search_20250305'; name: 'web_search'; max_uses?: number; } /** Ephemeral prompt-cache breakpoint */ type CacheControl = { type: 'ephemeral'; }; /** Outbound text block with an optional cache breakpoint (request-side only) */ type AnthropicTextBlock = { type: 'text'; text: string; cache_control?: CacheControl; }; /** Message whose content may be a plain string or block array (block form carries cache_control) */ type AnthropicMessage = { role: ChatMessageDto['role']; content: string | AnthropicTextBlock[]; }; /** Anthropic request payload */ export type AnthropicRequestPayload = { model: string; messages: AnthropicMessage[]; max_tokens: number; stream: boolean; system?: string | AnthropicTextBlock[]; thinking?: AnthropicThinkingConfig; output_config?: { effort: 'low' | 'medium' | 'high' | 'max'; }; tools?: AnthropicWebSearchTool[]; }; export declare class AnthropicProvider extends AIProvider { protected readonly providerName = "Anthropic"; readonly defaultBaseUrl = "https://api.anthropic.com"; readonly path = "/v1/messages"; buildHeaders(apiKey: string): Record; buildPayload(messages: ChatMessageDto[], model: string, opts: ChatRequestOpts, stream: boolean): AnthropicRequestPayload; parseNonStreamingResponse(json: ProviderResponseDto): ChatResponseDto; protected parseProviderStreamChunk(json: ProviderStreamEventDto): ChatStreamPieceDto | null; /** * Cache breakpoints on the final two messages. The last extends conversations whose tail is the * new user turn (tb.ai bulbs, chat/raw modes); the second-to-last covers code-mode chat payloads, * whose tail is an ephemeral script-context message rebuilt every turn — there the durable * conversation prefix ends one message earlier, so a last-only breakpoint would never be hit. */ private withTailMessagesCached; private isAnthropicResponse; private isAnthropicEvent; /** * Claude 4.6+ (including the entire 5 family): adaptive thinking + `output_config.effort`, * higher output limit. Older models use legacy `thinking.type: 'enabled'` + `budget_tokens`. * * Version IDs come in two shapes and the minor is OPTIONAL: * - `claude-opus-4-8`, `claude-haiku-4-5-20251001` — major-minor * - `claude-sonnet-5`, `claude-fable-5` — the 5 family dropped the minor * A two-group regex misses the single-number ids, misreading Sonnet 5 as pre-4.6 and sending it * down the legacy `thinking.type: 'enabled'` path — which the 5 family rejects outright * ("use thinking.type.adaptive and output_config.effort"). `[a-z]+` (not `\w+`) also avoids * matching the number-first legacy names (`claude-3-5-sonnet`), which stay non-modern. */ private isModernModel; /** Fable / Mythos think unconditionally: `thinking.disabled` is a 400 on them, not a no-op, so * minimal floors to low-effort thinking instead of off. */ private alwaysThinks; private getMaxTokens; } export {}; //# sourceMappingURL=anthropic.d.ts.map