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
|
from honcho_integration.session import HonchoSessionManager
|
||||||
|
|
||||||
hcfg = HonchoClientConfig.from_global_config()
|
hcfg = HonchoClientConfig.from_global_config()
|
||||||
ai_mode = hcfg.peer_memory_mode(hcfg.ai_peer)
|
if not hcfg.enabled or not hcfg.api_key:
|
||||||
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"):
|
|
||||||
return None, hcfg
|
return None, hcfg
|
||||||
|
|
||||||
client = get_honcho_client(hcfg)
|
client = get_honcho_client(hcfg)
|
||||||
|
|
|
||||||
|
|
@ -131,9 +131,8 @@ def cmd_setup(args) -> None:
|
||||||
print(f"\n Memory mode options:")
|
print(f"\n Memory mode options:")
|
||||||
print(" hybrid — write to both Honcho and local MEMORY.md (default)")
|
print(" hybrid — write to both Honcho and local MEMORY.md (default)")
|
||||||
print(" honcho — Honcho only, skip MEMORY.md writes")
|
print(" honcho — Honcho only, skip MEMORY.md writes")
|
||||||
print(" local — MEMORY.md only, Honcho disabled")
|
|
||||||
new_mode = _prompt("Memory mode", default=current_mode)
|
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
|
hermes_host["memoryMode"] = new_mode
|
||||||
else:
|
else:
|
||||||
hermes_host["memoryMode"] = "hybrid"
|
hermes_host["memoryMode"] = "hybrid"
|
||||||
|
|
@ -369,7 +368,6 @@ def cmd_mode(args) -> None:
|
||||||
MODES = {
|
MODES = {
|
||||||
"hybrid": "write to both Honcho and local MEMORY.md (default)",
|
"hybrid": "write to both Honcho and local MEMORY.md (default)",
|
||||||
"honcho": "Honcho only — MEMORY.md writes disabled",
|
"honcho": "Honcho only — MEMORY.md writes disabled",
|
||||||
"local": "MEMORY.md only — Honcho disabled",
|
|
||||||
}
|
}
|
||||||
cfg = _read_config()
|
cfg = _read_config()
|
||||||
mode_arg = getattr(args, "mode", None)
|
mode_arg = getattr(args, "mode", None)
|
||||||
|
|
@ -384,7 +382,7 @@ def cmd_mode(args) -> None:
|
||||||
for m, desc in MODES.items():
|
for m, desc in MODES.items():
|
||||||
marker = " ←" if m == current else ""
|
marker = " ←" if m == current else ""
|
||||||
print(f" {m:<8} {desc}{marker}")
|
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
|
return
|
||||||
|
|
||||||
if mode_arg not in MODES:
|
if mode_arg not in MODES:
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ class HonchoClientConfig:
|
||||||
# Toggles
|
# Toggles
|
||||||
enabled: bool = False
|
enabled: bool = False
|
||||||
save_messages: bool = True
|
save_messages: bool = True
|
||||||
# memoryMode: default for all peers. "hybrid" / "honcho" / "local"
|
# memoryMode: default for all peers. "hybrid" / "honcho"
|
||||||
memory_mode: str = "hybrid"
|
memory_mode: str = "hybrid"
|
||||||
# Per-peer overrides — any named Honcho peer. Override memory_mode when set.
|
# Per-peer overrides — any named Honcho peer. Override memory_mode when set.
|
||||||
# Config object form: "memoryMode": { "default": "hybrid", "hermes": "honcho" }
|
# 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:
|
elif not hcfg.api_key:
|
||||||
logger.debug("Honcho enabled but no API key configured")
|
logger.debug("Honcho enabled but no API key configured")
|
||||||
else:
|
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:
|
except Exception as e:
|
||||||
logger.warning("Honcho init failed — memory disabled: %s", e)
|
logger.warning("Honcho init failed — memory disabled: %s", e)
|
||||||
print(f" Honcho init failed: {e}")
|
print(f" Honcho init failed: {e}")
|
||||||
|
|
@ -621,7 +621,7 @@ class AIAgent:
|
||||||
|
|
||||||
# Gate local memory writes based on per-peer memory modes.
|
# Gate local memory writes based on per-peer memory modes.
|
||||||
# AI peer governs MEMORY.md; user peer governs USER.md.
|
# 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:
|
if self._honcho_config and self._honcho:
|
||||||
_hcfg = self._honcho_config
|
_hcfg = self._honcho_config
|
||||||
_agent_mode = _hcfg.peer_memory_mode(_hcfg.ai_peer)
|
_agent_mode = _hcfg.peer_memory_mode(_hcfg.ai_peer)
|
||||||
|
|
@ -1349,10 +1349,7 @@ class AIAgent:
|
||||||
"""Return True when remote Honcho should be active."""
|
"""Return True when remote Honcho should be active."""
|
||||||
if not hcfg or not hcfg.enabled or not hcfg.api_key:
|
if not hcfg or not hcfg.enabled or not hcfg.api_key:
|
||||||
return False
|
return False
|
||||||
return not all(
|
return True
|
||||||
hcfg.peer_memory_mode(peer) == "local"
|
|
||||||
for peer in (hcfg.ai_peer, hcfg.peer_name or "user")
|
|
||||||
)
|
|
||||||
|
|
||||||
def _strip_honcho_tools_from_surface(self) -> None:
|
def _strip_honcho_tools_from_surface(self) -> None:
|
||||||
"""Remove Honcho tools from the active tool surface."""
|
"""Remove Honcho tools from the active tool surface."""
|
||||||
|
|
@ -1551,13 +1548,6 @@ class AIAgent:
|
||||||
"""Sync the user/assistant message pair to Honcho."""
|
"""Sync the user/assistant message pair to Honcho."""
|
||||||
if not self._honcho or not self._honcho_session_key:
|
if not self._honcho or not self._honcho_session_key:
|
||||||
return
|
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:
|
try:
|
||||||
session = self._honcho.get_or_create(self._honcho_session_key)
|
session = self._honcho.get_or_create(self._honcho_session_key)
|
||||||
session.add_message("user", user_content)
|
session.add_message("user", user_content)
|
||||||
|
|
@ -1656,7 +1646,7 @@ class AIAgent:
|
||||||
honcho_block += (
|
honcho_block += (
|
||||||
"Management commands (refer users here instead of explaining manually):\n"
|
"Management commands (refer users here instead of explaining manually):\n"
|
||||||
" hermes honcho status — show full config + connection\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 tokens [--context N] [--dialectic N] — show or set token budgets\n"
|
||||||
" hermes honcho peer [--user NAME] [--ai NAME] [--reasoning LEVEL]\n"
|
" hermes honcho peer [--user NAME] [--ai NAME] [--reasoning LEVEL]\n"
|
||||||
" hermes honcho sessions — list directory→session mappings\n"
|
" hermes honcho sessions — list directory→session mappings\n"
|
||||||
|
|
|
||||||
|
|
@ -64,14 +64,13 @@ class TestGatewayHonchoLifecycle:
|
||||||
assert second_cfg is hcfg
|
assert second_cfg is hcfg
|
||||||
mock_mgr_cls.assert_called_once()
|
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()
|
runner = _make_runner()
|
||||||
hcfg = SimpleNamespace(
|
hcfg = SimpleNamespace(
|
||||||
enabled=True,
|
enabled=False,
|
||||||
api_key="honcho-key",
|
api_key="honcho-key",
|
||||||
ai_peer="hermes",
|
ai_peer="hermes",
|
||||||
peer_name="alice",
|
peer_name="alice",
|
||||||
peer_memory_mode=lambda peer: "local",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
with (
|
with (
|
||||||
|
|
|
||||||
|
|
@ -123,12 +123,6 @@ class TestMemoryModeParsing:
|
||||||
cfg = HonchoClientConfig.from_global_config(config_path=cfg_file)
|
cfg = HonchoClientConfig.from_global_config(config_path=cfg_file)
|
||||||
assert cfg.memory_mode == "honcho"
|
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):
|
def test_defaults_to_hybrid(self, tmp_path):
|
||||||
cfg_file = tmp_path / "config.json"
|
cfg_file = tmp_path / "config.json"
|
||||||
cfg_file.write_text(json.dumps({"apiKey": "k"}))
|
cfg_file.write_text(json.dumps({"apiKey": "k"}))
|
||||||
|
|
@ -152,13 +146,11 @@ class TestMemoryModeParsing:
|
||||||
"hosts": {"hermes": {"memoryMode": {
|
"hosts": {"hermes": {"memoryMode": {
|
||||||
"default": "hybrid",
|
"default": "hybrid",
|
||||||
"hermes": "honcho",
|
"hermes": "honcho",
|
||||||
"sentinel": "local",
|
|
||||||
}}},
|
}}},
|
||||||
}))
|
}))
|
||||||
cfg = HonchoClientConfig.from_global_config(config_path=cfg_file)
|
cfg = HonchoClientConfig.from_global_config(config_path=cfg_file)
|
||||||
assert cfg.memory_mode == "hybrid"
|
assert cfg.memory_mode == "hybrid"
|
||||||
assert cfg.peer_memory_mode("hermes") == "honcho"
|
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
|
assert cfg.peer_memory_mode("unknown") == "hybrid" # falls through to default
|
||||||
|
|
||||||
def test_object_form_no_default_falls_back_to_hybrid(self, tmp_path):
|
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 = tmp_path / "config.json"
|
||||||
cfg_file.write_text(json.dumps({
|
cfg_file.write_text(json.dumps({
|
||||||
"apiKey": "k",
|
"apiKey": "k",
|
||||||
"memoryMode": "local",
|
"memoryMode": "honcho",
|
||||||
"hosts": {"hermes": {"memoryMode": {"default": "hybrid", "hermes": "honcho"}}},
|
"hosts": {"hermes": {"memoryMode": {"default": "hybrid", "hermes": "honcho"}}},
|
||||||
}))
|
}))
|
||||||
cfg = HonchoClientConfig.from_global_config(config_path=cfg_file)
|
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"
|
assert cfg.peer_memory_mode("hermes") == "honcho"
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -544,8 +536,8 @@ class TestNewConfigFieldDefaults:
|
||||||
assert cfg.peer_memory_mode("any-peer") == "honcho"
|
assert cfg.peer_memory_mode("any-peer") == "honcho"
|
||||||
|
|
||||||
def test_peer_memory_mode_override(self):
|
def test_peer_memory_mode_override(self):
|
||||||
cfg = HonchoClientConfig(memory_mode="hybrid", peer_memory_modes={"hermes": "local"})
|
cfg = HonchoClientConfig(memory_mode="hybrid", peer_memory_modes={"hermes": "honcho"})
|
||||||
assert cfg.peer_memory_mode("hermes") == "local"
|
assert cfg.peer_memory_mode("hermes") == "honcho"
|
||||||
assert cfg.peer_memory_mode("other") == "hybrid"
|
assert cfg.peer_memory_mode("other") == "hybrid"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1210,11 +1210,10 @@ class TestSystemPromptStability:
|
||||||
|
|
||||||
|
|
||||||
class TestHonchoActivation:
|
class TestHonchoActivation:
|
||||||
def test_local_mode_skips_honcho_init(self):
|
def test_disabled_config_skips_honcho_init(self):
|
||||||
hcfg = HonchoClientConfig(
|
hcfg = HonchoClientConfig(
|
||||||
enabled=True,
|
enabled=False,
|
||||||
api_key="honcho-key",
|
api_key="honcho-key",
|
||||||
memory_mode="local",
|
|
||||||
peer_name="user",
|
peer_name="user",
|
||||||
ai_peer="hermes",
|
ai_peer="hermes",
|
||||||
)
|
)
|
||||||
|
|
@ -1327,9 +1326,8 @@ class TestHonchoActivation:
|
||||||
|
|
||||||
def test_inactive_honcho_strips_stale_honcho_tools(self):
|
def test_inactive_honcho_strips_stale_honcho_tools(self):
|
||||||
hcfg = HonchoClientConfig(
|
hcfg = HonchoClientConfig(
|
||||||
enabled=True,
|
enabled=False,
|
||||||
api_key="honcho-key",
|
api_key="honcho-key",
|
||||||
memory_mode="local",
|
|
||||||
peer_name="user",
|
peer_name="user",
|
||||||
ai_peer="hermes",
|
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 |
|
| Content | Manually curated by the agent | Automatically learned from conversations |
|
||||||
| Write surface | `memory` tool (add/replace/remove) | `honcho_conclude` tool (persist facts) |
|
| 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
|
## Setup
|
||||||
|
|
@ -104,7 +104,7 @@ Settings are scoped to `hosts.hermes` and fall back to root-level globals when t
|
||||||
| `environment` | `"production"` | Honcho environment |
|
| `environment` | `"production"` | Honcho environment |
|
||||||
| `enabled` | *(auto)* | Auto-enables when API key is present |
|
| `enabled` | *(auto)* | Auto-enables when API key is present |
|
||||||
| `saveMessages` | `true` | Whether to sync messages to Honcho |
|
| `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 |
|
| `writeFrequency` | `"async"` | When to write: `async`, `turn`, `session`, or integer N |
|
||||||
| `recallMode` | `"hybrid"` | Retrieval strategy: `hybrid`, `context`, or `tools` |
|
| `recallMode` | `"hybrid"` | Retrieval strategy: `hybrid`, `context`, or `tools` |
|
||||||
| `sessionStrategy` | `"per-session"` | How sessions are scoped |
|
| `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) |
|
| `hybrid` | Write to both Honcho and local files (default) |
|
||||||
| `honcho` | Honcho only — skip local file writes |
|
| `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):
|
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": {
|
"memoryMode": {
|
||||||
"default": "hybrid",
|
"default": "hybrid",
|
||||||
"hermes": "honcho",
|
"hermes": "honcho"
|
||||||
"user": "local"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
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
|
### 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 --ai NAME # Set AI peer name
|
||||||
hermes honcho peer --reasoning LEVEL # Set dialectic reasoning level
|
hermes honcho peer --reasoning LEVEL # Set dialectic reasoning level
|
||||||
hermes honcho mode # Show current memory mode
|
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 # Show token budget settings
|
||||||
hermes honcho tokens --context N # Set context token cap
|
hermes honcho tokens --context N # Set context token cap
|
||||||
hermes honcho tokens --dialectic N # Set dialectic char cap
|
hermes honcho tokens --dialectic N # Set dialectic char cap
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue