@node-llm/core 1.7.0 → 1.8.0
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/README.md +9 -8
- package/dist/aliases.d.ts +213 -0
- package/dist/aliases.d.ts.map +1 -1
- package/dist/aliases.js +238 -25
- package/dist/chat/Chat.d.ts +2 -2
- package/dist/chat/Chat.d.ts.map +1 -1
- package/dist/chat/Chat.js +21 -5
- package/dist/chat/ChatResponse.d.ts +5 -1
- package/dist/chat/ChatResponse.d.ts.map +1 -1
- package/dist/chat/ChatResponse.js +9 -3
- package/dist/chat/Content.d.ts +7 -0
- package/dist/chat/Content.d.ts.map +1 -1
- package/dist/config.d.ts +28 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +50 -0
- package/dist/llm.d.ts.map +1 -1
- package/dist/llm.js +3 -2
- package/dist/models/models.d.ts +321 -76
- package/dist/models/models.d.ts.map +1 -1
- package/dist/models/models.js +7764 -2934
- package/dist/providers/Provider.d.ts +5 -0
- package/dist/providers/Provider.d.ts.map +1 -1
- package/dist/providers/anthropic/Capabilities.d.ts +1 -0
- package/dist/providers/anthropic/Capabilities.d.ts.map +1 -1
- package/dist/providers/anthropic/Capabilities.js +8 -5
- package/dist/providers/bedrock/BedrockProvider.d.ts +53 -0
- package/dist/providers/bedrock/BedrockProvider.d.ts.map +1 -0
- package/dist/providers/bedrock/BedrockProvider.js +107 -0
- package/dist/providers/bedrock/Capabilities.d.ts +50 -0
- package/dist/providers/bedrock/Capabilities.d.ts.map +1 -0
- package/dist/providers/bedrock/Capabilities.js +233 -0
- package/dist/providers/bedrock/Chat.d.ts +26 -0
- package/dist/providers/bedrock/Chat.d.ts.map +1 -0
- package/dist/providers/bedrock/Chat.js +170 -0
- package/dist/providers/bedrock/Embeddings.d.ts +22 -0
- package/dist/providers/bedrock/Embeddings.d.ts.map +1 -0
- package/dist/providers/bedrock/Embeddings.js +100 -0
- package/dist/providers/bedrock/Image.d.ts +33 -0
- package/dist/providers/bedrock/Image.d.ts.map +1 -0
- package/dist/providers/bedrock/Image.js +154 -0
- package/dist/providers/bedrock/Models.d.ts +34 -0
- package/dist/providers/bedrock/Models.d.ts.map +1 -0
- package/dist/providers/bedrock/Models.js +131 -0
- package/dist/providers/bedrock/Moderation.d.ts +23 -0
- package/dist/providers/bedrock/Moderation.d.ts.map +1 -0
- package/dist/providers/bedrock/Moderation.js +138 -0
- package/dist/providers/bedrock/Streaming.d.ts +21 -0
- package/dist/providers/bedrock/Streaming.d.ts.map +1 -0
- package/dist/providers/bedrock/Streaming.js +240 -0
- package/dist/providers/bedrock/config.d.ts +57 -0
- package/dist/providers/bedrock/config.d.ts.map +1 -0
- package/dist/providers/bedrock/config.js +33 -0
- package/dist/providers/bedrock/index.d.ts +8 -0
- package/dist/providers/bedrock/index.d.ts.map +1 -0
- package/dist/providers/bedrock/index.js +30 -0
- package/dist/providers/bedrock/mapper.d.ts +37 -0
- package/dist/providers/bedrock/mapper.d.ts.map +1 -0
- package/dist/providers/bedrock/mapper.js +204 -0
- package/dist/providers/bedrock/types.d.ts +179 -0
- package/dist/providers/bedrock/types.d.ts.map +1 -0
- package/dist/providers/bedrock/types.js +7 -0
- package/dist/providers/deepseek/Capabilities.d.ts +3 -2
- package/dist/providers/deepseek/Capabilities.d.ts.map +1 -1
- package/dist/providers/deepseek/Capabilities.js +19 -5
- package/dist/providers/gemini/Capabilities.d.ts +1 -0
- package/dist/providers/gemini/Capabilities.d.ts.map +1 -1
- package/dist/providers/gemini/Capabilities.js +9 -6
- package/dist/providers/gemini/Chat.d.ts.map +1 -1
- package/dist/providers/gemini/Chat.js +6 -23
- package/dist/providers/ollama/Capabilities.d.ts.map +1 -1
- package/dist/providers/ollama/Capabilities.js +4 -1
- package/dist/providers/openai/Capabilities.d.ts +1 -0
- package/dist/providers/openai/Capabilities.d.ts.map +1 -1
- package/dist/providers/openai/Capabilities.js +14 -11
- package/dist/providers/registry.d.ts +2 -1
- package/dist/providers/registry.d.ts.map +1 -1
- package/dist/providers/registry.js +2 -1
- package/dist/utils/AwsSigV4.d.ts +51 -0
- package/dist/utils/AwsSigV4.d.ts.map +1 -0
- package/dist/utils/AwsSigV4.js +209 -0
- package/package.json +1 -1
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bedrock Chat Handler
|
|
3
|
+
*
|
|
4
|
+
* Executes chat requests against the Bedrock Converse API.
|
|
5
|
+
*/
|
|
6
|
+
import { validateBedrockConfig, getBedrockEndpoint } from "./config.js";
|
|
7
|
+
import { buildConverseRequest } from "./mapper.js";
|
|
8
|
+
import { signRequest } from "../../utils/AwsSigV4.js";
|
|
9
|
+
import { ModelRegistry } from "../../models/ModelRegistry.js";
|
|
10
|
+
import { fetchWithTimeout } from "../../utils/fetch.js";
|
|
11
|
+
import { logger } from "../../utils/logger.js";
|
|
12
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
13
|
+
// Chat Handler
|
|
14
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
15
|
+
export class BedrockChat {
|
|
16
|
+
config;
|
|
17
|
+
authMode;
|
|
18
|
+
baseUrl;
|
|
19
|
+
constructor(config) {
|
|
20
|
+
this.config = config;
|
|
21
|
+
this.authMode = validateBedrockConfig(config);
|
|
22
|
+
this.baseUrl = getBedrockEndpoint(config.region);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Execute a chat request against Bedrock Converse API.
|
|
26
|
+
*/
|
|
27
|
+
async execute(request) {
|
|
28
|
+
const modelId = request.model;
|
|
29
|
+
const url = `${this.baseUrl}/model/${modelId}/converse`;
|
|
30
|
+
// Build the Bedrock request body
|
|
31
|
+
const guardrail = this.config.guardrailIdentifier && this.config.guardrailVersion
|
|
32
|
+
? {
|
|
33
|
+
guardrailIdentifier: this.config.guardrailIdentifier,
|
|
34
|
+
guardrailVersion: this.config.guardrailVersion
|
|
35
|
+
}
|
|
36
|
+
: undefined;
|
|
37
|
+
const body = buildConverseRequest(request.messages, request.tools, {
|
|
38
|
+
maxTokens: request.max_tokens,
|
|
39
|
+
temperature: request.temperature,
|
|
40
|
+
thinking: request.thinking,
|
|
41
|
+
guardrail,
|
|
42
|
+
additionalModelRequestFields: request.additionalModelRequestFields
|
|
43
|
+
});
|
|
44
|
+
const bodyJson = JSON.stringify(body);
|
|
45
|
+
// Build headers based on auth mode
|
|
46
|
+
const headers = this.buildHeaders(url, bodyJson, request.headers);
|
|
47
|
+
logger.logRequest("Bedrock", "POST", url, body);
|
|
48
|
+
// Make the request
|
|
49
|
+
const response = await fetchWithTimeout(url, {
|
|
50
|
+
method: "POST",
|
|
51
|
+
headers,
|
|
52
|
+
body: bodyJson
|
|
53
|
+
}, request.requestTimeout ?? this.config.requestTimeout);
|
|
54
|
+
if (!response.ok) {
|
|
55
|
+
const errorText = await response.text();
|
|
56
|
+
logger.logResponse("Bedrock", response.status, response.statusText, errorText);
|
|
57
|
+
let message = errorText;
|
|
58
|
+
// Improve clarity for known AWS errors
|
|
59
|
+
if (errorText.includes("INVALID_PAYMENT_INSTRUMENT")) {
|
|
60
|
+
message =
|
|
61
|
+
"Billing setup incomplete for AWS Marketplace models. Ensure a credit card is set as default payment method.";
|
|
62
|
+
}
|
|
63
|
+
else if (errorText.includes("AccessDeniedException") &&
|
|
64
|
+
errorText.includes("model access")) {
|
|
65
|
+
message =
|
|
66
|
+
"Access denied for this model. Ensure you have requested and been granted access in the AWS Bedrock console (Model Access section).";
|
|
67
|
+
}
|
|
68
|
+
else if (errorText.includes("ThrottlingException")) {
|
|
69
|
+
message = "Bedrock API throttling. Too many requests. Please retry with backoff.";
|
|
70
|
+
}
|
|
71
|
+
else if (errorText.includes("ValidationException")) {
|
|
72
|
+
message = `Bedrock validation error: ${errorText}`;
|
|
73
|
+
}
|
|
74
|
+
throw new Error(`Bedrock API error (${response.status}): ${message}`);
|
|
75
|
+
}
|
|
76
|
+
const json = (await response.json());
|
|
77
|
+
logger.logResponse("Bedrock", response.status, response.statusText, json);
|
|
78
|
+
const result = this.parseResponse(json);
|
|
79
|
+
if (result.usage) {
|
|
80
|
+
result.usage = ModelRegistry.calculateCost(result.usage, modelId, "bedrock");
|
|
81
|
+
}
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Build request headers based on auth mode.
|
|
86
|
+
*/
|
|
87
|
+
buildHeaders(url, body, additionalHeaders) {
|
|
88
|
+
const headers = {
|
|
89
|
+
"Content-Type": "application/json",
|
|
90
|
+
Accept: "application/json",
|
|
91
|
+
...additionalHeaders
|
|
92
|
+
};
|
|
93
|
+
if (this.authMode === "apiKey") {
|
|
94
|
+
// Simple Bearer token auth
|
|
95
|
+
headers["Authorization"] = `Bearer ${this.config.apiKey}`;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
// SigV4 signing
|
|
99
|
+
const credentials = {
|
|
100
|
+
accessKeyId: this.config.accessKeyId,
|
|
101
|
+
secretAccessKey: this.config.secretAccessKey,
|
|
102
|
+
sessionToken: this.config.sessionToken
|
|
103
|
+
};
|
|
104
|
+
const signedHeaders = signRequest({
|
|
105
|
+
method: "POST",
|
|
106
|
+
url,
|
|
107
|
+
body,
|
|
108
|
+
credentials,
|
|
109
|
+
region: this.config.region,
|
|
110
|
+
service: "bedrock"
|
|
111
|
+
});
|
|
112
|
+
// Merge signed headers
|
|
113
|
+
headers["host"] = signedHeaders.host;
|
|
114
|
+
headers["x-amz-date"] = signedHeaders["x-amz-date"];
|
|
115
|
+
headers["x-amz-content-sha256"] = signedHeaders["x-amz-content-sha256"];
|
|
116
|
+
headers["Authorization"] = signedHeaders.authorization;
|
|
117
|
+
if (signedHeaders["x-amz-security-token"]) {
|
|
118
|
+
headers["x-amz-security-token"] = signedHeaders["x-amz-security-token"];
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return headers;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Parse Bedrock response to NodeLLM format.
|
|
125
|
+
*/
|
|
126
|
+
parseResponse(response) {
|
|
127
|
+
const message = response.output.message;
|
|
128
|
+
let content = null;
|
|
129
|
+
let thinkingText = null;
|
|
130
|
+
const toolCalls = [];
|
|
131
|
+
// Process content blocks
|
|
132
|
+
for (const block of message.content) {
|
|
133
|
+
if (block.text) {
|
|
134
|
+
content = content ? content + block.text : block.text;
|
|
135
|
+
}
|
|
136
|
+
if (block.reasoningContent?.text) {
|
|
137
|
+
thinkingText = thinkingText
|
|
138
|
+
? thinkingText + block.reasoningContent.text
|
|
139
|
+
: block.reasoningContent.text;
|
|
140
|
+
}
|
|
141
|
+
if (block.toolUse) {
|
|
142
|
+
toolCalls.push({
|
|
143
|
+
id: block.toolUse.toolUseId,
|
|
144
|
+
type: "function",
|
|
145
|
+
function: {
|
|
146
|
+
name: block.toolUse.name,
|
|
147
|
+
arguments: JSON.stringify(block.toolUse.input)
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Build usage info
|
|
153
|
+
const usage = {
|
|
154
|
+
input_tokens: response.usage.inputTokens,
|
|
155
|
+
output_tokens: response.usage.outputTokens,
|
|
156
|
+
total_tokens: response.usage.totalTokens,
|
|
157
|
+
cached_tokens: response.usage.cacheReadInputTokens,
|
|
158
|
+
cache_creation_tokens: response.usage.cacheWriteInputTokens
|
|
159
|
+
};
|
|
160
|
+
return {
|
|
161
|
+
content,
|
|
162
|
+
thinking: thinkingText ? { text: thinkingText } : undefined,
|
|
163
|
+
reasoning: thinkingText || undefined, // Keep deprecated field for compat
|
|
164
|
+
tool_calls: toolCalls.length > 0 ? toolCalls : undefined,
|
|
165
|
+
usage,
|
|
166
|
+
finish_reason: response.stopReason,
|
|
167
|
+
metadata: response.trace ? { trace: response.trace } : undefined
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bedrock Embeddings Handler
|
|
3
|
+
*
|
|
4
|
+
* Executes embedding requests against the Bedrock InvokeModel API.
|
|
5
|
+
*/
|
|
6
|
+
import { EmbeddingRequest, EmbeddingResponse } from "../Provider.js";
|
|
7
|
+
import { BedrockConfig } from "./config.js";
|
|
8
|
+
export declare class BedrockEmbeddings {
|
|
9
|
+
private readonly config;
|
|
10
|
+
private readonly authMode;
|
|
11
|
+
private readonly baseUrl;
|
|
12
|
+
constructor(config: BedrockConfig);
|
|
13
|
+
/**
|
|
14
|
+
* Execute an embedding request against Bedrock InvokeModel API.
|
|
15
|
+
*/
|
|
16
|
+
execute(request: EmbeddingRequest): Promise<EmbeddingResponse>;
|
|
17
|
+
/**
|
|
18
|
+
* Build request headers based on auth mode.
|
|
19
|
+
*/
|
|
20
|
+
private buildHeaders;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=Embeddings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Embeddings.d.ts","sourceRoot":"","sources":["../../../src/providers/bedrock/Embeddings.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,aAAa,EAA6C,MAAM,aAAa,CAAC;AAwBvF,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,MAAM,EAAE,aAAa;IAMjC;;OAEG;IACG,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAqDpE;;OAEG;IACH,OAAO,CAAC,YAAY;CAoCrB"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bedrock Embeddings Handler
|
|
3
|
+
*
|
|
4
|
+
* Executes embedding requests against the Bedrock InvokeModel API.
|
|
5
|
+
*/
|
|
6
|
+
import { validateBedrockConfig, getBedrockEndpoint } from "./config.js";
|
|
7
|
+
import { signRequest } from "../../utils/AwsSigV4.js";
|
|
8
|
+
import { fetchWithTimeout } from "../../utils/fetch.js";
|
|
9
|
+
import { logger } from "../../utils/logger.js";
|
|
10
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
11
|
+
// Embeddings Handler
|
|
12
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
13
|
+
export class BedrockEmbeddings {
|
|
14
|
+
config;
|
|
15
|
+
authMode;
|
|
16
|
+
baseUrl;
|
|
17
|
+
constructor(config) {
|
|
18
|
+
this.config = config;
|
|
19
|
+
this.authMode = validateBedrockConfig(config);
|
|
20
|
+
this.baseUrl = getBedrockEndpoint(config.region);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Execute an embedding request against Bedrock InvokeModel API.
|
|
24
|
+
*/
|
|
25
|
+
async execute(request) {
|
|
26
|
+
const modelId = request.model ?? "amazon.titan-embed-text-v2:0";
|
|
27
|
+
const url = `${this.baseUrl}/model/${modelId}/invoke`;
|
|
28
|
+
// Handle single vs multiple inputs (Titan only supports one at a time via InvokeModel)
|
|
29
|
+
const inputs = Array.isArray(request.input) ? request.input : [request.input];
|
|
30
|
+
const results = [];
|
|
31
|
+
let totalTokens = 0;
|
|
32
|
+
// Bedrock InvokeModel API for Titan embeddings processes one text at a time.
|
|
33
|
+
// We iterate through inputs and collect embeddings.
|
|
34
|
+
for (const text of inputs) {
|
|
35
|
+
const body = {
|
|
36
|
+
inputText: text,
|
|
37
|
+
// Titan V2 supports 256, 512, 1024 dimensions. NodeLLM doesn't have a standardized field for this yet,
|
|
38
|
+
// so we use the model's default (typically 1024 for V2) unless passed in headers/custom.
|
|
39
|
+
normalize: true
|
|
40
|
+
};
|
|
41
|
+
const bodyJson = JSON.stringify(body);
|
|
42
|
+
const headers = this.buildHeaders(url, bodyJson);
|
|
43
|
+
logger.logRequest("BedrockEmbeddings", "POST", url, body);
|
|
44
|
+
const response = await fetchWithTimeout(url, {
|
|
45
|
+
method: "POST",
|
|
46
|
+
headers,
|
|
47
|
+
body: bodyJson
|
|
48
|
+
}, request.requestTimeout ?? this.config.requestTimeout);
|
|
49
|
+
if (!response.ok) {
|
|
50
|
+
const errorText = await response.text();
|
|
51
|
+
logger.logResponse("BedrockEmbeddings", response.status, response.statusText, errorText);
|
|
52
|
+
throw new Error(`Bedrock Embeddings error (${response.status}): ${errorText}`);
|
|
53
|
+
}
|
|
54
|
+
const json = (await response.json());
|
|
55
|
+
results.push(json.embedding);
|
|
56
|
+
totalTokens += json.inputTextTokenCount;
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
vectors: results,
|
|
60
|
+
model: modelId,
|
|
61
|
+
input_tokens: totalTokens,
|
|
62
|
+
dimensions: results[0]?.length || 0
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Build request headers based on auth mode.
|
|
67
|
+
*/
|
|
68
|
+
buildHeaders(url, body) {
|
|
69
|
+
const headers = {
|
|
70
|
+
"Content-Type": "application/json",
|
|
71
|
+
Accept: "application/json"
|
|
72
|
+
};
|
|
73
|
+
if (this.authMode === "apiKey") {
|
|
74
|
+
headers["Authorization"] = `Bearer ${this.config.apiKey}`;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
const credentials = {
|
|
78
|
+
accessKeyId: this.config.accessKeyId,
|
|
79
|
+
secretAccessKey: this.config.secretAccessKey,
|
|
80
|
+
sessionToken: this.config.sessionToken
|
|
81
|
+
};
|
|
82
|
+
const signedHeaders = signRequest({
|
|
83
|
+
method: "POST",
|
|
84
|
+
url,
|
|
85
|
+
body: body,
|
|
86
|
+
credentials,
|
|
87
|
+
region: this.config.region,
|
|
88
|
+
service: "bedrock"
|
|
89
|
+
});
|
|
90
|
+
headers["host"] = signedHeaders.host;
|
|
91
|
+
headers["x-amz-date"] = signedHeaders["x-amz-date"];
|
|
92
|
+
headers["x-amz-content-sha256"] = signedHeaders["x-amz-content-sha256"];
|
|
93
|
+
headers["Authorization"] = signedHeaders.authorization;
|
|
94
|
+
if (signedHeaders["x-amz-security-token"]) {
|
|
95
|
+
headers["x-amz-security-token"] = signedHeaders["x-amz-security-token"];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return headers;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bedrock Image Generation Handler
|
|
3
|
+
*
|
|
4
|
+
* Supports Amazon Titan Image Generator and Stability.ai Stable Diffusion models.
|
|
5
|
+
*/
|
|
6
|
+
import { ImageRequest, ImageResponse } from "../Provider.js";
|
|
7
|
+
import { BedrockConfig } from "./config.js";
|
|
8
|
+
export declare class BedrockImage {
|
|
9
|
+
private readonly config;
|
|
10
|
+
private readonly baseUrl;
|
|
11
|
+
constructor(config: BedrockConfig);
|
|
12
|
+
/**
|
|
13
|
+
* Execute an image generation request.
|
|
14
|
+
*/
|
|
15
|
+
execute(request: ImageRequest): Promise<ImageResponse>;
|
|
16
|
+
/**
|
|
17
|
+
* Build model-specific request body.
|
|
18
|
+
*/
|
|
19
|
+
private buildRequestBody;
|
|
20
|
+
/**
|
|
21
|
+
* Parse model-specific response.
|
|
22
|
+
*/
|
|
23
|
+
private parseResponse;
|
|
24
|
+
/**
|
|
25
|
+
* Parse size string (e.g. "1024x1024") into height and width.
|
|
26
|
+
*/
|
|
27
|
+
private parseSize;
|
|
28
|
+
/**
|
|
29
|
+
* Build headers with SigV4 signing.
|
|
30
|
+
*/
|
|
31
|
+
private buildHeaders;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=Image.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Image.d.ts","sourceRoot":"","sources":["../../../src/providers/bedrock/Image.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAsB,MAAM,aAAa,CAAC;AAKhE,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,MAAM,EAAE,aAAa;IAKjC;;OAEG;IACG,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IA8B5D;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAuCxB;;OAEG;IACH,OAAO,CAAC,aAAa;IAwBrB;;OAEG;IACH,OAAO,CAAC,SAAS;IAejB;;OAEG;IACH,OAAO,CAAC,YAAY;CAsCrB"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bedrock Image Generation Handler
|
|
3
|
+
*
|
|
4
|
+
* Supports Amazon Titan Image Generator and Stability.ai Stable Diffusion models.
|
|
5
|
+
*/
|
|
6
|
+
import { getBedrockEndpoint } from "./config.js";
|
|
7
|
+
import { signRequest } from "../../utils/AwsSigV4.js";
|
|
8
|
+
import { fetchWithTimeout } from "../../utils/fetch.js";
|
|
9
|
+
import { logger } from "../../utils/logger.js";
|
|
10
|
+
export class BedrockImage {
|
|
11
|
+
config;
|
|
12
|
+
baseUrl;
|
|
13
|
+
constructor(config) {
|
|
14
|
+
this.config = config;
|
|
15
|
+
this.baseUrl = getBedrockEndpoint(config.region);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Execute an image generation request.
|
|
19
|
+
*/
|
|
20
|
+
async execute(request) {
|
|
21
|
+
const modelId = request.model ?? "amazon.titan-image-generator-v2:0";
|
|
22
|
+
const url = `${this.baseUrl}/model/${modelId}/invoke`;
|
|
23
|
+
const body = this.buildRequestBody(modelId, request);
|
|
24
|
+
const bodyJson = JSON.stringify(body);
|
|
25
|
+
const headers = this.buildHeaders(url, bodyJson, request.headers);
|
|
26
|
+
logger.logRequest("BedrockImage", "POST", url, body);
|
|
27
|
+
const response = await fetchWithTimeout(url, {
|
|
28
|
+
method: "POST",
|
|
29
|
+
headers,
|
|
30
|
+
body: bodyJson
|
|
31
|
+
}, request.requestTimeout ?? this.config.requestTimeout ?? 120000);
|
|
32
|
+
if (!response.ok) {
|
|
33
|
+
const errorText = await response.text();
|
|
34
|
+
logger.logResponse("BedrockImage", response.status, response.statusText, errorText);
|
|
35
|
+
throw new Error(`Bedrock Image Generation error (${response.status}): ${errorText}`);
|
|
36
|
+
}
|
|
37
|
+
const data = await response.json();
|
|
38
|
+
return this.parseResponse(modelId, data);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Build model-specific request body.
|
|
42
|
+
*/
|
|
43
|
+
buildRequestBody(modelId, request) {
|
|
44
|
+
const prompt = request.prompt;
|
|
45
|
+
// Amazon Titan
|
|
46
|
+
if (modelId.includes("amazon.titan-image")) {
|
|
47
|
+
return {
|
|
48
|
+
taskType: "TEXT_IMAGE",
|
|
49
|
+
textToImageParams: {
|
|
50
|
+
text: prompt
|
|
51
|
+
},
|
|
52
|
+
imageGenerationConfig: {
|
|
53
|
+
numberOfImages: request.n ?? 1,
|
|
54
|
+
height: this.parseSize(request.size)?.height ?? 1024,
|
|
55
|
+
width: this.parseSize(request.size)?.width ?? 1024,
|
|
56
|
+
cfgScale: 8.0
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
// Stability AI (Stable Diffusion)
|
|
61
|
+
if (modelId.includes("stability.stable-diffusion")) {
|
|
62
|
+
return {
|
|
63
|
+
text_prompts: [
|
|
64
|
+
{
|
|
65
|
+
text: prompt,
|
|
66
|
+
weight: 1
|
|
67
|
+
}
|
|
68
|
+
],
|
|
69
|
+
cfg_scale: 7,
|
|
70
|
+
steps: 30,
|
|
71
|
+
samples: request.n ?? 1,
|
|
72
|
+
width: this.parseSize(request.size)?.width ?? 1024,
|
|
73
|
+
height: this.parseSize(request.size)?.height ?? 1024
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
throw new Error(`Unsupported image generation model: ${modelId}`);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Parse model-specific response.
|
|
80
|
+
*/
|
|
81
|
+
parseResponse(modelId, data) {
|
|
82
|
+
// Amazon Titan returns { images: ["base64", ...] }
|
|
83
|
+
if (modelId.includes("amazon.titan-image")) {
|
|
84
|
+
const base64 = data.images?.[0];
|
|
85
|
+
if (!base64)
|
|
86
|
+
throw new Error("No image data returned from Titan");
|
|
87
|
+
return {
|
|
88
|
+
data: base64,
|
|
89
|
+
mime_type: "image/png"
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
// Stability AI returns { artifacts: [ { base64: "...", ... } ] }
|
|
93
|
+
if (modelId.includes("stability.stable-diffusion")) {
|
|
94
|
+
const base64 = data.artifacts?.[0]?.base64;
|
|
95
|
+
if (!base64)
|
|
96
|
+
throw new Error("No image data returned from Stable Diffusion");
|
|
97
|
+
return {
|
|
98
|
+
data: base64,
|
|
99
|
+
mime_type: "image/png"
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
throw new Error(`Unsupported model response format: ${modelId}`);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Parse size string (e.g. "1024x1024") into height and width.
|
|
106
|
+
*/
|
|
107
|
+
parseSize(size) {
|
|
108
|
+
if (!size)
|
|
109
|
+
return null;
|
|
110
|
+
const parts = size.toLowerCase().split("x");
|
|
111
|
+
const width = parts[0];
|
|
112
|
+
const height = parts[1];
|
|
113
|
+
if (width && height) {
|
|
114
|
+
return {
|
|
115
|
+
width: parseInt(width, 10),
|
|
116
|
+
height: parseInt(height, 10)
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Build headers with SigV4 signing.
|
|
123
|
+
*/
|
|
124
|
+
buildHeaders(url, body, additionalHeaders) {
|
|
125
|
+
const headers = {
|
|
126
|
+
"Content-Type": "application/json",
|
|
127
|
+
Accept: "application/json",
|
|
128
|
+
...additionalHeaders
|
|
129
|
+
};
|
|
130
|
+
if (this.config.apiKey) {
|
|
131
|
+
headers["Authorization"] = `Bearer ${this.config.apiKey}`;
|
|
132
|
+
}
|
|
133
|
+
else if (this.config.accessKeyId && this.config.secretAccessKey && this.config.region) {
|
|
134
|
+
const accessKeyId = this.config.accessKeyId;
|
|
135
|
+
const secretAccessKey = this.config.secretAccessKey;
|
|
136
|
+
const region = this.config.region;
|
|
137
|
+
const credentials = {
|
|
138
|
+
accessKeyId,
|
|
139
|
+
secretAccessKey,
|
|
140
|
+
sessionToken: this.config.sessionToken
|
|
141
|
+
};
|
|
142
|
+
const signedHeaders = signRequest({
|
|
143
|
+
method: "POST",
|
|
144
|
+
url,
|
|
145
|
+
body,
|
|
146
|
+
credentials,
|
|
147
|
+
region,
|
|
148
|
+
service: "bedrock"
|
|
149
|
+
});
|
|
150
|
+
return { ...headers, ...signedHeaders };
|
|
151
|
+
}
|
|
152
|
+
return headers;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bedrock Models Handler
|
|
3
|
+
*
|
|
4
|
+
* Lists and normalizes models from the Bedrock management API.
|
|
5
|
+
*/
|
|
6
|
+
import { BedrockConfig } from "./config.js";
|
|
7
|
+
import { ModelInfo } from "../Provider.js";
|
|
8
|
+
export declare class BedrockModels {
|
|
9
|
+
private readonly config;
|
|
10
|
+
private readonly baseUrl;
|
|
11
|
+
constructor(config: BedrockConfig);
|
|
12
|
+
/**
|
|
13
|
+
* List and normalize foundation models.
|
|
14
|
+
*/
|
|
15
|
+
execute(): Promise<ModelInfo[]>;
|
|
16
|
+
/**
|
|
17
|
+
* Parse Bedrock model list into NodeLLM format.
|
|
18
|
+
*/
|
|
19
|
+
private parseResponse;
|
|
20
|
+
/**
|
|
21
|
+
* Determine if a model should be included in the NodeLLM models list.
|
|
22
|
+
*/
|
|
23
|
+
private shouldIncludeModel;
|
|
24
|
+
/**
|
|
25
|
+
* Map summary to Model info.
|
|
26
|
+
*/
|
|
27
|
+
private mapToModel;
|
|
28
|
+
/**
|
|
29
|
+
* Normalize model ID for inference profiles if supported.
|
|
30
|
+
* Handles regional prefixes for Cross-Region Inference.
|
|
31
|
+
*/
|
|
32
|
+
private normalizeModelId;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=Models.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Models.d.ts","sourceRoot":"","sources":["../../../src/providers/bedrock/Models.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAyB,MAAM,aAAa,CAAC;AAGnE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAK3C,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,MAAM,EAAE,aAAa;IAOjC;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAyCrC;;OAEG;IACH,OAAO,CAAC,aAAa;IAQrB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAiB1B;;OAEG;IACH,OAAO,CAAC,UAAU;IA+BlB;;;OAGG;IACH,OAAO,CAAC,gBAAgB;CAkBzB"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bedrock Models Handler
|
|
3
|
+
*
|
|
4
|
+
* Lists and normalizes models from the Bedrock management API.
|
|
5
|
+
*/
|
|
6
|
+
import { validateBedrockConfig } from "./config.js";
|
|
7
|
+
import { Capabilities } from "./Capabilities.js";
|
|
8
|
+
import { signRequest } from "../../utils/AwsSigV4.js";
|
|
9
|
+
import { fetchWithTimeout } from "../../utils/fetch.js";
|
|
10
|
+
import { logger } from "../../utils/logger.js";
|
|
11
|
+
export class BedrockModels {
|
|
12
|
+
config;
|
|
13
|
+
baseUrl;
|
|
14
|
+
constructor(config) {
|
|
15
|
+
this.config = config;
|
|
16
|
+
validateBedrockConfig(config);
|
|
17
|
+
// Management API uses a different subdomain than the runtime API
|
|
18
|
+
this.baseUrl = `https://bedrock.${config.region}.amazonaws.com`;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* List and normalize foundation models.
|
|
22
|
+
*/
|
|
23
|
+
async execute() {
|
|
24
|
+
const url = `${this.baseUrl}/foundation-models`;
|
|
25
|
+
const body = ""; // GET request
|
|
26
|
+
const credentials = {
|
|
27
|
+
accessKeyId: this.config.accessKeyId,
|
|
28
|
+
secretAccessKey: this.config.secretAccessKey,
|
|
29
|
+
sessionToken: this.config.sessionToken
|
|
30
|
+
};
|
|
31
|
+
const signedHeaders = signRequest({
|
|
32
|
+
method: "GET",
|
|
33
|
+
url,
|
|
34
|
+
body,
|
|
35
|
+
credentials,
|
|
36
|
+
region: this.config.region,
|
|
37
|
+
service: "bedrock"
|
|
38
|
+
});
|
|
39
|
+
logger.logRequest("Bedrock", "GET", url);
|
|
40
|
+
const response = await fetchWithTimeout(url, {
|
|
41
|
+
method: "GET",
|
|
42
|
+
headers: {
|
|
43
|
+
...signedHeaders,
|
|
44
|
+
Accept: "application/json"
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
if (!response.ok) {
|
|
48
|
+
const errorText = await response.text();
|
|
49
|
+
logger.logResponse("Bedrock", response.status, response.statusText, errorText);
|
|
50
|
+
throw new Error(`Bedrock Models API error (${response.status}): ${errorText}`);
|
|
51
|
+
}
|
|
52
|
+
const json = (await response.json());
|
|
53
|
+
logger.logResponse("Bedrock", response.status, response.statusText, json);
|
|
54
|
+
return this.parseResponse(json);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Parse Bedrock model list into NodeLLM format.
|
|
58
|
+
*/
|
|
59
|
+
parseResponse(response) {
|
|
60
|
+
const summaries = response.modelSummaries || [];
|
|
61
|
+
// Filter and map models
|
|
62
|
+
// We primarily focus on models that support text conversation (Converse API)
|
|
63
|
+
return summaries.filter((m) => this.shouldIncludeModel(m)).map((m) => this.mapToModel(m));
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Determine if a model should be included in the NodeLLM models list.
|
|
67
|
+
*/
|
|
68
|
+
shouldIncludeModel(summary) {
|
|
69
|
+
const modelId = summary.modelId;
|
|
70
|
+
// We only support Claude, DeepSeek, Mistral, Llama, and Titan for now.
|
|
71
|
+
// Exclude embedding models and image models unless we strictly want to list them.
|
|
72
|
+
const isSupportedFamily = modelId.includes("anthropic.claude") ||
|
|
73
|
+
modelId.includes("deepseek") ||
|
|
74
|
+
modelId.includes("mistral") ||
|
|
75
|
+
modelId.includes("meta.llama") ||
|
|
76
|
+
modelId.includes("amazon.nova") ||
|
|
77
|
+
modelId.includes("amazon.titan-text") ||
|
|
78
|
+
modelId.includes("amazon.titan-embed");
|
|
79
|
+
return isSupportedFamily;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Map summary to Model info.
|
|
83
|
+
*/
|
|
84
|
+
mapToModel(summary) {
|
|
85
|
+
const modelId = summary.modelId;
|
|
86
|
+
const normalizedId = this.normalizeModelId(summary);
|
|
87
|
+
const capabilities = Capabilities.getCapabilities(modelId);
|
|
88
|
+
const pricing = Capabilities.getPricing(modelId);
|
|
89
|
+
const contextWindow = Capabilities.getContextWindow(modelId);
|
|
90
|
+
const maxTokens = Capabilities.getMaxOutputTokens(modelId);
|
|
91
|
+
return {
|
|
92
|
+
id: normalizedId,
|
|
93
|
+
name: summary.modelName || Capabilities.formatDisplayName(modelId),
|
|
94
|
+
provider: "bedrock",
|
|
95
|
+
family: Capabilities.getModelFamily(modelId),
|
|
96
|
+
context_window: contextWindow,
|
|
97
|
+
max_output_tokens: maxTokens,
|
|
98
|
+
modalities: {
|
|
99
|
+
input: summary.inputModalities || ["text"],
|
|
100
|
+
output: summary.outputModalities || ["text"]
|
|
101
|
+
},
|
|
102
|
+
capabilities,
|
|
103
|
+
pricing,
|
|
104
|
+
metadata: {
|
|
105
|
+
bedrock_model_id: modelId,
|
|
106
|
+
provider_name: summary.providerName,
|
|
107
|
+
inference_types: summary.inferenceTypesSupported || [],
|
|
108
|
+
streaming_supported: summary.responseStreamingSupported || false
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Normalize model ID for inference profiles if supported.
|
|
114
|
+
* Handles regional prefixes for Cross-Region Inference.
|
|
115
|
+
*/
|
|
116
|
+
normalizeModelId(summary) {
|
|
117
|
+
const modelId = summary.modelId;
|
|
118
|
+
const types = summary.inferenceTypesSupported || [];
|
|
119
|
+
// If it supports INFERENCE_PROFILE but NOT ON_DEMAND directly,
|
|
120
|
+
// it likely requires the regional prefix.
|
|
121
|
+
const needsPrefix = types.includes("INFERENCE_PROFILE") && !types.includes("ON_DEMAND");
|
|
122
|
+
if (needsPrefix) {
|
|
123
|
+
const region = this.config.region;
|
|
124
|
+
const prefix = region.split("-")[0]; // 'us', 'eu', 'ap'
|
|
125
|
+
if (prefix && !/^[a-z]{2}\./.test(modelId)) {
|
|
126
|
+
return `${prefix}.${modelId}`;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return modelId;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bedrock Moderation Handler
|
|
3
|
+
*
|
|
4
|
+
* Implements the standalone moderation endpoint using Bedrock Guardrails.
|
|
5
|
+
* Use this to check content for safety before sending it to an LLM.
|
|
6
|
+
*/
|
|
7
|
+
import { ModerationRequest, ModerationResponse } from "../Provider.js";
|
|
8
|
+
import { BedrockConfig } from "./config.js";
|
|
9
|
+
export declare class BedrockModeration {
|
|
10
|
+
private readonly config;
|
|
11
|
+
private readonly authMode;
|
|
12
|
+
private readonly baseUrl;
|
|
13
|
+
constructor(config: BedrockConfig);
|
|
14
|
+
/**
|
|
15
|
+
* Execute a moderation request against Bedrock Guardrails.
|
|
16
|
+
*/
|
|
17
|
+
execute(request: ModerationRequest): Promise<ModerationResponse>;
|
|
18
|
+
private applyGuardrail;
|
|
19
|
+
private mapToModerationResult;
|
|
20
|
+
private mapConfidence;
|
|
21
|
+
private buildHeaders;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=Moderation.d.ts.map
|