superlocalmemory 3.6.22 → 3.7.0
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.
- package/CHANGELOG.md +52 -0
- package/README.md +275 -72
- package/bin/slm-npm +43 -89
- package/docs/pi-dev-integration.md +43 -0
- package/ide/configs/antigravity-mcp.json +2 -2
- package/ide/configs/chatgpt-desktop-mcp.json +1 -1
- package/ide/configs/claude-desktop-mcp.json +2 -2
- package/ide/configs/windsurf-mcp.json +2 -2
- package/ide/hooks/context-hook.js +6 -2
- package/ide/hooks/post-recall-hook.js +7 -3
- package/ide/hooks/tool-event-hook.sh +2 -1
- package/package.json +19 -10
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/_GENERATED.md +1 -1
- package/plugin/agents/slm-memory-advisor.md +1 -1
- package/plugin/requirements.txt +1 -1
- package/plugin/skills/slm-session/SKILL.md +1 -1
- package/plugin-src/rules/AGENTS.md +1 -1
- package/pyproject.toml +40 -8
- package/scripts/postinstall-interactive.js +17 -94
- package/scripts/postinstall.js +185 -258
- package/scripts/preuninstall.js +9 -50
- package/src/superlocalmemory/__init__.py +2 -2
- package/src/superlocalmemory/attribution/mathematical_dna.py +1 -1
- package/src/superlocalmemory/attribution/signer.py +34 -19
- package/src/superlocalmemory/attribution/watermark.py +1 -1
- package/src/superlocalmemory/cli/_lazy_init.py +3 -5
- package/src/superlocalmemory/cli/commands.py +490 -195
- package/src/superlocalmemory/cli/context_commands.py +5 -4
- package/src/superlocalmemory/cli/daemon.py +282 -187
- package/src/superlocalmemory/cli/db_migrate.py +3 -1
- package/src/superlocalmemory/cli/diagnostics_cmd.py +28 -0
- package/src/superlocalmemory/cli/evidence_cmd.py +103 -0
- package/src/superlocalmemory/cli/ingest_cmd.py +7 -3
- package/src/superlocalmemory/cli/main.py +128 -31
- package/src/superlocalmemory/cli/pending_store.py +54 -38
- package/src/superlocalmemory/cli/scale_engine_cmd.py +37 -0
- package/src/superlocalmemory/cli/service_installer.py +57 -52
- package/src/superlocalmemory/cli/setup_wizard.py +142 -88
- package/src/superlocalmemory/cli/version_banner.py +2 -1
- package/src/superlocalmemory/code_graph/config.py +3 -1
- package/src/superlocalmemory/core/backend_orchestrator.py +81 -21
- package/src/superlocalmemory/core/config.py +65 -20
- package/src/superlocalmemory/core/consolidation_engine.py +9 -7
- package/src/superlocalmemory/core/context_cache.py +56 -8
- package/src/superlocalmemory/core/derivation_lineage.py +246 -0
- package/src/superlocalmemory/core/embedding_worker.py +32 -20
- package/src/superlocalmemory/core/embeddings.py +54 -18
- package/src/superlocalmemory/core/engine.py +150 -104
- package/src/superlocalmemory/core/engine_ingestion.py +513 -0
- package/src/superlocalmemory/core/engine_wiring.py +2 -0
- package/src/superlocalmemory/core/evidence_bundle.py +526 -0
- package/src/superlocalmemory/core/fact_consolidator.py +5 -11
- package/src/superlocalmemory/core/graph_analyzer.py +2 -2
- package/src/superlocalmemory/core/health_monitor.py +4 -2
- package/src/superlocalmemory/core/ingestion_command.py +636 -0
- package/src/superlocalmemory/core/injection.py +69 -18
- package/src/superlocalmemory/core/lifecycle_state.py +153 -0
- package/src/superlocalmemory/core/maintenance.py +23 -22
- package/src/superlocalmemory/core/maintenance_scheduler.py +51 -35
- package/src/superlocalmemory/core/mutations.py +143 -0
- package/src/superlocalmemory/core/platform_utils.py +7 -4
- package/src/superlocalmemory/core/ram_lock.py +16 -5
- package/src/superlocalmemory/core/rate_limit.py +1 -1
- package/src/superlocalmemory/core/recall_pipeline.py +60 -101
- package/src/superlocalmemory/core/recall_worker.py +76 -59
- package/src/superlocalmemory/core/registry.py +1 -1
- package/src/superlocalmemory/core/scale_engine.py +293 -0
- package/src/superlocalmemory/core/score_contract.py +62 -0
- package/src/superlocalmemory/core/security_primitives.py +3 -1
- package/src/superlocalmemory/core/slm_disabled.py +3 -5
- package/src/superlocalmemory/core/store_pipeline.py +172 -40
- package/src/superlocalmemory/core/tier_manager.py +32 -20
- package/src/superlocalmemory/core/worker_pool.py +13 -4
- package/src/superlocalmemory/dynamics/activation_guided_quantization.py +1 -1
- package/src/superlocalmemory/dynamics/eap_scheduler.py +10 -3
- package/src/superlocalmemory/dynamics/ebbinghaus_langevin_coupling.py +1 -1
- package/src/superlocalmemory/dynamics/fisher_langevin_coupling.py +1 -1
- package/src/superlocalmemory/encoding/auto_linker.py +1 -1
- package/src/superlocalmemory/encoding/cognitive_consolidator.py +7 -16
- package/src/superlocalmemory/encoding/consolidator.py +22 -5
- package/src/superlocalmemory/encoding/fact_extractor.py +1 -1
- package/src/superlocalmemory/encoding/foresight.py +2 -0
- package/src/superlocalmemory/encoding/graph_builder.py +1 -1
- package/src/superlocalmemory/encoding/temporal_parser.py +2 -0
- package/src/superlocalmemory/evaluation/__init__.py +13 -0
- package/src/superlocalmemory/evaluation/calibration.py +308 -0
- package/src/superlocalmemory/evolution/skill_evolver.py +2 -1
- package/src/superlocalmemory/graph/cozo_backend.py +256 -23
- package/src/superlocalmemory/hooks/_outcome_common.py +21 -11
- package/src/superlocalmemory/hooks/antigravity_adapter.py +10 -31
- package/src/superlocalmemory/hooks/auto_invoker.py +25 -27
- package/src/superlocalmemory/hooks/auto_recall.py +31 -6
- package/src/superlocalmemory/hooks/auto_recall_hook.py +13 -33
- package/src/superlocalmemory/hooks/before_web_hook.py +9 -7
- package/src/superlocalmemory/hooks/claude_code_hooks.py +126 -39
- package/src/superlocalmemory/hooks/codex_assets.py +59 -0
- package/src/superlocalmemory/hooks/codex_hooks.py +186 -0
- package/src/superlocalmemory/hooks/context_payload.py +1 -1
- package/src/superlocalmemory/hooks/copilot_adapter.py +9 -24
- package/src/superlocalmemory/hooks/cursor_adapter.py +10 -32
- package/src/superlocalmemory/hooks/hook_daemon.py +4 -2
- package/src/superlocalmemory/hooks/hook_handlers.py +241 -55
- package/src/superlocalmemory/hooks/memory_protocol.py +5 -3
- package/src/superlocalmemory/hooks/post_tool_async_hook.py +4 -2
- package/src/superlocalmemory/hooks/session_registry.py +15 -8
- package/src/superlocalmemory/hooks/stop_outcome_hook.py +10 -6
- package/src/superlocalmemory/hooks/topic_shift_hook.py +42 -12
- package/src/superlocalmemory/hooks/user_prompt_hook.py +9 -14
- package/src/superlocalmemory/hooks/user_prompt_rehash_hook.py +19 -11
- package/src/superlocalmemory/infra/auth_middleware.py +38 -5
- package/src/superlocalmemory/infra/backup.py +7 -5
- package/src/superlocalmemory/infra/cloud_backup.py +18 -8
- package/src/superlocalmemory/infra/daemon_identity.py +248 -0
- package/src/superlocalmemory/infra/data_root.py +199 -0
- package/src/superlocalmemory/infra/event_bus.py +3 -1
- package/src/superlocalmemory/infra/local_diagnostics.py +327 -0
- package/src/superlocalmemory/infra/process_reaper.py +23 -0
- package/src/superlocalmemory/ingestion/adapter_manager.py +27 -9
- package/src/superlocalmemory/ingestion/base_adapter.py +25 -31
- package/src/superlocalmemory/ingestion/calendar_adapter.py +13 -4
- package/src/superlocalmemory/ingestion/credentials.py +14 -7
- package/src/superlocalmemory/ingestion/gmail_adapter.py +13 -4
- package/src/superlocalmemory/ingestion/transcript_adapter.py +7 -2
- package/src/superlocalmemory/learning/consolidation_quantization_worker.py +1 -1
- package/src/superlocalmemory/learning/ensemble.py +11 -0
- package/src/superlocalmemory/learning/entity_compiler.py +1 -1
- package/src/superlocalmemory/learning/feedback.py +1 -1
- package/src/superlocalmemory/learning/forgetting_scheduler.py +12 -7
- package/src/superlocalmemory/learning/quantization_scheduler.py +1 -1
- package/src/superlocalmemory/learning/ranker.py +4 -1
- package/src/superlocalmemory/learning/source_quality.py +1 -1
- package/src/superlocalmemory/learning/trigram_index.py +3 -2
- package/src/superlocalmemory/llm/backbone.py +13 -8
- package/src/superlocalmemory/math/ebbinghaus.py +1 -1
- package/src/superlocalmemory/math/fisher.py +1 -1
- package/src/superlocalmemory/math/fisher_quantized.py +1 -1
- package/src/superlocalmemory/math/hopfield.py +1 -1
- package/src/superlocalmemory/math/langevin.py +1 -1
- package/src/superlocalmemory/math/polar_quant.py +3 -4
- package/src/superlocalmemory/math/qjl.py +1 -1
- package/src/superlocalmemory/math/sheaf.py +1 -1
- package/src/superlocalmemory/math/turbo_quant.py +3 -2
- package/src/superlocalmemory/mcp/_daemon_proxy.py +12 -11
- package/src/superlocalmemory/mcp/_pool_adapter.py +27 -0
- package/src/superlocalmemory/mcp/http_transport.py +53 -0
- package/src/superlocalmemory/mcp/server.py +39 -13
- package/src/superlocalmemory/mcp/shared.py +69 -3
- package/src/superlocalmemory/mcp/tools_active.py +141 -31
- package/src/superlocalmemory/mcp/tools_core.py +128 -29
- package/src/superlocalmemory/mcp/tools_evolution.py +5 -7
- package/src/superlocalmemory/mcp/tools_learning.py +42 -2
- package/src/superlocalmemory/mcp/tools_mesh.py +7 -23
- package/src/superlocalmemory/mcp/tools_optimize.py +8 -1
- package/src/superlocalmemory/mcp/tools_v28.py +23 -2
- package/src/superlocalmemory/mcp/tools_v3.py +26 -1
- package/src/superlocalmemory/mcp/tools_v33.py +56 -17
- package/src/superlocalmemory/mesh/broker.py +2 -0
- package/src/superlocalmemory/mesh/remote_sync.py +50 -12
- package/src/superlocalmemory/optimize/cache/manager.py +77 -1
- package/src/superlocalmemory/optimize/cache/semantic.py +23 -3
- package/src/superlocalmemory/optimize/compress/ccr.py +4 -0
- package/src/superlocalmemory/optimize/compress/router.py +6 -1
- package/src/superlocalmemory/optimize/config/__init__.py +5 -0
- package/src/superlocalmemory/optimize/config/store.py +6 -4
- package/src/superlocalmemory/optimize/proxy/_helpers.py +15 -5
- package/src/superlocalmemory/optimize/proxy/capture.py +3 -2
- package/src/superlocalmemory/optimize/proxy/server.py +2 -2
- package/src/superlocalmemory/optimize/storage/db.py +14 -13
- package/src/superlocalmemory/retrieval/agentic.py +1 -1
- package/src/superlocalmemory/retrieval/ann_index.py +1 -1
- package/src/superlocalmemory/retrieval/bm25_channel.py +35 -11
- package/src/superlocalmemory/retrieval/bridge_discovery.py +73 -8
- package/src/superlocalmemory/retrieval/engine.py +169 -79
- package/src/superlocalmemory/retrieval/entity_channel.py +289 -67
- package/src/superlocalmemory/retrieval/forgetting_filter.py +1 -1
- package/src/superlocalmemory/retrieval/fusion.py +1 -1
- package/src/superlocalmemory/retrieval/hopfield_channel.py +118 -30
- package/src/superlocalmemory/retrieval/profile_channel.py +1 -1
- package/src/superlocalmemory/retrieval/quantization_aware_search.py +16 -10
- package/src/superlocalmemory/retrieval/reranker.py +56 -20
- package/src/superlocalmemory/retrieval/scope_policy.py +85 -0
- package/src/superlocalmemory/retrieval/semantic_channel.py +122 -14
- package/src/superlocalmemory/retrieval/spreading_activation.py +141 -25
- package/src/superlocalmemory/retrieval/strategy.py +1 -1
- package/src/superlocalmemory/retrieval/temporal_channel.py +30 -15
- package/src/superlocalmemory/retrieval/vector_store.py +1 -1
- package/src/superlocalmemory/server/api.py +10 -7
- package/src/superlocalmemory/server/bandit_loops.py +4 -2
- package/src/superlocalmemory/server/recall_serializer.py +24 -0
- package/src/superlocalmemory/server/route_mutations.py +84 -0
- package/src/superlocalmemory/server/routes/agents.py +8 -6
- package/src/superlocalmemory/server/routes/brain.py +14 -12
- package/src/superlocalmemory/server/routes/chat.py +29 -12
- package/src/superlocalmemory/server/routes/data_io.py +55 -24
- package/src/superlocalmemory/server/routes/helpers.py +29 -4
- package/src/superlocalmemory/server/routes/ingest.py +53 -36
- package/src/superlocalmemory/server/routes/memories.py +104 -43
- package/src/superlocalmemory/server/routes/mesh.py +31 -0
- package/src/superlocalmemory/server/routes/profiles.py +26 -4
- package/src/superlocalmemory/server/routes/tiers.py +43 -11
- package/src/superlocalmemory/server/routes/timeline.py +5 -1
- package/src/superlocalmemory/server/routes/v3_api.py +76 -21
- package/src/superlocalmemory/server/security_middleware.py +1 -1
- package/src/superlocalmemory/server/ui.py +6 -3
- package/src/superlocalmemory/server/unified_daemon.py +680 -293
- package/src/superlocalmemory/server/write_identity.py +147 -0
- package/src/superlocalmemory/storage/access_log.py +4 -3
- package/src/superlocalmemory/storage/database.py +118 -25
- package/src/superlocalmemory/storage/migration_runner.py +84 -1
- package/src/superlocalmemory/storage/migration_v33.py +1 -1
- package/src/superlocalmemory/storage/migrations/M002_model_state_history.py +6 -60
- package/src/superlocalmemory/storage/migrations/M018_ingestion_operations.py +120 -0
- package/src/superlocalmemory/storage/migrations/M019_derivation_lineage.py +54 -0
- package/src/superlocalmemory/storage/migrations/M020_model_state_integrity.py +52 -0
- package/src/superlocalmemory/storage/migrations/__init__.py +5 -0
- package/src/superlocalmemory/storage/models.py +16 -0
- package/src/superlocalmemory/storage/quantized_store.py +20 -3
- package/src/superlocalmemory/storage/v2_migrator.py +5 -3
- package/src/superlocalmemory/ui/favicon.svg +5 -0
- package/src/superlocalmemory/ui/index.html +1 -0
- package/src/superlocalmemory/ui/js/compliance.js +1 -1
- package/src/superlocalmemory/ui/js/core.js +49 -8
- package/src/superlocalmemory/ui/js/dashboard.js +23 -2
- package/src/superlocalmemory/ui/js/feedback.js +1 -1
- package/src/superlocalmemory/ui/js/graph-filters.js +1 -1
- package/src/superlocalmemory/ui/js/graph-ui.js +1 -1
- package/src/superlocalmemory/ui/js/lifecycle.js +1 -1
- package/src/superlocalmemory/ui/js/ng-mesh.js +15 -49
- package/src/superlocalmemory/ui/js/settings.js +4 -2
- package/src/superlocalmemory/vector/lancedb_backend.py +57 -9
- package/bin/slm +0 -59
- package/bin/slm.bat +0 -77
- package/bin/slm.cmd +0 -5
- package/ide/integrations/langchain/README.md +0 -106
- package/ide/integrations/langchain/langchain_superlocalmemory/__init__.py +0 -9
- package/ide/integrations/langchain/langchain_superlocalmemory/chat_message_history.py +0 -201
- package/ide/integrations/langchain/pyproject.toml +0 -38
- package/ide/integrations/langchain/tests/__init__.py +0 -3
- package/ide/integrations/langchain/tests/test_chat_message_history.py +0 -215
- package/ide/integrations/langchain/tests/test_security.py +0 -117
- package/ide/integrations/llamaindex/README.md +0 -81
- package/ide/integrations/llamaindex/llama_index/storage/chat_store/superlocalmemory/__init__.py +0 -9
- package/ide/integrations/llamaindex/llama_index/storage/chat_store/superlocalmemory/base.py +0 -316
- package/ide/integrations/llamaindex/pyproject.toml +0 -43
- package/ide/integrations/llamaindex/tests/__init__.py +0 -3
- package/ide/integrations/llamaindex/tests/test_chat_store.py +0 -294
- package/ide/integrations/llamaindex/tests/test_security.py +0 -241
- package/plugin-src/.mcp.json +0 -12
- package/plugin-src/agents/slm-memory-advisor.md +0 -44
- package/plugin-src/agents/slm-optimize-advisor.md +0 -38
- package/plugin-src/hooks/.gitkeep +0 -0
- package/plugin-src/hooks/hooks.json +0 -23
- package/plugin-src/manifest.json +0 -25
- package/plugin-src/requirements.txt +0 -1
- package/plugin-src/rules/CLAUDE.md.fragment +0 -44
- package/plugin-src/scripts/ensure-venv.bat +0 -122
- package/plugin-src/scripts/ensure-venv.sh +0 -105
- package/plugin-src/scripts/slm-launch +0 -15
- package/plugin-src/scripts/slm-launch.bat +0 -17
- package/plugin-src/settings.json +0 -16
- package/plugin-src/skills/slm-cache/SKILL.md +0 -140
- package/plugin-src/skills/slm-compress/SKILL.md +0 -143
- package/plugin-src/skills/slm-graph/SKILL.md +0 -300
- package/plugin-src/skills/slm-recall/SKILL.md +0 -204
- package/plugin-src/skills/slm-remember/SKILL.md +0 -194
- package/plugin-src/skills/slm-session/SKILL.md +0 -207
- package/plugin-src/skills/slm-status/SKILL.md +0 -149
- package/scripts/__tests__/build-plugin.test.mjs +0 -613
- package/scripts/_savings_math.py +0 -270
- package/scripts/build-dmg.sh +0 -417
- package/scripts/build-plugin.js +0 -742
- package/scripts/build-slm-hook.ps1 +0 -40
- package/scripts/build-slm-hook.sh +0 -45
- package/scripts/build_entry.py +0 -452
- package/scripts/ci/stage5b_gate.sh +0 -50
- package/scripts/dogfood_savings.py +0 -490
- package/scripts/generate-thumbnails.py +0 -218
- package/scripts/install-skills.ps1 +0 -4
- package/scripts/install-skills.sh +0 -5
- package/scripts/install.ps1 +0 -701
- package/scripts/install.sh +0 -1015
- package/scripts/postinstall_binary.js +0 -287
- package/scripts/prepack.js +0 -33
- package/scripts/release_manifest.py +0 -273
- package/scripts/slm-hook.spec +0 -56
- package/scripts/start-dashboard.ps1 +0 -52
- package/scripts/start-dashboard.sh +0 -41
- package/scripts/sync-wiki.ps1 +0 -127
- package/scripts/sync-wiki.sh +0 -82
- package/scripts/test-dmg.sh +0 -161
- package/scripts/test-npm-package.ps1 +0 -252
- package/scripts/test-npm-package.sh +0 -207
- package/scripts/verify-install.ps1 +0 -294
- package/scripts/verify-install.sh +0 -266
- package/scripts/verify-v27.ps1 +0 -301
- package/scripts/verify-v27.sh +0 -233
- package/src/superlocalmemory.egg-info/PKG-INFO +0 -513
- package/src/superlocalmemory.egg-info/SOURCES.txt +0 -529
- package/src/superlocalmemory.egg-info/dependency_links.txt +0 -1
- package/src/superlocalmemory.egg-info/entry_points.txt +0 -2
- package/src/superlocalmemory.egg-info/requires.txt +0 -71
- package/src/superlocalmemory.egg-info/top_level.txt +0 -1
|
@@ -18,6 +18,7 @@ Part of Qualixar | Author: Varun Pratap Bhardwaj
|
|
|
18
18
|
from __future__ import annotations
|
|
19
19
|
|
|
20
20
|
import logging
|
|
21
|
+
from pathlib import Path
|
|
21
22
|
from typing import Any
|
|
22
23
|
|
|
23
24
|
from superlocalmemory.core.config import CANONICAL_RECALL_LIMIT, SLMConfig
|
|
@@ -32,6 +33,19 @@ logger = logging.getLogger(__name__)
|
|
|
32
33
|
from superlocalmemory.core.hooks import HookRegistry
|
|
33
34
|
|
|
34
35
|
|
|
36
|
+
def _verify_ingestion_schema(memory_db: Path) -> bool:
|
|
37
|
+
"""Verify M018 using an explicitly owned SQLite connection."""
|
|
38
|
+
import sqlite3
|
|
39
|
+
|
|
40
|
+
from superlocalmemory.storage.migrations import M018_ingestion_operations
|
|
41
|
+
|
|
42
|
+
connection = sqlite3.connect(str(memory_db))
|
|
43
|
+
try:
|
|
44
|
+
return bool(M018_ingestion_operations.verify(connection))
|
|
45
|
+
finally:
|
|
46
|
+
connection.close()
|
|
47
|
+
|
|
48
|
+
|
|
35
49
|
class MemoryEngine:
|
|
36
50
|
"""Main orchestrator for the SuperLocalMemory V3 memory system.
|
|
37
51
|
|
|
@@ -170,7 +184,9 @@ class MemoryEngine:
|
|
|
170
184
|
# Previously only the daemon lifespan ran apply_deferred, so an existing
|
|
171
185
|
# pre-3.6.15 database used WITHOUT the daemon hit
|
|
172
186
|
# "table memories has no column named scope" on the first scoped write.
|
|
173
|
-
# Idempotent (skips applied migrations)
|
|
187
|
+
# Idempotent (skips applied migrations). M018 is now a hard runtime
|
|
188
|
+
# prerequisite: allowing initialization to continue without it would
|
|
189
|
+
# make every advertised write path fail after startup.
|
|
174
190
|
try:
|
|
175
191
|
from superlocalmemory.storage.migration_runner import (
|
|
176
192
|
apply_all, apply_deferred,
|
|
@@ -178,10 +194,22 @@ class MemoryEngine:
|
|
|
178
194
|
_base = self._config.base_dir
|
|
179
195
|
_learning_db = _base / "learning.db"
|
|
180
196
|
_memory_db = self._db.db_path
|
|
197
|
+
# Forward migrations extend the historical learning schema. A
|
|
198
|
+
# fresh explicit data root has no learning.db yet, so bootstrap
|
|
199
|
+
# those base tables before applying M001/M002/M009.
|
|
200
|
+
from superlocalmemory.learning.database import LearningDatabase
|
|
201
|
+
LearningDatabase(_learning_db)
|
|
181
202
|
apply_all(_learning_db, _memory_db)
|
|
182
203
|
apply_deferred(_learning_db, _memory_db)
|
|
204
|
+
if not _verify_ingestion_schema(_memory_db):
|
|
205
|
+
raise RuntimeError(
|
|
206
|
+
"required M018 canonical-ingestion schema is unavailable"
|
|
207
|
+
)
|
|
183
208
|
except Exception as exc:
|
|
184
|
-
|
|
209
|
+
raise RuntimeError(
|
|
210
|
+
"MemoryEngine initialization stopped because the required "
|
|
211
|
+
f"ingestion migration failed: {exc}"
|
|
212
|
+
) from exc
|
|
185
213
|
|
|
186
214
|
# V3.4.7: Apply "Learning Brain" schema (tool_events, behavioral_assertions)
|
|
187
215
|
try:
|
|
@@ -364,11 +392,30 @@ class MemoryEngine:
|
|
|
364
392
|
meta = {}
|
|
365
393
|
if not isinstance(meta, dict):
|
|
366
394
|
meta = {}
|
|
367
|
-
_scope = meta.
|
|
368
|
-
_shared = meta.
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
395
|
+
_scope = meta.pop("scope", None) or "personal"
|
|
396
|
+
_shared = meta.pop("shared_with", None)
|
|
397
|
+
_source_type = str(
|
|
398
|
+
meta.pop("_slm_source_type", "legacy-pending")
|
|
399
|
+
)
|
|
400
|
+
_idempotency_key = str(
|
|
401
|
+
meta.pop("_slm_idempotency_key", f"pending:{item['id']}")
|
|
402
|
+
)
|
|
403
|
+
if item.get("tags"):
|
|
404
|
+
meta.setdefault("tags", item["tags"])
|
|
405
|
+
from superlocalmemory.core.engine_ingestion import (
|
|
406
|
+
canonical_store,
|
|
407
|
+
local_trusted_actor_id,
|
|
408
|
+
)
|
|
409
|
+
canonical_store(
|
|
410
|
+
self,
|
|
411
|
+
item["content"],
|
|
412
|
+
source_type=_source_type,
|
|
413
|
+
trusted_actor_id=local_trusted_actor_id("engine-startup"),
|
|
414
|
+
metadata=meta or None,
|
|
415
|
+
scope=_scope,
|
|
416
|
+
shared_with=_shared,
|
|
417
|
+
session_id=str(meta.get("session_id") or ""),
|
|
418
|
+
idempotency_key=_idempotency_key,
|
|
372
419
|
)
|
|
373
420
|
mark_done(item["id"], base_dir)
|
|
374
421
|
except Exception as exc:
|
|
@@ -397,54 +444,45 @@ class MemoryEngine:
|
|
|
397
444
|
self._require_full("store")
|
|
398
445
|
self._ensure_init()
|
|
399
446
|
|
|
400
|
-
from superlocalmemory.core.
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
ann_index=self._ann_index,
|
|
418
|
-
sheaf_checker=self._sheaf_checker,
|
|
419
|
-
retrieval_engine=self._retrieval_engine,
|
|
420
|
-
provenance=self._provenance,
|
|
421
|
-
hooks=self._hooks,
|
|
422
|
-
vector_store=self._vector_store,
|
|
423
|
-
context_generator=self._context_generator,
|
|
424
|
-
temporal_validator=self._temporal_validator,
|
|
425
|
-
auto_linker=self._auto_linker,
|
|
426
|
-
consolidation_engine=self._consolidation_engine,
|
|
447
|
+
from superlocalmemory.core.engine_ingestion import (
|
|
448
|
+
canonical_store,
|
|
449
|
+
local_trusted_actor_id,
|
|
450
|
+
)
|
|
451
|
+
return canonical_store(
|
|
452
|
+
self,
|
|
453
|
+
content,
|
|
454
|
+
source_type="python-api",
|
|
455
|
+
trusted_actor_id=local_trusted_actor_id("python-api"),
|
|
456
|
+
metadata=metadata,
|
|
457
|
+
scope=scope,
|
|
458
|
+
shared_with=shared_with,
|
|
459
|
+
session_id=session_id,
|
|
460
|
+
session_date=session_date,
|
|
461
|
+
speaker=speaker,
|
|
462
|
+
role=role,
|
|
463
|
+
require_complete=False,
|
|
427
464
|
)
|
|
428
465
|
|
|
429
466
|
def store_fact_direct(self, fact: AtomicFact) -> str:
|
|
430
|
-
"""
|
|
467
|
+
"""Durably store a pre-built fact with full enrichment."""
|
|
431
468
|
self._require_full("store_fact_direct")
|
|
432
469
|
self._ensure_init()
|
|
433
470
|
|
|
434
|
-
from superlocalmemory.core.
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
vector_store=self._vector_store,
|
|
471
|
+
from superlocalmemory.core.engine_ingestion import (
|
|
472
|
+
canonical_store_fact,
|
|
473
|
+
local_trusted_actor_id,
|
|
474
|
+
)
|
|
475
|
+
return canonical_store_fact(
|
|
476
|
+
self,
|
|
477
|
+
fact,
|
|
478
|
+
trusted_actor_id=local_trusted_actor_id("python-api-prebuilt"),
|
|
443
479
|
)
|
|
444
480
|
|
|
445
481
|
def store_fast(
|
|
446
482
|
self, content: str, metadata: dict[str, Any] | None = None,
|
|
447
483
|
*, scope: str = "personal", shared_with: list[str] | None = None,
|
|
484
|
+
session_date: str | None = None, speaker: str = "", role: str = "user",
|
|
485
|
+
index_external: bool = True,
|
|
448
486
|
) -> list[str]:
|
|
449
487
|
"""v3.5.5 WRITE-THROUGH: synchronous verbatim insert for IMMEDIATE recall.
|
|
450
488
|
|
|
@@ -470,14 +508,9 @@ class MemoryEngine:
|
|
|
470
508
|
from superlocalmemory.storage.models import (
|
|
471
509
|
AtomicFact, FactType, MemoryRecord,
|
|
472
510
|
)
|
|
473
|
-
|
|
511
|
+
from superlocalmemory.core.engine_ingestion import content_passes_admission
|
|
512
|
+
if not content_passes_admission(content):
|
|
474
513
|
return []
|
|
475
|
-
try:
|
|
476
|
-
from superlocalmemory.core.injection import is_low_quality
|
|
477
|
-
if is_low_quality(content):
|
|
478
|
-
return []
|
|
479
|
-
except Exception:
|
|
480
|
-
pass
|
|
481
514
|
# v3.6.6 ingest gate: reject 1MB monsters + prompt-template pollution;
|
|
482
515
|
# clamp the searchable FACT copy (head+tail) while the memories row keeps
|
|
483
516
|
# the FULL original. Embedding/BM25 use the clamped copy so a 167KB paste
|
|
@@ -500,8 +533,10 @@ class MemoryEngine:
|
|
|
500
533
|
now = datetime.now(timezone.utc).isoformat()
|
|
501
534
|
record = MemoryRecord(
|
|
502
535
|
profile_id=self._profile_id, content=content,
|
|
503
|
-
session_date=now[:10],
|
|
536
|
+
session_date=session_date or now[:10],
|
|
504
537
|
session_id=(metadata or {}).get("session_id", ""),
|
|
538
|
+
speaker=speaker,
|
|
539
|
+
role=role,
|
|
505
540
|
metadata=metadata or {},
|
|
506
541
|
scope=scope, shared_with=shared_with,
|
|
507
542
|
)
|
|
@@ -513,44 +548,42 @@ class MemoryEngine:
|
|
|
513
548
|
r"\b([A-Z][a-z]+(?:\s[A-Z][a-z]+){0,3})\b", fact_text)}
|
|
514
549
|
| {m.group(1) for m in _re.finditer(r"\b([A-Z]{2,})\b", fact_text)}
|
|
515
550
|
)
|
|
516
|
-
#
|
|
517
|
-
#
|
|
518
|
-
#
|
|
519
|
-
#
|
|
520
|
-
#
|
|
521
|
-
#
|
|
551
|
+
# Queryable admission must never acquire the embedding worker lock.
|
|
552
|
+
# On a warm daemon that looked cheap, but on a clean Mode A install the
|
|
553
|
+
# background model load owns that lock for up to 180s and turned the
|
|
554
|
+
# receipt-first path into a hidden synchronous wait. The canonical
|
|
555
|
+
# materializer below runs the complete pipeline and promotes this same
|
|
556
|
+
# fact with its embedding, Fisher parameters, entities and graph edges.
|
|
557
|
+
# Until then it is deliberately BM25/entity/date recallable.
|
|
522
558
|
emb = None
|
|
523
559
|
fmean = fvar = None
|
|
524
|
-
try:
|
|
525
|
-
emb = self._embedder.embed(fact_text) if self._embedder else None
|
|
526
|
-
if emb:
|
|
527
|
-
fmean, fvar = self._embedder.compute_fisher_params(emb)
|
|
528
|
-
except Exception:
|
|
529
|
-
emb = None
|
|
530
560
|
fact = AtomicFact(
|
|
531
561
|
fact_id=_uuid.uuid4().hex[:16], memory_id=record.memory_id,
|
|
532
562
|
profile_id=self._profile_id, content=fact_text,
|
|
533
563
|
fact_type=FactType.EPISODIC, entities=ents,
|
|
534
|
-
observation_date=now[:10],
|
|
564
|
+
observation_date=session_date or now[:10],
|
|
565
|
+
confidence=0.7, importance=0.5,
|
|
535
566
|
embedding=emb, fisher_mean=fmean, fisher_variance=fvar,
|
|
536
567
|
created_at=now,
|
|
537
568
|
scope=scope, shared_with=shared_with,
|
|
538
569
|
)
|
|
539
570
|
self._db.store_fact(fact) # FTS5 trigger → immediately BM25-recallable
|
|
540
571
|
# Upsert to vector store so the semantic channel finds it now.
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
vs
|
|
545
|
-
|
|
546
|
-
|
|
572
|
+
if index_external:
|
|
573
|
+
try:
|
|
574
|
+
vs = getattr(self, "_vector_store", None)
|
|
575
|
+
if emb and vs and getattr(vs, "available", False):
|
|
576
|
+
vs.upsert(fact.fact_id, self._profile_id, emb)
|
|
577
|
+
except Exception:
|
|
578
|
+
pass
|
|
547
579
|
# Persist BM25 tokens too (covers the in-memory rank_bm25 fallback path).
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
bm25
|
|
552
|
-
|
|
553
|
-
|
|
580
|
+
if index_external:
|
|
581
|
+
try:
|
|
582
|
+
bm25 = getattr(self._retrieval_engine, "_bm25", None)
|
|
583
|
+
if bm25:
|
|
584
|
+
bm25.add(fact.fact_id, fact_text, self._profile_id)
|
|
585
|
+
except Exception:
|
|
586
|
+
pass
|
|
554
587
|
return [fact.fact_id]
|
|
555
588
|
|
|
556
589
|
# -- Recall operations --------------------------------------------------
|
|
@@ -574,11 +607,10 @@ class MemoryEngine:
|
|
|
574
607
|
``put_nowait`` and the actual ``pending_outcomes`` INSERT runs
|
|
575
608
|
on a background worker.
|
|
576
609
|
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
but is silently treated as False.
|
|
610
|
+
``fast=True`` is the latency-bounded path: it skips spreading
|
|
611
|
+
activation and remote agentic verification while retaining semantic,
|
|
612
|
+
lexical, graph, temporal, and Hopfield retrieval. Use full recall when
|
|
613
|
+
maximum multi-round quality matters more than response time.
|
|
582
614
|
|
|
583
615
|
Multi-scope: ``include_global`` / ``include_shared`` control which
|
|
584
616
|
scopes participate in retrieval. ``None`` (the default) means "use the
|
|
@@ -599,31 +631,33 @@ class MemoryEngine:
|
|
|
599
631
|
if include_shared is None:
|
|
600
632
|
include_shared = bool(getattr(_scope_cfg, "recall_include_shared", False))
|
|
601
633
|
|
|
602
|
-
if fast:
|
|
603
|
-
logger.warning(
|
|
604
|
-
"fast=True is deprecated (v3.6.9): SpreadingActivation now "
|
|
605
|
-
"completes in ~36ms; fast mode is slower and reduces quality. "
|
|
606
|
-
"Pass fast=False (the default) to silence this warning."
|
|
607
|
-
)
|
|
608
|
-
fast = False
|
|
609
|
-
|
|
610
634
|
pid = profile_id or self._profile_id
|
|
611
635
|
|
|
612
636
|
from superlocalmemory.core.recall_pipeline import run_recall
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
637
|
+
try:
|
|
638
|
+
response = run_recall(
|
|
639
|
+
query, pid, mode=mode, limit=limit, agent_id=agent_id,
|
|
640
|
+
config=self._config,
|
|
641
|
+
retrieval_engine=self._retrieval_engine,
|
|
642
|
+
trust_scorer=self._trust_scorer,
|
|
643
|
+
embedder=self._embedder,
|
|
644
|
+
db=self._db, llm=self._llm,
|
|
645
|
+
hooks=self._hooks,
|
|
646
|
+
access_log=self._access_log,
|
|
647
|
+
auto_linker=self._auto_linker,
|
|
648
|
+
fast=fast,
|
|
649
|
+
include_global=include_global,
|
|
650
|
+
include_shared=include_shared,
|
|
651
|
+
)
|
|
652
|
+
except Exception as exc:
|
|
653
|
+
from superlocalmemory.infra.local_diagnostics import record_operation
|
|
654
|
+
|
|
655
|
+
record_operation("recall", client=agent_id, error=exc)
|
|
656
|
+
raise
|
|
657
|
+
|
|
658
|
+
from superlocalmemory.infra.local_diagnostics import record_recall
|
|
659
|
+
|
|
660
|
+
record_recall(self._db, response, client=agent_id)
|
|
627
661
|
|
|
628
662
|
# S9-DASH-02: enqueue for pending_outcomes. Non-blocking; errors
|
|
629
663
|
# swallowed because signal capture is never load-bearing on
|
|
@@ -685,7 +719,19 @@ class MemoryEngine:
|
|
|
685
719
|
def close(self) -> None:
|
|
686
720
|
if self._maintenance_scheduler is not None:
|
|
687
721
|
self._maintenance_scheduler.stop()
|
|
722
|
+
if self._retrieval_engine is not None:
|
|
723
|
+
try:
|
|
724
|
+
self._retrieval_engine.close()
|
|
725
|
+
except Exception:
|
|
726
|
+
pass
|
|
688
727
|
if self._db is not None:
|
|
728
|
+
try:
|
|
729
|
+
from superlocalmemory.core.recall_pipeline import (
|
|
730
|
+
release_recall_resources,
|
|
731
|
+
)
|
|
732
|
+
release_recall_resources(self._db)
|
|
733
|
+
except Exception:
|
|
734
|
+
pass
|
|
689
735
|
try:
|
|
690
736
|
self._db.close()
|
|
691
737
|
except Exception:
|