diff --git a/AGENTS.md b/AGENTS.md index dd45310ca86d..842f5c89ca30 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -40,7 +40,7 @@ hermes-agent/ │ │ # yuanbao, webhook, api_server, ...). See ADDING_A_PLATFORM.md. │ └── builtin_hooks/ # Extension point for always-registered gateway hooks (none shipped) ├── plugins/ # Plugin system (see "Plugins" section below) -│ ├── memory/ # Memory-provider plugins (honcho, mem0, supermemory, ...) +│ ├── memory/ # Memory-provider plugins (honcho, memgw, mem0, supermemory, ...) │ ├── context_engine/ # Context-engine plugins │ ├── model-providers/ # Inference backend plugins (openrouter, anthropic, gmi, ...) │ ├── kanban/ # Multi-agent board dispatcher + worker plugin @@ -513,7 +513,7 @@ explicitly (it's idempotent). ### Memory-provider plugins (`plugins/memory//`) Separate discovery system for pluggable memory backends. Current built-in -providers include **honcho, mem0, supermemory, byterover, hindsight, +providers include **honcho, memgw, mem0, supermemory, byterover, hindsight, holographic, openviking, retaindb**. Each provider implements the `MemoryProvider` ABC (see `agent/memory_provider.py`) @@ -546,6 +546,13 @@ landing in this tree. PRs that add a new directory under provider as its own repo. Existing in-tree providers stay; bug fixes to them are welcome. +**Fork exception:** `plugins/memory/memgw/` is intentionally bundled in this +fork because Memory Gateway is the owner's default backend and must be +available on every synced machine without per-host plugin installation. It +degrades to built-in memory when the `mcp` dependency or required gateway auth +is absent. If this fork is upstreamed, move `memgw` to a standalone user plugin +or pip entry point before submission. + ### Model-provider plugins (`plugins/model-providers//`) Every inference backend (openrouter, anthropic, gmi, deepseek, nvidia, …) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5b1ae34aa070..6fa9962d640b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -51,7 +51,7 @@ If your skill is specialized, community-contributed, or niche, it's better suite ## Memory Providers: Ship as a Standalone Plugin -**We are no longer accepting new memory providers into this repo.** The set of built-in providers under `plugins/memory/` (honcho, mem0, supermemory, byterover, hindsight, holographic, openviking, retaindb) is closed. If you want to add a new memory backend, publish it as a **standalone plugin repo** that users install into `~/.hermes/plugins/` (or via a pip entry point). +**We are no longer accepting new memory providers into this repo.** The set of built-in providers under `plugins/memory/` (honcho, memgw, mem0, supermemory, byterover, hindsight, holographic, openviking, retaindb) is closed. If you want to add a new memory backend, publish it as a **standalone plugin repo** that users install into `~/.hermes/plugins/` (or via a pip entry point). Standalone memory plugins: @@ -61,7 +61,7 @@ Standalone memory plugins: - Can register their own CLI subcommands via `register_cli(subparser)` in a `cli.py` file - Get all the same lifecycle hooks and config plumbing as in-tree providers -PRs that add a new directory under `plugins/memory/` will be closed with a pointer to publish the provider as its own repo. Existing in-tree providers stay; bug fixes to them are welcome. +PRs that add a new directory under `plugins/memory/` will be closed with a pointer to publish the provider as its own repo. Existing in-tree providers stay; bug fixes to them are welcome. `memgw` is a fork-specific exception because Memory Gateway is the owner's default backend and is intentionally synchronized with this fork. This isn't a quality bar — it's a coupling-and-maintenance decision. Memory providers are the most common plugin type and they shouldn't all live in this tree. diff --git a/plugins/memory/memgw/README.md b/plugins/memory/memgw/README.md index fec303d22e10..5f8fa1639282 100644 --- a/plugins/memory/memgw/README.md +++ b/plugins/memory/memgw/README.md @@ -2,8 +2,8 @@ Connects Hermes to the self-hosted **Memory Gateway** (Neo4j + Qdrant + Notion) over its Streamable-HTTP MCP endpoint. Unlike sealed memory backends, the -gateway fuses **semantic + keyword + graph** retrieval and grounds answers in a -knowledge graph and the Obsidian vault. +gateway combines **semantic + keyword** retrieval with graph context and grounds +answers in a knowledge graph and the Obsidian vault. ## Why this over a generic memory backend @@ -18,14 +18,15 @@ knowledge graph and the Obsidian vault. ## Tools exposed to the model -- `memgw_recall` — hybrid recall (semantic + keyword + graph fusion via RRF) +- `memgw_recall` — hybrid recall (semantic + keyword retrieval with graph context from the gateway) - `memgw_retain` — store a durable memory - `memgw_reflect` — synthesized beliefs (mental models) on a topic ## Auto behaviour - **prefetch** — background `recall` (or `reflect`) injected before each turn -- **sync_turn** — store completed turns (non-blocking, single-writer) +- **on_session_switch** — clear cached prefetch and invalidate in-flight workers +- **sync_turn** — store completed turns (non-blocking; all active writer threads are joined on shutdown) - **on_delegation** — record a subagent task+result as an `experience` - **on_session_end** — store a lightweight session summary @@ -43,12 +44,30 @@ export MEMGW_API_URL="https://mcp.danizhaky.com/mcp" # or http://localhost:808 export MEMGW_API_KEY="" # required for cloud mode ``` -Config can also live in `$HERMES_HOME/memgw.json`. +Config can also live in `$HERMES_HOME/memgw.json`. File values override +environment defaults: + +```json +{ + "api_url": "https://mcp.danizhaky.com/mcp", + "api_key": "...", + "recall_limit": 5, + "prefetch_method": "recall" +} +``` + +`prefetch_method` may be `recall`, `reflect`, or `off`. ### Modes - **Cloud** (default): hosted gateway at `mcp.danizhaky.com`, Bearer-authenticated. -- **Local**: point `MEMGW_API_URL` at a `localhost` gateway — no key required. +- **Local**: point `MEMGW_API_URL` at an exact loopback host (`localhost`, + `127.0.0.1`, or `::1`) — no key required. URLs that only contain + "localhost" in another component are not trusted. + +Gateway sessions pass `user_id` through recall and turn-sync calls so a shared +gateway can scope memory per chat user. Delegation and session-summary writes use +the provider's initialized user scope. A circuit breaker pauses calls for 120s after 5 consecutive failures so a gateway outage never blocks the turn loop; recall degrades gracefully to empty. diff --git a/website/docs/developer-guide/gateway-internals.md b/website/docs/developer-guide/gateway-internals.md index ebbe6c0e970f..bf646ccae6a3 100644 --- a/website/docs/developer-guide/gateway-internals.md +++ b/website/docs/developer-guide/gateway-internals.md @@ -212,11 +212,13 @@ Hooks are discovered from `gateway/builtin_hooks/` (an extension point — curre ## Memory Provider Integration -When a memory provider plugin (e.g., Honcho) is enabled: +When a memory provider plugin (for example Honcho or memgw) is enabled: 1. Gateway creates an `AIAgent` per message with the session ID -2. The `MemoryManager` initializes the provider with the session context -3. Provider tools (e.g., `honcho_profile`, `viking_search`) are routed through: +2. The `MemoryManager` initializes the provider with the session context and, + on multi-user platforms, the platform user ID +3. Provider tools (for example `honcho_profile`, `viking_search`, or + `memgw_recall`) are routed through: ```text AIAgent._invoke_tool() @@ -224,7 +226,17 @@ AIAgent._invoke_tool() → provider.handle_tool_call(name, args) ``` -4. On session end/reset, `on_session_end()` fires for cleanup and final data flush +4. After each turn, `sync_turn(..., session_id=..., user_id=...)` persists the + exchange when the provider implements it +5. Before the next turn, `queue_prefetch(..., session_id=..., user_id=...)` + can warm provider context without blocking the active response +6. On session switches, `on_session_switch()` lets providers clear + session-scoped caches before new context is injected +7. On session end/reset, `on_session_end()` fires for cleanup and final data flush + +Providers should pass `user_id` through to their backend when it supports +tenant/user scoping. This is especially important for shared gateway +deployments where multiple chat users may share one Hermes process. ### Memory Flush Lifecycle diff --git a/website/docs/developer-guide/memory-provider-plugin.md b/website/docs/developer-guide/memory-provider-plugin.md index d08022a44a15..b468af144ded 100644 --- a/website/docs/developer-guide/memory-provider-plugin.md +++ b/website/docs/developer-guide/memory-provider-plugin.md @@ -78,11 +78,19 @@ class MyMemoryProvider(MemoryProvider): | `prefetch(query)` | Before each API call | Return recalled context | | `queue_prefetch(query)` | After each turn | Pre-warm for next turn | | `sync_turn(user, assistant)` | After each completed turn | Persist conversation | +| `on_session_switch(new_session_id)` | Session resume/reset/switch | Clear stale per-session caches | +| `on_delegation(task, result)` | Subagent finishes | Persist delegated task outcomes | | `on_session_end(messages)` | Conversation ends | Final extraction/flush | | `on_pre_compress(messages)` | Before context compression | Save insights before discard | | `on_memory_write(action, target, content)` | Built-in memory writes | Mirror to your backend | | `shutdown()` | Process exit | Clean up connections | +Providers used by messaging gateways may also receive `session_id` and `user_id` +keyword arguments on `queue_prefetch()` and `sync_turn()`. Use these for +multi-user scoping instead of deriving identity from global process state. The +`memgw` provider is the reference pattern for an MCP-backed provider that bridges +an async client behind synchronous memory-provider hooks. + ## Config Schema `get_config_schema()` returns a list of field descriptors used by `hermes memory setup`: diff --git a/website/docs/integrations/index.md b/website/docs/integrations/index.md index 0b7ec938c17d..1c61c6534e16 100644 --- a/website/docs/integrations/index.md +++ b/website/docs/integrations/index.md @@ -76,7 +76,7 @@ Speech-to-text supports six providers: local faster-whisper (free, runs on-devic ## Memory & Personalization - **[Built-in Memory](/docs/user-guide/features/memory)** — Persistent, curated memory via `MEMORY.md` and `USER.md` files. The agent maintains bounded stores of personal notes and user profile data that survive across sessions. -- **[Memory Providers](/docs/user-guide/features/memory-providers)** — Plug in external memory backends for deeper personalization. Eight providers are supported: Honcho (dialectic reasoning), OpenViking (tiered retrieval), Mem0 (cloud extraction), Hindsight (knowledge graphs), Holographic (local SQLite), RetainDB (hybrid search), ByteRover (CLI-based), and Supermemory. +- **[Memory Providers](/docs/user-guide/features/memory-providers)** — Plug in external memory backends for deeper personalization. Nine providers are supported: memgw (Memory Gateway over MCP), Honcho (dialectic reasoning), OpenViking (tiered retrieval), Mem0 (cloud extraction), Hindsight (knowledge graphs), Holographic (local SQLite), RetainDB (hybrid search), ByteRover (CLI-based), and Supermemory. ## Messaging Platforms diff --git a/website/docs/reference/cli-commands.md b/website/docs/reference/cli-commands.md index 8a4f49f7353f..969842df0dce 100644 --- a/website/docs/reference/cli-commands.md +++ b/website/docs/reference/cli-commands.md @@ -987,7 +987,7 @@ See [Hooks](../user-guide/features/hooks.md) for event signatures and payload sh hermes memory ``` -Set up and manage external memory provider plugins. Available providers: honcho, openviking, mem0, hindsight, holographic, retaindb, byterover, supermemory. Only one external provider can be active at a time. Built-in memory (MEMORY.md/USER.md) is always active. +Set up and manage external memory provider plugins. Available providers: memgw, honcho, openviking, mem0, hindsight, holographic, retaindb, byterover, supermemory. Only one external provider can be active at a time. Built-in memory (MEMORY.md/USER.md) is always active. Subcommands: diff --git a/website/docs/reference/environment-variables.md b/website/docs/reference/environment-variables.md index 87c4f849b406..422edc57a2d7 100644 --- a/website/docs/reference/environment-variables.md +++ b/website/docs/reference/environment-variables.md @@ -153,6 +153,8 @@ For native Anthropic auth, Hermes prefers Claude Code's own credential files whe | `GITHUB_TOKEN` | GitHub token for Skills Hub (higher API rate limits, skill publish) | | `HONCHO_API_KEY` | Cross-session user modeling ([honcho.dev](https://honcho.dev/)) | | `HONCHO_BASE_URL` | Base URL for self-hosted Honcho instances (default: Honcho cloud). No API key required for local instances | +| `MEMGW_API_URL` | Memory Gateway MCP endpoint for the `memgw` memory provider (default: `https://mcp.danizhaky.com/mcp`). Base hosts are normalized to `/mcp`. | +| `MEMGW_API_KEY` | Bearer token for the `memgw` memory provider. Required for non-loopback endpoints; omitted only for exact loopback hosts (`localhost`, `127.0.0.1`, `::1`). | | `HINDSIGHT_TIMEOUT` | Timeout in seconds for Hindsight memory-provider API calls (default: `60`). Bump this if your Hindsight instance is slow to respond during `/sync` or `on_session_switch` and you're seeing timeouts in `errors.log`. | | `SUPERMEMORY_API_KEY` | Semantic long-term memory with profile recall and session ingest ([supermemory.ai](https://supermemory.ai)) | | `DAYTONA_API_KEY` | Daytona cloud sandboxes ([daytona.io](https://daytona.io/)) | diff --git a/website/docs/reference/tools-reference.md b/website/docs/reference/tools-reference.md index 2a85d0e18900..2f084af89b40 100644 --- a/website/docs/reference/tools-reference.md +++ b/website/docs/reference/tools-reference.md @@ -110,6 +110,10 @@ Scoped to the Feishu document-comment handler. Drives comment read/write operati **Honcho tools** (`honcho_profile`, `honcho_search`, `honcho_context`, `honcho_reasoning`, `honcho_conclude`) are no longer built-in. They are available via the Honcho memory provider plugin at `plugins/memory/honcho/`. See [Memory Providers](../user-guide/features/memory-providers.md) for installation and usage. ::: +::::note +**Memory Gateway tools** (`memgw_recall`, `memgw_retain`, `memgw_reflect`) are injected only when the `memgw` memory provider is active and available. They call the configured Memory Gateway MCP endpoint for hybrid recall, durable writes, and reflection. See [Memory Providers](../user-guide/features/memory-providers.md#memgw-memory-gateway) for setup, auth, and failure-mode details. +:::: + ## `image_gen` toolset | Tool | Description | Requires environment | diff --git a/website/docs/user-guide/features/memory-providers.md b/website/docs/user-guide/features/memory-providers.md index d4b4ff5fe86e..1d040a0b046d 100644 --- a/website/docs/user-guide/features/memory-providers.md +++ b/website/docs/user-guide/features/memory-providers.md @@ -1,12 +1,12 @@ --- sidebar_position: 4 title: "Memory Providers" -description: "External memory provider plugins — Honcho, OpenViking, Mem0, Hindsight, Holographic, RetainDB, ByteRover, Supermemory" +description: "External memory provider plugins — Honcho, memgw, OpenViking, Mem0, Hindsight, Holographic, RetainDB, ByteRover, Supermemory" --- # Memory Providers -Hermes Agent ships with 8 external memory provider plugins that give the agent persistent, cross-session knowledge beyond the built-in MEMORY.md and USER.md. Only **one** external provider can be active at a time — the built-in memory is always active alongside it. +Hermes Agent ships with 9 external memory provider plugins that give the agent persistent, cross-session knowledge beyond the built-in MEMORY.md and USER.md. Only **one** external provider can be active at a time — the built-in memory is always active alongside it. ## Quick Start @@ -22,7 +22,7 @@ Or set manually in `~/.hermes/config.yaml`: ```yaml memory: - provider: openviking # or honcho, mem0, hindsight, holographic, retaindb, byterover, supermemory + provider: memgw # or honcho, openviking, mem0, hindsight, holographic, retaindb, byterover, supermemory ``` ## How It Works @@ -40,6 +40,51 @@ The built-in memory (MEMORY.md / USER.md) continues to work exactly as before. T ## Available Providers +### memgw (Memory Gateway) + +Self-hosted Memory Gateway integration over Streamable-HTTP MCP. The gateway combines vector recall, exact-term recall, graph context, durable writes, and reflection in a backend shared with the `persistent-memory` service. + +| | | +|---|---| +| **Best for** | Teams that already operate the Memory Gateway and need exact entity/ID recall plus graph-grounded context | +| **Requires** | `mcp` package (`pip install hermes-agent[mcp]` or install the repo's `mcp` extra) + a Memory Gateway endpoint | +| **Data storage** | Self-hosted Memory Gateway (Neo4j + Qdrant + Notion/Obsidian integrations) | +| **Cost** | Free/self-hosted infrastructure cost | + +**Tools:** `memgw_recall` (hybrid recall), `memgw_retain` (write durable memory), `memgw_reflect` (synthesized beliefs / mental models). + +**Setup:** +```bash +hermes memory setup # select "memgw" +# Or manually: +hermes config set memory.provider memgw +echo 'MEMGW_API_URL=https://mcp.example.com/mcp' >> ~/.hermes/.env +echo 'MEMGW_API_KEY=***' >> ~/.hermes/.env +``` + +For local development, keyless mode is allowed only when `MEMGW_API_URL` parses to an exact loopback host: `localhost`, `127.0.0.1`, or `::1`. Cloud/non-loopback endpoints require `MEMGW_API_KEY`. + +**Config:** `$HERMES_HOME/memgw.json` overrides environment defaults. + +| Key | Default | Description | +|-----|---------|-------------| +| `api_url` | `https://mcp.danizhaky.com/mcp` | Memory Gateway MCP URL. A base host is normalized to `/mcp`. | +| `api_key` | empty | Bearer key. Required unless the parsed host is exact loopback. | +| `recall_limit` | `5` | Max results for automatic prefetch recall. Model-facing `memgw_recall` accepts an explicit `limit` up to 50. | +| `prefetch_method` | `recall` | Automatic prefetch mode: `recall`, `reflect`, or `off`. | + +**Automatic behavior:** +- Background prefetch runs after each turn and injects the latest completed recall before the next model call. +- Session switches clear cached prefetch output and invalidate in-flight workers, preventing stale context from a previous session. +- Completed turns and delegation outcomes are retained asynchronously; shutdown waits for tracked writers before closing the MCP client. +- Gateway sessions pass `user_id` into recall and write paths so shared deployments can scope memory per user. + +**Failure handling:** The provider is inert when `mcp` is not installed or auth is missing for a non-loopback URL. Runtime transport failures trip a circuit breaker after 5 consecutive failures and pause Memory Gateway calls for 120 seconds, returning graceful tool errors instead of blocking the agent loop. + +See the [plugin README](https://github.com/dizhaky/hermes-agent/blob/main/plugins/memory/memgw/README.md) for fork-specific notes and the [Memory Gateway backend](https://github.com/dizhaky/persistent-memory) for server operations. + +--- + ### Honcho AI-native cross-session user modeling with dialectic reasoning, session-scoped context injection, semantic search, and persistent conclusions. Base context now includes the session summary alongside user representation and peer cards, giving the agent awareness of what has already been discussed. @@ -526,6 +571,7 @@ echo 'SUPERMEMORY_API_KEY=***' >> ~/.hermes/.env | Provider | Storage | Cost | Tools | Dependencies | Unique Feature | |----------|---------|------|-------|-------------|----------------| +| **memgw** | Self-hosted | Free | 3 | `mcp` + gateway | Exact-term + semantic + graph-grounded recall | | **Honcho** | Cloud | Paid | 5 | `honcho-ai` | Dialectic user modeling + session-scoped context | | **OpenViking** | Self-hosted | Free | 5 | `openviking` + server | Filesystem hierarchy + tiered loading | | **Mem0** | Cloud | Paid | 3 | `mem0ai` | Server-side LLM extraction | @@ -540,7 +586,7 @@ echo 'SUPERMEMORY_API_KEY=***' >> ~/.hermes/.env Each provider's data is isolated per [profile](/docs/user-guide/profiles): - **Local storage providers** (Holographic, ByteRover) use `$HERMES_HOME/` paths which differ per profile -- **Config file providers** (Honcho, Mem0, Hindsight, Supermemory) store config in `$HERMES_HOME/` so each profile has its own credentials +- **Config file providers** (memgw, Honcho, Mem0, Hindsight, Supermemory) store config in `$HERMES_HOME/` so each profile has its own credentials - **Cloud providers** (RetainDB) auto-derive profile-scoped project names - **Env var providers** (OpenViking) are configured via each profile's `.env` file diff --git a/website/docs/user-guide/features/memory.md b/website/docs/user-guide/features/memory.md index 5c07df635782..ce575ec27b12 100644 --- a/website/docs/user-guide/features/memory.md +++ b/website/docs/user-guide/features/memory.md @@ -213,7 +213,7 @@ memory: ## External Memory Providers -For deeper, persistent memory that goes beyond MEMORY.md and USER.md, Hermes ships with 8 external memory provider plugins — including Honcho, OpenViking, Mem0, Hindsight, Holographic, RetainDB, ByteRover, and Supermemory. +For deeper, persistent memory that goes beyond MEMORY.md and USER.md, Hermes ships with 9 external memory provider plugins — including memgw, Honcho, OpenViking, Mem0, Hindsight, Holographic, RetainDB, ByteRover, and Supermemory. External providers run **alongside** built-in memory (never replacing it) and add capabilities like knowledge graphs, semantic search, automatic fact extraction, and cross-session user modeling. diff --git a/website/docs/user-guide/features/overview.md b/website/docs/user-guide/features/overview.md index 5ad06641540b..5d3a950e3b76 100644 --- a/website/docs/user-guide/features/overview.md +++ b/website/docs/user-guide/features/overview.md @@ -40,7 +40,7 @@ Hermes Agent includes a rich set of capabilities that extend far beyond basic ch - **[Fallback Providers](fallback-providers.md)** — Automatic failover to backup LLM providers when your primary model encounters errors, including independent fallback for auxiliary tasks like vision and compression. - **[Credential Pools](credential-pools.md)** — Distribute API calls across multiple keys for the same provider. Automatic rotation on rate limits or failures. - **[Prompt caching](../configuration#prompt-caching)** — Built-in cross-session 1-hour prefix cache for Claude on native Anthropic, OpenRouter, and Nous Portal. Always-on; no configuration required. -- **[Memory Providers](memory-providers.md)** — Plug in external memory backends (Honcho, OpenViking, Mem0, Hindsight, Holographic, RetainDB, ByteRover, Supermemory) for cross-session user modeling and personalization beyond the built-in memory system. +- **[Memory Providers](memory-providers.md)** — Plug in external memory backends (memgw, Honcho, OpenViking, Mem0, Hindsight, Holographic, RetainDB, ByteRover, Supermemory) for cross-session user modeling and personalization beyond the built-in memory system. - **[API Server](api-server.md)** — Expose Hermes as an OpenAI-compatible HTTP endpoint. Connect any frontend that speaks the OpenAI format — Open WebUI, LobeChat, LibreChat, and more. - **[IDE Integration (ACP)](acp.md)** — Use Hermes inside ACP-compatible editors such as VS Code, Zed, and JetBrains. Chat, tool activity, file diffs, and terminal commands render inside your editor. - **[RL Training](rl-training.md)** — Generate trajectory data from agent sessions for reinforcement learning and model fine-tuning.