mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-29 06:31:32 +00:00
fix(honcho): inherit identity-mapping config in cloned profile blocks
PR #27371 added host-scoped userPeerAliases, runtimePeerPrefix, and pinPeerName, but the cloned-profile allowlist in plugins/memory/honcho/cli.py::clone_honcho_for_profile() omitted them. A new profile created via 'hermes honcho setup' or similar would silently drop the operator's identity-mapping config, causing gateway users to resolve to raw runtime IDs and fragmenting Honcho memory across an unintended set of peers. Add the three keys to the allowlist and a regression test class covering all three plus the unset case.
This commit is contained in:
parent
30b391ab36
commit
00e6830204
2 changed files with 94 additions and 3 deletions
|
|
@ -40,12 +40,18 @@ def clone_honcho_for_profile(profile_name: str) -> bool:
|
|||
if new_host in hosts:
|
||||
return False # already exists
|
||||
|
||||
# Clone settings from default block, override identity fields
|
||||
# Clone settings from default block, override identity fields.
|
||||
# Identity-mapping keys (pinPeerName, userPeerAliases, runtimePeerPrefix)
|
||||
# carry the operator's runtime-to-peer routing intent from #27371.
|
||||
# Without them in this allowlist, a cloned profile would silently lose
|
||||
# the mapping and gateway users would resolve to raw runtime IDs,
|
||||
# fragmenting Honcho memory across an unintended set of peers.
|
||||
new_block = {}
|
||||
for key in ("recallMode", "writeFrequency", "sessionStrategy",
|
||||
"sessionPeerPrefix", "contextTokens", "dialecticReasoningLevel",
|
||||
"dialecticDynamic", "dialecticMaxChars", "messageMaxChars",
|
||||
"dialecticMaxInputChars", "saveMessages", "observation"):
|
||||
"dialecticMaxInputChars", "saveMessages", "observation",
|
||||
"pinPeerName", "userPeerAliases", "runtimePeerPrefix"):
|
||||
val = default_block.get(key)
|
||||
if val is not None:
|
||||
new_block[key] = val
|
||||
|
|
|
|||
|
|
@ -153,4 +153,89 @@ class TestCmdStatus:
|
|||
|
||||
out = capsys.readouterr().out
|
||||
assert "FAILED (Invalid API key)" in out
|
||||
assert "Connection... OK" not in out
|
||||
assert "Connection... OK" not in out
|
||||
|
||||
|
||||
class TestCloneHonchoForProfile:
|
||||
"""Regression tests for clone_honcho_for_profile identity-key carryover.
|
||||
|
||||
PR #27371 added userPeerAliases, runtimePeerPrefix, and pinPeerName as
|
||||
host-scoped identity-mapping config. These keys must survive profile
|
||||
cloning, otherwise a new profile silently fragments memory by resolving
|
||||
gateway users to raw runtime IDs instead of operator-declared peers.
|
||||
"""
|
||||
|
||||
def _setup_clone_env(self, monkeypatch, tmp_path, cfg):
|
||||
import plugins.memory.honcho.cli as honcho_cli
|
||||
cfg_path = tmp_path / "config.json"
|
||||
cfg_path.write_text("{}")
|
||||
monkeypatch.setattr(honcho_cli, "_read_config", lambda: cfg)
|
||||
monkeypatch.setattr(honcho_cli, "_config_path", lambda: cfg_path)
|
||||
monkeypatch.setattr(honcho_cli, "_local_config_path", lambda: cfg_path)
|
||||
monkeypatch.setattr(honcho_cli, "_ensure_peer_exists", lambda host_key=None: True)
|
||||
written = {}
|
||||
def _write(c, path=None):
|
||||
written["cfg"] = c
|
||||
monkeypatch.setattr(honcho_cli, "_write_config", _write)
|
||||
return honcho_cli, written
|
||||
|
||||
def test_user_peer_aliases_carry_into_cloned_profile(self, monkeypatch, tmp_path):
|
||||
cfg = {
|
||||
"apiKey": "***",
|
||||
"hosts": {
|
||||
"hermes": {
|
||||
"userPeerAliases": {"86701400": "eri", "discord-491827364": "eri"},
|
||||
"peerName": "eri",
|
||||
},
|
||||
},
|
||||
}
|
||||
honcho_cli, written = self._setup_clone_env(monkeypatch, tmp_path, cfg)
|
||||
ok = honcho_cli.clone_honcho_for_profile("coder")
|
||||
assert ok is True
|
||||
new_block = written["cfg"]["hosts"]["hermes.coder"]
|
||||
assert new_block["userPeerAliases"] == {"86701400": "eri", "discord-491827364": "eri"}
|
||||
|
||||
def test_runtime_peer_prefix_carries_into_cloned_profile(self, monkeypatch, tmp_path):
|
||||
cfg = {
|
||||
"apiKey": "***",
|
||||
"hosts": {
|
||||
"hermes": {
|
||||
"runtimePeerPrefix": "telegram_",
|
||||
"peerName": "eri",
|
||||
},
|
||||
},
|
||||
}
|
||||
honcho_cli, written = self._setup_clone_env(monkeypatch, tmp_path, cfg)
|
||||
ok = honcho_cli.clone_honcho_for_profile("coder")
|
||||
assert ok is True
|
||||
new_block = written["cfg"]["hosts"]["hermes.coder"]
|
||||
assert new_block["runtimePeerPrefix"] == "telegram_"
|
||||
|
||||
def test_pin_peer_name_carries_into_cloned_profile(self, monkeypatch, tmp_path):
|
||||
cfg = {
|
||||
"apiKey": "***",
|
||||
"hosts": {
|
||||
"hermes": {
|
||||
"pinPeerName": True,
|
||||
"peerName": "eri",
|
||||
},
|
||||
},
|
||||
}
|
||||
honcho_cli, written = self._setup_clone_env(monkeypatch, tmp_path, cfg)
|
||||
ok = honcho_cli.clone_honcho_for_profile("coder")
|
||||
assert ok is True
|
||||
new_block = written["cfg"]["hosts"]["hermes.coder"]
|
||||
assert new_block["pinPeerName"] is True
|
||||
|
||||
def test_unset_identity_keys_do_not_appear_in_cloned_profile(self, monkeypatch, tmp_path):
|
||||
cfg = {
|
||||
"apiKey": "***",
|
||||
"hosts": {"hermes": {"peerName": "eri"}},
|
||||
}
|
||||
honcho_cli, written = self._setup_clone_env(monkeypatch, tmp_path, cfg)
|
||||
ok = honcho_cli.clone_honcho_for_profile("coder")
|
||||
assert ok is True
|
||||
new_block = written["cfg"]["hosts"]["hermes.coder"]
|
||||
assert "userPeerAliases" not in new_block
|
||||
assert "runtimePeerPrefix" not in new_block
|
||||
assert "pinPeerName" not in new_block
|
||||
Loading…
Add table
Add a link
Reference in a new issue