Skip to main content

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()
info

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

OptionTypeDescription
memory_typestrFilter by memory type
statusstrFilter by status (e.g., "active")
limitintMax results to return (default: 50)
offsetintPagination offset
sort_bystrSort field: "created_at", "confidence", or "last_accessed_at"
sort_orderstr"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

OptionTypeDefaultDescription
include_entitiesboolNoneInclude entity nodes in the graph
include_character_memoriesboolNoneInclude 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

OptionTypeDescription
start_datestrISO date string for range start
end_datestrISO date string for range end
group_bystr"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")
warning

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.

tip

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