From 50a0716c4d08138507fdb742ae1e581996c2299d Mon Sep 17 00:00:00 2001 From: mohe Date: Sat, 20 Jun 2026 01:21:03 +0800 Subject: [PATCH] add dynamic session switch documentation --- docs/dynamic-session-switch.md | 125 +++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 docs/dynamic-session-switch.md diff --git a/docs/dynamic-session-switch.md b/docs/dynamic-session-switch.md new file mode 100644 index 0000000..be2258a --- /dev/null +++ b/docs/dynamic-session-switch.md @@ -0,0 +1,125 @@ +# 动态 Session 切换机制 + +## 问题 + +多个 Agent 在核心群(coregroup)里聊天,各自有不同的 CLI session 和 XMPP session。当 mohe 在 CLI 发出一条消息到核心群,其他 Agent(zhiwei、xxm)回复时,mohe 的 bot 应该能**看到自己说过的上下文**,而不是只看到 xmpp session 里孤立的消息。 + +## 架构 + +``` +CLI session A ──→ xmpp_session_bridge.py ──→ XMPP 核心群 + │ + ├── 写入 xmpp-mohe-v2 历史 + └── 记录 session A ID → state_meta + +XMPP bot 收到群消息 ──→ api_server.py + │ + ├── state_meta 有活跃 session? + ├── 是 → 加载那个 session 的上下文 + └── 否 → 加载默认 xmpp-mohe-v2 上下文 +``` + +## 文件说明 + +### 1. `xmpp_session_bridge.py` — 从 CLI 发消息到核心群 + +位置:`~/.hermes/scripts/xmpp_session_bridge.py` + +作用:从当前 CLI session 发送消息到核心群,同时记录当前 session ID。 + +```bash +# 用法 +python3 xmpp_session_bridge.py send "消息内容" "$HERMES_SESSION_ID" --agent mohe +python3 xmpp_session_bridge.py send "消息内容" "$HERMES_SESSION_ID" --agent zhiwei + +# 查询当前活跃 session +python3 xmpp_session_bridge.py active + +# 清除活跃 session +python3 xmpp_session_bridge.py clear +``` + +做了什么: + +1. 通过 `docker exec ejabberd ejabberdctl send_message groupchat` 发送 XMPP 消息 +2. 将消息写入对应 agent 的 session 历史(如 `xmpp-mohe-v2`),带 `[YOU]` 前缀 +3. 将当前 session ID + 时间戳写入 `state_meta`(表 `state_meta`,key `active_xmpp_sender_session`) + +### 2. `state_meta` 表 — 跨 session 通信 + +数据库:`~/.hermes/state.db` + +```sql +-- state_meta 表结构(Hermes 内置) +CREATE TABLE state_meta ( + key TEXT PRIMARY KEY, + value TEXT +); + +-- 写入的 value 格式 +{"session_id": "20260619_190821_7c0afe", "timestamp": 1234567890, "source": "cli"} +``` + +- key: `active_xmpp_sender_session`(固定) +- value: JSON,含 session_id、timestamp、source +- 有效期 1 小时(api_server.py 检查时判断) + +### 3. `api_server.py` — session 重定向 + +文件:`hermes-agent/gateway/platforms/api_server.py` + +当 bot 收到核心群消息时,API server 加载 session 历史。关键逻辑: + +```python +# 当处理 xmpp-mohe-v2 / xmpp-zhiwei 等 session 时: +if session_id in ("xmpp-mohe-v2", "xmpp-mohe", "xmpp-zhiwei", "xmpp-zhiwei-v2"): + try: + # 查 state_meta 表 + row = db.execute("SELECT value FROM state_meta WHERE key='active_xmpp_sender_session'") + if row: + data = json.loads(row[0]) + age = time.time() - data.get("timestamp", 0) + if age < 3600: # 1 小时内有效 + session_id = data.get("session_id", session_id) # 切换 session! + except Exception: + pass +``` + +如果 `state_meta` 中有活跃的 sender session,就把 Bot 当前的 session 换成那个 CLI session 的上下文。这样 Bot 能看到你在 CLI 里说过的完整对话。 + +## Agent 配置 + +在 `xmpp_agent_core.py` 中定义: + +| Agent | JID | Nick | Session ID | HTTP端口 | Gateway端口 | +|-------|-----|------|-----------|---------|------------| +| mohe | mohe@yoin.fun | mohe | xmpp-mohe-v2 | 5804 | 8642 | +| zhiwei | zhiwei@yoin.fun | zhiwei | xmpp-zhiwei | 5805 | 8643 | +| xiaoguo | xiaoguo@yoin.fun | xiaoguo | xmpp-xiaoguo | 5806 | 8645 | + +## 如何添加新的 Agent + +1. 在 `xmpp_agent_core.py` 的 `AGENTS` 字典里添加新 agent +2. 在 `api_server.py` 的 session 重定向列表里加上新 session ID +3. 添加 agent 时需配置:JID、密码、昵称、Gateway 地址、Session ID、@提及格式 + +## 自我识别标记 + +每条写入 session 历史的消息都带 `[YOU]` 前缀。当 LLM 加载上下文时,看到 `[YOU]` 就知道这是自己说过的话,不会把它当成别人的发言。 + +```python +# xmpp_session_bridge.py 中写入时 +db.execute("INSERT INTO messages (...) VALUES ('xmpp-mohe-v2', 'user', f'[YOU] {text}', ...)") + +# api_server.py 中历史消息处理 +my_names = profile_to_names.get(pname, ...) +for msg in history: + if any(content.startswith(name) for name in my_names): + msg["content"] = "[YOU] " + content +``` + +## 注意事项 + +1. **有效期 1 小时** — 超过 1 小时没有新的 CLI 发消息到核心群,自动回退到默认 session +2. **多个 Agent 不冲突** — mohe 和 zhiwei 各有自己的 session ID 和 state_meta key +3. **发消息必须带 session ID** — 不带的话 state_meta 不会被更新,bot 看不到 CLI 上下文