Skip to content

feat(memory): introduce MemoryProvider protocol and registry for long-term memory integrations#3958

Closed
danhdoan wants to merge 1 commit into
NousResearch:mainfrom
danhdoan:feat/memory-provider-interface
Closed

feat(memory): introduce MemoryProvider protocol and registry for long-term memory integrations#3958
danhdoan wants to merge 1 commit into
NousResearch:mainfrom
danhdoan:feat/memory-provider-interface

Conversation

@danhdoan

Copy link
Copy Markdown

What does this PR do?

Introduces a MemoryProvider protocol and MemoryProviderRegistry that define a standard lifecycle contract for long-term memory integrations in Hermes Agent.

Currently, Honcho is wired directly into AIAgent in run_agent.py with ~250 lines of inline code scattered across 20+ locations. There is no abstract interface — adding a second memory provider would require inserting new if/else blocks into every one of those locations, and a third provider would triple the wiring. This PR establishes the interface so that future memory integrations (and eventually Honcho itself) can plug in through a clean registry without modifying core agent code.

The interface was designed by tracing every Honcho integration point in the current codebase to ensure full compatibility. See the linked issue for the detailed analysis, provider mapping table, and migration plan.

This PR adds the interface and tests only. No existing code is modified. No behavioral changes.

Related Issue

Implemented #3943

Type of Change

  • ✨ New feature (non-breaking change that adds functionality)
  • ✅ Tests (adding or improving test coverage)

Changes Made

  • agent/memory/__init__.py — Package public API re-exports
  • agent/memory/protocol.pyMemoryProvider Protocol with 9 methods: name, is_available, initialize, shutdown, capabilities, enrich_turn, on_memory_write, on_turn_complete, on_compress
  • agent/memory/registry.pyMemoryProviderRegistry with parallel execution (ThreadPoolExecutor), error isolation, and enforced deadlines (5s enrichment, 120s compression, 15s shutdown)
  • agent/memory/context.py — Context sanitization helpers (sanitize_context, build_memory_context_block, inject_memory_context) for centralized prompt injection defense
  • tests/agent/test_memory.py — 58 tests covering protocol conformance, registry lifecycle, capabilities, parallel enrichment with deadlines, error isolation, threading contracts, shutdown idempotency, and context sanitization

How to Test

  1. python -m pytest tests/agent/test_memory.py -v — all 58 tests should pass
  2. python -m pytest tests/ -q — no existing tests should be affected (no existing code modified)
  3. Verify no import of agent.memory exists anywhere in the codebase outside of the new files and tests

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: macOS Darwin 25.3.0

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — protocol.py contains full API documentation in docstrings
  • I've updated cli-config.yaml.example if I added/changed config keys — N/A (no config changes)
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — N/A (interface only, no architectural changes to existing code)
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — uses only stdlib threading and concurrent.futures, no platform-specific code
  • I've updated tool descriptions/schemas if I changed tool behavior — N/A (no tool changes)

…term memory integrations

Add agent/memory/ package defining a lifecycle contract for memory
providers (Honcho, ByteRover, future integrations). The interface
replaces the current pattern of hardwiring each integration directly
into AIAgent with scattered if/else blocks.

The package provides:

- MemoryProvider Protocol (9 methods): is_available, initialize,
  shutdown, capabilities, enrich_turn, on_memory_write,
  on_turn_complete, on_compress, and name property

- MemoryProviderRegistry: orchestrates multiple providers with
  parallel execution (ThreadPoolExecutor with deadlines), error
  isolation (_safe_call wrapper), and enforced deadlines for
  enrichment (5s), compression flush (120s), and shutdown (15s)

- Context sanitization helpers: sanitize_context,
  build_memory_context_block, inject_memory_context — centralized
  prompt injection defense via <memory-context> fencing

Design decisions:
- Protocol over ABC (duck-typing, no forced inheritance)
- One registry per AIAgent (not a singleton — gateway-safe)
- Providers are smart, registry is thin (no assembly logic)
- Non-daemon threads for on_compress (must complete before
  messages are permanently discarded)
- Daemon threads for on_memory_write and on_turn_complete
  (fire-and-forget, acceptable to lose)

No existing code modified. No behavioral changes. 58 tests.
@danhdoan danhdoan force-pushed the feat/memory-provider-interface branch from a2f2b47 to c64d716 Compare March 30, 2026 14:50
@danhdoan danhdoan changed the title feat(agent): introduce MemoryProvider protocol and registry for long-term memory integrations feat(memory): introduce MemoryProvider protocol and registry for long-term memory integrations Mar 30, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the thorough analysis and well-structured PR, @danhdoan! This automated hermes-sweeper review found that the interface you proposed has since been implemented on main.

What landed:

  • agent/memory_provider.pyMemoryProvider ABC with full lifecycle contract (is_available, initialize, shutdown, prefetch, sync_turn, on_memory_write, get_tool_schemas, handle_tool_call, and optional hooks)
  • agent/memory_manager.py — orchestration/registry layer with parallel execution and error isolation
  • agent/memory_manager.py:58sanitize_context and build_memory_context_block context helpers
  • plugins/memory/__init__.py — plugin discovery system (discover_memory_providers, load_memory_provider, user-installed provider scanning)

Merged: commit 924bc67e on 2026-04-02 (PR #4623), shipped in v2026.4.3.

Your design analysis in the linked issue #3943 and the method-level mapping you did were genuinely valuable — they clearly informed the shape of the final interface. If you want to contribute further, the memory plugin ecosystem (plugins/memory/) is actively growing and would welcome new providers or improvements to existing ones.

This is an automated review by hermes-sweeper.

@teknium1 teknium1 closed this Apr 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants