Skip to content

fix(opencode): filter disabled models in model pickers - #1079

Merged
xintaofei merged 2 commits into
spacering-net:mainfrom
lesscodex:fix/opencode-disabled-model-pickers
Nov 3, 2026
Merged

xintaofei merged 2 commits into
spacering-net:mainfrom
lesscodex:fix/opencode-disabled-model-pickers

Conversation

@xyalter

@xyalter xyalter commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Description

Filter models marked disabled: true from OpenCode's settings and chat model pickers.

In settings, filter the combined configured and catalog models by provider and config model ID. Remove the fallback that reintroduces disabled models or providers when no options remain.

In chat, read model visibility rules at session launch and filter model options in the shared update path. This covers grouped options, model variants, emitted updates, and session snapshots.

Validation

  • 52 related frontend tests passed.
  • 6 targeted Rust tests passed.
  • Targeted ESLint and TypeScript checks passed.

Fixes #1078

@xyalter
xyalter marked this pull request as draft November 2, 2026 01:19
@xyalter xyalter changed the title fix(opencode): filter disabled models in settings pickers fix(opencode): filter disabled models in model pickers Nov 2, 2026
@xyalter
xyalter force-pushed the fix/opencode-disabled-model-pickers branch from b4d7c41 to b3e5a65 Compare November 2, 2026 01:41
@xyalter
xyalter marked this pull request as ready for review November 2, 2026 02:47
@xintaofei

Copy link
Copy Markdown
Collaborator

@xyalter Thanks for tracking this down and for the thorough tests. The settings-page bug in #1078 is real. Codeg's default-model pickers merge configured and catalog models without looking at disabled, and the config-only fallback could bring a filtered-out provider back. Your frontend change fixes both, and the "before the catalog loads" test covers the case that is easy to miss.

We'd suggest narrowing the PR before merging: keep the settings fix, drop the chat-side filter, and limit the settings filter to 2.x providers blocks.

Summary

  1. OpenCode already removes disabled models from the chat model list it sends over ACP, so codeg doesn't need its own filter there.
  2. The Rust filter re-reads OpenCode's config on its own. Where that reading differs from OpenCode's, it can hide models OpenCode still offers and accepts.
  3. The settings filter should honor disabled only on 2.x providers blocks, because OpenCode 2 ignores it on 1.x provider blocks. A small patch is below.

1. OpenCode already filters the chat list

