@ai-sdk/anthropic 4.0.92 → 4.0.94

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/index.js CHANGED
@@ -64,6 +64,330 @@ var AnthropicFiles = class {
64
64
  }
65
65
  };
66
66
  //#endregion
67
+ //#region src/anthropic-model-catalog.ts
68
+ /**
69
+ * Options accepted under `providerOptions.anthropic`. The `satisfies` check
70
+ * keeps this list in sync with the option schema.
71
+ */
72
+ const anthropicProviderOptions = { language: {
73
+ sendReasoning: { description: "Whether to send reasoning to the model." },
74
+ structuredOutputMode: { description: "How structured outputs are generated." },
75
+ thinking: { description: "Extended thinking configuration." },
76
+ disableParallelToolUse: { description: "Use at most one tool per response." },
77
+ cacheControl: { description: "Prompt cache control settings." },
78
+ metadata: { description: "Request metadata, such as a user ID." },
79
+ mcpServers: { description: "MCP servers to use in the request." },
80
+ container: { description: "Container and Agent Skills configuration." },
81
+ toolStreaming: { description: "Fine-grained streaming of tool inputs and outputs." },
82
+ effort: { description: "Effort spent on thinking, text, and tool calls." },
83
+ taskBudget: { description: "Advisory token budget for an agentic task." },
84
+ speed: { description: "Fast mode for faster output token speeds." },
85
+ serviceTier: { description: "Service tier for the request." },
86
+ inferenceGeo: { description: "Where model inference runs." },
87
+ fallbacks: { description: "Server-side fallback models." },
88
+ anthropicBeta: { description: "Additional beta features to enable." },
89
+ safeguards: { description: "Server-side safeguards to run." },
90
+ compaction: { description: "On-demand conversation summary." },
91
+ contextManagement: { description: "Server-side context management." }
92
+ } };
93
+ const legacyClaude = defineRuntime({});
94
+ const currentClaude = defineRuntime({
95
+ maxOutputTokens: 128e3,
96
+ nativeStructuredOutput: true,
97
+ adaptiveThinking: true
98
+ });
99
+ const currentClaudeWithoutSampling = defineRuntime({
100
+ ...currentClaude,
101
+ samplingParameters: false,
102
+ xhighEffort: true
103
+ });
104
+ function defineRuntime(overrides) {
105
+ return {
106
+ maxOutputTokens: 4096,
107
+ nativeStructuredOutput: false,
108
+ adaptiveThinking: false,
109
+ samplingParameters: true,
110
+ xhighEffort: false,
111
+ thinkingCanBeDisabledAboveHighEffort: true,
112
+ thinkingCanBeDisabled: true,
113
+ budgetThinking: true,
114
+ forcedToolUse: true,
115
+ betweenToolsThinking: false,
116
+ knownModel: true,
117
+ ...overrides
118
+ };
119
+ }
120
+ const runtimeRules = [
121
+ {
122
+ matches: (modelId) => modelId.includes("claude-sonnet-5-5"),
123
+ definition: defineRuntime({
124
+ ...currentClaudeWithoutSampling,
125
+ thinkingCanBeDisabledAboveHighEffort: false,
126
+ thinkingCanBeDisabled: false,
127
+ budgetThinking: false,
128
+ forcedToolUse: false,
129
+ betweenToolsThinking: true
130
+ })
131
+ },
132
+ {
133
+ matches: (modelId) => modelId.includes("claude-opus-5-5"),
134
+ definition: defineRuntime({
135
+ ...currentClaudeWithoutSampling,
136
+ thinkingCanBeDisabledAboveHighEffort: false,
137
+ thinkingCanBeDisabled: false,
138
+ budgetThinking: false,
139
+ forcedToolUse: false
140
+ })
141
+ },
142
+ {
143
+ matches: (modelId) => modelId.includes("claude-haiku-5-5"),
144
+ definition: defineRuntime({
145
+ ...currentClaudeWithoutSampling,
146
+ thinkingCanBeDisabledAboveHighEffort: false,
147
+ budgetThinking: false
148
+ })
149
+ },
150
+ {
151
+ matches: (modelId) => modelId.includes("claude-opus-5"),
152
+ definition: defineRuntime({
153
+ ...currentClaudeWithoutSampling,
154
+ thinkingCanBeDisabledAboveHighEffort: false
155
+ })
156
+ },
157
+ {
158
+ matches: (modelId) => modelId.includes("claude-fable-5-1"),
159
+ definition: defineRuntime({
160
+ ...currentClaudeWithoutSampling,
161
+ thinkingCanBeDisabled: false,
162
+ budgetThinking: false,
163
+ forcedToolUse: false
164
+ })
165
+ },
166
+ {
167
+ matches: (modelId) => modelId.includes("claude-fable-5"),
168
+ definition: defineRuntime({
169
+ ...currentClaudeWithoutSampling,
170
+ thinkingCanBeDisabled: false,
171
+ budgetThinking: false
172
+ })
173
+ },
174
+ {
175
+ matches: (modelId) => modelId.includes("claude-opus-4-8") || modelId.includes("claude-opus-4-7") || modelId.includes("claude-sonnet-5"),
176
+ definition: currentClaudeWithoutSampling
177
+ },
178
+ {
179
+ matches: (modelId) => modelId.includes("claude-sonnet-4-6") || modelId.includes("claude-opus-4-6"),
180
+ definition: currentClaude
181
+ },
182
+ {
183
+ matches: (modelId) => modelId.includes("claude-sonnet-4-5") || modelId.includes("claude-opus-4-5") || modelId.includes("claude-haiku-4-5"),
184
+ definition: defineRuntime({
185
+ maxOutputTokens: 64e3,
186
+ nativeStructuredOutput: true
187
+ })
188
+ },
189
+ {
190
+ matches: (modelId) => modelId.includes("claude-opus-4-1"),
191
+ definition: defineRuntime({
192
+ maxOutputTokens: 32e3,
193
+ nativeStructuredOutput: true
194
+ })
195
+ },
196
+ {
197
+ matches: (modelId) => /claude-sonnet-4(?:-|@)/.test(modelId),
198
+ definition: defineRuntime({ maxOutputTokens: 64e3 })
199
+ },
200
+ {
201
+ matches: (modelId) => /claude-opus-4(?:-|@)/.test(modelId),
202
+ definition: defineRuntime({ maxOutputTokens: 32e3 })
203
+ },
204
+ {
205
+ matches: (modelId) => modelId.includes("claude-3-haiku"),
206
+ definition: legacyClaude
207
+ },
208
+ {
209
+ matches: (modelId) => /claude-(?:instant(?:-|$)|v?2(?=$|[-.:])|3(?=$|[-.]))/.test(modelId),
210
+ definition: defineRuntime({ knownModel: false })
211
+ }
212
+ ];
213
+ const anthropicModelCatalog = Object.fromEntries(Object.entries({
214
+ "claude-opus-5-5": {
215
+ toolSearch: true,
216
+ compaction: true,
217
+ effort: true
218
+ },
219
+ "claude-opus-5": {
220
+ toolSearch: true,
221
+ compaction: true,
222
+ effort: true
223
+ },
224
+ "claude-sonnet-5-5": {
225
+ toolSearch: true,
226
+ compaction: true,
227
+ effort: true
228
+ },
229
+ "claude-sonnet-5": {
230
+ toolSearch: true,
231
+ compaction: true,
232
+ effort: true
233
+ },
234
+ "claude-haiku-5-5": {
235
+ toolSearch: true,
236
+ compaction: true,
237
+ effort: true
238
+ },
239
+ "claude-fable-5-1": {
240
+ toolSearch: true,
241
+ compaction: true,
242
+ effort: true
243
+ },
244
+ "claude-fable-5": {
245
+ toolSearch: true,
246
+ compaction: true,
247
+ effort: true
248
+ },
249
+ "claude-opus-4-8": {
250
+ toolSearch: true,
251
+ compaction: true,
252
+ effort: true
253
+ },
254
+ "claude-opus-4-7": {
255
+ toolSearch: true,
256
+ compaction: true,
257
+ effort: true
258
+ },
259
+ "claude-opus-4-6": {
260
+ toolSearch: true,
261
+ compaction: true,
262
+ effort: true
263
+ },
264
+ "claude-sonnet-4-6": {
265
+ toolSearch: true,
266
+ compaction: true,
267
+ effort: true
268
+ },
269
+ "claude-opus-4-5": {
270
+ toolSearch: true,
271
+ compaction: false,
272
+ effort: true
273
+ },
274
+ "claude-haiku-4-5": {
275
+ toolSearch: true,
276
+ compaction: false,
277
+ effort: false
278
+ },
279
+ "claude-sonnet-4-5": {
280
+ toolSearch: true,
281
+ compaction: false,
282
+ effort: false
283
+ },
284
+ "claude-opus-4-1": {
285
+ toolSearch: false,
286
+ compaction: false,
287
+ effort: false
288
+ },
289
+ "claude-opus-4-0": {
290
+ toolSearch: false,
291
+ compaction: false,
292
+ effort: false
293
+ },
294
+ "claude-sonnet-4-0": {
295
+ toolSearch: false,
296
+ compaction: false,
297
+ effort: false
298
+ }
299
+ }).map(([modelId, capabilities]) => [modelId, createAnthropicLanguageModelEntry(modelId, capabilities)]));
300
+ function getAnthropicLanguageModelEntry(modelId) {
301
+ return Object.prototype.hasOwnProperty.call(anthropicModelCatalog, modelId) ? anthropicModelCatalog[modelId] : createAnthropicLanguageModelEntry(modelId);
302
+ }
303
+ function createAnthropicLanguageModelEntry(modelId, documented) {
304
+ const runtime = resolveRuntimeDefinition(modelId);
305
+ const declared = documented != null;
306
+ const samplingSupport = runtime.samplingParameters ? true : { condition: "Only supported when thinking is disabled." };
307
+ const reasoningSupport = runtime.adaptiveThinking || runtime.budgetThinking;
308
+ return {
309
+ capabilities: { language: {
310
+ inputs: {
311
+ image: declared ? true : "unknown",
312
+ audio: declared ? false : "unknown"
313
+ },
314
+ objectGeneration: declared ? true : "unknown",
315
+ tools: {
316
+ usage: declared ? true : "unknown",
317
+ streaming: declared ? true : "unknown",
318
+ forcedChoice: runtime.forcedToolUse,
319
+ computerUse: declared ? true : "unknown",
320
+ webSearch: declared ? true : "unknown",
321
+ toolSearch: documented?.toolSearch ?? "unknown"
322
+ },
323
+ reasoning: {
324
+ support: reasoningSupport,
325
+ efforts: runtime.xhighEffort ? [
326
+ "low",
327
+ "medium",
328
+ "high",
329
+ "xhigh",
330
+ "max"
331
+ ] : void 0,
332
+ adaptive: runtime.adaptiveThinking,
333
+ budget: runtime.budgetThinking,
334
+ canDisable: runtime.thinkingCanBeDisabled,
335
+ canDisableAboveHighEffort: runtime.thinkingCanBeDisabledAboveHighEffort,
336
+ supportsXhighEffort: runtime.xhighEffort,
337
+ betweenTools: runtime.betweenToolsThinking
338
+ },
339
+ sampling: {
340
+ temperature: samplingSupport,
341
+ topP: samplingSupport,
342
+ topK: samplingSupport,
343
+ logprobs: false
344
+ },
345
+ structuredOutput: { native: runtime.nativeStructuredOutput },
346
+ compaction: documented?.compaction ?? "unknown"
347
+ } },
348
+ providerOptions: { language: declareProviderOptions(anthropicProviderOptions.language, declared ? true : "unknown", {
349
+ thinking: reasoningSupport,
350
+ effort: documented?.effort ?? "unknown",
351
+ speed: declared ? modelId === "claude-opus-4-6" : "unknown",
352
+ taskBudget: modelId === "claude-opus-4-7" ? true : "unknown"
353
+ }) },
354
+ requestConfig: { language: {
355
+ maxOutputTokens: runtime.maxOutputTokens,
356
+ knownModel: runtime.knownModel
357
+ } }
358
+ };
359
+ }
360
+ /** Applies one default support value to every option, except the listed ones. */
361
+ function declareProviderOptions(definitions, support, exceptions) {
362
+ return Object.fromEntries(Object.keys(definitions).map((option) => [option, exceptions[option] ?? support]));
363
+ }
364
+ function resolveRuntimeDefinition(modelId) {
365
+ const rule = runtimeRules.find((rule) => rule.matches(modelId));
366
+ if (rule != null) return rule.definition;
367
+ return modelId.includes("claude-") ? defineRuntime({
368
+ ...currentClaudeWithoutSampling,
369
+ thinkingCanBeDisabledAboveHighEffort: false,
370
+ knownModel: false
371
+ }) : defineRuntime({ knownModel: false });
372
+ }
373
+ /** Compatibility projection for the provider's existing request preparation. */
374
+ function getAnthropicModelCapabilities(modelId) {
375
+ const { capabilities: { language }, requestConfig: { language: requestConfig } } = getAnthropicLanguageModelEntry(modelId);
376
+ return {
377
+ maxOutputTokens: requestConfig.maxOutputTokens,
378
+ supportsStructuredOutput: language.structuredOutput.native,
379
+ supportsAdaptiveThinking: language.reasoning.adaptive,
380
+ rejectsSamplingParameters: language.sampling.temperature !== true,
381
+ supportsXhighEffort: language.reasoning.supportsXhighEffort,
382
+ rejectsThinkingDisabledAboveHighEffort: !language.reasoning.canDisableAboveHighEffort,
383
+ rejectsThinkingDisabled: !language.reasoning.canDisable,
384
+ rejectsBudgetThinking: !language.reasoning.budget,
385
+ rejectsForcedToolUse: !language.tools.forcedChoice,
386
+ supportsBetweenToolsThinking: language.reasoning.betweenTools,
387
+ isKnownModel: requestConfig.knownModel
388
+ };
389
+ }
390
+ //#endregion
67
391
  //#region src/map-anthropic-citation.ts
