teff.memory¶
teff.memory
¶
Long-term memory: cross-session facts stored over a vector store.
Modules:
| Name | Description |
|---|---|
base |
Long-term memory: a namespace store over a vector store. |
context |
Context injection helpers for long-term memory. |
extract |
LLM-based fact extraction for long-term memory. |
tool |
Agent-facing tool for long-term memory (remember / recall / forget). |
Classes:
| Name | Description |
|---|---|
MemoryConfig |
Declarative memory injection for |
MemoryExtractor |
Extract durable facts from a conversation using an LLM. |
MemoryItem |
A single stored memory. |
MemoryStore |
Namespace-scoped semantic memory over a :class: |
MemoryTool |
Tool that lets an agent read and write long-term memory. |
Functions:
| Name | Description |
|---|---|
last_user_text |
Return the most recent non-empty user message text. |
memory_context |
Return a formatted block of recalled memories, or |
memory_context_from_config |
Recall block for a node's |
MemoryConfig
dataclass
¶
Declarative memory injection for agent / llm nodes.
Passed to :class:~teff.node.agent.ReActAgent,
:class:~teff.node.llm.LLM (and the flow.react() /
flow.harness() / flow.llm() helpers) via the memory
parameter. A plain config dict is accepted too — that is what YAML
workflows deserialize to.
Attributes:
| Name | Type | Description |
|---|---|---|
store |
MemoryStore | dict | None
|
A ready :class: |
namespace |
tuple[str, ...] | list[str] | str | None
|
Namespace subtree to recall from (a string becomes a
single-segment namespace). Each segment may reference
|
k |
int
|
Maximum number of memories recalled per turn. |
header |
str
|
First line of the injected block. |
Methods:
| Name | Description |
|---|---|
to_dict |
Config-dict form (used internally; YAML round-trips as this). |
Source code in teff/memory/context.py
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | |
to_dict
¶
to_dict()
Config-dict form (used internally; YAML round-trips as this).
Source code in teff/memory/context.py
54 55 56 57 58 59 60 61 | |
MemoryExtractor
¶
Extract durable facts from a conversation using an LLM.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
harness
|
Harness | None
|
A :class: |
None
|
model
|
str | None
|
Model name for a self-built harness (ignored when harness is given). |
None
|
provider
|
str | None
|
Provider key for a self-built harness. |
None
|
system_prompt
|
str | None
|
Overrides the default extraction prompt. |
None
|
temperature
|
float
|
Sampling temperature for the extraction call. |
0.0
|
Methods:
| Name | Description |
|---|---|
extract |
Return the durable facts found in conversation. |
save |
Extract facts and write them into memory. |
Source code in teff/memory/extract.py
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | |
extract
async
¶
extract(conversation)
Return the durable facts found in conversation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
conversation
|
list[dict]
|
OpenAI-style messages ( |
required |
Source code in teff/memory/extract.py
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | |
save
async
¶
save(memory, conversation, namespace, *, ttl=None)
Extract facts and write them into memory.
Each fact is stored under a stable key derived from its text (a short SHA-1), so re-extracting the same fact updates it in place.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
memory
|
Any
|
A :class: |
required |
conversation
|
list[dict]
|
The messages to extract facts from. |
required |
namespace
|
tuple[str, ...]
|
Namespace to store the facts under. |
required |
ttl
|
float | None
|
Per-item TTL in seconds, or |
None
|
Returns:
| Type | Description |
|---|---|
list[tuple[str, str]]
|
The |
Source code in teff/memory/extract.py
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | |
MemoryItem
dataclass
¶
A single stored memory.
Attributes:
| Name | Type | Description |
|---|---|---|
key |
str
|
Item key within its namespace. |
value |
dict
|
The stored |
namespace |
tuple[str, ...]
|
The namespace the item lives under. |
updated_at |
float
|
Unix timestamp of the last write. |
score |
float | None
|
Similarity score from a semantic search, or |
Source code in teff/memory/base.py
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | |
MemoryStore
¶
Namespace-scoped semantic memory over a :class:VectorStore.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
store
|
VectorStore
|
Backing vector store (in-memory, sqlite, qdrant, ...). |
required |
embedder
|
Embedder
|
Embedding service used for |
required |
ttl
|
float | None
|
Default seconds an item lives unless overridden at |
None
|
Methods:
| Name | Description |
|---|---|
cleanup |
Delete expired items; return how many were removed. |
delete |
Remove the item under |
get |
Return the item under |
list |
Return the keys stored under namespace (recency order). |
put |
Upsert value under |
search |
Return the k most relevant items under namespace. |
Attributes:
| Name | Type | Description |
|---|---|---|
store |
VectorStore
|
The backing vector store (exposed for lifecycle tools). |
Source code in teff/memory/base.py
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 | |
cleanup
async
¶
cleanup(*, max_age=None)
Delete expired items; return how many were removed.
max_age additionally removes items whose updated_at is
older than that many seconds. Expired items are removed from the
backing store (not merely hidden).
Source code in teff/memory/base.py
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | |
delete
async
¶
delete(namespace, key)
Remove the item under namespace::key (no-op if absent).
Source code in teff/memory/base.py
146 147 148 | |
get
async
¶
get(namespace, key)
Return the item under namespace::key, or None.
Expired items are reported as missing.
Source code in teff/memory/base.py
133 134 135 136 137 138 139 140 141 142 143 144 | |
list
async
¶
list(namespace, limit=100, offset=0)
Return the keys stored under namespace (recency order).
Source code in teff/memory/base.py
201 202 203 204 205 206 207 | |
put
async
¶
put(namespace, key, value, *, ttl=_UNSET)
Upsert value under namespace::key.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
namespace
|
tuple[str, ...]
|
Hierarchical path ( |
required |
key
|
str
|
Unique key within the namespace; writing to an existing key overwrites it. |
required |
value
|
dict
|
The memory dict; must contain a non-empty |
required |
ttl
|
float | None | object
|
|
_UNSET
|
Source code in teff/memory/base.py
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | |
search
async
¶
search(namespace, *, query=None, k=10, filter=None)
Return the k most relevant items under namespace.
With query, items are ranked by semantic similarity to it; a
namespace match also covers deeper sub-namespaces (prefix
semantics). Without query, the most recently written items are
returned instead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
namespace
|
tuple[str, ...]
|
Namespace subtree to search. |
required |
query
|
str | None
|
Natural-language query; when |
None
|
k
|
int
|
Maximum number of results. |
10
|
filter
|
dict | None
|
Extra metadata filter DSL (see
:func: |
None
|
Source code in teff/memory/base.py
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | |
MemoryTool
¶
Bases: Tool
Tool that lets an agent read and write long-term memory.
Usage::
memory = MemoryTool(
store=SQLiteVectorStore(path="./memory.db", dim=768),
embedder=Embedder(provider="ollama", model="nomic-embed-text"),
namespace=("users", "u1"),
)
await memory.arun(action="remember", text="prefers email over Slack")
result = await memory.arun(action="recall", query="how to reach them?")
Actions (passed as action):
remember— upsert a fact (textplus optionalmetadata). Whensimilarity_thresholdis set and a semantically close item already exists in the namespace, the new text overwrites that item instead of creating a duplicate.recall— return top-k memories for aquery(or the most recent if no query is given), formatted for a prompt.forget— delete the memory atkey.list— enumerate stored keys.
Can be built from a config dict (e.g. a tools: entry in a
workflow YAML)::
{
"name": "memory",
"store": {"type": "sqlite", "path": "./memory.db", "dim": 768},
"embedder": {"provider": "ollama", "model": "nomic-embed-text"},
"namespace": ["users", "${USER_ID}"],
"default_k": 5,
"similarity_threshold": 0.6,
}
Supported store types match RAGTool: in_memory (default),
sqlite, chroma, qdrant, pgvector, faiss, lance,
milvus, weaviate, pinecone.
Methods:
| Name | Description |
|---|---|
arun |
Run a memory operation and return a human-readable result. |
Source code in teff/memory/tool.py
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | |
arun
async
¶
arun(action='recall', key='', text='', value=None, query='', metadata=None, k=None)
Run a memory operation and return a human-readable result.
The namespace is fixed at construction time and can never be
overridden by the caller — an agent cannot address another owner's
memories by passing a namespace. Per-owner isolation is achieved by
building one tool per owner (namespace=("users", owner)).
Source code in teff/memory/tool.py
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | |
last_user_text
¶
last_user_text(messages, fallback='')
Return the most recent non-empty user message text.
Source code in teff/memory/context.py
145 146 147 148 149 150 151 152 153 | |
memory_context
async
¶
memory_context(store, query, *, namespace=(), k=5, header=DEFAULT_HEADER, bullet='-')
Return a formatted block of recalled memories, or "" if none.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
store
|
Any
|
A :class: |
required |
query
|
str
|
Natural-language query used for the semantic recall. |
required |
namespace
|
tuple[str, ...]
|
Namespace subtree to recall from. |
()
|
k
|
int
|
Maximum number of memories to include. |
5
|
header
|
str
|
First line of the block. |
DEFAULT_HEADER
|
bullet
|
str
|
Per-item bullet prefix. |
'-'
|
The returned string is meant to be appended to a system prompt; it is empty when nothing matched, so callers can skip it entirely.
Source code in teff/memory/context.py
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | |
memory_context_from_config
async
¶
memory_context_from_config(cfg, *, state, ctx)
Recall block for a node's memory config, or "" when off.
Shared by :class:~teff.node.agent.ReActAgent and
:class:~teff.node.llm.LLM. Reads the node's memory config
({store, namespace, k, header}), resolves the store — a
:class:~teff.memory.base.MemoryStore instance, or a config dict
built via memory_from_config using ctx's provider registry —
and recalls memories for the most recent user message. Namespace
segments may reference ${owner} / ${session_id} /
${checkpoint_id}, resolved from ctx — the building block for
per-user memory behind a shared multi-tenant graph.
The returned block is meant to be prepended to the LLM messages as a
system message; it is empty when memory is unconfigured or
nothing matched.
Source code in teff/memory/context.py
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | |