Repository navigation
Description
Summary
When OpenCode runs as an ACP agent (opencode acp), session/new ignores the model set in opencode.json(c) and always reports a built-in fallback model (opencode/deepseek-v4.1-flash) as currentValue. ACP clients (e.g. Neovim plugins using OpenCode as their provider) therefore start sessions with the wrong model, while the TUI/server resolve the configured default correctly.
Environment
- opencode version: 2.0.11
- OS: Linux 7.0.0-31-generic (Ubuntu, x86_64)
- Terminal: alacritty (TERM=alacritty, COLORTERM=truecolor)
- Shell: /bin/bash
- Install/channel: latest (release)
- Active plugins: none
Config in use (~/.config/opencode/opencode.jsonc):
{
"$schema": "https://opencode.ai/config.json",
"model": "github-copilot/kimi-k3"
}Reproduction
- Set a default model in the global config, e.g.
"model": "github-copilot/kimi-k3"as above. - Verify the server honors it:
opencode api get /api/model/default→ returnsgithub-copilot/kimi-k3(works as expected). - Start OpenCode as an ACP agent:
opencode acp(this is what editor integrations spawn). - Send
initialize(protocolVersion 1), thensession/newwith anycwdandmcpServers: []over newline-delimited JSON-RPC. - Inspect the
configOptionsin thesession/newresult.
Minimal probe script (Python):
import json, subprocess, threading, time
proc = subprocess.Popen(["opencode", "acp"], stdin=subprocess.PIPE,
stdout=subprocess.PIPE, text=True, cwd="/tmp")
lines = []
threading.Thread(target=lambda: [lines.append(l) for l in proc.stdout], daemon=True).start()
def send(obj):
proc.stdin.write(json.dumps(obj) + "\n"); proc.stdin.flush()
send({"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {
"protocolVersion": 1,
"clientCapabilities": {"fs": {"readTextFile": False, "writeTextFile": False}, "terminal": False},
"clientInfo": {"name": "probe", "version": "0.0.1"}}})
time.sleep(2)
send({"jsonrpc": "2.0", "id": 2, "method": "session/new",
"params": {"cwd": "/tmp", "mcpServers": []}})
time.sleep(4)
for l in lines:
try:
res = json.loads(l).get("result") or {}
except ValueError:
continue
for opt in res.get("configOptions") or []:
if opt.get("category") == "model":
print("currentValue:", opt.get("currentValue"))
proc.kill()Expected Behavior
The model config option's currentValue in the session/new response reflects the configured default model (github-copilot/kimi-k3), matching what the TUI and the HTTP API (/api/model/default) resolve.
Actual Behavior
currentValue is always opencode/deepseek-v4.1-flash, regardless of the model set in global or project config, and regardless of the cwd passed to session/new (tested from a config-free temp dir, from the home directory, and from ~/.config/opencode itself — same result everywhere).
Notes:
- The configured model is present in the option's
optionslist, so this is not an availability problem. - The model can be corrected per session afterwards:
session/set_config_optionwithconfigId: "model",value: "github-copilot/kimi-k3"succeeds and sticks. So only the initial default is wrong. - Impact: any ACP client that relies on the agent's default (e.g.
agentic.nvimwithprovider = "opencode-acp") silently runs sessions on the fallback model instead of the user's configured one. Users must either switch models manually per session or configure the client to force the model aftersession/new(agentic.nvim:acp_providers["opencode-acp"].initial_model). - Reproducible: consistently, on every
session/new.
Activity
onlinerj commentedon Sep 21, 2026
I'd like to investigate and work on this. I'll first reproduce it on current v2, trace how the configured model reaches ACP session creation, and add regression coverage if the bug is still present. Please let me know if someone is already working on it.
onlinerj commentedon Sep 29, 2026
Update: I found potentially related work in #50619, which restores plugin activation waiting before ACP catalog loading. I’m holding off on a separate implementation until we establish whether it also fixes this issue. This report differs slightly: the configured model appears in the options but isn’t selected as the default.
nexxeln commentedon Sep 30, 2026
Fixed by #52286 (merged in 1844c11): ACP no longer pins agent/model from an early catalog snapshot on
session/new, and it refreshes the catalog (pushingconfig_option_update/available_commands_update) when plugins finish loading config agents, providers, and commands. It also reloads the catalog before rejecting an unknown model or mode inset_config_option/set_mode. Please reopen if you still see this on a release that includes the fix.