Files
OmniRoute/tests/unit/codex-stream-false.test.mjs
diegosouzapw 48467bc514 feat(core): add db health checks and provider interoperability
Add automated SQLite health diagnostics with optional auto-repair,
startup and scheduled execution, authenticated API routes, an MCP tool,
and dashboard visibility for status and repair actions.

Improve provider compatibility by adding Cursor usage fetching and
v3.1.0 parity headers, introducing a per-connection Codex Responses
store opt-in with session fallback, fixing Codex non-stream combo and
SSE translation behavior, sanitizing Gemini googleSearch tool payloads
and Qwen thinking tool_choice handling, and hardening cleanup and call
log storage paths.
2026-04-13 13:11:30 -03:00

255 lines
6.9 KiB
JavaScript

import test from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
const TEST_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-codex-stream-false-"));
process.env.DATA_DIR = TEST_DATA_DIR;
const core = await import("../../src/lib/db/core.ts");
const { handleChatCore } = await import("../../open-sse/handlers/chatCore.ts");
const { handleComboChat } = await import("../../open-sse/services/combo.ts");
const { CodexExecutor } = await import("../../open-sse/executors/codex.ts");
const originalFetch = globalThis.fetch;
function noopLog() {
return {
debug() {},
info() {},
warn() {},
error() {},
};
}
function createComboLog() {
const entries = [];
return {
info: (tag, msg) => entries.push({ level: "info", tag, msg }),
warn: (tag, msg) => entries.push({ level: "warn", tag, msg }),
error: (tag, msg) => entries.push({ level: "error", tag, msg }),
entries,
};
}
function jsonResponse(body, status = 200) {
return new Response(JSON.stringify(body), {
status,
headers: { "content-type": "application/json" },
});
}
function buildResponsesSse(text = "Brasilia") {
return new Response(
[
"event: response.created",
'data: {"type":"response.created","response":{"id":"resp_1","model":"gpt-5.3-codex","status":"in_progress","output":[]}}',
"",
"event: response.output_text.delta",
`data: ${JSON.stringify({
type: "response.output_text.delta",
output_index: 0,
delta: text,
})}`,
"",
"event: response.completed",
`data: ${JSON.stringify({
type: "response.completed",
response: {
id: "resp_1",
object: "response",
model: "gpt-5.3-codex",
status: "completed",
output: [
{
type: "message",
role: "assistant",
content: [{ type: "output_text", text }],
},
],
usage: { input_tokens: 6, output_tokens: 1 },
},
})}`,
"",
"data: [DONE]",
"",
].join("\n"),
{
status: 200,
headers: { "Content-Type": "text/event-stream" },
}
);
}
async function resetStorage() {
core.resetDbInstance();
fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true });
fs.mkdirSync(TEST_DATA_DIR, { recursive: true });
}
async function waitForAsyncSideEffects() {
await new Promise((resolve) => setImmediate(resolve));
await new Promise((resolve) => setTimeout(resolve, 10));
}
async function invokeChatCore({
body,
provider = "openai",
model = "gpt-4o-mini",
endpoint = "/v1/chat/completions",
accept = "application/json",
responseFactory,
} = {}) {
const calls = [];
globalThis.fetch = async (url, init = {}) => {
const headers =
init.headers instanceof Headers
? Object.fromEntries(init.headers.entries())
: init.headers || {};
const call = {
url: String(url),
method: init.method || "GET",
headers,
body: init.body ? JSON.parse(String(init.body)) : null,
};
calls.push(call);
return responseFactory(call);
};
try {
const requestBody = structuredClone(body);
const result = await handleChatCore({
body: requestBody,
modelInfo: { provider, model, extendedContext: false },
credentials: {
apiKey: "sk-test",
accessToken: "codex-token",
providerSpecificData: {},
},
log: noopLog(),
clientRawRequest: {
endpoint,
body: structuredClone(body),
headers: new Headers({ accept }),
},
userAgent: "unit-test",
});
await waitForAsyncSideEffects();
return { result, calls, call: calls.at(-1) };
} finally {
globalThis.fetch = originalFetch;
}
}
test.beforeEach(async () => {
globalThis.fetch = originalFetch;
await resetStorage();
});
test.after(async () => {
globalThis.fetch = originalFetch;
await resetStorage();
fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true });
});
test("CodexExecutor.transformRequest clones the request body before forcing stream=true", () => {
const executor = new CodexExecutor();
const body = {
model: "gpt-5.4",
input: [{ role: "user", content: [{ type: "input_text", text: "Oi" }] }],
stream: false,
reasoning: { effort: "low" },
};
const original = structuredClone(body);
const transformed = executor.transformRequest("gpt-5.4", body, false, {
requestEndpointPath: "/responses",
});
assert.notStrictEqual(transformed, body);
assert.deepEqual(body, original);
assert.equal(transformed.stream, true);
});
test("chatCore converts Responses-style SSE fallback into JSON when stream=false", async () => {
const { result, call } = await invokeChatCore({
body: {
model: "gpt-4o-mini",
stream: false,
messages: [{ role: "user", content: "Qual a capital do Brasil?" }],
},
provider: "openai",
model: "gpt-4o-mini",
responseFactory: () => buildResponsesSse("Brasilia"),
});
const payload = await result.response.json();
assert.equal(result.success, true);
assert.equal(call.headers.Accept || call.headers.accept, "application/json");
assert.equal(payload.object, "chat.completion");
assert.equal(payload.choices[0].message.content, "Brasilia");
assert.ok(payload.usage.total_tokens >= 7);
assert.ok(payload.usage.prompt_tokens > 0);
assert.ok(payload.usage.completion_tokens > 0);
});
test("handleComboChat validates non-stream quality using the original client stream intent", async () => {
const combo = {
name: "codex-stream-false-quality",
models: ["codex/gpt-5.4", "openai/gpt-4o-mini"],
};
const log = createComboLog();
const seenModels = [];
const result = await handleComboChat({
body: {
stream: false,
messages: [{ role: "user", content: "Qual a capital do Brasil?" }],
},
combo,
handleSingleModel: async (requestBody, modelStr) => {
seenModels.push(modelStr);
if (modelStr === "codex/gpt-5.4") {
requestBody.stream = true;
return jsonResponse({
choices: [
{ index: 0, message: { role: "assistant", content: "" }, finish_reason: "stop" },
],
});
}
return jsonResponse({
choices: [
{
index: 0,
message: { role: "assistant", content: "Brasilia" },
finish_reason: "stop",
},
],
});
},
isModelAvailable: async () => true,
log,
settings: null,
allCombos: null,
});
const payload = await result.json();
assert.equal(result.ok, true);
assert.deepEqual(seenModels, ["codex/gpt-5.4", "openai/gpt-4o-mini"]);
assert.equal(payload.choices[0].message.content, "Brasilia");
assert.ok(
log.entries.some(
(entry) =>
entry.level === "warn" &&
String(entry.msg).includes(
"failed quality check: empty content and no tool_calls in response"
)
)
);
});