@animalabs/membrane 0.5.4 → 0.5.5
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/dist/providers/bedrock.d.ts +43 -0
- package/dist/providers/bedrock.d.ts.map +1 -0
- package/dist/providers/bedrock.js +443 -0
- package/dist/providers/bedrock.js.map +1 -0
- package/dist/providers/index.d.ts +1 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +1 -0
- package/dist/providers/index.js.map +1 -1
- package/package.json +1 -1
- package/src/providers/bedrock.ts +675 -0
- package/src/providers/index.ts +5 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AWS Bedrock provider adapter for Anthropic Claude models
|
|
3
|
+
*
|
|
4
|
+
* Uses the Anthropic Messages API format through AWS Bedrock.
|
|
5
|
+
*/
|
|
6
|
+
import type { ProviderAdapter, ProviderRequest, ProviderRequestOptions, ProviderResponse, StreamCallbacks } from '../types/index.js';
|
|
7
|
+
export interface BedrockAdapterConfig {
|
|
8
|
+
/** AWS access key ID */
|
|
9
|
+
accessKeyId?: string;
|
|
10
|
+
/** AWS secret access key */
|
|
11
|
+
secretAccessKey?: string;
|
|
12
|
+
/** AWS region (defaults to us-west-2) */
|
|
13
|
+
region?: string;
|
|
14
|
+
/** AWS session token (for temporary credentials) */
|
|
15
|
+
sessionToken?: string;
|
|
16
|
+
/** Default max tokens */
|
|
17
|
+
defaultMaxTokens?: number;
|
|
18
|
+
/** Anthropic API version header (defaults to 2023-06-01) */
|
|
19
|
+
anthropicVersion?: string;
|
|
20
|
+
}
|
|
21
|
+
export declare class BedrockAdapter implements ProviderAdapter {
|
|
22
|
+
readonly name = "bedrock";
|
|
23
|
+
private accessKeyId;
|
|
24
|
+
private secretAccessKey;
|
|
25
|
+
private sessionToken?;
|
|
26
|
+
private region;
|
|
27
|
+
private defaultMaxTokens;
|
|
28
|
+
private anthropicVersion;
|
|
29
|
+
constructor(config?: BedrockAdapterConfig);
|
|
30
|
+
supportsModel(modelId: string): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Convert a standard Claude model ID to Bedrock format if needed
|
|
33
|
+
*/
|
|
34
|
+
private toBedrockModelId;
|
|
35
|
+
complete(request: ProviderRequest, options?: ProviderRequestOptions): Promise<ProviderResponse>;
|
|
36
|
+
stream(request: ProviderRequest, callbacks: StreamCallbacks, options?: ProviderRequestOptions): Promise<ProviderResponse>;
|
|
37
|
+
private buildRequest;
|
|
38
|
+
private invokeModel;
|
|
39
|
+
private invokeModelWithStream;
|
|
40
|
+
private parseResponse;
|
|
41
|
+
private handleError;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=bedrock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bedrock.d.ts","sourceRoot":"","sources":["../../src/providers/bedrock.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,sBAAsB,EACtB,gBAAgB,EAChB,eAAe,EAEhB,MAAM,mBAAmB,CAAC;AAc3B,MAAM,WAAW,oBAAoB;IACnC,wBAAwB;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,4BAA4B;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,yBAAyB;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,4DAA4D;IAC5D,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AA8LD,qBAAa,cAAe,YAAW,eAAe;IACpD,QAAQ,CAAC,IAAI,aAAa;IAE1B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,gBAAgB,CAAS;gBAErB,MAAM,GAAE,oBAAyB;IAa7C,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAKvC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAwBlB,QAAQ,CACZ,OAAO,EAAE,eAAe,EACxB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,gBAAgB,CAAC;IActB,MAAM,CACV,OAAO,EAAE,eAAe,EACxB,SAAS,EAAE,eAAe,EAC1B,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,gBAAgB,CAAC;IAa5B,OAAO,CAAC,YAAY;YAsCN,WAAW;YA0CX,qBAAqB;IAwLnC,OAAO,CAAC,aAAa;IAsCrB,OAAO,CAAC,WAAW;CAkCpB"}
|
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AWS Bedrock provider adapter for Anthropic Claude models
|
|
3
|
+
*
|
|
4
|
+
* Uses the Anthropic Messages API format through AWS Bedrock.
|
|
5
|
+
*/
|
|
6
|
+
import { MembraneError, rateLimitError, contextLengthError, authError, serverError, abortError, } from '../types/index.js';
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// AWS Signature V4 Implementation
|
|
9
|
+
// ============================================================================
|
|
10
|
+
async function hmacSha256(key, data) {
|
|
11
|
+
const cryptoKey = await crypto.subtle.importKey('raw', key, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
|
|
12
|
+
return crypto.subtle.sign('HMAC', cryptoKey, new TextEncoder().encode(data));
|
|
13
|
+
}
|
|
14
|
+
async function sha256(data) {
|
|
15
|
+
const hash = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(data));
|
|
16
|
+
return Array.from(new Uint8Array(hash))
|
|
17
|
+
.map(b => b.toString(16).padStart(2, '0'))
|
|
18
|
+
.join('');
|
|
19
|
+
}
|
|
20
|
+
async function getSignatureKey(secretKey, dateStamp, region, service) {
|
|
21
|
+
const kDate = await hmacSha256(new TextEncoder().encode('AWS4' + secretKey), dateStamp);
|
|
22
|
+
const kRegion = await hmacSha256(kDate, region);
|
|
23
|
+
const kService = await hmacSha256(kRegion, service);
|
|
24
|
+
return hmacSha256(kService, 'aws4_request');
|
|
25
|
+
}
|
|
26
|
+
function getAmzDate() {
|
|
27
|
+
const now = new Date();
|
|
28
|
+
const amzDate = now.toISOString().replace(/[:-]|\.\d{3}/g, '');
|
|
29
|
+
const dateStamp = amzDate.slice(0, 8);
|
|
30
|
+
return { amzDate, dateStamp };
|
|
31
|
+
}
|
|
32
|
+
async function signRequest(method, url, headers, body, accessKeyId, secretAccessKey, sessionToken, region, service) {
|
|
33
|
+
const { amzDate, dateStamp } = getAmzDate();
|
|
34
|
+
// Prepare headers for signing
|
|
35
|
+
const signedHeaders = {
|
|
36
|
+
...headers,
|
|
37
|
+
host: url.host,
|
|
38
|
+
'x-amz-date': amzDate,
|
|
39
|
+
};
|
|
40
|
+
if (sessionToken) {
|
|
41
|
+
signedHeaders['x-amz-security-token'] = sessionToken;
|
|
42
|
+
}
|
|
43
|
+
// Create canonical request
|
|
44
|
+
const sortedHeaderKeys = Object.keys(signedHeaders).sort();
|
|
45
|
+
const canonicalHeaders = sortedHeaderKeys
|
|
46
|
+
.map(k => `${k.toLowerCase()}:${signedHeaders[k]?.trim()}`)
|
|
47
|
+
.join('\n') + '\n';
|
|
48
|
+
const signedHeadersList = sortedHeaderKeys.map(k => k.toLowerCase()).join(';');
|
|
49
|
+
const payloadHash = await sha256(body);
|
|
50
|
+
// URI-encode path components for canonical request (AWS SigV4 requirement)
|
|
51
|
+
// AWS requires double-encoding: %3A in the URL becomes %253A in the canonical request
|
|
52
|
+
// We encode each segment without decoding first to achieve double-encoding
|
|
53
|
+
const canonicalUri = url.pathname
|
|
54
|
+
.split('/')
|
|
55
|
+
.map(segment => encodeURIComponent(segment))
|
|
56
|
+
.join('/');
|
|
57
|
+
const canonicalRequest = [
|
|
58
|
+
method,
|
|
59
|
+
canonicalUri,
|
|
60
|
+
url.search.slice(1), // Remove leading '?'
|
|
61
|
+
canonicalHeaders,
|
|
62
|
+
signedHeadersList,
|
|
63
|
+
payloadHash,
|
|
64
|
+
].join('\n');
|
|
65
|
+
// Create string to sign
|
|
66
|
+
const algorithm = 'AWS4-HMAC-SHA256';
|
|
67
|
+
const credentialScope = `${dateStamp}/${region}/${service}/aws4_request`;
|
|
68
|
+
const stringToSign = [
|
|
69
|
+
algorithm,
|
|
70
|
+
amzDate,
|
|
71
|
+
credentialScope,
|
|
72
|
+
await sha256(canonicalRequest),
|
|
73
|
+
].join('\n');
|
|
74
|
+
// Calculate signature
|
|
75
|
+
const signingKey = await getSignatureKey(secretAccessKey, dateStamp, region, service);
|
|
76
|
+
const signatureBuffer = await hmacSha256(signingKey, stringToSign);
|
|
77
|
+
const signature = Array.from(new Uint8Array(signatureBuffer))
|
|
78
|
+
.map(b => b.toString(16).padStart(2, '0'))
|
|
79
|
+
.join('');
|
|
80
|
+
// Create authorization header
|
|
81
|
+
const authorization = `${algorithm} Credential=${accessKeyId}/${credentialScope}, SignedHeaders=${signedHeadersList}, Signature=${signature}`;
|
|
82
|
+
return {
|
|
83
|
+
...signedHeaders,
|
|
84
|
+
authorization,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
// ============================================================================
|
|
88
|
+
// Bedrock Adapter
|
|
89
|
+
// ============================================================================
|
|
90
|
+
export class BedrockAdapter {
|
|
91
|
+
name = 'bedrock';
|
|
92
|
+
accessKeyId;
|
|
93
|
+
secretAccessKey;
|
|
94
|
+
sessionToken;
|
|
95
|
+
region;
|
|
96
|
+
defaultMaxTokens;
|
|
97
|
+
anthropicVersion;
|
|
98
|
+
constructor(config = {}) {
|
|
99
|
+
this.accessKeyId = config.accessKeyId ?? process.env.AWS_ACCESS_KEY_ID ?? '';
|
|
100
|
+
this.secretAccessKey = config.secretAccessKey ?? process.env.AWS_SECRET_ACCESS_KEY ?? '';
|
|
101
|
+
this.sessionToken = config.sessionToken ?? process.env.AWS_SESSION_TOKEN;
|
|
102
|
+
this.region = config.region ?? process.env.AWS_REGION ?? 'us-west-2';
|
|
103
|
+
this.defaultMaxTokens = config.defaultMaxTokens ?? 4096;
|
|
104
|
+
this.anthropicVersion = config.anthropicVersion ?? 'bedrock-2023-05-31';
|
|
105
|
+
if (!this.accessKeyId || !this.secretAccessKey) {
|
|
106
|
+
throw new Error('AWS credentials required: accessKeyId and secretAccessKey');
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
supportsModel(modelId) {
|
|
110
|
+
// Support both Bedrock model IDs and standard Claude model IDs
|
|
111
|
+
return modelId.includes('claude') || modelId.startsWith('anthropic.');
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Convert a standard Claude model ID to Bedrock format if needed
|
|
115
|
+
*/
|
|
116
|
+
toBedrockModelId(modelId) {
|
|
117
|
+
// If already in Bedrock format, use as-is
|
|
118
|
+
if (modelId.startsWith('anthropic.')) {
|
|
119
|
+
return modelId;
|
|
120
|
+
}
|
|
121
|
+
// Map common Claude model IDs to Bedrock format
|
|
122
|
+
const modelMap = {
|
|
123
|
+
'claude-3-5-sonnet-20241022': 'anthropic.claude-3-5-sonnet-20241022-v2:0',
|
|
124
|
+
'claude-3-5-sonnet-latest': 'anthropic.claude-3-5-sonnet-20241022-v2:0',
|
|
125
|
+
'claude-3-5-haiku-20241022': 'anthropic.claude-3-5-haiku-20241022-v1:0',
|
|
126
|
+
'claude-3-5-haiku-latest': 'anthropic.claude-3-5-haiku-20241022-v1:0',
|
|
127
|
+
'claude-3-opus-20240229': 'anthropic.claude-3-opus-20240229-v1:0',
|
|
128
|
+
'claude-3-sonnet-20240229': 'anthropic.claude-3-sonnet-20240229-v1:0',
|
|
129
|
+
'claude-3-haiku-20240307': 'anthropic.claude-3-haiku-20240307-v1:0',
|
|
130
|
+
'claude-sonnet-4-20250514': 'anthropic.claude-sonnet-4-20250514-v1:0',
|
|
131
|
+
'claude-opus-4-20250514': 'anthropic.claude-opus-4-20250514-v1:0',
|
|
132
|
+
// Haiku 4.5 aliases
|
|
133
|
+
'claude-haiku-4-5-20251001': 'anthropic.claude-3-5-haiku-20241022-v1:0',
|
|
134
|
+
};
|
|
135
|
+
return modelMap[modelId] ?? `anthropic.${modelId}-v1:0`;
|
|
136
|
+
}
|
|
137
|
+
async complete(request, options) {
|
|
138
|
+
const bedrockModelId = this.toBedrockModelId(request.model);
|
|
139
|
+
const bedrockRequest = this.buildRequest(request);
|
|
140
|
+
const fullRequest = { modelId: bedrockModelId, ...bedrockRequest };
|
|
141
|
+
options?.onRequest?.(fullRequest);
|
|
142
|
+
try {
|
|
143
|
+
const response = await this.invokeModel(bedrockModelId, bedrockRequest, options?.signal);
|
|
144
|
+
return this.parseResponse(response, fullRequest);
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
throw this.handleError(error, fullRequest);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
async stream(request, callbacks, options) {
|
|
151
|
+
const bedrockModelId = this.toBedrockModelId(request.model);
|
|
152
|
+
const bedrockRequest = this.buildRequest(request);
|
|
153
|
+
const fullRequest = { modelId: bedrockModelId, ...bedrockRequest, stream: true };
|
|
154
|
+
options?.onRequest?.(fullRequest);
|
|
155
|
+
try {
|
|
156
|
+
return await this.invokeModelWithStream(bedrockModelId, bedrockRequest, callbacks, options?.signal);
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
throw this.handleError(error, fullRequest);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
buildRequest(request) {
|
|
163
|
+
const params = {
|
|
164
|
+
anthropic_version: this.anthropicVersion,
|
|
165
|
+
max_tokens: request.maxTokens || this.defaultMaxTokens,
|
|
166
|
+
messages: request.messages,
|
|
167
|
+
};
|
|
168
|
+
// Handle system prompt
|
|
169
|
+
if (request.system) {
|
|
170
|
+
params.system = request.system;
|
|
171
|
+
}
|
|
172
|
+
if (request.temperature !== undefined) {
|
|
173
|
+
params.temperature = request.temperature;
|
|
174
|
+
}
|
|
175
|
+
if (request.stopSequences && request.stopSequences.length > 0) {
|
|
176
|
+
params.stop_sequences = request.stopSequences;
|
|
177
|
+
}
|
|
178
|
+
if (request.tools && request.tools.length > 0) {
|
|
179
|
+
params.tools = request.tools;
|
|
180
|
+
}
|
|
181
|
+
// Handle extended thinking
|
|
182
|
+
if (request.thinking) {
|
|
183
|
+
params.thinking = request.thinking;
|
|
184
|
+
}
|
|
185
|
+
// Apply extra params, excluding internal membrane fields
|
|
186
|
+
if (request.extra) {
|
|
187
|
+
const { normalizedMessages, prompt, ...rest } = request.extra;
|
|
188
|
+
Object.assign(params, rest);
|
|
189
|
+
}
|
|
190
|
+
return params;
|
|
191
|
+
}
|
|
192
|
+
async invokeModel(modelId, request, signal) {
|
|
193
|
+
const url = new URL(`https://bedrock-runtime.${this.region}.amazonaws.com/model/${encodeURIComponent(modelId)}/invoke`);
|
|
194
|
+
const body = JSON.stringify(request);
|
|
195
|
+
const headers = {
|
|
196
|
+
'content-type': 'application/json',
|
|
197
|
+
accept: 'application/json',
|
|
198
|
+
};
|
|
199
|
+
const signedHeaders = await signRequest('POST', url, headers, body, this.accessKeyId, this.secretAccessKey, this.sessionToken, this.region, 'bedrock');
|
|
200
|
+
const response = await fetch(url.toString(), {
|
|
201
|
+
method: 'POST',
|
|
202
|
+
headers: signedHeaders,
|
|
203
|
+
body,
|
|
204
|
+
signal,
|
|
205
|
+
});
|
|
206
|
+
if (!response.ok) {
|
|
207
|
+
const errorText = await response.text();
|
|
208
|
+
throw new BedrockError(response.status, errorText);
|
|
209
|
+
}
|
|
210
|
+
return response.json();
|
|
211
|
+
}
|
|
212
|
+
async invokeModelWithStream(modelId, request, callbacks, signal) {
|
|
213
|
+
const url = new URL(`https://bedrock-runtime.${this.region}.amazonaws.com/model/${encodeURIComponent(modelId)}/invoke-with-response-stream`);
|
|
214
|
+
const body = JSON.stringify(request);
|
|
215
|
+
const headers = {
|
|
216
|
+
'content-type': 'application/json',
|
|
217
|
+
accept: 'application/vnd.amazon.eventstream',
|
|
218
|
+
};
|
|
219
|
+
const signedHeaders = await signRequest('POST', url, headers, body, this.accessKeyId, this.secretAccessKey, this.sessionToken, this.region, 'bedrock');
|
|
220
|
+
const response = await fetch(url.toString(), {
|
|
221
|
+
method: 'POST',
|
|
222
|
+
headers: signedHeaders,
|
|
223
|
+
body,
|
|
224
|
+
signal,
|
|
225
|
+
});
|
|
226
|
+
if (!response.ok) {
|
|
227
|
+
const errorText = await response.text();
|
|
228
|
+
throw new BedrockError(response.status, errorText);
|
|
229
|
+
}
|
|
230
|
+
// Parse the binary event stream
|
|
231
|
+
const contentBlocks = [];
|
|
232
|
+
let currentBlockIndex = -1;
|
|
233
|
+
let finalMessage;
|
|
234
|
+
let inputTokens = 0;
|
|
235
|
+
let outputTokens = 0;
|
|
236
|
+
let stopReason = 'end_turn';
|
|
237
|
+
let fullText = '';
|
|
238
|
+
const reader = response.body?.getReader();
|
|
239
|
+
if (!reader) {
|
|
240
|
+
throw new Error('No response body');
|
|
241
|
+
}
|
|
242
|
+
let buffer = new Uint8Array(0);
|
|
243
|
+
try {
|
|
244
|
+
while (true) {
|
|
245
|
+
const { done, value } = await reader.read();
|
|
246
|
+
if (done)
|
|
247
|
+
break;
|
|
248
|
+
// Append new data to buffer
|
|
249
|
+
const newBuffer = new Uint8Array(buffer.length + value.length);
|
|
250
|
+
newBuffer.set(buffer);
|
|
251
|
+
newBuffer.set(value, buffer.length);
|
|
252
|
+
buffer = newBuffer;
|
|
253
|
+
// Parse complete events from buffer
|
|
254
|
+
while (buffer.length >= 16) {
|
|
255
|
+
// AWS event stream format:
|
|
256
|
+
// 4 bytes: total byte length (big-endian)
|
|
257
|
+
// 4 bytes: headers length (big-endian)
|
|
258
|
+
// 4 bytes: prelude CRC
|
|
259
|
+
// headers
|
|
260
|
+
// payload
|
|
261
|
+
// 4 bytes: message CRC
|
|
262
|
+
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
263
|
+
const totalLength = view.getUint32(0, false);
|
|
264
|
+
const headersLength = view.getUint32(4, false);
|
|
265
|
+
if (buffer.length < totalLength) {
|
|
266
|
+
// Incomplete message, wait for more data
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
// Extract payload (skip prelude, headers, and CRCs)
|
|
270
|
+
const payloadStart = 12 + headersLength;
|
|
271
|
+
const payloadEnd = totalLength - 4;
|
|
272
|
+
const payloadBytes = buffer.slice(payloadStart, payloadEnd);
|
|
273
|
+
// Parse headers to find event type
|
|
274
|
+
let eventType = '';
|
|
275
|
+
let headerOffset = 12;
|
|
276
|
+
const headerEnd = 12 + headersLength;
|
|
277
|
+
while (headerOffset < headerEnd) {
|
|
278
|
+
const nameLength = buffer[headerOffset];
|
|
279
|
+
headerOffset += 1;
|
|
280
|
+
const name = new TextDecoder().decode(buffer.slice(headerOffset, headerOffset + nameLength));
|
|
281
|
+
headerOffset += nameLength;
|
|
282
|
+
const valueType = buffer[headerOffset];
|
|
283
|
+
headerOffset += 1;
|
|
284
|
+
if (valueType === 7) {
|
|
285
|
+
// String type
|
|
286
|
+
const valueLength = new DataView(buffer.buffer, buffer.byteOffset + headerOffset, 2).getUint16(0, false);
|
|
287
|
+
headerOffset += 2;
|
|
288
|
+
const value = new TextDecoder().decode(buffer.slice(headerOffset, headerOffset + valueLength));
|
|
289
|
+
headerOffset += valueLength;
|
|
290
|
+
if (name === ':event-type') {
|
|
291
|
+
eventType = value;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
// Skip other header types
|
|
296
|
+
break;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
// Parse the JSON payload
|
|
300
|
+
if (eventType === 'chunk' && payloadBytes.length > 0) {
|
|
301
|
+
try {
|
|
302
|
+
const payloadJson = JSON.parse(new TextDecoder().decode(payloadBytes));
|
|
303
|
+
if (payloadJson.bytes) {
|
|
304
|
+
// Decode base64 payload
|
|
305
|
+
const eventData = JSON.parse(atob(payloadJson.bytes));
|
|
306
|
+
if (eventData.type === 'message_start' && eventData.message) {
|
|
307
|
+
inputTokens = eventData.message.usage?.input_tokens ?? 0;
|
|
308
|
+
}
|
|
309
|
+
else if (eventData.type === 'content_block_start') {
|
|
310
|
+
currentBlockIndex = eventData.index ?? 0;
|
|
311
|
+
contentBlocks[currentBlockIndex] = eventData.content_block;
|
|
312
|
+
callbacks.onContentBlock?.(currentBlockIndex, eventData.content_block);
|
|
313
|
+
}
|
|
314
|
+
else if (eventData.type === 'content_block_delta') {
|
|
315
|
+
if (eventData.delta?.type === 'text_delta' && eventData.delta.text) {
|
|
316
|
+
fullText += eventData.delta.text;
|
|
317
|
+
callbacks.onChunk(eventData.delta.text);
|
|
318
|
+
if (contentBlocks[currentBlockIndex]) {
|
|
319
|
+
contentBlocks[currentBlockIndex].text = (contentBlocks[currentBlockIndex].text ?? '') + eventData.delta.text;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
else if (eventData.delta?.type === 'thinking_delta' && eventData.delta.thinking) {
|
|
323
|
+
callbacks.onChunk(eventData.delta.thinking);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
else if (eventData.type === 'message_delta') {
|
|
327
|
+
if (eventData.usage) {
|
|
328
|
+
outputTokens = eventData.usage.output_tokens;
|
|
329
|
+
}
|
|
330
|
+
if (eventData.delta?.stop_reason) {
|
|
331
|
+
stopReason = eventData.delta.stop_reason;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
catch {
|
|
337
|
+
// Skip malformed events
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
// Remove processed message from buffer
|
|
341
|
+
buffer = buffer.slice(totalLength);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
finally {
|
|
346
|
+
reader.releaseLock();
|
|
347
|
+
}
|
|
348
|
+
// Build response from accumulated data
|
|
349
|
+
finalMessage = {
|
|
350
|
+
id: 'msg_stream',
|
|
351
|
+
type: 'message',
|
|
352
|
+
role: 'assistant',
|
|
353
|
+
content: contentBlocks.map(b => ({
|
|
354
|
+
type: b.type,
|
|
355
|
+
text: b.text,
|
|
356
|
+
})),
|
|
357
|
+
model: modelId,
|
|
358
|
+
stop_reason: stopReason,
|
|
359
|
+
usage: {
|
|
360
|
+
input_tokens: inputTokens,
|
|
361
|
+
output_tokens: outputTokens,
|
|
362
|
+
},
|
|
363
|
+
};
|
|
364
|
+
return this.parseResponse(finalMessage, { modelId, ...request, stream: true });
|
|
365
|
+
}
|
|
366
|
+
parseResponse(response, rawRequest) {
|
|
367
|
+
const content = [];
|
|
368
|
+
for (const block of response.content) {
|
|
369
|
+
if (block.type === 'text' && block.text) {
|
|
370
|
+
content.push({ type: 'text', text: block.text });
|
|
371
|
+
}
|
|
372
|
+
else if (block.type === 'tool_use' && block.id && block.name) {
|
|
373
|
+
content.push({
|
|
374
|
+
type: 'tool_use',
|
|
375
|
+
id: block.id,
|
|
376
|
+
name: block.name,
|
|
377
|
+
input: block.input,
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
else if (block.type === 'thinking' && block.thinking) {
|
|
381
|
+
content.push({
|
|
382
|
+
type: 'thinking',
|
|
383
|
+
thinking: block.thinking,
|
|
384
|
+
signature: block.signature,
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
return {
|
|
389
|
+
content,
|
|
390
|
+
stopReason: response.stop_reason ?? 'end_turn',
|
|
391
|
+
stopSequence: response.stop_sequence ?? undefined,
|
|
392
|
+
usage: {
|
|
393
|
+
inputTokens: response.usage.input_tokens,
|
|
394
|
+
outputTokens: response.usage.output_tokens,
|
|
395
|
+
cacheCreationTokens: response.usage.cache_creation_input_tokens,
|
|
396
|
+
cacheReadTokens: response.usage.cache_read_input_tokens,
|
|
397
|
+
},
|
|
398
|
+
model: response.model,
|
|
399
|
+
rawRequest,
|
|
400
|
+
raw: response,
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
handleError(error, rawRequest) {
|
|
404
|
+
if (error instanceof BedrockError) {
|
|
405
|
+
const status = error.status;
|
|
406
|
+
const message = error.message;
|
|
407
|
+
if (status === 429) {
|
|
408
|
+
return rateLimitError(message, undefined, error, rawRequest);
|
|
409
|
+
}
|
|
410
|
+
if (status === 401 || status === 403) {
|
|
411
|
+
return authError(message, error, rawRequest);
|
|
412
|
+
}
|
|
413
|
+
if (message.includes('context') || message.includes('too long') || message.includes('token')) {
|
|
414
|
+
return contextLengthError(message, error, rawRequest);
|
|
415
|
+
}
|
|
416
|
+
if (status >= 500) {
|
|
417
|
+
return serverError(message, status, error, rawRequest);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
421
|
+
return abortError(undefined, rawRequest);
|
|
422
|
+
}
|
|
423
|
+
return new MembraneError({
|
|
424
|
+
type: 'unknown',
|
|
425
|
+
message: error instanceof Error ? error.message : String(error),
|
|
426
|
+
retryable: false,
|
|
427
|
+
rawError: error,
|
|
428
|
+
rawRequest,
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
// ============================================================================
|
|
433
|
+
// Error Class
|
|
434
|
+
// ============================================================================
|
|
435
|
+
class BedrockError extends Error {
|
|
436
|
+
status;
|
|
437
|
+
constructor(status, message) {
|
|
438
|
+
super(message);
|
|
439
|
+
this.status = status;
|
|
440
|
+
this.name = 'BedrockError';
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
//# sourceMappingURL=bedrock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bedrock.js","sourceRoot":"","sources":["../../src/providers/bedrock.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,4 +7,5 @@ export { OpenAIAdapter, toOpenAIContent, fromOpenAIContent, type OpenAIAdapterCo
|
|
|
7
7
|
export { OpenAICompatibleAdapter, toOpenAIMessages, fromOpenAIMessage, type OpenAICompatibleAdapterConfig, } from './openai-compatible.js';
|
|
8
8
|
export { OpenAICompletionsAdapter, type OpenAICompletionsAdapterConfig, } from './openai-completions.js';
|
|
9
9
|
export { MockAdapter, createEchoAdapter, createCannedAdapter, type MockAdapterConfig, } from './mock.js';
|
|
10
|
+
export { BedrockAdapter, type BedrockAdapterConfig, } from './bedrock.js';
|
|
10
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,KAAK,sBAAsB,GAC5B,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,EACrB,KAAK,uBAAuB,GAC7B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,KAAK,mBAAmB,GACzB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,6BAA6B,GACnC,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,wBAAwB,EACxB,KAAK,8BAA8B,GACpC,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,KAAK,iBAAiB,GACvB,MAAM,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,KAAK,sBAAsB,GAC5B,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,EACrB,KAAK,uBAAuB,GAC7B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,KAAK,mBAAmB,GACzB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,6BAA6B,GACnC,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,wBAAwB,EACxB,KAAK,8BAA8B,GACpC,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,KAAK,iBAAiB,GACvB,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,cAAc,EACd,KAAK,oBAAoB,GAC1B,MAAM,cAAc,CAAC"}
|
package/dist/providers/index.js
CHANGED
|
@@ -7,4 +7,5 @@ export { OpenAIAdapter, toOpenAIContent, fromOpenAIContent, } from './openai.js'
|
|
|
7
7
|
export { OpenAICompatibleAdapter, toOpenAIMessages, fromOpenAIMessage, } from './openai-compatible.js';
|
|
8
8
|
export { OpenAICompletionsAdapter, } from './openai-completions.js';
|
|
9
9
|
export { MockAdapter, createEchoAdapter, createCannedAdapter, } from './mock.js';
|
|
10
|
+
export { BedrockAdapter, } from './bedrock.js';
|
|
10
11
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,GAErB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,GAEtB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,aAAa,EACb,eAAe,EACf,iBAAiB,GAElB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,iBAAiB,GAElB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,wBAAwB,GAEzB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,mBAAmB,GAEpB,MAAM,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,GAErB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,GAEtB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,aAAa,EACb,eAAe,EACf,iBAAiB,GAElB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,iBAAiB,GAElB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,wBAAwB,GAEzB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,mBAAmB,GAEpB,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,cAAc,GAEf,MAAM,cAAc,CAAC"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,675 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AWS Bedrock provider adapter for Anthropic Claude models
|
|
3
|
+
*
|
|
4
|
+
* Uses the Anthropic Messages API format through AWS Bedrock.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type {
|
|
8
|
+
ProviderAdapter,
|
|
9
|
+
ProviderRequest,
|
|
10
|
+
ProviderRequestOptions,
|
|
11
|
+
ProviderResponse,
|
|
12
|
+
StreamCallbacks,
|
|
13
|
+
ContentBlock,
|
|
14
|
+
} from '../types/index.js';
|
|
15
|
+
import {
|
|
16
|
+
MembraneError,
|
|
17
|
+
rateLimitError,
|
|
18
|
+
contextLengthError,
|
|
19
|
+
authError,
|
|
20
|
+
serverError,
|
|
21
|
+
abortError,
|
|
22
|
+
} from '../types/index.js';
|
|
23
|
+
|
|
24
|
+
// ============================================================================
|
|
25
|
+
// Adapter Configuration
|
|
26
|
+
// ============================================================================
|
|
27
|
+
|
|
28
|
+
export interface BedrockAdapterConfig {
|
|
29
|
+
/** AWS access key ID */
|
|
30
|
+
accessKeyId?: string;
|
|
31
|
+
|
|
32
|
+
/** AWS secret access key */
|
|
33
|
+
secretAccessKey?: string;
|
|
34
|
+
|
|
35
|
+
/** AWS region (defaults to us-west-2) */
|
|
36
|
+
region?: string;
|
|
37
|
+
|
|
38
|
+
/** AWS session token (for temporary credentials) */
|
|
39
|
+
sessionToken?: string;
|
|
40
|
+
|
|
41
|
+
/** Default max tokens */
|
|
42
|
+
defaultMaxTokens?: number;
|
|
43
|
+
|
|
44
|
+
/** Anthropic API version header (defaults to 2023-06-01) */
|
|
45
|
+
anthropicVersion?: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// ============================================================================
|
|
49
|
+
// Bedrock Request/Response Types
|
|
50
|
+
// ============================================================================
|
|
51
|
+
|
|
52
|
+
interface BedrockMessageRequest {
|
|
53
|
+
anthropic_version: string;
|
|
54
|
+
max_tokens: number;
|
|
55
|
+
messages: Array<{
|
|
56
|
+
role: 'user' | 'assistant';
|
|
57
|
+
content: unknown;
|
|
58
|
+
}>;
|
|
59
|
+
system?: string | Array<{ type: 'text'; text: string; cache_control?: { type: 'ephemeral' } }>;
|
|
60
|
+
temperature?: number;
|
|
61
|
+
stop_sequences?: string[];
|
|
62
|
+
tools?: unknown[];
|
|
63
|
+
thinking?: { type: 'enabled'; budget_tokens: number };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
interface BedrockMessageResponse {
|
|
67
|
+
id: string;
|
|
68
|
+
type: 'message';
|
|
69
|
+
role: 'assistant';
|
|
70
|
+
content: Array<{
|
|
71
|
+
type: 'text' | 'tool_use' | 'thinking';
|
|
72
|
+
text?: string;
|
|
73
|
+
thinking?: string;
|
|
74
|
+
signature?: string;
|
|
75
|
+
id?: string;
|
|
76
|
+
name?: string;
|
|
77
|
+
input?: unknown;
|
|
78
|
+
}>;
|
|
79
|
+
model: string;
|
|
80
|
+
stop_reason: 'end_turn' | 'max_tokens' | 'stop_sequence' | 'tool_use' | null;
|
|
81
|
+
stop_sequence?: string | null;
|
|
82
|
+
usage: {
|
|
83
|
+
input_tokens: number;
|
|
84
|
+
output_tokens: number;
|
|
85
|
+
cache_creation_input_tokens?: number;
|
|
86
|
+
cache_read_input_tokens?: number;
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
interface BedrockStreamEvent {
|
|
91
|
+
type: string;
|
|
92
|
+
index?: number;
|
|
93
|
+
content_block?: {
|
|
94
|
+
type: string;
|
|
95
|
+
text?: string;
|
|
96
|
+
thinking?: string;
|
|
97
|
+
id?: string;
|
|
98
|
+
name?: string;
|
|
99
|
+
input?: unknown;
|
|
100
|
+
};
|
|
101
|
+
delta?: {
|
|
102
|
+
type: string;
|
|
103
|
+
text?: string;
|
|
104
|
+
thinking?: string;
|
|
105
|
+
partial_json?: string;
|
|
106
|
+
stop_reason?: string;
|
|
107
|
+
stop_sequence?: string;
|
|
108
|
+
};
|
|
109
|
+
message?: BedrockMessageResponse;
|
|
110
|
+
usage?: {
|
|
111
|
+
input_tokens: number;
|
|
112
|
+
output_tokens: number;
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// ============================================================================
|
|
117
|
+
// AWS Signature V4 Implementation
|
|
118
|
+
// ============================================================================
|
|
119
|
+
|
|
120
|
+
async function hmacSha256(key: ArrayBuffer | Uint8Array, data: string): Promise<ArrayBuffer> {
|
|
121
|
+
const cryptoKey = await crypto.subtle.importKey(
|
|
122
|
+
'raw',
|
|
123
|
+
key,
|
|
124
|
+
{ name: 'HMAC', hash: 'SHA-256' },
|
|
125
|
+
false,
|
|
126
|
+
['sign']
|
|
127
|
+
);
|
|
128
|
+
return crypto.subtle.sign('HMAC', cryptoKey, new TextEncoder().encode(data));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async function sha256(data: string): Promise<string> {
|
|
132
|
+
const hash = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(data));
|
|
133
|
+
return Array.from(new Uint8Array(hash))
|
|
134
|
+
.map(b => b.toString(16).padStart(2, '0'))
|
|
135
|
+
.join('');
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async function getSignatureKey(
|
|
139
|
+
secretKey: string,
|
|
140
|
+
dateStamp: string,
|
|
141
|
+
region: string,
|
|
142
|
+
service: string
|
|
143
|
+
): Promise<ArrayBuffer> {
|
|
144
|
+
const kDate = await hmacSha256(new TextEncoder().encode('AWS4' + secretKey), dateStamp);
|
|
145
|
+
const kRegion = await hmacSha256(kDate, region);
|
|
146
|
+
const kService = await hmacSha256(kRegion, service);
|
|
147
|
+
return hmacSha256(kService, 'aws4_request');
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function getAmzDate(): { amzDate: string; dateStamp: string } {
|
|
151
|
+
const now = new Date();
|
|
152
|
+
const amzDate = now.toISOString().replace(/[:-]|\.\d{3}/g, '');
|
|
153
|
+
const dateStamp = amzDate.slice(0, 8);
|
|
154
|
+
return { amzDate, dateStamp };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
async function signRequest(
|
|
158
|
+
method: string,
|
|
159
|
+
url: URL,
|
|
160
|
+
headers: Record<string, string>,
|
|
161
|
+
body: string,
|
|
162
|
+
accessKeyId: string,
|
|
163
|
+
secretAccessKey: string,
|
|
164
|
+
sessionToken: string | undefined,
|
|
165
|
+
region: string,
|
|
166
|
+
service: string
|
|
167
|
+
): Promise<Record<string, string>> {
|
|
168
|
+
const { amzDate, dateStamp } = getAmzDate();
|
|
169
|
+
|
|
170
|
+
// Prepare headers for signing
|
|
171
|
+
const signedHeaders: Record<string, string> = {
|
|
172
|
+
...headers,
|
|
173
|
+
host: url.host,
|
|
174
|
+
'x-amz-date': amzDate,
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
if (sessionToken) {
|
|
178
|
+
signedHeaders['x-amz-security-token'] = sessionToken;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Create canonical request
|
|
182
|
+
const sortedHeaderKeys = Object.keys(signedHeaders).sort();
|
|
183
|
+
const canonicalHeaders = sortedHeaderKeys
|
|
184
|
+
.map(k => `${k.toLowerCase()}:${signedHeaders[k]?.trim()}`)
|
|
185
|
+
.join('\n') + '\n';
|
|
186
|
+
const signedHeadersList = sortedHeaderKeys.map(k => k.toLowerCase()).join(';');
|
|
187
|
+
const payloadHash = await sha256(body);
|
|
188
|
+
|
|
189
|
+
// URI-encode path components for canonical request (AWS SigV4 requirement)
|
|
190
|
+
// AWS requires double-encoding: %3A in the URL becomes %253A in the canonical request
|
|
191
|
+
// We encode each segment without decoding first to achieve double-encoding
|
|
192
|
+
const canonicalUri = url.pathname
|
|
193
|
+
.split('/')
|
|
194
|
+
.map(segment => encodeURIComponent(segment))
|
|
195
|
+
.join('/');
|
|
196
|
+
|
|
197
|
+
const canonicalRequest = [
|
|
198
|
+
method,
|
|
199
|
+
canonicalUri,
|
|
200
|
+
url.search.slice(1), // Remove leading '?'
|
|
201
|
+
canonicalHeaders,
|
|
202
|
+
signedHeadersList,
|
|
203
|
+
payloadHash,
|
|
204
|
+
].join('\n');
|
|
205
|
+
|
|
206
|
+
// Create string to sign
|
|
207
|
+
const algorithm = 'AWS4-HMAC-SHA256';
|
|
208
|
+
const credentialScope = `${dateStamp}/${region}/${service}/aws4_request`;
|
|
209
|
+
const stringToSign = [
|
|
210
|
+
algorithm,
|
|
211
|
+
amzDate,
|
|
212
|
+
credentialScope,
|
|
213
|
+
await sha256(canonicalRequest),
|
|
214
|
+
].join('\n');
|
|
215
|
+
|
|
216
|
+
// Calculate signature
|
|
217
|
+
const signingKey = await getSignatureKey(secretAccessKey, dateStamp, region, service);
|
|
218
|
+
const signatureBuffer = await hmacSha256(signingKey, stringToSign);
|
|
219
|
+
const signature = Array.from(new Uint8Array(signatureBuffer))
|
|
220
|
+
.map(b => b.toString(16).padStart(2, '0'))
|
|
221
|
+
.join('');
|
|
222
|
+
|
|
223
|
+
// Create authorization header
|
|
224
|
+
const authorization = `${algorithm} Credential=${accessKeyId}/${credentialScope}, SignedHeaders=${signedHeadersList}, Signature=${signature}`;
|
|
225
|
+
|
|
226
|
+
return {
|
|
227
|
+
...signedHeaders,
|
|
228
|
+
authorization,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// ============================================================================
|
|
233
|
+
// Bedrock Adapter
|
|
234
|
+
// ============================================================================
|
|
235
|
+
|
|
236
|
+
export class BedrockAdapter implements ProviderAdapter {
|
|
237
|
+
readonly name = 'bedrock';
|
|
238
|
+
|
|
239
|
+
private accessKeyId: string;
|
|
240
|
+
private secretAccessKey: string;
|
|
241
|
+
private sessionToken?: string;
|
|
242
|
+
private region: string;
|
|
243
|
+
private defaultMaxTokens: number;
|
|
244
|
+
private anthropicVersion: string;
|
|
245
|
+
|
|
246
|
+
constructor(config: BedrockAdapterConfig = {}) {
|
|
247
|
+
this.accessKeyId = config.accessKeyId ?? process.env.AWS_ACCESS_KEY_ID ?? '';
|
|
248
|
+
this.secretAccessKey = config.secretAccessKey ?? process.env.AWS_SECRET_ACCESS_KEY ?? '';
|
|
249
|
+
this.sessionToken = config.sessionToken ?? process.env.AWS_SESSION_TOKEN;
|
|
250
|
+
this.region = config.region ?? process.env.AWS_REGION ?? 'us-west-2';
|
|
251
|
+
this.defaultMaxTokens = config.defaultMaxTokens ?? 4096;
|
|
252
|
+
this.anthropicVersion = config.anthropicVersion ?? 'bedrock-2023-05-31';
|
|
253
|
+
|
|
254
|
+
if (!this.accessKeyId || !this.secretAccessKey) {
|
|
255
|
+
throw new Error('AWS credentials required: accessKeyId and secretAccessKey');
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
supportsModel(modelId: string): boolean {
|
|
260
|
+
// Support both Bedrock model IDs and standard Claude model IDs
|
|
261
|
+
return modelId.includes('claude') || modelId.startsWith('anthropic.');
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Convert a standard Claude model ID to Bedrock format if needed
|
|
266
|
+
*/
|
|
267
|
+
private toBedrockModelId(modelId: string): string {
|
|
268
|
+
// If already in Bedrock format, use as-is
|
|
269
|
+
if (modelId.startsWith('anthropic.')) {
|
|
270
|
+
return modelId;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Map common Claude model IDs to Bedrock format
|
|
274
|
+
const modelMap: Record<string, string> = {
|
|
275
|
+
'claude-3-5-sonnet-20241022': 'anthropic.claude-3-5-sonnet-20241022-v2:0',
|
|
276
|
+
'claude-3-5-sonnet-latest': 'anthropic.claude-3-5-sonnet-20241022-v2:0',
|
|
277
|
+
'claude-3-5-haiku-20241022': 'anthropic.claude-3-5-haiku-20241022-v1:0',
|
|
278
|
+
'claude-3-5-haiku-latest': 'anthropic.claude-3-5-haiku-20241022-v1:0',
|
|
279
|
+
'claude-3-opus-20240229': 'anthropic.claude-3-opus-20240229-v1:0',
|
|
280
|
+
'claude-3-sonnet-20240229': 'anthropic.claude-3-sonnet-20240229-v1:0',
|
|
281
|
+
'claude-3-haiku-20240307': 'anthropic.claude-3-haiku-20240307-v1:0',
|
|
282
|
+
'claude-sonnet-4-20250514': 'anthropic.claude-sonnet-4-20250514-v1:0',
|
|
283
|
+
'claude-opus-4-20250514': 'anthropic.claude-opus-4-20250514-v1:0',
|
|
284
|
+
// Haiku 4.5 aliases
|
|
285
|
+
'claude-haiku-4-5-20251001': 'anthropic.claude-3-5-haiku-20241022-v1:0',
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
return modelMap[modelId] ?? `anthropic.${modelId}-v1:0`;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
async complete(
|
|
292
|
+
request: ProviderRequest,
|
|
293
|
+
options?: ProviderRequestOptions
|
|
294
|
+
): Promise<ProviderResponse> {
|
|
295
|
+
const bedrockModelId = this.toBedrockModelId(request.model);
|
|
296
|
+
const bedrockRequest = this.buildRequest(request);
|
|
297
|
+
const fullRequest = { modelId: bedrockModelId, ...bedrockRequest };
|
|
298
|
+
options?.onRequest?.(fullRequest);
|
|
299
|
+
|
|
300
|
+
try {
|
|
301
|
+
const response = await this.invokeModel(bedrockModelId, bedrockRequest, options?.signal);
|
|
302
|
+
return this.parseResponse(response, fullRequest);
|
|
303
|
+
} catch (error) {
|
|
304
|
+
throw this.handleError(error, fullRequest);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
async stream(
|
|
309
|
+
request: ProviderRequest,
|
|
310
|
+
callbacks: StreamCallbacks,
|
|
311
|
+
options?: ProviderRequestOptions
|
|
312
|
+
): Promise<ProviderResponse> {
|
|
313
|
+
const bedrockModelId = this.toBedrockModelId(request.model);
|
|
314
|
+
const bedrockRequest = this.buildRequest(request);
|
|
315
|
+
const fullRequest = { modelId: bedrockModelId, ...bedrockRequest, stream: true };
|
|
316
|
+
options?.onRequest?.(fullRequest);
|
|
317
|
+
|
|
318
|
+
try {
|
|
319
|
+
return await this.invokeModelWithStream(bedrockModelId, bedrockRequest, callbacks, options?.signal);
|
|
320
|
+
} catch (error) {
|
|
321
|
+
throw this.handleError(error, fullRequest);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
private buildRequest(request: ProviderRequest): BedrockMessageRequest {
|
|
326
|
+
const params: BedrockMessageRequest = {
|
|
327
|
+
anthropic_version: this.anthropicVersion,
|
|
328
|
+
max_tokens: request.maxTokens || this.defaultMaxTokens,
|
|
329
|
+
messages: request.messages as BedrockMessageRequest['messages'],
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
// Handle system prompt
|
|
333
|
+
if (request.system) {
|
|
334
|
+
params.system = request.system as BedrockMessageRequest['system'];
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if (request.temperature !== undefined) {
|
|
338
|
+
params.temperature = request.temperature;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if (request.stopSequences && request.stopSequences.length > 0) {
|
|
342
|
+
params.stop_sequences = request.stopSequences;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if (request.tools && request.tools.length > 0) {
|
|
346
|
+
params.tools = request.tools;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Handle extended thinking
|
|
350
|
+
if ((request as any).thinking) {
|
|
351
|
+
params.thinking = (request as any).thinking;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Apply extra params, excluding internal membrane fields
|
|
355
|
+
if (request.extra) {
|
|
356
|
+
const { normalizedMessages, prompt, ...rest } = request.extra as Record<string, unknown>;
|
|
357
|
+
Object.assign(params, rest);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
return params;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
private async invokeModel(
|
|
364
|
+
modelId: string,
|
|
365
|
+
request: BedrockMessageRequest,
|
|
366
|
+
signal?: AbortSignal
|
|
367
|
+
): Promise<BedrockMessageResponse> {
|
|
368
|
+
const url = new URL(
|
|
369
|
+
`https://bedrock-runtime.${this.region}.amazonaws.com/model/${encodeURIComponent(modelId)}/invoke`
|
|
370
|
+
);
|
|
371
|
+
|
|
372
|
+
const body = JSON.stringify(request);
|
|
373
|
+
const headers: Record<string, string> = {
|
|
374
|
+
'content-type': 'application/json',
|
|
375
|
+
accept: 'application/json',
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
const signedHeaders = await signRequest(
|
|
379
|
+
'POST',
|
|
380
|
+
url,
|
|
381
|
+
headers,
|
|
382
|
+
body,
|
|
383
|
+
this.accessKeyId,
|
|
384
|
+
this.secretAccessKey,
|
|
385
|
+
this.sessionToken,
|
|
386
|
+
this.region,
|
|
387
|
+
'bedrock'
|
|
388
|
+
);
|
|
389
|
+
|
|
390
|
+
const response = await fetch(url.toString(), {
|
|
391
|
+
method: 'POST',
|
|
392
|
+
headers: signedHeaders,
|
|
393
|
+
body,
|
|
394
|
+
signal,
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
if (!response.ok) {
|
|
398
|
+
const errorText = await response.text();
|
|
399
|
+
throw new BedrockError(response.status, errorText);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
return response.json() as Promise<BedrockMessageResponse>;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
private async invokeModelWithStream(
|
|
406
|
+
modelId: string,
|
|
407
|
+
request: BedrockMessageRequest,
|
|
408
|
+
callbacks: StreamCallbacks,
|
|
409
|
+
signal?: AbortSignal
|
|
410
|
+
): Promise<ProviderResponse> {
|
|
411
|
+
const url = new URL(
|
|
412
|
+
`https://bedrock-runtime.${this.region}.amazonaws.com/model/${encodeURIComponent(modelId)}/invoke-with-response-stream`
|
|
413
|
+
);
|
|
414
|
+
|
|
415
|
+
const body = JSON.stringify(request);
|
|
416
|
+
const headers: Record<string, string> = {
|
|
417
|
+
'content-type': 'application/json',
|
|
418
|
+
accept: 'application/vnd.amazon.eventstream',
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
const signedHeaders = await signRequest(
|
|
422
|
+
'POST',
|
|
423
|
+
url,
|
|
424
|
+
headers,
|
|
425
|
+
body,
|
|
426
|
+
this.accessKeyId,
|
|
427
|
+
this.secretAccessKey,
|
|
428
|
+
this.sessionToken,
|
|
429
|
+
this.region,
|
|
430
|
+
'bedrock'
|
|
431
|
+
);
|
|
432
|
+
|
|
433
|
+
const response = await fetch(url.toString(), {
|
|
434
|
+
method: 'POST',
|
|
435
|
+
headers: signedHeaders,
|
|
436
|
+
body,
|
|
437
|
+
signal,
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
if (!response.ok) {
|
|
441
|
+
const errorText = await response.text();
|
|
442
|
+
throw new BedrockError(response.status, errorText);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// Parse the binary event stream
|
|
446
|
+
const contentBlocks: Array<{ type: string; text?: string }> = [];
|
|
447
|
+
let currentBlockIndex = -1;
|
|
448
|
+
let finalMessage: BedrockMessageResponse | undefined;
|
|
449
|
+
let inputTokens = 0;
|
|
450
|
+
let outputTokens = 0;
|
|
451
|
+
let stopReason: string = 'end_turn';
|
|
452
|
+
let fullText = '';
|
|
453
|
+
|
|
454
|
+
const reader = response.body?.getReader();
|
|
455
|
+
if (!reader) {
|
|
456
|
+
throw new Error('No response body');
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
let buffer = new Uint8Array(0);
|
|
460
|
+
|
|
461
|
+
try {
|
|
462
|
+
while (true) {
|
|
463
|
+
const { done, value } = await reader.read();
|
|
464
|
+
if (done) break;
|
|
465
|
+
|
|
466
|
+
// Append new data to buffer
|
|
467
|
+
const newBuffer = new Uint8Array(buffer.length + value.length);
|
|
468
|
+
newBuffer.set(buffer);
|
|
469
|
+
newBuffer.set(value, buffer.length);
|
|
470
|
+
buffer = newBuffer;
|
|
471
|
+
|
|
472
|
+
// Parse complete events from buffer
|
|
473
|
+
while (buffer.length >= 16) {
|
|
474
|
+
// AWS event stream format:
|
|
475
|
+
// 4 bytes: total byte length (big-endian)
|
|
476
|
+
// 4 bytes: headers length (big-endian)
|
|
477
|
+
// 4 bytes: prelude CRC
|
|
478
|
+
// headers
|
|
479
|
+
// payload
|
|
480
|
+
// 4 bytes: message CRC
|
|
481
|
+
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
482
|
+
const totalLength = view.getUint32(0, false);
|
|
483
|
+
const headersLength = view.getUint32(4, false);
|
|
484
|
+
|
|
485
|
+
if (buffer.length < totalLength) {
|
|
486
|
+
// Incomplete message, wait for more data
|
|
487
|
+
break;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// Extract payload (skip prelude, headers, and CRCs)
|
|
491
|
+
const payloadStart = 12 + headersLength;
|
|
492
|
+
const payloadEnd = totalLength - 4;
|
|
493
|
+
const payloadBytes = buffer.slice(payloadStart, payloadEnd);
|
|
494
|
+
|
|
495
|
+
// Parse headers to find event type
|
|
496
|
+
let eventType = '';
|
|
497
|
+
let headerOffset = 12;
|
|
498
|
+
const headerEnd = 12 + headersLength;
|
|
499
|
+
while (headerOffset < headerEnd) {
|
|
500
|
+
const nameLength = buffer[headerOffset]!;
|
|
501
|
+
headerOffset += 1;
|
|
502
|
+
const name = new TextDecoder().decode(buffer.slice(headerOffset, headerOffset + nameLength));
|
|
503
|
+
headerOffset += nameLength;
|
|
504
|
+
const valueType = buffer[headerOffset]!;
|
|
505
|
+
headerOffset += 1;
|
|
506
|
+
|
|
507
|
+
if (valueType === 7) {
|
|
508
|
+
// String type
|
|
509
|
+
const valueLength = new DataView(buffer.buffer, buffer.byteOffset + headerOffset, 2).getUint16(0, false);
|
|
510
|
+
headerOffset += 2;
|
|
511
|
+
const value = new TextDecoder().decode(buffer.slice(headerOffset, headerOffset + valueLength));
|
|
512
|
+
headerOffset += valueLength;
|
|
513
|
+
|
|
514
|
+
if (name === ':event-type') {
|
|
515
|
+
eventType = value;
|
|
516
|
+
}
|
|
517
|
+
} else {
|
|
518
|
+
// Skip other header types
|
|
519
|
+
break;
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// Parse the JSON payload
|
|
524
|
+
if (eventType === 'chunk' && payloadBytes.length > 0) {
|
|
525
|
+
try {
|
|
526
|
+
const payloadJson = JSON.parse(new TextDecoder().decode(payloadBytes));
|
|
527
|
+
if (payloadJson.bytes) {
|
|
528
|
+
// Decode base64 payload
|
|
529
|
+
const eventData = JSON.parse(atob(payloadJson.bytes)) as BedrockStreamEvent;
|
|
530
|
+
|
|
531
|
+
if (eventData.type === 'message_start' && eventData.message) {
|
|
532
|
+
inputTokens = eventData.message.usage?.input_tokens ?? 0;
|
|
533
|
+
} else if (eventData.type === 'content_block_start') {
|
|
534
|
+
currentBlockIndex = eventData.index ?? 0;
|
|
535
|
+
contentBlocks[currentBlockIndex] = eventData.content_block as { type: string };
|
|
536
|
+
callbacks.onContentBlock?.(currentBlockIndex, eventData.content_block);
|
|
537
|
+
} else if (eventData.type === 'content_block_delta') {
|
|
538
|
+
if (eventData.delta?.type === 'text_delta' && eventData.delta.text) {
|
|
539
|
+
fullText += eventData.delta.text;
|
|
540
|
+
callbacks.onChunk(eventData.delta.text);
|
|
541
|
+
if (contentBlocks[currentBlockIndex]) {
|
|
542
|
+
contentBlocks[currentBlockIndex]!.text = (contentBlocks[currentBlockIndex]!.text ?? '') + eventData.delta.text;
|
|
543
|
+
}
|
|
544
|
+
} else if (eventData.delta?.type === 'thinking_delta' && eventData.delta.thinking) {
|
|
545
|
+
callbacks.onChunk(eventData.delta.thinking);
|
|
546
|
+
}
|
|
547
|
+
} else if (eventData.type === 'message_delta') {
|
|
548
|
+
if (eventData.usage) {
|
|
549
|
+
outputTokens = eventData.usage.output_tokens;
|
|
550
|
+
}
|
|
551
|
+
if (eventData.delta?.stop_reason) {
|
|
552
|
+
stopReason = eventData.delta.stop_reason;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
} catch {
|
|
557
|
+
// Skip malformed events
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
// Remove processed message from buffer
|
|
562
|
+
buffer = buffer.slice(totalLength);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
} finally {
|
|
566
|
+
reader.releaseLock();
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// Build response from accumulated data
|
|
570
|
+
finalMessage = {
|
|
571
|
+
id: 'msg_stream',
|
|
572
|
+
type: 'message',
|
|
573
|
+
role: 'assistant',
|
|
574
|
+
content: contentBlocks.map(b => ({
|
|
575
|
+
type: b.type as 'text',
|
|
576
|
+
text: b.text,
|
|
577
|
+
})),
|
|
578
|
+
model: modelId,
|
|
579
|
+
stop_reason: stopReason as BedrockMessageResponse['stop_reason'],
|
|
580
|
+
usage: {
|
|
581
|
+
input_tokens: inputTokens,
|
|
582
|
+
output_tokens: outputTokens,
|
|
583
|
+
},
|
|
584
|
+
};
|
|
585
|
+
|
|
586
|
+
return this.parseResponse(finalMessage, { modelId, ...request, stream: true });
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
private parseResponse(response: BedrockMessageResponse, rawRequest: unknown): ProviderResponse {
|
|
590
|
+
const content: ContentBlock[] = [];
|
|
591
|
+
|
|
592
|
+
for (const block of response.content) {
|
|
593
|
+
if (block.type === 'text' && block.text) {
|
|
594
|
+
content.push({ type: 'text', text: block.text });
|
|
595
|
+
} else if (block.type === 'tool_use' && block.id && block.name) {
|
|
596
|
+
content.push({
|
|
597
|
+
type: 'tool_use',
|
|
598
|
+
id: block.id,
|
|
599
|
+
name: block.name,
|
|
600
|
+
input: block.input as Record<string, unknown>,
|
|
601
|
+
});
|
|
602
|
+
} else if (block.type === 'thinking' && block.thinking) {
|
|
603
|
+
content.push({
|
|
604
|
+
type: 'thinking',
|
|
605
|
+
thinking: block.thinking,
|
|
606
|
+
signature: block.signature,
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
return {
|
|
612
|
+
content,
|
|
613
|
+
stopReason: response.stop_reason ?? 'end_turn',
|
|
614
|
+
stopSequence: response.stop_sequence ?? undefined,
|
|
615
|
+
usage: {
|
|
616
|
+
inputTokens: response.usage.input_tokens,
|
|
617
|
+
outputTokens: response.usage.output_tokens,
|
|
618
|
+
cacheCreationTokens: response.usage.cache_creation_input_tokens,
|
|
619
|
+
cacheReadTokens: response.usage.cache_read_input_tokens,
|
|
620
|
+
},
|
|
621
|
+
model: response.model,
|
|
622
|
+
rawRequest,
|
|
623
|
+
raw: response,
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
private handleError(error: unknown, rawRequest?: unknown): MembraneError {
|
|
628
|
+
if (error instanceof BedrockError) {
|
|
629
|
+
const status = error.status;
|
|
630
|
+
const message = error.message;
|
|
631
|
+
|
|
632
|
+
if (status === 429) {
|
|
633
|
+
return rateLimitError(message, undefined, error, rawRequest);
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
if (status === 401 || status === 403) {
|
|
637
|
+
return authError(message, error, rawRequest);
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
if (message.includes('context') || message.includes('too long') || message.includes('token')) {
|
|
641
|
+
return contextLengthError(message, error, rawRequest);
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
if (status >= 500) {
|
|
645
|
+
return serverError(message, status, error, rawRequest);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
650
|
+
return abortError(undefined, rawRequest);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
return new MembraneError({
|
|
654
|
+
type: 'unknown',
|
|
655
|
+
message: error instanceof Error ? error.message : String(error),
|
|
656
|
+
retryable: false,
|
|
657
|
+
rawError: error,
|
|
658
|
+
rawRequest,
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
// ============================================================================
|
|
664
|
+
// Error Class
|
|
665
|
+
// ============================================================================
|
|
666
|
+
|
|
667
|
+
class BedrockError extends Error {
|
|
668
|
+
constructor(
|
|
669
|
+
public status: number,
|
|
670
|
+
message: string
|
|
671
|
+
) {
|
|
672
|
+
super(message);
|
|
673
|
+
this.name = 'BedrockError';
|
|
674
|
+
}
|
|
675
|
+
}
|