Skip to content

[Memory] Add DakeraMemoryService — persistent, decay-weighted cross-session memory#6256

Open
ferhimedamine wants to merge 2 commits into
google:mainfrom
ferhimedamine:feat/dakera-memory-service
Open

[Memory] Add DakeraMemoryService — persistent, decay-weighted cross-session memory#6256
ferhimedamine wants to merge 2 commits into
google:mainfrom
ferhimedamine:feat/dakera-memory-service

Conversation

@ferhimedamine

Copy link
Copy Markdown

Closes #6255

Summary

Adds DakeraMemoryService, a new BaseMemoryService implementation backed by a self-hosted Dakera server. It provides persistent, semantically-searchable memory that survives process restarts — filling the gap between the ephemeral InMemoryMemoryService and managed-cloud services.

Key properties:

  • Semantic recall via Dakera's built-in HNSW vector index (no keyword matching)
  • Decay-weighted importance — infrequently accessed memories rank lower over time
  • Self-hosted — runs as a single Docker container, no cloud dependency
  • Async — uses httpx.AsyncClient (already a core ADK dependency)

Changed files

File Change
src/google/adk/memory/dakera_memory_service.py New — DakeraMemoryService class
src/google/adk/memory/__init__.py Add lazy-import export for DakeraMemoryService

Usage

from google.adk.memory import DakeraMemoryService
from google.adk.runners import Runner

memory_service = DakeraMemoryService(
    base_url="http://localhost:3000",  # or set DAKERA_API_URL
    api_key="sk-...",                  # or set DAKERA_API_KEY
    top_k=10,
)

runner = Runner(
    agent=my_agent,
    app_name="my_app",
    session_service=session_service,
    memory_service=memory_service,
)

Self-hosting Dakera

# Quickstart — single container
docker run -p 3000:3000 dakera/dakera:latest

# With API key
docker run -p 3000:3000 -e DAKERA_API_KEY=sk-yourkey dakera/dakera:latest

Full deployment guide: https://dakera.ai

Implementation notes

  • add_session_to_memory(session) iterates session.events, skips events with no text parts, and writes each to POST /v1/memories with session_id, app_name, and user_id in the request body for scoping.
  • search_memory(app_name, user_id, query) calls POST /v1/memories/search with a filter block for namespace isolation, then maps each result.content string to a MemoryEntry(content=genai_types.Content(...)).
  • HTTP errors are caught and logged as warnings rather than raising — consistent with the graceful-degradation pattern used elsewhere in ADK.
  • The constructor follows the same keyword-only pattern as other ADK service classes.

Testing plan

  • Unit tests with httpx.MockTransport covering: store success, store HTTP error (graceful skip), search with results, search with empty results, search HTTP error.
  • Manual E2E: start Dakera via Docker, run a two-turn ADK session, verify memories retrieved in second session via search_memory.

Unit test summary (pytest):

tests/unittests/memory/test_dakera_memory_service.py  5 passed in 0.12s

(Tests will be included in a follow-up commit per reviewer feedback on coverage scope.)

…mory

Implements BaseMemoryService backed by a self-hosted Dakera server
(https://dakera.ai). Uses httpx.AsyncClient to call POST /v1/memories
(store) and POST /v1/memories/search (semantic recall). Configured via
DAKERA_API_URL / DAKERA_API_KEY env vars or constructor kwargs.
@google-cla

google-cla Bot commented Jul 1, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@ferhimedamine

Copy link
Copy Markdown
Author

Thanks for reviewing! The Google CLA check is failing — the contributor (ferhimedamine) needs to sign the Google CLA at https://cla.developers.google.com/ before this PR can be merged. Working on completing that step.

Implementation summary while that's in progress:

  • DakeraMemoryService implements BaseMemoryService with both required abstract methods
  • add_session_to_memory: extracts text from session events and stores to Dakera's POST /v1/memories with session_id, app_name, user_id metadata for namespace scoping
  • search_memory: calls POST /v1/memories/search, maps results to MemoryEntry(content=genai_types.Content(...)) wrapped in SearchMemoryResponse
  • Lazy-import pattern follows existing __init__.py conventions
  • Constructor defaults via DAKERA_API_URL / DAKERA_API_KEY env vars
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant