mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-05-17 03:56:18 +00:00
| .. | ||
| src/supermemory_cartesia | ||
| pyproject.toml | ||
| README.md | ||
| requirements.txt | ||
Supermemory Cartesia SDK
Memory-enhanced voice agents with Supermemory and Cartesia Line.
Installation
pip install supermemory-cartesia
Quick Start
import os
from line.llm_agent import LlmAgent, LlmConfig
from line.voice_agent_app import VoiceAgentApp
from supermemory_cartesia import SupermemoryCartesiaAgent
async def get_agent(env, call_request):
# Extract container_tag from call metadata (typically user ID)
container_tag = call_request.metadata.get("user_id", "default-user")
# Create base LLM agent
base_agent = LlmAgent(
model="gemini/gemini-2.5-flash-preview-09-2025",
config=LlmConfig(
system_prompt="You are a helpful voice assistant with memory.",
introduction="Hello! Great to talk with you again!"
)
)
# Wrap with Supermemory
memory_agent = SupermemoryCartesiaAgent(
agent=base_agent,
api_key=os.getenv("SUPERMEMORY_API_KEY"),
container_tag=container_tag,
custom_id=call_request.call_id,
)
return memory_agent
# Create voice agent app
app = VoiceAgentApp(get_agent=get_agent)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
Configuration
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
agent |
LlmAgent | Yes | The Cartesia Line agent to wrap |
container_tag |
str | Yes | Primary container tag for memory scoping (e.g., user ID) |
custom_id |
str | Yes | Custom ID for grouping conversation messages into a single document |
add_memory |
Literal | No | Memory persistence mode: "always" (default) or "never" |
container_tags |
List[str] | No | Additional container tags for organization (e.g., ["org", "prod"]) |
api_key |
str | No | Supermemory API key (or set SUPERMEMORY_API_KEY env var) |
config |
MemoryConfig | No | Advanced configuration |
base_url |
str | No | Custom API endpoint |
Advanced Configuration
from supermemory_cartesia import SupermemoryCartesiaAgent
memory_agent = SupermemoryCartesiaAgent(
agent=base_agent,
container_tag="user-123",
custom_id="conversation-456",
add_memory="always", # "always" (default) or "never"
container_tags=["org-acme", "prod"], # Optional: additional tags
config=SupermemoryCartesiaAgent.MemoryConfig(
search_limit=10, # Max memories to retrieve
search_threshold=0.1, # Similarity threshold
mode="full", # "profile", "query", or "full"
system_prompt="Based on previous conversations, I recall:\n\n",
),
)
# Read-only mode - retrieve memories but don't save new ones
read_only_agent = SupermemoryCartesiaAgent(
agent=base_agent,
container_tag="user-123",
custom_id="conversation-456",
add_memory="never", # Only retrieve, don't save
)
Memory Modes
| Mode | Static Profile | Dynamic Profile | Search Results |
|---|---|---|---|
"profile" |
Yes | Yes | No |
"query" |
No | No | Yes |
"full" |
Yes | Yes | Yes |
How It Works
- Intercepts events - Listens for
UserTurnEndedevents from Cartesia Line - Retrieves memories - Queries Supermemory
/v4/profileAPI with user's message - Enriches context - Adds memories to event history as system message
- Stores messages - Sends conversation to Supermemory (background, non-blocking)
- Passes to agent - Forwards enriched event to wrapped LlmAgent
What Gets Stored
User and assistant messages are sent to Supermemory:
{
"content": "User: What's the weather?\nAssistant: It's sunny today!",
"container_tags": ["user-123", "org-acme", "prod"],
"metadata": { "platform": "cartesia" }
}
Architecture
Cartesia Line uses an event-driven architecture:
User Speaks (Audio)
↓
[Ink STT] → Automatic speech recognition
↓
UserTurnEnded Event {content: "user message", history: [...]}
↓
┌──────────────────────────────────────────────┐
│ SUPERMEMORY CARTESIA AGENT (Wrapper) │
│ │
│ process(env, event): │
│ 1. Intercept UserTurnEnded │
│ 2. Extract user message │
│ 3. Query Supermemory API │
│ 4. Enrich event.history with memories │
│ 5. Pass to wrapped LlmAgent │
│ 6. Store conversation (async background) │
└──────────────────────────────────────────────┘
↓
AgentSendText Event {text: "response"}
↓
[Sonic TTS] → Ultra-fast speech synthesis
↓
Audio Output
Comparison with Pipecat SDK
| Aspect | Pipecat | Cartesia Line |
|---|---|---|
| Integration Pattern | Extends FrameProcessor |
Wrapper around LlmAgent |
| Event Handling | process_frame() method |
process() method |
| Events | LLMContextFrame, LLMMessagesFrame |
UserTurnEnded, CallStarted |
| Context Object | LLMContext.get_messages() |
event.history |
| Memory Injection | Modify context.add_message() |
Modify event.history |
Full Example with Tools
import os
from line.llm_agent import LlmAgent, LlmConfig
from line.tools import LoopbackTool
from line.voice_agent_app import VoiceAgentApp
from supermemory_cartesia import SupermemoryCartesiaAgent
# Define custom tools
async def get_weather(location: str) -> str:
return f"The weather in {location} is sunny, 72°F"
weather_tool = LoopbackTool(
name="get_weather",
description="Get current weather for a location",
function=get_weather
)
async def get_agent(env, call_request):
container_tag = call_request.metadata.get("user_id", "default-user")
org_id = call_request.metadata.get("org_id")
# Create LLM agent with tools
base_agent = LlmAgent(
model="gemini/gemini-2.5-flash-preview-09-2025",
tools=[weather_tool],
config=LlmConfig(
system_prompt="You are a personal assistant with memory and tools.",
introduction="Hi! How can I help you today?"
)
)
# Wrap with Supermemory
memory_agent = SupermemoryCartesiaAgent(
agent=base_agent,
api_key=os.getenv("SUPERMEMORY_API_KEY"),
container_tag=container_tag,
custom_id=call_request.call_id,
container_tags=[org_id] if org_id else None,
config=SupermemoryCartesiaAgent.MemoryConfig(
mode="full",
search_limit=15,
search_threshold=0.15,
)
)
return memory_agent
app = VoiceAgentApp(get_agent=get_agent)
Development
# Clone repository
git clone https://github.com/supermemoryai/supermemory
cd supermemory/packages/cartesia-sdk-python
# Install in development mode
pip install -e ".[dev]"
# Run tests
pytest
# Format code
black .
isort .
License
MIT