A model-level disabled: true in a 2.x block sets enabled = false (config/plugin/provider.ts#L272). The ACP catalog keeps only enabled models (acp/catalog.ts#L150), and the model select is built from that list (acp/config-option.ts#L22-L35). Codeg's chat picker shows OpenCode's configOptions as they arrive. We didn't find any codeg code that adds OpenCode models to it from another source.

We ran the script further down against the real binaries, OpenCode 2.2.0 (this branch's pin) and 2.2.5 (current main's pin), on macOS arm64. Both gave the same result:

native: ['relay/a']
legacy: ['relay/a', 'relay/b']

With a 2.x providers block, relay/b is already gone from the chat list without any codeg change. With a 1.x provider block, OpenCode 2 still offers relay/b and accepts it as the session model through session/set_config_option. With the 2.x block, the same call fails with model not found: relay/b. The 1.x model schema has no model-level disabled (v1/config/provider.ts#L8-L75), so the flag is dropped when OpenCode migrates the block.

If you saw a disabled model in the chat picker with a 2.x block, please share the OpenCode version and the relevant part of the config (no keys needed). That would be a case this check doesn't cover, and we'd like to look at it.

2. Where the Rust filter disagrees with OpenCode

hidden_models_for_env reads the global, project, .opencode and system config files once at launch (connection.rs#L2763-L2766). It then removes those models from every later model update. OpenCode resolves config with more inputs than those files, so the two can disagree. We checked these cases against OpenCode 2.2.5:

  • 1.x provider blocks. The reader honors disabled there, so it hides relay/b in the case above, which OpenCode offers.
  • OPENCODE_CONFIG / OPENCODE_CONFIG_CONTENT. OpenCode reads both (server-process.ts#L132-L133), and the reader doesn't. With b disabled in the global file and OPENCODE_CONFIG_CONTENT setting b back to disabled: false, OpenCode offers relay/b again. The reader would still hide it.
  • Project config turned off. With OPENCODE_DISABLE_PROJECT_CONFIG or OPENCODE_CONFIG_PROJECT_DISABLE set to true, OpenCode skips project config (server-process.ts#L122-L126). The reader still scans the project directories (opencode_models.rs#L100-L116). With a project opencode.json disabling c and either flag set to true, OpenCode offers relay/c, and the reader would hide it.
  • Changes while the agent runs. OpenCode reloads affected catalogs on model.updated events (acp/catalog.ts#L39-L78). Attached sessions subscribe to catalog changes (acp/sessions.ts#L142-L159) and receive config_option_update when their options change (acp/sessions.ts#L81-L88). The reader's list is fixed at launch, so a model it hid at launch would stay hidden in codeg after OpenCode re-enables it, until the agent restarts. We didn't test which config edits trigger that event.

The # split in filter_opencode_model_options also doesn't match OpenCode 2. Its model values are plain provider/model, and effort levels come in a separate effort select (acp/config-option.ts#L36-L54).

Since OpenCode already gives the right list, we'd remove opencode_models.rs and the connection.rs / session_state.rs changes rather than try to match OpenCode's config resolution in full.

3. Settings: honor disabled on 2.x blocks only

buildConnectedProviders collects disabled from both block shapes, so a 1.x block's disabled model is hidden in settings while OpenCode still offers it. readProviderBlocks already lets a 2.x block replace a 1.x block with the same id, so a shape check is enough. This patch applies to your branch head. The two OpenCode test files pass with it, along with ESLint and tsc. The new test fails without the source change.

Patch
diff --git a/src/lib/opencode-connect.test.ts b/src/lib/opencode-connect.test.ts
index 261449aa6..d2cd6fd77 100644
--- a/src/lib/opencode-connect.test.ts
+++ b/src/lib/opencode-connect.test.ts
@@ -593,6 +593,20 @@ describe("integrations and the panel view", () => {
       expect(buildConnectedModelOptions({ connected, catalog })).toEqual([])
     }
   )
+
+  it("keeps models a 1.x provider block marks disabled, as OpenCode 2 does", () => {
+    const connected = buildConnectedProviders({
+      config: {
+        provider: { relay: { models: { a: {}, b: { disabled: true } } } },
+      },
+      integrations: [],
+      catalog: [],
+    })
+    const groups = buildConnectedModelOptions({ connected, catalog: [] })
+    expect(groups.flatMap((group) => group.models.map((m) => m.value))).toEqual(
+      ["relay/a", "relay/b"]
+    )
+  })
 })
 
 describe("custom provider ids and labels", () => {
diff --git a/src/lib/opencode-connect.ts b/src/lib/opencode-connect.ts
index 207981f59..d67236d81 100644
--- a/src/lib/opencode-connect.ts
+++ b/src/lib/opencode-connect.ts
@@ -702,9 +702,14 @@ export function buildConnectedProviders(params: {
       baseUrl: block?.baseUrl ?? "",
       npm: block?.npm ?? "",
       modelIds: block?.modelIds ?? [],
-      disabledModelIds: Object.values(block?.models ?? {})
-        .filter((model) => model.disabled)
-        .map((model) => model.id),
+      // OpenCode 2 reads `disabled` on 2.x blocks only; a 1.x block's
+      // model-level `disabled` is dropped when it migrates the block.
+      disabledModelIds:
+        block?.shape === "native"
+          ? Object.values(block.models)
+              .filter((model) => model.disabled)
+              .map((model) => model.id)
+          : [],
     })
   }
   result.sort(

A smaller gap, not a blocker: OpenCode 2 turns a 1.x model's status: "deprecated" into disabled when it migrates the block, and the settings list doesn't do that yet. That gap was there before this PR.

How we checked

  • Both versions of the script output above, plus the OPENCODE_CONFIG_CONTENT and project-config cases from section 2, run against OpenCode 2.2.5.
  • The three frontend test files this PR touches pass on your branch, before and after the patch.
Reproduction script

It points HOME and XDG_* at a temp directory and clears other shell variables. The isolation is partial: system-wide OpenCode config, and any opencode.json in the temp directory's parent directories, are still read. Run bash repro.sh /path/to/opencode; it needs python3 on PATH.

#!/usr/bin/env bash
# Usage: bash repro.sh /path/to/opencode
# Starts `opencode acp` twice with HOME and XDG_* pointing at a temp dir, once
# with a native `providers` block and once with a legacy `provider` block, each
# marking model `b` as disabled, and prints the model choices from session/new.
set -euo pipefail
OC="$1"
"$OC" --version || { echo "cannot run $OC" >&2; exit 1; }
ROOT="$(mktemp -d /tmp/oc-disabled.XXXXXXXX)"
trap 'rm -rf "$ROOT"' EXIT

cat > "$ROOT/driver.py" <<'PY'
import json, subprocess, sys
cwd, cmd = sys.argv[1], sys.argv[2:]
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                     stderr=subprocess.DEVNULL, text=True)
def call(i, method, params):
    p.stdin.write(json.dumps({"jsonrpc": "2.0", "id": i, "method": method,
                              "params": params}) + "\n")
    p.stdin.flush()
    for line in p.stdout:
        msg = json.loads(line)
        if msg.get("id") == i:
            return msg
    sys.exit("opencode exited before answering " + method)
try:
    call(1, "initialize", {"protocolVersion": 1, "clientCapabilities": {}})
    res = call(2, "session/new", {"cwd": cwd, "mcpServers": []})
    if "error" in res:
        sys.exit("session/new failed: " + json.dumps(res["error"]))
    for opt in res["result"].get("configOptions", []):
        if opt.get("category") == "model":
            rows = [r for o in opt["options"] for r in o.get("options", [o])]
            print([r["value"] for r in rows if r["value"].startswith("relay/")])
finally:
    p.kill()
PY

run() {
  local name="$1" config="$2" dir="$ROOT/$1"
  mkdir -p "$dir/xdg/config/opencode" "$dir/work"
  printf '%s' "$config" > "$dir/xdg/config/opencode/opencode.json"
  echo '{}' > "$dir/models.json"
  printf '%s: ' "$name"
  (cd "$dir/work" && env -i PATH="$PATH" HOME="$dir" \
    XDG_CONFIG_HOME="$dir/xdg/config" XDG_DATA_HOME="$dir/xdg/data" \
    XDG_STATE_HOME="$dir/xdg/state" XDG_CACHE_HOME="$dir/xdg/cache" \
    OPENCODE_DISABLE_AUTOUPDATE=true OPENCODE_DISABLE_MODELS_FETCH=true \
    OPENCODE_MODELS_PATH="$dir/models.json" \
    python3 -I "$ROOT/driver.py" "$dir/work" "$OC" acp)
}

run native '{"model":"relay/a","providers":{"relay":{
  "package":"@ai-sdk/openai-compatible",
  "settings":{"baseURL":"http://127.0.0.1:9/v1","apiKey":"x"},
  "models":{"a":{},"b":{"disabled":true}}}}}'
run legacy '{"model":"relay/a","provider":{"relay":{
  "npm":"@ai-sdk/openai-compatible",
  "options":{"baseURL":"http://127.0.0.1:9/v1","apiKey":"x"},
  "models":{"a":{},"b":{"disabled":true}}}}}'

