Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
8c7629d
fix(hermes): forward llm/extraction config blocks into the runtime
fengyue-xve Oct 10, 2026
832e671
docs(hermes): install the provider from the monorepo subdirectory path
fengyue-xve Oct 10, 2026
345c600
Merge pull request #23 from TencentCloud/chore/sync-develop-after-1.0.2
github-actions[bot] Oct 16, 2026
8635251
fix(page): reject stale regeneration writebacks
66cmw Oct 19, 2026
40da8de
fix(host-files): reject rooted Windows include patterns
fengyue-xve Oct 21, 2026
689bb4f
fix(memory): batch extraction and persist the extracted cursor (#25)
TrueFurina Oct 25, 2026
f248e3f
fix(memory): keep document review off the save path
eileennchen Oct 26, 2026
ec2e6e4
Merge pull request #31 from TencentCloud/fix/manual-review-background
Bosheng0422 Oct 28, 2026
715b895
fix(memory): expose background manual document review API
eileennchen Oct 28, 2026
3863a03
fix(manual-docs): advance audit cursor on uncertain results
TrueFurina Oct 28, 2026
86f0308
fix(memory): commit candidates and the extraction cursor atomically (…
TrueFurina Oct 29, 2026
543bf4f
fix(retention): only advance the audit cursor for atoms actually comp…
TrueFurina Oct 30, 2026
8d0c906
Merge pull request #32 from TencentCloud/fix/manual-review-service
Bosheng0422 Nov 2, 2026
bef0c99
Merge branch 'develop' into fix/hermes-llm-extraction-config
Bosheng0422 Nov 2, 2026
b4d0223
Merge branch 'develop' into fix/windows-host-file-globs
Bosheng0422 Nov 2, 2026
f760ad1
Sync develop with upstream
TrueFurina Nov 2, 2026
ed3582b
Merge pull request #15 from fengyue-xve/fix/hermes-llm-extraction-config
Bosheng0422 Nov 2, 2026
c24acc4
Merge develop into PR #26 and retain both changelog entries
eileennchen Nov 2, 2026
d76ce3a
Merge develop into PR #24 and reconcile page revision handoff
eileennchen Nov 2, 2026
7d9bfc0
fix(manual-docs): keep an unverified comparison out of "complete"
TrueFurina Nov 2, 2026
41bd690
Merge develop into PR #16 and retain installation documentation
eileennchen Nov 2, 2026
ded7957
Merge pull request #26 from fengyue-xve/fix/windows-host-file-globs
Bosheng0422 Nov 2, 2026
b68e582
Merge latest develop into PR #24 and retain both accepted fixes
eileennchen Nov 2, 2026
be45309
Merge pull request #16 from fengyue-xve/docs/hermes-install-paths
Bosheng0422 Nov 2, 2026
1d5bb95
Merge pull request #24 from 66cmw/codex/page-regeneration-ready
Bosheng0422 Nov 2, 2026
58f6bb4
fix(manual-docs): count only live atoms in the unresolved set
TrueFurina Nov 2, 2026
a32811c
Merge branch 'develop' into fix/manual-docs-uncertain-cursor-advance
Bosheng0422 Nov 3, 2026
a8fd7d2
Merge branch 'develop' into fix/extractor-batch-sessions
Bosheng0422 Nov 3, 2026
cbec9bc
fix(manual-docs): re-audit legacy progress without uncertainty state
eileennchen Nov 3, 2026
c377e56
test(memory): formalize extraction failure/retry assertions (#25)
TrueFurina Nov 3, 2026
ef41fbf
Merge pull request #29 from TrueFurina/fix/extractor-batch-sessions
Bosheng0422 Nov 4, 2026
403c70a
Merge branch 'develop' into fix/manual-docs-uncertain-cursor-advance
Bosheng0422 Nov 4, 2026
4398189
Merge pull request #33 from TrueFurina/fix/manual-docs-uncertain-curs…
Bosheng0422 Nov 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,10 @@ jobs:

- name: Test
run: make test

- name: Test real Harness background review
run: |
# Pin the host containing the asynchronous review scheduler (Harness #110).
uv pip install "octop-harness @ git+https://github.com/TencentCloud/octop-harness.git@84c19536dec83a5d36e3c17a18f2df8f71c0f65e"
uv run --no-sync python -c "from octop_harness.middleware.memory import MemoryMiddleware"
uv run --no-sync pytest tests/test_backend_parity.py -k HarnessManualReview -q -rs
7 changes: 7 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ jobs:
- name: Run tests
run: make test

- name: Test real Harness background review
run: |
# Pin the host containing the asynchronous review scheduler (Harness #110).
uv pip install "octop-harness @ git+https://github.com/TencentCloud/octop-harness.git@84c19536dec83a5d36e3c17a18f2df8f71c0f65e"
uv run --no-sync python -c "from octop_harness.middleware.memory import MemoryMiddleware"
uv run --no-sync pytest tests/test_backend_parity.py -k HarnessManualReview -q -rs

- name: Build package
run: make build

Expand Down
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### 修复
- 候选提炼按单批事件数(默认 100)与字符预算(默认 20,000)分批调用模型,不再把整个 session 的事件塞进一次请求;此前长会话积压会让 prompt 超出上下文、以「长度截断 / 超时」失败(#25)。
- 「已提炼」游标写入 `{ns}_meta`(`extracted_ids/v1/<session>`),重启后从 meta 恢复,不再整段重跑(#25)。增量提取路径以 `strict=True` 持久化游标:游标写失败会让整个事务回滚、候选写入一并撤销,事件留在未提炼状态等待重试,而非被默默跳过;仅非严格路径的持久化失败才只告警。
### 文档

- **修正 Hermes 安装文档**:`docs/integrations.md` 与 provider README 收敛为一条可用路径——用 `hermes plugins install TencentCloud/octop-memory/plugins/hermes/octopmemory --ref <完整 40 位 SHA>` 从本仓子目录直接安装,无需独立插件仓库;并补充用 `hermes --print-runtime-command` 获取网关实际解释器。同时写明仓库未向 PyPI 发布独立的 `octop-memory-hermes` 插件包(按旧命令执行会 404),`installer.py` 仅为仓库内 E2E 工具(#10)。
### 修复

- 旧手动文档审计记录缺少 `uncertain` 字段时,不再信任其已比较进度:只读状态将活跃事实列为待审,后续按现有批次上限重审一次;新格式的空未决集合保留有效进度,避免重复调用模型(#33)。
- EntityPage 再生成写回校验页面修订号,拒绝覆盖模型调用期间的用户编辑、事实 dirty 标记或更新的生成结果;迟到的生成失败不会重新污染已成功的新页。SQLite/PostgreSQL schema 2 自动补充修订列,SQLite 并发首次迁移使用短写事务;原有 summary_version 含义及不带条件的旧页接口调用保持兼容。
- Windows 宿主文件扫描忽略带根或驱动器的 allowlist glob,避免 rooted pattern 抛错;portable source 测试正确隔离 Windows 用户目录。
- **Hermes 适配器不再丢弃 `llm` / `extraction` 配置**:`_bridge_config()` 现在按桥解析器的同一语义把两个配置块转发进 `MemoryRuntimeConfig`,`$HERMES_HOME/octopmemory.json` 里的模型端点与抽取开关能真正抵达运行时;非对象值按缺省处理,坏配置不会挡住启动,`stats` 输出依旧不回显 `api_key`。此前 Hermes 宿主永远落到 `NoopLLMClient`,模型辅助抽取静默不可用(无 candidate/atom,也不报错)(#9)。
- 补齐 `MemoryService.review_new_memory(max_atoms=20)` 公共入口,修复宿主保存后和定时维护静默跳过手动文档审核的问题;保存仍不等待模型。新增真实 octop-harness 中间件与 SQLite/PostgreSQL 的跨包测试,并纳入 CI 和发布检查(TencentCloud/Octop#2358)。
- 手动文档审计中,无结论(`uncertain`)的比较仍推进游标,但不再被报告为 `complete`:未验证的 atom 按断言哈希记录,后续无待比对项的巡检仍返回 `uncertain`;新文档 revision 重新比对后可恢复 `complete`(TencentCloud/octop-memory#33)。
- 手动文档审计的未决集合改按当前活跃 atom 计算:已停用、已删除或断言已变的记录不再滞留,`remaining` 与状态读取同样只统计活跃 atom,因此停用一个 atom 后无需修改文档即可清除 `uncertain`,SQLite/PostgreSQL 同组回归(TencentCloud/octop-memory#33)。

## [1.0.2] - 2026-10-16

### 新增
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ Prompt recall routes `atom` and `raw` by default, adds `page_headline` when an e

Synthetic runtime failures are excluded from automatic capture, extraction and raw prompt fallback. octop-harness / Octop raise model errors into checkpoint task failures and display diagnostics separately; automatic team failure notifications are excluded from capture. Hosts that still create synthetic replies must mark them with `payload.octop_runtime_error=true`; online filtering uses structured provenance only. Agents decide when to call `memory_save`; approvals and manual saves are protected by their provenance, without intent or troubleshooting-value keyword lists. Automatic capture keeps its length policy with no intent-keyword exception; explicit saves bypass that capture policy. Original diagnostics remain inspectable by ID. `operations.retention.audit_runtime_errors(memory)` previews eligible records by default; even `apply=True` retires only automatic atoms whose evidence is entirely marked as runtime failures. The fixed legacy retry envelope only nominates `review_atom_ids` / `review_candidate_ids`; missing and mixed evidence stays unchanged for human review.

`MemoryService.reconcile_manual_documents({"USER.md": text, "MEMORY.md": text})` gives owner-edited documents priority. Bridge exposes the same operation and `manual_document_review_status`. Proven conflicts softly retire the old atom and create a replacement review candidate with original evidence and a journal trail; acceptance makes the replacement a confirmed fact. Duplicate atoms remain stored; pass the actual session snapshot as `recall(..., manual_context=documents)` to suppress repeated context. An optional `manual_documents_provider` checks current files after saves/automatic promotions, without refreshing chat snapshots. Each call checks up to 100 new facts and accepts at most 100,000 document characters. Partial checks are resumable; unavailable/uncertain/invalid semantic checks are explicit and never force retirement. Full documents are comparison metadata, not indexed atoms. See ADR-042.
`MemoryService.reconcile_manual_documents({"USER.md": text, "MEMORY.md": text})` gives owner-edited documents priority. Bridge exposes the same operation and `manual_document_review_status`. Proven conflicts softly retire the old atom and create a replacement review candidate with original evidence and a journal trail; acceptance makes the replacement a confirmed fact. Duplicate atoms remain stored; pass the actual session snapshot as `recall(..., manual_context=documents)` to suppress repeated context. An optional `manual_documents_provider` supplies current files to background review. `save`, extraction, and promotion do not synchronously run manual-document comparison; the host calls the public `MemoryService.review_new_memory(max_atoms=20)` on a background worker (the method itself is synchronous). An explicit reconcile still checks up to 100 new facts per call and accepts at most 100,000 document characters. A failed model batch is deferred, and three failures mark those facts uncertain without retiring them. Partial checks are resumable; unavailable/uncertain/invalid semantic checks are explicit and never force retirement. Full documents are comparison metadata, not indexed atoms. See ADR-042.

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).

Expand Down
2 changes: 1 addition & 1 deletion README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ prompt 召回默认路由 `atom`、`raw`;解析到 entity 时加入 `page_head

系统生成的运行报错不自动进入长期记忆,也不通过历史 raw 兜底召回。octop-harness / Octop 将模型异常保留为 checkpoint 失败任务,由宿主单独显示错误;团队自动失败通知排除采集。仍生成合成报错的宿主必须使用 `payload.octop_runtime_error=true` 标记;在线链路只按结构化来源排除,不判断“记住”“已验证”等文字。Agent 自行决定调用 `memory_save`,手工保存与人工批准由来源记录保护。后台采集保留原长度策略,不再有记忆意图关键词例外;主动保存不受此长度限制。原始诊断证据仍可按 ID 检查。`operations.retention.audit_runtime_errors(memory)` 默认仅预览,显式 `apply=True` 也仅软停用全部证据均有错误标记的自动 Atom。旧版固定报错格式只生成 `review_atom_ids` / `review_candidate_ids` 审核清单;证据缺失或混合来源也保留待审,不自动改变这些记录的状态。

手动文档治理使用 `MemoryService.reconcile_manual_documents({"USER.md": text, "MEMORY.md": text})`,Bridge 对应 `reconcile_manual_documents` / `manual_document_review_status`。手动文档优先:明确冲突的旧 Atom 软停用,文档中的替代事实转为待审核 Candidate,保留旧来源和 Journal;采纳才更新为确定事实。重复 Atom 保留,`recall(..., manual_context=实际会话快照)` 避免重复注入。宿主可传 `manual_documents_provider` 在 save/自动晋升后检查当前文件,不刷新聊天快照。每次最多核对 100 条新事实、文档总长最多 100,000 字符;partial 可继续,模型不可用、不确定或证据无效会明确报告,不擅自停用。完整文档只存对账元数据,不导入 Atom 或索引。规则见 ADR-042。
手动文档治理使用 `MemoryService.reconcile_manual_documents({"USER.md": text, "MEMORY.md": text})`,Bridge 对应 `reconcile_manual_documents` / `manual_document_review_status`。手动文档优先:明确冲突的旧 Atom 软停用,文档中的替代事实转为待审核 Candidate,保留旧来源和 Journal;采纳才更新为确定事实。重复 Atom 保留,`recall(..., manual_context=实际会话快照)` 避免重复注入。宿主可传 `manual_documents_provider` 给后台核对读取当前文件,不刷新聊天快照。`save`、提炼和晋升不再同步触发手动文档对账;宿主在后台 worker 调用公开的 `MemoryService.review_new_memory(max_atoms=20)`,默认每批最多核对 20 条;该方法本身同步执行,不能在用户回合等待。显式核对仍是每次最多 100 条新事实、文档总长最多 100,000 字符。模型失败的一批会推迟,连续 3 次失败记为 uncertain 并跳过,不废弃。partial 可继续,模型不可用、不确定或证据无效会明确报告,不擅自停用。完整文档只存对账元数据,不导入 Atom 或索引。规则见 ADR-042。

贡献入口见 [CONTRIBUTING.md](CONTRIBUTING.md),架构与数据流见[项目地图](docs/agent/PROJECT_MAP.md)。AI 协作规则见 [AGENTS.md](AGENTS.md),任务澄清与交接沿用 [HANDOFF.md](docs/agent/HANDOFF.md)。

Expand Down
22 changes: 22 additions & 0 deletions docs/agent/DECISIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,28 @@ memory 接收当前文件作治理,不负责文件读写或刷新提示词;
重复 Atom 不删,召回只在实际 session snapshot 含同一信息时抑制;不会把新文件版本硬塞入旧会话。
元数据保存对账版本和审计比较快照;独立小清单参与 recall cache key,避免旧缓存复活。
模型失败、不确定、伪造证据、版本变化和超限均显式报告;每次最多 100 条新 Atom 可续查。
已比较的 hash 与未决的 `uncertain` hash 分别保存;旧记录没有未决字典时,无法由 checked 推断结论,
选择一次有界重审而不猜测完成状态。读取仅计算待审项,不落库;首次对账写入新格式后保留进度。
代价是旧 complete 报告也可能触发额外比较;显式空未决字典属于有效新格式,不能按假值重复失效。
采纳检查最后对账版本,宿主附当前文档可拦截未重新对账的变化。使用既有 Service/Bridge/
retention/promotion/recall 模块及 backend contract,不建新 schema、全文索引或独立加载器。
SQLite/真实 PG 同组测试验证事务、幂等、证据保留及 prompt 过滤。

## ADR-043:页面生成使用独立变更修订进行条件写回(Proposed)

`summary_version` 只随成功生成与人工编辑变化,不能检测已 dirty 页面上的新事实;时间戳也可能相同。
新增 storage 管理的 `mutation_version`,正文写入和 dirty 标记时原子递增,不改变 summary_version 的既有含义。
regenerator 先确保 stub 存在,再读取修订、笔记和 Atom,模型调用在事务外执行。
写回成功或失败状态时在同条 UPDATE 核对读取修订。冲突不覆盖、不清新 dirty、不累加较新页的失败数;
失败状态本身不递增修订:失败次数和 dirty 状态不改变生成输入,仍有效的并发结果可以提交,
而成功写回推进修订后,迟到失败仍会被原来的条件拦截。
旧生成结果记 `page_regen_failed: stale_snapshot`,由后续显式调用或 dirty 批次重试,不在一次调用中无界重试。
条件更新失败不能再用无条件 upsert 兜底。人工编辑、重复 dirty、其它生成和低层 upsert 都推进修订;
调用方传入的 EntityPage 修订不作为 upsert 的赋值来源,导入在目标 store 重新建立修订。
SQLite/PG schema 2 均增加默认零列并自动迁移已有页面;SQLite 在 BEGIN IMMEDIATE 短事务内检查列并 ALTER,
序列化不同连接的首次迁移,PG 在初始化事务级 advisory lock 内先检查列是否存在,仅缺列时 ALTER,
避免 no-op ALTER 对共享页面表申请独占锁。无生产依赖变更。
Memory 在未指定版本条件时不向 backend 转发新参数,保留旧调用方式;条件写入要求自定义 backend 实现新签名、
维护修订号并进行原子比较。不捕获 TypeError 再无条件重放,避免将兼容处理变成覆盖缺口。
范围是遵守现有 dirty 契约的写入,
不为绕过 dirty 的低层 Atom SQL 增加新治理,也不承诺页面 journal 与正文提交是同一事务。
Loading
Loading