Skip to main content
ADK’s memory service is an interface; Anona implements it. Wire AnonaMemoryService in as your agent’s memory_service and it can recall across sessions, deployments and restarts, scoped to the right user automatically, because ADK hands you user_id on every call.

Setup

Nothing here is automatic

Both directions require you to wire something. This is how ADK’s memory services work in general, not a limitation of this adapter. Reading: two options, different cost. Attach the built-in load_memory tool (above) and the model decides for itself when to call it, with zero calls if it never asks. Attach preload_memory instead (from google.adk.tools import preload_memory) and it runs on its own, with no model decision involved. But “automatic” here is more expensive than it sounds: it fires before every model call, not once per turn. A single tool-calling turn (the model calls one tool, then answers) measured 2 separate retrieve calls, both for the identical query, because ADK re-runs it once per model step, not once per turn. Unlike this SDK’s LangChain adapter, there is no per-turn cache to collapse that back down. A three-tool-call turn costs four retrieves for one logical question, all billed. Reach for preload_memory only once that cost is a deliberate choice; load_memory is the lower-cost default for most agents. You can also call await tool_context.search_memory(query) directly from inside your own tool or callback code if neither built-in shape fits. Writing. A session is never saved to memory just because a run finished. The supported hook is Context.add_session_to_memory(), reachable from any callback that receives a context. after_agent_callback, as above, is the natural place, since it fires once per runner.run_async() call, after any internal tool-calling loop has finished. Skip this and Anona never receives a single turn; the agent still runs, silently, with no memory. Note the callback’s parameter must be named exactly callback_context, because ADK invokes it as a keyword argument. You can also call memory_service.add_session_to_memory(session) directly: add_session_to_memory on the callback context is just a shortcut for that, using the callback’s own session. Calling this again on a session you’ve already saved, the normal shape of a multi-turn conversation with one call per turn on the same session.id, is safe: you don’t need to track what you’ve already sent yourself. In the common case (each call sees the same, growing event history, true of the after_agent_callback idiom above, and of a fresh session_service.get_session(...) fetch) only what’s new goes out. If a call instead receives a different, shorter view of the same session, for example a trimmed fetch via GetSessionConfig(num_recent_events=N), this can’t always tell which of those events it already saw, and resends the whole view rather than guess and risk dropping something new. So: never a silently lost turn; occasionally, in that specific case, a duplicate.

Per-user isolation, at no cost

ADK passes user_id and app_name on every memory call, and this adapter maps them onto Anona’s scope, asymmetrically between writing and reading: app_name is written as agent_id but deliberately not forwarded on a read. Anona consolidates raw memories into synthesized observations over time, and an observation is tagged by user only, not by the agent that happened to write the originating turns, so a two-key user_id + agent_id search would never match a consolidated observation, only raw, unconsolidated facts. Since app_name is the one scope key ADK supplies automatically with no way to opt out, forwarding it on every read would have silently hidden your agent’s best answers behind its rawest ones, for every ADK user, all the time. Isolation itself is unaffected: user_id (the key that actually keeps one end user’s memories from another’s) is forwarded on every call, read and write alike. One space serves every user of your app, and a memory written under one user_id is only ever returned to that same user. You configure nothing.

Failure behaviour

If Anona is unreachable, search_memory returns no memories and the agent continues. Failures are logged, never raised.