feat(core): remind the model of the active output style every turn - #10282
feat(core): remind the model of the active output style every turn#10282qqqys wants to merge 21 commits into
Conversation
Every non-default output style now sends its turn reminder as a <system-reminder> on each user and cron turn, next to the date, plan-mode and arena reminders. The headless-Learning gate moves into a shared resolveEffectiveOutputStyle() so the prompt and the reminder can never disagree about which style is active. Reminder text is escaped before it is wrapped, so a file-supplied turnReminder cannot close the block. Claude-Session: https://claude.ai/code/session_01Gk1gryVzWuW58zkBtoBvnM
Hand-written Config mocks that never set a style (client-goal.test.ts) should not need the interaction-mode accessors, and the default path should not pay for a mode lookup it does not use. Claude-Session: https://claude.ai/code/session_01Gk1gryVzWuW58zkBtoBvnM
|
|
|
Re-run after the autofix rounds and a base update — gate re-confirmed at the new head.
Moving on to code review. 🔍 中文说明autofix 多轮及 base 更新后的重跑——准入结论不变,在新 head 上重新确认。
进入代码审查。🔍 — Qwen Code · qwen3.8-max Reviewed at |
Code reviewNo blockers. What I verified reading the diff at the reviewed commit:
Test evidence — the PR's own CI (unattended run; nothing executed locally)At the previous head (
Unattended CI run, so no local tmux drive-through. There is also nothing user-visible to drive yet — no surface can select a style on this commit — so real-scenario coverage starts mattering once the selection-surface slice lands. A sandboxed Final CI results for
One row per check name (latest run); skipped checks omitted; failures sort first. / 每个检查名一行(取最新一次运行),省略 skipped,失败项排在最前。 中文说明代码审查无阻塞项。在受审 commit 上逐行核对:
测试证据——来自 PR 自己的 CI(无人值守运行,本地不执行任何代码)上一个 head(
无人值守 CI 运行,故无本地 tmux 实测;且本 commit 上尚无用户可见面(没有任何入口可选风格),真实场景覆盖将在选择入口切片落地后才有意义。本 PR 已有一个沙箱 (上方 CI 表格由 finalize 工作流在 CI 结束后原地更新。) — Qwen Code · qwen3.8-max Reviewed at |
|
Confidence: 4/5 — a clean, minimal slice that does exactly what the merged design said the next piece would; the points kept back are the unrelated test-hygiene drive-by (justified, harmless) and the inherent fact that the reminder cannot be observed against a live model until a selection surface exists. Stepping back over the whole picture: the motivation is real — style drift over long sessions is a documented failure mode, and Claude Code shipped this exact fix — and the implementation is the smallest structure that keeps the prompt and the per-turn reminder honest with each other. The negative case is pinned too: with no style selectable today, the outgoing request is byte-identical, and there are tests asserting exactly that. The 24-case "reminds iff the prompt carries the section" matrix is the test I would have asked for. Every one of the 110 production lines is doing a job; if I had to maintain this in six months I'd thank the author, not curse them. Verdict: approve. CI is still in flight at the reviewed commit (unit suite running, web-shell E2E Smoke not yet started), so approval is deferred until CI lands green on 中文说明信心:4/5——干净、最小的切片,恰好实现了已合并设计预留的下一块;扣掉的一分来自无关的测试卫生顺手改动(有正当理由、无害),以及一个固有事实:选择入口落地前,无法在真实模型上观察该提醒。 整体回顾:动机真实——长会话中的风格漂移是已被记录失效模式,Claude Code 也上线过完全相同的修复;实现是讓提示词与每轮提醒互相约束的最小结构。反面情形同样被钉死:今天没有任何入口可选风格,发出的请求逐字节不变,且有测试专门断言这一点。24 例"提醒当且仅当提示词携带风格段落"矩阵正是我会要求的测试。110 行生产代码各司其职;六个月后维护它,只会感谢作者。 结论:批准。受审 commit 上 CI 仍在进行(单元测试运行中,web-shell E2E Smoke 尚未开始),因此批准推迟到该 commit 的 CI 全部变绿;若有检查变红或 head 移动,将不批准并在状态评论中说明。上一个 head 上变红的 web-shell E2E Smoke 更像 runner 或合入 main 的噪声而非本 diff(证据见 Stage 2 评论)——本次 commit 的重跑会给出定论。 — Qwen Code · qwen3.8-max Reviewed at |
|
@qwen-code /takeover |
|
🤝 Takeover engaged: the autofix loop now manages this PR — it will address new review feedback and resolve base conflicts until the label is removed or the round cap is reached. This is a fork PR, so the first round comes from the next scheduled scan (usually within minutes). Remove the 中文说明🤝 已接管:autofix 循环现在管理此 PR —— 将持续处理新的评审反馈与 base 冲突,直到移除标签或达到轮次上限。本 PR 来自 fork,首轮处理将由下一次定时扫描执行(通常几分钟内)。移除 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship — CI landed green after the review. ✅
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Reviewed. Suggestions are inline.
Not explored to full depth (tool budget reached): "agent 1d": none — the walk completed within budget (6 tool calls)..
Test Plan (not a blocker): src/core/output-styles.test.ts — no such file or directory; src/core/prompts.test.ts — no such file or directory; src/core/client.test.ts — no such file or directory; 500 tests pass — this review observed 22043, 1770, 25160, 1667, 605, 4331, 639 passed.
中文说明
已审查。 建议见行内评论。
未探索到全部深度(达到工具调用预算):"agent 1d":none — the walk completed within budget (6 tool calls).。
Test Plan(非阻断):src/core/output-styles.test.ts — no such file or directory; src/core/prompts.test.ts — no such file or directory; src/core/client.test.ts — no such file or directory; 500 tests pass — this review observed 22043, 1770, 25160, 1667, 605, 4331, 639 passed。
— qwen3.8-max via Qwen Code /review (v0.22.2)
A custom systemPrompt routes through getCustomSystemPrompt() and a QWEN_SYSTEM_MD override replaces the base prompt verbatim — neither carries an output-style section, yet the per-turn reminder still fired for them. Gate the reminder on the same decision that puts the style section into the prompt: a shared isSystemMdActive() in prompts.ts, consulted by getCoreSystemPrompt() and the reminder site alike, plus the existing getSystemPrompt() override check. Also route the reminder envelope through the centralized wrapSystemReminder() instead of a third inline copy, and pin the intended cron-turn inclusion with a test.
A fixed /tmp/qwen-code-test-root breaks whenever a prior run by another user (e.g. a sandboxed root run on a shared runner) leaves the directory behind: mkdirSync(recursive) no-ops on the foreign directory and every write into it EACCESes. Reproduced the 80 deterministic-gate failures locally with a stale root-owned directory present; mkdtempSync isolates each run from any leftover state.
|
🤖 Addressed the latest review feedback (round 1/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 1/100 轮)。改动内容与我反驳保留之处如下: Review feedback addressed — PR #10282 (round 3, same-run verification repair)The previous commit Deterministic rejection — diagnosis and fixEvidence chain:
Local reproduction (exact gate failure): at the pre-round HEAD ( Fix (minimal, test-only): the suite now gets a unique per-run root — Footprint note: the fix touches Inline findings (re-verified resolved in the preserved commit b31d8fe)All three findings were fixed in code by the previous round's commit, which this round keeps intact; each was re-verified against current HEAD:
All witnesses are green in this round's focused run (651 passed across the five touched test files). Mutation probes
Verification
中文说明已处理的评审反馈 — PR #10282(第 3 轮,同轮验证修复)上一个提交 确定性拒绝项 — 诊断与修复证据链:
本地复现(与门禁失败完全一致): 在第 2 轮提交( 修复(最小化,仅测试): 套件现在使用每次运行唯一的根目录 —— 足迹说明: 本修复改动了 行内发现(已在保留的提交 b31d8fe 中解决并复核)三条发现均已在上一轮的提交中从代码上修复,本轮完整保留该提交,并逐条对照当前 HEAD 复核:
所有见证测试在本轮聚焦运行中为绿(五个改动的测试文件共 651 个通过)。 变异探针
验证
Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 Re-review when you have a moment. After round 100 this bot stops and leaves the PR for a human. · 有空请复审;第 100 轮后本 bot 停止并将 PR 交给人工。 🧠 Handled by Qwen Code · model/模型 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Reviewed. Suggestions are inline.
Test Plan (not a blocker): src/core/output-styles.test.ts — no such file or directory; src/core/prompts.test.ts — no such file or directory; src/core/client.test.ts — no such file or directory; 500 tests pass — this review observed 22047, 1770, 25164, 1667, 605, 4331, 639 passed.
中文说明
已审查。 建议见行内评论。
Test Plan(非阻断):src/core/output-styles.test.ts — no such file or directory; src/core/prompts.test.ts — no such file or directory; src/core/client.test.ts — no such file or directory; 500 tests pass — this review observed 22047, 1770, 25164, 1667, 605, 4331, 639 passed。
— qwen3.8-max via Qwen Code /review (v0.22.2)
…s.ts Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
|
🤖 Addressed the latest review feedback (round 2/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 2/100 轮)。改动内容与我反驳保留之处如下: Review response — PR #10282 (round: newer than 2026-08-27T13:15:23Z)Commit: Feedback points and decisions[rc:3873558153] R1-1 (Suggestion, fix-induced): the reminder gate centralises only halfway — Implemented. The finding is correct: the round-1 gate in Changes:
[rv:5042992550] Review body (COMMENTED): no action beyond the inline finding. The Test Plan note ( Failed checks: all CANCELLED (workflow run cancelled, not real failures). No local action; CI re-runs after the push. Mutation probes (each applied, focused suite run, then restored)
After each restore the focused suite returned to green (49 passed). Note: Diff growthThis round: source +39/−92 (net −53 in client.ts/prompts.ts production code), tests +172/−25 — the round is net-subtractive on source. Window remains far under budget. VerificationCommands actually run and their results:
中文说明审查回应 — PR #10282(本轮:2026-08-27T13:15:23Z 之后的新反馈)提交: 反馈点与处理决定[rc:3873558153] R1-1(Suggestion,修复引入):提醒门禁只做了一半的集中化 —— 已实现。 该发现是对的:第 1 轮在 改动内容:
[rv:5042992550] 审查正文(COMMENTED):除行内发现外无需处理。 其中 Test Plan 备注( 失败的检查:全部为 CANCELLED(工作流运行被取消,并非真实失败)。本地无需处理;推送后 CI 会重跑。 变异探针(逐一应用、运行聚焦套件、再还原)
每次还原后聚焦套件恢复绿色(49 通过)。 说明: 差异增长本轮:源码 +39/−92(生产代码净 −53),测试 +172/−25 —— 本轮在源码上是净缩减的。窗口总量仍远低于预算。 验证实际运行的命令及结果:
Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 Re-review when you have a moment. After round 100 this bot stops and leaves the PR for a human. · 有空请复审;第 100 轮后本 bot 停止并将 PR 交给人工。 🧠 Handled by Qwen Code · model/模型 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed. Suggestions are inline.
Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.
Test Plan (not a blocker): src/core/output-styles.test.ts — no such file or directory; src/core/prompts.test.ts — no such file or directory; src/core/client.test.ts — no such file or directory; 500 tests pass — this review observed 22083, 1770, 25150, 1667, 605, 4331, 639 passed.
Convergence: round 3 posted 2 inline comment(s), 2 of them reported for the first time; the previous round posted 1 (1 new). The rate of new findings is not falling. Batching the remaining fixes and verifying them before the next push, or dropping this PR's reviews to --severity-floor critical, keeps the loop from re-deriving the same set. No Critical finding is open on this round, so merging and moving the remaining Suggestion threads to a follow-up issue is available as an ending — a merged pull request cannot diverge further. (Observation only — nothing was withheld from this review because of this observation.)
中文说明
仅完成部分审查,审查缺口已披露。 建议见行内评论。
未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。
Test Plan(非阻断):src/core/output-styles.test.ts — no such file or directory; src/core/prompts.test.ts — no such file or directory; src/core/client.test.ts — no such file or directory; 500 tests pass — this review observed 22083, 1770, 25150, 1667, 605, 4331, 639 passed。
收敛情况:第 3 轮发布了 2 条行内评论,其中 2 条是首次提出;上一轮发布了 1 条(其中 1 条首次提出)。新发现的产出速度没有下降。把剩余修复攒成一批、验证后再推送,或将本 PR 的评审降到 --severity-floor critical,可以避免循环反复推导同一组发现。本轮没有未决的 Critical,因此"合入后把剩余 Suggestion 线程转到后续 issue"是一个可选的结束方式——已合入的 PR 不会继续发散。(仅为观察——本轮评审未因此扣留任何内容。)
— qwen3.8-max via Qwen Code /review (v0.22.2)
…rding The prompts.test.ts matrix only asserted that a custom systemPrompt override appears in the rendered prompt, never that it replaces the default base — and the config.getModel() forwarding in getMainSessionBaseSystemPrompt had no witness after the client-side assertions moved to the prompt layer. Both mutants (layering the override on the base; dropping the model forward) shipped green in a scratch probe. Add the replacement assertion and an end-to-end coder-model case; each now kills its mutant. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
|
🤖 Addressed the latest review feedback (round 3/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 3/100 轮)。改动内容与我反驳保留之处如下: Autofix review round — PR #10282 (round addressing feedback at head
|
| Probe | Target | Pre-fix result | Post-fix result |
|---|---|---|---|
A: override branch → getCoreSystemPrompt(overrideSystemPrompt, config.getModel()) |
R3-1 pin | suite green (148/148) — missing pin confirmed | 9 failed | 140 passed (exactly the custom=yes / systemMd=off rows) |
B: config.getModel() → undefined |
R3-3 pin | 172/172 green across prompts/prompt-tool-examples/client-goal | 1 failed | 148 passed (exactly the new forwarding test) |
Both mutants were reverted after each probe; the final committed tree is green.
Verification
All commands actually run this round, in order:
- Baseline
npx vitest run src/core/prompts.test.ts(packages/core) — 148 passed (pre-fix baseline) - Mutant A vs pre-fix suite — 148 passed (reproduced missing pin), rendered-prompt probe confirmed default identity survives
- Mutant B vs pre-fix suite (
prompts.test.ts+prompt-tool-examples.test.ts+client-goal.test.ts) — 172 passed (reproduced missing pin) npx vitest run src/core/prompts.test.tswith fixes — 149 passed- Mutant A vs fixed suite — 9 failed | 140 passed (witness kills the mutant); mutant reverted
- Mutant B vs fixed suite — 1 failed | 148 passed (witness kills the mutant); mutant reverted
npx vitest run src/core/prompts.test.ts src/core/client.test.ts src/core/client-goal.test.ts src/core/output-styles.test.ts src/tools/write-file.test.ts(packages/core) — 646 passed (5 files)npm run build— passednpm run typecheck— passednpm run lint— passed
Integration tests were not run: the round is test-only and the touched behavior is fully exercised by the unit suite. No settings source changed, so npm run generate:settings-schema was not required.
中文说明
Autofix 审查轮次 — PR #10282(针对 head b2dc15bbf5 上的反馈)
无 --conflict(false):未合并 origin/main。本轮没有未决的 Critical;两个可操作项均为自动审查器的 Suggestion,关于早前某轮把覆盖从 client.test.ts 迁移到 prompts.test.ts 时丢失的测试钉子。两者都先通过变异探测复现,然后才实施修复,目前均已在代码中解决。
反馈点及处置
[rc:3875343795] R3-1 — Suggestion — 已解决。 prompts.test.ts 中的矩阵('reminds if and only if the prompt carries the style section')只断言了自定义 systemPrompt 覆盖会出现在渲染出的提示词中(toContain(customPrompt)),从未断言它替换了默认基础提示词——因此 client.test.ts 中那句 "Routing the override to the custom base is pinned by prompts.test.ts" 注释夸大了实际覆盖。
- 复现(修复前):把
getMainSessionBaseSystemPrompt变异为叠加覆盖而非替换(getCoreSystemPrompt(overrideSystemPrompt, config.getModel()))——套件仍全绿(148/148);直接探测渲染结果得到CONTAINS_DEFAULT_IDENTITY=true、FIRST_120="You are Qwen Code, an interactive CLI agent developed by Alibaba Group, specializing in software engineering tasks. Your",证实该回归下--system-prompt用户会在自己的覆盖之上悄悄收到默认身份提示词。 - 修复:在矩阵的
customPrompt分支中加入expect(prompt).not.toContain('You are Qwen Code');,参照已有的QWEN_SYSTEM_IDENTITY_MD用例。加上该断言后,同一变异恰好让九个custom=yes / systemMd=off矩阵行变红(9 failed | 140 passed);恢复后的代码保持 149/149 全绿。client.test.ts中的注释照原文即成立,因此无需修改注释。
[rc:3875343803] R3-3 — Suggestion — 已解决。 迁移后的 getMainSessionBaseSystemPrompt 中 config.getModel() 的转发失去了唯一的测试钉子(toHaveBeenCalledWith(undefined, 'test-model', ...) 断言被删除);矩阵里的 getModel: () => 'test-model' 无法区分差异,因为 'test-model' 不会选中任何提示词变体。
- 复现(修复前):把转发变异为
undefined——prompts.test.ts+prompt-tool-examples.test.ts+client-goal.test.ts仍全绿(172/172),因此一行回归就会让 coder/vl 模型在没有任何测试失败的情况下收到通用的 tool-call 示例。 - 修复:在同一 describe 块新增
it('forwards the config model to the base prompt')——令配置的getModel()返回'qwen3-coder-7b',端到端经过getMainSessionBaseSystemPrompt演练,断言渲染结果包含 coder XML 标记'<function=run_shell_command>'。加上该用例后,同一变异恰好让该测试失败(1 failed | 148 passed,共 149);恢复后的代码保持全绿。
审查正文披露(rv:5045067304,仅信息性——无需行动): 被跳过的 "Integration Tests (CLI, No Sandbox)" CI 任务与测试计划路径不匹配属于审查工具自身的披露,不是发现项;本轮只改了一个单元测试文件,下面的聚焦 Vitest 运行已完全覆盖。关于收敛的观察(无未决 Critical;建议攒批修复)与本轮做法一致——剩余的两个 Suggestion 已在同一提交中全部解决。
变更内容
packages/core/src/core/prompts.test.ts(+12 行,纯测试):在既有矩阵中加入一条"替换"断言,外加一个新的端到端模型转发用例。无源码改动、无注释改动,未触碰其他任何内容。
变异探测记录(见证验证)
| 探测 | 目标 | 修复前结果 | 修复后结果 |
|---|---|---|---|
A:覆盖分支 → getCoreSystemPrompt(overrideSystemPrompt, config.getModel()) |
R3-1 钉子 | 套件全绿(148/148)——确认缺钉子 | 9 failed | 140 passed(恰好是 custom=yes / systemMd=off 各行) |
B:config.getModel() → undefined |
R3-3 钉子 | prompts/prompt-tool-examples/client-goal 共 172/172 全绿 | 1 failed | 148 passed(恰好是新的转发测试) |
两个变异在每次探测后均已还原;最终提交的代码树为全绿。
验证
本轮实际依次执行的命令:
- 基线
npx vitest run src/core/prompts.test.ts(packages/core)— 148 通过(修复前基线) - 变异 A 对修复前套件 — 148 通过(复现缺失的钉子),渲染探测确认默认身份仍然存在
- 变异 B 对修复前套件(
prompts.test.ts+prompt-tool-examples.test.ts+client-goal.test.ts)— 172 通过(复现缺失的钉子) npx vitest run src/core/prompts.test.ts(含修复)— 149 通过- 变异 A 对修复后套件 — 9 failed | 140 passed(见证杀死该变异);变异已还原
- 变异 B 对修复后套件 — 1 failed | 148 passed(见证杀死该变异);变异已还原
npx vitest run src/core/prompts.test.ts src/core/client.test.ts src/core/client-goal.test.ts src/core/output-styles.test.ts src/tools/write-file.test.ts(packages/core)— 646 通过(5 个文件)npm run build— 通过npm run typecheck— 通过npm run lint— 通过
未运行集成测试:本轮为纯测试改动,涉及行为已由单元测试套件完全覆盖。未改动任何 settings 源,因此不需要 npm run generate:settings-schema。
Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。
Re-review when you have a moment. After round 100 this bot stops and leaves the PR for a human. · 有空请复审;第 100 轮后本 bot 停止并将 PR 交给人工。
🧠 Handled by Qwen Code · model/模型 qwen3.8-max
|
Qwen Code review did not complete successfully. The review pipeline failed before a review could be posted. A transient error is retried automatically; if you are seeing this, retry with |
|
🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下: Autofix round: no changes neededFeedback newer than the last evaluation (2026-08-28T13:17:45Z) contains no actionable request, so this round makes no code changes and no commit.
No verification commands were run because nothing was changed. 中文说明Autofix 轮次:无需修改上次评估(2026-08-28T13:17:45Z)之后的反馈中没有任何可执行的修改请求,因此本轮不做任何代码修改,也不提交任何提交。
本轮未运行任何验证命令,因为没有任何改动。 Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 🧠 Handled by Qwen Code · model/模型 |
The ACP session assembles its own per-turn reminders because it calls the chat directly and bypasses LlmClient.sendMessageStream; the style reminder was missing from that list, so an ACP prompt carried the style section but never the nudge. It now reads the same resolveMainSessionOutputStyle() decision as the prompt, so a custom system prompt or QWEN_SYSTEM_MD keeps it silent there as well. Also pins that Retry, Notification and Teammate turns carry no style reminder. Claude-Session: https://claude.ai/code/session_01Gk1gryVzWuW58zkBtoBvnM
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.
Test Plan (not a blocker): src/core/output-styles.test.ts — no such file or directory; src/core/prompts.test.ts — no such file or directory; src/core/client.test.ts — no such file or directory; 500 tests pass — this review observed 22164, 1794, 1690, 605, 4443, 639 passed.
Deferred under the convergence posture (round 11, not a blocker) — recorded, not requested in this round:
packages/cli/src/acp-integration/session/Session.ts:10395 — [probe] ACP notification turns get the style reminder; LlmClient excludes Notification turnspackages/cli/src/acp-integration/session/Session.ts:10395 — [review] Style-reminder assembly duplicated between client.ts and Session.tspackages/cli/src/acp-integration/session/Session.ts:10395 — [probe] Outer getOutputStyle?.() pre-guard duplicates the resolver's no-style decisionpackages/cli/src/acp-integration/session/Session.ts:10392 — [review] #buildInitialSystemReminders doc comment not updated for the new branchpackages/cli/src/acp-integration/session/Session.test.ts:4087 — [probe] 'every ACP prompt' test sends one prompt; per-turn repetition unpinned on ACPpackages/cli/src/acp-integration/session/Session.ts:10395 — [probe] CLI --continue resume surface gets no style reminder; ACP continuations now do
中文说明
未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。
Test Plan(非阻断):src/core/output-styles.test.ts — no such file or directory; src/core/prompts.test.ts — no such file or directory; src/core/client.test.ts — no such file or directory; 500 tests pass — this review observed 22164, 1794, 1690, 605, 4443, 639 passed。
收敛姿态下延后(第 11 轮,非阻断)——已记录,本轮不要求修改:共 6 条(原文未翻译,列表见上方英文部分)。
— qwen3.8-max via Qwen Code /review (v0.22.3)
|
🔀 Base updated: red check(s) [Test (ubuntu-latest, Node 22.x)] pass on current main — merged current main via update-branch; CI will re-run. 中文说明🔀 已更新 base:红色检查 [Test (ubuntu-latest, Node 22.x)] 在当前 main 上通过 —— 已通过 update-branch 合入当前 main,CI 将重新运行。 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed.
3 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:
- Style-reminder assembly duplicated between client.ts and Session.ts, incl. the outer getOutputStyle?.() pre-guard — already reported (round 11 deferred list, review 5057521972)
- ACP notification turns get the style reminder; LlmClient excludes Notification turns — already reported (round 11 deferred list, review 5057521972)
- QWEN_SYSTEM_MD resolved twice in getCoreSystemPrompt — already reported (round 9 deferred list, review 5054124083)
Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.
Test Plan (not a blocker): src/core/output-styles.test.ts — no such file or directory; src/core/prompts.test.ts — no such file or directory; src/core/client.test.ts — no such file or directory; 500 tests pass — this review observed 22289, 1795, 1699, 605, 4590, 642 passed.
中文说明
仅完成部分审查,审查缺口已披露。
本轮确认的 3 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。
未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。
Test Plan(非阻断):src/core/output-styles.test.ts — no such file or directory; src/core/prompts.test.ts — no such file or directory; src/core/client.test.ts — no such file or directory; 500 tests pass — this review observed 22289, 1795, 1699, 605, 4590, 642 passed。
— qwen3.8-max via Qwen Code /review (v0.22.3)
|
🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下: Autofix round: no changes neededFeedback newer than the last evaluation (2026-08-28T21:48:03Z) contains no actionable request, so this round makes no code changes and no commit.
Verification (read-only round, HEAD 2834eef)
中文说明Autofix 轮次:无需修改上次评估(2026-08-28T21:48:03Z)之后的反馈中没有任何可执行的修改请求,因此本轮不做任何代码修改,也不产生任何提交。
验证(只读轮次,HEAD 2834eef)
Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。
🧠 Handled by Qwen Code · model/模型 |
|
🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下: Autofix review round — no code changes (PR #10282)No review bodies, inline comments, or issue-level comments newer than the last evaluation were present. The only feedback this round is two failed checks in the SDK Java workflow (run
Disposition: no code change — failures are not attributable to this PREvidence trail (all verified against the reviewed head
Why no speculative fixThis runner has no Java/Maven toolchain and no GitHub credentials, so the job logs cannot be fetched and Suggested next stepRerun the two failed jobs (the repo's Diagnostics performed (read-only)
中文说明Autofix 评审轮次 — 无代码改动(PR #10282)自上次评估以来,没有新的 review body、行内评论或 issue 级评论。本轮唯一的反馈是 SDK Java 工作流(run
处置:不做代码改动 — 失败与本 PR 无关证据链(均基于被评审的 head
为什么不做推测性修复本 runner 没有 Java/Maven 工具链,也没有 GitHub 凭据,因此无法拉取 job 日志,也无法在本地复现 建议的下一步重新运行这两个失败的 job(仓库的 已执行的诊断(只读)
Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 🧠 Handled by Qwen Code · model/模型 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed.
4 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:
- R13-1 ACP background-notification turns get the style reminder while LlmClient excludes Notification turns — already reported (round 11 deferred list 'ACP notification turns get the style reminder; LlmClient excludes Notification turns', re…
- R13-2 Style-reminder assembly duplicated between client.ts and Session.ts — already reported (round 11 deferred list 'Style-reminder assembly duplicated between client.ts and Session.ts', review 5057521972)
- R13-3 Headless twin buildInitialSystemReminders lacks the style reminder (continueInterrupted re-injection loses it) — already reported (round 11 deferred list 'CLI --continue resume surface gets no style reminder; ACP continuations now do'…
- R13-4 Redundant outer getOutputStyle?.() pre-guard on the ACP mirror — already reported (round 11 deferred list 'Outer getOutputStyle?.() pre-guard duplicates the resolver's no-style decision', review 5057521972)
Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.
Not explored to full depth (tool budget reached): "agent 6c": running the recommended core/cli vitest suites to confirm the new tests pass — node_modules and dist are not installed in this worktree, and npm ci + npm run….
Test Plan (not a blocker): src/core/output-styles.test.ts — no such file or directory; src/core/prompts.test.ts — no such file or directory; src/core/client.test.ts — no such file or directory.
中文说明
仅完成部分审查,审查缺口已披露。
本轮确认的 4 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。
未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。
未探索到全部深度(达到工具调用预算):"agent 6c":running the recommended core/cli vitest suites to confirm the new tests pass — node_modules and dist are not installed in this worktree, and npm ci + npm run…。
Test Plan(非阻断):src/core/output-styles.test.ts — no such file or directory; src/core/prompts.test.ts — no such file or directory; src/core/client.test.ts — no such file or directory。
— qwen3.8-max via Qwen Code /review (v0.22.3)
|
🔀 Base updated: red check(s) [Test (ubuntu-latest, Node 22.x)] pass on current main — merged current main via update-branch; CI will re-run. 中文说明🔀 已更新 base:红色检查 [Test (ubuntu-latest, Node 22.x)] 在当前 main 上通过 —— 已通过 update-branch 合入当前 main,CI 将重新运行。 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed.
5 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:
- R13-1 ACP background-notification turns get the style reminder while LlmClient excludes Notification turns — already reported (round 11 deferred list 'ACP notification turns get the style reminder; LlmClient excludes Notification turns', re…
- R13-2 Style-reminder assembly duplicated between client.ts and Session.ts — already reported (round 11 deferred list 'Style-reminder assembly duplicated between client.ts and Session.ts', review 5057521972)
- R13-3 Headless twin buildInitialSystemReminders lacks the style reminder (continueInterrupted re-injection loses it) — already reported (round 11 deferred list 'CLI --continue resume surface gets no style reminder; ACP continuations now do'…
- ACP cron-fired and background-notification reminder paths lack tests — already reported (round 8 deferred list 'No ACP-mode test for the reminder injection gate', review 5053261510)
- Arena agents carry the style section but never receive the per-turn reminder — already reported (round 5 deferred list 'Style reminder never reaches ACP, arena, or forked sessions', review 5048374377)
Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.
Not explored to full depth (tool budget reached): "agent 4": none — no check was cut short.; "agent 1a": none — no check was cut short..
Test Plan (not a blocker): src/core/output-styles.test.ts — no such file or directory; src/core/prompts.test.ts — no such file or directory; src/core/client.test.ts — no such file or directory; 500 tests pass — this review observed 22469, 1795, 1699, 605, 4604, 642 passed.
中文说明
仅完成部分审查,审查缺口已披露。
本轮确认的 5 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。
未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。
未探索到全部深度(达到工具调用预算):"agent 4":none — no check was cut short.;"agent 1a":none — no check was cut short.。
Test Plan(非阻断):src/core/output-styles.test.ts — no such file or directory; src/core/prompts.test.ts — no such file or directory; src/core/client.test.ts — no such file or directory; 500 tests pass — this review observed 22469, 1795, 1699, 605, 4604, 642 passed。
— qwen3.8-max via Qwen Code /review (v0.22.3)
|
🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下: Autofix review round: no changes neededI reviewed the latest feedback on this PR and no code change is warranted this round. Point by point: The two new review passes posted zero new findingsBoth review comments in this batch (
These are already tracked from earlier rounds and intentionally deferred rather than expanded into this PR, consistent with the minimal-diff guidance for this window. No outstanding inline or issue-level commentsThere are no inline review comments and no issue-level comments in this batch. Every prior inline finding (R1-1 through R4-1) already has an "Addressed in …" reply from earlier rounds, and no review on this PR is in a The listed "failed" checks are CANCELLED, not failing
No changes were made this round. 中文说明Autofix 审查轮次:无需改动我已审阅本 PR 的最新反馈,本轮无需进行任何代码改动。逐点说明如下: 两次新的审查均未提出任何新发现本批次的两条审查评论(
这些条目已在更早轮次中被记录在案,并被有意延期处理,而非并入本 PR 扩大范围——这与本窗口期“保持最小 diff”的指导意见一致。 没有未处理的行内评论或议题级评论本批次中没有行内审查评论,也没有议题级评论。此前的每一条行内发现(R1-1 到 R4-1)在更早轮次中都已有 “Addressed in …”(已在……中处理)的回复,且本 PR 上没有任何审查处于 被列为“失败”的检查实为 CANCELLED(已取消),并非真正失败
本轮未做任何改动。 Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 🧠 Handled by Qwen Code · model/模型 |
Independent verification — real environment, wire captureI verified this PR locally against a real bundled CLI ( Trees under test — base Verdict: the PR does what it says, and the no-op claim is exact. Two behaviours worth a maintainer's eye before merge are at the bottom; both are already on the deferred list, and I'm attaching measurements rather than asking for new work. 1. The bug it fixes, and the no-op claim
2. Behaviour matrix — 17/17 rows match the PR's descriptionEvery row is a separate run of the real CLI. The invariant the PR is built around — remind if and only if the prompt carries the section — held in all of them, including the ones the unit tests don't cover:
3. Escaping holds for the whole rendered lineA hostile 4. Do the new tests actually hold this down? 10/10 mutants killedI reverted each decision in the diff one at a time. No survivors — including the two that matter most: swapping Suites on the merged tree: The 5. Two measurements for the record (not merge blockers)a) Over ACP, a background-task-notification turn gets the reminder; in
b) The reminder repeats every turn and every copy stays in the transcript, so turn N ships N copies. The Risk section reads as a flat "+25 tokens per turn"; measured, the incremental cost is flat (144 chars ≈ 35 tokens with the envelope) but the request grows, so the cumulative cost over a session is quadratic. This is not new and not this PR's doing — c) Nit, forward-looking: RecommendationApprove on behaviour. The core claim — reminder if and only if section, byte-identical for every session that exists today, cached prefix untouched — is confirmed on the wire across 17 configurations and three entry points (headless, ACP, ACP-cron), and the test suite has no blind spot I could find in 10 mutants. Item (a) is the only one I'd want a decision recorded on before the selection surface makes any of this reachable. 中文说明独立验证 —— 真实环境、链路抓包我在本地用真实打包产物(从合并树构建的 被测树 —— base 结论:这个 PR 做到了它说的事,而且「空操作」这一条是精确成立的。 底部有两条值得维护者过目的行为特征,二者都已在延期清单上,我只是补上测量数据,并非要求新工作。 1. 它修的那个 bug,以及空操作这一条
2. 行为矩阵 —— 17/17 行与 PR 描述一致每一行都是真实 CLI 的一次独立运行。本 PR 所围绕的不变式 —— 当且仅当提示词带该段落时才提醒 —— 在全部行中成立,包括单测未覆盖的那些:
3. 转义对整行渲染结果都成立恶意的 4. 新测试真的把行为钉住了吗?10/10 变异体全部被杀我逐一回退 diff 中的每个决策。无存活变异体 —— 包括最关键的两个:把 合并树上的套件:
5. 两条记录在案的测量(非合并阻塞项)a) ACP 下后台任务通知轮会收到提醒,而
b) 提醒逐轮重复,且每份都留在 transcript 里,因此第 N 轮会发出 N 份。 风险一节读起来像是「每轮固定 +25 token」;实测下来,增量成本是固定的(144 字符 ≈ 含标签约 35 token),但请求本身在变大,所以整个会话的累计成本是平方级的。这不是新问题,也不是本 PR 造成的 —— 在同一套装置上, c) 前瞻性小项: 建议行为层面建议通过。 核心主张 —— 当且仅当有段落才提醒、对今天存在的每一个会话逐字节无变化、缓存前缀不受影响 —— 在 17 种配置、三个入口(headless、ACP、ACP-cron)上于链路层面得到确认,且我用 10 个变异体没能找出测试盲区。(a) 是唯一一条我希望在选择入口让这些变得可达之前先把决策记录下来的。 |
…LM#10282) Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
|
🤖 Addressed the latest review feedback (round 5/100). What changed, and what I pushed back on: · 已处理最新评审反馈(第 5/100 轮)。改动内容与我反驳保留之处如下: Autofix review round — same-run verification repair (PR #10282)The deterministic gate rejected the previous commit Diagnosis (evidence, not a guess)
Change (this round, one commit)Per-file timeout budgets mirroring the house pattern (
A config-level fix ( Mutation probes (both branches witnessed)
Feedback dispositions (only feedback this window: [ic:5468448060])@wenshao's independent wire-capture verification — verdict "Approve on behaviour":
No inline review comments exist this window, so there are no resolved threads and no reply entries. Remaining risk (honest note)This round hardens exactly the three files the gate rejected, but pool-wide contention can still flake a different suite in a future full-suite gate run; the strategic fix (config-level ecs budgets for the whole suite) is in flight on Conflict notes
VerificationCommands actually run this round:
中文说明Autofix 审查轮 —— 同轮验证修复(PR #10282)确定性门禁拒绝了上一个提交 诊断(基于证据,而非猜测)
改动(本轮,单个提交)逐文件设置超时预算,沿用仓库既有模式(
配置层修复( 变异探针(两个分支都有见证)
反馈处置(本窗口唯一反馈:[ic:5468448060])@wenshao 的独立链路抓包验证 —— 结论「行为层面建议通过」:
本窗口没有行内评审评论,因此没有可解析的线程,也没有回复条目。 遗留风险(如实说明)本轮只加固了门禁拒绝的那三个文件;在池级争用下,未来某次全量门禁运行仍可能让其他套件偶发失败。战略性修复(整个套件层面的配置级 ecs 预算)在 冲突说明
验证本轮实际运行的命令:
Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 Re-review when you have a moment. After round 100 this bot stops and leaves the PR for a human. · 有空请复审;第 100 轮后本 bot 停止并将 PR 交给人工。 🧠 Handled by Qwen Code · model/模型 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally; this round's local test phase also did not start (budget exhausted during install+build, no suite executed).
Test Plan (not a blocker): src/core/output-styles.test.ts — no such file or directory; src/core/prompts.test.ts — no such file or directory; src/core/client.test.ts — no such file or directory.
Deferred under the convergence posture (round 15, not a blocker) — recorded, not requested in this round:
packages/cli/src/commands/update.test.ts:76 (+2 locations) — [review] ecs-qwen timeout block pasted into three test files
中文说明
未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally; this round's local test phase also did not start (budget exhausted during install+build, no suite executed)。
Test Plan(非阻断):src/core/output-styles.test.ts — no such file or directory; src/core/prompts.test.ts — no such file or directory; src/core/client.test.ts — no such file or directory。
收敛姿态下延后(第 15 轮,非阻断)——已记录,本轮不要求修改:共 1 条(原文未翻译,列表见上方英文部分)。
— qwen3.8-max via Qwen Code /review (v0.22.3)
🩺 serve daemon A/BBuilt the PR base vs this PR head ✅ No response changes against the PR base across 12 scenario(s). — Qwen Code · serve A/B |
|
🔀 Base updated: red check(s) [Test (ubuntu-latest, Node 22.x)] pass on current main — merged current main via update-branch; CI will re-run. 中文说明🔀 已更新 base:红色检查 [Test (ubuntu-latest, Node 22.x)] 在当前 main 上通过 —— 已通过 update-branch 合入当前 main,CI 将重新运行。 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed.
3 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:
- R16-1 ACP background-notification turns get the style reminder while LlmClient excludes Notification turns — already reported (round 11 deferred list 'ACP notification turns get the style reminder; LlmClient excludes Notification turns', re…
- R16-3 Headless twin buildInitialSystemReminders lacks the style reminder (continueInterrupted re-injection loses it) — already reported (round 11 deferred list 'CLI --continue resume surface gets no style reminder; ACP continuations now do'…
- R16-5 ecs-qwen timeout block pasted into three test files — already reported (round 15 deferred list, review 5061206621)
Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.
Not reviewed: build-and-test — full packages/cli and packages/core unit suites timed out under shared-runner contention (diff-touched files: 1,453 tests passed); test-efficacy probe inconclusive.
Not explored to full depth (tool budget reached): "agent 1c": exhaustively verifying every test suite that drives LlmClient.sendMessageStream with a partial mock config has all five getters the resolver now calls (527 ca….
Test Plan (not a blocker): src/core/output-styles.test.ts — no such file or directory; src/core/prompts.test.ts — no such file or directory; src/core/client.test.ts — no such file or directory.
中文说明
仅完成部分审查,审查缺口已披露。
本轮确认的 3 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。
未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。
未审查:build-and-test — full packages/cli and packages/core unit suites timed out under shared-runner contention (diff-touched files: 1,453 tests passed); test-efficacy probe inconclusive。
未探索到全部深度(达到工具调用预算):"agent 1c":exhaustively verifying every test suite that drives LlmClient.sendMessageStream with a partial mock config has all five getters the resolver now calls (527 ca…。
Test Plan(非阻断):src/core/output-styles.test.ts — no such file or directory; src/core/prompts.test.ts — no such file or directory; src/core/client.test.ts — no such file or directory。
— qwen3.8-max via Qwen Code /review (v0.22.3)
|
🔀 Base updated: red check(s) [web-shell E2E Smoke (ubuntu-latest, Node 22.x)] pass on current main — merged current main via update-branch; CI will re-run. 中文说明🔀 已更新 base:红色检查 [web-shell E2E Smoke (ubuntu-latest, Node 22.x)] 在当前 main 上通过 —— 已通过 update-branch 合入当前 main,CI 将重新运行。 |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Partially reviewed — gaps disclosed.
4 Suggestion-level finding(s) this review confirmed are already reported on this PR and are not repeated:
- R17-1 ACP background-notification turns get the style reminder while LlmClient excludes Notification turns — already reported (round 11 deferred list 'ACP notification turns get the style reminder; LlmClient excludes Notification turns', re…
- R17-2 Redundant outer getOutputStyle?.() pre-guard on the ACP mirror — already reported (round 11 deferred list 'Outer getOutputStyle?.() pre-guard duplicates the resolver's no-style decision', review 5057521972; re-carried as R13-4)
- R17-3 Style-reminder assembly duplicated between client.ts and Session.ts — already reported (round 11 deferred list 'Style-reminder assembly duplicated between client.ts and Session.ts', review 5057521972; re-carried as R13-2)
- R17-5 ecs-qwen timeout block pasted into three test files — already reported (round 15 deferred list 'ecs-qwen timeout block pasted into three test files', review 5061206621; re-carried as R16-5)
Not reviewed: build-and-test — the test phase never ran under the build-test harness (install + 15 workspace builds consumed the per-call budget; the packages/cli build also hit its time budget); test-efficacy probe inconclusive with an unvalidated harness.
Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.
Test Plan (not a blocker): src/core/output-styles.test.ts — no such file or directory; src/core/prompts.test.ts — no such file or directory; src/core/client.test.ts — no such file or directory.
Deferred under the convergence posture (round 17, not a blocker) — recorded, not requested in this round:
packages/cli/src/acp-integration/session/Session.ts:10676 — [review] ACP reminder gate lacks a QWEN_SYSTEM_MD test at this call site
中文说明
仅完成部分审查,审查缺口已披露。
本轮确认的 4 条建议级发现已在 PR 上报告过,不再重复发布(列表见上方英文部分)。
未审查:build-and-test — the test phase never ran under the build-test harness (install + 15 workspace builds consumed the per-call budget; the packages/cli build also hit its time budget); test-efficacy probe inconclusive with an unvalidated harness。
未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。
Test Plan(非阻断):src/core/output-styles.test.ts — no such file or directory; src/core/prompts.test.ts — no such file or directory; src/core/client.test.ts — no such file or directory。
收敛姿态下延后(第 17 轮,非阻断)——已记录,本轮不要求修改:共 1 条(原文未翻译,列表见上方英文部分)。
— qwen3.8-max via Qwen Code /review (v0.22.3)
|
🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下: Autofix round: no action taken (PR #10282)Mode: Critical-only mode is active (5 change-producing rounds complete). The actionable sections this round contain no findings — Reviews, Inline comments, and Issue-level comments are all empty. The deferred non-Critical feedback section is an audit record only and was not treated as work. No code changes were made and nothing was committed. Failed checks — diagnosed as job-level timeouts on the shared ECS pool, not code failures: The three checks listed as failed all concluded
Supporting evidence:
Why no fix was attempted: a 中文说明Autofix 轮次:未采取任何行动(PR #10282)模式: 当前处于仅处理 Critical 的模式(已完成 5 个产生改动的轮次)。本轮可执行区域中没有任何发现 —— Reviews、Inline comments 和 Issue-level comments 均为空。被延后的非 Critical 反馈部分仅作为审计记录,不作为本轮工作处理。本轮未做任何代码改动,也没有提交任何内容。 失败检查 —— 经诊断为共享 ECS 资源池上的作业级超时,而非代码失败: 三个被列为失败的检查结论均为
佐证:
为何未尝试修复: 超时导致的 Deferred non-Critical feedbackCritical-only mode is active: 5 change-producing rounds are complete. The workflow excluded the non-Critical feedback below from this round's actionable sections; the items remain open for human follow-up. Maintainer feedback is deferred only after its author has used 2 regular feedback batches in this window's Critical-only tail; authors at that budget, if any, are named below. (
中文说明已进入仅处理 Critical 的模式:已完成 5 个产生改动的轮次。本轮可执行区域已排除下方非 Critical 反馈;这些条目保持开放,留待人工跟进。维护者反馈仅在其本人于本窗口 Critical-only 阶段已使用 2 批常规反馈预算后才会延后;达到预算的作者(如有)在下方点名。(评论 Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 🧠 Handled by Qwen Code · model/模型 |






What this PR does
This injects the per-turn output-style reminder that #9565 rendered but never sent. Whenever a non-default output style is active, every user turn (and every cron-fired turn) now carries a
<system-reminder>line of the formConcise output style is active. Be concise: answer first, cut the narration, keep only what the user needs.— the style's ownturnReminderwhen it defines one, otherwise the genericRemember to follow the specific guidelines for this style.The line joins the existing system-reminder block that already carries the date, plan-mode, and arena reminders, so it sits immediately ahead of the newest user text; tool-result turns are untouched, since the reminder only needs to travel with a fresh user message.The rule that drops the Learning style from headless runs — its hand-off asks the user to write code and waits, which a single-turn run can never answer — moves out of
getCoreSystemPromptinto a sharedresolveEffectiveOutputStyle()that both the prompt builder and the reminder consult. That keeps the two in step by construction: a session is never reminded about a style its system prompt does not actually carry. The prompt builder's behaviour is unchanged; the existing headless-Learning tests inprompts.test.tspass as they were.The reminder text goes through
escapeSystemReminderTags()before being wrapped, so a style whose reminder contains a stray</system-reminder>cannot break out of its block. That matters once user- and project-level style files load in a follow-up, because a custom style'sturnReminderwill be file-supplied text.Why it's needed
A style lives in the cached system prompt, and the model drifts back to the default voice over a long conversation — an Explanatory session quietly stops explaining, a Concise one starts narrating again. A short reminder that travels with each new user message is what keeps the style in force for the whole session, and it is the last piece of the core layer that #9565 deliberately left for a separate PR: that PR pinned where the style sits in the prompt, this one pins how it is kept alive turn to turn. Both are still unreachable by users until the selection surfaces land, so this stays a no-op for every existing session; it is the second of the slices that lead up to that surface.
Attaching the reminder as a per-turn message rather than re-stating it in the system prompt is also what keeps the cached prompt prefix stable — the style section is written once, and the nudge rides in the volatile part of the request where it costs a few tokens instead of a cache miss.
Reviewer Test Plan
How to verify
From
packages/core, runnpx vitest run src/core/output-styles.test.ts src/core/prompts.test.ts src/core/client.test.ts— 500 tests pass, 10 of them new. Theoutput style turn reminderblock inclient.test.tsis the one to read: it asserts the exact reminder string on two consecutive user turns, the generic wording for a style without its ownturnReminder, that nothing is added when no style is active, that aToolResultturn carries no reminder, that Learning is skipped in a headless session and present onceisInteractive()is true, and that a reminder containing</system-reminder>is escaped so exactly one closing tag remains.output-styles.test.tscoversresolveEffectiveOutputStyle()across all three interaction modes.Also worth confirming the negative: with
getOutputStyle()returningundefined— every real session today — the request sent to the model is byte-identical to before. The date-reminder and IDE-context tests that assert the full request array are unchanged and still pass.npm run typecheck --workspace @qwen-code/qwen-code-core,eslint, andprettier --checkwere run over every changed file.Evidence (Before & After)
N/A — no user-visible surface; nothing selects a style yet, so no session's request changes on this commit alone.
Tested on
Environment (optional)
Linux, Node 22, unit tests only.
Risk & Scope
--output-styleflag,/output-stylecommand, custom.qwen/output-styles/*.mdfiles, and theoutput_stylefield onsystem/initfollow in separate PRs. Whether a reminder is also wanted onSteer/Retry/Notificationturns can be decided once a style is selectable and observed.resolveEffectiveOutputStyle()is a new export;getCoreSystemPromptkeeps its signature and output.Linked Issues
Follows #9565.
中文说明
这个 PR 做了什么
本 PR 注入了 #9565 已渲染但从未发送的每轮 output-style 提醒。只要有非默认的输出风格生效,每个用户轮(以及每个 cron 触发的轮次)现在都会携带一行
<system-reminder>,形如Concise output style is active. Be concise: answer first, cut the narration, keep only what the user needs.—— 风格定义了turnReminder时用它自己的文案,否则用通用的Remember to follow the specific guidelines for this style.。这一行加入到已经承载日期、plan-mode 和 arena 提醒的那个 system-reminder 块中,因此紧挨着最新的用户文本;工具结果轮不受影响,因为提醒只需要跟随新的用户消息一起发送。把 Learning 风格从 headless 运行中剔除的规则 —— 它的交接会请用户写代码然后等待,而单轮运行永远无法回应 —— 从
getCoreSystemPrompt移入一个共享的resolveEffectiveOutputStyle(),提示词构建器和提醒两处共同查询它。这样二者在构造上就保持一致:一个会话绝不会被提醒一个其系统提示词实际并不携带的风格。提示词构建器的行为没有变化;prompts.test.ts中已有的 headless-Learning 测试原样通过。提醒文本在被包裹之前会经过
escapeSystemReminderTags(),因此一个提醒里含有多余</system-reminder>的风格无法逃出它的块。这一点在后续 PR 加载用户级和项目级风格文件后会很重要,因为自定义风格的turnReminder将是来自文件的文本。为什么需要它
风格存在于被缓存的系统提示词中,而模型在长对话里会漂回默认语气 —— Explanatory 会话悄悄不再解释,Concise 会话又开始叙述过程。一条随每条新用户消息一起发送的简短提醒,正是让风格在整个会话中持续生效的手段,也是 #9565 刻意留给单独 PR 的 core 层最后一块:那个 PR 钉死了风格在提示词中的位置,这个 PR 钉死它如何逐轮保持有效。在选择入口落地之前,二者对用户仍不可达,所以对所有既有会话这仍是空操作;这是通向那个入口的第二个切片。
把提醒作为每轮消息附加、而不是在系统提示词里重复声明,也是保持缓存前缀稳定的关键 —— 风格段落只写一次,提醒则在请求的易变部分中传递,代价是几个 token 而不是一次缓存失效。
评审者测试计划
如何验证
在
packages/core下运行npx vitest run src/core/output-styles.test.ts src/core/prompts.test.ts src/core/client.test.ts—— 500 个测试通过,其中 10 个是新增的。值得阅读的是client.test.ts中的output style turn reminder块:它断言连续两个用户轮上精确的提醒字符串、没有自带turnReminder的风格使用通用文案、没有风格生效时不添加任何内容、ToolResult轮不携带提醒、headless 会话中跳过 Learning 而isInteractive()为 true 后出现、以及含有</system-reminder>的提醒被转义后恰好只剩一个闭合标签。output-styles.test.ts覆盖了resolveEffectiveOutputStyle()在三种交互模式下的行为。同样值得确认反面情况:当
getOutputStyle()返回undefined时 —— 也就是今天的每一个真实会话 —— 发送给模型的请求与之前逐字节一致。断言完整请求数组的日期提醒和 IDE 上下文测试没有改动且仍然通过。对每个改动文件运行了
npm run typecheck --workspace @qwen-code/qwen-code-core、eslint和prettier --check。证据(Before & After)
N/A —— 没有用户可见界面;目前没有任何东西选中风格,所以仅凭这个 commit 任何会话的请求都不会变化。
测试环境
环境(可选)
Linux,Node 22,仅单元测试。
风险与影响范围
--output-style参数、/output-style命令、自定义.qwen/output-styles/*.md文件,以及system/init上的output_style字段会在各自的后续 PR 中落地。是否也要在Steer/Retry/Notification轮上提醒,可以在风格可选并被观察之后再决定。resolveEffectiveOutputStyle()是新增导出;getCoreSystemPrompt的签名和输出保持不变。关联 Issue
承接 #9565。