Google ADK
xmemory Integration Guide for Google ADK
Section titled “xmemory Integration Guide for 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.
Installation
Section titled “Installation”pip install xmemory-aiAuthentication & Configuration
Section titled “Authentication & Configuration”The client reads credentials from environment variables by default.
| Variable | Description |
|---|---|
XMEM_AUTH_TOKEN | Bearer token for the xmemory API |
XMEM_API_URL | API base URL (defaults to https://api.xmemory.ai) |
Set them before running your agent:
export XMEM_AUTH_TOKEN="your-token-here"Or pass them explicitly when constructing the client (see below).
Core Concepts
Section titled “Core Concepts”| Concept | Description |
|---|---|
| Instance | A named memory store with a typed schema. Identified by an instance_id string. |
| Schema | A YAML or JSON definition of the data structure xmemory extracts and stores. Generate schemas using generate_schema(). |
| Write | Send free-form text; xmemory extracts structured objects and merges them into the instance. |
| Read | Query the instance in natural language; xmemory answers from stored structured data. |
Quick Start
Section titled “Quick Start”from xmemory import xmemory_instance, SchemaType
xmem = xmemory_instance(token="your-token-here")
# Step 1: generate a schema from a plain-language descriptionschema_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 schemaresp = 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 memoryxmem.write("Alice Johnson joined the team today. Her email is alice@example.com.")
# Step 4: read it backresult = xmem.read("What is Alice's email address?")print(result.reader_result)Schemas
Section titled “Schemas”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 descriptionresp = 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_schemaObject names in schemas use CamelCase (e.g. UserPreferences, OpenTask, ConversationEntry). The generation endpoint handles this automatically.
Updating a schema
Section titled “Updating a schema”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.
Defining Tools for Google ADK
Section titled “Defining Tools for Google ADK”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 osfrom google.adk.agents import Agentfrom google.adk.tools import FunctionToolfrom 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), ],)Async Writes
Section titled “Async Writes”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}"Managing Instances
Section titled “Managing Instances”Create a new instance
Section titled “Create a new instance”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 valueReuse an existing instance
Section titled “Reuse an existing instance”xmem = xmemory_instance( token="your-token-here", instance_id="your-saved-instance-id",)Update the schema of an existing instance
Section titled “Update the schema of an existing instance”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)Read Modes
Section titled “Read Modes”The read method supports three modes via ReadMode:
| Mode | Description |
|---|---|
ReadMode.SINGLE_ANSWER | Natural language answer to the query (default). Best for most agent use cases. |
ReadMode.RAW_TABLES | Returns raw structured data tables without summarisation. |
ReadMode.XRESPONSE | Full structured response envelope with metadata. |
from xmemory import ReadMode
# Natural language answerresp = xmem.read("What tasks are overdue?", read_mode=ReadMode.SINGLE_ANSWER)
# Raw structured dataresp = xmem.read("List all tasks", read_mode=ReadMode.RAW_TABLES)Extraction Logic
Section titled “Extraction Logic”The write and write_async methods accept an extraction_logic parameter:
| Value | Description |
|---|---|
ExtractionLogic.FAST | Fastest; lower accuracy. Use for high-volume, low-stakes writes. |
ExtractionLogic.REGULAR | Balanced speed and accuracy. |
ExtractionLogic.DEEP | Most thorough extraction (default). Best for important or complex information. |
Error Handling
Section titled “Error Handling”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}")Complete Agent Example
Section titled “Complete Agent Example”import osfrom google.adk.agents import Agentfrom google.adk.tools import FunctionToolfrom 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), ],)Reference
Section titled “Reference”xmemory_instance()
Section titled “xmemory_instance()”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) -> XmemoryAPIXmemoryAPI methods
Section titled “XmemoryAPI methods”| Method | Description |
|---|---|
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. |