@ai-sdk/anthropic 2.0.99 → 2.0.100

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.mjs CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  } from "@ai-sdk/provider-utils";
12
12
 
13
13
  // src/version.ts
14
- var VERSION = true ? "2.0.99" : "0.0.0-test";
14
+ var VERSION = true ? "2.0.100" : "0.0.0-test";
15
15
 
16
16
  // src/anthropic-messages-language-model.ts
17
17
  import {
@@ -702,7 +702,7 @@ var anthropicProviderOptions = z3.object({
702
702
  * Determines how structured outputs are generated.
703
703
  *
704
704
  * - `outputFormat`: Use the `output_format` parameter to specify the structured output format.
705
- * - `jsonTool`: Use a special 'json' tool to specify the structured output format (default).
705
+ * - `jsonTool`: Use a special JSON response tool to specify the structured output format (default).
706
706
  * - `auto`: Use 'outputFormat' when supported, otherwise use 'jsonTool'.
707
707
  */
708
708
  structuredOutputMode: z3.enum(["outputFormat", "jsonTool", "auto"]).optional(),
@@ -2275,6 +2275,15 @@ function isPlainObject(value) {
2275
2275
  }
2276
2276
 
2277
2277
  // src/anthropic-messages-language-model.ts
2278
+ function getJsonResponseToolName(tools) {
2279
+ const toolNames = new Set(tools == null ? void 0 : tools.map((tool) => tool.name));
2280
+ let name = "json";
2281
+ let suffix = 1;
2282
+ while (toolNames.has(name)) {
2283
+ name = `json_${suffix++}`;
2284
+ }
2285
+ return name;
2286
+ }
2278
2287
  function createCitationSource(citation, citationDocuments, generateId3) {
2279
2288
  var _a;
2280
2289
  if (citation.type !== "page_location" && citation.type !== "char_location") {
@@ -2380,12 +2389,6 @@ var AnthropicMessagesLanguageModel = class {
2380
2389
  setting: "responseFormat",
2381
2390
  details: "JSON response format requires a schema. The response format is ignored."
2382
2391
  });
2383
- } else if (tools != null) {
2384
- warnings.push({
2385
- type: "unsupported-setting",
2386
- setting: "tools",
2387
- details: "JSON response format does not support tools. The provided tools are ignored."
2388
- });
2389
2392
  }
2390
2393
  }
2391
2394
  const anthropicOptions = await parseProviderOptions2({
@@ -2435,9 +2438,10 @@ var AnthropicMessagesLanguageModel = class {
2435
2438
  const isAnthropicModel = isKnownModel || this.modelId.includes("claude-");
2436
2439
  const structureOutputMode = (_a = anthropicOptions == null ? void 0 : anthropicOptions.structuredOutputMode) != null ? _a : "jsonTool";
2437
2440
  const useStructuredOutput = structureOutputMode === "outputFormat" || structureOutputMode === "auto" && supportsStructuredOutput;
2441
+ const jsonResponseToolName = getJsonResponseToolName(tools);
2438
2442
  const jsonResponseTool = (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null && !useStructuredOutput ? {
2439
2443
  type: "function",
2440
- name: "json",
2444
+ name: jsonResponseToolName,
2441
2445
  description: "Respond with a JSON object.",
2442
2446
  inputSchema: responseFormat.schema
2443
2447
  } : void 0;
@@ -2680,8 +2684,8 @@ var AnthropicMessagesLanguageModel = class {
2680
2684
  betas: toolsBetas
2681
2685
  } = await prepareTools(
2682
2686
  jsonResponseTool != null ? {
2683
- tools: [jsonResponseTool],
2684
- toolChoice: { type: "tool", toolName: jsonResponseTool.name },
2687
+ tools: [...tools != null ? tools : [], jsonResponseTool],
2688
+ toolChoice: tools != null && tools.length > 0 ? { type: "required" } : { type: "tool", toolName: jsonResponseTool.name },
2685
2689
  disableParallelToolUse: true,
2686
2690
  cacheControlValidator
2687
2691
  } : {
@@ -2705,7 +2709,7 @@ var AnthropicMessagesLanguageModel = class {
2705
2709
  ...userSuppliedBetas,
2706
2710
  ...(_i = anthropicOptions == null ? void 0 : anthropicOptions.anthropicBeta) != null ? _i : []
2707
2711
  ]),
2708
- usesJsonResponseTool: jsonResponseTool != null
2712
+ jsonResponseToolName: jsonResponseTool != null ? jsonResponseToolName : void 0
2709
2713
  };
2710
2714
  }
2711
2715
  async getHeaders({
@@ -2763,7 +2767,7 @@ var AnthropicMessagesLanguageModel = class {
2763
2767
  }
2764
2768
  async doGenerate(options) {
2765
2769
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
2766
- const { args, warnings, betas, usesJsonResponseTool } = await this.getArgs({
2770
+ const { args, warnings, betas, jsonResponseToolName } = await this.getArgs({
2767
2771
  ...options,
2768
2772
  userSuppliedBetas: await this.getBetasFromHeaders(options.headers)
2769
2773
  });
@@ -2784,10 +2788,11 @@ var AnthropicMessagesLanguageModel = class {
2784
2788
  fetch: this.config.fetch
2785
2789
  });
2786
2790
  const content = [];
2791
+ let isJsonResponseFromTool = false;
2787
2792
  for (const part of response.content) {
2788
2793
  switch (part.type) {
2789
2794
  case "text": {
2790
- if (!usesJsonResponseTool) {
2795
+ if (jsonResponseToolName == null) {
2791
2796
  const webSearchCitations = (_a = part.citations) == null ? void 0 : _a.filter(
2792
2797
  (citation) => citation.type === "web_search_result_location"
2793
2798
  );
@@ -2854,18 +2859,21 @@ var AnthropicMessagesLanguageModel = class {
2854
2859
  break;
2855
2860
  }
2856
2861
  case "tool_use": {
2857
- content.push(
2858
- // when a json response tool is used, the tool call becomes the text:
2859
- usesJsonResponseTool ? {
2862
+ const isJsonResponseTool = part.name === jsonResponseToolName;
2863
+ if (isJsonResponseTool) {
2864
+ isJsonResponseFromTool = true;
2865
+ content.push({
2860
2866
  type: "text",
2861
2867
  text: JSON.stringify(part.input)
2862
- } : {
2868
+ });
2869
+ } else {
2870
+ content.push({
2863
2871
  type: "tool-call",
2864
2872
  toolCallId: part.id,
2865
2873
  toolName: part.name,
2866
2874
  input: JSON.stringify(part.input)
2867
- }
2868
- );
2875
+ });
2876
+ }
2869
2877
  break;
2870
2878
  }
2871
2879
  case "server_tool_use": {
@@ -3047,7 +3055,7 @@ var AnthropicMessagesLanguageModel = class {
3047
3055
  content,
3048
3056
  finishReason: mapAnthropicStopReason({
3049
3057
  finishReason: response.stop_reason,
3050
- isJsonResponseFromTool: usesJsonResponseTool
3058
+ isJsonResponseFromTool
3051
3059
  }),
3052
3060
  usage: {
3053
3061
  inputTokens,
@@ -3115,7 +3123,7 @@ var AnthropicMessagesLanguageModel = class {
3115
3123
  }
3116
3124
  async doStream(options) {
3117
3125
  var _a, _b;
3118
- const { args, warnings, betas, usesJsonResponseTool } = await this.getArgs({
3126
+ const { args, warnings, betas, jsonResponseToolName } = await this.getArgs({
3119
3127
  ...options,
3120
3128
  userSuppliedBetas: await this.getBetasFromHeaders(options.headers)
3121
3129
  });
@@ -3147,6 +3155,7 @@ var AnthropicMessagesLanguageModel = class {
3147
3155
  let container = null;
3148
3156
  let iterations = null;
3149
3157
  let contextManagement = null;
3158
+ let isJsonResponseFromTool = false;
3150
3159
  let isMessageOpen = false;
3151
3160
  let activeMessageId;
3152
3161
  let hasInvalidMessageSequence = false;
@@ -3230,20 +3239,31 @@ var AnthropicMessagesLanguageModel = class {
3230
3239
  return;
3231
3240
  }
3232
3241
  case "tool_use": {
3233
- contentBlocks[value.index] = usesJsonResponseTool ? { type: "text", citations: [] } : {
3234
- type: "tool-call",
3235
- toolCallId: value.content_block.id,
3236
- toolName: value.content_block.name,
3237
- input: "",
3238
- firstDelta: true
3239
- };
3240
- controller.enqueue(
3241
- usesJsonResponseTool ? { type: "text-start", id: String(value.index) } : {
3242
+ const isJsonResponseTool = value.content_block.name === jsonResponseToolName;
3243
+ if (isJsonResponseTool) {
3244
+ isJsonResponseFromTool = true;
3245
+ contentBlocks[value.index] = {
3246
+ type: "text",
3247
+ citations: []
3248
+ };
3249
+ controller.enqueue({
3250
+ type: "text-start",
3251
+ id: String(value.index)
3252
+ });
3253
+ } else {
3254
+ contentBlocks[value.index] = {
3255
+ type: "tool-call",
3256
+ toolCallId: value.content_block.id,
3257
+ toolName: value.content_block.name,
3258
+ input: "",
3259
+ firstDelta: true
3260
+ };
3261
+ controller.enqueue({
3242
3262
  type: "tool-input-start",
3243
3263
  id: value.content_block.id,
3244
3264
  toolName: value.content_block.name
3245
- }
3246
- );
3265
+ });
3266
+ }
3247
3267
  return;
3248
3268
  }
3249
3269
  case "server_tool_use": {
@@ -3439,22 +3459,21 @@ var AnthropicMessagesLanguageModel = class {
3439
3459
  });
3440
3460
  break;
3441
3461
  }
3442
- case "tool-call":
3443
- if (!usesJsonResponseTool) {
3444
- controller.enqueue({
3445
- type: "tool-input-end",
3446
- id: contentBlock.toolCallId
3447
- });
3448
- const toolName = contentBlock.toolName === "text_editor_code_execution" || contentBlock.toolName === "bash_code_execution" ? "code_execution" : contentBlock.toolName;
3449
- controller.enqueue({
3450
- type: "tool-call",
3451
- toolCallId: contentBlock.toolCallId,
3452
- toolName,
3453
- input: contentBlock.input === "" ? "{}" : contentBlock.input,
3454
- providerExecuted: contentBlock.providerExecuted
3455
- });
3456
- }
3462
+ case "tool-call": {
3463
+ controller.enqueue({
3464
+ type: "tool-input-end",
3465
+ id: contentBlock.toolCallId
3466
+ });
3467
+ const toolName = contentBlock.toolName === "text_editor_code_execution" || contentBlock.toolName === "bash_code_execution" ? "code_execution" : contentBlock.toolName;
3468
+ controller.enqueue({
3469
+ type: "tool-call",
3470
+ toolCallId: contentBlock.toolCallId,
3471
+ toolName,
3472
+ input: contentBlock.input === "" ? "{}" : contentBlock.input,
3473
+ providerExecuted: contentBlock.providerExecuted
3474
+ });
3457
3475
  break;
3476
+ }
3458
3477
  }
3459
3478
  delete contentBlocks[value.index];
3460
3479
  }
@@ -3465,7 +3484,7 @@ var AnthropicMessagesLanguageModel = class {
3465
3484
  const deltaType = value.delta.type;
3466
3485
  switch (deltaType) {
3467
3486
  case "text_delta": {
3468
- if (usesJsonResponseTool) {
3487
+ if (jsonResponseToolName != null) {
3469
3488
  return;
3470
3489
  }
3471
3490
  controller.enqueue({
@@ -3514,10 +3533,7 @@ var AnthropicMessagesLanguageModel = class {
3514
3533
  if (delta.length === 0) {
3515
3534
  return;
3516
3535
  }
3517
- if (usesJsonResponseTool) {
3518
- if ((contentBlock == null ? void 0 : contentBlock.type) !== "text") {
3519
- return;
3520
- }
3536
+ if ((contentBlock == null ? void 0 : contentBlock.type) === "text") {
3521
3537
  controller.enqueue({
3522
3538
  type: "text-delta",
3523
3539
  id: String(value.index),
@@ -3626,7 +3642,7 @@ var AnthropicMessagesLanguageModel = class {
3626
3642
  usage.totalTokens = ((_g = usage.inputTokens) != null ? _g : 0) + ((_h = usage.outputTokens) != null ? _h : 0);
3627
3643
  finishReason = mapAnthropicStopReason({
3628
3644
  finishReason: value.delta.stop_reason,
3629
- isJsonResponseFromTool: usesJsonResponseTool
3645
+ isJsonResponseFromTool
3630
3646
  });
3631
3647
  stopDetails = mapAnthropicStopDetails(value.delta.stop_details);
3632
3648
  stopSequence = (_i = value.delta.stop_sequence) != null ? _i : null;