@ai-sdk/amazon-bedrock 4.0.167 → 4.0.168

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.
@@ -35,7 +35,7 @@ var import_provider_utils = require("@ai-sdk/provider-utils");
35
35
  var import_aws4fetch = require("aws4fetch");
36
36
 
37
37
  // src/version.ts
38
- var VERSION = true ? "4.0.167" : "0.0.0-test";
38
+ var VERSION = true ? "4.0.168" : "0.0.0-test";
39
39
 
40
40
  // src/bedrock-sigv4-fetch.ts
41
41
  function createSigV4FetchFunction(getCredentials, fetch, service = "bedrock") {
@@ -23,7 +23,7 @@ import {
23
23
  import { AwsV4Signer } from "aws4fetch";
24
24
 
25
25
  // src/version.ts
26
- var VERSION = true ? "4.0.167" : "0.0.0-test";
26
+ var VERSION = true ? "4.0.168" : "0.0.0-test";
27
27
 
28
28
  // src/bedrock-sigv4-fetch.ts
29
29
  function createSigV4FetchFunction(getCredentials, fetch, service = "bedrock") {
@@ -256,6 +256,51 @@ const { text } = await generateText({
256
256
  Amazon Bedrock language models can also be used in the `streamText` function
257
257
  (see [AI SDK Core](/docs/ai-sdk-core)).
258
258
 
259
+ ### Structured Outputs
260
+
261
+ For Anthropic models, you can use the `structuredOutputMode` provider option to
262
+ choose how Amazon Bedrock generates structured outputs:
263
+
264
+ - `"outputFormat"`: Use Bedrock's native `output_config.format` parameter.
265
+ - `"jsonTool"`: Use a special `json` tool with required tool choice.
266
+ - `"auto"`: Use native structured output when supported and otherwise fall
267
+ back to the JSON tool. This is the default.
268
+
269
+ In `"auto"` mode, Claude Sonnet 4.6 and Claude Haiku 4.5 use the JSON tool
270
+ fallback because native structured output can be unreliable across workloads
271
+ and Bedrock accounts. You can set `"outputFormat"` to opt into native structured
272
+ output when it works for your account and workload, or use `"jsonTool"` to force
273
+ the fallback for any model:
274
+
275
+ ```ts
276
+ import {
277
+ bedrock,
278
+ type AmazonBedrockLanguageModelOptions,
279
+ } from '@ai-sdk/amazon-bedrock';
280
+ import { generateText, Output } from 'ai';
281
+ import { z } from 'zod';
282
+
283
+ const { output } = await generateText({
284
+ model: bedrock('eu.anthropic.claude-sonnet-4-6'),
285
+ output: Output.object({
286
+ schema: z.object({
287
+ summary: z.string(),
288
+ findings: z.array(z.string()),
289
+ }),
290
+ }),
291
+ prompt: 'Summarize the inspection report.',
292
+ providerOptions: {
293
+ bedrock: {
294
+ structuredOutputMode: 'jsonTool',
295
+ } satisfies AmazonBedrockLanguageModelOptions,
296
+ },
297
+ });
298
+ ```
299
+
300
+ For parity with the Anthropic provider,
301
+ `providerOptions.anthropic.structuredOutputMode` is also honored for Anthropic
302
+ models on Bedrock. When both are provided, the `bedrock` value takes precedence.
303
+
259
304
  ### File Inputs
260
305
 
261
306
  <Note type="warning">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/amazon-bedrock",
3
- "version": "4.0.167",
3
+ "version": "4.0.168",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -1,14 +1,17 @@
1
1
  export function supportsStrictTools(modelId: string): boolean {
2
- return !rejectsNewerSchemaFields(modelId);
2
+ return !matchesModel(modelId, MODELS_WITHOUT_STRICT_TOOL_SUPPORT);
3
3
  }
4
4
 
5
5
  export function supportsNativeStructuredOutput(modelId: string): boolean {
6
- return !rejectsNewerSchemaFields(modelId);
6
+ return !matchesModel(
7
+ modelId,
8
+ MODELS_WITHOUT_RELIABLE_NATIVE_STRUCTURED_OUTPUT,
9
+ );
7
10
  }
8
11
 
9
12
  // Bedrock validates against its own copy of the Messages schema, which rejects
10
13
  // `output_config.format` and tool `strict` for the newest Claude models
11
- const MODELS_REJECTING_NEWER_SCHEMA_FIELDS = [
14
+ const MODELS_WITHOUT_STRICT_TOOL_SUPPORT = [
12
15
  'claude-opus-4-7',
13
16
  'claude-opus-4-8',
14
17
  'claude-opus-5',
@@ -16,8 +19,15 @@ const MODELS_REJECTING_NEWER_SCHEMA_FIELDS = [
16
19
  'claude-sonnet-5',
17
20
  ];
18
21
 
19
- function rejectsNewerSchemaFields(modelId: string): boolean {
20
- return MODELS_REJECTING_NEWER_SCHEMA_FIELDS.some(model =>
21
- modelId.includes(model),
22
- );
22
+ // Native structured output is unreliable for additional models even though
23
+ // their strict tool support remains available. Sonnet 4.6 can fail to adhere
24
+ // to complex schemas, while Haiku 4.5 support varies between Bedrock accounts.
25
+ const MODELS_WITHOUT_RELIABLE_NATIVE_STRUCTURED_OUTPUT = [
26
+ ...MODELS_WITHOUT_STRICT_TOOL_SUPPORT,
27
+ 'claude-sonnet-4-6',
28
+ 'claude-haiku-4-5',
29
+ ];
30
+
31
+ function matchesModel(modelId: string, models: string[]): boolean {
32
+ return models.some(model => modelId.includes(model));
23
33
  }
@@ -63,6 +63,7 @@ type BedrockChatConfig = {
63
63
 
64
64
  const anthropicProviderOptions = z.object({
65
65
  disableParallelToolUse: z.boolean().optional(),
66
+ structuredOutputMode: z.enum(['outputFormat', 'jsonTool', 'auto']).optional(),
66
67
  });
67
68
 
68
69
  export class BedrockChatLanguageModel implements LanguageModelV3 {
@@ -177,14 +178,52 @@ export class BedrockChatLanguageModel implements LanguageModelV3 {
177
178
  const { supportsStructuredOutput: modelSupportsStructuredOutput } =
178
179
  getModelCapabilities(this.modelId);
179
180
 
181
+ const structuredOutputMode =
182
+ bedrockOptions.structuredOutputMode ??
183
+ anthropicOptions?.structuredOutputMode ??
184
+ 'auto';
185
+
186
+ if (structuredOutputMode === 'jsonTool') {
187
+ const additionalModelRequestFields = {
188
+ ...bedrockOptions.additionalModelRequestFields,
189
+ };
190
+ const outputConfig = additionalModelRequestFields.output_config;
191
+
192
+ if (
193
+ outputConfig != null &&
194
+ typeof outputConfig === 'object' &&
195
+ !Array.isArray(outputConfig)
196
+ ) {
197
+ const outputConfigWithoutFormat = { ...outputConfig };
198
+ delete outputConfigWithoutFormat.format;
199
+
200
+ if (Object.keys(outputConfigWithoutFormat).length > 0) {
201
+ additionalModelRequestFields.output_config =
202
+ outputConfigWithoutFormat;
203
+ } else {
204
+ delete additionalModelRequestFields.output_config;
205
+ }
206
+
207
+ bedrockOptions.additionalModelRequestFields =
208
+ additionalModelRequestFields;
209
+ }
210
+ }
211
+
212
+ const modelSupportsNativeStructuredOutput =
213
+ supportsNativeStructuredOutput(this.modelId) &&
214
+ (modelSupportsStructuredOutput || isThinkingEnabled);
215
+
180
216
  const useNativeStructuredOutput =
181
217
  isAnthropicModel &&
182
- supportsNativeStructuredOutput(this.modelId) &&
183
- (modelSupportsStructuredOutput || isThinkingEnabled) &&
184
218
  responseFormat?.type === 'json' &&
185
- responseFormat.schema != null;
219
+ responseFormat.schema != null &&
220
+ (structuredOutputMode === 'outputFormat' ||
221
+ (structuredOutputMode === 'auto' &&
222
+ modelSupportsNativeStructuredOutput));
186
223
 
187
224
  const useJsonInstructionForStructuredOutput =
225
+ !useNativeStructuredOutput &&
226
+ structuredOutputMode !== 'jsonTool' &&
188
227
  isAnthropicModel &&
189
228
  !supportsStrictTools(this.modelId) &&
190
229
  responseFormat?.type === 'json' &&
@@ -438,6 +477,7 @@ export class BedrockChatLanguageModel implements LanguageModelV3 {
438
477
  reasoningConfig: _,
439
478
  additionalModelRequestFields: __,
440
479
  serviceTier: ___,
480
+ structuredOutputMode: ____,
441
481
  ...filteredBedrockOptions
442
482
  } = providerOptions?.bedrock || {};
443
483
 
@@ -107,6 +107,14 @@ export type BedrockFilePartProviderOptions = z.infer<
107
107
  >;
108
108
 
109
109
  export const amazonBedrockLanguageModelOptions = z.object({
110
+ /**
111
+ * Determines how structured outputs are generated for Anthropic models.
112
+ *
113
+ * - `outputFormat`: Use the native `output_config.format` parameter.
114
+ * - `jsonTool`: Use a special 'json' tool to specify the structured output format.
115
+ * - `auto`: Use `outputFormat` when supported, otherwise use `jsonTool` (default).
116
+ */
117
+ structuredOutputMode: z.enum(['outputFormat', 'jsonTool', 'auto']).optional(),
110
118
  /**
111
119
  * Additional inference parameters that the model supports,
112
120
  * beyond the base set of inference parameters that Converse