mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-04 06:12:10 +03:00
Bypass semantic cache in combo live tests
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { NextResponse } from "next/server";
|
||||
import { buildComboTestRequestBody, extractComboTestResponseText } from "@/lib/combos/testHealth";
|
||||
import { getComboByName } from "@/lib/localDb";
|
||||
@@ -67,6 +68,10 @@ export async function POST(request) {
|
||||
// Internal dashboard tests still use the normal /v1 pipeline but
|
||||
// bypass REQUIRE_API_KEY so admins can test with local session auth.
|
||||
"X-Internal-Test": "combo-health-check",
|
||||
// Force a fresh execution path so combo tests cannot be satisfied by
|
||||
// OmniRoute's semantic cache or other request reuse layers.
|
||||
"X-OmniRoute-No-Cache": "true",
|
||||
"X-Request-Id": `combo-test-${randomUUID()}`,
|
||||
},
|
||||
body: JSON.stringify(testBody),
|
||||
signal: controller.signal,
|
||||
|
||||
@@ -29,6 +29,25 @@ function toNumber(value: unknown, fallback = 0): number {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
function getHeaderValue(
|
||||
headers: { get?: (name: string) => string | null } | Record<string, unknown> | null | undefined,
|
||||
name: string
|
||||
): string | null {
|
||||
if (!headers) return null;
|
||||
|
||||
if (typeof headers.get === "function") {
|
||||
return headers.get(name);
|
||||
}
|
||||
|
||||
const needle = name.toLowerCase();
|
||||
for (const [key, value] of Object.entries(headers)) {
|
||||
if (key.toLowerCase() !== needle) continue;
|
||||
return typeof value === "string" ? value : null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// ─── Singleton ─────────────────
|
||||
|
||||
let memoryCache: LRUCache | null = null;
|
||||
@@ -309,7 +328,9 @@ export function getCacheStats() {
|
||||
* Only non-streaming, deterministic (temperature=0) requests.
|
||||
*/
|
||||
export function isCacheable(body, headers) {
|
||||
if (headers?.get?.("x-omniroute-no-cache") === "true") return false;
|
||||
if ((getHeaderValue(headers, "x-omniroute-no-cache") || "").toLowerCase() === "true") {
|
||||
return false;
|
||||
}
|
||||
if (body.stream !== false) return false;
|
||||
if ((body.temperature ?? 0) !== 0) return false;
|
||||
return true;
|
||||
|
||||
@@ -10,6 +10,11 @@ process.env.DATA_DIR = TEST_DATA_DIR;
|
||||
const core = await import("../../src/lib/db/core.ts");
|
||||
const providersDb = await import("../../src/lib/db/providers.ts");
|
||||
const chatRoute = await import("../../src/app/api/v1/chat/completions/route.ts");
|
||||
const {
|
||||
generateSignature,
|
||||
invalidateBySignature,
|
||||
setCachedResponse,
|
||||
} = await import("../../src/lib/semanticCache.ts");
|
||||
const {
|
||||
clearModelUnavailability,
|
||||
resetAllAvailability,
|
||||
@@ -43,6 +48,17 @@ async function seedSuppressedConnection() {
|
||||
});
|
||||
}
|
||||
|
||||
async function seedHealthyConnection() {
|
||||
return providersDb.createProviderConnection({
|
||||
provider: "openai",
|
||||
authType: "apikey",
|
||||
name: "openai-cache-test",
|
||||
apiKey: "sk-cache-test",
|
||||
isActive: true,
|
||||
testStatus: "active",
|
||||
});
|
||||
}
|
||||
|
||||
function makeRequest(extraHeaders = {}) {
|
||||
return new Request("http://localhost/v1/chat/completions", {
|
||||
method: "POST",
|
||||
@@ -126,3 +142,67 @@ test("combo live test bypasses local cooldown and breaker state to perform a rea
|
||||
const updated = await providersDb.getProviderConnectionById(created.id);
|
||||
assert.equal(updated.testStatus, "active");
|
||||
});
|
||||
|
||||
test("combo live test bypasses semantic cache and forces a fresh upstream request", async () => {
|
||||
await seedHealthyConnection();
|
||||
|
||||
const signature = generateSignature(
|
||||
"gpt-4o-mini",
|
||||
[{ role: "user", content: "Reply with OK only." }],
|
||||
0,
|
||||
1
|
||||
);
|
||||
|
||||
setCachedResponse(signature, "gpt-4o-mini", {
|
||||
id: "chatcmpl-cached",
|
||||
choices: [
|
||||
{
|
||||
message: {
|
||||
role: "assistant",
|
||||
content: "CACHED",
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const fetchCalls = [];
|
||||
globalThis.fetch = async (url, init = {}) => {
|
||||
fetchCalls.push({ url: String(url), init });
|
||||
return Response.json({
|
||||
id: "chatcmpl-live",
|
||||
choices: [
|
||||
{
|
||||
message: {
|
||||
role: "assistant",
|
||||
content: "LIVE",
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
};
|
||||
|
||||
try {
|
||||
const cachedResponse = await chatRoute.POST(makeRequest());
|
||||
const cachedBody = await cachedResponse.json();
|
||||
|
||||
assert.equal(cachedResponse.status, 200);
|
||||
assert.equal(fetchCalls.length, 0);
|
||||
assert.equal(cachedBody.choices[0].message.content, "CACHED");
|
||||
|
||||
const liveResponse = await chatRoute.POST(
|
||||
makeRequest({
|
||||
"X-Internal-Test": "combo-health-check",
|
||||
"X-OmniRoute-No-Cache": "true",
|
||||
"X-Request-Id": "combo-test-cache-bypass",
|
||||
})
|
||||
);
|
||||
const liveBody = await liveResponse.json();
|
||||
|
||||
assert.equal(liveResponse.status, 200);
|
||||
assert.equal(fetchCalls.length, 1);
|
||||
assert.match(fetchCalls[0].url, /\/chat\/completions$/);
|
||||
assert.equal(liveBody.choices[0].message.content, "LIVE");
|
||||
} finally {
|
||||
invalidateBySignature(signature);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -82,6 +82,8 @@ test("combo test route marks a model healthy only when it returns assistant text
|
||||
assert.equal(fetchCalls.length, 1);
|
||||
assert.equal(fetchCalls[0].url, "http://localhost/v1/chat/completions");
|
||||
assert.equal(fetchCalls[0].init.headers["X-Internal-Test"], "combo-health-check");
|
||||
assert.equal(fetchCalls[0].init.headers["X-OmniRoute-No-Cache"], "true");
|
||||
assert.match(fetchCalls[0].init.headers["X-Request-Id"], /^combo-test-/);
|
||||
assert.equal(forwardedBody.model, "openrouter/openai/gpt-5.4");
|
||||
assert.equal(forwardedBody.messages[0].content, "Reply with OK only.");
|
||||
assert.equal(body.resolvedBy, "openrouter/openai/gpt-5.4");
|
||||
|
||||
Reference in New Issue
Block a user