Metadata-Version: 2.4
Name: hermes-memoryrouter
Version: 0.1.1
Summary: MemoryRouter memory provider for Hermes Agent: persistent, cross-session conversation memory. Stores clean user/assistant exchanges and recalls relevant memories before each turn.
Author-email: John Rood <john@johnrood.com>
License: MIT License
        
        Copyright (c) 2026 John Rood
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Homepage, https://memoryrouter.ai/hermes
Project-URL: Documentation, https://docs.memoryrouter.ai/hermes
Project-URL: Repository, https://github.com/John-Rood/hermes-memoryrouter
Keywords: hermes,hermes-agent,nous,memory,memoryrouter,ai-memory,persistent-memory,agent-memory
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Dynamic: license-file

# Persistent memory for Hermes Agent

[![PyPI](https://img.shields.io/pypi/v/hermes-memoryrouter)](https://pypi.org/project/hermes-memoryrouter/)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)

Persistent conversational memory for [Nous Research Hermes Agent](https://github.com/NousResearch/hermes-agent), powered by [MemoryRouter](https://memoryrouter.ai/hermes). Your agent can remember what you told it yesterday across sessions, without you manually curating every useful detail into a memory file. Hermes already has persistent MEMORY.md and USER.md files. This native memory provider adds automatic capture of conversational exchanges and relevant recall from your MemoryRouter vault.

**Tested against `hermes-agent==0.19.0`, the current PyPI release on September 8, 2026, with Python 3.12.** Hermes 0.19.0 requires Python 3.11 through 3.13. Python 3.14 can silently resolve an older Hermes release, so use a supported Python version.

## 30-second install

Requires a working [Hermes Agent](https://github.com/NousResearch/hermes-agent) install. Use the same Python environment as Hermes. [Create a MemoryRouter account and get your key](https://app.memoryrouter.ai/signup?utm_source=github&utm_medium=readme&utm_campaign=hermes), then export `MEMORYROUTER_API_KEY` in the shell where you run Hermes.

```sh
pip install hermes-memoryrouter
hermes-memoryrouter install
hermes config set memory.provider memoryrouter
```

The installer copies the packaged provider into `${HERMES_HOME:-~/.hermes}/plugins/memoryrouter/`. Hermes 0.19.0 discovers memory providers from this directory, not from pip entry points. Re-run the install command after upgrading the package.

The package also declares `hermes_agent.memory_providers` with `memoryrouter = "hermes_memoryrouter:register"` for Hermes versions that support memory-provider entry points. On those versions, pip install plus the config command is sufficient. The directory install remains a fallback.

Manual equivalent if you do not want to use the helper:

```sh
export HERMES_HOME="${HERMES_HOME:-$HOME/.hermes}"
mkdir -p "$HERMES_HOME/plugins/memoryrouter"
cp -R "$(python -c 'import hermes_memoryrouter,pathlib; print(pathlib.Path(hermes_memoryrouter.__file__).parent)')/." "$HERMES_HOME/plugins/memoryrouter/"
hermes config set memory.provider memoryrouter
```

## API key

The plugin never reads the macOS Keychain. Key lookup order:

1. `MEMORYROUTER_API_KEY` in the environment
2. `MEMORYROUTER_API_KEY_FILE` pointing to a mode-0600 file
3. `$HERMES_HOME/memoryrouter.key` (mode 0600)
4. `MEMORYROUTER_API_KEY=` inside `$HERMES_HOME/.env`

Without a key the provider is idle. To use a file instead of an environment variable:

```sh
export HERMES_HOME="${HERMES_HOME:-$HOME/.hermes}"
umask 077
printf '%s\n' 'YOUR_MEMORYROUTER_KEY' > "$HERMES_HOME/memoryrouter.key"
chmod 600 "$HERMES_HOME/memoryrouter.key"
hermes memory status
```

`hermes memory setup` is also available for interactive configuration. Keep your model provider and model key as configured in Hermes. This plugin supplies memory, not model inference.

## How it works

- **Capture:** stores clean user messages and final assistant replies after completed turns.
- **Recall:** retrieves relevant past conversation context before each turn, bounded by a 2.5-second default timeout and a 24,000-character cap.
- **Filter:** excludes tool results, tool calls, thinking blocks, system text, and recalled-memory wrappers from capture.
- **Fail open:** memory errors do not crash a conversation. Recall can delay a turn up to its timeout; capture runs in the background.

This is a native Hermes `MemoryProvider`, not OpenClaw's `mr-memory` plugin. Completed conversational exchanges are sent to the MemoryRouter account behind your key. Only configure it for conversations you want stored there.

## Configuration

Non-secret settings live in `$HERMES_HOME/memoryrouter.json`. The setup wizard only asks for the key.

| Option | Default | Description |
|--------|---------|-------------|
| `base_url` | `https://api.memoryrouter.ai` | API endpoint. Also `MEMORYROUTER_BASE_URL`. |
| `density` | `default` | Retrieval density: `low` / `default` / `high` / `xhigh`. |
| `vault` | `core` | `core` shares memories across sessions. `session` isolates each conversation via `X-Session-ID`. |
| `auto_recall` | `true` | Inject relevant memories before each turn. |
| `auto_capture` | `true` | Store completed exchanges. |
| `include_subagents` | `false` | Also store subagent turns. |
| `recall_limit` | `0` | Explicit chunk-count override (0 = server default). |
| `recall_max_chars` | `24000` | Hard bound on the injected recall block. |
| `store_max_chars` | `8000` | Per-side bound on stored text. |
| `store_timeout` | `10` | Seconds per store attempt. |
| `recall_timeout` | `2.5` | Max seconds recall may delay a turn. |
| `debug` | `false` | Verbose logging. |

## How capture works

Hermes calls `sync_turn(user, assistant, messages=...)` after each completed turn. The plugin:

1. Takes the user and assistant strings Hermes already split out.
2. Strips `<system-reminder>`, `<memory_context>`, thinking tags, and tool-call XML.
3. Drops slash commands (`/new`, `/status`, …) and trivial prompts (`ok`, `thanks`, `hi`).
4. If either side is empty, falls back to the last clean user/assistant pair in `messages`, ignoring tool and system roles.
5. Truncates each side and POSTs `{messages:[{role:user},{role:assistant}]}` to `/v1/memory/ingest` on a daemon thread.

Recall uses `/v1/memory/prepare` with the current user text as the query. Results are wrapped in `<memoryrouter-context>` so they cannot be re-ingested.

By default (`vault: core`) exchanges go to the key's core vault, so session B can recall what session A stored. That is the point of persistent memory.

## CLI

When `memory.provider` is `memoryrouter`:

```sh
hermes memoryrouter status
hermes memoryrouter config
```

## Development

```sh
python -m pytest -q
```

Unit tests are offline (local HTTP mock). The release gate also runs actual Hermes conversations in two separate Python processes with GPT-4.1 mini and no enabled toolsets. A unique token taught in session A must appear exactly in session B, whose prompt does not contain the token. The gate is repeated from a fresh PyPI install after publishing. `scripts/live_cross_session.py` is a separate lower-level provider smoke test.

## License

[MIT](./LICENSE) © John Rood · [memoryrouter.ai](https://memoryrouter.ai)
