Memory

Memory Manager

The component that orchestrates built-in and external memory providers.

Memory Manager

What it is

The component that orchestrates built-in and external memory providers.

In plain terms

Picture a research lab that keeps its own logbook, written into directly by whoever’s on shift, but the lab has, at most, one partner lab it shares results with — a runner photocopies each new logbook page and carries it over there, never splitting the same delivery between two competing partners at once. MemoryManager plays that runner’s role inside Hermes: the built-in notebook is written to directly by the memory tool, and MemoryManager plugs in, at most, one outside memory service — asking it for anything relevant before each turn and forwarding it a copy of whatever the notebook just saved.

Why it matters

MemoryManager sits between Hermes’s built-in memory store and, optionally, a single external provider — plugins like mem0, hindsight, or supermemory plug in here rather than replacing the built-in system wholesale. When an external provider is active, MemoryManager is also what injects that provider’s own tools into the agent’s available toolset, so the model can call them directly rather than going through an abstraction layer. Capping external providers at one keeps memory backend choice a deliberate configuration decision rather than something that silently stacks.

How it works

MemoryManager stitches together whatever it’s given (agent/memory_manager.py) — but it holds at most one provider, an external plugin; the built-in MEMORY.md/USER.md store lives outside it, read and written directly by the memory tool. Before each turn, prefetch_all() asks the registered provider for relevant context; once a turn finishes, sync_all() hands the completed exchange to a single background worker thread, so a slow or stuck provider — one was observed hanging nearly five minutes — can never freeze the conversation. Whenever the built-in memory tool commits a write, the agent loop separately notifies MemoryManager, which mirrors that entry out to whichever external provider is active. Tool schemas from every provider get merged into one list, with built-in tool names such as clarify always winning over anything a provider tries to register under the same name, and a second external provider is rejected outright with a logged warning rather than silently stacking.

A concrete example

A user runs Hermes with mem0 configured as the external memory provider. Behind the scenes, MemoryManager does three things:

  1. Before each turn, it asks mem0 — the one provider it manages — for anything relevant to the incoming message; the built-in notebook’s own contribution is separate, already baked into the system prompt at session start.
  2. Once the assistant replies, it queues the finished exchange to a background thread, so mem0’s own write never delays the next message.
  3. If the user later tries to also enable Honcho as a second external provider, MemoryManager logs a rejection and keeps mem0 as the only external backend.

How it connects

This note belongs to the Memory family. Its closest neighboring concepts are: Memory, Memory Provider, Agent Runtime, Personal OS.

Source evidence

  • vendor/hermes-agent/agent/memory_manager.py:505-515#MemoryManager.prefetch_all — Verified Source Map evidence for MemoryManager. MemoryManager calls prefetch on each registered provider in order, skips empty results, isolates individual provider failures, and merges the remaining text.

Workflows

  • No first-pass workflow mapping yet; this concept still appears in the vault graph through articles and source evidence.
  • No article currently mentions this concept by name/alias often enough to qualify (see mention-mining policy).