octop-memory 0.9.9__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.
Files changed (128) hide show
  1. octop_memory-0.9.9/.gitignore +104 -0
  2. octop_memory-0.9.9/AGENTS.md +96 -0
  3. octop_memory-0.9.9/CHANGELOG.md +24 -0
  4. octop_memory-0.9.9/CONTRIBUTING.md +92 -0
  5. octop_memory-0.9.9/LICENSE +21 -0
  6. octop_memory-0.9.9/PKG-INFO +230 -0
  7. octop_memory-0.9.9/README.md +186 -0
  8. octop_memory-0.9.9/README_CN.md +183 -0
  9. octop_memory-0.9.9/SECURITY.md +28 -0
  10. octop_memory-0.9.9/assets/images/banner.jpeg +0 -0
  11. octop_memory-0.9.9/docs/agent/DECISIONS.md +162 -0
  12. octop_memory-0.9.9/docs/agent/GLOSSARY.md +24 -0
  13. octop_memory-0.9.9/docs/agent/HANDOFF.md +19 -0
  14. octop_memory-0.9.9/docs/agent/KNOWN_RISKS.md +20 -0
  15. octop_memory-0.9.9/docs/agent/PROJECT_MAP.md +71 -0
  16. octop_memory-0.9.9/docs/agent/README_AUDIT.md +21 -0
  17. octop_memory-0.9.9/docs/agent/TEST_MATRIX.md +40 -0
  18. octop_memory-0.9.9/docs/integrations.md +222 -0
  19. octop_memory-0.9.9/pyproject.toml +173 -0
  20. octop_memory-0.9.9/src/octop_memory/__init__.py +56 -0
  21. octop_memory-0.9.9/src/octop_memory/_config_io.py +98 -0
  22. octop_memory-0.9.9/src/octop_memory/adapters/__init__.py +1 -0
  23. octop_memory-0.9.9/src/octop_memory/adapters/bridge/__init__.py +37 -0
  24. octop_memory-0.9.9/src/octop_memory/adapters/bridge/handlers.py +125 -0
  25. octop_memory-0.9.9/src/octop_memory/adapters/bridge/server.py +343 -0
  26. octop_memory-0.9.9/src/octop_memory/adapters/cli/__init__.py +130 -0
  27. octop_memory-0.9.9/src/octop_memory/adapters/cli/atom_cmd.py +143 -0
  28. octop_memory-0.9.9/src/octop_memory/adapters/cli/candidate_cmd.py +795 -0
  29. octop_memory-0.9.9/src/octop_memory/adapters/cli/checkpoint_cmd.py +81 -0
  30. octop_memory-0.9.9/src/octop_memory/adapters/cli/config.py +155 -0
  31. octop_memory-0.9.9/src/octop_memory/adapters/cli/consolidate_cmd.py +123 -0
  32. octop_memory-0.9.9/src/octop_memory/adapters/cli/dashboard.py +125 -0
  33. octop_memory-0.9.9/src/octop_memory/adapters/cli/db_cmd.py +265 -0
  34. octop_memory-0.9.9/src/octop_memory/adapters/cli/entity_cmd.py +121 -0
  35. octop_memory-0.9.9/src/octop_memory/adapters/cli/episode_cmd.py +239 -0
  36. octop_memory-0.9.9/src/octop_memory/adapters/cli/gc_cmd.py +97 -0
  37. octop_memory-0.9.9/src/octop_memory/adapters/cli/journal_cmd.py +114 -0
  38. octop_memory-0.9.9/src/octop_memory/adapters/cli/memory_cmd.py +290 -0
  39. octop_memory-0.9.9/src/octop_memory/adapters/cli/migration_cmd.py +330 -0
  40. octop_memory-0.9.9/src/octop_memory/adapters/cli/openclaw_cmd.py +624 -0
  41. octop_memory-0.9.9/src/octop_memory/adapters/cli/page_cmd.py +267 -0
  42. octop_memory-0.9.9/src/octop_memory/adapters/cli/portable_cmd.py +279 -0
  43. octop_memory-0.9.9/src/octop_memory/adapters/cli/raw_cmd.py +229 -0
  44. octop_memory-0.9.9/src/octop_memory/adapters/cli/recall_cmd.py +127 -0
  45. octop_memory-0.9.9/src/octop_memory/adapters/cli/slim_cmd.py +84 -0
  46. octop_memory-0.9.9/src/octop_memory/adapters/cli/thread_cmd.py +152 -0
  47. octop_memory-0.9.9/src/octop_memory/adapters/dashboard/__init__.py +8 -0
  48. octop_memory-0.9.9/src/octop_memory/adapters/dashboard/server.py +712 -0
  49. octop_memory-0.9.9/src/octop_memory/adapters/dashboard/static/index.html +892 -0
  50. octop_memory-0.9.9/src/octop_memory/application/__init__.py +1 -0
  51. octop_memory-0.9.9/src/octop_memory/application/checkpoint_maintenance.py +28 -0
  52. octop_memory-0.9.9/src/octop_memory/application/config.py +71 -0
  53. octop_memory-0.9.9/src/octop_memory/application/dashboard_data.py +1217 -0
  54. octop_memory-0.9.9/src/octop_memory/application/host_files.py +512 -0
  55. octop_memory-0.9.9/src/octop_memory/application/path_projection.py +349 -0
  56. octop_memory-0.9.9/src/octop_memory/application/runtime.py +1057 -0
  57. octop_memory-0.9.9/src/octop_memory/core.py +1856 -0
  58. octop_memory-0.9.9/src/octop_memory/domain/__init__.py +1 -0
  59. octop_memory-0.9.9/src/octop_memory/domain/alias.py +43 -0
  60. octop_memory-0.9.9/src/octop_memory/domain/datetime.py +23 -0
  61. octop_memory-0.9.9/src/octop_memory/operations/__init__.py +1 -0
  62. octop_memory-0.9.9/src/octop_memory/operations/migration/__init__.py +45 -0
  63. octop_memory-0.9.9/src/octop_memory/operations/migration/backfill.py +282 -0
  64. octop_memory-0.9.9/src/octop_memory/operations/migration/export.py +304 -0
  65. octop_memory-0.9.9/src/octop_memory/operations/migration/import_.py +384 -0
  66. octop_memory-0.9.9/src/octop_memory/operations/migration/portable/__init__.py +84 -0
  67. octop_memory-0.9.9/src/octop_memory/operations/migration/portable/adopter.py +469 -0
  68. octop_memory-0.9.9/src/octop_memory/operations/migration/portable/doctor.py +377 -0
  69. octop_memory-0.9.9/src/octop_memory/operations/migration/portable/models.py +254 -0
  70. octop_memory-0.9.9/src/octop_memory/operations/migration/portable/packer.py +264 -0
  71. octop_memory-0.9.9/src/octop_memory/operations/migration/portable/sources.py +246 -0
  72. octop_memory-0.9.9/src/octop_memory/operations/migration/preview.py +95 -0
  73. octop_memory-0.9.9/src/octop_memory/operations/migration/rename.py +420 -0
  74. octop_memory-0.9.9/src/octop_memory/pipeline/__init__.py +1 -0
  75. octop_memory-0.9.9/src/octop_memory/pipeline/episode/__init__.py +365 -0
  76. octop_memory-0.9.9/src/octop_memory/pipeline/episode/digest.py +496 -0
  77. octop_memory-0.9.9/src/octop_memory/pipeline/episode/prompts.py +157 -0
  78. octop_memory-0.9.9/src/octop_memory/pipeline/extractor/__init__.py +265 -0
  79. octop_memory-0.9.9/src/octop_memory/pipeline/extractor/parser.py +394 -0
  80. octop_memory-0.9.9/src/octop_memory/pipeline/extractor/prompts.py +454 -0
  81. octop_memory-0.9.9/src/octop_memory/pipeline/lifecycle/__init__.py +79 -0
  82. octop_memory-0.9.9/src/octop_memory/pipeline/lifecycle/checkpoint_gc.py +604 -0
  83. octop_memory-0.9.9/src/octop_memory/pipeline/lifecycle/consolidate.py +368 -0
  84. octop_memory-0.9.9/src/octop_memory/pipeline/lifecycle/gc.py +368 -0
  85. octop_memory-0.9.9/src/octop_memory/pipeline/lifecycle/maintenance.py +337 -0
  86. octop_memory-0.9.9/src/octop_memory/pipeline/lifecycle/vacuum.py +626 -0
  87. octop_memory-0.9.9/src/octop_memory/pipeline/page/__init__.py +54 -0
  88. octop_memory-0.9.9/src/octop_memory/pipeline/page/headline.py +58 -0
  89. octop_memory-0.9.9/src/octop_memory/pipeline/page/prompts.py +110 -0
  90. octop_memory-0.9.9/src/octop_memory/pipeline/page/regenerator.py +407 -0
  91. octop_memory-0.9.9/src/octop_memory/pipeline/page/trigger.py +73 -0
  92. octop_memory-0.9.9/src/octop_memory/pipeline/page/user_notes.py +105 -0
  93. octop_memory-0.9.9/src/octop_memory/pipeline/promotion/__init__.py +629 -0
  94. octop_memory-0.9.9/src/octop_memory/pipeline/promotion/checks.py +711 -0
  95. octop_memory-0.9.9/src/octop_memory/pipeline/promotion/fallback.py +294 -0
  96. octop_memory-0.9.9/src/octop_memory/pipeline/promotion/llm_hook.py +265 -0
  97. octop_memory-0.9.9/src/octop_memory/pipeline/recall/__init__.py +568 -0
  98. octop_memory-0.9.9/src/octop_memory/pipeline/recall/budget.py +164 -0
  99. octop_memory-0.9.9/src/octop_memory/pipeline/recall/cache.py +100 -0
  100. octop_memory-0.9.9/src/octop_memory/pipeline/recall/diversify.py +67 -0
  101. octop_memory-0.9.9/src/octop_memory/pipeline/recall/multi_source.py +471 -0
  102. octop_memory-0.9.9/src/octop_memory/pipeline/recall/parser.py +273 -0
  103. octop_memory-0.9.9/src/octop_memory/pipeline/recall/rerank.py +298 -0
  104. octop_memory-0.9.9/src/octop_memory/pipeline/recall/router.py +118 -0
  105. octop_memory-0.9.9/src/octop_memory/pipeline/recall/suppress.py +115 -0
  106. octop_memory-0.9.9/src/octop_memory/pipeline/recall/thread_state.py +148 -0
  107. octop_memory-0.9.9/src/octop_memory/pipeline/recall/timeout.py +123 -0
  108. octop_memory-0.9.9/src/octop_memory/ports/__init__.py +1 -0
  109. octop_memory-0.9.9/src/octop_memory/ports/llm/__init__.py +47 -0
  110. octop_memory-0.9.9/src/octop_memory/ports/llm/_protocol.py +104 -0
  111. octop_memory-0.9.9/src/octop_memory/ports/llm/mock.py +104 -0
  112. octop_memory-0.9.9/src/octop_memory/ports/llm/openai_compat.py +217 -0
  113. octop_memory-0.9.9/src/octop_memory/service.py +275 -0
  114. octop_memory-0.9.9/src/octop_memory/storage/__init__.py +1 -0
  115. octop_memory-0.9.9/src/octop_memory/storage/backends/__init__.py +606 -0
  116. octop_memory-0.9.9/src/octop_memory/storage/backends/fts_text.py +91 -0
  117. octop_memory-0.9.9/src/octop_memory/storage/backends/postgres.py +2540 -0
  118. octop_memory-0.9.9/src/octop_memory/storage/backends/sqlite.py +2429 -0
  119. octop_memory-0.9.9/src/octop_memory/storage/backends/sqlite_checkpoint.py +219 -0
  120. octop_memory-0.9.9/src/octop_memory/storage/backends/sqlite_checkpoint_job.py +114 -0
  121. octop_memory-0.9.9/src/octop_memory/storage/backends/sqlite_checkpoint_live.py +88 -0
  122. octop_memory-0.9.9/src/octop_memory/storage/backends/sqlite_checkpoint_maintenance.py +267 -0
  123. octop_memory-0.9.9/src/octop_memory/storage/driver_errors.py +64 -0
  124. octop_memory-0.9.9/src/octop_memory/storage/vector/__init__.py +104 -0
  125. octop_memory-0.9.9/src/octop_memory/storage/vector/chroma.py +168 -0
  126. octop_memory-0.9.9/src/octop_memory/storage/vector/embeddings.py +262 -0
  127. octop_memory-0.9.9/src/octop_memory/storage/vector/qdrant.py +199 -0
  128. octop_memory-0.9.9/src/octop_memory/types.py +568 -0
