Skip to content

Pending inputs not consumed until all todos complete in Agent mode — no mid-turn intervention granularity #874

@douglarek

Description

@douglarek

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

  1. EN: In Plan mode, have the assistant produce a checklist_write with 5 todos.
    CN: Plan 模式下让助手生成一个 5 步的 checklist_write
  2. EN: Switch to Agent mode, send a message to trigger full-plan execution.
    CN: 切到 Agent 模式,发一条消息触发全量执行。
  3. 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。
  4. EN: Observe: the message appears in the Pending inputs preview area but is not acted on.
    CN: 观察:消息出现在 Pending inputs 预览区,但不会立即生效。
  5. 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-3512decide_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_messagesTurnComplete 后只 pop_queued_message() 一条,其余继续等待后续 Turn,而这些新 Turn 又会进入 loading 状态,形成排队积压。

关键代码锚点:

  • crates/tui/src/tui/app.rs:3504-3512decide_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

Metadata

Metadata

Assignees

No one assigned

    Labels

    v0.8.61Targeted for CodeWhale v0.8.61v0.8.69Targeting v0.8.69

    Projects

    Status
    Backlog

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions