Memory & Knowledge Graph
Query the character's persistent memory system to retrieve facts, relationships, and conversation history across sessions.
Overview
Estuary characters remember things about users across conversations. The memory system stores facts, relationships, and context as a knowledge graph. The SDK provides a MemoryClient accessible via client.memory that lets you query this data through the REST API.
Memory is scoped to a specific character-player pair -- each player has their own memory with each character.
For more details on how memory works, see the Memory System platform documentation.
Authentication
The MemoryClient authenticates using the same API key configured on the EstuaryClient. It becomes available after connect():
async with EstuaryClient(config) as client:
await client.connect()
# client.memory is now ready to use
facts = await client.memory.get_core_facts()
The memory API uses REST endpoints, not the WebSocket connection. However, client.memory requires connect() first because the character and player IDs are confirmed during the session handshake.
Listing Memories
Retrieve a paginated list of memories with optional filtering and sorting:
result = await client.memory.get_memories(
status="active",
limit=20,
offset=0,
sort_by="created_at",
sort_order="desc",
)
print(f"Total memories: {result.total}")
for memory in result.memories:
print(f"[{memory.memory_type}] {memory.content}")
Filter Options
| Option | Type | Description |
|---|---|---|
memory_type | str | Filter by memory type |
status | str | Filter by status (e.g., "active") |
limit | int | Max results to return (default: 50) |
offset | int | Pagination offset |
sort_by | str | Sort field: "created_at", "confidence", or "last_accessed_at" |
sort_order | str | "asc" or "desc" |
Core Facts
Core facts are high-confidence, stable pieces of information the character has learned about the player -- things like their name, preferences, or important details:
result = await client.memory.get_core_facts()
for fact in result.core_facts:
print(f"{fact.fact_key}: {fact.fact_value}")
Knowledge Graph
The knowledge graph represents memories as a network of entities and relationships:
graph = await client.memory.get_graph(
include_entities=True,
include_character_memories=True,
)
print("Nodes:", len(graph.nodes))
print("Edges:", len(graph.edges))
print("Stats:", graph.stats)
Graph Options
| Option | Type | Default | Description |
|---|---|---|---|
include_entities | bool | None | Include entity nodes in the graph |
include_character_memories | bool | None | Include the character's own memories |
Searching Memories
Search across all memories using natural language:
results = await client.memory.search("likes pizza")
print(f"Found {results.total} results for \"{results.query}\"")
for result in results.results:
print(f"Score: {result.similarity_score} — {result.memory.content}")
Search uses semantic similarity, so the query does not need to match the stored text exactly.
Timeline
View memories organized chronologically:
timeline = await client.memory.get_timeline(group_by="week")
print(f"Total memories: {timeline.total_memories}")
for group in timeline.timeline:
print(f"{group.date}: {len(group.memories)} memories")
Timeline Options
| Option | Type | Description |
|---|---|---|
start_date | str | ISO date string for range start |
end_date | str | ISO date string for range end |
group_by | str | "day", "week", or "month" |
Statistics
Get aggregate statistics about the character's memory for this player:
stats = await client.memory.get_stats()
print(f"Active: {stats.total_active}, Core facts: {stats.core_facts}")
print(f"By type: {stats.by_type}")
Deleting Memories
Delete all memories for this player-character pair:
result = await client.memory.delete_all(confirm=True)
print(f"Deleted {result.deleted_count} memories")
This is irreversible. The confirm=True parameter is a safety guard.
Example: Memory Dashboard
import asyncio
from estuary_sdk import EstuaryClient, EstuaryConfig
config = EstuaryConfig(
server_url="https://api.estuary-ai.com",
api_key="est_your_api_key",
character_id="your-character-uuid",
player_id="user-123",
)
async def main():
async with EstuaryClient(config) as client:
await client.connect()
# Fetch everything concurrently
facts, graph, stats, timeline = await asyncio.gather(
client.memory.get_core_facts(),
client.memory.get_graph(include_entities=True),
client.memory.get_stats(),
client.memory.get_timeline(group_by="week"),
)
print("=== Core Facts ===")
for fact in facts.core_facts:
print(f" {fact.fact_key}: {fact.fact_value}")
print("\n=== Knowledge Graph ===")
print(f" {len(graph.nodes)} nodes, {len(graph.edges)} edges")
print("\n=== Stats ===")
print(f" Active: {stats.total_active}, Core facts: {stats.core_facts}")
print("\n=== Timeline ===")
for group in timeline.timeline:
print(f" {group.date}: {len(group.memories)} memories")
asyncio.run(main())
Real-Time Memory Events
If you want to be notified when new memories are extracted during a conversation, enable realtime_memory in your config:
config = EstuaryConfig(
server_url="https://api.estuary-ai.com",
api_key="est_your_api_key",
character_id="your-character-uuid",
player_id="user-123",
realtime_memory=True,
)
async with EstuaryClient(config) as client:
async def on_memory_updated(event):
print(f"Extracted {event.memories_extracted} memories, {event.facts_extracted} facts")
for memory in event.new_memories:
print(f" [{memory.memory_type}] {memory.content} (confidence: {memory.confidence})")
client.on("memory_updated", on_memory_updated)
await client.connect()
The memory_updated event fires after each bot response when the server finishes extracting memories from the conversation turn.
Real-time memory events are useful for building UIs that show the user what the character has learned, or for triggering application logic based on extracted facts.
Next Steps
- API Reference: Data Models -- Memory type definitions
- Memory System (Platform) -- How memory works under the hood