If we've misread OpenCode's behavior anywhere, or you have a case where the chat picker shows a model OpenCode won't accept, please say so and we'll take another look.

@xyalter
xyalter force-pushed the fix/opencode-disabled-model-pickers branch from e97afc6 to 62c139e Compare November 3, 2026 05:48
@xyalter

xyalter commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the detailed review. I verified the ACP behavior and narrowed the PR as suggested.

Changes made:

  • Removed Codeg’s chat-side OpenCode config reader, model filter, session state, and related Rust tests. Chat model visibility is now left to the model options OpenCode provides through ACP.
  • Kept the settings-page fix that filters disabled models after combining configured and catalog models, and removed the fallback that could reintroduce filtered models or providers.
  • Limited model-level disabled filtering to native 2.x providers blocks. A model-level disabled value in a legacy 1.x provider block remains visible because OpenCode 2 ignores that unsupported field.
  • Added regression coverage for the legacy provider case.
  • Left the existing legacy status: "deprecated" handling gap unchanged.

Validation:

  • 49 tests passed across the three affected frontend test files.
  • Targeted ESLint passed.
  • Full TypeScript check passed.
  • Server-mode Rust cargo check passed.

@xintaofei
xintaofei merged commit f8d6f5a into spacering-net:main Nov 3, 2026
13 checks passed
xintaofei added a commit that referenced this pull request Nov 3, 2026
This release adds CNB repository support and global system instruction editing, makes tasks awaiting your response easier to continue, and improves notifications and conversation history.

## New

