入口点
- Gateway RPC:
agent和agent.wait。 - CLI:
openclaw agent。
运行顺序
agentRPC 验证参数,解析会话(sessionKey/sessionId),持久化会话元数据,并立即返回{ runId, acceptedAt }。agentCommand执行该轮:解析模型 + thinking/verbose/trace 默认值,加载 skills 快照,调用runEmbeddedAgent,并在嵌入式循环尚未发出时补发一个 lifecycle end/error。runEmbeddedAgent:通过按会话和全局队列串行化运行,解析模型 + 认证配置文件,构建 OpenClaw 会话,订阅运行时事件,流式输出 assistant/tool 增量,强制执行运行超时(到期时中止),并返回负载及使用情况元数据。对于 Codex app-server 轮次,它还会在已接受的轮次停止产生 app-server 进度且未触发终态事件时中止该轮次。subscribeEmbeddedAgentSession将运行时事件桥接到agent流:工具事件映射到stream: "tool",assistant 增量映射到stream: "assistant",生命周期事件映射到stream: "lifecycle"(phase: "start" | "end" | "error")。agent.wait(waitForAgentRun)等待某个runId上的 lifecycle end/error,并返回{ status: ok|error|timeout, startedAt, endedAt, error? }。
排队与并发
运行会按每个会话键(session lane)进行串行处理,并可选地通过全局 lane 进行处理,从而防止工具/会话竞争。消息通道会选择一种队列模式(steer/followup/collect/interrupt)并将其送入该 lane 系统;参见 命令队列。 在流式传输开始前,已获准的运行会记录其持久化的activeWriterRunId 声明。每次追加或重写转录内容时都会提供 expectedWriterRunId,同步提交事务会验证它是否仍与当前活动声明匹配。因此,被取代的运行无法提交过时的转录数据。SQLite 写入队列会按代理对变更进行排序,而 Gateway 状态目录锁则防止另一个 Gateway 或 openclaw agent --local 进程同时拥有同一个状态目录。
会话和工作区准备
- 工作区已解析并创建;沙箱运行可能会将其重定向到沙箱工作区根目录。
- 技能已加载(或从快照中重复使用),并注入环境和提示词中。
- 引导/上下文文件已解析并注入系统提示词中。
- 会话记录目标和写入器声明已在开始流式传输之前准备就绪。之后的重写、压缩和截断会使用同一个事务内写入器声明围栏。
提示词组装
系统提示词由 OpenClaw 的基础提示词、技能提示词、引导上下文以及每次运行的覆盖项构建而成。模型特定的限制和压缩预留 token 会被强制执行。有关模型所看到的内容,请参见系统提示词。钩子
OpenClaw 有两套钩子系统:- 内部钩子(Gateway 钩子):用于命令和生命周期事件的事件驱动脚本。
- 插件钩子:agent/tool 生命周期和 Gateway 流水线内的扩展点。
内部钩子(Gateway 钩子)
agent:bootstrap: 在系统提示词最终确定之前,构建 bootstrap 文件时运行。可用于添加或移除 bootstrap 上下文文件。- 命令钩子:
/new、/reset、/stop,以及其他命令事件(参见钩子文档)。
插件钩子
这些钩子在 agent 循环或 Gateway 流水线内部运行:
出站/工具守卫的钩子决策规则:
before_tool_call:{ block: true }是终态并会停止低优先级处理器。{ block: false }是无操作,不会清除先前的阻止。before_install: 与上面的终态/无操作语义相同。对于必须覆盖 CLI 安装和更新路径的、由运维拥有的安装允许/阻止决策,请使用security.installPolicy,而不是before_install。message_sending:{ cancel: true }是终态并会停止低优先级处理器。{ cancel: false }是无操作,不会清除先前的取消。
流式传输
- Assistant 增量会从代理运行时作为
assistant事件流式输出。 - 块流式传输可以在
text_end或message_end上发出部分回复。 - 推理流式传输可以是单独的流,也可以是块回复。
- 有关分块和块回复行为,请参阅 流式传输。
工具执行
- 工具开始/更新/结束事件会在
tool流上发出。 - 在记录/发送之前,会对工具结果进行清理,以限制大小和图像负载。
- 会跟踪消息工具发送,以抑制重复的助手确认。
回复整形
最终载荷由助手文本(加上可选推理)、内联工具摘要(在详细且允许时)以及模型出错时的助手错误文本组成。- 精确的静默标记
NO_REPLY会从外发载荷中被过滤掉。 - 消息工具的重复项会从最终载荷列表中移除。
- 如果没有可渲染的载荷剩余,并且某个工具出错了,则会发出一个回退工具错误回复,除非某个消息工具已经发送了用户可见的回复。
压缩和重试
自动压缩会发出compaction 流事件,并且可以触发重试。重试时,内存中的缓冲区和工具摘要会重置,以避免重复输出。参见 压缩。
事件流
lifecycle:由subscribeEmbeddedAgentSession发出(并且在agentCommand中作为回退机制)。assistant:来自代理运行时的流式增量。tool:来自代理运行时的流式工具事件。
聊天通道处理
Assistant 增量内容缓冲到 chatdelta 消息中。chat final 会在 生命周期结束/出错 时发出。
超时
卡住会话诊断
启用诊断后,内置的两分钟阈值会将长时间处于processing 且未观察到回复、工具、状态、阻塞或 ACP 进度的会话分类为:
- 活动中的嵌入式运行、模型调用和工具调用会报告为
session.long_running。受控的静默模型调用会一直报告为session.long_running,直到达到中止阈值,因此较慢或非流式提供方不会过早被标记为停滞。 - 没有近期进展的活动会报告为
session.stalled。受控的模型调用在中止阈值时或之后切换为session.stalled;无归属的陈旧模型/工具活动只要不是长时间运行,就不会被隐藏。 session.stuck仅保留给可恢复的陈旧会话账本记录,包括带有陈旧无归属模型/工具活动的空闲排队会话。
session.stuck 诊断会退避。
何时会更早结束
- Agent 超时(中止)
- AbortSignal(取消)
- 网关断开连接或 RPC 超时
agent.wait超时(仅等待,不会停止 agent)。