@ai-sdk/anthropic 2.0.47 → 2.0.49

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.47" : "0.0.0-test";
14
+ var VERSION = true ? "2.0.49" : "0.0.0-test";
15
15
 
16
16
  // src/anthropic-messages-language-model.ts
17
17
  import {
@@ -546,6 +546,20 @@ var anthropicFilePartProviderOptions = z3.object({
546
546
  });
547
547
  var anthropicProviderOptions = z3.object({
548
548
  sendReasoning: z3.boolean().optional(),
549
+ /**
550
+ * Determines how structured outputs are generated.
551
+ *
552
+ * - `outputFormat`: Use the `output_format` parameter to specify the structured output format.
553
+ * - `jsonTool`: Use a special 'json' tool to specify the structured output format (default).
554
+ * - `auto`: Use 'outputFormat' when supported, otherwise use 'jsonTool'.
555
+ */
556
+ structuredOutputMode: z3.enum(["outputFormat", "jsonTool", "auto"]).optional(),
557
+ /**
558
+ * Configuration for enabling Claude's extended thinking.
559
+ *
560
+ * When enabled, responses include thinking content blocks showing Claude's thinking process before the final answer.
561
+ * Requires a minimum budget of 1,024 tokens and counts towards the `max_tokens` limit.
562
+ */
549
563
  thinking: z3.object({
550
564
  type: z3.union([z3.literal("enabled"), z3.literal("disabled")]),
551
565
  budgetTokens: z3.number().optional()
@@ -1773,6 +1787,7 @@ var AnthropicMessagesLanguageModel = class {
1773
1787
  return (_c = (_b = (_a = this.config).supportedUrls) == null ? void 0 : _b.call(_a)) != null ? _c : {};
1774
1788
  }
1775
1789
  async getArgs({
1790
+ userSuppliedBetas,
1776
1791
  prompt,
1777
1792
  maxOutputTokens,
1778
1793
  temperature,
@@ -1787,7 +1802,7 @@ var AnthropicMessagesLanguageModel = class {
1787
1802
  toolChoice,
1788
1803
  providerOptions
1789
1804
  }) {
1790
- var _a, _b, _c, _d;
1805
+ var _a, _b, _c, _d, _e;
1791
1806
  const warnings = [];
1792
1807
  if (frequencyPenalty != null) {
1793
1808
  warnings.push({
@@ -1837,27 +1852,33 @@ var AnthropicMessagesLanguageModel = class {
1837
1852
  });
1838
1853
  }
1839
1854
  }
1840
- const jsonResponseTool = (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null ? {
1841
- type: "function",
1842
- name: "json",
1843
- description: "Respond with a JSON object.",
1844
- inputSchema: responseFormat.schema
1845
- } : void 0;
1846
1855
  const anthropicOptions = await parseProviderOptions2({
1847
1856
  provider: "anthropic",
1848
1857
  providerOptions,
1849
1858
  schema: anthropicProviderOptions
1850
1859
  });
1860
+ const {
1861
+ maxOutputTokens: maxOutputTokensForModel,
1862
+ supportsStructuredOutput,
1863
+ isKnownModel
1864
+ } = getModelCapabilities(this.modelId);
1865
+ const structureOutputMode = (_a = anthropicOptions == null ? void 0 : anthropicOptions.structuredOutputMode) != null ? _a : "jsonTool";
1866
+ const useStructuredOutput = structureOutputMode === "outputFormat" || structureOutputMode === "auto" && supportsStructuredOutput;
1867
+ const jsonResponseTool = (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null && !useStructuredOutput ? {
1868
+ type: "function",
1869
+ name: "json",
1870
+ description: "Respond with a JSON object.",
1871
+ inputSchema: responseFormat.schema
1872
+ } : void 0;
1851
1873
  const cacheControlValidator = new CacheControlValidator();
1852
1874
  const { prompt: messagesPrompt, betas } = await convertToAnthropicMessagesPrompt({
1853
1875
  prompt,
1854
- sendReasoning: (_a = anthropicOptions == null ? void 0 : anthropicOptions.sendReasoning) != null ? _a : true,
1876
+ sendReasoning: (_b = anthropicOptions == null ? void 0 : anthropicOptions.sendReasoning) != null ? _b : true,
1855
1877
  warnings,
1856
1878
  cacheControlValidator
1857
1879
  });
1858
- const isThinking = ((_b = anthropicOptions == null ? void 0 : anthropicOptions.thinking) == null ? void 0 : _b.type) === "enabled";
1859
- const thinkingBudget = (_c = anthropicOptions == null ? void 0 : anthropicOptions.thinking) == null ? void 0 : _c.budgetTokens;
1860
- const { maxOutputTokens: maxOutputTokensForModel, knownModel } = getMaxOutputTokensForModel(this.modelId);
1880
+ const isThinking = ((_c = anthropicOptions == null ? void 0 : anthropicOptions.thinking) == null ? void 0 : _c.type) === "enabled";
1881
+ const thinkingBudget = (_d = anthropicOptions == null ? void 0 : anthropicOptions.thinking) == null ? void 0 : _d.budgetTokens;
1861
1882
  const maxTokens = maxOutputTokens != null ? maxOutputTokens : maxOutputTokensForModel;
1862
1883
  const baseArgs = {
1863
1884
  // model id:
@@ -1875,11 +1896,18 @@ var AnthropicMessagesLanguageModel = class {
1875
1896
  ...(anthropicOptions == null ? void 0 : anthropicOptions.effort) && {
1876
1897
  output_config: { effort: anthropicOptions.effort }
1877
1898
  },
1899
+ // structured output:
1900
+ ...useStructuredOutput && (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null && {
1901
+ output_format: {
1902
+ type: "json_schema",
1903
+ schema: responseFormat.schema
1904
+ }
1905
+ },
1878
1906
  // container with agent skills:
1879
1907
  ...(anthropicOptions == null ? void 0 : anthropicOptions.container) && {
1880
1908
  container: {
1881
1909
  id: anthropicOptions.container.id,
1882
- skills: (_d = anthropicOptions.container.skills) == null ? void 0 : _d.map((skill) => ({
1910
+ skills: (_e = anthropicOptions.container.skills) == null ? void 0 : _e.map((skill) => ({
1883
1911
  type: skill.type,
1884
1912
  skill_id: skill.skillId,
1885
1913
  version: skill.version
@@ -1922,7 +1950,7 @@ var AnthropicMessagesLanguageModel = class {
1922
1950
  }
1923
1951
  baseArgs.max_tokens = maxTokens + thinkingBudget;
1924
1952
  }
1925
- if (knownModel && baseArgs.max_tokens > maxOutputTokensForModel) {
1953
+ if (isKnownModel && baseArgs.max_tokens > maxOutputTokensForModel) {
1926
1954
  if (maxOutputTokens != null) {
1927
1955
  warnings.push({
1928
1956
  type: "unsupported-setting",
@@ -1948,6 +1976,9 @@ var AnthropicMessagesLanguageModel = class {
1948
1976
  if (anthropicOptions == null ? void 0 : anthropicOptions.effort) {
1949
1977
  betas.add("effort-2025-11-24");
1950
1978
  }
1979
+ if (useStructuredOutput) {
1980
+ betas.add("structured-outputs-2025-11-13");
1981
+ }
1951
1982
  const {
1952
1983
  tools: anthropicTools2,
1953
1984
  toolChoice: anthropicToolChoice,
@@ -1974,7 +2005,7 @@ var AnthropicMessagesLanguageModel = class {
1974
2005
  tool_choice: anthropicToolChoice
1975
2006
  },
1976
2007
  warnings: [...warnings, ...toolWarnings, ...cacheWarnings],
1977
- betas: /* @__PURE__ */ new Set([...betas, ...toolsBetas]),
2008
+ betas: /* @__PURE__ */ new Set([...betas, ...toolsBetas, ...userSuppliedBetas]),
1978
2009
  usesJsonResponseTool: jsonResponseTool != null
1979
2010
  };
1980
2011
  }
@@ -1984,8 +2015,20 @@ var AnthropicMessagesLanguageModel = class {
1984
2015
  }) {
1985
2016
  return combineHeaders(
1986
2017
  await resolve(this.config.headers),
1987
- betas.size > 0 ? { "anthropic-beta": Array.from(betas).join(",") } : {},
1988
- headers
2018
+ headers,
2019
+ betas.size > 0 ? { "anthropic-beta": Array.from(betas).join(",") } : {}
2020
+ );
2021
+ }
2022
+ async getBetasFromHeaders(requestHeaders) {
2023
+ var _a, _b;
2024
+ const configHeaders = await resolve(this.config.headers);
2025
+ const configBetaHeader = (_a = configHeaders["anthropic-beta"]) != null ? _a : "";
2026
+ const requestBetaHeader = (_b = requestHeaders == null ? void 0 : requestHeaders["anthropic-beta"]) != null ? _b : "";
2027
+ return new Set(
2028
+ [
2029
+ ...configBetaHeader.toLowerCase().split(","),
2030
+ ...requestBetaHeader.toLowerCase().split(",")
2031
+ ].map((beta) => beta.trim()).filter((beta) => beta !== "")
1989
2032
  );
1990
2033
  }
1991
2034
  buildRequestUrl(isStreaming) {
@@ -2021,7 +2064,10 @@ var AnthropicMessagesLanguageModel = class {
2021
2064
  }
2022
2065
  async doGenerate(options) {
2023
2066
  var _a, _b, _c, _d, _e, _f, _g, _h;
2024
- const { args, warnings, betas, usesJsonResponseTool } = await this.getArgs(options);
2067
+ const { args, warnings, betas, usesJsonResponseTool } = await this.getArgs({
2068
+ ...options,
2069
+ userSuppliedBetas: await this.getBetasFromHeaders(options.headers)
2070
+ });
2025
2071
  const citationDocuments = this.extractCitationDocuments(options.prompt);
2026
2072
  const {
2027
2073
  responseHeaders,
@@ -2286,7 +2332,10 @@ var AnthropicMessagesLanguageModel = class {
2286
2332
  };
2287
2333
  }
2288
2334
  async doStream(options) {
2289
- const { args, warnings, betas, usesJsonResponseTool } = await this.getArgs(options);
2335
+ const { args, warnings, betas, usesJsonResponseTool } = await this.getArgs({
2336
+ ...options,
2337
+ userSuppliedBetas: await this.getBetasFromHeaders(options.headers)
2338
+ });
2290
2339
  const citationDocuments = this.extractCitationDocuments(options.prompt);
2291
2340
  const body = { ...args, stream: true };
2292
2341
  const { responseHeaders, value: response } = await postJsonToApi({
@@ -2750,27 +2799,49 @@ var AnthropicMessagesLanguageModel = class {
2750
2799
  };
2751
2800
  }
2752
2801
  };
2753
- function getMaxOutputTokensForModel(modelId) {
2802
+ function getModelCapabilities(modelId) {
2754
2803
  if (modelId.includes("claude-sonnet-4-5") || modelId.includes("claude-opus-4-5")) {
2755
2804
  return {
2756
2805
  maxOutputTokens: 64e3,
2757
- knownModel: true
2806
+ supportsStructuredOutput: true,
2807
+ isKnownModel: true
2758
2808
  };
2759
2809
  } else if (modelId.includes("claude-opus-4-1")) {
2760
2810
  return {
2761
2811
  maxOutputTokens: 32e3,
2762
- knownModel: true
2812
+ supportsStructuredOutput: true,
2813
+ isKnownModel: true
2763
2814
  };
2764
2815
  } else if (modelId.includes("claude-sonnet-4-") || modelId.includes("claude-3-7-sonnet") || modelId.includes("claude-haiku-4-5")) {
2765
- return { maxOutputTokens: 64e3, knownModel: true };
2816
+ return {
2817
+ maxOutputTokens: 64e3,
2818
+ supportsStructuredOutput: false,
2819
+ isKnownModel: true
2820
+ };
2766
2821
  } else if (modelId.includes("claude-opus-4-")) {
2767
- return { maxOutputTokens: 32e3, knownModel: true };
2822
+ return {
2823
+ maxOutputTokens: 32e3,
2824
+ supportsStructuredOutput: false,
2825
+ isKnownModel: true
2826
+ };
2768
2827
  } else if (modelId.includes("claude-3-5-haiku")) {
2769
- return { maxOutputTokens: 8192, knownModel: true };
2828
+ return {
2829
+ maxOutputTokens: 8192,
2830
+ supportsStructuredOutput: false,
2831
+ isKnownModel: true
2832
+ };
2770
2833
  } else if (modelId.includes("claude-3-haiku")) {
2771
- return { maxOutputTokens: 4096, knownModel: true };
2834
+ return {
2835
+ maxOutputTokens: 4096,
2836
+ supportsStructuredOutput: false,
2837
+ isKnownModel: true
2838
+ };
2772
2839
  } else {
2773
- return { maxOutputTokens: 4096, knownModel: false };
2840
+ return {
2841
+ maxOutputTokens: 4096,
2842
+ supportsStructuredOutput: false,
2843
+ isKnownModel: false
2844
+ };
2774
2845
  }
2775
2846
  }
2776
2847