菜单栏状态逻辑 #
显示内容 #
- 菜单栏图标和菜单第一行状态文字均反映当前 Agent 工作状态。
- 工作进行时隐藏健康状态;所有会话空闲后恢复显示。
- 菜单中的"Nodes"区块仅列出设备(通过
node.list 配对的节点),不包含客户端/在线状态条目。
- 当提供商用量快照可用时,Context 下方会出现"Usage"区块。
状态模型 #
- 会话:事件携带
runId(每次运行)以及载荷中的 sessionKey。"main"会话的键为 main;若不存在,则回退到最近更新的会话。
- 优先级:main 始终优先。若 main 处于活动状态,立即显示其状态。若 main 空闲,则显示最近活跃的非 main 会话。活动进行中不会来回切换;只有当前会话空闲或 main 变为活动时才切换。
- 活动类型:
job:高层命令执行(state: started|streaming|done|error)。
tool:phase: start|result,含 toolName 和 meta/args。
IconState 枚举(Swift) #
idle
workingMain(ActivityKind)
workingOther(ActivityKind)
overridden(ActivityKind)(调试覆盖)
ActivityKind → 字形映射 #
exec → 💻
read → 📄
write → ✍️
edit → 📝
attach → 📎
- 默认 → 🛠️
视觉映射 #
idle:普通小龙虾图标。
workingMain:带字形徽章,全色调,腿部"工作中"动画。
workingOther:带字形徽章,柔和色调,无快速抖动。
overridden:无论活动如何,均使用所选字形/色调。
状态行文字(菜单) #
- 工作进行中:
<会话角色> · <活动标签>
- 示例:
Main · exec: pnpm test、Other · read: apps/macos/Sources/OpenClaw/AppState.swift。
- 空闲时:回退到健康状态摘要。
事件摄取 #
- 来源:控制通道
agent 事件(ControlChannel.handleAgentEvent)。
- 解析字段:
stream: "job" 含 data.state,用于启动/停止。
stream: "tool" 含 data.phase、name、可选的 meta/args。
- 标签:
exec:args.command 第一行。
read/write:缩短的路径。
edit:路径加上从 meta/diff 数量推断出的变更类型。
- 回退:工具名称。
调试覆盖 #
- Settings ▸ Debug ▸ “Icon override” 选择器:
System (auto)(默认)
Working: main(按工具类型)
Working: other(按工具类型)
Idle
- 通过
@AppStorage("iconOverride") 存储;映射到 IconState.overridden。
测试清单 #
- 触发 main 会话任务:验证图标立即切换,且状态行显示 main 标签。
- main 空闲时触发非 main 会话任务:图标/状态显示非 main;保持稳定直到完成。
- 另一会话活动时启动 main:图标立即切换到 main。
- 快速连续工具调用:确保徽章不闪烁(工具结果的 TTL 缓冲)。
- 所有会话空闲后健康行恢复显示。