Skip to content
Draft
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
18 changes: 9 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,17 @@ jobs:
- name: Install dependencies
run: uv sync --all-extras --dev

- name: Run linting
run: |
uv run ruff check src tests examples
uv run isort --check-only src tests examples
uv run pyink --check src tests examples
- name: Format check
run: make format-check

- name: Run type checking
run: uv run mypy src
- name: Lint
run: make lint

- name: Run tests
run: uv run pytest tests -v --cov=adk_redis --cov-report=xml
- name: Type check
run: make type-check

- name: Tests with coverage
run: uv run pytest tests --cov=adk_redis --cov-report=xml

- name: Upload coverage
uses: codecov/codecov-action@v4
Expand Down
44 changes: 44 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,50 @@ and this project adheres to [Semantic Versioning](https://semver.org/).

## [Unreleased]

## [0.0.7] - 2026-06-02

### Added

- Selectable memory backend support across all ADK memory surfaces.
`RedisLongTermMemoryService`, `RedisWorkingMemorySessionService`,
and the six memory tools (`SearchMemoryTool`, `CreateMemoryTool`,
`GetMemoryTool`, `UpdateMemoryTool`, `DeleteMemoryTool`,
`MemoryPromptTool`) now accept a `backend` field:
- `backend="redis-agent-memory"` (default) routes through the managed
`redis-agent-memory` SDK.
- `backend="opensource-agent-memory"` keeps the self-hosted Agent
Memory Server path through `agent-memory-client`.
- `RedisLongTermMemoryService` now implements the newer ADK write hooks
`add_events_to_memory()` and `add_memory()`, verified against upstream
`google/adk-python@ae95a97`. Older ADK versions that only call
`add_session_to_memory()` and `search_memory()` keep working.
- New spec at `docs/specs/redis-agent-memory-default.md` describing the
dual-backend design, config surface, and test scope.
- Examples (`simple_redis_memory`, `travel_agent_memory_hybrid`,
`travel_agent_memory_tools`) surface a `REDIS_MEMORY_BACKEND` env
var in `.env.example`, README, and agent wiring so users can switch
backends without code changes.
- `tests/integration/test_memory_backends_end_to_end.py`: live
round-trip coverage for both backends. Skips when
`REDIS_AGENT_MEMORY_API_BASE_URL` / `REDIS_AGENT_MEMORY_API_KEY` /
`REDIS_AGENT_MEMORY_STORE_ID` or `AGENT_MEMORY_SERVER_URL` are not
set.

### Changed

- `memory` extra now installs both `agent-memory-client>=0.14.0` and
`redis-agent-memory>=0.0.4`.
- CI workflow (`.github/workflows/ci.yml`) now invokes the
`format-check`, `lint`, and `type-check` Make targets so the
Makefile is the single source of truth for local and CI checks.

### Docs

- Updated `docs/concepts/memory.md`, `docs/concepts/sessions.md`, and
the `docs/user_guide/` how-to guides for `memory_service`,
`session_service`, `memory_server_setup`, and `redis_setup` to
reflect the backend choice.

## [0.0.6] - 2026-05-20

### Breaking
Expand Down
27 changes: 22 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@

---

`adk-redis` is the Redis layer for [Google ADK](https://github.com/google/adk-python) agents. It implements ADK's `BaseMemoryService`, `BaseSessionService`, and `BaseTool` interfaces against Redis, [RedisVL](https://docs.redisvl.com), and the [Redis Agent Memory Server](https://github.com/redis/agent-memory-server). It also ships MCP toolset helpers and semantic-cache providers.
`adk-redis` is the Redis layer for [Google ADK](https://github.com/google/adk-python) agents. It implements ADK's `BaseMemoryService`, `BaseSessionService`, and `BaseTool` interfaces against Redis, [RedisVL](https://docs.redisvl.com), Redis Agent Memory, and the [Redis Agent Memory Server](https://github.com/redis/agent-memory-server). It also ships MCP toolset helpers and semantic-cache providers.

| Surface | What you get | Backed by |
|---|---|---|
| **Sessions** | `BaseSessionService` with auto-summarization and context-window management | Agent Memory Server |
| **Long-term memory** | `BaseMemoryService` with semantic search and recency boosting | Agent Memory Server |
| **Memory tools** | LLM-controlled memory CRUD operations | Agent Memory Server |
| **Sessions** | `BaseSessionService` with durable conversation state | Redis Agent Memory or Agent Memory Server |
| **Long-term memory** | `BaseMemoryService` with semantic search | Redis Agent Memory or Agent Memory Server |
| **Memory tools** | LLM-controlled memory CRUD operations | Redis Agent Memory or Agent Memory Server |
| **Search tools** | Vector, hybrid, range, text, and SQL search as `BaseTool` subclasses | RedisVL |
| **MCP search** | `search-records` / `upsert-records` via ADK's native `McpToolset` | `rvl mcp` server |
| **Semantic cache** | Skip repeat LLM calls by semantic similarity | RedisVL or [Redis LangCache](https://redis.io/langcache) |
Expand All @@ -52,11 +52,18 @@ pip install 'adk-redis[langcache]' # managed semantic cache provider
pip install 'adk-redis[all]' # everything above
```

Memory backends are selected with `backend`:

| Backend | Use when | Client |
|---|---|---|
| `redis-agent-memory` | You want Redis Agent Memory managed by Redis or the Redis Agent Memory data plane | `redis-agent-memory` |
| `opensource-agent-memory` | You want the open source self-hosted Agent Memory Server | `agent-memory-client` |

---

## Quick start

**Prerequisites:** Python 3.10+, Redis 8.4+, and (for memory features) a running [Agent Memory Server](https://github.com/redis/agent-memory-server). See the [Quickstart](https://redis-developer.github.io/adk-redis/user_guide/01_integration/) for full setup steps.
**Prerequisites:** Python 3.10+, Redis 8.4+, and one memory backend. See the [Quickstart](https://redis-developer.github.io/adk-redis/user_guide/01_integration/) for full setup steps.

```python
from google.adk import Agent
Expand All @@ -71,13 +78,19 @@ from adk_redis import (

session_service = RedisWorkingMemorySessionService(
config=RedisWorkingMemorySessionServiceConfig(
backend="redis-agent-memory",
api_base_url="http://localhost:8088",
api_key="...",
store_id="...",
default_namespace="my_app",
),
)
memory_service = RedisLongTermMemoryService(
config=RedisLongTermMemoryServiceConfig(
backend="redis-agent-memory",
api_base_url="http://localhost:8088",
api_key="...",
store_id="...",
default_namespace="my_app",
),
)
Expand All @@ -96,6 +109,10 @@ runner = Runner(
)
```

For the open source self-hosted Agent Memory Server, set
`backend="opensource-agent-memory"` and omit `api_key` and `store_id` unless your
server requires them.

→ *More examples: [search tools](https://redis-developer.github.io/adk-redis/user_guide/how_to_guides/search_tools/), [MCP search](https://redis-developer.github.io/adk-redis/concepts/search/), [semantic caching](https://redis-developer.github.io/adk-redis/user_guide/how_to_guides/semantic_cache/)*

---
Expand Down
35 changes: 22 additions & 13 deletions docs/concepts/memory.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Sessions + Memory with MCP + Tools

Use ADK's native `McpToolset` to connect your agent to the Agent Memory Server's MCP endpoint, or use the REST-based memory tools directly. The LLM decides when to search, create, update, or delete memories.
Use ADK's native `McpToolset` to connect your agent to the Agent Memory
Server's MCP endpoint, or use the Python memory tools directly. The Python
tools can target Redis Agent Memory or the self-hosted Agent Memory Server.
The LLM decides when to search, create, update, or delete memories.

## Quick Reference

Expand Down Expand Up @@ -80,9 +83,11 @@ agent = Agent(
| `memory_prompt` | Enrich a prompt with relevant memories |
| `set_working_memory` | Write to the current session's working memory |

## Option 2: REST-Based Tools
## Option 2: SDK-Based Tools

Use the Python memory tool classes for direct REST access. No MCP server needed; the tools call the Agent Memory Server REST API.
Use the Python memory tool classes for direct SDK access. Tools can call Redis
Agent Memory through `redis-agent-memory`, or the self-hosted Agent Memory
Server through `agent-memory-client`.

```python
from google.adk import Agent
Expand All @@ -97,9 +102,11 @@ from adk_redis import (
)

config = MemoryToolConfig(
backend="redis-agent-memory",
api_base_url="http://localhost:8000",
api_key="...",
store_id="...",
default_namespace="my_app",
recency_boost=True,
)

agent = Agent(
Expand All @@ -115,36 +122,38 @@ agent = Agent(
)
```

### Available REST Tools
### Available SDK Tools

| Tool | Description |
|------|-------------|
| `SearchMemoryTool` | Semantic search with optional recency boost |
| `SearchMemoryTool` | Semantic search over long-term memories |
| `CreateMemoryTool` | Store a new memory (semantic, episodic, or message) |
| `GetMemoryTool` | Retrieve a memory by ID |
| `UpdateMemoryTool` | Update content, topics, or metadata |
| `DeleteMemoryTool` | Remove memories by ID |
| `MemoryPromptTool` | Enrich a system prompt with relevant memories |

## MCP vs REST Decision
## MCP vs SDK Decision

| | MCP | REST Tools |
| | MCP | SDK Tools |
|---|---|---|
| **Multi-language** | Yes (Python, TypeScript, any MCP client) | Python only |
| **Shared server** | Yes, multiple agents connect to one MCP endpoint | Each agent connects directly to REST API |
| **Shared server** | Yes, multiple agents connect to one MCP endpoint | Each agent connects through the SDK |
| **Extra service** | Requires MCP server running | No extra service (direct HTTP) |
| **Tool filtering** | `tool_filter` on `McpToolset` | Choose which tool classes to instantiate |

## Configuration (REST Tools)
## Configuration (SDK Tools)

| Option | Default | Description |
|--------|---------|-------------|
| `api_base_url` | `http://localhost:8000` | Agent Memory Server URL |
| `backend` | `redis-agent-memory` | `redis-agent-memory` or `opensource-agent-memory` |
| `api_base_url` | `http://localhost:8000` | Memory backend URL |
| `api_key` | `None` | Redis Agent Memory API key |
| `store_id` | `None` | Redis Agent Memory store ID |
| `timeout` | `30` | HTTP timeout in seconds |
| `default_namespace` | `default` | Namespace for memory isolation |
| `search_top_k` | `10` | Default max search results |
| `recency_boost` | `True` | Bias scoring toward newer memories |
| `distance_threshold` | `None` | Max vector distance for search results |
| `distance_threshold` | `None` | Compatibility alias for search threshold |
| `deduplicate` | `True` | Deduplicate when creating memories |

Launch with the [ADK web UI](https://google.github.io/adk-docs/runtime/) for interactive testing:
Expand Down
86 changes: 39 additions & 47 deletions docs/concepts/sessions.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,28 @@ Use `RedisWorkingMemorySessionService` and `RedisLongTermMemoryService` when you

| Feature | Details |
|---------|---------|
| **Session storage** | Agent Memory Server working memory (Redis JSON) |
| **Long-term memory** | Agent Memory Server with vector + full-text indexes |
| **Auto-summarization** | Old messages are summarized when context window fills |
| **Memory extraction** | Background promotion of facts to long-term storage |
| **Search** | Semantic, keyword, and hybrid search across sessions |
| **Session storage** | Redis Agent Memory session events or Agent Memory Server working memory |
| **Long-term memory** | Redis Agent Memory records or Agent Memory Server long-term memory |
| **Direct memory writes** | `add_memory()` stores durable semantic or episodic facts |
| **Event memory writes** | `add_session_to_memory()` stores ADK events as `message` memories |
| **Search** | Backend long-term search across scoped records |
| **Multi-process** | Safe for horizontal scaling; all state lives in Redis |

## How It Works

```mermaid
flowchart TD
U([User message]) --> R[ADK Runner]
R -->|append_event| WM[Working Memory<br/>messages · context · data]
WM -->|auto-summarize| WM
WM -->|background extraction| LTM[Long-Term Memory<br/>vector + full-text index]
R -->|append_event| WM[Session Events]
R -->|add_memory| LTM[Long-Term Memory]
R -->|add_session_to_memory| MSG[Message Memories]
MSG --> LTM
LTM -->|search_memory| R
R --> A([Agent response])

subgraph AMS [Agent Memory Server]
subgraph RAM [Configured Memory Backend]
WM
MSG
LTM
end

Expand All @@ -35,13 +37,13 @@ flowchart TD
FT[(Full-text index)]
end

AMS --- Redis
RAM --- Redis
```

1. The ADK `Runner` calls `append_event()` after every turn, forwarding the message to the Agent Memory Server.
2. When the conversation exceeds `context_window_max` tokens, the server summarizes older messages and stores the summary in a `context` field.
3. A background task extracts structured memories (facts, preferences, events) and promotes them to long-term storage.
4. On future sessions, `search_memory()` retrieves relevant memories via hybrid search.
1. The ADK `Runner` calls `append_event()` after every turn, forwarding the message to the configured memory backend.
2. ADK callbacks or API routes can call `add_session_to_memory()` to store session events as long-term `message` memories.
3. Agents and callbacks can call `add_memory()` or memory tools to store durable `semantic` or `episodic` records.
4. On future sessions, `search_memory()` retrieves relevant memories from the configured backend.

## Usage

Expand All @@ -58,18 +60,21 @@ from adk_redis import (

session_service = RedisWorkingMemorySessionService(
config=RedisWorkingMemorySessionServiceConfig(
backend="redis-agent-memory",
api_base_url="http://localhost:8000",
api_key="...",
store_id="...",
default_namespace="my_app",
model_name="gpt-4o",
context_window_max=8000,
),
)

memory_service = RedisLongTermMemoryService(
config=RedisLongTermMemoryServiceConfig(
backend="redis-agent-memory",
api_base_url="http://localhost:8000",
api_key="...",
store_id="...",
default_namespace="my_app",
recency_boost=True,
),
)

Expand All @@ -86,6 +91,10 @@ runner = Runner(
)
```

To use the open source self-hosted Agent Memory Server instead, set
`backend="opensource-agent-memory"` on both configs. Redis Agent Memory is the
default backend.

Launch with the [ADK web UI](https://google.github.io/adk-docs/runtime/) for interactive testing:

```bash
Expand All @@ -98,57 +107,40 @@ adk web .

| Option | Default | Description |
|--------|---------|-------------|
| `api_base_url` | `http://localhost:8000` | Agent Memory Server URL |
| `backend` | `redis-agent-memory` | `redis-agent-memory` or `opensource-agent-memory` |
| `api_base_url` | `http://localhost:8000` | Memory backend URL |
| `api_key` | `None` | Redis Agent Memory API key |
| `store_id` | `None` | Redis Agent Memory store ID |
| `timeout` | `30.0` | HTTP request timeout in seconds |
| `default_namespace` | `None` | Logical grouping for multi-tenant isolation |
| `model_name` | `None` | Model name used for context window sizing and summarization |
| `context_window_max` | `None` | Token limit that triggers auto-summarization |
| `extraction_strategy` | `discrete` | How memories are extracted (`discrete`, `summary`, `preferences`, `custom`) |
| `session_ttl_seconds` | `None` | Optional TTL; expired sessions are cleaned up by Redis |

### Memory Service (`RedisLongTermMemoryServiceConfig`)

| Option | Default | Description |
|--------|---------|-------------|
| `api_base_url` | `http://localhost:8000` | Agent Memory Server URL |
| `backend` | `redis-agent-memory` | `redis-agent-memory` or `opensource-agent-memory` |
| `api_base_url` | `http://localhost:8000` | Memory backend URL |
| `api_key` | `None` | Redis Agent Memory API key |
| `store_id` | `None` | Redis Agent Memory store ID |
| `timeout` | `30.0` | HTTP request timeout in seconds |
| `default_namespace` | `None` | Namespace for memory isolation |
| `search_top_k` | `10` | Max results returned from `search_memory()` |
| `distance_threshold` | `None` | Max vector distance for search results (0.0-1.0) |
| `recency_boost` | `True` | Bias search scoring toward newer memories |
| `semantic_weight` | `0.8` | Weight for semantic similarity (0.0-1.0) |
| `recency_weight` | `0.2` | Weight for recency score (0.0-1.0) |
| `extraction_strategy` | `discrete` | How memories are extracted (`discrete`, `summary`, `preferences`, `custom`) |

## Automatic Summarization

When conversation messages exceed `context_window_max` tokens, the server:

1. Summarizes older messages into a compact paragraph.
2. Stores the summary in the `context` field of working memory.
3. Removes the summarized messages to free space.
4. Keeps recent messages intact.

```mermaid
flowchart LR
M["msg1 msg2 ... msg10"] -->|exceeds threshold| S[Summarize]
S --> C["context: 'User discussed trip planning...'"]
S --> K["msg8 msg9 msg10<br/>(recent kept)"]
```
| `similarity_threshold` | `None` | Min similarity for search results (0.0-1.0) |
| `store_events_as_messages` | `True` | Store ADK events as `message` memories |

## Memory Types

The server extracts three types of memories from conversations:
Redis Agent Memory and Agent Memory Server support three memory types:

| Type | Description | Example |
|------|-------------|---------|
| **Semantic** | Facts, preferences, general knowledge | "User prefers window seats" |
| **Episodic** | Events with temporal context | "User visited Paris in March 2024" |
| **Message** | Conversation records (auto-generated) | Stored from working memory messages |
| **Message** | Conversation records | "user: I prefer window seats" |

## Cross-Process Scaling

Because all state lives in the Agent Memory Server (backed by Redis), multiple processes can share sessions:
Because all state lives in Redis, multiple processes can share sessions:

- **Horizontal scaling**: deploy multiple agent replicas behind a load balancer.
- **Seamless failover**: if one instance goes down, another picks up the session.
Expand Down
Loading
Loading