@ai-sdk/amazon-bedrock 5.0.62 → 5.0.65
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 +36 -0
- package/dist/anthropic/index.js +39 -2
- package/dist/anthropic/index.js.map +1 -1
- package/dist/index.js +178 -36
- package/dist/index.js.map +1 -1
- package/dist/mantle/index.cjs +1 -1
- package/dist/mantle/index.js +1 -1
- package/docs/08-amazon-bedrock.mdx +77 -0
- package/package.json +4 -4
- package/src/amazon-bedrock-api-types.ts +9 -1
- package/src/amazon-bedrock-chat-language-model-options.ts +27 -0
- package/src/amazon-bedrock-chat-language-model.ts +104 -27
- package/src/amazon-bedrock-prepare-tools.ts +30 -1
- package/src/amazon-bedrock-stream-error.ts +31 -0
- package/src/anthropic/amazon-bedrock-anthropic-fetch.ts +21 -1
- package/src/convert-amazon-bedrock-usage.ts +7 -1
- package/src/convert-to-amazon-bedrock-chat-messages.ts +71 -6
package/dist/mantle/index.cjs
CHANGED
|
@@ -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 ? "5.0.
|
|
38
|
+
var VERSION = true ? "5.0.65" : "0.0.0-test";
|
|
39
39
|
|
|
40
40
|
// src/amazon-bedrock-sigv4-fetch.ts
|
|
41
41
|
function createSigV4FetchFunction(getCredentials, fetch, service = "bedrock") {
|
package/dist/mantle/index.js
CHANGED
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
import { AwsV4Signer } from "aws4fetch";
|
|
24
24
|
|
|
25
25
|
// src/version.ts
|
|
26
|
-
var VERSION = true ? "5.0.
|
|
26
|
+
var VERSION = true ? "5.0.65" : "0.0.0-test";
|
|
27
27
|
|
|
28
28
|
// src/amazon-bedrock-sigv4-fetch.ts
|
|
29
29
|
function createSigV4FetchFunction(getCredentials, fetch, service = "bedrock") {
|
|
@@ -292,6 +292,83 @@ if (result.providerMetadata?.bedrock.trace) {
|
|
|
292
292
|
|
|
293
293
|
See the [Amazon Bedrock Guardrails documentation](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html) for more information.
|
|
294
294
|
|
|
295
|
+
#### Guard Content
|
|
296
|
+
|
|
297
|
+
You can mark individual text or image parts as guard content using `providerOptions` on the part itself. This wraps the part in a [`guardContent`](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_GuardrailConverseContentBlock.html) block, which tells Bedrock Guardrails to evaluate that content specifically.
|
|
298
|
+
|
|
299
|
+
For text parts, you can also specify `guardContentQualifiers` to indicate how the content should be treated by the guardrail (e.g. as a grounding source, a query, or guard content):
|
|
300
|
+
|
|
301
|
+
```ts
|
|
302
|
+
const result = await generateText({
|
|
303
|
+
model: bedrock('anthropic.claude-3-sonnet-20240229-v1:0'),
|
|
304
|
+
providerOptions: {
|
|
305
|
+
bedrock: {
|
|
306
|
+
guardrailConfig: {
|
|
307
|
+
guardrailIdentifier: '1abcd2ef34gh',
|
|
308
|
+
guardrailVersion: '1',
|
|
309
|
+
},
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
messages: [
|
|
313
|
+
{
|
|
314
|
+
role: 'user',
|
|
315
|
+
content: [
|
|
316
|
+
{
|
|
317
|
+
type: 'text',
|
|
318
|
+
text: 'London is the capital of UK. Tokyo is the capital of Japan.',
|
|
319
|
+
providerOptions: {
|
|
320
|
+
bedrock: {
|
|
321
|
+
guardContent: true,
|
|
322
|
+
guardContentQualifiers: ['grounding_source'],
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
type: 'text',
|
|
328
|
+
text: 'Some additional background information.',
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
type: 'text',
|
|
332
|
+
text: 'What is the capital of Japan?',
|
|
333
|
+
providerOptions: {
|
|
334
|
+
bedrock: {
|
|
335
|
+
guardContent: true,
|
|
336
|
+
guardContentQualifiers: ['query'],
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
],
|
|
341
|
+
},
|
|
342
|
+
],
|
|
343
|
+
});
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
Image parts can also be marked as guard content:
|
|
347
|
+
|
|
348
|
+
```ts
|
|
349
|
+
{
|
|
350
|
+
type: 'file',
|
|
351
|
+
data: {
|
|
352
|
+
type: 'data',
|
|
353
|
+
data: imageBase64,
|
|
354
|
+
},
|
|
355
|
+
mediaType: 'image/png',
|
|
356
|
+
providerOptions: {
|
|
357
|
+
bedrock: {
|
|
358
|
+
guardContent: true,
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
}
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
The available `guardContentQualifiers` are:
|
|
365
|
+
|
|
366
|
+
- `'grounding_source'` — content used as a grounding source for the guardrail
|
|
367
|
+
- `'query'` — content treated as a query to evaluate
|
|
368
|
+
- `'guard_content'` — content to be evaluated by the guardrail
|
|
369
|
+
|
|
370
|
+
See the [Amazon Bedrock Guardrails with Converse API documentation](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails-use-converse-api.html) for more information.
|
|
371
|
+
|
|
295
372
|
### Citations
|
|
296
373
|
|
|
297
374
|
Amazon Bedrock supports citations for document-based inputs across compatible models. When enabled:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/amazon-bedrock",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.65",
|
|
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.
|
|
45
|
-
"@ai-sdk/openai": "4.0.
|
|
44
|
+
"@ai-sdk/anthropic": "4.0.44",
|
|
45
|
+
"@ai-sdk/openai": "4.0.49",
|
|
46
46
|
"@ai-sdk/provider": "4.0.8",
|
|
47
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
47
|
+
"@ai-sdk/provider-utils": "5.0.32",
|
|
48
48
|
"@smithy/eventstream-codec": "^4.3.3",
|
|
49
49
|
"@smithy/util-utf8": "^4.3.3",
|
|
50
50
|
"aws4fetch": "^1.0.20"
|
|
@@ -183,8 +183,16 @@ export interface AmazonBedrockDocumentBlock {
|
|
|
183
183
|
};
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
export interface AmazonBedrockGuardrailTextBlock extends AmazonBedrockTextBlock {
|
|
187
|
+
qualifiers?: Array<'grounding_source' | 'query' | 'guard_content'>;
|
|
188
|
+
}
|
|
189
|
+
|
|
186
190
|
export interface AmazonBedrockGuardrailConverseContentBlock {
|
|
187
|
-
guardContent:
|
|
191
|
+
guardContent:
|
|
192
|
+
| {
|
|
193
|
+
text: AmazonBedrockGuardrailTextBlock;
|
|
194
|
+
}
|
|
195
|
+
| AmazonBedrockImageBlock;
|
|
188
196
|
}
|
|
189
197
|
|
|
190
198
|
export interface AmazonBedrockImageBlock {
|
|
@@ -106,6 +106,33 @@ export type AmazonBedrockFilePartProviderOptions = z.infer<
|
|
|
106
106
|
typeof amazonBedrockFilePartProviderOptions
|
|
107
107
|
>;
|
|
108
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Amazon Bedrock text part provider options for guardrail content.
|
|
111
|
+
* These options apply to individual text parts.
|
|
112
|
+
*/
|
|
113
|
+
export const amazonBedrockTextPartProviderOptions = z.object({
|
|
114
|
+
guardContent: z.boolean().optional(),
|
|
115
|
+
guardContentQualifiers: z
|
|
116
|
+
.array(z.enum(['grounding_source', 'query', 'guard_content']))
|
|
117
|
+
.optional(),
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
export type AmazonBedrockTextPartProviderOptions = z.infer<
|
|
121
|
+
typeof amazonBedrockTextPartProviderOptions
|
|
122
|
+
>;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Amazon Bedrock image part provider options for guardrail content.
|
|
126
|
+
* These options apply to individual image parts.
|
|
127
|
+
*/
|
|
128
|
+
export const amazonBedrockImagePartProviderOptions = z.object({
|
|
129
|
+
guardContent: z.boolean().optional(),
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
export type AmazonBedrockImagePartProviderOptions = z.infer<
|
|
133
|
+
typeof amazonBedrockImagePartProviderOptions
|
|
134
|
+
>;
|
|
135
|
+
|
|
109
136
|
export const amazonBedrockLanguageModelChatOptions = z.object({
|
|
110
137
|
/**
|
|
111
138
|
* Additional inference parameters that the model supports,
|
|
@@ -14,6 +14,7 @@ import type {
|
|
|
14
14
|
} from '@ai-sdk/provider';
|
|
15
15
|
import {
|
|
16
16
|
combineHeaders,
|
|
17
|
+
createProviderStreamError,
|
|
17
18
|
createJsonErrorResponseHandler,
|
|
18
19
|
createJsonResponseHandler,
|
|
19
20
|
injectJsonInstructionIntoMessages,
|
|
@@ -51,6 +52,10 @@ import {
|
|
|
51
52
|
} from './amazon-bedrock-anthropic-model-support';
|
|
52
53
|
import { AmazonBedrockErrorSchema } from './amazon-bedrock-error';
|
|
53
54
|
import { createAmazonBedrockEventStreamResponseHandler } from './amazon-bedrock-event-stream-response-handler';
|
|
55
|
+
import {
|
|
56
|
+
getAmazonBedrockStreamErrorMetadata,
|
|
57
|
+
type AmazonBedrockStreamErrorType,
|
|
58
|
+
} from './amazon-bedrock-stream-error';
|
|
54
59
|
import { prepareTools } from './amazon-bedrock-prepare-tools';
|
|
55
60
|
import {
|
|
56
61
|
convertAmazonBedrockUsage,
|
|
@@ -68,6 +73,32 @@ type AmazonBedrockChatConfig = {
|
|
|
68
73
|
generateId: () => string;
|
|
69
74
|
};
|
|
70
75
|
|
|
76
|
+
const anthropicProviderOptions = z.object({
|
|
77
|
+
disableParallelToolUse: z.boolean().optional(),
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
function createAmazonBedrockStreamError({
|
|
81
|
+
type,
|
|
82
|
+
error,
|
|
83
|
+
data,
|
|
84
|
+
}: {
|
|
85
|
+
type: AmazonBedrockStreamErrorType;
|
|
86
|
+
error: Record<string, unknown>;
|
|
87
|
+
data: unknown;
|
|
88
|
+
}) {
|
|
89
|
+
const message =
|
|
90
|
+
typeof error.message === 'string'
|
|
91
|
+
? error.message
|
|
92
|
+
: `Amazon Bedrock stream failed with ${type}`;
|
|
93
|
+
|
|
94
|
+
return createProviderStreamError({
|
|
95
|
+
message,
|
|
96
|
+
type,
|
|
97
|
+
...getAmazonBedrockStreamErrorMetadata(type),
|
|
98
|
+
data,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
71
102
|
export class AmazonBedrockChatLanguageModel implements LanguageModelV4 {
|
|
72
103
|
readonly specificationVersion = 'v4';
|
|
73
104
|
readonly provider = 'amazon-bedrock';
|
|
@@ -128,6 +159,12 @@ export class AmazonBedrockChatLanguageModel implements LanguageModelV4 {
|
|
|
128
159
|
})) ??
|
|
129
160
|
{};
|
|
130
161
|
|
|
162
|
+
const anthropicOptions = await parseProviderOptions({
|
|
163
|
+
provider: 'anthropic',
|
|
164
|
+
providerOptions,
|
|
165
|
+
schema: anthropicProviderOptions,
|
|
166
|
+
});
|
|
167
|
+
|
|
131
168
|
const warnings: SharedV4Warning[] = [];
|
|
132
169
|
|
|
133
170
|
if (frequencyPenalty != null) {
|
|
@@ -180,7 +217,10 @@ export class AmazonBedrockChatLanguageModel implements LanguageModelV4 {
|
|
|
180
217
|
}
|
|
181
218
|
|
|
182
219
|
const isAnthropicModel = this.modelId.includes('anthropic');
|
|
183
|
-
const
|
|
220
|
+
const openAIModelId = /^(?:[^.]+\.)?(openai\..+)$/.exec(this.modelId)?.[1];
|
|
221
|
+
const isOpenAIModel = openAIModelId != null;
|
|
222
|
+
const isOpenAIGptOssModel =
|
|
223
|
+
openAIModelId?.startsWith('openai.gpt-oss-') ?? false;
|
|
184
224
|
|
|
185
225
|
amazonBedrockOptions = resolveAmazonBedrockReasoningConfig({
|
|
186
226
|
reasoning,
|
|
@@ -231,6 +271,7 @@ export class AmazonBedrockChatLanguageModel implements LanguageModelV4 {
|
|
|
231
271
|
toolChoice:
|
|
232
272
|
jsonResponseTool != null ? { type: 'required' } : toolChoice,
|
|
233
273
|
modelId: this.modelId,
|
|
274
|
+
disableParallelToolUse: anthropicOptions?.disableParallelToolUse,
|
|
234
275
|
});
|
|
235
276
|
|
|
236
277
|
warnings.push(...toolWarnings);
|
|
@@ -329,11 +370,20 @@ export class AmazonBedrockChatLanguageModel implements LanguageModelV4 {
|
|
|
329
370
|
},
|
|
330
371
|
};
|
|
331
372
|
} else if (isOpenAIModel) {
|
|
332
|
-
//
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
373
|
+
// gpt-oss models expect `reasoning_effort` as a flat value, while
|
|
374
|
+
// GPT-5.x models expect a nested `reasoning.effort` object.
|
|
375
|
+
amazonBedrockOptions.additionalModelRequestFields = isOpenAIGptOssModel
|
|
376
|
+
? {
|
|
377
|
+
...amazonBedrockOptions.additionalModelRequestFields,
|
|
378
|
+
reasoning_effort: maxReasoningEffort,
|
|
379
|
+
}
|
|
380
|
+
: {
|
|
381
|
+
...amazonBedrockOptions.additionalModelRequestFields,
|
|
382
|
+
reasoning: {
|
|
383
|
+
...amazonBedrockOptions.additionalModelRequestFields?.reasoning,
|
|
384
|
+
effort: maxReasoningEffort,
|
|
385
|
+
},
|
|
386
|
+
};
|
|
337
387
|
} else {
|
|
338
388
|
// other models (such as Nova 2) use reasoningConfig format
|
|
339
389
|
amazonBedrockOptions.additionalModelRequestFields = {
|
|
@@ -756,9 +806,19 @@ export class AmazonBedrockChatLanguageModel implements LanguageModelV4 {
|
|
|
756
806
|
},
|
|
757
807
|
|
|
758
808
|
transform(chunk, controller) {
|
|
759
|
-
function enqueueError(
|
|
809
|
+
function enqueueError(
|
|
810
|
+
type: AmazonBedrockStreamErrorType,
|
|
811
|
+
amazonBedrockError: Record<string, unknown>,
|
|
812
|
+
) {
|
|
760
813
|
finishReason = { unified: 'error', raw: undefined };
|
|
761
|
-
controller.enqueue({
|
|
814
|
+
controller.enqueue({
|
|
815
|
+
type: 'error',
|
|
816
|
+
error: createAmazonBedrockStreamError({
|
|
817
|
+
type,
|
|
818
|
+
error: amazonBedrockError,
|
|
819
|
+
data: chunk.rawValue,
|
|
820
|
+
}),
|
|
821
|
+
});
|
|
762
822
|
}
|
|
763
823
|
|
|
764
824
|
// Emit raw chunk if requested (before anything else)
|
|
@@ -768,7 +828,8 @@ export class AmazonBedrockChatLanguageModel implements LanguageModelV4 {
|
|
|
768
828
|
|
|
769
829
|
// handle failed chunk parsing / validation:
|
|
770
830
|
if (!chunk.success) {
|
|
771
|
-
|
|
831
|
+
finishReason = { unified: 'error', raw: undefined };
|
|
832
|
+
controller.enqueue({ type: 'error', error: chunk.error });
|
|
772
833
|
return;
|
|
773
834
|
}
|
|
774
835
|
|
|
@@ -776,23 +837,32 @@ export class AmazonBedrockChatLanguageModel implements LanguageModelV4 {
|
|
|
776
837
|
|
|
777
838
|
// handle errors:
|
|
778
839
|
if (value.internalServerException) {
|
|
779
|
-
enqueueError(
|
|
840
|
+
enqueueError(
|
|
841
|
+
'internalServerException',
|
|
842
|
+
value.internalServerException,
|
|
843
|
+
);
|
|
780
844
|
return;
|
|
781
845
|
}
|
|
782
846
|
if (value.modelStreamErrorException) {
|
|
783
|
-
enqueueError(
|
|
847
|
+
enqueueError(
|
|
848
|
+
'modelStreamErrorException',
|
|
849
|
+
value.modelStreamErrorException,
|
|
850
|
+
);
|
|
784
851
|
return;
|
|
785
852
|
}
|
|
786
853
|
if (value.serviceUnavailableException) {
|
|
787
|
-
enqueueError(
|
|
854
|
+
enqueueError(
|
|
855
|
+
'serviceUnavailableException',
|
|
856
|
+
value.serviceUnavailableException,
|
|
857
|
+
);
|
|
788
858
|
return;
|
|
789
859
|
}
|
|
790
860
|
if (value.throttlingException) {
|
|
791
|
-
enqueueError(value.throttlingException);
|
|
861
|
+
enqueueError('throttlingException', value.throttlingException);
|
|
792
862
|
return;
|
|
793
863
|
}
|
|
794
864
|
if (value.validationException) {
|
|
795
|
-
enqueueError(value.validationException);
|
|
865
|
+
enqueueError('validationException', value.validationException);
|
|
796
866
|
return;
|
|
797
867
|
}
|
|
798
868
|
|
|
@@ -1244,6 +1314,13 @@ const AmazonBedrockRedactedReasoningSchema = z.object({
|
|
|
1244
1314
|
data: z.string(),
|
|
1245
1315
|
});
|
|
1246
1316
|
|
|
1317
|
+
const AmazonBedrockCacheDetailSchema = z
|
|
1318
|
+
.object({
|
|
1319
|
+
inputTokens: z.number(),
|
|
1320
|
+
ttl: z.string(),
|
|
1321
|
+
})
|
|
1322
|
+
.catchall(z.json());
|
|
1323
|
+
|
|
1247
1324
|
// limited version of the schema, focused on what is needed for the implementation
|
|
1248
1325
|
// this approach limits breakages when the API changes and increases efficiency
|
|
1249
1326
|
const AmazonBedrockResponseSchema = z.object({
|
|
@@ -1286,16 +1363,16 @@ const AmazonBedrockResponseSchema = z.object({
|
|
|
1286
1363
|
trace: z.unknown().nullish(),
|
|
1287
1364
|
performanceConfig: z.object({ latency: z.string() }).nullish(),
|
|
1288
1365
|
serviceTier: z.object({ type: z.string() }).nullish(),
|
|
1289
|
-
usage: z
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1366
|
+
usage: z
|
|
1367
|
+
.object({
|
|
1368
|
+
inputTokens: z.number(),
|
|
1369
|
+
outputTokens: z.number(),
|
|
1370
|
+
totalTokens: z.number(),
|
|
1371
|
+
cacheReadInputTokens: z.number().nullish(),
|
|
1372
|
+
cacheWriteInputTokens: z.number().nullish(),
|
|
1373
|
+
cacheDetails: z.array(AmazonBedrockCacheDetailSchema).nullish(),
|
|
1374
|
+
})
|
|
1375
|
+
.catchall(z.json()),
|
|
1299
1376
|
});
|
|
1300
1377
|
|
|
1301
1378
|
// limited version of the schema, focussed on what is needed for the implementation
|
|
@@ -1361,12 +1438,12 @@ const AmazonBedrockStreamSchema = z.object({
|
|
|
1361
1438
|
.object({
|
|
1362
1439
|
cacheReadInputTokens: z.number().nullish(),
|
|
1363
1440
|
cacheWriteInputTokens: z.number().nullish(),
|
|
1364
|
-
cacheDetails: z
|
|
1365
|
-
.array(z.object({ inputTokens: z.number(), ttl: z.string() }))
|
|
1366
|
-
.nullish(),
|
|
1441
|
+
cacheDetails: z.array(AmazonBedrockCacheDetailSchema).nullish(),
|
|
1367
1442
|
inputTokens: z.number(),
|
|
1368
1443
|
outputTokens: z.number(),
|
|
1444
|
+
totalTokens: z.number().optional(),
|
|
1369
1445
|
})
|
|
1446
|
+
.catchall(z.json())
|
|
1370
1447
|
.nullish(),
|
|
1371
1448
|
})
|
|
1372
1449
|
.nullish(),
|
|
@@ -19,10 +19,12 @@ export async function prepareTools({
|
|
|
19
19
|
tools,
|
|
20
20
|
toolChoice,
|
|
21
21
|
modelId,
|
|
22
|
+
disableParallelToolUse,
|
|
22
23
|
}: {
|
|
23
24
|
tools: LanguageModelV4CallOptions['tools'];
|
|
24
25
|
toolChoice?: LanguageModelV4CallOptions['toolChoice'];
|
|
25
26
|
modelId: string;
|
|
27
|
+
disableParallelToolUse?: boolean;
|
|
26
28
|
}): Promise<{
|
|
27
29
|
toolConfig: AmazonBedrockToolConfiguration;
|
|
28
30
|
additionalTools: Record<string, unknown> | undefined;
|
|
@@ -85,6 +87,7 @@ export async function prepareTools({
|
|
|
85
87
|
} = await prepareAnthropicTools({
|
|
86
88
|
tools: ProviderTools,
|
|
87
89
|
toolChoice,
|
|
90
|
+
disableParallelToolUse,
|
|
88
91
|
supportsStructuredOutput: false,
|
|
89
92
|
supportsStrictTools: false,
|
|
90
93
|
});
|
|
@@ -161,10 +164,36 @@ export async function prepareTools({
|
|
|
161
164
|
});
|
|
162
165
|
}
|
|
163
166
|
|
|
167
|
+
if (
|
|
168
|
+
isAnthropicModel &&
|
|
169
|
+
!usingAnthropicTools &&
|
|
170
|
+
disableParallelToolUse &&
|
|
171
|
+
amazonBedrockTools.length > 0 &&
|
|
172
|
+
toolChoice?.type !== 'none'
|
|
173
|
+
) {
|
|
174
|
+
additionalTools = {
|
|
175
|
+
tool_choice:
|
|
176
|
+
toolChoice?.type === 'required'
|
|
177
|
+
? { type: 'any', disable_parallel_tool_use: true }
|
|
178
|
+
: toolChoice?.type === 'tool'
|
|
179
|
+
? {
|
|
180
|
+
type: 'tool',
|
|
181
|
+
name: toolChoice.toolName,
|
|
182
|
+
disable_parallel_tool_use: true,
|
|
183
|
+
}
|
|
184
|
+
: { type: 'auto', disable_parallel_tool_use: true },
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
164
188
|
// Handle toolChoice for standard Bedrock tools, but NOT for Anthropic provider-defined tools
|
|
165
189
|
let amazonBedrockToolChoice: AmazonBedrockToolConfiguration['toolChoice'] =
|
|
166
190
|
undefined;
|
|
167
|
-
if (
|
|
191
|
+
if (
|
|
192
|
+
!usingAnthropicTools &&
|
|
193
|
+
additionalTools?.tool_choice == null &&
|
|
194
|
+
amazonBedrockTools.length > 0 &&
|
|
195
|
+
toolChoice
|
|
196
|
+
) {
|
|
168
197
|
const type = toolChoice.type;
|
|
169
198
|
switch (type) {
|
|
170
199
|
case 'auto':
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export type AmazonBedrockStreamErrorType =
|
|
2
|
+
| 'internalServerException'
|
|
3
|
+
| 'modelStreamErrorException'
|
|
4
|
+
| 'serviceUnavailableException'
|
|
5
|
+
| 'throttlingException'
|
|
6
|
+
| 'validationException';
|
|
7
|
+
|
|
8
|
+
export function getAmazonBedrockStreamErrorMetadata(type: string): {
|
|
9
|
+
statusCode?: number;
|
|
10
|
+
isRetryable?: boolean;
|
|
11
|
+
} {
|
|
12
|
+
switch (type) {
|
|
13
|
+
case 'internalServerException':
|
|
14
|
+
case 'InternalServerException':
|
|
15
|
+
return { statusCode: 500, isRetryable: true };
|
|
16
|
+
case 'modelStreamErrorException':
|
|
17
|
+
case 'ModelStreamErrorException':
|
|
18
|
+
return { statusCode: 424, isRetryable: true };
|
|
19
|
+
case 'serviceUnavailableException':
|
|
20
|
+
case 'ServiceUnavailableException':
|
|
21
|
+
return { statusCode: 503, isRetryable: true };
|
|
22
|
+
case 'throttlingException':
|
|
23
|
+
case 'ThrottlingException':
|
|
24
|
+
return { statusCode: 429, isRetryable: true };
|
|
25
|
+
case 'validationException':
|
|
26
|
+
case 'ValidationException':
|
|
27
|
+
return { statusCode: 400, isRetryable: false };
|
|
28
|
+
default:
|
|
29
|
+
return {};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
} from '@ai-sdk/provider-utils';
|
|
6
6
|
import { z } from 'zod/v4';
|
|
7
7
|
import { createAmazonBedrockEventStreamDecoder } from '../amazon-bedrock-event-stream-decoder';
|
|
8
|
+
import { getAmazonBedrockStreamErrorMetadata } from '../amazon-bedrock-stream-error';
|
|
8
9
|
|
|
9
10
|
const amazonBedrockErrorSchema = z.looseObject({
|
|
10
11
|
message: z.string().optional(),
|
|
@@ -93,9 +94,28 @@ function transformAmazonBedrockEventStreamToSSE(
|
|
|
93
94
|
controller.enqueue(textEncoder.encode('data: [DONE]\n\n'));
|
|
94
95
|
}
|
|
95
96
|
} else if (event.messageType === 'exception') {
|
|
97
|
+
const parsed = await safeParseJSON({ text: event.data });
|
|
98
|
+
const data = parsed.success ? parsed.value : event.data;
|
|
99
|
+
const message =
|
|
100
|
+
typeof data === 'object' &&
|
|
101
|
+
data != null &&
|
|
102
|
+
typeof (data as Record<string, unknown>).message === 'string'
|
|
103
|
+
? (data as Record<string, unknown>).message
|
|
104
|
+
: event.data;
|
|
105
|
+
const type = event.eventType ?? event.exceptionType ?? 'error';
|
|
106
|
+
const metadata = getAmazonBedrockStreamErrorMetadata(type);
|
|
107
|
+
|
|
96
108
|
controller.enqueue(
|
|
97
109
|
textEncoder.encode(
|
|
98
|
-
`data: ${JSON.stringify({
|
|
110
|
+
`data: ${JSON.stringify({
|
|
111
|
+
type: 'error',
|
|
112
|
+
error: {
|
|
113
|
+
type,
|
|
114
|
+
message,
|
|
115
|
+
...metadata,
|
|
116
|
+
data,
|
|
117
|
+
},
|
|
118
|
+
})}\n\n`,
|
|
99
119
|
),
|
|
100
120
|
);
|
|
101
121
|
}
|
|
@@ -1,12 +1,18 @@
|
|
|
1
|
-
import type { LanguageModelV4Usage } from '@ai-sdk/provider';
|
|
1
|
+
import type { JSONValue, LanguageModelV4Usage } from '@ai-sdk/provider';
|
|
2
2
|
import { createNullLanguageModelUsage } from '@ai-sdk/provider-utils';
|
|
3
3
|
|
|
4
4
|
export type AmazonBedrockUsage = {
|
|
5
|
+
[key: string]: JSONValue | undefined;
|
|
5
6
|
inputTokens: number;
|
|
6
7
|
outputTokens: number;
|
|
7
8
|
totalTokens?: number;
|
|
8
9
|
cacheReadInputTokens?: number | null;
|
|
9
10
|
cacheWriteInputTokens?: number | null;
|
|
11
|
+
cacheDetails?: Array<{
|
|
12
|
+
[key: string]: JSONValue | undefined;
|
|
13
|
+
inputTokens: number;
|
|
14
|
+
ttl: string;
|
|
15
|
+
}> | null;
|
|
10
16
|
};
|
|
11
17
|
|
|
12
18
|
export function convertAmazonBedrockUsage(
|
|
@@ -33,7 +33,11 @@ import {
|
|
|
33
33
|
type AmazonBedrockVideoFormat,
|
|
34
34
|
type AmazonBedrockVideoMimeType,
|
|
35
35
|
} from './amazon-bedrock-api-types';
|
|
36
|
-
import {
|
|
36
|
+
import {
|
|
37
|
+
amazonBedrockFilePartProviderOptions,
|
|
38
|
+
amazonBedrockImagePartProviderOptions,
|
|
39
|
+
amazonBedrockTextPartProviderOptions,
|
|
40
|
+
} from './amazon-bedrock-chat-language-model-options';
|
|
37
41
|
import { amazonBedrockReasoningMetadataSchema } from './amazon-bedrock-reasoning-metadata';
|
|
38
42
|
import { normalizeToolCallId } from './normalize-tool-call-id';
|
|
39
43
|
|
|
@@ -110,6 +114,40 @@ async function shouldEnableCitations(
|
|
|
110
114
|
return amazonBedrockOptions?.citations?.enabled ?? false;
|
|
111
115
|
}
|
|
112
116
|
|
|
117
|
+
async function getTextPartGuardContentOptions(
|
|
118
|
+
providerMetadata: SharedV4ProviderMetadata | undefined,
|
|
119
|
+
) {
|
|
120
|
+
return (
|
|
121
|
+
(await parseProviderOptions({
|
|
122
|
+
provider: 'amazonBedrock',
|
|
123
|
+
providerOptions: providerMetadata,
|
|
124
|
+
schema: amazonBedrockTextPartProviderOptions,
|
|
125
|
+
})) ??
|
|
126
|
+
(await parseProviderOptions({
|
|
127
|
+
provider: 'bedrock',
|
|
128
|
+
providerOptions: providerMetadata,
|
|
129
|
+
schema: amazonBedrockTextPartProviderOptions,
|
|
130
|
+
}))
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async function getImagePartGuardContentOptions(
|
|
135
|
+
providerMetadata: SharedV4ProviderMetadata | undefined,
|
|
136
|
+
) {
|
|
137
|
+
return (
|
|
138
|
+
(await parseProviderOptions({
|
|
139
|
+
provider: 'amazonBedrock',
|
|
140
|
+
providerOptions: providerMetadata,
|
|
141
|
+
schema: amazonBedrockImagePartProviderOptions,
|
|
142
|
+
})) ??
|
|
143
|
+
(await parseProviderOptions({
|
|
144
|
+
provider: 'bedrock',
|
|
145
|
+
providerOptions: providerMetadata,
|
|
146
|
+
schema: amazonBedrockImagePartProviderOptions,
|
|
147
|
+
}))
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
113
151
|
export async function convertToAmazonBedrockChatMessages(
|
|
114
152
|
prompt: LanguageModelV4Prompt,
|
|
115
153
|
isMistral: boolean = false,
|
|
@@ -162,9 +200,24 @@ export async function convertToAmazonBedrockChatMessages(
|
|
|
162
200
|
|
|
163
201
|
switch (part.type) {
|
|
164
202
|
case 'text': {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
203
|
+
const textOptions = await getTextPartGuardContentOptions(
|
|
204
|
+
part.providerOptions,
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
if (textOptions?.guardContent) {
|
|
208
|
+
amazonBedrockContent.push({
|
|
209
|
+
guardContent: {
|
|
210
|
+
text: {
|
|
211
|
+
text: part.text,
|
|
212
|
+
qualifiers: textOptions.guardContentQualifiers,
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
} else {
|
|
217
|
+
amazonBedrockContent.push({
|
|
218
|
+
text: part.text,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
168
221
|
break;
|
|
169
222
|
}
|
|
170
223
|
|
|
@@ -251,7 +304,11 @@ export async function convertToAmazonBedrockChatMessages(
|
|
|
251
304
|
|
|
252
305
|
switch (getTopLevelMediaType(fullMediaType)) {
|
|
253
306
|
case 'image': {
|
|
254
|
-
|
|
307
|
+
const imageOptions =
|
|
308
|
+
await getImagePartGuardContentOptions(
|
|
309
|
+
part.providerOptions,
|
|
310
|
+
);
|
|
311
|
+
const imageBlock: AmazonBedrockImageBlock = {
|
|
255
312
|
image: {
|
|
256
313
|
format:
|
|
257
314
|
getAmazonBedrockImageFormat(fullMediaType),
|
|
@@ -260,7 +317,15 @@ export async function convertToAmazonBedrockChatMessages(
|
|
|
260
317
|
functionality: 'File URL data',
|
|
261
318
|
}),
|
|
262
319
|
},
|
|
263
|
-
}
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
if (imageOptions?.guardContent) {
|
|
323
|
+
amazonBedrockContent.push({
|
|
324
|
+
guardContent: imageBlock,
|
|
325
|
+
});
|
|
326
|
+
} else {
|
|
327
|
+
amazonBedrockContent.push(imageBlock);
|
|
328
|
+
}
|
|
264
329
|
break;
|
|
265
330
|
}
|
|
266
331
|
case 'video': {
|