@ai-sdk/amazon-bedrock 5.0.0-beta.3 → 5.0.0-beta.30
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 +226 -4
- package/README.md +2 -0
- package/dist/anthropic/index.js +34 -6
- package/dist/anthropic/index.js.map +1 -1
- package/dist/anthropic/index.mjs +31 -3
- package/dist/anthropic/index.mjs.map +1 -1
- package/dist/index.d.mts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +132 -38
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +131 -33
- package/dist/index.mjs.map +1 -1
- package/docs/08-amazon-bedrock.mdx +52 -6
- package/package.json +4 -6
- package/src/anthropic/bedrock-anthropic-fetch.ts +26 -0
- package/src/anthropic/bedrock-anthropic-provider.ts +11 -1
- package/src/bedrock-api-types.ts +3 -0
- package/src/bedrock-chat-language-model.ts +98 -4
- package/src/bedrock-chat-options.ts +10 -0
- package/src/bedrock-prepare-tools.ts +1 -0
- package/src/convert-to-bedrock-chat-messages.ts +45 -33
|
@@ -514,6 +514,37 @@ console.log(amazonResult.text); // text response
|
|
|
514
514
|
See [AI SDK UI: Chatbot](/docs/ai-sdk-ui/chatbot#reasoning) for more details
|
|
515
515
|
on how to integrate reasoning into your chatbot.
|
|
516
516
|
|
|
517
|
+
## Service Tiers
|
|
518
|
+
|
|
519
|
+
Amazon Bedrock supports selecting an inference service tier per request via the `serviceTier` provider option.
|
|
520
|
+
|
|
521
|
+
```ts
|
|
522
|
+
import {
|
|
523
|
+
bedrock,
|
|
524
|
+
type AmazonBedrockLanguageModelOptions,
|
|
525
|
+
} from '@ai-sdk/amazon-bedrock';
|
|
526
|
+
import { generateText } from 'ai';
|
|
527
|
+
|
|
528
|
+
const result = await generateText({
|
|
529
|
+
model: bedrock('us.anthropic.claude-sonnet-4-20250514-v1:0'),
|
|
530
|
+
prompt: 'Summarize this support ticket backlog.',
|
|
531
|
+
providerOptions: {
|
|
532
|
+
bedrock: {
|
|
533
|
+
serviceTier: 'priority',
|
|
534
|
+
} satisfies AmazonBedrockLanguageModelOptions,
|
|
535
|
+
},
|
|
536
|
+
});
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
Supported values are:
|
|
540
|
+
|
|
541
|
+
- `reserved`
|
|
542
|
+
- `priority`
|
|
543
|
+
- `default`
|
|
544
|
+
- `flex`
|
|
545
|
+
|
|
546
|
+
See the [Amazon Bedrock service tiers documentation](https://docs.aws.amazon.com/bedrock/latest/userguide/service-tiers-inference.html) for model availability and behavior.
|
|
547
|
+
|
|
517
548
|
## Extended Context Window
|
|
518
549
|
|
|
519
550
|
Claude Sonnet 4 models on Amazon Bedrock support an extended context window of up to 1 million tokens when using the `context-1m-2025-08-07` beta feature.
|
|
@@ -546,6 +577,11 @@ Via Anthropic, Amazon Bedrock provides three provider-defined tools that can be
|
|
|
546
577
|
|
|
547
578
|
They are available via the `tools` property of the provider instance.
|
|
548
579
|
|
|
580
|
+
<Note>
|
|
581
|
+
Amazon Bedrock does not support strict mode on tool definitions. Setting
|
|
582
|
+
`strict: true` on a tool will be ignored and a warning will be emitted.
|
|
583
|
+
</Note>
|
|
584
|
+
|
|
549
585
|
### Bash Tool
|
|
550
586
|
|
|
551
587
|
The Bash Tool allows running bash commands. Here's how to create and use it:
|
|
@@ -1375,6 +1411,16 @@ const { text } = await generateText({
|
|
|
1375
1411
|
});
|
|
1376
1412
|
```
|
|
1377
1413
|
|
|
1414
|
+
### Provider Options
|
|
1415
|
+
|
|
1416
|
+
The following optional provider options are available for Bedrock Anthropic models:
|
|
1417
|
+
|
|
1418
|
+
- `metadata` _object_
|
|
1419
|
+
|
|
1420
|
+
Optional. Metadata to include with the request. See the [Anthropic API documentation](https://platform.claude.com/docs/en/api/messages/create) for details.
|
|
1421
|
+
|
|
1422
|
+
- `userId` _string_ - An external identifier for the end-user.
|
|
1423
|
+
|
|
1378
1424
|
### Cache Control
|
|
1379
1425
|
|
|
1380
1426
|
In the messages and message parts, you can use the `providerOptions` property to set cache control breakpoints.
|
|
@@ -1428,7 +1474,7 @@ They are available via the `tools` property of the provider instance.
|
|
|
1428
1474
|
|
|
1429
1475
|
```ts
|
|
1430
1476
|
import { bedrockAnthropic } from '@ai-sdk/amazon-bedrock/anthropic';
|
|
1431
|
-
import { generateText,
|
|
1477
|
+
import { generateText, isStepCount } from 'ai';
|
|
1432
1478
|
|
|
1433
1479
|
const result = await generateText({
|
|
1434
1480
|
model: bedrockAnthropic('us.anthropic.claude-sonnet-4-5-20250929-v1:0'),
|
|
@@ -1441,7 +1487,7 @@ const result = await generateText({
|
|
|
1441
1487
|
}),
|
|
1442
1488
|
},
|
|
1443
1489
|
prompt: 'List the files in my directory.',
|
|
1444
|
-
stopWhen:
|
|
1490
|
+
stopWhen: isStepCount(2),
|
|
1445
1491
|
});
|
|
1446
1492
|
```
|
|
1447
1493
|
|
|
@@ -1449,7 +1495,7 @@ const result = await generateText({
|
|
|
1449
1495
|
|
|
1450
1496
|
```ts
|
|
1451
1497
|
import { bedrockAnthropic } from '@ai-sdk/amazon-bedrock/anthropic';
|
|
1452
|
-
import { generateText,
|
|
1498
|
+
import { generateText, isStepCount } from 'ai';
|
|
1453
1499
|
|
|
1454
1500
|
const result = await generateText({
|
|
1455
1501
|
model: bedrockAnthropic('us.anthropic.claude-sonnet-4-5-20250929-v1:0'),
|
|
@@ -1462,7 +1508,7 @@ const result = await generateText({
|
|
|
1462
1508
|
}),
|
|
1463
1509
|
},
|
|
1464
1510
|
prompt: 'Update my README file.',
|
|
1465
|
-
stopWhen:
|
|
1511
|
+
stopWhen: isStepCount(5),
|
|
1466
1512
|
});
|
|
1467
1513
|
```
|
|
1468
1514
|
|
|
@@ -1470,7 +1516,7 @@ const result = await generateText({
|
|
|
1470
1516
|
|
|
1471
1517
|
```ts
|
|
1472
1518
|
import { bedrockAnthropic } from '@ai-sdk/amazon-bedrock/anthropic';
|
|
1473
|
-
import { generateText,
|
|
1519
|
+
import { generateText, isStepCount } from 'ai';
|
|
1474
1520
|
import fs from 'fs';
|
|
1475
1521
|
|
|
1476
1522
|
const result = await generateText({
|
|
@@ -1505,7 +1551,7 @@ const result = await generateText({
|
|
|
1505
1551
|
}),
|
|
1506
1552
|
},
|
|
1507
1553
|
prompt: 'Take a screenshot.',
|
|
1508
|
-
stopWhen:
|
|
1554
|
+
stopWhen: isStepCount(3),
|
|
1509
1555
|
});
|
|
1510
1556
|
```
|
|
1511
1557
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/amazon-bedrock",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.30",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
"@smithy/eventstream-codec": "^4.0.1",
|
|
39
39
|
"@smithy/util-utf8": "^4.0.0",
|
|
40
40
|
"aws4fetch": "^1.0.20",
|
|
41
|
-
"@ai-sdk/anthropic": "4.0.0-beta.
|
|
42
|
-
"@ai-sdk/provider": "4.0.0-beta.
|
|
43
|
-
"@ai-sdk/provider-utils": "5.0.0-beta.
|
|
41
|
+
"@ai-sdk/anthropic": "4.0.0-beta.26",
|
|
42
|
+
"@ai-sdk/provider": "4.0.0-beta.10",
|
|
43
|
+
"@ai-sdk/provider-utils": "5.0.0-beta.18"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@types/node": "20.17.24",
|
|
@@ -74,9 +74,7 @@
|
|
|
74
74
|
"build": "pnpm clean && tsup --tsconfig tsconfig.build.json",
|
|
75
75
|
"build:watch": "pnpm clean && tsup --watch",
|
|
76
76
|
"clean": "del-cli dist docs *.tsbuildinfo",
|
|
77
|
-
"lint": "eslint \"./**/*.ts*\"",
|
|
78
77
|
"type-check": "tsc --build",
|
|
79
|
-
"prettier-check": "prettier --check \"./**/*.ts*\"",
|
|
80
78
|
"test": "pnpm test:node && pnpm test:edge",
|
|
81
79
|
"test:update": "pnpm test:node -u",
|
|
82
80
|
"test:watch": "vitest --config vitest.node.config.js",
|
|
@@ -3,14 +3,40 @@ import {
|
|
|
3
3
|
FetchFunction,
|
|
4
4
|
safeParseJSON,
|
|
5
5
|
} from '@ai-sdk/provider-utils';
|
|
6
|
+
import { z } from 'zod/v4';
|
|
6
7
|
import { createBedrockEventStreamDecoder } from '../bedrock-event-stream-decoder';
|
|
7
8
|
|
|
9
|
+
const bedrockErrorSchema = z.looseObject({
|
|
10
|
+
message: z.string().optional(),
|
|
11
|
+
});
|
|
12
|
+
|
|
8
13
|
export function createBedrockAnthropicFetch(
|
|
9
14
|
baseFetch: FetchFunction,
|
|
10
15
|
): FetchFunction {
|
|
11
16
|
return async (url, options) => {
|
|
12
17
|
const response = await baseFetch(url, options);
|
|
13
18
|
|
|
19
|
+
// Transform Bedrock error responses into Anthropic error format
|
|
20
|
+
// so that anthropicFailedResponseHandler can extract the message.
|
|
21
|
+
if (!response.ok) {
|
|
22
|
+
const text = await response.text();
|
|
23
|
+
const parsed = await safeParseJSON({ text, schema: bedrockErrorSchema });
|
|
24
|
+
|
|
25
|
+
const message =
|
|
26
|
+
parsed.success && parsed.value.message ? parsed.value.message : text;
|
|
27
|
+
|
|
28
|
+
const anthropicError = JSON.stringify({
|
|
29
|
+
type: 'error',
|
|
30
|
+
error: { type: 'error', message },
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
return new Response(anthropicError, {
|
|
34
|
+
status: response.status,
|
|
35
|
+
statusText: response.statusText,
|
|
36
|
+
headers: response.headers,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
14
40
|
const contentType = response.headers.get('content-type');
|
|
15
41
|
if (
|
|
16
42
|
contentType?.includes('application/vnd.amazon.eventstream') &&
|
|
@@ -47,6 +47,10 @@ const BEDROCK_TOOL_BETA_MAP: Record<string, string> = {
|
|
|
47
47
|
text_editor_20250728: 'computer-use-2025-01-24',
|
|
48
48
|
computer_20250124: 'computer-use-2025-01-24',
|
|
49
49
|
computer_20241022: 'computer-use-2024-10-22',
|
|
50
|
+
tool_search_tool_regex_20251119: 'tool-search-tool-2025-10-19',
|
|
51
|
+
// BM25 is not currently supported on Bedrock, but including the beta flag
|
|
52
|
+
// so that Bedrock returns a more useful error message if it's used.
|
|
53
|
+
tool_search_tool_bm25_20251119: 'tool-search-tool-2025-10-19',
|
|
50
54
|
};
|
|
51
55
|
|
|
52
56
|
export interface BedrockAnthropicProvider extends ProviderV4 {
|
|
@@ -257,7 +261,13 @@ export function createBedrockAnthropic(
|
|
|
257
261
|
}`,
|
|
258
262
|
|
|
259
263
|
transformRequestBody: (args, betas) => {
|
|
260
|
-
const {
|
|
264
|
+
const {
|
|
265
|
+
model: _model,
|
|
266
|
+
stream: _stream,
|
|
267
|
+
tool_choice,
|
|
268
|
+
tools,
|
|
269
|
+
...rest
|
|
270
|
+
} = args;
|
|
261
271
|
|
|
262
272
|
const transformedToolChoice =
|
|
263
273
|
tool_choice != null
|
package/src/bedrock-api-types.ts
CHANGED
|
@@ -13,6 +13,9 @@ export interface BedrockConverseInput {
|
|
|
13
13
|
};
|
|
14
14
|
additionalModelRequestFields?: Record<string, unknown>;
|
|
15
15
|
additionalModelResponseFieldPaths?: string[];
|
|
16
|
+
serviceTier?: {
|
|
17
|
+
type: string;
|
|
18
|
+
};
|
|
16
19
|
guardrailConfig?:
|
|
17
20
|
| BedrockGuardrailConfiguration
|
|
18
21
|
| BedrockGuardrailStreamConfiguration
|
|
@@ -19,10 +19,14 @@ import {
|
|
|
19
19
|
combineHeaders,
|
|
20
20
|
createJsonErrorResponseHandler,
|
|
21
21
|
createJsonResponseHandler,
|
|
22
|
+
isCustomReasoning,
|
|
23
|
+
mapReasoningToProviderBudget,
|
|
24
|
+
mapReasoningToProviderEffort,
|
|
22
25
|
parseProviderOptions,
|
|
23
26
|
postJsonToApi,
|
|
24
27
|
resolve,
|
|
25
28
|
} from '@ai-sdk/provider-utils';
|
|
29
|
+
import { getModelCapabilities } from '@ai-sdk/anthropic/internal';
|
|
26
30
|
import { z } from 'zod/v4';
|
|
27
31
|
import {
|
|
28
32
|
BEDROCK_STOP_REASONS,
|
|
@@ -30,6 +34,7 @@ import {
|
|
|
30
34
|
BedrockStopReason,
|
|
31
35
|
} from './bedrock-api-types';
|
|
32
36
|
import {
|
|
37
|
+
AmazonBedrockLanguageModelOptions,
|
|
33
38
|
BedrockChatModelId,
|
|
34
39
|
amazonBedrockLanguageModelOptions,
|
|
35
40
|
} from './bedrock-chat-options';
|
|
@@ -70,6 +75,7 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
|
|
|
70
75
|
seed,
|
|
71
76
|
tools,
|
|
72
77
|
toolChoice,
|
|
78
|
+
reasoning,
|
|
73
79
|
providerOptions,
|
|
74
80
|
}: LanguageModelV4CallOptions): Promise<{
|
|
75
81
|
command: BedrockConverseInput;
|
|
@@ -78,7 +84,7 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
|
|
|
78
84
|
betas: Set<string>;
|
|
79
85
|
}> {
|
|
80
86
|
// Parse provider options
|
|
81
|
-
|
|
87
|
+
let bedrockOptions =
|
|
82
88
|
(await parseProviderOptions({
|
|
83
89
|
provider: 'bedrock',
|
|
84
90
|
providerOptions,
|
|
@@ -137,13 +143,26 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
|
|
|
137
143
|
}
|
|
138
144
|
|
|
139
145
|
const isAnthropicModel = this.modelId.includes('anthropic');
|
|
146
|
+
const isOpenAIModel = this.modelId.startsWith('openai.');
|
|
147
|
+
|
|
148
|
+
bedrockOptions = resolveBedrockReasoningConfig({
|
|
149
|
+
reasoning,
|
|
150
|
+
bedrockOptions,
|
|
151
|
+
warnings,
|
|
152
|
+
isAnthropicModel,
|
|
153
|
+
modelId: this.modelId,
|
|
154
|
+
});
|
|
155
|
+
|
|
140
156
|
const isThinkingEnabled =
|
|
141
157
|
bedrockOptions.reasoningConfig?.type === 'enabled' ||
|
|
142
158
|
bedrockOptions.reasoningConfig?.type === 'adaptive';
|
|
143
159
|
|
|
160
|
+
const { supportsStructuredOutput: modelSupportsStructuredOutput } =
|
|
161
|
+
getModelCapabilities(this.modelId);
|
|
162
|
+
|
|
144
163
|
const useNativeStructuredOutput =
|
|
145
164
|
isAnthropicModel &&
|
|
146
|
-
isThinkingEnabled &&
|
|
165
|
+
(modelSupportsStructuredOutput || isThinkingEnabled) &&
|
|
147
166
|
responseFormat?.type === 'json' &&
|
|
148
167
|
responseFormat.schema != null;
|
|
149
168
|
|
|
@@ -247,7 +266,6 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
|
|
|
247
266
|
|
|
248
267
|
const maxReasoningEffort =
|
|
249
268
|
bedrockOptions.reasoningConfig?.maxReasoningEffort;
|
|
250
|
-
const isOpenAIModel = this.modelId.startsWith('openai.');
|
|
251
269
|
|
|
252
270
|
if (maxReasoningEffort != null) {
|
|
253
271
|
if (isAnthropicModel) {
|
|
@@ -368,6 +386,7 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
|
|
|
368
386
|
const {
|
|
369
387
|
reasoningConfig: _,
|
|
370
388
|
additionalModelRequestFields: __,
|
|
389
|
+
serviceTier: ___,
|
|
371
390
|
...filteredBedrockOptions
|
|
372
391
|
} = providerOptions?.bedrock || {};
|
|
373
392
|
|
|
@@ -387,6 +406,11 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
|
|
|
387
406
|
...(Object.keys(inferenceConfig).length > 0 && {
|
|
388
407
|
inferenceConfig,
|
|
389
408
|
}),
|
|
409
|
+
...(bedrockOptions.serviceTier != null && {
|
|
410
|
+
serviceTier: {
|
|
411
|
+
type: bedrockOptions.serviceTier,
|
|
412
|
+
},
|
|
413
|
+
}),
|
|
390
414
|
...filteredBedrockOptions,
|
|
391
415
|
...(toolConfig.tools !== undefined && toolConfig.tools.length > 0
|
|
392
416
|
? { toolConfig }
|
|
@@ -441,7 +465,7 @@ export class BedrockChatLanguageModel implements LanguageModelV4 {
|
|
|
441
465
|
// map response content to content array
|
|
442
466
|
for (const part of response.output.message.content) {
|
|
443
467
|
// text
|
|
444
|
-
if (part.text) {
|
|
468
|
+
if (part.text != null) {
|
|
445
469
|
content.push({ type: 'text', text: part.text });
|
|
446
470
|
}
|
|
447
471
|
|
|
@@ -1122,3 +1146,73 @@ export const bedrockReasoningMetadataSchema = z.object({
|
|
|
1122
1146
|
export type BedrockReasoningMetadata = z.infer<
|
|
1123
1147
|
typeof bedrockReasoningMetadataSchema
|
|
1124
1148
|
>;
|
|
1149
|
+
|
|
1150
|
+
const bedrockReasoningEffortMap: Partial<
|
|
1151
|
+
Record<string, 'low' | 'medium' | 'high' | 'max'>
|
|
1152
|
+
> = {
|
|
1153
|
+
minimal: 'low',
|
|
1154
|
+
low: 'low',
|
|
1155
|
+
medium: 'medium',
|
|
1156
|
+
high: 'high',
|
|
1157
|
+
xhigh: 'max',
|
|
1158
|
+
};
|
|
1159
|
+
|
|
1160
|
+
function resolveBedrockReasoningConfig({
|
|
1161
|
+
reasoning,
|
|
1162
|
+
bedrockOptions,
|
|
1163
|
+
warnings,
|
|
1164
|
+
isAnthropicModel,
|
|
1165
|
+
modelId,
|
|
1166
|
+
}: {
|
|
1167
|
+
reasoning: LanguageModelV4CallOptions['reasoning'];
|
|
1168
|
+
bedrockOptions: AmazonBedrockLanguageModelOptions;
|
|
1169
|
+
warnings: SharedV4Warning[];
|
|
1170
|
+
isAnthropicModel: boolean;
|
|
1171
|
+
modelId: string;
|
|
1172
|
+
}): AmazonBedrockLanguageModelOptions {
|
|
1173
|
+
if (!isCustomReasoning(reasoning) || bedrockOptions.reasoningConfig != null) {
|
|
1174
|
+
return bedrockOptions;
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
const result = { ...bedrockOptions };
|
|
1178
|
+
|
|
1179
|
+
if (isAnthropicModel) {
|
|
1180
|
+
const capabilities = getModelCapabilities(modelId);
|
|
1181
|
+
|
|
1182
|
+
if (reasoning === 'none') {
|
|
1183
|
+
result.reasoningConfig = { type: 'disabled' };
|
|
1184
|
+
} else if (capabilities.supportsAdaptiveThinking) {
|
|
1185
|
+
const effort = mapReasoningToProviderEffort({
|
|
1186
|
+
reasoning,
|
|
1187
|
+
effortMap: bedrockReasoningEffortMap,
|
|
1188
|
+
warnings,
|
|
1189
|
+
});
|
|
1190
|
+
result.reasoningConfig = {
|
|
1191
|
+
type: 'adaptive',
|
|
1192
|
+
maxReasoningEffort: effort,
|
|
1193
|
+
};
|
|
1194
|
+
} else {
|
|
1195
|
+
const budgetTokens = mapReasoningToProviderBudget({
|
|
1196
|
+
reasoning,
|
|
1197
|
+
maxOutputTokens: capabilities.maxOutputTokens,
|
|
1198
|
+
maxReasoningBudget: capabilities.maxOutputTokens,
|
|
1199
|
+
warnings,
|
|
1200
|
+
});
|
|
1201
|
+
if (budgetTokens != null) {
|
|
1202
|
+
result.reasoningConfig = {
|
|
1203
|
+
type: 'enabled',
|
|
1204
|
+
budgetTokens,
|
|
1205
|
+
};
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
} else if (reasoning !== 'none') {
|
|
1209
|
+
const effort = mapReasoningToProviderEffort({
|
|
1210
|
+
reasoning,
|
|
1211
|
+
effortMap: bedrockReasoningEffortMap,
|
|
1212
|
+
warnings,
|
|
1213
|
+
});
|
|
1214
|
+
result.reasoningConfig = { maxReasoningEffort: effort };
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
return result;
|
|
1218
|
+
}
|
|
@@ -122,6 +122,16 @@ export const amazonBedrockLanguageModelOptions = z.object({
|
|
|
122
122
|
* Anthropic beta features to enable
|
|
123
123
|
*/
|
|
124
124
|
anthropicBeta: z.array(z.string()).optional(),
|
|
125
|
+
/**
|
|
126
|
+
* Service tier for the request.
|
|
127
|
+
* @see https://docs.aws.amazon.com/bedrock/latest/userguide/service-tiers-inference.html
|
|
128
|
+
*
|
|
129
|
+
* - 'reserved': Uses provisioned throughput capacity
|
|
130
|
+
* - 'priority': Prioritizes low-latency inference when capacity is available
|
|
131
|
+
* - 'default': Standard on-demand tier
|
|
132
|
+
* - 'flex': Lower-cost tier for flexible latency workloads
|
|
133
|
+
*/
|
|
134
|
+
serviceTier: z.enum(['reserved', 'priority', 'default', 'flex']).optional(),
|
|
125
135
|
});
|
|
126
136
|
|
|
127
137
|
export type AmazonBedrockLanguageModelOptions = z.infer<
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
} from '@ai-sdk/provider';
|
|
8
8
|
import {
|
|
9
9
|
convertToBase64,
|
|
10
|
+
isProviderReference,
|
|
10
11
|
parseProviderOptions,
|
|
11
12
|
stripFileExtension,
|
|
12
13
|
} from '@ai-sdk/provider-utils';
|
|
@@ -112,6 +113,12 @@ export async function convertToBedrockChatMessages(
|
|
|
112
113
|
}
|
|
113
114
|
|
|
114
115
|
case 'file': {
|
|
116
|
+
if (isProviderReference(part.data)) {
|
|
117
|
+
throw new UnsupportedFunctionalityError({
|
|
118
|
+
functionality: 'file parts with provider references',
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
115
122
|
if (part.data instanceof URL) {
|
|
116
123
|
// The AI SDK automatically downloads files for user file parts with URLs
|
|
117
124
|
throw new UnsupportedFunctionalityError({
|
|
@@ -253,6 +260,9 @@ export async function convertToBedrockChatMessages(
|
|
|
253
260
|
const message = block.messages[j];
|
|
254
261
|
const isLastMessage = j === block.messages.length - 1;
|
|
255
262
|
const { content } = message;
|
|
263
|
+
const hasReasoningBlocks = content.some(
|
|
264
|
+
part => part.type === 'reasoning',
|
|
265
|
+
);
|
|
256
266
|
|
|
257
267
|
for (let k = 0; k < content.length; k++) {
|
|
258
268
|
const part = content[k];
|
|
@@ -260,8 +270,8 @@ export async function convertToBedrockChatMessages(
|
|
|
260
270
|
|
|
261
271
|
switch (part.type) {
|
|
262
272
|
case 'text': {
|
|
263
|
-
// Skip empty text blocks
|
|
264
|
-
if (!part.text.trim()) {
|
|
273
|
+
// Skip empty text blocks unless reasoning blocks are present
|
|
274
|
+
if (!part.text.trim() && !hasReasoningBlocks) {
|
|
265
275
|
break;
|
|
266
276
|
}
|
|
267
277
|
|
|
@@ -287,33 +297,41 @@ export async function convertToBedrockChatMessages(
|
|
|
287
297
|
schema: bedrockReasoningMetadataSchema,
|
|
288
298
|
});
|
|
289
299
|
|
|
290
|
-
if (reasoningMetadata != null) {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
text: trimIfLast(
|
|
299
|
-
isLastBlock,
|
|
300
|
-
isLastMessage,
|
|
301
|
-
isLastContentPart,
|
|
302
|
-
part.text,
|
|
303
|
-
),
|
|
304
|
-
signature: reasoningMetadata.signature,
|
|
305
|
-
},
|
|
300
|
+
if (reasoningMetadata?.signature != null) {
|
|
301
|
+
// do not trim reasoning text when a signature is present:
|
|
302
|
+
// the signature validates the exact original bytes
|
|
303
|
+
bedrockContent.push({
|
|
304
|
+
reasoningContent: {
|
|
305
|
+
reasoningText: {
|
|
306
|
+
text: part.text,
|
|
307
|
+
signature: reasoningMetadata.signature,
|
|
306
308
|
},
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
309
|
+
},
|
|
310
|
+
});
|
|
311
|
+
} else if (reasoningMetadata?.redactedData != null) {
|
|
312
|
+
bedrockContent.push({
|
|
313
|
+
reasoningContent: {
|
|
314
|
+
redactedReasoning: {
|
|
315
|
+
data: reasoningMetadata.redactedData,
|
|
314
316
|
},
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
+
},
|
|
318
|
+
});
|
|
319
|
+
} else {
|
|
320
|
+
// trim the last text part if it's the last message in the block
|
|
321
|
+
// because Bedrock does not allow trailing whitespace
|
|
322
|
+
// in pre-filled assistant responses
|
|
323
|
+
bedrockContent.push({
|
|
324
|
+
reasoningContent: {
|
|
325
|
+
reasoningText: {
|
|
326
|
+
text: trimIfLast(
|
|
327
|
+
isLastBlock,
|
|
328
|
+
isLastMessage,
|
|
329
|
+
isLastContentPart,
|
|
330
|
+
part.text,
|
|
331
|
+
),
|
|
332
|
+
},
|
|
333
|
+
},
|
|
334
|
+
});
|
|
317
335
|
}
|
|
318
336
|
|
|
319
337
|
break;
|
|
@@ -352,12 +370,6 @@ export async function convertToBedrockChatMessages(
|
|
|
352
370
|
return { system, messages };
|
|
353
371
|
}
|
|
354
372
|
|
|
355
|
-
function isBedrockImageFormat(format: string): format is BedrockImageFormat {
|
|
356
|
-
return Object.values(BEDROCK_IMAGE_MIME_TYPES).includes(
|
|
357
|
-
format as BedrockImageFormat,
|
|
358
|
-
);
|
|
359
|
-
}
|
|
360
|
-
|
|
361
373
|
function getBedrockImageFormat(mimeType?: string): BedrockImageFormat {
|
|
362
374
|
if (!mimeType) {
|
|
363
375
|
throw new UnsupportedFunctionalityError({
|