Skip to main content
khora.integrations.google_adk.KhoraMemoryService implements Google ADK’s BaseMemoryService so a Runner can use khora as its long-term memory in one line:
The adapter is a drop-in replacement for ADK’s InMemoryMemoryService and VertexAiMemoryBankService. Each ADK (app_name, user_id) pair maps to a deterministic khora namespace UUID5, so two service instances on the same khora deployment see the same memory without a shared registry.
ADK 2.0 incoming. google-adk is on a weekly release cadence and the 2.0 line is already in beta. The adapter is pinned google-adk>=1.32,<2.0 and tagged stability: experimental until ADK 2.x GAs and the adapter smoke passes against it.

Scope (v0.14)

  • KhoraMemoryService: long-term memory service implementing add_session_to_memory, add_events_to_memory, and search_memory. Shipped.
  • KhoraSessionService: NOT shipped. ADK ships InMemorySessionService + DatabaseSessionService (SQLAlchemy) for short-term turn state. khora offers no differentiator there. Revisit only if a single-DB story for sessions + memory becomes a real user ask.

Install

This pulls google-adk>=1.32,<2.0. The adapter is registered under the khora.integrations entry-point group, so discover() returns it without explicit registration.

Constructor

Method semantics

All methods are async. ADK invokes them from its own event loop, so no sync bridging is involved.
  • add_session_to_memory(session): ingests every event in session.events as a separate khora document. Events with no usable content (no text parts AND no non-text parts) are skipped, matching InMemoryMemoryService. Re-ingesting the same session is safe: deduplication keys off event.id via Document.external_id.
  • add_events_to_memory(*, app_name, user_id, events, session_id, custom_metadata): incremental delta of events for an existing namespace. Same deduplication contract as add_session_to_memory. custom_metadata is merged into every event’s Document.metadata.
  • search_memory(*, app_name, user_id, query): Khora.recall against the resolved namespace. Returns SearchMemoryResponse with one MemoryEntry per matched event (chunks belonging to the same event are coalesced). Returns an empty response when the namespace hasn’t been ingested into yet.

Session attribution

Session.id (an arbitrary string) maps to a UUID5-derived session_id. Pure UUID strings round-trip verbatim. Use Khora.forget_session(namespace, session_id) to drop a whole conversation atomically.

Non-text Parts

function_call, function_response, and inline_data parts are JSON-encoded into Document.metadata["adk_parts"]. The bytes of inline_data are dropped (mime type + sha1 prefix kept). They would bloat the document store without being useful for vector recall. A short placeholder is rendered as the document content for events that carry only tool calls so they remain retrievable by name.

Quickstart

example.py
The block above is enforced byte-identical against examples/integrations/google_adk/example.py by tools/check_examples_drift.py (CI gate).

Limits and future work

  • Filter / metadata pushdown: search_memory runs khora’s standard hybrid recall. ADK’s contract doesn’t surface a filter parameter yet. When it does, we’ll forward app_name / user_id / tags to the SQL layer instead of relying on the namespace partition.
  • Session service: explicit non-goal for v0.14 (see “Scope” above).
  • inline_data bytes are dropped on ingest. Multi-modal long-term memory needs a dedicated blob-store hookup before the bytes can be preserved without ballooning the document table.
  • Aligning with ADK 2.x: the adapter is pinned <2.0 until the beta’s BaseMemoryService shape stabilises. Track upstream changes via the nightly-skew CI job.