Metadata-Version: 2.5
Name: google-adk-memorysync
Version: 1.0.0
Summary: MemorySync memory for Google ADK: a real BaseMemoryService (ingestion included) powering the native load_memory/preload_memory tools, a guaranteed per-turn context tool, persistence callbacks, and agent memory tools.
Project-URL: Homepage, https://memorysync.io
Project-URL: Documentation, https://docs.memorysync.io/guides/google-adk
Project-URL: API Reference, https://docs.memorysync.io/api/overview
Project-URL: Changelog, https://docs.memorysync.io/release-notes
Project-URL: Support, https://docs.memorysync.io/debugging/support
Project-URL: Status, https://status.memorysync.io
Author: MemorySync
License: MIT
Keywords: adk,agent-development-kit,agent-memory,ai,ai-agents,google-adk,llm,long-term-memory,memory,memory-service,memorysync
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: google-adk<3,>=2
Requires-Dist: httpx<1.0,>=0.25
Requires-Dist: memorysync>=1.9
Description-Content-Type: text/markdown

# google-adk-memorysync

Long-term memory for [Google ADK](https://google.github.io/adk-docs/) (Agent Development Kit), backed by [MemorySync](https://memorysync.io) — a **real** `BaseMemoryService` whose ingestion methods actually store your sessions, powering ADK's native `load_memory` / `preload_memory` tools with durable, cross-session, cross-app memory.

- **`MemorySyncMemoryService`** — all four `BaseMemoryService` methods implemented: `add_session_to_memory`, `add_events_to_memory`, `add_memory`, `search_memory`. Plug it into `Runner(memory_service=...)` and ADK's own memory tools just work.
- **`MemorySyncContextTool`** — guaranteed memory injection before every turn plus automatic user-turn persistence, no memory-tool calls left to model discretion.
- **`create_memory_callbacks`** — an `after_model_callback` that persists assistant turns.
- **Five agent tools** — add, search, list, update, delete; they never raise.
- **Async helpers** — `get_memory_context`, `search_memories`, `save_turn`.

```bash
pip install google-adk-memorysync google-adk
```

Set `MEMORYSYNC_API_KEY` in the environment (create a key at [app.memorysync.io](https://app.memorysync.io)), or pass `api_key` explicitly. Python 3.10+, `google-adk` 2.x.

## The memory service

```python
from google.adk.agents import LlmAgent
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.adk.tools import preload_memory
from google_adk_memorysync import MemorySyncMemoryService

memory_service = MemorySyncMemoryService()  # reads MEMORYSYNC_API_KEY

agent = LlmAgent(
    name="assistant",
    model="gemini-2.5-flash",
    instruction="You are a helpful assistant.",
    tools=[preload_memory],  # ADK's native tool — our service powers it
)

runner = Runner(
    agent=agent,
    app_name="support",
    session_service=InMemorySessionService(),
    memory_service=memory_service,
)

# ... after a conversation, ingest the session:
session = await runner.session_service.get_session(
    app_name="support", user_id="customer-7", session_id=session_id
)
await memory_service.add_session_to_memory(session)
```

The next run — any session, any process, any deploy — `preload_memory` injects what MemorySync knows about the user before the model call.

**Ingestion is real.** `add_session_to_memory` persists every completed text turn (streaming `partial` chunks, tool traffic and authorless events are skipped) and raises on failure — a memory service that silently drops sessions is data loss behind a green pipeline. Re-ingesting the same session converges instead of duplicating: every event carries an idempotency seed derived from its ADK event id.

**Incremental ingestion.** `add_events_to_memory(app_name=..., user_id=..., events=[...])` persists events as they happen and converges with a later whole-session `add_session_to_memory` — same seeds on both paths, each event stored exactly once.

**Search never raises.** `search_memory` returns proper `MemoryEntry` objects (`content`, `author`, `timestamp`, `custom_metadata.memory_id`) so ADK's `preload_memory` formatter renders them natively; failures degrade to an empty response through `on_error`.

**Scoping.** By default the same user's memory follows them across ADK apps (that's the point of a memory service); pass `scope_to_app=True` to silo each `app_name`.

## Guaranteed context injection

ADK's `load_memory` leaves recall to model discretion and `preload_memory` only injects — nothing persists turns as they happen. The context tool does both:

```python
from google_adk_memorysync import MemorySyncContextTool

agent = LlmAgent(
    name="assistant",
    model="gemini-2.5-flash",
    instruction="You are a helpful assistant.",
    tools=[MemorySyncContextTool()],  # inject memory + persist user turns
)
```

Before every turn it recalls relevant memories for `tool_context.user_id` and appends them to the request instructions — once per invocation, even when a multi-tool turn makes several model calls. After injection it persists the user's message (`persist=False` for read-only). Outages degrade to a memoryless turn through `on_error`, never a crashed one.

Pair it with the assistant-side callback for a full loop with zero manual calls:

```python
from google_adk_memorysync import MemorySyncContextTool, create_memory_callbacks

agent = LlmAgent(
    name="assistant",
    model="gemini-2.5-flash",
    instruction="You are a helpful assistant.",
    tools=[MemorySyncContextTool()],
    **create_memory_callbacks(),  # after_model_callback persists assistant turns
)
```

All surfaces share the same idempotency seeds, so mixing the service, the tool and the callbacks cannot double-store a turn.

## Agent tools

```python
from google_adk_memorysync import create_memorysync_tools

agent = LlmAgent(
    name="assistant",
    model="gemini-2.5-flash",
    instruction="Use the memory tools to remember durable facts.",
    tools=create_memorysync_tools(user_id="customer-7"),
)

# Untrusted agents: search + list only.
create_memorysync_tools(user_id="customer-7", read_only=True)
```

`add_memory`, `search_memory`, `list_memories`, `update_memory`, `delete_memory` — the same five operations, same response strings as the MemorySync LangChain, AI SDK, CrewAI, Mastra, OpenAI Agents and LlamaIndex tool sets. Plain async callables that ADK auto-wraps as `FunctionTool`s; failures return short readable strings, never exceptions.

## Helpers

```python
from google_adk_memorysync import get_memory_context, save_turn, search_memories

context = await get_memory_context("what should I cook?", user_id="customer-7")
hits = await search_memories("dietary preferences", user_id="customer-7")
await save_turn(user_id="customer-7", user="I'm vegetarian", assistant="Noted!")
```

`save_turn` raises on failure — an explicit persist call is owed the truth.

## Version support

| Package | Requires | Runtime |
| --- | --- | --- |
| `google-adk-memorysync` 1.0.0 | `google-adk` >=2,<3 | Python 3.10+ |

CI drives a REAL ADK `Runner` — native `preload_memory` end to end, repeated-ingestion convergence, partial-event filtering, per-invocation injection dedup — against the latest `google-adk` 2.x release on every push.

## Documentation

- [Google ADK Memory guide](https://docs.memorysync.io/guides/google-adk)
- [MemorySync docs](https://docs.memorysync.io)
- [Get an API key](https://app.memorysync.io)
