Skip to content

Google ADK

This guide explains how to integrate xmemory-ai into agents built with the Google Agent Development Kit (ADK).

xmemory gives your agent persistent, structured memory: write free-form text, have it extracted into a typed schema, and query it back in natural language at any time.


Terminal window
pip install xmemory-ai

The client reads credentials from environment variables by default.

VariableDescription
XMEM_AUTH_TOKENBearer token for the xmemory API
XMEM_API_URLAPI base URL (defaults to https://api.xmemory.ai)

Set them before running your agent:

Terminal window
export XMEM_AUTH_TOKEN="your-token-here"

Or pass them explicitly when constructing the client (see below).


ConceptDescription
InstanceA named memory store with a typed schema. Identified by an instance_id string.
SchemaA YAML or JSON definition of the data structure xmemory extracts and stores. Generate schemas using generate_schema().
WriteSend free-form text; xmemory extracts structured objects and merges them into the instance.
ReadQuery the instance in natural language; xmemory answers from stored structured data.

from xmemory import xmemory_instance, SchemaType
xmem = xmemory_instance(token="your-token-here")
# Step 1: generate a schema from a plain-language description
schema_resp = xmem.generate_schema(
"Track contacts with their name, email address, and notes."
)
schema_yml = schema_resp.generated_schema
# Step 2: create a memory instance using the generated schema
resp = xmem.create_instance(schema_yml, SchemaType.YML)
instance_id = resp.instance_id # save this — you will reuse it across sessions
xmem._client.instance_id = instance_id # bind to this instance for subsequent calls
# Step 3: write information into memory
xmem.write("Alice Johnson joined the team today. Her email is alice@example.com.")
# Step 4: read it back
result = xmem.read("What is Alice's email address?")
print(result.reader_result)

Use generate_schema() to create or update schemas. The generation endpoint understands xmemory’s schema format and naming conventions, and produces schemas that extract data correctly.

# Generate a schema from a plain-language description
resp = xmem.generate_schema(
"Track user preferences, past conversations, and open tasks with priorities and due dates."
)
schema_yml = resp.generated_schema # pass this directly to create_instance or update_schema

Object names in schemas use CamelCase (e.g. UserPreferences, OpenTask, ConversationEntry). The generation endpoint handles this automatically.

When your memory needs change, describe the updated structure and regenerate:

resp = xmem.generate_schema(
"Track user preferences, past conversations, and open tasks with priorities, due dates, and assignees.",
old_schema_yml=current_schema_yml, # pass the existing schema so changes are incremental
)
xmem.update_schema(resp.generated_schema, SchemaType.YML)

Passing old_schema_yml preserves existing objects and fields — only the described changes are applied.


The recommended pattern is to wrap xmemory operations as ADK FunctionTool instances and register them on your agent. The agent decides when to call them.

import os
from google.adk.agents import Agent
from google.adk.tools import FunctionTool
from xmemory import xmemory_instance, ExtractionLogic, ReadMode, XmemoryAPIError
INSTANCE_ID = os.environ["XMEM_INSTANCE_ID"]
xmem = xmemory_instance(
token=os.environ["XMEM_AUTH_TOKEN"],
instance_id=INSTANCE_ID,
)
def remember(text: str) -> str:
"""
Store information in long-term memory.
Call this whenever the user shares facts, preferences, or context worth remembering.
Args:
text: Free-form text describing what to remember.
Returns:
Confirmation string.
"""
try:
resp = xmem.write(text, extraction_logic=ExtractionLogic.DEEP)
return f"Stored in memory (write_id={resp.extract_write_id})."
except XmemoryAPIError as e:
return f"Memory write failed: {e}"
def recall(query: str) -> str:
"""
Retrieve information from long-term memory.
Call this when you need to recall facts, preferences, or context stored in previous sessions.
Args:
query: Natural language question about stored information.
Returns:
Answer derived from stored memory.
"""
try:
resp = xmem.read(query, read_mode=ReadMode.SINGLE_ANSWER)
return str(resp.reader_result) if resp.reader_result is not None else "Nothing found."
except XmemoryAPIError as e:
return f"Memory read failed: {e}"
agent = Agent(
name="my_agent",
model="gemini-2.0-flash",
instruction="You are a helpful assistant with long-term memory. Use your memory tools to remember and recall information.",
tools=[
FunctionTool(remember),
FunctionTool(recall),
],
)

For latency-sensitive agents, use write_async to enqueue a write and continue without blocking, then poll for completion with write_status.

from xmemory import WriteQueueStatus, XmemoryAPIError
def remember_async(text: str) -> str:
"""
Enqueue a memory write without blocking. Returns a write_id to check later.
Args:
text: Free-form text to store.
Returns:
The write_id assigned to this operation.
"""
try:
resp = xmem.write_async(text, extraction_logic=ExtractionLogic.DEEP)
return f"Write enqueued. write_id={resp.write_id}"
except XmemoryAPIError as e:
return f"Memory write failed: {e}"
def check_write_status(write_id: str) -> str:
"""
Check the status of a previously enqueued memory write.
Args:
write_id: The write_id returned by remember_async.
Returns:
Current status: queued, processing, completed, failed, or not_found.
"""
try:
resp = xmem.write_status(write_id)
status = resp.write_status
if status == WriteQueueStatus.FAILED:
return f"Write failed: {resp.error_detail}"
if status == WriteQueueStatus.COMPLETED:
return f"Write completed at {resp.completed_at}."
return f"Write status: {status}."
except XmemoryAPIError as e:
return f"Status check failed: {e}"

Generate the schema first, then create the instance:

from xmemory import xmemory_instance, SchemaType
xmem = xmemory_instance(token="your-token-here")
schema_resp = xmem.generate_schema(
"Track user preferences and open tasks with priorities and due dates."
)
resp = xmem.create_instance(schema_resp.generated_schema, SchemaType.YML)
print(resp.instance_id) # persist this value
xmem = xmemory_instance(
token="your-token-here",
instance_id="your-saved-instance-id",
)

Generate the updated schema incrementally, then apply it:

schema_resp = xmem.generate_schema(
"Track user preferences and open tasks with priorities, due dates, and assignees.",
old_schema_yml=current_schema_yml,
)
xmem.update_schema(schema_resp.generated_schema, SchemaType.YML)

The read method supports three modes via ReadMode:

ModeDescription
ReadMode.SINGLE_ANSWERNatural language answer to the query (default). Best for most agent use cases.
ReadMode.RAW_TABLESReturns raw structured data tables without summarisation.
ReadMode.XRESPONSEFull structured response envelope with metadata.
from xmemory import ReadMode
# Natural language answer
resp = xmem.read("What tasks are overdue?", read_mode=ReadMode.SINGLE_ANSWER)
# Raw structured data
resp = xmem.read("List all tasks", read_mode=ReadMode.RAW_TABLES)

The write and write_async methods accept an extraction_logic parameter:

ValueDescription
ExtractionLogic.FASTFastest; lower accuracy. Use for high-volume, low-stakes writes.
ExtractionLogic.REGULARBalanced speed and accuracy.
ExtractionLogic.DEEPMost thorough extraction (default). Best for important or complex information.

All xmemory operations raise XmemoryAPIError on failure. The exception carries an optional .status attribute with the HTTP status code.

from xmemory import XmemoryAPIError, XmemoryHealthCheckError
try:
xmem.check_health()
except XmemoryHealthCheckError as e:
print(f"API unreachable: {e}")
try:
resp = xmem.write("...")
except XmemoryAPIError as e:
print(f"Error {e.status}: {e}")

import os
from google.adk.agents import Agent
from google.adk.tools import FunctionTool
from xmemory import (
xmemory_instance,
ExtractionLogic,
ReadMode,
WriteQueueStatus,
XmemoryAPIError,
)
xmem = xmemory_instance(
token=os.environ["XMEM_AUTH_TOKEN"],
instance_id=os.environ["XMEM_INSTANCE_ID"],
)
def remember(text: str) -> str:
"""Store information in long-term memory. Call whenever the user shares facts worth preserving."""
try:
resp = xmem.write(text, extraction_logic=ExtractionLogic.DEEP)
return "Remembered."
except XmemoryAPIError as e:
return f"Could not store memory: {e}"
def recall(query: str) -> str:
"""Recall information from long-term memory. Call when you need context from past sessions."""
try:
resp = xmem.read(query, read_mode=ReadMode.SINGLE_ANSWER)
return str(resp.reader_result) if resp.reader_result is not None else "Nothing found."
except XmemoryAPIError as e:
return f"Could not recall memory: {e}"
def remember_in_background(text: str) -> str:
"""Enqueue a memory write without waiting. Use when you don't need to confirm storage immediately."""
try:
resp = xmem.write_async(text, extraction_logic=ExtractionLogic.REGULAR)
return f"Enqueued. write_id={resp.write_id}"
except XmemoryAPIError as e:
return f"Could not enqueue: {e}"
def check_memory_write(write_id: str) -> str:
"""Check if a background memory write has completed."""
try:
resp = xmem.write_status(write_id)
if resp.write_status == WriteQueueStatus.COMPLETED:
return "Memory saved successfully."
if resp.write_status == WriteQueueStatus.FAILED:
return f"Memory write failed: {resp.error_detail}"
return f"Status: {resp.write_status}."
except XmemoryAPIError as e:
return f"Status check failed: {e}"
agent = Agent(
name="persistent_memory_agent",
model="gemini-2.0-flash",
instruction=(
"You are a helpful assistant with persistent long-term memory across sessions. "
"Use `remember` to store important facts the user shares. "
"Use `recall` before answering questions that may depend on past context. "
"Use `remember_in_background` for non-critical information to avoid latency."
),
tools=[
FunctionTool(remember),
FunctionTool(recall),
FunctionTool(remember_in_background),
FunctionTool(check_memory_write),
],
)

xmemory_instance(
*,
url: str | None = None, # defaults to XMEM_API_URL env var or https://api.xmemory.ai
instance_id: str | None = None,
token: str | None = None, # defaults to XMEM_AUTH_TOKEN env var
timeout: int = 60, # default request timeout in seconds
) -> XmemoryAPI
MethodDescription
check_health()Raises XmemoryHealthCheckError if the API is unreachable.
generate_schema(schema_description, *, old_schema_yml)Generate a schema from a description. Use this before create_instance or update_schema. Returns GenerateSchemaResponse.
create_instance(schema_text, schema_type)Create a new memory instance from a generated schema. Returns CreateInstanceResponse.
update_schema(schema_text, schema_type)Update the schema of the current instance. Returns bool.
write(text, *, extraction_logic, timeout)Synchronous write. Returns WriteResponse.
write_async(text, *, extraction_logic, timeout)Enqueue a write. Returns AsyncWriteResponse with write_id.
write_status(write_id, *, timeout)Poll status of an async write. Returns WriteStatusResponse.
read(query, *, read_mode, timeout)Query memory. Returns ReadResponse.
extract(text, *, extraction_logic, timeout)Extract objects without writing. Returns ExtractionResponse.