pycontextdb 0.3.2__tar.gz → 0.4.1__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.
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/.github/workflows/ci.yml +2 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/CHANGELOG.md +19 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/PKG-INFO +41 -4
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/README.md +40 -3
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/__init__.py +17 -1
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/client.py +479 -0
- pycontextdb-0.4.1/contextdb/connectors/__init__.py +25 -0
- pycontextdb-0.4.1/contextdb/connectors/base.py +62 -0
- pycontextdb-0.4.1/contextdb/connectors/postgres.py +243 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/core/__init__.py +18 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/core/exceptions.py +25 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/core/models.py +47 -1
- pycontextdb-0.4.1/contextdb/dynamics/trust.py +808 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/memory/factual.py +37 -1
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/store/postgres_store.py +4 -1
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/store/sqlite_store.py +4 -1
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/store/vector_index.py +14 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/docs/api.md +20 -3
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/docs/architecture.md +14 -4
- pycontextdb-0.4.1/docs/connectors.md +56 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/docs/index.md +7 -0
- pycontextdb-0.4.1/docs/memory_evolution.md +135 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/pyproject.toml +1 -1
- pycontextdb-0.4.1/tests/unit/test_connectors.py +47 -0
- pycontextdb-0.4.1/tests/unit/test_memory_evolution.py +639 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/unit/test_models.py +40 -0
- pycontextdb-0.4.1/tests/unit/test_postgres_connector.py +80 -0
- pycontextdb-0.4.1/tests/unit/test_postgres_memory_evolution.py +411 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/unit/test_vector_index.py +24 -0
- pycontextdb-0.3.2/contextdb/dynamics/trust.py +0 -373
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/.github/CODEOWNERS +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/.github/copilot-instructions.md +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/.github/pull_request_template.md +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/.github/workflows/publish.yml +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/.gitignore +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/.pre-commit-config.yaml +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/COMMERCIAL.md +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/CONTRIBUTING.md +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/LICENSE +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/NOTICE +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/OPEN_CORE.md +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/ai-tools/.cursorrules +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/ai-tools/CLAUDE.md +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/ai-tools/README.md +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/ai-tools/llms-full.txt +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/ai-tools/llms.txt +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/assets/README.md +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/assets/architecture.png +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/assets/benchmarks.png +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/assets/hero.png +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/assets/performance.png +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/assets/problem.png +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/assets/quickstart.png +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/benchmarks/__init__.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/benchmarks/run_benchmarks.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/benchmarks/trust_bakeoff.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/agents/__init__.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/agents/memory_bus.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/agents/rl_manager.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/cli.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/core/clock.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/core/config.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/core/policy.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/core/slots.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/dynamics/__init__.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/dynamics/evolution.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/dynamics/formation.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/dynamics/retrieval.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/dynamics/salience.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/graphs/__init__.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/graphs/base.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/graphs/causal.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/graphs/entity.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/graphs/semantic.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/graphs/temporal.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/integrations/__init__.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/integrations/act.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/integrations/autogen.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/integrations/crewai.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/integrations/langchain.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/integrations/livekit.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/integrations/openai_tools.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/integrations/pipecat.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/integrations/prompting.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/mcp.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/memory/__init__.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/memory/experiential.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/memory/working.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/pool.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/privacy/__init__.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/privacy/audit.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/privacy/injection.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/privacy/pii_detector.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/privacy/retention.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/py.typed +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/serve.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/store/__init__.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/store/base.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/store/factory.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/store/pg_sql.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/utils/__init__.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/utils/embeddings.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/utils/llm.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/contextdb/utils/migrations.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/docs/migrations.md +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/docs/multi_tenant.md +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/docs/postgres.md +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/docs/prompts.md +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/docs/quickstart.md +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/docs/serve.md +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/docs/trust_policy.md +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/examples/customer_support.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/examples/multi_agent_team.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/examples/phone_agent.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/examples/research_assistant.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/legal/CLA-entity.md +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/legal/CLA-individual.md +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/legal/signed/README.md +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/mkdocs.yml +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/scripts/check_open_core_boundary.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/scripts/check_release.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/__init__.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/conftest.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/evals/__init__.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/evals/test_trust_model.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/integration/__init__.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/integration/test_client.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/integration/test_langchain_integration.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/pg_util.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/test_version.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/unit/__init__.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/unit/test_audit.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/unit/test_config.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/unit/test_decision_scope.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/unit/test_embeddings.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/unit/test_evolution.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/unit/test_formation.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/unit/test_graphs.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/unit/test_host_api.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/unit/test_init.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/unit/test_memory_bus.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/unit/test_open_core_boundary.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/unit/test_pg_sql.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/unit/test_pii_detector.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/unit/test_postgres_concurrency.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/unit/test_retention.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/unit/test_retrieval.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/unit/test_scoped_id_access.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/unit/test_serve.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/unit/test_store.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/unit/test_trust_policy.py +0 -0
- {pycontextdb-0.3.2 → pycontextdb-0.4.1}/tests/unit/test_vector_scope.py +0 -0
|
@@ -2,6 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.4.1 — 2026-08-24
|
|
6
|
+
|
|
7
|
+
- NOOP audit entries now carry the existing memory ID and canonical slot
|
|
8
|
+
identifiers when a duplicate, explicit target, or unambiguous slot resolves
|
|
9
|
+
to a current memory. Ambiguous slot-only NOOPs fail closed, while all NOOPs
|
|
10
|
+
remain content-free and leave the memory version unchanged.
|
|
11
|
+
|
|
12
|
+
## 0.4.0 — 2026-08-23
|
|
13
|
+
|
|
14
|
+
- Explicit deterministic `add` / `update` / `delete` / `noop` memory
|
|
15
|
+
evolution with public result and error contracts, lineage, scoped hard
|
|
16
|
+
deletion, content-free NOOP audit, and post-commit consistency tokens.
|
|
17
|
+
Postgres applies memory rows, revisions, and audit in one transaction;
|
|
18
|
+
ordinary `factual.add()` remains compatible and same-speaker duplicates
|
|
19
|
+
are now true no-ops.
|
|
20
|
+
- Public connector contracts plus a minimal local PostgreSQL/Supabase reader
|
|
21
|
+
with stable timestamp-plus-key cursors and soft-delete mapping. Hosts retain
|
|
22
|
+
control of credentials, scheduling, retries, and memory writes.
|
|
23
|
+
|
|
5
24
|
## 0.3.2 — 2026-08-20
|
|
6
25
|
|
|
7
26
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: pycontextdb
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: The unified context layer for AI agents — memory you can act on without treating wishes as facts
|
|
5
5
|
Project-URL: Homepage, https://github.com/atomsai/contextdb
|
|
6
6
|
Project-URL: Documentation, https://contextdb.dev
|
|
@@ -74,7 +74,7 @@ Description-Content-Type: text/markdown
|
|
|
74
74
|
<p align="center">
|
|
75
75
|
<a href="https://pypi.org/project/pycontextdb/"><img src="https://img.shields.io/pypi/v/pycontextdb.svg" alt="PyPI version"></a>
|
|
76
76
|
<a href="https://github.com/atomsai/contextdb/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License: Apache 2.0"></a>
|
|
77
|
-
<a href="https://github.com/atomsai/contextdb/blob/main/tests/"><img src="https://img.shields.io/badge/tests-
|
|
77
|
+
<a href="https://github.com/atomsai/contextdb/blob/main/tests/"><img src="https://img.shields.io/badge/tests-195%20passing-brightgreen.svg" alt="Tests"></a>
|
|
78
78
|
<a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.10%2B-blue.svg" alt="Python 3.10+"></a>
|
|
79
79
|
<a href="https://github.com/atomsai/contextdb/blob/main/pyproject.toml"><img src="https://img.shields.io/badge/mypy-strict-blue.svg" alt="Type Checked"></a>
|
|
80
80
|
<a href="https://github.com/atomsai/contextdb/blob/main/benchmarks/run_benchmarks.py"><img src="https://img.shields.io/badge/search_p95-%3C5ms_%40_5K-brightgreen.svg" alt="Search p95"></a>
|
|
@@ -102,7 +102,7 @@ Description-Content-Type: text/markdown
|
|
|
102
102
|
| **Search latency (5K memories)** | p50 **3.9ms** · p95 **5.0ms** |
|
|
103
103
|
| **Vector search (10K × 1,536d)** | p50 **0.8ms** · p95 **1.0ms** |
|
|
104
104
|
| **PII detection** | 100,000+ texts/sec |
|
|
105
|
-
| **Tests** |
|
|
105
|
+
| **Tests** | 195 passing (incl. 34 trust-model acceptance evals) · ruff clean · mypy `--strict` clean |
|
|
106
106
|
| **Dependencies** | SQLite + NumPy (FAISS / Postgres optional) |
|
|
107
107
|
|
|
108
108
|
Those search numbers are **SQLite + the in-repo mock embedder**. A recall
|
|
@@ -155,7 +155,7 @@ Databricks Lakebase gives agents a hard drive. ContextDB gives agents a brain.
|
|
|
155
155
|
| PostgreSQL / MongoDB | Static rows; no lifecycle; no graph links | `FactualMemory` with formation, evolution, and consolidation |
|
|
156
156
|
| S3 / flat files | Write-only archive; not queryable by meaning or time | `ExperientialMemory` for trajectories, reflections, and workflows |
|
|
157
157
|
| Custom glue code | Brittle; rebuilt at every company; 2-4 engineering months | One `init()` call, one async SDK, one dependency |
|
|
158
|
-
|
|
|
158
|
+
| Ad hoc update/delete glue | Corrections overwrite history; deletion leaves vector residue | Deterministic `evolve()` operations with lineage, audit, and consistency results |
|
|
159
159
|
| *(nothing today)* | Raw PII stored indefinitely; compliance risk | PII detection, typed TTLs, hash-chained audit log |
|
|
160
160
|
|
|
161
161
|
---
|
|
@@ -217,6 +217,43 @@ async def main() -> None:
|
|
|
217
217
|
asyncio.run(main())
|
|
218
218
|
```
|
|
219
219
|
|
|
220
|
+
### Explicit memory evolution
|
|
221
|
+
|
|
222
|
+
When the caller already knows the operation, apply it directly:
|
|
223
|
+
|
|
224
|
+
```python
|
|
225
|
+
current = await db.factual.evolve(
|
|
226
|
+
"add",
|
|
227
|
+
"Customer prefers email.",
|
|
228
|
+
source="user_stated",
|
|
229
|
+
entity="user",
|
|
230
|
+
attribute="contact_preference",
|
|
231
|
+
)
|
|
232
|
+
assert current.memory is not None
|
|
233
|
+
result = await db.factual.evolve(
|
|
234
|
+
"update",
|
|
235
|
+
"Customer prefers SMS, not email.",
|
|
236
|
+
source="user_stated",
|
|
237
|
+
target_memory_id=current.memory.id,
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
print(result.previous_memory_ids)
|
|
241
|
+
print(result.memory.id)
|
|
242
|
+
print(result.consistency_token.memory_version)
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
`evolve()` supports `add`, `update`, `delete`, and `noop`. Corrections create a
|
|
246
|
+
successor and close the predecessor; they do not overwrite corrected content
|
|
247
|
+
in place. Delete hard-removes the selected row and vector. Same-speaker
|
|
248
|
+
duplicates are true no-ops and do not advance the memory version. The caller
|
|
249
|
+
selects the operation; this path does not use an LLM planner or the optional RL
|
|
250
|
+
manager.
|
|
251
|
+
|
|
252
|
+
See the
|
|
253
|
+
[explicit evolution contract](https://github.com/atomsai/contextdb/blob/main/docs/memory_evolution.md)
|
|
254
|
+
for conflict, contested-slot, audit, scoping, and Postgres transaction
|
|
255
|
+
semantics.
|
|
256
|
+
|
|
220
257
|
---
|
|
221
258
|
|
|
222
259
|
## Experiential memory
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<p align="center">
|
|
9
9
|
<a href="https://pypi.org/project/pycontextdb/"><img src="https://img.shields.io/pypi/v/pycontextdb.svg" alt="PyPI version"></a>
|
|
10
10
|
<a href="https://github.com/atomsai/contextdb/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License: Apache 2.0"></a>
|
|
11
|
-
<a href="https://github.com/atomsai/contextdb/blob/main/tests/"><img src="https://img.shields.io/badge/tests-
|
|
11
|
+
<a href="https://github.com/atomsai/contextdb/blob/main/tests/"><img src="https://img.shields.io/badge/tests-195%20passing-brightgreen.svg" alt="Tests"></a>
|
|
12
12
|
<a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.10%2B-blue.svg" alt="Python 3.10+"></a>
|
|
13
13
|
<a href="https://github.com/atomsai/contextdb/blob/main/pyproject.toml"><img src="https://img.shields.io/badge/mypy-strict-blue.svg" alt="Type Checked"></a>
|
|
14
14
|
<a href="https://github.com/atomsai/contextdb/blob/main/benchmarks/run_benchmarks.py"><img src="https://img.shields.io/badge/search_p95-%3C5ms_%40_5K-brightgreen.svg" alt="Search p95"></a>
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
| **Search latency (5K memories)** | p50 **3.9ms** · p95 **5.0ms** |
|
|
37
37
|
| **Vector search (10K × 1,536d)** | p50 **0.8ms** · p95 **1.0ms** |
|
|
38
38
|
| **PII detection** | 100,000+ texts/sec |
|
|
39
|
-
| **Tests** |
|
|
39
|
+
| **Tests** | 195 passing (incl. 34 trust-model acceptance evals) · ruff clean · mypy `--strict` clean |
|
|
40
40
|
| **Dependencies** | SQLite + NumPy (FAISS / Postgres optional) |
|
|
41
41
|
|
|
42
42
|
Those search numbers are **SQLite + the in-repo mock embedder**. A recall
|
|
@@ -89,7 +89,7 @@ Databricks Lakebase gives agents a hard drive. ContextDB gives agents a brain.
|
|
|
89
89
|
| PostgreSQL / MongoDB | Static rows; no lifecycle; no graph links | `FactualMemory` with formation, evolution, and consolidation |
|
|
90
90
|
| S3 / flat files | Write-only archive; not queryable by meaning or time | `ExperientialMemory` for trajectories, reflections, and workflows |
|
|
91
91
|
| Custom glue code | Brittle; rebuilt at every company; 2-4 engineering months | One `init()` call, one async SDK, one dependency |
|
|
92
|
-
|
|
|
92
|
+
| Ad hoc update/delete glue | Corrections overwrite history; deletion leaves vector residue | Deterministic `evolve()` operations with lineage, audit, and consistency results |
|
|
93
93
|
| *(nothing today)* | Raw PII stored indefinitely; compliance risk | PII detection, typed TTLs, hash-chained audit log |
|
|
94
94
|
|
|
95
95
|
---
|
|
@@ -151,6 +151,43 @@ async def main() -> None:
|
|
|
151
151
|
asyncio.run(main())
|
|
152
152
|
```
|
|
153
153
|
|
|
154
|
+
### Explicit memory evolution
|
|
155
|
+
|
|
156
|
+
When the caller already knows the operation, apply it directly:
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
current = await db.factual.evolve(
|
|
160
|
+
"add",
|
|
161
|
+
"Customer prefers email.",
|
|
162
|
+
source="user_stated",
|
|
163
|
+
entity="user",
|
|
164
|
+
attribute="contact_preference",
|
|
165
|
+
)
|
|
166
|
+
assert current.memory is not None
|
|
167
|
+
result = await db.factual.evolve(
|
|
168
|
+
"update",
|
|
169
|
+
"Customer prefers SMS, not email.",
|
|
170
|
+
source="user_stated",
|
|
171
|
+
target_memory_id=current.memory.id,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
print(result.previous_memory_ids)
|
|
175
|
+
print(result.memory.id)
|
|
176
|
+
print(result.consistency_token.memory_version)
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
`evolve()` supports `add`, `update`, `delete`, and `noop`. Corrections create a
|
|
180
|
+
successor and close the predecessor; they do not overwrite corrected content
|
|
181
|
+
in place. Delete hard-removes the selected row and vector. Same-speaker
|
|
182
|
+
duplicates are true no-ops and do not advance the memory version. The caller
|
|
183
|
+
selects the operation; this path does not use an LLM planner or the optional RL
|
|
184
|
+
manager.
|
|
185
|
+
|
|
186
|
+
See the
|
|
187
|
+
[explicit evolution contract](https://github.com/atomsai/contextdb/blob/main/docs/memory_evolution.md)
|
|
188
|
+
for conflict, contested-slot, audit, scoping, and Postgres transaction
|
|
189
|
+
semantics.
|
|
190
|
+
|
|
154
191
|
---
|
|
155
192
|
|
|
156
193
|
## Experiential memory
|
|
@@ -10,6 +10,11 @@ from contextdb.core.config import ContextDBConfig
|
|
|
10
10
|
from contextdb.core.exceptions import (
|
|
11
11
|
ConfigError,
|
|
12
12
|
ContextDBError,
|
|
13
|
+
EvolutionConflictError,
|
|
14
|
+
EvolutionOperationConflictError,
|
|
15
|
+
EvolutionTargetNotFoundError,
|
|
16
|
+
EvolutionTargetRequiredError,
|
|
17
|
+
MemoryEvolutionError,
|
|
13
18
|
MemoryNotFoundError,
|
|
14
19
|
PrivacyError,
|
|
15
20
|
ScopeConflictError,
|
|
@@ -21,7 +26,10 @@ from contextdb.core.exceptions import (
|
|
|
21
26
|
from contextdb.core.models import (
|
|
22
27
|
Edge,
|
|
23
28
|
Entity,
|
|
29
|
+
EvolutionOperation,
|
|
30
|
+
EvolutionOutcome,
|
|
24
31
|
MemoryConsistencyToken,
|
|
32
|
+
MemoryEvolutionResult,
|
|
25
33
|
MemoryItem,
|
|
26
34
|
MemoryStatus,
|
|
27
35
|
MemoryType,
|
|
@@ -33,7 +41,7 @@ from contextdb.core.policy import TrustPolicy
|
|
|
33
41
|
from contextdb.pool import ContextDBPool
|
|
34
42
|
from contextdb.utils.embeddings import EmbeddingProvider
|
|
35
43
|
|
|
36
|
-
__version__ = "0.
|
|
44
|
+
__version__ = "0.4.1"
|
|
37
45
|
|
|
38
46
|
__all__ = [
|
|
39
47
|
"Clock",
|
|
@@ -45,7 +53,15 @@ __all__ = [
|
|
|
45
53
|
"Edge",
|
|
46
54
|
"EmbeddingProvider",
|
|
47
55
|
"Entity",
|
|
56
|
+
"EvolutionConflictError",
|
|
57
|
+
"EvolutionOperationConflictError",
|
|
58
|
+
"EvolutionOperation",
|
|
59
|
+
"EvolutionOutcome",
|
|
60
|
+
"EvolutionTargetNotFoundError",
|
|
61
|
+
"EvolutionTargetRequiredError",
|
|
48
62
|
"FrozenClock",
|
|
63
|
+
"MemoryEvolutionError",
|
|
64
|
+
"MemoryEvolutionResult",
|
|
49
65
|
"MemoryItem",
|
|
50
66
|
"MemoryConsistencyToken",
|
|
51
67
|
"MemoryNotFoundError",
|