zai-org / zai-org/feedback

[Bug] v3.8.1: Thought-level changes silently discarded after first selection (stale_runtime_refresh_ignored) + reasoning_effort never sent for custom OpenAI-compatible providers

Open
#339 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

priority: P2 status: 待评估 type: Bug
Dominant language
No language data
Stars
22
Forks
1
PR merge metrics
No merged PRs in 30d

Description

提交前确认 · Pre-submission checklist
  • 我已搜索过现有 issue,确认这不是重复 / I searched existing issues and confirmed this isn't a duplicate.
  • 我已阅读 CONTRIBUTING.md / I've read CONTRIBUTING.md.
问题类别 · Category

模型设置 / 切换 · Model config

涉及的 Agent 框架 · Agent framework

ZCode Agent(自研)

严重程度 · Severity

阻塞使用 · Blocking (无法使用核心功能 / core function unusable)

复现频率 · Reproducibility

必现 · Always

问题描述 · Description

Custom OpenAI-compatible models (stealth/ox-alpha via OpenRouter, x-preview-f-free via opencode zen, qwen/qwen3.8-max-free via tokenrouter) configured with reasoning levels (provider.<id>.models.<model>.reasoning + modelCatalog.overrides) show a Thought-Level selector, but it never controls actual requests.

Bug A — level changes silently discarded after the first selection.
First selection in a session applies (previousThoughtLevel: null). Every later change logs session.reasoning_effort.updated but the runtime keeps the old value and the dropdown reverts. Host log shows the cause — 13 occurrences today, blocking BOTH directions:

warn zcode_protocol.session_thought.stale_runtime_refresh_ignored
"Ignored stale session runtime thought refresh"
{"currentThought":"high","incomingThought":"max"}

A retry loop repeats the same pair every few minutes without converging; later selections log a stale previousThoughtLevel pinned to an old value — two state layers permanently diverged.

Bug B — reasoning_effort never reaches the wire.
Even in fresh chats with Max explicitly selected (host logs confirm runtimeModel carries thoughtLevel:"max"), outgoing request bodies never contain reasoning_effort. Verified via model-I/O capture: 0 of 265 requests in one day contained the parameter, across all sessions/models/config paths tried (v2 config, ~/.zcode/cli/config.json, legacy provider options).

Bug C — model selection never persists. Every new session creation logs session.model_selection.persist_failed {"error":"FOREIGN KEY constraint failed"} (77× today) → last-used model/level is never remembered.

Related: #306, #223, #319, #202.

复现步骤 · Steps to reproduce
  1. Add a custom OpenAI-compatible provider/model with reasoning variants + modelCatalog.overrides (see attached config-redacted.txt)
  2. Create a new chat with that model, select Thought Level = Max → applies correctly (first selection)
  3. Send one message
  4. Switch Max→High→Low→Max repeatedly → dropdown keeps reverting to High, Max never sticks again
  5. Inspect outgoing request bodies (model-I/O logs) → no reasoning_effort parameter at any point
期望表现 · Expected behavior

A selected Thought Level must always apply to the session runtime, and every subsequent chat-completions request must carry reasoning_effort: .

实际表现 · Actual behavior

Only the first selection per session takes effect. Afterwards all changes are discarded by zcode_protocol.session_thought.stale_runtime_refresh_ignored (13x/day), the UI reverts to the old level, and 0 of 265 captured outgoing requests contained reasoning_effort — even though the host log confirms thoughtLevel:"max" was applied. Additionally, session.model_selection.persist_failed ("FOREIGN KEY constraint failed") fires on every session creation (77x/day).

ZCode 版本 · ZCode version

v3.8.1 (3.8.1.5310)

设备 / 系统 / 浏览器 · Device / OS / Browser

Windows 10 x64 (build 26100) · ZCode Desktop

截图 / 录屏 / 日志 · Screenshots / Recordings / Logs

Attached:

  • 🎥 Screen recording: fresh-chat Max selection OK → after first message, repeated changes revert
  • 📄 zcode-2026-08-21-bug-evidence.txt — filtered log, 564 events, PII redacted:
    195× reasoning_effort.updated · 78× persist_failed(FOREIGN KEY) ·
    13× stale_runtime_refresh_ignored · 3× thought_unavailable-on-resume
  • 📄 config-redacted.txt — exact repro config, all credentials redacted

Key lines from the log:

warn zcode_protocol.session_thought.stale_runtime_refresh_ignored
"Ignored stale session runtime thought refresh"
{"currentThought":"high","incomingThought":"max"}   ← same pair retried ~every 5 min, never converges

warn session.model_selection.persist_failed
{"error":"FOREIGN KEY constraint failed"}

log.zip
https://github.com/user-attachments/assets/d39c9bf6-78a3-480c-b50e-13f254079490

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the attached config-redacted.txt and reproduce the selection sequence while reviewing zcode_protocol.session_thought.stale_runtime_refresh_ignored and session.model_selection.persist_failed in the supplied logs. Use model-I/O capture to verify the selected level reaches every request and determine whether model selection persists without the reported foreign-key error; done means all level changes stick, reasoning_effort is sent, and persistence succeeds.

Written by the indexing model from the issue text.

Assessment

Domain
api, backend, database, desktop
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.