@ai-sdk/anthropic 3.0.0-beta.43 → 3.0.0-beta.45

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.
@@ -624,7 +624,16 @@ var anthropicProviderOptions = import_v43.z.object({
624
624
  version: import_v43.z.string().optional()
625
625
  })
626
626
  ).optional()
627
- }).optional()
627
+ }).optional(),
628
+ /**
629
+ * Whether to enable tool streaming (and structured output streaming).
630
+ *
631
+ * When set to false, the model will return all tool calls and results
632
+ * at once after a delay.
633
+ *
634
+ * @default true
635
+ */
636
+ toolStreaming: import_v43.z.boolean().optional()
628
637
  });
629
638
 
630
639
  // src/anthropic-prepare-tools.ts
@@ -1873,9 +1882,10 @@ var AnthropicMessagesLanguageModel = class {
1873
1882
  seed,
1874
1883
  tools,
1875
1884
  toolChoice,
1876
- providerOptions
1885
+ providerOptions,
1886
+ stream
1877
1887
  }) {
1878
- var _a, _b, _c, _d;
1888
+ var _a, _b, _c, _d, _e;
1879
1889
  const warnings = [];
1880
1890
  if (frequencyPenalty != null) {
1881
1891
  warnings.push({
@@ -1902,12 +1912,6 @@ var AnthropicMessagesLanguageModel = class {
1902
1912
  setting: "responseFormat",
1903
1913
  details: "JSON response format requires a schema. The response format is ignored."
1904
1914
  });
1905
- } else if (tools != null) {
1906
- warnings.push({
1907
- type: "unsupported-setting",
1908
- setting: "tools",
1909
- details: "JSON response format does not support tools. The provided tools are ignored."
1910
- });
1911
1915
  }
1912
1916
  }
1913
1917
  const jsonResponseTool = (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null ? {
@@ -2031,6 +2035,9 @@ var AnthropicMessagesLanguageModel = class {
2031
2035
  });
2032
2036
  }
2033
2037
  }
