Files
AgentsMeeting/docs/dynamic-session-switch.md
T

126 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 动态 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 上下文