@ai-sdk/anthropic-aws 0.0.0 → 1.0.0-beta.10

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 ADDED
@@ -0,0 +1,97 @@
1
+ # @ai-sdk/anthropic-aws
2
+
3
+ ## 1.0.0-beta.10
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [19c5ee2]
8
+ - @ai-sdk/anthropic@4.0.0-beta.69
9
+
10
+ ## 1.0.0-beta.9
11
+
12
+ ### Patch Changes
13
+
14
+ - Updated dependencies [0416e3e]
15
+ - @ai-sdk/provider@4.0.0-beta.20
16
+ - @ai-sdk/anthropic@4.0.0-beta.68
17
+ - @ai-sdk/provider-utils@5.0.0-beta.50
18
+
19
+ ## 1.0.0-beta.8
20
+
21
+ ### Patch Changes
22
+
23
+ - b8396f0: trigger initial beta release
24
+ - Updated dependencies [b8396f0]
25
+ - @ai-sdk/anthropic@4.0.0-beta.67
26
+ - @ai-sdk/provider-utils@5.0.0-beta.49
27
+ - @ai-sdk/provider@4.0.0-beta.19
28
+
29
+ ## 1.0.0-canary.7
30
+
31
+ ### Patch Changes
32
+
33
+ - Updated dependencies [aeda373]
34
+ - Updated dependencies [375fdd7]
35
+ - Updated dependencies [b4507d5]
36
+ - @ai-sdk/provider-utils@5.0.0-canary.48
37
+ - @ai-sdk/anthropic@4.0.0-canary.66
38
+
39
+ ## 1.0.0-canary.6
40
+
41
+ ### Patch Changes
42
+
43
+ - Updated dependencies [bae5e2b]
44
+ - @ai-sdk/provider-utils@5.0.0-canary.47
45
+ - @ai-sdk/anthropic@4.0.0-canary.65
46
+
47
+ ## 1.0.0-canary.5
48
+
49
+ ### Patch Changes
50
+
51
+ - Updated dependencies [6b4d325]
52
+ - @ai-sdk/anthropic@4.0.0-canary.64
53
+
54
+ ## 1.0.0-canary.4
55
+
56
+ ### Patch Changes
57
+
58
+ - Updated dependencies [ce769dd]
59
+ - @ai-sdk/provider@4.0.0-canary.18
60
+ - @ai-sdk/anthropic@4.0.0-canary.63
61
+ - @ai-sdk/provider-utils@5.0.0-canary.46
62
+
63
+ ## 1.0.0-canary.3
64
+
65
+ ### Patch Changes
66
+
67
+ - Updated dependencies [ee798eb]
68
+ - Updated dependencies [daf6637]
69
+ - @ai-sdk/provider-utils@5.0.0-canary.45
70
+ - @ai-sdk/anthropic@4.0.0-canary.62
71
+
72
+ ## 1.0.0-canary.2
73
+
74
+ ### Patch Changes
75
+
76
+ - Updated dependencies [e02f041]
77
+ - @ai-sdk/anthropic@4.0.0-canary.61
78
+
79
+ ## 1.0.0-canary.1
80
+
81
+ ### Patch Changes
82
+
83
+ - Updated dependencies [6c93e36]
84
+ - Updated dependencies [f617ac2]
85
+ - @ai-sdk/provider-utils@5.0.0-canary.44
86
+ - @ai-sdk/anthropic@4.0.0-canary.60
87
+
88
+ ## 1.0.0-canary.0
89
+
90
+ ### Major Changes
91
+
92
+ - e617cba: feat(anthropic-aws): add Claude Platform on AWS provider
93
+
94
+ ### Patch Changes
95
+
96
+ - Updated dependencies [648705c]
97
+ - @ai-sdk/anthropic@4.0.0-canary.59
package/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2023 Vercel, Inc.
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
package/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # AI SDK - Claude Platform on AWS Provider
2
+
3
+ The **[Claude Platform on AWS provider](https://ai-sdk.dev/providers/ai-sdk-providers/anthropic-aws)** for the [AI SDK](https://ai-sdk.dev/docs)
4
+ gives you access to the Anthropic Messages API hosted in AWS at
5
+ `aws-external-anthropic.{region}.api.aws`, authenticated with AWS SigV4 or an
6
+ AWS-provisioned API key.
7
+
8
+ Same wire format and feature set as `@ai-sdk/anthropic` — model IDs, streaming,
9
+ prompt caching, tool use, computer use, Agent Skills, and `anthropic-beta`
10
+ headers all match the first-party Claude API.
11
+
12
+ ## Setup
13
+
14
+ ```bash
15
+ npm install @ai-sdk/anthropic-aws
16
+ ```
17
+
18
+ ## Provider Instance
19
+
20
+ ```ts
21
+ import { createAnthropicAws } from '@ai-sdk/anthropic-aws';
22
+
23
+ // SigV4 — picks up AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN
24
+ const anthropicAws = createAnthropicAws({
25
+ region: 'us-west-2',
26
+ workspaceId: 'wrkspc_…',
27
+ });
28
+ ```
29
+
30
+ ## Example
31
+
32
+ ```ts
33
+ import { createAnthropicAws } from '@ai-sdk/anthropic-aws';
34
+ import { generateText } from 'ai';
35
+
36
+ const anthropicAws = createAnthropicAws();
37
+
38
+ const { text } = await generateText({
39
+ model: anthropicAws('claude-sonnet-4-6'),
40
+ prompt: 'Invent a new holiday and describe its traditions.',
41
+ });
42
+ ```
43
+
44
+ ## Documentation
45
+
46
+ Please check out the **[Claude Platform on AWS provider documentation](https://ai-sdk.dev/providers/ai-sdk-providers/anthropic-aws)** for more information.
@@ -0,0 +1,99 @@
1
+ import { ProviderV4, LanguageModelV4, FilesV4, SkillsV4 } from '@ai-sdk/provider';
2
+ import { FetchFunction } from '@ai-sdk/provider-utils';
3
+ import { AnthropicModelId, anthropicTools } from '@ai-sdk/anthropic/internal';
4
+
5
+ interface AnthropicAwsCredentials {
6
+ region: string;
7
+ accessKeyId: string;
8
+ secretAccessKey: string;
9
+ sessionToken?: string;
10
+ }
11
+
12
+ interface AnthropicAwsProvider extends ProviderV4 {
13
+ /**
14
+ * Creates a model for text generation.
15
+ */
16
+ (modelId: AnthropicModelId): LanguageModelV4;
17
+ /**
18
+ * Creates a model for text generation.
19
+ */
20
+ languageModel(modelId: AnthropicModelId): LanguageModelV4;
21
+ /**
22
+ * @deprecated Use `embeddingModel` instead.
23
+ */
24
+ textEmbeddingModel(modelId: string): never;
25
+ files(): FilesV4;
26
+ /**
27
+ * Returns a SkillsV4 interface for uploading skills to Anthropic.
28
+ */
29
+ skills(): SkillsV4;
30
+ tools: typeof anthropicTools;
31
+ }
32
+ interface AnthropicAwsProviderSettings {
33
+ /**
34
+ * The AWS region to use for Claude Platform on AWS. Defaults to the value of the
35
+ * `AWS_REGION` environment variable. Required — there is no fallback default.
36
+ */
37
+ region?: string;
38
+ /**
39
+ * The Anthropic workspace ID for this AWS account. Sent on every request via the
40
+ * `anthropic-workspace-id` header. Defaults to the value of the
41
+ * `ANTHROPIC_AWS_WORKSPACE_ID` environment variable.
42
+ */
43
+ workspaceId?: string;
44
+ /**
45
+ * API key for authenticating requests via the `x-api-key` header.
46
+ * When provided, this will be used instead of AWS SigV4 authentication.
47
+ * Defaults to the value of the `ANTHROPIC_AWS_API_KEY` environment variable.
48
+ */
49
+ apiKey?: string;
50
+ /**
51
+ * The AWS access key ID to use for SigV4 authentication. Defaults to the value of the
52
+ * `AWS_ACCESS_KEY_ID` environment variable.
53
+ */
54
+ accessKeyId?: string;
55
+ /**
56
+ * The AWS secret access key to use for SigV4 authentication. Defaults to the value of the
57
+ * `AWS_SECRET_ACCESS_KEY` environment variable.
58
+ */
59
+ secretAccessKey?: string;
60
+ /**
61
+ * The AWS session token to use for SigV4 authentication. Defaults to the value of the
62
+ * `AWS_SESSION_TOKEN` environment variable.
63
+ */
64
+ sessionToken?: string;
65
+ /**
66
+ * Base URL for the Claude Platform on AWS API calls.
67
+ */
68
+ baseURL?: string;
69
+ /**
70
+ * Custom headers to include in the requests.
71
+ */
72
+ headers?: Record<string, string | undefined>;
73
+ /**
74
+ * Custom fetch implementation. You can use it as a middleware to intercept requests,
75
+ * or to provide a custom fetch implementation for e.g. testing.
76
+ */
77
+ fetch?: FetchFunction;
78
+ /**
79
+ * The AWS credential provider to use to get dynamic credentials similar to the
80
+ * AWS SDK. Setting a provider here will cause its credential values to be used
81
+ * instead of the `accessKeyId`, `secretAccessKey`, and `sessionToken` settings.
82
+ */
83
+ credentialProvider?: () => PromiseLike<Omit<AnthropicAwsCredentials, 'region'>>;
84
+ generateId?: () => string;
85
+ }
86
+ /**
87
+ * Create a Claude Platform on AWS provider instance.
88
+ * This provider uses the Anthropic Messages API hosted in AWS, authenticated
89
+ * with AWS SigV4 or an AWS-provisioned API key.
90
+ */
91
+ declare function createAnthropicAws(options?: AnthropicAwsProviderSettings): AnthropicAwsProvider;
92
+ /**
93
+ * Default Claude Platform on AWS provider instance.
94
+ */
95
+ declare const anthropicAws: AnthropicAwsProvider;
96
+
97
+ declare const VERSION: string;
98
+
99
+ export { type AnthropicAwsCredentials, type AnthropicAwsProvider, type AnthropicAwsProviderSettings, VERSION, anthropicAws, createAnthropicAws };
package/dist/index.js ADDED
@@ -0,0 +1,249 @@
1
+ // src/anthropic-aws-provider.ts
2
+ import {
3
+ NoSuchModelError
4
+ } from "@ai-sdk/provider";
5
+ import {
6
+ loadOptionalSetting,
7
+ loadSetting,
8
+ withoutTrailingSlash
9
+ } from "@ai-sdk/provider-utils";
10
+ import {
11
+ AnthropicFiles,
12
+ AnthropicLanguageModel,
13
+ AnthropicSkills,
14
+ anthropicTools
15
+ } from "@ai-sdk/anthropic/internal";
16
+
17
+ // src/anthropic-aws-fetch.ts
18
+ import {
19
+ combineHeaders,
20
+ normalizeHeaders,
21
+ withUserAgentSuffix,
22
+ getRuntimeEnvironmentUserAgent
23
+ } from "@ai-sdk/provider-utils";
24
+ import { AwsV4Signer } from "aws4fetch";
25
+
26
+ // src/version.ts
27
+ var VERSION = true ? "1.0.0-beta.10" : "0.0.0-test";
28
+
29
+ // src/anthropic-aws-fetch.ts
30
+ function createSigV4FetchFunction(getCredentials, fetch) {
31
+ return async (input, init) => {
32
+ var _a, _b;
33
+ const effectiveFetch = fetch != null ? fetch : globalThis.fetch;
34
+ const request = input instanceof Request ? input : void 0;
35
+ const originalHeaders = combineHeaders(
36
+ normalizeHeaders(request == null ? void 0 : request.headers),
37
+ normalizeHeaders(init == null ? void 0 : init.headers)
38
+ );
39
+ const headersWithUserAgent = withUserAgentSuffix(
40
+ originalHeaders,
41
+ `ai-sdk/anthropic-aws/${VERSION}`,
42
+ getRuntimeEnvironmentUserAgent()
43
+ );
44
+ let effectiveBody = (_a = init == null ? void 0 : init.body) != null ? _a : void 0;
45
+ if (effectiveBody === void 0 && request && request.body !== null) {
46
+ try {
47
+ effectiveBody = await request.clone().text();
48
+ } catch (e) {
49
+ }
50
+ }
51
+ const effectiveMethod = (_b = init == null ? void 0 : init.method) != null ? _b : request == null ? void 0 : request.method;
52
+ if ((effectiveMethod == null ? void 0 : effectiveMethod.toUpperCase()) !== "POST" || !effectiveBody) {
53
+ return effectiveFetch(input, {
54
+ ...init,
55
+ headers: headersWithUserAgent
56
+ });
57
+ }
58
+ const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
59
+ const body = prepareBodyString(effectiveBody);
60
+ const credentials = await getCredentials();
61
+ const signer = new AwsV4Signer({
62
+ url,
63
+ method: "POST",
64
+ headers: Object.entries(headersWithUserAgent),
65
+ body,
66
+ region: credentials.region,
67
+ accessKeyId: credentials.accessKeyId,
68
+ secretAccessKey: credentials.secretAccessKey,
69
+ sessionToken: credentials.sessionToken,
70
+ service: "aws-external-anthropic"
71
+ });
72
+ const signingResult = await signer.sign();
73
+ const signedHeaders = normalizeHeaders(signingResult.headers);
74
+ const combinedHeaders = combineHeaders(headersWithUserAgent, signedHeaders);
75
+ return effectiveFetch(input, {
76
+ ...init,
77
+ body,
78
+ headers: combinedHeaders
79
+ });
80
+ };
81
+ }
82
+ function prepareBodyString(body) {
83
+ if (typeof body === "string") {
84
+ return body;
85
+ } else if (body instanceof Uint8Array) {
86
+ return new TextDecoder().decode(body);
87
+ } else if (body instanceof ArrayBuffer) {
88
+ return new TextDecoder().decode(new Uint8Array(body));
89
+ } else {
90
+ return JSON.stringify(body);
91
+ }
92
+ }
93
+ function createApiKeyFetchFunction(apiKey, fetch) {
94
+ return async (input, init) => {
95
+ const effectiveFetch = fetch != null ? fetch : globalThis.fetch;
96
+ const originalHeaders = normalizeHeaders(init == null ? void 0 : init.headers);
97
+ const headersWithUserAgent = withUserAgentSuffix(
98
+ originalHeaders,
99
+ `ai-sdk/anthropic-aws/${VERSION}`,
100
+ getRuntimeEnvironmentUserAgent()
101
+ );
102
+ const finalHeaders = combineHeaders(headersWithUserAgent, {
103
+ "x-api-key": apiKey
104
+ });
105
+ return effectiveFetch(input, {
106
+ ...init,
107
+ headers: finalHeaders
108
+ });
109
+ };
110
+ }
111
+
112
+ // src/anthropic-aws-provider.ts
113
+ function createAnthropicAws(options = {}) {
114
+ const apiKey = loadOptionalSetting({
115
+ settingValue: options.apiKey,
116
+ environmentVariableName: "ANTHROPIC_AWS_API_KEY"
117
+ });
118
+ const fetchFunction = apiKey ? createApiKeyFetchFunction(apiKey, options.fetch) : createSigV4FetchFunction(async () => {
119
+ const region = loadSetting({
120
+ settingValue: options.region,
121
+ settingName: "region",
122
+ environmentVariableName: "AWS_REGION",
123
+ description: "AWS region"
124
+ });
125
+ if (options.credentialProvider) {
126
+ try {
127
+ return {
128
+ ...await options.credentialProvider(),
129
+ region
130
+ };
131
+ } catch (error) {
132
+ const errorMessage = error instanceof Error ? error.message : String(error);
133
+ throw new Error(
134
+ `AWS credential provider failed: ${errorMessage}. Please ensure your credential provider returns valid AWS credentials with accessKeyId and secretAccessKey properties.`
135
+ );
136
+ }
137
+ }
138
+ try {
139
+ return {
140
+ region,
141
+ accessKeyId: loadSetting({
142
+ settingValue: options.accessKeyId,
143
+ settingName: "accessKeyId",
144
+ environmentVariableName: "AWS_ACCESS_KEY_ID",
145
+ description: "AWS access key ID"
146
+ }),
147
+ secretAccessKey: loadSetting({
148
+ settingValue: options.secretAccessKey,
149
+ settingName: "secretAccessKey",
150
+ environmentVariableName: "AWS_SECRET_ACCESS_KEY",
151
+ description: "AWS secret access key"
152
+ }),
153
+ sessionToken: loadOptionalSetting({
154
+ settingValue: options.sessionToken,
155
+ environmentVariableName: "AWS_SESSION_TOKEN"
156
+ })
157
+ };
158
+ } catch (error) {
159
+ const errorMessage = error instanceof Error ? error.message : String(error);
160
+ if (errorMessage.includes("AWS_ACCESS_KEY_ID") || errorMessage.includes("accessKeyId")) {
161
+ throw new Error(
162
+ `AWS SigV4 authentication requires AWS credentials. Please provide either:
163
+ 1. Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables
164
+ 2. Provide accessKeyId and secretAccessKey in options
165
+ 3. Use a credentialProvider function
166
+ 4. Use API key authentication with ANTHROPIC_AWS_API_KEY or apiKey option
167
+ Original error: ${errorMessage}`
168
+ );
169
+ }
170
+ if (errorMessage.includes("AWS_SECRET_ACCESS_KEY") || errorMessage.includes("secretAccessKey")) {
171
+ throw new Error(
172
+ `AWS SigV4 authentication requires both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. Please ensure both credentials are provided.
173
+ Original error: ${errorMessage}`
174
+ );
175
+ }
176
+ throw error;
177
+ }
178
+ }, options.fetch);
179
+ const getBaseURL = () => {
180
+ var _a;
181
+ return (_a = withoutTrailingSlash(options.baseURL)) != null ? _a : `https://aws-external-anthropic.${loadSetting({
182
+ settingValue: options.region,
183
+ settingName: "region",
184
+ environmentVariableName: "AWS_REGION",
185
+ description: "AWS region"
186
+ })}.api.aws/v1`;
187
+ };
188
+ const getHeaders = () => ({
189
+ "anthropic-version": "2023-06-01",
190
+ "anthropic-workspace-id": loadSetting({
191
+ settingValue: options.workspaceId,
192
+ settingName: "workspaceId",
193
+ environmentVariableName: "ANTHROPIC_AWS_WORKSPACE_ID",
194
+ description: "Anthropic AWS workspace ID"
195
+ }),
196
+ ...options.headers
197
+ });
198
+ const createChatModel = (modelId) => new AnthropicLanguageModel(modelId, {
199
+ provider: "anthropic-aws.messages",
200
+ baseURL: getBaseURL(),
201
+ headers: getHeaders,
202
+ fetch: fetchFunction,
203
+ generateId: options.generateId,
204
+ supportedUrls: () => ({
205
+ "image/*": [/^https?:\/\/.*$/],
206
+ "application/pdf": [/^https?:\/\/.*$/]
207
+ })
208
+ });
209
+ const provider = function(modelId) {
210
+ if (new.target) {
211
+ throw new Error(
212
+ "The Anthropic AWS model function cannot be called with the new keyword."
213
+ );
214
+ }
215
+ return createChatModel(modelId);
216
+ };
217
+ provider.specificationVersion = "v4";
218
+ provider.languageModel = createChatModel;
219
+ provider.chat = createChatModel;
220
+ provider.messages = createChatModel;
221
+ provider.embeddingModel = (modelId) => {
222
+ throw new NoSuchModelError({ modelId, modelType: "embeddingModel" });
223
+ };
224
+ provider.textEmbeddingModel = provider.embeddingModel;
225
+ provider.imageModel = (modelId) => {
226
+ throw new NoSuchModelError({ modelId, modelType: "imageModel" });
227
+ };
228
+ provider.files = () => new AnthropicFiles({
229
+ provider: "anthropic-aws.messages",
230
+ baseURL: getBaseURL(),
231
+ headers: getHeaders,
232
+ fetch: fetchFunction
233
+ });
234
+ provider.skills = () => new AnthropicSkills({
235
+ provider: "anthropic-aws.skills",
236
+ baseURL: getBaseURL(),
237
+ headers: getHeaders,
238
+ fetch: fetchFunction
239
+ });
240
+ provider.tools = anthropicTools;
241
+ return provider;
242
+ }
243
+ var anthropicAws = createAnthropicAws();
244
+ export {
245
+ VERSION,
246
+ anthropicAws,
247
+ createAnthropicAws
248
+ };
249
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/anthropic-aws-provider.ts","../src/anthropic-aws-fetch.ts","../src/version.ts"],"sourcesContent":["import {\n NoSuchModelError,\n type FilesV4,\n type LanguageModelV4,\n type ProviderV4,\n type SkillsV4,\n} from '@ai-sdk/provider';\nimport {\n loadOptionalSetting,\n loadSetting,\n withoutTrailingSlash,\n type FetchFunction,\n} from '@ai-sdk/provider-utils';\nimport {\n AnthropicFiles,\n AnthropicLanguageModel,\n AnthropicSkills,\n anthropicTools,\n type AnthropicModelId,\n} from '@ai-sdk/anthropic/internal';\nimport {\n createApiKeyFetchFunction,\n createSigV4FetchFunction,\n type AnthropicAwsCredentials,\n} from './anthropic-aws-fetch';\n\nexport interface AnthropicAwsProvider extends ProviderV4 {\n /**\n * Creates a model for text generation.\n */\n (modelId: AnthropicModelId): LanguageModelV4;\n\n /**\n * Creates a model for text generation.\n */\n languageModel(modelId: AnthropicModelId): LanguageModelV4;\n\n /**\n * @deprecated Use `embeddingModel` instead.\n */\n textEmbeddingModel(modelId: string): never;\n\n files(): FilesV4;\n\n /**\n * Returns a SkillsV4 interface for uploading skills to Anthropic.\n */\n skills(): SkillsV4;\n\n tools: typeof anthropicTools;\n}\n\nexport interface AnthropicAwsProviderSettings {\n /**\n * The AWS region to use for Claude Platform on AWS. Defaults to the value of the\n * `AWS_REGION` environment variable. Required — there is no fallback default.\n */\n region?: string;\n\n /**\n * The Anthropic workspace ID for this AWS account. Sent on every request via the\n * `anthropic-workspace-id` header. Defaults to the value of the\n * `ANTHROPIC_AWS_WORKSPACE_ID` environment variable.\n */\n workspaceId?: string;\n\n /**\n * API key for authenticating requests via the `x-api-key` header.\n * When provided, this will be used instead of AWS SigV4 authentication.\n * Defaults to the value of the `ANTHROPIC_AWS_API_KEY` environment variable.\n */\n apiKey?: string;\n\n /**\n * The AWS access key ID to use for SigV4 authentication. Defaults to the value of the\n * `AWS_ACCESS_KEY_ID` environment variable.\n */\n accessKeyId?: string;\n\n /**\n * The AWS secret access key to use for SigV4 authentication. Defaults to the value of the\n * `AWS_SECRET_ACCESS_KEY` environment variable.\n */\n secretAccessKey?: string;\n\n /**\n * The AWS session token to use for SigV4 authentication. Defaults to the value of the\n * `AWS_SESSION_TOKEN` environment variable.\n */\n sessionToken?: string;\n\n /**\n * Base URL for the Claude Platform on AWS API calls.\n */\n baseURL?: string;\n\n /**\n * Custom headers to include in the requests.\n */\n headers?: Record<string, string | undefined>;\n\n /**\n * Custom fetch implementation. You can use it as a middleware to intercept requests,\n * or to provide a custom fetch implementation for e.g. testing.\n */\n fetch?: FetchFunction;\n\n /**\n * The AWS credential provider to use to get dynamic credentials similar to the\n * AWS SDK. Setting a provider here will cause its credential values to be used\n * instead of the `accessKeyId`, `secretAccessKey`, and `sessionToken` settings.\n */\n credentialProvider?: () => PromiseLike<\n Omit<AnthropicAwsCredentials, 'region'>\n >;\n\n generateId?: () => string;\n}\n\n/**\n * Create a Claude Platform on AWS provider instance.\n * This provider uses the Anthropic Messages API hosted in AWS, authenticated\n * with AWS SigV4 or an AWS-provisioned API key.\n */\nexport function createAnthropicAws(\n options: AnthropicAwsProviderSettings = {},\n): AnthropicAwsProvider {\n const apiKey = loadOptionalSetting({\n settingValue: options.apiKey,\n environmentVariableName: 'ANTHROPIC_AWS_API_KEY',\n });\n\n const fetchFunction = apiKey\n ? createApiKeyFetchFunction(apiKey, options.fetch)\n : createSigV4FetchFunction(async () => {\n const region = loadSetting({\n settingValue: options.region,\n settingName: 'region',\n environmentVariableName: 'AWS_REGION',\n description: 'AWS region',\n });\n\n if (options.credentialProvider) {\n try {\n return {\n ...(await options.credentialProvider()),\n region,\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n throw new Error(\n `AWS credential provider failed: ${errorMessage}. ` +\n 'Please ensure your credential provider returns valid AWS credentials ' +\n 'with accessKeyId and secretAccessKey properties.',\n );\n }\n }\n\n try {\n return {\n region,\n accessKeyId: loadSetting({\n settingValue: options.accessKeyId,\n settingName: 'accessKeyId',\n environmentVariableName: 'AWS_ACCESS_KEY_ID',\n description: 'AWS access key ID',\n }),\n secretAccessKey: loadSetting({\n settingValue: options.secretAccessKey,\n settingName: 'secretAccessKey',\n environmentVariableName: 'AWS_SECRET_ACCESS_KEY',\n description: 'AWS secret access key',\n }),\n sessionToken: loadOptionalSetting({\n settingValue: options.sessionToken,\n environmentVariableName: 'AWS_SESSION_TOKEN',\n }),\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n if (\n errorMessage.includes('AWS_ACCESS_KEY_ID') ||\n errorMessage.includes('accessKeyId')\n ) {\n throw new Error(\n 'AWS SigV4 authentication requires AWS credentials. Please provide either:\\n' +\n '1. Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables\\n' +\n '2. Provide accessKeyId and secretAccessKey in options\\n' +\n '3. Use a credentialProvider function\\n' +\n '4. Use API key authentication with ANTHROPIC_AWS_API_KEY or apiKey option\\n' +\n `Original error: ${errorMessage}`,\n );\n }\n if (\n errorMessage.includes('AWS_SECRET_ACCESS_KEY') ||\n errorMessage.includes('secretAccessKey')\n ) {\n throw new Error(\n 'AWS SigV4 authentication requires both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. ' +\n 'Please ensure both credentials are provided.\\n' +\n `Original error: ${errorMessage}`,\n );\n }\n throw error;\n }\n }, options.fetch);\n\n const getBaseURL = (): string =>\n withoutTrailingSlash(options.baseURL) ??\n `https://aws-external-anthropic.${loadSetting({\n settingValue: options.region,\n settingName: 'region',\n environmentVariableName: 'AWS_REGION',\n description: 'AWS region',\n })}.api.aws/v1`;\n\n const getHeaders = (): Record<string, string | undefined> => ({\n 'anthropic-version': '2023-06-01',\n 'anthropic-workspace-id': loadSetting({\n settingValue: options.workspaceId,\n settingName: 'workspaceId',\n environmentVariableName: 'ANTHROPIC_AWS_WORKSPACE_ID',\n description: 'Anthropic AWS workspace ID',\n }),\n ...options.headers,\n });\n\n const createChatModel = (modelId: AnthropicModelId) =>\n new AnthropicLanguageModel(modelId, {\n provider: 'anthropic-aws.messages',\n baseURL: getBaseURL(),\n headers: getHeaders,\n fetch: fetchFunction,\n generateId: options.generateId,\n supportedUrls: () => ({\n 'image/*': [/^https?:\\/\\/.*$/],\n 'application/pdf': [/^https?:\\/\\/.*$/],\n }),\n });\n\n const provider = function (modelId: AnthropicModelId) {\n if (new.target) {\n throw new Error(\n 'The Anthropic AWS model function cannot be called with the new keyword.',\n );\n }\n return createChatModel(modelId);\n };\n\n provider.specificationVersion = 'v4' as const;\n provider.languageModel = createChatModel;\n provider.chat = createChatModel;\n provider.messages = createChatModel;\n\n provider.embeddingModel = (modelId: string) => {\n throw new NoSuchModelError({ modelId, modelType: 'embeddingModel' });\n };\n provider.textEmbeddingModel = provider.embeddingModel;\n provider.imageModel = (modelId: string) => {\n throw new NoSuchModelError({ modelId, modelType: 'imageModel' });\n };\n\n provider.files = () =>\n new AnthropicFiles({\n provider: 'anthropic-aws.messages',\n baseURL: getBaseURL(),\n headers: getHeaders,\n fetch: fetchFunction,\n });\n\n provider.skills = () =>\n new AnthropicSkills({\n provider: 'anthropic-aws.skills',\n baseURL: getBaseURL(),\n headers: getHeaders,\n fetch: fetchFunction,\n });\n\n provider.tools = anthropicTools;\n\n return provider;\n}\n\n/**\n * Default Claude Platform on AWS provider instance.\n */\nexport const anthropicAws = createAnthropicAws();\n","import {\n combineHeaders,\n normalizeHeaders,\n withUserAgentSuffix,\n getRuntimeEnvironmentUserAgent,\n type FetchFunction,\n} from '@ai-sdk/provider-utils';\nimport { AwsV4Signer } from 'aws4fetch';\nimport { VERSION } from './version';\n\nexport interface AnthropicAwsCredentials {\n region: string;\n accessKeyId: string;\n secretAccessKey: string;\n sessionToken?: string;\n}\n\n/**\n * Creates a fetch function that applies AWS Signature Version 4 signing for\n * Claude Platform on AWS.\n *\n * @param getCredentials - Function that returns the AWS credentials to use when signing.\n * @param fetch - Optional original fetch implementation to wrap. Defaults to global fetch.\n * @returns A FetchFunction that signs requests before passing them to the underlying fetch.\n */\nexport function createSigV4FetchFunction(\n getCredentials: () =>\n | AnthropicAwsCredentials\n | PromiseLike<AnthropicAwsCredentials>,\n fetch?: FetchFunction,\n): FetchFunction {\n return async (\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> => {\n const effectiveFetch = fetch ?? globalThis.fetch;\n const request = input instanceof Request ? input : undefined;\n const originalHeaders = combineHeaders(\n normalizeHeaders(request?.headers),\n normalizeHeaders(init?.headers),\n );\n const headersWithUserAgent = withUserAgentSuffix(\n originalHeaders,\n `ai-sdk/anthropic-aws/${VERSION}`,\n getRuntimeEnvironmentUserAgent(),\n );\n\n let effectiveBody: BodyInit | undefined = init?.body ?? undefined;\n if (effectiveBody === undefined && request && request.body !== null) {\n try {\n effectiveBody = await request.clone().text();\n } catch {}\n }\n\n const effectiveMethod = init?.method ?? request?.method;\n\n if (effectiveMethod?.toUpperCase() !== 'POST' || !effectiveBody) {\n return effectiveFetch(input, {\n ...init,\n headers: headersWithUserAgent as HeadersInit,\n });\n }\n\n const url =\n typeof input === 'string'\n ? input\n : input instanceof URL\n ? input.href\n : input.url;\n\n const body = prepareBodyString(effectiveBody);\n const credentials = await getCredentials();\n const signer = new AwsV4Signer({\n url,\n method: 'POST',\n headers: Object.entries(headersWithUserAgent),\n body,\n region: credentials.region,\n accessKeyId: credentials.accessKeyId,\n secretAccessKey: credentials.secretAccessKey,\n sessionToken: credentials.sessionToken,\n service: 'aws-external-anthropic',\n });\n\n const signingResult = await signer.sign();\n const signedHeaders = normalizeHeaders(signingResult.headers);\n const combinedHeaders = combineHeaders(headersWithUserAgent, signedHeaders);\n\n return effectiveFetch(input, {\n ...init,\n body,\n headers: combinedHeaders as HeadersInit,\n });\n };\n}\n\nfunction prepareBodyString(body: BodyInit | undefined): string {\n if (typeof body === 'string') {\n return body;\n } else if (body instanceof Uint8Array) {\n return new TextDecoder().decode(body);\n } else if (body instanceof ArrayBuffer) {\n return new TextDecoder().decode(new Uint8Array(body));\n } else {\n return JSON.stringify(body);\n }\n}\n\n/**\n * Creates a fetch function that applies x-api-key header authentication.\n *\n * @param apiKey - The API key to use for x-api-key header authentication.\n * @param fetch - Optional original fetch implementation to wrap. Defaults to global fetch.\n * @returns A FetchFunction that adds the x-api-key header to requests.\n */\nexport function createApiKeyFetchFunction(\n apiKey: string,\n fetch?: FetchFunction,\n): FetchFunction {\n return async (\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> => {\n const effectiveFetch = fetch ?? globalThis.fetch;\n const originalHeaders = normalizeHeaders(init?.headers);\n const headersWithUserAgent = withUserAgentSuffix(\n originalHeaders,\n `ai-sdk/anthropic-aws/${VERSION}`,\n getRuntimeEnvironmentUserAgent(),\n );\n\n const finalHeaders = combineHeaders(headersWithUserAgent, {\n 'x-api-key': apiKey,\n });\n\n return effectiveFetch(input, {\n ...init,\n headers: finalHeaders as HeadersInit,\n });\n };\n}\n","// Version string of this package injected at build time.\ndeclare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n"],"mappings":"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","names":[]}
@@ -0,0 +1,151 @@
1
+ ---
2
+ title: Claude Platform on AWS
3
+ description: Learn how to use the Claude Platform on AWS provider.
4
+ ---
5
+
6
+ # Claude Platform on AWS Provider
7
+
8
+ The Claude Platform on AWS provider for the [AI SDK](/docs) gives you access to the Anthropic Messages API hosted inside your AWS environment. Anthropic operates the stack, so you get the same API surface and feature set as the first-party [Anthropic provider](/providers/ai-sdk-providers/anthropic) — including streaming, prompt caching, tool use, computer use, Agent Skills, and `anthropic-beta` headers — with AWS-native authentication and AWS Marketplace billing.
9
+
10
+ This differs from [Amazon Bedrock](/providers/ai-sdk-providers/amazon-bedrock) in two important ways: Claude Platform on AWS uses Anthropic's Messages API directly (not Bedrock's `Converse`/`InvokeModel`), and new features are available the same day they launch on the first-party Claude API (no AWS integration delay).
11
+
12
+ ## Setup
13
+
14
+ The Claude Platform on AWS provider is available in the `@ai-sdk/anthropic-aws` module. You can install it with:
15
+
16
+ <Tabs items={['pnpm', 'npm', 'yarn', 'bun']}>
17
+ <Tab>
18
+ <Snippet text="pnpm add @ai-sdk/anthropic-aws" dark />
19
+ </Tab>
20
+ <Tab>
21
+ <Snippet text="npm install @ai-sdk/anthropic-aws" dark />
22
+ </Tab>
23
+ <Tab>
24
+ <Snippet text="yarn add @ai-sdk/anthropic-aws" dark />
25
+ </Tab>
26
+ <Tab>
27
+ <Snippet text="bun add @ai-sdk/anthropic-aws" dark />
28
+ </Tab>
29
+ </Tabs>
30
+
31
+ ### Prerequisites
32
+
33
+ Before you can use the provider, your AWS account must be subscribed to Claude Platform on AWS through the AWS Marketplace, and outbound web identity federation must be enabled on the account (a one-time setup step):
34
+
35
+ ```bash
36
+ aws iam enable-outbound-web-identity-federation
37
+ ```
38
+
39
+ Without this, every request returns `Outbound web identity federation is disabled for your account`. This is the most common setup error.
40
+
41
+ You'll also need your workspace ID. When you subscribe, AWS provisions an initial workspace for your account in the selected region. You can find the ID in the Claude Console under **Workspaces** (accessed from the AWS Console via the Claude Platform on AWS service page).
42
+
43
+ ### Authentication
44
+
45
+ The provider supports two authentication methods:
46
+
47
+ #### Using AWS SigV4 (recommended for production)
48
+
49
+ SigV4 integrates with your existing AWS IAM policies, roles, and auditing. Configure AWS credentials using any method supported by the AWS default credential provider chain — environment variables, shared credentials file, web identity (IRSA), ECS container credentials, or EC2 instance metadata.
50
+
51
+ ```bash
52
+ AWS_REGION=us-west-2
53
+ ANTHROPIC_AWS_WORKSPACE_ID=wrkspc_…
54
+ AWS_ACCESS_KEY_ID=…
55
+ AWS_SECRET_ACCESS_KEY=…
56
+ # AWS_SESSION_TOKEN=… # only for temporary credentials (SSO, STS, assumed role)
57
+ ```
58
+
59
+ Then use the default provider instance:
60
+
61
+ ```ts
62
+ import { anthropicAws } from '@ai-sdk/anthropic-aws';
63
+ ```
64
+
65
+ Or instantiate explicitly:
66
+
67
+ ```ts
68
+ import { createAnthropicAws } from '@ai-sdk/anthropic-aws';
69
+
70
+ const anthropicAws = createAnthropicAws({
71
+ region: 'us-west-2',
72
+ workspaceId: 'wrkspc_…',
73
+ });
74
+ ```
75
+
76
+ For dynamic credentials (e.g., assuming a role at request time):
77
+
78
+ ```ts
79
+ const anthropicAws = createAnthropicAws({
80
+ region: 'us-west-2',
81
+ workspaceId: 'wrkspc_…',
82
+ credentialProvider: async () => fetchCredentialsFromSTS(),
83
+ });
84
+ ```
85
+
86
+ #### Using an API key
87
+
88
+ For simpler integration paths (local development, scripts, migration from the first-party Claude API), you can authenticate with an API key instead of SigV4. Your Anthropic account representative provisions API keys for Claude Platform on AWS.
89
+
90
+ ```bash
91
+ ANTHROPIC_AWS_API_KEY=sk-…
92
+ ```
93
+
94
+ When `apiKey` is set, it takes precedence over any SigV4 credentials in the environment.
95
+
96
+ ```ts
97
+ import { createAnthropicAws } from '@ai-sdk/anthropic-aws';
98
+
99
+ const anthropicAws = createAnthropicAws({
100
+ region: 'us-west-2',
101
+ workspaceId: 'wrkspc_…',
102
+ apiKey: 'sk-…',
103
+ });
104
+ ```
105
+
106
+ ### Provider Settings
107
+
108
+ | Setting | Description |
109
+ | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
110
+ | `region` | AWS region for the Claude Platform on AWS endpoint. Reads from `AWS_REGION` if omitted. Required — no fallback default. |
111
+ | `workspaceId` | Anthropic workspace ID for this AWS account. Sent on every request via the `anthropic-workspace-id` header. Reads from `ANTHROPIC_AWS_WORKSPACE_ID` if omitted. |
112
+ | `apiKey` | API key for `x-api-key` authentication. When provided, used instead of SigV4. Reads from `ANTHROPIC_AWS_API_KEY` if omitted. |
113
+ | `accessKeyId` | AWS access key ID for SigV4. Reads from `AWS_ACCESS_KEY_ID`. |
114
+ | `secretAccessKey` | AWS secret access key for SigV4. Reads from `AWS_SECRET_ACCESS_KEY`. |
115
+ | `sessionToken` | AWS session token for SigV4 (temporary credentials only). Reads from `AWS_SESSION_TOKEN`. |
116
+ | `baseURL` | Base URL override. Defaults to `https://aws-external-anthropic.{region}.api.aws/v1`. |
117
+ | `headers` | Custom headers to include on every request. |
118
+ | `fetch` | Custom fetch implementation for testing or middleware. |
119
+ | `credentialProvider` | Function returning dynamic AWS credentials. Overrides `accessKeyId`, `secretAccessKey`, and `sessionToken`. |
120
+
121
+ ## Language Models
122
+
123
+ You can create models that call the Anthropic Messages API on AWS using the provider instance:
124
+
125
+ ```ts
126
+ import { anthropicAws } from '@ai-sdk/anthropic-aws';
127
+
128
+ const model = anthropicAws('claude-sonnet-4-6');
129
+ ```
130
+
131
+ Model IDs are identical to the first-party Anthropic API. See the [Anthropic provider docs](/providers/ai-sdk-providers/anthropic#language-models) for the full list of language model options, prompt caching, computer use, web search, code execution, and Agent Skills. All of these work identically here because Claude Platform on AWS uses Anthropic's runtime directly.
132
+
133
+ ### Example
134
+
135
+ ```ts
136
+ import { anthropicAws } from '@ai-sdk/anthropic-aws';
137
+ import { generateText } from 'ai';
138
+
139
+ const { text } = await generateText({
140
+ model: anthropicAws('claude-sonnet-4-6'),
141
+ prompt: 'Invent a new holiday and describe its traditions.',
142
+ });
143
+ ```
144
+
145
+ ## IAM permissions
146
+
147
+ Your IAM principal needs permission to call the Claude Platform on AWS actions on your workspace. AWS provides three managed policies:
148
+
149
+ - `AnthropicFullAccess` — grants `aws-external-anthropic:*` on all resources.
150
+ - `AnthropicInferenceAccess` — grants read actions plus `CreateInference`, `CreateBatchInference`, `CancelBatchInference`, `DeleteBatchInference`, and `CountTokens` on all workspaces. **This is the minimum for calling models.**
151
+ - `AnthropicReadOnlyAccess` — grants `Get*`, `List*`, and `CallWithBearerToken` on all workspaces. Insufficient for inference.
package/package.json CHANGED
@@ -1 +1,78 @@
1
- {"name":"@ai-sdk/anthropic-aws","version":"0.0.0"}
1
+ {
2
+ "name": "@ai-sdk/anthropic-aws",
3
+ "version": "1.0.0-beta.10",
4
+ "type": "module",
5
+ "license": "Apache-2.0",
6
+ "sideEffects": false,
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "files": [
10
+ "dist/**/*",
11
+ "docs/**/*",
12
+ "src",
13
+ "!src/**/*.test.ts",
14
+ "!src/**/*.test-d.ts",
15
+ "!src/**/__snapshots__",
16
+ "!src/**/__fixtures__",
17
+ "CHANGELOG.md",
18
+ "README.md"
19
+ ],
20
+ "directories": {
21
+ "doc": "./docs"
22
+ },
23
+ "exports": {
24
+ "./package.json": "./package.json",
25
+ ".": {
26
+ "types": "./dist/index.d.ts",
27
+ "import": "./dist/index.js",
28
+ "default": "./dist/index.js"
29
+ }
30
+ },
31
+ "dependencies": {
32
+ "aws4fetch": "^1.0.20",
33
+ "@ai-sdk/anthropic": "4.0.0-beta.69",
34
+ "@ai-sdk/provider": "4.0.0-beta.20",
35
+ "@ai-sdk/provider-utils": "5.0.0-beta.50"
36
+ },
37
+ "devDependencies": {
38
+ "@types/node": "22.19.19",
39
+ "tsup": "^8.5.1",
40
+ "typescript": "5.8.3",
41
+ "zod": "3.25.76",
42
+ "@ai-sdk/test-server": "2.0.0-beta.7",
43
+ "@vercel/ai-tsconfig": "0.0.0"
44
+ },
45
+ "peerDependencies": {
46
+ "zod": "^3.25.76 || ^4.1.8"
47
+ },
48
+ "engines": {
49
+ "node": ">=22"
50
+ },
51
+ "publishConfig": {
52
+ "access": "public",
53
+ "provenance": true
54
+ },
55
+ "homepage": "https://ai-sdk.dev/docs",
56
+ "repository": {
57
+ "type": "git",
58
+ "url": "https://github.com/vercel/ai",
59
+ "directory": "packages/anthropic-aws"
60
+ },
61
+ "bugs": {
62
+ "url": "https://github.com/vercel/ai/issues"
63
+ },
64
+ "keywords": [
65
+ "ai"
66
+ ],
67
+ "scripts": {
68
+ "build": "pnpm clean && tsup --tsconfig tsconfig.build.json",
69
+ "build:watch": "pnpm clean && tsup --watch",
70
+ "clean": "del-cli dist docs *.tsbuildinfo",
71
+ "type-check": "tsc --build",
72
+ "test": "pnpm test:node && pnpm test:edge",
73
+ "test:update": "pnpm test:node -u",
74
+ "test:watch": "vitest --config vitest.node.config.js",
75
+ "test:edge": "vitest --config vitest.edge.config.js --run",
76
+ "test:node": "vitest --config vitest.node.config.js --run"
77
+ }
78
+ }
@@ -0,0 +1,141 @@
1
+ import {
2
+ combineHeaders,
3
+ normalizeHeaders,
4
+ withUserAgentSuffix,
5
+ getRuntimeEnvironmentUserAgent,
6
+ type FetchFunction,
7
+ } from '@ai-sdk/provider-utils';
8
+ import { AwsV4Signer } from 'aws4fetch';
9
+ import { VERSION } from './version';
10
+
11
+ export interface AnthropicAwsCredentials {
12
+ region: string;
13
+ accessKeyId: string;
14
+ secretAccessKey: string;
15
+ sessionToken?: string;
16
+ }
17
+
18
+ /**
19
+ * Creates a fetch function that applies AWS Signature Version 4 signing for
20
+ * Claude Platform on AWS.
21
+ *
22
+ * @param getCredentials - Function that returns the AWS credentials to use when signing.
23
+ * @param fetch - Optional original fetch implementation to wrap. Defaults to global fetch.
24
+ * @returns A FetchFunction that signs requests before passing them to the underlying fetch.
25
+ */
26
+ export function createSigV4FetchFunction(
27
+ getCredentials: () =>
28
+ | AnthropicAwsCredentials
29
+ | PromiseLike<AnthropicAwsCredentials>,
30
+ fetch?: FetchFunction,
31
+ ): FetchFunction {
32
+ return async (
33
+ input: RequestInfo | URL,
34
+ init?: RequestInit,
35
+ ): Promise<Response> => {
36
+ const effectiveFetch = fetch ?? globalThis.fetch;
37
+ const request = input instanceof Request ? input : undefined;
38
+ const originalHeaders = combineHeaders(
39
+ normalizeHeaders(request?.headers),
40
+ normalizeHeaders(init?.headers),
41
+ );
42
+ const headersWithUserAgent = withUserAgentSuffix(
43
+ originalHeaders,
44
+ `ai-sdk/anthropic-aws/${VERSION}`,
45
+ getRuntimeEnvironmentUserAgent(),
46
+ );
47
+
48
+ let effectiveBody: BodyInit | undefined = init?.body ?? undefined;
49
+ if (effectiveBody === undefined && request && request.body !== null) {
50
+ try {
51
+ effectiveBody = await request.clone().text();
52
+ } catch {}
53
+ }
54
+
55
+ const effectiveMethod = init?.method ?? request?.method;
56
+
57
+ if (effectiveMethod?.toUpperCase() !== 'POST' || !effectiveBody) {
58
+ return effectiveFetch(input, {
59
+ ...init,
60
+ headers: headersWithUserAgent as HeadersInit,
61
+ });
62
+ }
63
+
64
+ const url =
65
+ typeof input === 'string'
66
+ ? input
67
+ : input instanceof URL
68
+ ? input.href
69
+ : input.url;
70
+
71
+ const body = prepareBodyString(effectiveBody);
72
+ const credentials = await getCredentials();
73
+ const signer = new AwsV4Signer({
74
+ url,
75
+ method: 'POST',
76
+ headers: Object.entries(headersWithUserAgent),
77
+ body,
78
+ region: credentials.region,
79
+ accessKeyId: credentials.accessKeyId,
80
+ secretAccessKey: credentials.secretAccessKey,
81
+ sessionToken: credentials.sessionToken,
82
+ service: 'aws-external-anthropic',
83
+ });
84
+
85
+ const signingResult = await signer.sign();
86
+ const signedHeaders = normalizeHeaders(signingResult.headers);
87
+ const combinedHeaders = combineHeaders(headersWithUserAgent, signedHeaders);
88
+
89
+ return effectiveFetch(input, {
90
+ ...init,
91
+ body,
92
+ headers: combinedHeaders as HeadersInit,
93
+ });
94
+ };
95
+ }
96
+
97
+ function prepareBodyString(body: BodyInit | undefined): string {
98
+ if (typeof body === 'string') {
99
+ return body;
100
+ } else if (body instanceof Uint8Array) {
101
+ return new TextDecoder().decode(body);
102
+ } else if (body instanceof ArrayBuffer) {
103
+ return new TextDecoder().decode(new Uint8Array(body));
104
+ } else {
105
+ return JSON.stringify(body);
106
+ }
107
+ }
108
+
109
+ /**
110
+ * Creates a fetch function that applies x-api-key header authentication.
111
+ *
112
+ * @param apiKey - The API key to use for x-api-key header authentication.
113
+ * @param fetch - Optional original fetch implementation to wrap. Defaults to global fetch.
114
+ * @returns A FetchFunction that adds the x-api-key header to requests.
115
+ */
116
+ export function createApiKeyFetchFunction(
117
+ apiKey: string,
118
+ fetch?: FetchFunction,
119
+ ): FetchFunction {
120
+ return async (
121
+ input: RequestInfo | URL,
122
+ init?: RequestInit,
123
+ ): Promise<Response> => {
124
+ const effectiveFetch = fetch ?? globalThis.fetch;
125
+ const originalHeaders = normalizeHeaders(init?.headers);
126
+ const headersWithUserAgent = withUserAgentSuffix(
127
+ originalHeaders,
128
+ `ai-sdk/anthropic-aws/${VERSION}`,
129
+ getRuntimeEnvironmentUserAgent(),
130
+ );
131
+
132
+ const finalHeaders = combineHeaders(headersWithUserAgent, {
133
+ 'x-api-key': apiKey,
134
+ });
135
+
136
+ return effectiveFetch(input, {
137
+ ...init,
138
+ headers: finalHeaders as HeadersInit,
139
+ });
140
+ };
141
+ }
@@ -0,0 +1,289 @@
1
+ import {
2
+ NoSuchModelError,
3
+ type FilesV4,
4
+ type LanguageModelV4,
5
+ type ProviderV4,
6
+ type SkillsV4,
7
+ } from '@ai-sdk/provider';
8
+ import {
9
+ loadOptionalSetting,
10
+ loadSetting,
11
+ withoutTrailingSlash,
12
+ type FetchFunction,
13
+ } from '@ai-sdk/provider-utils';
14
+ import {
15
+ AnthropicFiles,
16
+ AnthropicLanguageModel,
17
+ AnthropicSkills,
18
+ anthropicTools,
19
+ type AnthropicModelId,
20
+ } from '@ai-sdk/anthropic/internal';
21
+ import {
22
+ createApiKeyFetchFunction,
23
+ createSigV4FetchFunction,
24
+ type AnthropicAwsCredentials,
25
+ } from './anthropic-aws-fetch';
26
+
27
+ export interface AnthropicAwsProvider extends ProviderV4 {
28
+ /**
29
+ * Creates a model for text generation.
30
+ */
31
+ (modelId: AnthropicModelId): LanguageModelV4;
32
+
33
+ /**
34
+ * Creates a model for text generation.
35
+ */
36
+ languageModel(modelId: AnthropicModelId): LanguageModelV4;
37
+
38
+ /**
39
+ * @deprecated Use `embeddingModel` instead.
40
+ */
41
+ textEmbeddingModel(modelId: string): never;
42
+
43
+ files(): FilesV4;
44
+
45
+ /**
46
+ * Returns a SkillsV4 interface for uploading skills to Anthropic.
47
+ */
48
+ skills(): SkillsV4;
49
+
50
+ tools: typeof anthropicTools;
51
+ }
52
+
53
+ export interface AnthropicAwsProviderSettings {
54
+ /**
55
+ * The AWS region to use for Claude Platform on AWS. Defaults to the value of the
56
+ * `AWS_REGION` environment variable. Required — there is no fallback default.
57
+ */
58
+ region?: string;
59
+
60
+ /**
61
+ * The Anthropic workspace ID for this AWS account. Sent on every request via the
62
+ * `anthropic-workspace-id` header. Defaults to the value of the
63
+ * `ANTHROPIC_AWS_WORKSPACE_ID` environment variable.
64
+ */
65
+ workspaceId?: string;
66
+
67
+ /**
68
+ * API key for authenticating requests via the `x-api-key` header.
69
+ * When provided, this will be used instead of AWS SigV4 authentication.
70
+ * Defaults to the value of the `ANTHROPIC_AWS_API_KEY` environment variable.
71
+ */
72
+ apiKey?: string;
73
+
74
+ /**
75
+ * The AWS access key ID to use for SigV4 authentication. Defaults to the value of the
76
+ * `AWS_ACCESS_KEY_ID` environment variable.
77
+ */
78
+ accessKeyId?: string;
79
+
80
+ /**
81
+ * The AWS secret access key to use for SigV4 authentication. Defaults to the value of the
82
+ * `AWS_SECRET_ACCESS_KEY` environment variable.
83
+ */
84
+ secretAccessKey?: string;
85
+
86
+ /**
87
+ * The AWS session token to use for SigV4 authentication. Defaults to the value of the
88
+ * `AWS_SESSION_TOKEN` environment variable.
89
+ */
90
+ sessionToken?: string;
91
+
92
+ /**
93
+ * Base URL for the Claude Platform on AWS API calls.
94
+ */
95
+ baseURL?: string;
96
+
97
+ /**
98
+ * Custom headers to include in the requests.
99
+ */
100
+ headers?: Record<string, string | undefined>;
101
+
102
+ /**
103
+ * Custom fetch implementation. You can use it as a middleware to intercept requests,
104
+ * or to provide a custom fetch implementation for e.g. testing.
105
+ */
106
+ fetch?: FetchFunction;
107
+
108
+ /**
109
+ * The AWS credential provider to use to get dynamic credentials similar to the
110
+ * AWS SDK. Setting a provider here will cause its credential values to be used
111
+ * instead of the `accessKeyId`, `secretAccessKey`, and `sessionToken` settings.
112
+ */
113
+ credentialProvider?: () => PromiseLike<
114
+ Omit<AnthropicAwsCredentials, 'region'>
115
+ >;
116
+
117
+ generateId?: () => string;
118
+ }
119
+
120
+ /**
121
+ * Create a Claude Platform on AWS provider instance.
122
+ * This provider uses the Anthropic Messages API hosted in AWS, authenticated
123
+ * with AWS SigV4 or an AWS-provisioned API key.
124
+ */
125
+ export function createAnthropicAws(
126
+ options: AnthropicAwsProviderSettings = {},
127
+ ): AnthropicAwsProvider {
128
+ const apiKey = loadOptionalSetting({
129
+ settingValue: options.apiKey,
130
+ environmentVariableName: 'ANTHROPIC_AWS_API_KEY',
131
+ });
132
+
133
+ const fetchFunction = apiKey
134
+ ? createApiKeyFetchFunction(apiKey, options.fetch)
135
+ : createSigV4FetchFunction(async () => {
136
+ const region = loadSetting({
137
+ settingValue: options.region,
138
+ settingName: 'region',
139
+ environmentVariableName: 'AWS_REGION',
140
+ description: 'AWS region',
141
+ });
142
+
143
+ if (options.credentialProvider) {
144
+ try {
145
+ return {
146
+ ...(await options.credentialProvider()),
147
+ region,
148
+ };
149
+ } catch (error) {
150
+ const errorMessage =
151
+ error instanceof Error ? error.message : String(error);
152
+ throw new Error(
153
+ `AWS credential provider failed: ${errorMessage}. ` +
154
+ 'Please ensure your credential provider returns valid AWS credentials ' +
155
+ 'with accessKeyId and secretAccessKey properties.',
156
+ );
157
+ }
158
+ }
159
+
160
+ try {
161
+ return {
162
+ region,
163
+ accessKeyId: loadSetting({
164
+ settingValue: options.accessKeyId,
165
+ settingName: 'accessKeyId',
166
+ environmentVariableName: 'AWS_ACCESS_KEY_ID',
167
+ description: 'AWS access key ID',
168
+ }),
169
+ secretAccessKey: loadSetting({
170
+ settingValue: options.secretAccessKey,
171
+ settingName: 'secretAccessKey',
172
+ environmentVariableName: 'AWS_SECRET_ACCESS_KEY',
173
+ description: 'AWS secret access key',
174
+ }),
175
+ sessionToken: loadOptionalSetting({
176
+ settingValue: options.sessionToken,
177
+ environmentVariableName: 'AWS_SESSION_TOKEN',
178
+ }),
179
+ };
180
+ } catch (error) {
181
+ const errorMessage =
182
+ error instanceof Error ? error.message : String(error);
183
+ if (
184
+ errorMessage.includes('AWS_ACCESS_KEY_ID') ||
185
+ errorMessage.includes('accessKeyId')
186
+ ) {
187
+ throw new Error(
188
+ 'AWS SigV4 authentication requires AWS credentials. Please provide either:\n' +
189
+ '1. Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables\n' +
190
+ '2. Provide accessKeyId and secretAccessKey in options\n' +
191
+ '3. Use a credentialProvider function\n' +
192
+ '4. Use API key authentication with ANTHROPIC_AWS_API_KEY or apiKey option\n' +
193
+ `Original error: ${errorMessage}`,
194
+ );
195
+ }
196
+ if (
197
+ errorMessage.includes('AWS_SECRET_ACCESS_KEY') ||
198
+ errorMessage.includes('secretAccessKey')
199
+ ) {
200
+ throw new Error(
201
+ 'AWS SigV4 authentication requires both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. ' +
202
+ 'Please ensure both credentials are provided.\n' +
203
+ `Original error: ${errorMessage}`,
204
+ );
205
+ }
206
+ throw error;
207
+ }
208
+ }, options.fetch);
209
+
210
+ const getBaseURL = (): string =>
211
+ withoutTrailingSlash(options.baseURL) ??
212
+ `https://aws-external-anthropic.${loadSetting({
213
+ settingValue: options.region,
214
+ settingName: 'region',
215
+ environmentVariableName: 'AWS_REGION',
216
+ description: 'AWS region',
217
+ })}.api.aws/v1`;
218
+
219
+ const getHeaders = (): Record<string, string | undefined> => ({
220
+ 'anthropic-version': '2023-06-01',
221
+ 'anthropic-workspace-id': loadSetting({
222
+ settingValue: options.workspaceId,
223
+ settingName: 'workspaceId',
224
+ environmentVariableName: 'ANTHROPIC_AWS_WORKSPACE_ID',
225
+ description: 'Anthropic AWS workspace ID',
226
+ }),
227
+ ...options.headers,
228
+ });
229
+
230
+ const createChatModel = (modelId: AnthropicModelId) =>
231
+ new AnthropicLanguageModel(modelId, {
232
+ provider: 'anthropic-aws.messages',
233
+ baseURL: getBaseURL(),
234
+ headers: getHeaders,
235
+ fetch: fetchFunction,
236
+ generateId: options.generateId,
237
+ supportedUrls: () => ({
238
+ 'image/*': [/^https?:\/\/.*$/],
239
+ 'application/pdf': [/^https?:\/\/.*$/],
240
+ }),
241
+ });
242
+
243
+ const provider = function (modelId: AnthropicModelId) {
244
+ if (new.target) {
245
+ throw new Error(
246
+ 'The Anthropic AWS model function cannot be called with the new keyword.',
247
+ );
248
+ }
249
+ return createChatModel(modelId);
250
+ };
251
+
252
+ provider.specificationVersion = 'v4' as const;
253
+ provider.languageModel = createChatModel;
254
+ provider.chat = createChatModel;
255
+ provider.messages = createChatModel;
256
+
257
+ provider.embeddingModel = (modelId: string) => {
258
+ throw new NoSuchModelError({ modelId, modelType: 'embeddingModel' });
259
+ };
260
+ provider.textEmbeddingModel = provider.embeddingModel;
261
+ provider.imageModel = (modelId: string) => {
262
+ throw new NoSuchModelError({ modelId, modelType: 'imageModel' });
263
+ };
264
+
265
+ provider.files = () =>
266
+ new AnthropicFiles({
267
+ provider: 'anthropic-aws.messages',
268
+ baseURL: getBaseURL(),
269
+ headers: getHeaders,
270
+ fetch: fetchFunction,
271
+ });
272
+
273
+ provider.skills = () =>
274
+ new AnthropicSkills({
275
+ provider: 'anthropic-aws.skills',
276
+ baseURL: getBaseURL(),
277
+ headers: getHeaders,
278
+ fetch: fetchFunction,
279
+ });
280
+
281
+ provider.tools = anthropicTools;
282
+
283
+ return provider;
284
+ }
285
+
286
+ /**
287
+ * Default Claude Platform on AWS provider instance.
288
+ */
289
+ export const anthropicAws = createAnthropicAws();
package/src/index.ts ADDED
@@ -0,0 +1,7 @@
1
+ export { anthropicAws, createAnthropicAws } from './anthropic-aws-provider';
2
+ export type {
3
+ AnthropicAwsProvider,
4
+ AnthropicAwsProviderSettings,
5
+ } from './anthropic-aws-provider';
6
+ export type { AnthropicAwsCredentials } from './anthropic-aws-fetch';
7
+ export { VERSION } from './version';
package/src/version.ts ADDED
@@ -0,0 +1,6 @@
1
+ // Version string of this package injected at build time.
2
+ declare const __PACKAGE_VERSION__: string | undefined;
3
+ export const VERSION: string =
4
+ typeof __PACKAGE_VERSION__ !== 'undefined'
5
+ ? __PACKAGE_VERSION__
6
+ : '0.0.0-test';