fix(tui): AI 输出中排队消息不再自动注入,输入框贴底(排队语义 + 渲染顺序) - #40
Closed
yq04 wants to merge 2 commits into
Closed
Conversation
问题:AI 输出期间提交的普通消息显示「⏳ 已排队」却在下一个工具边界被
onSteerDrain 无过滤 drain 成 [User guidance] 注入给 AI——界面文案与真实
行为矛盾(界面撒谎)。
修复(对齐 kimi-cli/codex:普通消息只入队,turn 结束后交还用户):
- onSteerDrain 改为 drain('next'):仅注入紧急意图(halt=now / redirect=next,
steer 特性保留);普通消息(later 级)留在队列
- notifyRunSettled:run 自然结束(isFinal)时队列残留回填输入框,用户再次
Enter 才发送(复用 backfillSteerToInput);守护中断(watchdog/convergence)
经 guardianAbortPending 标志区分,不回填(保留自动续跑流程)
- 新增 steer-queue-confirm.test.ts:4 条契约测试(不注入/紧急注入保留/
结束回填/回填后 Enter 提交),修复前 1/3/4 RED
回归:user-commit-paths / abort-interrupt-ux / abort-resubmit /
slash-passthrough / queue-lane 全部通过(38/38),typecheck app.ts 无新增错误。
问题:renderLive chrome 段中,输入框(topBorder+inputLines+botBorder)渲染在 中游,其后仍有图片摘要/状态行(metrics+权限模式)/@file 诊断/上下文提示/ slash 提示/文件补全——滚动到底时屏幕最底行是状态行,输入框极限位置不在 界面最下方(与 Claude Code 的输入框贴底惯例不符)。 修复:调整 chrome 段渲染顺序——全部辅助行移到输入框上方,输入框成为 live region 最后一行。reservedTail/chromeStart 计算不变(行数不变仅顺序变)。 新增 input-bottom-line.test.ts:2 条契约测试(botBorder 为最后一行 / 状态行 在输入框上方),修复前 RED(实测 botBorder 后仍有状态行)。 回归:fixed-viewport / live-engine-ghost-render / live-engine / input-* / steer-queue-confirm 全部通过(133/133),typecheck app.ts 无错误。
Owner
|
已回合 dev 主线(cherry-pick 保留作者署名): 验证:typecheck 通过;新增 6 条契约全绿(steer-queue-confirm 4 + input-bottom-line 2);TUI 域 2213 测试 2212 过 / 0 失败(1 为既有 todo 占位)。 内容将随下次 sync 进入公开仓 main。感谢贡献——根因分析(kimi-cli/codex 对照)与 RED→GREEN 测试基线都很扎实。 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
修复 TUI 端的两个交互问题:
问题 1:排队消息在工具边界被自动注入
复现
AI 输出过程中发送普通消息 → 界面显示
⏳ 已排队: "..."→ 下一个工具回合消息以[User guidance]格式注入给 AI,AI 立即执行。用户以为消息在排队,实际已发出。根因
src/tui/engine/app.ts中onSteerDrain回调无优先级过滤地 drain 整个 steer 队列:AI 输出期间每个工具回合都会触发该回调,把普通消息格式化为
[User guidance — 用户新指令...]注入给正在运行的 AI。代码注释自己承认「此时仍显示已排队是界面在撒谎」。修复
对齐 kimi-cli / codex 的共识(普通消息在 AI 输出期间只入队,turn 结束后才处理):
onSteerDrain改为drain('next'):只注入紧急意图(halt=now /redirect=next,即用户主动喊停/改方向,steer 特性保留);普通消息(guidance/question/augment/ack → later 级)留在队列notifyRunSettled在 run 自然结束(isFinal)时把队列残留回填输入框(复用既有backfillSteerToInput机制),提示「⏮ 已把 N 条排队消息拉回输入框」,由用户再次按 Enter 确认后发送guardianAbortPending标志区分,不回填、不打断续跑流程参考实现
_queued_messages,注释明确「messages waiting to be sent after the turn ends」;turn 结束后 drain 作为新 turn 发送;Ctrl+S 才是显式立即注入maybe_send_next_queued_input()自动发送问题 2:输入框不在界面最下方
复现
界面滚动到底时,屏幕最底行是状态行(metrics + 权限模式),输入框在其上方——输入框的极限位置不在屏幕最下方(与 Claude Code 的输入框贴底惯例不符)。
根因
renderLive的 chrome 段中,输入框(topBorder + inputLines + botBorder)渲染在中游,其后仍渲染图片摘要、状态行(formatPermissionModeLinemetrics + 权限模式)、@file 诊断、上下文提示、slash 提示、文件补全候选。修复
调整 chrome 段渲染顺序:全部辅助行移到输入框上方,输入框成为 live region 最后一行。
reservedTail/chromeStart计算不变(行数不变,仅顺序变化),不影响定高视口逻辑。测试
新增
src/tui/engine/__tests__/steer-queue-confirm.test.ts(4 条契约):onSteerDrain返回[User guidance...]注入文本、队列被清空)src/tui/engine/__tests__/input-bottom-line.test.ts(2 条契约):test ⚡- 0s ... ⏵ auto-safe)回归
user-commit-paths/abort-interrupt-ux/abort-resubmit/slash-passthrough/queue-lane:38/38 通过(含「守护中断 settle 不回填」既有契约)fixed-viewport/live-engine-ghost-render/live-engine/input-*/ 新增测试:133/133 通过approval-key工作区路径判定,Windows 环境问题,在原始上游 HEAD 同样复现)app.ts零错误(src/server/__tests__/session-search.test.ts的 8 个 TS2322 为预存在错误,与本次改动无关)变更文件
src/tui/engine/app.ts(onSteerDrain 优先级过滤 + notifyRunSettled 自然结束回填 + chrome 段顺序调整)src/tui/engine/__tests__/steer-queue-confirm.test.ts(新增)src/tui/engine/__tests__/input-bottom-line.test.ts(新增)验证建议(本地)
真实终端交互:
npm start后 AI 输出中发送消息 → 应看到「⏳ 已排队」且 AI 不被打断;回合结束后消息回填输入框,按 Enter 才发送。滚动到底时输入框应贴屏幕最底部。