All plugins

upstash

Long-term memory and searchable chat history for Hermes on Upstash Redis Search (BM25, no vector database or embeddings). Recalls related memories into each turn, saves every session as a searchable transcript, mirrors the built-in memory tool (adds, corrections and removals), and gives the model upstash_memory_save / upstash_memory_search / upstash_memory_forget and upstash_chat_search. Memories use the same keys as @upstash/agentkit-sdk, so they are shared with AgentKit apps on the same database. Works on the Upstash Free plan (one search index). Disclosure — memories and full chat transcripts are written to the Upstash Redis database you configure (UPSTASH_REDIS_REST_URL / UPSTASH_REDIS_REST_TOKEN) and sent to it over HTTPS on every turn; nothing else is contacted. Telemetry is opt-in and off by default: UPSTASH_HERMES_TELEMETRY=1 adds SDK, Python version and platform tags to request headers sent to that same database.

UpstashMemoryv0.2.2Updated 1 hour ago

About

Long-term memory and searchable chat history for Hermes on Upstash Redis Search (BM25, no vector database or embeddings). Recalls related memories into each turn, saves every session as a searchable transcript, mirrors the built-in memory tool (adds, corrections and removals), and gives the model upstash_memory_save / upstash_memory_search / upstash_memory_forget and upstash_chat_search. Memories use the same keys as @upstash/agentkit-sdk, so they are shared with AgentKit apps on the same database. Works on the Upstash Free plan (one search index). Disclosure — memories and full chat transcripts are written to the Upstash Redis database you configure (UPSTASH_REDIS_REST_URL / UPSTASH_REDIS_REST_TOKEN) and sent to it over HTTPS on every turn; nothing else is contacted. Telemetry is opt-in and off by default: UPSTASH_HERMES_TELEMETRY=1 adds SDK, Python version and platform tags to request headers sent to that same database.

upstash-hermes-memory

An Upstash Redis memory provider for Hermes Agent, built on
the same Redis Search layout as @upstash/agentkit-sdk's AgentMemory and ChatHistory. A memory
your AI SDK app saves is recalled by your Hermes agent, and the other way round.

What it does in Hermes

  • Recall: before each turn, the memories closest to the user's message are added to the prompt.
  • Chat history: after each turn, the turn is appended in place to the session's searchable
    transcript document, so a write stays the size of one turn however long the session runs.
  • Mirroring: facts the built-in memory tool adds are also saved to Redis, and when Hermes
    corrects (replace/patch) or removes one, the Redis copy is updated or deleted too.
  • Tools: upstash_memory_save, upstash_memory_search, upstash_memory_forget and
    upstash_chat_search (search past conversations).

Subagents, cron jobs and context flushes can read memory but never write it.

Setup

# into the Python environment Hermes runs in
pip install upstash-hermes-memory

Then select it in Hermes's config.yaml:

memory:
  provider: upstash

And give it a database, in your environment or ~/.hermes/.env (hermes memory setup asks for
these):

| Variable | |
| --- | --- |
| UPSTASH_REDIS_REST_URL, UPSTASH_REDIS_REST_TOKEN | Required. From the Upstash console. |
| UPSTASH_HERMES_USER_ID | Whose memories these are. Defaults to the gateway user, then the Hermes profile name, then default. |
| UPSTASH_HERMES_NAMESPACE | Key namespace. Default agentkit, so memories sit at the TS SDK's default keys and are shared with AgentKit apps on the same database. |
| UPSTASH_HERMES_TELEMETRY | Set to 1 to send telemetry. Off by default; see Telemetry. |

Telemetry

Off by default. Set UPSTASH_HERMES_TELEMETRY=1 to opt in: requests to your Upstash database then
carry upstash-hermes-memory@<version> in the Upstash-Telemetry-Sdk header, next to the
upstash-redis client's own telemetry headers (SDK version, Python version, platform). Nothing
else is collected and nothing goes anywhere but your database. Without the opt-in the provider
creates its Redis client with allow_telemetry=False, so none of these headers are sent.
UPSTASH_DISABLE_TELEMETRY=1 turns telemetry off even when opted in.

Redis layout

| | Key | Value |
| --- | --- | --- |
| Memory | agentkit:memory:<user>:<id> | JSON {text, userId, createdAt, ...metadata}, as the TS SDK writes it |
| Chat | agentkit:chat:<user>:<session> | JSON {kind: "chat", userId, sessionId, userMessages, modelMessages, messages, createdAt, updatedAt} |

Memory and chats share one search index, agentkit, covering both prefixes, so the provider
works on Upstash's Free plan, which allows one index per database. An AgentKit TS app on the same
database still creates its own memory index, so using both needs a plan with more than one index.

User and session ids are used as they are, so the same id reads the same keys from Hermes and the
TS SDK. Like the TS SDK, the provider refuses a user id with : (the key separator), and keeps no
transcript for a session id with one. Indexes are created on first use. AgentMemory and ChatHistory are importable on their own for
use outside Hermes.

Development

uv sync --all-packages && pnpm py:lint && pnpm py:test   # Redis tests need UPSTASH_REDIS_REST_* set
uv run python python/hermes-memory/e2e/hermes_e2e.py     # a real Hermes session, needs OPENAI_API_KEY

The e2e script installs the package into a temporary directory and runs Hermes with a temporary
HERMES_HOME, so your own Hermes install is not touched. Hermes's built-in memory is turned off
there. One session saves two facts; a fresh session started right after must name them without
calling any tool (checked in Hermes's state.db), so they can only come from the automatic recall;
and a control session as another user must not know them. The script then checks the keys and
transcripts in Redis (and, if packages/sdk is built, that the TS AgentMemory recalls them too)
before cleaning up.

README from the reviewed commit 1a18931; it updates when the author re-pins.

More by Upstash

2 plugins by Upstash in the catalog.