mini-agent 是一个常驻的个人 AI 助手服务。它有 Telegram、Web 和 Android APK 三种使用入口,但三者并不共享同一条处理链。把它们都画成“客户端 -> EventBus -> Handler”会误导后续维护:网站的大部分请求是 WebChannel 直连后端服务,APK 的 /message 才会创建可恢复的后台执行任务,Telegram 则把消息和命令发布到 EventBus。
下面两张图基于当前代码整理。第一张看运行时入口和边界,第二张看模块依赖与 Actor 调度。
运行时入口不是一条线
- 打开当前运行架构图 — 支持暗亮主题切换和 PNG/JPEG/WebP/SVG 导出
网站前端:WebChannel 直接调用服务
网站通过 WebChannel 暴露 HTTP API。/chat 直接调用 ConversationManager.chat();/query 和 /task 直接调用 CodeTaskExecutor;/history 读取会话;待办、日程、推送 token 与 /sync/* 端点则直接操作相应的 manager。
这条路径有鉴权和配额边界。启用多租户后,UserManager 从 Bearer token 恢复用户和角色,WebChannel 把用户 ID 传给会话、Pi 工作区和用量统计。普通 Web 请求不经过 EventBus,也不需要先进入 MessageHandler。
Android APK:/message 是后台执行协议
APK 使用 /message。WebChannel 先按 (owner_user_id, request_id) 创建或复用 ExecutionTask,再由 ExecutionTaskManager 在后台调用 MessageHandler._handle_chat()。客户端可以走 SSE 接收 ack、delta、end 和 error,连接断开不会取消任务;任务状态和结果位置会写入 execution_tasks.db,之后可查询或显式取消。
/message 复用了 MessageHandler 的命令、意图和话题语义,但它不是网站 /chat、/query、/task 的替代入口。这个分开是为了让 APK 获得幂等、后台执行和 SSE 重连,而不改变网站 API 的直连行为。
Telegram:事件进入 EventBus
TelegramChannel 负责轮询、命令解析和 chat ID 校验。普通消息、/task、/query 与话题命令会发布为不同事件;MessageHandler 订阅这些事件,并用 asyncio.ensure_future() 接续异步工作。
EventBus 的 handler 是同步函数,异常会被隔离并记录。它不是异步消息队列,也不是 WebChannel 的统一入口。当前注册的关键事件如下:
| 事件 | 发布者 | 订阅者 | 作用 |
|---|---|---|---|
message_received | TelegramChannel | MessageHandler | 普通 Telegram 消息 |
task_command | TelegramChannel | MessageHandler | /task |
query_command | TelegramChannel | MessageHandler | /query |
topic_command | TelegramChannel | MessageHandler | 开始或结束话题 |
cron_tick | Scheduler | CronDispatcher | 定时任务分发 |
file_changed | BlogFileHandler | BlogSyncTask | 博客文件变更后的 Git 同步 |
Actor 调度只处理定时任务
- 打开模块与 Actor 调度图 — 支持暗亮主题切换和 PNG/JPEG/WebP/SVG 导出
项目没有 Akka 依赖,但实现了一个小型 Actor 式调度层:TaskActor 定义 handle(data) 协议,CronDispatcher 按 task 名从注册表取出 Actor 并等待其完成。Scheduler 发布 cron_tick,EventBus 把事件交给 dispatcher。
agent.py 默认注册四个 Actor:
TodoReminderActor:查询临近截止的待办,通过 Notifier 和可选 FCM 推送提醒。ScheduledMessageActor:检查应触发的日程,发送通知或运行查询。DailyDigestActor:通过 CodeTaskExecutor 生成每日 AI 日报。MemoryConsolidationActor:调用 ConversationManager 压缩活跃会话。
启用 sync.enabled 且配置 peer_url 后,服务额外注册 SyncTodosSchedulesActor,并给待办提醒与日程 Actor 注入 SyncClient,以便发提醒前刷新 Android 推送 token。同步 Actor 同时对应 sync_todos_schedules 与 sync_todos_schedules_evening 两个调度名。
Actor 并不是项目里所有的后台对象。ExecutionTaskManager 服务 APK 请求生命周期;BlogSyncTask 订阅文件事件;ResultBlogActor 与 BlogUpdateActor 处理博客生成。这三类都不经过 CronDispatcher。
MessageHandler、会话和任务执行
MessageHandler 是 Telegram 与 APK /message 的共享业务入口。它先识别显式命令;处于话题模式时,普通文本直接作为 query;其他消息再交给 IntentRouter 或 ConversationManager。TopicSessionStore 由 WebChannel 和 MessageHandler 共享,因此 HTTP 的 /topic/start、/topic/end 与 APK 消息看到的是同一份打开话题状态。
需要 Pi 的查询和任务最终进入 CodeTaskExecutor。默认后端使用 PiRpcClient 启动一个新的 pi --mode rpc --no-session 子进程,读取 JSONL 流并把文本增量返回给调用者。启用 pi_sandbox 时,子进程只继承白名单环境变量;可用的 bwrap 会进一步限制文件系统。在多租户 Web 模式下,缺少可用的文件系统沙箱会让启动直接失败。
会话和执行记录不放在同一个库里:ConversationManager 使用 LangGraph checkpoint 与 memories.db 保存上下文和摘要;用户、待办、日程、推送 token、执行任务和结果日志各自有对应存储。这种拆分让运行时状态、业务数据和可恢复任务不需要共用一张表。
博客与同步是两条独立工作流
查询结果满足条件时,ResultBlogActor 会把单次回答或话题会话转成 BlogSource,交给 BlogUpdateActor。后者决定写入新文章、更新已有文章,或把不通过安全和格式门槛的结果放入 review 目录。文章写入 posts 后,watchdog 发出 file_changed;BlogSyncTask 再执行 git add、git commit、git pull --rebase 与 git push。
这条 Git 工作流不依赖 scheduler.enabled。只要 BLOG_POSTS 已配置并且文件监听启动,实例就会同步博客。它和 todo/schedule 同步是两件事:后者由 SyncClient 调用对端的 /sync/todos、/sync/schedules 和 /sync/push-tokens,用 updated_at 与 updated_by 处理同一时刻的冲突;origin 只用于区分行的归属和避免复合主键冲突,不是冲突写入者 ID。
阅读代码时的顺序
先从 agent.py 看对象如何创建、哪些功能受配置开关控制;再沿自己的入口读下去:网站看 channels/web.py,APK 看 /message 与 tasks/execution_tasks.py,Telegram 看 channels/telegram.py 和 handlers/message_handler.py。定时工作从 core/scheduler.py、core/event_bus.py、tasks/cron_dispatcher.py 往下读;博客和同步分别进入 tasks/result_blog.py、tasks/blog_update.py、tasks/blog_sync.py 与 tasks/sync_actor.py。
这样不会把直连 API、事件分发、Actor 调度和文件监听混成一个“总线架构”。它们协作,但承担的是不同的责任。
Sources
- mini-agent:WebChannel 路由与 /message 执行入口 — 网站 API、APK 后台任务和 SSE 的实现。
- mini-agent:agent.py 组合根 — 依赖创建、Actor 注册、Scheduler、文件监听与配置分支。
- mini-agent:EventBus 与 CronDispatcher — TaskActor 协议、定时 Actor 和分发机制。
- mini-agent:ExecutionTaskManager — /message 的幂等后台执行与 SSE 事件缓存。
- mini-agent:博客生成与同步 — ResultBlogActor、BlogUpdateActor、BlogSyncTask 和同步 Actor 的实现。