memorize(): make delivery resumable per memcell so retries and replays are idempotent

未关闭
#516 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

@chuiwenwei 已经在做这个了。

开始于 2026年11月6日。

  • #577 来自 @chuiwenwei —— 未关闭

评估

难度
5/5
预计耗时
一周以上
新手友好度
35/100
Issue 类型
功能
描述清晰度
基本清楚
活跃度
活跃
技术栈
python
领域
ai, backend

调研方向

Start with service/memorize.py and service/_boundary.py, then trace markdown entry ID generation and OME dispatch. The issue describes the pending per-memcell delivery state, resume path, deterministic downstream IDs, event deduplication, and retry changes needed. Done means retries resume pending memcells without duplicating entries or events; the suggested boundary-call retry is only a smaller first step.

由索引模型根据 Issue 内容生成。

描述

Why

memorize() is not atomic: boundary detection writes the memcell and consumes
the session buffer, then episode extraction and the OME pipelines run. A
failure after that point cannot be retried safely today:

  • re-running an /add cuts a second memcell from the same messages;
  • re-running a /flush finds an empty buffer and does nothing, leaving the
    memcell without its episode.

This is why the async_mode queue (branch feat/memorize-async-mode, PR to follow) ships with max_attempts = 1 and
documents crash recovery as at-least-once. The same limitation applies to
synchronous clients that retry a 5xx.

What the cloud engine does

Replays are idempotent there because three things line up:

  1. the unit of retry is the memcell, not the add request: the memcell is
    persisted with a "not yet dispatched" marker and an orphan re-dispatch
    sweep resumes from it instead of re-running boundary detection;
  2. downstream ids are deterministic (entry_id = <prefix>_<memcell_id>_<subject>_<idx>
    with a unique index; cluster ids are hashes), so a replay overwrites
    instead of appending;
  3. OME runs at-least-once on top of 1 and 2.

What EverOS would need

  • a per-memcell delivery state on memcell (written with the memcell, cleared
    when every pipeline finished) and a resume entry point that runs only the
    pipelines for memcells still marked pending;
  • episode / derived-entry ids derived from the memcell (today ep_<date>_<seq>),
    or a "memcell already has its entry" check in the markdown writer;
  • OME event dedup keyed by memcell id;
  • the queue (and the sync path's error mapping) switched to "retry = resume
    pending memcells" instead of "re-run the request".

Touches service/memorize.py, service/_boundary.py, the markdown entry id
scheme and OME dispatch; larger than the queue feature itself, so a separate
change.

Possible first step (small)

Retry only failures that happen before anything is written: wrap the boundary
LLM call (_boundary.py, the _detect call) in a typed error, let the queue
retry only that type (max_attempts back to 3 for it), and map it to 503 on
the sync path. Covers the most common failure (LLM down / rate-limited)
without any duplication risk. Roughly a dozen lines.

主要语言
Python
星标
13.3k
派生
926
平均合并
19 小时 29 分钟
30 天内合并 PR
43

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

EverMind-AI/EverOS 的其他 Issue

查看 EverMind-AI/EverOS 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。