@tanstack/ai-anthropic 0.15.13 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/adapters/summarize.d.ts +2 -2
- package/dist/esm/adapters/summarize.js.map +1 -1
- package/dist/esm/adapters/text.js +90 -0
- package/dist/esm/adapters/text.js.map +1 -1
- package/dist/esm/model-meta.d.ts +35 -207
- package/dist/esm/model-meta.js +4 -35
- package/dist/esm/model-meta.js.map +1 -1
- package/dist/esm/text/text-provider-options.d.ts +65 -2
- package/dist/esm/text/text-provider-options.js.map +1 -1
- package/package.json +3 -3
- package/src/adapters/summarize.ts +2 -2
- package/src/adapters/text.ts +165 -0
- package/src/model-meta.ts +99 -466
- package/src/text/text-provider-options.ts +70 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text-provider-options.js","sources":["../../../src/text/text-provider-options.ts"],"sourcesContent":["import type {\n BetaContextManagementConfig,\n BetaToolChoiceAny,\n BetaToolChoiceAuto,\n BetaToolChoiceTool,\n} from '@anthropic-ai/sdk/resources/beta/messages/messages'\nimport type { CacheControlEphemeral } from '@anthropic-ai/sdk/resources'\nimport type { AnthropicContainerSkill, AnthropicTool } from '../tools'\nimport type {\n MessageParam,\n TextBlockParam,\n} from '@anthropic-ai/sdk/resources/messages'\n\n/**\n * Per-prompt metadata Anthropic understands on `systemPrompts` entries.\n *\n * Used via the structured form of `systemPrompts`:\n *\n * @example\n * import type { AnthropicSystemPromptMetadata } from '@tanstack/ai-anthropic'\n *\n * chat({\n * adapter: anthropicText(),\n * model: 'claude-sonnet-4-6',\n * systemPrompts: [\n * {\n * content: 'Stable instructions — cache me.',\n * metadata: { cache_control: { type: 'ephemeral' } } satisfies AnthropicSystemPromptMetadata,\n * },\n * 'Volatile per-request instruction.',\n * ],\n * })\n */\nexport interface AnthropicSystemPromptMetadata {\n /**\n * Anthropic prompt-caching control applied to this system prompt's\n * `TextBlockParam`.\n *\n * @see https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching\n */\n cache_control?: CacheControlEphemeral\n}\n\nexport interface AnthropicContainerOptions {\n /**\n * Container identifier for reuse across requests.\n * Container parameters with skills to be loaded.\n */\n container?: {\n id: string | null\n /**\n * List of skills to load into the container.\n *\n * @deprecated Configure skills on the `code_execution` tool instead:\n * `codeExecutionTool(config, { skills })`. The adapter lifts those into\n * `container.skills` and attaches the required beta headers. Setting\n * skills here bypasses the beta-header wiring and may stop working.\n */\n skills: Array<AnthropicContainerSkill> | null\n } | null\n}\n\nexport interface AnthropicContextManagementOptions {\n /**\n * Context management configuration.\n\nThis allows you to control how Claude manages context across multiple requests, such as whether to clear function results or not.\n */\n context_management?: BetaContextManagementConfig | null\n}\n\nexport interface AnthropicMCPOptions {\n /**\n * MCP servers to be utilized in this request\n * Maximum of 20 servers\n */\n mcp_servers?: Array<MCPServer>\n}\n\nexport interface AnthropicServiceTierOptions {\n /**\n * Determines whether to use priority capacity (if available) or standard capacity for this request.\n */\n service_tier?: 'auto' | 'standard_only'\n}\n\nexport interface AnthropicStopSequencesOptions {\n /**\n * Custom text sequences that will cause the model to stop generating.\n\nAnthropic models will normally stop when they have naturally completed their turn, which will result in a response stop_reason of \"end_turn\".\n\nIf you want the model to stop generating when it encounters custom strings of text, you can use the stop_sequences parameter. If the model encounters one of the custom sequences, the response stop_reason value will be \"stop_sequence\" and the response stop_sequence value will contain the matched stop sequence.\n */\n stop_sequences?: Array<string>\n}\n\nexport interface AnthropicThinkingOptions {\n /**\n * Configuration for enabling Claude's extended thinking.\n\nWhen enabled, responses include thinking content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your max_tokens limit.\n */\n thinking?:\n | {\n /**\n* Determines how many tokens Claude can use for its internal reasoning process. Larger budgets can enable more thorough analysis for complex problems, improving response quality.\n\nMust be ≥1024 and less than max_tokens\n*/\n budget_tokens: number\n\n type: 'enabled'\n }\n | {\n type: 'disabled'\n }\n}\n\nexport interface AnthropicAdaptiveThinkingOptions {\n /**\n * Configuration for Claude's adaptive thinking (Opus 4.6+).\n *\n * In adaptive mode, Claude dynamically decides when and how much to think.\n * Use the effort parameter to control thinking depth.\n * `thinking: {type: \"enabled\"}` with `budget_tokens` is deprecated on Opus 4.6.\n */\n thinking?:\n | {\n type: 'adaptive'\n /**\n * Controls what (if any) thinking content is streamed back.\n *\n * - `'summarized'`: stream summarized thinking via `thinking_delta`\n * events (the user-visible reasoning text).\n * - `'omitted'`: stream the thinking block's `signature_delta` only\n * (no reasoning text reaches the client).\n *\n * On Claude Opus 4.6 the default is `'summarized'`. On\n * Claude Opus 4.7 the default flipped to `'omitted'` — callers\n * must set `'summarized'` explicitly to get the reasoning text.\n */\n display?: 'summarized' | 'omitted'\n }\n | {\n /**\n * @deprecated Use `type: 'adaptive'` with the effort parameter on Opus 4.6+.\n */\n budget_tokens: number\n type: 'enabled'\n }\n | {\n type: 'disabled'\n }\n}\n\nexport interface AnthropicEffortOptions {\n /**\n * Controls the thinking depth for adaptive thinking mode (Opus 4.6+).\n *\n * - `max`: Absolute highest capability\n * - `high`: Default - Claude will almost always think\n * - `medium`: Balanced cost-quality\n * - `low`: May skip thinking for simpler problems\n */\n effort?: 'max' | 'high' | 'medium' | 'low'\n}\n\nexport interface AnthropicOutputConfigOptions {\n /**\n * Output configuration for the model's response.\n *\n * On Claude 4.7+ the top-level `effort` field was relocated under\n * `output_config.effort`, and `thinking: { type: 'enabled', budget_tokens }`\n * was replaced by `thinking: { type: 'adaptive' }` paired with\n * `output_config.effort`. Earlier models continue to accept the legacy\n * top-level `effort` / `thinking.type: 'enabled'` shape.\n *\n * The engine also writes `output_config.format` here when the caller\n * passes `outputSchema` to a Claude 4.5+ adapter (issue #605 native\n * combined mode). Both fields coexist: user-supplied `effort` is\n * preserved when the engine adds `format`.\n */\n output_config?: {\n effort?: 'low' | 'medium' | 'high' | 'max' | null\n }\n}\n\nexport interface AnthropicToolChoiceOptions {\n tool_choice?: BetaToolChoiceAny | BetaToolChoiceTool | BetaToolChoiceAuto\n}\n\nexport interface AnthropicSamplingOptions {\n /**\n * Only sample from the top K options for each subsequent token.\n\nUsed to remove \"long tail\" low probability responses.\nRecommended for advanced use cases only. You usually only need to use temperature.\n\nRequired range: x >= 0\n */\n top_k?: number\n /**\n * Amount of randomness injected into the response.\n * Either use this or top_p, but not both.\n * Defaults to 1.0. Ranges from 0.0 to 1.0. Use temperature closer to 0.0 for analytical / multiple choice, and closer to 1.0 for creative and generative tasks.\n * @default 1.0\n */\n temperature?: number\n /**\n * Use nucleus sampling.\n *\n * In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by top_p. You should either alter temperature or top_p, but not both.\n */\n top_p?: number\n /**\n * The maximum number of tokens to generate before stopping. This parameter only specifies the absolute maximum number of tokens to generate. Required by the API; the adapter defaults to 1024 when omitted.\n * Range x >= 1.\n */\n max_tokens?: number\n}\n\nexport type ExternalTextProviderOptions = AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicThinkingOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions &\n Partial<AnthropicAdaptiveThinkingOptions> &\n Partial<AnthropicEffortOptions> &\n Partial<AnthropicOutputConfigOptions>\n\nexport interface InternalTextProviderOptions extends ExternalTextProviderOptions {\n model: string\n\n messages: Array<MessageParam>\n\n /**\n * The maximum number of tokens to generate before stopping. This parameter only specifies the absolute maximum number of tokens to generate.\n * Range x >= 1.\n */\n max_tokens: number\n /**\n * Whether to incrementally stream the response using server-sent events.\n */\n stream?: boolean\n /**\n * System prompt — built by the adapter from the user-facing\n * `systemPrompts: Array<string>` on the chat call. This field is internal:\n * users should pass system prompts via `systemPrompts`, not via\n * `modelOptions`.\n *\n * A system prompt is a way of providing context and instructions to Claude,\n * such as specifying a particular goal or role.\n */\n system?: string | Array<TextBlockParam>\n\n tools?: Array<AnthropicTool>\n\n /**\n * Schema-constrained final answer in a single Messages request (issue\n * #605). Set by the engine when the adapter declared\n * `supportsCombinedToolsAndSchema` and a caller passed `outputSchema`\n * to `chat()`. The model emits tool calls during the agent loop and a\n * schema-matching JSON message on the natural final turn — no separate\n * finalization round-trip needed.\n *\n * The SDK type (`BetaOutputConfig`) currently exposes only `effort`;\n * `format` is accepted at runtime per the deprecation notice on the\n * older `output_format` field\n * (https://platform.claude.com/docs/en/build-with-claude/structured-outputs).\n * We type it explicitly here so the adapter call site doesn't need a\n * cast.\n */\n output_config?: {\n effort?: 'low' | 'medium' | 'high' | 'max' | null\n format?: {\n type: 'json_schema'\n schema: Record<string, unknown>\n }\n }\n}\n\nconst validateTopPandTemperature = (options: InternalTextProviderOptions) => {\n if (options.top_p !== undefined && options.temperature !== undefined) {\n throw new Error('You should either set top_p or temperature, but not both.')\n }\n}\n\nexport interface CacheControl {\n type: 'ephemeral'\n ttl: '5m' | '1h'\n}\n\nconst validateThinking = (options: InternalTextProviderOptions) => {\n const thinking = options.thinking\n if (thinking && thinking.type === 'enabled') {\n if (thinking.budget_tokens < 1024) {\n throw new Error('thinking.budget_tokens must be at least 1024.')\n }\n if (thinking.budget_tokens >= options.max_tokens) {\n throw new Error('thinking.budget_tokens must be less than max_tokens.')\n }\n }\n}\n\ninterface MCPServer {\n name: string\n url: string\n type: 'url'\n authorization_token?: string | null\n tool_configuration: {\n allowed_tools?: Array<string> | null\n enabled?: boolean | null\n } | null\n}\n\nconst validateMaxTokens = (options: InternalTextProviderOptions) => {\n if (options.max_tokens < 1) {\n throw new Error('max_tokens must be at least 1.')\n }\n}\n\nexport const validateTextProviderOptions = (\n options: InternalTextProviderOptions,\n) => {\n validateTopPandTemperature(options)\n validateThinking(options)\n validateMaxTokens(options)\n}\n"],"names":[],"mappings":"AA6RA,MAAM,6BAA6B,CAAC,YAAyC;AAC3E,MAAI,QAAQ,UAAU,UAAa,QAAQ,gBAAgB,QAAW;AACpE,UAAM,IAAI,MAAM,2DAA2D;AAAA,EAC7E;AACF;AAOA,MAAM,mBAAmB,CAAC,YAAyC;AACjE,QAAM,WAAW,QAAQ;AACzB,MAAI,YAAY,SAAS,SAAS,WAAW;AAC3C,QAAI,SAAS,gBAAgB,MAAM;AACjC,YAAM,IAAI,MAAM,+CAA+C;AAAA,IACjE;AACA,QAAI,SAAS,iBAAiB,QAAQ,YAAY;AAChD,YAAM,IAAI,MAAM,sDAAsD;AAAA,IACxE;AAAA,EACF;AACF;AAaA,MAAM,oBAAoB,CAAC,YAAyC;AAClE,MAAI,QAAQ,aAAa,GAAG;AAC1B,UAAM,IAAI,MAAM,gCAAgC;AAAA,EAClD;AACF;AAEO,MAAM,8BAA8B,CACzC,YACG;AACH,6BAA2B,OAAO;AAClC,mBAAiB,OAAO;AACxB,oBAAkB,OAAO;AAC3B;"}
|
|
1
|
+
{"version":3,"file":"text-provider-options.js","sources":["../../../src/text/text-provider-options.ts"],"sourcesContent":["import type {\n BetaContextManagementConfig,\n BetaToolChoiceAny,\n BetaToolChoiceAuto,\n BetaToolChoiceTool,\n} from '@anthropic-ai/sdk/resources/beta/messages/messages'\nimport type { CacheControlEphemeral } from '@anthropic-ai/sdk/resources'\nimport type { AnthropicContainerSkill, AnthropicTool } from '../tools'\nimport type {\n MessageParam,\n TextBlockParam,\n} from '@anthropic-ai/sdk/resources/messages'\n\n/**\n * Per-prompt metadata Anthropic understands on `systemPrompts` entries.\n *\n * Used via the structured form of `systemPrompts`:\n *\n * @example\n * import type { AnthropicSystemPromptMetadata } from '@tanstack/ai-anthropic'\n *\n * chat({\n * adapter: anthropicText(),\n * model: 'claude-sonnet-4-6',\n * systemPrompts: [\n * {\n * content: 'Stable instructions — cache me.',\n * metadata: { cache_control: { type: 'ephemeral' } } satisfies AnthropicSystemPromptMetadata,\n * },\n * 'Volatile per-request instruction.',\n * ],\n * })\n */\nexport interface AnthropicSystemPromptMetadata {\n /**\n * Anthropic prompt-caching control applied to this system prompt's\n * `TextBlockParam`.\n *\n * @see https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching\n */\n cache_control?: CacheControlEphemeral\n}\n\nexport interface AnthropicContainerOptions {\n /**\n * Container identifier for reuse across requests.\n * Container parameters with skills to be loaded.\n */\n container?: {\n id: string | null\n /**\n * List of skills to load into the container.\n *\n * @deprecated Configure skills on the `code_execution` tool instead:\n * `codeExecutionTool(config, { skills })`. The adapter lifts those into\n * `container.skills` and attaches the required beta headers. Setting\n * skills here bypasses the beta-header wiring and may stop working.\n */\n skills: Array<AnthropicContainerSkill> | null\n } | null\n}\n\nexport interface AnthropicContextManagementOptions {\n /**\n * Context management configuration.\n\nThis allows you to control how Claude manages context across multiple requests, such as whether to clear function results or not.\n */\n context_management?: BetaContextManagementConfig | null\n}\n\nexport interface AnthropicMCPOptions {\n /**\n * MCP servers to be utilized in this request\n * Maximum of 20 servers\n */\n mcp_servers?: Array<MCPServer>\n}\n\nexport interface AnthropicServiceTierOptions {\n /**\n * Determines whether to use priority capacity (if available) or standard capacity for this request.\n */\n service_tier?: 'auto' | 'standard_only'\n}\n\nexport interface AnthropicStopSequencesOptions {\n /**\n * Custom text sequences that will cause the model to stop generating.\n\nAnthropic models will normally stop when they have naturally completed their turn, which will result in a response stop_reason of \"end_turn\".\n\nIf you want the model to stop generating when it encounters custom strings of text, you can use the stop_sequences parameter. If the model encounters one of the custom sequences, the response stop_reason value will be \"stop_sequence\" and the response stop_sequence value will contain the matched stop sequence.\n */\n stop_sequences?: Array<string>\n}\n\nexport interface AnthropicThinkingOptions {\n /**\n * Configuration for enabling Claude's extended thinking.\n\nWhen enabled, responses include thinking content blocks showing Claude's thinking process before the final answer. Requires a minimum budget of 1,024 tokens and counts towards your max_tokens limit.\n */\n thinking?:\n | {\n /**\n* Determines how many tokens Claude can use for its internal reasoning process. Larger budgets can enable more thorough analysis for complex problems, improving response quality.\n\nMust be ≥1024 and less than max_tokens\n*/\n budget_tokens: number\n\n type: 'enabled'\n }\n | {\n type: 'disabled'\n }\n}\n\nexport interface AnthropicAdaptiveThinkingOptions {\n /**\n * Configuration for Claude's adaptive thinking (Opus 4.6+).\n *\n * In adaptive mode, Claude dynamically decides when and how much to think.\n * Use the effort parameter to control thinking depth.\n * `thinking: {type: \"enabled\"}` with `budget_tokens` is deprecated on Opus 4.6.\n */\n thinking?:\n | {\n type: 'adaptive'\n /**\n * Controls what (if any) thinking content is streamed back.\n *\n * - `'summarized'`: stream summarized thinking via `thinking_delta`\n * events (the user-visible reasoning text).\n * - `'omitted'`: stream the thinking block's `signature_delta` only\n * (no reasoning text reaches the client).\n *\n * On Claude Opus 4.6 the default is `'summarized'`. On\n * Claude Opus 4.7 the default flipped to `'omitted'` — callers\n * must set `'summarized'` explicitly to get the reasoning text.\n */\n display?: 'summarized' | 'omitted'\n }\n | {\n /**\n * @deprecated Use `type: 'adaptive'` with the effort parameter on Opus 4.6+.\n */\n budget_tokens: number\n type: 'enabled'\n }\n | {\n type: 'disabled'\n }\n}\n\n/**\n * Thinking configuration for models where thinking is always on\n * (e.g. Claude Fable 5).\n *\n * On these models the only accepted explicit configuration is\n * `{type: 'adaptive'}` — both `{type: 'disabled'}` and\n * `{type: 'enabled', budget_tokens}` are rejected with a 400. Omitting the\n * `thinking` field entirely also runs adaptive thinking.\n */\nexport interface AnthropicAdaptiveOnlyThinkingOptions {\n thinking?: {\n type: 'adaptive'\n /**\n * Controls what (if any) thinking content is streamed back.\n *\n * - `'summarized'`: stream summarized thinking via `thinking_delta`\n * events (the user-visible reasoning text).\n * - `'omitted'` (default): stream the thinking block's\n * `signature_delta` only (no reasoning text reaches the client).\n */\n display?: 'summarized' | 'omitted'\n }\n}\n\n/**\n * Thinking configuration for models that accept adaptive thinking or an\n * explicit opt-out, but no manual token budget (e.g. Claude Sonnet 5,\n * Claude Opus 4.7/4.8).\n *\n * `{type: 'enabled', budget_tokens}` is rejected with a 400 on these\n * models. On Claude Sonnet 5, omitting the `thinking` field runs adaptive\n * thinking by default; on Opus 4.7/4.8 it runs without thinking — set\n * `{type: 'adaptive'}` explicitly there.\n */\nexport interface AnthropicAdaptiveOrDisabledThinkingOptions {\n thinking?:\n | {\n type: 'adaptive'\n /**\n * Controls what (if any) thinking content is streamed back.\n * Defaults to `'omitted'` — set `'summarized'` to receive the\n * reasoning text.\n */\n display?: 'summarized' | 'omitted'\n }\n | {\n type: 'disabled'\n }\n}\n\n/**\n * `max_tokens` on its own, for models that reject the sampling parameters\n * (`temperature`, `top_p`, `top_k`) — e.g. Claude Fable 5 and Claude Opus\n * 4.7/4.8 reject them outright, and Claude Sonnet 5 returns a 400 when a\n * non-default sampling value is sent.\n */\nexport interface AnthropicMaxTokensOptions {\n /**\n * The maximum number of tokens to generate before stopping. This parameter only specifies the absolute maximum number of tokens to generate. Required by the API; the adapter defaults to 1024 when omitted.\n * Range x >= 1.\n */\n max_tokens?: number\n}\n\nexport interface AnthropicEffortOptions {\n /**\n * Controls the thinking depth for adaptive thinking mode (Opus 4.6+).\n *\n * - `max`: Absolute highest capability\n * - `high`: Default - Claude will almost always think\n * - `medium`: Balanced cost-quality\n * - `low`: May skip thinking for simpler problems\n */\n effort?: 'max' | 'high' | 'medium' | 'low'\n}\n\nexport interface AnthropicOutputConfigOptions {\n /**\n * Output configuration for the model's response.\n *\n * On Claude 4.7+ the top-level `effort` field was relocated under\n * `output_config.effort`, and `thinking: { type: 'enabled', budget_tokens }`\n * was replaced by `thinking: { type: 'adaptive' }` paired with\n * `output_config.effort`. Earlier models continue to accept the legacy\n * top-level `effort` / `thinking.type: 'enabled'` shape.\n *\n * The engine also writes `output_config.format` here when the caller\n * passes `outputSchema` to a Claude 4.5+ adapter (issue #605 native\n * combined mode). Both fields coexist: user-supplied `effort` is\n * preserved when the engine adds `format`.\n */\n output_config?: {\n /**\n * `'xhigh'` is accepted on Claude Opus 4.7+, Claude Sonnet 5, and\n * Claude Fable 5; older models support `'low'`–`'max'` only.\n */\n effort?: 'low' | 'medium' | 'high' | 'xhigh' | 'max' | null\n }\n}\n\nexport interface AnthropicToolChoiceOptions {\n tool_choice?: BetaToolChoiceAny | BetaToolChoiceTool | BetaToolChoiceAuto\n}\n\nexport interface AnthropicSamplingOptions {\n /**\n * Only sample from the top K options for each subsequent token.\n\nUsed to remove \"long tail\" low probability responses.\nRecommended for advanced use cases only. You usually only need to use temperature.\n\nRequired range: x >= 0\n */\n top_k?: number\n /**\n * Amount of randomness injected into the response.\n * Either use this or top_p, but not both.\n * Defaults to 1.0. Ranges from 0.0 to 1.0. Use temperature closer to 0.0 for analytical / multiple choice, and closer to 1.0 for creative and generative tasks.\n * @default 1.0\n */\n temperature?: number\n /**\n * Use nucleus sampling.\n *\n * In nucleus sampling, we compute the cumulative distribution over all the options for each subsequent token in decreasing probability order and cut it off once it reaches a particular probability specified by top_p. You should either alter temperature or top_p, but not both.\n */\n top_p?: number\n /**\n * The maximum number of tokens to generate before stopping. This parameter only specifies the absolute maximum number of tokens to generate. Required by the API; the adapter defaults to 1024 when omitted.\n * Range x >= 1.\n */\n max_tokens?: number\n}\n\nexport type ExternalTextProviderOptions = AnthropicContainerOptions &\n AnthropicContextManagementOptions &\n AnthropicMCPOptions &\n AnthropicServiceTierOptions &\n AnthropicStopSequencesOptions &\n AnthropicThinkingOptions &\n AnthropicToolChoiceOptions &\n AnthropicSamplingOptions &\n Partial<AnthropicAdaptiveThinkingOptions> &\n Partial<AnthropicEffortOptions> &\n Partial<AnthropicOutputConfigOptions>\n\nexport interface InternalTextProviderOptions extends ExternalTextProviderOptions {\n model: string\n\n messages: Array<MessageParam>\n\n /**\n * The maximum number of tokens to generate before stopping. This parameter only specifies the absolute maximum number of tokens to generate.\n * Range x >= 1.\n */\n max_tokens: number\n /**\n * Whether to incrementally stream the response using server-sent events.\n */\n stream?: boolean\n /**\n * System prompt — built by the adapter from the user-facing\n * `systemPrompts: Array<string>` on the chat call. This field is internal:\n * users should pass system prompts via `systemPrompts`, not via\n * `modelOptions`.\n *\n * A system prompt is a way of providing context and instructions to Claude,\n * such as specifying a particular goal or role.\n */\n system?: string | Array<TextBlockParam>\n\n tools?: Array<AnthropicTool>\n\n /**\n * Schema-constrained final answer in a single Messages request (issue\n * #605). Set by the engine when the adapter declared\n * `supportsCombinedToolsAndSchema` and a caller passed `outputSchema`\n * to `chat()`. The model emits tool calls during the agent loop and a\n * schema-matching JSON message on the natural final turn — no separate\n * finalization round-trip needed.\n *\n * The SDK type (`BetaOutputConfig`) currently exposes only `effort`;\n * `format` is accepted at runtime per the deprecation notice on the\n * older `output_format` field\n * (https://platform.claude.com/docs/en/build-with-claude/structured-outputs).\n * We type it explicitly here so the adapter call site doesn't need a\n * cast.\n */\n output_config?: {\n effort?: 'low' | 'medium' | 'high' | 'xhigh' | 'max' | null\n format?: {\n type: 'json_schema'\n schema: Record<string, unknown>\n }\n }\n}\n\nconst validateTopPandTemperature = (options: InternalTextProviderOptions) => {\n if (options.top_p !== undefined && options.temperature !== undefined) {\n throw new Error('You should either set top_p or temperature, but not both.')\n }\n}\n\nexport interface CacheControl {\n type: 'ephemeral'\n ttl: '5m' | '1h'\n}\n\nconst validateThinking = (options: InternalTextProviderOptions) => {\n const thinking = options.thinking\n if (thinking && thinking.type === 'enabled') {\n if (thinking.budget_tokens < 1024) {\n throw new Error('thinking.budget_tokens must be at least 1024.')\n }\n if (thinking.budget_tokens >= options.max_tokens) {\n throw new Error('thinking.budget_tokens must be less than max_tokens.')\n }\n }\n}\n\ninterface MCPServer {\n name: string\n url: string\n type: 'url'\n authorization_token?: string | null\n tool_configuration: {\n allowed_tools?: Array<string> | null\n enabled?: boolean | null\n } | null\n}\n\nconst validateMaxTokens = (options: InternalTextProviderOptions) => {\n if (options.max_tokens < 1) {\n throw new Error('max_tokens must be at least 1.')\n }\n}\n\nexport const validateTextProviderOptions = (\n options: InternalTextProviderOptions,\n) => {\n validateTopPandTemperature(options)\n validateThinking(options)\n validateMaxTokens(options)\n}\n"],"names":[],"mappings":"AAiWA,MAAM,6BAA6B,CAAC,YAAyC;AAC3E,MAAI,QAAQ,UAAU,UAAa,QAAQ,gBAAgB,QAAW;AACpE,UAAM,IAAI,MAAM,2DAA2D;AAAA,EAC7E;AACF;AAOA,MAAM,mBAAmB,CAAC,YAAyC;AACjE,QAAM,WAAW,QAAQ;AACzB,MAAI,YAAY,SAAS,SAAS,WAAW;AAC3C,QAAI,SAAS,gBAAgB,MAAM;AACjC,YAAM,IAAI,MAAM,+CAA+C;AAAA,IACjE;AACA,QAAI,SAAS,iBAAiB,QAAQ,YAAY;AAChD,YAAM,IAAI,MAAM,sDAAsD;AAAA,IACxE;AAAA,EACF;AACF;AAaA,MAAM,oBAAoB,CAAC,YAAyC;AAClE,MAAI,QAAQ,aAAa,GAAG;AAC1B,UAAM,IAAI,MAAM,gCAAgC;AAAA,EAClD;AACF;AAEO,MAAM,8BAA8B,CACzC,YACG;AACH,6BAA2B,OAAO;AAClC,mBAAiB,OAAO;AACxB,oBAAkB,OAAO;AAC3B;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/ai-anthropic",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "Anthropic Claude adapter for TanStack AI chat, tool calling, thinking, and structured outputs.",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -53,12 +53,12 @@
|
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
55
|
"zod": "^4.0.0",
|
|
56
|
-
"@tanstack/ai": "^0.39.
|
|
56
|
+
"@tanstack/ai": "^0.39.1"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@vitest/coverage-v8": "4.0.14",
|
|
60
60
|
"zod": "^4.2.0",
|
|
61
|
-
"@tanstack/ai": "0.39.
|
|
61
|
+
"@tanstack/ai": "0.39.1"
|
|
62
62
|
},
|
|
63
63
|
"scripts": {
|
|
64
64
|
"build": "vite build",
|
|
@@ -17,7 +17,7 @@ export type AnthropicSummarizeModel = (typeof ANTHROPIC_MODELS)[number]
|
|
|
17
17
|
* Creates an Anthropic summarize adapter with explicit API key.
|
|
18
18
|
* Type resolution happens here at the call site.
|
|
19
19
|
*
|
|
20
|
-
* @param model - The model name (e.g., 'claude-sonnet-
|
|
20
|
+
* @param model - The model name (e.g., 'claude-sonnet-5', 'claude-haiku-4-5')
|
|
21
21
|
* @param apiKey - Your Anthropic API key
|
|
22
22
|
* @param config - Optional additional configuration
|
|
23
23
|
* @returns Configured Anthropic summarize adapter instance with resolved types
|
|
@@ -48,7 +48,7 @@ export function createAnthropicSummarize<
|
|
|
48
48
|
* Creates an Anthropic summarize adapter with automatic API key detection.
|
|
49
49
|
* Type resolution happens here at the call site.
|
|
50
50
|
*
|
|
51
|
-
* @param model - The model name (e.g., 'claude-sonnet-
|
|
51
|
+
* @param model - The model name (e.g., 'claude-sonnet-5', 'claude-haiku-4-5')
|
|
52
52
|
* @param config - Optional configuration (excluding apiKey which is auto-detected)
|
|
53
53
|
* @returns Configured Anthropic summarize adapter instance with resolved types
|
|
54
54
|
*
|
package/src/adapters/text.ts
CHANGED
|
@@ -28,11 +28,14 @@ import type {
|
|
|
28
28
|
ContentBlockParam,
|
|
29
29
|
DocumentBlockParam,
|
|
30
30
|
ImageBlockParam,
|
|
31
|
+
ServerToolUseBlockParam,
|
|
31
32
|
TextBlockParam,
|
|
32
33
|
ThinkingBlockParam,
|
|
33
34
|
ToolUseBlockParam,
|
|
34
35
|
URLImageSource,
|
|
35
36
|
URLPDFSource,
|
|
37
|
+
WebFetchToolResultBlockParam,
|
|
38
|
+
WebSearchToolResultBlockParam,
|
|
36
39
|
} from '@anthropic-ai/sdk/resources/messages'
|
|
37
40
|
import type Anthropic_SDK from '@anthropic-ai/sdk'
|
|
38
41
|
import type { AnthropicBeta } from '@anthropic-ai/sdk/resources/beta/beta'
|
|
@@ -57,6 +60,83 @@ import type {
|
|
|
57
60
|
} from '../message-types'
|
|
58
61
|
import type { AnthropicClientConfig } from '../utils'
|
|
59
62
|
|
|
63
|
+
/**
|
|
64
|
+
* The block type carried by an Anthropic provider-executed (server) tool's
|
|
65
|
+
* stored result. Mirrors the `*_tool_result` block emitted by the streaming
|
|
66
|
+
* API so it can be replayed verbatim into a later turn.
|
|
67
|
+
*/
|
|
68
|
+
type AnthropicServerToolResultBlockType =
|
|
69
|
+
| 'web_search_tool_result'
|
|
70
|
+
| 'web_fetch_tool_result'
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Anthropic payload stashed on a provider-executed tool call's `metadata`
|
|
74
|
+
* (under the `anthropic` key, alongside `providerExecuted: true`). Holds enough
|
|
75
|
+
* to reconstruct the original `server_tool_use` + `*_tool_result` blocks so the
|
|
76
|
+
* model still sees prior `web_search` / `web_fetch` evidence on the next turn.
|
|
77
|
+
*/
|
|
78
|
+
interface AnthropicServerToolMetadata {
|
|
79
|
+
serverToolType: ServerToolUseBlockParam['name']
|
|
80
|
+
resultBlockType: AnthropicServerToolResultBlockType
|
|
81
|
+
/** Raw result block content, preserved verbatim from the stream. */
|
|
82
|
+
result: unknown
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Narrow an opaque tool-call `metadata` to {@link AnthropicServerToolMetadata}
|
|
87
|
+
* when it follows the provider-executed convention, else `null`.
|
|
88
|
+
*/
|
|
89
|
+
function readAnthropicServerToolMetadata(
|
|
90
|
+
metadata: unknown,
|
|
91
|
+
): AnthropicServerToolMetadata | null {
|
|
92
|
+
if (typeof metadata !== 'object' || metadata === null) return null
|
|
93
|
+
const outer = metadata as { providerExecuted?: unknown; anthropic?: unknown }
|
|
94
|
+
if (outer.providerExecuted !== true) return null
|
|
95
|
+
const inner = outer.anthropic
|
|
96
|
+
if (typeof inner !== 'object' || inner === null) return null
|
|
97
|
+
const { serverToolType, resultBlockType, result } = inner as {
|
|
98
|
+
serverToolType?: unknown
|
|
99
|
+
resultBlockType?: unknown
|
|
100
|
+
result?: unknown
|
|
101
|
+
}
|
|
102
|
+
if (
|
|
103
|
+
typeof serverToolType !== 'string' ||
|
|
104
|
+
(resultBlockType !== 'web_search_tool_result' &&
|
|
105
|
+
resultBlockType !== 'web_fetch_tool_result')
|
|
106
|
+
) {
|
|
107
|
+
return null
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
// Validated as a string above; widen back to the SDK's tool-name union.
|
|
111
|
+
serverToolType: serverToolType as ServerToolUseBlockParam['name'],
|
|
112
|
+
resultBlockType,
|
|
113
|
+
result,
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Reconstruct the `*_tool_result` block param from stored server-tool metadata.
|
|
119
|
+
* The `result` content is opaque round-trip data, asserted to the SDK's param
|
|
120
|
+
* content type at this single boundary.
|
|
121
|
+
*/
|
|
122
|
+
function buildServerToolResultBlock(
|
|
123
|
+
toolUseId: string,
|
|
124
|
+
meta: AnthropicServerToolMetadata,
|
|
125
|
+
): WebSearchToolResultBlockParam | WebFetchToolResultBlockParam {
|
|
126
|
+
if (meta.resultBlockType === 'web_search_tool_result') {
|
|
127
|
+
return {
|
|
128
|
+
type: 'web_search_tool_result',
|
|
129
|
+
tool_use_id: toolUseId,
|
|
130
|
+
content: meta.result as WebSearchToolResultBlockParam['content'],
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
type: 'web_fetch_tool_result',
|
|
135
|
+
tool_use_id: toolUseId,
|
|
136
|
+
content: meta.result as WebFetchToolResultBlockParam['content'],
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
60
140
|
/**
|
|
61
141
|
* Computes the `betas` array for a Messages request. Unions:
|
|
62
142
|
* - `interleaved-thinking-2025-05-14` when interleaved thinking is enabled,
|
|
@@ -636,6 +716,25 @@ export class AnthropicTextAdapter<
|
|
|
636
716
|
parsedInput = toolCall.function.arguments
|
|
637
717
|
}
|
|
638
718
|
|
|
719
|
+
// Provider-executed server tools (e.g. web_search) replay as the
|
|
720
|
+
// original `server_tool_use` + result blocks so the model still sees
|
|
721
|
+
// the prior evidence. Their result was captured verbatim during
|
|
722
|
+
// streaming (see processAnthropicStream).
|
|
723
|
+
const serverMeta = readAnthropicServerToolMetadata(toolCall.metadata)
|
|
724
|
+
if (serverMeta) {
|
|
725
|
+
const serverToolUseBlock: ServerToolUseBlockParam = {
|
|
726
|
+
type: 'server_tool_use',
|
|
727
|
+
id: toolCall.id,
|
|
728
|
+
name: serverMeta.serverToolType,
|
|
729
|
+
input: parsedInput,
|
|
730
|
+
}
|
|
731
|
+
contentBlocks.push(serverToolUseBlock)
|
|
732
|
+
contentBlocks.push(
|
|
733
|
+
buildServerToolResultBlock(toolCall.id, serverMeta),
|
|
734
|
+
)
|
|
735
|
+
continue
|
|
736
|
+
}
|
|
737
|
+
|
|
639
738
|
const toolUseBlock: ToolUseBlockParam = {
|
|
640
739
|
type: 'tool_use',
|
|
641
740
|
id: toolCall.id,
|
|
@@ -806,6 +905,14 @@ export class AnthropicTextAdapter<
|
|
|
806
905
|
// input.
|
|
807
906
|
let currentServerTool: { id: string; name: string; input: string } | null =
|
|
808
907
|
null
|
|
908
|
+
// Completed server tools awaiting their matching result block. Anthropic
|
|
909
|
+
// emits `server_tool_use` then a separate `*_tool_result` block; we hold
|
|
910
|
+
// the call here (keyed by id) until the result arrives so we can emit a
|
|
911
|
+
// single provider-executed tool call carrying the raw result for round-trip.
|
|
912
|
+
const completedServerTools = new Map<
|
|
913
|
+
string,
|
|
914
|
+
{ id: string; name: string; input: string }
|
|
915
|
+
>()
|
|
809
916
|
|
|
810
917
|
// AG-UI lifecycle tracking
|
|
811
918
|
const runId = options.runId ?? genId()
|
|
@@ -881,6 +988,61 @@ export class AnthropicTextAdapter<
|
|
|
881
988
|
},
|
|
882
989
|
)
|
|
883
990
|
}
|
|
991
|
+
|
|
992
|
+
// Emit the server tool as a single provider-executed tool call,
|
|
993
|
+
// carrying its raw result so the evidence (e.g. web_search sources)
|
|
994
|
+
// round-trips into the next turn's request. The agent loop skips
|
|
995
|
+
// provider-executed calls, so this never triggers client execution.
|
|
996
|
+
const serverTool = completedServerTools.get(
|
|
997
|
+
event.content_block.tool_use_id,
|
|
998
|
+
)
|
|
999
|
+
if (serverTool) {
|
|
1000
|
+
completedServerTools.delete(serverTool.id)
|
|
1001
|
+
|
|
1002
|
+
let parsedInput: unknown = {}
|
|
1003
|
+
try {
|
|
1004
|
+
const parsed = serverTool.input
|
|
1005
|
+
? JSON.parse(serverTool.input)
|
|
1006
|
+
: {}
|
|
1007
|
+
parsedInput = parsed && typeof parsed === 'object' ? parsed : {}
|
|
1008
|
+
} catch {
|
|
1009
|
+
parsedInput = {}
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
const serverToolMetadata = {
|
|
1013
|
+
providerExecuted: true,
|
|
1014
|
+
anthropic: {
|
|
1015
|
+
serverToolType: serverTool.name,
|
|
1016
|
+
resultBlockType: event.content_block.type,
|
|
1017
|
+
result: content,
|
|
1018
|
+
},
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
currentToolIndex++
|
|
1022
|
+
yield {
|
|
1023
|
+
type: EventType.TOOL_CALL_START,
|
|
1024
|
+
toolCallId: serverTool.id,
|
|
1025
|
+
toolCallName: serverTool.name,
|
|
1026
|
+
toolName: serverTool.name,
|
|
1027
|
+
parentMessageId: messageId,
|
|
1028
|
+
model,
|
|
1029
|
+
timestamp: Date.now(),
|
|
1030
|
+
index: currentToolIndex,
|
|
1031
|
+
metadata: serverToolMetadata,
|
|
1032
|
+
}
|
|
1033
|
+
yield {
|
|
1034
|
+
type: EventType.TOOL_CALL_END,
|
|
1035
|
+
toolCallId: serverTool.id,
|
|
1036
|
+
toolCallName: serverTool.name,
|
|
1037
|
+
toolName: serverTool.name,
|
|
1038
|
+
model,
|
|
1039
|
+
timestamp: Date.now(),
|
|
1040
|
+
input: parsedInput,
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
// Text after the server tool starts a fresh message segment.
|
|
1044
|
+
hasEmittedTextMessageStart = false
|
|
1045
|
+
}
|
|
884
1046
|
} else if (event.content_block.type === 'thinking') {
|
|
885
1047
|
accumulatedThinking = ''
|
|
886
1048
|
accumulatedSignature = ''
|
|
@@ -1095,6 +1257,9 @@ export class AnthropicTextAdapter<
|
|
|
1095
1257
|
input: currentServerTool.input,
|
|
1096
1258
|
},
|
|
1097
1259
|
)
|
|
1260
|
+
// Hold the call until its result block arrives so we can emit
|
|
1261
|
+
// both together as one provider-executed tool call.
|
|
1262
|
+
completedServerTools.set(currentServerTool.id, currentServerTool)
|
|
1098
1263
|
}
|
|
1099
1264
|
currentServerTool = null
|
|
1100
1265
|
} else if (
|