agmem 0.1.3__tar.gz → 0.1.5__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.
- {agmem-0.1.3/agmem.egg-info → agmem-0.1.5}/PKG-INFO +24 -18
- {agmem-0.1.3 → agmem-0.1.5}/README.md +20 -17
- {agmem-0.1.3 → agmem-0.1.5/agmem.egg-info}/PKG-INFO +24 -18
- {agmem-0.1.3 → agmem-0.1.5}/agmem.egg-info/SOURCES.txt +7 -4
- {agmem-0.1.3 → agmem-0.1.5}/agmem.egg-info/requires.txt +4 -0
- {agmem-0.1.3 → agmem-0.1.5}/docs/CONFIG.md +12 -0
- agmem-0.1.5/docs/FEDERATED.md +73 -0
- agmem-0.1.5/docs/SEQUENTIAL_VALIDATION.md +22 -0
- {agmem-0.1.3 → agmem-0.1.5}/docs/TEST_REPORT.md +17 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/daemon.py +21 -3
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/distill.py +10 -2
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/federated.py +7 -1
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/garden.py +10 -2
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/gc.py +18 -1
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/prove.py +4 -2
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/timeline.py +28 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/when.py +28 -0
- agmem-0.1.5/memvcs/core/compression_pipeline.py +165 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/crypto_verify.py +12 -1
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/distiller.py +70 -4
- agmem-0.1.5/memvcs/core/federated.py +157 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/gardener.py +80 -5
- agmem-0.1.5/memvcs/core/ipfs_remote.py +199 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/knowledge_graph.py +79 -6
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/objects.py +33 -21
- agmem-0.1.5/memvcs/core/pack.py +292 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/remote.py +200 -3
- agmem-0.1.5/memvcs/core/zk_proofs.py +160 -0
- {agmem-0.1.3 → agmem-0.1.5}/pyproject.toml +6 -1
- agmem-0.1.5/tests/test_crypto_verify.py +120 -0
- {agmem-0.1.3 → agmem-0.1.5}/tests/test_encryption.py +23 -0
- agmem-0.1.5/tests/test_federated.py +68 -0
- agmem-0.1.5/tests/test_ipfs_remote.py +66 -0
- {agmem-0.1.3 → agmem-0.1.5}/tests/test_pack_gc.py +52 -1
- agmem-0.1.5/tests/test_privacy_budget.py +154 -0
- agmem-0.1.5/tests/test_zk_proofs.py +60 -0
- agmem-0.1.3/docs/aux/MARKET_POSITIONING.md +0 -168
- agmem-0.1.3/docs/aux/README.md +0 -7
- agmem-0.1.3/docs/aux/STRESS_TEST_REPORT.md +0 -47
- agmem-0.1.3/memvcs/core/federated.py +0 -86
- agmem-0.1.3/memvcs/core/ipfs_remote.py +0 -39
- agmem-0.1.3/memvcs/core/pack.py +0 -92
- agmem-0.1.3/memvcs/core/zk_proofs.py +0 -26
- agmem-0.1.3/tests/test_crypto_verify.py +0 -67
- agmem-0.1.3/tests/test_privacy_budget.py +0 -56
- {agmem-0.1.3 → agmem-0.1.5}/LICENSE +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/MANIFEST.in +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/agmem.egg-info/dependency_links.txt +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/agmem.egg-info/entry_points.txt +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/agmem.egg-info/top_level.txt +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/docs/AGMEM_PUBLISHING_SETUP.md +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/docs/GTM.md +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/docs/KNOWLEDGE_GRAPH.md +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/docs/aux/INSTALL.md +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/examples/basic_workflow.sh +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/__init__.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/cli.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/__init__.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/add.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/audit.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/base.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/blame.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/branch.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/checkout.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/clean.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/clone.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/commit.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/decay.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/diff.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/fsck.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/graph.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/init.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/log.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/mcp.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/merge.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/pack.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/pull.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/push.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/recall.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/reflog.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/remote.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/repair.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/reset.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/resolve.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/resurrect.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/search.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/serve.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/show.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/stash.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/status.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/tag.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/test.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/tree.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/commands/verify.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/__init__.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/access_index.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/audit.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/config_loader.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/consistency.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/constants.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/decay.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/diff.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/encryption.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/hooks.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/llm/__init__.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/llm/anthropic_provider.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/llm/base.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/llm/factory.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/llm/openai_provider.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/merge.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/pii_scanner.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/privacy_budget.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/refs.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/repository.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/schema.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/staging.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/storage/__init__.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/storage/base.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/storage/gcs.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/storage/local.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/storage/s3.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/temporal_index.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/test_runner.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/trust.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/core/vector_store.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/integrations/__init__.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/integrations/mcp_server.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/integrations/web_ui/__init__.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/integrations/web_ui/server.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/retrieval/__init__.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/retrieval/base.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/retrieval/pack.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/retrieval/recaller.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/retrieval/strategies.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/utils/__init__.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/memvcs/utils/helpers.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/setup.cfg +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/setup.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/tests/test_access_index.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/tests/test_advanced_commands.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/tests/test_audit.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/tests/test_commit_importance.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/tests/test_consistency.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/tests/test_decay.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/tests/test_edge_cases.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/tests/test_llm_provider.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/tests/test_objects.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/tests/test_pii.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/tests/test_plan_features.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/tests/test_repository.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/tests/test_resolve_helpers.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/tests/test_retrieval.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/tests/test_temporal_index.py +0 -0
- {agmem-0.1.3 → agmem-0.1.5}/tests/test_trust.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agmem
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
4
4
|
Summary: Agentic Memory Version Control System - Git for AI agent memories
|
|
5
5
|
Home-page: https://github.com/vivek-tiwari-vt/agmem
|
|
6
6
|
Author: agmem Team
|
|
@@ -33,6 +33,7 @@ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
|
33
33
|
Requires-Dist: black==24.10.0; extra == "dev"
|
|
34
34
|
Requires-Dist: flake8>=5.0.0; extra == "dev"
|
|
35
35
|
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
36
|
+
Requires-Dist: bandit[toml]>=1.7.0; extra == "dev"
|
|
36
37
|
Provides-Extra: llm
|
|
37
38
|
Requires-Dist: openai>=1.0.0; extra == "llm"
|
|
38
39
|
Requires-Dist: anthropic>=0.18.0; extra == "llm"
|
|
@@ -68,6 +69,8 @@ Provides-Extra: crypto
|
|
|
68
69
|
Requires-Dist: cryptography>=41.0.0; extra == "crypto"
|
|
69
70
|
Provides-Extra: ipfs
|
|
70
71
|
Requires-Dist: requests>=2.28.0; extra == "ipfs"
|
|
72
|
+
Provides-Extra: ipfs-daemon
|
|
73
|
+
Requires-Dist: ipfshttpclient>=0.8.0; extra == "ipfs-daemon"
|
|
71
74
|
Provides-Extra: all
|
|
72
75
|
Requires-Dist: mcp>=1.0.0; extra == "all"
|
|
73
76
|
Requires-Dist: cryptography>=41.0.0; extra == "all"
|
|
@@ -129,12 +132,12 @@ agmem solves all of these problems with a familiar Git-like interface.
|
|
|
129
132
|
- ✅ **Tamper-evident audit trail** — Append-only hash-chained log (init, add, commit, checkout, merge, push, pull, config); `agmem audit` and `agmem audit --verify`
|
|
130
133
|
- ✅ **Multi-agent trust** — Trust store (full / conditional / untrusted) per public key; applied on pull/merge; clone copies remote keys
|
|
131
134
|
- ✅ **Conflict resolution** — `agmem resolve` with ours/theirs/both; conflicts persisted in `.mem/merge/`; path-safe
|
|
132
|
-
- ✅ **Differential privacy** — Epsilon/delta budget in `.mem/privacy_budget.json`; `--private` on `agmem distill` and `agmem garden
|
|
133
|
-
- ✅ **Pack files & GC** — `agmem gc` (reachable from refs, prune loose, optional
|
|
135
|
+
- ✅ **Differential privacy** — Epsilon/delta budget in `.mem/privacy_budget.json`; `--private` on `agmem distill` and `agmem garden`; noise applied to counts and frontmatter
|
|
136
|
+
- ✅ **Pack files & GC** — `agmem gc [--repack]` (reachable from refs, prune loose, optional pack file + index); ObjectStore reads from pack when loose missing
|
|
134
137
|
- ✅ **Multi-provider LLM** — OpenAI and Anthropic via `memvcs.core.llm`; config/repo or env; used by gardener, distiller, consistency, merge
|
|
135
138
|
- ✅ **Temporal querying** — Point-in-time and range queries in temporal index; frontmatter timestamps
|
|
136
|
-
- ✅ **Federated collaboration** — `agmem federated push|pull
|
|
137
|
-
- ✅ **Zero-knowledge proofs** — `agmem prove` (
|
|
139
|
+
- ✅ **Federated collaboration** — `agmem federated push|pull`; real summaries (topic counts, fact hashes); optional DP on outbound; coordinator API in docs/FEDERATED.md
|
|
140
|
+
- ✅ **Zero-knowledge proofs** — `agmem prove` (hash/signature-based): keyword containment (Merkle set membership), memory freshness (signed timestamp)
|
|
138
141
|
- ✅ **Daemon health** — Periodic Merkle verification in daemon loop; safe auto-remediation hooks
|
|
139
142
|
- ✅ **GPU acceleration** — Vector store detects GPU for embedding model when available
|
|
140
143
|
- ✅ **Optional** — `serve`, `daemon` (watch + auto-commit), `garden` (episode archival), MCP server; install extras as needed
|
|
@@ -264,9 +267,9 @@ All commands are listed below. Highlights: **`agmem blame <file>`** (who changed
|
|
|
264
267
|
| `agmem verify [ref]` | Belief consistency (contradictions); use `--crypto` to verify commit Merkle/signature |
|
|
265
268
|
| `agmem audit [--verify] [--max n]` | Show tamper-evident audit log; `--verify` checks hash chain |
|
|
266
269
|
| `agmem resolve [path]` | Resolve merge conflicts (ours/theirs/both); path under `current/` |
|
|
267
|
-
| `agmem gc [--dry-run] [--prune-days n]` | Garbage collection: delete unreachable loose objects; optional
|
|
268
|
-
| `agmem prove --memory <path> --property keyword\|freshness --value <v> [-o out]` | Generate ZK proofs (
|
|
269
|
-
| `agmem federated push\|pull` | Federated collaboration (
|
|
270
|
+
| `agmem gc [--dry-run] [--repack] [--prune-days n]` | Garbage collection: delete unreachable loose objects; optional pack file creation |
|
|
271
|
+
| `agmem prove --memory <path> --property keyword\|freshness --value <v> [-o out]` | Generate ZK proofs (keyword: Merkle set membership; freshness: signed timestamp) |
|
|
272
|
+
| `agmem federated push\|pull` | Federated collaboration (real summaries, optional DP; requires coordinator in config) |
|
|
270
273
|
|
|
271
274
|
### Optional (install extras)
|
|
272
275
|
|
|
@@ -370,26 +373,26 @@ The following 18 capabilities are implemented (or stubbed) per the agmem feature
|
|
|
370
373
|
|
|
371
374
|
| # | Feature | Description |
|
|
372
375
|
|---|---------|-------------|
|
|
373
|
-
| **9** | **Decentralized storage (IPFS)** | Push/pull via
|
|
374
|
-
| **10** | **Pack files and garbage collection** | Pack loose objects into pack file + index; GC deletes unreachable
|
|
375
|
-
| **11** | **Enhanced cloud remote operations** | Push conflict detection
|
|
376
|
+
| **9** | **Decentralized storage (IPFS)** | Push/pull via gateway (POST /api/v0/add, GET /ipfs/<cid>). Bundle/unbundle in `memvcs.core.ipfs_remote`; optional `agmem[ipfs]`. |
|
|
377
|
+
| **10** | **Pack files and garbage collection** | Pack loose objects into pack file + index; GC deletes unreachable; ObjectStore reads from pack. **Command:** `agmem gc [--dry-run] [--repack] [--prune-days n]`. |
|
|
378
|
+
| **11** | **Enhanced cloud remote operations** | Push conflict detection; S3/GCS remotes with distributed locking (acquire before push/fetch, release in finally). Config: `lock_table` for S3. |
|
|
376
379
|
|
|
377
380
|
### Tier 5 — Intelligence and retrieval
|
|
378
381
|
|
|
379
382
|
| # | Feature | Description |
|
|
380
383
|
|---|---------|-------------|
|
|
381
384
|
| **12** | **Multi-provider LLM** | `memvcs.core.llm`: OpenAI and Anthropic; factory by config or env. Used by gardener, distiller, consistency checker, merge. Credentials via env (e.g. `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`). |
|
|
382
|
-
| **13** | **Enhanced semantic compression** | Multi-stage pipeline
|
|
383
|
-
| **14** | **Temporal querying and time-travel** | Point-in-time and range
|
|
384
|
-
| **15** | **Cross-memory relationship graph** | Knowledge graph
|
|
385
|
+
| **13** | **Enhanced semantic compression** | Multi-stage pipeline in `memvcs.core.compression_pipeline`: chunk, fact extraction, dedup by hash; hybrid retrieval in strategies. |
|
|
386
|
+
| **14** | **Temporal querying and time-travel** | Point-in-time and range in `memvcs.core.temporal_index`; CLI: `agmem when --from/--to`, `agmem timeline --from/--to`. |
|
|
387
|
+
| **15** | **Cross-memory relationship graph** | Knowledge graph: co-occurrence, causal edges; incremental-update docstring in `knowledge_graph.py`. |
|
|
385
388
|
|
|
386
389
|
### Tier 6 — Operations and maintenance
|
|
387
390
|
|
|
388
391
|
| # | Feature | Description |
|
|
389
392
|
|---|---------|-------------|
|
|
390
|
-
| **16** | **Automated memory health monitoring** | Daemon
|
|
391
|
-
| **17** | **GPU-accelerated operations** | Vector store
|
|
392
|
-
| **18** | **Test suite and quality** |
|
|
393
|
+
| **16** | **Automated memory health monitoring** | Daemon: configurable `daemon.health_check_interval_seconds` and `AGMEM_DAEMON_HEALTH_INTERVAL`; alert only on verify failure; suggest `agmem fsck`. |
|
|
394
|
+
| **17** | **GPU-accelerated operations** | Vector store `_device()` returns cuda/mps/cpu; model loaded with that device. |
|
|
395
|
+
| **18** | **Test suite and quality** | Tests: crypto (tampered blob, key missing), encryption (wrong key, corrupted ciphertext), privacy budget, pack/GC, ZK prove/verify, federated mock, IPFS bundle; see docs/TEST_REPORT.md. |
|
|
393
396
|
|
|
394
397
|
### New files and config (summary)
|
|
395
398
|
|
|
@@ -399,7 +402,10 @@ The following 18 capabilities are implemented (or stubbed) per the agmem feature
|
|
|
399
402
|
| `memvcs/core/audit.py` | Tamper-evident audit append and verify |
|
|
400
403
|
| `memvcs/core/trust.py` | Trust store (key → level) |
|
|
401
404
|
| `memvcs/core/privacy_budget.py` | Epsilon/delta budget for DP |
|
|
402
|
-
| `memvcs/core/pack.py` | Pack format, index, GC |
|
|
405
|
+
| `memvcs/core/pack.py` | Pack format, index, GC, repack |
|
|
406
|
+
| `memvcs/core/compression_pipeline.py` | Chunk, fact extraction, dedup; hybrid retrieval |
|
|
407
|
+
| `memvcs/core/zk_proofs.py` | Hash/signature-based proofs (keyword, freshness) |
|
|
408
|
+
| `docs/FEDERATED.md` | Coordinator API for federated push/pull |
|
|
403
409
|
| `memvcs/core/encryption.py` | AES-256-GCM, Argon2id, config |
|
|
404
410
|
| `memvcs/core/llm/` | LLM provider interface and OpenAI/Anthropic |
|
|
405
411
|
| `memvcs/core/zk_proofs.py` | ZK proof stubs |
|
|
@@ -37,12 +37,12 @@ agmem solves all of these problems with a familiar Git-like interface.
|
|
|
37
37
|
- ✅ **Tamper-evident audit trail** — Append-only hash-chained log (init, add, commit, checkout, merge, push, pull, config); `agmem audit` and `agmem audit --verify`
|
|
38
38
|
- ✅ **Multi-agent trust** — Trust store (full / conditional / untrusted) per public key; applied on pull/merge; clone copies remote keys
|
|
39
39
|
- ✅ **Conflict resolution** — `agmem resolve` with ours/theirs/both; conflicts persisted in `.mem/merge/`; path-safe
|
|
40
|
-
- ✅ **Differential privacy** — Epsilon/delta budget in `.mem/privacy_budget.json`; `--private` on `agmem distill` and `agmem garden
|
|
41
|
-
- ✅ **Pack files & GC** — `agmem gc` (reachable from refs, prune loose, optional
|
|
40
|
+
- ✅ **Differential privacy** — Epsilon/delta budget in `.mem/privacy_budget.json`; `--private` on `agmem distill` and `agmem garden`; noise applied to counts and frontmatter
|
|
41
|
+
- ✅ **Pack files & GC** — `agmem gc [--repack]` (reachable from refs, prune loose, optional pack file + index); ObjectStore reads from pack when loose missing
|
|
42
42
|
- ✅ **Multi-provider LLM** — OpenAI and Anthropic via `memvcs.core.llm`; config/repo or env; used by gardener, distiller, consistency, merge
|
|
43
43
|
- ✅ **Temporal querying** — Point-in-time and range queries in temporal index; frontmatter timestamps
|
|
44
|
-
- ✅ **Federated collaboration** — `agmem federated push|pull
|
|
45
|
-
- ✅ **Zero-knowledge proofs** — `agmem prove` (
|
|
44
|
+
- ✅ **Federated collaboration** — `agmem federated push|pull`; real summaries (topic counts, fact hashes); optional DP on outbound; coordinator API in docs/FEDERATED.md
|
|
45
|
+
- ✅ **Zero-knowledge proofs** — `agmem prove` (hash/signature-based): keyword containment (Merkle set membership), memory freshness (signed timestamp)
|
|
46
46
|
- ✅ **Daemon health** — Periodic Merkle verification in daemon loop; safe auto-remediation hooks
|
|
47
47
|
- ✅ **GPU acceleration** — Vector store detects GPU for embedding model when available
|
|
48
48
|
- ✅ **Optional** — `serve`, `daemon` (watch + auto-commit), `garden` (episode archival), MCP server; install extras as needed
|
|
@@ -172,9 +172,9 @@ All commands are listed below. Highlights: **`agmem blame <file>`** (who changed
|
|
|
172
172
|
| `agmem verify [ref]` | Belief consistency (contradictions); use `--crypto` to verify commit Merkle/signature |
|
|
173
173
|
| `agmem audit [--verify] [--max n]` | Show tamper-evident audit log; `--verify` checks hash chain |
|
|
174
174
|
| `agmem resolve [path]` | Resolve merge conflicts (ours/theirs/both); path under `current/` |
|
|
175
|
-
| `agmem gc [--dry-run] [--prune-days n]` | Garbage collection: delete unreachable loose objects; optional
|
|
176
|
-
| `agmem prove --memory <path> --property keyword\|freshness --value <v> [-o out]` | Generate ZK proofs (
|
|
177
|
-
| `agmem federated push\|pull` | Federated collaboration (
|
|
175
|
+
| `agmem gc [--dry-run] [--repack] [--prune-days n]` | Garbage collection: delete unreachable loose objects; optional pack file creation |
|
|
176
|
+
| `agmem prove --memory <path> --property keyword\|freshness --value <v> [-o out]` | Generate ZK proofs (keyword: Merkle set membership; freshness: signed timestamp) |
|
|
177
|
+
| `agmem federated push\|pull` | Federated collaboration (real summaries, optional DP; requires coordinator in config) |
|
|
178
178
|
|
|
179
179
|
### Optional (install extras)
|
|
180
180
|
|
|
@@ -278,26 +278,26 @@ The following 18 capabilities are implemented (or stubbed) per the agmem feature
|
|
|
278
278
|
|
|
279
279
|
| # | Feature | Description |
|
|
280
280
|
|---|---------|-------------|
|
|
281
|
-
| **9** | **Decentralized storage (IPFS)** | Push/pull via
|
|
282
|
-
| **10** | **Pack files and garbage collection** | Pack loose objects into pack file + index; GC deletes unreachable
|
|
283
|
-
| **11** | **Enhanced cloud remote operations** | Push conflict detection
|
|
281
|
+
| **9** | **Decentralized storage (IPFS)** | Push/pull via gateway (POST /api/v0/add, GET /ipfs/<cid>). Bundle/unbundle in `memvcs.core.ipfs_remote`; optional `agmem[ipfs]`. |
|
|
282
|
+
| **10** | **Pack files and garbage collection** | Pack loose objects into pack file + index; GC deletes unreachable; ObjectStore reads from pack. **Command:** `agmem gc [--dry-run] [--repack] [--prune-days n]`. |
|
|
283
|
+
| **11** | **Enhanced cloud remote operations** | Push conflict detection; S3/GCS remotes with distributed locking (acquire before push/fetch, release in finally). Config: `lock_table` for S3. |
|
|
284
284
|
|
|
285
285
|
### Tier 5 — Intelligence and retrieval
|
|
286
286
|
|
|
287
287
|
| # | Feature | Description |
|
|
288
288
|
|---|---------|-------------|
|
|
289
289
|
| **12** | **Multi-provider LLM** | `memvcs.core.llm`: OpenAI and Anthropic; factory by config or env. Used by gardener, distiller, consistency checker, merge. Credentials via env (e.g. `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`). |
|
|
290
|
-
| **13** | **Enhanced semantic compression** | Multi-stage pipeline
|
|
291
|
-
| **14** | **Temporal querying and time-travel** | Point-in-time and range
|
|
292
|
-
| **15** | **Cross-memory relationship graph** | Knowledge graph
|
|
290
|
+
| **13** | **Enhanced semantic compression** | Multi-stage pipeline in `memvcs.core.compression_pipeline`: chunk, fact extraction, dedup by hash; hybrid retrieval in strategies. |
|
|
291
|
+
| **14** | **Temporal querying and time-travel** | Point-in-time and range in `memvcs.core.temporal_index`; CLI: `agmem when --from/--to`, `agmem timeline --from/--to`. |
|
|
292
|
+
| **15** | **Cross-memory relationship graph** | Knowledge graph: co-occurrence, causal edges; incremental-update docstring in `knowledge_graph.py`. |
|
|
293
293
|
|
|
294
294
|
### Tier 6 — Operations and maintenance
|
|
295
295
|
|
|
296
296
|
| # | Feature | Description |
|
|
297
297
|
|---|---------|-------------|
|
|
298
|
-
| **16** | **Automated memory health monitoring** | Daemon
|
|
299
|
-
| **17** | **GPU-accelerated operations** | Vector store
|
|
300
|
-
| **18** | **Test suite and quality** |
|
|
298
|
+
| **16** | **Automated memory health monitoring** | Daemon: configurable `daemon.health_check_interval_seconds` and `AGMEM_DAEMON_HEALTH_INTERVAL`; alert only on verify failure; suggest `agmem fsck`. |
|
|
299
|
+
| **17** | **GPU-accelerated operations** | Vector store `_device()` returns cuda/mps/cpu; model loaded with that device. |
|
|
300
|
+
| **18** | **Test suite and quality** | Tests: crypto (tampered blob, key missing), encryption (wrong key, corrupted ciphertext), privacy budget, pack/GC, ZK prove/verify, federated mock, IPFS bundle; see docs/TEST_REPORT.md. |
|
|
301
301
|
|
|
302
302
|
### New files and config (summary)
|
|
303
303
|
|
|
@@ -307,7 +307,10 @@ The following 18 capabilities are implemented (or stubbed) per the agmem feature
|
|
|
307
307
|
| `memvcs/core/audit.py` | Tamper-evident audit append and verify |
|
|
308
308
|
| `memvcs/core/trust.py` | Trust store (key → level) |
|
|
309
309
|
| `memvcs/core/privacy_budget.py` | Epsilon/delta budget for DP |
|
|
310
|
-
| `memvcs/core/pack.py` | Pack format, index, GC |
|
|
310
|
+
| `memvcs/core/pack.py` | Pack format, index, GC, repack |
|
|
311
|
+
| `memvcs/core/compression_pipeline.py` | Chunk, fact extraction, dedup; hybrid retrieval |
|
|
312
|
+
| `memvcs/core/zk_proofs.py` | Hash/signature-based proofs (keyword, freshness) |
|
|
313
|
+
| `docs/FEDERATED.md` | Coordinator API for federated push/pull |
|
|
311
314
|
| `memvcs/core/encryption.py` | AES-256-GCM, Argon2id, config |
|
|
312
315
|
| `memvcs/core/llm/` | LLM provider interface and OpenAI/Anthropic |
|
|
313
316
|
| `memvcs/core/zk_proofs.py` | ZK proof stubs |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agmem
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
4
4
|
Summary: Agentic Memory Version Control System - Git for AI agent memories
|
|
5
5
|
Home-page: https://github.com/vivek-tiwari-vt/agmem
|
|
6
6
|
Author: agmem Team
|
|
@@ -33,6 +33,7 @@ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
|
33
33
|
Requires-Dist: black==24.10.0; extra == "dev"
|
|
34
34
|
Requires-Dist: flake8>=5.0.0; extra == "dev"
|
|
35
35
|
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
36
|
+
Requires-Dist: bandit[toml]>=1.7.0; extra == "dev"
|
|
36
37
|
Provides-Extra: llm
|
|
37
38
|
Requires-Dist: openai>=1.0.0; extra == "llm"
|
|
38
39
|
Requires-Dist: anthropic>=0.18.0; extra == "llm"
|
|
@@ -68,6 +69,8 @@ Provides-Extra: crypto
|
|
|
68
69
|
Requires-Dist: cryptography>=41.0.0; extra == "crypto"
|
|
69
70
|
Provides-Extra: ipfs
|
|
70
71
|
Requires-Dist: requests>=2.28.0; extra == "ipfs"
|
|
72
|
+
Provides-Extra: ipfs-daemon
|
|
73
|
+
Requires-Dist: ipfshttpclient>=0.8.0; extra == "ipfs-daemon"
|
|
71
74
|
Provides-Extra: all
|
|
72
75
|
Requires-Dist: mcp>=1.0.0; extra == "all"
|
|
73
76
|
Requires-Dist: cryptography>=41.0.0; extra == "all"
|
|
@@ -129,12 +132,12 @@ agmem solves all of these problems with a familiar Git-like interface.
|
|
|
129
132
|
- ✅ **Tamper-evident audit trail** — Append-only hash-chained log (init, add, commit, checkout, merge, push, pull, config); `agmem audit` and `agmem audit --verify`
|
|
130
133
|
- ✅ **Multi-agent trust** — Trust store (full / conditional / untrusted) per public key; applied on pull/merge; clone copies remote keys
|
|
131
134
|
- ✅ **Conflict resolution** — `agmem resolve` with ours/theirs/both; conflicts persisted in `.mem/merge/`; path-safe
|
|
132
|
-
- ✅ **Differential privacy** — Epsilon/delta budget in `.mem/privacy_budget.json`; `--private` on `agmem distill` and `agmem garden
|
|
133
|
-
- ✅ **Pack files & GC** — `agmem gc` (reachable from refs, prune loose, optional
|
|
135
|
+
- ✅ **Differential privacy** — Epsilon/delta budget in `.mem/privacy_budget.json`; `--private` on `agmem distill` and `agmem garden`; noise applied to counts and frontmatter
|
|
136
|
+
- ✅ **Pack files & GC** — `agmem gc [--repack]` (reachable from refs, prune loose, optional pack file + index); ObjectStore reads from pack when loose missing
|
|
134
137
|
- ✅ **Multi-provider LLM** — OpenAI and Anthropic via `memvcs.core.llm`; config/repo or env; used by gardener, distiller, consistency, merge
|
|
135
138
|
- ✅ **Temporal querying** — Point-in-time and range queries in temporal index; frontmatter timestamps
|
|
136
|
-
- ✅ **Federated collaboration** — `agmem federated push|pull
|
|
137
|
-
- ✅ **Zero-knowledge proofs** — `agmem prove` (
|
|
139
|
+
- ✅ **Federated collaboration** — `agmem federated push|pull`; real summaries (topic counts, fact hashes); optional DP on outbound; coordinator API in docs/FEDERATED.md
|
|
140
|
+
- ✅ **Zero-knowledge proofs** — `agmem prove` (hash/signature-based): keyword containment (Merkle set membership), memory freshness (signed timestamp)
|
|
138
141
|
- ✅ **Daemon health** — Periodic Merkle verification in daemon loop; safe auto-remediation hooks
|
|
139
142
|
- ✅ **GPU acceleration** — Vector store detects GPU for embedding model when available
|
|
140
143
|
- ✅ **Optional** — `serve`, `daemon` (watch + auto-commit), `garden` (episode archival), MCP server; install extras as needed
|
|
@@ -264,9 +267,9 @@ All commands are listed below. Highlights: **`agmem blame <file>`** (who changed
|
|
|
264
267
|
| `agmem verify [ref]` | Belief consistency (contradictions); use `--crypto` to verify commit Merkle/signature |
|
|
265
268
|
| `agmem audit [--verify] [--max n]` | Show tamper-evident audit log; `--verify` checks hash chain |
|
|
266
269
|
| `agmem resolve [path]` | Resolve merge conflicts (ours/theirs/both); path under `current/` |
|
|
267
|
-
| `agmem gc [--dry-run] [--prune-days n]` | Garbage collection: delete unreachable loose objects; optional
|
|
268
|
-
| `agmem prove --memory <path> --property keyword\|freshness --value <v> [-o out]` | Generate ZK proofs (
|
|
269
|
-
| `agmem federated push\|pull` | Federated collaboration (
|
|
270
|
+
| `agmem gc [--dry-run] [--repack] [--prune-days n]` | Garbage collection: delete unreachable loose objects; optional pack file creation |
|
|
271
|
+
| `agmem prove --memory <path> --property keyword\|freshness --value <v> [-o out]` | Generate ZK proofs (keyword: Merkle set membership; freshness: signed timestamp) |
|
|
272
|
+
| `agmem federated push\|pull` | Federated collaboration (real summaries, optional DP; requires coordinator in config) |
|
|
270
273
|
|
|
271
274
|
### Optional (install extras)
|
|
272
275
|
|
|
@@ -370,26 +373,26 @@ The following 18 capabilities are implemented (or stubbed) per the agmem feature
|
|
|
370
373
|
|
|
371
374
|
| # | Feature | Description |
|
|
372
375
|
|---|---------|-------------|
|
|
373
|
-
| **9** | **Decentralized storage (IPFS)** | Push/pull via
|
|
374
|
-
| **10** | **Pack files and garbage collection** | Pack loose objects into pack file + index; GC deletes unreachable
|
|
375
|
-
| **11** | **Enhanced cloud remote operations** | Push conflict detection
|
|
376
|
+
| **9** | **Decentralized storage (IPFS)** | Push/pull via gateway (POST /api/v0/add, GET /ipfs/<cid>). Bundle/unbundle in `memvcs.core.ipfs_remote`; optional `agmem[ipfs]`. |
|
|
377
|
+
| **10** | **Pack files and garbage collection** | Pack loose objects into pack file + index; GC deletes unreachable; ObjectStore reads from pack. **Command:** `agmem gc [--dry-run] [--repack] [--prune-days n]`. |
|
|
378
|
+
| **11** | **Enhanced cloud remote operations** | Push conflict detection; S3/GCS remotes with distributed locking (acquire before push/fetch, release in finally). Config: `lock_table` for S3. |
|
|
376
379
|
|
|
377
380
|
### Tier 5 — Intelligence and retrieval
|
|
378
381
|
|
|
379
382
|
| # | Feature | Description |
|
|
380
383
|
|---|---------|-------------|
|
|
381
384
|
| **12** | **Multi-provider LLM** | `memvcs.core.llm`: OpenAI and Anthropic; factory by config or env. Used by gardener, distiller, consistency checker, merge. Credentials via env (e.g. `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`). |
|
|
382
|
-
| **13** | **Enhanced semantic compression** | Multi-stage pipeline
|
|
383
|
-
| **14** | **Temporal querying and time-travel** | Point-in-time and range
|
|
384
|
-
| **15** | **Cross-memory relationship graph** | Knowledge graph
|
|
385
|
+
| **13** | **Enhanced semantic compression** | Multi-stage pipeline in `memvcs.core.compression_pipeline`: chunk, fact extraction, dedup by hash; hybrid retrieval in strategies. |
|
|
386
|
+
| **14** | **Temporal querying and time-travel** | Point-in-time and range in `memvcs.core.temporal_index`; CLI: `agmem when --from/--to`, `agmem timeline --from/--to`. |
|
|
387
|
+
| **15** | **Cross-memory relationship graph** | Knowledge graph: co-occurrence, causal edges; incremental-update docstring in `knowledge_graph.py`. |
|
|
385
388
|
|
|
386
389
|
### Tier 6 — Operations and maintenance
|
|
387
390
|
|
|
388
391
|
| # | Feature | Description |
|
|
389
392
|
|---|---------|-------------|
|
|
390
|
-
| **16** | **Automated memory health monitoring** | Daemon
|
|
391
|
-
| **17** | **GPU-accelerated operations** | Vector store
|
|
392
|
-
| **18** | **Test suite and quality** |
|
|
393
|
+
| **16** | **Automated memory health monitoring** | Daemon: configurable `daemon.health_check_interval_seconds` and `AGMEM_DAEMON_HEALTH_INTERVAL`; alert only on verify failure; suggest `agmem fsck`. |
|
|
394
|
+
| **17** | **GPU-accelerated operations** | Vector store `_device()` returns cuda/mps/cpu; model loaded with that device. |
|
|
395
|
+
| **18** | **Test suite and quality** | Tests: crypto (tampered blob, key missing), encryption (wrong key, corrupted ciphertext), privacy budget, pack/GC, ZK prove/verify, federated mock, IPFS bundle; see docs/TEST_REPORT.md. |
|
|
393
396
|
|
|
394
397
|
### New files and config (summary)
|
|
395
398
|
|
|
@@ -399,7 +402,10 @@ The following 18 capabilities are implemented (or stubbed) per the agmem feature
|
|
|
399
402
|
| `memvcs/core/audit.py` | Tamper-evident audit append and verify |
|
|
400
403
|
| `memvcs/core/trust.py` | Trust store (key → level) |
|
|
401
404
|
| `memvcs/core/privacy_budget.py` | Epsilon/delta budget for DP |
|
|
402
|
-
| `memvcs/core/pack.py` | Pack format, index, GC |
|
|
405
|
+
| `memvcs/core/pack.py` | Pack format, index, GC, repack |
|
|
406
|
+
| `memvcs/core/compression_pipeline.py` | Chunk, fact extraction, dedup; hybrid retrieval |
|
|
407
|
+
| `memvcs/core/zk_proofs.py` | Hash/signature-based proofs (keyword, freshness) |
|
|
408
|
+
| `docs/FEDERATED.md` | Coordinator API for federated push/pull |
|
|
403
409
|
| `memvcs/core/encryption.py` | AES-256-GCM, Argon2id, config |
|
|
404
410
|
| `memvcs/core/llm/` | LLM provider interface and OpenAI/Anthropic |
|
|
405
411
|
| `memvcs/core/zk_proofs.py` | ZK proof stubs |
|
|
@@ -11,13 +11,12 @@ agmem.egg-info/requires.txt
|
|
|
11
11
|
agmem.egg-info/top_level.txt
|
|
12
12
|
docs/AGMEM_PUBLISHING_SETUP.md
|
|
13
13
|
docs/CONFIG.md
|
|
14
|
+
docs/FEDERATED.md
|
|
14
15
|
docs/GTM.md
|
|
15
16
|
docs/KNOWLEDGE_GRAPH.md
|
|
17
|
+
docs/SEQUENTIAL_VALIDATION.md
|
|
16
18
|
docs/TEST_REPORT.md
|
|
17
19
|
docs/aux/INSTALL.md
|
|
18
|
-
docs/aux/MARKET_POSITIONING.md
|
|
19
|
-
docs/aux/README.md
|
|
20
|
-
docs/aux/STRESS_TEST_REPORT.md
|
|
21
20
|
examples/basic_workflow.sh
|
|
22
21
|
memvcs/__init__.py
|
|
23
22
|
memvcs/cli.py
|
|
@@ -69,6 +68,7 @@ memvcs/commands/when.py
|
|
|
69
68
|
memvcs/core/__init__.py
|
|
70
69
|
memvcs/core/access_index.py
|
|
71
70
|
memvcs/core/audit.py
|
|
71
|
+
memvcs/core/compression_pipeline.py
|
|
72
72
|
memvcs/core/config_loader.py
|
|
73
73
|
memvcs/core/consistency.py
|
|
74
74
|
memvcs/core/constants.py
|
|
@@ -127,6 +127,8 @@ tests/test_crypto_verify.py
|
|
|
127
127
|
tests/test_decay.py
|
|
128
128
|
tests/test_edge_cases.py
|
|
129
129
|
tests/test_encryption.py
|
|
130
|
+
tests/test_federated.py
|
|
131
|
+
tests/test_ipfs_remote.py
|
|
130
132
|
tests/test_llm_provider.py
|
|
131
133
|
tests/test_objects.py
|
|
132
134
|
tests/test_pack_gc.py
|
|
@@ -137,4 +139,5 @@ tests/test_repository.py
|
|
|
137
139
|
tests/test_resolve_helpers.py
|
|
138
140
|
tests/test_retrieval.py
|
|
139
141
|
tests/test_temporal_index.py
|
|
140
|
-
tests/test_trust.py
|
|
142
|
+
tests/test_trust.py
|
|
143
|
+
tests/test_zk_proofs.py
|
|
@@ -37,6 +37,7 @@ pytest-cov>=4.0.0
|
|
|
37
37
|
black==24.10.0
|
|
38
38
|
flake8>=5.0.0
|
|
39
39
|
mypy>=1.0.0
|
|
40
|
+
bandit[toml]>=1.7.0
|
|
40
41
|
|
|
41
42
|
[distill]
|
|
42
43
|
openai>=1.0.0
|
|
@@ -51,6 +52,9 @@ networkx>=3.0
|
|
|
51
52
|
[ipfs]
|
|
52
53
|
requests>=2.28.0
|
|
53
54
|
|
|
55
|
+
[ipfs-daemon]
|
|
56
|
+
ipfshttpclient>=0.8.0
|
|
57
|
+
|
|
54
58
|
[llm]
|
|
55
59
|
openai>=1.0.0
|
|
56
60
|
anthropic>=0.18.0
|
|
@@ -27,6 +27,8 @@ cloud:
|
|
|
27
27
|
lock_table: null # optional DynamoDB table for distributed locks
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
+
- When using **s3://** or **gs://** as a remote URL (`agmem remote add origin s3://bucket/prefix`), push and fetch **acquire a distributed lock** (DynamoDB for S3 when `lock_table` is set, or storage-based lock for GCS) before running and **release it** in a `finally` block. This prevents concurrent pushes/fetches from corrupting the remote.
|
|
31
|
+
|
|
30
32
|
- Set `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` in the environment (or use `~/.aws/credentials` and omit these in config).
|
|
31
33
|
- If `access_key_var` / `secret_key_var` are set, agmem resolves credentials with `os.getenv(var)` and passes them to the S3 client. If unset, boto3 uses its default credential chain.
|
|
32
34
|
|
|
@@ -44,6 +46,16 @@ cloud:
|
|
|
44
46
|
- **credentials_json_var**: Name of an env var whose value is a JSON string (service account key). Useful for CI; never put the JSON in the config file.
|
|
45
47
|
- If neither is set, GCS uses Application Default Credentials (`GOOGLE_APPLICATION_CREDENTIALS` or `gcloud auth`).
|
|
46
48
|
|
|
49
|
+
### Daemon health monitoring
|
|
50
|
+
|
|
51
|
+
```yaml
|
|
52
|
+
daemon:
|
|
53
|
+
health_check_interval_seconds: 3600 # periodic Merkle/signature check (default 3600); 0 to disable
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
- Override via env: `AGMEM_DAEMON_HEALTH_INTERVAL` (seconds).
|
|
57
|
+
- On verify failure the daemon only logs to stderr and suggests `agmem fsck`; no automatic destructive action.
|
|
58
|
+
|
|
47
59
|
### PII / hooks
|
|
48
60
|
|
|
49
61
|
```yaml
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Federated collaboration
|
|
2
|
+
|
|
3
|
+
Agmem can push local summaries to an external coordinator and pull merged summaries. No coordinator is shipped with the package; you run your own or use a third-party service.
|
|
4
|
+
|
|
5
|
+
## Configuration
|
|
6
|
+
|
|
7
|
+
In `.mem/config.json` or user config:
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{
|
|
11
|
+
"federated": {
|
|
12
|
+
"enabled": true,
|
|
13
|
+
"coordinator_url": "https://your-coordinator.example.com",
|
|
14
|
+
"memory_types": ["episodic", "semantic"],
|
|
15
|
+
"differential_privacy": {
|
|
16
|
+
"enabled": true,
|
|
17
|
+
"epsilon": 0.1,
|
|
18
|
+
"delta": 1e-5
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
- `coordinator_url`: Base URL of the coordinator (no trailing slash).
|
|
25
|
+
- `memory_types`: Which memory dirs to include in the summary.
|
|
26
|
+
- `differential_privacy.enabled`: If true, numeric fields in the summary are noised before push.
|
|
27
|
+
|
|
28
|
+
## Coordinator API
|
|
29
|
+
|
|
30
|
+
The coordinator must expose two endpoints.
|
|
31
|
+
|
|
32
|
+
### POST /push
|
|
33
|
+
|
|
34
|
+
**Request**
|
|
35
|
+
|
|
36
|
+
- Body: JSON object (local summary from `produce_local_summary`).
|
|
37
|
+
- `Content-Type: application/json`.
|
|
38
|
+
|
|
39
|
+
**Summary shape**
|
|
40
|
+
|
|
41
|
+
- `memory_types`: list of strings (e.g. `["episodic", "semantic"]`).
|
|
42
|
+
- `topics`: dict of memory type → integer count (file count per type; may be noised if DP enabled).
|
|
43
|
+
- `topic_hashes`: dict of memory type → list of topic labels (no raw content).
|
|
44
|
+
- `fact_count`: integer (total fact/file count; may be noised if DP enabled).
|
|
45
|
+
|
|
46
|
+
**Response**
|
|
47
|
+
|
|
48
|
+
- Status `200` or `201`: success.
|
|
49
|
+
- Any other status: push is considered failed (agmem reports the status).
|
|
50
|
+
|
|
51
|
+
### GET /pull
|
|
52
|
+
|
|
53
|
+
**Request**
|
|
54
|
+
|
|
55
|
+
- No body.
|
|
56
|
+
|
|
57
|
+
**Response**
|
|
58
|
+
|
|
59
|
+
- Status `200`: body is JSON (merged summary from coordinator).
|
|
60
|
+
- Any other status or failure: pull returns `None` (agmem reports failure).
|
|
61
|
+
|
|
62
|
+
The merged summary shape is defined by the coordinator (e.g. aggregated topic counts, list of topic labels from all agents). Agmem does not interpret it; it only prints the returned object.
|
|
63
|
+
|
|
64
|
+
## Commands
|
|
65
|
+
|
|
66
|
+
- `agmem federated push`: Produce local summary (with optional DP) and POST to coordinator `/push`.
|
|
67
|
+
- `agmem federated pull`: GET coordinator `/pull` and print merged summary.
|
|
68
|
+
|
|
69
|
+
## Security
|
|
70
|
+
|
|
71
|
+
- Use HTTPS for `coordinator_url`.
|
|
72
|
+
- Request timeout is 30 seconds.
|
|
73
|
+
- No authentication is built in; if the coordinator requires auth, you must extend the client (e.g. custom header or token in config) or run the coordinator behind a gateway that adds auth.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Sequential validation (post-implementation)
|
|
2
|
+
|
|
3
|
+
After completing the feature plan, validate main user flows and document gaps.
|
|
4
|
+
|
|
5
|
+
## Flows to validate
|
|
6
|
+
|
|
7
|
+
1. **init → add → commit → branch → merge** — Core Git-like workflow; unchanged.
|
|
8
|
+
2. **push/pull** — file:// unchanged; s3:///gs:// now use storage adapter + distributed lock (acquire before, release in finally).
|
|
9
|
+
3. **garden/distill with --private** — Budget checked and spent; add_noise applied to counts and frontmatter (Gardener: clusters_found, insights_generated, episodes_archived, source_episodes; Distiller: fact_count, confidence_score, clusters_processed, facts_extracted, episodes_archived).
|
|
10
|
+
4. **gc/repack** — run_gc deletes unreachable loose objects; --repack runs run_repack to pack reachable loose into pack file + index, then deletes those loose; ObjectStore.retrieve reads from pack when loose missing.
|
|
11
|
+
5. **prove/verify** — prove_keyword_containment (Merkle set membership) and prove_memory_freshness (signed timestamp) produce proofs; verify_proof checks them.
|
|
12
|
+
6. **federated push/pull** — produce_local_summary builds topic counts and topic_hashes; optional DP noising; push_updates/pull_merged HTTP to coordinator (no in-package server).
|
|
13
|
+
7. **IPFS** — push_to_ipfs bundles objects and POSTs to gateway /api/v0/add; pull_from_ipfs GETs by CID and unbundles into loose objects.
|
|
14
|
+
8. **when/timeline --from/--to** — Temporal range filter via TemporalIndex.range_query; only commits in range included.
|
|
15
|
+
9. **Daemon health** — health_check_interval from config or AGMEM_DAEMON_HEALTH_INTERVAL; on verify failure only stderr + suggest agmem fsck.
|
|
16
|
+
|
|
17
|
+
## Known gaps / edge cases
|
|
18
|
+
|
|
19
|
+
- **ZK freshness** — Requires AGMEM_SIGNING_PRIVATE_KEY (or AGMEM_SIGNING_PRIVATE_KEY_FILE) in env to produce proof; verify works with proof that embeds public_key_pem_b64.
|
|
20
|
+
- **IPFS gateway** — Many public gateways are read-only; POST /api/v0/add may fail. Use a writable gateway or local IPFS daemon (ipfshttpclient) for push.
|
|
21
|
+
- **Cloud remote** — Clone still uses parse_remote_url (file only); push/fetch support s3:// and gs:// with lock. Clone from s3/gs not implemented.
|
|
22
|
+
- **Pack** — Single pack file per run_repack; ObjectStore reads from first .idx found in objects/pack (no multi-pack merge yet).
|
|
@@ -76,6 +76,23 @@ This report is based on full-flow tests (`scripts/test_full_flow.py`), manual co
|
|
|
76
76
|
| StagedFile vs dict | ✅ Fixed | Commit and PII scanner use `_get_blob_hash` / `_get_blob_hash_from_staged` so both StagedFile and dict work. |
|
|
77
77
|
| diff_with_head bytes | ✅ Fixed | Tree content decoded from bytes before `json.loads`. |
|
|
78
78
|
|
|
79
|
+
### 1.8 Test suite (edge cases and coverage)
|
|
80
|
+
|
|
81
|
+
| Area | Status | Notes |
|
|
82
|
+
|------|--------|------|
|
|
83
|
+
| **Crypto** | ✅ Tests | Merkle build/verify, tampered blob fails verification, signature present but no public key. |
|
|
84
|
+
| **Encryption** | ✅ Tests | Round-trip, wrong key fails, corrupted ciphertext fails. |
|
|
85
|
+
| **Privacy budget** | ✅ Tests | load_budget, spend_epsilon, add_noise, Gardener/Distiller DP integration (mocked). |
|
|
86
|
+
| **Pack/GC** | ✅ Tests | list_loose_objects, run_gc, write_pack, retrieve_from_pack, ObjectStore read from pack, run_repack dry-run. |
|
|
87
|
+
| **ZK proofs** | ✅ Tests | prove_keyword_containment / verify_proof round-trip; keyword not in file returns False; freshness (skipped without signing key). |
|
|
88
|
+
| **Federated** | ✅ Tests | produce_local_summary (topic_hashes, fact_count), DP noising; push/pull with mock coordinator. |
|
|
89
|
+
| **IPFS** | ✅ Tests | parse_ipfs_url, bundle/unbundle round-trip; push/pull with mock gateway. |
|
|
90
|
+
|
|
91
|
+
### Security (vulnerability check)
|
|
92
|
+
|
|
93
|
+
- **Bandit**: Run `bandit -r memvcs -ll` (install with `pip install agmem[dev]` or `pip install bandit[toml]`). Fix any high/critical findings (path traversal, injection, insecure crypto).
|
|
94
|
+
- **Manual**: New and modified code reviewed for: path traversal (user paths under repo/current), injection (subprocess, HTTP, config), key handling (no keys in logs), dependency versions (known CVEs).
|
|
95
|
+
|
|
79
96
|
---
|
|
80
97
|
|
|
81
98
|
## 2. What Does Not Work or Is Limited
|
|
@@ -205,13 +205,29 @@ class DaemonCommand:
|
|
|
205
205
|
|
|
206
206
|
# Health monitoring: periodic integrity check (configurable interval)
|
|
207
207
|
last_health_check = 0
|
|
208
|
-
health_check_interval = 3600 # 1 hour
|
|
208
|
+
health_check_interval = 3600 # default 1 hour
|
|
209
|
+
try:
|
|
210
|
+
from ..core.config_loader import load_agmem_config
|
|
211
|
+
|
|
212
|
+
config = load_agmem_config(repo.root)
|
|
213
|
+
daemon_cfg = config.get("daemon") or {}
|
|
214
|
+
health_check_interval = int(daemon_cfg.get("health_check_interval_seconds", 3600))
|
|
215
|
+
if health_check_interval <= 0:
|
|
216
|
+
health_check_interval = 0
|
|
217
|
+
except Exception:
|
|
218
|
+
pass
|
|
219
|
+
env_interval = os.environ.get("AGMEM_DAEMON_HEALTH_INTERVAL")
|
|
220
|
+
if env_interval is not None:
|
|
221
|
+
try:
|
|
222
|
+
health_check_interval = int(env_interval)
|
|
223
|
+
except ValueError:
|
|
224
|
+
pass
|
|
209
225
|
|
|
210
226
|
try:
|
|
211
227
|
while running:
|
|
212
228
|
time.sleep(1)
|
|
213
229
|
|
|
214
|
-
# Periodic health check (Merkle/signature, optional)
|
|
230
|
+
# Periodic health check (Merkle/signature, optional). Alert only; no destructive action.
|
|
215
231
|
if (
|
|
216
232
|
health_check_interval
|
|
217
233
|
and (time.time() - last_health_check) >= health_check_interval
|
|
@@ -229,8 +245,10 @@ class DaemonCommand:
|
|
|
229
245
|
load_public_key(repo.mem_dir),
|
|
230
246
|
mem_dir=repo.mem_dir,
|
|
231
247
|
)
|
|
232
|
-
if not ok and err
|
|
248
|
+
if not ok and err:
|
|
233
249
|
sys.stderr.write(f"Health check: {err}\n")
|
|
250
|
+
if "tampered" in (err or "").lower():
|
|
251
|
+
sys.stderr.write("Run 'agmem fsck' for safe integrity check.\n")
|
|
234
252
|
except Exception:
|
|
235
253
|
pass
|
|
236
254
|
last_health_check = time.time()
|
|
@@ -53,21 +53,29 @@ class DistillCommand:
|
|
|
53
53
|
if code != 0:
|
|
54
54
|
return code
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
use_dp = getattr(args, "private", False)
|
|
57
|
+
dp_epsilon = None
|
|
58
|
+
dp_delta = None
|
|
59
|
+
if use_dp:
|
|
57
60
|
from ..core.privacy_budget import load_budget, spend_epsilon
|
|
58
61
|
|
|
59
|
-
spent, max_eps,
|
|
62
|
+
spent, max_eps, delta = load_budget(repo.mem_dir)
|
|
60
63
|
epsilon_cost = 0.1
|
|
61
64
|
if not spend_epsilon(repo.mem_dir, epsilon_cost):
|
|
62
65
|
print(f"Privacy budget exceeded (spent {spent:.2f}, max {max_eps}).")
|
|
63
66
|
return 1
|
|
64
67
|
if spent + epsilon_cost > max_eps * 0.8:
|
|
65
68
|
print(f"Privacy budget low: {spent + epsilon_cost:.2f}/{max_eps}")
|
|
69
|
+
dp_epsilon = 0.05
|
|
70
|
+
dp_delta = delta
|
|
66
71
|
|
|
67
72
|
config = DistillerConfig(
|
|
68
73
|
source_dir=args.source,
|
|
69
74
|
target_dir=args.target,
|
|
70
75
|
create_safety_branch=not args.no_branch,
|
|
76
|
+
use_dp=use_dp,
|
|
77
|
+
dp_epsilon=dp_epsilon,
|
|
78
|
+
dp_delta=dp_delta,
|
|
71
79
|
)
|
|
72
80
|
distiller = Distiller(repo, config)
|
|
73
81
|
|
|
@@ -38,7 +38,13 @@ class FederatedCommand:
|
|
|
38
38
|
return 1
|
|
39
39
|
|
|
40
40
|
if args.action == "push":
|
|
41
|
-
summary = produce_local_summary(
|
|
41
|
+
summary = produce_local_summary(
|
|
42
|
+
repo.root,
|
|
43
|
+
cfg["memory_types"],
|
|
44
|
+
use_dp=cfg.get("use_dp", False),
|
|
45
|
+
dp_epsilon=cfg.get("dp_epsilon") or 0.1,
|
|
46
|
+
dp_delta=cfg.get("dp_delta") or 1e-5,
|
|
47
|
+
)
|
|
42
48
|
msg = push_updates(repo.root, summary)
|
|
43
49
|
print(msg)
|
|
44
50
|
return 0 if "Pushed" in msg else 1
|
|
@@ -50,14 +50,19 @@ class GardenCommand:
|
|
|
50
50
|
if code != 0:
|
|
51
51
|
return code
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
use_dp = getattr(args, "private", False)
|
|
54
|
+
dp_epsilon = None
|
|
55
|
+
dp_delta = None
|
|
56
|
+
if use_dp:
|
|
54
57
|
from ..core.privacy_budget import load_budget, spend_epsilon
|
|
55
58
|
|
|
56
|
-
spent, max_eps,
|
|
59
|
+
spent, max_eps, delta = load_budget(repo.mem_dir)
|
|
57
60
|
epsilon_cost = 0.1
|
|
58
61
|
if not spend_epsilon(repo.mem_dir, epsilon_cost):
|
|
59
62
|
print(f"Privacy budget exceeded (spent {spent:.2f}, max {max_eps}).")
|
|
60
63
|
return 1
|
|
64
|
+
dp_epsilon = 0.05
|
|
65
|
+
dp_delta = delta
|
|
61
66
|
|
|
62
67
|
# Build config
|
|
63
68
|
config = GardenerConfig(
|
|
@@ -65,6 +70,9 @@ class GardenCommand:
|
|
|
65
70
|
auto_commit=not args.no_commit,
|
|
66
71
|
llm_provider=args.llm if args.llm != "none" else None,
|
|
67
72
|
llm_model=args.model,
|
|
73
|
+
use_dp=use_dp,
|
|
74
|
+
dp_epsilon=dp_epsilon,
|
|
75
|
+
dp_delta=dp_delta,
|
|
68
76
|
)
|
|
69
77
|
|
|
70
78
|
# Create gardener
|