MemorySync
Getting Started

Pipecat Voice Memory

Long-term memory for Pipecat voice pipelines — one FrameProcessor between your context aggregator and LLM enriches every context frame under a hard latency budget and persists only what is new. Built on the current frame API and tested through Pipecat’s own harness.

What the package provides

PieceWhat it does
MemorySyncMemoryServiceA FrameProcessor you place before your LLM service. Each LLMContextFrame is enriched with relevant memories (as a system message) and mined for new turns to persist — then pushed on, enriched or not, on time.
Budgeted enrichmentRecall runs under a hard timeout (default 1.2s). A slow or dead memory backend means an unenriched frame, never a stalled voice reply.
Delta-only captureOnly messages not seen before are stored, tracked by deterministic idempotency seeds — O(new), not O(entire context) per frame.
Lifecycle safetyOn EndFrame, queued writes get a bounded window to land so the call’s final exchange is never lost; CancelFrame pushes first, then briefly salvages.
Mem0SupermemoryZepMemorySync
Pipecat integration✓ in-tree service△ exists but imports a removed frame API — cannot load on Pipecat 1.x✗ nonepipecat-memorysync package
Recall latency budget✗ unbounded await before every LLM push✓ hard timeout, default 1.2s, tested against a 5s-slow backend
Write amplification✗ re-stores the ENTIRE context every frame — O(n²) writes per call✓ delta-only with idempotency seeds, proven by test (3 stores for 3 new messages)
Injected context re-storedunguarded✓ the injected block is capture-excluded, tested
End-of-call data losspending stores can be torn down✓ graceful EndFrame flush, tested
Tested via the official harness△ partial✓ every test runs through pipecat.tests.utils.run_test

Install and place it

pip install pipecat-memorysync

Placement matters: after context_aggregator.user() so the frame carries the full context, before llm so enrichment reaches the model. The service is reusable across pipeline runs; call await memory.aclose() at application shutdown for an explicit flush.

What runs when

MomentWhat happens
LLMContextFrame arrivesRecall runs under the budget; relevant memories land as a system message (position configurable). The frame is pushed on time either way.
Same frame, after pushNew user and assistant messages — and only new ones — persist in the background with role fidelity. The injected memory block is excluded.
EndFrame (graceful end)Queued stores get a bounded 3s window to land before the pipeline stops — the final exchange is not lost.
CancelFrame (abort)The frame is pushed first; writes get a brief salvage window.
Backend slow / dead / over quotaUnenriched frame, silent skip — the pipeline is never affected. Free-tier quota exhaustion is silent by design; evaluation keys surface strict 429s instead.

Configuration

ParameterDefaultMeaning
top_k5Memories injected per turn
recall_timeout1.2Hard recall budget in seconds
system_promptguarded headerPrefix line for the injected block; doubles as the capture-exclusion marker
add_as_system_messageTrueInject as a system message (else appended to the latest user message)
position"end""start" or "end" of the message list
min_prompt_chars8Skip recall for trivial prompts

Supported versions

SurfaceRequiresVerified on
pipecat-memorysync 1.0.0pipecat-ai 1.x, Python 3.10+14 CI checks driven through pipecat.tests.utils.run_test — the framework’s official harness — on the latest pipecat-ai: budget enforcement, delta-only proof, injection exclusion, role fidelity, EndFrame flush, quota modes

Where to go next

Was this page helpful?