- **CNB (cnb.cool) joins the supported code hosting platforms**, with issue and merge request management, automatic issue processing, and task delivery through merge requests. (#1066, @abigmiu)
- **Global system instructions can be viewed and edited directly in agent settings** for supported agents such as Claude Code, Codex and OpenCode, making it easier to set preferences and working rules. (#1060, @ana52070)
- **Channel and webhook notifications can be limited to top-level session completions and errors**, reducing sub-agent notifications while keeping permission requests and questions visible.

## Improved

- **Tasks awaiting permission, an answer or plan approval now prioritize “Respond”**, opening the conversation so you can handle the request and let the task continue.
- **Webhook notifications include conversation, agent and parent-session details**, making their source and delegation relationships easier to identify.
- **Expandable steps in the execution timeline highlight on hover and keyboard focus**, making it easier to see which step you are about to open.
- **Self-updated Hermes 0.22.6 installations retain provider-grouped model selection and mode switching**, with reasoning effort available alongside them.
- **Updated Claude Code to claude-agent-acp 0.100.0 and CodeBuddy to 2.179.3.**

## Fixed

- **OpenCode’s `/` menu once again lists the skills it loads**, making them available in chat, automation and task editors.
- **OpenCode’s default model lists in Settings correctly hide disabled models and providers.** (#1079, @xyalter)
- **DeepSeek Harness 0.2.x history correctly displays tool output, failures and cache-write usage**, including conversations migrated from earlier versions. (#1086, @Cuinnchen)
- **PowerShell in the built-in terminal and “Run on this computer” loads your profile**, allowing fnm, conda, aliases and other environment customizations to work.
- **Reopening a Pi conversation correctly restores its message history**, fixing cases where the conversation appeared empty.
- **Claude Code preserves the original conversation and explains why it cannot be restored**, avoiding an unexpected switch to an empty session when it is held by a background task or its worktree cannot be reopened.
- **Claude Code replies triggered by MCP prompt commands no longer appear twice in the conversation.**

Thanks to @abigmiu, @ana52070, @xyalter and @Cuinnchen for contributing to this release, and to @grykom, @branll, @DaYePython and @ZhangSanMo for the reports and suggestions.

-----------------------------

# 发布版本 0.42.0

这一版新增 CNB 仓库支持和全局系统提示词编辑,让等待你回应的任务更容易继续,并改进消息通知与历史会话展示。

## 新增

- **新增腾讯 CNB(cnb.cool)支持**,可管理 Issue 和合并请求、自动处理 Issue,并将任务成果交付为合并请求。(#1066,@abigmiu)
- **支持在智能体设置中直接查看和编辑全局系统提示词**,适用于 Claude Code、Codex、OpenCode 等智能体,方便配置角色、回复偏好和工作规范。(#1060,@ana52070)
- **消息渠道和 Webhook 可仅推送主会话的完成与错误通知**,减少子智能体的通知干扰,同时保留授权请求和提问提醒。

## 改进

- **等待授权、回答问题或审批计划的任务会优先显示「去回应」**,点击即可打开会话处理请求,回应后任务会自动继续。
- **Webhook 通知会附带会话、智能体及父会话信息**,方便识别消息来源和委派关系。
- **执行过程中可展开的步骤会在鼠标悬停或键盘聚焦时高亮**,更容易看清即将打开的步骤。
- **兼容自行升级的 Hermes 0.22.6**,保留按供应商分组的模型选择和模式切换,并支持调整推理强度。
- **Claude Code 适配器更新至 claude-agent-acp 0.100.0,CodeBuddy 更新至 2.179.3。**

## 修复

- **OpenCode 的 `/` 菜单恢复显示已加载的技能**,可在聊天、自动化和任务编辑器中直接选用。
- **OpenCode 设置中的默认模型列表会正确隐藏已禁用的模型和供应商。**(#1079,@xyalter)
- **DeepSeek Harness 0.2.x 的历史会话能正确显示工具输出、失败状态和缓存写入用量**,从旧版迁移的会话也能正常查看。(#1086,@Cuinnchen)
- **内置终端和「在本机运行」会正确加载 PowerShell 个人配置**,让 fnm、conda、命令别名等自定义环境正常生效。
- **重新打开 Pi 会话时可以正确恢复历史消息**,修复部分会话记录显示为空的问题。
- **Claude Code 无法恢复会话时会保留原会话并说明原因**,避免因后台任务占用或工作树无法重新打开而误切到空白会话。
- **Claude Code 使用 MCP 提示词命令时,同一轮对话不再重复显示。**

感谢 @abigmiu、@ana52070、@xyalter 和 @Cuinnchen 为本次发布做出的贡献,也感谢 @grykom、@branll、@DaYePython 和 @ZhangSanMo 的问题反馈和功能建议。
@xyalter
xyalter deleted the fix/opencode-disabled-model-pickers branch November 4, 2026 13:46
youxuanxue added a commit to youxuanxue/codeg that referenced this pull request Nov 8, 2026
* fix(opencode): filter disabled models in model pickers

* fix(opencode): narrow disabled model filtering

* fix(deepseek): read first-class tool results in v4 session logs

Session format v4 (DSH 0.2.x) lifts a tool result out of the released-v3
`tool-result` wrapper block into a first-class `role: "tool"` message:
`toolCallId`, the content blocks and the `isError` flag all move up to
`data.message`. The log reader already selects the numerically highest
canonical generation, so the moment a session directory holds a v4
successor — published by a 0.2.x write open on a migrated session, or
written directly by a 0.2.x agent — the parser selects that file and the
v3-only arm produced a ToolResult with no output and `isError: false`.

Read both shapes: use the wrapper when it is present, so released v3 and
older render exactly as before, and otherwise read the message's own
fields. Map v4's `usage.cacheWriteTokens` onto cache creation as well; v3
logs lack the key and still read as zero.

Tests: cargo test --no-default-features --features server-bin --lib
parsers::deepseek (38 passed), including v4 success/error results, the
source.callId fallback, an end-to-end retained-v3 + v4 successor fixture,
and the renamed usage counter.

* fix(deepseek): correct cacheWriteTokens provenance and pin it across generations

The step `usage` object is the same in session-format v3 and v4: upstream
lists cacheReadTokens / cacheWriteTokens / reasoningTokens as optional in
both schemas. What changed is DSH 0.2.x's DeepSeek adapter, which moved to
the Messages API and reports `cache_creation_input_tokens` as
cacheWriteTokens (0.1.x reported reasoningTokens). Reword the comments that
called it a v4 rename, note that the counts are disjoint like TurnUsage, and
run the cache-write test under both the legacy and v4 headers, including a
step whose only non-zero counter is the cache write.

* feat(activity): ink in an expandable step row on hover and focus

Pointing at or keyboard-focusing a step row that opens now darkens the
whole row to the foreground, as the "Collapse" row at the foot of a list
does: its grey label, description, command, path, figure and chevron,
and the grey glyph in its rail ring. Tones keep their colour (a diff's
counts, a failure, an amber wait), as do a running label's shimmer and
agent logos; the ring itself is unchanged. Hovering a member of an open
group lights only that member.

Covers the step rows, delegation "Waiting for task result" and cancel
checks, codeg tool and question records laid out as rows, and goals.
Hover applies only on devices with a hovering pointer.

* fix(terminal): load the user's PowerShell profile (spacering-net#1088)

Built-in terminal PowerShell tabs (interactive and folder-command ones)
and "run on this computer" commands launched PowerShell with -NoProfile,
so whatever the user's $PROFILE sets up was missing: fnm's --use-on-cd,
conda, aliases, PATH edits. The POSIX shells beside them already load
their startup files through -l -i and -l. Those launches now leave out
-NoProfile; the profile runs before -Command, so the UTF-8 output, the
codeg tab title and a command tab's stop-on-error still apply.

The ACP fallback for agent command lines keeps -NoProfile, matching its
non-login POSIX -c; so does the OfficeCLI installer.

* fix(chat): list OpenCode's skills in its slash menu (spacering-net#1089)

OpenCode 2.x advertises only its commands over ACP (/init, /review,
/goal, /compact), never a skill, though it still loads every skill.
Since the move from 1.x, which advertised skills as commands, typing /
offered none of them.

The / menu now lists every skill OpenCode loads after its commands:
~/.claude/skills and ~/.agents/skills, its config folder, and the
.claude, .agents and .opencode folders of the workspace and of every
directory above it, nested skill folders included, respecting
OpenCode's switches that turn the .claude and project folders off.
A new acp_list_agent_runtime_skills command feeds the menus (other
agents get what acp_list_agent_skills returns); the Skills settings
page keeps its own listing. A skill named after a command stays out;
a picked skill is sent as /<skill>. The automation and task composers
and the transcript's token badges follow the same rule.

* feat(acp): bump CodeBuddy to 2.179.3; hold Hermes at 0.22.2

Pin CodeBuddy 2.179.3, which needs no adaptation: its wire protocol,
selectors, transcripts and both Stop behaviours match 2.179.2.

Hermes stays at 0.22.2. On 0.22.6, config.yaml MCP servers still
report "not connected" in a session that also gets MCP servers from
codeg (upstream #143502), and outside macOS stopping the conversation
that started the shared gateway still takes the gateway down, ending
other conversations' turns.

Users of Hermes' self-updating installer already run 0.22.6 through
codeg, and its own config options replaced the grouped model selector
and the mode selector codeg builds. codeg now keeps both, folds in the
values Hermes pushes (its edit approval policy into the mode, a new
model into its provider's group) and shows reasoning effort beside
them. 0.22.2 sessions are unchanged.

* fix(settings): polish the agent system instructions editor

Put the section in a card like its neighbours, show the instructions file
as a path row that elides the directory but always keeps the file name
(with a copy button), let the editor grow with its content up to a cap,
and only enable Save while there is an unsaved edit, next to an
"Unsaved changes" note and a Discard button.

* # Release version 0.42.0

This release adds CNB repository support and global system instruction editing, makes tasks awaiting your response easier to continue, and improves notifications and conversation history.

## New

- **CNB (cnb.cool) joins the supported code hosting platforms**, with issue and merge request management, automatic issue processing, and task delivery through merge requests. (spacering-net#1066, @abigmiu)
- **Global system instructions can be viewed and edited directly in agent settings** for supported agents such as Claude Code, Codex and OpenCode, making it easier to set preferences and working rules. (spacering-net#1060, @ana52070)
- **Channel and webhook notifications can be limited to top-level session completions and errors**, reducing sub-agent notifications while keeping permission requests and questions visible.

## Improved

- **Tasks awaiting permission, an answer or plan approval now prioritize “Respond”**, opening the conversation so you can handle the request and let the task continue.
- **Webhook notifications include conversation, agent and parent-session details**, making their source and delegation relationships easier to identify.
- **Expandable steps in the execution timeline highlight on hover and keyboard focus**, making it easier to see which step you are about to open.
- **Self-updated Hermes 0.22.6 installations retain provider-grouped model selection and mode switching**, with reasoning effort available alongside them.
- **Updated Claude Code to claude-agent-acp 0.100.0 and CodeBuddy to 2.179.3.**

## Fixed

- **OpenCode’s `/` menu once again lists the skills it loads**, making them available in chat, automation and task editors.
- **OpenCode’s default model lists in Settings correctly hide disabled models and providers.** (spacering-net#1079, @xyalter)
- **DeepSeek Harness 0.2.x history correctly displays tool output, failures and cache-write usage**, including conversations migrated from earlier versions. (spacering-net#1086, @Cuinnchen)
- **PowerShell in the built-in terminal and “Run on this computer” loads your profile**, allowing fnm, conda, aliases and other environment customizations to work.
- **Reopening a Pi conversation correctly restores its message history**, fixing cases where the conversation appeared empty.
- **Claude Code preserves the original conversation and explains why it cannot be restored**, avoiding an unexpected switch to an empty session when it is held by a background task or its worktree cannot be reopened.
- **Claude Code replies triggered by MCP prompt commands no longer appear twice in the conversation.**

Thanks to @abigmiu, @ana52070, @xyalter and @Cuinnchen for contributing to this release, and to @grykom, @branll, @DaYePython and @ZhangSanMo for the reports and suggestions.

-----------------------------

# 发布版本 0.42.0

这一版新增 CNB 仓库支持和全局系统提示词编辑,让等待你回应的任务更容易继续,并改进消息通知与历史会话展示。

## 新增

- **新增腾讯 CNB(cnb.cool)支持**,可管理 Issue 和合并请求、自动处理 Issue,并将任务成果交付为合并请求。(spacering-net#1066,@abigmiu)
- **支持在智能体设置中直接查看和编辑全局系统提示词**,适用于 Claude Code、Codex、OpenCode 等智能体,方便配置角色、回复偏好和工作规范。(spacering-net#1060,@ana52070)
- **消息渠道和 Webhook 可仅推送主会话的完成与错误通知**,减少子智能体的通知干扰,同时保留授权请求和提问提醒。

## 改进

- **等待授权、回答问题或审批计划的任务会优先显示「去回应」**,点击即可打开会话处理请求,回应后任务会自动继续。
- **Webhook 通知会附带会话、智能体及父会话信息**,方便识别消息来源和委派关系。
- **执行过程中可展开的步骤会在鼠标悬停或键盘聚焦时高亮**,更容易看清即将打开的步骤。
- **兼容自行升级的 Hermes 0.22.6**,保留按供应商分组的模型选择和模式切换,并支持调整推理强度。
- **Claude Code 适配器更新至 claude-agent-acp 0.100.0,CodeBuddy 更新至 2.179.3。**

## 修复

- **OpenCode 的 `/` 菜单恢复显示已加载的技能**,可在聊天、自动化和任务编辑器中直接选用。
- **OpenCode 设置中的默认模型列表会正确隐藏已禁用的模型和供应商。**(spacering-net#1079,@xyalter)
- **DeepSeek Harness 0.2.x 的历史会话能正确显示工具输出、失败状态和缓存写入用量**,从旧版迁移的会话也能正常查看。(spacering-net#1086,@Cuinnchen)
- **内置终端和「在本机运行」会正确加载 PowerShell 个人配置**,让 fnm、conda、命令别名等自定义环境正常生效。
- **重新打开 Pi 会话时可以正确恢复历史消息**,修复部分会话记录显示为空的问题。
- **Claude Code 无法恢复会话时会保留原会话并说明原因**,避免因后台任务占用或工作树无法重新打开而误切到空白会话。
- **Claude Code 使用 MCP 提示词命令时,同一轮对话不再重复显示。**

感谢 @abigmiu、@ana52070、@xyalter 和 @Cuinnchen 为本次发布做出的贡献,也感谢 @grykom、@branll、@DaYePython 和 @ZhangSanMo 的问题反馈和功能建议。

* fix(browser): hide a browser tab's page under a fullscreen chat table

Streamdown portals its fullscreen table (and mermaid view) to <body> as
role="dialog" with no data-state, so the occlusion fallback detector
missed it and the native page covered the right side of the table.
Match those views by their data-streamdown marker.

* feat(acp): bump eight agent pins, Hermes to 0.22.7

Pin Hermes Agent 0.22.7, CodeBuddy 2.180.0, Grok 1.0.77, Kimi Code
2.5.1, Cursor 2026.11.05-86047df, Qoder 1.1.83, ZCode 0.82.1 and
Command Code 1.88.4.

Hermes leaves 0.22.2 with the two regressions 0.22.6 already had,
now noted as its known state: config.yaml MCP servers report "not
connected" in a session that also gets MCP servers from codeg
(upstream #143502), and where the shared gateway daemon is a child
of the viewer that started it (Linux, Windows, macOS without the
launchd job) stopping that conversation takes the daemon down,
ending other Hermes conversations' running turns.

Kimi Code 2.5.0 renamed mcp.json's stdio `runtime_id` to
`environment_id`. codeg's writer now keeps `environment_id` and the
boolean `deferred` every transport accepts (a user's `deferred` was
dropped whenever codeg rewrote the entry), keeps `runtime_id` for
older Kimi and still drops the `kaos` executor.

Cursor's history parser names the new ToolCall variants 95
(`manage_access`) and 1000 (`execute`), and the ACP retry patch
covers 86047df, whose bundles carry the same statement in all six
archives.

* fix(office): auto-open only Office files the agent's tools wrote this turn (spacering-net#1090, spacering-net#1091)

Replace the watcher-driven auto-preview with a per-turn list: each running
turn records Office paths named by its tool calls, confirms them by
mtime/birthtime against the turn window, and publishes them on
folder://agent-turn-files. The list is cleared when the turn ends (normal,
cancel, error or disconnect). The workspace opens only announced paths under
the active folder, and never re-opens a document closed in the same window.

* fix(acp): keep a session's background work alive when its view goes away (spacering-net#1096)

Closing or replacing a conversation view, the provider unmounting and the
idle sweeps only spared a connection that was prompting or had
transcript-watcher work, so they killed the agent CLI with an AIR async
task (a codex background terminal, a Claude Monitor or workflow task),
Remote Control or a running delegated sub-agent still inside it.

- Every self-initiated teardown now goes through one gate,
  isConnectionBusy, which also counts live async tasks, Remote Control and
  running delegations; the reconnect popover warns for the same work.
  Explicit disconnects (reconnect, restart to apply, agent switch) are
  unchanged.
- The broker reports every delegation on the parent's stream as a
  lifecycle-only DelegationChildRunning frame, synthetic ids included, and
  the backend sweep spares a parent while one of its children is still a
  live connection.
- A view releases the store's active key when it unmounts for good, so an
  owner it left running is reclaimed once its work settles.
- Deleting a conversation ends every live connection bound to it, for
  every client.

* feat(acp): adapt to claude-agent-acp 0.101.0

- Pin claude-agent-acp 0.101.0 (Claude Agent SDK 0.3.318, Claude Code
  2.1.318) and record what the release changes for codeg: sessions start
  in Auto, idle compaction, and the config_file_invalid startup refusal.
- Draw the compaction Claude Code runs on its own between turns: the
  transcript watcher holds the boundary and summary until the /compact
  echo shows codeg did not send it, so the live view matches history.
  The compaction card labels the idle trigger in all ten locales.
- Keep local paths in protocol error messages instead of replacing them
  with <local-path>; they are often what the user has to act on.
- docs/cli.md: in Auto, Claude Code decides most actions itself and
  --permissions only answers what it asks; --mode default restores Manual.

* fix(acp): keep Grok uninstalled after codeg removes it

npm 12 blocks install scripts nobody allowed, and codeg allowed none for
Grok, so @xai-official/grok's postinstall never ran. Its launcher then
unpacks the build into ~/.grok/bin on first run without recording
`[cli].installer = "npm"`, and from then on runs whatever
~/.grok/bin/grok is. Once codeg uninstalled the package, that copy read
as Grok's own native install, so Grok still showed as installed, and an
upgrade never reached the binary that runs (1.0.70 kept running after an
upgrade to 1.0.77).

Install Grok with `--ignore-scripts=false --allow-scripts=@xai-official/grok`,
as Hermes already is, so its postinstall moves ~/.grok/bin/grok onto the
new build and records it as npm's. A copy with no record now counts as
npm's when it is laid out as npm leaves it (a link to, or a copy of, a
`grok-<version>` build beside it; Grok's own installers keep their builds
in ~/.grok/downloads), which also covers copies left by earlier installs
and by npm 12 installs made by hand. Hermes' bootstrap hint and runtime
check stay Hermes-only.

* feat(forge): handle several related issues as one task

Issues can be picked across pages and filters (checkboxes, Shift ranges,
select page) and handed to ONE work task; PR/MR combining is not offered.

- New work_task_source_key table (backfilled) holds every item a task
  carries, so dedup, the retry/requeue guards, list chips and
  auto-processing count each issue, not just the lead.
- The prompt has one fenced block per issue; the agent judges each
  report and opens its reply with a verdict per issue.
- The first delivery fixes which issues the pull request closes (one
  Closes line each, the rest Related to); write-back comments on every
  issue.
- Board card, search and task detail list all issues; merged PRs no
  longer offer Start.

* fix(office): allow a coarse file-clock tick before the turn start

Linux and Windows stamp file times from a coarse kernel clock that lags
SystemTime::now() by up to one tick, so a file written right after a
turn started could read as older than the turn and never be confirmed.
Credit file times down to 50 ms before the start, in both the live and
the final check. Also drop the unused `mut` lint on non-Unix in the
written_files test, which failed Windows clippy.

* ci: drop the install script jobs from the Test workflow

Removes the install.sh checks on ubuntu-22.04 and macos-latest and the install.ps1 check in Windows PowerShell 5.1. scripts/test-install-stop.sh stays for running by hand.

* feat(acp): bump Hermes 0.23.0, CodeBuddy 2.181.0, Kimi Code 2.5.2, Qoder 1.1.84

Qoder 1.1.84 turns MCP lazy loading on by default: the model gets
mcp_list/mcp_get/mcp_call instead of the servers' tools, so codeg's
own MCP tools would be reached only through mcp_call while codeg's
cards, auto-allow and history key on the mcp__<server>__<tool> name.
codeg now launches Qoder with --settings '{"mcp":{"lazyLoad":false}}';
every release sampled from 1.1.0 to 1.1.84 accepts the flag.

A Kimi tool card that showed a status (an MCP call reconnecting, an
MCP server's OAuth prompt) kept that status as its title after the
call settled, because Kimi never sends the call's own title again.
The card now shows the status while the call runs and gets its own
title back when it settles.

Hermes 0.23.0 keeps the two regressions 0.22.7 had, still noted as
its known state: config.yaml MCP servers report "not connected" next
to codeg's (upstream #143502), and stopping the conversation whose
viewer started the shared daemon takes the daemon down unless
launchd runs it. The registry notes record what each release was
checked against.

* feat(forge): show an issue's tick box in place of its state icon

Issue rows no longer carry a fixed column of tick boxes. The box shares
the state icon's cell: it replaces the icon while the row is hovered or
the box has keyboard focus, and stays in its place while the issue is
ticked. A box that cannot be ticked (the issue has a task under way)
shows greyed out on hover only. Rows that cannot be picked keep the icon
as before.

* feat(forge): drop the "Select this page" box from the issue list

The list no longer opens with a row that ticks every pickable issue on
the page. Issues are picked one by one or as a Shift range; Esc, the
selection bar and picks kept across pages work as before. The unused
selectPage string is removed from all locales.

* # Release version 0.42.1

This release lets you handle related issues in one task, keeps background work running when you leave a conversation, improves Office previews, and updates multiple agents.

## New

- **Related issues can be selected across pages and handled in one task**, with a single PR or merge request and a choice of which issues it closes when merged.

## Improved

- **Claude Code is updated to 2.1.318 with adapter 0.101.0**, and new sessions default to Auto unless you have selected another permission mode.
- **Claude Code’s idle context compaction appears directly in the conversation**, including its summary, without needing to reopen the session.
- **Updated Hermes Agent to 0.23.0, CodeBuddy to 2.181.0, Grok to 1.0.77, Kimi Code to 2.5.2, Cursor to 2026.11.05-86047df, Qoder to 1.1.84, the ZCode bridge to 0.82.1 and Command Code to 1.88.4.**

## Fixed

- **Closing or switching conversation panes, or refreshing the web page, no longer unexpectedly stops background commands, Remote Control or running sub-agents.**
- **Office auto-preview reliably opens documents created or modified in the current turn**, fixing unrelated templates opening, closed previews reappearing and occasional missed previews on Linux and Windows.
- **Updating Grok through codeg now runs the updated version**, and uninstalling it correctly removes its installed status.
- **Kimi Code retains MCP execution environment and deferred tool-loading settings when codeg saves or syncs its configuration.**
- **Kimi Code tool cards restore their correct titles when calls finish**, instead of continuing to show reconnection or sign-in messages.
- **Qoder 1.1.84 keeps MCP tool cards and history displaying correctly**, while codeg’s built-in tools such as questions continue without unnecessary permission requests.
- **Cursor conversation history includes the new access-management and code-execution tool steps.**
- **The built-in browser no longer covers fullscreen tables or Mermaid diagrams opened from chat.**
- **Agent error messages retain the file paths needed to locate and fix configuration problems.**

## Note

- **Claude Code’s Auto mode may refuse commands when an API gateway cannot support its permission checks**, in which case you can switch to Manual.
- **In Hermes 0.23.0, MCP servers configured in Hermes itself cannot connect when used alongside MCP servers injected by codeg.**
- **On Linux, Windows and some macOS setups, disconnecting the session that started Hermes’ shared background service may interrupt tasks running in other Hermes conversations.**

Thanks to @Time-w (spacering-net#1090), @HOMEFTW (spacering-net#1091) and @monkeyDragonLiu (spacering-net#1096) for the reports.

-----------------------------

# 发布版本 0.42.1

这一版支持将多个相关 Issue 合并为一个任务处理,修复会话页面关闭导致后台任务中断、Office 文档误弹出等问题,并更新多个智能体。

## 新增

- **支持跨页多选相关 Issue 并合并为一个任务处理**,统一交付为 PR 或合并请求,并选择合并后关闭哪些 Issue。

## 改进

- **Claude Code 更新至 2.1.318,适配器更新至 0.101.0**,未指定其他权限模式时,新会话默认使用 Auto 模式。
- **Claude Code 空闲时自动压缩上下文的结果会直接显示在会话中**,无需重新打开即可查看压缩摘要。
- **Hermes Agent 更新至 0.23.0,CodeBuddy 更新至 2.181.0,Grok 更新至 1.0.77,Kimi Code 更新至 2.5.2,Cursor 更新至 2026.11.05-86047df,Qoder 更新至 1.1.84,ZCode 桥接更新至 0.82.1,Command Code 更新至 1.88.4。**

## 修复

- **关闭或切换会话面板、刷新网页时,后台命令、远程控制和正在运行的子智能体不再被意外中断。**
- **Office 自动预览准确识别智能体本轮创建或修改的文档**,修复无关模板误打开、关闭后反复弹出及 Linux、Windows 下偶尔漏开预览的问题。
- **通过 codeg 更新 Grok 后会实际运行新版本**,卸载后也会正确显示为未安装。
- **保存或同步 Kimi Code 的 MCP 配置时,会保留运行环境和工具延迟加载设置。**
- **Kimi Code 工具调用结束后会恢复正确的卡片标题**,不再残留「重连中」或登录授权提示。
- **Qoder 升级至 1.1.84 后,MCP 工具卡片和历史记录仍能正确显示**,codeg 内置提问等工具也不会出现多余的授权请求。
- **Cursor 历史会话能正确显示新增的权限管理和代码执行工具步骤。**
- **打开聊天中的全屏表格或 Mermaid 图表时,内置浏览器页面不再遮挡内容。**
- **智能体错误提示会保留相关文件路径**,方便定位和修复配置问题。

## 注意

- **Claude Code 的 Auto 模式在 API 网关无法支持其权限检查时可能拒绝执行命令**,遇到这种情况可切换至 Manual 模式。
- **Hermes 0.23.0 自身配置的 MCP 服务,在与 codeg 注入的 MCP 服务同时使用时暂时无法连接。**
- **在 Linux、Windows 及部分 macOS 环境中,断开启动 Hermes 共享后台服务的会话,可能中断其他 Hermes 会话正在执行的任务。**

感谢 @Time-w(spacering-net#1090)、@HOMEFTW(spacering-net#1091)和 @monkeyDragonLiu(spacering-net#1096)的问题反馈。

---------

Co-authored-by: xy <[email protected]>
Co-authored-by: CHEN KUN <[email protected]>
Co-authored-by: xintaofei <[email protected]>
Co-authored-by: xintaofei <[email protected]>
Co-authored-by: yyy <[email protected]>
Co-authored-by: Cursor <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] OpenCode model pickers include disabled models

2 participants