68
392
  function mapAnthropicCitation(citation, documents) {
69
393
  if (citation.type === "web_search_result_location" || citation.type === "search_result_location") {
@@ -3376,8 +3700,10 @@ function sanitizeDefinition(definition) {
3376
3700
  }
3377
3701
  function sanitizeSchema(schema) {
3378
3702
  const result = {};
3379
- const schemaWithDefs = schema;
3380
- if (schema.$ref != null) return { $ref: schema.$ref };
3703
+ if (schema.$ref != null) return {
3704
+ $ref: schema.$ref,
3705
+ ...sanitizeSchemaDefinitions(schema)
3706
+ };
3381
3707
  if (schema.$schema != null) result.$schema = schema.$schema;
3382
3708
  if (schema.$id != null) result.$id = schema.$id;
3383
3709
  if (schema.title != null) result.title = schema.title;
@@ -3389,11 +3715,7 @@ function sanitizeSchema(schema) {
3389
3715
  if (schema.anyOf != null) result.anyOf = schema.anyOf.map(sanitizeDefinition);
3390
3716
  else if (schema.oneOf != null) result.anyOf = schema.oneOf.map(sanitizeDefinition);
3391
3717
  if (schema.allOf != null) result.allOf = schema.allOf.map(sanitizeDefinition);
3392
- if (schema.definitions != null) result.definitions = Object.fromEntries(Object.entries(schema.definitions).map(([name, definition]) => [name, sanitizeDefinition(definition)]));
3393
- if (schemaWithDefs.$defs != null) {
3394
- const resultWithDefs = result;
3395
- resultWithDefs.$defs = Object.fromEntries(Object.entries(schemaWithDefs.$defs).map(([name, definition]) => [name, sanitizeDefinition(definition)]));
3396
- }
3718
+ Object.assign(result, sanitizeSchemaDefinitions(schema));
3397
3719
  if (schema.type === "object" || schema.properties != null) {
3398
3720
  if (schema.properties != null) result.properties = Object.fromEntries(Object.entries(schema.properties).map(([name, definition]) => [name, sanitizeDefinition(definition)]));
3399
3721
  result.additionalProperties = false;
@@ -3405,6 +3727,14 @@ function sanitizeSchema(schema) {
3405
3727
  if (constraintDescription != null) result.description = result.description == null ? constraintDescription : `${result.description}\n${constraintDescription}`;
3406
3728
  return result;
3407
3729
  }
3730
+ function sanitizeSchemaDefinitions(schema) {
3731
+ const { $defs } = schema;
3732
+ const sanitizeAll = (definitions) => Object.fromEntries(Object.entries(definitions).map(([name, definition]) => [name, sanitizeDefinition(definition)]));
3733
+ return {
3734
+ ...schema.definitions != null && { definitions: sanitizeAll(schema.definitions) },
3735
+ ...$defs != null && { $defs: sanitizeAll($defs) }
3736
+ };
3737
+ }
3408
3738
  function getConstraintDescription(schema) {
3409
3739
  const descriptions = DESCRIPTION_CONSTRAINT_KEYS.flatMap((key) => {
3410
3740
  const value = schema[key];
@@ -3422,6 +3752,155 @@ function formatConstraintValue(value) {
3422
3752
  return JSON.stringify(value);
3423
3753
  }
3424
3754
  //#endregion
3755
+ //#region src/has-circular-schema-reference.ts
3756
+ const SCHEMA_MAP_KEYWORDS = /* @__PURE__ */ new Set([
3757
+ "dependentSchemas",
3758
+ "patternProperties",
3759
+ "properties"
3760
+ ]);
3761
+ const DATA_KEYWORDS = /* @__PURE__ */ new Set([
3762
+ "const",
3763
+ "default",
3764
+ "enum",
3765
+ "examples"
3766
+ ]);
3767
+ /**
3768
+ * Whether a JSON schema contains a cycle of local `$ref`s, e.g. a tree node
3769
+ * whose children reference the node itself.
3770
+ *
3771
+ * Anthropic's native structured outputs reject such schemas, while the JSON
3772
+ * response tool accepts them.
3773
+ */
3774
+ function hasCircularSchemaReference(schema) {
3775
+ const visiting = /* @__PURE__ */ new Set();
3776
+ const visited = /* @__PURE__ */ new Set();
3777
+ const visit = (pointer) => {
3778
+ if (visiting.has(pointer)) return true;
3779
+ if (visited.has(pointer)) return false;
3780
+ const target = resolveSchemaPointer(schema, pointer);
3781
+ if (target === void 0) return false;
3782
+ visiting.add(pointer);
3783
+ const isCircular = collectLocalRefs(target).some(visit);
3784
+ visiting.delete(pointer);
3785
+ visited.add(pointer);
3786
+ return isCircular;
3787
+ };
3788
+ return visit("#");
3789
+ }
3790
+ function collectLocalRefs(node, refs = []) {
3791
+ if (Array.isArray(node)) {
3792
+ for (const item of node) collectLocalRefs(item, refs);
3793
+ return refs;
3794
+ }
3795
+ if (!isRecord(node)) return refs;
3796
+ for (const [key, value] of Object.entries(node)) if (key === "$ref") {
3797
+ if (typeof value === "string" && value.startsWith("#")) refs.push(value);
3798
+ } else if (SCHEMA_MAP_KEYWORDS.has(key) && isRecord(value)) for (const subschema of Object.values(value)) collectLocalRefs(subschema, refs);
3799
+ else if (key !== "$defs" && key !== "definitions" && !DATA_KEYWORDS.has(key)) collectLocalRefs(value, refs);
3800
+ return refs;
3801
+ }
3802
+ function resolveSchemaPointer(schema, pointer) {
3803
+ if (pointer === "#") return schema;
3804
+ if (!pointer.startsWith("#/")) return;
3805
+ let decodedPointer;
3806
+ try {
3807
+ decodedPointer = decodeURIComponent(pointer.slice(2));
3808
+ } catch {
3809
+ return;
3810
+ }
3811
+ let current = schema;
3812
+ for (const rawSegment of decodedPointer.split("/")) {
3813
+ const segment = rawSegment.replace(/~1/g, "/").replace(/~0/g, "~");
3814
+ if (Array.isArray(current)) current = current[Number(segment)];
3815
+ else if (isRecord(current)) current = current[segment];
3816
+ else return;
3817
+ }
3818
+ return current;
3819
+ }
3820
+ //#endregion
3821
+ //#region src/supports-native-structured-output-schema.ts
3822
+ const MAX_OPTIONAL_PROPERTIES = 10;
3823
+ const SUBSCHEMA_KEYWORDS = [
3824
+ "additionalProperties",
3825
+ "contains",
3826
+ "else",
3827
+ "if",
3828
+ "items",
3829
+ "not",
3830
+ "then"
3831
+ ];
3832
+ const SUBSCHEMA_LIST_KEYWORDS = [
3833
+ "allOf",
3834
+ "anyOf",
3835
+ "oneOf",
3836
+ "prefixItems"
3837
+ ];
3838
+ const SUBSCHEMA_MAP_KEYWORDS = [
3839
+ "dependentSchemas",
3840
+ "patternProperties",
3841
+ "properties"
3842
+ ];
3843
+ /**
3844
+ * Whether Anthropic's native structured outputs (`output_config.format`) can
3845
+ * represent a schema without rejecting it or losing data.
3846
+ *
3847
+ * Rejected: self-referencing schemas, and schemas with too many optional
3848
+ * properties. Lossy: open objects (maps, free-form objects), which native
3849
+ * structured outputs close with `additionalProperties: false`, so the model
3850
+ * can only return `{}` for them.
3851
+ */
3852
+ function supportsNativeStructuredOutputSchema(schema) {
3853
+ if (hasCircularSchemaReference(schema)) return false;
3854
+ const { optionalProperties, hasOpenObject } = getSchemaStats(schema, schema, /* @__PURE__ */ new Map());
3855
+ return !hasOpenObject && optionalProperties <= MAX_OPTIONAL_PROPERTIES;
3856
+ }
3857
+ function getSchemaStats(node, root, refStats) {
3858
+ const stats = {
3859
+ optionalProperties: 0,
3860
+ hasOpenObject: false
3861
+ };
3862
+ if (!isRecord(node)) return stats;
3863
+ const add = (child) => {
3864
+ const childStats = getSchemaStats(child, root, refStats);
3865
+ stats.optionalProperties += childStats.optionalProperties;
3866
+ stats.hasOpenObject ||= childStats.hasOpenObject;
3867
+ };
3868
+ if (typeof node.$ref === "string" && node.$ref.startsWith("#")) {
3869
+ let resolved = refStats.get(node.$ref);
3870
+ if (resolved == null) {
3871
+ resolved = getSchemaStats(resolveSchemaPointer(root, node.$ref), root, refStats);
3872
+ refStats.set(node.$ref, resolved);
3873
+ }
3874
+ stats.optionalProperties += resolved.optionalProperties;
3875
+ stats.hasOpenObject ||= resolved.hasOpenObject;
3876
+ }
3877
+ if (isOpenObject(node)) stats.hasOpenObject = true;
3878
+ if (isRecord(node.properties)) {
3879
+ const required = new Set(Array.isArray(node.required) ? node.required : []);
3880
+ stats.optionalProperties += Object.keys(node.properties).filter((name) => !required.has(name)).length;
3881
+ }
3882
+ for (const keyword of SUBSCHEMA_KEYWORDS) {
3883
+ const value = node[keyword];
3884
+ if (Array.isArray(value)) value.forEach(add);
3885
+ else add(value);
3886
+ }
3887
+ for (const keyword of SUBSCHEMA_LIST_KEYWORDS) {
3888
+ const value = node[keyword];
3889
+ if (Array.isArray(value)) value.forEach(add);
3890
+ }
3891
+ for (const keyword of SUBSCHEMA_MAP_KEYWORDS) {
3892
+ const value = node[keyword];
3893
+ if (isRecord(value)) Object.values(value).forEach(add);
3894
+ }
3895
+ return stats;
3896
+ }
3897
+ function isOpenObject(node) {
3898
+ const { additionalProperties, patternProperties, properties, type } = node;
3899
+ if (additionalProperties === true || isRecord(additionalProperties)) return true;
3900
+ if (isRecord(patternProperties) && Object.keys(patternProperties).length > 0) return true;
3901
+ return (type === "object" || Array.isArray(type) && type.includes("object")) && properties == null && additionalProperties !== false;
3902
+ }
3903
+ //#endregion
3425
3904
  //#region src/anthropic-language-model.ts
3426
3905
  function createAnthropicStreamError(error) {
3427
3906
  const inferredMetadata = getAnthropicStreamErrorMetadata(error.type);
@@ -3540,6 +4019,28 @@ function getProviderOptionsName(provider) {
3540
4019
  const dotIndex = provider.indexOf(".");
3541
4020
  return dotIndex === -1 ? provider : provider.substring(0, dotIndex);
3542
4021
  }
4022
+ const TEXT_OR_THINKING_BLOCK_TYPES = /* @__PURE__ */ new Set([
4023
+ "redacted_thinking",
4024
+ "text",
4025
+ "thinking"
4026
+ ]);
4027
+ function isContinuationStopReason(stopReason) {
4028
+ return stopReason === "pause_turn" || stopReason === "tool_use";
4029
+ }
4030
+ /**
4031
+ * Text parts to return when the JSON response tool is in use: the text after
4032
+ * the last tool call or result, and only if the tool was never called.
4033
+ */
4034
+ function getJsonResponseToolFallbackText(content, stopReason) {
4035
+ const text = /* @__PURE__ */ new Set();
4036
+ if (isContinuationStopReason(stopReason)) return text;
4037
+ for (const part of content) {
4038
+ if (part.type === "tool_use" && part.name === "json") return /* @__PURE__ */ new Set();
4039
+ if (part.type === "text") text.add(part);
4040
+ else if (!TEXT_OR_THINKING_BLOCK_TYPES.has(part.type)) text.clear();
4041
+ }
4042
+ return text;
4043
+ }
3543
4044
  var AnthropicLanguageModel = class AnthropicLanguageModel {
3544
4045
  static [WORKFLOW_SERIALIZE](model) {
3545
4046
  return serializeModelOptions({
@@ -3616,7 +4117,7 @@ var AnthropicLanguageModel = class AnthropicLanguageModel {
3616
4117
  }) : null;
3617
4118
  const usedCustomProviderKey = customProviderOptions != null;
3618
4119
  const anthropicOptions = Object.assign({}, canonicalOptions ?? {}, customProviderOptions ?? {});
3619
- const { maxOutputTokens: maxOutputTokensForModel, supportsStructuredOutput: modelSupportsStructuredOutput, supportsAdaptiveThinking, rejectsSamplingParameters, supportsXhighEffort, rejectsThinkingDisabledAboveHighEffort, rejectsThinkingDisabled, rejectsBudgetThinking, rejectsForcedToolUse, supportsBetweenToolsThinking, isKnownModel } = getModelCapabilities(modelId);
4120
+ const { maxOutputTokens: maxOutputTokensForModel, supportsStructuredOutput: modelSupportsStructuredOutput, supportsAdaptiveThinking, rejectsSamplingParameters, supportsXhighEffort, rejectsThinkingDisabledAboveHighEffort, rejectsThinkingDisabled, rejectsBudgetThinking, rejectsForcedToolUse, supportsBetweenToolsThinking, isKnownModel } = getAnthropicModelCapabilities(modelId);
3620
4121
  if (!isKnownModel && maxOutputTokens == null) warnings.push({
3621
4122
  type: "compatibility",
3622
4123
  feature: "maxOutputTokens",
@@ -3653,7 +4154,7 @@ var AnthropicLanguageModel = class AnthropicLanguageModel {
3653
4154
  const supportsStrictTools = (config.supportsStrictTools ?? true) && modelSupportsStructuredOutput;
3654
4155
  const structureOutputMode = anthropicOptions?.structuredOutputMode ?? "auto";
3655
4156
  let useStructuredOutput = structureOutputMode === "outputFormat" || structureOutputMode === "auto" && supportsStructuredOutput;
3656
- if (!useStructuredOutput && rejectsForcedToolUse && supportsStructuredOutput && responseFormat?.type === "json" && responseFormat.schema != null) {
4157
+ if (!useStructuredOutput && rejectsForcedToolUse && modelSupportsStructuredOutput && responseFormat?.type === "json" && responseFormat.schema != null && supportsNativeStructuredOutputSchema(responseFormat.schema)) {
3657
4158
  warnings.push({
3658
4159
  type: "unsupported",
3659
4160
  feature: "providerOptions.anthropic.structuredOutputMode",
@@ -4060,9 +4561,10 @@ var AnthropicLanguageModel = class AnthropicLanguageModel {
4060
4561
  const serverToolCalls = {};
4061
4562
  let isJsonResponseFromTool = false;
4062
4563
  const hasWebSearchResults = response.content.some((part) => part.type === "web_search_tool_result" && Array.isArray(part.content) && part.content.length > 0);
4564
+ const jsonResponseToolFallbackText = usesJsonResponseTool ? getJsonResponseToolFallbackText(response.content, response.stop_reason) : void 0;
4063
4565
  for (const part of response.content) switch (part.type) {
4064
4566
  case "text":
4065
- if (!usesJsonResponseTool) {
4567
+ if (jsonResponseToolFallbackText == null || jsonResponseToolFallbackText.has(part)) {
4066
4568
  const citations = part.citations ?? [];
4067
4569
  content.push({
4068
4570
  type: "text",
@@ -4500,6 +5002,16 @@ var AnthropicLanguageModel = class AnthropicLanguageModel {
4500
5002
  let safeguardResults;
4501
5003
  let container = null;
4502
5004
  let isJsonResponseFromTool = false;
5005
+ const heldBackText = [];
5006
+ const heldBackTextByIndex = /* @__PURE__ */ new Map();
5007
+ const createTextEnd = (id, citations) => ({
5008
+ type: "text-end",
5009
+ id,
5010
+ ...citations.length > 0 && {
5011
+ citations: citations.map((citation) => mapAnthropicCitation(citation, citationDocuments)),
5012
+ providerMetadata: { anthropic: { citations } }
5013
+ }
5014
+ });
4503
5015
  let hasWebSearchResults = false;
4504
5016
  const fallbackWebCitations = [];
4505
5017
  let isMessageOpen = false;
@@ -4546,9 +5058,19 @@ var AnthropicLanguageModel = class AnthropicLanguageModel {
4546
5058
  return;
4547
5059
  }
4548
5060
  blockType = contentBlockType;
5061
+ if (!TEXT_OR_THINKING_BLOCK_TYPES.has(contentBlockType)) heldBackText.length = 0;
4549
5062
  switch (contentBlockType) {
4550
5063
  case "text":
4551
- if (usesJsonResponseTool) return;
5064
+ if (usesJsonResponseTool) {
5065
+ const entry = {
5066
+ id: String(value.index),
5067
+ text: "",
5068
+ citations: []
5069
+ };
5070
+ heldBackText.push(entry);
5071
+ heldBackTextByIndex.set(value.index, entry);
5072
+ return;
5073
+ }
4552
5074
  contentBlocks[value.index] = {
4553
5075
  type: "text",
4554
5076
  citations: []
@@ -4934,14 +5456,7 @@ var AnthropicLanguageModel = class AnthropicLanguageModel {
4934
5456
  const contentBlock = contentBlocks[value.index];
4935
5457
  switch (contentBlock.type) {
4936
5458
  case "text":
4937
- controller.enqueue({
4938
- type: "text-end",
4939
- id: String(value.index),
4940
- ...contentBlock.citations.length > 0 && {
4941
- citations: contentBlock.citations.map((citation) => mapAnthropicCitation(citation, citationDocuments)),
4942
- providerMetadata: { anthropic: { citations: contentBlock.citations } }
4943
- }
4944
- });
5459
+ controller.enqueue(createTextEnd(String(value.index), contentBlock.citations));
4945
5460
  break;
4946
5461
  case "reasoning":
4947
5462
  controller.enqueue({
@@ -5001,7 +5516,11 @@ var AnthropicLanguageModel = class AnthropicLanguageModel {
5001
5516
  const deltaType = value.delta.type;
5002
5517
  switch (deltaType) {
5003
5518
  case "text_delta":
5004
- if (usesJsonResponseTool) return;
5519
+ if (usesJsonResponseTool) {
5520
+ const entry = heldBackTextByIndex.get(value.index);
5521
+ if (entry != null) entry.text += value.delta.text;
5522
+ return;
5523
+ }
5005
5524
  controller.enqueue({
5006
5525
  type: "text-delta",
5007
5526
  id: String(value.index),
@@ -5062,6 +5581,7 @@ var AnthropicLanguageModel = class AnthropicLanguageModel {
5062
5581
  const citation = value.delta.citation;
5063
5582
  const contentBlock = contentBlocks[value.index];
5064
5583
  if (contentBlock?.type === "text") contentBlock.citations.push(citation);
5584
+ heldBackTextByIndex.get(value.index)?.citations.push(citation);
5065
5585
  if (citation.type === "web_search_result_location") fallbackWebCitations.push(citation);
5066
5586
  else {
5067
5587
  const source = createCitationSource(citation, citationDocuments, generateId);
@@ -5087,6 +5607,7 @@ var AnthropicLanguageModel = class AnthropicLanguageModel {
5087
5607
  }
5088
5608
  isMessageOpen = true;
5089
5609
  activeMessageId = value.message.id;
5610
+ heldBackTextByIndex.clear();
5090
5611
  usage.input_tokens = value.message.usage.input_tokens;
5091
5612
  usage.cache_read_input_tokens = value.message.usage.cache_read_input_tokens ?? 0;
5092
5613
  usage.cache_creation_input_tokens = value.message.usage.cache_creation_input_tokens ?? 0;
@@ -5207,6 +5728,20 @@ var AnthropicLanguageModel = class AnthropicLanguageModel {
5207
5728
  if (source) controller.enqueue(source);
5208
5729
  }
5209
5730
  fallbackWebCitations.length = 0;
5731
+ if (!isJsonResponseFromTool && !isContinuationStopReason(finishReason.raw)) for (const { id, text, citations } of heldBackText) {
5732
+ if (text.length === 0) continue;
5733
+ controller.enqueue({
5734
+ type: "text-start",
5735
+ id
5736
+ });
5737
+ controller.enqueue({
5738
+ type: "text-delta",
5739
+ id,
5740
+ delta: text
5741
+ });
5742
+ controller.enqueue(createTextEnd(id, citations));
5743
+ }
5744
+ heldBackText.length = 0;
5210
5745
  controller.enqueue({
5211
5746
  type: "finish",
5212
5747
  finishReason,
@@ -5306,222 +5841,6 @@ var AnthropicLanguageModel = class AnthropicLanguageModel {
5306
5841
  };
5307
5842
  }
5308
5843
  };
5309
- /**
5310
- * Returns the capabilities of a Claude model that are used for defaults and feature selection.
5311
- *
5312
- * @see https://docs.claude.com/en/docs/about-claude/models/overview#model-comparison-table
5313
- * @see https://platform.claude.com/docs/en/build-with-claude/structured-outputs
5314
- */
5315
- function getModelCapabilities(modelId) {
5316
- if (modelId.includes("claude-sonnet-5-5")) return {
5317
- maxOutputTokens: 128e3,
5318
- supportsStructuredOutput: true,
5319
- supportsAdaptiveThinking: true,
5320
- rejectsSamplingParameters: true,
5321
- supportsXhighEffort: true,
5322
- rejectsThinkingDisabledAboveHighEffort: true,
5323
- rejectsThinkingDisabled: true,
5324
- rejectsBudgetThinking: true,
5325
- rejectsForcedToolUse: true,
5326
- supportsBetweenToolsThinking: true,
5327
- isKnownModel: true
5328
- };
5329
- else if (modelId.includes("claude-opus-5-5")) return {
5330
- maxOutputTokens: 128e3,
5331
- supportsStructuredOutput: true,
5332
- supportsAdaptiveThinking: true,
5333
- rejectsSamplingParameters: true,
5334
- supportsXhighEffort: true,
5335
- rejectsThinkingDisabledAboveHighEffort: true,
5336
- rejectsThinkingDisabled: true,
5337
- rejectsBudgetThinking: true,
5338
- rejectsForcedToolUse: true,
5339
- supportsBetweenToolsThinking: false,
5340
- isKnownModel: true
5341
- };
5342
- else if (modelId.includes("claude-haiku-5-5")) return {
5343
- maxOutputTokens: 128e3,
5344
- supportsStructuredOutput: true,
5345
- supportsAdaptiveThinking: true,
5346
- rejectsSamplingParameters: true,
5347
- supportsXhighEffort: true,
5348
- rejectsThinkingDisabledAboveHighEffort: true,
5349
- rejectsThinkingDisabled: false,
5350
- rejectsBudgetThinking: true,
5351
- rejectsForcedToolUse: false,
5352
- supportsBetweenToolsThinking: false,
5353
- isKnownModel: true
5354
- };
5355
- else if (modelId.includes("claude-opus-5")) return {
5356
- maxOutputTokens: 128e3,
5357
- supportsStructuredOutput: true,
5358
- supportsAdaptiveThinking: true,
5359
- rejectsSamplingParameters: true,
5360
- supportsXhighEffort: true,
5361
- rejectsThinkingDisabledAboveHighEffort: true,
5362
- rejectsThinkingDisabled: false,
5363
- rejectsBudgetThinking: false,
5364
- rejectsForcedToolUse: false,
5365
- supportsBetweenToolsThinking: false,
5366
- isKnownModel: true
5367
- };
5368
- else if (modelId.includes("claude-fable-5-1")) return {
5369
- maxOutputTokens: 128e3,
5370
- supportsStructuredOutput: true,
5371
- supportsAdaptiveThinking: true,
5372
- rejectsSamplingParameters: true,
5373
- supportsXhighEffort: true,
5374
- rejectsThinkingDisabledAboveHighEffort: false,
5375
- rejectsThinkingDisabled: true,
5376
- rejectsBudgetThinking: true,
5377
- rejectsForcedToolUse: true,
5378
- supportsBetweenToolsThinking: false,
5379
- isKnownModel: true
5380
- };
5381
- else if (modelId.includes("claude-fable-5")) return {
5382
- maxOutputTokens: 128e3,
5383
- supportsStructuredOutput: true,
5384
- supportsAdaptiveThinking: true,
5385
- rejectsSamplingParameters: true,
5386
- supportsXhighEffort: true,
5387
- rejectsThinkingDisabledAboveHighEffort: false,
5388
- rejectsThinkingDisabled: true,
5389
- rejectsBudgetThinking: true,
5390
- rejectsForcedToolUse: false,
5391
- supportsBetweenToolsThinking: false,
5392
- isKnownModel: true
5393
- };
5394
- else if (modelId.includes("claude-opus-4-8") || modelId.includes("claude-opus-4-7") || modelId.includes("claude-sonnet-5")) return {
5395
- maxOutputTokens: 128e3,
5396
- supportsStructuredOutput: true,
5397
- supportsAdaptiveThinking: true,
5398
- rejectsSamplingParameters: true,
5399
- supportsXhighEffort: true,
5400
- rejectsThinkingDisabledAboveHighEffort: false,
5401
- rejectsThinkingDisabled: false,
5402
- rejectsBudgetThinking: false,
5403
- rejectsForcedToolUse: false,
5404
- supportsBetweenToolsThinking: false,
5405
- isKnownModel: true
5406
- };
5407
- else if (modelId.includes("claude-sonnet-4-6") || modelId.includes("claude-opus-4-6")) return {
5408
- maxOutputTokens: 128e3,
5409
- supportsStructuredOutput: true,
5410
- supportsAdaptiveThinking: true,
5411
- rejectsSamplingParameters: false,
5412
- supportsXhighEffort: false,
5413
- rejectsThinkingDisabledAboveHighEffort: false,
5414
- rejectsThinkingDisabled: false,
5415
- rejectsBudgetThinking: false,
5416
- rejectsForcedToolUse: false,
5417
- supportsBetweenToolsThinking: false,
5418
- isKnownModel: true
5419
- };
5420
- else if (modelId.includes("claude-sonnet-4-5") || modelId.includes("claude-opus-4-5") || modelId.includes("claude-haiku-4-5")) return {
5421
- maxOutputTokens: 64e3,
5422
- supportsStructuredOutput: true,
5423
- supportsAdaptiveThinking: false,
5424
- rejectsSamplingParameters: false,
5425
- supportsXhighEffort: false,
5426
- rejectsThinkingDisabledAboveHighEffort: false,
5427
- rejectsThinkingDisabled: false,
5428
- rejectsBudgetThinking: false,
5429
- rejectsForcedToolUse: false,
5430
- supportsBetweenToolsThinking: false,
5431
- isKnownModel: true
5432
- };
5433
- else if (modelId.includes("claude-opus-4-1")) return {
5434
- maxOutputTokens: 32e3,
5435
- supportsStructuredOutput: true,
5436
- supportsAdaptiveThinking: false,
5437
- rejectsSamplingParameters: false,
5438
- supportsXhighEffort: false,
5439
- rejectsThinkingDisabledAboveHighEffort: false,
5440
- rejectsThinkingDisabled: false,
5441
- rejectsBudgetThinking: false,
5442
- rejectsForcedToolUse: false,
5443
- supportsBetweenToolsThinking: false,
5444
- isKnownModel: true
5445
- };
5446
- else if (/claude-sonnet-4(?:-|@)/.test(modelId)) return {
5447
- maxOutputTokens: 64e3,
5448
- supportsStructuredOutput: false,
5449
- supportsAdaptiveThinking: false,
5450
- rejectsSamplingParameters: false,
5451
- supportsXhighEffort: false,
5452
- rejectsThinkingDisabledAboveHighEffort: false,
5453
- rejectsThinkingDisabled: false,
5454
- rejectsBudgetThinking: false,
5455
- rejectsForcedToolUse: false,
5456
- supportsBetweenToolsThinking: false,
5457
- isKnownModel: true
5458
- };
5459
- else if (/claude-opus-4(?:-|@)/.test(modelId)) return {
5460
- maxOutputTokens: 32e3,
5461
- supportsStructuredOutput: false,
5462
- supportsAdaptiveThinking: false,
5463
- rejectsSamplingParameters: false,
5464
- supportsXhighEffort: false,
5465
- rejectsThinkingDisabledAboveHighEffort: false,
5466
- rejectsThinkingDisabled: false,
5467
- rejectsBudgetThinking: false,
5468
- rejectsForcedToolUse: false,
5469
- supportsBetweenToolsThinking: false,
5470
- isKnownModel: true
5471
- };
5472
- else if (modelId.includes("claude-3-haiku")) return {
5473
- maxOutputTokens: 4096,
5474
- supportsStructuredOutput: false,
5475
- supportsAdaptiveThinking: false,
5476
- rejectsSamplingParameters: false,
5477
- supportsXhighEffort: false,
5478
- rejectsThinkingDisabledAboveHighEffort: false,
5479
- rejectsThinkingDisabled: false,
5480
- rejectsBudgetThinking: false,
5481
- rejectsForcedToolUse: false,
5482
- supportsBetweenToolsThinking: false,
5483
- isKnownModel: true
5484
- };
5485
- else if (/claude-(?:instant(?:-|$)|v?2(?=$|[-.:])|3(?=$|[-.]))/.test(modelId)) return {
5486
- maxOutputTokens: 4096,
5487
- supportsStructuredOutput: false,
5488
- supportsAdaptiveThinking: false,
5489
- rejectsSamplingParameters: false,
5490
- supportsXhighEffort: false,
5491
- rejectsThinkingDisabledAboveHighEffort: false,
5492
- rejectsThinkingDisabled: false,
5493
- rejectsBudgetThinking: false,
5494
- rejectsForcedToolUse: false,
5495
- supportsBetweenToolsThinking: false,
5496
- isKnownModel: false
5497
- };
5498
- else if (modelId.includes("claude-")) return {
5499
- maxOutputTokens: 128e3,
5500
- supportsStructuredOutput: true,
5501
- supportsAdaptiveThinking: true,
5502
- rejectsSamplingParameters: true,
5503
- supportsXhighEffort: true,
5504
- rejectsThinkingDisabledAboveHighEffort: true,
5505
- rejectsThinkingDisabled: false,
5506
- rejectsBudgetThinking: false,
5507
- rejectsForcedToolUse: false,
5508
- supportsBetweenToolsThinking: false,
5509
- isKnownModel: false
5510
- };
5511
- else return {
5512
- maxOutputTokens: 4096,
5513
- supportsStructuredOutput: false,
5514
- supportsAdaptiveThinking: false,
5515
- rejectsSamplingParameters: false,
5516
- supportsXhighEffort: false,
5517
- rejectsThinkingDisabledAboveHighEffort: false,
5518
- rejectsThinkingDisabled: false,
5519
- rejectsBudgetThinking: false,
5520
- rejectsForcedToolUse: false,
5521
- supportsBetweenToolsThinking: false,
5522
- isKnownModel: false
5523
- };
5524
- }
5525
5844
  function hasDynamicFilteringWebToolWithoutCodeExecution(tools) {
5526
5845
  if (!tools) return false;
5527
5846
  let hasDynamicFilteringWebTool = false;
@@ -7025,7 +7344,7 @@ var AnthropicSkills = class {
7025
7344
  };
7026
7345
  //#endregion
7027
7346
  //#region src/version.ts
7028
- const VERSION = "4.0.92";
7347
+ const VERSION = "4.0.94";
7029
7348
  //#endregion
7030
7349
  //#region src/anthropic-provider.ts
7031
7350
  const ANTHROPIC_API_URL = "https://api.anthropic.com";