mem01session 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mem01session-0.1.0/.env.example +6 -0
- mem01session-0.1.0/.gitignore +11 -0
- mem01session-0.1.0/LICENSE +21 -0
- mem01session-0.1.0/PKG-INFO +283 -0
- mem01session-0.1.0/README.md +258 -0
- mem01session-0.1.0/artifacts/prepared-input-scaling.json +119 -0
- mem01session-0.1.0/docs/superpowers/plans/2026-07-13-mem01session-embedded-redesign.md +350 -0
- mem01session-0.1.0/docs/superpowers/plans/2026-07-13-mem01session-lifecycle-hardening.md +123 -0
- mem01session-0.1.0/examples/__init__.py +1 -0
- mem01session-0.1.0/examples/build_week_demo.py +7 -0
- mem01session-0.1.0/pyproject.toml +61 -0
- mem01session-0.1.0/scripts/prepare_offline_wheelhouse.py +43 -0
- mem01session-0.1.0/src/mem01session/__init__.py +25 -0
- mem01session-0.1.0/src/mem01session/demo.py +614 -0
- mem01session-0.1.0/src/mem01session/fixtures/build_week_conversations.json +42 -0
- mem01session-0.1.0/src/mem01session/items.py +66 -0
- mem01session-0.1.0/src/mem01session/memory_block.py +127 -0
- mem01session-0.1.0/src/mem01session/metrics.py +37 -0
- mem01session-0.1.0/src/mem01session/py.typed +1 -0
- mem01session-0.1.0/src/mem01session/runtime.py +672 -0
- mem01session-0.1.0/src/mem01session/session.py +522 -0
- mem01session-0.1.0/tests/fakes.py +222 -0
- mem01session-0.1.0/tests/test_demo.py +358 -0
- mem01session-0.1.0/tests/test_items.py +104 -0
- mem01session-0.1.0/tests/test_memory_block.py +199 -0
- mem01session-0.1.0/tests/test_metrics.py +30 -0
- mem01session-0.1.0/tests/test_packaging.py +125 -0
- mem01session-0.1.0/tests/test_runner_integration.py +193 -0
- mem01session-0.1.0/tests/test_runtime.py +1379 -0
- mem01session-0.1.0/tests/test_session.py +834 -0
- mem01session-0.1.0/tests/test_session_semantics.py +1023 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 mem01 contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mem01session
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Embedded long-term memory sessions for the OpenAI Agents SDK
|
|
5
|
+
Author: mem01 contributors
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Typing :: Typed
|
|
15
|
+
Requires-Python: >=3.11
|
|
16
|
+
Requires-Dist: mem01[openai]>=0.1.0
|
|
17
|
+
Requires-Dist: openai-agents~=0.18.2
|
|
18
|
+
Provides-Extra: dev
|
|
19
|
+
Requires-Dist: build<2,>=1.2; extra == 'dev'
|
|
20
|
+
Requires-Dist: mypy<2,>=1.14; extra == 'dev'
|
|
21
|
+
Requires-Dist: pytest-asyncio<2,>=0.25; extra == 'dev'
|
|
22
|
+
Requires-Dist: pytest<10,>=8.3; extra == 'dev'
|
|
23
|
+
Requires-Dist: ruff<1,>=0.9; extra == 'dev'
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
# mem01session
|
|
27
|
+
|
|
28
|
+
`mem01session` gives the OpenAI Agents SDK belief-based, cross-conversation
|
|
29
|
+
memory without a memory sidecar. The user installs one package, supplies normal
|
|
30
|
+
environment variables, and imports the canonical `memSession` alias. Internally,
|
|
31
|
+
the SDK's file-backed `SQLiteSession` retains the exact short-term item chain,
|
|
32
|
+
while the embedded mem01 engine extracts and recalls long-term beliefs through
|
|
33
|
+
OpenAI and Postgres/pgvector.
|
|
34
|
+
|
|
35
|
+
The distribution and import name are both `mem01session`.
|
|
36
|
+
|
|
37
|
+
## Install and configure
|
|
38
|
+
|
|
39
|
+
Python 3.11 or newer is declared. This checkout has not been published. Local
|
|
40
|
+
development with the sibling engine checkout uses:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
python -m venv .venv
|
|
44
|
+
source .venv/bin/activate
|
|
45
|
+
pip install -e "../mem01[openai]" -e ".[dev]"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Once the owner chooses to publish it, the intended installation is:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install mem01session
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Only two variables are required for normal operation:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
export OPENAI_API_KEY="your-key"
|
|
58
|
+
export DATABASE_URL="postgresql://user:password@db.example/mem01"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`MEM01_LLM_MODEL` optionally overrides the extraction model and defaults to
|
|
62
|
+
`gpt-5.6-sol`. `MEM01_EMBEDDING_MODEL` defaults to
|
|
63
|
+
`text-embedding-3-small`. The OpenAI endpoint is built in; there is no memory
|
|
64
|
+
service URL to configure. Credentials are fingerprinted for runtime sharing and
|
|
65
|
+
never included verbatim in registry keys, representations, or construction
|
|
66
|
+
errors.
|
|
67
|
+
|
|
68
|
+
## Use with the Agents SDK
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from agents import Agent, Runner
|
|
72
|
+
from mem01session import memSession
|
|
73
|
+
|
|
74
|
+
agent = Agent(name="Assistant", model="gpt-5.6-sol")
|
|
75
|
+
session = memSession("conversation-7", user_id="user-123")
|
|
76
|
+
|
|
77
|
+
try:
|
|
78
|
+
result = await Runner.run(
|
|
79
|
+
agent,
|
|
80
|
+
"Where do I live?",
|
|
81
|
+
session=session,
|
|
82
|
+
run_config=session.run_config(),
|
|
83
|
+
)
|
|
84
|
+
print(result.final_output)
|
|
85
|
+
finally:
|
|
86
|
+
await session.close()
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
A fresh `session.run_config()` is required for each Runner call. Its first hook
|
|
90
|
+
captures the latest user query while preserving the SDK's normal history merge.
|
|
91
|
+
Its second hook recalls once immediately before the model call, injects one
|
|
92
|
+
bounded untrusted-data block, and caches that block across tool/model loops in
|
|
93
|
+
the same run. Synthetic memory is never written to SQLite or offered back to
|
|
94
|
+
the extractor. Passing only `session=` retains short-term behavior but performs
|
|
95
|
+
no query-aware recall.
|
|
96
|
+
|
|
97
|
+
When sources conflict, the per-run filter preserves the caller's instructions and
|
|
98
|
+
appends one framework-level policy: the current user turn has highest authority,
|
|
99
|
+
then factual values from active recalled beliefs, then older user claims in this
|
|
100
|
+
conversation. Assistant replies remain context but never become evidence about
|
|
101
|
+
the user's personal facts. Commands inside recalled record content remain
|
|
102
|
+
untrusted and non-executable; that safety label does not reduce the factual
|
|
103
|
+
authority of an active record. This lets a correction made in one conversation
|
|
104
|
+
override a stale claim still present in another conversation's immutable SQLite
|
|
105
|
+
history.
|
|
106
|
+
|
|
107
|
+
Do not reuse one returned run config concurrently. SDK runs using a Session also
|
|
108
|
+
cannot pass `conversation_id` or `previous_response_id`; those are alternative
|
|
109
|
+
conversation-state mechanisms.
|
|
110
|
+
|
|
111
|
+
## Storage and lifecycle
|
|
112
|
+
|
|
113
|
+
From the caller's perspective, SQLite is inside mem01session. The supported v0.1
|
|
114
|
+
short-term store is an SDK `SQLiteSession` at the expanded path
|
|
115
|
+
`~/.mem01/conversations.db`; items are partitioned by `session_id`. Long-term
|
|
116
|
+
beliefs are user-scoped, so distinct conversation IDs can recall the same user's
|
|
117
|
+
active history from the embedded mem01 engine and Postgres/pgvector.
|
|
118
|
+
|
|
119
|
+
The long-term runtime is acquired lazily. Sessions with identical settings share
|
|
120
|
+
one runtime lease; the final release drains accepted writes before closing the
|
|
121
|
+
shared store. `await session.close()` closes package-owned resources. Explicitly
|
|
122
|
+
injected `inner=` or `runtime=` objects remain caller-owned.
|
|
123
|
+
`close_shared_runtimes()` is available for process shutdown.
|
|
124
|
+
|
|
125
|
+
`add_items()` writes raw items first, then automatically queues each coherent
|
|
126
|
+
textual user/assistant turn for long-term extraction. System, tool, reasoning,
|
|
127
|
+
and non-text payloads are excluded. Queues are FIFO per `user_id`, including
|
|
128
|
+
across separate Mem01Session objects that share a runtime, so one user's
|
|
129
|
+
corrections cannot overtake their earlier facts. Different users may progress
|
|
130
|
+
independently. The answering agent never receives or calls a memory tool.
|
|
131
|
+
|
|
132
|
+
The next recall, `memory_history()`, correction, or forget operation waits for
|
|
133
|
+
previously accepted writes for that user. Call `await session.flush_memory()`
|
|
134
|
+
when application code needs the same durability barrier explicitly. Graceful
|
|
135
|
+
runtime shutdown also drains accepted work; because the queue is in process,
|
|
136
|
+
an abrupt process or machine failure before a flush can still lose an accepted
|
|
137
|
+
but unfinished write.
|
|
138
|
+
|
|
139
|
+
Memory is failure-open by default: raw SQLite persistence succeeds and a
|
|
140
|
+
sanitized `last_memory_error` records a queue or barrier failure. With
|
|
141
|
+
`strict=True`, enqueue failures are raised during `add_items()`, while a failure
|
|
142
|
+
that occurs after enqueue is raised at the next same-user recall, management
|
|
143
|
+
operation, or explicit flush. No raw provider exception or credential-bearing
|
|
144
|
+
detail is exposed.
|
|
145
|
+
|
|
146
|
+
`get_items(limit=N)`, `pop_item()`, and `clear_session()` operate only on the raw
|
|
147
|
+
SQLite transcript. `clear_session()` starts that conversation over, but it does not
|
|
148
|
+
delete any durable beliefs already extracted for the user.
|
|
149
|
+
|
|
150
|
+
Use `memory_history()`, `correct_memory()`, and `forget_memory()` for targeted
|
|
151
|
+
long-term management. Use `clear_memory()` only when you intend to hard-delete all
|
|
152
|
+
durable records for the session's configured `user_id`; it waits for that user's
|
|
153
|
+
accepted writes before deleting them and does not clear the SQLite transcript:
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
beliefs = await session.memory_history(include_invalidated=True, limit=100)
|
|
157
|
+
await session.correct_memory("belief-1", "Lives in San Francisco")
|
|
158
|
+
await session.forget_memory("belief-2", reason="user requested deletion")
|
|
159
|
+
await session.flush_memory()
|
|
160
|
+
deleted_count = await session.clear_memory()
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Recalled records expose their full UTC lifecycle time as `stored_at`, allowing
|
|
164
|
+
clients to compare exact ordering rather than date-only labels.
|
|
165
|
+
|
|
166
|
+
## Deterministic judge demo
|
|
167
|
+
|
|
168
|
+
The default demo is key-free and performs no network or database calls. It runs
|
|
169
|
+
a checked-in 40-conversation fixture through 120 actual `Agent` + `Runner`
|
|
170
|
+
preparation calls: a fresh stock Session per conversation, one reused stock
|
|
171
|
+
Session, and fresh `memSession` IDs sharing one user. Local fake model/runtime
|
|
172
|
+
objects make preparation reproducible; their answer text is an observation,
|
|
173
|
+
never a pass/fail guarantee.
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
python examples/build_week_demo.py
|
|
177
|
+
python examples/build_week_demo.py --json
|
|
178
|
+
python examples/build_week_demo.py --write-artifact
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
`--write-artifact` regenerates
|
|
182
|
+
`artifacts/prepared-input-scaling.json` exactly from the fixture. At conversations
|
|
183
|
+
1/10/40, the generated prepared-item counts are:
|
|
184
|
+
|
|
185
|
+
| Strategy | 1 | 10 | 40 |
|
|
186
|
+
| --- | ---: | ---: | ---: |
|
|
187
|
+
| Fresh stock | 1 | 1 | 1 |
|
|
188
|
+
| Reused stock | 1 | 19 | 79 |
|
|
189
|
+
| memSession | 2 | 2 | 2 |
|
|
190
|
+
|
|
191
|
+
The artifact labels its measurement `offline_prepared_model_input`, its estimator
|
|
192
|
+
`utf8_bytes_upper_bound`, and both deterministic local fakes explicitly. The
|
|
193
|
+
numbers are prepared-input measurements, not provider usage or billed-token
|
|
194
|
+
claims. The complete memory system item remains within the configured 800-byte
|
|
195
|
+
upper-bound budget.
|
|
196
|
+
|
|
197
|
+
`--check` first uses the engine's normal `.env` discovery (`mem01/.env`, the
|
|
198
|
+
workspace `.env`, then the current directory) without overriding existing
|
|
199
|
+
process variables. It validates the two required live settings without
|
|
200
|
+
initializing clients or making Runner/model calls. The deterministic default
|
|
201
|
+
does not load `.env` at all.
|
|
202
|
+
|
|
203
|
+
`--live` is the only mode that may use OpenAI and Postgres. Each invocation uses
|
|
204
|
+
a unique user scope and four fresh conversation IDs, then runs the NYC/$2,400
|
|
205
|
+
turn, the move to SF, the location/rent question, and the unsupported sister-name
|
|
206
|
+
question through `gpt-5.6-sol`. Its secret-safe JSON labels outputs as model
|
|
207
|
+
observations and includes the observed belief lifecycle; neither answer wording
|
|
208
|
+
nor lifecycle shape is treated as a deterministic guarantee.
|
|
209
|
+
|
|
210
|
+
## Build and offline wheel smoke
|
|
211
|
+
|
|
212
|
+
Build both local projects first:
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
.venv/bin/python -m build ../mem01
|
|
216
|
+
.venv/bin/python -m build
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Provision a complete local wheelhouse from a trusted index while connected:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
mkdir -p /tmp/mem01session-wheelhouse
|
|
223
|
+
.venv/bin/python scripts/prepare_offline_wheelhouse.py \
|
|
224
|
+
/tmp/mem01session-wheelhouse
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Then disconnect from the index and perform a normal dependency-resolving
|
|
228
|
+
installation into a clean environment using only that wheelhouse:
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
python -m venv /tmp/mem01session-wheel-smoke
|
|
232
|
+
/tmp/mem01session-wheel-smoke/bin/pip install --no-index \
|
|
233
|
+
--find-links /tmp/mem01session-wheelhouse mem01session==0.1.0
|
|
234
|
+
/tmp/mem01session-wheel-smoke/bin/python -c \
|
|
235
|
+
"from mem01session import memSession; print(memSession.__name__)"
|
|
236
|
+
/tmp/mem01session-wheel-smoke/bin/mem01session-demo --json
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
This proves both local project wheels and every resolved runtime dependency can
|
|
240
|
+
be installed and imported without access to an index.
|
|
241
|
+
|
|
242
|
+
The same clean-venv smoke is available as an explicit packaging integration
|
|
243
|
+
test:
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
MEM01SESSION_WHEELHOUSE=/tmp/mem01session-wheelhouse \
|
|
247
|
+
.venv/bin/pytest tests/test_packaging.py \
|
|
248
|
+
-k clean_preprovisioned_venv -q
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## Scope, provenance, and current status
|
|
252
|
+
|
|
253
|
+
The **Pre-existing mem01 engine** supplied belief types, extraction, recall,
|
|
254
|
+
lifecycle operations, and storage foundations before this Build Week effort.
|
|
255
|
+
**Build Week work** added the OpenAI-only embedded runtime builder and pooled
|
|
256
|
+
Postgres ownership in that engine, plus this renamed package, internal
|
|
257
|
+
SQLite composition, per-run hooks, lifecycle hardening, deterministic evidence,
|
|
258
|
+
packaging checks, and documentation.
|
|
259
|
+
|
|
260
|
+
Codex assisted with planning, implementation, tests, and review. The human owner
|
|
261
|
+
made the product decisions: the `mem01session`/`memSession` identity,
|
|
262
|
+
SQLite-inside packaging, OpenAI-only scope, `gpt-5.6-sol`, explicit
|
|
263
|
+
failure behavior, and postponing all publication and video work.
|
|
264
|
+
|
|
265
|
+
Development verification in this workspace uses macOS on Apple Silicon,
|
|
266
|
+
Python 3.14.4, and `openai-agents` 0.18.2. The declared package floor remains
|
|
267
|
+
Python 3.11; no broader platform matrix is claimed here.
|
|
268
|
+
|
|
269
|
+
No deployment has been performed. No video has been created. No package,
|
|
270
|
+
repository change, or artifact has been pushed or published from this work.
|
|
271
|
+
Everything remains local and uncommitted pending owner confirmation.
|
|
272
|
+
|
|
273
|
+
## Development gates
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
pytest -q
|
|
277
|
+
ruff check .
|
|
278
|
+
ruff format --check .
|
|
279
|
+
mypy src
|
|
280
|
+
python -m build
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
Licensed under the MIT License.
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
# mem01session
|
|
2
|
+
|
|
3
|
+
`mem01session` gives the OpenAI Agents SDK belief-based, cross-conversation
|
|
4
|
+
memory without a memory sidecar. The user installs one package, supplies normal
|
|
5
|
+
environment variables, and imports the canonical `memSession` alias. Internally,
|
|
6
|
+
the SDK's file-backed `SQLiteSession` retains the exact short-term item chain,
|
|
7
|
+
while the embedded mem01 engine extracts and recalls long-term beliefs through
|
|
8
|
+
OpenAI and Postgres/pgvector.
|
|
9
|
+
|
|
10
|
+
The distribution and import name are both `mem01session`.
|
|
11
|
+
|
|
12
|
+
## Install and configure
|
|
13
|
+
|
|
14
|
+
Python 3.11 or newer is declared. This checkout has not been published. Local
|
|
15
|
+
development with the sibling engine checkout uses:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
python -m venv .venv
|
|
19
|
+
source .venv/bin/activate
|
|
20
|
+
pip install -e "../mem01[openai]" -e ".[dev]"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Once the owner chooses to publish it, the intended installation is:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install mem01session
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Only two variables are required for normal operation:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
export OPENAI_API_KEY="your-key"
|
|
33
|
+
export DATABASE_URL="postgresql://user:password@db.example/mem01"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`MEM01_LLM_MODEL` optionally overrides the extraction model and defaults to
|
|
37
|
+
`gpt-5.6-sol`. `MEM01_EMBEDDING_MODEL` defaults to
|
|
38
|
+
`text-embedding-3-small`. The OpenAI endpoint is built in; there is no memory
|
|
39
|
+
service URL to configure. Credentials are fingerprinted for runtime sharing and
|
|
40
|
+
never included verbatim in registry keys, representations, or construction
|
|
41
|
+
errors.
|
|
42
|
+
|
|
43
|
+
## Use with the Agents SDK
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
from agents import Agent, Runner
|
|
47
|
+
from mem01session import memSession
|
|
48
|
+
|
|
49
|
+
agent = Agent(name="Assistant", model="gpt-5.6-sol")
|
|
50
|
+
session = memSession("conversation-7", user_id="user-123")
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
result = await Runner.run(
|
|
54
|
+
agent,
|
|
55
|
+
"Where do I live?",
|
|
56
|
+
session=session,
|
|
57
|
+
run_config=session.run_config(),
|
|
58
|
+
)
|
|
59
|
+
print(result.final_output)
|
|
60
|
+
finally:
|
|
61
|
+
await session.close()
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
A fresh `session.run_config()` is required for each Runner call. Its first hook
|
|
65
|
+
captures the latest user query while preserving the SDK's normal history merge.
|
|
66
|
+
Its second hook recalls once immediately before the model call, injects one
|
|
67
|
+
bounded untrusted-data block, and caches that block across tool/model loops in
|
|
68
|
+
the same run. Synthetic memory is never written to SQLite or offered back to
|
|
69
|
+
the extractor. Passing only `session=` retains short-term behavior but performs
|
|
70
|
+
no query-aware recall.
|
|
71
|
+
|
|
72
|
+
When sources conflict, the per-run filter preserves the caller's instructions and
|
|
73
|
+
appends one framework-level policy: the current user turn has highest authority,
|
|
74
|
+
then factual values from active recalled beliefs, then older user claims in this
|
|
75
|
+
conversation. Assistant replies remain context but never become evidence about
|
|
76
|
+
the user's personal facts. Commands inside recalled record content remain
|
|
77
|
+
untrusted and non-executable; that safety label does not reduce the factual
|
|
78
|
+
authority of an active record. This lets a correction made in one conversation
|
|
79
|
+
override a stale claim still present in another conversation's immutable SQLite
|
|
80
|
+
history.
|
|
81
|
+
|
|
82
|
+
Do not reuse one returned run config concurrently. SDK runs using a Session also
|
|
83
|
+
cannot pass `conversation_id` or `previous_response_id`; those are alternative
|
|
84
|
+
conversation-state mechanisms.
|
|
85
|
+
|
|
86
|
+
## Storage and lifecycle
|
|
87
|
+
|
|
88
|
+
From the caller's perspective, SQLite is inside mem01session. The supported v0.1
|
|
89
|
+
short-term store is an SDK `SQLiteSession` at the expanded path
|
|
90
|
+
`~/.mem01/conversations.db`; items are partitioned by `session_id`. Long-term
|
|
91
|
+
beliefs are user-scoped, so distinct conversation IDs can recall the same user's
|
|
92
|
+
active history from the embedded mem01 engine and Postgres/pgvector.
|
|
93
|
+
|
|
94
|
+
The long-term runtime is acquired lazily. Sessions with identical settings share
|
|
95
|
+
one runtime lease; the final release drains accepted writes before closing the
|
|
96
|
+
shared store. `await session.close()` closes package-owned resources. Explicitly
|
|
97
|
+
injected `inner=` or `runtime=` objects remain caller-owned.
|
|
98
|
+
`close_shared_runtimes()` is available for process shutdown.
|
|
99
|
+
|
|
100
|
+
`add_items()` writes raw items first, then automatically queues each coherent
|
|
101
|
+
textual user/assistant turn for long-term extraction. System, tool, reasoning,
|
|
102
|
+
and non-text payloads are excluded. Queues are FIFO per `user_id`, including
|
|
103
|
+
across separate Mem01Session objects that share a runtime, so one user's
|
|
104
|
+
corrections cannot overtake their earlier facts. Different users may progress
|
|
105
|
+
independently. The answering agent never receives or calls a memory tool.
|
|
106
|
+
|
|
107
|
+
The next recall, `memory_history()`, correction, or forget operation waits for
|
|
108
|
+
previously accepted writes for that user. Call `await session.flush_memory()`
|
|
109
|
+
when application code needs the same durability barrier explicitly. Graceful
|
|
110
|
+
runtime shutdown also drains accepted work; because the queue is in process,
|
|
111
|
+
an abrupt process or machine failure before a flush can still lose an accepted
|
|
112
|
+
but unfinished write.
|
|
113
|
+
|
|
114
|
+
Memory is failure-open by default: raw SQLite persistence succeeds and a
|
|
115
|
+
sanitized `last_memory_error` records a queue or barrier failure. With
|
|
116
|
+
`strict=True`, enqueue failures are raised during `add_items()`, while a failure
|
|
117
|
+
that occurs after enqueue is raised at the next same-user recall, management
|
|
118
|
+
operation, or explicit flush. No raw provider exception or credential-bearing
|
|
119
|
+
detail is exposed.
|
|
120
|
+
|
|
121
|
+
`get_items(limit=N)`, `pop_item()`, and `clear_session()` operate only on the raw
|
|
122
|
+
SQLite transcript. `clear_session()` starts that conversation over, but it does not
|
|
123
|
+
delete any durable beliefs already extracted for the user.
|
|
124
|
+
|
|
125
|
+
Use `memory_history()`, `correct_memory()`, and `forget_memory()` for targeted
|
|
126
|
+
long-term management. Use `clear_memory()` only when you intend to hard-delete all
|
|
127
|
+
durable records for the session's configured `user_id`; it waits for that user's
|
|
128
|
+
accepted writes before deleting them and does not clear the SQLite transcript:
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
beliefs = await session.memory_history(include_invalidated=True, limit=100)
|
|
132
|
+
await session.correct_memory("belief-1", "Lives in San Francisco")
|
|
133
|
+
await session.forget_memory("belief-2", reason="user requested deletion")
|
|
134
|
+
await session.flush_memory()
|
|
135
|
+
deleted_count = await session.clear_memory()
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Recalled records expose their full UTC lifecycle time as `stored_at`, allowing
|
|
139
|
+
clients to compare exact ordering rather than date-only labels.
|
|
140
|
+
|
|
141
|
+
## Deterministic judge demo
|
|
142
|
+
|
|
143
|
+
The default demo is key-free and performs no network or database calls. It runs
|
|
144
|
+
a checked-in 40-conversation fixture through 120 actual `Agent` + `Runner`
|
|
145
|
+
preparation calls: a fresh stock Session per conversation, one reused stock
|
|
146
|
+
Session, and fresh `memSession` IDs sharing one user. Local fake model/runtime
|
|
147
|
+
objects make preparation reproducible; their answer text is an observation,
|
|
148
|
+
never a pass/fail guarantee.
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
python examples/build_week_demo.py
|
|
152
|
+
python examples/build_week_demo.py --json
|
|
153
|
+
python examples/build_week_demo.py --write-artifact
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
`--write-artifact` regenerates
|
|
157
|
+
`artifacts/prepared-input-scaling.json` exactly from the fixture. At conversations
|
|
158
|
+
1/10/40, the generated prepared-item counts are:
|
|
159
|
+
|
|
160
|
+
| Strategy | 1 | 10 | 40 |
|
|
161
|
+
| --- | ---: | ---: | ---: |
|
|
162
|
+
| Fresh stock | 1 | 1 | 1 |
|
|
163
|
+
| Reused stock | 1 | 19 | 79 |
|
|
164
|
+
| memSession | 2 | 2 | 2 |
|
|
165
|
+
|
|
166
|
+
The artifact labels its measurement `offline_prepared_model_input`, its estimator
|
|
167
|
+
`utf8_bytes_upper_bound`, and both deterministic local fakes explicitly. The
|
|
168
|
+
numbers are prepared-input measurements, not provider usage or billed-token
|
|
169
|
+
claims. The complete memory system item remains within the configured 800-byte
|
|
170
|
+
upper-bound budget.
|
|
171
|
+
|
|
172
|
+
`--check` first uses the engine's normal `.env` discovery (`mem01/.env`, the
|
|
173
|
+
workspace `.env`, then the current directory) without overriding existing
|
|
174
|
+
process variables. It validates the two required live settings without
|
|
175
|
+
initializing clients or making Runner/model calls. The deterministic default
|
|
176
|
+
does not load `.env` at all.
|
|
177
|
+
|
|
178
|
+
`--live` is the only mode that may use OpenAI and Postgres. Each invocation uses
|
|
179
|
+
a unique user scope and four fresh conversation IDs, then runs the NYC/$2,400
|
|
180
|
+
turn, the move to SF, the location/rent question, and the unsupported sister-name
|
|
181
|
+
question through `gpt-5.6-sol`. Its secret-safe JSON labels outputs as model
|
|
182
|
+
observations and includes the observed belief lifecycle; neither answer wording
|
|
183
|
+
nor lifecycle shape is treated as a deterministic guarantee.
|
|
184
|
+
|
|
185
|
+
## Build and offline wheel smoke
|
|
186
|
+
|
|
187
|
+
Build both local projects first:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
.venv/bin/python -m build ../mem01
|
|
191
|
+
.venv/bin/python -m build
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Provision a complete local wheelhouse from a trusted index while connected:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
mkdir -p /tmp/mem01session-wheelhouse
|
|
198
|
+
.venv/bin/python scripts/prepare_offline_wheelhouse.py \
|
|
199
|
+
/tmp/mem01session-wheelhouse
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Then disconnect from the index and perform a normal dependency-resolving
|
|
203
|
+
installation into a clean environment using only that wheelhouse:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
python -m venv /tmp/mem01session-wheel-smoke
|
|
207
|
+
/tmp/mem01session-wheel-smoke/bin/pip install --no-index \
|
|
208
|
+
--find-links /tmp/mem01session-wheelhouse mem01session==0.1.0
|
|
209
|
+
/tmp/mem01session-wheel-smoke/bin/python -c \
|
|
210
|
+
"from mem01session import memSession; print(memSession.__name__)"
|
|
211
|
+
/tmp/mem01session-wheel-smoke/bin/mem01session-demo --json
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
This proves both local project wheels and every resolved runtime dependency can
|
|
215
|
+
be installed and imported without access to an index.
|
|
216
|
+
|
|
217
|
+
The same clean-venv smoke is available as an explicit packaging integration
|
|
218
|
+
test:
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
MEM01SESSION_WHEELHOUSE=/tmp/mem01session-wheelhouse \
|
|
222
|
+
.venv/bin/pytest tests/test_packaging.py \
|
|
223
|
+
-k clean_preprovisioned_venv -q
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Scope, provenance, and current status
|
|
227
|
+
|
|
228
|
+
The **Pre-existing mem01 engine** supplied belief types, extraction, recall,
|
|
229
|
+
lifecycle operations, and storage foundations before this Build Week effort.
|
|
230
|
+
**Build Week work** added the OpenAI-only embedded runtime builder and pooled
|
|
231
|
+
Postgres ownership in that engine, plus this renamed package, internal
|
|
232
|
+
SQLite composition, per-run hooks, lifecycle hardening, deterministic evidence,
|
|
233
|
+
packaging checks, and documentation.
|
|
234
|
+
|
|
235
|
+
Codex assisted with planning, implementation, tests, and review. The human owner
|
|
236
|
+
made the product decisions: the `mem01session`/`memSession` identity,
|
|
237
|
+
SQLite-inside packaging, OpenAI-only scope, `gpt-5.6-sol`, explicit
|
|
238
|
+
failure behavior, and postponing all publication and video work.
|
|
239
|
+
|
|
240
|
+
Development verification in this workspace uses macOS on Apple Silicon,
|
|
241
|
+
Python 3.14.4, and `openai-agents` 0.18.2. The declared package floor remains
|
|
242
|
+
Python 3.11; no broader platform matrix is claimed here.
|
|
243
|
+
|
|
244
|
+
No deployment has been performed. No video has been created. No package,
|
|
245
|
+
repository change, or artifact has been pushed or published from this work.
|
|
246
|
+
Everything remains local and uncommitted pending owner confirmation.
|
|
247
|
+
|
|
248
|
+
## Development gates
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
pytest -q
|
|
252
|
+
ruff check .
|
|
253
|
+
ruff format --check .
|
|
254
|
+
mypy src
|
|
255
|
+
python -m build
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Licensed under the MIT License.
|