mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
refactor(honcho): remove local memory mode
The "local" memoryMode was redundant with enabled: false. Simplifies the mode system to hybrid and honcho only.
This commit is contained in:
parent
f896bb5d8c
commit
ae2a5e5743
8 changed files with 22 additions and 49 deletions
|
|
@ -287,9 +287,7 @@ class GatewayRunner:
|
|||
from honcho_integration.session import HonchoSessionManager
|
||||
|
||||
hcfg = HonchoClientConfig.from_global_config()
|
||||
ai_mode = hcfg.peer_memory_mode(hcfg.ai_peer)
|
||||
user_mode = hcfg.peer_memory_mode(hcfg.peer_name or "user")
|
||||
if not hcfg.enabled or not hcfg.api_key or (ai_mode == "local" and user_mode == "local"):
|
||||
if not hcfg.enabled or not hcfg.api_key:
|
||||
return None, hcfg
|
||||
|
||||
client = get_honcho_client(hcfg)
|
||||
|
|
|
|||
|
|
@ -131,9 +131,8 @@ def cmd_setup(args) -> None:
|
|||
print(f"\n Memory mode options:")
|
||||
print(" hybrid — write to both Honcho and local MEMORY.md (default)")
|
||||
print(" honcho — Honcho only, skip MEMORY.md writes")
|
||||
print(" local — MEMORY.md only, Honcho disabled")
|
||||
new_mode = _prompt("Memory mode", default=current_mode)
|
||||
if new_mode in ("hybrid", "honcho", "local"):
|
||||
if new_mode in ("hybrid", "honcho"):
|
||||
hermes_host["memoryMode"] = new_mode
|
||||
else:
|
||||
hermes_host["memoryMode"] = "hybrid"
|
||||
|
|
@ -369,7 +368,6 @@ def cmd_mode(args) -> None:
|
|||
MODES = {
|
||||
"hybrid": "write to both Honcho and local MEMORY.md (default)",
|
||||
"honcho": "Honcho only — MEMORY.md writes disabled",
|
||||
"local": "MEMORY.md only — Honcho disabled",
|
||||
}
|
||||
cfg = _read_config()
|
||||
mode_arg = getattr(args, "mode", None)
|
||||
|
|
@ -384,7 +382,7 @@ def cmd_mode(args) -> None:
|
|||
for m, desc in MODES.items():
|
||||
marker = " ←" if m == current else ""
|
||||
print(f" {m:<8} {desc}{marker}")
|
||||
print(f"\n Set with: hermes honcho mode [hybrid|honcho|local]\n")
|
||||
print(f"\n Set with: hermes honcho mode [hybrid|honcho]\n")
|
||||
return
|
||||
|
||||
if mode_arg not in MODES:
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ class HonchoClientConfig:
|
|||
# Toggles
|
||||
enabled: bool = False
|
||||
save_messages: bool = True
|
||||
# memoryMode: default for all peers. "hybrid" / "honcho" / "local"
|
||||
# memoryMode: default for all peers. "hybrid" / "honcho"
|
||||
memory_mode: str = "hybrid"
|
||||
# Per-peer overrides — any named Honcho peer. Override memory_mode when set.
|
||||
# Config object form: "memoryMode": { "default": "hybrid", "hermes": "honcho" }
|
||||
|
|
|
|||
18
run_agent.py
18
run_agent.py
|
|
@ -607,7 +607,7 @@ class AIAgent:
|
|||
elif not hcfg.api_key:
|
||||
logger.debug("Honcho enabled but no API key configured")
|
||||
else:
|
||||
logger.debug("Honcho local-only mode active; remote Honcho init skipped")
|
||||
logger.debug("Honcho enabled but missing API key or disabled in config")
|
||||
except Exception as e:
|
||||
logger.warning("Honcho init failed — memory disabled: %s", e)
|
||||
print(f" Honcho init failed: {e}")
|
||||
|
|
@ -621,7 +621,7 @@ class AIAgent:
|
|||
|
||||
# Gate local memory writes based on per-peer memory modes.
|
||||
# AI peer governs MEMORY.md; user peer governs USER.md.
|
||||
# "honcho" = Honcho only, disable local; "local" = local only, no Honcho sync.
|
||||
# "honcho" = Honcho only, disable local writes.
|
||||
if self._honcho_config and self._honcho:
|
||||
_hcfg = self._honcho_config
|
||||
_agent_mode = _hcfg.peer_memory_mode(_hcfg.ai_peer)
|
||||
|
|
@ -1349,10 +1349,7 @@ class AIAgent:
|
|||
"""Return True when remote Honcho should be active."""
|
||||
if not hcfg or not hcfg.enabled or not hcfg.api_key:
|
||||
return False
|
||||
return not all(
|
||||
hcfg.peer_memory_mode(peer) == "local"
|
||||
for peer in (hcfg.ai_peer, hcfg.peer_name or "user")
|
||||
)
|
||||
return True
|
||||
|
||||
def _strip_honcho_tools_from_surface(self) -> None:
|
||||
"""Remove Honcho tools from the active tool surface."""
|
||||
|
|
@ -1551,13 +1548,6 @@ class AIAgent:
|
|||
"""Sync the user/assistant message pair to Honcho."""
|
||||
if not self._honcho or not self._honcho_session_key:
|
||||
return
|
||||
# Skip Honcho sync only if BOTH peer modes are local
|
||||
_cfg = self._honcho_config
|
||||
if _cfg and all(
|
||||
_cfg.peer_memory_mode(p) == "local"
|
||||
for p in (_cfg.ai_peer, _cfg.peer_name or "user")
|
||||
):
|
||||
return
|
||||
try:
|
||||
session = self._honcho.get_or_create(self._honcho_session_key)
|
||||
session.add_message("user", user_content)
|
||||
|
|
@ -1656,7 +1646,7 @@ class AIAgent:
|
|||
honcho_block += (
|
||||
"Management commands (refer users here instead of explaining manually):\n"
|
||||
" hermes honcho status — show full config + connection\n"
|
||||
" hermes honcho mode [hybrid|honcho|local] — show or set memory mode\n"
|
||||
" hermes honcho mode [hybrid|honcho] — show or set memory mode\n"
|
||||
" hermes honcho tokens [--context N] [--dialectic N] — show or set token budgets\n"
|
||||
" hermes honcho peer [--user NAME] [--ai NAME] [--reasoning LEVEL]\n"
|
||||
" hermes honcho sessions — list directory→session mappings\n"
|
||||
|
|
|
|||
|
|
@ -64,14 +64,13 @@ class TestGatewayHonchoLifecycle:
|
|||
assert second_cfg is hcfg
|
||||
mock_mgr_cls.assert_called_once()
|
||||
|
||||
def test_gateway_skips_honcho_manager_in_local_mode(self):
|
||||
def test_gateway_skips_honcho_manager_when_disabled(self):
|
||||
runner = _make_runner()
|
||||
hcfg = SimpleNamespace(
|
||||
enabled=True,
|
||||
enabled=False,
|
||||
api_key="honcho-key",
|
||||
ai_peer="hermes",
|
||||
peer_name="alice",
|
||||
peer_memory_mode=lambda peer: "local",
|
||||
)
|
||||
|
||||
with (
|
||||
|
|
|
|||
|
|
@ -123,12 +123,6 @@ class TestMemoryModeParsing:
|
|||
cfg = HonchoClientConfig.from_global_config(config_path=cfg_file)
|
||||
assert cfg.memory_mode == "honcho"
|
||||
|
||||
def test_local_only(self, tmp_path):
|
||||
cfg_file = tmp_path / "config.json"
|
||||
cfg_file.write_text(json.dumps({"apiKey": "k", "memoryMode": "local"}))
|
||||
cfg = HonchoClientConfig.from_global_config(config_path=cfg_file)
|
||||
assert cfg.memory_mode == "local"
|
||||
|
||||
def test_defaults_to_hybrid(self, tmp_path):
|
||||
cfg_file = tmp_path / "config.json"
|
||||
cfg_file.write_text(json.dumps({"apiKey": "k"}))
|
||||
|
|
@ -152,13 +146,11 @@ class TestMemoryModeParsing:
|
|||
"hosts": {"hermes": {"memoryMode": {
|
||||
"default": "hybrid",
|
||||
"hermes": "honcho",
|
||||
"sentinel": "local",
|
||||
}}},
|
||||
}))
|
||||
cfg = HonchoClientConfig.from_global_config(config_path=cfg_file)
|
||||
assert cfg.memory_mode == "hybrid"
|
||||
assert cfg.peer_memory_mode("hermes") == "honcho"
|
||||
assert cfg.peer_memory_mode("sentinel") == "local"
|
||||
assert cfg.peer_memory_mode("unknown") == "hybrid" # falls through to default
|
||||
|
||||
def test_object_form_no_default_falls_back_to_hybrid(self, tmp_path):
|
||||
|
|
@ -177,11 +169,11 @@ class TestMemoryModeParsing:
|
|||
cfg_file = tmp_path / "config.json"
|
||||
cfg_file.write_text(json.dumps({
|
||||
"apiKey": "k",
|
||||
"memoryMode": "local",
|
||||
"memoryMode": "honcho",
|
||||
"hosts": {"hermes": {"memoryMode": {"default": "hybrid", "hermes": "honcho"}}},
|
||||
}))
|
||||
cfg = HonchoClientConfig.from_global_config(config_path=cfg_file)
|
||||
assert cfg.memory_mode == "hybrid" # host default wins over global "local"
|
||||
assert cfg.memory_mode == "hybrid" # host default wins over global "honcho"
|
||||
assert cfg.peer_memory_mode("hermes") == "honcho"
|
||||
|
||||
|
||||
|
|
@ -544,8 +536,8 @@ class TestNewConfigFieldDefaults:
|
|||
assert cfg.peer_memory_mode("any-peer") == "honcho"
|
||||
|
||||
def test_peer_memory_mode_override(self):
|
||||
cfg = HonchoClientConfig(memory_mode="hybrid", peer_memory_modes={"hermes": "local"})
|
||||
assert cfg.peer_memory_mode("hermes") == "local"
|
||||
cfg = HonchoClientConfig(memory_mode="hybrid", peer_memory_modes={"hermes": "honcho"})
|
||||
assert cfg.peer_memory_mode("hermes") == "honcho"
|
||||
assert cfg.peer_memory_mode("other") == "hybrid"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1210,11 +1210,10 @@ class TestSystemPromptStability:
|
|||
|
||||
|
||||
class TestHonchoActivation:
|
||||
def test_local_mode_skips_honcho_init(self):
|
||||
def test_disabled_config_skips_honcho_init(self):
|
||||
hcfg = HonchoClientConfig(
|
||||
enabled=True,
|
||||
enabled=False,
|
||||
api_key="honcho-key",
|
||||
memory_mode="local",
|
||||
peer_name="user",
|
||||
ai_peer="hermes",
|
||||
)
|
||||
|
|
@ -1327,9 +1326,8 @@ class TestHonchoActivation:
|
|||
|
||||
def test_inactive_honcho_strips_stale_honcho_tools(self):
|
||||
hcfg = HonchoClientConfig(
|
||||
enabled=True,
|
||||
enabled=False,
|
||||
api_key="honcho-key",
|
||||
memory_mode="local",
|
||||
peer_name="user",
|
||||
ai_peer="hermes",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ Hermes has two memory systems that can work together or be configured separately
|
|||
| Content | Manually curated by the agent | Automatically learned from conversations |
|
||||
| Write surface | `memory` tool (add/replace/remove) | `honcho_conclude` tool (persist facts) |
|
||||
|
||||
Set `memoryMode` to `honcho` to use Honcho exclusively, or `local` to disable Honcho and use only local files. See [Memory Modes](#memory-modes) for per-peer configuration.
|
||||
Set `memoryMode` to `honcho` to use Honcho exclusively. See [Memory Modes](#memory-modes) for per-peer configuration.
|
||||
|
||||
|
||||
## Setup
|
||||
|
|
@ -104,7 +104,7 @@ Settings are scoped to `hosts.hermes` and fall back to root-level globals when t
|
|||
| `environment` | `"production"` | Honcho environment |
|
||||
| `enabled` | *(auto)* | Auto-enables when API key is present |
|
||||
| `saveMessages` | `true` | Whether to sync messages to Honcho |
|
||||
| `memoryMode` | `"hybrid"` | Memory mode: `hybrid`, `honcho`, or `local` |
|
||||
| `memoryMode` | `"hybrid"` | Memory mode: `hybrid` or `honcho` |
|
||||
| `writeFrequency` | `"async"` | When to write: `async`, `turn`, `session`, or integer N |
|
||||
| `recallMode` | `"hybrid"` | Retrieval strategy: `hybrid`, `context`, or `tools` |
|
||||
| `sessionStrategy` | `"per-session"` | How sessions are scoped |
|
||||
|
|
@ -122,7 +122,6 @@ All host-level fields fall back to the equivalent root-level key if not set unde
|
|||
|------|--------|
|
||||
| `hybrid` | Write to both Honcho and local files (default) |
|
||||
| `honcho` | Honcho only — skip local file writes |
|
||||
| `local` | Local files only — skip all Honcho activity |
|
||||
|
||||
Memory mode can be set globally or per-peer (user, agent1, agent2, etc):
|
||||
|
||||
|
|
@ -130,13 +129,12 @@ Memory mode can be set globally or per-peer (user, agent1, agent2, etc):
|
|||
{
|
||||
"memoryMode": {
|
||||
"default": "hybrid",
|
||||
"hermes": "honcho",
|
||||
"user": "local"
|
||||
"hermes": "honcho"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
When both active peers resolve to `local`, Hermes skips all remote Honcho activity entirely — no client initialization, no session creation, no prefetch.
|
||||
To disable Honcho entirely, set `enabled: false` or remove the API key.
|
||||
|
||||
### Recall Modes
|
||||
|
||||
|
|
@ -300,7 +298,7 @@ hermes honcho peer --user NAME # Set user peer name
|
|||
hermes honcho peer --ai NAME # Set AI peer name
|
||||
hermes honcho peer --reasoning LEVEL # Set dialectic reasoning level
|
||||
hermes honcho mode # Show current memory mode
|
||||
hermes honcho mode [hybrid|honcho|local] # Set memory mode
|
||||
hermes honcho mode [hybrid|honcho] # Set memory mode
|
||||
hermes honcho tokens # Show token budget settings
|
||||
hermes honcho tokens --context N # Set context token cap
|
||||
hermes honcho tokens --dialectic N # Set dialectic char cap
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue