From f9a2985d045f5e56fe6c8f9698701b51c6bb6656 Mon Sep 17 00:00:00 2001 From: cmondary Date: Fri, 4 Sep 2026 17:34:15 +0200 Subject: [PATCH 01/14] ADD OpenCode ZAI MiMo and Zen providers --- src/lib/harness/opencodeCatalog.ts | 11 +++++++++++ src/lib/harness/opencodeProtocol.test.ts | 15 +++++++++++++++ src/lib/models.ts | 22 ++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/src/lib/harness/opencodeCatalog.ts b/src/lib/harness/opencodeCatalog.ts index 450881d7..b64746d6 100644 --- a/src/lib/harness/opencodeCatalog.ts +++ b/src/lib/harness/opencodeCatalog.ts @@ -1,5 +1,6 @@ import { homeDir } from "../fs"; import { + MODELS, setHarnessModels, type AgentModel, type ModelSetting, @@ -195,6 +196,16 @@ export function flattenOpenCodeModels( }); } } + // Keep the providers MonoCode knows about even when the local OpenCode + // installation has not emitted them yet. Once configured, the live catalog + // entries above replace these fallback entries by their complete metadata. + const seen = new Set(models.map((model) => model.nativeId)); + for (const model of MODELS) { + if (model.harness !== "opencode" || !model.nativeId || seen.has(model.nativeId)) { + continue; + } + models.push(model); + } return models.sort((left, right) => left.name.localeCompare(right.name)); } diff --git a/src/lib/harness/opencodeProtocol.test.ts b/src/lib/harness/opencodeProtocol.test.ts index f5ad7b74..0a31b988 100644 --- a/src/lib/harness/opencodeProtocol.test.ts +++ b/src/lib/harness/opencodeProtocol.test.ts @@ -106,6 +106,9 @@ describe("OpenCode CLI inventory parsers", () => { expect(models.map((model) => model.nativeId)).toEqual([ "anthropic/claude-sonnet-4-6", "opencode/glm-5", + "mimo/mimo-v2.5-pro", + "opencode-zen/big-pickle", + "zai/glm-5.2", ]); expect(models[1].settings?.some((setting) => setting.id === "variant")).toBe( true, @@ -115,6 +118,18 @@ describe("OpenCode CLI inventory parsers", () => { ); }); + it("keeps the requested built-in providers in the OpenCode catalog", () => { + const models = flattenOpenCodeModels( + { providers: new Map(), connected: [] }, + [], + ); + expect(models.map((model) => model.nativeId)).toEqual([ + "mimo/mimo-v2.5-pro", + "opencode-zen/big-pickle", + "zai/glm-5.2", + ]); + }); + it("parses agent list headers", () => { const agents = parseAgentListCliOutput( ["build (primary)", "{}", "compaction (primary)", "{}"].join("\n"), diff --git a/src/lib/models.ts b/src/lib/models.ts index a5a9ef1d..867b89ac 100644 --- a/src/lib/models.ts +++ b/src/lib/models.ts @@ -152,6 +152,28 @@ export const MODELS: AgentModel[] = [ name: "Claude Sonnet 4.6", }, { id: "opencode:gpt-5.4", harness: "opencode", name: "GPT-5.4" }, + // Built-in OpenCode-compatible providers. These remain available as a + // fallback until `opencode models --verbose` returns a live catalog. + { + id: "opencode:zai/glm-5.2", + harness: "opencode", + name: "Z.AI · GLM-5.2", + nativeId: "zai/glm-5.2", + contextWindow: 200_000, + }, + { + id: "opencode:mimo/mimo-v2.5-pro", + harness: "opencode", + name: "MiMo · MiMo V2.5 Pro", + nativeId: "mimo/mimo-v2.5-pro", + contextWindow: 1_048_576, + }, + { + id: "opencode:opencode-zen/big-pickle", + harness: "opencode", + name: "OpenCode Zen · Big Pickle", + nativeId: "opencode-zen/big-pickle", + }, { id: "pi:default", harness: "pi", From 4f17d979492468125c3d761d93c9921815427f82 Mon Sep 17 00:00:00 2001 From: cmondary Date: Sat, 5 Sep 2026 08:37:50 +0200 Subject: [PATCH 02/14] ADD first-class OpenAI-compatible provider tabs --- src/chrome/HarnessIcon.tsx | 10 ++++++++- src/lib/harness/availability.ts | 10 ++++++++- src/lib/harness/opencodeAdapter.ts | 14 ++++++++++++ src/lib/harness/register.ts | 9 +++++++- src/lib/models.ts | 34 ++++++++++++++++++++++++++++++ src/lib/session.ts | 25 +++++++++++++++++++++- 6 files changed, 98 insertions(+), 4 deletions(-) diff --git a/src/chrome/HarnessIcon.tsx b/src/chrome/HarnessIcon.tsx index 73f978a9..11f610d6 100644 --- a/src/chrome/HarnessIcon.tsx +++ b/src/chrome/HarnessIcon.tsx @@ -15,6 +15,10 @@ export const HARNESS_ICONS: Record = { cursor, grok, opencode, + zai: opencode, + mimo: opencode, + openrouter: opencode, + nvidia: opencode, pi, omp, fx, @@ -25,6 +29,10 @@ export const MONOCHROME_HARNESSES = new Set([ "cursor", "grok", "opencode", + "zai", + "mimo", + "openrouter", + "nvidia", "pi", "omp", "fx", @@ -83,7 +91,7 @@ export function HarnessIcon({ ); } - if (harness === "opencode") { + if (["opencode", "zai", "mimo", "openrouter", "nvidia"].includes(harness)) { return ( = { install: "curl -fsSL https://x.ai/cli/install.sh | bash", }, opencode: { name: "OpenCode CLI" }, + zai: { name: "Z.AI via OpenCode CLI" }, + mimo: { name: "MiMo via OpenCode CLI" }, + openrouter: { name: "OpenRouter via OpenCode CLI" }, + nvidia: { name: "NVIDIA via OpenCode CLI" }, pi: { name: "Pi CLI", install: "npm i -g @earendil-works/pi-coding-agent" }, omp: { name: "omp CLI", install: "curl -fsSL https://omp.sh/install | sh" }, fx: { name: "fx CLI", install: "curl -fsSL https://fx.sh/setup.sh | bash" }, @@ -38,6 +42,10 @@ let availability: HarnessAvailability = { cursor: false, grok: false, opencode: false, + zai: false, + mimo: false, + openrouter: false, + nvidia: false, pi: false, omp: false, fx: false, @@ -119,7 +127,7 @@ export function probeHarnessAvailability( return [id, false] as const; } } - if (id === "opencode") { + if (["opencode", "zai", "mimo", "openrouter", "nvidia"].includes(id)) { try { await resolveOpenCodeBinary(); return [id, true] as const; diff --git a/src/lib/harness/opencodeAdapter.ts b/src/lib/harness/opencodeAdapter.ts index 71e8fc05..828a0852 100644 --- a/src/lib/harness/opencodeAdapter.ts +++ b/src/lib/harness/opencodeAdapter.ts @@ -18,6 +18,7 @@ import { import { generateOpenCodeSessionTitle } from "./opencodeTitle"; import { warmupOpenCodeText } from "./opencodeText"; import { registerHarness, type HarnessAdapter } from "./registry"; +import type { HarnessId } from "../session"; export const openCodeAdapter: HarnessAdapter = { id: "opencode", @@ -46,3 +47,16 @@ export function ensureOpenCodeRegistered(): void { registerHarness(openCodeAdapter); registered = true; } + +/** + * OpenAI-compatible providers use the OpenCode runtime, but remain separate + * provider tabs in MonoCode. The selected model's native id tells OpenCode + * which provider/model pair to route to. + */ +export function ensureOpenCodeProviderRegistered(id: Exclude): void { + if (registeredProviders.has(id)) return; + registerHarness({ ...openCodeAdapter, id, refreshCatalog: undefined }); + registeredProviders.add(id); +} + +const registeredProviders = new Set(); diff --git a/src/lib/harness/register.ts b/src/lib/harness/register.ts index c8fbfe86..06a2e07c 100644 --- a/src/lib/harness/register.ts +++ b/src/lib/harness/register.ts @@ -3,7 +3,10 @@ import { ensureCodexRegistered } from "./codexAdapter"; import { ensureCursorRegistered } from "./cursorAdapter"; import { ensureFxRegistered } from "./fxAdapter"; import { ensureGrokRegistered } from "./grokAdapter"; -import { ensureOpenCodeRegistered } from "./opencodeAdapter"; +import { + ensureOpenCodeProviderRegistered, + ensureOpenCodeRegistered, +} from "./opencodeAdapter"; import { ensureOmpRegistered } from "./ompAdapter"; import { ensurePiRegistered } from "./piAdapter"; @@ -14,6 +17,10 @@ export function registerBuiltinHarnesses(): void { ensureCodexRegistered(); ensureGrokRegistered(); ensureOpenCodeRegistered(); + ensureOpenCodeProviderRegistered("zai"); + ensureOpenCodeProviderRegistered("mimo"); + ensureOpenCodeProviderRegistered("openrouter"); + ensureOpenCodeProviderRegistered("nvidia"); ensurePiRegistered(); ensureOmpRegistered(); ensureFxRegistered(); diff --git a/src/lib/models.ts b/src/lib/models.ts index 867b89ac..4c97cc60 100644 --- a/src/lib/models.ts +++ b/src/lib/models.ts @@ -174,6 +174,32 @@ export const MODELS: AgentModel[] = [ name: "OpenCode Zen · Big Pickle", nativeId: "opencode-zen/big-pickle", }, + { + id: "zai:glm-5.2", + harness: "zai", + name: "GLM-5.2", + nativeId: "zai/glm-5.2", + contextWindow: 200_000, + }, + { + id: "mimo:mimo-v2.5-pro", + harness: "mimo", + name: "MiMo V2.5 Pro", + nativeId: "mimo/mimo-v2.5-pro", + contextWindow: 1_048_576, + }, + { + id: "openrouter:deepseek/deepseek-chat-v3.1", + harness: "openrouter", + name: "DeepSeek Chat V3.1", + nativeId: "openrouter/deepseek/deepseek-chat-v3.1", + }, + { + id: "nvidia:nvidia/llama-3.3-nemotron-super-49b-v1", + harness: "nvidia", + name: "NVIDIA Nemotron Super", + nativeId: "nvidia/nvidia/llama-3.3-nemotron-super-49b-v1", + }, { id: "pi:default", harness: "pi", @@ -200,6 +226,10 @@ export const DEFAULT_MODEL_ID: Record = { cursor: "cursor:composer-2.5", grok: "grok:grok-4.6", opencode: "opencode:glm-5", + zai: "zai:glm-5.2", + mimo: "mimo:mimo-v2.5-pro", + openrouter: "openrouter:deepseek/deepseek-chat-v3.1", + nvidia: "nvidia:nvidia/llama-3.3-nemotron-super-49b-v1", pi: "pi:default", omp: "omp:default", fx: "fx:zai/glm-5.2-fast", @@ -225,6 +255,10 @@ const HARNESS_ORDER: HarnessId[] = [ "cursor", "grok", "opencode", + "zai", + "mimo", + "openrouter", + "nvidia", "pi", "omp", "fx", diff --git a/src/lib/session.ts b/src/lib/session.ts index 41e9ece3..3d6791fe 100644 --- a/src/lib/session.ts +++ b/src/lib/session.ts @@ -11,7 +11,18 @@ import { } from "./models"; export type HarnessId = - "claude" | "codex" | "cursor" | "grok" | "opencode" | "pi" | "omp" | "fx"; + | "claude" + | "codex" + | "cursor" + | "grok" + | "opencode" + | "zai" + | "mimo" + | "openrouter" + | "nvidia" + | "pi" + | "omp" + | "fx"; export const HARNESSES: HarnessId[] = [ "claude", @@ -19,6 +30,10 @@ export const HARNESSES: HarnessId[] = [ "cursor", "grok", "opencode", + "zai", + "mimo", + "openrouter", + "nvidia", "pi", "omp", "fx", @@ -261,6 +276,10 @@ export const HARNESS_LABEL: Record = { cursor: "cursor", grok: "grok", opencode: "opencode", + zai: "zai", + mimo: "mimo", + openrouter: "openrouter", + nvidia: "nvidia", pi: "pi", omp: "omp", fx: "fx", @@ -272,6 +291,10 @@ export const HARNESS_TITLE: Record = { cursor: "Cursor", grok: "Grok Build", opencode: "OpenCode", + zai: "Z.AI", + mimo: "MiMo", + openrouter: "OpenRouter", + nvidia: "NVIDIA", pi: "Pi", omp: "omp", fx: "fx", From 486211bff5d05f799967d1229ca76c39f6dafe2a Mon Sep 17 00:00:00 2001 From: cmondary Date: Sat, 5 Sep 2026 08:44:19 +0200 Subject: [PATCH 03/14] FIX route ZAI and MiMo through OpenCode Go --- src/assets/providers/mimo.svg | 1 + src/assets/providers/nvidia.svg | 1 + src/assets/providers/openrouter.svg | 1 + src/assets/providers/zai.svg | 1 + src/chrome/HarnessIcon.tsx | 12 ++++--- src/lib/harness/opencodeCatalog.ts | 36 ++++++++++++++++--- src/lib/harness/opencodeProtocol.test.ts | 24 +++++++++---- src/lib/models.ts | 46 +++++++++++++----------- 8 files changed, 87 insertions(+), 35 deletions(-) create mode 100644 src/assets/providers/mimo.svg create mode 100644 src/assets/providers/nvidia.svg create mode 100644 src/assets/providers/openrouter.svg create mode 100644 src/assets/providers/zai.svg diff --git a/src/assets/providers/mimo.svg b/src/assets/providers/mimo.svg new file mode 100644 index 00000000..cf52ba67 --- /dev/null +++ b/src/assets/providers/mimo.svg @@ -0,0 +1 @@ + diff --git a/src/assets/providers/nvidia.svg b/src/assets/providers/nvidia.svg new file mode 100644 index 00000000..ccd2b69c --- /dev/null +++ b/src/assets/providers/nvidia.svg @@ -0,0 +1 @@ + diff --git a/src/assets/providers/openrouter.svg b/src/assets/providers/openrouter.svg new file mode 100644 index 00000000..59d28fc0 --- /dev/null +++ b/src/assets/providers/openrouter.svg @@ -0,0 +1 @@ + diff --git a/src/assets/providers/zai.svg b/src/assets/providers/zai.svg new file mode 100644 index 00000000..fd44c0c2 --- /dev/null +++ b/src/assets/providers/zai.svg @@ -0,0 +1 @@ + diff --git a/src/chrome/HarnessIcon.tsx b/src/chrome/HarnessIcon.tsx index 11f610d6..5fd70509 100644 --- a/src/chrome/HarnessIcon.tsx +++ b/src/chrome/HarnessIcon.tsx @@ -6,6 +6,10 @@ import fx from "../assets/providers/fx.svg"; import grok from "../assets/providers/grok.svg"; import omp from "../assets/providers/omp.svg"; import opencode from "../assets/providers/opencode.svg"; +import zai from "../assets/providers/zai.svg"; +import mimo from "../assets/providers/mimo.svg"; +import openrouter from "../assets/providers/openrouter.svg"; +import nvidia from "../assets/providers/nvidia.svg"; import pi from "../assets/providers/pi.svg"; import type { HarnessId } from "../lib/session"; @@ -15,10 +19,10 @@ export const HARNESS_ICONS: Record = { cursor, grok, opencode, - zai: opencode, - mimo: opencode, - openrouter: opencode, - nvidia: opencode, + zai, + mimo, + openrouter, + nvidia, pi, omp, fx, diff --git a/src/lib/harness/opencodeCatalog.ts b/src/lib/harness/opencodeCatalog.ts index b64746d6..cf118ccd 100644 --- a/src/lib/harness/opencodeCatalog.ts +++ b/src/lib/harness/opencodeCatalog.ts @@ -45,7 +45,15 @@ export function refreshOpenCodeCatalog(): Promise { if (inflight) return inflight; inflight = discoverOpenCodeModels() .then((models) => { - if (models.length > 0) setHarnessModels("opencode", models); + const byHarness = new Map(); + for (const model of models) { + const entries = byHarness.get(model.harness) ?? []; + entries.push(model); + byHarness.set(model.harness, entries); + } + for (const [harness, entries] of byHarness) { + if (entries.length > 0) setHarnessModels(harness, entries); + } }) .catch((error: unknown) => { console.debug("[monocode] opencode catalog", error); @@ -185,10 +193,11 @@ export function flattenOpenCodeModels( for (const [modelId, model] of Object.entries(provider.models)) { const name = model.name?.trim() || titleCaseSlug(modelId); const nativeId = `${provider.id}/${model.id ?? modelId}`; + const harness = providerHarness(provider.id, model.id ?? modelId); const contextWindow = model.limit?.context; models.push({ - id: `opencode:${nativeId}`, - harness: "opencode", + id: `${harness}:${nativeId}`, + harness, name, nativeId, settings: openCodeModelSettings(provider.id, model, primaryAgents), @@ -201,7 +210,11 @@ export function flattenOpenCodeModels( // entries above replace these fallback entries by their complete metadata. const seen = new Set(models.map((model) => model.nativeId)); for (const model of MODELS) { - if (model.harness !== "opencode" || !model.nativeId || seen.has(model.nativeId)) { + if ( + !["opencode", "zai", "mimo", "openrouter", "nvidia"].includes(model.harness) || + !model.nativeId || + seen.has(model.nativeId) + ) { continue; } models.push(model); @@ -209,6 +222,21 @@ export function flattenOpenCodeModels( return models.sort((left, right) => left.name.localeCompare(right.name)); } +function providerHarness( + providerID: string, + modelID: string, +): AgentModel["harness"] { + if (providerID === "zai" || (providerID === "opencode-go" && modelID.startsWith("glm-"))) { + return "zai"; + } + if (providerID === "mimo" || (providerID === "opencode-go" && modelID.startsWith("mimo-"))) { + return "mimo"; + } + if (providerID === "openrouter") return "openrouter"; + if (providerID === "nvidia") return "nvidia"; + return "opencode"; +} + function openCodeModelSettings( providerID: string, model: OpenCodeModelJson, diff --git a/src/lib/harness/opencodeProtocol.test.ts b/src/lib/harness/opencodeProtocol.test.ts index 0a31b988..a59f099f 100644 --- a/src/lib/harness/opencodeProtocol.test.ts +++ b/src/lib/harness/opencodeProtocol.test.ts @@ -105,12 +105,17 @@ describe("OpenCode CLI inventory parsers", () => { ]); expect(models.map((model) => model.nativeId)).toEqual([ "anthropic/claude-sonnet-4-6", + "openrouter/deepseek/deepseek-chat-v3.1", "opencode/glm-5", - "mimo/mimo-v2.5-pro", - "opencode-zen/big-pickle", - "zai/glm-5.2", + "opencode-go/glm-5.1", + "opencode-go/glm-5.2", + "opencode-go/glm-5.3", + "opencode-go/glm-5.3-flash", + "opencode-go/mimo-v2.5", + "opencode-go/mimo-v2.5-pro", + "nvidia/nvidia/llama-3.3-nemotron-super-49b-v1", ]); - expect(models[1].settings?.some((setting) => setting.id === "variant")).toBe( + expect(models[2].settings?.some((setting) => setting.id === "variant")).toBe( true, ); expect(models[0].settings?.find((setting) => setting.id === "agent")?.value).toBe( @@ -124,9 +129,14 @@ describe("OpenCode CLI inventory parsers", () => { [], ); expect(models.map((model) => model.nativeId)).toEqual([ - "mimo/mimo-v2.5-pro", - "opencode-zen/big-pickle", - "zai/glm-5.2", + "openrouter/deepseek/deepseek-chat-v3.1", + "opencode-go/glm-5.1", + "opencode-go/glm-5.2", + "opencode-go/glm-5.3", + "opencode-go/glm-5.3-flash", + "opencode-go/mimo-v2.5", + "opencode-go/mimo-v2.5-pro", + "nvidia/nvidia/llama-3.3-nemotron-super-49b-v1", ]); }); diff --git a/src/lib/models.ts b/src/lib/models.ts index 4c97cc60..1f334f5e 100644 --- a/src/lib/models.ts +++ b/src/lib/models.ts @@ -152,42 +152,48 @@ export const MODELS: AgentModel[] = [ name: "Claude Sonnet 4.6", }, { id: "opencode:gpt-5.4", harness: "opencode", name: "GPT-5.4" }, - // Built-in OpenCode-compatible providers. These remain available as a - // fallback until `opencode models --verbose` returns a live catalog. { - id: "opencode:zai/glm-5.2", - harness: "opencode", - name: "Z.AI · GLM-5.2", - nativeId: "zai/glm-5.2", + id: "zai:glm-5.2", + harness: "zai", + name: "GLM-5.2", + nativeId: "opencode-go/glm-5.2", contextWindow: 200_000, }, { - id: "opencode:mimo/mimo-v2.5-pro", - harness: "opencode", - name: "MiMo · MiMo V2.5 Pro", - nativeId: "mimo/mimo-v2.5-pro", - contextWindow: 1_048_576, + id: "zai:glm-5.1", + harness: "zai", + name: "GLM-5.1", + nativeId: "opencode-go/glm-5.1", + contextWindow: 202_752, }, { - id: "opencode:opencode-zen/big-pickle", - harness: "opencode", - name: "OpenCode Zen · Big Pickle", - nativeId: "opencode-zen/big-pickle", + id: "zai:glm-5.3", + harness: "zai", + name: "GLM-5.3", + nativeId: "opencode-go/glm-5.3", + contextWindow: 1_000_000, }, { - id: "zai:glm-5.2", + id: "zai:glm-5.3-flash", harness: "zai", - name: "GLM-5.2", - nativeId: "zai/glm-5.2", - contextWindow: 200_000, + name: "GLM-5.3 Flash", + nativeId: "opencode-go/glm-5.3-flash", + contextWindow: 1_000_000, }, { id: "mimo:mimo-v2.5-pro", harness: "mimo", name: "MiMo V2.5 Pro", - nativeId: "mimo/mimo-v2.5-pro", + nativeId: "opencode-go/mimo-v2.5-pro", contextWindow: 1_048_576, }, + { + id: "mimo:mimo-v2.5", + harness: "mimo", + name: "MiMo V2.5", + nativeId: "opencode-go/mimo-v2.5", + contextWindow: 1_000_000, + }, { id: "openrouter:deepseek/deepseek-chat-v3.1", harness: "openrouter", From edd2faf3b911d1263e157a4dbac4a5e094a38bc4 Mon Sep 17 00:00:00 2001 From: cmondary Date: Sat, 5 Sep 2026 08:53:13 +0200 Subject: [PATCH 04/14] FIX use direct ZAI and Xiaomi providers --- src/lib/harness/opencodeCatalog.ts | 17 ++++++++++------- src/lib/harness/opencodeProtocol.test.ts | 24 ++++++++++++------------ src/lib/models.ts | 12 ++++++------ 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/lib/harness/opencodeCatalog.ts b/src/lib/harness/opencodeCatalog.ts index cf118ccd..9bd56fe2 100644 --- a/src/lib/harness/opencodeCatalog.ts +++ b/src/lib/harness/opencodeCatalog.ts @@ -193,7 +193,7 @@ export function flattenOpenCodeModels( for (const [modelId, model] of Object.entries(provider.models)) { const name = model.name?.trim() || titleCaseSlug(modelId); const nativeId = `${provider.id}/${model.id ?? modelId}`; - const harness = providerHarness(provider.id, model.id ?? modelId); + const harness = providerHarness(provider.id); const contextWindow = model.limit?.context; models.push({ id: `${harness}:${nativeId}`, @@ -222,14 +222,17 @@ export function flattenOpenCodeModels( return models.sort((left, right) => left.name.localeCompare(right.name)); } -function providerHarness( - providerID: string, - modelID: string, -): AgentModel["harness"] { - if (providerID === "zai" || (providerID === "opencode-go" && modelID.startsWith("glm-"))) { +function providerHarness(providerID: string): AgentModel["harness"] { + if ( + providerID === "zai" || + providerID === "zai-coding-plan" + ) { return "zai"; } - if (providerID === "mimo" || (providerID === "opencode-go" && modelID.startsWith("mimo-"))) { + if ( + providerID === "mimo" || + providerID.startsWith("xiaomi-token-plan-") + ) { return "mimo"; } if (providerID === "openrouter") return "openrouter"; diff --git a/src/lib/harness/opencodeProtocol.test.ts b/src/lib/harness/opencodeProtocol.test.ts index a59f099f..b502905a 100644 --- a/src/lib/harness/opencodeProtocol.test.ts +++ b/src/lib/harness/opencodeProtocol.test.ts @@ -107,12 +107,12 @@ describe("OpenCode CLI inventory parsers", () => { "anthropic/claude-sonnet-4-6", "openrouter/deepseek/deepseek-chat-v3.1", "opencode/glm-5", - "opencode-go/glm-5.1", - "opencode-go/glm-5.2", - "opencode-go/glm-5.3", - "opencode-go/glm-5.3-flash", - "opencode-go/mimo-v2.5", - "opencode-go/mimo-v2.5-pro", + "zai-coding-plan/glm-5.1", + "zai-coding-plan/glm-5.2", + "zai-coding-plan/glm-5.3", + "zai-coding-plan/glm-5.3-flash", + "xiaomi-token-plan-ams/mimo-v2.5", + "xiaomi-token-plan-ams/mimo-v2.5-pro", "nvidia/nvidia/llama-3.3-nemotron-super-49b-v1", ]); expect(models[2].settings?.some((setting) => setting.id === "variant")).toBe( @@ -130,12 +130,12 @@ describe("OpenCode CLI inventory parsers", () => { ); expect(models.map((model) => model.nativeId)).toEqual([ "openrouter/deepseek/deepseek-chat-v3.1", - "opencode-go/glm-5.1", - "opencode-go/glm-5.2", - "opencode-go/glm-5.3", - "opencode-go/glm-5.3-flash", - "opencode-go/mimo-v2.5", - "opencode-go/mimo-v2.5-pro", + "zai-coding-plan/glm-5.1", + "zai-coding-plan/glm-5.2", + "zai-coding-plan/glm-5.3", + "zai-coding-plan/glm-5.3-flash", + "xiaomi-token-plan-ams/mimo-v2.5", + "xiaomi-token-plan-ams/mimo-v2.5-pro", "nvidia/nvidia/llama-3.3-nemotron-super-49b-v1", ]); }); diff --git a/src/lib/models.ts b/src/lib/models.ts index 1f334f5e..0968a8a5 100644 --- a/src/lib/models.ts +++ b/src/lib/models.ts @@ -156,42 +156,42 @@ export const MODELS: AgentModel[] = [ id: "zai:glm-5.2", harness: "zai", name: "GLM-5.2", - nativeId: "opencode-go/glm-5.2", + nativeId: "zai-coding-plan/glm-5.2", contextWindow: 200_000, }, { id: "zai:glm-5.1", harness: "zai", name: "GLM-5.1", - nativeId: "opencode-go/glm-5.1", + nativeId: "zai-coding-plan/glm-5.1", contextWindow: 202_752, }, { id: "zai:glm-5.3", harness: "zai", name: "GLM-5.3", - nativeId: "opencode-go/glm-5.3", + nativeId: "zai-coding-plan/glm-5.3", contextWindow: 1_000_000, }, { id: "zai:glm-5.3-flash", harness: "zai", name: "GLM-5.3 Flash", - nativeId: "opencode-go/glm-5.3-flash", + nativeId: "zai-coding-plan/glm-5.3-flash", contextWindow: 1_000_000, }, { id: "mimo:mimo-v2.5-pro", harness: "mimo", name: "MiMo V2.5 Pro", - nativeId: "opencode-go/mimo-v2.5-pro", + nativeId: "xiaomi-token-plan-ams/mimo-v2.5-pro", contextWindow: 1_048_576, }, { id: "mimo:mimo-v2.5", harness: "mimo", name: "MiMo V2.5", - nativeId: "opencode-go/mimo-v2.5", + nativeId: "xiaomi-token-plan-ams/mimo-v2.5", contextWindow: 1_000_000, }, { From c56e685e77694cff631a2d19898db854c0fde84b Mon Sep 17 00:00:00 2001 From: cmondary Date: Sat, 5 Sep 2026 09:02:37 +0200 Subject: [PATCH 05/14] ADD provider icons from CodexBar --- NOTICE | 3 +++ src/assets/providers/mimo.svg | 5 ++++- src/assets/providers/openrouter.svg | 14 +++++++++++++- src/assets/providers/zai.svg | 6 +++++- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/NOTICE b/NOTICE index cda0c48f..0ec36818 100644 --- a/NOTICE +++ b/NOTICE @@ -2,3 +2,6 @@ MonoCode is not affiliated with, endorsed by, or sponsored by the makers of the agent harnesses it can drive. Provider marks that appear in the UI (including Claude, Codex, Cursor, Grok, OpenCode, Pi, omp, and fx) are trademarks of their respective owners and are used only to identify those products. + +The Z.AI, MiMo, and OpenRouter provider SVG marks are adapted from CodexBar, +Copyright (c) 2026 Peter Steinberger, and are distributed under the MIT License. diff --git a/src/assets/providers/mimo.svg b/src/assets/providers/mimo.svg index cf52ba67..50b1b8e3 100644 --- a/src/assets/providers/mimo.svg +++ b/src/assets/providers/mimo.svg @@ -1 +1,4 @@ - + + + + diff --git a/src/assets/providers/openrouter.svg b/src/assets/providers/openrouter.svg index 59d28fc0..94e78fee 100644 --- a/src/assets/providers/openrouter.svg +++ b/src/assets/providers/openrouter.svg @@ -1 +1,13 @@ - + + + + + + + + + + + + + diff --git a/src/assets/providers/zai.svg b/src/assets/providers/zai.svg index fd44c0c2..90265520 100644 --- a/src/assets/providers/zai.svg +++ b/src/assets/providers/zai.svg @@ -1 +1,5 @@ - + + + + + From 34de8197146eef3ede1fa4e651cd054457852d03 Mon Sep 17 00:00:00 2001 From: cmondary Date: Sat, 5 Sep 2026 09:10:46 +0200 Subject: [PATCH 06/14] FIX render distinct provider icons --- src/chrome/HarnessIcon.tsx | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/chrome/HarnessIcon.tsx b/src/chrome/HarnessIcon.tsx index 5fd70509..f0809b0e 100644 --- a/src/chrome/HarnessIcon.tsx +++ b/src/chrome/HarnessIcon.tsx @@ -95,16 +95,6 @@ export function HarnessIcon({ ); } - if (["opencode", "zai", "mimo", "openrouter", "nvidia"].includes(harness)) { - return ( - - - - ); - } if (harness === "pi") { return ( @@ -129,6 +119,25 @@ export function HarnessIcon({ ); } + if (MONOCHROME_HARNESSES.has(harness)) { + const icon = HARNESS_ICONS[harness]; + return ( + + ); + } return ( Date: Sat, 5 Sep 2026 09:15:32 +0200 Subject: [PATCH 07/14] FIX render provider SVG assets in Tauri --- src/assets/providers/mimo.svg | 4 ++-- src/assets/providers/openrouter.svg | 2 +- src/chrome/HarnessIcon.tsx | 23 +++++++---------------- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/src/assets/providers/mimo.svg b/src/assets/providers/mimo.svg index 50b1b8e3..bd0ed759 100644 --- a/src/assets/providers/mimo.svg +++ b/src/assets/providers/mimo.svg @@ -1,4 +1,4 @@ - - + + diff --git a/src/assets/providers/openrouter.svg b/src/assets/providers/openrouter.svg index 94e78fee..f9867e52 100644 --- a/src/assets/providers/openrouter.svg +++ b/src/assets/providers/openrouter.svg @@ -1,4 +1,4 @@ - + diff --git a/src/chrome/HarnessIcon.tsx b/src/chrome/HarnessIcon.tsx index f0809b0e..a47cdaed 100644 --- a/src/chrome/HarnessIcon.tsx +++ b/src/chrome/HarnessIcon.tsx @@ -119,23 +119,14 @@ export function HarnessIcon({ ); } - if (MONOCHROME_HARNESSES.has(harness)) { - const icon = HARNESS_ICONS[harness]; + if (harness === "opencode") { return ( - + + + ); } return ( From 7190c94e590096a1e24f2897e7c8e1b2bcd4ed05 Mon Sep 17 00:00:00 2001 From: cmondary Date: Sat, 5 Sep 2026 09:26:18 +0200 Subject: [PATCH 08/14] FIX refresh provider catalogs and retire NVIDIA model --- src/lib/harness/opencodeAdapter.ts | 2 +- src/lib/harness/opencodeCatalog.ts | 53 +++++++++++++++++++++++- src/lib/harness/opencodeProtocol.test.ts | 4 +- src/lib/models.ts | 8 ++-- 4 files changed, 58 insertions(+), 9 deletions(-) diff --git a/src/lib/harness/opencodeAdapter.ts b/src/lib/harness/opencodeAdapter.ts index 828a0852..4b620459 100644 --- a/src/lib/harness/opencodeAdapter.ts +++ b/src/lib/harness/opencodeAdapter.ts @@ -55,7 +55,7 @@ export function ensureOpenCodeRegistered(): void { */ export function ensureOpenCodeProviderRegistered(id: Exclude): void { if (registeredProviders.has(id)) return; - registerHarness({ ...openCodeAdapter, id, refreshCatalog: undefined }); + registerHarness({ ...openCodeAdapter, id, refreshCatalog: refreshOpenCodeCatalog }); registeredProviders.add(id); } diff --git a/src/lib/harness/opencodeCatalog.ts b/src/lib/harness/opencodeCatalog.ts index 9bd56fe2..b5ea3166 100644 --- a/src/lib/harness/opencodeCatalog.ts +++ b/src/lib/harness/opencodeCatalog.ts @@ -27,6 +27,16 @@ type OpenCodeModelJson = { limit?: { context?: number; input?: number; output?: number }; }; +type OpenRouterModelJson = { + id?: string; + name?: string; + context_length?: number; + architecture?: { + input_modalities?: string[]; + output_modalities?: string[]; + }; +}; + type ParsedProvider = { id: string; name: string; @@ -89,7 +99,40 @@ async function discoverOpenCodeModels(): Promise { } catch (error) { console.debug("[monocode] opencode agents", error); } - return flattenOpenCodeModels(parsed, agents); + const models = flattenOpenCodeModels(parsed, agents); + const openRouterModels = await discoverOpenRouterModels(); + return [...models, ...openRouterModels]; +} + +async function discoverOpenRouterModels(): Promise { + try { + const response = await fetch("https://openrouter.ai/api/v1/models"); + if (!response.ok) throw new Error(`OpenRouter models HTTP ${response.status}`); + const payload = (await response.json()) as { data?: OpenRouterModelJson[] }; + return (payload.data ?? []) + .filter((model) => { + const input = model.architecture?.input_modalities ?? ["text"]; + const output = model.architecture?.output_modalities ?? ["text"]; + return input.includes("text") && output.includes("text"); + }) + .flatMap((model) => { + const nativeId = model.id?.trim(); + if (!nativeId) return []; + return [{ + id: `openrouter:openrouter/${nativeId}`, + harness: "openrouter" as const, + name: model.name?.trim() || nativeId, + nativeId: `openrouter/${nativeId}`, + ...(model.context_length && model.context_length > 0 + ? { contextWindow: model.context_length } + : {}), + }]; + }) + .sort((left, right) => left.name.localeCompare(right.name)); + } catch (error) { + console.debug("[monocode] openrouter public catalog", error); + return []; + } } export function parseModelsCliOutput(stdout: string): { @@ -193,6 +236,7 @@ export function flattenOpenCodeModels( for (const [modelId, model] of Object.entries(provider.models)) { const name = model.name?.trim() || titleCaseSlug(modelId); const nativeId = `${provider.id}/${model.id ?? modelId}`; + if (isRetiredModel(nativeId)) continue; const harness = providerHarness(provider.id); const contextWindow = model.limit?.context; models.push({ @@ -213,7 +257,8 @@ export function flattenOpenCodeModels( if ( !["opencode", "zai", "mimo", "openrouter", "nvidia"].includes(model.harness) || !model.nativeId || - seen.has(model.nativeId) + seen.has(model.nativeId) || + isRetiredModel(model.nativeId) ) { continue; } @@ -222,6 +267,10 @@ export function flattenOpenCodeModels( return models.sort((left, right) => left.name.localeCompare(right.name)); } +function isRetiredModel(nativeId: string): boolean { + return nativeId === "nvidia/nvidia/llama-3.3-nemotron-super-49b-v1"; +} + function providerHarness(providerID: string): AgentModel["harness"] { if ( providerID === "zai" || diff --git a/src/lib/harness/opencodeProtocol.test.ts b/src/lib/harness/opencodeProtocol.test.ts index b502905a..6513f5d8 100644 --- a/src/lib/harness/opencodeProtocol.test.ts +++ b/src/lib/harness/opencodeProtocol.test.ts @@ -113,7 +113,7 @@ describe("OpenCode CLI inventory parsers", () => { "zai-coding-plan/glm-5.3-flash", "xiaomi-token-plan-ams/mimo-v2.5", "xiaomi-token-plan-ams/mimo-v2.5-pro", - "nvidia/nvidia/llama-3.3-nemotron-super-49b-v1", + "nvidia/nvidia/llama-3.3-nemotron-super-49b-v1.5", ]); expect(models[2].settings?.some((setting) => setting.id === "variant")).toBe( true, @@ -136,7 +136,7 @@ describe("OpenCode CLI inventory parsers", () => { "zai-coding-plan/glm-5.3-flash", "xiaomi-token-plan-ams/mimo-v2.5", "xiaomi-token-plan-ams/mimo-v2.5-pro", - "nvidia/nvidia/llama-3.3-nemotron-super-49b-v1", + "nvidia/nvidia/llama-3.3-nemotron-super-49b-v1.5", ]); }); diff --git a/src/lib/models.ts b/src/lib/models.ts index 0968a8a5..c68f50cc 100644 --- a/src/lib/models.ts +++ b/src/lib/models.ts @@ -201,10 +201,10 @@ export const MODELS: AgentModel[] = [ nativeId: "openrouter/deepseek/deepseek-chat-v3.1", }, { - id: "nvidia:nvidia/llama-3.3-nemotron-super-49b-v1", + id: "nvidia:nvidia/llama-3.3-nemotron-super-49b-v1.5", harness: "nvidia", - name: "NVIDIA Nemotron Super", - nativeId: "nvidia/nvidia/llama-3.3-nemotron-super-49b-v1", + name: "NVIDIA Nemotron Super 49B v1.5", + nativeId: "nvidia/nvidia/llama-3.3-nemotron-super-49b-v1.5", }, { id: "pi:default", @@ -235,7 +235,7 @@ export const DEFAULT_MODEL_ID: Record = { zai: "zai:glm-5.2", mimo: "mimo:mimo-v2.5-pro", openrouter: "openrouter:deepseek/deepseek-chat-v3.1", - nvidia: "nvidia:nvidia/llama-3.3-nemotron-super-49b-v1", + nvidia: "nvidia:nvidia/llama-3.3-nemotron-super-49b-v1.5", pi: "pi:default", omp: "omp:default", fx: "fx:zai/glm-5.2-fast", From 84ac8b019711e99473cf76f920bafe2887758f4c Mon Sep 17 00:00:00 2001 From: cmondary Date: Sat, 5 Sep 2026 09:40:22 +0200 Subject: [PATCH 09/14] FIX OpenRouter native model ids --- src/lib/harness/opencodeCatalog.ts | 9 ++++++--- src/lib/harness/opencodeProtocol.test.ts | 4 ++-- src/lib/models.ts | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/lib/harness/opencodeCatalog.ts b/src/lib/harness/opencodeCatalog.ts index b5ea3166..ca86f448 100644 --- a/src/lib/harness/opencodeCatalog.ts +++ b/src/lib/harness/opencodeCatalog.ts @@ -119,10 +119,10 @@ async function discoverOpenRouterModels(): Promise { const nativeId = model.id?.trim(); if (!nativeId) return []; return [{ - id: `openrouter:openrouter/${nativeId}`, + id: `openrouter:${nativeId}`, harness: "openrouter" as const, name: model.name?.trim() || nativeId, - nativeId: `openrouter/${nativeId}`, + nativeId, ...(model.context_length && model.context_length > 0 ? { contextWindow: model.context_length } : {}), @@ -235,7 +235,10 @@ export function flattenOpenCodeModels( if (!connected.has(provider.id)) continue; for (const [modelId, model] of Object.entries(provider.models)) { const name = model.name?.trim() || titleCaseSlug(modelId); - const nativeId = `${provider.id}/${model.id ?? modelId}`; + const nativeId = + provider.id === "openrouter" + ? (model.id ?? modelId) + : `${provider.id}/${model.id ?? modelId}`; if (isRetiredModel(nativeId)) continue; const harness = providerHarness(provider.id); const contextWindow = model.limit?.context; diff --git a/src/lib/harness/opencodeProtocol.test.ts b/src/lib/harness/opencodeProtocol.test.ts index 6513f5d8..84d23e62 100644 --- a/src/lib/harness/opencodeProtocol.test.ts +++ b/src/lib/harness/opencodeProtocol.test.ts @@ -105,7 +105,7 @@ describe("OpenCode CLI inventory parsers", () => { ]); expect(models.map((model) => model.nativeId)).toEqual([ "anthropic/claude-sonnet-4-6", - "openrouter/deepseek/deepseek-chat-v3.1", + "deepseek/deepseek-chat-v3.1", "opencode/glm-5", "zai-coding-plan/glm-5.1", "zai-coding-plan/glm-5.2", @@ -129,7 +129,7 @@ describe("OpenCode CLI inventory parsers", () => { [], ); expect(models.map((model) => model.nativeId)).toEqual([ - "openrouter/deepseek/deepseek-chat-v3.1", + "deepseek/deepseek-chat-v3.1", "zai-coding-plan/glm-5.1", "zai-coding-plan/glm-5.2", "zai-coding-plan/glm-5.3", diff --git a/src/lib/models.ts b/src/lib/models.ts index c68f50cc..d61844bb 100644 --- a/src/lib/models.ts +++ b/src/lib/models.ts @@ -198,7 +198,7 @@ export const MODELS: AgentModel[] = [ id: "openrouter:deepseek/deepseek-chat-v3.1", harness: "openrouter", name: "DeepSeek Chat V3.1", - nativeId: "openrouter/deepseek/deepseek-chat-v3.1", + nativeId: "deepseek/deepseek-chat-v3.1", }, { id: "nvidia:nvidia/llama-3.3-nemotron-super-49b-v1.5", From 0296e78c27807e959f294c0c192c92ef315c340a Mon Sep 17 00:00:00 2001 From: cmondary Date: Sat, 5 Sep 2026 09:43:06 +0200 Subject: [PATCH 10/14] FIX preserve OpenRouter provider model namespace --- src/lib/harness/opencodeCatalog.ts | 9 +++------ src/lib/harness/opencodeProtocol.test.ts | 4 ++-- src/lib/models.ts | 2 +- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/lib/harness/opencodeCatalog.ts b/src/lib/harness/opencodeCatalog.ts index ca86f448..b5ea3166 100644 --- a/src/lib/harness/opencodeCatalog.ts +++ b/src/lib/harness/opencodeCatalog.ts @@ -119,10 +119,10 @@ async function discoverOpenRouterModels(): Promise { const nativeId = model.id?.trim(); if (!nativeId) return []; return [{ - id: `openrouter:${nativeId}`, + id: `openrouter:openrouter/${nativeId}`, harness: "openrouter" as const, name: model.name?.trim() || nativeId, - nativeId, + nativeId: `openrouter/${nativeId}`, ...(model.context_length && model.context_length > 0 ? { contextWindow: model.context_length } : {}), @@ -235,10 +235,7 @@ export function flattenOpenCodeModels( if (!connected.has(provider.id)) continue; for (const [modelId, model] of Object.entries(provider.models)) { const name = model.name?.trim() || titleCaseSlug(modelId); - const nativeId = - provider.id === "openrouter" - ? (model.id ?? modelId) - : `${provider.id}/${model.id ?? modelId}`; + const nativeId = `${provider.id}/${model.id ?? modelId}`; if (isRetiredModel(nativeId)) continue; const harness = providerHarness(provider.id); const contextWindow = model.limit?.context; diff --git a/src/lib/harness/opencodeProtocol.test.ts b/src/lib/harness/opencodeProtocol.test.ts index 84d23e62..6513f5d8 100644 --- a/src/lib/harness/opencodeProtocol.test.ts +++ b/src/lib/harness/opencodeProtocol.test.ts @@ -105,7 +105,7 @@ describe("OpenCode CLI inventory parsers", () => { ]); expect(models.map((model) => model.nativeId)).toEqual([ "anthropic/claude-sonnet-4-6", - "deepseek/deepseek-chat-v3.1", + "openrouter/deepseek/deepseek-chat-v3.1", "opencode/glm-5", "zai-coding-plan/glm-5.1", "zai-coding-plan/glm-5.2", @@ -129,7 +129,7 @@ describe("OpenCode CLI inventory parsers", () => { [], ); expect(models.map((model) => model.nativeId)).toEqual([ - "deepseek/deepseek-chat-v3.1", + "openrouter/deepseek/deepseek-chat-v3.1", "zai-coding-plan/glm-5.1", "zai-coding-plan/glm-5.2", "zai-coding-plan/glm-5.3", diff --git a/src/lib/models.ts b/src/lib/models.ts index d61844bb..c68f50cc 100644 --- a/src/lib/models.ts +++ b/src/lib/models.ts @@ -198,7 +198,7 @@ export const MODELS: AgentModel[] = [ id: "openrouter:deepseek/deepseek-chat-v3.1", harness: "openrouter", name: "DeepSeek Chat V3.1", - nativeId: "deepseek/deepseek-chat-v3.1", + nativeId: "openrouter/deepseek/deepseek-chat-v3.1", }, { id: "nvidia:nvidia/llama-3.3-nemotron-super-49b-v1.5", From f1ca1af166d01e8a73dd03262b67c0f45ff97b50 Mon Sep 17 00:00:00 2001 From: cmondary Date: Sat, 5 Sep 2026 09:45:43 +0200 Subject: [PATCH 11/14] FIX filter retired NVIDIA catalog models --- src/lib/harness/opencodeCatalog.ts | 6 +++++- src/lib/models.ts | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/lib/harness/opencodeCatalog.ts b/src/lib/harness/opencodeCatalog.ts index b5ea3166..85218bdd 100644 --- a/src/lib/harness/opencodeCatalog.ts +++ b/src/lib/harness/opencodeCatalog.ts @@ -268,7 +268,11 @@ export function flattenOpenCodeModels( } function isRetiredModel(nativeId: string): boolean { - return nativeId === "nvidia/nvidia/llama-3.3-nemotron-super-49b-v1"; + return new Set([ + "nvidia/deepseek-ai/deepseek-v4-pro", + "nvidia/z-ai/glm-5.2", + "nvidia/nvidia/llama-3.3-nemotron-super-49b-v1", + ]).has(nativeId); } function providerHarness(providerID: string): AgentModel["harness"] { diff --git a/src/lib/models.ts b/src/lib/models.ts index c68f50cc..5ec5709a 100644 --- a/src/lib/models.ts +++ b/src/lib/models.ts @@ -235,7 +235,7 @@ export const DEFAULT_MODEL_ID: Record = { zai: "zai:glm-5.2", mimo: "mimo:mimo-v2.5-pro", openrouter: "openrouter:deepseek/deepseek-chat-v3.1", - nvidia: "nvidia:nvidia/llama-3.3-nemotron-super-49b-v1.5", + nvidia: "nvidia:nvidia/nemotron-3.5-lightning-30b-a3b", pi: "pi:default", omp: "omp:default", fx: "fx:zai/glm-5.2-fast", From 88c6df172e1ddf247c5090b92583e8f23f9d34fd Mon Sep 17 00:00:00 2001 From: cmondary Date: Sat, 5 Sep 2026 09:59:50 +0200 Subject: [PATCH 12/14] FIX provider marks on light theme --- src/chrome/HarnessIcon.tsx | 4 +++- src/index.css | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/chrome/HarnessIcon.tsx b/src/chrome/HarnessIcon.tsx index a47cdaed..7b3fa4b1 100644 --- a/src/chrome/HarnessIcon.tsx +++ b/src/chrome/HarnessIcon.tsx @@ -134,7 +134,9 @@ export function HarnessIcon({ src={HARNESS_ICONS[harness]} alt="" draggable={false} - className={`block object-contain ${className}`} + className={`block object-contain ${ + MONOCHROME_HARNESSES.has(harness) ? "provider-icon-monochrome" : "" + } ${className}`} /> ); } diff --git a/src/index.css b/src/index.css index 1378ce63..277d0aad 100644 --- a/src/index.css +++ b/src/index.css @@ -47,6 +47,12 @@ html.theme-light { color-scheme: light; } +/* CodexBar's monochrome provider marks are white SVGs. Keep them visible on + the light theme without altering the colored NVIDIA mark. */ +html.theme-light .provider-icon-monochrome { + filter: invert(1); +} + html, body, #root { From 43f5b5d7eb86f25e8e659cc0dcbaa3a55efd33d7 Mon Sep 17 00:00:00 2001 From: cmondary Date: Sat, 5 Sep 2026 10:01:26 +0200 Subject: [PATCH 13/14] FIX filter retired NVIDIA Nano models --- src/lib/harness/opencodeCatalog.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib/harness/opencodeCatalog.ts b/src/lib/harness/opencodeCatalog.ts index 85218bdd..fef01aa9 100644 --- a/src/lib/harness/opencodeCatalog.ts +++ b/src/lib/harness/opencodeCatalog.ts @@ -272,6 +272,8 @@ function isRetiredModel(nativeId: string): boolean { "nvidia/deepseek-ai/deepseek-v4-pro", "nvidia/z-ai/glm-5.2", "nvidia/nvidia/llama-3.3-nemotron-super-49b-v1", + "nvidia/nvidia/nvidia-nemotron-nano-9b-v2", + "nvidia/nvidia/nemotron-nano-12b-v2-vl", ]).has(nativeId); } From 9b07e516030a130d4c934e6da1115d980c176b1d Mon Sep 17 00:00:00 2001 From: cmondary Date: Sat, 5 Sep 2026 10:07:32 +0200 Subject: [PATCH 14/14] FIX provider icon contrast in light theme --- src/index.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/index.css b/src/index.css index 277d0aad..bb9f843a 100644 --- a/src/index.css +++ b/src/index.css @@ -50,7 +50,8 @@ html.theme-light { /* CodexBar's monochrome provider marks are white SVGs. Keep them visible on the light theme without altering the colored NVIDIA mark. */ html.theme-light .provider-icon-monochrome { - filter: invert(1); + /* White source mark -> the same soft dark tone used by text-content. */ + filter: invert(0.82); } html,