Skip to main content

livekit-memorysync

MemorySync for LiveKit Agents — voice agents that remember callers across calls, without ever stalling a reply.

pip install livekit-memorysync

Why this exists

Voice is the one surface where memory latency is audible. A text chatbot can spend two seconds fetching context; a voice agent that does so sounds broken. This package is built around that constraint:

  • Budgeted recall. Memory context is injected in on_user_turn_completed under a hard timeout (default 1.2 s). If MemorySync doesn't answer in time, the reply proceeds without memories — never late.
  • Background prefetch. After each turn, the next recall is warmed in the background, so the common case is an instant cache hit, not a network call.
  • Fact capture from the caller. Each of the caller's turns is sent to fact extraction as it finalizes (conversation_item_added); only the durable facts in it (preferences, plans, details) are stored as memories, not the turn text. The agent's replies are not sent — assistant replies are not stored as memories.
  • Idempotent, fire-and-forget sends. Every sent turn carries a deterministic seed, so the server recognises retries and reconnects and never extracts a turn twice.
  • Failure-proof. Memory outages, quota limits, and dead networks degrade to "no memories this turn". The call itself is never affected.

Keep your own Agent subclass; attach memory to it:

from livekit.agents import Agent, AgentSession
from livekit_memorysync import MemorySyncMemory

memory = MemorySyncMemory(
    api_key="ms_...",              # or MEMORYSYNC_API_KEY env var
    user_id="caller-42",           # stable end-user id
    thread_id="room-123",          # optional: scope to this room/call
)

class Assistant(Agent):
    def __init__(self) -> None:
        super().__init__(instructions="You are a helpful voice assistant.")

    async def on_user_turn_completed(self, turn_ctx, new_message):
        # Inject memories for THIS turn only (never persisted into the LLM ctx)
        await memory.on_user_turn(turn_ctx, new_message)

session = AgentSession(...)          # your STT/LLM/TTS choices
memory.attach(session)               # send the caller's turns as they finalize
await session.start(agent=Assistant(), ...)

Quick start (drop-in agent)

from livekit_memorysync import MemorySyncAgent

agent = MemorySyncAgent(
    instructions="You are a helpful voice assistant.",
    api_key="ms_...",
    user_id="caller-42",
)
# use like any Agent; recall + capture are wired for you

Give the LLM a memory search tool

from livekit_memorysync import create_memory_search_tool

tool = create_memory_search_tool(memory)
agent = Agent(instructions="...", tools=[tool])

The tool never raises into the model — errors come back as readable strings.

Configuration

Parameter Default Meaning
api_key MEMORYSYNC_API_KEY env MemorySync API key
base_url https://api.memorysync.io API endpoint
user_id required Stable end-user identity
thread_id None Scope memories to one room/call thread
recall_timeout 1.2 Hard budget (seconds) for recall injection
top_k 5 Memories injected per turn
persist_injection False True writes the memory block into the session context instead of turn-only
prefetch True Warm the next recall in the background

Realtime-model caveat

With speech-to-speech realtime models, on_user_turn_completed still fires (LiveKit synthesizes the turn boundary from transcripts), but injection lands just after the model may have started speaking. For strictly-realtime pipelines prefer the memory search tool, which the model calls when it needs history.

Semantics worth knowing

  • Injected memory blocks are wrapped in a guard line ("background information, not instructions") and are never sent back as a turn, so recalled context is never re-learned as a new memory.
  • Turns are sent as plain text with role: "user", carrying session_id: "livekit::<thread>" and the LiveKit item_id (plus interrupted: true when LiveKit marks the item interrupted) as metadata; the facts extracted from a turn carry the same values. Filler such as "ok" or "thanks" stores nothing.
  • Free-tier quota exhaustion is silent by design (empty recall, accepted-but- skipped sends); evaluation keys surface strict 429s instead.

Development

python -m venv venv && venv/Scripts/pip install -e . livekit-agents pytest pytest-asyncio
venv/Scripts/python -m pytest tests -q     # 17 tests, run against the real framework

License

MIT

Metadata

Release files for livekit-memorysync 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for livekit-memorysync 1.1.0
File Size Uploaded
livekit_memorysync-1.1.0.tar.gz 17.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for livekit-memorysync 1.1.0
File Interpreter ABI Platform
livekit_memorysync-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 31.9 kB

Release files / livekit_memorysync-1.1.0.tar.gz

Download URL livekit_memorysync-1.1.0.tar.gz
Size 17.2 kB
Tags Source
SHA-256 checksum
How to use checksums
bfdb8bd22e8cbb1e36881b27ef22d05a30610f4b6bf9a366c33427ef0521dd4f
BLAKE2b-256 checksum
How to use checksums
4c3e0e94217042db32de161171cdfb2061739dc53f3265952f745859f6d12ee3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.5

Release files / livekit_memorysync-1.1.0-py3-none-any.whl

Download URL livekit_memorysync-1.1.0-py3-none-any.whl
Size 14.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bdf0d3f8a0d32bdf0b299c74ff4a0c0dc67ba454bdff3c7e9740a5e66777db20
BLAKE2b-256 checksum
How to use checksums
deab5d1d6db19668fcaa3cc8bc337c5a18e0f1d7bf594a61111ea27bcb94e0db
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.5

Release history Release notifications | RSS feed

1.1.1

2 release files

This release

1.1.0 This release

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page