lh agent run stream completion ignores waiting_for_human and reports “Agent finished”

这个报错通常出现在用 LobeChat CLI( lh agent run )以非 JSON 文本模式跑 Agent,且运行过程中服务端下发 agent_runtime_end 且 data.reason 为 waiting_for_human (等待人工审批/回答)时:CLI 仍然打印 ✓ Age

快速结论:这个报错通常出现在用 LobeChat CLI(lh agent run)以非 JSON 文本模式跑 Agent,且运行过程中服务端下发 agent_runtime_end 且 data.reason 为 waiting_for_human(等待人工审批/回答)时:CLI 仍然打印 ✓ Agent finished,并以正常状态退出,让调用方误以为运行已成功完成。优先排查 CLI 的流结束事件(SSE/WebSocket)处理逻辑是否会透传并区分结束原因。

适用环境:Issue 为源码级发现,未提供完整的端到端运行环境(未给出操作系统、Python、CUDA、显卡、依赖版本等)。已确认涉及的工具为 LobeChat CLI(apps/cli/src/utils/agentStream.ts、apps/cli/src/commands/agent.ts)、服务端 AgentRuntimeCoordinator 与 STREAM_END_STATUSES,以及 SSE / WebSocket 两种流通道。

最快修复方案:升级到已包含 #20389 的版本。该修复让结束原因映射为不同结果与退出码:done → ✓ Agent finished,退出码 0;waiting_for_human → ⏸ Agent paused: waiting for human approval — approve or answer it in LobeHub, the CLI does not wait for it,退出码 2;error → ✗ Agent failed: …,退出码 1;interrupted → ■ Agent interrupted,退出码 1。文本模式与 --json 模式一致。

注意事项:该修复只解决 CLI 端“结束原因与退出状态未区分”的问题;waiting_for_human 时 CLI 并不会继续等待人工审批,仍需在 LobeHub 侧完成审批或回答。Issue 中提到的轮询回退(polling fallback)的退出状态与缺失结果文案属于配套后续项,不在本次修复范围内。

问题场景

在 LobeChat CLI 中运行 lh agent run(尤其是使用 --no-headless,其帮助文本写明 “wait for human approval on tool calls”),Agent 运行到需要人工审批工具调用的阶段,服务端下发 agent_runtime_end 且 data.reason 为 waiting_for_human。此时无论是 SSE 还是 WebSocket 流助手,在非 JSON 文本模式下都会打印 ✓ Agent finished 并正常返回,而没有把它当作“暂停等待人工”的状态,脚本或调用方因此无法区分“运行已成功完成”和“运行在等待人工输入”。

报错原文

✓ Agent finished

agent_runtime_end
data.reason: "waiting_for_human"

原因分析

已确认的根因:服务端在 done、error、interrupted、waiting_for_human 四种状态下都会结束流,并带上 data.reason = state.status。而 CLI 的 renderEnd 只读取了 stepCount、usage、cost,忽略了 data.reason(agentStream.ts 约 484-500 行);SSE 处理器在非 JSON 模式下于约 105 行调用它并在 107 行返回,WebSocket 处理器在约 331 行调用并在 336 行 resolve。JSON 模式虽然跳过 renderEnd,但这些结束事件分支同样按正常结束处理。因此两种模式下都会输出 ✓ Agent finished 并正常退出。

环境排查

  • 确认当前 CLI 版本是否已包含 #20389 修复;未升级时该行为可复现。
  • 确认使用的是 lh agent run,并注意是否加了 --no-headless(该选项与人工审批有关)。
  • 确认输出模式:文本模式与 --json 模式都会受该结束事件分支影响。
  • 确认触发结束的原因确实是 waiting_for_human,而非 done / error / interrupted。
  • Issue 未提供操作系统、Python、CUDA、显卡、依赖等版本信息,这些不作为本次排查依据。

解决步骤

  1. 升级到包含 #20389 的版本,使结束原因映射到对应的输出文案与退出码。
  2. 升级后确认输出契约:done 打印 ✓ Agent finished 并退出 0;waiting_for_human 打印 ⏸ Agent paused: waiting for human approval — approve or answer it in LobeHub, the CLI does not wait for it 并退出 2;error 打印 ✗ Agent failed: … 并退出 1;interrupted 打印 ■ Agent interrupted 并退出 1。
  3. 查看 --no-headless 帮助文本与 lh agent run --help,它们现在记录了这一退出契约。
  4. 如果调用方需要处理等待人工的情况,按退出码 2 分支处理,并到 LobeHub 侧完成审批或回答(CLI 不会替你等待)。
  5. 若你依赖轮询回退路径的退出状态与缺失结果文案,注意那属于本 Issue 之外、留待后续处理的部分。

验证方法

用一个会下发 agent_runtime_end{reason:"waiting_for_human"} 的 gateway 实跑真实 CLI:修复前(canary)会打印 ✓ Agent finished 并退出 0;修复后(#20389)应打印 ⏸ Agent paused … 并退出 2。也可在文本模式与 --json 模式下分别检查文案与退出码是否一致。

参考来源

lobehub/lobe-chat #19613

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 27672

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注