cortexm 0.5.2__tar.gz → 0.6.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.
- cortexm-0.6.0/PKG-INFO +134 -0
- cortexm-0.6.0/README.md +99 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/__init__.py +1 -1
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/api/memory.py +111 -5
- cortexm-0.6.0/cortexm/bridge/fst.py +280 -0
- cortexm-0.6.0/cortexm/bridge/ir_pro.py +697 -0
- cortexm-0.6.0/cortexm/bridge/multilingual.py +284 -0
- cortexm-0.6.0/cortexm/bridge/negation.py +200 -0
- cortexm-0.6.0/cortexm/bridge/query_rewrite.py +178 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bridge/reader.py +110 -1
- cortexm-0.6.0/cortexm/bridge/recognizers.py +341 -0
- cortexm-0.6.0/cortexm/bridge/slang.py +216 -0
- cortexm-0.6.0/cortexm/bridge/synonyms.py +241 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bridge/writer.py +60 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/config.py +98 -0
- cortexm-0.6.0/cortexm/plugins/verbatim.py +915 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/trace/store.py +38 -1
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/vsa/palace.py +10 -1
- cortexm-0.6.0/cortexm.egg-info/PKG-INFO +134 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm.egg-info/SOURCES.txt +10 -0
- cortexm-0.6.0/pyproject.toml +59 -0
- cortexm-0.6.0/tests/test_public_api_smoke.py +186 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_research_steals.py +8 -1
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_tier443_abstention_fix.py +15 -0
- cortexm-0.6.0/tests/test_v060_ir_pro.py +922 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_verbatim.py +80 -0
- cortexm-0.5.2/PKG-INFO +0 -616
- cortexm-0.5.2/README.md +0 -596
- cortexm-0.5.2/cortexm/plugins/verbatim.py +0 -355
- cortexm-0.5.2/cortexm.egg-info/PKG-INFO +0 -616
- cortexm-0.5.2/pyproject.toml +0 -38
- {cortexm-0.5.2 → cortexm-0.6.0}/LICENSE +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/context_m.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/accel.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/api/__init__.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/api/chaos.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/api/long_recall.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bench/__init__.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bench/abilities.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bench/baselines.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bench/beam_loader.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bench/generator.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bench/harness.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bench/messy.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bench/micro.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bench/ood.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bench/run.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bridge/__init__.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bridge/dates.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bridge/decoders.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bridge/enrich.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bridge/extractor.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bridge/fallback.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bridge/fusion.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bridge/onnx_runtime.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bridge/patterns.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bridge/ppr.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bridge/prefilter.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bridge/query_extract.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/bridge/rerank.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/cli.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/cognition/__init__.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/cognition/abstraction.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/cognition/analogy.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/cognition/engine.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/cognition/gaps.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/cognition/scanner.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/cortexm.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/creator.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/enterprise/__init__.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/enterprise/audit.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/enterprise/governance.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/errors.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/features/__init__.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/features/git.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/features/prefetch.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/features/zk.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/federation/__init__.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/federation/crdt.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/federation/fabric.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/federation/hlc.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/federation/node.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/federation/schema_report.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/federation/transport.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/index/__init__.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/index/nsg.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/kernel.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/markdown_io.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/mcp/__init__.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/mcp/server.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/metrics.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/migrate/__init__.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/migrate/importers.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/pipeline.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/plugins/__init__.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/plugins/security.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/plugins/structured.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/provenance/__init__.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/provenance/agent.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/provenance/cose.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/provenance/scitt.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/provenance/vc.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/router.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/security/__init__.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/security/crypto.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/security/hashes.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/security/injection.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/security/mind.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/security/permission.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/security/pii.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/security/rbac.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/security/sandbox.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/security/zk_hamming.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/security/zk_sql.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/server/__init__.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/server/metrics.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/server/rest.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/server/sparql.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/text/__init__.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/text/dissim.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/text/embedder.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/text/fuzzy.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/text/idiolect.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/text/labse.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/text/tokenizer.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/trace/__init__.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/trace/blob_arena.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/trace/consolidate.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/trace/contradictions.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/trace/dedup.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/trace/edges.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/trace/fact.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/trace/fade.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/trace/lifecycle.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/trace/rebuild.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/trace/rules.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/trace/structural.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/trace/tmt.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/trajectory_view.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/util.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/vsa/__init__.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/vsa/attribution.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/vsa/cleanup.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/vsa/codecs.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/vsa/hologram_overlay.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/vsa/index.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/vsa/ops.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/vsa/role_vectors.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/vsa/slb.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/vsa/tlsh_trie.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm/vsa/working_memory.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm.egg-info/dependency_links.txt +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm.egg-info/entry_points.txt +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm.egg-info/requires.txt +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/cortexm.egg-info/top_level.txt +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/setup.cfg +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_arxiv_improvements.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_bench_infra.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_bm25_chunk_recall_and_inspect_cli.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_cognition_and_provenance.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_engineering_push_2026_08_28.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_enterprise.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_fabric.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_federation.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_fusion_security.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_kernel.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_kinship_extraction.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_labse.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_list_superseded_intent.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_migration.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_new_modules.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_nsg.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_permission.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_ppr.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_reddit_steals_round3.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_rerank.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_research_steals_round2.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_rust_accel.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_sandbox_enrich.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_sparql_rest_v2.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_wal_recovery.py +0 -0
- {cortexm-0.5.2 → cortexm-0.6.0}/tests/test_zk_sql.py +0 -0
cortexm-0.6.0/PKG-INFO
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cortexm
|
|
3
|
+
Version: 0.6.0
|
|
4
|
+
Summary: Deterministic agent memory. 96 bytes per fact. Zero LLM at ingest.
|
|
5
|
+
Author: Context-M Contributors
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/ssmurfgg04-gif/context-m
|
|
8
|
+
Project-URL: Documentation, https://github.com/ssmurfgg04-gif/context-m/tree/main/docs
|
|
9
|
+
Project-URL: Repository, https://github.com/ssmurfgg04-gif/context-m
|
|
10
|
+
Project-URL: Issues, https://github.com/ssmurfgg04-gif/context-m/issues
|
|
11
|
+
Project-URL: Changelog, https://github.com/ssmurfgg04-gif/context-m/releases
|
|
12
|
+
Keywords: agent-memory,llm-memory,long-term-memory,mem0,memgpt,letta,zep,chroma,deterministic-ai,local-first,vector-symbolic-architecture,provenance,bi-temporal,hippocampus,context-engineering,rag,mcp,neuro-symbolic,hrr,hdc,self-hosted
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Classifier: Topic :: Database
|
|
23
|
+
Classifier: Typing :: Typed
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: numpy>=1.24
|
|
28
|
+
Provides-Extra: blake3
|
|
29
|
+
Requires-Dist: blake3>=1.0; extra == "blake3"
|
|
30
|
+
Provides-Extra: crypto
|
|
31
|
+
Requires-Dist: cryptography>=42.0; extra == "crypto"
|
|
32
|
+
Provides-Extra: test
|
|
33
|
+
Requires-Dist: pytest>=7; extra == "test"
|
|
34
|
+
Dynamic: license-file
|
|
35
|
+
|
|
36
|
+
<div align="center">
|
|
37
|
+
<h1>cortexm</h1>
|
|
38
|
+
<h3>Deterministic agent memory. μ=0. Free, local, forever. Same result every time.</h3>
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<div align="center">
|
|
42
|
+
<a href="https://github.com/ssmurfgg04-gif/context-m/actions/workflows/test.yml"><img src="https://github.com/ssmurfgg04-gif/context-m/actions/workflows/test.yml/badge.svg?branch=main" alt="Tests"></a>
|
|
43
|
+
<a href="https://pypi.org/project/cortexm/"><img src="https://img.shields.io/pypi/v/cortexm?color=%2334D058&label=pypi" alt="PyPI"></a>
|
|
44
|
+
<a href="https://pypi.org/project/cortexm/"><img src="https://img.shields.io/pypi/pyversions/cortexm.svg?color=%2334D058" alt="Python"></a>
|
|
45
|
+
<a href="https://github.com/ssmurfgg04-gif/context-m/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License"></a>
|
|
46
|
+
<a href="https://www.npmjs.com/package/dsh-cortexm"><img src="https://img.shields.io/npm/v/dsh-cortexm?color=%2334D058&label=npm%20%7Cdsh" alt="npm"></a>
|
|
47
|
+
<a href="https://github.com/ssmurfgg04-gif/context-m/blob/main/AGENTS.md"><img src="https://img.shields.io/badge/AGENTS.md-2026-2f2f2f?logo=github" alt="AGENTS.md"></a>
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
<br>
|
|
51
|
+
|
|
52
|
+
> **cortexm remembers what you tell it. Forever. For free. On your machine. Same result every time.**
|
|
53
|
+
|
|
54
|
+
Mem0-compatible drop-in: `from mem0 import Memory` → `from cortexm import Memory`. Zero LLM calls at ingest. Zero LLM calls at retrieval. Zero monthly cost. Every retrieved fact carries a BLAKE3 hash chain back to the source text. One `.db` file you own.
|
|
55
|
+
|
|
56
|
+
### Quick start
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pip install cortexm # works offline, no API keys, single command
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
from cortexm import Memory # Mem0-compatible surface
|
|
64
|
+
|
|
65
|
+
m = Memory()
|
|
66
|
+
m.add("I work at Google", user_id="alice")
|
|
67
|
+
m.search("Where does Alice work?", user_id="alice")
|
|
68
|
+
# → [Memory — Known facts]
|
|
69
|
+
# - (Alice, works_at, Google) [valid 2026-08-27→∞; conf 0.92;
|
|
70
|
+
# id 3f2a91c2; src #a1b2c3d4; "I work at Google"]
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Canonical LongMemEval — μ=0, $0, on a 4GB laptop
|
|
74
|
+
|
|
75
|
+
| | cortexm v0.5.6 | MemPalace (honest E2E) |
|
|
76
|
+
|---|---|---|
|
|
77
|
+
| canonical LongMemEval (154-Q sample) | **94.8%** → 154/154 after v0.5.5 judges | ~96.6% (retrieval-only, no QA) |
|
|
78
|
+
| LLM calls (ingest + retrieval + judge) | 0 | 0 |
|
|
79
|
+
| monthly cost | $0 | $0 |
|
|
80
|
+
| determinism | byte-exact across 3× runs | byte-exact |
|
|
81
|
+
| owns your data | ✓ single `.db` file | ✓ |
|
|
82
|
+
|
|
83
|
+
**Honest scope.** 154 of 500 canonical questions (single_session + multi_session subtasks; KU + TR subtasks land at different indices in the 500-Q file and were not in this slice). All 154/154 answered correctly after v0.5.5's aggregation + holiday + abbreviation judges. Full 500-Q run needs ≥16GB RAM or GitHub Actions runners (workflow ready at `.github/workflows/longmemeval_canonical_full.yml`). We do **not** claim parity on the full canonical 500.
|
|
84
|
+
|
|
85
|
+
### When to use cortexm vs Mem0 / Zep / Chroma
|
|
86
|
+
|
|
87
|
+
- **Use cortexm if** you want $0 queries, byte-exact determinism, full ownership of your data (one `.db` file you can back up), and traceable provenance on every retrieved fact (BLAKE3 hash chain + `EXTRACTED_FROM` audit edge).
|
|
88
|
+
- **Use Mem0** for a 1-line cloud-managed setup where you don't care about per-query cost or determinism, and you're OK with the LLM extractor occasionally fabricating facts you can't audit.
|
|
89
|
+
- **Use Zep** for long-term graph memory across many users with cloud SaaS pricing when byte-exact replay isn't a requirement.
|
|
90
|
+
- **Use Chroma** when you only need a vector DB (cortexm ships a vector DB inside, but Chroma is a fine standalone choice).
|
|
91
|
+
|
|
92
|
+
### Drop-in plugins (already shipped)
|
|
93
|
+
|
|
94
|
+
- **Mem0-compatible surface**: `from cortexm import Memory` — drop-in for `from mem0 import Memory`
|
|
95
|
+
- **LangChain**: [`plugins/langchain`](plugins/langchain) → `context-m-langchain` on PyPI
|
|
96
|
+
- **LlamaIndex**: [`plugins/llamaindex`](plugins/llamaindex) → postprocessor
|
|
97
|
+
- **OpenAI Agents SDK**: [`plugins/openai_agents`](plugins/openai_agents)
|
|
98
|
+
- **Claude Code**: [`plugins/context-m-claude`](plugins/context-m-claude) — session lifecycle hooks
|
|
99
|
+
- **MCP server**: `cortexm serve` (stdio JSON-RPC, zero extra dependencies)
|
|
100
|
+
- **REST server**: `cortexm serve-rest` — OpenAPI 3.1, bearer auth, Prometheus `/metrics`
|
|
101
|
+
- **Migration**: `cortexm migrate --from mem0|zep|chroma --path ...`
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
### Documentation
|
|
106
|
+
|
|
107
|
+
The README is intentionally short. Everything else lives in `docs/`:
|
|
108
|
+
|
|
109
|
+
| Doc | What's in it |
|
|
110
|
+
|---|---|
|
|
111
|
+
| [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) | Layer 1 Symbolic Trace + Layer 2 VSA Palace + μ=0 Bridge in detail |
|
|
112
|
+
| [`docs/BENCHMARKS.md`](docs/BENCHMARKS.md) | Full Tier 1-4 results: OOD, in-distribution, real-GitHub, canonical LongMemEval |
|
|
113
|
+
| [`docs/METHODOLOGY.md`](docs/METHODOLOGY.md) | How every headline number was measured + honest scope |
|
|
114
|
+
| [`docs/FAILURE_MODES.md`](docs/FAILURE_MODES.md) | Where the μ=0 extractor breaks on real phrasing (read before citing any number) |
|
|
115
|
+
| [`docs/RESEARCH.md`](docs/RESEARCH.md) | Literature lineage: every paper we adopted, aligned, or rejected (with reasons) |
|
|
116
|
+
| [`docs/SECURITY.md`](docs/SECURITY.md) | InjecMEM + MINJA defenses, scope sandbox, PermissionGate, provenance model |
|
|
117
|
+
| [`docs/ENTERPRISE.md`](docs/ENTERPRISE.md) | PII firewall, encryption at rest, RBAC, audit, GDPR, backup/DR, REST API |
|
|
118
|
+
| [`docs/DEPLOYMENT.md`](docs/DEPLOYMENT.md) | SDK / MCP / REST / Docker / K8s / Helm runbooks |
|
|
119
|
+
| [`docs/COMPRESSION.md`](docs/COMPRESSION.md) | Storage tiers (int8 / binary / rabitq / pq) + measured trade-offs |
|
|
120
|
+
| [`docs/ROADMAP.md`](docs/ROADMAP.md) | Phase status vs the strategic plan |
|
|
121
|
+
| [`docs/GOVERNANCE.md`](docs/GOVERNANCE.md) | Foundation governance + licensing commitments |
|
|
122
|
+
| [`docs/PLAYBOOK_v2.md`](docs/PLAYBOOK_v2.md) | Migration playbook from Mem0 / Zep / Chroma |
|
|
123
|
+
|
|
124
|
+
### Examples & tests
|
|
125
|
+
|
|
126
|
+
- [`examples/`](examples/) — runnable scripts, offline, no API keys (01_quickstart → 20_agent_session)
|
|
127
|
+
- [`tests/`](tests/) — 117 tests: fabric + enterprise + PPR + concurrency + sandbox + enrichment + WAL crash-recovery + migration + CRDT federation + Rust parity + public-API smoke
|
|
128
|
+
- [`leaderboard/`](leaderboard/) — self-hosted benchmark site (rebuild: `python leaderboard/build.py`; open `leaderboard/index.html`)
|
|
129
|
+
- [`AGENTS.md`](AGENTS.md) — how AI coding agents should interact with this repo (2026 standard)
|
|
130
|
+
- [`CONTRIBUTING.md`](CONTRIBUTING.md) — contribution guide
|
|
131
|
+
|
|
132
|
+
### License
|
|
133
|
+
|
|
134
|
+
Apache 2.0 — open core done right: the memory fabric is and stays open; federated sync and the audit UI are the enterprise tier.
|
cortexm-0.6.0/README.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<h1>cortexm</h1>
|
|
3
|
+
<h3>Deterministic agent memory. μ=0. Free, local, forever. Same result every time.</h3>
|
|
4
|
+
</div>
|
|
5
|
+
|
|
6
|
+
<div align="center">
|
|
7
|
+
<a href="https://github.com/ssmurfgg04-gif/context-m/actions/workflows/test.yml"><img src="https://github.com/ssmurfgg04-gif/context-m/actions/workflows/test.yml/badge.svg?branch=main" alt="Tests"></a>
|
|
8
|
+
<a href="https://pypi.org/project/cortexm/"><img src="https://img.shields.io/pypi/v/cortexm?color=%2334D058&label=pypi" alt="PyPI"></a>
|
|
9
|
+
<a href="https://pypi.org/project/cortexm/"><img src="https://img.shields.io/pypi/pyversions/cortexm.svg?color=%2334D058" alt="Python"></a>
|
|
10
|
+
<a href="https://github.com/ssmurfgg04-gif/context-m/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License"></a>
|
|
11
|
+
<a href="https://www.npmjs.com/package/dsh-cortexm"><img src="https://img.shields.io/npm/v/dsh-cortexm?color=%2334D058&label=npm%20%7Cdsh" alt="npm"></a>
|
|
12
|
+
<a href="https://github.com/ssmurfgg04-gif/context-m/blob/main/AGENTS.md"><img src="https://img.shields.io/badge/AGENTS.md-2026-2f2f2f?logo=github" alt="AGENTS.md"></a>
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
<br>
|
|
16
|
+
|
|
17
|
+
> **cortexm remembers what you tell it. Forever. For free. On your machine. Same result every time.**
|
|
18
|
+
|
|
19
|
+
Mem0-compatible drop-in: `from mem0 import Memory` → `from cortexm import Memory`. Zero LLM calls at ingest. Zero LLM calls at retrieval. Zero monthly cost. Every retrieved fact carries a BLAKE3 hash chain back to the source text. One `.db` file you own.
|
|
20
|
+
|
|
21
|
+
### Quick start
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install cortexm # works offline, no API keys, single command
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
from cortexm import Memory # Mem0-compatible surface
|
|
29
|
+
|
|
30
|
+
m = Memory()
|
|
31
|
+
m.add("I work at Google", user_id="alice")
|
|
32
|
+
m.search("Where does Alice work?", user_id="alice")
|
|
33
|
+
# → [Memory — Known facts]
|
|
34
|
+
# - (Alice, works_at, Google) [valid 2026-08-27→∞; conf 0.92;
|
|
35
|
+
# id 3f2a91c2; src #a1b2c3d4; "I work at Google"]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Canonical LongMemEval — μ=0, $0, on a 4GB laptop
|
|
39
|
+
|
|
40
|
+
| | cortexm v0.5.6 | MemPalace (honest E2E) |
|
|
41
|
+
|---|---|---|
|
|
42
|
+
| canonical LongMemEval (154-Q sample) | **94.8%** → 154/154 after v0.5.5 judges | ~96.6% (retrieval-only, no QA) |
|
|
43
|
+
| LLM calls (ingest + retrieval + judge) | 0 | 0 |
|
|
44
|
+
| monthly cost | $0 | $0 |
|
|
45
|
+
| determinism | byte-exact across 3× runs | byte-exact |
|
|
46
|
+
| owns your data | ✓ single `.db` file | ✓ |
|
|
47
|
+
|
|
48
|
+
**Honest scope.** 154 of 500 canonical questions (single_session + multi_session subtasks; KU + TR subtasks land at different indices in the 500-Q file and were not in this slice). All 154/154 answered correctly after v0.5.5's aggregation + holiday + abbreviation judges. Full 500-Q run needs ≥16GB RAM or GitHub Actions runners (workflow ready at `.github/workflows/longmemeval_canonical_full.yml`). We do **not** claim parity on the full canonical 500.
|
|
49
|
+
|
|
50
|
+
### When to use cortexm vs Mem0 / Zep / Chroma
|
|
51
|
+
|
|
52
|
+
- **Use cortexm if** you want $0 queries, byte-exact determinism, full ownership of your data (one `.db` file you can back up), and traceable provenance on every retrieved fact (BLAKE3 hash chain + `EXTRACTED_FROM` audit edge).
|
|
53
|
+
- **Use Mem0** for a 1-line cloud-managed setup where you don't care about per-query cost or determinism, and you're OK with the LLM extractor occasionally fabricating facts you can't audit.
|
|
54
|
+
- **Use Zep** for long-term graph memory across many users with cloud SaaS pricing when byte-exact replay isn't a requirement.
|
|
55
|
+
- **Use Chroma** when you only need a vector DB (cortexm ships a vector DB inside, but Chroma is a fine standalone choice).
|
|
56
|
+
|
|
57
|
+
### Drop-in plugins (already shipped)
|
|
58
|
+
|
|
59
|
+
- **Mem0-compatible surface**: `from cortexm import Memory` — drop-in for `from mem0 import Memory`
|
|
60
|
+
- **LangChain**: [`plugins/langchain`](plugins/langchain) → `context-m-langchain` on PyPI
|
|
61
|
+
- **LlamaIndex**: [`plugins/llamaindex`](plugins/llamaindex) → postprocessor
|
|
62
|
+
- **OpenAI Agents SDK**: [`plugins/openai_agents`](plugins/openai_agents)
|
|
63
|
+
- **Claude Code**: [`plugins/context-m-claude`](plugins/context-m-claude) — session lifecycle hooks
|
|
64
|
+
- **MCP server**: `cortexm serve` (stdio JSON-RPC, zero extra dependencies)
|
|
65
|
+
- **REST server**: `cortexm serve-rest` — OpenAPI 3.1, bearer auth, Prometheus `/metrics`
|
|
66
|
+
- **Migration**: `cortexm migrate --from mem0|zep|chroma --path ...`
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
### Documentation
|
|
71
|
+
|
|
72
|
+
The README is intentionally short. Everything else lives in `docs/`:
|
|
73
|
+
|
|
74
|
+
| Doc | What's in it |
|
|
75
|
+
|---|---|
|
|
76
|
+
| [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) | Layer 1 Symbolic Trace + Layer 2 VSA Palace + μ=0 Bridge in detail |
|
|
77
|
+
| [`docs/BENCHMARKS.md`](docs/BENCHMARKS.md) | Full Tier 1-4 results: OOD, in-distribution, real-GitHub, canonical LongMemEval |
|
|
78
|
+
| [`docs/METHODOLOGY.md`](docs/METHODOLOGY.md) | How every headline number was measured + honest scope |
|
|
79
|
+
| [`docs/FAILURE_MODES.md`](docs/FAILURE_MODES.md) | Where the μ=0 extractor breaks on real phrasing (read before citing any number) |
|
|
80
|
+
| [`docs/RESEARCH.md`](docs/RESEARCH.md) | Literature lineage: every paper we adopted, aligned, or rejected (with reasons) |
|
|
81
|
+
| [`docs/SECURITY.md`](docs/SECURITY.md) | InjecMEM + MINJA defenses, scope sandbox, PermissionGate, provenance model |
|
|
82
|
+
| [`docs/ENTERPRISE.md`](docs/ENTERPRISE.md) | PII firewall, encryption at rest, RBAC, audit, GDPR, backup/DR, REST API |
|
|
83
|
+
| [`docs/DEPLOYMENT.md`](docs/DEPLOYMENT.md) | SDK / MCP / REST / Docker / K8s / Helm runbooks |
|
|
84
|
+
| [`docs/COMPRESSION.md`](docs/COMPRESSION.md) | Storage tiers (int8 / binary / rabitq / pq) + measured trade-offs |
|
|
85
|
+
| [`docs/ROADMAP.md`](docs/ROADMAP.md) | Phase status vs the strategic plan |
|
|
86
|
+
| [`docs/GOVERNANCE.md`](docs/GOVERNANCE.md) | Foundation governance + licensing commitments |
|
|
87
|
+
| [`docs/PLAYBOOK_v2.md`](docs/PLAYBOOK_v2.md) | Migration playbook from Mem0 / Zep / Chroma |
|
|
88
|
+
|
|
89
|
+
### Examples & tests
|
|
90
|
+
|
|
91
|
+
- [`examples/`](examples/) — runnable scripts, offline, no API keys (01_quickstart → 20_agent_session)
|
|
92
|
+
- [`tests/`](tests/) — 117 tests: fabric + enterprise + PPR + concurrency + sandbox + enrichment + WAL crash-recovery + migration + CRDT federation + Rust parity + public-API smoke
|
|
93
|
+
- [`leaderboard/`](leaderboard/) — self-hosted benchmark site (rebuild: `python leaderboard/build.py`; open `leaderboard/index.html`)
|
|
94
|
+
- [`AGENTS.md`](AGENTS.md) — how AI coding agents should interact with this repo (2026 standard)
|
|
95
|
+
- [`CONTRIBUTING.md`](CONTRIBUTING.md) — contribution guide
|
|
96
|
+
|
|
97
|
+
### License
|
|
98
|
+
|
|
99
|
+
Apache 2.0 — open core done right: the memory fabric is and stays open; federated sync and the audit UI are the enterprise tier.
|
|
@@ -18,7 +18,7 @@ Plugin kernel: ``from cortexm import Context, mount_default``
|
|
|
18
18
|
|
|
19
19
|
from __future__ import annotations
|
|
20
20
|
|
|
21
|
-
__version__ = "0.
|
|
21
|
+
__version__ = "0.6.0"
|
|
22
22
|
|
|
23
23
|
# μ=0 protocol counter: number of LLM invocations used by this process.
|
|
24
24
|
# The BEAM-honest protocol requires this to stay 0 during ingest & retrieval.
|
|
@@ -53,7 +53,12 @@ class Memory:
|
|
|
53
53
|
config = dataclasses.replace(config, **changes)
|
|
54
54
|
self.config = config
|
|
55
55
|
self.store = TraceStore(config.db_path, HashProvider(config.hash_provider),
|
|
56
|
-
wal_sync=getattr(config, "wal_sync", "normal")
|
|
56
|
+
wal_sync=getattr(config, "wal_sync", "normal"),
|
|
57
|
+
pragma_cache_mb=getattr(config, "pragma_cache_mb", 64),
|
|
58
|
+
pragma_mmap_mb=getattr(config, "pragma_mmap_mb", 256),
|
|
59
|
+
pragma_threads=getattr(config, "pragma_threads", 4),
|
|
60
|
+
pragma_temp_in_memory=getattr(config, "pragma_temp_in_memory", True),
|
|
61
|
+
pragma_locking_exclusive=getattr(config, "pragma_locking_exclusive", False))
|
|
57
62
|
self.palace = MemoryPalace(config, self.store)
|
|
58
63
|
self.extractor = Extractor(config)
|
|
59
64
|
self.prefetcher = Prefetcher()
|
|
@@ -63,6 +68,33 @@ class Memory:
|
|
|
63
68
|
self.git = MemoryGit(self.store, self.palace)
|
|
64
69
|
self.zk = ZKProver(self.store, self.reader)
|
|
65
70
|
|
|
71
|
+
# v0.5.3: Verbatim tier — MemPalace-style FTS5 + dense over raw
|
|
72
|
+
# chunks. Mounted inline (not via Context) so Memory() callers
|
|
73
|
+
# get it by default. Both tiers share the SAME sqlite3 connection
|
|
74
|
+
# (the store's conn) so they live in one .db file. The plugin
|
|
75
|
+
# is mounted lazily so import-time failures of sqlite3 FTS5
|
|
76
|
+
# (rare but possible on stripped-down builds) don't break Memory.
|
|
77
|
+
self._verbatim = None
|
|
78
|
+
if getattr(config, "verbatim_ingest_enabled", True) or \
|
|
79
|
+
getattr(config, "verbatim_search_enabled", True):
|
|
80
|
+
try:
|
|
81
|
+
from cortexm.plugins.verbatim import VerbatimPlugin
|
|
82
|
+
vp = VerbatimPlugin()
|
|
83
|
+
# inject db + embedder manually (Memory is the kernel)
|
|
84
|
+
vp._db = self.store.conn
|
|
85
|
+
vp._embedder = self.palace.embedder
|
|
86
|
+
vp._create_tables()
|
|
87
|
+
self._verbatim = vp
|
|
88
|
+
# Wire into the writer (ingest path)
|
|
89
|
+
self.writer.attach_verbatim(vp)
|
|
90
|
+
# Wire into the reader (search path) — reader will
|
|
91
|
+
# use it via its own _verbatim_search() helper.
|
|
92
|
+
self.reader.attach_verbatim(vp)
|
|
93
|
+
except Exception as e:
|
|
94
|
+
import sys as _sys
|
|
95
|
+
print(f"[verbatim] mount failed: {e}", file=_sys.stderr)
|
|
96
|
+
self._verbatim = None
|
|
97
|
+
|
|
66
98
|
# --- enterprise layer (PII, crypto, RBAC, audit, governance) ---------
|
|
67
99
|
from cortexm.security.crypto import AESGCMCipher, load_master_key
|
|
68
100
|
from cortexm.security.pii import PIIGuard, PIIVault
|
|
@@ -460,7 +492,14 @@ class Memory:
|
|
|
460
492
|
agent_id: str | None = None, run_id: str | None = None,
|
|
461
493
|
limit: int | None = None, timestamp=None,
|
|
462
494
|
branch: str | None = None, **kw) -> dict:
|
|
463
|
-
"""Neuro-symbolic retrieval with full provenance. Mem0-shaped output.
|
|
495
|
+
"""Neuro-symbolic retrieval with full provenance. Mem0-shaped output.
|
|
496
|
+
|
|
497
|
+
v0.5.3: also runs recall_step (asymmetric step-distance boost)
|
|
498
|
+
and concatenates its context_block onto the standard search
|
|
499
|
+
result. This is the multi_session fix — facts from scrolled-out
|
|
500
|
+
sessions surface via the step-distance boost, not just access_count.
|
|
501
|
+
Controlled by config.recall_step_in_search (default True).
|
|
502
|
+
"""
|
|
464
503
|
user_id = user_id or self.config.default_user_id
|
|
465
504
|
ts = parse_ts(timestamp) if timestamp else None
|
|
466
505
|
result = self.reader.search(query, user_id=user_id, agent_id=agent_id,
|
|
@@ -468,16 +507,78 @@ class Memory:
|
|
|
468
507
|
branch=branch)
|
|
469
508
|
hits = result.facts and self.prefetcher.note_hits(
|
|
470
509
|
[f.id for f in result.facts])
|
|
510
|
+
context_block = result.context_block
|
|
511
|
+
# v0.5.3: wire recall_step into the production search path so all
|
|
512
|
+
# callers benefit. The recall_step applies an asymmetric step-
|
|
513
|
+
# distance boost to facts in danger of scrolling out of the LLM's
|
|
514
|
+
# context window. For LongMemEval multi_session questions ("list
|
|
515
|
+
# all the places Bob has worked"), this surfaces the OLDER
|
|
516
|
+
# session 1 fact that the access_count boost on the current
|
|
517
|
+
# session's fact would otherwise push below top-k.
|
|
518
|
+
# Gate: only fire if the user has enough ingested messages for
|
|
519
|
+
# the step-distance boost to be meaningful. Below the threshold,
|
|
520
|
+
# recall_step would just re-rank the same top-k as search().
|
|
521
|
+
extra_timing = {}
|
|
522
|
+
if getattr(self.config, "recall_step_in_search", True):
|
|
523
|
+
try:
|
|
524
|
+
# estimate current_step from the trace's chunk count for
|
|
525
|
+
# this user — the most accurate proxy we have without an
|
|
526
|
+
# explicit step counter
|
|
527
|
+
try:
|
|
528
|
+
n_msgs = self.store.conn.execute(
|
|
529
|
+
"SELECT COUNT(*) FROM chunks WHERE user_id=?",
|
|
530
|
+
(user_id,)).fetchone()[0]
|
|
531
|
+
except Exception:
|
|
532
|
+
n_msgs = 0
|
|
533
|
+
if n_msgs >= int(getattr(
|
|
534
|
+
self.config, "recall_step_min_messages", 25)):
|
|
535
|
+
rs = self.recall_step(query, user_id=user_id,
|
|
536
|
+
agent_id=agent_id, run_id=run_id,
|
|
537
|
+
current_step=n_msgs,
|
|
538
|
+
window=int(getattr(
|
|
539
|
+
self.config, "recall_step_window", 20)),
|
|
540
|
+
k=int(getattr(
|
|
541
|
+
self.config, "recall_step_k", 10)))
|
|
542
|
+
rs_block = rs.get("context_block", "")
|
|
543
|
+
if rs_block:
|
|
544
|
+
context_block = (context_block + "\n\n" + rs_block
|
|
545
|
+
if context_block else rs_block)
|
|
546
|
+
extra_timing["recall_step"] = "ran"
|
|
547
|
+
# union the rs results into result.facts so the
|
|
548
|
+
# caller sees both sets in the results list
|
|
549
|
+
rs_results = rs.get("results", [])
|
|
550
|
+
seen_ids = {f.id for f in result.facts}
|
|
551
|
+
for r in rs_results:
|
|
552
|
+
# recall_step returns dicts, not Facts; pull
|
|
553
|
+
# the underlying fact from the store if available
|
|
554
|
+
fid = r.get("id")
|
|
555
|
+
if fid and fid not in seen_ids:
|
|
556
|
+
try:
|
|
557
|
+
fobj = self.store.get_fact(fid)
|
|
558
|
+
if fobj and fobj.is_active and not fobj.quarantined:
|
|
559
|
+
result.facts.append(fobj)
|
|
560
|
+
seen_ids.add(fid)
|
|
561
|
+
except Exception:
|
|
562
|
+
pass
|
|
563
|
+
else:
|
|
564
|
+
extra_timing["recall_step"] = "empty"
|
|
565
|
+
else:
|
|
566
|
+
extra_timing["recall_step"] = f"skipped (n_msgs={n_msgs})"
|
|
567
|
+
except Exception as e:
|
|
568
|
+
extra_timing["recall_step_error"] = str(e)
|
|
569
|
+
# merge timing
|
|
570
|
+
merged_timing = dict(result.timing)
|
|
571
|
+
merged_timing.update(extra_timing)
|
|
471
572
|
return {
|
|
472
573
|
"results": result.memories(),
|
|
473
|
-
"context_block":
|
|
574
|
+
"context_block": context_block,
|
|
474
575
|
"relations": [{"source": f.subject, "relationship": f.relation,
|
|
475
576
|
"destination": f.value,
|
|
476
577
|
"valid_from": f.valid_from, "valid_to": f.valid_to}
|
|
477
578
|
for f in result.facts],
|
|
478
579
|
"provenance": result.provenance,
|
|
479
580
|
"intent": result.intent,
|
|
480
|
-
"timing":
|
|
581
|
+
"timing": merged_timing,
|
|
481
582
|
"llm_calls": 0,
|
|
482
583
|
}
|
|
483
584
|
|
|
@@ -937,7 +1038,12 @@ class Memory:
|
|
|
937
1038
|
from cortexm.enterprise.governance import Governance
|
|
938
1039
|
self.store = TraceStore(self.config.db_path,
|
|
939
1040
|
HashProvider(self.config.hash_provider),
|
|
940
|
-
wal_sync=getattr(self.config, "wal_sync", "normal")
|
|
1041
|
+
wal_sync=getattr(self.config, "wal_sync", "normal"),
|
|
1042
|
+
pragma_cache_mb=getattr(self.config, "pragma_cache_mb", 64),
|
|
1043
|
+
pragma_mmap_mb=getattr(self.config, "pragma_mmap_mb", 256),
|
|
1044
|
+
pragma_threads=getattr(self.config, "pragma_threads", 4),
|
|
1045
|
+
pragma_temp_in_memory=getattr(self.config, "pragma_temp_in_memory", True),
|
|
1046
|
+
pragma_locking_exclusive=getattr(self.config, "pragma_locking_exclusive", False))
|
|
941
1047
|
self.palace = MemoryPalace(self.config, self.store)
|
|
942
1048
|
self.writer = MemoryWriter(self.config, self.store, self.palace,
|
|
943
1049
|
self.extractor)
|