Files
diegosouzapw--omniroute/tests/unit/codex-responses-ws-model-resolution.test.ts
2026-07-13 13:39:12 +08:00

63 lines
2.6 KiB
TypeScript

/**
* tests/unit/codex-responses-ws-model-resolution.test.ts
*
* The Codex Responses-over-WebSocket bridge is codex-only, but the OpenAI Codex
* CLI rejects provider-prefixed model ids ("codex/gpt-5.5") client-side when
* `supports_websockets` is enabled and sends bare ids ("gpt-5.5"). Those can
* resolve to a non-codex default provider, which the bridge would reject.
* `resolveCodexWsModelInfo` re-resolves bare ids under the codex/ prefix.
*
* Empirically: with the bare id, ChatGPT's codex backend accepts model
* "gpt-5.5" and streams a response; without this re-resolution OmniRoute routed
* "gpt-5.5" to openrouter ("No credentials for provider: openrouter").
*/
import test from "node:test";
import assert from "node:assert/strict";
import {
resolveCodexWsModelInfo,
type ModelResolver,
} from "../../src/app/api/internal/codex-responses-ws/modelResolution.ts";
// A resolver mirroring OmniRoute's real behavior: bare "gpt-5.5" → openrouter,
// but the codex/ prefix forces provider=codex with the prefix stripped.
const realisticResolver: ModelResolver = async (m) =>
m.startsWith("codex/")
? { provider: "codex", model: m.slice("codex/".length) }
: { provider: "openrouter", model: m };
test("bare ChatGPT model id re-resolves to codex provider with stripped model", async () => {
const info = await resolveCodexWsModelInfo("gpt-5.5", realisticResolver);
assert.equal(info.provider, "codex");
assert.equal(info.model, "gpt-5.5", "model sent upstream must be the bare ChatGPT id");
});
test("provider-prefixed id is respected without a second resolve call", async () => {
let calls = 0;
const resolver: ModelResolver = async (m) => {
calls += 1;
return { provider: "codex", model: m.replace(/^codex\//, "") };
};
const info = await resolveCodexWsModelInfo("codex/gpt-5.5", resolver);
assert.equal(info.provider, "codex");
assert.equal(info.model, "gpt-5.5");
assert.equal(calls, 1, "must not double-resolve an explicitly prefixed id");
});
test("first resolution already codex short-circuits", async () => {
let calls = 0;
const resolver: ModelResolver = async (m) => {
calls += 1;
return { provider: "codex", model: m };
};
const info = await resolveCodexWsModelInfo("gpt-5.5", resolver);
assert.equal(info.provider, "codex");
assert.equal(calls, 1);
});
test("genuinely non-codex model stays non-codex (bridge then rejects it)", async () => {
const resolver: ModelResolver = async (m) => ({ provider: "openai", model: m });
const info = await resolveCodexWsModelInfo("gpt-4o", resolver);
assert.notEqual(info.provider, "codex");
});