From f61cc464f0a150313959d66dc9c87f27f18e0b8b Mon Sep 17 00:00:00 2001 From: Teknium Date: Wed, 15 Apr 2026 11:07:24 -0700 Subject: [PATCH] fix: include thread_id in _parse_session_key and fix stale parts reference _parse_session_key() now extracts the optional 6th part (thread_id) from session keys, and _notify_active_sessions_of_shutdown uses _parsed.get() instead of the removed 'parts' variable. Without this, shutdown notifications silently failed (NameError caught by try/except) and forum topic routing was lost. --- gateway/run.py | 14 +++++++++----- .../test_background_process_notifications.py | 10 ++++++++-- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/gateway/run.py b/gateway/run.py index f9bf9a38b99..327f8ae32a4 100644 --- a/gateway/run.py +++ b/gateway/run.py @@ -485,17 +485,21 @@ def _resolve_hermes_bin() -> Optional[list[str]]: def _parse_session_key(session_key: str) -> "dict | None": """Parse a session key into its component parts. - Session keys follow the format ``agent:main:{platform}:{chat_type}:{chat_id}``. - Returns a dict with ``platform``, ``chat_type``, and ``chat_id`` keys, - or None if the key doesn't match the expected format. + Session keys follow the format + ``agent:main:{platform}:{chat_type}:{chat_id}[:{thread_id}[:{user_id}]]``. + Returns a dict with ``platform``, ``chat_type``, ``chat_id``, and + optionally ``thread_id`` keys, or None if the key doesn't match. """ parts = session_key.split(":") if len(parts) >= 5 and parts[0] == "agent" and parts[1] == "main": - return { + result = { "platform": parts[2], "chat_type": parts[3], "chat_id": parts[4], } + if len(parts) > 5: + result["thread_id"] = parts[5] + return result return None @@ -1526,7 +1530,7 @@ class GatewayRunner: # Include thread_id if present so the message lands in the # correct forum topic / thread. - thread_id = parts[5] if len(parts) > 5 else None + thread_id = _parsed.get("thread_id") metadata = {"thread_id": thread_id} if thread_id else None await adapter.send(chat_id, msg, metadata=metadata) diff --git a/tests/gateway/test_background_process_notifications.py b/tests/gateway/test_background_process_notifications.py index 68eb5e30439..eabf92be634 100644 --- a/tests/gateway/test_background_process_notifications.py +++ b/tests/gateway/test_background_process_notifications.py @@ -383,9 +383,15 @@ def test_parse_session_key_valid(): def test_parse_session_key_with_extra_parts(): - """Extra trailing parts (thread_id etc.) are ignored — only first 5 matter.""" + """Thread ID (6th part) is extracted; further parts are ignored.""" result = _parse_session_key("agent:main:discord:group:chan123:thread456") - assert result == {"platform": "discord", "chat_type": "group", "chat_id": "chan123"} + assert result == {"platform": "discord", "chat_type": "group", "chat_id": "chan123", "thread_id": "thread456"} + + +def test_parse_session_key_with_user_id_part(): + """7th part (user_id) is ignored — only up to thread_id is extracted.""" + result = _parse_session_key("agent:main:telegram:group:chat1:thread42:user99") + assert result == {"platform": "telegram", "chat_type": "group", "chat_id": "chat1", "thread_id": "thread42"} def test_parse_session_key_too_short():