@tanstack/ai-anthropic 0.16.9 → 0.17.1
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.d.ts +12 -4
- package/dist/esm/adapters/text.js +23 -4
- package/dist/esm/adapters/text.js.map +1 -1
- package/dist/esm/index.d.ts +4 -3
- package/dist/esm/index.js +3 -3
- package/dist/esm/message-types.d.ts +8 -9
- package/dist/esm/model-meta.d.ts +7 -0
- package/dist/esm/model-meta.js +19 -1
- package/dist/esm/model-meta.js.map +1 -1
- package/dist/esm/utils/client.d.ts +17 -0
- package/dist/esm/utils/client.js.map +1 -1
- package/dist/esm/vertex/auth.d.ts +15 -0
- package/dist/esm/vertex/auth.js +30 -0
- package/dist/esm/vertex/auth.js.map +1 -0
- package/dist/esm/vertex/index.d.ts +11 -0
- package/dist/esm/vertex/index.js +18 -0
- package/dist/esm/vertex/index.js.map +1 -0
- package/package.json +15 -3
- package/src/adapters/text.ts +66 -9
- package/src/index.ts +5 -0
- package/src/message-types.ts +10 -8
- package/src/model-meta.ts +22 -0
- package/src/utils/client.ts +21 -0
- package/src/vertex/auth.ts +66 -0
- package/src/vertex/index.ts +29 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { BaseTextAdapter, StructuredOutputOptions, StructuredOutputResult } from '@tanstack/ai/adapters';
|
|
2
2
|
import { ANTHROPIC_MODELS, AnthropicChatModelProviderOptionsByName, AnthropicChatModelToolCapabilitiesByName, AnthropicModelInputModalitiesByName } from '../model-meta.js';
|
|
3
3
|
import { AnthropicBeta } from '@anthropic-ai/sdk/resources/beta/beta';
|
|
4
|
-
import { AnyTool, Modality,
|
|
4
|
+
import { AnyTool, Modality, AdapterYieldChunk, TextOptions } from '@tanstack/ai';
|
|
5
5
|
import { AnthropicSystemPromptMetadata, ExternalTextProviderOptions } from '../text/text-provider-options.js';
|
|
6
6
|
import { AnthropicMessageMetadataByModality } from '../message-types.js';
|
|
7
|
-
import { AnthropicClientConfig } from '../utils/client.js';
|
|
7
|
+
import { AnthropicClientConfig, AnthropicMessagesClient } from '../utils/client.js';
|
|
8
8
|
/**
|
|
9
9
|
* Computes the `betas` array for a Messages request. Unions:
|
|
10
10
|
* - `interleaved-thinking-2025-05-14` when interleaved thinking is enabled,
|
|
@@ -25,6 +25,9 @@ export declare function computeAnthropicBetas(tools: Array<AnyTool> | undefined,
|
|
|
25
25
|
*/
|
|
26
26
|
export interface AnthropicTextConfig extends AnthropicClientConfig {
|
|
27
27
|
}
|
|
28
|
+
export type AnthropicTextAdapterConfig = AnthropicTextConfig | {
|
|
29
|
+
client: AnthropicMessagesClient;
|
|
30
|
+
};
|
|
28
31
|
/**
|
|
29
32
|
* Anthropic-specific provider options for text/chat
|
|
30
33
|
*/
|
|
@@ -50,8 +53,8 @@ export declare class AnthropicTextAdapter<TModel extends (typeof ANTHROPIC_MODEL
|
|
|
50
53
|
readonly kind: "text";
|
|
51
54
|
readonly name: "anthropic";
|
|
52
55
|
private readonly client;
|
|
53
|
-
constructor(config:
|
|
54
|
-
chatStream(options: TextOptions<TProviderOptions>): AsyncIterable<
|
|
56
|
+
constructor(config: AnthropicTextAdapterConfig, model: TModel);
|
|
57
|
+
chatStream(options: TextOptions<TProviderOptions>): AsyncIterable<AdapterYieldChunk>;
|
|
55
58
|
/**
|
|
56
59
|
* Generate structured output using Anthropic's tool-based approach.
|
|
57
60
|
* Anthropic doesn't have native structured output, so we use a tool with the schema
|
|
@@ -86,6 +89,11 @@ export declare class AnthropicTextAdapter<TModel extends (typeof ANTHROPIC_MODEL
|
|
|
86
89
|
* Type resolution happens here at the call site.
|
|
87
90
|
*/
|
|
88
91
|
export declare function createAnthropicChat<TModel extends (typeof ANTHROPIC_MODELS)[number]>(model: TModel, apiKey: string, config?: Omit<AnthropicTextConfig, 'apiKey'>): AnthropicTextAdapter<TModel, ResolveProviderOptions<TModel>, ResolveInputModalities<TModel>>;
|
|
92
|
+
/**
|
|
93
|
+
* Creates an Anthropic chat adapter with an injected Messages client.
|
|
94
|
+
* Type resolution happens here at the call site.
|
|
95
|
+
*/
|
|
96
|
+
export declare function createAnthropicChatWithClient<TModel extends (typeof ANTHROPIC_MODELS)[number]>(model: TModel, client: AnthropicMessagesClient): AnthropicTextAdapter<TModel, ResolveProviderOptions<TModel>, ResolveInputModalities<TModel>>;
|
|
89
97
|
/**
|
|
90
98
|
* Creates an Anthropic text adapter with automatic API key detection.
|
|
91
99
|
* Type resolution happens here at the call site.
|
|
@@ -65,6 +65,14 @@ function computeAnthropicBetas(tools, modelOptions) {
|
|
|
65
65
|
return betas.size > 0 ? Array.from(betas) : void 0;
|
|
66
66
|
}
|
|
67
67
|
/**
|
|
68
|
+
* Restore the package SDK's precise overloads at the adapter boundary.
|
|
69
|
+
* Alternative clients may use a separate Anthropic 0.x SDK whose declarations
|
|
70
|
+
* drift while implementing the same Messages protocol at runtime.
|
|
71
|
+
*/
|
|
72
|
+
function asSdkAnthropicMessagesClient(client) {
|
|
73
|
+
return client;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
68
76
|
* Anthropic Text (Chat) Adapter
|
|
69
77
|
*
|
|
70
78
|
* Tree-shakeable adapter for Anthropic chat/text completion functionality.
|
|
@@ -76,7 +84,7 @@ var AnthropicTextAdapter = class extends BaseTextAdapter {
|
|
|
76
84
|
client;
|
|
77
85
|
constructor(config, model) {
|
|
78
86
|
super({}, model);
|
|
79
|
-
this.client = createAnthropicClient(config);
|
|
87
|
+
this.client = "client" in config ? asSdkAnthropicMessagesClient(config.client) : createAnthropicClient(config);
|
|
80
88
|
}
|
|
81
89
|
async *chatStream(options) {
|
|
82
90
|
const { logger } = options;
|
|
@@ -289,11 +297,12 @@ var AnthropicTextAdapter = class extends BaseTextAdapter {
|
|
|
289
297
|
type: "url",
|
|
290
298
|
url: part.source.value
|
|
291
299
|
},
|
|
292
|
-
...metadata
|
|
300
|
+
...metadata?.cache_control !== void 0 && { cache_control: metadata.cache_control }
|
|
293
301
|
};
|
|
294
302
|
}
|
|
295
303
|
case "document": {
|
|
296
304
|
const metadata = part.metadata;
|
|
305
|
+
const title = metadata?.title ?? metadata?.filename;
|
|
297
306
|
return {
|
|
298
307
|
type: "document",
|
|
299
308
|
source: part.source.type === "data" ? {
|
|
@@ -304,7 +313,10 @@ var AnthropicTextAdapter = class extends BaseTextAdapter {
|
|
|
304
313
|
type: "url",
|
|
305
314
|
url: part.source.value
|
|
306
315
|
},
|
|
307
|
-
...metadata
|
|
316
|
+
...metadata?.cache_control !== void 0 && { cache_control: metadata.cache_control },
|
|
317
|
+
...metadata?.citations !== void 0 && { citations: metadata.citations },
|
|
318
|
+
...metadata?.context !== void 0 && { context: metadata.context },
|
|
319
|
+
...title !== void 0 && { title }
|
|
308
320
|
};
|
|
309
321
|
}
|
|
310
322
|
case "audio":
|
|
@@ -847,6 +859,13 @@ function createAnthropicChat(model, apiKey, config) {
|
|
|
847
859
|
}, model);
|
|
848
860
|
}
|
|
849
861
|
/**
|
|
862
|
+
* Creates an Anthropic chat adapter with an injected Messages client.
|
|
863
|
+
* Type resolution happens here at the call site.
|
|
864
|
+
*/
|
|
865
|
+
function createAnthropicChatWithClient(model, client) {
|
|
866
|
+
return new AnthropicTextAdapter({ client }, model);
|
|
867
|
+
}
|
|
868
|
+
/**
|
|
850
869
|
* Creates an Anthropic text adapter with automatic API key detection.
|
|
851
870
|
* Type resolution happens here at the call site.
|
|
852
871
|
*/
|
|
@@ -854,6 +873,6 @@ function anthropicText(model, config) {
|
|
|
854
873
|
return createAnthropicChat(model, getAnthropicApiKeyFromEnv(), config);
|
|
855
874
|
}
|
|
856
875
|
//#endregion
|
|
857
|
-
export { AnthropicTextAdapter, anthropicText, computeAnthropicBetas, createAnthropicChat };
|
|
876
|
+
export { AnthropicTextAdapter, anthropicText, computeAnthropicBetas, createAnthropicChat, createAnthropicChatWithClient };
|
|
858
877
|
|
|
859
878
|
//# sourceMappingURL=text.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.js","names":[],"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 { getAnthropicProviderToolKind } from '../tools/anthropic-provider-tool'\nimport {\n readCodeExecutionConfig,\n readCodeExecutionSkills,\n} from '../tools/code-execution-tool'\nimport { validateTextProviderOptions } from '../text/text-provider-options'\nimport { buildAnthropicUsage } from '../usage'\nimport {\n createAnthropicClient,\n generateId,\n getAnthropicApiKeyFromEnv,\n} from '../utils/client'\nimport {\n ANTHROPIC_COMBINED_TOOLS_AND_SCHEMA_MODELS,\n getAnthropicDefaultMaxTokens,\n} 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 ServerToolUseBlockParam,\n TextBlockParam,\n ThinkingBlockParam,\n ToolUseBlockParam,\n URLImageSource,\n URLPDFSource,\n WebFetchToolResultBlockParam,\n WebSearchToolResultBlockParam,\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 AnyTool,\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/client'\n\n/**\n * The block type carried by an Anthropic provider-executed (server) tool's\n * stored result. Mirrors the `*_tool_result` block emitted by the streaming\n * API so it can be replayed verbatim into a later turn.\n */\ntype AnthropicServerToolResultBlockType =\n | 'web_search_tool_result'\n | 'web_fetch_tool_result'\n\n/**\n * Anthropic payload stashed on a provider-executed tool call's `metadata`\n * (under the `anthropic` key, alongside `providerExecuted: true`). Holds enough\n * to reconstruct the original `server_tool_use` + `*_tool_result` blocks so the\n * model still sees prior `web_search` / `web_fetch` evidence on the next turn.\n */\ninterface AnthropicServerToolMetadata {\n serverToolType: ServerToolUseBlockParam['name']\n resultBlockType: AnthropicServerToolResultBlockType\n /** Raw result block content, preserved verbatim from the stream. */\n result: unknown\n}\n\n/**\n * Narrow an opaque tool-call `metadata` to {@link AnthropicServerToolMetadata}\n * when it follows the provider-executed convention, else `null`.\n */\nfunction readAnthropicServerToolMetadata(\n metadata: unknown,\n): AnthropicServerToolMetadata | null {\n if (typeof metadata !== 'object' || metadata === null) return null\n const outer = metadata as { providerExecuted?: unknown; anthropic?: unknown }\n if (outer.providerExecuted !== true) return null\n const inner = outer.anthropic\n if (typeof inner !== 'object' || inner === null) return null\n const { serverToolType, resultBlockType, result } = inner as {\n serverToolType?: unknown\n resultBlockType?: unknown\n result?: unknown\n }\n if (\n typeof serverToolType !== 'string' ||\n (resultBlockType !== 'web_search_tool_result' &&\n resultBlockType !== 'web_fetch_tool_result')\n ) {\n return null\n }\n return {\n // Validated as a string above; widen back to the SDK's tool-name union.\n serverToolType: serverToolType as ServerToolUseBlockParam['name'],\n resultBlockType,\n result,\n }\n}\n\n/**\n * Reconstruct the `*_tool_result` block param from stored server-tool metadata.\n * The `result` content is opaque round-trip data, asserted to the SDK's param\n * content type at this single boundary.\n */\nfunction buildServerToolResultBlock(\n toolUseId: string,\n meta: AnthropicServerToolMetadata,\n): WebSearchToolResultBlockParam | WebFetchToolResultBlockParam {\n if (meta.resultBlockType === 'web_search_tool_result') {\n return {\n type: 'web_search_tool_result',\n tool_use_id: toolUseId,\n content: meta.result as WebSearchToolResultBlockParam['content'],\n }\n }\n return {\n type: 'web_fetch_tool_result',\n tool_use_id: toolUseId,\n content: meta.result as WebFetchToolResultBlockParam['content'],\n }\n}\n\n/**\n * Computes the `betas` array for a Messages request. Unions:\n * - `interleaved-thinking-2025-05-14` when interleaved thinking is enabled,\n * - `code-execution-2025-08-25` when a `code_execution` tool is present,\n * - `skills-2025-10-02` when that tool carries skills,\n * - `context-management-2025-06-27` when `context_management` is set.\n * Returns `undefined` when none apply (so the call site omits `betas`).\n */\nexport function computeAnthropicBetas(\n tools: Array<AnyTool> | undefined,\n modelOptions:\n | {\n thinking?: {\n type?: 'enabled' | 'disabled' | 'adaptive'\n budget_tokens?: number\n }\n context_management?: unknown | null\n }\n | undefined,\n): Array<AnthropicBeta> | undefined {\n const betas = new Set<AnthropicBeta>()\n\n const useInterleavedThinking =\n modelOptions?.thinking?.type === 'enabled' &&\n typeof modelOptions.thinking.budget_tokens === 'number' &&\n modelOptions.thinking.budget_tokens > 0\n if (useInterleavedThinking) betas.add('interleaved-thinking-2025-05-14')\n\n // Context editing requires the beta header; the body field alone is not\n // enough (issue #1074). `null` is a typed \"unset\" — do not enable the beta.\n if (modelOptions?.context_management != null) {\n betas.add('context-management-2025-06-27')\n }\n\n // Code-execution beta is version-aware: select from the FIRST code_execution\n // tool's config type.\n const codeExecTool = tools?.find(\n (tool) => getAnthropicProviderToolKind(tool) === 'code_execution',\n )\n if (codeExecTool) {\n const cfgType = readCodeExecutionConfig(codeExecTool)?.type\n // Each code_execution tool version pairs with a specific beta. Known\n // legacy variant maps explicitly; current/future variants (e.g.\n // `code_execution_20250825` and later) use the latest `-08-25` beta.\n betas.add(\n cfgType === 'code_execution_20250522'\n ? 'code-execution-2025-05-22'\n : 'code-execution-2025-08-25',\n )\n }\n\n // Skills beta: scan ALL code_execution tools so this AGREES with the\n // container-lift, which lifts skills from any code_execution tool that\n // carries them (not just the first).\n const hasSkills = tools?.some(\n (tool) =>\n getAnthropicProviderToolKind(tool) === 'code_execution' &&\n (readCodeExecutionSkills(tool)?.length ?? 0) > 0,\n )\n if (hasSkills) betas.add('skills-2025-10-02')\n\n return betas.size > 0 ? Array.from(betas) : undefined\n}\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 beta set depends on both the tools and the modelOptions.\n const betas = computeAnthropicBetas(options.tools, options.modelOptions)\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 // `structuredOutput()` issues a non-streaming `messages.create({ stream:\n // false })` below, so the defaulted `max_tokens` must stay under the SDK's\n // non-streaming 10-minute guard (issue #849) — pass `stream: false`.\n const requestParams = this.mapCommonOptionsToAnthropic(chatOptions, {\n stream: false,\n })\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 const betas = computeAnthropicBetas(\n chatOptions.tools,\n chatOptions.modelOptions,\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 ...(betas && { betas }),\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 { stream = true }: { stream?: boolean } = {},\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 'cache_control',\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 // Anthropic's Messages API *requires* `max_tokens`, so we must always send a\n // value. When the caller doesn't specify one, default to the resolved\n // model's real output ceiling (from model-meta) rather than a low constant\n // that silently truncates long responses with `stop_reason: \"max_tokens\"`\n // (issue #849). `max_tokens` is a ceiling, not a reservation — billing is on\n // tokens actually generated, so a higher default costs nothing extra.\n // For non-streaming requests (the `structuredOutput()` path) the default is\n // clamped to the SDK's non-streaming-safe limit so it doesn't trip the\n // \"streaming required\" 10-minute guard — see getAnthropicDefaultMaxTokens.\n const defaultMaxTokens =\n modelOptions?.max_tokens ??\n getAnthropicDefaultMaxTokens(this.model, { stream })\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 // Lift skills attached to a `code_execution` tool into the top-level\n // `container.skills` request param (Anthropic's required shape). Preserve any\n // `container.id` supplied via modelOptions for container reuse. This is the\n // canonical path for skills; `modelOptions.container.skills` is deprecated.\n const toolSkills = options.tools\n ?.map((tool) =>\n getAnthropicProviderToolKind(tool) === 'code_execution'\n ? readCodeExecutionSkills(tool)\n : undefined,\n )\n .find((skills) => skills && skills.length > 0)\n\n if (toolSkills && toolSkills.length > 0) {\n const existingContainer = validProviderOptions.container ?? undefined\n validProviderOptions.container = {\n id: existingContainer?.id ?? null,\n skills: toolSkills,\n }\n }\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 // Provider-executed server tools (e.g. web_search) replay as the\n // original `server_tool_use` + result blocks so the model still sees\n // the prior evidence. Their result was captured verbatim during\n // streaming (see processAnthropicStream).\n const serverMeta = readAnthropicServerToolMetadata(toolCall.metadata)\n if (serverMeta) {\n const serverToolUseBlock: ServerToolUseBlockParam = {\n type: 'server_tool_use',\n id: toolCall.id,\n name: serverMeta.serverToolType,\n input: parsedInput,\n }\n contentBlocks.push(serverToolUseBlock)\n contentBlocks.push(\n buildServerToolResultBlock(toolCall.id, serverMeta),\n )\n continue\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 // Completed server tools awaiting their matching result block. Anthropic\n // emits `server_tool_use` then a separate `*_tool_result` block; we hold\n // the call here (keyed by id) until the result arrives so we can emit a\n // single provider-executed tool call carrying the raw result for round-trip.\n const completedServerTools = new Map<\n string,\n { id: string; name: string; input: string }\n >()\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\n // Emit the server tool as a single provider-executed tool call,\n // carrying its raw result so the evidence (e.g. web_search sources)\n // round-trips into the next turn's request. The agent loop skips\n // provider-executed calls, so this never triggers client execution.\n const serverTool = completedServerTools.get(\n event.content_block.tool_use_id,\n )\n if (serverTool) {\n completedServerTools.delete(serverTool.id)\n\n let parsedInput: unknown = {}\n try {\n const parsed = serverTool.input\n ? JSON.parse(serverTool.input)\n : {}\n parsedInput = parsed && typeof parsed === 'object' ? parsed : {}\n } catch {\n parsedInput = {}\n }\n\n const serverToolMetadata = {\n providerExecuted: true,\n anthropic: {\n serverToolType: serverTool.name,\n resultBlockType: event.content_block.type,\n result: content,\n },\n }\n\n currentToolIndex++\n yield {\n type: EventType.TOOL_CALL_START,\n toolCallId: serverTool.id,\n toolCallName: serverTool.name,\n toolName: serverTool.name,\n parentMessageId: messageId,\n model,\n timestamp: Date.now(),\n index: currentToolIndex,\n metadata: serverToolMetadata,\n }\n yield {\n type: EventType.TOOL_CALL_END,\n toolCallId: serverTool.id,\n toolCallName: serverTool.name,\n toolName: serverTool.name,\n model,\n timestamp: Date.now(),\n input: parsedInput,\n }\n\n // Text after the server tool starts a fresh message segment.\n hasEmittedTextMessageStart = false\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 parentMessageId: messageId,\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 parentMessageId: messageId,\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 // Hold the call until its result block arrives so we can emit\n // both together as one provider-executed tool call.\n completedServerTools.set(currentServerTool.id, currentServerTool)\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 // Surface a warning when the truncating cap was the\n // adapter-supplied default (caller didn't pass `max_tokens`), so\n // the truncation isn't silently attributed to the model \"doing\n // nothing\" (issue #849). When the caller set `max_tokens`\n // themselves, hitting it is their own deliberate ceiling.\n if (options.modelOptions?.max_tokens == null) {\n const defaultedMaxTokens = getAnthropicDefaultMaxTokens(model)\n logger.warn(\n `anthropic response truncated at the default max_tokens (${defaultedMaxTokens}) for model=${model}; pass maxTokens (or modelOptions.max_tokens) to raise the output ceiling`,\n {\n source: 'anthropic.processAnthropicStream',\n model,\n defaultedMaxTokens,\n },\n )\n }\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"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"text.js","names":[],"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 { getAnthropicProviderToolKind } from '../tools/anthropic-provider-tool'\nimport {\n readCodeExecutionConfig,\n readCodeExecutionSkills,\n} from '../tools/code-execution-tool'\nimport { validateTextProviderOptions } from '../text/text-provider-options'\nimport { buildAnthropicUsage } from '../usage'\nimport {\n createAnthropicClient,\n generateId,\n getAnthropicApiKeyFromEnv,\n} from '../utils/client'\nimport {\n ANTHROPIC_COMBINED_TOOLS_AND_SCHEMA_MODELS,\n getAnthropicDefaultMaxTokens,\n} 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 ServerToolUseBlockParam,\n TextBlockParam,\n ThinkingBlockParam,\n ToolUseBlockParam,\n URLImageSource,\n URLPDFSource,\n WebFetchToolResultBlockParam,\n WebSearchToolResultBlockParam,\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 AnyTool,\n ContentPart,\n Modality,\n ModelMessage,\n AdapterYieldChunk,\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 {\n AnthropicClientConfig,\n AnthropicMessagesClient,\n} from '../utils/client'\n\n/**\n * The block type carried by an Anthropic provider-executed (server) tool's\n * stored result. Mirrors the `*_tool_result` block emitted by the streaming\n * API so it can be replayed verbatim into a later turn.\n */\ntype AnthropicServerToolResultBlockType =\n | 'web_search_tool_result'\n | 'web_fetch_tool_result'\n\n/**\n * Anthropic payload stashed on a provider-executed tool call's `metadata`\n * (under the `anthropic` key, alongside `providerExecuted: true`). Holds enough\n * to reconstruct the original `server_tool_use` + `*_tool_result` blocks so the\n * model still sees prior `web_search` / `web_fetch` evidence on the next turn.\n */\ninterface AnthropicServerToolMetadata {\n serverToolType: ServerToolUseBlockParam['name']\n resultBlockType: AnthropicServerToolResultBlockType\n /** Raw result block content, preserved verbatim from the stream. */\n result: unknown\n}\n\n/**\n * Narrow an opaque tool-call `metadata` to {@link AnthropicServerToolMetadata}\n * when it follows the provider-executed convention, else `null`.\n */\nfunction readAnthropicServerToolMetadata(\n metadata: unknown,\n): AnthropicServerToolMetadata | null {\n if (typeof metadata !== 'object' || metadata === null) return null\n const outer = metadata as { providerExecuted?: unknown; anthropic?: unknown }\n if (outer.providerExecuted !== true) return null\n const inner = outer.anthropic\n if (typeof inner !== 'object' || inner === null) return null\n const { serverToolType, resultBlockType, result } = inner as {\n serverToolType?: unknown\n resultBlockType?: unknown\n result?: unknown\n }\n if (\n typeof serverToolType !== 'string' ||\n (resultBlockType !== 'web_search_tool_result' &&\n resultBlockType !== 'web_fetch_tool_result')\n ) {\n return null\n }\n return {\n // Validated as a string above; widen back to the SDK's tool-name union.\n serverToolType: serverToolType as ServerToolUseBlockParam['name'],\n resultBlockType,\n result,\n }\n}\n\n/**\n * Reconstruct the `*_tool_result` block param from stored server-tool metadata.\n * The `result` content is opaque round-trip data, asserted to the SDK's param\n * content type at this single boundary.\n */\nfunction buildServerToolResultBlock(\n toolUseId: string,\n meta: AnthropicServerToolMetadata,\n): WebSearchToolResultBlockParam | WebFetchToolResultBlockParam {\n if (meta.resultBlockType === 'web_search_tool_result') {\n return {\n type: 'web_search_tool_result',\n tool_use_id: toolUseId,\n content: meta.result as WebSearchToolResultBlockParam['content'],\n }\n }\n return {\n type: 'web_fetch_tool_result',\n tool_use_id: toolUseId,\n content: meta.result as WebFetchToolResultBlockParam['content'],\n }\n}\n\n/**\n * Computes the `betas` array for a Messages request. Unions:\n * - `interleaved-thinking-2025-05-14` when interleaved thinking is enabled,\n * - `code-execution-2025-08-25` when a `code_execution` tool is present,\n * - `skills-2025-10-02` when that tool carries skills,\n * - `context-management-2025-06-27` when `context_management` is set.\n * Returns `undefined` when none apply (so the call site omits `betas`).\n */\nexport function computeAnthropicBetas(\n tools: Array<AnyTool> | undefined,\n modelOptions:\n | {\n thinking?: {\n type?: 'enabled' | 'disabled' | 'adaptive'\n budget_tokens?: number\n }\n context_management?: unknown | null\n }\n | undefined,\n): Array<AnthropicBeta> | undefined {\n const betas = new Set<AnthropicBeta>()\n\n const useInterleavedThinking =\n modelOptions?.thinking?.type === 'enabled' &&\n typeof modelOptions.thinking.budget_tokens === 'number' &&\n modelOptions.thinking.budget_tokens > 0\n if (useInterleavedThinking) betas.add('interleaved-thinking-2025-05-14')\n\n // Context editing requires the beta header; the body field alone is not\n // enough (issue #1074). `null` is a typed \"unset\" — do not enable the beta.\n if (modelOptions?.context_management != null) {\n betas.add('context-management-2025-06-27')\n }\n\n // Code-execution beta is version-aware: select from the FIRST code_execution\n // tool's config type.\n const codeExecTool = tools?.find(\n (tool) => getAnthropicProviderToolKind(tool) === 'code_execution',\n )\n if (codeExecTool) {\n const cfgType = readCodeExecutionConfig(codeExecTool)?.type\n // Each code_execution tool version pairs with a specific beta. Known\n // legacy variant maps explicitly; current/future variants (e.g.\n // `code_execution_20250825` and later) use the latest `-08-25` beta.\n betas.add(\n cfgType === 'code_execution_20250522'\n ? 'code-execution-2025-05-22'\n : 'code-execution-2025-08-25',\n )\n }\n\n // Skills beta: scan ALL code_execution tools so this AGREES with the\n // container-lift, which lifts skills from any code_execution tool that\n // carries them (not just the first).\n const hasSkills = tools?.some(\n (tool) =>\n getAnthropicProviderToolKind(tool) === 'code_execution' &&\n (readCodeExecutionSkills(tool)?.length ?? 0) > 0,\n )\n if (hasSkills) betas.add('skills-2025-10-02')\n\n return betas.size > 0 ? Array.from(betas) : undefined\n}\n\n/**\n * Configuration for Anthropic text adapter\n */\nexport interface AnthropicTextConfig extends AnthropicClientConfig {}\n\nexport type AnthropicTextAdapterConfig =\n | AnthropicTextConfig\n | { client: AnthropicMessagesClient }\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\ntype SdkAnthropicMessagesClient = {\n beta: {\n messages: Pick<Anthropic_SDK['beta']['messages'], 'create'>\n }\n}\n\n/**\n * Restore the package SDK's precise overloads at the adapter boundary.\n * Alternative clients may use a separate Anthropic 0.x SDK whose declarations\n * drift while implementing the same Messages protocol at runtime.\n */\nfunction asSdkAnthropicMessagesClient(\n client: AnthropicMessagesClient,\n): SdkAnthropicMessagesClient {\n // oxlint-disable-next-line eslint-js/no-restricted-syntax -- The public callable deliberately erases version-specific SDK overloads; restore this package's SDK type at the internal boundary.\n return client as unknown as SdkAnthropicMessagesClient\n}\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: SdkAnthropicMessagesClient\n\n constructor(config: AnthropicTextAdapterConfig, model: TModel) {\n super({}, model)\n this.client =\n 'client' in config\n ? asSdkAnthropicMessagesClient(config.client)\n : createAnthropicClient(config)\n }\n\n async *chatStream(\n options: TextOptions<TProviderOptions>,\n ): AsyncIterable<AdapterYieldChunk> {\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 beta set depends on both the tools and the modelOptions.\n const betas = computeAnthropicBetas(options.tools, options.modelOptions)\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 // `structuredOutput()` issues a non-streaming `messages.create({ stream:\n // false })` below, so the defaulted `max_tokens` must stay under the SDK's\n // non-streaming 10-minute guard (issue #849) — pass `stream: false`.\n const requestParams = this.mapCommonOptionsToAnthropic(chatOptions, {\n stream: false,\n })\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 const betas = computeAnthropicBetas(\n chatOptions.tools,\n chatOptions.modelOptions,\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 ...(betas && { betas }),\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 { stream = true }: { stream?: boolean } = {},\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 'cache_control',\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 // Anthropic's Messages API *requires* `max_tokens`, so we must always send a\n // value. When the caller doesn't specify one, default to the resolved\n // model's real output ceiling (from model-meta) rather than a low constant\n // that silently truncates long responses with `stop_reason: \"max_tokens\"`\n // (issue #849). `max_tokens` is a ceiling, not a reservation — billing is on\n // tokens actually generated, so a higher default costs nothing extra.\n // For non-streaming requests (the `structuredOutput()` path) the default is\n // clamped to the SDK's non-streaming-safe limit so it doesn't trip the\n // \"streaming required\" 10-minute guard — see getAnthropicDefaultMaxTokens.\n const defaultMaxTokens =\n modelOptions?.max_tokens ??\n getAnthropicDefaultMaxTokens(this.model, { stream })\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 // Lift skills attached to a `code_execution` tool into the top-level\n // `container.skills` request param (Anthropic's required shape). Preserve any\n // `container.id` supplied via modelOptions for container reuse. This is the\n // canonical path for skills; `modelOptions.container.skills` is deprecated.\n const toolSkills = options.tools\n ?.map((tool) =>\n getAnthropicProviderToolKind(tool) === 'code_execution'\n ? readCodeExecutionSkills(tool)\n : undefined,\n )\n .find((skills) => skills && skills.length > 0)\n\n if (toolSkills && toolSkills.length > 0) {\n const existingContainer = validProviderOptions.container ?? undefined\n validProviderOptions.container = {\n id: existingContainer?.id ?? null,\n skills: toolSkills,\n }\n }\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?.cache_control !== undefined && {\n cache_control: metadata.cache_control,\n }),\n }\n }\n case 'document': {\n const metadata = part.metadata as AnthropicDocumentMetadata | undefined\n const title = metadata?.title ?? metadata?.filename\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?.cache_control !== undefined && {\n cache_control: metadata.cache_control,\n }),\n ...(metadata?.citations !== undefined && {\n citations: metadata.citations,\n }),\n ...(metadata?.context !== undefined && {\n context: metadata.context,\n }),\n ...(title !== undefined && { title }),\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 // Provider-executed server tools (e.g. web_search) replay as the\n // original `server_tool_use` + result blocks so the model still sees\n // the prior evidence. Their result was captured verbatim during\n // streaming (see processAnthropicStream).\n const serverMeta = readAnthropicServerToolMetadata(toolCall.metadata)\n if (serverMeta) {\n const serverToolUseBlock: ServerToolUseBlockParam = {\n type: 'server_tool_use',\n id: toolCall.id,\n name: serverMeta.serverToolType,\n input: parsedInput,\n }\n contentBlocks.push(serverToolUseBlock)\n contentBlocks.push(\n buildServerToolResultBlock(toolCall.id, serverMeta),\n )\n continue\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<AdapterYieldChunk> {\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 // Completed server tools awaiting their matching result block. Anthropic\n // emits `server_tool_use` then a separate `*_tool_result` block; we hold\n // the call here (keyed by id) until the result arrives so we can emit a\n // single provider-executed tool call carrying the raw result for round-trip.\n const completedServerTools = new Map<\n string,\n { id: string; name: string; input: string }\n >()\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\n // Emit the server tool as a single provider-executed tool call,\n // carrying its raw result so the evidence (e.g. web_search sources)\n // round-trips into the next turn's request. The agent loop skips\n // provider-executed calls, so this never triggers client execution.\n const serverTool = completedServerTools.get(\n event.content_block.tool_use_id,\n )\n if (serverTool) {\n completedServerTools.delete(serverTool.id)\n\n let parsedInput: unknown = {}\n try {\n const parsed = serverTool.input\n ? JSON.parse(serverTool.input)\n : {}\n parsedInput = parsed && typeof parsed === 'object' ? parsed : {}\n } catch {\n parsedInput = {}\n }\n\n const serverToolMetadata = {\n providerExecuted: true,\n anthropic: {\n serverToolType: serverTool.name,\n resultBlockType: event.content_block.type,\n result: content,\n },\n }\n\n currentToolIndex++\n yield {\n type: EventType.TOOL_CALL_START,\n toolCallId: serverTool.id,\n toolCallName: serverTool.name,\n toolName: serverTool.name,\n parentMessageId: messageId,\n model,\n timestamp: Date.now(),\n index: currentToolIndex,\n metadata: serverToolMetadata,\n }\n yield {\n type: EventType.TOOL_CALL_END,\n toolCallId: serverTool.id,\n toolCallName: serverTool.name,\n toolName: serverTool.name,\n model,\n timestamp: Date.now(),\n input: parsedInput,\n }\n\n // Text after the server tool starts a fresh message segment.\n hasEmittedTextMessageStart = false\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 parentMessageId: messageId,\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 parentMessageId: messageId,\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 // Hold the call until its result block arrives so we can emit\n // both together as one provider-executed tool call.\n completedServerTools.set(currentServerTool.id, currentServerTool)\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 // Surface a warning when the truncating cap was the\n // adapter-supplied default (caller didn't pass `max_tokens`), so\n // the truncation isn't silently attributed to the model \"doing\n // nothing\" (issue #849). When the caller set `max_tokens`\n // themselves, hitting it is their own deliberate ceiling.\n if (options.modelOptions?.max_tokens == null) {\n const defaultedMaxTokens = getAnthropicDefaultMaxTokens(model)\n logger.warn(\n `anthropic response truncated at the default max_tokens (${defaultedMaxTokens}) for model=${model}; pass maxTokens (or modelOptions.max_tokens) to raise the output ceiling`,\n {\n source: 'anthropic.processAnthropicStream',\n model,\n defaultedMaxTokens,\n },\n )\n }\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 chat adapter with an injected Messages client.\n * Type resolution happens here at the call site.\n */\nexport function createAnthropicChatWithClient<\n TModel extends (typeof ANTHROPIC_MODELS)[number],\n>(\n model: TModel,\n client: AnthropicMessagesClient,\n): AnthropicTextAdapter<\n TModel,\n ResolveProviderOptions<TModel>,\n ResolveInputModalities<TModel>\n> {\n return new AnthropicTextAdapter({ client }, 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"],"mappings":"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"}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
export { AnthropicTextAdapter, anthropicText, createAnthropicChat, type AnthropicTextConfig, type AnthropicTextProviderOptions, } from './adapters/text.js';
|
|
1
|
+
export { AnthropicTextAdapter, anthropicText, createAnthropicChat, createAnthropicChatWithClient, type AnthropicTextAdapterConfig, type AnthropicTextConfig, type AnthropicTextProviderOptions, } from './adapters/text.js';
|
|
2
|
+
export type { AnthropicMessagesClient } from './utils/client.js';
|
|
2
3
|
export type { AnthropicSystemPromptMetadata } from './text/text-provider-options.js';
|
|
3
4
|
export { anthropicSummarize, createAnthropicSummarize, type AnthropicSummarizeConfig, type AnthropicSummarizeModel, } from './adapters/summarize.js';
|
|
4
|
-
export type { AnthropicChatModel, AnthropicChatModelProviderOptionsByName, AnthropicChatModelToolCapabilitiesByName, AnthropicModelInputModalitiesByName, } from './model-meta.js';
|
|
5
|
-
export { ANTHROPIC_MODELS, ANTHROPIC_COMBINED_TOOLS_AND_SCHEMA_MODELS, } from './model-meta.js';
|
|
5
|
+
export type { AnthropicChatModel, AnthropicVertexChatModel, AnthropicChatModelProviderOptionsByName, AnthropicChatModelToolCapabilitiesByName, AnthropicModelInputModalitiesByName, } from './model-meta.js';
|
|
6
|
+
export { ANTHROPIC_MODELS, ANTHROPIC_VERTEX_CHAT_MODELS, ANTHROPIC_COMBINED_TOOLS_AND_SCHEMA_MODELS, } from './model-meta.js';
|
|
6
7
|
export type { AnthropicTextMetadata, AnthropicImageMetadata, AnthropicDocumentMetadata, AnthropicAudioMetadata, AnthropicVideoMetadata, AnthropicMessageMetadataByModality, } from './message-types.js';
|
|
7
8
|
export { convertToolsToProviderFormat } from './tools/tool-converter.js';
|
|
8
9
|
export type { AnthropicTool, CustomTool } from './tools/index.js';
|
package/dist/esm/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { convertToolsToProviderFormat } from "./tools/tool-converter.js";
|
|
2
|
-
import { ANTHROPIC_COMBINED_TOOLS_AND_SCHEMA_MODELS, ANTHROPIC_MODELS } from "./model-meta.js";
|
|
3
|
-
import { AnthropicTextAdapter, anthropicText, createAnthropicChat } from "./adapters/text.js";
|
|
2
|
+
import { ANTHROPIC_COMBINED_TOOLS_AND_SCHEMA_MODELS, ANTHROPIC_MODELS, ANTHROPIC_VERTEX_CHAT_MODELS } from "./model-meta.js";
|
|
3
|
+
import { AnthropicTextAdapter, anthropicText, createAnthropicChat, createAnthropicChatWithClient } from "./adapters/text.js";
|
|
4
4
|
import { anthropicSummarize, createAnthropicSummarize } from "./adapters/summarize.js";
|
|
5
|
-
export { ANTHROPIC_COMBINED_TOOLS_AND_SCHEMA_MODELS, ANTHROPIC_MODELS, AnthropicTextAdapter, anthropicSummarize, anthropicText, convertToolsToProviderFormat, createAnthropicChat, createAnthropicSummarize };
|
|
5
|
+
export { ANTHROPIC_COMBINED_TOOLS_AND_SCHEMA_MODELS, ANTHROPIC_MODELS, ANTHROPIC_VERTEX_CHAT_MODELS, AnthropicTextAdapter, anthropicSummarize, anthropicText, convertToolsToProviderFormat, createAnthropicChat, createAnthropicChatWithClient, createAnthropicSummarize };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CacheControlEphemeral, TextCitationParam } from '@anthropic-ai/sdk/resources';
|
|
1
|
+
import { CacheControlEphemeral, CitationsConfigParam, TextCitationParam } from '@anthropic-ai/sdk/resources';
|
|
2
2
|
/**
|
|
3
3
|
* Supported image media types for Anthropic.
|
|
4
4
|
*/
|
|
@@ -8,10 +8,7 @@ export type AnthropicImageMediaType = 'image/jpeg' | 'image/png' | 'image/gif' |
|
|
|
8
8
|
*/
|
|
9
9
|
export interface AnthropicImageMetadata {
|
|
10
10
|
/**
|
|
11
|
-
* The
|
|
12
|
-
* Required when using base64 source type.
|
|
13
|
-
*
|
|
14
|
-
* @see https://docs.anthropic.com/claude/docs/vision#supported-image-types
|
|
11
|
+
* @deprecated Ignored. The media type is taken from `source.mimeType`.
|
|
15
12
|
*/
|
|
16
13
|
mediaType?: AnthropicImageMediaType;
|
|
17
14
|
/**
|
|
@@ -38,17 +35,19 @@ export type AnthropicDocumentMediaType = 'application/pdf';
|
|
|
38
35
|
*/
|
|
39
36
|
export interface AnthropicDocumentMetadata {
|
|
40
37
|
/**
|
|
41
|
-
* The
|
|
42
|
-
* Required for document content, typically 'application/pdf'.
|
|
43
|
-
*
|
|
44
|
-
* @see https://docs.anthropic.com/claude/docs/pdf-support
|
|
38
|
+
* @deprecated Ignored. The media type is taken from `source.mimeType`.
|
|
45
39
|
*/
|
|
46
40
|
mediaType?: AnthropicDocumentMediaType;
|
|
47
41
|
/**
|
|
48
42
|
* Cache control settings for the document.
|
|
49
43
|
*/
|
|
50
44
|
cache_control?: CacheControlEphemeral;
|
|
45
|
+
citations?: CitationsConfigParam;
|
|
51
46
|
context?: string;
|
|
47
|
+
/**
|
|
48
|
+
* The document filename. Used as the document title when `title` is absent.
|
|
49
|
+
*/
|
|
50
|
+
filename?: string;
|
|
52
51
|
title?: string;
|
|
53
52
|
}
|
|
54
53
|
/**
|
package/dist/esm/model-meta.d.ts
CHANGED
|
@@ -263,6 +263,13 @@ declare const CLAUDE_OPUS_5_FAST: {
|
|
|
263
263
|
};
|
|
264
264
|
};
|
|
265
265
|
export declare const ANTHROPIC_MODELS: readonly ["claude-opus-5", "claude-opus-5-fast", "claude-opus-4-6", "claude-opus-4-5", "claude-sonnet-4-6", "claude-sonnet-4-5", "claude-haiku-4-5", "claude-opus-4-1", "claude-opus-4-7", "claude-opus-4-8", "claude-fable-5", "claude-sonnet-5"];
|
|
266
|
+
/**
|
|
267
|
+
* Claude chat models on Vertex AI / Gemini Enterprise Agent Platform.
|
|
268
|
+
* This list is the Google partner catalog, not the full Anthropic API catalog.
|
|
269
|
+
* Source: https://docs.cloud.google.com/gemini-enterprise-agent-platform/models/partner-models/use-partner-models
|
|
270
|
+
*/
|
|
271
|
+
export declare const ANTHROPIC_VERTEX_CHAT_MODELS: readonly ["claude-opus-5", "claude-sonnet-5", "claude-fable-5", "claude-opus-4-8", "claude-opus-4-7", "claude-opus-4-6", "claude-sonnet-4-6", "claude-opus-4-5", "claude-sonnet-4-5", "claude-opus-4-1", "claude-haiku-4-5"];
|
|
272
|
+
export type AnthropicVertexChatModel = (typeof ANTHROPIC_VERTEX_CHAT_MODELS)[number];
|
|
266
273
|
/**
|
|
267
274
|
* Fallback `max_tokens` ceiling for a model whose metadata carries no
|
|
268
275
|
* `max_output_tokens` (e.g. an unrecognized model id). Anthropic's Messages
|
package/dist/esm/model-meta.js
CHANGED
|
@@ -369,6 +369,24 @@ var ANTHROPIC_MODELS = [
|
|
|
369
369
|
CLAUDE_SONNET_5.id
|
|
370
370
|
];
|
|
371
371
|
/**
|
|
372
|
+
* Claude chat models on Vertex AI / Gemini Enterprise Agent Platform.
|
|
373
|
+
* This list is the Google partner catalog, not the full Anthropic API catalog.
|
|
374
|
+
* Source: https://docs.cloud.google.com/gemini-enterprise-agent-platform/models/partner-models/use-partner-models
|
|
375
|
+
*/
|
|
376
|
+
var ANTHROPIC_VERTEX_CHAT_MODELS = [
|
|
377
|
+
CLAUDE_OPUS_5.id,
|
|
378
|
+
CLAUDE_SONNET_5.id,
|
|
379
|
+
CLAUDE_FABLE_5.id,
|
|
380
|
+
CLAUDE_OPUS_4_8.id,
|
|
381
|
+
CLAUDE_OPUS_4_7.id,
|
|
382
|
+
CLAUDE_OPUS_4_6.id,
|
|
383
|
+
CLAUDE_SONNET_4_6.id,
|
|
384
|
+
CLAUDE_OPUS_4_5.id,
|
|
385
|
+
CLAUDE_SONNET_4_5.id,
|
|
386
|
+
CLAUDE_OPUS_4_1.id,
|
|
387
|
+
CLAUDE_HAIKU_4_5.id
|
|
388
|
+
];
|
|
389
|
+
/**
|
|
372
390
|
* Fallback `max_tokens` ceiling for a model whose metadata carries no
|
|
373
391
|
* `max_output_tokens` (e.g. an unrecognized model id). Anthropic's Messages
|
|
374
392
|
* API *requires* `max_tokens`, so the adapter must always send a value. 64K is
|
|
@@ -455,6 +473,6 @@ var ANTHROPIC_COMBINED_TOOLS_AND_SCHEMA_MODELS = /* @__PURE__ */ new Set([
|
|
|
455
473
|
CLAUDE_HAIKU_4_5.id
|
|
456
474
|
]);
|
|
457
475
|
//#endregion
|
|
458
|
-
export { ANTHROPIC_COMBINED_TOOLS_AND_SCHEMA_MODELS, ANTHROPIC_DEFAULT_MAX_OUTPUT_TOKENS, ANTHROPIC_MAX_NONSTREAMING_TOKENS, ANTHROPIC_MODELS, getAnthropicDefaultMaxTokens };
|
|
476
|
+
export { ANTHROPIC_COMBINED_TOOLS_AND_SCHEMA_MODELS, ANTHROPIC_DEFAULT_MAX_OUTPUT_TOKENS, ANTHROPIC_MAX_NONSTREAMING_TOKENS, ANTHROPIC_MODELS, ANTHROPIC_VERTEX_CHAT_MODELS, getAnthropicDefaultMaxTokens };
|
|
459
477
|
|
|
460
478
|
//# sourceMappingURL=model-meta.js.map
|