2038
+ if (stream && ((_e = anthropicOptions == null ? void 0 : anthropicOptions.toolStreaming) != null ? _e : true)) {
2039
+ betas.add("fine-grained-tool-streaming-2025-05-14");
2040
+ }
2034
2041
  const {
2035
2042
  tools: anthropicTools2,
2036
2043
  toolChoice: anthropicToolChoice,
@@ -2038,8 +2045,8 @@ var AnthropicMessagesLanguageModel = class {
2038
2045
  betas: toolsBetas
2039
2046
  } = await prepareTools(
2040
2047
  jsonResponseTool != null ? {
2041
- tools: [jsonResponseTool],
2042
- toolChoice: { type: "tool", toolName: jsonResponseTool.name },
2048
+ tools: [...tools != null ? tools : [], jsonResponseTool],
2049
+ toolChoice: { type: "required" },
2043
2050
  disableParallelToolUse: true,
2044
2051
  cacheControlValidator
2045
2052
  } : {
@@ -2054,7 +2061,9 @@ var AnthropicMessagesLanguageModel = class {
2054
2061
  args: {
2055
2062
  ...baseArgs,
2056
2063
  tools: anthropicTools2,
2057
- tool_choice: anthropicToolChoice
2064
+ tool_choice: anthropicToolChoice,
2065
+ stream: stream === true ? true : void 0
2066
+ // do not send when not streaming
2058
2067
  },
2059
2068
  warnings: [...warnings, ...toolWarnings, ...cacheWarnings],
2060
2069
  betas: /* @__PURE__ */ new Set([...betas, ...toolsBetas]),
@@ -2104,7 +2113,10 @@ var AnthropicMessagesLanguageModel = class {
2104
2113
  }
2105
2114
  async doGenerate(options) {
2106
2115
  var _a, _b, _c, _d, _e, _f, _g, _h;
2107
- const { args, warnings, betas, usesJsonResponseTool } = await this.getArgs(options);
2116
+ const { args, warnings, betas, usesJsonResponseTool } = await this.getArgs({
2117
+ ...options,
2118
+ stream: false
2119
+ });
2108
2120
  const citationDocuments = this.extractCitationDocuments(options.prompt);
2109
2121
  const {
2110
2122
  responseHeaders,
@@ -2123,6 +2135,7 @@ var AnthropicMessagesLanguageModel = class {
2123
2135
  });
2124
2136
  const content = [];
2125
2137
  const mcpToolCalls = {};
2138
+ let isJsonResponseFromTool = false;
2126
2139
  for (const part of response.content) {
2127
2140
  switch (part.type) {
2128
2141
  case "text": {
@@ -2168,18 +2181,21 @@ var AnthropicMessagesLanguageModel = class {
2168
2181
  break;
2169
2182
  }
2170
2183
  case "tool_use": {
2171
- content.push(
2172
- // when a json response tool is used, the tool call becomes the text:
2173
- usesJsonResponseTool ? {
2184
+ const isJsonResponseTool = usesJsonResponseTool && part.name === "json";
2185
+ if (isJsonResponseTool) {
2186
+ isJsonResponseFromTool = true;
2187
+ content.push({
2174
2188
  type: "text",
2175
2189
  text: JSON.stringify(part.input)
2176
- } : {
2190
+ });
2191
+ } else {
2192
+ content.push({
2177
2193
  type: "tool-call",
2178
2194
  toolCallId: part.id,
2179
2195
  toolName: part.name,
2180
2196
  input: JSON.stringify(part.input)
2181
- }
2182
- );
2197
+ });
2198
+ }
2183
2199
  break;
2184
2200
  }
2185
2201
  case "server_tool_use": {
@@ -2366,7 +2382,7 @@ var AnthropicMessagesLanguageModel = class {
2366
2382
  content,
2367
2383
  finishReason: mapAnthropicStopReason({
2368
2384
  finishReason: response.stop_reason,
2369
- isJsonResponseFromTool: usesJsonResponseTool
2385
+ isJsonResponseFromTool
2370
2386
  }),
2371
2387
  usage: {
2372
2388
  inputTokens: response.usage.input_tokens,
@@ -2401,9 +2417,16 @@ var AnthropicMessagesLanguageModel = class {
2401
2417
  };
2402
2418
  }
2403
2419
  async doStream(options) {
2404
- const { args, warnings, betas, usesJsonResponseTool } = await this.getArgs(options);
2420
+ const {
2421
+ args: body,
2422
+ warnings,
2423
+ betas,
2424
+ usesJsonResponseTool
2425
+ } = await this.getArgs({
2426
+ ...options,
2427
+ stream: true
2428
+ });
2405
2429
  const citationDocuments = this.extractCitationDocuments(options.prompt);
2406
- const body = { ...args, stream: true };
2407
2430
  const { responseHeaders, value: response } = await (0, import_provider_utils11.postJsonToApi)({
2408
2431
  url: this.buildRequestUrl(true),
2409
2432
  headers: await this.getHeaders({ betas, headers: options.headers }),
@@ -2427,6 +2450,7 @@ var AnthropicMessagesLanguageModel = class {
2427
2450
  let cacheCreationInputTokens = null;
2428
2451
  let stopSequence = null;
2429
2452
  let container = null;
2453
+ let isJsonResponseFromTool = false;
2430
2454
  let blockType = void 0;
2431
2455
  const generateId2 = this.generateId;
2432
2456
  return {
@@ -2455,6 +2479,9 @@ var AnthropicMessagesLanguageModel = class {
2455
2479
  blockType = contentBlockType;
2456
2480
  switch (contentBlockType) {
2457
2481
  case "text": {
2482
+ if (usesJsonResponseTool) {
2483
+ return;
2484
+ }
2458
2485
  contentBlocks[value.index] = { type: "text" };
2459
2486
  controller.enqueue({
2460
2487
  type: "text-start",
@@ -2484,20 +2511,28 @@ var AnthropicMessagesLanguageModel = class {
2484
2511
  return;
2485
2512
  }
2486
2513
  case "tool_use": {
2487
- contentBlocks[value.index] = usesJsonResponseTool ? { type: "text" } : {
2488
- type: "tool-call",
2489
- toolCallId: part.id,
2490
- toolName: part.name,
2491
- input: "",
2492
- firstDelta: true
2493
- };
2494
- controller.enqueue(
2495
- usesJsonResponseTool ? { type: "text-start", id: String(value.index) } : {
2514
+ const isJsonResponseTool = usesJsonResponseTool && part.name === "json";
2515
+ if (isJsonResponseTool) {
2516
+ isJsonResponseFromTool = true;
2517
+ contentBlocks[value.index] = { type: "text" };
2518
+ controller.enqueue({
2519
+ type: "text-start",
2520
+ id: String(value.index)
2521
+ });
2522
+ } else {
2523
+ contentBlocks[value.index] = {
2524
+ type: "tool-call",
2525
+ toolCallId: part.id,
2526
+ toolName: part.name,
2527
+ input: "",
2528
+ firstDelta: true
2529
+ };
2530
+ controller.enqueue({
2496
2531
  type: "tool-input-start",
2497
2532
  id: part.id,
2498
2533
  toolName: part.name
2499
- }
2500
- );
2534
+ });
2535
+ }
2501
2536
  return;
2502
2537
  }
2503
2538
  case "server_tool_use": {
@@ -2713,7 +2748,8 @@ var AnthropicMessagesLanguageModel = class {
2713
2748
  break;
2714
2749
  }
2715
2750
  case "tool-call":
2716
- if (!usesJsonResponseTool) {
2751
+ const isJsonResponseTool = usesJsonResponseTool && contentBlock.toolName === "json";
2752
+ if (!isJsonResponseTool) {
2717
2753
  controller.enqueue({
2718
2754
  type: "tool-input-end",
2719
2755
  id: contentBlock.toolCallId
@@ -2777,7 +2813,7 @@ var AnthropicMessagesLanguageModel = class {
2777
2813
  if (delta.length === 0) {
2778
2814
  return;
2779
2815
  }
2780
- if (usesJsonResponseTool) {
2816
+ if (isJsonResponseFromTool) {
2781
2817
  if ((contentBlock == null ? void 0 : contentBlock.type) !== "text") {
2782
2818
  return;
2783
2819
  }
@@ -2842,7 +2878,7 @@ var AnthropicMessagesLanguageModel = class {
2842
2878
  usage.totalTokens = ((_f = usage.inputTokens) != null ? _f : 0) + ((_g = value.usage.output_tokens) != null ? _g : 0);
2843
2879
  finishReason = mapAnthropicStopReason({
2844
2880
  finishReason: value.delta.stop_reason,
2845
- isJsonResponseFromTool: usesJsonResponseTool
2881
+ isJsonResponseFromTool
2846
2882
  });
2847
2883
  stopSequence = (_h = value.delta.stop_sequence) != null ? _h : null;
2848
2884
  container = value.delta.container != null ? {