Description
EN: When the Agent mode executes a multi-step todo list created in Plan mode, user messages typed mid-turn (pressing Enter) are enqueued into queued_messages but only consumed at TurnComplete — i.e. after all todos have finished. There is no mid-turn intervention path between "wait for everything" (Enter → Queue → TurnComplete) and "nuke the entire turn" (Esc).
CN: Agent 模式执行 Plan 模式梳理的多步 todo 时,用户中途按 Enter 的消息会进入 queued_messages,但只在 Turn 完成(全部 todos 执行完毕)后才被消费。用户缺少"等全部"和"炸掉整个 Turn"之间的中间粒度干预手段。
Steps to reproduce
- EN: In Plan mode, have the assistant produce a
checklist_write with 5 todos.
CN: Plan 模式下让助手生成一个 5 步的 checklist_write。
- EN: Switch to Agent mode, send a message to trigger full-plan execution.
CN: 切到 Agent 模式,发一条消息触发全量执行。
- EN: While the assistant is executing todo
#2, type "skip todo #4, do X instead" in the composer and press Enter.
CN: 助手执行到第 2 步时,在输入框输入 "跳过 todo #4,改为方案 X" 并按 Enter。
- EN: Observe: the message appears in the Pending inputs preview area but is not acted on.
CN: 观察:消息出现在 Pending inputs 预览区,但不会立即生效。
- EN: Wait — the assistant finishes
#3, #4, #5 as originally planned. Only then does the queued message dispatch as a new turn.
CN: 等待 —— 助手按原计划执行完 #3、#4、#5,Turn 结束后排队消息才被 dispatch。
Expected behavior
EN: A mid-turn intervention mechanism with finer granularity than "Esc the whole turn":
- Ability to promote a selected queued message into an immediate steer, or
- A "send now" action in the
PendingInputPreview widget that steers the chosen item into the current turn.
CN: 一个比"Esc 整个 Turn"更细粒度的干预通道:
- 能将选中的排队消息提升为即时 steer 注入当前 Turn,或
PendingInputPreview 中提供逐条"立即发送"的快捷操作。
Actual behavior
EN: decide_submit_disposition() returns Queue uniformly when is_loading = true. The main Turn loop in the engine drains rx_steer (used by Ctrl+Enter) every iteration, but never inspects queued_messages. At TurnComplete, only one message is popped via pop_queued_message() — the rest wait for subsequent turns, which themselves re-enter loading state, perpetuating the backlog.
Key code sites:
crates/tui/src/tui/app.rs:3504-3512 — decide_submit_disposition
crates/tui/src/tui/ui.rs:1024-1025 — end-of-turn consumption (single pop)
crates/tui/src/tui/ui.rs:2291 — Tab also queues, does not steer
crates/tui/src/core/engine/turn_loop.rs:50 — steer channel drained per step, but only via Ctrl+Enter
CN: decide_submit_disposition() 在 is_loading = true 时统一返回 Queue。Engine 层的 Turn 循环每轮都会 drain rx_steer(Ctrl+Enter 专用通道),但从不会检查 queued_messages。TurnComplete 后只 pop_queued_message() 一条,其余继续等待后续 Turn,而这些新 Turn 又会进入 loading 状态,形成排队积压。
关键代码锚点:
crates/tui/src/tui/app.rs:3504-3512 — decide_submit_disposition
crates/tui/src/tui/ui.rs:1024-1025 — TurnComplete 后只弹一条
crates/tui/src/tui/ui.rs:2291 — Tab 也是 queue,非 steer
crates/tui/src/core/engine/turn_loop.rs:50 — steer 通道只在 Ctrl+Enter 时被写入
Environment
- OS: Linux
- DeepSeek CLI version: 0.8.x (current
main)
- Model: deepseek-v4-pro / deepseek-v4-flash
- Shell: bash
Description
EN: When the Agent mode executes a multi-step todo list created in Plan mode, user messages typed mid-turn (pressing Enter) are enqueued into
queued_messagesbut only consumed atTurnComplete— i.e. after all todos have finished. There is no mid-turn intervention path between "wait for everything" (Enter → Queue → TurnComplete) and "nuke the entire turn" (Esc).CN: Agent 模式执行 Plan 模式梳理的多步 todo 时,用户中途按 Enter 的消息会进入
queued_messages,但只在 Turn 完成(全部 todos 执行完毕)后才被消费。用户缺少"等全部"和"炸掉整个 Turn"之间的中间粒度干预手段。Steps to reproduce
checklist_writewith 5 todos.CN: Plan 模式下让助手生成一个 5 步的
checklist_write。CN: 切到 Agent 模式,发一条消息触发全量执行。
#2, type"skip todo #4, do X instead"in the composer and press Enter.CN: 助手执行到第 2 步时,在输入框输入 "跳过 todo
#4,改为方案 X" 并按 Enter。CN: 观察:消息出现在 Pending inputs 预览区,但不会立即生效。
#3, #4, #5as originally planned. Only then does the queued message dispatch as a new turn.CN: 等待 —— 助手按原计划执行完
#3、#4、#5,Turn 结束后排队消息才被 dispatch。Expected behavior
EN: A mid-turn intervention mechanism with finer granularity than "Esc the whole turn":
PendingInputPreviewwidget that steers the chosen item into the current turn.CN: 一个比"Esc 整个 Turn"更细粒度的干预通道:
PendingInputPreview中提供逐条"立即发送"的快捷操作。Actual behavior
EN:
decide_submit_disposition()returnsQueueuniformly whenis_loading = true. The main Turn loop in the engine drainsrx_steer(used by Ctrl+Enter) every iteration, but never inspectsqueued_messages. AtTurnComplete, only one message is popped viapop_queued_message()— the rest wait for subsequent turns, which themselves re-enter loading state, perpetuating the backlog.Key code sites:
crates/tui/src/tui/app.rs:3504-3512—decide_submit_dispositioncrates/tui/src/tui/ui.rs:1024-1025— end-of-turn consumption (single pop)crates/tui/src/tui/ui.rs:2291— Tab also queues, does not steercrates/tui/src/core/engine/turn_loop.rs:50— steer channel drained per step, but only via Ctrl+EnterCN:
decide_submit_disposition()在is_loading = true时统一返回Queue。Engine 层的 Turn 循环每轮都会 drainrx_steer(Ctrl+Enter 专用通道),但从不会检查queued_messages。TurnComplete后只pop_queued_message()一条,其余继续等待后续 Turn,而这些新 Turn 又会进入 loading 状态,形成排队积压。关键代码锚点:
crates/tui/src/tui/app.rs:3504-3512—decide_submit_dispositioncrates/tui/src/tui/ui.rs:1024-1025— TurnComplete 后只弹一条crates/tui/src/tui/ui.rs:2291— Tab 也是 queue,非 steercrates/tui/src/core/engine/turn_loop.rs:50— steer 通道只在 Ctrl+Enter 时被写入Environment
main)