Home/Documentation
Advanced

Advanced Voice Memory Surface

Use memoair-voice directly when you need manual lane control, custom prompt injection, custom server/router code, or an LLM-decided search_memory tool. Most voice agents should use the framework packages instead.

For LiveKit, start with the framework package: memoair-livekit (drop-in MemoAirLiveKitAgent). It auto-injects context before every LLM turn. Pipecat, Vapi, and Retell adapter packages land in v0.4; until then this page (and the canonical examples/livekit/voice_agents/memoair_voice_custom_agent.py example) is the supported path for those frameworks and any other custom integration.

Install

terminal
BASH
pip install "memoair-voice>=0.3.1"

Raw client

MemoAirVoiceClient wraps the internal runtime pool. Constructed once at boot with the account-scoped API key plus the project and agent IDs; the pool spawns one voice-runtime per (project_id, user.id) as calls arrive, downloading the runtime binary on first use.

advanced_client.py
PYTHON
import os
import asyncio
from memoair_voice import MemoAirVoiceClient
 
async def main() -> None:
client = MemoAirVoiceClient(
api_key=os.environ["MEMOAIR_API_KEY"],
project_id=os.environ["MEMOAIR_PROJECT_ID"],
agent_id=os.environ["MEMOAIR_AGENT_ID"],
)
try:
result = await client.search_memory(
"what timezone does the user prefer?",
user={"id": "user_42", "name": "Demo User"},
lanes=["profile", "working", "permanent", "org"],
timeout_ms=250,
)
print(result.contextText)
 
await client.save_response(
user_text="What time is standup?",
assistant_text="10:30 IST.",
user={"id": "user_42", "name": "Demo User"},
metadata={"framework": "custom"},
)
finally:
await client.aclose()
 
asyncio.run(main())

Build an org index from code

Most teams upload org knowledge in the dashboard. Use code when you need CI-driven or app-driven indexing.

build_index.py
PYTHON
client = MemoAirVoiceClient(
api_key=os.environ["MEMOAIR_API_KEY"],
project_id=os.environ["MEMOAIR_PROJECT_ID"],
agent_id=os.environ["MEMOAIR_AGENT_ID"],
)
try:
# create_index is a cloud-only call — no runtime, no user_id needed.
result = await client.create_index(
"product-knowledge",
documents=[
{"id": "returns", "text": "Returns are allowed within 30 days."},
{"id": "shipping", "text": "Express shipping takes 1-2 days."},
],
)
# IndexBuildResult(index_name="product-knowledge", chunk_count=2, version=…)
print(result)
finally:
await client.aclose()

LLM tool escape hatch

The framework packages auto-search every turn. If you explicitly want the model to decide when to search, expose the raw tool.

tool_surface.py
PYTHON
# search_memory_tool() lives on the low-level MemoAirVoiceMemory client,
# which the high-level MemoAirVoiceClient wraps. Construct it directly when
# you need the LLM-decided tool surface for a specific (project, user).
from memoair_voice import MemoAirVoiceMemory
 
async with MemoAirVoiceMemory(
api_key=os.environ["MEMOAIR_API_KEY"],
project_id=os.environ["MEMOAIR_PROJECT_ID"],
user_id="user_42",
) as memory:
tool = memory.search_memory_tool(search_memory_timeout_ms=250)
 
# Register with your framework's tool surface.
# Example: OpenAI-style schema for a custom agent runtime.
openai_tool = tool.schema()
 
async def handle_tool_call(query: str) -> str:
return await tool(query, intent="answer_current_user")

When to use this page

  • You are building a framework adapter that MemoAir does not ship yet.
  • You need lane-level control for experiments or evaluation harnesses.
  • You want LLM-decided retrieval instead of deterministic auto-inject.
  • You are debugging raw runtime responses and traces.

Framework defaults

If none of the above applies and you're on LiveKit, use memoair-livekit for the drop-in MemoAirLiveKitAgent. For Pipecat / Vapi / Retell — and any other non-LiveKit framework — use MemoAirVoiceClient with the custom-agent pattern at examples/livekit/voice_agents/memoair_voice_custom_agent.py; first-class adapter packages for those three are scheduled for v0.4. See Pipecat, Vapi, and Retell for the framework-specific wiring.

Full method signatures and options for the surfaces shown on this page: Python SDK Reference.