superlocalmemory 3.6.23 → 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 +271 -71
- package/bin/slm-npm +43 -89
- 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 +18 -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 +453 -191
- 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 +1 -1
- 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 +123 -35
- 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 +219 -32
- 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 +1 -1
- 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 +12 -12
- 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 +8 -63
- 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/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 -516
- 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
|
@@ -12,12 +12,11 @@ All adapters inherit this. Enforces stateless, safe, cross-platform operation:
|
|
|
12
12
|
- Structured logging
|
|
13
13
|
|
|
14
14
|
Part of Qualixar | Author: Varun Pratap Bhardwaj
|
|
15
|
-
License:
|
|
15
|
+
License: AGPL-3.0-or-later
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
18
|
from __future__ import annotations
|
|
19
19
|
|
|
20
|
-
import json
|
|
21
20
|
import logging
|
|
22
21
|
import os
|
|
23
22
|
import signal
|
|
@@ -132,35 +131,30 @@ class BaseAdapter:
|
|
|
132
131
|
|
|
133
132
|
def _ingest(self, item: IngestItem) -> bool:
|
|
134
133
|
"""POST to daemon /ingest endpoint. Returns True on success."""
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
data=payload
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
logger.info("Daemon returned 429, backing off 5s")
|
|
160
|
-
self._stop_event.wait(5)
|
|
161
|
-
return self._ingest(item) # Retry once
|
|
162
|
-
logger.debug("Ingest failed: %s", exc)
|
|
163
|
-
return False
|
|
134
|
+
payload = {
|
|
135
|
+
"content": item.content,
|
|
136
|
+
"source_type": self.source_type,
|
|
137
|
+
"dedup_key": item.dedup_key,
|
|
138
|
+
"metadata": item.metadata if item.metadata else {},
|
|
139
|
+
}
|
|
140
|
+
for attempt in range(2):
|
|
141
|
+
try:
|
|
142
|
+
from superlocalmemory.cli.daemon import daemon_request
|
|
143
|
+
|
|
144
|
+
data = daemon_request("POST", "/ingest", payload)
|
|
145
|
+
if data and data.get("ingested"):
|
|
146
|
+
self._items_this_hour += 1
|
|
147
|
+
self._total_ingested += 1
|
|
148
|
+
return True
|
|
149
|
+
return False # Already ingested (dedup)
|
|
150
|
+
except Exception as exc:
|
|
151
|
+
if "429" in str(exc) and attempt == 0:
|
|
152
|
+
logger.info("Daemon returned 429, backing off 5s")
|
|
153
|
+
self._stop_event.wait(5)
|
|
154
|
+
continue
|
|
155
|
+
logger.debug("Ingest failed: %s", exc)
|
|
156
|
+
return False
|
|
157
|
+
return False
|
|
164
158
|
|
|
165
159
|
def _rate_limited(self) -> bool:
|
|
166
160
|
if time.time() - self._hour_start > 3600:
|
|
@@ -10,7 +10,7 @@ Tier 2: Google Calendar API with OAuth polling — shares Gmail OAuth credential
|
|
|
10
10
|
OPT-IN only. Enabled via: slm adapters enable calendar
|
|
11
11
|
|
|
12
12
|
Part of Qualixar | Author: Varun Pratap Bhardwaj
|
|
13
|
-
License:
|
|
13
|
+
License: AGPL-3.0-or-later
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
16
|
from __future__ import annotations
|
|
@@ -22,10 +22,19 @@ from datetime import datetime, timezone
|
|
|
22
22
|
from pathlib import Path
|
|
23
23
|
|
|
24
24
|
from superlocalmemory.ingestion.base_adapter import BaseAdapter, AdapterConfig, IngestItem
|
|
25
|
+
from superlocalmemory.infra.data_root import state_path
|
|
25
26
|
|
|
26
27
|
logger = logging.getLogger("superlocalmemory.ingestion.calendar")
|
|
27
28
|
|
|
28
29
|
|
|
30
|
+
def _adapters_config_path() -> Path:
|
|
31
|
+
return state_path("adapters.json")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _import_dir() -> Path:
|
|
35
|
+
return state_path("import")
|
|
36
|
+
|
|
37
|
+
|
|
29
38
|
class CalendarAdapter(BaseAdapter):
|
|
30
39
|
"""Google Calendar ingestion with automatic tier detection."""
|
|
31
40
|
|
|
@@ -62,7 +71,7 @@ class CalendarAdapter(BaseAdapter):
|
|
|
62
71
|
if self._tier != "auto":
|
|
63
72
|
return
|
|
64
73
|
|
|
65
|
-
adapters_path =
|
|
74
|
+
adapters_path = _adapters_config_path()
|
|
66
75
|
cfg = {}
|
|
67
76
|
if adapters_path.exists():
|
|
68
77
|
cfg = json.loads(adapters_path.read_text()).get("calendar", {})
|
|
@@ -79,7 +88,7 @@ class CalendarAdapter(BaseAdapter):
|
|
|
79
88
|
return
|
|
80
89
|
|
|
81
90
|
# Look for ICS files
|
|
82
|
-
import_dir =
|
|
91
|
+
import_dir = _import_dir()
|
|
83
92
|
ics_files = list(import_dir.glob("*.ics")) if import_dir.exists() else []
|
|
84
93
|
if ics_files:
|
|
85
94
|
self._tier = "ics"
|
|
@@ -330,7 +339,7 @@ if __name__ == "__main__":
|
|
|
330
339
|
import logging as _logging
|
|
331
340
|
_logging.basicConfig(level=_logging.INFO, format="%(asctime)s %(message)s")
|
|
332
341
|
|
|
333
|
-
adapters_path =
|
|
342
|
+
adapters_path = _adapters_config_path()
|
|
334
343
|
tier = "auto"
|
|
335
344
|
if adapters_path.exists():
|
|
336
345
|
cfg = json.loads(adapters_path.read_text()).get("calendar", {})
|
|
@@ -8,7 +8,7 @@ Uses OS keychain via keyring library (macOS Keychain, Windows Credential Locker,
|
|
|
8
8
|
Linux SecretService). Falls back to file-based storage with restricted permissions.
|
|
9
9
|
|
|
10
10
|
Part of Qualixar | Author: Varun Pratap Bhardwaj
|
|
11
|
-
License:
|
|
11
|
+
License: AGPL-3.0-or-later
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
14
|
from __future__ import annotations
|
|
@@ -19,12 +19,18 @@ import os
|
|
|
19
19
|
import sys
|
|
20
20
|
from pathlib import Path
|
|
21
21
|
|
|
22
|
+
from superlocalmemory.infra.data_root import state_path
|
|
23
|
+
|
|
22
24
|
logger = logging.getLogger("superlocalmemory.ingestion.credentials")
|
|
23
25
|
|
|
24
|
-
_CRED_DIR =
|
|
26
|
+
_CRED_DIR = None # test-only compatibility override
|
|
25
27
|
_SERVICE_PREFIX = "slm"
|
|
26
28
|
|
|
27
29
|
|
|
30
|
+
def _credential_dir() -> Path:
|
|
31
|
+
return Path(_CRED_DIR) if _CRED_DIR is not None else state_path("credentials")
|
|
32
|
+
|
|
33
|
+
|
|
28
34
|
def store_credential(service: str, key: str, value: str) -> bool:
|
|
29
35
|
"""Store a credential securely. Returns True on success."""
|
|
30
36
|
# Try OS keychain first
|
|
@@ -38,8 +44,9 @@ def store_credential(service: str, key: str, value: str) -> bool:
|
|
|
38
44
|
|
|
39
45
|
# Fallback: encrypted file with restricted permissions
|
|
40
46
|
try:
|
|
41
|
-
|
|
42
|
-
|
|
47
|
+
cred_dir = _credential_dir()
|
|
48
|
+
cred_dir.mkdir(parents=True, exist_ok=True)
|
|
49
|
+
cred_file = cred_dir / f"{service}.json"
|
|
43
50
|
|
|
44
51
|
existing = {}
|
|
45
52
|
if cred_file.exists():
|
|
@@ -54,7 +61,7 @@ def store_credential(service: str, key: str, value: str) -> bool:
|
|
|
54
61
|
# Restrict permissions (Unix only — Windows skipped)
|
|
55
62
|
if sys.platform != "win32":
|
|
56
63
|
os.chmod(cred_file, 0o600)
|
|
57
|
-
os.chmod(
|
|
64
|
+
os.chmod(cred_dir, 0o700)
|
|
58
65
|
|
|
59
66
|
logger.debug("Stored %s/%s in file (keychain unavailable)", service, key)
|
|
60
67
|
return True
|
|
@@ -76,7 +83,7 @@ def load_credential(service: str, key: str) -> str | None:
|
|
|
76
83
|
|
|
77
84
|
# Fallback: file
|
|
78
85
|
try:
|
|
79
|
-
cred_file =
|
|
86
|
+
cred_file = _credential_dir() / f"{service}.json"
|
|
80
87
|
if cred_file.exists():
|
|
81
88
|
data = json.loads(cred_file.read_text())
|
|
82
89
|
return data.get(key)
|
|
@@ -100,7 +107,7 @@ def delete_credential(service: str, key: str) -> bool:
|
|
|
100
107
|
|
|
101
108
|
# Also remove from file
|
|
102
109
|
try:
|
|
103
|
-
cred_file =
|
|
110
|
+
cred_file = _credential_dir() / f"{service}.json"
|
|
104
111
|
if cred_file.exists():
|
|
105
112
|
data = json.loads(cred_file.read_text())
|
|
106
113
|
if key in data:
|
|
@@ -12,7 +12,7 @@ Tier 3: Gmail API with Pub/Sub push — full GCP (future)
|
|
|
12
12
|
OPT-IN only. Enabled via: slm adapters enable gmail
|
|
13
13
|
|
|
14
14
|
Part of Qualixar | Author: Varun Pratap Bhardwaj
|
|
15
|
-
License:
|
|
15
|
+
License: AGPL-3.0-or-later
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
18
|
from __future__ import annotations
|
|
@@ -23,10 +23,19 @@ import sys
|
|
|
23
23
|
from pathlib import Path
|
|
24
24
|
|
|
25
25
|
from superlocalmemory.ingestion.base_adapter import BaseAdapter, AdapterConfig, IngestItem
|
|
26
|
+
from superlocalmemory.infra.data_root import state_path
|
|
26
27
|
|
|
27
28
|
logger = logging.getLogger("superlocalmemory.ingestion.gmail")
|
|
28
29
|
|
|
29
30
|
|
|
31
|
+
def _adapters_config_path() -> Path:
|
|
32
|
+
return state_path("adapters.json")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _import_dir() -> Path:
|
|
36
|
+
return state_path("import")
|
|
37
|
+
|
|
38
|
+
|
|
30
39
|
class GmailAdapter(BaseAdapter):
|
|
31
40
|
"""Gmail ingestion with automatic tier detection."""
|
|
32
41
|
|
|
@@ -71,7 +80,7 @@ class GmailAdapter(BaseAdapter):
|
|
|
71
80
|
if self._tier != "auto":
|
|
72
81
|
return
|
|
73
82
|
|
|
74
|
-
adapters_path =
|
|
83
|
+
adapters_path = _adapters_config_path()
|
|
75
84
|
cfg = {}
|
|
76
85
|
if adapters_path.exists():
|
|
77
86
|
cfg = json.loads(adapters_path.read_text()).get("gmail", {})
|
|
@@ -93,7 +102,7 @@ class GmailAdapter(BaseAdapter):
|
|
|
93
102
|
return
|
|
94
103
|
|
|
95
104
|
# Default: look for mbox file
|
|
96
|
-
mbox_dir =
|
|
105
|
+
mbox_dir = _import_dir()
|
|
97
106
|
mbox_files = list(mbox_dir.glob("*.mbox")) if mbox_dir.exists() else []
|
|
98
107
|
if mbox_files:
|
|
99
108
|
self._tier = "mbox"
|
|
@@ -359,7 +368,7 @@ if __name__ == "__main__":
|
|
|
359
368
|
import logging as _logging
|
|
360
369
|
_logging.basicConfig(level=_logging.INFO, format="%(asctime)s %(message)s")
|
|
361
370
|
|
|
362
|
-
adapters_path =
|
|
371
|
+
adapters_path = _adapters_config_path()
|
|
363
372
|
tier = "auto"
|
|
364
373
|
if adapters_path.exists():
|
|
365
374
|
cfg = json.loads(adapters_path.read_text()).get("gmail", {})
|
|
@@ -11,7 +11,7 @@ to the daemon's /ingest endpoint.
|
|
|
11
11
|
OPT-IN only. Enabled via: slm adapters enable transcript
|
|
12
12
|
|
|
13
13
|
Part of Qualixar | Author: Varun Pratap Bhardwaj
|
|
14
|
-
License:
|
|
14
|
+
License: AGPL-3.0-or-later
|
|
15
15
|
"""
|
|
16
16
|
|
|
17
17
|
from __future__ import annotations
|
|
@@ -23,12 +23,17 @@ import time
|
|
|
23
23
|
from pathlib import Path
|
|
24
24
|
|
|
25
25
|
from superlocalmemory.ingestion.base_adapter import BaseAdapter, AdapterConfig, IngestItem
|
|
26
|
+
from superlocalmemory.infra.data_root import state_path
|
|
26
27
|
|
|
27
28
|
logger = logging.getLogger("superlocalmemory.ingestion.transcript")
|
|
28
29
|
|
|
29
30
|
_WATCH_EXTENSIONS = {".srt", ".vtt", ".txt"}
|
|
30
31
|
|
|
31
32
|
|
|
33
|
+
def _adapters_config_path() -> Path:
|
|
34
|
+
return state_path("adapters.json")
|
|
35
|
+
|
|
36
|
+
|
|
32
37
|
class TranscriptAdapter(BaseAdapter):
|
|
33
38
|
"""Watches a directory for transcript files and ingests them."""
|
|
34
39
|
|
|
@@ -142,7 +147,7 @@ if __name__ == "__main__":
|
|
|
142
147
|
|
|
143
148
|
# Load config
|
|
144
149
|
watch_dir = ""
|
|
145
|
-
adapters_path =
|
|
150
|
+
adapters_path = _adapters_config_path()
|
|
146
151
|
if adapters_path.exists():
|
|
147
152
|
cfg = json.loads(adapters_path.read_text())
|
|
148
153
|
watch_dir = cfg.get("transcript", {}).get("watch_dir", "")
|
|
@@ -12,7 +12,7 @@ Wraps CognitiveConsolidator with scheduling logic:
|
|
|
12
12
|
Integration point: ConsolidationEngine._step7_ccq() calls this worker.
|
|
13
13
|
|
|
14
14
|
Part of Qualixar | Author: Varun Pratap Bhardwaj
|
|
15
|
-
License:
|
|
15
|
+
License: AGPL-3.0-or-later
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
18
|
from __future__ import annotations
|
|
@@ -269,6 +269,17 @@ def ensemble_rerank(
|
|
|
269
269
|
for b, l in zip(n_bandit, n_lgbm)
|
|
270
270
|
]
|
|
271
271
|
|
|
272
|
+
# Retain the model/policy utility for auditability without overwriting the
|
|
273
|
+
# public query-relative relevance score.
|
|
274
|
+
for candidate, utility in zip(candidates, blended):
|
|
275
|
+
if isinstance(candidate, dict):
|
|
276
|
+
candidate["ranking_score"] = float(utility)
|
|
277
|
+
else:
|
|
278
|
+
try:
|
|
279
|
+
candidate.ranking_score = float(utility)
|
|
280
|
+
except (AttributeError, TypeError):
|
|
281
|
+
pass
|
|
282
|
+
|
|
272
283
|
# Stable-sort descending so equal scores preserve original order.
|
|
273
284
|
indexed = list(enumerate(candidates))
|
|
274
285
|
indexed.sort(key=lambda pair: -blended[pair[0]])
|
|
@@ -11,7 +11,7 @@ Builds knowledge summaries using PageRank centrality + Louvain community detecti
|
|
|
11
11
|
Runs after consolidation (every 6 hours or on-demand).
|
|
12
12
|
|
|
13
13
|
Part of Qualixar | Author: Varun Pratap Bhardwaj
|
|
14
|
-
License:
|
|
14
|
+
License: AGPL-3.0-or-later
|
|
15
15
|
"""
|
|
16
16
|
|
|
17
17
|
from __future__ import annotations
|
|
@@ -18,7 +18,7 @@ HR-08: Runs synchronously in main thread.
|
|
|
18
18
|
HR-09: Access events are idempotent.
|
|
19
19
|
|
|
20
20
|
Part of Qualixar | Author: Varun Pratap Bhardwaj
|
|
21
|
-
License:
|
|
21
|
+
License: AGPL-3.0-or-later
|
|
22
22
|
"""
|
|
23
23
|
|
|
24
24
|
from __future__ import annotations
|
|
@@ -60,7 +60,7 @@ class ForgettingScheduler:
|
|
|
60
60
|
self._last_run_times: dict[str, float] = {}
|
|
61
61
|
|
|
62
62
|
def run_decay_cycle(
|
|
63
|
-
self, profile_id: str, *, force: bool = False,
|
|
63
|
+
self, profile_id: str, *, force: bool = False, dry_run: bool = False,
|
|
64
64
|
) -> dict:
|
|
65
65
|
"""Run a full decay cycle for all facts in a profile.
|
|
66
66
|
|
|
@@ -70,6 +70,7 @@ class ForgettingScheduler:
|
|
|
70
70
|
Args:
|
|
71
71
|
profile_id: Profile to process.
|
|
72
72
|
force: If True, bypass interval check.
|
|
73
|
+
dry_run: Compute transitions without persisting retention or lifecycle.
|
|
73
74
|
|
|
74
75
|
Returns:
|
|
75
76
|
Stats dict: {total, active, warm, cold, archive, forgotten,
|
|
@@ -87,7 +88,8 @@ class ForgettingScheduler:
|
|
|
87
88
|
facts_data = self._fetch_facts_with_metadata(profile_id)
|
|
88
89
|
|
|
89
90
|
if not facts_data:
|
|
90
|
-
|
|
91
|
+
if not dry_run:
|
|
92
|
+
self._last_run_times[profile_id] = now
|
|
91
93
|
return {
|
|
92
94
|
"total": 0, "active": 0, "warm": 0, "cold": 0,
|
|
93
95
|
"archive": 0, "forgotten": 0, "transitions": 0,
|
|
@@ -100,7 +102,8 @@ class ForgettingScheduler:
|
|
|
100
102
|
retention_results = self._ebbinghaus.batch_compute_retention(facts_data)
|
|
101
103
|
|
|
102
104
|
# Step 4: Batch UPSERT into fact_retention
|
|
103
|
-
|
|
105
|
+
if not dry_run:
|
|
106
|
+
self._db.batch_upsert_retention(retention_results, profile_id)
|
|
104
107
|
|
|
105
108
|
# Step 5: Count zones and transitions
|
|
106
109
|
zone_counts = {"active": 0, "warm": 0, "cold": 0, "archive": 0, "forgotten": 0}
|
|
@@ -121,11 +124,13 @@ class ForgettingScheduler:
|
|
|
121
124
|
forgotten_fact_ids.append(result["fact_id"])
|
|
122
125
|
|
|
123
126
|
# Step 6: Soft-delete forgotten facts (HR-04)
|
|
124
|
-
|
|
125
|
-
|
|
127
|
+
if not dry_run:
|
|
128
|
+
for fact_id in forgotten_fact_ids:
|
|
129
|
+
self._soft_delete_with_audit(fact_id, profile_id)
|
|
126
130
|
|
|
127
131
|
# Update last run time
|
|
128
|
-
|
|
132
|
+
if not dry_run:
|
|
133
|
+
self._last_run_times[profile_id] = now
|
|
129
134
|
|
|
130
135
|
return {
|
|
131
136
|
"total": len(retention_results),
|
|
@@ -208,7 +208,10 @@ class AdaptiveRanker:
|
|
|
208
208
|
return self._rerank_heuristic(results, query_context)
|
|
209
209
|
|
|
210
210
|
order = np.argsort(-scores, kind="stable")
|
|
211
|
-
return [
|
|
211
|
+
return [
|
|
212
|
+
{**results[int(i)], "_adaptive_score": float(scores[int(i)])}
|
|
213
|
+
for i in order
|
|
214
|
+
]
|
|
212
215
|
|
|
213
216
|
# --- legacy load path (back-compat) --------------------------------
|
|
214
217
|
|
|
@@ -44,6 +44,7 @@ from typing import Optional
|
|
|
44
44
|
# Import the RAM semaphore at module scope so tests can monkeypatch
|
|
45
45
|
# ``trigram_index.ram_reservation`` to a no-op on CI boxes with tight RAM.
|
|
46
46
|
from superlocalmemory.core.ram_lock import ram_reservation
|
|
47
|
+
from superlocalmemory.infra.data_root import DynamicStatePath, state_path
|
|
47
48
|
|
|
48
49
|
|
|
49
50
|
# --------------------------------------------------------------------------
|
|
@@ -205,7 +206,7 @@ class TrigramIndex:
|
|
|
205
206
|
``(entity_id, hits)`` candidates.
|
|
206
207
|
"""
|
|
207
208
|
|
|
208
|
-
CACHE_DB_PATH: Path =
|
|
209
|
+
CACHE_DB_PATH: Path = DynamicStatePath("active_brain_cache.db")
|
|
209
210
|
MAX_TRIGRAMS: int = 1_000_000
|
|
210
211
|
LOOKUP_LIMIT: int = 10
|
|
211
212
|
LOOKUP_MIN_HITS: int = 2
|
|
@@ -537,7 +538,7 @@ def get_or_none() -> Optional[TrigramIndex]:
|
|
|
537
538
|
return _SINGLETON
|
|
538
539
|
if not TrigramIndex.CACHE_DB_PATH.exists():
|
|
539
540
|
return None
|
|
540
|
-
default_source =
|
|
541
|
+
default_source = state_path("memory.db")
|
|
541
542
|
if not default_source.exists():
|
|
542
543
|
return None
|
|
543
544
|
_SINGLETON = TrigramIndex(source_db_path=default_source)
|
|
@@ -26,7 +26,7 @@ References:
|
|
|
26
26
|
the classical compact groups.
|
|
27
27
|
|
|
28
28
|
Part of Qualixar | Author: Varun Pratap Bhardwaj
|
|
29
|
-
License:
|
|
29
|
+
License: AGPL-3.0-or-later
|
|
30
30
|
"""
|
|
31
31
|
|
|
32
32
|
from __future__ import annotations
|
|
@@ -41,6 +41,7 @@ import numpy as np
|
|
|
41
41
|
from numpy.typing import NDArray
|
|
42
42
|
|
|
43
43
|
from superlocalmemory.core.config import PolarQuantConfig
|
|
44
|
+
from superlocalmemory.infra.data_root import state_path
|
|
44
45
|
|
|
45
46
|
logger = logging.getLogger(__name__)
|
|
46
47
|
|
|
@@ -113,9 +114,7 @@ class PolarQuantEncoder:
|
|
|
113
114
|
"""
|
|
114
115
|
path_str = self._config.rotation_matrix_path
|
|
115
116
|
if not path_str:
|
|
116
|
-
path_str = str(
|
|
117
|
-
Path.home() / ".superlocalmemory" / f"polar_rotation_{self._d}.npy",
|
|
118
|
-
)
|
|
117
|
+
path_str = str(state_path(f"polar_rotation_{self._d}.npy"))
|
|
119
118
|
|
|
120
119
|
path = Path(path_str)
|
|
121
120
|
|
|
@@ -14,7 +14,7 @@ Severity = ||delta_0 f(e)|| / (||R_a emb_a|| + ||R_b emb_b||).
|
|
|
14
14
|
Refs: Curry 2014 (arXiv:1303.3255), Hansen & Ghrist 2019, Robinson 2020.
|
|
15
15
|
|
|
16
16
|
Part of Qualixar | Author: Varun Pratap Bhardwaj
|
|
17
|
-
License:
|
|
17
|
+
License: AGPL-3.0-or-later
|
|
18
18
|
"""
|
|
19
19
|
from __future__ import annotations
|
|
20
20
|
|
|
@@ -9,7 +9,7 @@ D_mse <= sqrt(3*pi/2) / 4^b. No scipy (HR-SCIPY-01). 2-byte "TQ" prefix on
|
|
|
9
9
|
all BLOBs (HR-MIG-02). Bit-widths: 2, 4, 8 only (HR-3BIT-01).
|
|
10
10
|
|
|
11
11
|
References: TurboQuant (arXiv 2504.19874), PolarQuant (arXiv 2502.02617).
|
|
12
|
-
Part of Qualixar | Author: Varun Pratap Bhardwaj | License:
|
|
12
|
+
Part of Qualixar | Author: Varun Pratap Bhardwaj | License: AGPL-3.0-or-later
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
@@ -24,6 +24,7 @@ import numpy as np
|
|
|
24
24
|
from numpy.typing import NDArray
|
|
25
25
|
|
|
26
26
|
from superlocalmemory.core.config import PolarQuantConfig
|
|
27
|
+
from superlocalmemory.infra.data_root import canonical_data_root
|
|
27
28
|
|
|
28
29
|
logger = logging.getLogger(__name__)
|
|
29
30
|
|
|
@@ -173,7 +174,7 @@ class TurboQuantEncoder:
|
|
|
173
174
|
def _load_or_create_rotation_matrix(self) -> NDArray:
|
|
174
175
|
"""Load/create rotation matrix with copy-on-detect (AUDIT C4-MED-01)."""
|
|
175
176
|
d = self._d
|
|
176
|
-
slm_dir =
|
|
177
|
+
slm_dir = canonical_data_root()
|
|
177
178
|
|
|
178
179
|
turbo_path_str = self._config.rotation_matrix_path
|
|
179
180
|
if not turbo_path_str:
|
|
@@ -79,25 +79,26 @@ class DaemonPoolProxy:
|
|
|
79
79
|
def store(
|
|
80
80
|
self, content: str, metadata: dict | None = None,
|
|
81
81
|
) -> dict[str, Any]:
|
|
82
|
-
body =
|
|
82
|
+
body = {
|
|
83
83
|
"content": content,
|
|
84
84
|
"tags": (metadata or {}).get("tags", ""),
|
|
85
85
|
"metadata": metadata or {},
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
data=body,
|
|
90
|
-
headers={"Content-Type": "application/json"},
|
|
91
|
-
method="POST",
|
|
92
|
-
)
|
|
86
|
+
"session_id": (metadata or {}).get("session_id", ""),
|
|
87
|
+
"idempotency_key": (metadata or {}).get("idempotency_key") or None,
|
|
88
|
+
}
|
|
93
89
|
try:
|
|
94
|
-
|
|
95
|
-
|
|
90
|
+
# One identity-aware daemon client owns descriptor validation,
|
|
91
|
+
# capability delivery, and exact-instance targeting. A raw urllib
|
|
92
|
+
# POST here previously became unauthenticated when /remember was
|
|
93
|
+
# hardened and could also attach to a stale/foreign port.
|
|
94
|
+
from superlocalmemory.cli.daemon import daemon_request
|
|
95
|
+
|
|
96
|
+
data = daemon_request("POST", "/remember", body)
|
|
96
97
|
except Exception as exc:
|
|
97
98
|
logger.warning("daemon /remember failed: %s", exc)
|
|
98
99
|
return {"ok": False, "error": str(exc)}
|
|
99
100
|
if not isinstance(data, dict):
|
|
100
|
-
return {"ok": False, "error": "
|
|
101
|
+
return {"ok": False, "error": "owned daemon unavailable"}
|
|
101
102
|
data.setdefault("ok", True)
|
|
102
103
|
return data
|
|
103
104
|
|