llm-switcher 1.2.10 → 1.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/package.json +1 -1
- package/proxy.mjs +8 -0
- package/tests/gateway.e2e.test.mjs +11 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Changelog — LLM Switcher
|
|
2
2
|
|
|
3
|
+
## Release 1.2.11
|
|
4
|
+
|
|
5
|
+
- **Test connection on a Bifrost model:** The test sent a plain `ping` request, and Anthropic answers that with a fake 429 for a Claude Code account. Now, when intact names `bifrost_ua` for the model, the test reports that the key works and the model is served, and it sends no message.
|
|
6
|
+
|
|
3
7
|
## Release 1.2.10
|
|
4
8
|
|
|
5
9
|
- **Bifrost in the log:** The log line and the request inspector showed `anthropic -> openai-chat` for a Bifrost request, because the gateway logged the profile's `outFormat` before it checked Bifrost. Now both show `bifrost`.
|
package/package.json
CHANGED
package/proxy.mjs
CHANGED
|
@@ -1123,6 +1123,14 @@ async function testUpstream(body, cfg) {
|
|
|
1123
1123
|
const apiKey = resolveApiKey(cfg, body.key, body.apiKey, baseURL);
|
|
1124
1124
|
const model = body.model || 'default';
|
|
1125
1125
|
const profile = { baseURL, apiKey, mode: body.mode, outFormat: body.outFormat || undefined };
|
|
1126
|
+
// A Bifrost model answers only its own client: a plain test request would draw a fake 429.
|
|
1127
|
+
// The model lookup itself proves the key and the model, so it is the test.
|
|
1128
|
+
const lookupStart = Date.now();
|
|
1129
|
+
const bifrostUA = await bifrostUAFor(profile, model);
|
|
1130
|
+
if (bifrostUA) {
|
|
1131
|
+
return { status: 200, json: { ok: true, latency: Date.now() - lookupStart, outFormat: 'bifrost',
|
|
1132
|
+
sample: `Bifrost: the key works and ${model} is served. Only the real client (${bifrostUA}) can call it, so no test message was sent.` } };
|
|
1133
|
+
}
|
|
1126
1134
|
const outFormat = resolveOutFormat(profile, model);
|
|
1127
1135
|
const { url, headers } = upstreamEndpoint(profile, outFormat, model, false, null);
|
|
1128
1136
|
const ir = { model, system: '', messages: [{ role: 'user', content: 'ping' }], tools: [], toolChoice: null, params: { maxTokens: 16, temperature: null, topP: null, topK: null, stop: [] }, thinking: { type: 'disabled' }, stream: false };
|
|
@@ -1251,6 +1251,17 @@ test('Codex WS: conversation.item.create is echoed and response.cancel stops the
|
|
|
1251
1251
|
ws.socket.destroy();
|
|
1252
1252
|
});
|
|
1253
1253
|
|
|
1254
|
+
test('Test connection on a Bifrost model checks the model and the key, and sends no fake request', async () => {
|
|
1255
|
+
const before = received.length;
|
|
1256
|
+
const r = await post('/api/test-upstream', { baseURL: `http://127.0.0.1:${upstreamPort}/intact/v1`, apiKey: 'k', model: 'claude/claude-opus-5', mode: 'convert' });
|
|
1257
|
+
const j = await r.json();
|
|
1258
|
+
assert.equal(j.ok, true);
|
|
1259
|
+
assert.equal(j.outFormat, 'bifrost');
|
|
1260
|
+
assert.match(j.sample, /claude-cli\//);
|
|
1261
|
+
const sent = received.slice(before).map(x => x.url);
|
|
1262
|
+
assert.ok(!sent.some(u => u.includes('/messages') || u.includes('/chat/completions')), `sent ${sent}`);
|
|
1263
|
+
});
|
|
1264
|
+
|
|
1254
1265
|
test('Admin test-upstream reports latency and a sample from the upstream', async () => {
|
|
1255
1266
|
const r = await post('/api/test-upstream', { baseURL: `http://127.0.0.1:${upstreamPort}/chat/v1`, apiKey: 'k', model: 'm', mode: 'convert' });
|
|
1256
1267
|
assert.equal(r.status, 200);
|