zero exec · 一次性 prompt 执行详细序列图

Headless one-shot:CLI 解析装配 → agent.Run 多轮循环(流式 / 工具 / 自动权限)→ 事件落 stdout → 退出码

Shell / Caller zero exec "…" runExec cli/exec.go agent.Run agent/loop.go Provider / LLM stream API Tools + Sandbox registry / engine Writer stdout / stderr 阶段 1 · 解析与装配(无 LLM 调用,全部同步) args + stdin(可 --file / stream-json) runExec 顺序装配: 1. parseExecArgs → applyExecMode(模式预设填充未设字段) 2. resolveWorkspaceRoot(--worktree 则准备隔离工作树) 3. newCoreRegistry + escalate_model / specialist / MCP / plugins 4. resolveExecPermissionMode(--auto / --skip-permissions-unsafe) 5. resolveConfig(overrides: model/maxTurns) → DefaultRegistry 6. --list-tools 分支:直接输出工具清单并退出 7. resolveExecPrompt:inline / --file / stdin(stream-json) 8. resolveExecImages + vision gate(模型不支持则丢弃+告警) 9. sandbox.NewScope → CoreToolsScoped 重注册 + buildExecSandboxEngine 10. buildProvider + resolveExecRunMetadata + notify.New 失败即退出: 无 provider → provider_error prompt 为空 / 文件缺失 → usage error(非 0 退出码) sessions.PrepareExec(可 --resume / --fork)→ FormatExecPrompt streamjson.CreateRunID → execEventWriter{format, runID, sessionID} writer.runStart(cwd, metadata, permissionMode) → 首个事件(text/json/stream-json) unsafe 模式额外发 warning;sessionRecorder.append(user message) 阶段 2 · 进入 agent.Run · 播种消息(无交互回调) agent.Run(runCtx, prompt, provider, Options{…}) Options 关键项(headless 特征): RequireCompletionSignal=true(不轻信"无工具即完成") OnPermissionRequest / OnAskUser 未设 → 权限按模式自动裁决 回调 OnText/OnToolCall/OnToolResult/OnUsage/OnPermission → writer SeedMessagesWithImages(systemPrompt, prompt, images);maxTurns=12(默认) 阶段 3 · 多轮循环 · for turn := 0; turn < maxTurns (紫框 = 每轮重复) loop [每一轮 turn] partitionTools(按权限模式+过滤器暴露工具) maybeCompact:接近上下文窗口则先摘要旧历史(PROACTIVE) streamWithReconnect(request{messages, tools, effort}) 流式 token / reasoning / tool-call 片段 OnText/OnReasoning/OnToolCallDelta → writer.text(stream-json 逐段;text 累积;json 收尾) CollectStream 汇总为 collected{Text, ToolCalls, Usage, Error} 韧性处理: 连接中断 → 退避重连 上下文超限 → 压缩后重试本轮 image 拒绝 → 友好错误退出 alt [本轮响应内容] ┌ 分支 A · 仅文本(无工具调用)→ 完成判定 RequireCompletionSignal 门控(headless): • selfReportedIncompletion → Incomplete=true,退出码 4 • 续写线索 / 未完成 plan 项 → continueNudge 续推(有上限) • SelfCorrect 开:一次 task-grounded 验收核对 • 均通过 → result.FinalAnswer = collected.Text,返回(跳出循环) 空轮/无输出 guard:连续空响应触发 runaway 停止 └ 分支 B · 含工具调用 → 逐个执行(内层 loop) OnToolCall → writer.toolCall + sessionRecorder.captureCheckpoint(可安全 rewind) executeToolCall(call, permissionMode, options) 权限自动裁决(无交互 prompt): unsafe→全允许;auto→只读/工作区内写允许,危险操作按 sandbox.Evaluate 命令前缀白名单 matchCommandPrefix;被拒 → tool_result 记录 denial OnPermission(event) → writer.permission(仅记录,不阻塞) ToolResult{output, status, changedFiles} OnToolResult → writer.toolResult;append 到 messages(供下一轮) 批后:changedFiles 触发一次 SelfCorrect AfterEdit;重复失败 guard 停止;escalate_model 切模型 ↻ 进入下一轮 turn(带新 messages) 达到 maxTurns 上限: finalAnswerAfterMaxTurns 请求"不再调用工具的最终总结";仍空则 Incomplete=true(退出码 4) ↑ 循环结束(返回 Result{FinalAnswer, Incomplete, Turns, Usage}) return (result, err) 阶段 4 · 收尾 · 通知 / 落盘 / 退出码 runExec 依 err / result 分派: • notifier.Notify(Completion)(stderr,可 webhook) • ctx.Canceled(Ctrl+C/SIGTERM)→ interrupted 事件,退出码 130 • provider error → error 事件 / provider_error,退出码 3 • result.Incomplete → final + error(incomplete),退出码 4 • 成功 → writer.final(FinalAnswer) + runEnd("success"),退出码 0 • sessionRecorder.append(assistant message) 持久化 defer:closeMCP/Specialist、lspShutdown、warnIfRecordingFailed final / done / error 终止事件 → stdout(按 -o text|json|stream-json) 返回退出码 (0 / 3 / 4 / 130) 图例 同步调用 (CLI→loop) provider 流式往返 工具执行 (sandbox) writer 事件 → stdout 返回值 权限自动裁决(非交互) 注:headless exec 与 TUI 共用同一个 agent.Run 循环;差异在于 exec 不注册交互式权限/追问回调,且默认开启 RequireCompletionSignal。

装配阶段(无 LLM)

  • parseExecArgsapplyExecMode 预设填充
  • • registry 分层:core + escalate + specialist + MCP + plugins
  • • prompt 三来源:inline / --file / stdin(stream-json)
  • --list-tools 在此短路,永不联网

Headless 权限模型

  • OnPermissionRequest / OnAskUser 不注册
  • • 权限按模式自动裁决:unsafe 全允许 / auto 按 sandbox
  • • ask_user 降级为"用最佳假设继续"
  • OnPermission 仅记录事件,不阻塞

轮次循环 agent.Run

  • maxTurns 默认 12,可 --max-turns
  • • 每轮:partitionTools → 压缩 → 流式 → 判定分支
  • • 分支 A 仅文本 → 完成门控;分支 B 执行工具
  • • 达上限 → finalAnswerAfterMaxTurns 强制收尾

韧性与自纠错

  • • 断连退避重连;上下文超限 → 压缩后重试本轮
  • • 空轮 / 重复失败 guard 防止 runaway
  • --self-correct:LSP + 测试验证 + 验收核对
  • • 每个 mutating 工具前写 checkpoint 供 /rewind

输出与事件流

  • execEventWriter 三格式:text / json / stream-json
  • • 事件:runStart → text/toolCall/toolResult/usage → final/done
  • • stream-json 逐段发;json 收尾;text 累积
  • • stdout 载数据,stderr 载告警/通知(严格分离)

退出码语义

  • 0 成功;2 用法错误
  • 3 provider 错误;4 incomplete(未完成)
  • 130 被信号中断(Ctrl+C / SIGTERM)
  • • incomplete 不算成功:便于 cron / CI 消费者识别