From caf4d786917c00c4a768740bf60620b5a565bffa Mon Sep 17 00:00:00 2001 From: Ruslan Strazhnyk Date: Sat, 5 Sep 2026 11:31:33 +0200 Subject: [PATCH] feat: list all Codex models in /orch and add Qwen 3.8 Cerebras row The /orch Codex section offered only Codex default and GPT 6 Astra while the runner allowlist supports eight models. Expose all of them, guarded by a test that keeps the picker in sync with codexrunner.SupportedModels() in both directions. Also adds a coming-soon Qwen 3.8 row to the Cerebras section with a qwen-3.8 model ID (qwen/qwen3.8 aliases); confirm the ID against the live Cerebras API at launch. --- internal/api/cerebras.go | 7 +++++++ internal/api/cerebras_test.go | 4 ++++ internal/tui/tui_backend.go | 8 ++++++++ internal/tui/tui_backend_cc_test.go | 20 ++++++++++++++++++++ 4 files changed, 39 insertions(+) diff --git a/internal/api/cerebras.go b/internal/api/cerebras.go index 3988c58..43b5bf8 100644 --- a/internal/api/cerebras.go +++ b/internal/api/cerebras.go @@ -19,6 +19,10 @@ const ( // reasoning via the top-level reasoning_effort parameter (off by default). // Model ID per the Cerebras + Gemma 4 hackathon docs. CerebrasGemma4Model = "gemma-4-31b" + // CerebrasQwen38Model is Alibaba's Qwen 3.8 as hosted on Cerebras. + // Announced as coming soon to the Cerebras model catalog; the ID follows + // Cerebras naming and must be confirmed against the live API at launch. + CerebrasQwen38Model = "qwen-3.8" ) // ResolveCerebrasModel expands shorthand aliases to full Cerebras model IDs. @@ -27,12 +31,15 @@ const ( // "" → CerebrasDefaultModel (gpt-oss-120b) // "gemma" → CerebrasGemma4Model (gemma-4-31b) // "gemma-4-31b" → CerebrasGemma4Model +// "qwen" → CerebrasQwen38Model (qwen-3.8) func ResolveCerebrasModel(name string) string { switch strings.ToLower(strings.TrimSpace(name)) { case "", "default": return CerebrasDefaultModel case "gemma", "gemma4", "gemma-4", "gemma-4-31b", "gemma4-31b", "gemma-4-31": return CerebrasGemma4Model + case "qwen", "qwen3.8", "qwen-3-8", "qwen-3.8": + return CerebrasQwen38Model } return name } diff --git a/internal/api/cerebras_test.go b/internal/api/cerebras_test.go index 0c6f2ba..855d516 100644 --- a/internal/api/cerebras_test.go +++ b/internal/api/cerebras_test.go @@ -15,6 +15,10 @@ func TestResolveCerebrasModel(t *testing.T) { {"gemma-4-31b", CerebrasGemma4Model}, {"gemma4-31b", CerebrasGemma4Model}, {"gemma-4-31", CerebrasGemma4Model}, + {"qwen", CerebrasQwen38Model}, + {"Qwen3.8", CerebrasQwen38Model}, + {"qwen-3-8", CerebrasQwen38Model}, + {"qwen-3.8", CerebrasQwen38Model}, {"zai-glm-4.7", "zai-glm-4.7"}, // unknown passes through {" gemma ", CerebrasGemma4Model}, // whitespace trimmed } diff --git a/internal/tui/tui_backend.go b/internal/tui/tui_backend.go index e814c95..25988a1 100644 --- a/internal/tui/tui_backend.go +++ b/internal/tui/tui_backend.go @@ -144,6 +144,13 @@ var ccModels = []pickerEntry{ var codexModels = []pickerEntry{ {backend: "codex", modelID: "", label: "Codex default", subLabel: "uses Codex config", external: true, isFav: true, shortcut: '6'}, {backend: "codex", modelID: "gpt-6-astra", label: "GPT 6 Astra", external: true, isNew: true}, + {backend: "codex", modelID: "gpt-5.6-sol", label: "GPT 5.6 Sol", external: true}, + {backend: "codex", modelID: "gpt-5.6-terra", label: "GPT 5.6 Terra", external: true}, + {backend: "codex", modelID: "gpt-5.6-luna", label: "GPT 5.6 Luna", external: true}, + {backend: "codex", modelID: "gpt-5.5", label: "GPT 5.5", external: true}, + {backend: "codex", modelID: "gpt-5.4", label: "GPT 5.4", external: true}, + {backend: "codex", modelID: "gpt-5.4-mini", label: "GPT 5.4 Mini", external: true}, + {backend: "codex", modelID: "gpt-5.3-codex-spark", label: "GPT 5.3 Codex Spark", external: true}, } var apiModels = []pickerEntry{ @@ -161,6 +168,7 @@ var cerebrasModels = []pickerEntry{ {backend: "cerebras", modelID: "gpt-oss-120b", label: "GPT-OSS 120B", subLabel: "fast", isFav: true, external: true}, {backend: "cerebras", modelID: "zai-glm-4.7", label: "GLM 4.7", subLabel: "premium", external: true}, {backend: "cerebras", modelID: "gemma-4-31b", label: "Gemma 4 31B", subLabel: "vision · preview", external: true}, + {backend: "cerebras", modelID: api.CerebrasQwen38Model, label: "Qwen 3.8", subLabel: "coming soon", external: true, isNew: true}, } // OpenCodeModelEntry is one model offered by an enabled opencode provider. The diff --git a/internal/tui/tui_backend_cc_test.go b/internal/tui/tui_backend_cc_test.go index 4040dea..e950700 100644 --- a/internal/tui/tui_backend_cc_test.go +++ b/internal/tui/tui_backend_cc_test.go @@ -3,6 +3,7 @@ package tui import ( "testing" + "github.com/qualitymax/qmax-code/codexrunner" "github.com/qualitymax/qmax-code/internal/api" ) @@ -61,6 +62,25 @@ func TestPickerCodexDefaultAndExplicitModel(t *testing.T) { } } +func TestPickerOffersEverySupportedCodexModel(t *testing.T) { + offered := map[string]bool{} + for _, e := range codexModels { + if e.backend == "codex" && e.modelID != "" { + offered[e.modelID] = true + } + } + for _, m := range codexrunner.SupportedModels() { + if !offered[m] { + t.Errorf("picker is missing supported Codex model %q", m) + } + } + for m := range offered { + if codexrunner.ValidateModel(m) != nil { + t.Errorf("picker offers Codex model %q outside the runner allowlist", m) + } + } +} + func TestPickerIncludesFable51ForDirectAPI(t *testing.T) { m := newModelPickerModel("", api.ModelFable51, "high", "", "", false, false, false, false, nil) cur := m.allEntries[m.cursor]