# Agent Phone Runtime — Architecture ## 当前状态 (2026-06-11) 项目有两个并行实现,需要合并: --- ## 实现 A:Python/Termux 栈(已跑通) **假设**:Hermes 运行在 Pixel 的 Termux 里,一切本地化,不依赖 Mac。 ``` Android System ↓ root su + dumpsys notification (2s 轮询) notification_monitor.py (root Python daemon) ↓ HTTP POST localhost:8765 event_server.py (FastAPI + SQLite queue, Termux) ↑ MCP stdio android_mcp.py (FastMCP server) ↑ MCP protocol Hermes Agent (Termux) ``` ### 文件位置(设备) ``` ~/.hermes/event_bus/ ├── event_server.py # FastAPI HTTP 事件队列,127.0.0.1:8765 ├── notification_monitor.py # root 进程,轮询 dumpsys,POST 通知 ├── android_mcp.py # FastMCP stdio server (Hermes 调用) ├── start_all.sh # 一键启动(需 Termux 终端里运行) ├── stop_all.sh # 一键停止 └── events.db # SQLite 事件持久化 ``` ### EventServer API(127.0.0.1:8765) | 端点 | 用途 | |------|------| | `POST /events` | Android 推送单条事件 | | `POST /events/batch` | 批量推送 | | `GET /events?since_id=X` | MCP 增量拉取 | | `GET /events/latest?limit=N` | 最近 N 条 | | `GET /stats` | 队列统计 | | `GET /health` | 健康检查 | ### MCP 工具(android_mcp.py) | 工具 | 功能 | |------|------| | `get_events(since_id, limit, type_filter, app_filter)` | 增量拉取事件 | | `get_latest(limit, type_filter, app_filter)` | 最近 N 条事件 | | `get_stats()` | 队列统计 | | `list_event_apps()` | 哪些 App 有活动 | | `query_wechat(sql, key?, db_path?)` | root + sqlcipher 查微信 DB | ### 已验证 - ✅ EventServer 接收 → SQLite 持久化 - ✅ notification_monitor 捕获真实系统通知 - ✅ MCP JSON-RPC stdio 协议完整通讯 - ✅ Hermes config 已注册 `android-phone` MCP server - ✅ `since_id` 增量轮询、类型过滤 - ✅ WeChat sqlcipher 工具框架 ### 已知限制 - notification_monitor 用 `dumpsys` 轮询(2s 延迟,不是实时推送) - 没有 AccessibilityService(无 UI Tree 事件) - notification_monitor 需要 root 才能跑 dumpsys - `start_all.sh` 必须从 Termux 终端 app 里运行(不能通过 `adb run-as`) --- ## 实现 B:Kotlin Android APK(架构完整,大部分为 stub) **假设**:Hermes 运行在 Mac 或单独机器,通过 gRPC/MCP HTTP 连接 Android。 ``` Hermes Agent (外部) ↓ gRPC :50051 (未接 codegen) / MCP HTTP :8080 AndroidRuntimeServer.kt (gRPC service) ↓ EventBus (SharedFlow) AgentNotificationListenerService.kt ← 实时通知(无需 root) AgentAccessibilityService.kt ← UI Tree 事件 ↓ Unix Domain Socket @agent_events (NDJSON) EventStreamServer.kt ``` ### 模块结构 ``` android/ ├── core/ # 统一实体模型 (Person/Conversation/Message/Event/Task/Document) ├── event-bus/ # EventBus (SharedFlow) + Unix Socket (NDJSON, @agent_events) ├── app/ # AccessibilityService + NotificationListenerService + BootReceiver ├── mcp-server/ # gRPC server + MCP HTTP/SSE server (port 8080) + ActionDispatcher ├── memory-graph/ # Room DB schema + GraphSchema 验证 (stub) ├── data-extraction/# SQLite/MMKV/Realm/LevelDB 提取器 (stub) └── frida-bridge/ # Frida REST API 客户端 (OkHttp) ``` ### 实现状态 | 模块 | 状态 | |------|------| | AgentNotificationListenerService | ✅ 完整实现 | | AgentAccessibilityService | ✅ 完整实现 | | EventBus + Unix Socket | ✅ 完整实现 | | MCP HTTP/SSE server (port 8080) | ✅ 完整实现 | | gRPC server | ⚠️ 接口定义完整,未接 protoc codegen | | ActionDispatcher / QueryDispatcher | ⚠️ 路由逻辑完整,handler 为 stub | | Memory Graph | ⚠️ Schema 设计完整,MemoryGraph.kt 为空 stub | | Data Extraction (SQLite/MMKV/etc) | ⚠️ 类结构完整,实际读取为 stub | | Frida Bridge | ✅ HTTP client 完整,JS scripts 框架完整 | **注意**:TASKS.md 所有任务标记为 `[x]`,但实际代码中大量为 stub,不代表功能可用。 ### MCP HTTP/SSE 协议(port 8080) - `GET /sse` — Server-Sent Events 流 - `POST /messages` — JSON-RPC 2.0 - `tools/list`, `tools/call`, `initialize` ### gRPC 协议(port 50051) ```protobuf service AndroidRuntime { rpc Execute(ActionRequest) returns (ActionResponse); rpc Query(QueryRequest) returns (QueryResponse); rpc Subscribe(SubscribeRequest) returns (stream Event); } ``` --- ## 架构差异 | 维度 | 实现 A (Python/Termux) | 实现 B (Kotlin APK) | |------|----------------------|---------------------| | Hermes 位置 | Android 本机 Termux | 外部机器 | | 事件采集 | dumpsys 轮询 (root, 2s) | NotificationListenerService (实时) | | Accessibility | ❌ | ✅ | | MCP 传输 | stdio (FastMCP) | HTTP/SSE :8080 | | 持久化 | SQLite event queue | SharedFlow (内存) + Room | | 可用状态 | ✅ 端到端跑通 | ⚠️ 未编译部署 | | WeChat DB | ✅ sqlcipher 工具可用 | ⚠️ stub | | Frida | ❌ | ✅ HTTP client 框架 | --- ## 合并方案 目标:保留两边的优势,以"Hermes 在 Termux 本机"为基础架构。 ### 阶段 1(当前可做):打通 APK 事件源 1. 编译安装 Android APK 2. APK 的 `AgentNotificationListenerService` 实时收到通知后: - **方案 A**:POST 到 EventServer `localhost:8765`(最简) - **方案 B**:android_mcp.py 订阅 Unix Socket `@agent_events`,写入 SQLite 3. 去掉 `notification_monitor.py`(dumpsys 轮询),替换为 APK 实时推送 ### 阶段 2:接入 AccessibilityService APK 的 `AgentAccessibilityService` 捕获 UI Tree 事件,同样推送到 EventServer。 在 MCP 增加 `get_ui_state(package?)` 工具。 ### 阶段 3:接入 Frida APK 的 `FridaBridge.kt` 已实现 frida-server REST client。 在 `android_mcp.py` 增加 `frida_call(package, script)` 工具,内部调用 FridaBridge HTTP API。 ### 阶段 4:gRPC(可选) 如果后续需要 Hermes 从 Mac 控制 Android,再接 gRPC protoc codegen。 当前 Hermes 在 Termux 本机,stdio MCP 足够,gRPC 优先级低。 --- ## 启动指南 ### 前置条件 - Pixel 8 Pro,Root(Magisk) - Termux 已安装,Hermes 已安装(`~/.hermes/hermes-agent/`) - 已在 Termux 给予 Root 权限 ### 启动服务(在 Termux 终端里运行) ```bash bash ~/.hermes/event_bus/start_all.sh ``` 输出: ``` [+] EventServer started (pid XXXX) on http://127.0.0.1:8765 [+] NotificationMonitor started as root (pid XXXX) ``` ### 停止服务 ```bash bash ~/.hermes/event_bus/stop_all.sh ``` ### Hermes MCP 配置(已写入 `~/.hermes/config.yaml`) ```yaml mcp_servers: android-phone: command: /data/data/com.termux/files/home/.hermes/hermes-agent/venv/bin/python args: - /data/data/com.termux/files/home/.hermes/event_bus/android_mcp.py env: EVENT_BUS_DB: /data/data/com.termux/files/home/.hermes/event_bus/events.db timeout: 30 connect_timeout: 10 ``` ### Hermes 里使用 在 Hermes 对话中直接问: - "手机上最近有什么通知?" - "查一下微信最近 20 条消息" - "现在哪个 App 在前台?" --- ## WeChat SQLCipher Key 存放:`~/.hermes/event_bus/wechat_key`(默认 `e03ce81`) DB 路径:`/data/data/com.tencent.mm/MicroMsg//EnMicroMsg.db`(root 读取) 详细实现参考:`/Users/yibo/Documents/aipcrm/server/services/wechat/` --- ## 文件清单 ### Mac 端(开发) ``` /Users/yibo/Documents/lemonAI/phoneuse/ ├── ARCHITECTURE.md # 本文档 ├── phoneuse.md # 项目 Vision & Milestone 原始文档 ├── TASKS.md # 任务追踪(另一进程生成) ├── android/ # Kotlin Android APK 项目 ├── event_server.py # EventServer 源码 ├── notification_monitor.py # Notification monitor 源码 ├── android_mcp.py # MCP server 源码 ├── start_all.sh # 启动脚本 ├── stop_all.sh # 停止脚本 └── test_mcp_rpc.py # MCP 协议测试脚本 ``` ### 设备端(Pixel 8 Pro) ``` ~/.hermes/event_bus/ # 所有运行时文件 ~/.hermes/config.yaml # 含 mcp_servers.android-phone 配置 ~/.hermes/logs/ # event_server.log, notification_monitor.log ```