@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.
@@ -25,6 +25,7 @@ declare class AnthropicMessagesLanguageModel implements LanguageModelV2 {
25
25
  get supportedUrls(): Record<string, RegExp[]> | PromiseLike<Record<string, RegExp[]>>;
26
26
  private getArgs;
27
27
  private getHeaders;
28
+ private getBetasFromHeaders;
28
29
  private buildRequestUrl;
29
30
  private transformRequestBody;
30
31
  private extractCitationDocuments;
@@ -25,6 +25,7 @@ declare class AnthropicMessagesLanguageModel implements LanguageModelV2 {
25
25
  get supportedUrls(): Record<string, RegExp[]> | PromiseLike<Record<string, RegExp[]>>;
26
26
  private getArgs;
27
27
  private getHeaders;
28
+ private getBetasFromHeaders;
28
29
  private buildRequestUrl;
29
30
  private transformRequestBody;
30
31
  private extractCitationDocuments;
@@ -545,6 +545,20 @@ var anthropicFilePartProviderOptions = import_v43.z.object({
545
545
  });
546
546
  var anthropicProviderOptions = import_v43.z.object({
547
547
  sendReasoning: import_v43.z.boolean().optional(),
548
+ /**
549
+ * Determines how structured outputs are generated.
550
+ *
551
+ * - `outputFormat`: Use the `output_format` parameter to specify the structured output format.
552
+ * - `jsonTool`: Use a special 'json' tool to specify the structured output format (default).
553
+ * - `auto`: Use 'outputFormat' when supported, otherwise use 'jsonTool'.
554
+ */
555
+ structuredOutputMode: import_v43.z.enum(["outputFormat", "jsonTool", "auto"]).optional(),
556
+ /**
557
+ * Configuration for enabling Claude's extended thinking.
558
+ *
559
+ * When enabled, responses include thinking content blocks showing Claude's thinking process before the final answer.
560
+ * Requires a minimum budget of 1,024 tokens and counts towards the `max_tokens` limit.
561
+ */
548
562
  thinking: import_v43.z.object({
549
563
  type: import_v43.z.union([import_v43.z.literal("enabled"), import_v43.z.literal("disabled")]),
550
564
  budgetTokens: import_v43.z.number().optional()
@@ -1748,6 +1762,7 @@ var AnthropicMessagesLanguageModel = class {
1748
1762
  return (_c = (_b = (_a = this.config).supportedUrls) == null ? void 0 : _b.call(_a)) != null ? _c : {};
1749
1763
  }
1750
1764
  async getArgs({
1765
+ userSuppliedBetas,
1751
1766
  prompt,
1752
1767
  maxOutputTokens,
1753
1768
  temperature,
@@ -1762,7 +1777,7 @@ var AnthropicMessagesLanguageModel = class {
1762
1777
  toolChoice,
1763
1778
  providerOptions
1764
1779
  }) {
1765
- var _a, _b, _c, _d;
1780
+ var _a, _b, _c, _d, _e;
1766
1781
  const warnings = [];
1767
1782
  if (frequencyPenalty != null) {
1768
1783
  warnings.push({
@@ -1812,27 +1827,33 @@ var AnthropicMessagesLanguageModel = class {
1812
1827
  });
1813
1828
  }
1814
1829
  }
1815
- const jsonResponseTool = (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null ? {
1816
- type: "function",
1817
- name: "json",
1818
- description: "Respond with a JSON object.",
1819
- inputSchema: responseFormat.schema
1820
- } : void 0;
1821
1830
  const anthropicOptions = await (0, import_provider_utils11.parseProviderOptions)({
1822
1831
  provider: "anthropic",
1823
1832
  providerOptions,
1824
1833
  schema: anthropicProviderOptions
1825
1834
  });
1835
+ const {
1836
+ maxOutputTokens: maxOutputTokensForModel,
1837
+ supportsStructuredOutput,
1838
+ isKnownModel
1839
+ } = getModelCapabilities(this.modelId);
1840
+ const structureOutputMode = (_a = anthropicOptions == null ? void 0 : anthropicOptions.structuredOutputMode) != null ? _a : "jsonTool";
1841
+ const useStructuredOutput = structureOutputMode === "outputFormat" || structureOutputMode === "auto" && supportsStructuredOutput;
1842
+ const jsonResponseTool = (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null && !useStructuredOutput ? {
1843
+ type: "function",
1844
+ name: "json",
1845
+ description: "Respond with a JSON object.",
1846
+ inputSchema: responseFormat.schema
1847
+ } : void 0;
1826
1848
  const cacheControlValidator = new CacheControlValidator();
1827
1849
  const { prompt: messagesPrompt, betas } = await convertToAnthropicMessagesPrompt({
1828
1850
  prompt,
1829
- sendReasoning: (_a = anthropicOptions == null ? void 0 : anthropicOptions.sendReasoning) != null ? _a : true,
1851
+ sendReasoning: (_b = anthropicOptions == null ? void 0 : anthropicOptions.sendReasoning) != null ? _b : true,
1830
1852
  warnings,
1831
1853
  cacheControlValidator
1832
1854
  });
1833
- const isThinking = ((_b = anthropicOptions == null ? void 0 : anthropicOptions.thinking) == null ? void 0 : _b.type) === "enabled";
1834
- const thinkingBudget = (_c = anthropicOptions == null ? void 0 : anthropicOptions.thinking) == null ? void 0 : _c.budgetTokens;
1835
- const { maxOutputTokens: maxOutputTokensForModel, knownModel } = getMaxOutputTokensForModel(this.modelId);
1855
+ const isThinking = ((_c = anthropicOptions == null ? void 0 : anthropicOptions.thinking) == null ? void 0 : _c.type) === "enabled";
1856
+ const thinkingBudget = (_d = anthropicOptions == null ? void 0 : anthropicOptions.thinking) == null ? void 0 : _d.budgetTokens;
1836
1857
  const maxTokens = maxOutputTokens != null ? maxOutputTokens : maxOutputTokensForModel;
1837
1858
  const baseArgs = {
1838
1859
  // model id:
@@ -1850,11 +1871,18 @@ var AnthropicMessagesLanguageModel = class {
1850
1871
  ...(anthropicOptions == null ? void 0 : anthropicOptions.effort) && {
1851
1872
  output_config: { effort: anthropicOptions.effort }
1852
1873
  },
1874
+ // structured output:
1875
+ ...useStructuredOutput && (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null && {
1876
+ output_format: {
1877
+ type: "json_schema",
1878
+ schema: responseFormat.schema
1879
+ }
1880
+ },
1853
1881
  // container with agent skills:
1854
1882
  ...(anthropicOptions == null ? void 0 : anthropicOptions.container) && {
1855
1883
  container: {
1856
1884
  id: anthropicOptions.container.id,
1857
- skills: (_d = anthropicOptions.container.skills) == null ? void 0 : _d.map((skill) => ({
1885
+ skills: (_e = anthropicOptions.container.skills) == null ? void 0 : _e.map((skill) => ({
1858
1886
  type: skill.type,
1859
1887
  skill_id: skill.skillId,
1860
1888
  version: skill.version
@@ -1897,7 +1925,7 @@ var AnthropicMessagesLanguageModel = class {
1897
1925
  }
1898
1926
  baseArgs.max_tokens = maxTokens + thinkingBudget;
1899
1927
  }
1900
- if (knownModel && baseArgs.max_tokens > maxOutputTokensForModel) {
1928
+ if (isKnownModel && baseArgs.max_tokens > maxOutputTokensForModel) {
1901
1929
  if (maxOutputTokens != null) {
1902
1930
  warnings.push({
1903
1931
  type: "unsupported-setting",
@@ -1923,6 +1951,9 @@ var AnthropicMessagesLanguageModel = class {
1923
1951
  if (anthropicOptions == null ? void 0 : anthropicOptions.effort) {
1924
1952
  betas.add("effort-2025-11-24");
1925
1953
  }
1954
+ if (useStructuredOutput) {
1955
+ betas.add("structured-outputs-2025-11-13");
1956
+ }
1926
1957
  const {
1927
1958
  tools: anthropicTools2,
1928
1959
  toolChoice: anthropicToolChoice,
@@ -1949,7 +1980,7 @@ var AnthropicMessagesLanguageModel = class {
1949
1980
  tool_choice: anthropicToolChoice
1950
1981
  },
1951
1982
  warnings: [...warnings, ...toolWarnings, ...cacheWarnings],
1952
- betas: /* @__PURE__ */ new Set([...betas, ...toolsBetas]),
1983
+ betas: /* @__PURE__ */ new Set([...betas, ...toolsBetas, ...userSuppliedBetas]),
1953
1984
  usesJsonResponseTool: jsonResponseTool != null
1954
1985
  };
1955
1986
  }
@@ -1959,8 +1990,20 @@ var AnthropicMessagesLanguageModel = class {
1959
1990
  }) {
1960
1991
  return (0, import_provider_utils11.combineHeaders)(
1961
1992
  await (0, import_provider_utils11.resolve)(this.config.headers),
1962
- betas.size > 0 ? { "anthropic-beta": Array.from(betas).join(",") } : {},
1963
- headers
1993
+ headers,
1994
+ betas.size > 0 ? { "anthropic-beta": Array.from(betas).join(",") } : {}
1995
+ );
1996
+ }
1997
+ async getBetasFromHeaders(requestHeaders) {
1998
+ var _a, _b;
1999
+ const configHeaders = await (0, import_provider_utils11.resolve)(this.config.headers);
2000
+ const configBetaHeader = (_a = configHeaders["anthropic-beta"]) != null ? _a : "";
2001
+ const requestBetaHeader = (_b = requestHeaders == null ? void 0 : requestHeaders["anthropic-beta"]) != null ? _b : "";
2002
+ return new Set(
2003
+ [
2004
+ ...configBetaHeader.toLowerCase().split(","),
2005
+ ...requestBetaHeader.toLowerCase().split(",")
2006
+ ].map((beta) => beta.trim()).filter((beta) => beta !== "")
1964
2007
  );
1965
2008
  }
1966
2009
  buildRequestUrl(isStreaming) {
@@ -1996,7 +2039,10 @@ var AnthropicMessagesLanguageModel = class {
1996
2039
  }
1997
2040
  async doGenerate(options) {
1998
2041
  var _a, _b, _c, _d, _e, _f, _g, _h;
1999
- const { args, warnings, betas, usesJsonResponseTool } = await this.getArgs(options);
2042
+ const { args, warnings, betas, usesJsonResponseTool } = await this.getArgs({
2043
+ ...options,
2044
+ userSuppliedBetas: await this.getBetasFromHeaders(options.headers)
2045
+ });
2000
2046
  const citationDocuments = this.extractCitationDocuments(options.prompt);
2001
2047
  const {
2002
2048
  responseHeaders,
@@ -2261,7 +2307,10 @@ var AnthropicMessagesLanguageModel = class {
2261
2307
  };
2262
2308
  }
2263
2309
  async doStream(options) {
2264
- const { args, warnings, betas, usesJsonResponseTool } = await this.getArgs(options);
2310
+ const { args, warnings, betas, usesJsonResponseTool } = await this.getArgs({
2311
+ ...options,
2312
+ userSuppliedBetas: await this.getBetasFromHeaders(options.headers)
2313
+ });
2265
2314
  const citationDocuments = this.extractCitationDocuments(options.prompt);
2266
2315
  const body = { ...args, stream: true };
2267
2316
  const { responseHeaders, value: response } = await (0, import_provider_utils11.postJsonToApi)({
@@ -2725,27 +2774,49 @@ var AnthropicMessagesLanguageModel = class {
2725
2774
  };
2726
2775
  }
2727
2776
  };
2728
- function getMaxOutputTokensForModel(modelId) {
2777
+ function getModelCapabilities(modelId) {
2729
2778
  if (modelId.includes("claude-sonnet-4-5") || modelId.includes("claude-opus-4-5")) {
2730
2779
  return {
2731
2780
  maxOutputTokens: 64e3,
2732
- knownModel: true
2781
+ supportsStructuredOutput: true,
2782
+ isKnownModel: true
2733
2783
  };
2734
2784
  } else if (modelId.includes("claude-opus-4-1")) {
2735
2785
  return {
2736
2786
  maxOutputTokens: 32e3,
2737
- knownModel: true
2787
+ supportsStructuredOutput: true,
2788
+ isKnownModel: true
2738
2789
  };
2739
2790
  } else if (modelId.includes("claude-sonnet-4-") || modelId.includes("claude-3-7-sonnet") || modelId.includes("claude-haiku-4-5")) {
2740
- return { maxOutputTokens: 64e3, knownModel: true };
2791
+ return {
2792
+ maxOutputTokens: 64e3,
2793
+ supportsStructuredOutput: false,
2794
+ isKnownModel: true
2795
+ };
2741
2796
  } else if (modelId.includes("claude-opus-4-")) {
2742
- return { maxOutputTokens: 32e3, knownModel: true };
2797
+ return {
2798
+ maxOutputTokens: 32e3,
2799
+ supportsStructuredOutput: false,
2800
+ isKnownModel: true
2801
+ };
2743
2802
  } else if (modelId.includes("claude-3-5-haiku")) {
2744
- return { maxOutputTokens: 8192, knownModel: true };
2803
+ return {
2804
+ maxOutputTokens: 8192,
2805
+ supportsStructuredOutput: false,
2806
+ isKnownModel: true
2807
+ };
2745
2808
  } else if (modelId.includes("claude-3-haiku")) {
2746
- return { maxOutputTokens: 4096, knownModel: true };
2809
+ return {
2810
+ maxOutputTokens: 4096,
2811
+ supportsStructuredOutput: false,
2812
+ isKnownModel: true
2813
+ };
2747
2814
  } else {
2748
- return { maxOutputTokens: 4096, knownModel: false };
2815
+ return {
2816
+ maxOutputTokens: 4096,
2817
+ supportsStructuredOutput: false,
2818
+ isKnownModel: false
2819
+ };
2749
2820
  }
2750
2821
  }
2751
2822