loop-memory 0.4.11__tar.gz → 0.4.12__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.
- {loop_memory-0.4.11 → loop_memory-0.4.12}/PKG-INFO +3 -1
- {loop_memory-0.4.11 → loop_memory-0.4.12}/README.md +2 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/cli/commands/cognitive.py +46 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/cli/main.py +4 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/serve/routes/system.py +43 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/storage/sqlite_store.py +572 -1
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory.egg-info/PKG-INFO +3 -1
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory.egg-info/SOURCES.txt +2 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/pyproject.toml +1 -1
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_agents_init.py +3 -3
- loop_memory-0.4.12/tests/test_audit_triggers_2026_09_27.py +188 -0
- loop_memory-0.4.12/tests/test_import_okf_2026_09_27.py +425 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_supersession_chain.py +1 -1
- {loop_memory-0.4.11 → loop_memory-0.4.12}/LICENSE +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/__init__.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/backends/__init__.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/backends/embedding.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/backends/sentence_embedder.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/backends/vector_store.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/cli/__init__.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/cli/_common.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/cli/commands/__init__.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/cli/commands/diag.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/cli/commands/graph.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/cli/commands/hooks.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/cli/commands/read.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/cli/commands/rules.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/cli/commands/serve.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/cli/commands/write.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/engine/__init__.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/engine/loop.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/engine/reflect.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/examples/__init__.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/examples/demo.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/export/__init__.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/export/memory_md.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/graph/__init__.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/graph/build.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/graph/extract.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/ingest/__init__.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/ingest/loader.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/ingest/pipeline.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/jobs/__init__.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/jobs/cognitive.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/jobs/compact.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/jobs/consolidate.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/jobs/contradiction.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/jobs/evolution.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/jobs/graph.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/jobs/llm_compact_pass.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/jobs/llm_consolidate.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/jobs/scheduler.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/llm/__init__.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/llm/base.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/llm/openai_adapter.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/llm/providers.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/mcp/__init__.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/memory/__init__.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/memory/types.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/privacy/__init__.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/privacy/private.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/privacy/redact.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/py.typed +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/sdk.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/sdk_extensions.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/security/__init__.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/security/secrets.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/serve/__init__.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/serve/app.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/serve/handlers.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/serve/routes/_shared.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/serve/routes/admin.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/serve/routes/cognitive.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/serve/routes/export.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/serve/routes/graph.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/serve/routes/insights.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/serve/routes/memories.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/serve/routes/sessions.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/serve/routes/wiki.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/serve/static/__init__.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/serve/static/index.html +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/serve/watcher.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/storage/__init__.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/storage/retrieval.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/storage/snapshot.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/wiki/__init__.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/wiki/backfill.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/wiki/classifier.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/wiki/prompts.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory/wiki/scope.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory.egg-info/dependency_links.txt +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory.egg-info/entry_points.txt +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory.egg-info/requires.txt +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/loop_memory.egg-info/top_level.txt +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/setup.cfg +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_admin_ingest_route.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_agent_memory_api.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_agent_memory_sdk.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_auth_token_rotate.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_busy_timeout_2026_09_24.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_cache_cap_2026_09_23.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_cli_audit_supersede.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_cli_export_okf.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_cli_init.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_cli_memory_stats.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_cli_recall_as_of.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_cli_recall_paths.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_cli_recall_verbose.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_cli_rules.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_cli_snapshot.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_cli_v7.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_cli_version.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_contradictions.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_evolution.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_evolution_quality.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_expanduser.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_export_ask.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_export_okf.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_graph.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_healthz_readyz_2026_09_24.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_ingest.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_llm_consolidator.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_llm_fingerprint_not_persisted.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_llm_providers.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_llm_test_endpoint.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_loop.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_mcp.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_memories_pagination.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_memory_stats.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_openclaw_loader.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_package_version.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_path_safety_2026_09_23.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_recall_as_of.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_recall_paths.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_recall_provenance.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_reflection.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_repo_framing.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_routes_audit_2026_09_13.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_routes_audit_2026_09_20.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_score_api.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_scoring_v2.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_secrets.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_serve_app.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_serve_handlers.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_session_order.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_short_query.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_snapshot.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_store.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_subgraph_hops_2026_09_23.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_summarization.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_universal_memory.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_vector_store.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_watcher.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_wiki_classifier.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_wiki_export_escape.py +0 -0
- {loop_memory-0.4.11 → loop_memory-0.4.12}/tests/test_wiki_prompts.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: loop-memory
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.12
|
|
4
4
|
Summary: A general-purpose, local memory system for every AI agent you run. Loop Memory auto-captures conversations from Codex / Claude / Hermes / OpenClaw, scores them by importance × recency × usage × feedback, distils them into a curated wiki, and serves everything from a single web UI.
|
|
5
5
|
Author: Loop Memory contributors <loop-memory@users.noreply.github.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -66,6 +66,8 @@ Dynamic: license-file
|
|
|
66
66
|
|
|
67
67
|
---
|
|
68
68
|
|
|
69
|
+
> **What's new in 0.4.12** — **OKF bundle import** + **DB-level audit enforcement** (audit 2026-09-27). The new `loop-memory import-okf <in_dir>` (and `POST /api/import/okf`) is the symmetric counterpart to `export-okf` (0.4.9) — bring an OKF v0.2 bundle back into Loop Memory as wiki pages, with idempotent upsert on `(scope, slug)`, optional `--dry-run` and `--skip-conflicts`. Source: `thecolourfoundation/rune` HN launch (MIT, 2026-09-25) + `okf-memory/okf-agent-memory` Issues #12-#15 + `Deja-Vu` (MIT, 2026-09-24) + Google OKF v0.2 spec (Apache-2.0, 2026-09-01). The new `MemoryStore._install_audit_triggers()` installs 12 SQLite triggers on `memories` / `wiki_pages` / `relations` / `consolidation_runs` so the `audit_log` table cannot be skipped — even a raw `sqlite3` writer that bypasses the Python wrapper still appends an audit row with `actor='db_trigger'`. New `MemoryStore.list_audit_log()` reads the log; `GET /api/stats` reports `audit_log` + `audit_triggers` counts. Source: `cogstate-eng/memory-eternal v0.4.3` `enforceAudit()` pattern (MIT, 2026-09-23). 31 new regression cases. [Full CHANGELOG →](./CHANGELOG.md#0412---2026-09-27)
|
|
70
|
+
|
|
69
71
|
> **What's new in 0.4.11** — **operational probes** +
|
|
70
72
|
**SQLite write-contention fix** (audit 2026-09-24). New
|
|
71
73
|
``GET /api/healthz`` (liveness) + ``GET /api/readyz``
|
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
25
|
+
> **What's new in 0.4.12** — **OKF bundle import** + **DB-level audit enforcement** (audit 2026-09-27). The new `loop-memory import-okf <in_dir>` (and `POST /api/import/okf`) is the symmetric counterpart to `export-okf` (0.4.9) — bring an OKF v0.2 bundle back into Loop Memory as wiki pages, with idempotent upsert on `(scope, slug)`, optional `--dry-run` and `--skip-conflicts`. Source: `thecolourfoundation/rune` HN launch (MIT, 2026-09-25) + `okf-memory/okf-agent-memory` Issues #12-#15 + `Deja-Vu` (MIT, 2026-09-24) + Google OKF v0.2 spec (Apache-2.0, 2026-09-01). The new `MemoryStore._install_audit_triggers()` installs 12 SQLite triggers on `memories` / `wiki_pages` / `relations` / `consolidation_runs` so the `audit_log` table cannot be skipped — even a raw `sqlite3` writer that bypasses the Python wrapper still appends an audit row with `actor='db_trigger'`. New `MemoryStore.list_audit_log()` reads the log; `GET /api/stats` reports `audit_log` + `audit_triggers` counts. Source: `cogstate-eng/memory-eternal v0.4.3` `enforceAudit()` pattern (MIT, 2026-09-23). 31 new regression cases. [Full CHANGELOG →](./CHANGELOG.md#0412---2026-09-27)
|
|
26
|
+
|
|
25
27
|
> **What's new in 0.4.11** — **operational probes** +
|
|
26
28
|
**SQLite write-contention fix** (audit 2026-09-24). New
|
|
27
29
|
``GET /api/healthz`` (liveness) + ``GET /api/readyz``
|
|
@@ -119,6 +119,23 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
119
119
|
eo.add_argument("--scope", default=None,
|
|
120
120
|
help="Filter: 'global' or a single source token (e.g. codex)")
|
|
121
121
|
|
|
122
|
+
# Audit 2026-09-27: OKF v0.2 bundle import
|
|
123
|
+
# (thecolourfoundation/rune + okf-memory/okf-agent-memory Issues
|
|
124
|
+
# #12-#15 + Deja-Vu HN front-page). Symmetric counterpart to
|
|
125
|
+
# ``export-okf`` (0.4.9): bring an OKF bundle back into Loop
|
|
126
|
+
# Memory as wiki pages. Idempotent upsert on (scope, slug).
|
|
127
|
+
io = sub.add_parser(
|
|
128
|
+
"import-okf",
|
|
129
|
+
help="Import an OKF v0.2 bundle directory as wiki pages")
|
|
130
|
+
io.add_argument("in_dir",
|
|
131
|
+
help="Bundle directory containing index.md and pages/")
|
|
132
|
+
io.add_argument("--scope", default=None,
|
|
133
|
+
help="Scope tag for imported pages (default: bundle's index.md, then 'global')")
|
|
134
|
+
io.add_argument("--dry-run", action="store_true",
|
|
135
|
+
help="Parse every file but do not write")
|
|
136
|
+
io.add_argument("--skip-conflicts", action="store_true",
|
|
137
|
+
help="Don't overwrite an existing (scope, slug) row")
|
|
138
|
+
|
|
122
139
|
return p
|
|
123
140
|
|
|
124
141
|
|
|
@@ -375,3 +392,32 @@ def run_export_okf(args) -> int:
|
|
|
375
392
|
s = MemoryStore(ns.db)
|
|
376
393
|
r = s.export_okf(ns.out_dir, scope_filter=ns.scope)
|
|
377
394
|
return _emit(r)
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
def run_import_okf(args) -> int:
|
|
398
|
+
"""``loop-memory import-okf <in_dir> [--scope S] [--dry-run] [--skip-conflicts]``
|
|
399
|
+
|
|
400
|
+
Audit 2026-09-27: OKF v0.2 bundle import
|
|
401
|
+
(thecolourfoundation/rune + okf-memory/okf-agent-memory Issues
|
|
402
|
+
#12-#15 + Deja-Vu HN front-page). Returns the summary dict
|
|
403
|
+
from ``MemoryStore.import_okf`` so the caller can confirm what
|
|
404
|
+
landed where. ``--dry-run`` parses every file but writes nothing;
|
|
405
|
+
``--skip-conflicts`` turns INSERT-vs-existing conflicts into
|
|
406
|
+
a ``skipped`` counter rather than an UPDATE.
|
|
407
|
+
"""
|
|
408
|
+
import argparse as _ap
|
|
409
|
+
p = _ap.ArgumentParser(prog="loop-memory import-okf")
|
|
410
|
+
p.add_argument("in_dir")
|
|
411
|
+
p.add_argument("--scope", default=None)
|
|
412
|
+
p.add_argument("--dry-run", action="store_true")
|
|
413
|
+
p.add_argument("--skip-conflicts", action="store_true")
|
|
414
|
+
p.add_argument("--db", default=os.environ.get("LOOP_MEMORY_DB", DEFAULT_DB))
|
|
415
|
+
ns = p.parse_args(args)
|
|
416
|
+
s = MemoryStore(ns.db)
|
|
417
|
+
r = s.import_okf(
|
|
418
|
+
ns.in_dir,
|
|
419
|
+
scope=ns.scope,
|
|
420
|
+
dry_run=ns.dry_run,
|
|
421
|
+
skip_conflicts=ns.skip_conflicts,
|
|
422
|
+
)
|
|
423
|
+
return _emit(r)
|
|
@@ -26,6 +26,7 @@ Usage:
|
|
|
26
26
|
loop-memory export <out_dir> # write a MEMORY.md bundle (v7)
|
|
27
27
|
loop-memory export-bundle <out_dir> # explicit v7 bundle alias
|
|
28
28
|
loop-memory import <in_dir> # re-hydrate a bundle
|
|
29
|
+
loop-memory import-okf <in_dir> [--scope S] [--dry-run] [--skip-conflicts] # ingest an OKF v0.2 bundle as wiki pages (audit 2026-09-27)
|
|
29
30
|
loop-memory fork [--branch-tag T] # snapshot every wiki page
|
|
30
31
|
loop-memory graph-edge <src> <dst> [--kind K] [--weight W] # push a relation
|
|
31
32
|
loop-memory subgraph <query> # print a small subgraph
|
|
@@ -128,6 +129,8 @@ COMMANDS = {
|
|
|
128
129
|
# Audit 2026-09-20 — OKF v0.2 export (akitaonrails/ai-memory 2.0
|
|
129
130
|
# + okf-agent-memory + Google OKF spec).
|
|
130
131
|
"export-okf": cognitive_cmd.run_export_okf,
|
|
132
|
+
# Audit 2026-09-27: OKF v0.2 bundle import (rune + okf-agent-memory #12-#15 + Deja-Vu).
|
|
133
|
+
"import-okf": cognitive_cmd.run_import_okf,
|
|
131
134
|
"rules": rules_cmd.run_rules,
|
|
132
135
|
"version": _run_version,
|
|
133
136
|
}
|
|
@@ -172,6 +175,7 @@ COMMAND_HELP: dict[str, str] = {
|
|
|
172
175
|
"memory-stats": "loop-memory memory-stats <id> [--prefix] # per-memory lifetime stats (audit 2026-09-06, agentmemory v1.3.0).",
|
|
173
176
|
"snapshot": "loop-memory snapshot <out.memory.sqlite> # write a portable SQLite snapshot (audit 2026-09-06, codexa-memory v0.2.0).",
|
|
174
177
|
"export-okf": "loop-memory export-okf <out_dir> [--scope S] # write an OKF v0.2 bundle (audit 2026-09-20).",
|
|
178
|
+
"import-okf": "loop-memory import-okf <in_dir> [--scope S] [--dry-run] [--skip-conflicts] # ingest an OKF v0.2 bundle as wiki pages (audit 2026-09-27).",
|
|
175
179
|
"restore": "loop-memory restore <in.memory.sqlite> # re-hydrate a portable SQLite snapshot.",
|
|
176
180
|
# Audit 2026-09-13 — L0 outline recall (tigerless-labs/agent-memory v0.3.0).
|
|
177
181
|
"recall-paths": "loop-memory recall-paths <query> [--limit N] # cheap L0 outline (id+abstract+score) instead of full text (audit 2026-09-13).",
|
|
@@ -485,6 +485,49 @@ def register(app: FastAPI, store: MemoryStore, scheduler: Optional[Any] = None,
|
|
|
485
485
|
raise HTTPException(500, f"export-okf failed: {e}")
|
|
486
486
|
return r
|
|
487
487
|
|
|
488
|
+
@app.post("/api/import/okf")
|
|
489
|
+
def import_okf(body: dict):
|
|
490
|
+
"""Audit 2026-09-27: OKF v0.2 bundle import.
|
|
491
|
+
|
|
492
|
+
Body shape::
|
|
493
|
+
|
|
494
|
+
{
|
|
495
|
+
"in_dir": "/abs/path/to/bundle",
|
|
496
|
+
"scope": "global", # optional
|
|
497
|
+
"dry_run": false, # optional
|
|
498
|
+
"skip_conflicts": false # optional
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
Walks ``<in_dir>/index.md`` + ``<in_dir>/pages/*.md`` and
|
|
502
|
+
upserts each page as a wiki row keyed on ``(scope, slug)``.
|
|
503
|
+
``in_dir`` is validated by ``_safe_resolve_path`` (live DB
|
|
504
|
+
+ system dirs are still refused; per-user temp is OK).
|
|
505
|
+
Returns the same summary dict as the CLI handler.
|
|
506
|
+
"""
|
|
507
|
+
from ._shared import _safe_resolve_path as _safe_path
|
|
508
|
+
in_dir = (body.get("in_dir") or "").strip()
|
|
509
|
+
if not in_dir:
|
|
510
|
+
raise HTTPException(400, "in_dir is required")
|
|
511
|
+
scope = body.get("scope")
|
|
512
|
+
if scope is not None:
|
|
513
|
+
scope = str(scope).strip() or None
|
|
514
|
+
dry_run = bool(body.get("dry_run", False))
|
|
515
|
+
skip_conflicts = bool(body.get("skip_conflicts", False))
|
|
516
|
+
try:
|
|
517
|
+
safe_dir = _safe_path(in_dir, kind="read", live_db_path=str(store.path))
|
|
518
|
+
except ValueError as e:
|
|
519
|
+
raise HTTPException(400, str(e))
|
|
520
|
+
try:
|
|
521
|
+
r = store.import_okf(
|
|
522
|
+
safe_dir,
|
|
523
|
+
scope=scope,
|
|
524
|
+
dry_run=dry_run,
|
|
525
|
+
skip_conflicts=skip_conflicts,
|
|
526
|
+
)
|
|
527
|
+
except Exception as e:
|
|
528
|
+
raise HTTPException(500, f"import-okf failed: {e}")
|
|
529
|
+
return r
|
|
530
|
+
|
|
488
531
|
@app.get("/api/recall/outline")
|
|
489
532
|
def recall_outline(query: str = "", limit: int = 12,
|
|
490
533
|
include: str = "memories,wiki,entities",
|