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

4.6 KiB
Raw Permalink Blame History

动态 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。

# 用法
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_metakey active_xmpp_sender_session

2. state_meta 表 — 跨 session 通信

数据库:~/.hermes/state.db

-- 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 历史。关键逻辑:

# 当处理 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.pyAGENTS 字典里添加新 agent
  2. api_server.py 的 session 重定向列表里加上新 session ID
  3. 添加 agent 时需配置:JID、密码、昵称、Gateway 地址、Session ID、@提及格式

自我识别标记

每条写入 session 历史的消息都带 [YOU] 前缀。当 LLM 加载上下文时,看到 [YOU] 就知道这是自己说过的话,不会把它当成别人的发言。

# 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 上下文