Skip to main content

Google ADK plugin for MemEngine persistent memory layer

Project description

memengine-adk

Google ADK plugin and tools for MemEngine — a standalone persistent memory layer for AI agents.

PyPI version Python License


What is this?

memengine-adk integrates MemEngine into Google ADK agents, giving them persistent long-term memory across sessions without changing your agent logic.

MemEngine runs as a separate HTTP service. This package is the ADK-side adapter.


Requirements

  • Python 3.10+
  • google-adk >= 0.1.0
  • A running MemEngine instance

Installation

pip install memengine-adk

Start MemEngine before running your agent:

uvicorn memengine.main:app --host 0.0.0.0 --port 8001

Admin UI: http://localhost:8001/admin


Integration Approaches

Approach Memory happens Agent changes needed Best for
Plugin Every turn, automatically None Production chatbots, assistants
Tools When agent decides Add tool descriptions Autonomous agents
Callbacks You control everything Full custom integration Advanced use cases

Approach 1: Plugin (Recommended)

The plugin hooks into ADK's Runner and handles all memory reads and writes automatically.

from google.adk.agents import LlmAgent
from google.adk.runners import InMemoryRunner
from memengine_adk import MemEnginePlugin

plugin = MemEnginePlugin(
    base_url="http://localhost:8001",
    user_id="user_001",       # stable user identifier
    agent_id="my_assistant",  # memory namespace
    top_k=5,                  # memories to inject per turn
)

agent = LlmAgent(
    name="my_agent",
    model="gemini-2.0-flash",
    instruction="You are a helpful personal assistant.",
)

runner = InMemoryRunner(
    agent=agent,
    app_name="my_app",
    plugins=[plugin],
)

async for event in runner.run_async(
    user_id="user_001",
    session_id="session_abc",
    new_message="My name is Alice and I prefer dark mode.",
):
    if event.is_final_response():
        print(event.content.parts[0].text)

How the plugin works

Callback When it runs What it does
on_user_message_callback User sends a message Enqueues async long-term memory write evaluation
before_model_callback Before each LLM call Calls /memory/process, injects system_prompt
after_model_callback After each LLM reply Caches assistant reply for next turn's write evaluation

MemEnginePlugin parameters

Parameter Type Default Description
base_url str http://localhost:8001 MemEngine service URL
user_id str default_user Stable user identifier
agent_id str adk_agent Memory namespace — different agent_ids are fully isolated
top_k int 5 Max long-term memories injected per turn
enabled bool True Set False to disable without removing the plugin

Approach 2: Tools (Explicit Agent Control)

Exposes memory as ADK FunctionTools. The agent decides when to save and fetch.

from google.adk.agents import LlmAgent
from google.adk.runners import InMemoryRunner
from memengine_adk import MemEngineSaveTool, MemEngineFetchTool

save_tool = MemEngineSaveTool(
    base_url="http://localhost:8001",
    user_id="user_001",
    agent_id="my_assistant",
)
fetch_tool = MemEngineFetchTool(
    base_url="http://localhost:8001",
    user_id="user_001",
    agent_id="my_assistant",
)

agent = LlmAgent(
    name="my_agent",
    model="gemini-2.0-flash",
    instruction="""You are a helpful personal assistant with persistent memory.

Use fetch_memories at the start of conversations to recall what you know about the user.
Use save_memory when the user shares something important (name, preferences, decisions).""",
    tools=[save_tool, fetch_tool],
)

runner = InMemoryRunner(agent=agent, app_name="my_app")

Available tools

save_memory(content, chat_id) Save important information to long-term memory. Use when the user shares something worth remembering across future conversations.

fetch_memories(query, limit) Retrieve stored memories. Supports optional keyword filter. Returns up to limit records (default 10).


Approach 3: Callbacks (Manual Integration)

Use MemEngineClient directly for full control in custom runners or non-standard ADK setups.

from memengine_adk import MemEngineClient

client = MemEngineClient(base_url="http://localhost:8001")

# Before LLM call — get enriched system_prompt
result = await client.process(
    user_id="user_001",
    agent_id="my_assistant",
    chat_id="session_abc",
    user_input=user_message,
    assistant_output=last_reply,
)
system_prompt = result["system_prompt"]

# List memories
memories = await client.list_memories(user_id="user_001", agent_id="my_assistant")
for m in memories:
    print(m.content, m.score)

await client.aclose()

MemEngineClient methods

Method Description
process(user_id, agent_id, chat_id, user_input, assistant_output) Process a turn, returns system_prompt and long_term_written
list_memories(user_id, agent_id, limit, q) List long-term memories with optional keyword filter
aclose() Close the underlying HTTP client

Environment Variables

All constructor parameters can be set via environment variables for convenience:

export MEMENGINE_URL=http://localhost:8001
export MEMENGINE_USER_ID=user_001
export MEMENGINE_AGENT_ID=my_assistant
import os
plugin = MemEnginePlugin(
    base_url=os.getenv("MEMENGINE_URL", "http://localhost:8001"),
    user_id=os.getenv("MEMENGINE_USER_ID", "default_user"),
    agent_id=os.getenv("MEMENGINE_AGENT_ID", "adk_agent"),
)

Running the Examples

cd sdk/memengine-adk

# Plugin demo (automatic memory)
python -m examples.plugin_demo.agent

# Tools demo (agent-controlled memory)
python -m examples.tools_demo.agent

Both examples read MEMENGINE_URL, MEMENGINE_USER_ID, MEMENGINE_AGENT_ID from environment.


Memory Concepts

agent_id is the namespace. Memories are scoped by (user_id, agent_id). Two agents with different agent_id values have completely separate memory spaces for the same user.

Long-term writes are async. When long_term_written > 0, it means the turn was enqueued for memory extraction — not instantly persisted. The MemEngine background worker processes it shortly after.

system_prompt replaces your static instruction. The value returned by /memory/process already includes your agent's configured base instruction plus short-term context and long-term memories. If you use the Plugin, this is injected automatically.


Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

memengine_adk-0.1.0.tar.gz (7.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

memengine_adk-0.1.0-py3-none-any.whl (8.9 kB view details)

Uploaded Python 3

File details

Details for the file memengine_adk-0.1.0.tar.gz.

File metadata

  • Download URL: memengine_adk-0.1.0.tar.gz
  • Upload date:
  • Size: 7.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.11

File hashes

Hashes for memengine_adk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6f5e696599a68e17fb06466d35ac1401ab4cb50bdf85acb3dbdc9fe2ed1372a7
MD5 3d4680aa99d9431acb7e7d01ab17a204
BLAKE2b-256 7d2758df97d811ff7bf8d13cd42c7e6f5a4ad52b69cb59f02f6b49eba71d57b7

See more details on using hashes here.

File details

Details for the file memengine_adk-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: memengine_adk-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 8.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.11

File hashes

Hashes for memengine_adk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 42cfbaf2296e0a120e2aa5ece1007a8aacfdfc7279da10df4c0d410106e867c0
MD5 2914a4767bffb8feb36bbc60b7ff2801
BLAKE2b-256 d3d445ae17ae19b728795cd2ee60ff361314df8584a4bf0b8353a40977f19c71

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page