feat(xxm): dynamic TUI session context injection for coregroup

- chat_bridge: mark_active_tui_session() + get_active_tui_session()
  Tracks active TUI session via temp/.active_tui_session.json,
  auto-expires after 1 hour (matching Hermes state_meta pattern)
- chat_bridge: inject TUI context when processing coregroup messages
  Bot now sees what hmo was discussing in TUI when replying in group
- session_router: record active session ID on every TUI message
  Uses _resolve_session() to get the current bound session ID
This commit is contained in:
hmo
2026-06-20 01:27:39 +08:00
parent 50a0716c4d
commit e8fba49cb8
2 changed files with 63 additions and 0 deletions
+52
View File
@@ -17,6 +17,41 @@ os.environ["NO_PROXY"] = "*"
import requests import requests
_TZ = timezone(timedelta(hours=8)) _TZ = timezone(timedelta(hours=8))
# ── Dynamic TUI session tracking ──
# When xxm is chatting with hmo in TUI, record the active session ID.
# When the bot processes a coregroup message, it injects TUI context
# so the LLM knows what hmo and xxm were discussing in the TUI.
# Auto-expires after 1 hour (matching Hermes' state_meta pattern).
_ACTIVE_SESSION_FILE = os.path.join(
os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
"temp", ".active_tui_session.json")
def mark_active_tui_session(session_id: str):
"""Record the active TUI session ID + timestamp."""
try:
d = os.path.dirname(_ACTIVE_SESSION_FILE)
if d: os.makedirs(d, exist_ok=True)
with open(_ACTIVE_SESSION_FILE, "w") as f:
json.dump({"session_id": session_id, "timestamp": int(time.time())}, f)
except Exception:
pass
def get_active_tui_session(max_age: int = 3600) -> str | None:
"""Return active TUI session ID if recent enough (< 1 hour)."""
try:
if not os.path.exists(_ACTIVE_SESSION_FILE):
return None
with open(_ACTIVE_SESSION_FILE, "r") as f:
data = json.load(f)
age = time.time() - data.get("timestamp", 0)
if age < max_age:
return data.get("session_id")
except Exception:
pass
return None
# ── Logging ── # ── Logging ──
_LOG_FILE = os.path.join( _LOG_FILE = os.path.join(
os.path.dirname(os.path.dirname(os.path.abspath(__file__))), os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
@@ -650,6 +685,23 @@ class SessionBridge:
if recent_ctx: if recent_ctx:
sys_prompt += f"\n\n最近对话:\n{recent_ctx}" sys_prompt += f"\n\n最近对话:\n{recent_ctx}"
# Dynamic session switching: inject TUI context for coregroup messages
if "[群聊" in message:
tui_sid = get_active_tui_session()
if tui_sid:
try:
from session_router import extract_session_context
tui_ctx = extract_session_context(tui_sid, limit=50)
if tui_ctx:
sys_prompt += (
"\n\n【你的 TUI 工作台最近对话】"
f"\n(老莫在 TUI 和你讨论这些时,转发了群聊消息,"
f"请结合下面的 TUI 对话理解他在群里的意图。"
f"群聊和 TUI 是同一个人,两份上下文关联看)\n{tui_ctx}"
)
except Exception:
pass
# Build messages array # Build messages array
messages = [ messages = [
{"role": "system", "content": sys_prompt}, {"role": "system", "content": sys_prompt},
+11
View File
@@ -620,5 +620,16 @@ class SessionRouter:
tagged = f"{prefix}{message}" tagged = f"{prefix}{message}"
history = [{"role": "user", "content": tagged}] history = [{"role": "user", "content": tagged}]
# Dynamic context switching: record active TUI session
# so bot can inject TUI context when replying to coregroup
if channel != "xmpp":
try:
sid = self._resolve_session(key, allow_create=False)
if sid:
from chat_bridge import mark_active_tui_session
mark_active_tui_session(sid)
except Exception:
pass
# 4. Run LLM command loop # 4. Run LLM command loop
return self._llm_loop(key, history) return self._llm_loop(key, history)