daemon 后台服务
常驻后台的枢纽 —— 接 webhook、管 worker、映射 session、分发事件
Vyane 的 CLI 和 MCP 工具是「点一下跑一次」的入口,而 daemon 是一直挂在后台的常驻进程,负责那些需要持续在场的活:接外部消息、管子进程、记事件、等审批。你派一个后台任务、goal 被额度挡住要接力、research 跑一整晚 —— 背后都是它在盯着。
它可以由操作系统的服务管理器托管,进程本体是 python -m vyane.daemon.main。配置为开机启动和失败重启后,平时不需要手动维护进程。
四大职能
daemon 的核心就四件事:
| 职能 | 干什么 |
|---|---|
| webhook 接收 | 收 GitHub 等外部系统打来的回调,把外部动静变成内部任务 |
| worker 管理 | 拉起、恢复、健康监控子进程 —— 每个后台任务是一个独立子进程 |
| session 映射 | 把逻辑会话(topic 级)对应到底层 harness 的真实 session ID |
| 事件分发 | 进程内的 pub/sub 广播:一处发事件,多处订阅,再落库存档 |
一句话:它是「外面进来的信号」和「里面跑着的活」之间的总机。
子系统
daemon 内部由一组各管一摊的子系统拼成。下面这些都在源码 daemon/ 目录里落地:
| 子系统 | 职责 | 类比 |
|---|---|---|
| scheduler | 定时任务、路由 / 重试 / DAG 决策 | 排班表 |
| worker pool | 子进程注册表 + 拉起管理(WorkerRegistry / SubprocessManager) | 工位与工人 |
| event store(SSE) | 事件先进 EventBus 广播,再由 EventStore 批量落 SQLite | 监控录像 |
| approval inbox | 需要人拍板的动作先进这里排队,等批准再放行 | 待办审批箱 |
| research campaign | 后台跑一整轮多主题深度调研,定期回报进展 | 值夜班的调研员 |
| message queue | worker 之间收发消息(send / claim / reply / ack) | 内部信箱 |
event store 是「事件 → SSE」的那一层
事件先由进程内的 EventBus 广播给所有订阅者,EventStore 作为其中一个订阅者把事件批量写进 SQLite,支持时间范围查询和聚合。想实时看事件流的地方就从这里以 SSE(server-sent events,服务端推事件)读出去。
🚧 scheduler 目前是灰度状态
scheduler 有三档开关 --scheduler-mode {off, shadow, on}:off 完全不启,shadow 与现有自主循环并行跑但只做决策对比、不真派活,on 才由它独占调度。它还没正式替代旧的自主循环入口,当前多在 shadow 档验证。
注意:这里的 --scheduler-mode 是 scheduler 的开关,和派活内核的 VYANE_KERNEL_MODE(也有 off/shadow/enforce 档)是两套独立机制——一个管"定时任务/调度什么时候由谁接管",一个管"每次派活要不要过内核准入"。都在灰度,但别混成一个。
怎么看状态
看一眼 daemon 现在健不健康、有几个 worker 在跑、事件和花销多少:
uv run vyane daemon-status命令名是 daemon-status,不是 bare vyane daemon。常用附加参数:
| 参数 | 作用 |
|---|---|
--window-hours | 事件聚合窗口(小时,默认 1.0) |
--live-health | 额外去读 daemon 的 /health 端点,拿 kernel / scheduler 实时档位 |
--json | 输出 JSON,给脚本 / CI 用 |
怎么重启
daemon 由 launchd 管,重启走专门的命令(它会调 launchd 停再拉):
uv run vyane daemon-restart默认会先检查有没有 worker 子进程还在跑 —— 有活在跑就拒绝重启,免得打断任务。几种收尾方式:
# 等当前这轮任务收尾后再重启,不打断正在跑的活
uv run vyane daemon-restart --after-current-turn
# 明知会打断、就是要立刻重启
uv run vyane daemon-restart --force
# 延后 N 秒再重启
uv run vyane daemon-restart --delay-seconds 8默认不硬打断
daemon-restart 检测到有 worker 子进程 pending / running 时会返回 blocked 并拒绝执行。想在有活时也重启,要么用 --after-current-turn(等收尾),要么用 --force(明确表示打断是有意的)。
部署与运维
daemon 的落地细节 —— launchd plist、端口(VYANE_DAEMON_PORT)、日志位置、开机自启配置 —— 都在部署页里。