64 lines
2.3 KiB
Python
64 lines
2.3 KiB
Python
"""Regression tests for #30479 — session-scoped /model and /reasoning overrides
|
|
silently lost on Telegram forum/DM topics and after compression session splits.
|
|
|
|
Root cause: ``_handle_message_with_agent`` rewrites ``source.thread_id`` via
|
|
``_recover_telegram_topic_thread_id`` (lobby/stripped reply -> the user's
|
|
last-active bound topic) *before* deriving the session key for a message turn.
|
|
The ``/model`` and ``/reasoning`` command handlers derived their override key
|
|
from the raw inbound ``event.source``, skipping that recovery — so the override
|
|
was stored under one key and the next message turn read a different key, and the
|
|
override was dropped.
|
|
|
|
Fix: both command handlers normalize the source via
|
|
``_normalize_source_for_session_key`` before deriving the override key, so
|
|
storage and read keys are identical.
|
|
"""
|
|
|
|
import threading
|
|
from unittest.mock import MagicMock
|
|
|
|
import gateway.run as gateway_run
|
|
from gateway.config import Platform
|
|
from gateway.session import SessionSource, build_session_key
|
|
|
|
|
|
def _make_runner(recovered_thread_id=None):
|
|
runner = object.__new__(gateway_run.GatewayRunner)
|
|
runner.config = None
|
|
runner.session_store = None
|
|
runner._session_db = None
|
|
runner._session_model_overrides = {}
|
|
runner._session_reasoning_overrides = {}
|
|
runner._agent_cache = {}
|
|
runner._agent_cache_lock = threading.Lock()
|
|
# Stub topic recovery: returns the bound topic id for a lobby message,
|
|
# None otherwise (the real method's contract).
|
|
runner._recover_telegram_topic_thread_id = MagicMock(return_value=recovered_thread_id)
|
|
return runner
|
|
|
|
|
|
def _topic_dm_source(thread_id):
|
|
"""A Telegram DM in topic mode. thread_id="" / "1" == General/lobby."""
|
|
return SessionSource(
|
|
platform=Platform.TELEGRAM,
|
|
chat_id="555",
|
|
chat_name="Forum DM",
|
|
chat_type="dm",
|
|
user_id="user-1",
|
|
thread_id=thread_id,
|
|
)
|
|
|
|
|
|
def test_normalize_rewrites_lobby_thread_to_bound_topic():
|
|
"""A lobby (stripped) reply gets pinned to the user's bound topic id."""
|
|
runner = _make_runner(recovered_thread_id="42")
|
|
src = _topic_dm_source(thread_id="") # lobby/General — no message_thread_id
|
|
|
|
normalized = runner._normalize_source_for_session_key(src)
|
|
|
|
assert normalized.thread_id == "42"
|
|
# Original source is left untouched (we return a copy).
|
|
assert src.thread_id == ""
|
|
|
|
|