@ai-sdk/anthropic 3.0.0-beta.56 → 3.0.0-beta.57

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @ai-sdk/anthropic
2
2
 
3
+ ## 3.0.0-beta.57
4
+
5
+ ### Patch Changes
6
+
7
+ - b8ea36e: feat(provider/anthropic): Anthropic-native structured outputs
8
+
3
9
  ## 3.0.0-beta.56
4
10
 
5
11
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -45,6 +45,11 @@ interface AnthropicMessageMetadata {
45
45
  type AnthropicMessagesModelId = 'claude-haiku-4-5' | 'claude-haiku-4-5-20251001' | 'claude-sonnet-4-5' | 'claude-sonnet-4-5-20250929' | 'claude-opus-4-1' | 'claude-opus-4-0' | 'claude-sonnet-4-0' | 'claude-opus-4-1-20250805' | 'claude-opus-4-20250514' | 'claude-sonnet-4-20250514' | 'claude-3-7-sonnet-latest' | 'claude-3-7-sonnet-20250219' | 'claude-3-5-haiku-latest' | 'claude-3-5-haiku-20241022' | 'claude-3-haiku-20240307' | (string & {});
46
46
  declare const anthropicProviderOptions: z.ZodObject<{
47
47
  sendReasoning: z.ZodOptional<z.ZodBoolean>;
48
+ structuredOutputMode: z.ZodOptional<z.ZodEnum<{
49
+ outputFormat: "outputFormat";
50
+ jsonTool: "jsonTool";
51
+ auto: "auto";
52
+ }>>;
48
53
  thinking: z.ZodOptional<z.ZodObject<{
49
54
  type: z.ZodUnion<readonly [z.ZodLiteral<"enabled">, z.ZodLiteral<"disabled">]>;
50
55
  budgetTokens: z.ZodOptional<z.ZodNumber>;
package/dist/index.d.ts CHANGED
@@ -45,6 +45,11 @@ interface AnthropicMessageMetadata {
45
45
  type AnthropicMessagesModelId = 'claude-haiku-4-5' | 'claude-haiku-4-5-20251001' | 'claude-sonnet-4-5' | 'claude-sonnet-4-5-20250929' | 'claude-opus-4-1' | 'claude-opus-4-0' | 'claude-sonnet-4-0' | 'claude-opus-4-1-20250805' | 'claude-opus-4-20250514' | 'claude-sonnet-4-20250514' | 'claude-3-7-sonnet-latest' | 'claude-3-7-sonnet-20250219' | 'claude-3-5-haiku-latest' | 'claude-3-5-haiku-20241022' | 'claude-3-haiku-20240307' | (string & {});
46
46
  declare const anthropicProviderOptions: z.ZodObject<{
47
47
  sendReasoning: z.ZodOptional<z.ZodBoolean>;
48
+ structuredOutputMode: z.ZodOptional<z.ZodEnum<{
49
+ outputFormat: "outputFormat";
50
+ jsonTool: "jsonTool";
51
+ auto: "auto";
52
+ }>>;
48
53
  thinking: z.ZodOptional<z.ZodObject<{
49
54
  type: z.ZodUnion<readonly [z.ZodLiteral<"enabled">, z.ZodLiteral<"disabled">]>;
50
55
  budgetTokens: z.ZodOptional<z.ZodNumber>;
package/dist/index.js CHANGED
@@ -31,7 +31,7 @@ var import_provider4 = require("@ai-sdk/provider");
31
31
  var import_provider_utils20 = require("@ai-sdk/provider-utils");
32
32
 
33
33
  // src/version.ts
34
- var VERSION = true ? "3.0.0-beta.56" : "0.0.0-test";
34
+ var VERSION = true ? "3.0.0-beta.57" : "0.0.0-test";
35
35
 
36
36
  // src/anthropic-messages-language-model.ts
37
37
  var import_provider3 = require("@ai-sdk/provider");
@@ -593,6 +593,14 @@ var anthropicProviderOptions = import_v43.z.object({
593
593
  * This allows you to deactivate reasoning inputs for models that do not support them.
594
594
  */
595
595
  sendReasoning: import_v43.z.boolean().optional(),
596
+ /**
597
+ * Determines how structured outputs are generated.
598
+ *
599
+ * - `outputFormat`: Use the `output_format` parameter to specify the structured output format.
600
+ * - `jsonTool`: Use a special 'json' tool to specify the structured output format.
601
+ * - `auto`: Use 'outputFormat' when supported, otherwise use 'jsonTool' (default).
602
+ */
603
+ structuredOutputMode: import_v43.z.enum(["outputFormat", "jsonTool", "auto"]).optional(),
596
604
  /**
597
605
  * Configuration for enabling Claude's extended thinking.
598
606
  *
@@ -1906,7 +1914,7 @@ var AnthropicMessagesLanguageModel = class {
1906
1914
  providerOptions,
1907
1915
  stream
1908
1916
  }) {
1909
- var _a, _b, _c, _d, _e;
1917
+ var _a, _b, _c, _d, _e, _f;
1910
1918
  const warnings = [];
1911
1919
  if (frequencyPenalty != null) {
1912
1920
  warnings.push({
@@ -1950,27 +1958,33 @@ var AnthropicMessagesLanguageModel = class {
1950
1958
  });
1951
1959
  }
1952
1960
  }
1953
- const jsonResponseTool = (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null ? {
1954
- type: "function",
1955
- name: "json",
1956
- description: "Respond with a JSON object.",
1957
- inputSchema: responseFormat.schema
1958
- } : void 0;
1959
1961
  const anthropicOptions = await (0, import_provider_utils11.parseProviderOptions)({
1960
1962
  provider: "anthropic",
1961
1963
  providerOptions,
1962
1964
  schema: anthropicProviderOptions
1963
1965
  });
1966
+ const {
1967
+ maxOutputTokens: maxOutputTokensForModel,
1968
+ supportsStructuredOutput,
1969
+ isKnownModel
1970
+ } = getModelCapabilities(this.modelId);
1971
+ const structureOutputMode = (_a = anthropicOptions == null ? void 0 : anthropicOptions.structuredOutputMode) != null ? _a : "auto";
1972
+ const useStructuredOutput = structureOutputMode === "outputFormat" || structureOutputMode === "auto" && supportsStructuredOutput;
1973
+ const jsonResponseTool = (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null && !useStructuredOutput ? {
1974
+ type: "function",
1975
+ name: "json",
1976
+ description: "Respond with a JSON object.",
1977
+ inputSchema: responseFormat.schema
1978
+ } : void 0;
1964
1979
  const cacheControlValidator = new CacheControlValidator();
1965
1980
  const { prompt: messagesPrompt, betas } = await convertToAnthropicMessagesPrompt({
1966
1981
  prompt,
1967
- sendReasoning: (_a = anthropicOptions == null ? void 0 : anthropicOptions.sendReasoning) != null ? _a : true,
1982
+ sendReasoning: (_b = anthropicOptions == null ? void 0 : anthropicOptions.sendReasoning) != null ? _b : true,
1968
1983
  warnings,
1969
1984
  cacheControlValidator
1970
1985
  });
1971
- const isThinking = ((_b = anthropicOptions == null ? void 0 : anthropicOptions.thinking) == null ? void 0 : _b.type) === "enabled";
1972
- const thinkingBudget = (_c = anthropicOptions == null ? void 0 : anthropicOptions.thinking) == null ? void 0 : _c.budgetTokens;
1973
- const { maxOutputTokens: maxOutputTokensForModel, knownModel } = getMaxOutputTokensForModel(this.modelId);
1986
+ const isThinking = ((_c = anthropicOptions == null ? void 0 : anthropicOptions.thinking) == null ? void 0 : _c.type) === "enabled";
1987
+ const thinkingBudget = (_d = anthropicOptions == null ? void 0 : anthropicOptions.thinking) == null ? void 0 : _d.budgetTokens;
1974
1988
  const maxTokens = maxOutputTokens != null ? maxOutputTokens : maxOutputTokensForModel;
1975
1989
  const baseArgs = {
1976
1990
  // model id:
@@ -1985,6 +1999,13 @@ var AnthropicMessagesLanguageModel = class {
1985
1999
  ...isThinking && {
1986
2000
  thinking: { type: "enabled", budget_tokens: thinkingBudget }
1987
2001
  },
2002
+ // structured output:
2003
+ ...useStructuredOutput && (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null && {
2004
+ output_format: {
2005
+ type: "json_schema",
2006
+ schema: responseFormat.schema
2007
+ }
2008
+ },
1988
2009
  // mcp servers:
1989
2010
  ...(anthropicOptions == null ? void 0 : anthropicOptions.mcpServers) && anthropicOptions.mcpServers.length > 0 && {
1990
2011
  mcp_servers: anthropicOptions.mcpServers.map((server) => ({
@@ -2002,7 +2023,7 @@ var AnthropicMessagesLanguageModel = class {
2002
2023
  ...(anthropicOptions == null ? void 0 : anthropicOptions.container) && {
2003
2024
  container: {
2004
2025
  id: anthropicOptions.container.id,
2005
- skills: (_d = anthropicOptions.container.skills) == null ? void 0 : _d.map((skill) => ({
2026
+ skills: (_e = anthropicOptions.container.skills) == null ? void 0 : _e.map((skill) => ({
2006
2027
  type: skill.type,
2007
2028
  skill_id: skill.skillId,
2008
2029
  version: skill.version
@@ -2045,7 +2066,7 @@ var AnthropicMessagesLanguageModel = class {
2045
2066
  }
2046
2067
  baseArgs.max_tokens = maxTokens + thinkingBudget;
2047
2068
  }
2048
- if (knownModel && baseArgs.max_tokens > maxOutputTokensForModel) {
2069
+ if (isKnownModel && baseArgs.max_tokens > maxOutputTokensForModel) {
2049
2070
  if (maxOutputTokens != null) {
2050
2071
  warnings.push({
2051
2072
  type: "unsupported-setting",
@@ -2071,9 +2092,12 @@ var AnthropicMessagesLanguageModel = class {
2071
2092
  });
2072
2093
  }
2073
2094
  }
2074
- if (stream && ((_e = anthropicOptions == null ? void 0 : anthropicOptions.toolStreaming) != null ? _e : true)) {
2095
+ if (stream && ((_f = anthropicOptions == null ? void 0 : anthropicOptions.toolStreaming) != null ? _f : true)) {
2075
2096
  betas.add("fine-grained-tool-streaming-2025-05-14");
2076
2097
  }
2098
+ if (useStructuredOutput) {
2099
+ betas.add("structured-outputs-2025-11-13");
2100
+ }
2077
2101
  const {
2078
2102
  tools: anthropicTools2,
2079
2103
  toolChoice: anthropicToolChoice,
@@ -2950,17 +2974,49 @@ var AnthropicMessagesLanguageModel = class {
2950
2974
  };
2951
2975
  }
2952
2976
  };
2953
- function getMaxOutputTokensForModel(modelId) {
2954
- if (modelId.includes("claude-sonnet-4-") || modelId.includes("claude-3-7-sonnet") || modelId.includes("claude-haiku-4-5")) {
2955
- return { maxOutputTokens: 64e3, knownModel: true };
2977
+ function getModelCapabilities(modelId) {
2978
+ if (modelId.includes("claude-sonnet-4-5")) {
2979
+ return {
2980
+ maxOutputTokens: 64e3,
2981
+ supportsStructuredOutput: true,
2982
+ isKnownModel: true
2983
+ };
2984
+ } else if (modelId.includes("claude-opus-4-1")) {
2985
+ return {
2986
+ maxOutputTokens: 32e3,
2987
+ supportsStructuredOutput: true,
2988
+ isKnownModel: true
2989
+ };
2990
+ } else if (modelId.includes("claude-sonnet-4-") || modelId.includes("claude-3-7-sonnet") || modelId.includes("claude-haiku-4-5")) {
2991
+ return {
2992
+ maxOutputTokens: 64e3,
2993
+ supportsStructuredOutput: false,
2994
+ isKnownModel: true
2995
+ };
2956
2996
  } else if (modelId.includes("claude-opus-4-")) {
2957
- return { maxOutputTokens: 32e3, knownModel: true };
2997
+ return {
2998
+ maxOutputTokens: 32e3,
2999
+ supportsStructuredOutput: false,
3000
+ isKnownModel: true
3001
+ };
2958
3002
  } else if (modelId.includes("claude-3-5-haiku")) {
2959
- return { maxOutputTokens: 8192, knownModel: true };
3003
+ return {
3004
+ maxOutputTokens: 8192,
3005
+ supportsStructuredOutput: false,
3006
+ isKnownModel: true
3007
+ };
2960
3008
  } else if (modelId.includes("claude-3-haiku")) {
2961
- return { maxOutputTokens: 4096, knownModel: true };
3009
+ return {
3010
+ maxOutputTokens: 4096,
3011
+ supportsStructuredOutput: false,
3012
+ isKnownModel: true
3013
+ };
2962
3014
  } else {
2963
- return { maxOutputTokens: 4096, knownModel: false };
3015
+ return {
3016
+ maxOutputTokens: 4096,
3017
+ supportsStructuredOutput: false,
3018
+ isKnownModel: false
3019
+ };
2964
3020
  }
2965
3021
  }
2966
3022