@tanstack/ai-anthropic 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/adapters/text.js +6 -8
- package/dist/esm/adapters/text.js.map +1 -1
- package/dist/esm/text/text-provider-options.d.ts +18 -13
- package/dist/esm/text/text-provider-options.js.map +1 -1
- package/package.json +3 -3
- package/src/adapters/text.ts +16 -16
- package/src/text/text-provider-options.ts +18 -14
|
@@ -157,11 +157,13 @@ class AnthropicTextAdapter extends BaseTextAdapter {
|
|
|
157
157
|
"stop_sequences",
|
|
158
158
|
"thinking",
|
|
159
159
|
"tool_choice",
|
|
160
|
-
"top_k"
|
|
160
|
+
"top_k",
|
|
161
|
+
"temperature",
|
|
162
|
+
"top_p"
|
|
161
163
|
];
|
|
162
|
-
const
|
|
164
|
+
const droppedKeyExemptSet = /* @__PURE__ */ new Set([...validKeys, "max_tokens"]);
|
|
163
165
|
const droppedKeys = Object.keys(modelOptions).filter(
|
|
164
|
-
(key) => !
|
|
166
|
+
(key) => !droppedKeyExemptSet.has(key)
|
|
165
167
|
);
|
|
166
168
|
if (droppedKeys.length > 0) {
|
|
167
169
|
options.logger.errors(
|
|
@@ -187,7 +189,7 @@ class AnthropicTextAdapter extends BaseTextAdapter {
|
|
|
187
189
|
}
|
|
188
190
|
}
|
|
189
191
|
const thinkingBudget = validProviderOptions.thinking?.type === "enabled" ? validProviderOptions.thinking.budget_tokens : void 0;
|
|
190
|
-
const defaultMaxTokens =
|
|
192
|
+
const defaultMaxTokens = modelOptions?.max_tokens ?? 1024;
|
|
191
193
|
const maxTokens = thinkingBudget && thinkingBudget >= defaultMaxTokens ? thinkingBudget + 1 : defaultMaxTokens;
|
|
192
194
|
const systemBlocks = (() => {
|
|
193
195
|
const normalized = normalizeSystemPrompts(
|
|
@@ -217,10 +219,6 @@ class AnthropicTextAdapter extends BaseTextAdapter {
|
|
|
217
219
|
const requestParams = {
|
|
218
220
|
model: options.model,
|
|
219
221
|
max_tokens: maxTokens,
|
|
220
|
-
...options.temperature !== void 0 && {
|
|
221
|
-
temperature: options.temperature
|
|
222
|
-
},
|
|
223
|
-
...options.topP !== void 0 && { top_p: options.topP },
|
|
224
222
|
messages: formattedMessages,
|
|
225
223
|
...systemBlocks !== void 0 && { system: systemBlocks },
|
|
226
224
|
...tools !== void 0 && { tools },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.js","sources":["../../../src/adapters/text.ts"],"sourcesContent":["import { EventType, normalizeSystemPrompts } from '@tanstack/ai'\nimport { toRunErrorRawEvent } from '@tanstack/ai/adapter-internals'\nimport { BaseTextAdapter } from '@tanstack/ai/adapters'\nimport { convertToolsToProviderFormat } from '../tools/tool-converter'\nimport { validateTextProviderOptions } from '../text/text-provider-options'\nimport { buildAnthropicUsage } from '../usage'\nimport {\n createAnthropicClient,\n generateId,\n getAnthropicApiKeyFromEnv,\n} from '../utils'\nimport { ANTHROPIC_COMBINED_TOOLS_AND_SCHEMA_MODELS } from '../model-meta'\nimport type {\n ANTHROPIC_MODELS,\n AnthropicChatModelProviderOptionsByName,\n AnthropicChatModelToolCapabilitiesByName,\n AnthropicModelInputModalitiesByName,\n} from '../model-meta'\nimport type {\n StructuredOutputOptions,\n StructuredOutputResult,\n} from '@tanstack/ai/adapters'\nimport type { InternalLogger } from '@tanstack/ai/adapter-internals'\nimport type {\n Base64ImageSource,\n Base64PDFSource,\n ContentBlockParam,\n DocumentBlockParam,\n ImageBlockParam,\n TextBlockParam,\n ThinkingBlockParam,\n ToolUseBlockParam,\n URLImageSource,\n URLPDFSource,\n} from '@anthropic-ai/sdk/resources/messages'\nimport type Anthropic_SDK from '@anthropic-ai/sdk'\nimport type { AnthropicBeta } from '@anthropic-ai/sdk/resources/beta/beta'\nimport type {\n ContentPart,\n Modality,\n ModelMessage,\n StreamChunk,\n TextOptions,\n} from '@tanstack/ai'\nimport type {\n AnthropicSystemPromptMetadata,\n ExternalTextProviderOptions,\n InternalTextProviderOptions,\n} from '../text/text-provider-options'\nimport type {\n AnthropicDocumentMetadata,\n AnthropicImageMetadata,\n AnthropicMessageMetadataByModality,\n AnthropicTextMetadata,\n} from '../message-types'\nimport type { AnthropicClientConfig } from '../utils'\n\n/**\n * Configuration for Anthropic text adapter\n */\nexport interface AnthropicTextConfig extends AnthropicClientConfig {}\n\n/**\n * Anthropic-specific provider options for text/chat\n */\nexport type AnthropicTextProviderOptions = ExternalTextProviderOptions\n\n// ===========================\n// Type Resolution Helpers\n// ===========================\n\n/**\n * Resolve provider options for a specific model.\n * If the model has explicit options in the map, use those; otherwise use base options.\n */\ntype ResolveProviderOptions<TModel extends string> =\n TModel extends keyof AnthropicChatModelProviderOptionsByName\n ? AnthropicChatModelProviderOptionsByName[TModel]\n : AnthropicTextProviderOptions\n\n/**\n * Resolve input modalities for a specific model.\n * If the model has explicit modalities in the map, use those; otherwise use default.\n */\ntype ResolveInputModalities<TModel extends string> =\n TModel extends keyof AnthropicModelInputModalitiesByName\n ? AnthropicModelInputModalitiesByName[TModel]\n : readonly ['text', 'image', 'document']\n\ntype ResolveToolCapabilities<TModel extends string> =\n TModel extends keyof AnthropicChatModelToolCapabilitiesByName\n ? NonNullable<AnthropicChatModelToolCapabilitiesByName[TModel]>\n : readonly []\n\n// ===========================\n// Adapter Implementation\n// ===========================\n\n/**\n * Anthropic Text (Chat) Adapter\n *\n * Tree-shakeable adapter for Anthropic chat/text completion functionality.\n * Import only what you need for smaller bundle sizes.\n */\nexport class AnthropicTextAdapter<\n TModel extends (typeof ANTHROPIC_MODELS)[number],\n TProviderOptions extends Record<string, any> = ResolveProviderOptions<TModel>,\n TInputModalities extends ReadonlyArray<Modality> =\n ResolveInputModalities<TModel>,\n TToolCapabilities extends ReadonlyArray<string> =\n ResolveToolCapabilities<TModel>,\n> extends BaseTextAdapter<\n TModel,\n TProviderOptions,\n TInputModalities,\n AnthropicMessageMetadataByModality,\n TToolCapabilities,\n // TToolCallMetadata — anthropic has no tool-call metadata round-tripping\n unknown,\n // TSystemPromptMetadata — narrows `systemPrompts[i].metadata` at the\n // chat() call site so users get `cache_control` autocomplete.\n AnthropicSystemPromptMetadata\n> {\n override readonly kind = 'text' as const\n readonly name = 'anthropic' as const\n\n private readonly client: Anthropic_SDK\n\n constructor(config: AnthropicTextConfig, model: TModel) {\n super({}, model)\n this.client = createAnthropicClient(config)\n }\n\n async *chatStream(\n options: TextOptions<TProviderOptions>,\n ): AsyncIterable<StreamChunk> {\n const { logger } = options\n try {\n const requestParams = this.mapCommonOptionsToAnthropic(options)\n\n logger.request(\n `activity=chat provider=anthropic model=${this.model} messages=${options.messages.length} tools=${options.tools?.length ?? 0} stream=true`,\n { provider: 'anthropic', model: this.model },\n )\n\n // `betas` is attached at the call site rather than in the shared mapper\n // because the `interleaved-thinking-2025-05-14` header is only useful for\n // the streaming path.\n const modelOptions = options.modelOptions as\n | InternalTextProviderOptions\n | undefined\n const useInterleavedThinking =\n modelOptions?.thinking?.type === 'enabled' &&\n typeof modelOptions.thinking.budget_tokens === 'number' &&\n modelOptions.thinking.budget_tokens > 0\n const betas: Array<AnthropicBeta> | undefined = useInterleavedThinking\n ? ['interleaved-thinking-2025-05-14']\n : undefined\n\n // `client.beta.messages` is Anthropic's permanent staging surface, not a\n // sunset path: it's a superset of `client.messages` that additionally\n // accepts the `betas: AnthropicBeta[]` header (e.g. interleaved\n // thinking) plus richer `container` (skills) and `context_management`\n // shapes that `InternalTextProviderOptions` carries. We route every\n // Messages call through it so the request mapper stays single-shape.\n const stream = await this.client.beta.messages.create(\n {\n ...requestParams,\n stream: true,\n ...(betas && { betas }),\n },\n {\n signal: options.request?.signal,\n headers: options.request?.headers,\n },\n )\n\n yield* this.processAnthropicStream(\n stream,\n options,\n () => generateId(this.name),\n logger,\n )\n } catch (error: unknown) {\n const err = error as Error & { status?: number; code?: string }\n const rawEvent = toRunErrorRawEvent(error)\n logger.errors('anthropic.chatStream fatal', {\n error,\n source: 'anthropic.chatStream',\n })\n yield {\n type: EventType.RUN_ERROR,\n model: options.model,\n timestamp: Date.now(),\n message: err.message || 'Unknown error occurred',\n code: err.code || String(err.status),\n // Forward the Anthropic SDK error's `.error` response body (e.g.\n // `{ type, message }`) when present; never the raw exception object.\n ...(rawEvent !== undefined && { rawEvent }),\n error: {\n message: err.message || 'Unknown error occurred',\n code: err.code || String(err.status),\n },\n }\n }\n }\n\n /**\n * Generate structured output using Anthropic's tool-based approach.\n * Anthropic doesn't have native structured output, so we use a tool with the schema\n * and force the model to call it.\n * The outputSchema is already JSON Schema (converted in the ai layer).\n */\n async structuredOutput(\n options: StructuredOutputOptions<TProviderOptions>,\n ): Promise<StructuredOutputResult<unknown>> {\n const { chatOptions, outputSchema } = options\n const { logger } = chatOptions\n\n const requestParams = this.mapCommonOptionsToAnthropic(chatOptions)\n\n // Create a tool that will capture the structured output\n // Anthropic's SDK requires input_schema with type: 'object' literal\n const structuredOutputTool = {\n name: 'structured_output',\n description:\n 'Use this tool to provide your response in the required structured format.',\n input_schema: {\n type: 'object' as const,\n properties: outputSchema.properties ?? {},\n required: outputSchema.required ?? [],\n },\n }\n\n try {\n logger.request(\n `activity=chat provider=anthropic model=${this.model} messages=${chatOptions.messages.length} tools=${chatOptions.tools?.length ?? 0} stream=false`,\n { provider: 'anthropic', model: this.model },\n )\n // Make non-streaming request with tool_choice forced to our structured output tool\n const response = await this.client.beta.messages.create(\n {\n ...requestParams,\n stream: false,\n tools: [structuredOutputTool],\n tool_choice: { type: 'tool', name: 'structured_output' },\n },\n {\n signal: chatOptions.request?.signal,\n headers: chatOptions.request?.headers,\n },\n )\n\n // Extract the tool use content from the response\n let parsed: unknown = null\n let rawText = ''\n\n for (const block of response.content) {\n if (block.type === 'tool_use' && block.name === 'structured_output') {\n parsed = block.input\n rawText = JSON.stringify(block.input)\n break\n }\n }\n\n if (parsed === null) {\n // Fallback: try to extract text content and parse as JSON\n rawText = response.content\n .map((b) => {\n if (b.type === 'text') {\n return b.text\n }\n return ''\n })\n .join('')\n try {\n parsed = JSON.parse(rawText)\n } catch {\n throw new Error(\n `Failed to extract structured output from response. Content: ${rawText.slice(0, 200)}${rawText.length > 200 ? '...' : ''}`,\n )\n }\n }\n\n return {\n data: parsed,\n rawText,\n usage: buildAnthropicUsage(response.usage),\n }\n } catch (error: unknown) {\n const err = error as Error\n logger.errors('anthropic.structuredOutput fatal', {\n error,\n source: 'anthropic.structuredOutput',\n })\n throw new Error(\n `Structured output generation failed: ${err.message || 'Unknown error occurred'}`,\n )\n }\n }\n\n private mapCommonOptionsToAnthropic(\n options: TextOptions<AnthropicTextProviderOptions>,\n ) {\n const modelOptions = options.modelOptions as\n | InternalTextProviderOptions\n | undefined\n\n const formattedMessages = this.formatMessages(options.messages)\n const tools = options.tools\n ? convertToolsToProviderFormat(options.tools)\n : undefined\n\n const validProviderOptions: Partial<InternalTextProviderOptions> = {}\n if (modelOptions) {\n const validKeys: Array<keyof InternalTextProviderOptions> = [\n 'container',\n 'context_management',\n 'effort',\n 'mcp_servers',\n 'output_config',\n 'service_tier',\n 'stop_sequences',\n 'thinking',\n 'tool_choice',\n 'top_k',\n ]\n const validKeySet = new Set<string>(validKeys)\n const droppedKeys = Object.keys(modelOptions).filter(\n (key) => !validKeySet.has(key),\n )\n if (droppedKeys.length > 0) {\n // Reachable when callers cast around the public type (e.g.\n // `modelOptions: { system: ... } as any`). Without this warning the\n // unknown keys are silently dropped — `system` in particular was a\n // previously-tested path for attaching `cache_control` and we don't\n // want that to fail in production with no signal.\n options.logger.errors(\n `anthropic.mapCommonOptionsToAnthropic dropped unknown modelOptions key(s): ${droppedKeys.join(', ')}`,\n {\n source: 'anthropic.mapCommonOptionsToAnthropic',\n droppedKeys,\n hint: droppedKeys.includes('system')\n ? 'pass system prompts via the top-level `systemPrompts` option; `modelOptions.system` is no longer honored'\n : undefined,\n },\n )\n }\n for (const key of validKeys) {\n if (key in modelOptions) {\n const value = modelOptions[key]\n if (key === 'tool_choice' && typeof value === 'string') {\n ;(validProviderOptions as Record<string, unknown>)[key] = {\n type: value,\n }\n } else {\n ;(validProviderOptions as Record<string, unknown>)[key] = value\n }\n }\n }\n }\n\n const thinkingBudget =\n validProviderOptions.thinking?.type === 'enabled'\n ? validProviderOptions.thinking.budget_tokens\n : undefined\n const defaultMaxTokens = options.maxTokens || 1024\n const maxTokens =\n thinkingBudget && thinkingBudget >= defaultMaxTokens\n ? thinkingBudget + 1\n : defaultMaxTokens\n\n // `InternalTextProviderOptions.system` is typed\n // `string | Array<TextBlockParam>` (no `| undefined`), so build it\n // outside the literal and spread it conditionally rather than\n // assigning `undefined` under exactOptionalPropertyTypes.\n const systemBlocks = ((): Array<TextBlockParam> | undefined => {\n const normalized = normalizeSystemPrompts<AnthropicSystemPromptMetadata>(\n options.systemPrompts,\n )\n if (normalized.length === 0) return undefined\n return normalized.map(\n (p): TextBlockParam => ({\n type: 'text',\n text: p.content,\n ...(p.metadata?.cache_control && {\n cache_control: p.metadata.cache_control,\n }),\n }),\n )\n })()\n // Wire engine-threaded outputSchema into Messages `output_config.format`\n // alongside any `tools` so the model emits tool calls during the agent\n // loop and a single schema-constrained JSON message on its final turn.\n // Merge into any existing `output_config` so callers can keep tuning\n // `output_config.effort` alongside the schema.\n const combinedSchema = options.outputSchema as\n | Record<string, unknown>\n | undefined\n const outputConfig = combinedSchema\n ? {\n output_config: {\n ...(validProviderOptions.output_config ?? {}),\n format: {\n type: 'json_schema' as const,\n schema: combinedSchema,\n },\n },\n }\n : undefined\n\n // `InternalTextProviderOptions` declares `temperature`, `top_p`,\n // and `tools` as `T?: ...` (no `| undefined`), so spread them\n // conditionally rather than passing explicit `undefined` from the\n // optional common `TextOptions` fields under\n // exactOptionalPropertyTypes.\n const requestParams: InternalTextProviderOptions = {\n model: options.model,\n max_tokens: maxTokens,\n ...(options.temperature !== undefined && {\n temperature: options.temperature,\n }),\n ...(options.topP !== undefined && { top_p: options.topP }),\n messages: formattedMessages,\n ...(systemBlocks !== undefined && { system: systemBlocks }),\n ...(tools !== undefined && { tools }),\n ...validProviderOptions,\n ...(outputConfig ?? {}),\n }\n validateTextProviderOptions(requestParams)\n return requestParams\n }\n\n /**\n * Anthropic supports `output_config.format` + `tools` in a single streaming\n * Messages request only for Claude 4.5+ (GA 2026-01-29). For 4.4 and\n * earlier we keep the forced-tool-use workaround in\n * {@link structuredOutput} via the engine's finalization path.\n */\n supportsCombinedToolsAndSchema(): boolean {\n return ANTHROPIC_COMBINED_TOOLS_AND_SCHEMA_MODELS.has(this.model)\n }\n\n private convertContentPartToAnthropic(\n part: ContentPart,\n ): TextBlockParam | ImageBlockParam | DocumentBlockParam {\n switch (part.type) {\n case 'text': {\n const metadata = part.metadata as AnthropicTextMetadata | undefined\n return {\n type: 'text',\n text: part.content,\n ...metadata,\n }\n }\n\n case 'image': {\n const metadata = part.metadata as AnthropicImageMetadata | undefined\n const imageSource: Base64ImageSource | URLImageSource =\n part.source.type === 'data'\n ? {\n type: 'base64',\n data: part.source.value,\n media_type: part.source.mimeType as\n | 'image/jpeg'\n | 'image/png'\n | 'image/gif'\n | 'image/webp',\n }\n : {\n type: 'url',\n url: part.source.value,\n }\n return {\n type: 'image',\n source: imageSource,\n ...metadata,\n }\n }\n case 'document': {\n const metadata = part.metadata as AnthropicDocumentMetadata | undefined\n const docSource: Base64PDFSource | URLPDFSource =\n part.source.type === 'data'\n ? {\n type: 'base64',\n data: part.source.value,\n media_type: part.source.mimeType as 'application/pdf',\n }\n : {\n type: 'url',\n url: part.source.value,\n }\n return {\n type: 'document',\n source: docSource,\n ...metadata,\n }\n }\n case 'audio':\n case 'video':\n throw new Error(\n `Anthropic does not support ${part.type} content directly`,\n )\n default: {\n const _exhaustiveCheck: never = part\n throw new Error(\n `Unsupported content part type: ${(_exhaustiveCheck as ContentPart).type}`,\n )\n }\n }\n }\n\n private formatMessages(\n messages: Array<ModelMessage>,\n ): InternalTextProviderOptions['messages'] {\n const formattedMessages: InternalTextProviderOptions['messages'] = []\n\n for (const message of messages) {\n const role = message.role\n\n if (role === 'tool' && message.toolCallId) {\n const toolContent = message.content\n formattedMessages.push({\n role: 'user',\n content: [\n {\n type: 'tool_result',\n tool_use_id: message.toolCallId,\n content: Array.isArray(toolContent)\n ? toolContent.map((part) =>\n this.convertContentPartToAnthropic(part),\n )\n : typeof toolContent === 'string'\n ? toolContent\n : '',\n },\n ],\n })\n continue\n }\n\n if (role === 'assistant' && message.toolCalls?.length) {\n const contentBlocks: Array<ContentBlockParam> = []\n\n this.appendThinkingBlocks(contentBlocks, message.thinking)\n\n if (message.content) {\n const content =\n typeof message.content === 'string' ? message.content : ''\n const textBlock: TextBlockParam = {\n type: 'text',\n text: content,\n }\n contentBlocks.push(textBlock)\n }\n\n for (const toolCall of message.toolCalls) {\n let parsedInput: unknown = {}\n try {\n const parsed = toolCall.function.arguments\n ? JSON.parse(toolCall.function.arguments)\n : {}\n parsedInput = parsed && typeof parsed === 'object' ? parsed : {}\n } catch {\n parsedInput = toolCall.function.arguments\n }\n\n const toolUseBlock: ToolUseBlockParam = {\n type: 'tool_use',\n id: toolCall.id,\n name: toolCall.function.name,\n input: parsedInput,\n }\n contentBlocks.push(toolUseBlock)\n }\n\n formattedMessages.push({\n role: 'assistant',\n content: contentBlocks,\n })\n\n continue\n }\n\n if (role === 'assistant') {\n const contentBlocks: Array<ContentBlockParam> = []\n this.appendThinkingBlocks(contentBlocks, message.thinking)\n\n if (Array.isArray(message.content)) {\n for (const part of message.content) {\n contentBlocks.push(this.convertContentPartToAnthropic(part))\n }\n } else if (message.content) {\n contentBlocks.push({\n type: 'text',\n text: message.content,\n })\n }\n\n formattedMessages.push({\n role: 'assistant',\n content: contentBlocks.length > 0 ? contentBlocks : '',\n })\n continue\n }\n\n if (role === 'user' && Array.isArray(message.content)) {\n const contentBlocks = message.content.map((part) =>\n this.convertContentPartToAnthropic(part),\n )\n formattedMessages.push({\n role: 'user',\n content: contentBlocks,\n })\n continue\n }\n\n formattedMessages.push({\n role: 'user',\n content:\n typeof message.content === 'string'\n ? message.content\n : message.content\n ? message.content.map((c) =>\n this.convertContentPartToAnthropic(c),\n )\n : '',\n })\n }\n\n // Post-process: Anthropic requires strictly alternating user/assistant roles.\n // Tool results are sent as role:'user' messages, which can create consecutive\n // user messages when followed by a new user message. Merge them.\n return this.mergeConsecutiveSameRoleMessages(formattedMessages)\n }\n\n private appendThinkingBlocks(\n contentBlocks: Array<ContentBlockParam>,\n thinkingParts: ModelMessage['thinking'],\n ): void {\n if (!thinkingParts?.length) return\n\n for (const thinking of thinkingParts) {\n if (!thinking.signature) continue\n const block: ThinkingBlockParam = {\n type: 'thinking',\n thinking: thinking.content,\n signature: thinking.signature,\n }\n contentBlocks.push(block)\n }\n }\n\n /**\n * Merge consecutive messages of the same role into a single message.\n * Anthropic's API requires strictly alternating user/assistant roles.\n * Tool results are wrapped as role:'user' messages, which can collide\n * with actual user messages in multi-turn conversations.\n *\n * Also filters out empty assistant messages (e.g., from a previous failed request).\n */\n private mergeConsecutiveSameRoleMessages(\n messages: InternalTextProviderOptions['messages'],\n ): InternalTextProviderOptions['messages'] {\n const merged: InternalTextProviderOptions['messages'] = []\n\n for (const msg of messages) {\n // Skip empty assistant messages (no content or empty string)\n if (msg.role === 'assistant') {\n const hasContent = Array.isArray(msg.content)\n ? msg.content.length > 0\n : typeof msg.content === 'string' && msg.content.length > 0\n if (!hasContent) {\n continue\n }\n }\n\n const prev = merged[merged.length - 1]\n if (prev && prev.role === msg.role) {\n // Normalize both contents to arrays and concatenate\n const prevBlocks = Array.isArray(prev.content)\n ? prev.content\n : typeof prev.content === 'string' && prev.content\n ? [{ type: 'text' as const, text: prev.content }]\n : []\n const msgBlocks = Array.isArray(msg.content)\n ? msg.content\n : typeof msg.content === 'string' && msg.content\n ? [{ type: 'text' as const, text: msg.content }]\n : []\n prev.content = [...prevBlocks, ...msgBlocks]\n } else {\n merged.push({ ...msg })\n }\n }\n\n // De-duplicate tool_result blocks with the same tool_use_id.\n // This can happen when the core layer generates tool results from both\n // the tool-result part and the tool-call part's output field.\n for (const msg of merged) {\n if (Array.isArray(msg.content)) {\n const seenToolResultIds = new Set<string>()\n msg.content = msg.content.filter((block: any) => {\n if (block.type === 'tool_result' && block.tool_use_id) {\n if (seenToolResultIds.has(block.tool_use_id)) {\n return false // Remove duplicate\n }\n seenToolResultIds.add(block.tool_use_id)\n }\n return true\n })\n }\n }\n\n return merged\n }\n\n private async *processAnthropicStream(\n stream: AsyncIterable<Anthropic_SDK.Beta.BetaRawMessageStreamEvent>,\n options: TextOptions<AnthropicTextProviderOptions>,\n genId: () => string,\n logger: InternalLogger,\n ): AsyncIterable<StreamChunk> {\n const model = options.model\n let accumulatedContent = ''\n let accumulatedThinking = ''\n let accumulatedSignature = ''\n const toolCallsMap = new Map<\n number,\n { id: string; name: string; input: string; started: boolean }\n >()\n let currentToolIndex = -1\n // Server-side tools share the `input_json_delta` wire format with client\n // `tool_use` blocks; routing both to the same buffer corrupts client tool\n // input.\n let currentServerTool: { id: string; name: string; input: string } | null =\n null\n\n // AG-UI lifecycle tracking\n const runId = options.runId ?? genId()\n const threadId = options.threadId ?? genId()\n const messageId = genId()\n let stepId: string | null = null\n let reasoningMessageId: string | null = null\n let hasClosedReasoning = false\n let hasEmittedRunStarted = false\n let hasEmittedTextMessageStart = false\n let hasEmittedRunFinished = false\n // Track current content block type for proper content_block_stop handling\n let currentBlockType: string | null = null\n\n try {\n for await (const event of stream) {\n logger.provider(`provider=anthropic type=${event.type}`, {\n chunk: event,\n })\n // Emit RUN_STARTED on first event\n if (!hasEmittedRunStarted) {\n hasEmittedRunStarted = true\n yield {\n type: EventType.RUN_STARTED,\n runId,\n threadId,\n model,\n timestamp: Date.now(),\n parentRunId: options.parentRunId,\n }\n }\n\n if (event.type === 'content_block_start') {\n currentBlockType = event.content_block.type\n if (event.content_block.type === 'tool_use') {\n currentToolIndex++\n toolCallsMap.set(currentToolIndex, {\n id: event.content_block.id,\n name: event.content_block.name,\n input: '',\n started: false,\n })\n } else if (event.content_block.type === 'server_tool_use') {\n currentServerTool = {\n id: event.content_block.id,\n name: event.content_block.name,\n input: '',\n }\n } else if (\n event.content_block.type === 'web_fetch_tool_result' ||\n event.content_block.type === 'web_search_tool_result'\n ) {\n // The result content arrives in full at content_block_start (no\n // deltas). Surface error variants so a failed fetch/search isn't\n // invisible to the consumer.\n const content = event.content_block.content as\n | { type?: string; error_code?: string }\n | Array<unknown>\n const errorBlock =\n !Array.isArray(content) &&\n (content.type === 'web_fetch_tool_result_error' ||\n content.type === 'web_search_tool_result_error')\n ? content\n : null\n if (errorBlock) {\n logger.errors(\n `anthropic.${event.content_block.type} error_code=${errorBlock.error_code}`,\n {\n toolUseId: event.content_block.tool_use_id,\n blockType: event.content_block.type,\n errorCode: errorBlock.error_code,\n source: 'anthropic.processAnthropicStream',\n },\n )\n }\n } else if (event.content_block.type === 'thinking') {\n accumulatedThinking = ''\n accumulatedSignature = ''\n // Emit REASONING and STEP_STARTED for thinking\n stepId = genId()\n reasoningMessageId = genId()\n\n // Spec REASONING events\n yield {\n type: EventType.REASONING_START,\n messageId: reasoningMessageId,\n model,\n timestamp: Date.now(),\n }\n yield {\n type: EventType.REASONING_MESSAGE_START,\n messageId: reasoningMessageId,\n role: 'reasoning' as const,\n model,\n timestamp: Date.now(),\n }\n\n // Legacy STEP events (kept during transition)\n yield {\n type: EventType.STEP_STARTED,\n stepName: stepId,\n stepId,\n model,\n timestamp: Date.now(),\n stepType: 'thinking',\n }\n }\n } else if (event.type === 'content_block_delta') {\n if (event.delta.type === 'text_delta') {\n // Close reasoning before text starts\n if (reasoningMessageId && !hasClosedReasoning) {\n hasClosedReasoning = true\n yield {\n type: EventType.REASONING_MESSAGE_END,\n messageId: reasoningMessageId,\n model,\n timestamp: Date.now(),\n }\n yield {\n type: EventType.REASONING_END,\n messageId: reasoningMessageId,\n model,\n timestamp: Date.now(),\n }\n }\n\n // Emit TEXT_MESSAGE_START on first text content\n if (!hasEmittedTextMessageStart) {\n hasEmittedTextMessageStart = true\n yield {\n type: EventType.TEXT_MESSAGE_START,\n messageId,\n model,\n timestamp: Date.now(),\n role: 'assistant',\n }\n }\n\n const delta = event.delta.text\n accumulatedContent += delta\n yield {\n type: EventType.TEXT_MESSAGE_CONTENT,\n messageId,\n model,\n timestamp: Date.now(),\n delta,\n content: accumulatedContent,\n }\n } else if (\n event.delta.type === 'thinking_delta' &&\n reasoningMessageId\n ) {\n const delta = event.delta.thinking\n accumulatedThinking += delta\n\n // Spec REASONING content event\n yield {\n type: EventType.REASONING_MESSAGE_CONTENT,\n messageId: reasoningMessageId,\n delta,\n model,\n timestamp: Date.now(),\n }\n\n // Legacy STEP event\n yield {\n type: EventType.STEP_FINISHED,\n stepName: stepId || genId(),\n stepId: stepId || genId(),\n model,\n timestamp: Date.now(),\n delta,\n content: accumulatedThinking,\n }\n } else if (\n (event.delta as { type: string }).type === 'signature_delta'\n ) {\n accumulatedSignature +=\n (event.delta as { signature: string }).signature || ''\n } else if (event.delta.type === 'input_json_delta') {\n // Route deltas by current block type so server_tool_use input\n // never appends onto the prior client tool's buffer.\n if (currentBlockType === 'tool_use') {\n const existing = toolCallsMap.get(currentToolIndex)\n if (existing) {\n // Emit TOOL_CALL_START on first args delta\n if (!existing.started) {\n existing.started = true\n yield {\n type: EventType.TOOL_CALL_START,\n toolCallId: existing.id,\n toolCallName: existing.name,\n toolName: existing.name,\n model,\n timestamp: Date.now(),\n index: currentToolIndex,\n }\n }\n\n existing.input += event.delta.partial_json\n\n yield {\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: existing.id,\n model,\n timestamp: Date.now(),\n delta: event.delta.partial_json,\n args: existing.input,\n }\n }\n } else if (\n currentBlockType === 'server_tool_use' &&\n currentServerTool\n ) {\n // Accumulate server tool input internally. We don't emit\n // TOOL_CALL_* events: the call is executed by Anthropic, not\n // by our agent loop, so surfacing it as a client tool call\n // would cause downstream code to try (and fail) to run it.\n currentServerTool.input += event.delta.partial_json\n }\n }\n } else if (event.type === 'content_block_stop') {\n if (currentBlockType === 'thinking') {\n // Emit signature so it can be replayed in multi-turn context\n if (accumulatedSignature && stepId) {\n yield {\n type: EventType.STEP_FINISHED,\n stepName: stepId,\n stepId,\n model,\n timestamp: Date.now(),\n delta: '',\n content: accumulatedThinking,\n signature: accumulatedSignature,\n }\n }\n } else if (currentBlockType === 'tool_use') {\n const existing = toolCallsMap.get(currentToolIndex)\n if (existing) {\n // If tool call wasn't started yet (no args), start it now\n if (!existing.started) {\n existing.started = true\n yield {\n type: EventType.TOOL_CALL_START,\n toolCallId: existing.id,\n toolCallName: existing.name,\n toolName: existing.name,\n model,\n timestamp: Date.now(),\n index: currentToolIndex,\n }\n }\n\n // Emit TOOL_CALL_END\n let parsedInput: unknown = {}\n try {\n const parsed = existing.input ? JSON.parse(existing.input) : {}\n parsedInput = parsed && typeof parsed === 'object' ? parsed : {}\n } catch {\n parsedInput = {}\n }\n\n yield {\n type: EventType.TOOL_CALL_END,\n toolCallId: existing.id,\n toolCallName: existing.name,\n toolName: existing.name,\n model,\n timestamp: Date.now(),\n input: parsedInput,\n }\n\n // Reset so a new TEXT_MESSAGE_START is emitted if text follows tool calls\n hasEmittedTextMessageStart = false\n }\n } else if (currentBlockType === 'server_tool_use') {\n if (currentServerTool) {\n // Anthropic executes the call; we only need a breadcrumb so\n // consumers (devtools, telemetry) can see what ran.\n logger.provider(\n `provider=anthropic server_tool_use name=${currentServerTool.name}`,\n {\n toolUseId: currentServerTool.id,\n name: currentServerTool.name,\n input: currentServerTool.input,\n },\n )\n }\n currentServerTool = null\n } else if (\n currentBlockType === 'web_fetch_tool_result' ||\n currentBlockType === 'web_search_tool_result'\n ) {\n // The model already consumed the result; error variants were\n // already surfaced at content_block_start.\n } else {\n // Emit TEXT_MESSAGE_END only for text blocks (not tool_use blocks)\n if (hasEmittedTextMessageStart && accumulatedContent) {\n yield {\n type: EventType.TEXT_MESSAGE_END,\n messageId,\n model,\n timestamp: Date.now(),\n }\n }\n }\n currentBlockType = null\n } else if (event.type === 'message_stop') {\n // Close reasoning events if still open\n if (reasoningMessageId && !hasClosedReasoning) {\n hasClosedReasoning = true\n yield {\n type: EventType.REASONING_MESSAGE_END,\n messageId: reasoningMessageId,\n model,\n timestamp: Date.now(),\n }\n yield {\n type: EventType.REASONING_END,\n messageId: reasoningMessageId,\n model,\n timestamp: Date.now(),\n }\n }\n\n // Only emit RUN_FINISHED from message_stop if message_delta didn't already emit one.\n // message_delta carries the real stop_reason (tool_use, end_turn, etc.),\n // while message_stop is just a completion signal.\n if (!hasEmittedRunFinished) {\n yield {\n type: EventType.RUN_FINISHED,\n runId,\n threadId,\n model,\n timestamp: Date.now(),\n finishReason: 'stop',\n }\n }\n } else if (event.type === 'message_delta') {\n if (event.delta.stop_reason) {\n hasEmittedRunFinished = true\n\n // Close reasoning events if still open\n if (reasoningMessageId && !hasClosedReasoning) {\n hasClosedReasoning = true\n yield {\n type: EventType.REASONING_MESSAGE_END,\n messageId: reasoningMessageId,\n model,\n timestamp: Date.now(),\n }\n yield {\n type: EventType.REASONING_END,\n messageId: reasoningMessageId,\n model,\n timestamp: Date.now(),\n }\n }\n\n switch (event.delta.stop_reason) {\n case 'tool_use': {\n yield {\n type: EventType.RUN_FINISHED,\n runId,\n threadId,\n model,\n timestamp: Date.now(),\n finishReason: 'tool_calls',\n usage: buildAnthropicUsage(event.usage),\n }\n break\n }\n case 'max_tokens': {\n yield {\n type: EventType.RUN_ERROR,\n model,\n timestamp: Date.now(),\n message:\n 'The response was cut off because the maximum token limit was reached.',\n code: 'max_tokens',\n error: {\n message:\n 'The response was cut off because the maximum token limit was reached.',\n code: 'max_tokens',\n },\n }\n break\n }\n case 'stop_sequence':\n case 'end_turn':\n case 'pause_turn':\n case 'refusal':\n case 'model_context_window_exceeded':\n case 'compaction':\n default: {\n // All remaining Anthropic stop_reason variants map to the\n // generic \"stop\" finish reason — they describe *why* the\n // stream ended, but for AG-UI consumers the resulting event\n // shape is identical.\n yield {\n type: EventType.RUN_FINISHED,\n runId,\n threadId,\n model,\n timestamp: Date.now(),\n finishReason: 'stop',\n usage: buildAnthropicUsage(event.usage),\n }\n }\n }\n }\n }\n }\n } catch (error: unknown) {\n const err = error as Error & { status?: number; code?: string }\n const rawEvent = toRunErrorRawEvent(error)\n\n logger.errors('anthropic.processAnthropicStream fatal', {\n error,\n source: 'anthropic.processAnthropicStream',\n })\n yield {\n type: EventType.RUN_ERROR,\n model,\n timestamp: Date.now(),\n message: err.message || 'Unknown error occurred',\n code: err.code || String(err.status),\n // Forward the Anthropic SDK error's `.error` response body when present.\n ...(rawEvent !== undefined && { rawEvent }),\n error: {\n message: err.message || 'Unknown error occurred',\n code: err.code || String(err.status),\n },\n }\n }\n }\n}\n\n/**\n * Creates an Anthropic chat adapter with explicit API key.\n * Type resolution happens here at the call site.\n */\nexport function createAnthropicChat<\n TModel extends (typeof ANTHROPIC_MODELS)[number],\n>(\n model: TModel,\n apiKey: string,\n config?: Omit<AnthropicTextConfig, 'apiKey'>,\n): AnthropicTextAdapter<\n TModel,\n ResolveProviderOptions<TModel>,\n ResolveInputModalities<TModel>\n> {\n return new AnthropicTextAdapter({ apiKey, ...config }, model)\n}\n\n/**\n * Creates an Anthropic text adapter with automatic API key detection.\n * Type resolution happens here at the call site.\n */\nexport function anthropicText<TModel extends (typeof ANTHROPIC_MODELS)[number]>(\n model: TModel,\n config?: Omit<AnthropicTextConfig, 'apiKey'>,\n): AnthropicTextAdapter<\n TModel,\n ResolveProviderOptions<TModel>,\n ResolveInputModalities<TModel>\n> {\n const apiKey = getAnthropicApiKeyFromEnv()\n return createAnthropicChat(model, apiKey, config)\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"text.js","sources":["../../../src/adapters/text.ts"],"sourcesContent":["import { EventType, normalizeSystemPrompts } from '@tanstack/ai'\nimport { toRunErrorRawEvent } from '@tanstack/ai/adapter-internals'\nimport { BaseTextAdapter } from '@tanstack/ai/adapters'\nimport { convertToolsToProviderFormat } from '../tools/tool-converter'\nimport { validateTextProviderOptions } from '../text/text-provider-options'\nimport { buildAnthropicUsage } from '../usage'\nimport {\n createAnthropicClient,\n generateId,\n getAnthropicApiKeyFromEnv,\n} from '../utils'\nimport { ANTHROPIC_COMBINED_TOOLS_AND_SCHEMA_MODELS } from '../model-meta'\nimport type {\n ANTHROPIC_MODELS,\n AnthropicChatModelProviderOptionsByName,\n AnthropicChatModelToolCapabilitiesByName,\n AnthropicModelInputModalitiesByName,\n} from '../model-meta'\nimport type {\n StructuredOutputOptions,\n StructuredOutputResult,\n} from '@tanstack/ai/adapters'\nimport type { InternalLogger } from '@tanstack/ai/adapter-internals'\nimport type {\n Base64ImageSource,\n Base64PDFSource,\n ContentBlockParam,\n DocumentBlockParam,\n ImageBlockParam,\n TextBlockParam,\n ThinkingBlockParam,\n ToolUseBlockParam,\n URLImageSource,\n URLPDFSource,\n} from '@anthropic-ai/sdk/resources/messages'\nimport type Anthropic_SDK from '@anthropic-ai/sdk'\nimport type { AnthropicBeta } from '@anthropic-ai/sdk/resources/beta/beta'\nimport type {\n ContentPart,\n Modality,\n ModelMessage,\n StreamChunk,\n TextOptions,\n} from '@tanstack/ai'\nimport type {\n AnthropicSystemPromptMetadata,\n ExternalTextProviderOptions,\n InternalTextProviderOptions,\n} from '../text/text-provider-options'\nimport type {\n AnthropicDocumentMetadata,\n AnthropicImageMetadata,\n AnthropicMessageMetadataByModality,\n AnthropicTextMetadata,\n} from '../message-types'\nimport type { AnthropicClientConfig } from '../utils'\n\n/**\n * Configuration for Anthropic text adapter\n */\nexport interface AnthropicTextConfig extends AnthropicClientConfig {}\n\n/**\n * Anthropic-specific provider options for text/chat\n */\nexport type AnthropicTextProviderOptions = ExternalTextProviderOptions\n\n// ===========================\n// Type Resolution Helpers\n// ===========================\n\n/**\n * Resolve provider options for a specific model.\n * If the model has explicit options in the map, use those; otherwise use base options.\n */\ntype ResolveProviderOptions<TModel extends string> =\n TModel extends keyof AnthropicChatModelProviderOptionsByName\n ? AnthropicChatModelProviderOptionsByName[TModel]\n : AnthropicTextProviderOptions\n\n/**\n * Resolve input modalities for a specific model.\n * If the model has explicit modalities in the map, use those; otherwise use default.\n */\ntype ResolveInputModalities<TModel extends string> =\n TModel extends keyof AnthropicModelInputModalitiesByName\n ? AnthropicModelInputModalitiesByName[TModel]\n : readonly ['text', 'image', 'document']\n\ntype ResolveToolCapabilities<TModel extends string> =\n TModel extends keyof AnthropicChatModelToolCapabilitiesByName\n ? NonNullable<AnthropicChatModelToolCapabilitiesByName[TModel]>\n : readonly []\n\n// ===========================\n// Adapter Implementation\n// ===========================\n\n/**\n * Anthropic Text (Chat) Adapter\n *\n * Tree-shakeable adapter for Anthropic chat/text completion functionality.\n * Import only what you need for smaller bundle sizes.\n */\nexport class AnthropicTextAdapter<\n TModel extends (typeof ANTHROPIC_MODELS)[number],\n TProviderOptions extends Record<string, any> = ResolveProviderOptions<TModel>,\n TInputModalities extends ReadonlyArray<Modality> =\n ResolveInputModalities<TModel>,\n TToolCapabilities extends ReadonlyArray<string> =\n ResolveToolCapabilities<TModel>,\n> extends BaseTextAdapter<\n TModel,\n TProviderOptions,\n TInputModalities,\n AnthropicMessageMetadataByModality,\n TToolCapabilities,\n // TToolCallMetadata — anthropic has no tool-call metadata round-tripping\n unknown,\n // TSystemPromptMetadata — narrows `systemPrompts[i].metadata` at the\n // chat() call site so users get `cache_control` autocomplete.\n AnthropicSystemPromptMetadata\n> {\n override readonly kind = 'text' as const\n readonly name = 'anthropic' as const\n\n private readonly client: Anthropic_SDK\n\n constructor(config: AnthropicTextConfig, model: TModel) {\n super({}, model)\n this.client = createAnthropicClient(config)\n }\n\n async *chatStream(\n options: TextOptions<TProviderOptions>,\n ): AsyncIterable<StreamChunk> {\n const { logger } = options\n try {\n const requestParams = this.mapCommonOptionsToAnthropic(options)\n\n logger.request(\n `activity=chat provider=anthropic model=${this.model} messages=${options.messages.length} tools=${options.tools?.length ?? 0} stream=true`,\n { provider: 'anthropic', model: this.model },\n )\n\n // `betas` is attached at the call site rather than in the shared mapper\n // because the `interleaved-thinking-2025-05-14` header is only useful for\n // the streaming path.\n const modelOptions = options.modelOptions as\n | InternalTextProviderOptions\n | undefined\n const useInterleavedThinking =\n modelOptions?.thinking?.type === 'enabled' &&\n typeof modelOptions.thinking.budget_tokens === 'number' &&\n modelOptions.thinking.budget_tokens > 0\n const betas: Array<AnthropicBeta> | undefined = useInterleavedThinking\n ? ['interleaved-thinking-2025-05-14']\n : undefined\n\n // `client.beta.messages` is Anthropic's permanent staging surface, not a\n // sunset path: it's a superset of `client.messages` that additionally\n // accepts the `betas: AnthropicBeta[]` header (e.g. interleaved\n // thinking) plus richer `container` (skills) and `context_management`\n // shapes that `InternalTextProviderOptions` carries. We route every\n // Messages call through it so the request mapper stays single-shape.\n const stream = await this.client.beta.messages.create(\n {\n ...requestParams,\n stream: true,\n ...(betas && { betas }),\n },\n {\n signal: options.request?.signal,\n headers: options.request?.headers,\n },\n )\n\n yield* this.processAnthropicStream(\n stream,\n options,\n () => generateId(this.name),\n logger,\n )\n } catch (error: unknown) {\n const err = error as Error & { status?: number; code?: string }\n const rawEvent = toRunErrorRawEvent(error)\n logger.errors('anthropic.chatStream fatal', {\n error,\n source: 'anthropic.chatStream',\n })\n yield {\n type: EventType.RUN_ERROR,\n model: options.model,\n timestamp: Date.now(),\n message: err.message || 'Unknown error occurred',\n code: err.code || String(err.status),\n // Forward the Anthropic SDK error's `.error` response body (e.g.\n // `{ type, message }`) when present; never the raw exception object.\n ...(rawEvent !== undefined && { rawEvent }),\n error: {\n message: err.message || 'Unknown error occurred',\n code: err.code || String(err.status),\n },\n }\n }\n }\n\n /**\n * Generate structured output using Anthropic's tool-based approach.\n * Anthropic doesn't have native structured output, so we use a tool with the schema\n * and force the model to call it.\n * The outputSchema is already JSON Schema (converted in the ai layer).\n */\n async structuredOutput(\n options: StructuredOutputOptions<TProviderOptions>,\n ): Promise<StructuredOutputResult<unknown>> {\n const { chatOptions, outputSchema } = options\n const { logger } = chatOptions\n\n const requestParams = this.mapCommonOptionsToAnthropic(chatOptions)\n\n // Create a tool that will capture the structured output\n // Anthropic's SDK requires input_schema with type: 'object' literal\n const structuredOutputTool = {\n name: 'structured_output',\n description:\n 'Use this tool to provide your response in the required structured format.',\n input_schema: {\n type: 'object' as const,\n properties: outputSchema.properties ?? {},\n required: outputSchema.required ?? [],\n },\n }\n\n try {\n logger.request(\n `activity=chat provider=anthropic model=${this.model} messages=${chatOptions.messages.length} tools=${chatOptions.tools?.length ?? 0} stream=false`,\n { provider: 'anthropic', model: this.model },\n )\n // Make non-streaming request with tool_choice forced to our structured output tool\n const response = await this.client.beta.messages.create(\n {\n ...requestParams,\n stream: false,\n tools: [structuredOutputTool],\n tool_choice: { type: 'tool', name: 'structured_output' },\n },\n {\n signal: chatOptions.request?.signal,\n headers: chatOptions.request?.headers,\n },\n )\n\n // Extract the tool use content from the response\n let parsed: unknown = null\n let rawText = ''\n\n for (const block of response.content) {\n if (block.type === 'tool_use' && block.name === 'structured_output') {\n parsed = block.input\n rawText = JSON.stringify(block.input)\n break\n }\n }\n\n if (parsed === null) {\n // Fallback: try to extract text content and parse as JSON\n rawText = response.content\n .map((b) => {\n if (b.type === 'text') {\n return b.text\n }\n return ''\n })\n .join('')\n try {\n parsed = JSON.parse(rawText)\n } catch {\n throw new Error(\n `Failed to extract structured output from response. Content: ${rawText.slice(0, 200)}${rawText.length > 200 ? '...' : ''}`,\n )\n }\n }\n\n return {\n data: parsed,\n rawText,\n usage: buildAnthropicUsage(response.usage),\n }\n } catch (error: unknown) {\n const err = error as Error\n logger.errors('anthropic.structuredOutput fatal', {\n error,\n source: 'anthropic.structuredOutput',\n })\n throw new Error(\n `Structured output generation failed: ${err.message || 'Unknown error occurred'}`,\n )\n }\n }\n\n private mapCommonOptionsToAnthropic(\n options: TextOptions<AnthropicTextProviderOptions>,\n ) {\n const modelOptions = options.modelOptions\n\n const formattedMessages = this.formatMessages(options.messages)\n const tools = options.tools\n ? convertToolsToProviderFormat(options.tools)\n : undefined\n\n const validProviderOptions: Partial<InternalTextProviderOptions> = {}\n if (modelOptions) {\n const validKeys: Array<keyof AnthropicTextProviderOptions> = [\n 'container',\n 'context_management',\n 'effort',\n 'mcp_servers',\n 'output_config',\n 'service_tier',\n 'stop_sequences',\n 'thinking',\n 'tool_choice',\n 'top_k',\n 'temperature',\n 'top_p',\n ]\n // `max_tokens` is a legitimate public modelOptions field, but it is read\n // via a dedicated path (defaultMaxTokens below) rather than copied into\n // validProviderOptions. Exempt it from the dropped-key warning here so a\n // correct `modelOptions: { max_tokens }` call doesn't log a spurious\n // \"dropped unknown key\" error, while keeping it out of the copy loop.\n const droppedKeyExemptSet = new Set<string>([...validKeys, 'max_tokens'])\n const droppedKeys = Object.keys(modelOptions).filter(\n (key) => !droppedKeyExemptSet.has(key),\n )\n if (droppedKeys.length > 0) {\n // Reachable when callers cast around the public type (e.g.\n // `modelOptions: { system: ... } as any`). Without this warning the\n // unknown keys are silently dropped — `system` in particular was a\n // previously-tested path for attaching `cache_control` and we don't\n // want that to fail in production with no signal.\n options.logger.errors(\n `anthropic.mapCommonOptionsToAnthropic dropped unknown modelOptions key(s): ${droppedKeys.join(', ')}`,\n {\n source: 'anthropic.mapCommonOptionsToAnthropic',\n droppedKeys,\n hint: droppedKeys.includes('system')\n ? 'pass system prompts via the top-level `systemPrompts` option; `modelOptions.system` is no longer honored'\n : undefined,\n },\n )\n }\n for (const key of validKeys) {\n if (key in modelOptions) {\n const value = modelOptions[key]\n if (key === 'tool_choice' && typeof value === 'string') {\n ;(validProviderOptions as Record<string, unknown>)[key] = {\n type: value,\n }\n } else {\n ;(validProviderOptions as Record<string, unknown>)[key] = value\n }\n }\n }\n }\n\n const thinkingBudget =\n validProviderOptions.thinking?.type === 'enabled'\n ? validProviderOptions.thinking.budget_tokens\n : undefined\n const defaultMaxTokens = modelOptions?.max_tokens ?? 1024\n const maxTokens =\n thinkingBudget && thinkingBudget >= defaultMaxTokens\n ? thinkingBudget + 1\n : defaultMaxTokens\n\n // `InternalTextProviderOptions.system` is typed\n // `string | Array<TextBlockParam>` (no `| undefined`), so build it\n // outside the literal and spread it conditionally rather than\n // assigning `undefined` under exactOptionalPropertyTypes.\n const systemBlocks = ((): Array<TextBlockParam> | undefined => {\n const normalized = normalizeSystemPrompts<AnthropicSystemPromptMetadata>(\n options.systemPrompts,\n )\n if (normalized.length === 0) return undefined\n return normalized.map(\n (p): TextBlockParam => ({\n type: 'text',\n text: p.content,\n ...(p.metadata?.cache_control && {\n cache_control: p.metadata.cache_control,\n }),\n }),\n )\n })()\n // Wire engine-threaded outputSchema into Messages `output_config.format`\n // alongside any `tools` so the model emits tool calls during the agent\n // loop and a single schema-constrained JSON message on its final turn.\n // Merge into any existing `output_config` so callers can keep tuning\n // `output_config.effort` alongside the schema.\n const combinedSchema = options.outputSchema as\n | Record<string, unknown>\n | undefined\n const outputConfig = combinedSchema\n ? {\n output_config: {\n ...(validProviderOptions.output_config ?? {}),\n format: {\n type: 'json_schema' as const,\n schema: combinedSchema,\n },\n },\n }\n : undefined\n\n // `temperature`/`top_p` arrive via `...validProviderOptions` (sourced from\n // `modelOptions`). `InternalTextProviderOptions` declares `system` and\n // `tools` as `T?: ...` (no `| undefined`), so spread them conditionally\n // rather than passing explicit `undefined` under exactOptionalPropertyTypes.\n const requestParams: InternalTextProviderOptions = {\n model: options.model,\n max_tokens: maxTokens,\n messages: formattedMessages,\n ...(systemBlocks !== undefined && { system: systemBlocks }),\n ...(tools !== undefined && { tools }),\n ...validProviderOptions,\n ...(outputConfig ?? {}),\n }\n validateTextProviderOptions(requestParams)\n return requestParams\n }\n\n /**\n * Anthropic supports `output_config.format` + `tools` in a single streaming\n * Messages request only for Claude 4.5+ (GA 2026-01-29). For 4.4 and\n * earlier we keep the forced-tool-use workaround in\n * {@link structuredOutput} via the engine's finalization path.\n */\n supportsCombinedToolsAndSchema(): boolean {\n return ANTHROPIC_COMBINED_TOOLS_AND_SCHEMA_MODELS.has(this.model)\n }\n\n private convertContentPartToAnthropic(\n part: ContentPart,\n ): TextBlockParam | ImageBlockParam | DocumentBlockParam {\n switch (part.type) {\n case 'text': {\n const metadata = part.metadata as AnthropicTextMetadata | undefined\n return {\n type: 'text',\n text: part.content,\n ...metadata,\n }\n }\n\n case 'image': {\n const metadata = part.metadata as AnthropicImageMetadata | undefined\n const imageSource: Base64ImageSource | URLImageSource =\n part.source.type === 'data'\n ? {\n type: 'base64',\n data: part.source.value,\n media_type: part.source.mimeType as\n | 'image/jpeg'\n | 'image/png'\n | 'image/gif'\n | 'image/webp',\n }\n : {\n type: 'url',\n url: part.source.value,\n }\n return {\n type: 'image',\n source: imageSource,\n ...metadata,\n }\n }\n case 'document': {\n const metadata = part.metadata as AnthropicDocumentMetadata | undefined\n const docSource: Base64PDFSource | URLPDFSource =\n part.source.type === 'data'\n ? {\n type: 'base64',\n data: part.source.value,\n media_type: part.source.mimeType as 'application/pdf',\n }\n : {\n type: 'url',\n url: part.source.value,\n }\n return {\n type: 'document',\n source: docSource,\n ...metadata,\n }\n }\n case 'audio':\n case 'video':\n throw new Error(\n `Anthropic does not support ${part.type} content directly`,\n )\n default: {\n const _exhaustiveCheck: never = part\n throw new Error(\n `Unsupported content part type: ${(_exhaustiveCheck as ContentPart).type}`,\n )\n }\n }\n }\n\n private formatMessages(\n messages: Array<ModelMessage>,\n ): InternalTextProviderOptions['messages'] {\n const formattedMessages: InternalTextProviderOptions['messages'] = []\n\n for (const message of messages) {\n const role = message.role\n\n if (role === 'tool' && message.toolCallId) {\n const toolContent = message.content\n formattedMessages.push({\n role: 'user',\n content: [\n {\n type: 'tool_result',\n tool_use_id: message.toolCallId,\n content: Array.isArray(toolContent)\n ? toolContent.map((part) =>\n this.convertContentPartToAnthropic(part),\n )\n : typeof toolContent === 'string'\n ? toolContent\n : '',\n },\n ],\n })\n continue\n }\n\n if (role === 'assistant' && message.toolCalls?.length) {\n const contentBlocks: Array<ContentBlockParam> = []\n\n this.appendThinkingBlocks(contentBlocks, message.thinking)\n\n if (message.content) {\n const content =\n typeof message.content === 'string' ? message.content : ''\n const textBlock: TextBlockParam = {\n type: 'text',\n text: content,\n }\n contentBlocks.push(textBlock)\n }\n\n for (const toolCall of message.toolCalls) {\n let parsedInput: unknown = {}\n try {\n const parsed = toolCall.function.arguments\n ? JSON.parse(toolCall.function.arguments)\n : {}\n parsedInput = parsed && typeof parsed === 'object' ? parsed : {}\n } catch {\n parsedInput = toolCall.function.arguments\n }\n\n const toolUseBlock: ToolUseBlockParam = {\n type: 'tool_use',\n id: toolCall.id,\n name: toolCall.function.name,\n input: parsedInput,\n }\n contentBlocks.push(toolUseBlock)\n }\n\n formattedMessages.push({\n role: 'assistant',\n content: contentBlocks,\n })\n\n continue\n }\n\n if (role === 'assistant') {\n const contentBlocks: Array<ContentBlockParam> = []\n this.appendThinkingBlocks(contentBlocks, message.thinking)\n\n if (Array.isArray(message.content)) {\n for (const part of message.content) {\n contentBlocks.push(this.convertContentPartToAnthropic(part))\n }\n } else if (message.content) {\n contentBlocks.push({\n type: 'text',\n text: message.content,\n })\n }\n\n formattedMessages.push({\n role: 'assistant',\n content: contentBlocks.length > 0 ? contentBlocks : '',\n })\n continue\n }\n\n if (role === 'user' && Array.isArray(message.content)) {\n const contentBlocks = message.content.map((part) =>\n this.convertContentPartToAnthropic(part),\n )\n formattedMessages.push({\n role: 'user',\n content: contentBlocks,\n })\n continue\n }\n\n formattedMessages.push({\n role: 'user',\n content:\n typeof message.content === 'string'\n ? message.content\n : message.content\n ? message.content.map((c) =>\n this.convertContentPartToAnthropic(c),\n )\n : '',\n })\n }\n\n // Post-process: Anthropic requires strictly alternating user/assistant roles.\n // Tool results are sent as role:'user' messages, which can create consecutive\n // user messages when followed by a new user message. Merge them.\n return this.mergeConsecutiveSameRoleMessages(formattedMessages)\n }\n\n private appendThinkingBlocks(\n contentBlocks: Array<ContentBlockParam>,\n thinkingParts: ModelMessage['thinking'],\n ): void {\n if (!thinkingParts?.length) return\n\n for (const thinking of thinkingParts) {\n if (!thinking.signature) continue\n const block: ThinkingBlockParam = {\n type: 'thinking',\n thinking: thinking.content,\n signature: thinking.signature,\n }\n contentBlocks.push(block)\n }\n }\n\n /**\n * Merge consecutive messages of the same role into a single message.\n * Anthropic's API requires strictly alternating user/assistant roles.\n * Tool results are wrapped as role:'user' messages, which can collide\n * with actual user messages in multi-turn conversations.\n *\n * Also filters out empty assistant messages (e.g., from a previous failed request).\n */\n private mergeConsecutiveSameRoleMessages(\n messages: InternalTextProviderOptions['messages'],\n ): InternalTextProviderOptions['messages'] {\n const merged: InternalTextProviderOptions['messages'] = []\n\n for (const msg of messages) {\n // Skip empty assistant messages (no content or empty string)\n if (msg.role === 'assistant') {\n const hasContent = Array.isArray(msg.content)\n ? msg.content.length > 0\n : typeof msg.content === 'string' && msg.content.length > 0\n if (!hasContent) {\n continue\n }\n }\n\n const prev = merged[merged.length - 1]\n if (prev && prev.role === msg.role) {\n // Normalize both contents to arrays and concatenate\n const prevBlocks = Array.isArray(prev.content)\n ? prev.content\n : typeof prev.content === 'string' && prev.content\n ? [{ type: 'text' as const, text: prev.content }]\n : []\n const msgBlocks = Array.isArray(msg.content)\n ? msg.content\n : typeof msg.content === 'string' && msg.content\n ? [{ type: 'text' as const, text: msg.content }]\n : []\n prev.content = [...prevBlocks, ...msgBlocks]\n } else {\n merged.push({ ...msg })\n }\n }\n\n // De-duplicate tool_result blocks with the same tool_use_id.\n // This can happen when the core layer generates tool results from both\n // the tool-result part and the tool-call part's output field.\n for (const msg of merged) {\n if (Array.isArray(msg.content)) {\n const seenToolResultIds = new Set<string>()\n msg.content = msg.content.filter((block: any) => {\n if (block.type === 'tool_result' && block.tool_use_id) {\n if (seenToolResultIds.has(block.tool_use_id)) {\n return false // Remove duplicate\n }\n seenToolResultIds.add(block.tool_use_id)\n }\n return true\n })\n }\n }\n\n return merged\n }\n\n private async *processAnthropicStream(\n stream: AsyncIterable<Anthropic_SDK.Beta.BetaRawMessageStreamEvent>,\n options: TextOptions<AnthropicTextProviderOptions>,\n genId: () => string,\n logger: InternalLogger,\n ): AsyncIterable<StreamChunk> {\n const model = options.model\n let accumulatedContent = ''\n let accumulatedThinking = ''\n let accumulatedSignature = ''\n const toolCallsMap = new Map<\n number,\n { id: string; name: string; input: string; started: boolean }\n >()\n let currentToolIndex = -1\n // Server-side tools share the `input_json_delta` wire format with client\n // `tool_use` blocks; routing both to the same buffer corrupts client tool\n // input.\n let currentServerTool: { id: string; name: string; input: string } | null =\n null\n\n // AG-UI lifecycle tracking\n const runId = options.runId ?? genId()\n const threadId = options.threadId ?? genId()\n const messageId = genId()\n let stepId: string | null = null\n let reasoningMessageId: string | null = null\n let hasClosedReasoning = false\n let hasEmittedRunStarted = false\n let hasEmittedTextMessageStart = false\n let hasEmittedRunFinished = false\n // Track current content block type for proper content_block_stop handling\n let currentBlockType: string | null = null\n\n try {\n for await (const event of stream) {\n logger.provider(`provider=anthropic type=${event.type}`, {\n chunk: event,\n })\n // Emit RUN_STARTED on first event\n if (!hasEmittedRunStarted) {\n hasEmittedRunStarted = true\n yield {\n type: EventType.RUN_STARTED,\n runId,\n threadId,\n model,\n timestamp: Date.now(),\n parentRunId: options.parentRunId,\n }\n }\n\n if (event.type === 'content_block_start') {\n currentBlockType = event.content_block.type\n if (event.content_block.type === 'tool_use') {\n currentToolIndex++\n toolCallsMap.set(currentToolIndex, {\n id: event.content_block.id,\n name: event.content_block.name,\n input: '',\n started: false,\n })\n } else if (event.content_block.type === 'server_tool_use') {\n currentServerTool = {\n id: event.content_block.id,\n name: event.content_block.name,\n input: '',\n }\n } else if (\n event.content_block.type === 'web_fetch_tool_result' ||\n event.content_block.type === 'web_search_tool_result'\n ) {\n // The result content arrives in full at content_block_start (no\n // deltas). Surface error variants so a failed fetch/search isn't\n // invisible to the consumer.\n const content = event.content_block.content as\n | { type?: string; error_code?: string }\n | Array<unknown>\n const errorBlock =\n !Array.isArray(content) &&\n (content.type === 'web_fetch_tool_result_error' ||\n content.type === 'web_search_tool_result_error')\n ? content\n : null\n if (errorBlock) {\n logger.errors(\n `anthropic.${event.content_block.type} error_code=${errorBlock.error_code}`,\n {\n toolUseId: event.content_block.tool_use_id,\n blockType: event.content_block.type,\n errorCode: errorBlock.error_code,\n source: 'anthropic.processAnthropicStream',\n },\n )\n }\n } else if (event.content_block.type === 'thinking') {\n accumulatedThinking = ''\n accumulatedSignature = ''\n // Emit REASONING and STEP_STARTED for thinking\n stepId = genId()\n reasoningMessageId = genId()\n\n // Spec REASONING events\n yield {\n type: EventType.REASONING_START,\n messageId: reasoningMessageId,\n model,\n timestamp: Date.now(),\n }\n yield {\n type: EventType.REASONING_MESSAGE_START,\n messageId: reasoningMessageId,\n role: 'reasoning' as const,\n model,\n timestamp: Date.now(),\n }\n\n // Legacy STEP events (kept during transition)\n yield {\n type: EventType.STEP_STARTED,\n stepName: stepId,\n stepId,\n model,\n timestamp: Date.now(),\n stepType: 'thinking',\n }\n }\n } else if (event.type === 'content_block_delta') {\n if (event.delta.type === 'text_delta') {\n // Close reasoning before text starts\n if (reasoningMessageId && !hasClosedReasoning) {\n hasClosedReasoning = true\n yield {\n type: EventType.REASONING_MESSAGE_END,\n messageId: reasoningMessageId,\n model,\n timestamp: Date.now(),\n }\n yield {\n type: EventType.REASONING_END,\n messageId: reasoningMessageId,\n model,\n timestamp: Date.now(),\n }\n }\n\n // Emit TEXT_MESSAGE_START on first text content\n if (!hasEmittedTextMessageStart) {\n hasEmittedTextMessageStart = true\n yield {\n type: EventType.TEXT_MESSAGE_START,\n messageId,\n model,\n timestamp: Date.now(),\n role: 'assistant',\n }\n }\n\n const delta = event.delta.text\n accumulatedContent += delta\n yield {\n type: EventType.TEXT_MESSAGE_CONTENT,\n messageId,\n model,\n timestamp: Date.now(),\n delta,\n content: accumulatedContent,\n }\n } else if (\n event.delta.type === 'thinking_delta' &&\n reasoningMessageId\n ) {\n const delta = event.delta.thinking\n accumulatedThinking += delta\n\n // Spec REASONING content event\n yield {\n type: EventType.REASONING_MESSAGE_CONTENT,\n messageId: reasoningMessageId,\n delta,\n model,\n timestamp: Date.now(),\n }\n\n // Legacy STEP event\n yield {\n type: EventType.STEP_FINISHED,\n stepName: stepId || genId(),\n stepId: stepId || genId(),\n model,\n timestamp: Date.now(),\n delta,\n content: accumulatedThinking,\n }\n } else if (\n (event.delta as { type: string }).type === 'signature_delta'\n ) {\n accumulatedSignature +=\n (event.delta as { signature: string }).signature || ''\n } else if (event.delta.type === 'input_json_delta') {\n // Route deltas by current block type so server_tool_use input\n // never appends onto the prior client tool's buffer.\n if (currentBlockType === 'tool_use') {\n const existing = toolCallsMap.get(currentToolIndex)\n if (existing) {\n // Emit TOOL_CALL_START on first args delta\n if (!existing.started) {\n existing.started = true\n yield {\n type: EventType.TOOL_CALL_START,\n toolCallId: existing.id,\n toolCallName: existing.name,\n toolName: existing.name,\n model,\n timestamp: Date.now(),\n index: currentToolIndex,\n }\n }\n\n existing.input += event.delta.partial_json\n\n yield {\n type: EventType.TOOL_CALL_ARGS,\n toolCallId: existing.id,\n model,\n timestamp: Date.now(),\n delta: event.delta.partial_json,\n args: existing.input,\n }\n }\n } else if (\n currentBlockType === 'server_tool_use' &&\n currentServerTool\n ) {\n // Accumulate server tool input internally. We don't emit\n // TOOL_CALL_* events: the call is executed by Anthropic, not\n // by our agent loop, so surfacing it as a client tool call\n // would cause downstream code to try (and fail) to run it.\n currentServerTool.input += event.delta.partial_json\n }\n }\n } else if (event.type === 'content_block_stop') {\n if (currentBlockType === 'thinking') {\n // Emit signature so it can be replayed in multi-turn context\n if (accumulatedSignature && stepId) {\n yield {\n type: EventType.STEP_FINISHED,\n stepName: stepId,\n stepId,\n model,\n timestamp: Date.now(),\n delta: '',\n content: accumulatedThinking,\n signature: accumulatedSignature,\n }\n }\n } else if (currentBlockType === 'tool_use') {\n const existing = toolCallsMap.get(currentToolIndex)\n if (existing) {\n // If tool call wasn't started yet (no args), start it now\n if (!existing.started) {\n existing.started = true\n yield {\n type: EventType.TOOL_CALL_START,\n toolCallId: existing.id,\n toolCallName: existing.name,\n toolName: existing.name,\n model,\n timestamp: Date.now(),\n index: currentToolIndex,\n }\n }\n\n // Emit TOOL_CALL_END\n let parsedInput: unknown = {}\n try {\n const parsed = existing.input ? JSON.parse(existing.input) : {}\n parsedInput = parsed && typeof parsed === 'object' ? parsed : {}\n } catch {\n parsedInput = {}\n }\n\n yield {\n type: EventType.TOOL_CALL_END,\n toolCallId: existing.id,\n toolCallName: existing.name,\n toolName: existing.name,\n model,\n timestamp: Date.now(),\n input: parsedInput,\n }\n\n // Reset so a new TEXT_MESSAGE_START is emitted if text follows tool calls\n hasEmittedTextMessageStart = false\n }\n } else if (currentBlockType === 'server_tool_use') {\n if (currentServerTool) {\n // Anthropic executes the call; we only need a breadcrumb so\n // consumers (devtools, telemetry) can see what ran.\n logger.provider(\n `provider=anthropic server_tool_use name=${currentServerTool.name}`,\n {\n toolUseId: currentServerTool.id,\n name: currentServerTool.name,\n input: currentServerTool.input,\n },\n )\n }\n currentServerTool = null\n } else if (\n currentBlockType === 'web_fetch_tool_result' ||\n currentBlockType === 'web_search_tool_result'\n ) {\n // The model already consumed the result; error variants were\n // already surfaced at content_block_start.\n } else {\n // Emit TEXT_MESSAGE_END only for text blocks (not tool_use blocks)\n if (hasEmittedTextMessageStart && accumulatedContent) {\n yield {\n type: EventType.TEXT_MESSAGE_END,\n messageId,\n model,\n timestamp: Date.now(),\n }\n }\n }\n currentBlockType = null\n } else if (event.type === 'message_stop') {\n // Close reasoning events if still open\n if (reasoningMessageId && !hasClosedReasoning) {\n hasClosedReasoning = true\n yield {\n type: EventType.REASONING_MESSAGE_END,\n messageId: reasoningMessageId,\n model,\n timestamp: Date.now(),\n }\n yield {\n type: EventType.REASONING_END,\n messageId: reasoningMessageId,\n model,\n timestamp: Date.now(),\n }\n }\n\n // Only emit RUN_FINISHED from message_stop if message_delta didn't already emit one.\n // message_delta carries the real stop_reason (tool_use, end_turn, etc.),\n // while message_stop is just a completion signal.\n if (!hasEmittedRunFinished) {\n yield {\n type: EventType.RUN_FINISHED,\n runId,\n threadId,\n model,\n timestamp: Date.now(),\n finishReason: 'stop',\n }\n }\n } else if (event.type === 'message_delta') {\n if (event.delta.stop_reason) {\n hasEmittedRunFinished = true\n\n // Close reasoning events if still open\n if (reasoningMessageId && !hasClosedReasoning) {\n hasClosedReasoning = true\n yield {\n type: EventType.REASONING_MESSAGE_END,\n messageId: reasoningMessageId,\n model,\n timestamp: Date.now(),\n }\n yield {\n type: EventType.REASONING_END,\n messageId: reasoningMessageId,\n model,\n timestamp: Date.now(),\n }\n }\n\n switch (event.delta.stop_reason) {\n case 'tool_use': {\n yield {\n type: EventType.RUN_FINISHED,\n runId,\n threadId,\n model,\n timestamp: Date.now(),\n finishReason: 'tool_calls',\n usage: buildAnthropicUsage(event.usage),\n }\n break\n }\n case 'max_tokens': {\n yield {\n type: EventType.RUN_ERROR,\n model,\n timestamp: Date.now(),\n message:\n 'The response was cut off because the maximum token limit was reached.',\n code: 'max_tokens',\n error: {\n message:\n 'The response was cut off because the maximum token limit was reached.',\n code: 'max_tokens',\n },\n }\n break\n }\n case 'stop_sequence':\n case 'end_turn':\n case 'pause_turn':\n case 'refusal':\n case 'model_context_window_exceeded':\n case 'compaction':\n default: {\n // All remaining Anthropic stop_reason variants map to the\n // generic \"stop\" finish reason — they describe *why* the\n // stream ended, but for AG-UI consumers the resulting event\n // shape is identical.\n yield {\n type: EventType.RUN_FINISHED,\n runId,\n threadId,\n model,\n timestamp: Date.now(),\n finishReason: 'stop',\n usage: buildAnthropicUsage(event.usage),\n }\n }\n }\n }\n }\n }\n } catch (error: unknown) {\n const err = error as Error & { status?: number; code?: string }\n const rawEvent = toRunErrorRawEvent(error)\n\n logger.errors('anthropic.processAnthropicStream fatal', {\n error,\n source: 'anthropic.processAnthropicStream',\n })\n yield {\n type: EventType.RUN_ERROR,\n model,\n timestamp: Date.now(),\n message: err.message || 'Unknown error occurred',\n code: err.code || String(err.status),\n // Forward the Anthropic SDK error's `.error` response body when present.\n ...(rawEvent !== undefined && { rawEvent }),\n error: {\n message: err.message || 'Unknown error occurred',\n code: err.code || String(err.status),\n },\n }\n }\n }\n}\n\n/**\n * Creates an Anthropic chat adapter with explicit API key.\n * Type resolution happens here at the call site.\n */\nexport function createAnthropicChat<\n TModel extends (typeof ANTHROPIC_MODELS)[number],\n>(\n model: TModel,\n apiKey: string,\n config?: Omit<AnthropicTextConfig, 'apiKey'>,\n): AnthropicTextAdapter<\n TModel,\n ResolveProviderOptions<TModel>,\n ResolveInputModalities<TModel>\n> {\n return new AnthropicTextAdapter({ apiKey, ...config }, model)\n}\n\n/**\n * Creates an Anthropic text adapter with automatic API key detection.\n * Type resolution happens here at the call site.\n */\nexport function anthropicText<TModel extends (typeof ANTHROPIC_MODELS)[number]>(\n model: TModel,\n config?: Omit<AnthropicTextConfig, 'apiKey'>,\n): AnthropicTextAdapter<\n TModel,\n ResolveProviderOptions<TModel>,\n ResolveInputModalities<TModel>\n> {\n const apiKey = getAnthropicApiKeyFromEnv()\n return createAnthropicChat(model, apiKey, config)\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -179,6 +179,24 @@ export interface AnthropicSamplingOptions {
|
|
|
179
179
|
Required range: x >= 0
|
|
180
180
|
*/
|
|
181
181
|
top_k?: number;
|
|
182
|
+
/**
|
|
183
|
+
* Amount of randomness injected into the response.
|
|
184
|
+
* Either use this or top_p, but not both.
|
|
185
|
+
* Defaults to 1.0. Ranges from 0.0 to 1.0. Use temperature closer to 0.0 for analytical / multiple choice, and closer to 1.0 for creative and generative tasks.
|
|
186
|
+
* @default 1.0
|
|
187
|
+
*/
|
|
188
|
+
temperature?: number;
|
|
189
|
+
/**
|
|
190
|
+
* Use nucleus sampling.
|
|
191
|
+
*
|
|
192
|
+
* In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by top_p. You should either alter temperature or top_p, but not both.
|
|
193
|
+
*/
|
|
194
|
+
top_p?: number;
|
|
195
|
+
/**
|
|
196
|
+
* The maximum number of tokens to generate before stopping. This parameter only specifies the absolute maximum number of tokens to generate. Required by the API; the adapter defaults to 1024 when omitted.
|
|
197
|
+
* Range x >= 1.
|
|
198
|
+
*/
|
|
199
|
+
max_tokens?: number;
|
|
182
200
|
}
|
|
183
201
|
export type ExternalTextProviderOptions = AnthropicContainerOptions & AnthropicContextManagementOptions & AnthropicMCPOptions & AnthropicServiceTierOptions & AnthropicStopSequencesOptions & AnthropicThinkingOptions & AnthropicToolChoiceOptions & AnthropicSamplingOptions & Partial<AnthropicAdaptiveThinkingOptions> & Partial<AnthropicEffortOptions> & Partial<AnthropicOutputConfigOptions>;
|
|
184
202
|
export interface InternalTextProviderOptions extends ExternalTextProviderOptions {
|
|
@@ -203,13 +221,6 @@ export interface InternalTextProviderOptions extends ExternalTextProviderOptions
|
|
|
203
221
|
* such as specifying a particular goal or role.
|
|
204
222
|
*/
|
|
205
223
|
system?: string | Array<TextBlockParam>;
|
|
206
|
-
/**
|
|
207
|
-
* Amount of randomness injected into the response.
|
|
208
|
-
* Either use this or top_p, but not both.
|
|
209
|
-
* Defaults to 1.0. Ranges from 0.0 to 1.0. Use temperature closer to 0.0 for analytical / multiple choice, and closer to 1.0 for creative and generative tasks.
|
|
210
|
-
* @default 1.0
|
|
211
|
-
*/
|
|
212
|
-
temperature?: number;
|
|
213
224
|
tools?: Array<AnthropicTool>;
|
|
214
225
|
/**
|
|
215
226
|
* Schema-constrained final answer in a single Messages request (issue
|
|
@@ -233,12 +244,6 @@ export interface InternalTextProviderOptions extends ExternalTextProviderOptions
|
|
|
233
244
|
schema: Record<string, unknown>;
|
|
234
245
|
};
|
|
235
246
|
};
|
|
236
|
-
/**
|
|
237
|
-
* Use nucleus sampling.
|
|
238
|
-
|
|
239
|
-
In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by top_p. You should either alter temperature or top_p, but not both.
|
|
240
|
-
*/
|
|
241
|
-
top_p?: number;
|
|
242
247
|
}
|
|
243
248
|
export interface CacheControl {
|
|
244
249
|
type: 'ephemeral';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text-provider-options.js","sources":["../../../src/text/text-provider-options.ts"],"sourcesContent":["import type {\n BetaContextManagementConfig,\n BetaToolChoiceAny,\n BetaToolChoiceAuto,\n BetaToolChoiceTool,\n} from '@anthropic-ai/sdk/resources/beta/messages/messages'\nimport type { CacheControlEphemeral } from '@anthropic-ai/sdk/resources'\nimport type { AnthropicTool } from '../tools'\nimport type {\n MessageParam,\n TextBlockParam,\n} from '@anthropic-ai/sdk/resources/messages'\n\n/**\n * Per-prompt metadata Anthropic understands on `systemPrompts` entries.\n *\n * Used via the structured form of `systemPrompts`:\n *\n * @example\n * import type { AnthropicSystemPromptMetadata } from '@tanstack/ai-anthropic'\n *\n * chat({\n * adapter: anthropicText(),\n * model: 'claude-sonnet-4-6',\n * systemPrompts: [\n * {\n * content: 'Stable instructions — cache me.',\n * metadata: { cache_control: { type: 'ephemeral' } } satisfies AnthropicSystemPromptMetadata,\n * },\n * 'Volatile per-request instruction.',\n * ],\n * })\n */\nexport interface AnthropicSystemPromptMetadata {\n /**\n * Anthropic prompt-caching control applied to this system prompt's\n * `TextBlockParam`.\n *\n * @see https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching\n */\n cache_control?: CacheControlEphemeral\n}\n\nexport interface AnthropicContainerOptions {\n /**\n * Container identifier for reuse across requests.\n * Container parameters with skills to be loaded.\n */\n container?: {\n id: string | null\n /**\n * List of skills to load into the container\n */\n skills: Array<{\n /**\n * Between 1-64 characters\n */\n skill_id: string\n\n type: 'anthropic' | 'custom'\n /**\n * Skill version or latest by default\n */\n version?: string\n }> | null\n } | null\n}\n\nexport interface AnthropicContextManagementOptions {\n /**\n * Context management configuration.\n\nThis allows you to control how Claude manages context across multiple requests, such as whether to clear function results or not.\n */\n context_management?: BetaContextManagementConfig | null\n}\n\nexport interface AnthropicMCPOptions {\n /**\n * MCP servers to be utilized in this request\n * Maximum of 20 servers\n */\n mcp_servers?: Array<MCPServer>\n}\n\nexport interface AnthropicServiceTierOptions {\n /**\n * Determines whether to use priority capacity (if available) or standard capacity for this request.\n */\n service_tier?: 'auto' | 'standard_only'\n}\n\nexport interface AnthropicStopSequencesOptions {\n /**\n * Custom text sequences that will cause the model to stop generating.\n\nAnthropic models will normally stop when they have naturally completed their turn, which will result in a response stop_reason of \"end_turn\".\n\nIf you want the model to stop generating when it encounters custom strings of text, you can use the stop_sequences parameter. If the model encounters one of the custom sequences, the response stop_reason value will be \"stop_sequence\" and the response stop_sequence value will contain the matched stop sequence.\n */\n stop_sequences?: Array<string>\n}\n\nexport interface AnthropicThinkingOptions {\n /**\n * Configuration for enabling Claude's extended thinking.\n\nWhen enabled, responses include thinking content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your max_tokens limit.\n */\n thinking?:\n | {\n /**\n* Determines how many tokens Claude can use for its internal reasoning process. Larger budgets can enable more thorough analysis for complex problems, improving response quality.\n\nMust be ≥1024 and less than max_tokens\n*/\n budget_tokens: number\n\n type: 'enabled'\n }\n | {\n type: 'disabled'\n }\n}\n\nexport interface AnthropicAdaptiveThinkingOptions {\n /**\n * Configuration for Claude's adaptive thinking (Opus 4.6+).\n *\n * In adaptive mode, Claude dynamically decides when and how much to think.\n * Use the effort parameter to control thinking depth.\n * `thinking: {type: \"enabled\"}` with `budget_tokens` is deprecated on Opus 4.6.\n */\n thinking?:\n | {\n type: 'adaptive'\n /**\n * Controls what (if any) thinking content is streamed back.\n *\n * - `'summarized'`: stream summarized thinking via `thinking_delta`\n * events (the user-visible reasoning text).\n * - `'omitted'`: stream the thinking block's `signature_delta` only\n * (no reasoning text reaches the client).\n *\n * On Claude Opus 4.6 the default is `'summarized'`. On\n * Claude Opus 4.7 the default flipped to `'omitted'` — callers\n * must set `'summarized'` explicitly to get the reasoning text.\n */\n display?: 'summarized' | 'omitted'\n }\n | {\n /**\n * @deprecated Use `type: 'adaptive'` with the effort parameter on Opus 4.6+.\n */\n budget_tokens: number\n type: 'enabled'\n }\n | {\n type: 'disabled'\n }\n}\n\nexport interface AnthropicEffortOptions {\n /**\n * Controls the thinking depth for adaptive thinking mode (Opus 4.6+).\n *\n * - `max`: Absolute highest capability\n * - `high`: Default - Claude will almost always think\n * - `medium`: Balanced cost-quality\n * - `low`: May skip thinking for simpler problems\n */\n effort?: 'max' | 'high' | 'medium' | 'low'\n}\n\nexport interface AnthropicOutputConfigOptions {\n /**\n * Output configuration for the model's response.\n *\n * On Claude 4.7+ the top-level `effort` field was relocated under\n * `output_config.effort`, and `thinking: { type: 'enabled', budget_tokens }`\n * was replaced by `thinking: { type: 'adaptive' }` paired with\n * `output_config.effort`. Earlier models continue to accept the legacy\n * top-level `effort` / `thinking.type: 'enabled'` shape.\n *\n * The engine also writes `output_config.format` here when the caller\n * passes `outputSchema` to a Claude 4.5+ adapter (issue #605 native\n * combined mode). Both fields coexist: user-supplied `effort` is\n * preserved when the engine adds `format`.\n */\n output_config?: {\n effort?: 'low' | 'medium' | 'high' | 'max' | null\n }\n}\n\nexport interface AnthropicToolChoiceOptions {\n tool_choice?: BetaToolChoiceAny | BetaToolChoiceTool | BetaToolChoiceAuto\n}\n\nexport interface AnthropicSamplingOptions {\n /**\n * Only sample from the top K options for each subsequent token.\n\nUsed to remove \"long tail\" low probability responses.\nRecommended for advanced use cases only. You usually only need to use temperature.\n\nRequired range: x >= 0\n */\n top_k?: number\n}\n\nexport type ExternalTextProviderOptions = AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicThinkingOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions &\n Partial<AnthropicAdaptiveThinkingOptions> &\n Partial<AnthropicEffortOptions> &\n Partial<AnthropicOutputConfigOptions>\n\nexport interface InternalTextProviderOptions extends ExternalTextProviderOptions {\n model: string\n\n messages: Array<MessageParam>\n\n /**\n * The maximum number of tokens to generate before stopping. This parameter only specifies the absolute maximum number of tokens to generate.\n * Range x >= 1.\n */\n max_tokens: number\n /**\n * Whether to incrementally stream the response using server-sent events.\n */\n stream?: boolean\n /**\n * System prompt — built by the adapter from the user-facing\n * `systemPrompts: Array<string>` on the chat call. This field is internal:\n * users should pass system prompts via `systemPrompts`, not via\n * `modelOptions`.\n *\n * A system prompt is a way of providing context and instructions to Claude,\n * such as specifying a particular goal or role.\n */\n system?: string | Array<TextBlockParam>\n /**\n * Amount of randomness injected into the response.\n * Either use this or top_p, but not both.\n * Defaults to 1.0. Ranges from 0.0 to 1.0. Use temperature closer to 0.0 for analytical / multiple choice, and closer to 1.0 for creative and generative tasks.\n * @default 1.0\n */\n temperature?: number\n\n tools?: Array<AnthropicTool>\n\n /**\n * Schema-constrained final answer in a single Messages request (issue\n * #605). Set by the engine when the adapter declared\n * `supportsCombinedToolsAndSchema` and a caller passed `outputSchema`\n * to `chat()`. The model emits tool calls during the agent loop and a\n * schema-matching JSON message on the natural final turn — no separate\n * finalization round-trip needed.\n *\n * The SDK type (`BetaOutputConfig`) currently exposes only `effort`;\n * `format` is accepted at runtime per the deprecation notice on the\n * older `output_format` field\n * (https://platform.claude.com/docs/en/build-with-claude/structured-outputs).\n * We type it explicitly here so the adapter call site doesn't need a\n * cast.\n */\n output_config?: {\n effort?: 'low' | 'medium' | 'high' | 'max' | null\n format?: {\n type: 'json_schema'\n schema: Record<string, unknown>\n }\n }\n\n /**\n * Use nucleus sampling.\n\nIn nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by top_p. You should either alter temperature or top_p, but not both.\n */\n top_p?: number\n}\n\nconst validateTopPandTemperature = (options: InternalTextProviderOptions) => {\n if (options.top_p !== undefined && options.temperature !== undefined) {\n throw new Error('You should either set top_p or temperature, but not both.')\n }\n}\n\nexport interface CacheControl {\n type: 'ephemeral'\n ttl: '5m' | '1h'\n}\n\nconst validateThinking = (options: InternalTextProviderOptions) => {\n const thinking = options.thinking\n if (thinking && thinking.type === 'enabled') {\n if (thinking.budget_tokens < 1024) {\n throw new Error('thinking.budget_tokens must be at least 1024.')\n }\n if (thinking.budget_tokens >= options.max_tokens) {\n throw new Error('thinking.budget_tokens must be less than max_tokens.')\n }\n }\n}\n\ninterface MCPServer {\n name: string\n url: string\n type: 'url'\n authorization_token?: string | null\n tool_configuration: {\n allowed_tools?: Array<string> | null\n enabled?: boolean | null\n } | null\n}\n\nconst validateMaxTokens = (options: InternalTextProviderOptions) => {\n if (options.max_tokens < 1) {\n throw new Error('max_tokens must be at least 1.')\n }\n}\n\nexport const validateTextProviderOptions = (\n options: InternalTextProviderOptions,\n) => {\n validateTopPandTemperature(options)\n validateThinking(options)\n validateMaxTokens(options)\n}\n"],"names":[],"mappings":"AA+RA,MAAM,6BAA6B,CAAC,YAAyC;AAC3E,MAAI,QAAQ,UAAU,UAAa,QAAQ,gBAAgB,QAAW;AACpE,UAAM,IAAI,MAAM,2DAA2D;AAAA,EAC7E;AACF;AAOA,MAAM,mBAAmB,CAAC,YAAyC;AACjE,QAAM,WAAW,QAAQ;AACzB,MAAI,YAAY,SAAS,SAAS,WAAW;AAC3C,QAAI,SAAS,gBAAgB,MAAM;AACjC,YAAM,IAAI,MAAM,+CAA+C;AAAA,IACjE;AACA,QAAI,SAAS,iBAAiB,QAAQ,YAAY;AAChD,YAAM,IAAI,MAAM,sDAAsD;AAAA,IACxE;AAAA,EACF;AACF;AAaA,MAAM,oBAAoB,CAAC,YAAyC;AAClE,MAAI,QAAQ,aAAa,GAAG;AAC1B,UAAM,IAAI,MAAM,gCAAgC;AAAA,EAClD;AACF;AAEO,MAAM,8BAA8B,CACzC,YACG;AACH,6BAA2B,OAAO;AAClC,mBAAiB,OAAO;AACxB,oBAAkB,OAAO;AAC3B;"}
|
|
1
|
+
{"version":3,"file":"text-provider-options.js","sources":["../../../src/text/text-provider-options.ts"],"sourcesContent":["import type {\n BetaContextManagementConfig,\n BetaToolChoiceAny,\n BetaToolChoiceAuto,\n BetaToolChoiceTool,\n} from '@anthropic-ai/sdk/resources/beta/messages/messages'\nimport type { CacheControlEphemeral } from '@anthropic-ai/sdk/resources'\nimport type { AnthropicTool } from '../tools'\nimport type {\n MessageParam,\n TextBlockParam,\n} from '@anthropic-ai/sdk/resources/messages'\n\n/**\n * Per-prompt metadata Anthropic understands on `systemPrompts` entries.\n *\n * Used via the structured form of `systemPrompts`:\n *\n * @example\n * import type { AnthropicSystemPromptMetadata } from '@tanstack/ai-anthropic'\n *\n * chat({\n * adapter: anthropicText(),\n * model: 'claude-sonnet-4-6',\n * systemPrompts: [\n * {\n * content: 'Stable instructions — cache me.',\n * metadata: { cache_control: { type: 'ephemeral' } } satisfies AnthropicSystemPromptMetadata,\n * },\n * 'Volatile per-request instruction.',\n * ],\n * })\n */\nexport interface AnthropicSystemPromptMetadata {\n /**\n * Anthropic prompt-caching control applied to this system prompt's\n * `TextBlockParam`.\n *\n * @see https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching\n */\n cache_control?: CacheControlEphemeral\n}\n\nexport interface AnthropicContainerOptions {\n /**\n * Container identifier for reuse across requests.\n * Container parameters with skills to be loaded.\n */\n container?: {\n id: string | null\n /**\n * List of skills to load into the container\n */\n skills: Array<{\n /**\n * Between 1-64 characters\n */\n skill_id: string\n\n type: 'anthropic' | 'custom'\n /**\n * Skill version or latest by default\n */\n version?: string\n }> | null\n } | null\n}\n\nexport interface AnthropicContextManagementOptions {\n /**\n * Context management configuration.\n\nThis allows you to control how Claude manages context across multiple requests, such as whether to clear function results or not.\n */\n context_management?: BetaContextManagementConfig | null\n}\n\nexport interface AnthropicMCPOptions {\n /**\n * MCP servers to be utilized in this request\n * Maximum of 20 servers\n */\n mcp_servers?: Array<MCPServer>\n}\n\nexport interface AnthropicServiceTierOptions {\n /**\n * Determines whether to use priority capacity (if available) or standard capacity for this request.\n */\n service_tier?: 'auto' | 'standard_only'\n}\n\nexport interface AnthropicStopSequencesOptions {\n /**\n * Custom text sequences that will cause the model to stop generating.\n\nAnthropic models will normally stop when they have naturally completed their turn, which will result in a response stop_reason of \"end_turn\".\n\nIf you want the model to stop generating when it encounters custom strings of text, you can use the stop_sequences parameter. If the model encounters one of the custom sequences, the response stop_reason value will be \"stop_sequence\" and the response stop_sequence value will contain the matched stop sequence.\n */\n stop_sequences?: Array<string>\n}\n\nexport interface AnthropicThinkingOptions {\n /**\n * Configuration for enabling Claude's extended thinking.\n\nWhen enabled, responses include thinking content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your max_tokens limit.\n */\n thinking?:\n | {\n /**\n* Determines how many tokens Claude can use for its internal reasoning process. Larger budgets can enable more thorough analysis for complex problems, improving response quality.\n\nMust be ≥1024 and less than max_tokens\n*/\n budget_tokens: number\n\n type: 'enabled'\n }\n | {\n type: 'disabled'\n }\n}\n\nexport interface AnthropicAdaptiveThinkingOptions {\n /**\n * Configuration for Claude's adaptive thinking (Opus 4.6+).\n *\n * In adaptive mode, Claude dynamically decides when and how much to think.\n * Use the effort parameter to control thinking depth.\n * `thinking: {type: \"enabled\"}` with `budget_tokens` is deprecated on Opus 4.6.\n */\n thinking?:\n | {\n type: 'adaptive'\n /**\n * Controls what (if any) thinking content is streamed back.\n *\n * - `'summarized'`: stream summarized thinking via `thinking_delta`\n * events (the user-visible reasoning text).\n * - `'omitted'`: stream the thinking block's `signature_delta` only\n * (no reasoning text reaches the client).\n *\n * On Claude Opus 4.6 the default is `'summarized'`. On\n * Claude Opus 4.7 the default flipped to `'omitted'` — callers\n * must set `'summarized'` explicitly to get the reasoning text.\n */\n display?: 'summarized' | 'omitted'\n }\n | {\n /**\n * @deprecated Use `type: 'adaptive'` with the effort parameter on Opus 4.6+.\n */\n budget_tokens: number\n type: 'enabled'\n }\n | {\n type: 'disabled'\n }\n}\n\nexport interface AnthropicEffortOptions {\n /**\n * Controls the thinking depth for adaptive thinking mode (Opus 4.6+).\n *\n * - `max`: Absolute highest capability\n * - `high`: Default - Claude will almost always think\n * - `medium`: Balanced cost-quality\n * - `low`: May skip thinking for simpler problems\n */\n effort?: 'max' | 'high' | 'medium' | 'low'\n}\n\nexport interface AnthropicOutputConfigOptions {\n /**\n * Output configuration for the model's response.\n *\n * On Claude 4.7+ the top-level `effort` field was relocated under\n * `output_config.effort`, and `thinking: { type: 'enabled', budget_tokens }`\n * was replaced by `thinking: { type: 'adaptive' }` paired with\n * `output_config.effort`. Earlier models continue to accept the legacy\n * top-level `effort` / `thinking.type: 'enabled'` shape.\n *\n * The engine also writes `output_config.format` here when the caller\n * passes `outputSchema` to a Claude 4.5+ adapter (issue #605 native\n * combined mode). Both fields coexist: user-supplied `effort` is\n * preserved when the engine adds `format`.\n */\n output_config?: {\n effort?: 'low' | 'medium' | 'high' | 'max' | null\n }\n}\n\nexport interface AnthropicToolChoiceOptions {\n tool_choice?: BetaToolChoiceAny | BetaToolChoiceTool | BetaToolChoiceAuto\n}\n\nexport interface AnthropicSamplingOptions {\n /**\n * Only sample from the top K options for each subsequent token.\n\nUsed to remove \"long tail\" low probability responses.\nRecommended for advanced use cases only. You usually only need to use temperature.\n\nRequired range: x >= 0\n */\n top_k?: number\n /**\n * Amount of randomness injected into the response.\n * Either use this or top_p, but not both.\n * Defaults to 1.0. Ranges from 0.0 to 1.0. Use temperature closer to 0.0 for analytical / multiple choice, and closer to 1.0 for creative and generative tasks.\n * @default 1.0\n */\n temperature?: number\n /**\n * Use nucleus sampling.\n *\n * In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by top_p. You should either alter temperature or top_p, but not both.\n */\n top_p?: number\n /**\n * The maximum number of tokens to generate before stopping. This parameter only specifies the absolute maximum number of tokens to generate. Required by the API; the adapter defaults to 1024 when omitted.\n * Range x >= 1.\n */\n max_tokens?: number\n}\n\nexport type ExternalTextProviderOptions = AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicThinkingOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions &\n Partial<AnthropicAdaptiveThinkingOptions> &\n Partial<AnthropicEffortOptions> &\n Partial<AnthropicOutputConfigOptions>\n\nexport interface InternalTextProviderOptions extends ExternalTextProviderOptions {\n model: string\n\n messages: Array<MessageParam>\n\n /**\n * The maximum number of tokens to generate before stopping. This parameter only specifies the absolute maximum number of tokens to generate.\n * Range x >= 1.\n */\n max_tokens: number\n /**\n * Whether to incrementally stream the response using server-sent events.\n */\n stream?: boolean\n /**\n * System prompt — built by the adapter from the user-facing\n * `systemPrompts: Array<string>` on the chat call. This field is internal:\n * users should pass system prompts via `systemPrompts`, not via\n * `modelOptions`.\n *\n * A system prompt is a way of providing context and instructions to Claude,\n * such as specifying a particular goal or role.\n */\n system?: string | Array<TextBlockParam>\n\n tools?: Array<AnthropicTool>\n\n /**\n * Schema-constrained final answer in a single Messages request (issue\n * #605). Set by the engine when the adapter declared\n * `supportsCombinedToolsAndSchema` and a caller passed `outputSchema`\n * to `chat()`. The model emits tool calls during the agent loop and a\n * schema-matching JSON message on the natural final turn — no separate\n * finalization round-trip needed.\n *\n * The SDK type (`BetaOutputConfig`) currently exposes only `effort`;\n * `format` is accepted at runtime per the deprecation notice on the\n * older `output_format` field\n * (https://platform.claude.com/docs/en/build-with-claude/structured-outputs).\n * We type it explicitly here so the adapter call site doesn't need a\n * cast.\n */\n output_config?: {\n effort?: 'low' | 'medium' | 'high' | 'max' | null\n format?: {\n type: 'json_schema'\n schema: Record<string, unknown>\n }\n }\n}\n\nconst validateTopPandTemperature = (options: InternalTextProviderOptions) => {\n if (options.top_p !== undefined && options.temperature !== undefined) {\n throw new Error('You should either set top_p or temperature, but not both.')\n }\n}\n\nexport interface CacheControl {\n type: 'ephemeral'\n ttl: '5m' | '1h'\n}\n\nconst validateThinking = (options: InternalTextProviderOptions) => {\n const thinking = options.thinking\n if (thinking && thinking.type === 'enabled') {\n if (thinking.budget_tokens < 1024) {\n throw new Error('thinking.budget_tokens must be at least 1024.')\n }\n if (thinking.budget_tokens >= options.max_tokens) {\n throw new Error('thinking.budget_tokens must be less than max_tokens.')\n }\n }\n}\n\ninterface MCPServer {\n name: string\n url: string\n type: 'url'\n authorization_token?: string | null\n tool_configuration: {\n allowed_tools?: Array<string> | null\n enabled?: boolean | null\n } | null\n}\n\nconst validateMaxTokens = (options: InternalTextProviderOptions) => {\n if (options.max_tokens < 1) {\n throw new Error('max_tokens must be at least 1.')\n }\n}\n\nexport const validateTextProviderOptions = (\n options: InternalTextProviderOptions,\n) => {\n validateTopPandTemperature(options)\n validateThinking(options)\n validateMaxTokens(options)\n}\n"],"names":[],"mappings":"AAmSA,MAAM,6BAA6B,CAAC,YAAyC;AAC3E,MAAI,QAAQ,UAAU,UAAa,QAAQ,gBAAgB,QAAW;AACpE,UAAM,IAAI,MAAM,2DAA2D;AAAA,EAC7E;AACF;AAOA,MAAM,mBAAmB,CAAC,YAAyC;AACjE,QAAM,WAAW,QAAQ;AACzB,MAAI,YAAY,SAAS,SAAS,WAAW;AAC3C,QAAI,SAAS,gBAAgB,MAAM;AACjC,YAAM,IAAI,MAAM,+CAA+C;AAAA,IACjE;AACA,QAAI,SAAS,iBAAiB,QAAQ,YAAY;AAChD,YAAM,IAAI,MAAM,sDAAsD;AAAA,IACxE;AAAA,EACF;AACF;AAaA,MAAM,oBAAoB,CAAC,YAAyC;AAClE,MAAI,QAAQ,aAAa,GAAG;AAC1B,UAAM,IAAI,MAAM,gCAAgC;AAAA,EAClD;AACF;AAEO,MAAM,8BAA8B,CACzC,YACG;AACH,6BAA2B,OAAO;AAClC,mBAAiB,OAAO;AACxB,oBAAkB,OAAO;AAC3B;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/ai-anthropic",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "Anthropic Claude adapter for TanStack AI chat, tool calling, thinking, and structured outputs.",
|
|
5
5
|
"author": "",
|
|
6
6
|
"license": "MIT",
|
|
@@ -45,12 +45,12 @@
|
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"zod": "^4.0.0",
|
|
48
|
-
"@tanstack/ai": "^0.
|
|
48
|
+
"@tanstack/ai": "^0.27.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@vitest/coverage-v8": "4.0.14",
|
|
52
52
|
"zod": "^4.2.0",
|
|
53
|
-
"@tanstack/ai": "0.
|
|
53
|
+
"@tanstack/ai": "0.27.0"
|
|
54
54
|
},
|
|
55
55
|
"scripts": {
|
|
56
56
|
"build": "vite build",
|
package/src/adapters/text.ts
CHANGED
|
@@ -302,9 +302,7 @@ export class AnthropicTextAdapter<
|
|
|
302
302
|
private mapCommonOptionsToAnthropic(
|
|
303
303
|
options: TextOptions<AnthropicTextProviderOptions>,
|
|
304
304
|
) {
|
|
305
|
-
const modelOptions = options.modelOptions
|
|
306
|
-
| InternalTextProviderOptions
|
|
307
|
-
| undefined
|
|
305
|
+
const modelOptions = options.modelOptions
|
|
308
306
|
|
|
309
307
|
const formattedMessages = this.formatMessages(options.messages)
|
|
310
308
|
const tools = options.tools
|
|
@@ -313,7 +311,7 @@ export class AnthropicTextAdapter<
|
|
|
313
311
|
|
|
314
312
|
const validProviderOptions: Partial<InternalTextProviderOptions> = {}
|
|
315
313
|
if (modelOptions) {
|
|
316
|
-
const validKeys: Array<keyof
|
|
314
|
+
const validKeys: Array<keyof AnthropicTextProviderOptions> = [
|
|
317
315
|
'container',
|
|
318
316
|
'context_management',
|
|
319
317
|
'effort',
|
|
@@ -324,10 +322,17 @@ export class AnthropicTextAdapter<
|
|
|
324
322
|
'thinking',
|
|
325
323
|
'tool_choice',
|
|
326
324
|
'top_k',
|
|
325
|
+
'temperature',
|
|
326
|
+
'top_p',
|
|
327
327
|
]
|
|
328
|
-
|
|
328
|
+
// `max_tokens` is a legitimate public modelOptions field, but it is read
|
|
329
|
+
// via a dedicated path (defaultMaxTokens below) rather than copied into
|
|
330
|
+
// validProviderOptions. Exempt it from the dropped-key warning here so a
|
|
331
|
+
// correct `modelOptions: { max_tokens }` call doesn't log a spurious
|
|
332
|
+
// "dropped unknown key" error, while keeping it out of the copy loop.
|
|
333
|
+
const droppedKeyExemptSet = new Set<string>([...validKeys, 'max_tokens'])
|
|
329
334
|
const droppedKeys = Object.keys(modelOptions).filter(
|
|
330
|
-
(key) => !
|
|
335
|
+
(key) => !droppedKeyExemptSet.has(key),
|
|
331
336
|
)
|
|
332
337
|
if (droppedKeys.length > 0) {
|
|
333
338
|
// Reachable when callers cast around the public type (e.g.
|
|
@@ -364,7 +369,7 @@ export class AnthropicTextAdapter<
|
|
|
364
369
|
validProviderOptions.thinking?.type === 'enabled'
|
|
365
370
|
? validProviderOptions.thinking.budget_tokens
|
|
366
371
|
: undefined
|
|
367
|
-
const defaultMaxTokens =
|
|
372
|
+
const defaultMaxTokens = modelOptions?.max_tokens ?? 1024
|
|
368
373
|
const maxTokens =
|
|
369
374
|
thinkingBudget && thinkingBudget >= defaultMaxTokens
|
|
370
375
|
? thinkingBudget + 1
|
|
@@ -409,18 +414,13 @@ export class AnthropicTextAdapter<
|
|
|
409
414
|
}
|
|
410
415
|
: undefined
|
|
411
416
|
|
|
412
|
-
// `
|
|
413
|
-
//
|
|
414
|
-
//
|
|
415
|
-
//
|
|
416
|
-
// exactOptionalPropertyTypes.
|
|
417
|
+
// `temperature`/`top_p` arrive via `...validProviderOptions` (sourced from
|
|
418
|
+
// `modelOptions`). `InternalTextProviderOptions` declares `system` and
|
|
419
|
+
// `tools` as `T?: ...` (no `| undefined`), so spread them conditionally
|
|
420
|
+
// rather than passing explicit `undefined` under exactOptionalPropertyTypes.
|
|
417
421
|
const requestParams: InternalTextProviderOptions = {
|
|
418
422
|
model: options.model,
|
|
419
423
|
max_tokens: maxTokens,
|
|
420
|
-
...(options.temperature !== undefined && {
|
|
421
|
-
temperature: options.temperature,
|
|
422
|
-
}),
|
|
423
|
-
...(options.topP !== undefined && { top_p: options.topP }),
|
|
424
424
|
messages: formattedMessages,
|
|
425
425
|
...(systemBlocks !== undefined && { system: systemBlocks }),
|
|
426
426
|
...(tools !== undefined && { tools }),
|
|
@@ -206,6 +206,24 @@ Recommended for advanced use cases only. You usually only need to use temperatur
|
|
|
206
206
|
Required range: x >= 0
|
|
207
207
|
*/
|
|
208
208
|
top_k?: number
|
|
209
|
+
/**
|
|
210
|
+
* Amount of randomness injected into the response.
|
|
211
|
+
* Either use this or top_p, but not both.
|
|
212
|
+
* Defaults to 1.0. Ranges from 0.0 to 1.0. Use temperature closer to 0.0 for analytical / multiple choice, and closer to 1.0 for creative and generative tasks.
|
|
213
|
+
* @default 1.0
|
|
214
|
+
*/
|
|
215
|
+
temperature?: number
|
|
216
|
+
/**
|
|
217
|
+
* Use nucleus sampling.
|
|
218
|
+
*
|
|
219
|
+
* In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by top_p. You should either alter temperature or top_p, but not both.
|
|
220
|
+
*/
|
|
221
|
+
top_p?: number
|
|
222
|
+
/**
|
|
223
|
+
* The maximum number of tokens to generate before stopping. This parameter only specifies the absolute maximum number of tokens to generate. Required by the API; the adapter defaults to 1024 when omitted.
|
|
224
|
+
* Range x >= 1.
|
|
225
|
+
*/
|
|
226
|
+
max_tokens?: number
|
|
209
227
|
}
|
|
210
228
|
|
|
211
229
|
export type ExternalTextProviderOptions = AnthropicContainerOptions &
|
|
@@ -244,13 +262,6 @@ export interface InternalTextProviderOptions extends ExternalTextProviderOptions
|
|
|
244
262
|
* such as specifying a particular goal or role.
|
|
245
263
|
*/
|
|
246
264
|
system?: string | Array<TextBlockParam>
|
|
247
|
-
/**
|
|
248
|
-
* Amount of randomness injected into the response.
|
|
249
|
-
* Either use this or top_p, but not both.
|
|
250
|
-
* Defaults to 1.0. Ranges from 0.0 to 1.0. Use temperature closer to 0.0 for analytical / multiple choice, and closer to 1.0 for creative and generative tasks.
|
|
251
|
-
* @default 1.0
|
|
252
|
-
*/
|
|
253
|
-
temperature?: number
|
|
254
265
|
|
|
255
266
|
tools?: Array<AnthropicTool>
|
|
256
267
|
|
|
@@ -276,13 +287,6 @@ export interface InternalTextProviderOptions extends ExternalTextProviderOptions
|
|
|
276
287
|
schema: Record<string, unknown>
|
|
277
288
|
}
|
|
278
289
|
}
|
|
279
|
-
|
|
280
|
-
/**
|
|
281
|
-
* Use nucleus sampling.
|
|
282
|
-
|
|
283
|
-
In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by top_p. You should either alter temperature or top_p, but not both.
|
|
284
|
-
*/
|
|
285
|
-
top_p?: number
|
|
286
290
|
}
|
|
287
291
|
|
|
288
292
|
const validateTopPandTemperature = (options: InternalTextProviderOptions) => {
|