Skip to content

[建议 / Feature] 排队消息一多,队列面板无限增高把主对话顶出视野;且「立即」按钮等待前台执行停止期间无任何反馈(v3.14.x 桌面版) #863

Description

@DOIT-Ben

排队消息一多,队列面板无限增高把主对话顶出视野;且「立即」按钮响应要等整个前台执行真正停下(v3.14.x 桌面版)

摘要

任务执行中连续输入多条消息后,队列面板(ConversationQueuePanel)会随着条目数一直往上长,没有高度上限也没有滚动,把上面的对话内容整片推出视口。用户看不到自己在等的是什么回复,只能看到一列排队消息。

同时,点击某条的「立即」按钮(sendQueuedNow)后,界面长时间没有反馈。看代码后确认:这个动作会先中止当前前台执行并轮询等待其真正释放(preemptActiveTurnAndWait → waitForSessionIdle),前台执行越重等得越久,而按钮本身没有任何 loading 态。

两个问题叠在一起:队列越长面板越高,越看不清主对话;而想让某条快点发,又得等很久且没有任何进度提示。

环境

  • ZCode 桌面版 v3.14.x(Windows 11,x64)
  • 复现时使用默认 follow-up 模式(Queue)
  • 源码核对于公开仓库 zai-org/ZCode(默认分支 main)

问题一:队列面板无高度上限,遮挡主对话

现象

在主对话里连续排队 8~12 条消息(截图里就是这种情况),队列面板会占掉大半个窗口高度,主对话被挤到看不见。

源码定位

packages/ui/src/v4/ConversationQueuePanel.tsx:328-331,容器类名:

className={cn(
  "relative z-0 w-full overflow-hidden rounded-t-2xl border border-border bg-surface p-1 backdrop-blur-md",
  "-mb-7 pb-7",
)}

条目列表在 ConversationQueuePanel.tsx:371:

<ul className="space-y-0.5">

整个面板只有 overflow-hidden,没有任何 max-h-*,<ul> 也没有 overflow-y-auto。因此条目数量直接决定面板高度,条目越多面板越高,把 timeline 往上顶。

期望行为

队列面板应该有高度上限并内部滚动,例如:

  • 给容器加 max-h-[40vh](或按可用空间计算),<ul> 加 overflow-y-auto;
  • 或者超过 N 条后折叠成「还有 N 条排队」的可展开摘要,默认只显示前 2~3 条;
  • 无论多少条,主对话至少要保留可见区域。

截图里 12 条排队时,面板高度已经超过半屏。这类场景在长任务里很常见(用户想到什么就补一条),不是边缘情况。

问题二:「立即」按钮要等整个前台执行停下,且无加载态

现象

点「立即」后,按钮没有 loading、没有禁用态、没有任何反馈,要过一段时间才生效。前台执行越重(例如正在跑前台子智能体),等待越明显。

源码定位

UI 侧 packages/ui/src/v4/SessionPane.tsx:3226-3242,handleSendQueuedNow 只做了一次 focusTimelineToLatest() 然后 dispatchCommand("sendQueuedNow", ...),没有设置任何 pending/loading 状态:

const handleSendQueuedNow = useCallback(
  (queueItemId: string) => {
    const current = snapshotRef.current;
    if (!sessionId || current === null) return;
    focusTimelineToLatest();
    void dispatchCommand("sendQueuedNow", { queueItemId }, sessionId, current.revision).then(...);
  },
  [dispatchCommand, focusTimelineToLatest, sessionId],
);

而按钮本身在 ConversationQueuePanel.tsx:214-234 也没有 busy 态,只有 disabled={rowLocked}(仅编辑中的那一行会锁)。

后端这条路径是「先停再发」:apps/zcode-cli/packages/bootstrap/src/zcode-protocol-v4/commands/handlers/session-flow.ts:410-438 的 preemptActiveTurnAndWait 会调用 stopActiveForegroundExecution,然后 await waitForSessionIdle(record)。该轮询函数在 session-flow.ts:396-407:

async function waitForSessionIdle(record: V4SessionRecordView): Promise<void> {
  const deadline = Date.now() + IDLE_POLL_TIMEOUT_MS;
  while (
    record.activeAbortController !== undefined ||
    record.app.runtime?.getActiveForegroundExecutionId?.() !== undefined
  ) {
    if (Date.now() >= deadline) {
      throw new V4SessionIdleTimeoutError(record.app.sessionId);
    }
    await new Promise((resolve) => setTimeout(resolve, IDLE_POLL_INTERVAL_MS));
  }
}

其中 IDLE_POLL_INTERVAL_MS = 25、IDLE_POLL_TIMEOUT_MS = 5_000(session-flow.ts:23-24)。也就是说前台执行释放得慢时,用户要一直等到它真正 idle,界面上却什么提示都没有。

相关但不重复:#772 讨论的是这个按钮的语义(它会中止前台执行、取消前台子智能体,标签写 Steer 有误导)。本 issue 说的是交互反馈:等待期间 UI 完全没有状态提示。两者可以分别修。

期望行为

  1. 点击后按钮立即进入 pending 态(转圈 / 禁用 / 文案改成「正在切换…」),让用户知道点到了;
  2. 等待期间能看出「正在停止当前任务」这一步,而不是静默卡住;
  3. 如果最终超时(V4SessionIdleTimeoutError),要在界面上明确报错,不能只写日志。

复现步骤

  1. 让 agent 跑一个耗时较长、带前台子智能体的任务(不要用 run_in_background)。
  2. 在任务执行中连续输入 8~12 条消息并回车,让它们进入队列。
  3. 观察:队列面板持续增高,主对话被顶出可视区域。
  4. 点击任意一条的「立即」。

实际结果:面板高度随条目数线性增长并遮挡主对话;「立即」点击后长时间无任何视觉反馈。

期望结果:面板有高度上限、内部可滚动(或折叠),主对话始终可见;「立即」点击后立刻有 pending 反馈,等待停止的过程可见,超时有明确报错。

影响

  • 长任务里「一边看输出一边补需求」是主要用法,队列面板遮住主对话会直接让人失去上下文,只能反复滚动;
  • 「立即」无反馈会让人以为没点上而重复点击,而每次点击都会触发一次前台执行中止流程。

补充

如果维护者认为「面板加 max-height + 内部滚动」是最小改动,我可以按 zai-org/ZCode 的贡献流程提 PR(需要确认目标文件与测试约定)。上面的行号基于 main 分支当前内容,如已变动请以实际为准。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions