Skip to content

Commit 4be6e1f

Browse files
committed
test(codex): prove relay alias returns to relay route
Follow-up to log triage: the key failure was not only that an unroutable alias was visible, but that a third-party GPT alias could be absent from the third-party route and therefore be captured by the official GPT prefix route. Add an explicit sync regression for the LongNows-shaped case. When the official route owns gpt-5.5 and the LongNows GPT provider catalog retains both claude-opus-4-8 and gpt-5.5-longnows-gpt -> gpt-5.5, syncCodexMultiRouterPlanWithProviders must add gpt-5.5-longnows-gpt back into the LongNows route and persist upstream.modelMap so runtime exact matching sends it to the third-party provider. Validation: pnpm vitest run tests/lib/codexMultiRouterSync.test.ts tests/lib/codexMultiRouterWizard.test.ts src/components/codex/CodexRouterWorkspacePage.test.ts; pnpm typecheck; pnpm exec prettier --check tests/lib/codexMultiRouterSync.test.ts src/components/codex/CodexRouterWorkspacePage.tsx src/components/codex/CodexRouterWorkspacePage.test.ts memory.md; git diff --check
1 parent 935fa43 commit 4be6e1f

1 file changed

Lines changed: 90 additions & 0 deletions

File tree

tests/lib/codexMultiRouterSync.test.ts

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,96 @@ describe("codexMultiRouterSync", () => {
353353
expect(synced?.removedSpawnAgentModels).toEqual([]);
354354
});
355355

356+
it("同步 provider 模型变更时把新增第三方 GPT alias 加回第三方 route", () => {
357+
const official = provider({
358+
id: "official",
359+
name: "OpenAI Official",
360+
category: "official",
361+
settingsConfig: {
362+
modelCatalog: {
363+
models: [{ model: "gpt-5.5", contextWindow: 300000 }],
364+
},
365+
},
366+
});
367+
const longnows = provider({
368+
id: "longnows",
369+
name: "LongNows GPT",
370+
settingsConfig: {
371+
modelCatalog: {
372+
models: [
373+
{ model: "claude-opus-4-8", contextWindow: 200000 },
374+
{
375+
model: "gpt-5.5-longnows-gpt",
376+
upstreamModel: "gpt-5.5",
377+
displayName: "LongNows GPT",
378+
contextWindow: 272000,
379+
},
380+
],
381+
},
382+
},
383+
});
384+
const plan = provider({
385+
id: "router",
386+
settingsConfig: {
387+
modelCatalog: {
388+
models: [
389+
{ model: "gpt-5.5", contextWindow: 300000 },
390+
{ model: "claude-opus-4-8", contextWindow: 200000 },
391+
],
392+
spawnAgentModels: ["claude-opus-4-8"],
393+
},
394+
codexRouting: {
395+
enabled: true,
396+
routes: [
397+
{
398+
id: "router-official",
399+
targetProviderId: "official",
400+
match: { models: ["gpt-5.5"], prefixes: ["gpt"] },
401+
upstream: {
402+
apiFormat: "openai_responses",
403+
auth: { source: "managed_codex_oauth" },
404+
},
405+
},
406+
{
407+
id: "router-longnows",
408+
targetProviderId: "longnows",
409+
match: { models: ["claude-opus-4-8"], prefixes: ["claude"] },
410+
upstream: {
411+
apiFormat: "openai_chat",
412+
auth: { source: "provider_config" },
413+
},
414+
},
415+
],
416+
},
417+
},
418+
});
419+
420+
const synced = syncCodexMultiRouterPlanWithProviders(
421+
plan,
422+
new Map([
423+
[official.id, official],
424+
[longnows.id, longnows],
425+
[plan.id, plan],
426+
]),
427+
);
428+
429+
expect(synced).not.toBeNull();
430+
const routes = synced?.plan.settingsConfig.codexRouting.routes ?? [];
431+
expect(routes[1].match.models).toEqual([
432+
"claude-opus-4-8",
433+
"gpt-5.5-longnows-gpt",
434+
]);
435+
expect(routes[1].upstream.modelMap).toEqual({
436+
"gpt-5.5-longnows-gpt": "gpt-5.5",
437+
});
438+
expect(synced?.plan.settingsConfig.modelCatalog.models).toContainEqual({
439+
model: "gpt-5.5-longnows-gpt",
440+
upstreamModel: "gpt-5.5",
441+
displayName: "LongNows GPT",
442+
contextWindow: 272000,
443+
});
444+
});
445+
356446
it("provider id 改名时同步 route 目标并按新 provider 目录重建", () => {
357447
const renamed = provider({
358448
id: "new-provider",

0 commit comments

Comments
 (0)