mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-24 21:30:17 +08:00
15e712e779
Codex providers can now run in two modes per provider: - Proxy-Chat (route takeover): apiFormat=openai_chat, existing Responses<->Chat conversion. Unchanged. - Native-Responses (direct): apiFormat=openai_responses, no proxy. cc-switch generates ~/.codex/cc-switch-model-catalog.json so Codex shows the custom models and tools work without the freeform apply_patch (type=custom) tool that native gateways like MiMo reject; editing falls back to shell_command. Catalog generation is keyed on apiFormat (CodexCatalogToolProfile), decoupled from the takeover toggle, so native providers persist a catalog without enabling local route mapping. Codex's catalog parser requires base_instructions on every entry; the native template carries a neutral default and per-vendor official text overrides it (MiMo, MiniMax). Synthesized catalogs for Qwen/Doubao/LongCat use the neutral default. Existing native providers must be re-saved once to regenerate a valid catalog (no DB migration).
53 lines
1.9 KiB
TypeScript
53 lines
1.9 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { normalizeCodexCatalogModelsForSave } from "@/components/providers/forms/ProviderForm";
|
|
|
|
describe("ProviderForm Codex catalog helpers", () => {
|
|
it("normalizes catalog rows and removes empty or duplicate models", () => {
|
|
expect(
|
|
normalizeCodexCatalogModelsForSave([
|
|
{ model: " deepseek-v4-flash ", displayName: " DeepSeek " },
|
|
{ model: "deepseek-v4-flash", displayName: "Duplicate" },
|
|
{ model: "", displayName: "Empty" },
|
|
{ model: "kimi-k2", contextWindow: "128000 tokens" },
|
|
]),
|
|
).toEqual([
|
|
{ model: "deepseek-v4-flash", displayName: "DeepSeek" },
|
|
{ model: "kimi-k2", contextWindow: 128000 },
|
|
]);
|
|
});
|
|
|
|
it("preserves native-profile overrides (parallel tool calls + input modalities + base instructions)", () => {
|
|
expect(
|
|
normalizeCodexCatalogModelsForSave([
|
|
{
|
|
model: "MiniMax-M3",
|
|
displayName: "MiniMax-M3",
|
|
contextWindow: 1000000,
|
|
supportsParallelToolCalls: true,
|
|
inputModalities: ["text", "image"],
|
|
baseInstructions:
|
|
" You are Codex, a coding agent based on MiniMax-M3. ",
|
|
},
|
|
// false must be preserved (not dropped as falsy); empty modalities dropped;
|
|
// empty/whitespace baseInstructions dropped
|
|
{
|
|
model: "mimo-v2.5-pro",
|
|
supportsParallelToolCalls: false,
|
|
inputModalities: [],
|
|
baseInstructions: " ",
|
|
},
|
|
]),
|
|
).toEqual([
|
|
{
|
|
model: "MiniMax-M3",
|
|
displayName: "MiniMax-M3",
|
|
contextWindow: 1000000,
|
|
supportsParallelToolCalls: true,
|
|
inputModalities: ["text", "image"],
|
|
baseInstructions: "You are Codex, a coding agent based on MiniMax-M3.",
|
|
},
|
|
{ model: "mimo-v2.5-pro", supportsParallelToolCalls: false },
|
|
]);
|
|
});
|
|
});
|