UNPKG

@ai-sdk/amazon-bedrock

Version:
1,208 lines (1,207 loc) • 39.5 kB
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