@@ -0,0 +1,104 @@
1
+ # OS
2
+ .DS_Store
3
+ .DS_Store?
4
+ ._*
5
+ .Spotlight-V100
6
+ .Trashes
7
+ Thumbs.db
8
+ ehthumbs.db
9
+ Desktop.ini
10
+
11
+ # Environment / secrets
12
+ .env
13
+ .env.*
14
+ !.env.example
15
+
16
+ # Python
17
+ __pycache__/
18
+ *.py[cod]
19
+ *$py.class
20
+ *.so
21
+ .Python
22
+ build/
23
+ dist/
24
+ *.egg-info/
25
+ *.egg
26
+ .eggs/
27
+ wheels/
28
+ *.whl
29
+ pip-wheel-metadata/
30
+
31
+ # Virtual environments
32
+ .venv/
33
+ venv/
34
+ env/
35
+ ENV/
36
+
37
+ # Node
38
+ # hatchling only honours the ROOT .gitignore when collecting sdist files, so a
39
+ # nested plugins/openclaw/octopmemory/.gitignore is not enough: a local
40
+ # `npm install` (373MB / ~17k files) ends up inside the published sdist.
41
+ node_modules/
42
+
43
+ # Test / coverage
44
+ .pytest_cache/
45
+ .mypy_cache/
46
+ .ruff_cache/
47
+ .coverage
48
+ .coverage.*
49
+ htmlcov/
50
+ coverage.xml
51
+ .tox/
52
+ .nox/
53
+ .hypothesis/
54
+
55
+ # IDE / editors
56
+ .vscode/
57
+ .idea/
58
+ *.swp
59
+ *.swo
60
+ *~
61
+ .project
62
+ .pydevproject
63
+
64
+ # uv
65
+ .uv/
66
+
67
+ # hatch-vcs auto-generated version file
68
+ src/octop_memory/_version.py
69
+
70
+ # Personal assistant settings; shared project rules live in AGENTS.md.
71
+ /.codebuddy/
72
+ /.cursor/
73
+ /.claude/
74
+ # Local database diagnostics, never public fixtures.
75
+ /scripts/_smoke_dashboard.py
76
+ *.hmpkg
77
+ *.sqlite.bak
78
+ *.sqlite.before-slim.*.bak
79
+ *.db-journal
80
+ *.sqlite3
81
+ *.sqlite3-wal
82
+ *.sqlite3-shm
83
+
84
+ # 本地规划文档(开发期 planning,不外发)
85
+ /docs/plans/*.md
86
+
87
+ # 本地集成自检脚本(dogfood,不属于对外示例)
88
+ /examples/dogfood_*.py
89
+
90
+ # Local-only checkpoint benchmark
91
+ /scripts/benchmark_checkpoint_storage.py
92
+
93
+ # Local databases
94
+ *.sqlite
95
+ *.sqlite-journal
96
+ *.sqlite-wal
97
+ *.sqlite-shm
98
+ *.db
99
+ *.db-wal
100
+ *.db-shm
101
+
102
+ # Logs
103
+ *.log
104
+ logs/
@@ -0,0 +1,96 @@
1
+ # AGENTS.md
2
+
3
+ 本文件是所有 coding agent 共用的工作协议。用户入口见 [README_CN.md](README_CN.md),
4
+ 贡献入口见 [CONTRIBUTING.md](CONTRIBUTING.md),项目认知保留在 `docs/agent/`,宿主接入见
5
+ [docs/integrations.md](docs/integrations.md)。沿用 Harness 的澄清、实现、验证、文档对齐闭环。
6
+
7
+ ## 项目速览
8
+
9
+ `octop-memory` 是可独立使用的 Agent 记忆组件,为 Octop 及其他宿主提供记忆能力。
10
+ 本仓负责证据捕获、事实提炼、召回、存储与迁移;Agent 执行、模型调用调度和用户界面由宿主组织。
11
+ 核心是 stdlib + SQLite,PostgreSQL、向量索引和 LLM 通过可选后端/接口接入。
12
+
13
+ - 公共入口:`Memory`(`core.py`)与 `MemoryService`(`service.py`);共享编排在 `application/`。
14
+ - 业务流水线在 `pipeline/`,持久化在 `storage/`;CLI / JSON-RPC 在 `adapters/`。
15
+ - `plugins/<host>/` 是外部 Agent 适配目录;当前实现包括 OpenClaw、Hermes,新增宿主复用共享业务逻辑。
16
+ - 按任务找代码和验证入口,见 [PROJECT_MAP](docs/agent/PROJECT_MAP.md) 与 [TEST_MATRIX](docs/agent/TEST_MATRIX.md)。
17
+
18
+ ## 工作方式
19
+
20
+ - 开始前检查 `git status --short` 和相关 diff,保留用户已有改动。
21
+ - 非平凡改动先说明目标、涉及文件、预期行为、最小验证和风险;大任务分阶段,保持范围聚焦。
22
+ - 代码、测试、配置和文档同步更新;不顺手重构无关模块,不为每次任务新增文档。
23
+ - 中文解释设计,保留代码实体、字段、CLI、环境变量与错误信息原文。
24
+ - 示例使用通用占位符和临时数据库,不提交私人路径、运行记录、凭据、导出记忆或真实数据库。
25
+
26
+ ## Harness 文档闭环
27
+
28
+ **记录范围**:`docs/agent/` 用于理解代码和接续开发,记录业务逻辑、架构、public API、数据契约、
29
+ 召回/写入行为,以及相关 bug、新需求、设计取舍和未解决风险。
30
+ banner、排版、措辞、链接、Python 版本、依赖/锁文件、构建/CI 和个人工具配置等常规维护,
31
+ 只更新对应文件及必要的 README/CONTRIBUTING/CHANGELOG,不写入 Harness,也不为此新建 HANDOFF 或 ADR。
32
+ 若这类维护同时改变了运行行为或数据契约,仅记录其代码影响,不记录维护操作流水账。
33
+ 以下回写要求仅适用于上述代码相关范围;判断依据是实际影响,不是改动文件数量或是否修改了代码文件。
34
+
35
+ 1. **入场核对**:快速扫描相关代码、diff 与近期相关提交,对照 [HANDOFF](docs/agent/HANDOFF.md)
36
+ 和 [PROJECT_MAP](docs/agent/PROJECT_MAP.md)。核对召回 source/顺序、public API、配置、prompt 与验证命令;
37
+ 不依赖日期或提交数推断新鲜度。发现漂移,修正相关描述;范围外缺口记入 [KNOWN_RISKS](docs/agent/KNOWN_RISKS.md)。
38
+ 2. **文本澄清**:在现有 Issue / PR 或 HANDOFF 中写明 bug 的实际/预期行为、最小复现,
39
+ 或需求的使用场景、范围/不做什么、可验证验收条件;列出假设和待澄清问题。
40
+ 会改变范围、兼容性或数据安全的未决问题需先澄清;已明确授权的工作继续执行,不重复索要确认。
41
+ 3. **实现与验证**:按最小可验证闭环实现,运行相关测试及完整门禁。涉及召回/写入或双 backend 时执行下述硬规则。
42
+ 4. **认知回写**:代码相关的非平凡任务更新 HANDOFF 的当前状态、关键文件、验证结果、风险与下一步;
43
+ 模块/调用链/运行策略配置变更更新 PROJECT_MAP;重要代码取舍更新 [DECISIONS](docs/agent/DECISIONS.md);
44
+ 行为验证方式变更更新 [TEST_MATRIX](docs/agent/TEST_MATRIX.md);代码相关缺口更新 KNOWN_RISKS;
45
+ 术语变更更新 [GLOSSARY](docs/agent/GLOSSARY.md),对外行为变更核对 [README_AUDIT](docs/agent/README_AUDIT.md)。
46
+
47
+ 每份文档只承载自己的事实,不重复复制。HANDOFF 保留当前任务/未决项,历史通过 Issue / PR / Git 查阅;
48
+ DECISIONS 保留稳定 ADR 编号及替代关系,不追加日期流水账。只改 HANDOFF 而遗漏受影响的地图或测试矩阵不算完成。
49
+
50
+ ## 架构约束
51
+
52
+ - `Memory` 为公共存储 API;`MemoryService` / `Bridge` 复用 `application.MemoryRuntime`。
53
+ - pipeline、storage、domain 不依赖 adapters;storage 不依赖 pipeline;service 不依赖 bridge。
54
+ - 新宿主通过 application 接入;现有源码 dashboard 的直接 SQLite 访问不是新模块的模板。
55
+ - `AtomCard` 是事实真源,tree leaf 只引用 atom;Chroma/Qdrant 是可选 index,不是关系 backend。
56
+ - 不擅自改变 public API、数据格式、配置默认值或增加生产依赖。
57
+
58
+ ## 双 backend gate
59
+
60
+ SQLite/PostgreSQL 均为正式支持的 memory backend。涉及 public 读写、持久化编排、backend contract、
61
+ schema、SQL、transaction、FTS 或 lifecycle 时:
62
+
63
+ 1. 同步维护两种 backend,用同一组行为断言验证,优先扩展 `tests/test_backend_parity.py`。
64
+ 2. 使用真实专用 PostgreSQL 和 `TEST_POSTGRES_DSN`,确认相关 PG cases 未 skip。
65
+ 3. 有意的单 backend 能力必须明确拒绝另一 backend,并在 KNOWN_RISKS 中说明原因。
66
+ 4. backend-specific SQL 留在 `storage/backends/`;不把既有能力缺口当作新代码可以静默分叉的理由。
67
+
68
+ ## 召回与写入敏感路径
69
+
70
+ | 范围 | 需要说明的影响 |
71
+ |---|---|
72
+ | `core.py`、`storage/backends/` | 公共写入、事务、schema、索引、namespace |
73
+ | `pipeline/extractor/`、`pipeline/promotion/`、`pipeline/episode/` | 哪些内容成为 Candidate、AtomCard 或 Episode |
74
+ | `pipeline/recall/`、`pipeline/page/` | source、排序、raw policy、去重、budget、页面内容 |
75
+ | `application/runtime.py`、`application/path_projection.py`、`application/host_files.py` | 工具搜索、路径可读内容和 host 文件 |
76
+ | `adapters/bridge/handlers.py`、宿主插件 hook | capture/extract、memory_search/memory_get 的宿主行为 |
77
+
78
+ 修改这些行为时,用 `⚠️ 召回/写入路径变更` 明确说明具体影响、受影响 source/layer 和验证命令。
79
+ 仅编辑说明或构建清单时说明行为未变,不将文档整理描述为 runtime 变更。
80
+
81
+ ## 验证与交付
82
+
83
+ ```bash
84
+ make install-hooks # 每个 clone 一次,提交前不得绕过失败门禁
85
+ make all # format + lint + strict mypy + pytest
86
+ ```
87
+
88
+ 代码改动先运行最小相关测试,再执行完整门禁;纯文档维护只需相关文档检查,提交前仍执行完整门禁。
89
+ 失败时找到首个根因、做范围内最小修复并重跑;
90
+ 环境或既有问题阻止验证时,明确报告失败/skip 和复现命令,不声称通过。
91
+ 交付前确认实现符合验收、相关文档与代码一致;属于 Harness 记录范围的任务将实际验证和未解决项写入 HANDOFF;
92
+ 无法通过的门禁必须说明根因及后续命令,不能把未验证状态写成完成验收。
93
+ 完成回复简述改动、验证和剩余限制即可,不要求固定多节交接模板。
94
+
95
+ 未经用户明确授权,不执行 push、重写 Git 历史、大目录删除、生产部署或密钥修改。
96
+ 详细验证与双 backend 命令见 [TEST_MATRIX](docs/agent/TEST_MATRIX.md),发布检查见 [CONTRIBUTING.md](CONTRIBUTING.md)。
@@ -0,0 +1,24 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Added
11
+
12
+ - Distribution `octop-memory`, Python package `octop_memory`, CLI entry points
13
+ `octop-memory` / `octopmemory-bridge`, and host plugin ID `octopmemory`.
14
+ - Dual memory backends (SQLite + FTS5 default, PostgreSQL optional), optional Chroma/Qdrant
15
+ indexes, OpenClaw and Hermes host adapters, portable `.hmpkg` export/import.
16
+ - Idle maintenance, SQLite checkpoint compaction, and host-coordinated online slim helpers.
17
+
18
+ ### Notes
19
+
20
+ - Requires Python 3.12+.
21
+ - Default paths and environment variables use the `OCTOP_MEMORY_*` / `OCTOPMEMORY_*` prefixes;
22
+ PostgreSQL shared schema is `octop_memory`.
23
+
24
+ [Unreleased]: https://github.com/TencentCloud/octop-memory/compare/v0.9.9...HEAD
@@ -0,0 +1,92 @@
1
+ # 开发指南
2
+
3
+ 从 [README](README_CN.md) 了解用途,从本文了解实现和贡献流程。AI 工作规则只维护在
4
+ [AGENTS.md](AGENTS.md);外部 Agent 的接入方式、已有适配的安装配置和宿主契约统一见[集成指南](docs/integrations.md)。
5
+
6
+ ## 开始开发
7
+
8
+ 要求 Python 3.12+、支持 FTS5 的 SQLite 和 uv。
9
+
10
+ ```bash
11
+ git clone https://github.com/TencentCloud/octop-memory.git
12
+ cd octop-memory
13
+ make install
14
+ make install-hooks
15
+ make all
16
+ ```
17
+
18
+ 从 `main` 创建 `feature/*` 或 `fix/*`,用合成数据复现问题,再添加实现和相关行为测试。
19
+ `make all` 包括 format、lint、strict mypy、pytest;format 会改写文件。pre-commit 执行相同门禁。
20
+
21
+ 源码辅助目录各有用途:`examples/basic_usage.py` 是唯一的基础示例,使用临时数据库演示公共 API、
22
+ 组织树和 prompt recall;`evals/recall/` 是合成数据回归工具,指标局限见测试矩阵。
23
+ `scripts/` 保留插件构建、部署和宿主验收入口;部署/E2E 脚本需专用环境,不属于普通单测。
24
+ 个人工具设置留在被忽略的 `.claude/`、`.codebuddy/`、`.cursor/` 中,不复制项目规则或发布流程。
25
+
26
+ ## Harness 维护流程
27
+
28
+ 代码相关 bug / 新需求先写明问题、范围和验收,再实现、验证、同步项目认知。已有 Issue / PR 可作为澄清正文,
29
+ 在 [HANDOFF](docs/agent/HANDOFF.md) 留链接和当前状态即可;尚未开 Issue 的任务直接使用其中的简短模板。
30
+ 规则集中在 [AGENTS.md](AGENTS.md),人工开发者也沿用同一闭环。
31
+ banner、排版、链接、Python/依赖版本、构建/CI 等常规维护只更新对应文件与必要的用户说明,不写 Harness 记录。
32
+ 若同时改变运行行为或数据契约,只记录代码影响。
33
+
34
+ | 文档 | 单一职责 |
35
+ |---|---|
36
+ | [HANDOFF](docs/agent/HANDOFF.md) | 当前任务的澄清、进度、验证、遗留问题和下一步 |
37
+ | [PROJECT_MAP](docs/agent/PROJECT_MAP.md) | 模块入口、调用链、数据流与边界 |
38
+ | [DECISIONS](docs/agent/DECISIONS.md) | 架构选择、理由、代价和替代关系 |
39
+ | [TEST_MATRIX](docs/agent/TEST_MATRIX.md) | 按改动范围选择验证命令和环境 |
40
+ | [KNOWN_RISKS](docs/agent/KNOWN_RISKS.md) | 当前缺口、限制与应对 |
41
+ | [GLOSSARY](docs/agent/GLOSSARY.md) | 核心术语 |
42
+ | [README_AUDIT](docs/agent/README_AUDIT.md) | 对外声明与实现的核对项 |
43
+
44
+ 仅更新受影响的文档,不为每个任务新建文件;已完成任务的细节由 Issue / PR / Git 保存。
45
+ 开发从 [项目地图](docs/agent/PROJECT_MAP.md) 开始,验证命令见 [测试矩阵](docs/agent/TEST_MATRIX.md),
46
+ 已知限制见 [风险清单](docs/agent/KNOWN_RISKS.md)。
47
+
48
+ ## Checkpoint 维护
49
+
50
+ SQLite `CompactSqliteSaver` 默认复用较大的 `skills_metadata` 和 `memory_contents`,在同库
51
+ `hm_checkpoint_blobs` 保存不可变内容,`harness-checkpoint-v1` checkpoint 保存引用。
52
+ 内容和 checkpoint 原子提交,读取时恢复原值;旧 inline 仍可读,历史不会自动批量迁移。
53
+ 独立 reader 使用 `CheckpointSerializer.with_connection(conn)` 获取自身 decoder/cache 和一致事务视图。
54
+
55
+ ```bash
56
+ # 默认只读预览。
57
+ octop-memory db slim /path/to/memory.sqlite
58
+ # 停止所有数据库使用者后:自动备份、去重、VACUUM,不删历史。
59
+ octop-memory db slim /path/to/memory.sqlite --apply --offline
60
+ # 降级 reader 前,显式展开旧格式;备份路径必须不存在。
61
+ octop-memory --db /path/to/memory.sqlite db checkpoints \
62
+ --apply --offline --backup /path/to/new-backup.sqlite --expand
63
+ ```
64
+
65
+ `--offline` 是操作者声明,不会停止进程。备份包含已提交 WAL,并需要额外磁盘空间。
66
+ `OCTOP_MEMORY_CHECKPOINT_DEDUP=0` 仅停止新引用写入,不展开存量;旧 reader 无法直接读取新格式。
67
+ 迁移分批提交,重跑跳过已转换行;retention 需显式 completed thread、外部引用和依赖闭包。
68
+ 在线 `slim_live_checkpoints` 由宿主负责暂停新 invocation、协调 reader 和恢复;长 reader 可能延期 WAL 回收。
69
+ 这些格式维护仅支持 SQLite,明确拒绝 PostgreSQL;PG 使用原 saver,checkpoint_ns 不等于 memory namespace。
70
+
71
+ ## PR 与发布
72
+
73
+ PR 描述说明问题、改动、验证和剩余限制;用户可见变更更新 `CHANGELOG.md` 的 Unreleased。
74
+ 代码相关的非平凡改动更新现有 HANDOFF,并按影响同步地图、决策、测试、风险、术语和 README 核对项;不追加日期流水账。
75
+
76
+ `main` 是集成分支。发布从 `release/x.y.z`(或 `hotfix/*`)通过 PR 合入 main,
77
+ project version、CHANGELOG 与标签一致。现有 workflow 在合并后创建 `v*` tag 并触发 PyPI/GitHub Release;
78
+ 没有发布授权时只验证构建,不推 tag 或上传。
79
+ 公开发布统一走上述 PR 与 Actions 流程,不在本地用 `make publish` / `twine upload` 代替;
80
+ 发布前检查版本未占用、Unreleased 归档正确和门禁结果,发布后核对 tag 与产物,再按仓库策略清理发布分支。
81
+
82
+ ```bash
83
+ uv build --out-dir dist/package-review
84
+ uv build --wheel --out-dir dist/package-review/direct
85
+ ```
86
+
87
+ 首条从 sdist 重建 wheel;比较两种 wheel 解压后的文件名与内容。Python sdist 使用 allowlist,
88
+ 独立插件另行构建,测试/CI 留在完整 checkout。插件短 README 是分发入口,详细说明只有集成指南一份。
89
+
90
+ 不要提交 `.env`、数据库/WAL、备份、日志、`.hmpkg`、依赖安装目录或私人运维记录。
91
+ 个人 editor 配置、重复发布 skill 和访问个人真实库的诊断脚本不属于公共源码;
92
+ ignore 不删除已跟踪内容,工作树脱敏也不清理 Git 历史或已有附件。漏洞报告见 [SECURITY.md](SECURITY.md)。
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 orcakit
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,230 @@
1
+ Metadata-Version: 2.4
2
+ Name: octop-memory
3
+ Version: 0.9.9
4
+ Summary: Pluggable memory system with hierarchical recall, FTS search, and multiple backend support.
5
+ Project-URL: Homepage, https://github.com/TencentCloud/octop-memory
6
+ Project-URL: Repository, https://github.com/TencentCloud/octop-memory
7
+ Project-URL: Issues, https://github.com/TencentCloud/octop-memory/issues
8
+ Project-URL: Changelog, https://github.com/TencentCloud/octop-memory/blob/main/CHANGELOG.md
9
+ Author: orcakit
10
+ License: MIT
11
+ License-File: LICENSE
12
+ Keywords: agent,fts,llm,memory,recall,sqlite
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Requires-Python: >=3.12
22
+ Provides-Extra: chroma
23
+ Requires-Dist: chromadb>=0.4; extra == 'chroma'
24
+ Provides-Extra: cli
25
+ Requires-Dist: click>=8.0; extra == 'cli'
26
+ Provides-Extra: dashboard
27
+ Requires-Dist: click>=8.0; extra == 'dashboard'
28
+ Requires-Dist: fastapi>=0.110; extra == 'dashboard'
29
+ Requires-Dist: uvicorn[standard]>=0.29; extra == 'dashboard'
30
+ Provides-Extra: embeddings
31
+ Requires-Dist: sentence-transformers>=2.2; extra == 'embeddings'
32
+ Provides-Extra: langgraph
33
+ Requires-Dist: langgraph-checkpoint-sqlite>=2.0; extra == 'langgraph'
34
+ Requires-Dist: langgraph-checkpoint>=2.0; extra == 'langgraph'
35
+ Provides-Extra: langgraph-postgres
36
+ Requires-Dist: langgraph-checkpoint-postgres>=2.0; extra == 'langgraph-postgres'
37
+ Requires-Dist: langgraph-checkpoint>=2.0; extra == 'langgraph-postgres'
38
+ Requires-Dist: psycopg[binary]>=3.1; extra == 'langgraph-postgres'
39
+ Provides-Extra: postgres
40
+ Requires-Dist: psycopg[binary]>=3.1; extra == 'postgres'
41
+ Provides-Extra: qdrant
42
+ Requires-Dist: qdrant-client>=1.7; extra == 'qdrant'
43
+ Description-Content-Type: text/markdown
44
+
45
+ <p align="center">
46
+ <img src="assets/images/banner.jpeg" alt="Octop Memory" width="600" />
47
+ </p>
48
+
49
+ # Octop Memroy
50
+
51
+ **Persistent, portable memory for LLM agents.** Store facts, capture conversations, and retrieve relevant context through a shared Python runtime or host adapters.
52
+
53
+ [中文](README_CN.md) · [Developer guide](CONTRIBUTING.md) · [Integrations](docs/integrations.md) · [MIT License](LICENSE)
54
+
55
+ ## Project scope
56
+
57
+ Octop Memory provides cross-session memory for personal assistants, ongoing project work, and existing agents.
58
+ It is the memory component in the Octop ecosystem and can also run independently as a Python library,
59
+ CLI, or JSON-RPC bridge, without installing Octop. This repository owns memory capture, extraction, retrieval, storage,
60
+ and migration; the host application manages agent execution, tool scheduling, and user interfaces.
61
+
62
+ ## What it provides
63
+
64
+ - **Long-term memory:** extract candidates from raw events, then promote, merge, or review them into facts (`AtomCard`). Entity pages consolidate facts, episodes describe events, and the tree provides a hierarchical view.
65
+ - **Recall:** full-text search, optional vector search, ranking, deduplication, and a token budget for prompt context.
66
+ - **Two storage backends:** SQLite + FTS5 by default, PostgreSQL for server deployments. Chroma and Qdrant are optional vector indexes alongside either backend.
67
+ - **External agent adapters:** `MemoryService` for Python hosts and a JSON-RPC bridge for cross-language/subprocess hosts. Host adapters live in `plugins/`, currently including OpenClaw and Hermes.
68
+ - **Portability:** export/import and `.hmpkg` packages for moving memory between supported hosts.
69
+ - **Optional LangGraph checkpoints:** conversation recovery state alongside long-term memory.
70
+
71
+ The core requires **Python 3.12+**, aligned with Octop’s Python 3.12 baseline, and uses only the standard library, including `sqlite3` with FTS5. Manual storage and lexical recall need no model. Automated extraction, promotion checks, and page regeneration can use an injected `LLMClient`; installing the package alone does not configure a model.
72
+
73
+ ## Quick start
74
+
75
+ ```bash
76
+ pip install octop-memory
77
+ ```
78
+
79
+ ```python
80
+ from octop_memory import Memory, MemoryService
81
+
82
+ memory = Memory(
83
+ namespace="demo",
84
+ backend_config={"db_path": "./demo.sqlite"},
85
+ )
86
+ memory.store("User prefers Python for backend services", topic="preferences")
87
+
88
+ # Basic fact search returns MemoryNode leaf projections.
89
+ for node in memory.recall("Python"):
90
+ print(node.content)
91
+
92
+ # Prompt recall adds source selection, ranking, deduplication, and budgeting.
93
+ result = MemoryService(memory).recall("Python")
94
+ print(result.rendered)
95
+ ```
96
+
97
+ This creates a local database. Use terms present in the stored text for a minimal FTS example. `Memory.search()` searches archived conversation messages; it is a separate API from fact recall.
98
+
99
+ ### Optional dependencies
100
+
101
+ | Install | Purpose |
102
+ |---|---|
103
+ | `pip install "octop-memory[cli]"` | CLI and OpenClaw setup commands |
104
+ | `pip install "octop-memory[postgres]"` | PostgreSQL memory backend |
105
+ | `pip install "octop-memory[chroma,embeddings]"` | Chroma index and local embeddings |
106
+ | `pip install "octop-memory[qdrant,embeddings]"` | Qdrant index and local embeddings |
107
+ | `pip install "octop-memory[langgraph]"` | SQLite LangGraph checkpointer |
108
+ | `pip install "octop-memory[langgraph-postgres]"` | PostgreSQL LangGraph checkpointer |
109
+
110
+ Vector search requires constructing and injecting `vector_index` and `embedding_provider` into `Memory`; an extra installs dependencies only. The database backend remains `sqlite` or `postgres`.
111
+
112
+ ```python
113
+ memory = Memory(
114
+ namespace="demo",
115
+ backend="postgres",
116
+ backend_config={"dsn": "postgresql://user:pass@localhost/octop_memory"},
117
+ )
118
+ ```
119
+
120
+ Use deployment configuration for real credentials. SQLite isolates memory with table prefixes; PostgreSQL uses namespace-first keys in the shared `octop_memory` schema.
121
+
122
+ ## Code architecture
123
+
124
+ ```text
125
+ src/octop_memory/
126
+ ├── core.py / types.py # Public Memory API and data structures
127
+ ├── service.py # MemoryService: Python host entry point
128
+ ├── application/ # MemoryRuntime, config, host files, path projection
129
+ ├── pipeline/ # Extraction, promotion, recall, pages, episodes, lifecycle
130
+ ├── storage/ # SQLite / PostgreSQL, checkpoints, vector indexes
131
+ ├── ports/ # External capability interfaces, including LLM clients
132
+ ├── domain/ # Shared alias and time rules
133
+ ├── adapters/ # JSON-RPC bridge, CLI, source-only dashboard
134
+ └── operations/ # Import/export, migration, portable packages
135
+ plugins/ # External agent adapters, organized by host
136
+ examples/ # Public API example
137
+ tests/ / evals/ # Behavior tests / synthetic recall evaluation
138
+ docs/agent/ # Harness project map, decisions, and handoff
139
+ ```
140
+
141
+ Adapters call inward through application and pipeline/core/storage layers. `MemoryService` and `Bridge`
142
+ share `MemoryRuntime`; pipeline/storage do not depend on adapters, and backend-specific SQL stays in storage.
143
+ The source dashboard's direct SQLite access is an existing exception.
144
+
145
+ ### Host call flow
146
+
147
+ ```text
148
+ Python host → MemoryService ─────────┐
149
+ Hermes → in-process Bridge ──────────┤
150
+ OpenClaw → JSON-RPC bridge ───────────┴→ MemoryRuntime → pipelines → Memory
151
+ CLI → application / operations ────────────────────────────────────┘
152
+ ├→ SQLite / PostgreSQL
153
+ └→ optional vector index
154
+ ```
155
+
156
+ Hermes currently calls `Bridge` in-process; OpenClaw uses a bridge subprocess. `MemoryService.recall()` also calls the recall pipeline directly. Facts live in `AtomCard`; tree leaves reference atoms and project their content. The tree is an organization view, not an additional copy or independent recall source.
157
+
158
+ ### Long-term memory flow
159
+
160
+ ```text
161
+ RawEvent ──extraction──→ Candidate ──promotion──→ AtomCard ──dirty / regeneration──→ EntityPage
162
+ └──episode extraction──→ Episode └──atom_id reference──→ tree leaf
163
+ ```
164
+
165
+ Candidates do not all require human approval. Promotion checks value, evidence, entity resolution,
166
+ duplicates, and conflicts; it can promote, merge, or drop candidates automatically, leaving review/conflict
167
+ cases for user action. Pages are marked dirty and regenerated when triggered by runtime/CLI/host,
168
+ rather than immediately after every write. Episode extraction is a parallel path from raw events.
169
+ Manual `Memory.store()` needs no model and directly creates RawEvent/Candidate/AtomCard plus a leaf reference.
170
+
171
+ Prompt recall routes `atom` and `raw` by default, adds `page_headline` when an entity is resolved, and adds `vector` when configured. With the default raw fallback policy, durable hits suppress raw; passing the current session/thread excludes its raw events from prompt injection.
172
+
173
+ Start with [CONTRIBUTING.md](CONTRIBUTING.md); the [project map](docs/agent/PROJECT_MAP.md) covers architecture and data flow. AI contributors use [AGENTS.md](AGENTS.md), with task clarification and handoff in [HANDOFF.md](docs/agent/HANDOFF.md).
174
+
175
+ ## CLI
176
+
177
+ Install `[cli]`. Global options precede subcommands; use an explicit database and namespace when following examples.
178
+
179
+ ```bash
180
+ octop-memory --db ./demo.sqlite --namespace demo memory store --content "User prefers Python"
181
+ octop-memory --db ./demo.sqlite --namespace demo recall "Python"
182
+ octop-memory --db ./demo.sqlite --namespace demo memory tree
183
+ octop-memory --help
184
+ ```
185
+
186
+ | Commands | Purpose |
187
+ |---|---|
188
+ | `raw`, `candidate`, `atom`, `entity`, `page` | Inspect and manage memory layers |
189
+ | `episode`, `digest`, `journal` | Event summaries and decision records |
190
+ | `memory`, `recall`, `thread` | Tree operations, prompt recall, thread state |
191
+ | `export`, `import`, `migrate`, `portable` | Backup and migration |
192
+ | `db`, `gc`, `consolidate` | Storage maintenance and lifecycle operations |
193
+ | `config`, `openclaw`, `backfill` | Configuration, integration, historical extraction |
194
+
195
+ Run `<command> --help` for arguments. `db slim FILE` previews SQLite checkpoint deduplication; `--apply --offline` creates a backup and performs it without deleting history. Read [checkpoint compatibility and maintenance](CONTRIBUTING.md#checkpoint-维护) before migration or reader downgrade.
196
+
197
+ The dashboard is available from a source checkout with `[dashboard]` dependencies; its modules are currently excluded from the wheel. Installing `octop-memory[dashboard]` from PyPI alone does not provide the dashboard command.
198
+
199
+ ## External agent adapters
200
+
201
+ `plugins/<host>/` maps external agent hooks, tools, and configuration to the shared Python runtime.
202
+ OpenClaw and Hermes adapters are available today. Other agents can integrate through the Python API or JSON-RPC,
203
+ with an adapter implementing their host contract.
204
+
205
+ | Integration | Use case | Entry point |
206
+ |---|---|---|
207
+ | In-process Python | Custom agents / Python applications | `MemoryService.capture_turn()` / `recall()` / `search()` / `get()` / `extract()` |
208
+ | JSON-RPC bridge | Cross-language or separate processes | stdio `octopmemory-bridge` |
209
+ | Host plugin | Agent-specific lifecycle and tool interfaces | `plugins/<host>/`; OpenClaw and Hermes currently implemented |
210
+
211
+ See the [integration guide](docs/integrations.md) for installation, configuration, profiles, troubleshooting, and adapter boundaries.
212
+
213
+ Move memory with `octop-memory portable list-sources / pack / adopt / doctor`. Exported `.hmpkg` files contain memory data; keep them out of source control.
214
+
215
+ ## Development
216
+
217
+ ```bash
218
+ make install # uv sync --group dev
219
+ make install-hooks # required once per clone
220
+ make all # format + lint + strict mypy + tests
221
+ uv build # Python wheel + source distribution
222
+ ```
223
+
224
+ Run PostgreSQL behavior tests against a real test server with `TEST_POSTGRES_DSN`; skipped PG cases do not prove compatibility. OpenClaw has its own `npm ci`, `npm test`, and `npm run build` under `plugins/openclaw/octopmemory/`.
225
+
226
+ The repository retains tests, CI, examples, and plugins; the Python sdist contains the sources needed to rebuild the wheel. Development and release procedures live in [CONTRIBUTING.md](CONTRIBUTING.md).
227
+
228
+ ## License
229
+
230
+ [MIT](LICENSE). Report vulnerabilities through the channels in [SECURITY.md](SECURITY.md).