grafeo-memory 0.2.2__tar.gz → 0.3.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.
- {grafeo_memory-0.2.2 → grafeo_memory-0.3.0}/.env.example +18 -2
- {grafeo_memory-0.2.2 → grafeo_memory-0.3.0}/.github/workflows/ci.yml +12 -12
- grafeo_memory-0.3.0/.github/workflows/engine-compat.yml +45 -0
- {grafeo_memory-0.2.2 → grafeo_memory-0.3.0}/.github/workflows/pypi.yml +4 -4
- {grafeo_memory-0.2.2 → grafeo_memory-0.3.0}/.gitignore +25 -0
- grafeo_memory-0.3.0/.pre-commit-config.yaml +47 -0
- {grafeo_memory-0.2.2 → grafeo_memory-0.3.0}/CHANGELOG.md +114 -4
- grafeo_memory-0.3.0/PKG-INFO +599 -0
- grafeo_memory-0.3.0/README.md +544 -0
- grafeo_memory-0.3.0/docs/architecture.md +66 -0
- grafeo_memory-0.3.0/docs/benchmarks.md +109 -0
- {grafeo_memory-0.2.2 → grafeo_memory-0.3.0}/examples/async_memory.py +1 -1
- {grafeo_memory-0.2.2 → grafeo_memory-0.3.0}/examples/importance_scoring.py +2 -2
- {grafeo_memory-0.2.2 → grafeo_memory-0.3.0}/examples/mistral_quickstart.py +4 -4
- {grafeo_memory-0.2.2 → grafeo_memory-0.3.0}/examples/multimodal_vision.py +2 -2
- {grafeo_memory-0.2.2 → grafeo_memory-0.3.0}/examples/procedural_memory.py +1 -1
- {grafeo_memory-0.2.2 → grafeo_memory-0.3.0}/examples/temporal_bench.py +1 -1
- {grafeo_memory-0.2.2 → grafeo_memory-0.3.0}/examples/topology_boost.py +3 -3
- {grafeo_memory-0.2.2 → grafeo_memory-0.3.0}/examples/usage_tracking.py +1 -1
- grafeo_memory-0.3.0/grafeo_memory/__init__.py +164 -0
- grafeo_memory-0.3.0/grafeo_memory/_deprecated.py +83 -0
- grafeo_memory-0.3.0/grafeo_memory/agent_framework.py +388 -0
- grafeo_memory-0.3.0/grafeo_memory/bench/README.md +6 -0
- grafeo_memory-0.3.0/grafeo_memory/bench/__init__.py +7 -0
- grafeo_memory-0.3.0/grafeo_memory/bench/beam_eval.py +404 -0
- grafeo_memory-0.3.0/grafeo_memory/bench/common.py +233 -0
- grafeo_memory-0.3.0/grafeo_memory/bench/lme_eval.py +416 -0
- grafeo_memory-0.3.0/grafeo_memory/bench/locomo_eval.py +726 -0
- grafeo_memory-0.3.0/grafeo_memory/bench/matrix.py +524 -0
- grafeo_memory-0.3.0/grafeo_memory/bench/ruff.toml +11 -0
- grafeo_memory-0.3.0/grafeo_memory/bench/vector_search_bench.py +230 -0
- grafeo_memory-0.3.0/grafeo_memory/cli/__init__.py +11 -0
- grafeo_memory-0.2.2/src/grafeo_memory/cli.py → grafeo_memory-0.3.0/grafeo_memory/cli/app.py +45 -18
- grafeo_memory-0.3.0/grafeo_memory/common/README.md +13 -0
- grafeo_memory-0.3.0/grafeo_memory/common/__init__.py +63 -0
- grafeo_memory-0.3.0/grafeo_memory/common/cache.py +613 -0
- grafeo_memory-0.2.2/src/grafeo_memory/_compat.py → grafeo_memory-0.3.0/grafeo_memory/common/compat.py +17 -9
- grafeo_memory-0.3.0/grafeo_memory/common/exceptions.py +15 -0
- grafeo_memory-0.3.0/grafeo_memory/common/intervals.py +329 -0
- grafeo_memory-0.3.0/grafeo_memory/common/logging.py +106 -0
- grafeo_memory-0.3.0/grafeo_memory/common/paths.py +58 -0
- grafeo_memory-0.3.0/grafeo_memory/common/ruff.toml +11 -0
- grafeo_memory-0.3.0/grafeo_memory/common/secrets.py +37 -0
- grafeo_memory-0.3.0/grafeo_memory/common/settings.py +103 -0
- grafeo_memory-0.3.0/grafeo_memory/common/telemetry.py +32 -0
- grafeo_memory-0.3.0/grafeo_memory/common/timing.py +65 -0
- grafeo_memory-0.3.0/grafeo_memory/common/types.py +1077 -0
- grafeo_memory-0.3.0/grafeo_memory/core/__init__.py +4 -0
- grafeo_memory-0.3.0/grafeo_memory/core/_compat.py +4 -0
- grafeo_memory-0.3.0/grafeo_memory/core/_graph.py +36 -0
- {grafeo_memory-0.2.2/src/grafeo_memory → grafeo_memory-0.3.0/grafeo_memory/core}/_tracing.py +1 -1
- grafeo_memory-0.3.0/grafeo_memory/core/bucket.py +54 -0
- {grafeo_memory-0.2.2/src/grafeo_memory → grafeo_memory-0.3.0/grafeo_memory/core}/communities.py +12 -9
- grafeo_memory-0.3.0/grafeo_memory/core/extraction/__init__.py +16 -0
- {grafeo_memory-0.2.2/src/grafeo_memory → grafeo_memory-0.3.0/grafeo_memory/core}/extraction/entities.py +16 -16
- {grafeo_memory-0.2.2/src/grafeo_memory → grafeo_memory-0.3.0/grafeo_memory/core}/extraction/facts.py +8 -8
- grafeo_memory-0.3.0/grafeo_memory/core/extraction/ruff.toml +12 -0
- {grafeo_memory-0.2.2/src/grafeo_memory → grafeo_memory-0.3.0/grafeo_memory/core}/extraction/temporal.py +5 -5
- grafeo_memory-0.3.0/grafeo_memory/core/history.py +209 -0
- grafeo_memory-0.3.0/grafeo_memory/core/ontology/README.md +9 -0
- grafeo_memory-0.3.0/grafeo_memory/core/ontology/__init__.py +30 -0
- grafeo_memory-0.3.0/grafeo_memory/core/ontology/normalize.py +97 -0
- grafeo_memory-0.3.0/grafeo_memory/core/ontology/ruff.toml +14 -0
- grafeo_memory-0.3.0/grafeo_memory/core/ontology/scheme.py +220 -0
- grafeo_memory-0.3.0/grafeo_memory/core/ontology/temporal_rules.py +28 -0
- grafeo_memory-0.3.0/grafeo_memory/core/ontology/types.py +130 -0
- grafeo_memory-0.3.0/grafeo_memory/core/policy/__init__.py +32 -0
- grafeo_memory-0.3.0/grafeo_memory/core/policy/packs.py +116 -0
- grafeo_memory-0.3.0/grafeo_memory/core/policy/ruff.toml +14 -0
- grafeo_memory-0.3.0/grafeo_memory/core/policy/rules.py +51 -0
- grafeo_memory-0.3.0/grafeo_memory/core/policy/shapes.py +41 -0
- {grafeo_memory-0.2.2/src/grafeo_memory → grafeo_memory-0.3.0/grafeo_memory/core}/protocol.py +8 -4
- grafeo_memory-0.3.0/grafeo_memory/core/reconciliation/README.md +9 -0
- grafeo_memory-0.3.0/grafeo_memory/core/reconciliation/__init__.py +16 -0
- grafeo_memory-0.3.0/grafeo_memory/core/reconciliation/memories.py +393 -0
- grafeo_memory-0.3.0/grafeo_memory/core/reconciliation/relations.py +206 -0
- grafeo_memory-0.3.0/grafeo_memory/core/reconciliation/ruff.toml +11 -0
- grafeo_memory-0.3.0/grafeo_memory/core/reconciliation/temporal.py +158 -0
- {grafeo_memory-0.2.2/src/grafeo_memory → grafeo_memory-0.3.0/grafeo_memory/core}/reranker.py +8 -20
- grafeo_memory-0.3.0/grafeo_memory/core/ruff.toml +9 -0
- {grafeo_memory-0.2.2/src/grafeo_memory → grafeo_memory-0.3.0/grafeo_memory/core}/scoring.py +10 -56
- grafeo_memory-0.3.0/grafeo_memory/core/search/__init__.py +6 -0
- {grafeo_memory-0.2.2/src/grafeo_memory → grafeo_memory-0.3.0/grafeo_memory/core}/search/graph.py +13 -5
- grafeo_memory-0.3.0/grafeo_memory/core/search/ruff.toml +11 -0
- {grafeo_memory-0.2.2/src/grafeo_memory → grafeo_memory-0.3.0/grafeo_memory/core}/search/vector.py +45 -16
- grafeo_memory-0.3.0/grafeo_memory/core/taxonomy.py +272 -0
- grafeo_memory-0.3.0/grafeo_memory/core/tiers.py +62 -0
- {grafeo_memory-0.2.2/src/grafeo_memory → grafeo_memory-0.3.0/grafeo_memory/core}/vision.py +5 -5
- grafeo_memory-0.3.0/grafeo_memory/mcp/__init__.py +9 -0
- {grafeo_memory-0.2.2/src → grafeo_memory-0.3.0}/grafeo_memory/mcp/resources.py +16 -6
- grafeo_memory-0.3.0/grafeo_memory/mcp/server.py +135 -0
- {grafeo_memory-0.2.2/src → grafeo_memory-0.3.0}/grafeo_memory/mcp/tools.py +161 -12
- grafeo_memory-0.3.0/grafeo_memory/providers/__init__.py +4 -0
- grafeo_memory-0.3.0/grafeo_memory/providers/decision/README.md +10 -0
- grafeo_memory-0.3.0/grafeo_memory/providers/decision/__init__.py +51 -0
- grafeo_memory-0.3.0/grafeo_memory/providers/decision/fake.py +44 -0
- grafeo_memory-0.3.0/grafeo_memory/providers/decision/jev.py +226 -0
- grafeo_memory-0.3.0/grafeo_memory/providers/decision/packs.py +291 -0
- grafeo_memory-0.3.0/grafeo_memory/providers/decision/protocol.py +27 -0
- grafeo_memory-0.3.0/grafeo_memory/providers/decision/registry.py +92 -0
- grafeo_memory-0.3.0/grafeo_memory/providers/decision/ruff.toml +10 -0
- grafeo_memory-0.3.0/grafeo_memory/providers/decision/types.py +42 -0
- grafeo_memory-0.2.2/src/grafeo_memory/embedding.py → grafeo_memory-0.3.0/grafeo_memory/providers/embedding/__init__.py +21 -15
- grafeo_memory-0.3.0/grafeo_memory/providers/llm/__init__.py +6 -0
- grafeo_memory-0.3.0/grafeo_memory/providers/llm/model_registry.py +34 -0
- grafeo_memory-0.3.0/grafeo_memory/providers/llm/retry.py +47 -0
- grafeo_memory-0.3.0/grafeo_memory/providers/ruff.toml +10 -0
- grafeo_memory-0.3.0/grafeo_memory/ruff.toml +6 -0
- grafeo_memory-0.3.0/grafeo_memory/services/__init__.py +5 -0
- grafeo_memory-0.3.0/grafeo_memory/services/bucket.py +446 -0
- grafeo_memory-0.3.0/grafeo_memory/services/compile.py +241 -0
- grafeo_memory-0.2.2/src/grafeo_memory/manager.py → grafeo_memory-0.3.0/grafeo_memory/services/memory.py +1482 -180
- grafeo_memory-0.3.0/grafeo_memory/services/policy.py +203 -0
- grafeo_memory-0.3.0/grafeo_memory/services/retrieval.py +243 -0
- grafeo_memory-0.3.0/grafeo_memory/services/ruff.toml +8 -0
- grafeo_memory-0.3.0/grafeo_memory/services/schema.py +82 -0
- grafeo_memory-0.3.0/grafeo_memory/services/scoping.py +438 -0
- grafeo_memory-0.3.0/grafeo_memory/services/tiers.py +187 -0
- {grafeo_memory-0.2.2 → grafeo_memory-0.3.0}/pyproject.toml +47 -15
- grafeo_memory-0.3.0/tests/fixtures/grafeo_0_5/grafeo-memory-0.2.2/manifest.json +603 -0
- grafeo_memory-0.3.0/tests/fixtures/grafeo_0_5/grafeo-memory-0.2.2/memory.grafeo +0 -0
- grafeo_memory-0.3.0/tests/fixtures/grafeo_0_5/grafeo-memory-0.2.2/memory_wal/LOCK +0 -0
- grafeo_memory-0.3.0/tests/fixtures/grafeo_0_5/grafeo-memory-0.2.2/memory_wal/wal/wal_00000000.log +0 -0
- grafeo_memory-0.3.0/tests/fixtures/grafeo_0_5/grafeo-memory-0.2.3/manifest.json +739 -0
- grafeo_memory-0.3.0/tests/fixtures/grafeo_0_5/grafeo-memory-0.2.3/memory.grafeo +0 -0
- grafeo_memory-0.3.0/tests/fixtures/grafeo_0_5/grafeo-memory-0.2.3/memory_wal/LOCK +0 -0
- grafeo_memory-0.3.0/tests/fixtures/grafeo_0_5/grafeo-memory-0.2.3/memory_wal/wal/wal_00000000.log +0 -0
- grafeo_memory-0.3.0/tests/fixtures/grafeo_0_5/make_fixtures.py +239 -0
- {grafeo_memory-0.2.2 → grafeo_memory-0.3.0}/tests/mock_llm.py +6 -0
- grafeo_memory-0.3.0/tests/test_bench/__init__.py +0 -0
- grafeo_memory-0.3.0/tests/test_bench/conftest.py +36 -0
- grafeo_memory-0.3.0/tests/test_bench/test_cache_replay.py +64 -0
- grafeo_memory-0.3.0/tests/test_bench/test_common.py +65 -0
- grafeo_memory-0.3.0/tests/test_bench/test_gate.py +216 -0
- grafeo_memory-0.3.0/tests/test_common/__init__.py +0 -0
- grafeo_memory-0.3.0/tests/test_common/test_architecture.py +126 -0
- grafeo_memory-0.3.0/tests/test_common/test_cache.py +399 -0
- grafeo_memory-0.3.0/tests/test_common/test_deprecated_paths.py +51 -0
- grafeo_memory-0.3.0/tests/test_common/test_intervals.py +237 -0
- grafeo_memory-0.3.0/tests/test_common/test_settings.py +175 -0
- grafeo_memory-0.3.0/tests/test_common/test_small_modules.py +149 -0
- grafeo_memory-0.3.0/tests/test_core/__init__.py +0 -0
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_core}/test_bitemporal.py +2 -6
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_core}/test_communities.py +2 -2
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_core}/test_explain.py +1 -1
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_core}/test_extractor.py +3 -3
- grafeo_memory-0.3.0/tests/test_core/test_grafeo_contract.py +595 -0
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_core}/test_instrumentation.py +1 -1
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_core}/test_messages.py +3 -3
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_core}/test_multi_hop.py +2 -2
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_core}/test_multi_tenant.py +4 -4
- grafeo_memory-0.3.0/tests/test_core/test_ontology.py +314 -0
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_core}/test_persistence_lifecycle.py +35 -0
- grafeo_memory-0.3.0/tests/test_core/test_properties.py +66 -0
- grafeo_memory-0.3.0/tests/test_core/test_recon_temporal.py +276 -0
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_core}/test_reconciler.py +4 -4
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_core}/test_reranker.py +2 -2
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_core}/test_scoring.py +4 -4
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_core}/test_stats.py +1 -1
- grafeo_memory-0.3.0/tests/test_core/test_taxonomy.py +170 -0
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_core}/test_temporal.py +2 -7
- grafeo_memory-0.3.0/tests/test_core/test_time_travel.py +186 -0
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_core}/test_topology_scoring.py +8 -8
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_core}/test_types.py +33 -0
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_core}/test_vision.py +1 -1
- grafeo_memory-0.3.0/tests/test_providers/__init__.py +0 -0
- grafeo_memory-0.3.0/tests/test_providers/test_decisions.py +730 -0
- grafeo_memory-0.3.0/tests/test_providers/test_jev.py +149 -0
- grafeo_memory-0.3.0/tests/test_providers/test_retry.py +59 -0
- grafeo_memory-0.3.0/tests/test_services/__init__.py +0 -0
- grafeo_memory-0.3.0/tests/test_services/test_agent_framework.py +310 -0
- grafeo_memory-0.3.0/tests/test_services/test_bug_regressions.py +443 -0
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_services}/test_cli.py +24 -3
- grafeo_memory-0.3.0/tests/test_services/test_cli_integration.py +87 -0
- grafeo_memory-0.3.0/tests/test_services/test_compile.py +151 -0
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_services}/test_coverage_gaps.py +5 -5
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_services}/test_db_injection.py +2 -2
- grafeo_memory-0.3.0/tests/test_services/test_delete_cascade.py +258 -0
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_services}/test_episodes.py +1 -4
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_services}/test_graph_name.py +1 -1
- grafeo_memory-0.3.0/tests/test_services/test_history.py +220 -0
- grafeo_memory-0.3.0/tests/test_services/test_history_durability.py +218 -0
- grafeo_memory-0.3.0/tests/test_services/test_layers.py +533 -0
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_services}/test_manager.py +67 -19
- grafeo_memory-0.3.0/tests/test_services/test_mcp_integration.py +202 -0
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_services}/test_mcp_tools.py +28 -2
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_services}/test_new_features.py +52 -48
- grafeo_memory-0.3.0/tests/test_services/test_review_core.py +118 -0
- grafeo_memory-0.3.0/tests/test_services/test_upgrade_from_05.py +241 -0
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_services}/test_usage.py +2 -2
- grafeo_memory-0.3.0/uv.lock +2286 -0
- grafeo_memory-0.2.2/PKG-INFO +0 -387
- grafeo_memory-0.2.2/README.md +0 -349
- grafeo_memory-0.2.2/coverage.xml +0 -1741
- grafeo_memory-0.2.2/src/grafeo_memory/__init__.py +0 -99
- grafeo_memory-0.2.2/src/grafeo_memory/extraction/__init__.py +0 -16
- grafeo_memory-0.2.2/src/grafeo_memory/history.py +0 -139
- grafeo_memory-0.2.2/src/grafeo_memory/mcp/__init__.py +0 -5
- grafeo_memory-0.2.2/src/grafeo_memory/mcp/server.py +0 -94
- grafeo_memory-0.2.2/src/grafeo_memory/reconciliation/__init__.py +0 -11
- grafeo_memory-0.2.2/src/grafeo_memory/reconciliation/memories.py +0 -119
- grafeo_memory-0.2.2/src/grafeo_memory/reconciliation/relations.py +0 -73
- grafeo_memory-0.2.2/src/grafeo_memory/search/__init__.py +0 -6
- grafeo_memory-0.2.2/src/grafeo_memory/types.py +0 -389
- grafeo_memory-0.2.2/tests/test_history.py +0 -140
- grafeo_memory-0.2.2/uv.lock +0 -1772
- {grafeo_memory-0.2.2 → grafeo_memory-0.3.0}/CONTRIBUTING.md +0 -0
- {grafeo_memory-0.2.2 → grafeo_memory-0.3.0}/LICENCE +0 -0
- {grafeo_memory-0.2.2 → grafeo_memory-0.3.0}/examples/quickstart.py +0 -0
- {grafeo_memory-0.2.2/src → grafeo_memory-0.3.0}/grafeo_memory/__main__.py +0 -0
- {grafeo_memory-0.2.2/src/grafeo_memory → grafeo_memory-0.3.0/grafeo_memory/common}/schemas.py +0 -0
- {grafeo_memory-0.2.2/src/grafeo_memory → grafeo_memory-0.3.0/grafeo_memory/core}/messages.py +0 -0
- {grafeo_memory-0.2.2/src/grafeo_memory → grafeo_memory-0.3.0/grafeo_memory/core}/prompts.py +0 -0
- {grafeo_memory-0.2.2/src/grafeo_memory → grafeo_memory-0.3.0/grafeo_memory/core}/temporal.py +0 -0
- {grafeo_memory-0.2.2/src → grafeo_memory-0.3.0}/grafeo_memory/mcp/prompts.py +0 -0
- {grafeo_memory-0.2.2 → grafeo_memory-0.3.0}/tests/__init__.py +0 -0
- {grafeo_memory-0.2.2 → grafeo_memory-0.3.0}/tests/conftest.py +0 -0
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_common}/test_config_validation.py +0 -0
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_core}/test_multi_session.py +0 -0
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_core}/test_search_quality.py +0 -0
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_core}/test_temporal_integration.py +0 -0
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_services}/test_concurrency.py +0 -0
- {grafeo_memory-0.2.2/tests → grafeo_memory-0.3.0/tests/test_services}/test_error_surfacing.py +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# grafeo-memory
|
|
1
|
+
# grafeo-memory: environment variables
|
|
2
2
|
#
|
|
3
3
|
# Copy this file to .env and fill in the keys for your provider(s).
|
|
4
4
|
# Only the provider you use needs to be set.
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
# ── grafeo-memory config ────────────────────────────────────────────
|
|
11
11
|
# GRAFEO_MEMORY_MODEL=mistral:mistral-small-latest
|
|
12
|
-
# GRAFEO_MEMORY_DB=./memory.
|
|
12
|
+
# GRAFEO_MEMORY_DB=./memory.grafeo
|
|
13
13
|
# GRAFEO_MEMORY_USER=default
|
|
14
14
|
|
|
15
15
|
# ── LLM Providers (pydantic-ai) ─────────────────────────────────────
|
|
@@ -60,3 +60,19 @@ OPENROUTER_API_KEY=
|
|
|
60
60
|
|
|
61
61
|
# Mistral embeddings (used automatically when model is mistral:*)
|
|
62
62
|
# MISTRAL_API_KEY= (same key as above)
|
|
63
|
+
|
|
64
|
+
# ── LLM call cache (in-memory LRU + optional JSONL persistence) ──────────
|
|
65
|
+
# GRAFEO_MEMORY_CACHE_ENABLED=true
|
|
66
|
+
# GRAFEO_MEMORY_CACHE_MAX_ENTRIES=10000
|
|
67
|
+
# GRAFEO_MEMORY_CACHE_MAX_MEMORY_MB=128 # in-memory hot cache cap
|
|
68
|
+
# GRAFEO_MEMORY_CACHE_MAX_STORAGE_MB=512 # JSONL persistence file cap
|
|
69
|
+
# GRAFEO_MEMORY_CACHE_PERSIST_PATH=./memory.grafeo.llmcache.jsonl # default: <db>.llmcache.jsonl
|
|
70
|
+
|
|
71
|
+
# ── GrafeoDB engine limits (MB; unset = grafeo's detected machine default) ──
|
|
72
|
+
# GRAFEO_MEMORY_DB_MEMORY_LIMIT_MB=2048 # enforced per write; cold chunks spill
|
|
73
|
+
# GRAFEO_MEMORY_DB_SPILL_LIMIT_MB=4096 # on-disk spill/WAL cap
|
|
74
|
+
|
|
75
|
+
# ── Decision models (Typesafe Jev / System One) ─────────────────────────
|
|
76
|
+
# TYPESAFE_API_KEY=<template>
|
|
77
|
+
# GRAFEO_MEMORY_DECISION_MODEL=jev # registered name or entry point; unset = LLM-only pipeline
|
|
78
|
+
# GRAFEO_MEMORY_JEV_MODEL=jev-latest # Jev model version
|
|
@@ -10,8 +10,8 @@ jobs:
|
|
|
10
10
|
lint:
|
|
11
11
|
runs-on: ubuntu-latest
|
|
12
12
|
steps:
|
|
13
|
-
- uses: actions/checkout@
|
|
14
|
-
- uses: astral-sh/setup-uv@
|
|
13
|
+
- uses: actions/checkout@v7
|
|
14
|
+
- uses: astral-sh/setup-uv@v10.3.0
|
|
15
15
|
- run: uv sync
|
|
16
16
|
- run: uv run ruff check .
|
|
17
17
|
- run: uv run ruff format --check .
|
|
@@ -19,20 +19,20 @@ jobs:
|
|
|
19
19
|
typecheck:
|
|
20
20
|
runs-on: ubuntu-latest
|
|
21
21
|
steps:
|
|
22
|
-
- uses: actions/checkout@
|
|
23
|
-
- uses: astral-sh/setup-uv@
|
|
24
|
-
- run: uv sync
|
|
25
|
-
- run: uv run ty check
|
|
22
|
+
- uses: actions/checkout@v7
|
|
23
|
+
- uses: astral-sh/setup-uv@v10.3.0
|
|
24
|
+
- run: uv sync --all-extras # optional imports (mcp, httpx, openai, ...) must resolve
|
|
25
|
+
- run: uv run ty check
|
|
26
26
|
|
|
27
27
|
test:
|
|
28
28
|
runs-on: ${{ matrix.os }}
|
|
29
29
|
strategy:
|
|
30
30
|
matrix:
|
|
31
31
|
os: [ubuntu-latest, windows-latest]
|
|
32
|
-
python-version: ["3.12", "3.13", "3.14"]
|
|
32
|
+
python-version: ["3.12", "3.13", "3.14", "3.15"]
|
|
33
33
|
steps:
|
|
34
|
-
- uses: actions/checkout@
|
|
35
|
-
- uses: astral-sh/setup-uv@
|
|
34
|
+
- uses: actions/checkout@v7
|
|
35
|
+
- uses: astral-sh/setup-uv@v10.3.0
|
|
36
36
|
with:
|
|
37
37
|
python-version: ${{ matrix.python-version }}
|
|
38
38
|
- run: uv sync --all-extras
|
|
@@ -42,13 +42,13 @@ jobs:
|
|
|
42
42
|
name: Code Coverage
|
|
43
43
|
runs-on: ubuntu-latest
|
|
44
44
|
steps:
|
|
45
|
-
- uses: actions/checkout@
|
|
46
|
-
- uses: astral-sh/setup-uv@
|
|
45
|
+
- uses: actions/checkout@v7
|
|
46
|
+
- uses: astral-sh/setup-uv@v10.3.0
|
|
47
47
|
- run: uv sync --all-extras
|
|
48
48
|
- name: Generate coverage report
|
|
49
49
|
run: uv run pytest --cov=grafeo_memory --cov-report=xml:coverage.xml
|
|
50
50
|
- name: Upload coverage to Codecov
|
|
51
|
-
uses: codecov/codecov-action@
|
|
51
|
+
uses: codecov/codecov-action@v7
|
|
52
52
|
with:
|
|
53
53
|
token: ${{ secrets.CODECOV_TOKEN }}
|
|
54
54
|
files: coverage.xml
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
name: Engine compatibility
|
|
2
|
+
|
|
3
|
+
# Runs the suite against the newest grafeo releases on PyPI, pre-releases
|
|
4
|
+
# included, so an engine change that breaks grafeo-memory shows up before
|
|
5
|
+
# users hit it. tests/test_core/test_grafeo_contract.py names the engine behavior that
|
|
6
|
+
# changed.
|
|
7
|
+
#
|
|
8
|
+
# - within-pin: the newest grafeo that the requirement in pyproject.toml accepts
|
|
9
|
+
# - newest: the newest grafeo on PyPI, ignoring that requirement (early
|
|
10
|
+
# warning for the next minor release)
|
|
11
|
+
#
|
|
12
|
+
# Only grafeo moves: every other package stays at its locked version.
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
schedule:
|
|
16
|
+
- cron: "0 5 * * 1" # Mondays, 05:00 UTC
|
|
17
|
+
workflow_dispatch:
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
test:
|
|
21
|
+
name: grafeo ${{ matrix.grafeo }} (${{ matrix.os }})
|
|
22
|
+
runs-on: ${{ matrix.os }}
|
|
23
|
+
strategy:
|
|
24
|
+
fail-fast: false
|
|
25
|
+
matrix:
|
|
26
|
+
os: [ubuntu-latest, windows-latest]
|
|
27
|
+
grafeo: [within-pin, newest]
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/checkout@v7
|
|
30
|
+
- uses: astral-sh/setup-uv@v10.3.0
|
|
31
|
+
with:
|
|
32
|
+
python-version: "3.13"
|
|
33
|
+
- run: uv sync --all-extras --no-sources
|
|
34
|
+
- name: Newest grafeo the requirement accepts
|
|
35
|
+
if: matrix.grafeo == 'within-pin'
|
|
36
|
+
run: uv pip install --no-sources -r pyproject.toml --upgrade-package grafeo --prerelease allow
|
|
37
|
+
- name: Newest grafeo on PyPI
|
|
38
|
+
if: matrix.grafeo == 'newest'
|
|
39
|
+
run: uv pip install --upgrade --prerelease allow grafeo
|
|
40
|
+
- name: Engine under test
|
|
41
|
+
run: uv run --no-sync python -c "import grafeo; print(grafeo.__version__, grafeo.build_info())"
|
|
42
|
+
- name: Engine contract
|
|
43
|
+
run: uv run --no-sync pytest tests/test_core/test_grafeo_contract.py -v --no-cov
|
|
44
|
+
- name: Full suite
|
|
45
|
+
run: uv run --no-sync pytest -v
|
|
@@ -11,10 +11,10 @@ jobs:
|
|
|
11
11
|
build:
|
|
12
12
|
runs-on: ubuntu-latest
|
|
13
13
|
steps:
|
|
14
|
-
- uses: actions/checkout@
|
|
15
|
-
- uses: astral-sh/setup-uv@
|
|
14
|
+
- uses: actions/checkout@v7
|
|
15
|
+
- uses: astral-sh/setup-uv@v10.3.0
|
|
16
16
|
- run: uv build
|
|
17
|
-
- uses: actions/upload-artifact@
|
|
17
|
+
- uses: actions/upload-artifact@v7
|
|
18
18
|
with:
|
|
19
19
|
name: dist
|
|
20
20
|
path: dist/
|
|
@@ -24,7 +24,7 @@ jobs:
|
|
|
24
24
|
runs-on: ubuntu-latest
|
|
25
25
|
environment: pypi
|
|
26
26
|
steps:
|
|
27
|
-
- uses: actions/download-artifact@
|
|
27
|
+
- uses: actions/download-artifact@v8
|
|
28
28
|
with:
|
|
29
29
|
name: dist
|
|
30
30
|
path: dist/
|
|
@@ -32,8 +32,33 @@ venv/
|
|
|
32
32
|
# ── Testing & coverage ───────────────────────────────────────────────
|
|
33
33
|
.pytest_cache/
|
|
34
34
|
.coverage
|
|
35
|
+
coverage.xml
|
|
35
36
|
htmlcov/
|
|
36
37
|
*.log
|
|
37
38
|
|
|
38
39
|
# ── Database files (don't commit user data) ──────────────────────────
|
|
39
40
|
*.db
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# benchmark run data and LLM caches (large, regenerable)
|
|
44
|
+
.benchmarks/beam_runs/
|
|
45
|
+
.benchmarks/beam_data/
|
|
46
|
+
.benchmarks/lme_runs/
|
|
47
|
+
.benchmarks/lme_data/
|
|
48
|
+
.benchmarks/locomo_runs/
|
|
49
|
+
.benchmarks/locomo_data/
|
|
50
|
+
*.llmcache.jsonl
|
|
51
|
+
*.grafeo
|
|
52
|
+
*.grafeo.wal/
|
|
53
|
+
# left by the 0.6 upgrade (full copies of the old database) and by queries that spill to disk
|
|
54
|
+
*.grafeo.pre-0.6
|
|
55
|
+
*.grafeo.pre-0.6.wal/
|
|
56
|
+
*.db.pre-0.6/
|
|
57
|
+
*.grafeo.spill/
|
|
58
|
+
|
|
59
|
+
# Claude Code project context (internal)
|
|
60
|
+
.claude/
|
|
61
|
+
|
|
62
|
+
# grafeo 0.5 databases the upgrade tests open (tests/fixtures/grafeo_0_5/make_fixtures.py); after *.grafeo so they win
|
|
63
|
+
!tests/fixtures/grafeo_0_5/*/memory_wal/wal/*.log
|
|
64
|
+
!tests/fixtures/grafeo_0_5/*/memory.grafeo
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Pre-commit hooks for grafeo-memory
|
|
2
|
+
# Install: cargo install prek && prek install
|
|
3
|
+
# Run manually: prek run --all-files
|
|
4
|
+
# Docs: https://github.com/j178/prek
|
|
5
|
+
|
|
6
|
+
repos:
|
|
7
|
+
# Built-in prek hooks
|
|
8
|
+
- repo: builtin
|
|
9
|
+
hooks:
|
|
10
|
+
# Markdown is prose; never rewrite it mechanically
|
|
11
|
+
- id: trailing-whitespace
|
|
12
|
+
exclude: '\.md$'
|
|
13
|
+
- id: end-of-file-fixer
|
|
14
|
+
exclude: '\.md$'
|
|
15
|
+
- id: check-yaml
|
|
16
|
+
- id: check-toml
|
|
17
|
+
- id: check-merge-conflict
|
|
18
|
+
- id: check-added-large-files
|
|
19
|
+
args: ['--maxkb=1000']
|
|
20
|
+
|
|
21
|
+
# Typo checker
|
|
22
|
+
- repo: https://github.com/crate-ci/typos
|
|
23
|
+
rev: v1.29.4
|
|
24
|
+
hooks:
|
|
25
|
+
- id: typos
|
|
26
|
+
|
|
27
|
+
# Python hooks
|
|
28
|
+
- repo: local
|
|
29
|
+
hooks:
|
|
30
|
+
- id: ruff-check
|
|
31
|
+
name: ruff check
|
|
32
|
+
entry: uv run ruff check --fix --exit-non-zero-on-fix
|
|
33
|
+
language: system
|
|
34
|
+
types: [python]
|
|
35
|
+
|
|
36
|
+
- id: ruff-format
|
|
37
|
+
name: ruff format
|
|
38
|
+
entry: uv run ruff format
|
|
39
|
+
language: system
|
|
40
|
+
types: [python]
|
|
41
|
+
|
|
42
|
+
- id: ty-check
|
|
43
|
+
name: ty check
|
|
44
|
+
entry: uv run ty check .
|
|
45
|
+
language: system
|
|
46
|
+
pass_filenames: false
|
|
47
|
+
types: [python]
|
|
@@ -1,9 +1,113 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
All notable changes to grafeo-memory
|
|
3
|
+
All notable changes to grafeo-memory, an embedded AI memory layer on GrafeoDB.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
## [0.3.0] - 2026-11-12
|
|
6
|
+
|
|
7
|
+
Engine and architecture release: grafeo-memory runs on grafeo 0.6.2, its modules move into layers, and each reconciliation stage can run on the LLM, a decision model, or both. Before upgrading: the first open of a grafeo 0.5 database migrates it one way (the old copy stays as `<path>.pre-0.6`), every `db_path` is a single file, and pre-0.3 module paths still import but warn until 0.7. Every new toggle and layer is off by default, which keeps the 0.2 pipeline; the release also carries 0.2.3, which never shipped on its own.
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **Decision engines per pipeline stage**: `MemoryConfig.pipeline` (`PipelineConfig`, `StageConfig`) runs the `memories`, `relations` and `search` stages on `Engine.LLM` (default), `Engine.DECISION` or `Engine.HYBRID`, with the model named by `MemoryConfig.decision_model` (`"jev"`, `"fake"` or an entry point in `grafeo_memory.decision_models`). `HYBRID` asks the decision model first and sends the facts (for relations, the KEEP/DELETE verdicts) below `confidence_threshold` to one LLM call; the extraction stages stay on the LLM, and another engine there raises `ValueError`.
|
|
12
|
+
- **Jev decision model** (extra `jev`): `JevDecisionModel` calls TypeSafe's hosted System One API with `TYPESAFE_API_KEY`. It sends the reconciliation state (new facts and their candidate memories) to TypeSafe; the default pipeline sends nothing there.
|
|
13
|
+
- **Decision-model protocol**: `DecisionModel`, `CategoricalQuestion`, `ScoreQuestion`, `Decision`, `register_decision_model()`, `get_decision_model()` and the offline `FakeDecisionModel` are exported, with per-fact and pairwise question packs (`Granularity`) and three escalation signals (`EscalationSignal`).
|
|
14
|
+
- **Temporal pre-check** (`PipelineConfig.temporal_precheck`): a new fact whose validity interval overlaps no candidate memory is added without a model call, and the other facts reconcile against their overlapping candidates only. Only stated validity counts ("since 2019" has no end, "until 2022", "2020-2022", "in 2024", "on 7 May 2023", ISO dates); a fact without one, or a bare number such as "2048 followers", always reaches the engine.
|
|
15
|
+
- **Ontology normalization** (`PipelineConfig.ontology`): before graph writes, extracted entity names resolve to existing entities of the same type by exact label or alias (relations follow the rename), and a relation of a controlled type whose endpoint types break its domain or range is not written. Types match case-insensitively (`person`, `works at`). Free-text relation types and unknown entity types pass unchanged.
|
|
16
|
+
- **`compile()`** on `MemoryManager` and `AsyncMemoryManager` (also `acompile()`): an offline pass that merges entities of the same type and `graph_name` scope whose names embed at cosine 0.92 or more into the older node, moving their edges with their properties and keeping the merged name in `merged_from` (so `ontology` resolves it later), and reports relations that break the controlled vocabulary. It makes no LLM call, and the manager never runs it on its own.
|
|
17
|
+
- **Layer toggles on `PipelineConfig`**: `bitemporal` and `episodes` mirror `MemoryConfig.enable_bitemporal` and `enable_episodes`, `compile` is read by the benchmark harnesses, and `taxonomy`, `policy` and `bucket` switch on the layers below.
|
|
18
|
+
- **Open-decisions bucket** (`MemoryConfig.bucket`, `BucketConfig`): a decision-model answer below `floor` (default 0.5) is parked instead of applied or escalated. The fact is stored with `provisional=True`, the contested memory stays, and `list_open_decisions()` / `resolve_open_decision(id, answer)` let a person settle it; a later write touching the evidence, or `compile()`, re-judges it, and entries past `ttl_days` or beyond `max_open` expire to `unknown`.
|
|
19
|
+
- **Policy rule packs** (`MemoryConfig.policy`, `PolicyConfig`): `compliance` keeps credentials and card, IBAN and SSN numbers out of the store, `temporal` turns on the pre-check, `entrenchment` stops inferred decisions from overwriting certified or user-stated memories, and `lifecycle` certifies a memory after `compilation.promote_after` re-statements and applies `retention_days`. Each event carries the rung that decided it (`MemoryEvent.rung`), and `stats().layers` reports rule hits and the deterministic share.
|
|
20
|
+
- **Subject and instance scopes** (`MemoryConfig.taxonomy`, `TaxonomyConfig`): new memories get subject tags from ten designed roots, entities linked to enough memories become scopes, and searches boost (`mode="soft"`) or keep only (`"filter"`) the memories in the scopes a query routes to. `search(subjects=, scopes=)` and `add(scopes=)` pin scopes, `hard_roots` wall a root off, `scopes()` and `set_root_scheme()` show and edit the roots (retiring one never deletes memories), and `compile()` grows generated children.
|
|
21
|
+
- **Retrieval knobs** (`MemoryConfig.retrieval`, `RetrievalConfig`): `order="deterministic"` boosts and pulls in the memories of the entities a query names and their relation neighbours (`expansion_depth`), skipping hub entities such as conversation speakers that sit on more than `hub_share` of the memories, `temporal_filter` favors memories whose stated interval overlaps the query's, and `certified_boost` ranks certified memories higher.
|
|
22
|
+
- **Ontology knobs** (`MemoryConfig.ontology`, `OntologyConfig`): write-time embedding match of entity names, one decision-model question for the ambiguous rest (`rung4`), and `interval_closing`, which ends a superseded fact's validity at the new fact's stated start.
|
|
23
|
+
- **Working, procedural and episodic tiers** (`MemoryConfig.tiers`, `TiersConfig`): `assemble(query, session_id, budget)` returns a `ContextBlock` with the session window, instructions, facts and events within a token budget, each line with its provenance; `end_session()` promotes a session (with `defer_extraction`, `add()` only buffers and extraction runs once per session); `add_instruction()` stores certified procedural memories and `auto_triggers` picks up instruction turns.
|
|
24
|
+
- **Certification and compile**: `certify(memory_id)` marks a memory certified; `compile()` also returns merge proposals (cosine 0.85 to 0.92, open decisions when the bucket is on), and runs every `compilation.every_n_adds` adds when set.
|
|
25
|
+
- **MCP tools** `memory_open_decisions`, `memory_resolve_decision`, `memory_manage_roots`, `memory_assemble` and `memory_add_instruction`.
|
|
26
|
+
- **Store schema version**: a store that uses a layer records `schema_version` 2 and runs pending migrations on open; a store that never turns a layer on is left unchanged.
|
|
27
|
+
- **Benchmark overrides**: the harnesses take `--set KEY=VALUE` for any `MemoryConfig` field by dotted path (`--set bucket.floor=0.4`), and `matrix` has rounds 14 to 19, one per layer, and round 20 with the read-path knobs at `k=20`.
|
|
28
|
+
- **LLM call cache** (`MemoryConfig.cache`, `True` or `CacheConfig`): LLM, embedding and decision-model calls are answered from an in-memory LRU and, for a file database, from `<db_path>.llmcache.jsonl`, so an identical call reaches the provider once. Off by default; `cached_model()`, `cached_embedder()` and `MemoryCache` wrap a model or embedder directly, and `MemoryCache.clear()` removes the entries and the file.
|
|
29
|
+
- **Settings from the environment**: `GrafeoMemorySettings` reads `GRAFEO_MEMORY_*` variables and `.env` for the CLI and MCP server (model, database, user, cache, engine limits, decision model), and provider keys as secrets that are never logged. An empty variable counts as unset. The CLI and MCP server log to stderr at `GRAFEO_MEMORY_LOG_LEVEL` (default `WARNING`) with secret values redacted; `grafeo_memory.common.install_redaction()` adds the same filter to an application's handlers.
|
|
30
|
+
- **Transient LLM errors are retried**: timeouts, connection errors, 429 and 5xx from the LLM provider are retried with exponential backoff (`MemoryConfig.llm_retries`, default 3; `0` disables). A dropped connection used to fail the step silently, so entity extraction stored a fact without its entities.
|
|
31
|
+
- **Engine memory limits**: `MemoryConfig.db_memory_limit_bytes` and `db_spill_limit_bytes` (`GRAFEO_MEMORY_DB_MEMORY_LIMIT_MB`, `GRAFEO_MEMORY_DB_SPILL_LIMIT_MB`) are passed to grafeo when the manager opens its database.
|
|
32
|
+
- **Time travel** (grafeo 0.6.2 history retention): `MemoryConfig.history_retention` (`"off"`, `"forever"`, a `timedelta` or seconds) is passed when the manager opens its database, and a database file keeps it. `as_of(point)`, `execute_as_of(query, point, params)` and `get_memory_as_of(memory_id, point)` on both managers read the database, a query or a memory as it was at an epoch, an aware datetime or a `timedelta` ago (`None` when the memory did not exist yet).
|
|
33
|
+
- **Microsoft Agent Framework** (extra `agent-framework`): `grafeo_memory.agent_framework.GrafeoVectorStore` adapts a manager's database to the framework's `BaseVectorStore`, so its collection CRUD, search and agent tools (`create_upsert_tool`, `create_vector_search_tool`) store and find memories in grafeo. `eq` filters become grafeo's exact-match `filters=`; other operators raise `NotImplementedError`.
|
|
34
|
+
- **Benchmark harnesses** (extra `bench`): `python -m grafeo_memory.bench.locomo_eval`, `lme_eval`, `beam_eval` and `matrix` run LOCOMO, LongMemEval and BEAM with every engine and toggle as a flag and a shared call cache. See `docs/benchmarks.md`.
|
|
35
|
+
- **Python 3.15**: CI tests Python 3.12 to 3.15, and the package lists them in its classifiers.
|
|
36
|
+
- **Upgrade tests** (`tests/test_services/test_upgrade_from_05.py`): databases written on grafeo 0.5.44 by grafeo-memory 0.2.2 and 0.2.3, as a `.grafeo` file and as a WAL directory, open through the manager, the CLI and the MCP server, migrate once and keep every memory, embedding, history entry, entity, relation, graph metric and community. Vector search finds every memory and later writes persist.
|
|
37
|
+
- **Engine contract tests for grafeo 0.6**: floats stay floats, `hybrid_search(filters=...)` filters before ranking, non-finite vectors are refused, a path without extension is one file, an empty directory is refused, `detach_delete_node()` exists, and the 0.6.2 type rules hold (a string never equals a number, wrong-kind operands raise, procedure arguments are validated, lists with a null compare as unknown).
|
|
38
|
+
- Tests: 641 to 1071, with a regression test for each fix and end-to-end tests per layer.
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
|
|
42
|
+
Upgrade notes first: what breaks or behaves differently from 0.2.x.
|
|
43
|
+
|
|
44
|
+
- **The first open of a grafeo 0.5 database migrates it**: a `MemoryManager`, the CLI or the MCP server converts it at the same path and keeps the old file or WAL directory, unchanged, as `<path>.pre-0.6`; grafeo 0.5 cannot open the result. Stop every process that uses the database first and keep the `.pre-0.6` copy until going back is ruled out (README, "Upgrading Grafeo (0.5 to 0.6)"); for grafeo 0.5, stay on grafeo-memory 0.2.x.
|
|
45
|
+
- **Every `db_path` is a database file**: a path without the `.grafeo` extension no longer creates a WAL directory, and opening a directory that is not a grafeo 0.5 database (an empty one included) raises `GrafeoError`. Point `db_path`, `--db` or `GRAFEO_MEMORY_DB` at a file such as `./memories/memory.grafeo`.
|
|
46
|
+
- **Embeddings with NaN or infinite values raise `ValueError`** before anything is written: grafeo 0.5 stored such a vector and vector search never found it, grafeo 0.6 refuses it. Check the embedder if `add()`, `update()` or `search()` raises "the embedder must return finite floats".
|
|
47
|
+
- **Modules live in layers**: the source moved from `src/grafeo_memory/` to `grafeo_memory/` with `common/`, `providers/`, `core/`, `services/` and the entry points `cli/`, `mcp/` and `agent_framework.py`; lint and a test enforce the import order. `from grafeo_memory import ...` is unchanged (see Deprecated for the old module paths).
|
|
48
|
+
- **Relation reconciliation sees at most 50 candidates**: the existing relations shown to the LLM are those sharing an entity with a new relation (only those can conflict), ranked same source and relation type first, then same target and type or the same two entities, then the rest, newest first within a rank. 0.2.x showed every relation of the user, a prompt that grew without bound.
|
|
49
|
+
- **Numbers keep their type**: scores, similarities, importance and PageRank and betweenness values stay `float`, and timestamps `int`. grafeo 0.6 reads a GQL literal such as `0.5` as an exact decimal, so grafeo-memory writes such values only as parameters or through the direct API.
|
|
50
|
+
- **Deletes use `db.detach_delete_node()`** when the engine has it (grafeo 0.6.0), and a `DETACH DELETE` query otherwise.
|
|
51
|
+
- **Checked and kept on grafeo 0.6**: embeddings are converted to floats (a list of ints is still stored as a plain list and left out of vector search), and history stays in `:History` nodes (change data capture is still off by default and kept in memory only).
|
|
52
|
+
- **More LOCOMO questions answered**: on conversations 0 to 2 (385 questions, Mistral Small 4 for extraction, answers and judge, `k=100`) the default pipeline scores 0.9013 against 0.8727 for 0.2.2 under the same prompts. On all 10 conversations it scores 0.8753 (`docs/benchmarks.md`).
|
|
53
|
+
- **README**: new sections on decision engines and pipeline toggles (including what leaves the device), the call cache and the module layout; Persistence and "Upgrading Grafeo (0.5 to 0.6)" describe what grafeo 0.6 does with files, directories and 0.5 databases.
|
|
54
|
+
- **CI**: the type check installs the optional extras, so optional imports resolve; coverage leaves out the benchmark harnesses (they need datasets and API keys). `actions/checkout@v7`, `astral-sh/setup-uv@v10.3.0` (setup-uv no longer publishes major tags), `actions/upload-artifact@v7`, `actions/download-artifact@v8`, `codecov/codecov-action@v7`; `ty check` runs with the configured excludes.
|
|
55
|
+
|
|
56
|
+
### Deprecated
|
|
57
|
+
|
|
58
|
+
- **Pre-0.3 module paths**: `grafeo_memory.manager`, `.types`, `.schemas`, `.embedding`, `.history`, `.messages`, `.prompts`, `.protocol`, `.reranker`, `.scoring`, `.vision`, `.communities`, `.temporal`, `.extraction.*`, `.reconciliation.*`, `.search.*`, `._compat`, `._graph` and `._tracing` resolve to the modules at their new homes and raise `DeprecationWarning` naming the new path. They are removed in 0.7.
|
|
59
|
+
|
|
60
|
+
### Fixed
|
|
61
|
+
|
|
62
|
+
- **Searches in a shared database could miss a user's memories**: the default hybrid search let the engine pick the best `k` memories of all users and filtered by `user_id`, `agent_id`, `run_id`, `graph_name` and `filters` afterwards, so other users' memories could take every slot. The scope filters now go to grafeo 0.6's `hybrid_search(filters=...)`, which filters before it ranks.
|
|
63
|
+
- **A refused embedding left a memory without one**: the memory node was created before its embedding was checked and set, so a wrong-sized or non-finite embedding left a memory that vector search never finds, and `update()` changed the text before re-embedding it. The embedding is now checked before anything is written.
|
|
64
|
+
- **Mistral embeddings with mistralai 2 and later**: the CLI and the MCP server imported `from mistralai import Mistral`, which mistralai 2 moved to `mistralai.client`, and exited with "mistralai package not installed". `grafeo_memory.providers.embedding.mistral_client_class()` finds the client in either layout; the README and examples import it from `mistralai.client`.
|
|
65
|
+
- **Type of `search()`**: overloads on `grouped` give `SearchResponse` (and `dict[str, list[SearchResult]]` with `grouped=True`) instead of a union, so type checkers accept iterating the results.
|
|
66
|
+
|
|
67
|
+
### Dependencies
|
|
68
|
+
|
|
69
|
+
- **grafeo 0.6.2** (`grafeo>=0.6.2,<0.7`; 0.2.3 required `>=0.5.44,<0.6`).
|
|
70
|
+
- **pydantic-ai-slim 1.96 or later** (`>=1.96`, was unversioned): grafeo-memory reads `AgentRunResult.usage` as a property, which 1.96 introduced and pydantic-ai 2 requires. pydantic-ai 2 is supported; the lock has 2.66.
|
|
71
|
+
- **pydantic-settings and python-dotenv** are new runtime dependencies (`pydantic-settings>=2.6`, `python-dotenv>=1.0`), for the settings above.
|
|
72
|
+
- **mcp 2** for the `mcp` extra (`mcp>=2.2,<3`; was `>=1.26,<2`): the server uses the mcp 2.x API (`mcp.server.mcpserver.MCPServer`, `Context[AppContext, ServerSession]`).
|
|
73
|
+
- **mistralai 2 or later** for the `mistral`, `bench` and `all` extras (`mistralai>=2`): pydantic-ai's Mistral support already required 3.1, so 1.x never resolved; the client is imported from `mistralai.client`.
|
|
74
|
+
- **New extras**: `jev` (`httpx>=0.27`), `agent-framework` (`agent-framework-core>=1.25,<2`) and `bench` (`mistralai`, `nltk`, `numpy`, `pyarrow`).
|
|
75
|
+
- **Lockfile**: openai 3.49, anthropic 2.7, mistralai 3.7, google-genai 3.0, groq 1.7; development tools pytest 9.2, ruff 0.17 and ty 0.0.100 (its renamed rules `import-not-found` and `missing-attribute` are used in `pyproject.toml`).
|
|
76
|
+
|
|
77
|
+
## [0.2.3] - Unreleased (ships in 0.3.0)
|
|
78
|
+
|
|
79
|
+
Works with grafeo 0.5.44: deletes work again, memory history is stored durably, and an engine contract suite runs weekly against the newest grafeo.
|
|
80
|
+
|
|
81
|
+
### Added
|
|
82
|
+
|
|
83
|
+
- **Engine contract tests** (`tests/test_core/test_grafeo_contract.py`, 37 tests): every grafeo behavior grafeo-memory relies on (direct API calls and their errors, query shapes and result format, `DETACH DELETE`, vector, text, hybrid and MMR search, PageRank, betweenness and Louvain output, single-file and directory persistence, CDC defaults). A failure names the behavior that changed and the code that depends on it.
|
|
84
|
+
- **Weekly engine compatibility workflow** (`.github/workflows/engine-compat.yml`, also manual): runs the contract tests and the full suite on Linux and Windows against the newest grafeo the requirement accepts and the newest grafeo on PyPI, pre-releases included.
|
|
85
|
+
- Tests for delete cascades through every edge type, history on every write path and across close and reopen (single-file and WAL-directory databases), shared databases with and without CDC, the async manager, the MCP tools and server lifespan against a real manager, and the CLI against a database file; regression tests for each fix above (540 to 641 tests).
|
|
86
|
+
|
|
87
|
+
### Changed
|
|
88
|
+
|
|
89
|
+
- **History storage**: `:History` nodes carry `memory_id`, `event`, `timestamp` (epoch ms), the texts, `actor_id`, `role`, `user_id` and `graph_name`, and have no edges, so they do not change graph algorithm scores. `record_history()` always writes and returns the node id; new `record_history_batch()` (used by `add_batch(infer=False)`) and `adopt_legacy_history()`. `get_history()` gains a `graph_name` filter, still reads the `HAS_HISTORY` entries of grafeo-memory 0.1.x, and raises database errors instead of returning an empty list. Engine CDC is not used, and the CDC setting of a database passed in with `db=` is left alone.
|
|
90
|
+
- `history()` is scoped to the manager's `graph_name`.
|
|
91
|
+
- `delete()` records a DELETE history entry; `summarize()` records it through the same path.
|
|
92
|
+
- `update()` raises `ValueError` when `memory_id` is not a memory of the manager (it used to return an UPDATE event and change nothing). The MCP `memory_update` tool returns the error, the CLI exits with status 1.
|
|
93
|
+
- `memory_id` joins the property indexes created at startup.
|
|
94
|
+
- README, docstrings and `.env.example` use single-file `.grafeo` database paths; README has new Persistence (including upgrading to grafeo 0.6) and Memory History sections.
|
|
95
|
+
- Development dependencies moved from the deprecated `[tool.uv] dev-dependencies` to `[dependency-groups]`.
|
|
96
|
+
|
|
97
|
+
### Fixed
|
|
98
|
+
|
|
99
|
+
- **Deletes failed on grafeo 0.5.44**: the engine now refuses to delete a node that still has edges, and memories almost always have some (`HAS_ENTITY`, `LEADS_TO`, `SUPERSEDES`, `DERIVED_FROM`, `PRODUCED`). `delete()`, `delete_all()` and `summarize()` raised `GrafeoError`, and dissolved communities were silently kept. Nodes are now removed with `DETACH DELETE` (new helper `_graph.detach_delete_node()`); entities, relations and episodes stay.
|
|
100
|
+
- **`history()` was always empty on grafeo 0.5.32 and later**: history was read from engine change data capture, which became opt-in in 0.5.32 and is kept in memory only (lost on close, pruned by retention, with hybrid logical clock timestamps instead of epoch milliseconds), while `record_history()` wrote nothing whenever the engine had CDC. grafeo-memory now stores every change as a `:History` node in the same database (see Changed). History survives closing and reopening the database and a hard delete of the memory.
|
|
101
|
+
- **Search results lost fields**: the vector/graph merge, `enable_topology_boost`, `enable_importance`, the cross-session boost and `LLMReranker` rebuilt `SearchResult` by hand and dropped `created_at`, `session_id`, `valid_at`, `invalid_at`, `learned_at` (and the reranker also `memory_type`). Results found by both vector and graph search then failed `time_after`/`time_before`, ignored `point_in_time`, sorted wrongly for temporal queries, and `grouped=True` put them under `"default"`.
|
|
102
|
+
- **Embeddings that were not float lists were never found**: the engine indexes a property as a vector only when every element is a float, so an embedder returning ints stored memories that vector search skipped. Embeddings are now converted to floats before they are stored or searched.
|
|
103
|
+
- **Reconciliation acted on any node id the LLM returned**: an UPDATE or DELETE whose `target_memory_id` was not one of the candidates shown to the LLM (hallucinated, injected, another user's memory or a foreign node in a shared database) expired that node. Such decisions now lose their target: UPDATE becomes ADD and DELETE is skipped, with a warning.
|
|
104
|
+
- **`delete()`, `update()` and `set_importance()` accepted any node id**: in a shared database they could delete or change foreign nodes, or memories of another `graph_name`. They now act only on `:Memory` nodes in the manager's scope.
|
|
105
|
+
- **`delete_all()` left expired memories behind**: memories superseded by reconciliation (and their text) stayed in the database. They are now deleted too.
|
|
106
|
+
- **Session and episode chains forked within one millisecond**: `LEADS_TO` and `NEXT_EPISODE` picked the previous node by `created_at` alone, so quick successive adds all linked to the same node. Ties are now broken by node id.
|
|
107
|
+
|
|
108
|
+
### Dependencies
|
|
109
|
+
|
|
110
|
+
- **grafeo 0.5.44** (`grafeo>=0.5.44,<0.6`; was `>=0.5.27`): grafeo 0.5.44 changed the direct-write API (writes to missing nodes and deletes of connected nodes raise). The upper bound keeps this release off grafeo 0.6 and its one-way file migration; grafeo-memory 0.3.0 moves to grafeo 0.6, see the [versioning policy](https://grafeo.dev/versioning/).
|
|
7
111
|
|
|
8
112
|
## [0.2.2] - 2026-04-08
|
|
9
113
|
|
|
@@ -275,7 +379,13 @@ Initial release.
|
|
|
275
379
|
- **Windows async compatibility**: persistent `asyncio.Runner` and `ProactorEventLoop` safety net for Python 3.13+
|
|
276
380
|
- 230 tests, 83% coverage
|
|
277
381
|
|
|
278
|
-
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
385
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
386
|
+
|
|
387
|
+
[0.3.0]: https://github.com/GrafeoDB/grafeo-memory/compare/v0.2.2...v0.3.0
|
|
388
|
+
[0.2.2]: https://github.com/GrafeoDB/grafeo-memory/compare/v0.2.1...v0.2.2
|
|
279
389
|
[0.2.1]: https://github.com/GrafeoDB/grafeo-memory/compare/v0.2.0...v0.2.1
|
|
280
390
|
[0.2.0]: https://github.com/GrafeoDB/grafeo-memory/compare/v0.1.5...v0.2.0
|
|
281
391
|
[0.1.5]: https://github.com/GrafeoDB/grafeo-memory/compare/v0.1.4...v0.1.5
|