From 59f72d7efb6e2adc0266956b6cbe86ed9f2fe6d8 Mon Sep 17 00:00:00 2001 From: Derrick Barra Date: Fri, 20 Feb 2026 18:32:29 -0500 Subject: [PATCH 1/3] fix(cli): respect -m flag over agent model config The CLI -m flag was being ignored because: 1. Agent model took precedence over CLI flag 2. isModelValid() required provider to be in synced cache This caused custom providers like openrouter/* to fail with 'No provider selected' or fallback to default models. Fix by checking CLI -m flag first without strict validation: - currentModel() now checks args.model before agent model - fallbackModel() trusts CLI models even if not in cache This allows users to specify any provider/model via CLI: opencode -m openrouter/meta-llama/llama-3.1-8b-instruct Fixes # --- .../opencode/src/cli/cmd/tui/context/local.tsx | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/opencode/src/cli/cmd/tui/context/local.tsx b/packages/opencode/src/cli/cmd/tui/context/local.tsx index d93079f12a42..d563fef637ab 100644 --- a/packages/opencode/src/cli/cmd/tui/context/local.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/local.tsx @@ -154,7 +154,9 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ const fallbackModel = createMemo(() => { if (args.model) { const { providerID, modelID } = Provider.parseModel(args.model) - if (isModelValid({ providerID, modelID })) { + // FIX: Trust CLI-provided model even if not in synced provider list + // This allows using models like openrouter/* that may not be cached yet + if (providerID && modelID) { return { providerID, modelID, @@ -192,6 +194,16 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ const currentModel = createMemo(() => { const a = agent.current() + const args = useArgs() + + // FIX: Check CLI -m flag first without validation to allow custom providers like openrouter + if (args.model) { + const { providerID, modelID } = Provider.parseModel(args.model) + if (providerID && modelID) { + return { providerID, modelID } + } + } + return ( getFirstValidModel( () => modelStore.model[a.name], From 6482c8edd7b5f63c3034f3353a4e2cafe60708dc Mon Sep 17 00:00:00 2001 From: Derrick Barra Date: Fri, 20 Feb 2026 18:56:28 -0500 Subject: [PATCH 2/3] fix(cli): respect -m flag over agent model config The CLI -m flag was being ignored because: 1. Agent model took precedence over CLI flag 2. isModelValid() required provider to be in synced cache This fix: 1. Adds allowUncached parameter to isModelValid() for CLI models 2. Passes CLI -m flag through getFirstValidModel() chain with priority 3. Allows custom providers like openrouter/* to work even if not in cache Fixes #14502 --- .../src/cli/cmd/tui/context/local.tsx | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/context/local.tsx b/packages/opencode/src/cli/cmd/tui/context/local.tsx index d563fef637ab..39a8837be437 100644 --- a/packages/opencode/src/cli/cmd/tui/context/local.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/local.tsx @@ -21,16 +21,22 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ const sdk = useSDK() const toast = useToast() - function isModelValid(model: { providerID: string; modelID: string }) { + function isModelValid(model: { providerID: string; modelID: string }, allowUncached = false) { const provider = sync.data.provider.find((x) => x.id === model.providerID) - return !!provider?.models[model.modelID] + if (!provider) return false + // If model exists in cache, it's valid + if (provider.models[model.modelID]) return true + // If allowUncached is true (for CLI-provided models), accept it even if not in cache + return allowUncached } - function getFirstValidModel(...modelFns: (() => { providerID: string; modelID: string } | undefined)[]) { + function getFirstValidModel( + ...modelFns: (() => { providerID: string; modelID: string; allowUncached?: boolean } | undefined)[] + ) { for (const modelFn of modelFns) { const model = modelFn() if (!model) continue - if (isModelValid(model)) return model + if (isModelValid(model, model.allowUncached ?? false)) return model } } @@ -154,9 +160,7 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ const fallbackModel = createMemo(() => { if (args.model) { const { providerID, modelID } = Provider.parseModel(args.model) - // FIX: Trust CLI-provided model even if not in synced provider list - // This allows using models like openrouter/* that may not be cached yet - if (providerID && modelID) { + if (isModelValid({ providerID, modelID })) { return { providerID, modelID, @@ -196,16 +200,22 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ const a = agent.current() const args = useArgs() - // FIX: Check CLI -m flag first without validation to allow custom providers like openrouter - if (args.model) { - const { providerID, modelID } = Provider.parseModel(args.model) - if (providerID && modelID) { - return { providerID, modelID } - } - } + // FIX: Include CLI -m flag in model resolution chain + // This allows custom providers like openrouter/* to work even if not in cache + const cliModel = args.model + ? (() => { + const { providerID, modelID } = Provider.parseModel(args.model) + if (providerID && modelID) { + // Mark CLI-provided models to skip strict cache validation + return { providerID, modelID, allowUncached: true } + } + return undefined + })() + : undefined return ( getFirstValidModel( + () => cliModel, // CLI -m flag takes precedence () => modelStore.model[a.name], () => a.model, fallbackModel, From cc95e30c1499ee58cc4b92bcc5e80172146d0018 Mon Sep 17 00:00:00 2001 From: Derrick Barra Date: Fri, 20 Feb 2026 19:15:08 -0500 Subject: [PATCH 3/3] fix(types): strip allowUncached from returned model getFirstValidModel() now destructures the model to return only providerID and modelID, stripping the allowUncached flag. This ensures the return type matches what the rest of the codebase expects while still using allowUncached for validation. --- packages/opencode/src/cli/cmd/tui/context/local.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/opencode/src/cli/cmd/tui/context/local.tsx b/packages/opencode/src/cli/cmd/tui/context/local.tsx index 39a8837be437..dda5b36dbfa9 100644 --- a/packages/opencode/src/cli/cmd/tui/context/local.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/local.tsx @@ -36,7 +36,11 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({ for (const modelFn of modelFns) { const model = modelFn() if (!model) continue - if (isModelValid(model, model.allowUncached ?? false)) return model + if (isModelValid(model, model.allowUncached ?? false)) { + // Strip allowUncached from returned model to match expected type + const { providerID, modelID } = model + return { providerID, modelID } + } } }