mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-06 02:37:05 +08:00
feat(memory): add pluggable memory provider interface
Introduces MemoryProvider ABC, MemoryManager orchestrator, and BuiltinMemoryProvider for the existing MEMORY.md/USER.md system. Key design decisions: - Built-in memory is ALWAYS active, never disabled by external providers - Multiple providers can be active simultaneously - Prefetch results from all providers are merged per-turn - Sync fans out to all providers after each turn - Each provider can expose its own tools Three registration paths: 1. Built-in (BuiltinMemoryProvider) — always first, not removable 2. First-party (Honcho stays as-is for now, migration in follow-up) 3. Plugin — ctx.register_memory_provider() in plugin system Files: - agent/memory_provider.py — ABC with core + optional lifecycle hooks - agent/memory_manager.py — orchestrator, single integration point - agent/builtin_memory_provider.py — wraps existing MemoryStore - hermes_cli/plugins.py — register_memory_provider() + accessor - run_agent.py — MemoryManager wired alongside existing Honcho code - tests/agent/test_memory_provider.py — 37 tests This establishes the interface for all pending memory backend PRs (#1811 Hindsight, #2732 RetainDB, #2933 Mem0, #3499 Byterover, #3369 OpenViking, #2351 Holographic, #727 Cognitive) to implement as plugins rather than one-off integrations.
This commit is contained in:
@@ -152,6 +152,28 @@ class PluginContext:
|
||||
self._manager._plugin_tool_names.add(name)
|
||||
logger.debug("Plugin %s registered tool: %s", self.manifest.name, name)
|
||||
|
||||
# -- memory provider registration ----------------------------------------
|
||||
|
||||
def register_memory_provider(self, provider) -> None:
|
||||
"""Register a memory provider (must implement MemoryProvider ABC).
|
||||
|
||||
The provider will be added to the MemoryManager during agent init.
|
||||
Providers registered this way are additive — they never disable
|
||||
the built-in MEMORY.md/USER.md store.
|
||||
|
||||
Example plugin __init__.py::
|
||||
|
||||
from my_memory_backend import MyMemoryProvider
|
||||
|
||||
def register(ctx):
|
||||
ctx.register_memory_provider(MyMemoryProvider())
|
||||
"""
|
||||
self._manager._memory_providers.append(provider)
|
||||
logger.debug(
|
||||
"Plugin %s registered memory provider: %s",
|
||||
self.manifest.name, getattr(provider, "name", "unknown"),
|
||||
)
|
||||
|
||||
# -- hook registration --------------------------------------------------
|
||||
|
||||
def register_hook(self, hook_name: str, callback: Callable) -> None:
|
||||
@@ -183,6 +205,7 @@ class PluginManager:
|
||||
self._plugins: Dict[str, LoadedPlugin] = {}
|
||||
self._hooks: Dict[str, List[Callable]] = {}
|
||||
self._plugin_tool_names: Set[str] = set()
|
||||
self._memory_providers: List = [] # MemoryProvider instances from plugins
|
||||
self._discovered: bool = False
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
@@ -528,3 +551,13 @@ def get_plugin_toolsets() -> List[tuple]:
|
||||
result.append((ts_key, label, desc))
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def get_plugin_memory_providers() -> List:
|
||||
"""Return MemoryProvider instances registered by plugins.
|
||||
|
||||
Called during AIAgent init to add plugin memory providers to
|
||||
the MemoryManager alongside built-in providers.
|
||||
"""
|
||||
manager = get_plugin_manager()
|
||||
return list(manager._memory_providers)
|
||||
|
||||
Reference in New Issue
Block a user