From e467c0ef2cb4260e4e8d632330871f4a2d50c0b5 Mon Sep 17 00:00:00 2001 From: Erosika Date: Tue, 8 Sep 2026 16:12:06 -0400 Subject: [PATCH] fix(honcho): preview peer resolution through the runtime resolver peers map showed sanitize(prefix + user_id) for prefixed accounts. The runtime appends a sha256 suffix when sanitizing changed the id or it collides with an explicit peer, so the preview named a peer the gateway never writes to. The preview now builds a HonchoSessionManager with no client and asks it. --- plugins/memory/honcho/cli.py | 24 +++++++++++++++--------- tests/honcho_plugin/test_peers_map.py | 15 +++++++++++++++ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/plugins/memory/honcho/cli.py b/plugins/memory/honcho/cli.py index 62995b0b18..e9c9c500e6 100644 --- a/plugins/memory/honcho/cli.py +++ b/plugins/memory/honcho/cli.py @@ -1116,17 +1116,23 @@ def _preview_peer_resolution( user_id: str, *, pin: bool, aliases: dict, prefix: str, peer_name: str, user_id_alt: str = "", ) -> str: - """Mirror the runtime resolver ladder for display: pin → alias → prefix → raw.""" + """Resolve through the runtime resolver and label the rung that decided: pin, alias, prefix, raw. + Only the runtime knows when a prefixed id gets a hash suffix, so the CLI must not recompute it.""" + from plugins.memory.honcho.client import HonchoClientConfig + from plugins.memory.honcho.session import HonchoSessionManager + + config = HonchoClientConfig(peer_name=peer_name or None, pin_peer_name=bool(pin), + user_peer_aliases=aliases, runtime_peer_prefix=prefix) + manager = HonchoSessionManager(config=config, runtime_user_peer_name=user_id, + runtime_user_peer_name_alt=user_id_alt or None) + resolved = manager._resolve_user_peer_id("preview") if pin and peer_name: - return f"{_sanitize_peer_id(peer_name)} (pinned)" + return f"{resolved} (pinned)" # The runtime resolver tries the alt ID (Signal UUID, Feishu union_id) after the primary. - for rid in (user_id, user_id_alt): - alias = aliases.get(rid) if rid else None - if isinstance(alias, str) and alias.strip(): - return _sanitize_peer_id(alias.strip()) - if prefix: - return f"{_sanitize_peer_id(prefix + user_id)} (prefixed)" - return _sanitize_peer_id(user_id) + aliased = any(isinstance(aliases.get(rid), str) and aliases[rid].strip() for rid in (user_id, user_id_alt) if rid) + if not aliased and prefix.strip(): + return f"{resolved} (prefixed)" + return resolved def _resolution_base(resolved: str) -> str: diff --git a/tests/honcho_plugin/test_peers_map.py b/tests/honcho_plugin/test_peers_map.py index 57c9f253ff..f89f2726be 100644 --- a/tests/honcho_plugin/test_peers_map.py +++ b/tests/honcho_plugin/test_peers_map.py @@ -71,6 +71,21 @@ def test_preview_peer_resolution(user_id, kwargs, expected): assert _preview_peer_resolution(user_id, **kwargs) == expected +@pytest.mark.parametrize("user_id, peer_name", [("a:b", "eri"), ("111", "tg_111")], + ids=["sanitizing-changed-the-id", "collides-with-peer-name"]) +def test_prefixed_preview_matches_runtime_hash_suffix(user_id, peer_name): + """The runtime appends a hash when sanitizing changed the id or it collides with an explicit peer.""" + from plugins.memory.honcho.client import HonchoClientConfig + from plugins.memory.honcho.session import HonchoSessionManager + + manager = HonchoSessionManager( + config=HonchoClientConfig(peer_name=peer_name, runtime_peer_prefix="tg_"), runtime_user_peer_name=user_id, + ) + runtime = manager._resolve_user_peer_id("telegram:dm:1") + assert runtime.startswith(honcho_cli._sanitize_peer_id(f"tg_{user_id}") + "-") + assert _preview_peer_resolution(user_id, pin=False, aliases={}, prefix="tg_", peer_name=peer_name) == f"{runtime} (prefixed)" + + def _run_map(monkeypatch, tmp_path, *, answers, cfg, db_rows=(), ws_peers=None, workspaces=None): """Drive cmd_peers_map with scripted answers; returns what _write_config received.""" db = tmp_path / "state.db"