Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 48 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,50 @@
# nvidia-nat-redis
<div align="center">
<img src="assets/redis-logo.svg" alt="Redis" width="175px">

Redis Agent Memory integrations for
[NVIDIA NeMo Agent Toolkit](https://github.com/NVIDIA/NeMo-Agent-Toolkit).
# Nvidia-NAT-Redis
</div>

This standalone plugin exposes two NAT surfaces:
**Redis-backed memory for [NVIDIA NeMo Agent Toolkit](https://github.com/NVIDIA/NeMo-Agent-Toolkit)** — production [Redis Agent Memory](https://redis.github.io/agent-memory-server/quick-start/) integrations plus direct Redis plugins (the historical `nat.plugins.redis` stack).

1. `_type: redis_agent_memory_backend`
Redis Agent Memory as a NAT `MemoryEditor` long-term memory backend.
2. `_type: redis_agent_memory_auto_memory`
A native Redis Agent Memory wrapper that uses working memory plus
`memory_prompt` hydration on every turn.
In NAT, long-term recall is usually wired through memory tools such as `get_memory` and `add_memory`, which delegate to a **`MemoryEditor`** implementation. This package adds Redis-backed options in **two families**: **Redis Agent Memory** (AMS over HTTP — richer lifecycle, optional auto-memory workflow) and **direct Redis** (JSON + vector search or plain KV inside `nat.plugins.redis`, no AMS).

This repo is the standalone home for integrations that used to ship under
[`packages/nvidia_nat_redis`](https://github.com/NVIDIA/NeMo-Agent-Toolkit/tree/develop/packages/nvidia_nat_redis) in the NeMo Agent Toolkit monorepo.

### Redis Agent Memory (full stack)
1. `_type: redis_agent_memory_backend` — Redis Agent Memory as a NAT `MemoryEditor` long-term memory backend.
2. `_type: redis_agent_memory_auto_memory` — A native Redis Agent Memory wrapper that uses working memory plus
`memory_prompt` hydration on every turn.
AMS runs as a separate service; these surfaces talk to it via the agent-memory client.

1. `_type: redis_agent_memory_backend` — Redis Agent Memory behind NAT’s standard **`MemoryEditor`** contract (fits tool-driven long-term memory).
2. `_type: redis_agent_memory_auto_memory` — A **`workflow` wrapper** (not just another editor): working memory, `memory_prompt` hydration every turn, turn capture, and promotion — the fullest AMS-shaped integration.

### Direct Redis (simple in-Redis memory)

Loaded via the `nat_redis` setuptools entry point (same name as the historical
monorepo package):

- `_type: redis_memory` — Vector search over JSON documents in Redis (RediSearch); requires a workflow `embedder` and Redis Stack (or Redis with search + JSON support). Implements **`MemoryEditor`**-style semantic memory without AMS.
- `_type: redis` — NAT **object store** on plain Redis key–value storage (not semantic long-term memory).

| | **Redis Agent Memory** | **Direct Redis** |
| --- | --- | --- |
| **Runs** | AMS service + Redis | Redis only (your NAT process uses the client) |
| **Best for** | Learning-style memory, working memory, AMS filters and APIs | Lightweight Redis-native memory or KV object store |
| **Tradeoff** | Operate AMS; HTTP path | Simpler ops for `redis` / `redis_memory`; vector path needs embedder + search-capable Redis |

Use **Redis Agent Memory** when you want the Redis Agent Memory feature set.
Use **`redis_memory`** when you only need a lightweight Redis-native `MemoryEditor`
without AMS.

### Python imports (same as NeMo)

Direct Redis support is implemented only under **`nat.plugins.redis`** (for example
`from nat.plugins.redis.redis_editor import RedisEditor`), matching NeMo Agent
Toolkit. The setuptools entry point **`nat_redis`** loads
`nat.plugins.redis.register`. Redis Agent Memory code lives under
**`nvidia_nat_redis.redis_agent_memory`**.


## Install
Expand All @@ -30,9 +65,13 @@ uv sync --group dev --extra test

- Use `_type: redis_agent_memory_backend` when your workflow already uses NAT memory tools and you want Redis Agent Memory behind the standard `MemoryEditor` contract.
- Use `_type: redis_agent_memory_auto_memory` when you want Redis Agent Memory to own working-memory continuity, prompt hydration, and turn capture on every request. This exposes the richness of Redis Agent Memory in its fullest form.
- Use `_type: redis_memory` when you want the simpler direct-Redis memory from NeMo Agent Toolkit (Redis JSON + vector index, no Redis Agent Memory). You must configure an `embedder` reference and run a Redis deployment that supports the search commands used by the plugin.
- Use `_type: redis` when you need NAT’s Redis-backed **object store** (KV), not vector or AMS-backed semantic memory.

## Integration Modes

These examples cover the two **Redis Agent Memory** integration shapes (`MemoryEditor` backend vs `workflow` wrapper). For **`redis_memory`** / **`redis`**, see [Configuration reference](docs/configuration.md).

### Direct Long-Term Memory Backend

Use `_type: redis_agent_memory_backend` when you want Redis Agent Memory behind NAT's
Expand Down
66 changes: 66 additions & 0 deletions assets/redis-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
66 changes: 63 additions & 3 deletions docs/configuration.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
# Configuration

This package ships two Redis Agent Memory surfaces for NAT:
This package ships Redis Agent Memory surfaces and direct Redis plugins (migrated
from the NeMo Agent Toolkit `nvidia_nat_redis` package).

1. A long-term memory backend: `_type: redis_agent_memory_backend`
2. A native automatic wrapper: `_type: redis_agent_memory_auto_memory`
Redis Agent Memory is a production-ready agent memory layer that extracts and stores
relevant information and learns over time.

Direct Redis memory provides a more standard semantic memory layer for LLM applications.

**Full Redis Agent Memory auto wrapper**

1. Long-term memory backend: `_type: redis_agent_memory_backend`
2. Native automatic wrapper: `_type: redis_agent_memory_auto_memory`
Comment thread
justin-cechmanek marked this conversation as resolved.

**Direct Redis (entry point `nat_redis` → `nat.plugins.redis.register`)**

3. In-Redis vector memory: `_type: redis_memory`
4. Object store: `_type: redis`

For Python code, use **`nat.plugins.redis.*`** — the same module layout as NeMo
Agent Toolkit’s in-tree package.

## Long-Term Memory Backend

Expand Down Expand Up @@ -116,6 +132,50 @@ Wrapper flow:
2. Create or load Redis Agent Memory working memory for that identity.
3. Call `memory_prompt(...)`, invoke the inner chat function with the hydrated request, and append the finished turn back into working memory.

## Direct Redis memory (`redis_memory`)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should have a good look at the readme -- maybe dream a bit with codex/claude -- to think about how to make it easier, and clearer to understand that there are two redis memory types here and some different flavors. Maybe we LEAD with the plugin approach (MemoryEditor) and then underneath list the two options and clearly highlight tradeoffs of each and how they work.

I also think we need a bit more front matter (maybe logos) and hype to draw a bit more attention when landing on the readme. Thanks!!!

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made some additions to the README. Let me know what you think


Use `_type: redis_memory` for the lightweight Redis-backed `MemoryEditor` that
stores JSON documents and uses RediSearch vector queries. This matches the
behavior of the standalone
[`nvidia_nat_redis` package in NeMo Agent Toolkit](https://github.com/NVIDIA/NeMo-Agent-Toolkit/tree/develop/packages/nvidia_nat_redis).

Requirements:

- Redis with **JSON** and **search** (for example Redis Stack), because the implementation creates a JSON index and runs vector KNN queries.
- A workflow **embedder** instance; `embedder` must reference its name in the workflow configuration.

```yaml
memory:
redis_ltm:
_type: redis_memory
host: localhost
port: 6379
db: 0
key_prefix: nat
embedder: my_openai_embedder
```

Supported config fields:

- `host`, `port`, `db`, `password` (optional secret), `key_prefix`
- `embedder`: `EmbedderRef` to a configured embedder (LangChain wrapper)

## Direct Redis object store (`redis`)

Use `_type: redis` for the NAT object store that persists `ObjectStoreItem`
JSON at keys under `nat/object_store/{bucket_name}/...`, with optional TTL.

```yaml
object_store:
artifacts:
_type: redis
host: localhost
port: 6379
db: 0
bucket_name: my_bucket
ttl: 3600
```

## Examples

- [Redis Agent Memory native wrapper](../examples/agent_auto_memory/README.md)
Expand Down
2 changes: 1 addition & 1 deletion examples/agent_auto_memory/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ The example expects:

## Start Services

Compose starts Redis Stack and Agent Memory Server for local development. Both
Compose starts Redis Stack and Redis Agent Memory containers for local development. Both
ports bind to `127.0.0.1`, and AMS auth is disabled.

```bash
Expand Down
5 changes: 4 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ classifiers = [
]
dependencies = [
"agent-memory-client>=0.14.0,<1.0.0",
"langchain-core>=0.3.0,<2.0.0",
"nvidia-nat-core>=1.5.0,<2.0.0",
"redis>=4.3.4,<5.0.0",
]

[project.optional-dependencies]
Expand All @@ -38,6 +40,7 @@ source = "https://github.com/redis-developer/nvidia-nat-redis"

[project.entry-points.'nat.components']
redis_agent_memory = "nvidia_nat_redis.redis_agent_memory.register"
nat_redis = "nat.plugins.redis.register"

[dependency-groups]
dev = [
Expand All @@ -47,7 +50,7 @@ dev = [

[tool.setuptools.packages.find]
where = ["src"]
include = ["nvidia_nat_redis*"]
include = ["nvidia_nat_redis*", "nat.plugins*"]

[tool.setuptools_scm]
git_describe_command = "git describe --long --first-parent"
Expand Down
16 changes: 16 additions & 0 deletions src/nat/plugins/redis/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Direct Redis memory and object-store NAT components (NeMo ``nat.plugins.redis`` layout)."""
60 changes: 60 additions & 0 deletions src/nat/plugins/redis/memory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from nat.builder.builder import Builder
from nat.cli.register_workflow import register_memory
from nat.data_models.common import OptionalSecretStr, get_secret_value
from nat.data_models.component_ref import EmbedderRef
from nat.data_models.memory import MemoryBaseConfig
from pydantic import Field


class RedisMemoryClientConfig(MemoryBaseConfig, name="redis_memory"):
host: str = Field(default="localhost", description="Redis server host")
db: int = Field(default=0, description="Redis DB")
port: int = Field(default=6379, description="Redis server port")
password: OptionalSecretStr = Field(default=None, description="Password for the Redis server")
key_prefix: str = Field(default="nat", description="Key prefix to use for redis keys")
embedder: EmbedderRef = Field(description=("Instance name of the memory client instance from the workflow "
"configuration object."))


@register_memory(config_type=RedisMemoryClientConfig)
async def redis_memory_client(config: RedisMemoryClientConfig, builder: Builder):

from nat.builder.framework_enum import LLMFrameworkEnum

import redis.asyncio as redis

from .redis_editor import RedisEditor
from .schema import ensure_index_exists

redis_client = redis.Redis(host=config.host,
port=config.port,
db=config.db,
password=get_secret_value(config.password),
decode_responses=True,
socket_timeout=5.0,
socket_connect_timeout=5.0)

embedder = await builder.get_embedder(config.embedder, wrapper_type=LLMFrameworkEnum.LANGCHAIN)

test_embedding = await embedder.aembed_query("test")
embedding_dim = len(test_embedding)
await ensure_index_exists(client=redis_client, key_prefix=config.key_prefix, embedding_dim=embedding_dim)

memory_editor = RedisEditor(redis_client=redis_client, key_prefix=config.key_prefix, embedder=embedder)

yield memory_editor
Comment thread
justin-cechmanek marked this conversation as resolved.
Loading
Loading