@ai-sdk/amazon-bedrock 5.0.129 → 5.0.131

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.
@@ -4,7 +4,7 @@ let _ai_sdk_provider = require("@ai-sdk/provider");
4
4
  let _ai_sdk_provider_utils = require("@ai-sdk/provider-utils");
5
5
  let aws4fetch = require("aws4fetch");
6
6
  //#region src/version.ts
7
- const VERSION = "5.0.129";
7
+ const VERSION = "5.0.131";
8
8
  //#endregion
9
9
  //#region src/amazon-bedrock-sigv4-fetch.ts
10
10
  /**
@@ -3,7 +3,7 @@ import { InvalidArgumentError, LoadAPIKeyError, NoSuchModelError } from "@ai-sdk
3
3
  import { combineHeaders, getRuntimeEnvironmentUserAgent, isValidHostnamePart, loadOptionalSetting, loadSetting, normalizeHeaders, resolve, withUserAgentSuffix, withoutTrailingSlash } from "@ai-sdk/provider-utils";
4
4
  import { AwsV4Signer } from "aws4fetch";
5
5
  //#region src/version.ts
6
- const VERSION = "5.0.129";
6
+ const VERSION = "5.0.131";
7
7
  //#endregion
8
8
  //#region src/amazon-bedrock-sigv4-fetch.ts
9
9
  /**
@@ -295,6 +295,17 @@ choose how Amazon Bedrock generates structured outputs:
295
295
  - `"auto"`: Use native structured output when supported and otherwise fall
296
296
  back to the JSON tool. This is the default.
297
297
 
298
+ In `"auto"` mode, supported Claude 5 models use native output for compatible
299
+ schemas. Recursive references, open objects, and schemas with more than ten
300
+ optional properties fall back to the JSON tool, or JSON instructions for models
301
+ that reject forced tool use.
302
+
303
+ The JSON-tool fallback limits which application tools are available:
304
+ `toolChoice: 'none'` sends only the internal JSON response tool, and a named tool
305
+ choice sends only that application tool alongside the JSON response tool. The
306
+ fallback can produce a JSON response without calling the named application tool;
307
+ verify the selected call if your application requires it.
308
+
298
309
  In `"auto"` mode, Claude Sonnet 4.6 and Claude Haiku 4.5 use the JSON tool
299
310
  fallback because native structured output can be unreliable across workloads
300
311
  and Bedrock accounts. You can set `"outputFormat"` to opt into native structured
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/amazon-bedrock",
3
- "version": "5.0.129",
3
+ "version": "5.0.131",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -41,10 +41,10 @@
41
41
  }
42
42
  },
43
43
  "dependencies": {
44
- "@ai-sdk/anthropic": "4.0.93",
45
- "@ai-sdk/openai": "4.0.106",
44
+ "@ai-sdk/anthropic": "4.0.95",
45
+ "@ai-sdk/openai": "4.0.107",
46
46
  "@ai-sdk/provider": "4.0.35",
47
- "@ai-sdk/provider-utils": "5.0.72",
47
+ "@ai-sdk/provider-utils": "5.0.73",
48
48
  "@smithy/eventstream-codec": "^4.3.3",
49
49
  "@smithy/util-utf8": "^4.3.3",
50
50
  "aws4fetch": "^1.0.20"
@@ -17,9 +17,9 @@ export function isAnthropicModel({
17
17
  );
18
18
  }
19
19
 
20
- // Bedrock validates its own Messages schema. New Claude generations currently
21
- // reject native structured output and strict tools, so only known supported
22
- // Claude models receive those fields. Non-Claude models and opaque inference
20
+ // Bedrock validates its own Messages schema. Only known supported Claude
21
+ // models receive native structured output and strict tool fields.
22
+ // Non-Claude models and opaque inference
23
23
  // profile IDs retain their existing behavior.
24
24
  export function supportsStrictTools(modelId: string): boolean {
25
25
  return (
@@ -44,4 +44,6 @@ const MODELS_WITH_STRICT_TOOL_SUPPORT = [
44
44
  /claude-opus-4-(?:1|5|6)(?=[-.:]|$)/,
45
45
  /claude-sonnet-4-(?:5|6)(?=[-.:]|$)/,
46
46
  /claude-haiku-4-5(?=[-.:]|$)/,
47
+ /claude-(?:opus|sonnet)-5(?:-5)?(?:-\d{8})?(?:-v\d+)?(?=[:.]|$)/,
48
+ /claude-haiku-5-5(?:-\d{8})?(?:-v\d+)?(?=[:.]|$)/,
47
49
  ];
@@ -36,6 +36,7 @@ import {
36
36
  import {
37
37
  getModelCapabilities,
38
38
  sanitizeJsonSchema,
39
+ supportsNativeStructuredOutputSchema,
39
40
  } from '@ai-sdk/anthropic/internal';
40
41
  import { z } from 'zod/v4';
41
42
  import {
@@ -421,7 +422,8 @@ export class AmazonBedrockChatLanguageModel implements LanguageModelV4 {
421
422
  responseFormat.schema != null &&
422
423
  (structuredOutputMode === 'outputFormat' ||
423
424
  (structuredOutputMode === 'auto' &&
424
- modelSupportsNativeStructuredOutput));
425
+ modelSupportsNativeStructuredOutput &&
426
+ supportsNativeStructuredOutputSchema(responseFormat.schema)));
425
427
 
426
428
  const useJsonInstructionForStructuredOutput =
427
429
  !useNativeStructuredOutput &&
@@ -453,7 +455,17 @@ export class AmazonBedrockChatLanguageModel implements LanguageModelV4 {
453
455
 
454
456
  const { toolConfig, additionalTools, toolWarnings, betas } =
455
457
  await prepareTools({
456
- tools: jsonResponseTool ? [...(tools ?? []), jsonResponseTool] : tools,
458
+ tools: jsonResponseTool
459
+ ? [
460
+ ...(tools ?? []).filter(
461
+ tool =>
462
+ toolChoice?.type !== 'none' &&
463
+ (toolChoice?.type !== 'tool' ||
464
+ tool.name === toolChoice.toolName),
465
+ ),
466
+ jsonResponseTool,
467
+ ]
468
+ : tools,
457
469
  toolChoice:
458
470
  jsonResponseTool != null ? { type: 'required' } : toolChoice,
459
471
  modelId: this.modelId,
@@ -96,6 +96,14 @@ export async function prepareTools({
96
96
  rejectsForcedToolChoice && toolChoice.type === 'tool'
97
97
  ? providerTools.filter(tool => tool.name === toolChoice.toolName)
98
98
  : providerTools;
99
+ // A named tool choice keeps every function tool for these models (see
100
+ // below), so parallel tool use is disabled by default to keep the response
101
+ // to the named tool. `disableParallelToolUse: false` opts out.
102
+ const disableParallelToolUseForRequest =
103
+ disableParallelToolUse ??
104
+ (isAnthropicModel && toolChoice?.type === 'tool' && !rejectsForcedToolChoice
105
+ ? true
106
+ : undefined);
99
107
 
100
108
  let additionalTools: Record<string, unknown> | undefined = undefined;
101
109
  const amazonBedrockTools: AmazonBedrockTool[] = [];
@@ -112,7 +120,7 @@ export async function prepareTools({
112
120
  } = await prepareAnthropicTools({
113
121
  tools: providerTools,
114
122
  toolChoice,
115
- disableParallelToolUse,
123
+ disableParallelToolUse: disableParallelToolUseForRequest,
116
124
  supportsStructuredOutput: false,
117
125
  supportsStrictTools: false,
118
126
  rejectsForcedToolUse,
@@ -181,8 +189,12 @@ export async function prepareTools({
181
189
  preparedToolChoice = { type: 'auto' };
182
190
  }
183
191
 
192
+ // Anthropic models that accept forced tool use guarantee the named tool is
193
+ // called, so they keep every function tool. Other models only receive the
194
+ // named tool so they cannot call a different one.
184
195
  const filteredFunctionTools =
185
- toolChoice?.type === 'tool'
196
+ toolChoice?.type === 'tool' &&
197
+ (!isAnthropicModel || rejectsForcedToolChoice)
186
198
  ? functionTools.filter(t => t.name === toolChoice.toolName)
187
199
  : functionTools;
188
200
 
@@ -226,7 +238,7 @@ export async function prepareTools({
226
238
  if (
227
239
  isAnthropicModel &&
228
240
  !usingAnthropicTools &&
229
- disableParallelToolUse &&
241
+ disableParallelToolUseForRequest &&
230
242
  amazonBedrockTools.length > 0 &&
231
243
  preparedToolChoice?.type !== 'none'
232
244
  ) {
@@ -9,11 +9,13 @@ import {
9
9
  type SharedV4ProviderMetadata,
10
10
  } from '@ai-sdk/provider';
11
11
  import {
12
+ stringifyWithBigIntAndCycles,
12
13
  convertToBase64,
13
14
  getTopLevelMediaType,
14
15
  isFullMediaType,
15
16
  parseProviderOptions,
16
17
  resolveFullMediaType,
18
+ secureJsonParse,
17
19
  stripFileExtension,
18
20
  } from '@ai-sdk/provider-utils';
19
21
  import {
@@ -700,12 +702,27 @@ async function convertToolResultOutput({
700
702
  case 'json':
701
703
  case 'error-json':
702
704
  default:
703
- return [{ text: JSON.stringify(output.value) }];
705
+ return [{ text: stringifyWithBigIntAndCycles(output.value) }];
704
706
  }
705
707
  }
706
708
 
707
709
  // wrap invalid tool call input because Bedrock requires it to be an object
708
710
  function toBedrockToolInput(input: unknown): JSONObject {
711
+ if (typeof input === 'string') {
712
+ try {
713
+ const parsed = secureJsonParse(input);
714
+ if (
715
+ typeof parsed === 'object' &&
716
+ parsed !== null &&
717
+ !Array.isArray(parsed)
718
+ ) {
719
+ return parsed as JSONObject;
720
+ }
721
+ } catch {
722
+ // malformed JSON falls through to rawInvalidInput wrapper
723
+ }
724
+ }
725
+
709
726
  return typeof input === 'object' && input !== null && !Array.isArray(input)
710
727
  ? (input as JSONObject)
711
728
  : { rawInvalidInput: input as JSONValue };