Skip to content

Add selectable Redis Agent Memory backends#16

Draft
nkanu17 wants to merge 15 commits into
mainfrom
feat/selectable-agent-memory-backends
Draft

Add selectable Redis Agent Memory backends#16
nkanu17 wants to merge 15 commits into
mainfrom
feat/selectable-agent-memory-backends

Conversation

@nkanu17

@nkanu17 nkanu17 commented May 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds selectable Redis Agent Memory backend support across all ADK memory
surfaces while preserving the self-hosted Agent Memory Server path.

All public services and tools now accept a backend field:

  • backend="redis-agent-memory" (default): managed Redis Agent Memory via
    redis-agent-memory>=0.0.4.
  • backend="opensource-agent-memory": self-hosted Agent Memory Server via
    agent-memory-client>=0.14.0.

Public class names are unchanged: RedisWorkingMemorySessionService,
RedisLongTermMemoryService, MemoryToolConfig, and the six memory tools
(SearchMemoryTool, CreateMemoryTool, GetMemoryTool,
UpdateMemoryTool, DeleteMemoryTool, MemoryPromptTool).

Spec: docs/specs/redis-agent-memory-default.md.

What's in this PR

Code

  • src/adk_redis/memory/_backends.py: MemoryBackendName literal and
    backend name constants.
  • src/adk_redis/memory/long_term_memory.py: dual-backend dispatch for
    add_session_to_memory, add_events_to_memory, add_memory, and
    search_memory. Implements the newer ADK write hooks confirmed against
    upstream google/adk-python at commit ae95a97, while staying
    compatible with installed ADK versions that don't call them yet.
  • src/adk_redis/sessions/working_memory.py: dual-backend dispatch for
    append_event, get_session, and list_sessions. Redis Agent Memory
    path reconstructs ADK sessions from stored events; opensource path keeps
    Working Memory APIs, summarization, and extraction strategy settings.
  • src/adk_redis/tools/memory/*.py and _config.py: all six tools route
    to the configured backend; adds default_owner_id for tools that run
    outside an ADK user context.

Dependencies

  • pyproject.toml: the memory extra now installs both clients
    (agent-memory-client>=0.14.0, redis-agent-memory>=0.0.4).
  • Version bumped from 0.0.6 to 0.0.7.

Docs

  • docs/specs/redis-agent-memory-default.md: design spec for the dual
    backend, config surface, and test scope.
  • docs/specs/examples-memory-coverage-handover.md: handover for the
    follow-up work needed on examples/ and on managed-backend capability
    parity. Frames it as a two-phase assessment (implementation coverage
    first, example coverage second) and lists concrete capability gaps to
    validate against the public Redis Agent Memory docs.
  • docs/concepts/memory.md, docs/concepts/sessions.md,
    docs/llms.txt: concept pages and llms index updated to reflect the
    backend choice.
  • docs/user_guide/01_integration.md,
    docs/user_guide/how_to_guides/memory_service.md,
    docs/user_guide/how_to_guides/session_service.md,
    docs/user_guide/how_to_guides/memory_server_setup.md,
    docs/user_guide/how_to_guides/redis_setup.md: how-to guides updated.
  • CHANGELOG.md: new [0.0.7] entry under Added, Changed, and
    Docs sections.

Examples

  • examples/simple_redis_memory/,
    examples/travel_agent_memory_hybrid/,
    examples/travel_agent_memory_tools/: surface the REDIS_MEMORY_BACKEND
    env var in .env.example, README, and agent wiring so users can switch
    backends without code changes. Defaults are currently
    opensource-agent-memory; rebalancing against the library default
    (redis-agent-memory) is captured in the handover doc.

Tests

  • tests/memory/test_long_term_memory.py: backend dispatch, owner and
    namespace filters, event-to-memory writes, explicit add_memory
    payloads, and config defaults for both backends.
  • tests/sessions/test_working_memory.py: session reconstruction,
    deterministic internal session IDs, and self-hosted backend parity.
  • tests/tools/test_memory_tools.py: create / search / update / delete
    payloads for both backends.
  • tests/integration/test_memory_backends_end_to_end.py: new 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.

CI

  • .github/workflows/ci.yml: lint, format-check, and type-check steps
    now invoke the corresponding Makefile targets so the Makefile is the
    single source of truth for local and CI checks.

Status

  • Rebased onto current origin/main. PR diff is scoped to the memory
    backend work plus the handover doc.
  • make check: 112 passed, 10 skipped (integration suites skip
    cleanly without a configured backend) locally.
  • ADK upstream contract checked against google/adk-python@ae95a97.

Deferred to follow-up (see handover doc)

Captured in
docs/specs/examples-memory-coverage-handover.md:

  • No example currently exercises the redis-agent-memory backend under
    the adk web runner. All three memory examples default to
    opensource-agent-memory, which is the opposite of the library
    default.
  • Confirm what managed Redis Agent Memory (preview) covers vs the
    self-hosted Agent Memory Server. Known starting gaps to validate:
    configurable extraction strategy and debounce, working-memory
    auto-summarization, recency-boost weights, the MCP server endpoint,
    Session.state round-tripping, and non-text event payload fidelity.
  • The public ADK integration page at
    redis.io/docs/.../integrate/google-adk/redis-agent-memory/ does not
    yet describe the managed backend selector introduced here; flagged
    for coordination with whoever owns that page.
  • examples/simple_redis_memory/.env.example is empty.
  • Decide whether simple_redis_memory and travel_agent_memory_hybrid
    can move off get_fast_api_app to adk web (currently blocked by
    the ADK service-registry consumer being scoped to the FastAPI app
    factory).

Remaining for this PR

  • Flip from Draft to Ready for review.
  • (Optional) Provision the integration env vars in CI so the new live
    memory integration tests run on every PR.

How to test locally

# unit tests + skipped integration tests (no Redis or memory backends needed)
make check

# live integration against Redis Agent Memory
export REDIS_AGENT_MEMORY_API_BASE_URL=...
export REDIS_AGENT_MEMORY_API_KEY=...
export REDIS_AGENT_MEMORY_STORE_ID=...
uv run pytest tests/integration/test_memory_backends_end_to_end.py -v

# live integration against self-hosted Agent Memory Server
export AGENT_MEMORY_SERVER_URL=http://localhost:8000
uv run pytest tests/integration/test_memory_backends_end_to_end.py -v

Copilot AI review requested due to automatic review settings May 29, 2026 21:41

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

@nkanu17 nkanu17 force-pushed the feat/selectable-agent-memory-backends branch from a73ba82 to e9b8ee7 Compare June 2, 2026 15:20
nkanu17 added 3 commits June 2, 2026 10:31
Replace inline ruff/isort/pyink/mypy invocations with calls to
make format-check, make lint, and make type-check. The test step
keeps its --cov flags so coverage upload still works.
Add tests/integration/test_memory_backends_end_to_end.py covering:

- RedisLongTermMemoryService.add_memory + search_memory round-trip
  against managed Redis Agent Memory and against the self-hosted
  Agent Memory Server.
- RedisWorkingMemorySessionService append_event + get_session +
  delete_session round-trip against Redis Agent Memory.

Tests skip 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, matching the existing pattern
used by the search integration suite.
- pyproject.toml: 0.0.6 -> 0.0.7.
- CHANGELOG.md: add [0.0.7] entry documenting the dual-backend
  memory work (services, tools, examples), the new memory extra
  shipping both clients, the docs/spec additions, the new live
  integration tests, and the CI Makefile refactor.
Copilot AI review requested due to automatic review settings June 2, 2026 15:32

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 39 out of 39 changed files in this pull request and generated 5 comments.

Comment on lines +58 to +60
REDIS_AGENT_MEMORY_URL = os.environ.get("REDIS_AGENT_MEMORY_API_BASE_URL")
REDIS_AGENT_MEMORY_API_KEY = os.environ.get("REDIS_AGENT_MEMORY_API_KEY")
REDIS_AGENT_MEMORY_STORE_ID = os.environ.get("REDIS_AGENT_MEMORY_STORE_ID")
Comment on lines 125 to 127
return {"status": "error", "message": "memory_ids is required"}

try:
Comment on lines +128 to +131
if self._config.backend == OPENSOURCE_AGENT_MEMORY_BACKEND:
response = await self._get_agent_memory_server_client().delete_long_term_memories(
memory_ids=memory_ids,
)
Comment on lines 129 to 134
memory_id = args.get("memory_id")
content = args.get("content")
topics = args.get("topics")
self._get_namespace(args.get("namespace"))
self._get_user_id(args.get("user_id"))
namespace = args.get("namespace")
user_id = args.get("user_id")

Comment on lines 19 to 22
import logging
from typing import Any
import uuid

nkanu17 added 2 commits June 2, 2026 10:57
Captures follow-up work for PR #16:

- No example demonstrates redis-agent-memory backend under the adk web
  runner. travel_agent_memory_tools is the only adk web memory example
  and defaults to opensource-agent-memory.
- All three memory examples default REDIS_MEMORY_BACKEND to
  opensource-agent-memory, contradicting the library default
  (redis-agent-memory) documented in
  docs/specs/redis-agent-memory-default.md.
- simple_redis_memory and travel_agent_memory_hybrid cannot move to
  adk web because they register services through
  get_service_registry(), which only get_fast_api_app consults.

Proposes adding a new examples/simple_managed_memory/ (memory tools
only, managed backend default, no docker-compose) plus doc cleanups
and a top-level examples/README.md matrix.
Copilot AI review requested due to automatic review settings June 2, 2026 16:05
Restructure the memory example handover so the next person assesses
both implementation coverage and example coverage from scratch:

- Phase 1 reads the dispatch code in src/adk_redis/memory,
  src/adk_redis/sessions, and src/adk_redis/tools/memory, reads the
  installed redis-agent-memory SDK and the public Redis Agent Memory
  docs, then produces an ADK-surface-by-backend coverage table and a
  list of hard vs soft gaps.
- Phase 2 audits examples against the phase 1 conclusions and
  proposes the concrete add/change/leave plan.

Add a 'Capability differences from public docs' section pointing at
the official Redis Agent Memory docs (preview product) and the ADK
integration page, capturing concrete starting-point gaps to validate:

- Auto-promotion exists on managed but the policy is opaque (no
  documented extraction strategy or debounce).
- Auto-summarization, configurable extraction strategies, recency
  weights, and the MCP server endpoint are opensource-only.
- Identifier naming differences (ownerId / storeId vs user_id /
  namespace) and how Session.state plus non-text event payloads behave
  on managed need verification.
- The public ADK integration page does not yet describe the managed
  backend selector introduced by PR #16; flagged for coordination.

Drop the prescriptive options-A-vs-B recommendation so the takeover
person can decide based on the phase 1 findings.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 40 out of 40 changed files in this pull request and generated 3 comments.

Comment on lines +603 to +607
"events",
app_name,
user_id,
len(events),
),
Comment on lines +129 to +131
response = await self._get_agent_memory_server_client().delete_long_term_memories(
memory_ids=memory_ids,
)
if not message:
return

await self._get_agent_memory_server_client().append_messages_to_working_memory(

@limjoobin limjoobin left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Looks good! Just some comments for clarity, but functionality-wise it looks clear that you're creating an abstraction layer for agent memory backends, to support the managed Redis Agent Memory and self-hosted AMS backends

Comment on lines +24 to +27
MemoryBackendName = Literal[
"redis-agent-memory",
"opensource-agent-memory",
]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Not particularly crucial, but is there a reason why we defined REDIS_AGENT_MEMORY_BACKEND and OPENSOURCE_AGENT_MEMORY_BACKEND, but still use the hardcoded values in the Literal?

Might be a good idea to use these defined values for DRY-ness.

Suggested change
MemoryBackendName = Literal[
"redis-agent-memory",
"opensource-agent-memory",
]
MemoryBackendName = Literal[
REDIS_AGENT_MEMORY_BACKEND,
OPENSOURCE_AGENT_MEMORY_BACKEND,
]

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.

Good point

if memory.last_accessed
"id": read_field(memory, "id"),
"content": read_field(memory, "text"),
"topics": read_field(memory, "topics", []) or [],

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

actually i notice (across the repo) that or ... is always included when a default value is defined in read_field, but if it returns a default value, the or ... part seems to be redundant.

def test_memory_tool_config_accepts_opensource_backend():
"""Memory tool config accepts the self-hosted backend value."""
assert (
MemoryToolConfig(backend="opensource-agent-memory").backend

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Similar to before, it might be more DRY to use OPENSOURCE_AGENT_MEMORY_BACKEND from src/adk_redis/memory/_backends.py instead of hardcoding "opensource-agent-memory" for such instances when defining the backend

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.

Sounds good

…ects - and : chars, and current IDs exceeded the limit. This fix handles the IDs, and return empty sessions before first event (when Redis has nothing yet), so the first message can flow and create the real session.
Copilot AI review requested due to automatic review settings June 11, 2026 05:47

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review is ineligible. To be eligible to request a review, you need a paid Copilot license, or your organization must enable Copilot code review.

@hillarytoh

Copy link
Copy Markdown

Sorry I made a typo - for commit 2de43e9, I meant to say that Redis Agent Memory doesn't accept underscore _ chars. It does accept dashes -.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants