Files
hermes-agent/tests/gateway/test_qqbot_update_prompt_key.py
teknium1 c1e58f4cb2 fix(process-identity): desktop reap, Windows updater and profile liveness use the canonical matchers
Two kill/relaunch predicates decided identity by argv substring, the bug class root AGENTS.md
forbids: hermes_cli/dashboard_procs.py::_is_desktop_local_serve_cmdline (`"serve" not in cmd`,
on the orphan-reap KILL path) and hermes_cli/update_cmd_windows.py::_is_backend_argv
(`" serve" in argv_low`, in the very file that defines _hermes_holder_subcommand). Both now ask
the canonical token classifier; host/port are read as flag values, not substrings.

hermes_cli/profiles.py::_check_gateway_running open-coded rungs 1/3 of
gateway.status.resolve_gateway_liveness and skipped the multiplexer rung; it is now that ladder
scoped to the profile dir (pid probe keeps cleanup_stale=False so a probe for another profile
never unlinks its PID file). The gateway/status.py ladder itself is untouched.

Behavior change: `hermes kanban --preserve-cache --host 127.0.0.1 --port 0` and
`-m dashboard serve`-style argv are no longer classified as serve backends (never killed /
relaunched as one); a named profile served by the live default multiplexer now reads as
running from _check_gateway_running (previously only via the separate
_served_by_running_multiplexer OR at some call sites).
2026-09-13 05:21:02 -07:00

32 lines
1.3 KiB
Python

"""The QQ update-prompt authz key comes from ``build_session_key`` (profile-namespaced), not a
hard-coded ``agent:main:`` literal — a multiplexed secondary bot's clicks were rejected otherwise."""
from __future__ import annotations
from types import SimpleNamespace
from gateway.config import Platform
from gateway.platforms.qqbot.adapter import QQAdapter
from gateway.platforms.qqbot.keyboards import InteractionEvent
from gateway.session import SessionSource, build_session_key
def _adapter(owner_profile=None):
adapter = QQAdapter.__new__(QQAdapter)
adapter.config = SimpleNamespace(extra={})
adapter.platform = Platform.QQBOT
if owner_profile:
adapter._owner_profile = owner_profile
return adapter
def test_update_prompt_key_is_the_canonical_session_key_per_profile():
event = InteractionEvent(scene="c2c", user_openid="U1")
for profile in (None, "ops"):
adapter = _adapter(profile)
key = adapter._update_prompt_session_key(event, "U1")
source = SessionSource(platform=Platform.QQBOT, chat_id="U1", chat_type="c2c", profile=profile)
assert key == build_session_key(source, profile=profile)
assert adapter._is_authorized_interaction_for_session(event, key)
assert _adapter()._update_prompt_session_key(event, "U1") == "agent:main:qqbot:c2c:U1"