lynkr 8.0.0 → 9.0.1
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/.lynkr/telemetry.db +0 -0
- package/.lynkr/telemetry.db-shm +0 -0
- package/.lynkr/telemetry.db-wal +0 -0
- package/README.md +196 -322
- package/lynkr-skill.tar.gz +0 -0
- package/package.json +4 -3
- package/src/api/openai-router.js +64 -13
- package/src/api/providers-handler.js +171 -3
- package/src/api/router.js +9 -2
- package/src/clients/circuit-breaker.js +10 -247
- package/src/clients/codex-process.js +342 -0
- package/src/clients/codex-utils.js +143 -0
- package/src/clients/databricks.js +210 -63
- package/src/clients/resilience.js +540 -0
- package/src/clients/retry.js +22 -167
- package/src/clients/standard-tools.js +23 -0
- package/src/config/index.js +77 -0
- package/src/context/compression.js +42 -9
- package/src/context/distill.js +492 -0
- package/src/orchestrator/index.js +48 -8
- package/src/routing/complexity-analyzer.js +258 -5
- package/src/routing/index.js +12 -2
- package/src/routing/latency-tracker.js +148 -0
- package/src/routing/model-tiers.js +2 -0
- package/src/routing/quality-scorer.js +113 -0
- package/src/routing/telemetry.js +464 -0
- package/src/server.js +13 -12
- package/src/tools/code-graph.js +538 -0
- package/src/tools/code-mode.js +304 -0
- package/src/tools/index.js +4 -0
- package/src/tools/lazy-loader.js +18 -0
- package/src/tools/mcp-remote.js +7 -0
- package/src/tools/smart-selection.js +11 -0
- package/src/tools/tinyfish.js +358 -0
- package/src/tools/truncate.js +1 -0
- package/src/utils/payload.js +206 -0
- package/src/utils/perf-timer.js +80 -0
- package/.github/FUNDING.yml +0 -15
- package/.github/workflows/README.md +0 -215
- package/.github/workflows/ci.yml +0 -69
- package/.github/workflows/index.yml +0 -62
- package/.github/workflows/web-tools-tests.yml +0 -56
- package/CITATIONS.bib +0 -6
- package/DEPLOYMENT.md +0 -1001
- package/LYNKR-TUI-PLAN.md +0 -984
- package/PERFORMANCE-REPORT.md +0 -866
- package/PLAN-per-client-model-routing.md +0 -252
- package/docs/42642f749da6234f41b6b425c3bb07c9.txt +0 -1
- package/docs/BingSiteAuth.xml +0 -4
- package/docs/docs-style.css +0 -478
- package/docs/docs.html +0 -198
- package/docs/google5be250e608e6da39.html +0 -1
- package/docs/index.html +0 -577
- package/docs/index.md +0 -584
- package/docs/robots.txt +0 -4
- package/docs/sitemap.xml +0 -44
- package/docs/style.css +0 -1223
- package/docs/toon-integration-spec.md +0 -130
- package/documentation/README.md +0 -101
- package/documentation/api.md +0 -806
- package/documentation/claude-code-cli.md +0 -679
- package/documentation/codex-cli.md +0 -397
- package/documentation/contributing.md +0 -571
- package/documentation/cursor-integration.md +0 -734
- package/documentation/docker.md +0 -874
- package/documentation/embeddings.md +0 -762
- package/documentation/faq.md +0 -713
- package/documentation/features.md +0 -403
- package/documentation/headroom.md +0 -519
- package/documentation/installation.md +0 -758
- package/documentation/memory-system.md +0 -476
- package/documentation/production.md +0 -636
- package/documentation/providers.md +0 -1009
- package/documentation/routing.md +0 -476
- package/documentation/testing.md +0 -629
- package/documentation/token-optimization.md +0 -325
- package/documentation/tools.md +0 -697
- package/documentation/troubleshooting.md +0 -969
- package/final-test.js +0 -33
- package/headroom-sidecar/config.py +0 -93
- package/headroom-sidecar/requirements.txt +0 -14
- package/headroom-sidecar/server.py +0 -451
- package/monitor-agents.sh +0 -31
- package/scripts/audit-log-reader.js +0 -399
- package/scripts/compact-dictionary.js +0 -204
- package/scripts/test-deduplication.js +0 -448
- package/src/db/database.sqlite +0 -0
- package/te +0 -11622
- package/test/README.md +0 -212
- package/test/azure-openai-config.test.js +0 -213
- package/test/azure-openai-error-resilience.test.js +0 -238
- package/test/azure-openai-format-conversion.test.js +0 -354
- package/test/azure-openai-integration.test.js +0 -287
- package/test/azure-openai-routing.test.js +0 -175
- package/test/azure-openai-streaming.test.js +0 -171
- package/test/bedrock-integration.test.js +0 -457
- package/test/comprehensive-test-suite.js +0 -928
- package/test/config-validation.test.js +0 -207
- package/test/cursor-integration.test.js +0 -484
- package/test/format-conversion.test.js +0 -578
- package/test/hybrid-routing-integration.test.js +0 -269
- package/test/hybrid-routing-performance.test.js +0 -428
- package/test/llamacpp-integration.test.js +0 -882
- package/test/lmstudio-integration.test.js +0 -347
- package/test/memory/extractor.test.js +0 -398
- package/test/memory/retriever.test.js +0 -613
- package/test/memory/retriever.test.js.bak +0 -585
- package/test/memory/search.test.js +0 -537
- package/test/memory/search.test.js.bak +0 -389
- package/test/memory/store.test.js +0 -344
- package/test/memory/store.test.js.bak +0 -312
- package/test/memory/surprise.test.js +0 -300
- package/test/memory-performance.test.js +0 -472
- package/test/openai-integration.test.js +0 -683
- package/test/openrouter-error-resilience.test.js +0 -418
- package/test/passthrough-mode.test.js +0 -385
- package/test/performance-benchmark.js +0 -351
- package/test/performance-tests.js +0 -528
- package/test/routing.test.js +0 -225
- package/test/toon-compression.test.js +0 -131
- package/test/web-tools.test.js +0 -329
- package/test-agents-simple.js +0 -43
- package/test-cli-connection.sh +0 -33
- package/test-learning-unit.js +0 -126
- package/test-learning.js +0 -112
- package/test-parallel-agents.sh +0 -124
- package/test-parallel-direct.js +0 -155
- package/test-subagents.sh +0 -117
|
@@ -1,457 +0,0 @@
|
|
|
1
|
-
const assert = require("assert");
|
|
2
|
-
const { describe, it, beforeEach, afterEach } = require("node:test");
|
|
3
|
-
|
|
4
|
-
describe("AWS Bedrock Integration", () => {
|
|
5
|
-
let originalEnv;
|
|
6
|
-
|
|
7
|
-
beforeEach(() => {
|
|
8
|
-
originalEnv = { ...process.env };
|
|
9
|
-
|
|
10
|
-
// Clear module cache
|
|
11
|
-
delete require.cache[require.resolve("../src/config")];
|
|
12
|
-
delete require.cache[require.resolve("../src/clients/routing")];
|
|
13
|
-
delete require.cache[require.resolve("../src/clients/bedrock-utils")];
|
|
14
|
-
|
|
15
|
-
// Prevent .env TIER_* values from being picked up by dotenv
|
|
16
|
-
process.env.TIER_SIMPLE = "";
|
|
17
|
-
process.env.TIER_MEDIUM = "";
|
|
18
|
-
process.env.TIER_COMPLEX = "";
|
|
19
|
-
process.env.TIER_REASONING = "";
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
afterEach(() => {
|
|
23
|
-
process.env = originalEnv;
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
describe("Configuration", () => {
|
|
27
|
-
it("should accept bedrock as a valid MODEL_PROVIDER", () => {
|
|
28
|
-
process.env.MODEL_PROVIDER = "bedrock";
|
|
29
|
-
process.env.AWS_ACCESS_KEY_ID = "AKIATEST123";
|
|
30
|
-
process.env.AWS_SECRET_ACCESS_KEY = "testSecretKey123";
|
|
31
|
-
|
|
32
|
-
const config = require("../src/config");
|
|
33
|
-
assert.strictEqual(config.modelProvider.type, "bedrock");
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it("should throw error when AWS credentials are missing", () => {
|
|
37
|
-
process.env.MODEL_PROVIDER = "bedrock";
|
|
38
|
-
// Set to empty string to override .env file values
|
|
39
|
-
process.env.AWS_ACCESS_KEY_ID = "";
|
|
40
|
-
process.env.AWS_SECRET_ACCESS_KEY = "";
|
|
41
|
-
|
|
42
|
-
assert.throws(
|
|
43
|
-
() => require("../src/config"),
|
|
44
|
-
/AWS Bedrock requires AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY/
|
|
45
|
-
);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it("should use default region (us-east-1)", () => {
|
|
49
|
-
process.env.MODEL_PROVIDER = "bedrock";
|
|
50
|
-
process.env.AWS_ACCESS_KEY_ID = "AKIATEST123";
|
|
51
|
-
process.env.AWS_SECRET_ACCESS_KEY = "testSecretKey123";
|
|
52
|
-
process.env.AWS_BEDROCK_REGION = ""; // Override .env value
|
|
53
|
-
process.env.AWS_REGION = ""; // Override .env value
|
|
54
|
-
|
|
55
|
-
const config = require("../src/config");
|
|
56
|
-
assert.strictEqual(config.bedrock.region, "us-east-1");
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it("should use custom region when AWS_BEDROCK_REGION is set", () => {
|
|
60
|
-
process.env.MODEL_PROVIDER = "bedrock";
|
|
61
|
-
process.env.AWS_ACCESS_KEY_ID = "AKIATEST123";
|
|
62
|
-
process.env.AWS_SECRET_ACCESS_KEY = "testSecretKey123";
|
|
63
|
-
process.env.AWS_BEDROCK_REGION = "us-west-2";
|
|
64
|
-
|
|
65
|
-
const config = require("../src/config");
|
|
66
|
-
assert.strictEqual(config.bedrock.region, "us-west-2");
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it("should use AWS_REGION as fallback for region", () => {
|
|
70
|
-
process.env.MODEL_PROVIDER = "bedrock";
|
|
71
|
-
process.env.AWS_ACCESS_KEY_ID = "AKIATEST123";
|
|
72
|
-
process.env.AWS_SECRET_ACCESS_KEY = "testSecretKey123";
|
|
73
|
-
process.env.AWS_BEDROCK_REGION = ""; // Override .env value
|
|
74
|
-
process.env.AWS_REGION = "ap-southeast-1";
|
|
75
|
-
|
|
76
|
-
const config = require("../src/config");
|
|
77
|
-
assert.strictEqual(config.bedrock.region, "ap-southeast-1");
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it("should use default model ID", () => {
|
|
81
|
-
process.env.MODEL_PROVIDER = "bedrock";
|
|
82
|
-
process.env.AWS_ACCESS_KEY_ID = "AKIATEST123";
|
|
83
|
-
process.env.AWS_SECRET_ACCESS_KEY = "testSecretKey123";
|
|
84
|
-
process.env.AWS_BEDROCK_MODEL_ID = ""; // Override .env value
|
|
85
|
-
|
|
86
|
-
const config = require("../src/config");
|
|
87
|
-
assert.strictEqual(config.bedrock.modelId, "anthropic.claude-3-5-sonnet-20241022-v2:0");
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
it("should use custom model ID when AWS_BEDROCK_MODEL_ID is set", () => {
|
|
91
|
-
process.env.MODEL_PROVIDER = "bedrock";
|
|
92
|
-
process.env.AWS_ACCESS_KEY_ID = "AKIATEST123";
|
|
93
|
-
process.env.AWS_SECRET_ACCESS_KEY = "testSecretKey123";
|
|
94
|
-
process.env.AWS_BEDROCK_MODEL_ID = "anthropic.claude-3-opus-20240229-v1:0";
|
|
95
|
-
|
|
96
|
-
const config = require("../src/config");
|
|
97
|
-
assert.strictEqual(config.bedrock.modelId, "anthropic.claude-3-opus-20240229-v1:0");
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
describe("Model Family Detection", () => {
|
|
102
|
-
it("should detect claude family", () => {
|
|
103
|
-
process.env.MODEL_PROVIDER = "databricks";
|
|
104
|
-
process.env.DATABRICKS_API_KEY = "test";
|
|
105
|
-
process.env.DATABRICKS_API_BASE = "http://test.com";
|
|
106
|
-
|
|
107
|
-
const { detectModelFamily } = require("../src/clients/bedrock-utils");
|
|
108
|
-
assert.strictEqual(
|
|
109
|
-
detectModelFamily("anthropic.claude-3-5-sonnet-20241022-v2:0"),
|
|
110
|
-
"claude"
|
|
111
|
-
);
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it("should detect claude family from global inference profile", () => {
|
|
115
|
-
process.env.MODEL_PROVIDER = "databricks";
|
|
116
|
-
process.env.DATABRICKS_API_KEY = "test";
|
|
117
|
-
process.env.DATABRICKS_API_BASE = "http://test.com";
|
|
118
|
-
|
|
119
|
-
const { detectModelFamily } = require("../src/clients/bedrock-utils");
|
|
120
|
-
assert.strictEqual(
|
|
121
|
-
detectModelFamily("global.anthropic.claude-sonnet-4-5-20250929-v1:0"),
|
|
122
|
-
"claude"
|
|
123
|
-
);
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
it("should detect claude family from US inference profile", () => {
|
|
127
|
-
process.env.MODEL_PROVIDER = "databricks";
|
|
128
|
-
process.env.DATABRICKS_API_KEY = "test";
|
|
129
|
-
process.env.DATABRICKS_API_BASE = "http://test.com";
|
|
130
|
-
|
|
131
|
-
const { detectModelFamily } = require("../src/clients/bedrock-utils");
|
|
132
|
-
assert.strictEqual(
|
|
133
|
-
detectModelFamily("us.anthropic.claude-sonnet-4-5-20250929-v1:0"),
|
|
134
|
-
"claude"
|
|
135
|
-
);
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
it("should detect titan family", () => {
|
|
139
|
-
process.env.MODEL_PROVIDER = "databricks";
|
|
140
|
-
process.env.DATABRICKS_API_KEY = "test";
|
|
141
|
-
process.env.DATABRICKS_API_BASE = "http://test.com";
|
|
142
|
-
|
|
143
|
-
const { detectModelFamily } = require("../src/clients/bedrock-utils");
|
|
144
|
-
assert.strictEqual(
|
|
145
|
-
detectModelFamily("amazon.titan-text-express-v1"),
|
|
146
|
-
"titan"
|
|
147
|
-
);
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
it("should detect llama family", () => {
|
|
151
|
-
process.env.MODEL_PROVIDER = "databricks";
|
|
152
|
-
process.env.DATABRICKS_API_KEY = "test";
|
|
153
|
-
process.env.DATABRICKS_API_BASE = "http://test.com";
|
|
154
|
-
|
|
155
|
-
const { detectModelFamily } = require("../src/clients/bedrock-utils");
|
|
156
|
-
assert.strictEqual(
|
|
157
|
-
detectModelFamily("meta.llama3-70b-instruct-v1:0"),
|
|
158
|
-
"llama"
|
|
159
|
-
);
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
it("should detect jurassic family", () => {
|
|
163
|
-
process.env.MODEL_PROVIDER = "databricks";
|
|
164
|
-
process.env.DATABRICKS_API_KEY = "test";
|
|
165
|
-
process.env.DATABRICKS_API_BASE = "http://test.com";
|
|
166
|
-
|
|
167
|
-
const { detectModelFamily } = require("../src/clients/bedrock-utils");
|
|
168
|
-
assert.strictEqual(
|
|
169
|
-
detectModelFamily("ai21.j2-ultra-v1"),
|
|
170
|
-
"jurassic"
|
|
171
|
-
);
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
it("should detect cohere family", () => {
|
|
175
|
-
process.env.MODEL_PROVIDER = "databricks";
|
|
176
|
-
process.env.DATABRICKS_API_KEY = "test";
|
|
177
|
-
process.env.DATABRICKS_API_BASE = "http://test.com";
|
|
178
|
-
|
|
179
|
-
const { detectModelFamily } = require("../src/clients/bedrock-utils");
|
|
180
|
-
assert.strictEqual(
|
|
181
|
-
detectModelFamily("cohere.command-text-v14"),
|
|
182
|
-
"cohere"
|
|
183
|
-
);
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
it("should detect mistral family", () => {
|
|
187
|
-
process.env.MODEL_PROVIDER = "databricks";
|
|
188
|
-
process.env.DATABRICKS_API_KEY = "test";
|
|
189
|
-
process.env.DATABRICKS_API_BASE = "http://test.com";
|
|
190
|
-
|
|
191
|
-
const { detectModelFamily } = require("../src/clients/bedrock-utils");
|
|
192
|
-
assert.strictEqual(
|
|
193
|
-
detectModelFamily("mistral.mistral-7b-instruct-v0:2"),
|
|
194
|
-
"mistral"
|
|
195
|
-
);
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
it("should throw error for unsupported model", () => {
|
|
199
|
-
process.env.MODEL_PROVIDER = "databricks";
|
|
200
|
-
process.env.DATABRICKS_API_KEY = "test";
|
|
201
|
-
process.env.DATABRICKS_API_BASE = "http://test.com";
|
|
202
|
-
|
|
203
|
-
const { detectModelFamily } = require("../src/clients/bedrock-utils");
|
|
204
|
-
assert.throws(
|
|
205
|
-
() => detectModelFamily("unknown.model-v1"),
|
|
206
|
-
/Unsupported Bedrock model/
|
|
207
|
-
);
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
describe("Format Conversion - Request", () => {
|
|
212
|
-
it("should keep Claude requests in Anthropic format", () => {
|
|
213
|
-
process.env.MODEL_PROVIDER = "databricks";
|
|
214
|
-
process.env.DATABRICKS_API_KEY = "test";
|
|
215
|
-
process.env.DATABRICKS_API_BASE = "http://test.com";
|
|
216
|
-
|
|
217
|
-
const { convertAnthropicToBedrockFormat } = require("../src/clients/bedrock-utils");
|
|
218
|
-
|
|
219
|
-
const anthropicBody = {
|
|
220
|
-
messages: [{ role: "user", content: "Hello" }],
|
|
221
|
-
max_tokens: 1024,
|
|
222
|
-
temperature: 0.7,
|
|
223
|
-
};
|
|
224
|
-
|
|
225
|
-
const result = convertAnthropicToBedrockFormat(anthropicBody, "claude");
|
|
226
|
-
|
|
227
|
-
assert.strictEqual(result.anthropic_version, "bedrock-2023-05-31");
|
|
228
|
-
assert.strictEqual(result.max_tokens, 1024);
|
|
229
|
-
assert.strictEqual(result.temperature, 0.7);
|
|
230
|
-
assert.deepStrictEqual(result.messages, anthropicBody.messages);
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
it("should convert to Titan format", () => {
|
|
234
|
-
process.env.MODEL_PROVIDER = "databricks";
|
|
235
|
-
process.env.DATABRICKS_API_KEY = "test";
|
|
236
|
-
process.env.DATABRICKS_API_BASE = "http://test.com";
|
|
237
|
-
|
|
238
|
-
const { convertAnthropicToBedrockFormat } = require("../src/clients/bedrock-utils");
|
|
239
|
-
|
|
240
|
-
const anthropicBody = {
|
|
241
|
-
messages: [{ role: "user", content: "Hello" }],
|
|
242
|
-
max_tokens: 1024,
|
|
243
|
-
temperature: 0.8,
|
|
244
|
-
};
|
|
245
|
-
|
|
246
|
-
const result = convertAnthropicToBedrockFormat(anthropicBody, "titan");
|
|
247
|
-
|
|
248
|
-
assert.strictEqual(result.textGenerationConfig.maxTokenCount, 1024);
|
|
249
|
-
assert.strictEqual(result.textGenerationConfig.temperature, 0.8);
|
|
250
|
-
assert.ok(result.inputText.includes("Human: Hello"));
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
it("should convert to Llama format", () => {
|
|
254
|
-
process.env.MODEL_PROVIDER = "databricks";
|
|
255
|
-
process.env.DATABRICKS_API_KEY = "test";
|
|
256
|
-
process.env.DATABRICKS_API_BASE = "http://test.com";
|
|
257
|
-
|
|
258
|
-
const { convertAnthropicToBedrockFormat } = require("../src/clients/bedrock-utils");
|
|
259
|
-
|
|
260
|
-
const anthropicBody = {
|
|
261
|
-
messages: [{ role: "user", content: "Test" }],
|
|
262
|
-
max_tokens: 512,
|
|
263
|
-
temperature: 0.9,
|
|
264
|
-
};
|
|
265
|
-
|
|
266
|
-
const result = convertAnthropicToBedrockFormat(anthropicBody, "llama");
|
|
267
|
-
|
|
268
|
-
assert.strictEqual(result.max_gen_len, 512);
|
|
269
|
-
assert.strictEqual(result.temperature, 0.9);
|
|
270
|
-
assert.ok(result.prompt.includes("Human: Test"));
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
it("should convert to Jurassic format", () => {
|
|
274
|
-
process.env.MODEL_PROVIDER = "databricks";
|
|
275
|
-
process.env.DATABRICKS_API_KEY = "test";
|
|
276
|
-
process.env.DATABRICKS_API_BASE = "http://test.com";
|
|
277
|
-
|
|
278
|
-
const { convertAnthropicToBedrockFormat } = require("../src/clients/bedrock-utils");
|
|
279
|
-
|
|
280
|
-
const anthropicBody = {
|
|
281
|
-
messages: [{ role: "user", content: "Test" }],
|
|
282
|
-
max_tokens: 200,
|
|
283
|
-
temperature: 0.7,
|
|
284
|
-
};
|
|
285
|
-
|
|
286
|
-
const result = convertAnthropicToBedrockFormat(anthropicBody, "jurassic");
|
|
287
|
-
|
|
288
|
-
assert.strictEqual(result.maxTokens, 200);
|
|
289
|
-
assert.strictEqual(result.temperature, 0.7);
|
|
290
|
-
assert.ok(result.prompt.includes("Human: Test"));
|
|
291
|
-
});
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
describe("Format Conversion - Response", () => {
|
|
295
|
-
it("should parse Claude responses (native Anthropic)", () => {
|
|
296
|
-
process.env.MODEL_PROVIDER = "databricks";
|
|
297
|
-
process.env.DATABRICKS_API_KEY = "test";
|
|
298
|
-
process.env.DATABRICKS_API_BASE = "http://test.com";
|
|
299
|
-
|
|
300
|
-
const { convertBedrockResponseToAnthropic } = require("../src/clients/bedrock-utils");
|
|
301
|
-
|
|
302
|
-
const claudeResponse = {
|
|
303
|
-
id: "msg_123",
|
|
304
|
-
type: "message",
|
|
305
|
-
role: "assistant",
|
|
306
|
-
content: [{ type: "text", text: "Hello!" }],
|
|
307
|
-
stop_reason: "end_turn",
|
|
308
|
-
usage: { input_tokens: 10, output_tokens: 5 },
|
|
309
|
-
};
|
|
310
|
-
|
|
311
|
-
const result = convertBedrockResponseToAnthropic(
|
|
312
|
-
claudeResponse,
|
|
313
|
-
"claude",
|
|
314
|
-
"anthropic.claude-3-5-sonnet-20241022-v2:0"
|
|
315
|
-
);
|
|
316
|
-
|
|
317
|
-
assert.deepStrictEqual(result, claudeResponse);
|
|
318
|
-
});
|
|
319
|
-
|
|
320
|
-
it("should convert Titan responses to Anthropic format", () => {
|
|
321
|
-
process.env.MODEL_PROVIDER = "databricks";
|
|
322
|
-
process.env.DATABRICKS_API_KEY = "test";
|
|
323
|
-
process.env.DATABRICKS_API_BASE = "http://test.com";
|
|
324
|
-
|
|
325
|
-
const { convertBedrockResponseToAnthropic } = require("../src/clients/bedrock-utils");
|
|
326
|
-
|
|
327
|
-
const titanResponse = {
|
|
328
|
-
results: [{
|
|
329
|
-
outputText: "Response text",
|
|
330
|
-
tokenCount: 50,
|
|
331
|
-
completionReason: "FINISH",
|
|
332
|
-
}],
|
|
333
|
-
inputTextTokenCount: 20,
|
|
334
|
-
};
|
|
335
|
-
|
|
336
|
-
const result = convertBedrockResponseToAnthropic(
|
|
337
|
-
titanResponse,
|
|
338
|
-
"titan",
|
|
339
|
-
"amazon.titan-text-express-v1"
|
|
340
|
-
);
|
|
341
|
-
|
|
342
|
-
assert.strictEqual(result.role, "assistant");
|
|
343
|
-
assert.strictEqual(result.content[0].type, "text");
|
|
344
|
-
assert.strictEqual(result.content[0].text, "Response text");
|
|
345
|
-
assert.strictEqual(result.stop_reason, "end_turn");
|
|
346
|
-
assert.strictEqual(result.usage.input_tokens, 20);
|
|
347
|
-
assert.strictEqual(result.usage.output_tokens, 50);
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
it("should convert Llama responses to Anthropic format", () => {
|
|
351
|
-
process.env.MODEL_PROVIDER = "databricks";
|
|
352
|
-
process.env.DATABRICKS_API_KEY = "test";
|
|
353
|
-
process.env.DATABRICKS_API_BASE = "http://test.com";
|
|
354
|
-
|
|
355
|
-
const { convertBedrockResponseToAnthropic } = require("../src/clients/bedrock-utils");
|
|
356
|
-
|
|
357
|
-
const llamaResponse = {
|
|
358
|
-
generation: "Llama response",
|
|
359
|
-
prompt_token_count: 15,
|
|
360
|
-
generation_token_count: 30,
|
|
361
|
-
stop_reason: "stop",
|
|
362
|
-
};
|
|
363
|
-
|
|
364
|
-
const result = convertBedrockResponseToAnthropic(
|
|
365
|
-
llamaResponse,
|
|
366
|
-
"llama",
|
|
367
|
-
"meta.llama3-70b-instruct-v1:0"
|
|
368
|
-
);
|
|
369
|
-
|
|
370
|
-
assert.strictEqual(result.role, "assistant");
|
|
371
|
-
assert.strictEqual(result.content[0].text, "Llama response");
|
|
372
|
-
assert.strictEqual(result.stop_reason, "end_turn");
|
|
373
|
-
assert.strictEqual(result.usage.input_tokens, 15);
|
|
374
|
-
assert.strictEqual(result.usage.output_tokens, 30);
|
|
375
|
-
});
|
|
376
|
-
});
|
|
377
|
-
|
|
378
|
-
describe("Routing", () => {
|
|
379
|
-
it("should route to bedrock when MODEL_PROVIDER is bedrock", () => {
|
|
380
|
-
process.env.MODEL_PROVIDER = "bedrock";
|
|
381
|
-
process.env.AWS_ACCESS_KEY_ID = "AKIATEST123";
|
|
382
|
-
process.env.AWS_SECRET_ACCESS_KEY = "testSecretKey123";
|
|
383
|
-
|
|
384
|
-
const config = require("../src/config");
|
|
385
|
-
const routing = require("../src/clients/routing");
|
|
386
|
-
|
|
387
|
-
const payload = { messages: [{ role: "user", content: "test" }] };
|
|
388
|
-
const provider = routing.determineProviderSync(payload);
|
|
389
|
-
|
|
390
|
-
// determineProviderSync returns static MODEL_PROVIDER
|
|
391
|
-
assert.strictEqual(provider, "bedrock");
|
|
392
|
-
});
|
|
393
|
-
|
|
394
|
-
it("should return static routing from determineProviderSmart when tiers disabled", async () => {
|
|
395
|
-
process.env.MODEL_PROVIDER = "bedrock";
|
|
396
|
-
process.env.AWS_ACCESS_KEY_ID = "AKIATEST123";
|
|
397
|
-
process.env.AWS_SECRET_ACCESS_KEY = "testSecretKey123";
|
|
398
|
-
|
|
399
|
-
const config = require("../src/config");
|
|
400
|
-
const routing = require("../src/clients/routing");
|
|
401
|
-
|
|
402
|
-
// Many tools -- but without TIER_* vars, determineProviderSmart returns static routing
|
|
403
|
-
const payload = {
|
|
404
|
-
messages: [{ role: "user", content: "test" }],
|
|
405
|
-
tools: Array(20).fill({ name: "tool" }),
|
|
406
|
-
};
|
|
407
|
-
const result = await routing.determineProviderSmart(payload);
|
|
408
|
-
|
|
409
|
-
assert.strictEqual(result.provider, "bedrock");
|
|
410
|
-
assert.strictEqual(result.method, "static");
|
|
411
|
-
assert.strictEqual(result.reason, "tier_routing_disabled");
|
|
412
|
-
});
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
describe("Fallback Provider", () => {
|
|
416
|
-
it("should allow bedrock as fallback provider", () => {
|
|
417
|
-
process.env.MODEL_PROVIDER = "ollama";
|
|
418
|
-
process.env.OLLAMA_MODEL = "llama3.1";
|
|
419
|
-
process.env.OLLAMA_ENDPOINT = "http://localhost:11434";
|
|
420
|
-
process.env.FALLBACK_PROVIDER = "bedrock";
|
|
421
|
-
process.env.AWS_BEDROCK_API_KEY = "test-bedrock-key";
|
|
422
|
-
process.env.FALLBACK_ENABLED = "true";
|
|
423
|
-
|
|
424
|
-
// Should not throw
|
|
425
|
-
const config = require("../src/config");
|
|
426
|
-
assert.strictEqual(config.modelProvider.fallbackProvider, "bedrock");
|
|
427
|
-
});
|
|
428
|
-
|
|
429
|
-
it("should validate bedrock credentials when used as fallback", () => {
|
|
430
|
-
process.env.MODEL_PROVIDER = "ollama";
|
|
431
|
-
process.env.OLLAMA_MODEL = "llama3.1";
|
|
432
|
-
process.env.OLLAMA_ENDPOINT = "http://localhost:11434";
|
|
433
|
-
process.env.FALLBACK_PROVIDER = "bedrock";
|
|
434
|
-
process.env.FALLBACK_ENABLED = "true";
|
|
435
|
-
// Set to empty string to override .env file values
|
|
436
|
-
process.env.AWS_BEDROCK_API_KEY = "";
|
|
437
|
-
|
|
438
|
-
assert.throws(
|
|
439
|
-
() => require("../src/config"),
|
|
440
|
-
/FALLBACK_PROVIDER is set to 'bedrock' but AWS_BEDROCK_API_KEY is not configured/
|
|
441
|
-
);
|
|
442
|
-
});
|
|
443
|
-
|
|
444
|
-
it("should not allow local providers as fallback", () => {
|
|
445
|
-
process.env.MODEL_PROVIDER = "ollama";
|
|
446
|
-
process.env.OLLAMA_MODEL = "llama3.1";
|
|
447
|
-
process.env.OLLAMA_ENDPOINT = "http://localhost:11434";
|
|
448
|
-
process.env.FALLBACK_PROVIDER = "llamacpp";
|
|
449
|
-
process.env.FALLBACK_ENABLED = "true";
|
|
450
|
-
|
|
451
|
-
assert.throws(
|
|
452
|
-
() => require("../src/config"),
|
|
453
|
-
/FALLBACK_PROVIDER cannot be 'llamacpp'/
|
|
454
|
-
);
|
|
455
|
-
});
|
|
456
|
-
});
|
|
457
|
-
});
|