Memory stores
In shortReference for BaseStore, QdrantStore, Mem0Store, embedding classes, MemoryConfig, MemoryIntegration, preload helpers and store factories.
- 17 min read
- 13 sections
- Updated
- v0.10.0
- Markdown
A memory store keeps facts, preferences and past interactions across conversation threads, so an agent can recall them later. This page documents the tenxgraph.storage.store API: embeddings, QdrantStore, Mem0Store, memory configuration, retrieval helpers and factories. A checkpointer, by contrast, saves state within one thread.
For the concepts and a walkthrough, see Long-term memory and Use a memory store.
Import paths
from tenxgraph.storage.store import (
BaseStore, QdrantStore, Mem0Store,
MemoryConfig, AgentMemoryConfig, UserMemoryConfig, MemoryIntegration,
create_memory_preload_node, get_memory_system_prompt,
)
from tenxgraph.storage.store.store_schema import (
MemoryType, RetrievalStrategy, DistanceMetric,
MemorySearchResult, MemoryRecord,
) # MemoryType, DistanceMetric and MemorySearchResult are also exported from tenxgraph.storage.store
from tenxgraph.storage.store.embedding import (
BaseEmbedding, OpenAIEmbedding, GoogleEmbedding,
)
from tenxgraph.storage.store.long_term_memory import ReadMode # also exported from tenxgraph.storage.storeInstall the dependencies for the backends you use:
pip install openai # OpenAIEmbedding
pip install google-genai # GoogleEmbedding
pip install "10xgraph[qdrant]" # QdrantStore (qdrant-client)
pip install "10xgraph[mem0]" # Mem0Store (mem0ai)Enums
MemoryType
| Value | Use case |
|---|---|
EPISODIC |
Conversation memories: what happened in a past chat. |
SEMANTIC |
Facts and general knowledge, such as “the user prefers dark mode”. |
PROCEDURAL |
How-to knowledge, such as “to reset the password, go to Settings > Security”. |
ENTITY |
Named entities and their attributes. |
RELATIONSHIP |
Connections between entities. |
DECLARATIVE |
Explicit facts and events stated by the user. |
CUSTOM |
Application-defined memory categories. |
RetrievalStrategy
| Value | Description |
|---|---|
SIMILARITY |
Vector similarity search. The default in asearch. |
TEMPORAL |
Time-ordered retrieval, most recent first. |
RELEVANCE |
Relevance scoring combining recency and similarity. |
HYBRID |
Combines similarity and temporal signals. |
GRAPH_TRAVERSAL |
Navigates a knowledge graph to find connected memories. |
DistanceMetric
| Value | Description |
|---|---|
COSINE |
Cosine similarity. Best for normalised embeddings. |
EUCLIDEAN |
Euclidean (L2) distance. Sensitive to vector magnitude. |
DOT_PRODUCT |
Inner product. Fast; requires normalisation to equal cosine. |
MANHATTAN |
L1 distance. Robust to outliers. |
ReadMode
ReadMode is a string enum that controls how an agent reads long-term memory. Strings such as "preload" are accepted wherever a ReadMode is expected.
| Value | Description |
|---|---|
NO_RETRIEVAL |
Value "no_retrieval". The model cannot read past memories. Writing stays available through memory_tool when you register it. |
PRELOAD |
Value "preload". Relevant memories are retrieved and injected as a system message before the LLM call. |
POSTLOAD |
Value "postload". The model decides when to search by calling a memory tool. |
Embeddings
QdrantStore requires an embedding service to turn text into vectors for similarity search. Use a built-in class or subclass BaseEmbedding. Provider errors surface as RuntimeError.
BaseEmbedding
Abstract base class for all embedding implementations. Subclasses must implement aembed_batch, aembed and the dimension property. The example below is a toy deterministic embedding that runs without any API key, useful for tests only.
import hashlib
from tenxgraph.storage.store.embedding import BaseEmbedding
class HashEmbedding(BaseEmbedding):
"""Toy embedding for tests: hashes text into a fixed-size vector."""
async def aembed(self, text: str) -> list[float]:
digest = hashlib.sha256(text.encode()).digest()
return [b / 255 for b in digest] # 32 floats
async def aembed_batch(self, texts: list[str]) -> list[list[float]]:
return [await self.aembed(t) for t in texts]
@property
def dimension(self) -> int:
return 32
print(HashEmbedding().embed("hello")[:3]) # sync wrapper| Member | Abstract | Description |
|---|---|---|
aembed_batch(texts) |
Yes | Async: embed a list of texts. Returns one vector per text. |
aembed(text) |
Yes | Async: embed one text. Returns a vector. |
dimension |
Yes (property) | Embedding size as an integer. The collection is created with this size. |
embed_batch(texts) |
No | Sync wrapper around aembed_batch. |
embed(text) |
No | Sync wrapper around aembed. |
OpenAIEmbedding
Embedding service using OpenAI embedding models.
Requires: pip install openai
from tenxgraph.storage.store.embedding import OpenAIEmbedding
# Uses text-embedding-3-small by default; reads OPENAI_API_KEY
embedding = OpenAIEmbedding()
# Or pass the model and key explicitly
embedding = OpenAIEmbedding(
model="text-embedding-3-large",
api_key="<your-openai-key>",
)| Parameter | Type | Default | Description |
|---|---|---|---|
model |
str |
"text-embedding-3-small" |
OpenAI embedding model to use. |
api_key |
str | None |
None | OpenAI API key. If not provided, reads from OPENAI_API_KEY env var. |
Raises: ImportError if openai is not installed. ValueError if no key is found. The dimension property raises ValueError for a model name it does not know (known: text-embedding-3-small, text-embedding-3-large, text-embedding-3-xl, text-embedding-4-base, text-embedding-4-large), so wrap an unknown model in a custom BaseEmbedding subclass.
GoogleEmbedding
Embedding service using Google Gemini embedding models.
Requires: pip install google-genai
from tenxgraph.storage.store.embedding import GoogleEmbedding
# Uses gemini-embedding-001 by default; reads GOOGLE_API_KEY or GEMINI_API_KEY
embedding = GoogleEmbedding()
# Or pass the model, key and a reduced output size explicitly
embedding = GoogleEmbedding(
model="gemini-embedding-001",
api_key="<your-google-key>",
output_dimensionality=768, # optional
)| Parameter | Type | Default | Description |
|---|---|---|---|
model |
str |
"gemini-embedding-001" |
Google embedding model to use. |
api_key |
str | None |
None | Google API key. Reads from GOOGLE_API_KEY or GEMINI_API_KEY env vars if not provided. |
output_dimensionality |
int | None |
None | Optional: reduce output dimension. Some models support this. |
Raises: ImportError if google-genai is not installed. ValueError if no key is found. dimension returns output_dimensionality when set, 3072 for gemini-embedding-001, and 768 for other models.
Memory configuration
MemoryConfig is the object you pass to Agent(..., memory=...). It sets the store, the retrieval mode and two optional scopes: user memory (the model can search and write) and agent memory (the model can only search). All three are pydantic models.
MemoryConfig
Primary configuration object for Agent(..., memory=...). A str retrieval mode is converted to ReadMode. limit must be at least 1 and score_threshold must not be negative, otherwise validation raises.
| Field | Type | Default | Description |
|---|---|---|---|
store |
BaseStore | None |
None | The memory store (QdrantStore, Mem0Store, etc.). Required if memory is enabled. |
retrieval_mode |
ReadMode | str |
ReadMode.POSTLOAD |
How memories are retrieved: NO_RETRIEVAL, PRELOAD, or POSTLOAD. |
limit |
int |
5 | Maximum number of memories to retrieve per search. |
score_threshold |
float |
0.0 | Minimum similarity score for a memory to be returned. 0.0 = no threshold. |
max_tokens |
int | None |
None | Optional token budget for retrieved memory context. |
inject_system_prompt |
bool |
True | Whether to include memory system instructions in the model’s system prompt. |
config |
dict[str, Any] |
{} | Application-defined config passed to store methods. |
user_memory |
UserMemoryConfig | None |
UserMemoryConfig() | Config for user-scoped memory (searchable and writable by model). |
agent_memory |
AgentMemoryConfig | None |
AgentMemoryConfig() | Config for agent/app-scoped memory (searchable but not writable by model). |
from tenxgraph.core import Agent
from tenxgraph.storage.store import MemoryConfig, OpenAIEmbedding, QdrantStore, ReadMode
store = QdrantStore(embedding=OpenAIEmbedding(), path="./qdrant_data")
memory = MemoryConfig(
store=store,
retrieval_mode=ReadMode.PRELOAD, # inject memories before each model call
limit=5,
score_threshold=0.5,
max_tokens=2000,
)
agent = Agent(model="gpt-4o", memory=memory)UserMemoryConfig
Configuration for user-scoped long-term memory. The model can both search and write to user memories. memory_type and category must not be empty, and limit must be at least 1 when set.
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
bool |
True | Whether user memory is enabled. |
store |
BaseStore | None |
None | The store instance (if different from the parent MemoryConfig). |
memory_type |
str |
"episodic" |
Default memory type when storing. One of the MemoryType enum values. |
category |
str |
"general" |
Default memory category when storing. |
limit |
int | None |
None | Max memories to retrieve. If None, uses the parent config limit. |
score_threshold |
float | None |
None | Min similarity score, must not be negative. If None, uses the parent config threshold. |
config |
dict[str, Any] |
{} | Optional config dict passed to store calls. |
user_id |
str | None |
None | User identifier for scoping. Blank strings are rejected. |
AgentMemoryConfig
Configuration for agent/app-scoped long-term memory. The model can search but not write to agent memories.
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
bool |
False | Whether agent memory is enabled (disabled by default). |
store |
BaseStore | None |
None | The store instance (if different from the parent MemoryConfig). |
memory_type |
str |
"episodic" |
Default memory type. |
category |
str |
"general" |
Default memory category. |
limit |
int | None |
None | Max memories to retrieve. |
score_threshold |
float | None |
None | Min similarity score. |
config |
dict[str, Any] |
{} | Optional config dict. |
agent_id |
str | None |
None | Agent identifier for scoping. |
app_id |
str | None |
None | App identifier for scoping. |
Memory retrieval functions
These helpers build the system prompt and the preload graph node by hand, for graphs that do not use Agent(memory=...). MemoryIntegration bundles them.
get_memory_system_prompt(mode)
Returns a system prompt fragment for the given retrieval mode. All modes include write instructions because writing is always available.
from tenxgraph.storage.store import get_memory_system_prompt
prompt_fragment = get_memory_system_prompt(mode="preload")
print(prompt_fragment[:80]) # add this text to your system prompt| Parameter | Type | Default | Description |
|---|---|---|---|
mode |
str |
"no_retrieval" |
Retrieval mode: "no_retrieval", "preload", or "postload". |
Returns: A string prompt fragment suitable for concatenation into a larger system prompt. Includes memory-specific instructions and write guidance. mode="preload" produces text that begins:
You have been provided with long-term memory context from previous interactions. Use it to personalize your responses when relevant. The memory context appears as system messages labeled '[Long-term Memory Context]'.Agent(memory=...) uses the related get_agent_memory_system_prompt(memory_config) instead, which describes user_memory_tool and agent_memory_tool.
create_memory_preload_node(store, ...)
Factory function that returns a graph node for preloading memories. Wire it before your LLM node to retrieve relevant memories and inject them as a system message. The search ignores thread_id, so memories are shared across threads.
from tenxgraph.core import StateGraph
from tenxgraph.core.state import AgentState
from tenxgraph.storage.store import OpenAIEmbedding, QdrantStore, create_memory_preload_node
store = QdrantStore(embedding=OpenAIEmbedding(), path="./qdrant_data")
preload = create_memory_preload_node(store=store, limit=5, score_threshold=0.5)
graph = StateGraph(AgentState)
graph.add_node("memory_preload", preload)
graph.add_edge("memory_preload", "main_agent") # "main_agent" is your LLM node
graph.set_entry_point("memory_preload")| Parameter | Type | Default | Description |
|---|---|---|---|
store |
BaseStore |
Required | The memory store instance. |
query_builder |
Callable[[AgentState], str] | None |
None | Custom function to extract the search query from state. Default: extracts the latest user message text. |
limit |
int |
5 | Maximum memories to retrieve. |
score_threshold |
float |
0.0 | Minimum similarity score. 0.0 = no threshold. |
memory_types |
list[MemoryType] | None |
None | If specified, search only these memory types (e.g., [MemoryType.EPISODIC, MemoryType.SEMANTIC]). |
system_prompt_template |
str |
Built-in template | Template for the injected system message, filled with str.format. Must contain a {memories} placeholder. |
max_tokens |
int | None |
None | Optional token budget for retrieved context. |
Returns: An async node function (state: AgentState, config: dict) -> list[Message] that returns one system message, or an empty list if there is no user message, no match, or the search fails (the failure is logged).
MemoryIntegration
MemoryIntegration is a single entry point that builds the preload node, system prompt and memory tools for a hand-built graph.
from tenxgraph.core import StateGraph
from tenxgraph.core.state import AgentState
from tenxgraph.storage.store import MemoryIntegration, OpenAIEmbedding, QdrantStore
store = QdrantStore(embedding=OpenAIEmbedding(), path="./qdrant_data")
memory = MemoryIntegration(store=store, retrieval_mode="preload")
graph = StateGraph(AgentState)
memory.wire(graph, entry_to="main_agent") # adds "memory_preload" and the entry point
system_prompt = memory.system_prompt # add to your LLM node's prompt
tools = memory.tools # [memory_tool], register with ToolNode| Parameter | Type | Default | Description |
|---|---|---|---|
store |
BaseStore |
Required | The memory store. |
retrieval_mode |
ReadMode | str |
ReadMode.NO_RETRIEVAL |
Retrieval mode. |
limit |
int |
5 | Maximum memories to retrieve. |
score_threshold |
float |
0.0 | Minimum similarity score. |
max_tokens |
int | None |
None | Token budget for retrieved context. |
query_builder |
Callable[[AgentState], str] | None |
None | Custom search query extractor. |
preload_prompt_template |
str | None |
None | Custom preload template with {memories}. |
Properties: retrieval_mode, store, system_prompt, tools and preload_node (None unless mode is preload). wire(graph, entry_to, preload_node_name="memory_preload") adds the preload node in preload mode and otherwise only sets entry_to as the entry point.
BaseStore
Abstract base class that every store backend implements. Every method takes a config dict as its first argument; the store reads user_id (and, for some backends, thread_id, agent_id or app_id) from it.
Core async methods
| Method | Signature | Description |
|---|---|---|
astore |
async (config, content, memory_type=EPISODIC, category="general", metadata=None, **kwargs) -> str |
Add a memory. Returns the memory ID. |
asearch |
async (config, query, memory_type=None, category=None, limit=10, score_threshold=None, filters=None, retrieval_strategy=SIMILARITY, distance_metric=COSINE, max_tokens=4000, **kwargs) -> list[MemorySearchResult] |
Search memories by query. |
aget |
async (config, memory_id, **kwargs) -> MemorySearchResult | None |
Fetch a memory by ID. |
aget_all |
async (config, limit=100, **kwargs) -> list[MemorySearchResult] |
List memories in the config’s scope. |
aupdate |
async (config, memory_id, content, metadata=None, **kwargs) -> Any |
Update a memory’s content. |
adelete |
async (config, memory_id, **kwargs) -> Any |
Delete a memory by ID. |
aforget_memory |
async (config, **kwargs) -> Any |
Delete memories for a user or agent scope. Accepted keyword arguments are store-specific. |
asetup |
async () -> Any |
Create the collection or other backing resources. Implemented by QdrantStore; the base class raises NotImplementedError. |
arelease |
async () -> None |
Release connections. Not abstract, but the base implementation raises NotImplementedError; Mem0Store overrides it. |
There is no bulk abatch_store; call astore in a loop or with asyncio.gather.
Sync wrappers
store.store(config, content)
store.search(config, query)Each async method has a sync wrapper named without the a prefix (store, search, get, get_all, update, delete, forget_memory, setup, release). Use the async variants in async code.
Config dictionary
config = {
"user_id": "alice", # user scope (required by Mem0Store)
"thread_id": "thread-1", # optional; QdrantStore reads it
}MemorySearchResult
Returned by asearch, aget and aget_all. Each result represents a matching memory.
| Field | Type | Description |
|---|---|---|
id |
str |
Memory ID. |
content |
str |
The memory text. |
score |
float |
Similarity or relevance score, at least 0.0. |
memory_type |
MemoryType |
Categorisation. |
metadata |
dict |
Application-defined metadata. |
vector |
list[float] | None |
Embedding vector (if returned by backend). |
user_id |
str | None |
User scope. |
thread_id |
str | None |
Thread where this memory was created. |
timestamp |
datetime | None |
Creation time. |
QdrantStore
Vector store backed by Qdrant. Production-ready for similarity search.
import asyncio
from tenxgraph.storage.store import OpenAIEmbedding, QdrantStore
# Local Qdrant (persisted to disk)
store = QdrantStore(
embedding=OpenAIEmbedding(),
path="./qdrant_data",
)
# Remote Qdrant
store = QdrantStore(
embedding=OpenAIEmbedding(),
host="localhost",
port=6333,
)
# Qdrant Cloud
store = QdrantStore(
embedding=OpenAIEmbedding(),
url="https://xyz.qdrant.io",
api_key="<your-qdrant-api-key>",
)
asyncio.run(store.asetup()) # creates the collection; pass the store to graph.compile(store=store)path, url and host/port are checked in that order: path wins, then url, otherwise host (default localhost) and port (default 6333). Extra keyword arguments go to AsyncQdrantClient.
Constructor parameters
| Parameter | Type | Description |
|---|---|---|
embedding |
BaseEmbedding |
Embedding service used to vectorise text before storage and search. |
path |
str | None |
Local path for embedded Qdrant server. |
host |
str | None |
Remote Qdrant host. |
port |
int | None |
Remote Qdrant port (default: 6333). |
url |
str | None |
Qdrant Cloud URL. |
api_key |
str | None |
Qdrant Cloud API key. |
collection |
str | None |
Qdrant collection name. Defaults to DEFAULT_COLLECTION, which is "agentflow_memories". |
distance_metric |
DistanceMetric |
Distance metric for the collection. Default: COSINE. |
**kwargs |
Any |
Passed to AsyncQdrantClient. |
Mem0Store
Managed long-term memory using the mem0 library. Delegates all vector storage and memory management to Mem0.
from tenxgraph.storage.store import Mem0Store
store = Mem0Store(config={
"llm": {"provider": "openai", "config": {"model": "gpt-4o-mini"}},
"embedder": {"provider": "openai", "config": {"model": "text-embedding-3-small"}},
"vector_store": {"provider": "qdrant", "config": {"host": "localhost", "port": 6333}},
})
# pass the store to graph.compile(store=store); no asetup() call is needed| Parameter | Type | Default | Description |
|---|---|---|---|
config |
mem0 MemoryConfig | dict |
Required | Mem0 configuration. A dict goes through AsyncMemory.from_config. |
app_id |
str | None |
"agentflow_app" |
App identifier. A per-call config["app_id"] overrides it. |
Mem0Store delegates to Mem0’s AsyncMemory client, created lazily on first use. Every call needs user_id in the config dict, otherwise it raises ValueError. asetup is not implemented for Mem0Store, so do not call it. aforget_memory deletes all memories for the user.
Store factory functions
Convenience functions to create and configure store instances with common patterns.
create_local_qdrant_store(path, embedding, collection=...)
Create a QdrantStore with a local embedded Qdrant server.
from tenxgraph.storage.store import create_local_qdrant_store, OpenAIEmbedding
store = create_local_qdrant_store(
embedding=OpenAIEmbedding(),
path="./qdrant_data",
)| Parameter | Type | Description |
|---|---|---|
embedding |
BaseEmbedding |
The embedding service. |
path |
str |
Local directory path for Qdrant persistence. |
collection |
str |
Collection name. Default "agentflow_memories". |
**kwargs |
Any |
Passed to QdrantStore. |
Returns: A configured QdrantStore instance.
create_remote_qdrant_store(host, port, embedding, collection=...)
Create a QdrantStore connected to a remote Qdrant server.
from tenxgraph.storage.store import create_remote_qdrant_store, OpenAIEmbedding
store = create_remote_qdrant_store(
embedding=OpenAIEmbedding(),
host="localhost",
port=6333,
)| Parameter | Type | Description |
|---|---|---|
embedding |
BaseEmbedding |
The embedding service. |
host |
str |
Remote host address. |
port |
int |
Remote server port. Required (typically 6333). |
collection |
str |
Collection name. Default "agentflow_memories". |
**kwargs |
Any |
Passed to QdrantStore. |
Returns: A configured QdrantStore instance.
create_cloud_qdrant_store(url, api_key, embedding, collection=...)
Create a QdrantStore connected to Qdrant Cloud.
from tenxgraph.storage.store import create_cloud_qdrant_store, OpenAIEmbedding
store = create_cloud_qdrant_store(
embedding=OpenAIEmbedding(),
url="https://xyz.qdrant.io",
api_key="<your-qdrant-api-key>",
)| Parameter | Type | Description |
|---|---|---|
embedding |
BaseEmbedding |
The embedding service. |
url |
str |
Qdrant Cloud cluster URL. |
api_key |
str |
Qdrant Cloud API key. |
collection |
str |
Collection name. Default "agentflow_memories". |
**kwargs |
Any |
Passed to QdrantStore. |
Returns: A configured QdrantStore instance.
create_mem0_store(config, user_id="default_user", app_id="agentflow_app")
Create a Mem0Store with custom configuration.
from tenxgraph.storage.store import create_mem0_store
store = create_mem0_store(config={
"llm": {"provider": "openai", "config": {"model": "gpt-4o-mini"}},
"embedder": {"provider": "openai", "config": {"model": "text-embedding-3-small"}},
"vector_store": {"provider": "qdrant", "config": {"host": "localhost", "port": 6333}},
})| Parameter | Type | Description |
|---|---|---|
config |
dict |
Mem0 configuration with llm, embedder, and vector_store sections. |
user_id |
str |
Accepted but not used by Mem0Store; pass user_id in each call’s config. |
app_id |
str |
Default app identifier. |
Returns: A configured Mem0Store instance.
create_mem0_store_with_qdrant(qdrant_url, ...)
Create a Mem0Store backed by a Qdrant server, with OpenAI as the default LLM and embedder provider.
from tenxgraph.storage.store import create_mem0_store_with_qdrant
store = create_mem0_store_with_qdrant(
qdrant_url="http://localhost:6333",
llm_model="gpt-4o-mini",
)| Parameter | Type | Default | Description |
|---|---|---|---|
qdrant_url |
str |
Required | Qdrant server URL. |
qdrant_api_key |
str | None |
None | Qdrant API key. |
collection_name |
str |
"agentflow_memories" |
Qdrant collection used by Mem0. |
embedding_model |
str |
"text-embedding-ada-002" |
Embedder model name. |
llm_model |
str |
"gpt-4o-mini" |
LLM model name. |
app_id |
str |
"agentflow_app" |
App identifier. |
**kwargs |
Any |
Optional vector_store_config, embedder_provider, embedder_config, llm_provider, llm_config. |
Returns: A configured Mem0Store instance.
—|—|—|
| embedding | BaseEmbedding | The embedding service. |
| llm_model | str | OpenAI model to use for Mem0. |
| qdrant_path | str | Local path for the embedded Qdrant server. |
Returns: A configured Mem0Store instance.
Wiring into Agent memory
Pass a MemoryConfig to the Agent and the same store to graph.compile. With PRELOAD the agent searches memory itself before each call; with POSTLOAD it needs a ToolNode so the memory tools can be registered.
from tenxgraph.core import Agent, StateGraph
from tenxgraph.core.state import AgentState
from tenxgraph.storage.store import MemoryConfig, OpenAIEmbedding, QdrantStore, ReadMode
from tenxgraph.utils.constants import END
store = QdrantStore(embedding=OpenAIEmbedding(), path="./qdrant_data")
agent = Agent(
model="gpt-4o",
memory=MemoryConfig(store=store, retrieval_mode=ReadMode.PRELOAD, limit=5),
)
graph = StateGraph(AgentState)
graph.add_node("MAIN", agent)
graph.set_entry_point("MAIN")
graph.add_edge("MAIN", END)
app = graph.compile(store=store) # the store is injected into memory tools and nodesMemory is scoped by the user_id you pass in the invoke config. See Use a memory store for a full run.
Direct store usage in nodes
A node can call the store directly through dependency injection, for example to write custom memory logic.
from injectq import Inject
from tenxgraph.core.state import AgentState
from tenxgraph.storage.store import BaseStore
from tenxgraph.storage.store.store_schema import MemoryType, RetrievalStrategy
async def remember_node(
state: AgentState,
config: dict,
store: BaseStore = Inject[BaseStore],
) -> list:
text = state.context[-1].text()
# Retrieve relevant memories
memories = await store.asearch(
config={"user_id": config.get("user_id")},
query=text,
memory_type=MemoryType.EPISODIC,
retrieval_strategy=RetrievalStrategy.SIMILARITY,
limit=5,
)
context = "\n".join(m.content for m in memories) # use this in a prompt or state
# Store the user's latest message as a memory
await store.astore(
config={"user_id": config.get("user_id")},
content=text,
memory_type=MemoryType.EPISODIC,
)
return [] # no new messages; state enriched by memories aboveThe store parameter is injected when you pass store= to graph.compile().
Common errors
| Error | Cause | Fix |
|---|---|---|
ImportError: qdrant-client package is required for QdrantStore |
qdrant-client is not installed. |
pip install "10xgraph[qdrant]". |
ImportError: mem0 package is required for Mem0Store |
mem0ai is not installed. |
pip install "10xgraph[mem0]". |
ValueError: OpenAI API key must be provided... |
No api_key and no OPENAI_API_KEY. |
Set the variable or pass api_key. |
ValueError: user_id must be provided in config |
A Mem0Store call has no user_id. |
Put user_id in the config dict. |
RuntimeError: Memory requires an existing ToolNode... |
Agent(memory=...) in POSTLOAD mode without a tool node. |
Pass tool_node= or use PRELOAD. |
NotImplementedError from asetup |
Called asetup() on Mem0Store. |
Only QdrantStore implements it. |