@ai-sdk/amazon-bedrock
Version:
1,208 lines (1,207 loc) • 39.5 kB
JavaScript
import { InvalidArgumentError, LoadAPIKeyError, NoSuchModelError } from "@ai-sdk/provider";
import { combineHeaders, convertBase64ToUint8Array, getRuntimeEnvironmentUserAgent, isValidHostnamePart, lazySchema, loadOptionalSetting, loadSetting, normalizeHeaders, resolve, safeParseJSON, withUserAgentSuffix, withoutTrailingSlash, zodSchema } from "@ai-sdk/provider-utils";
import { AnthropicLanguageModel, anthropicTools, getModelCapabilities } from "@ai-sdk/anthropic/internal";
import { AwsV4Signer } from "aws4fetch";
import { z } from "zod/v4";
import { EventStreamCodec } from "@smithy/eventstream-codec";
import { fromUtf8, toUtf8 } from "@smithy/util-utf8";
//#region src/version.ts
const VERSION = "5.0.142";
//#endregion
//#region src/amazon-bedrock-sigv4-fetch.ts
/**
* Creates a fetch function that applies AWS Signature Version 4 signing.
*
* @param getCredentials - Function that returns the AWS credentials to use when signing.
* @param fetch - Optional original fetch implementation to wrap. Defaults to global fetch.
* @param service - The AWS service name to use for SigV4 signing scope. Defaults to 'bedrock'.
* @returns A FetchFunction that signs requests before passing them to the underlying fetch.
*/
function createSigV4FetchFunction(getCredentials, fetch, service = "bedrock") {
return async (input, init) => {
const effectiveFetch = fetch ?? globalThis.fetch;
const request = input instanceof Request ? input : void 0;
const originalHeaders = combineHeaders(normalizeHeaders(request?.headers), normalizeHeaders(init?.headers));
const headersWithUserAgent = withUserAgentSuffix(originalHeaders, `ai-sdk-amazon-bedrock/${VERSION}`, getRuntimeEnvironmentUserAgent());
let effectiveBody = init?.body ?? void 0;
if (effectiveBody === void 0 && request && request.body !== null) try {
effectiveBody = await request.clone().text();
} catch {}
if ((init?.method ?? request?.method)?.toUpperCase() !== "POST" || !effectiveBody) return effectiveFetch(input, {
...init,
headers: headersWithUserAgent
});
const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
const body = prepareBodyString(effectiveBody);
const credentials = await getCredentials();
const signingResult = await new AwsV4Signer({
url,
method: "POST",
headers: Object.entries(headersWithUserAgent).filter(([, value]) => isAscii(value)),
body,
region: credentials.region,
accessKeyId: credentials.accessKeyId,
secretAccessKey: credentials.secretAccessKey,
sessionToken: credentials.sessionToken,
service
}).sign();
const signedHeaders = normalizeHeaders(signingResult.headers);
const combinedHeaders = combineHeaders(headersWithUserAgent, signedHeaders);
return effectiveFetch(input, {
...init,
body,
headers: combinedHeaders
});
};
}
function prepareBodyString(body) {
if (typeof body === "string") return body;
else if (body instanceof Uint8Array) return new TextDecoder().decode(body);
else if (body instanceof ArrayBuffer) return new TextDecoder().decode(new Uint8Array(body));
else return JSON.stringify(body);
}
function isAscii(value) {
return !/[\u0080-\uffff]/.test(value);
}
/**
* Creates a fetch function that applies Bearer token authentication.
*
* @param apiKey - The API key to use for Bearer token authentication.
* @param fetch - Optional original fetch implementation to wrap. Defaults to global fetch.
* @returns A FetchFunction that adds Authorization header with Bearer token to requests.
*/
function createApiKeyFetchFunction(apiKey, fetch) {
return async (input, init) => {
const effectiveFetch = fetch ?? globalThis.fetch;
const originalHeaders = normalizeHeaders(init?.headers);
const headersWithUserAgent = withUserAgentSuffix(originalHeaders, `ai-sdk-amazon-bedrock/${VERSION}`, getRuntimeEnvironmentUserAgent());
const resolvedApiKey = await resolve(apiKey);
if (typeof apiKey !== "string" && (typeof resolvedApiKey !== "string" || !resolvedApiKey.trim())) throw new LoadAPIKeyError({ message: "Amazon Bedrock API key must be a non-empty string." });
const finalHeaders = combineHeaders(headersWithUserAgent, { Authorization: `Bearer ${typeof apiKey === "string" ? resolvedApiKey : resolvedApiKey.trim()}` });
return effectiveFetch(input, {
...init,
headers: finalHeaders
});
};
}
//#endregion
//#region src/amazon-bedrock-model-catalog.ts
const strictToolsAndNativeOutput = {
tools: { strict: true },
structuredOutput: { native: true }
};
const strictToolsOnly = {
tools: { strict: true },
structuredOutput: { native: false }
};
const noStrictToolsOrNativeOutput = {
tools: { strict: false },
structuredOutput: { native: false }
};
const claudeStructuredOutputCapabilities = {
"claude-opus-4": strictToolsAndNativeOutput,
"claude-sonnet-4": strictToolsAndNativeOutput,
"claude-opus-4-1": strictToolsAndNativeOutput,
"claude-opus-4-5": strictToolsAndNativeOutput,
"claude-sonnet-4-5": strictToolsAndNativeOutput,
"claude-haiku-4-5": strictToolsOnly,
"claude-opus-4-6": strictToolsAndNativeOutput,
"claude-sonnet-4-6": strictToolsOnly,
"claude-opus-4-7": noStrictToolsOrNativeOutput,
"claude-opus-4-8": noStrictToolsOrNativeOutput,
"claude-opus-5": strictToolsAndNativeOutput,
"claude-sonnet-5": strictToolsAndNativeOutput,
"claude-opus-5-5": strictToolsAndNativeOutput,
"claude-sonnet-5-5": strictToolsAndNativeOutput,
"claude-haiku-5-5": strictToolsAndNativeOutput,
"claude-fable-5": noStrictToolsOrNativeOutput,
"claude-fable-5-1": noStrictToolsOrNativeOutput,
"claude-fable-5-2": noStrictToolsOrNativeOutput
};
function resolveClaudeStructuredOutputCapabilities(modelId) {
if (!modelId.includes("claude-") || /claude-(?:instant|v?2|3)(?=[-.:]|$)/.test(modelId)) return strictToolsAndNativeOutput;
const canonicalModelId = /claude-[a-z]+-4-\d{1,2}(?=[-.:]|$)/.exec(modelId)?.[0] ?? /(claude-[a-z]+-\d+(?:-\d{1,2})?)(?:-\d{8})?(?:-v\d+)?(?=[:.]|$)/.exec(modelId)?.[1];
return canonicalModelId != null && Object.prototype.hasOwnProperty.call(claudeStructuredOutputCapabilities, canonicalModelId) ? claudeStructuredOutputCapabilities[canonicalModelId] : noStrictToolsOrNativeOutput;
}
const documentedLanguageModels = {
"amazon.titan-tg1-large": {
image: false,
objectGeneration: false,
tools: false,
streaming: false
},
"amazon.titan-text-express-v1": {
image: false,
objectGeneration: false,
tools: false,
streaming: false
},
"amazon.titan-text-lite-v1": {
image: false,
objectGeneration: false,
tools: false,
streaming: false
},
"us.amazon.nova-premier-v1:0": {
image: true,
objectGeneration: true,
tools: true,
streaming: true
},
"us.amazon.nova-pro-v1:0": {
image: true,
objectGeneration: true,
tools: true,
streaming: true
},
"us.amazon.nova-lite-v1:0": {
image: true,
objectGeneration: true,
tools: true,
streaming: true
},
"us.amazon.nova-micro-v1:0": {
image: false,
objectGeneration: true,
tools: true,
streaming: true
},
"anthropic.claude-haiku-4-5-20251001-v1:0": {
image: true,
objectGeneration: true,
tools: true,
streaming: true
},
"anthropic.claude-sonnet-4-20250514-v1:0": {
image: true,
objectGeneration: true,
tools: true,
streaming: true
},
"anthropic.claude-sonnet-4-5-20250929-v1:0": {
image: true,
objectGeneration: true,
tools: true,
streaming: true
},
"anthropic.claude-opus-4-20250514-v1:0": {
image: true,
objectGeneration: true,
tools: true,
streaming: true
},
"anthropic.claude-opus-4-1-20250805-v1:0": {
image: true,
objectGeneration: true,
tools: true,
streaming: true
},
"anthropic.claude-3-5-sonnet-20241022-v2:0": {
image: true,
objectGeneration: true,
tools: true,
streaming: true
},
"anthropic.claude-3-5-sonnet-20240620-v1:0": {
image: true,
objectGeneration: true,
tools: true,
streaming: true
},
"anthropic.claude-3-opus-20240229-v1:0": {
image: true,
objectGeneration: true,
tools: true,
streaming: true
},
"anthropic.claude-3-sonnet-20240229-v1:0": {
image: true,
objectGeneration: true,
tools: true,
streaming: true
},
"anthropic.claude-3-haiku-20240307-v1:0": {
image: true,
objectGeneration: true,
tools: true,
streaming: true
},
"us.anthropic.claude-sonnet-4-20250514-v1:0": {
image: true,
objectGeneration: true,
tools: true,
streaming: true
},
"us.anthropic.claude-sonnet-4-5-20250929-v1:0": {
image: true,
objectGeneration: true,
tools: true,
streaming: true
},
"us.anthropic.claude-opus-4-20250514-v1:0": {
image: true,
objectGeneration: true,
tools: true,
streaming: true
},
"us.anthropic.claude-opus-4-1-20250805-v1:0": {
image: true,
objectGeneration: true,
tools: true,
streaming: true
},
"us.anthropic.claude-3-5-sonnet-20241022-v2:0": {
image: true,
objectGeneration: true,
tools: true,
streaming: true
},
"us.anthropic.claude-3-5-sonnet-20240620-v1:0": {
image: true,
objectGeneration: true,
tools: true,
streaming: true
},
"us.anthropic.claude-3-sonnet-20240229-v1:0": {
image: true,
objectGeneration: true,
tools: true,
streaming: true
},
"us.anthropic.claude-3-opus-20240229-v1:0": {
image: true,
objectGeneration: true,
tools: true,
streaming: true
},
"us.anthropic.claude-3-haiku-20240307-v1:0": {
image: true,
objectGeneration: true,
tools: true,
streaming: true
},
"anthropic.claude-v2": {
image: false,
objectGeneration: false,
tools: false,
streaming: false
},
"anthropic.claude-v2:1": {
image: false,
objectGeneration: false,
tools: false,
streaming: false
},
"anthropic.claude-instant-v1": {
image: false,
objectGeneration: false,
tools: false,
streaming: false
},
"cohere.command-text-v14": {
image: false,
objectGeneration: false,
tools: false,
streaming: false
},
"cohere.command-light-text-v14": {
image: false,
objectGeneration: false,
tools: false,
streaming: false
},
"cohere.command-r-v1:0": {
image: false,
objectGeneration: false,
tools: true,
streaming: false
},
"cohere.command-r-plus-v1:0": {
image: false,
objectGeneration: false,
tools: true,
streaming: false
},
"us.deepseek.r1-v1:0": {
image: false,
objectGeneration: true,
tools: true,
streaming: true
},
"meta.llama3-8b-instruct-v1:0": {
image: false,
objectGeneration: false,
tools: false,
streaming: false
},
"meta.llama3-70b-instruct-v1:0": {
image: false,
objectGeneration: false,
tools: false,
streaming: false
},
"meta.llama3-1-8b-instruct-v1:0": {
image: false,
objectGeneration: false,
tools: false,
streaming: false
},
"meta.llama3-1-70b-instruct-v1:0": {
image: false,
objectGeneration: false,
tools: false,
streaming: false
},
"meta.llama3-1-405b-instruct-v1:0": {
image: false,
objectGeneration: false,
tools: false,
streaming: false
},
"meta.llama3-2-1b-instruct-v1:0": {
image: false,
objectGeneration: false,
tools: false,
streaming: false
},
"meta.llama3-2-3b-instruct-v1:0": {
image: false,
objectGeneration: false,
tools: false,
streaming: false
},
"meta.llama3-2-11b-instruct-v1:0": {
image: false,
objectGeneration: false,
tools: false,
streaming: false
},
"meta.llama3-2-90b-instruct-v1:0": {
image: false,
objectGeneration: false,
tools: false,
streaming: false
},
"us.meta.llama3-2-1b-instruct-v1:0": {
image: false,
objectGeneration: true,
tools: true,
streaming: true
},
"us.meta.llama3-2-3b-instruct-v1:0": {
image: false,
objectGeneration: true,
tools: true,
streaming: true
},
"us.meta.llama3-2-11b-instruct-v1:0": {
image: false,
objectGeneration: true,
tools: true,
streaming: true
},
"us.meta.llama3-2-90b-instruct-v1:0": {
image: false,
objectGeneration: true,
tools: true,
streaming: true
},
"us.meta.llama3-1-8b-instruct-v1:0": {
image: false,
objectGeneration: true,
tools: true,
streaming: true
},
"us.meta.llama3-1-70b-instruct-v1:0": {
image: false,
objectGeneration: true,
tools: true,
streaming: true
},
"us.meta.llama3-3-70b-instruct-v1:0": {
image: false,
objectGeneration: true,
tools: true,
streaming: true
},
"us.meta.llama4-scout-17b-instruct-v1:0": {
image: false,
objectGeneration: true,
tools: true,
streaming: true
},
"us.meta.llama4-maverick-17b-instruct-v1:0": {
image: false,
objectGeneration: true,
tools: true,
streaming: true
},
"mistral.mistral-7b-instruct-v0:2": {
image: false,
objectGeneration: false,
tools: false,
streaming: false
},
"mistral.mixtral-8x7b-instruct-v0:1": {
image: false,
objectGeneration: false,
tools: false,
streaming: false
},
"mistral.mistral-large-2402-v1:0": {
image: false,
objectGeneration: false,
tools: false,
streaming: false
},
"mistral.mistral-small-2402-v1:0": {
image: false,
objectGeneration: false,
tools: false,
streaming: false
},
"us.mistral.pixtral-large-2502-v1:0": {
image: true,
objectGeneration: true,
tools: true,
streaming: true
},
"openai.gpt-oss-120b-1:0": {
image: false,
objectGeneration: true,
tools: true,
streaming: true
},
"openai.gpt-oss-20b-1:0": {
image: false,
objectGeneration: true,
tools: true,
streaming: true
}
};
function createLanguageEntry(modelId) {
const documented = documentedLanguageModels[modelId];
const anthropic = getModelCapabilities(modelId);
const claude = modelId.includes("claude-");
const structuredOutputCapabilities = resolveClaudeStructuredOutputCapabilities(modelId);
const openaiModelId = /^(?:[^.]+\.)?(openai\..+)$/.exec(modelId)?.[1];
const nova2Reasoning = modelId.includes("amazon.nova-2-lite-v1:0");
const sampling = anthropic.rejectsSamplingParameters ? false : true;
return {
capabilities: { language: {
inputs: {
image: documented?.image ?? "unknown",
audio: "unknown"
},
objectGeneration: documented?.objectGeneration ?? "unknown",
tools: {
usage: documented?.tools ?? "unknown",
streaming: documented?.streaming ?? "unknown",
strict: structuredOutputCapabilities.tools.strict
},
reasoning: { support: openaiModelId != null || nova2Reasoning ? true : "unknown" },
sampling: {
temperature: sampling,
topP: sampling,
logprobs: false
},
structuredOutput: structuredOutputCapabilities.structuredOutput
} },
providerOptions: { language: {
structuredOutputMode: { condition: "Applies to Anthropic models; auto preserves each model’s native-output policy." },
additionalModelRequestFields: true,
reasoningConfig: { condition: "Supported reasoning configuration depends on the underlying model." },
anthropicBeta: { condition: "Requires an Anthropic model and a supported beta." },
serviceTier: { condition: "Requires a model and region supporting the selected tier." },
requestMetadata: true
} },
requestConfig: { language: {
anthropic: modelId.includes("anthropic"),
applicationInferenceProfile: modelId.includes(":application-inference-profile/"),
claude,
mistral: modelId.includes("mistral."),
openai: openaiModelId != null,
openaiGptOss: openaiModelId?.startsWith("openai.gpt-oss-") ?? false,
openaiGptOssReasoning: modelId.includes("openai.gpt-oss-"),
nova2Reasoning,
mantleRoute: /^(?:openai\.gpt-(?!oss-)|google\.gemma-4|xai\.)/.test(modelId) ? "openai/v1" : "v1"
} }
};
}
function getAmazonBedrockLanguageModelEntry(modelId) {
const entry = Object.prototype.hasOwnProperty.call(amazonBedrockModelCatalog, modelId) ? amazonBedrockModelCatalog[modelId] : void 0;
return entry?.capabilities.language != null ? entry : createLanguageEntry(modelId);
}
function getAmazonBedrockEmbeddingModelFamily(modelId) {
return modelId.includes("amazon.nova-") && modelId.includes("embed") ? "nova" : modelId.includes("cohere.embed-") ? "cohere" : "titan";
}
function embeddingEntry(modelId, defaultDimensions, customDimensions) {
const family = getAmazonBedrockEmbeddingModelFamily(modelId);
return {
capabilities: { embedding: {
defaultDimensions,
customDimensions
} },
providerOptions: { embedding: {
dimensions: family === "titan" && customDimensions,
normalize: family === "titan" && customDimensions,
embeddingDimension: family === "nova",
embeddingPurpose: family === "nova",
inputType: family === "cohere",
truncate: family !== "titan",
outputDimension: family === "cohere" && customDimensions
} }
};
}
const amazonBedrockImageModelCatalog = { "amazon.nova-canvas-v1:0": {
capabilities: { image: {
sizes: { description: "320–4096 pixels per side, divisible by 16; aspect ratio 1:4 to 4:1; fewer than 4,194,304 pixels." },
fileInput: true,
maskInput: true,
maxImagesPerCall: 5
} },
providerOptions: { image: {
quality: true,
negativeText: true,
cfgScale: true,
style: true,
taskType: true,
maskPrompt: true,
outPaintingMode: true,
similarityStrength: true
} }
} };
const rerankingEntry = {
capabilities: { reranking: {
documents: {
text: true,
object: true
},
topN: true
} },
providerOptions: { reranking: {
nextToken: true,
additionalModelRequestFields: true
} }
};
const languageModelIds = [
"amazon.titan-tg1-large",
"amazon.titan-text-express-v1",
"anthropic.claude-v2",
"anthropic.claude-v2:1",
"anthropic.claude-instant-v1",
"anthropic.claude-sonnet-5",
"anthropic.claude-sonnet-5-5",
"anthropic.claude-haiku-5-5",
"anthropic.claude-fable-5",
"anthropic.claude-fable-5-1",
"anthropic.claude-fable-5-2",
"anthropic.claude-opus-5",
"anthropic.claude-opus-5-5",
"anthropic.claude-opus-4-8",
"anthropic.claude-opus-4-7",
"anthropic.claude-opus-4-6-v1",
"anthropic.claude-sonnet-4-6-v1",
"anthropic.claude-opus-4-5-20251101-v1:0",
"anthropic.claude-haiku-4-5-20251001-v1:0",
"anthropic.claude-sonnet-4-5-20250929-v1:0",
"anthropic.claude-sonnet-4-20250514-v1:0",
"anthropic.claude-opus-4-20250514-v1:0",
"anthropic.claude-opus-4-1-20250805-v1:0",
"anthropic.claude-3-7-sonnet-20250219-v1:0",
"anthropic.claude-3-5-sonnet-20240620-v1:0",
"anthropic.claude-3-5-sonnet-20241022-v2:0",
"anthropic.claude-3-5-haiku-20241022-v1:0",
"anthropic.claude-3-sonnet-20240229-v1:0",
"anthropic.claude-3-haiku-20240307-v1:0",
"anthropic.claude-3-opus-20240229-v1:0",
"cohere.command-text-v14",
"cohere.command-light-text-v14",
"cohere.command-r-v1:0",
"cohere.command-r-plus-v1:0",
"meta.llama3-70b-instruct-v1:0",
"meta.llama3-8b-instruct-v1:0",
"meta.llama3-1-405b-instruct-v1:0",
"meta.llama3-1-70b-instruct-v1:0",
"meta.llama3-1-8b-instruct-v1:0",
"meta.llama3-2-11b-instruct-v1:0",
"meta.llama3-2-1b-instruct-v1:0",
"meta.llama3-2-3b-instruct-v1:0",
"meta.llama3-2-90b-instruct-v1:0",
"mistral.mistral-7b-instruct-v0:2",
"mistral.mixtral-8x7b-instruct-v0:1",
"mistral.mistral-large-2402-v1:0",
"mistral.mistral-small-2402-v1:0",
"openai.gpt-oss-120b-1:0",
"openai.gpt-oss-20b-1:0",
"amazon.titan-text-lite-v1",
"us.amazon.nova-premier-v1:0",
"us.amazon.nova-pro-v1:0",
"us.amazon.nova-micro-v1:0",
"us.amazon.nova-lite-v1:0",
"us.anthropic.claude-3-sonnet-20240229-v1:0",
"us.anthropic.claude-3-opus-20240229-v1:0",
"us.anthropic.claude-3-haiku-20240307-v1:0",
"us.anthropic.claude-3-5-sonnet-20240620-v1:0",
"us.anthropic.claude-3-5-haiku-20241022-v1:0",
"us.anthropic.claude-3-5-sonnet-20241022-v2:0",
"us.anthropic.claude-3-7-sonnet-20250219-v1:0",
"us.anthropic.claude-sonnet-5",
"us.anthropic.claude-sonnet-5-5",
"us.anthropic.claude-haiku-5-5",
"us.anthropic.claude-fable-5",
"us.anthropic.claude-fable-5-1",
"us.anthropic.claude-fable-5-2",
"us.anthropic.claude-opus-5",
"us.anthropic.claude-opus-5-5",
"us.anthropic.claude-opus-4-8",
"us.anthropic.claude-opus-4-7",
"us.anthropic.claude-opus-4-6-v1",
"us.anthropic.claude-sonnet-4-6-v1",
"us.anthropic.claude-opus-4-5-20251101-v1:0",
"us.anthropic.claude-sonnet-4-5-20250929-v1:0",
"us.anthropic.claude-sonnet-4-20250514-v1:0",
"us.anthropic.claude-opus-4-20250514-v1:0",
"us.anthropic.claude-opus-4-1-20250805-v1:0",
"us.anthropic.claude-haiku-4-5-20251001-v1:0",
"global.anthropic.claude-fable-5-1",
"global.anthropic.claude-fable-5-2",
"us.meta.llama3-2-11b-instruct-v1:0",
"us.meta.llama3-2-3b-instruct-v1:0",
"us.meta.llama3-2-90b-instruct-v1:0",
"us.meta.llama3-2-1b-instruct-v1:0",
"us.meta.llama3-1-8b-instruct-v1:0",
"us.meta.llama3-1-70b-instruct-v1:0",
"us.meta.llama3-3-70b-instruct-v1:0",
"us.deepseek.r1-v1:0",
"us.mistral.pixtral-large-2502-v1:0",
"us.meta.llama4-scout-17b-instruct-v1:0",
"us.meta.llama4-maverick-17b-instruct-v1:0",
"amazon.nova-2-lite-v1:0"
];
const amazonBedrockEmbeddingModelEntries = {
"amazon.titan-embed-text-v1": embeddingEntry("amazon.titan-embed-text-v1", 1536, false),
"amazon.titan-embed-text-v2:0": embeddingEntry("amazon.titan-embed-text-v2:0", 1024, true),
"amazon.nova-embed-text-v2:0": embeddingEntry("amazon.nova-embed-text-v2:0", 1024, true),
"cohere.embed-english-v3": embeddingEntry("cohere.embed-english-v3", 1024, false),
"cohere.embed-multilingual-v3": embeddingEntry("cohere.embed-multilingual-v3", 1024, false),
"cohere.embed-v4:0": embeddingEntry("cohere.embed-v4:0", 1536, true)
};
const amazonBedrockRerankingModelEntries = {
"amazon.rerank-v1:0": rerankingEntry,
"cohere.rerank-v3-5:0": rerankingEntry
};
const amazonBedrockModelCatalog = {
...Object.fromEntries(languageModelIds.map((id) => [id, createLanguageEntry(id)])),
...amazonBedrockEmbeddingModelEntries,
...amazonBedrockRerankingModelEntries,
...amazonBedrockImageModelCatalog
};
Object.fromEntries(Object.entries({
"us.anthropic.claude-fable-5-1": {
computerUse: true,
reasoning: true
},
"us.anthropic.claude-fable-5-2": {
computerUse: true,
reasoning: true
},
"us.anthropic.claude-sonnet-5-5": {
computerUse: true,
reasoning: true
},
"us.anthropic.claude-sonnet-5": {
computerUse: true,
reasoning: true
},
"us.anthropic.claude-haiku-5-5": {
computerUse: true,
reasoning: true
},
"us.anthropic.claude-fable-5": {
computerUse: true,
reasoning: true
},
"us.anthropic.claude-opus-4-8": {
computerUse: true,
reasoning: true
},
"us.anthropic.claude-opus-4-7": {
computerUse: true,
reasoning: true
},
"us.anthropic.claude-opus-4-6-v1": {
computerUse: true,
reasoning: true
},
"us.anthropic.claude-opus-4-5-20251101-v1:0": {
computerUse: true,
reasoning: true
},
"us.anthropic.claude-sonnet-4-5-20250929-v1:0": {
computerUse: true,
reasoning: true
},
"us.anthropic.claude-opus-4-20250514-v1:0": {
computerUse: true,
reasoning: true
},
"us.anthropic.claude-sonnet-4-20250514-v1:0": {
computerUse: true,
reasoning: true
},
"us.anthropic.claude-opus-4-1-20250805-v1:0": {
computerUse: true,
reasoning: true
},
"us.anthropic.claude-haiku-4-5-20251001-v1:0": {
computerUse: true,
reasoning: true
},
"us.anthropic.claude-3-5-sonnet-20241022-v2:0": {
computerUse: false,
reasoning: false
},
"anthropic.claude-3-5-haiku-20241022-v1:0": void 0,
"anthropic.claude-3-5-sonnet-20240620-v1:0": void 0,
"anthropic.claude-3-5-sonnet-20241022-v2:0": void 0,
"anthropic.claude-3-7-sonnet-20250219-v1:0": void 0,
"anthropic.claude-3-haiku-20240307-v1:0": void 0,
"anthropic.claude-3-opus-20240229-v1:0": void 0,
"anthropic.claude-3-sonnet-20240229-v1:0": void 0,
"anthropic.claude-fable-5": void 0,
"anthropic.claude-fable-5-1": void 0,
"anthropic.claude-fable-5-2": void 0,
"anthropic.claude-haiku-4-5-20251001-v1:0": void 0,
"anthropic.claude-haiku-5-5": void 0,
"anthropic.claude-opus-4-1-20250805-v1:0": void 0,
"anthropic.claude-opus-4-20250514-v1:0": void 0,
"anthropic.claude-opus-4-5-20251101-v1:0": void 0,
"anthropic.claude-opus-4-6-v1": void 0,
"anthropic.claude-opus-4-7": void 0,
"anthropic.claude-opus-4-8": void 0,
"anthropic.claude-opus-5": void 0,
"anthropic.claude-opus-5-5": void 0,
"anthropic.claude-sonnet-4-20250514-v1:0": void 0,
"anthropic.claude-sonnet-4-5-20250929-v1:0": void 0,
"anthropic.claude-sonnet-4-6-v1": void 0,
"anthropic.claude-sonnet-5": void 0,
"anthropic.claude-sonnet-5-5": void 0,
"global.anthropic.claude-fable-5-1": void 0,
"global.anthropic.claude-fable-5-2": void 0,
"us.anthropic.claude-3-5-haiku-20241022-v1:0": void 0,
"us.anthropic.claude-3-5-sonnet-20240620-v1:0": void 0,
"us.anthropic.claude-3-7-sonnet-20250219-v1:0": void 0,
"us.anthropic.claude-3-haiku-20240307-v1:0": void 0,
"us.anthropic.claude-3-opus-20240229-v1:0": void 0,
"us.anthropic.claude-3-sonnet-20240229-v1:0": void 0,
"us.anthropic.claude-opus-5": void 0,
"us.anthropic.claude-opus-5-5": void 0,
"us.anthropic.claude-sonnet-4-6-v1": void 0
}).flatMap(([id, support]) => {
if (support == null) return [];
const base = getAmazonBedrockLanguageModelEntry(id).capabilities.language;
return [[id, { capabilities: { language: {
...base,
inputs: {
image: true,
audio: false
},
objectGeneration: true,
tools: {
...base.tools,
usage: true,
streaming: true,
computerUse: support.computerUse
},
reasoning: { support: support.reasoning }
} } }]];
}));
Object.fromEntries(Object.entries({
"openai.gpt-oss-20b": {
chatCompletions: true,
responses: true
},
"openai.gpt-oss-120b": {
chatCompletions: true,
responses: true
},
"openai.gpt-oss-safeguard-20b": {
chatCompletions: true,
responses: false
},
"openai.gpt-oss-safeguard-120b": {
chatCompletions: true,
responses: false
}
}).map(([id, endpoints]) => {
return [id, { capabilities: { language: {
...getAmazonBedrockLanguageModelEntry(id).capabilities.language,
endpoints
} } }];
}));
//#endregion
//#region src/amazon-bedrock-anthropic-model-support.ts
function supportsStrictTools(modelId) {
return getAmazonBedrockLanguageModelEntry(modelId).capabilities.language.tools.strict;
}
function supportsNativeStructuredOutput(modelId) {
return getAmazonBedrockLanguageModelEntry(modelId).capabilities.language.structuredOutput.native;
}
//#endregion
//#region src/resolve-amazon-bedrock-base-url.ts
const AWS_PARTITION_DNS_SUFFIXES = [
{
regionPrefix: "cn-",
dnsSuffix: "amazonaws.com.cn"
},
{
regionPrefix: "us-iso-",
dnsSuffix: "c2s.ic.gov"
},
{
regionPrefix: "us-isob-",
dnsSuffix: "sc2s.sgov.gov"
},
{
regionPrefix: "eu-isoe-",
dnsSuffix: "cloud.adc-e.uk"
},
{
regionPrefix: "us-isof-",
dnsSuffix: "csp.hci.ic.gov"
},
{
regionPrefix: "eusc-",
dnsSuffix: "amazonaws.eu"
}
];
function resolveAmazonBedrockBaseURL({ baseURL, getRegion, service, serviceEndpointUrlEnvironmentVariableName }) {
const resolvedBaseURL = baseURL ?? loadOptionalSetting({
settingValue: void 0,
environmentVariableName: serviceEndpointUrlEnvironmentVariableName
}) ?? loadOptionalSetting({
settingValue: void 0,
environmentVariableName: "AWS_ENDPOINT_URL"
});
if (resolvedBaseURL != null) return withoutTrailingSlash(resolvedBaseURL) ?? resolvedBaseURL;
const region = getRegion();
if (!isValidHostnamePart(region)) throw new InvalidArgumentError({
argument: "region",
message: "Invalid AWS region. Expected a single DNS label (letters, digits, and hyphens). Use `baseURL` for custom endpoints."
});
const generatedBaseURL = `https://${service}.${region}.${AWS_PARTITION_DNS_SUFFIXES.find(({ regionPrefix }) => region.startsWith(regionPrefix))?.dnsSuffix ?? "amazonaws.com"}`;
return withoutTrailingSlash(generatedBaseURL) ?? generatedBaseURL;
}
//#endregion
//#region src/amazon-bedrock-event-stream-decoder.ts
function createAmazonBedrockEventStreamDecoder(body, processEvent) {
const codec = new EventStreamCodec(toUtf8, fromUtf8);
let buffer = /* @__PURE__ */ new Uint8Array(0);
const textDecoder = new TextDecoder();
return body.pipeThrough(new TransformStream({
async transform(chunk, controller) {
const newBuffer = new Uint8Array(buffer.length + chunk.length);
newBuffer.set(buffer);
newBuffer.set(chunk, buffer.length);
buffer = newBuffer;
while (buffer.length >= 4) {
const totalLength = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength).getUint32(0, false);
if (buffer.length < totalLength) break;
const subView = buffer.subarray(0, totalLength);
const decoded = codec.decode(subView);
buffer = buffer.slice(totalLength);
const messageType = decoded.headers[":message-type"]?.value;
const eventType = decoded.headers[":event-type"]?.value;
const exceptionType = decoded.headers[":exception-type"]?.value;
await processEvent({
messageType,
eventType,
exceptionType,
data: textDecoder.decode(decoded.body)
}, controller);
}
},
flush() {
if (buffer.length > 0) throw new Error(`Incomplete Amazon Bedrock event-stream frame: ${buffer.length} buffered bytes remain at end of stream.`);
}
}));
}
//#endregion
//#region src/amazon-bedrock-stream-error.ts
function getAmazonBedrockStreamErrorMetadata(type) {
switch (type) {
case "internalServerException":
case "InternalServerException": return {
statusCode: 500,
isRetryable: true
};
case "modelStreamErrorException":
case "ModelStreamErrorException": return {
statusCode: 424,
isRetryable: true
};
case "serviceUnavailableException":
case "ServiceUnavailableException": return {
statusCode: 503,
isRetryable: true
};
case "throttlingException":
case "ThrottlingException": return {
statusCode: 429,
isRetryable: true
};
case "validationException":
case "ValidationException": return {
statusCode: 400,
isRetryable: false
};
default: return {};
}
}
//#endregion
//#region src/anthropic/amazon-bedrock-anthropic-fetch.ts
const amazonBedrockErrorSchema = lazySchema(() => zodSchema(z.looseObject({ message: z.string().optional() })));
function createAmazonBedrockAnthropicFetch(baseFetch) {
return async (url, options) => {
const response = await baseFetch(url, options);
if (!response.ok) {
const text = await response.text();
const parsed = await safeParseJSON({
text,
schema: amazonBedrockErrorSchema
});
const message = parsed.success && parsed.value.message ? parsed.value.message : text;
const anthropicError = JSON.stringify({
type: "error",
error: {
type: "error",
message
}
});
return new Response(anthropicError, {
status: response.status,
statusText: response.statusText,
headers: response.headers
});
}
if (response.headers.get("content-type")?.includes("application/vnd.amazon.eventstream") && response.body != null) {
const transformedBody = transformAmazonBedrockEventStreamToSSE(response.body);
return new Response(transformedBody, {
status: response.status,
statusText: response.statusText,
headers: new Headers({
...Object.fromEntries(response.headers.entries()),
"content-type": "text/event-stream"
})
});
}
return response;
};
}
function transformAmazonBedrockEventStreamToSSE(body) {
const textEncoder = new TextEncoder();
return createAmazonBedrockEventStreamDecoder(body, async (event, controller) => {
if (event.messageType === "event") {
if (event.eventType === "chunk") {
const parsed = await safeParseJSON({ text: event.data });
if (!parsed.success) {
controller.enqueue(textEncoder.encode(`data: ${event.data}\n\n`));
return;
}
const bytes = parsed.value.bytes;
if (bytes) {
const anthropicEvent = new TextDecoder().decode(convertBase64ToUint8Array(bytes));
controller.enqueue(textEncoder.encode(`data: ${anthropicEvent}\n\n`));
} else controller.enqueue(textEncoder.encode(`data: ${event.data}\n\n`));
} else if (event.eventType === "messageStop") controller.enqueue(textEncoder.encode("data: [DONE]\n\n"));
} else if (event.messageType === "exception") {
const parsed = await safeParseJSON({ text: event.data });
const data = parsed.success ? parsed.value : event.data;
const message = typeof data === "object" && data != null && typeof data.message === "string" ? data.message : event.data;
const type = event.eventType ?? event.exceptionType ?? "error";
const metadata = getAmazonBedrockStreamErrorMetadata(type);
controller.enqueue(textEncoder.encode(`data: ${JSON.stringify({
type: "error",
error: {
type,
message,
...metadata,
data
}
})}\n\n`));
}
});
}
//#endregion
//#region src/anthropic/amazon-bedrock-anthropic-provider.ts
const BEDROCK_TOOL_VERSION_MAP = {
bash_20241022: "bash_20250124",
text_editor_20241022: "text_editor_20250728",
computer_20241022: "computer_20250124"
};
const BEDROCK_TOOL_NAME_MAP = { text_editor_20250728: "str_replace_based_edit_tool" };
const BEDROCK_TOOL_BETA_MAP = {
bash_20250124: "computer-use-2025-01-24",
bash_20241022: "computer-use-2024-10-22",
text_editor_20250124: "computer-use-2025-01-24",
text_editor_20241022: "computer-use-2024-10-22",
text_editor_20250429: "computer-use-2025-01-24",
text_editor_20250728: "computer-use-2025-01-24",
computer_20250124: "computer-use-2025-01-24",
computer_20241022: "computer-use-2024-10-22",
tool_search_tool_regex_20251119: "tool-search-tool-2025-10-19",
tool_search_tool_bm25_20251119: "tool-search-tool-2025-10-19"
};
/**
* Create an Amazon Bedrock Anthropic provider instance.
* This provider uses the native Anthropic API through Bedrock's InvokeModel endpoint,
* bypassing the Converse API for better feature compatibility.
*/
function createAmazonBedrockAnthropic(options = {}) {
const rawApiKey = typeof options.apiKey === "string" || options.apiKey == null ? loadOptionalSetting({
settingValue: options.apiKey,
environmentVariableName: "AWS_BEARER_TOKEN_BEDROCK"
}) : options.apiKey;
const apiKey = typeof rawApiKey === "string" ? rawApiKey.trim() || void 0 : rawApiKey;
const fetchFunction = createAmazonBedrockAnthropicFetch(apiKey ? createApiKeyFetchFunction(apiKey, options.fetch) : createSigV4FetchFunction(async () => {
const region = loadSetting({
settingValue: options.region,
settingName: "region",
environmentVariableName: "AWS_REGION",
description: "AWS region"
});
if (options.credentialProvider) try {
return {
...await options.credentialProvider(),
region
};
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
throw new Error(`AWS credential provider failed: ${errorMessage}. Please ensure your credential provider returns valid AWS credentials with accessKeyId and secretAccessKey properties.`);
}
try {
return {
region,
accessKeyId: loadSetting({
settingValue: options.accessKeyId,
settingName: "accessKeyId",
environmentVariableName: "AWS_ACCESS_KEY_ID",
description: "AWS access key ID"
}),
secretAccessKey: loadSetting({
settingValue: options.secretAccessKey,
settingName: "secretAccessKey",
environmentVariableName: "AWS_SECRET_ACCESS_KEY",
description: "AWS secret access key"
}),
sessionToken: loadOptionalSetting({
settingValue: options.sessionToken,
environmentVariableName: "AWS_SESSION_TOKEN"
})
};
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
if (errorMessage.includes("AWS_ACCESS_KEY_ID") || errorMessage.includes("accessKeyId")) throw new Error(`AWS SigV4 authentication requires AWS credentials. Please provide either:
1. Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables
2. Provide accessKeyId and secretAccessKey in options
3. Use a credentialProvider function
4. Use API key authentication with AWS_BEARER_TOKEN_BEDROCK or apiKey option
Original error: ${errorMessage}`);
if (errorMessage.includes("AWS_SECRET_ACCESS_KEY") || errorMessage.includes("secretAccessKey")) throw new Error(`AWS SigV4 authentication requires both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. Please ensure both credentials are provided.
Original error: ${errorMessage}`);
throw error;
}
}, options.fetch));
const getBaseURL = () => resolveAmazonBedrockBaseURL({
baseURL: options.baseURL,
getRegion: () => loadSetting({
settingValue: options.region,
settingName: "region",
environmentVariableName: "AWS_REGION",
description: "AWS region"
}),
service: "bedrock-runtime",
serviceEndpointUrlEnvironmentVariableName: "AWS_ENDPOINT_URL_BEDROCK_RUNTIME"
});
const getHeaders = async () => {
const baseHeaders = await resolve(options.headers) ?? {};
return withUserAgentSuffix(baseHeaders, `ai-sdk-amazon-bedrock/${VERSION}`);
};
const createChatModel = (modelId) => new AnthropicLanguageModel(modelId, {
provider: "bedrock.anthropic.messages",
baseURL: getBaseURL(),
headers: getHeaders,
fetch: fetchFunction,
buildRequestUrl: (baseURL, isStreaming) => `${baseURL}/model/${encodeURIComponent(modelId)}/${isStreaming ? "invoke-with-response-stream" : "invoke"}`,
transformRequestBody: (args, betas) => {
const { model: _model, stream: _stream, tool_choice, tools, ...rest } = args;
const transformedToolChoice = tool_choice != null ? {
type: tool_choice.type,
...tool_choice.name != null ? { name: tool_choice.name } : {}
} : void 0;
const requiredBetas = new Set(betas);
const transformedTools = tools?.map((rawTool) => {
const { eager_input_streaming: eagerInputStreaming, ...tool } = rawTool;
if (eagerInputStreaming === true) requiredBetas.add("fine-grained-tool-streaming-2025-05-14");
const toolType = tool.type;
if (toolType && toolType in BEDROCK_TOOL_VERSION_MAP) {
const newType = BEDROCK_TOOL_VERSION_MAP[toolType];
if (newType in BEDROCK_TOOL_BETA_MAP) requiredBetas.add(BEDROCK_TOOL_BETA_MAP[newType]);
const newName = newType in BEDROCK_TOOL_NAME_MAP ? BEDROCK_TOOL_NAME_MAP[newType] : tool.name;
return {
...tool,
type: newType,
name: newName
};
}
if (toolType && toolType in BEDROCK_TOOL_BETA_MAP) requiredBetas.add(BEDROCK_TOOL_BETA_MAP[toolType]);
if (toolType && toolType in BEDROCK_TOOL_NAME_MAP) return {
...tool,
name: BEDROCK_TOOL_NAME_MAP[toolType]
};
return tool;
});
return {
...rest,
...transformedTools != null ? { tools: transformedTools } : {},
...transformedToolChoice != null ? { tool_choice: transformedToolChoice } : {},
...requiredBetas.size > 0 ? { anthropic_beta: Array.from(requiredBetas) } : {},
anthropic_version: "bedrock-2023-05-31"
};
},
supportedUrls: () => ({}),
supportsNativeStructuredOutput: supportsNativeStructuredOutput(modelId),
supportsStrictTools: supportsStrictTools(modelId)
});
const provider = function(modelId) {
if (new.target) throw new Error("The Bedrock Anthropic model function cannot be called with the new keyword.");
return createChatModel(modelId);
};
provider.specificationVersion = "v4";
provider.languageModel = createChatModel;
provider.chat = createChatModel;
provider.messages = createChatModel;
provider.embeddingModel = (modelId) => {
throw new NoSuchModelError({
modelId,
modelType: "embeddingModel"
});
};
provider.textEmbeddingModel = provider.embeddingModel;
provider.imageModel = (modelId) => {
throw new NoSuchModelError({
modelId,
modelType: "imageModel"
});
};
provider.tools = anthropicTools;
return provider;
}
/**
* Default Bedrock Anthropic provider instance.
*/
const amazonBedrockAnthropic = createAmazonBedrockAnthropic();
//#endregion
export { amazonBedrockAnthropic, amazonBedrockAnthropic as bedrockAnthropic, createAmazonBedrockAnthropic, createAmazonBedrockAnthropic as createBedrockAnthropic };
//# sourceMappingURL=index.js.map