mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-08 13:12:08 +00:00
fix(mem0): make prompt label + platform setup honor host routing precedence
Follow-up on the salvaged #55614. The PR added host-based routing to _create_backend (precedence: oss > host > platform) but two sibling surfaces didn't mirror it: - system_prompt_block() checked host before oss, so an oss+host config ran OSS but told the model it was self-hosted HTTP. Reordered to match routing. - Platform setup (hermes memory setup mem0 --mode platform) left a stale host in mem0.json; since host beats platform, the user kept routing to the self-hosted server. save_config merges (no delete), so clear host to "" rather than pop() so the merge actually overwrites it. Adds regression tests for both (mutation-checked).
This commit is contained in:
parent
2a14205ff4
commit
53edf6f983
4 changed files with 42 additions and 5 deletions
|
|
@ -373,12 +373,16 @@ class Mem0MemoryProvider(MemoryProvider):
|
|||
return {"channel": self._channel} if self._channel else {}
|
||||
|
||||
def system_prompt_block(self) -> str:
|
||||
if self._host:
|
||||
mode_label = "self-hosted (HTTP API)"
|
||||
elif self._mode == "platform":
|
||||
mode_label = "platform (cloud API)"
|
||||
else:
|
||||
# Mirror the precedence in _create_backend (oss > host > platform) so
|
||||
# the label always names the backend that actually runs. Checking
|
||||
# ``host`` first here would mislabel an ``oss``+``host`` config as
|
||||
# self-hosted HTTP even though OSS wins the routing.
|
||||
if self._mode == "oss":
|
||||
mode_label = "OSS (self-hosted)"
|
||||
elif self._host:
|
||||
mode_label = "self-hosted (HTTP API)"
|
||||
else:
|
||||
mode_label = "platform (cloud API)"
|
||||
# Rerank is a Mem0 Platform feature only.
|
||||
rerank_note = " Rerank is available on search." if (self._mode == "platform" and not self._host) else ""
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -293,6 +293,13 @@ def _setup_platform(hermes_home: str, config: dict, flags: dict[str, str]) -> No
|
|||
return
|
||||
|
||||
provider_config["mode"] = "platform"
|
||||
# Clear any stale self-hosted host: routing checks ``host`` before platform
|
||||
# (see _create_backend), so leaving it would silently keep routing to the
|
||||
# self-hosted server even though the user just chose platform mode. Set it
|
||||
# to "" rather than pop() — save_config merges into the existing mem0.json
|
||||
# (existing.update), so a popped key would survive; an empty value overwrites
|
||||
# it and reads as falsy at routing time.
|
||||
provider_config["host"] = ""
|
||||
|
||||
from hermes_cli.config import save_config
|
||||
config["memory"]["provider"] = "mem0"
|
||||
|
|
|
|||
|
|
@ -179,6 +179,22 @@ class TestPostSetup:
|
|||
mem0_json = json.loads((tmp_path / "mem0.json").read_text())
|
||||
assert mem0_json["mode"] == "platform"
|
||||
|
||||
def test_platform_setup_clears_stale_host(self, tmp_path, monkeypatch):
|
||||
# A user who previously ran self-hosted has host in mem0.json. Switching
|
||||
# to platform must drop host — otherwise routing (host > platform) keeps
|
||||
# sending them to the self-hosted server despite --mode platform.
|
||||
(tmp_path / "mem0.json").write_text(
|
||||
json.dumps({"mode": "platform", "host": "http://old-selfhosted:8888"})
|
||||
)
|
||||
monkeypatch.setattr("sys.argv", ["hermes", "--mode", "platform", "--api-key", "sk-test"])
|
||||
monkeypatch.setattr("plugins.memory.mem0._setup.get_hermes_home", lambda: tmp_path)
|
||||
_inject_fake_hermes_cli(monkeypatch)
|
||||
config = {"memory": {}}
|
||||
post_setup(str(tmp_path), config)
|
||||
mem0_json = json.loads((tmp_path / "mem0.json").read_text())
|
||||
assert mem0_json["mode"] == "platform"
|
||||
assert not mem0_json.get("host") # cleared to falsy so routing → platform
|
||||
|
||||
def test_oss_flag_mode(self, tmp_path, monkeypatch):
|
||||
monkeypatch.setattr("sys.argv", [
|
||||
"hermes", "--mode", "oss", "--oss-llm-key", "sk-oai",
|
||||
|
|
|
|||
|
|
@ -581,6 +581,16 @@ class TestCreateBackendRouting:
|
|||
provider = self._provider(monkeypatch, mode="oss", host="http://sh:8888")
|
||||
assert isinstance(provider._create_backend(), OB)
|
||||
|
||||
def test_prompt_label_matches_routing_when_oss_and_host_both_set(self, monkeypatch):
|
||||
# system_prompt_block must mirror _create_backend precedence: with both
|
||||
# mode=oss and host set, OSS wins the routing, so the prompt must label
|
||||
# OSS — not "self-hosted (HTTP API)". Guards the prompt-vs-routing lie.
|
||||
provider = self._provider(monkeypatch, mode="oss", host="http://sh:8888")
|
||||
provider._user_id = "test"
|
||||
block = provider.system_prompt_block()
|
||||
assert "OSS" in block
|
||||
assert "HTTP API" not in block
|
||||
|
||||
|
||||
class TestSelfHostedConfig:
|
||||
"""Config plumbing for self-hosted (MEM0_HOST env + is_available)."""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue