Files
Octop/docs/memory-slim.md
347dee56f4 refactor(infra): group agents modules and clarify package ownership (#1164)
* refactor(agents): group thin modules into domain subpackages

Move plugin helpers, memory, settings stores, persona/MBTI, and avatar
bootstrap code under plugins/, memory/, settings/, persona/, and experts/
while keeping top-level import shims so existing call sites stay stable.

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(agents): drop compatibility shims after subpackage move

Call sites already import the new package paths; remove the top-level
re-export stubs so the agents tree only shows real modules.

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(agents): move thread helpers into threads/

Group artifact shaping, fork, and context breakdown under
agents/threads so top-level only keeps lifecycle/config adapters.

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(agents): fold profile/runtime/tool catalog into settings/

Move the remaining config-surface helpers under settings/ and drop the
skill_package id-list aliases in favor of dump/parse_id_list.

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(agents): group workspace_dir and execute_env under workspace/

Keep path resolution and harness execute-env injection together as one
workspace package; leave only manager and conversation_mode at top level.

Co-authored-by: Cursor <cursoragent@cursor.com>

* refactor(infra): fix history/SkillHub ownership and drop thin providers/

Move history_projection under history/, share SkillHub host/limits and
route expert skill downloads through skills.skillhub_market, and fold
Codex OAuth helpers into agents.providers to remove the tiny providers/
package.

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs: sync AGENTS.md and guides with infra/agents layout

Reflect subpackages (settings/workspace/threads/persona, history/, skills/)
and drop stale runtime.py / mbti_profiles paths after the agents reorg.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: jubaoliang <jubaoliang@tencent.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-25 22:32:41 +08:00

17 KiB
Raw Permalink Blame History

手动在线整理 memory.sqlite

用户命令与表现

升级本次 Octop 和 octop-memory 0.9.11 或更新版本,重启 Octop 一次加载控制入口。之后每次整理无需停服:

octop memory list             # 只看可整理的智能体名称和 ID,不触发维护
octop memory slim             # 使用已设定的默认智能体;没有默认时按编号选择
octop memory slim --agent ID  # 已知 ID 时直接指定
octop memory slim --all       # 顺序整理列表中所有符合条件的智能体

不需要记住 agent 名称或 ID;没有默认智能体时会列出运行中、使用兼容 SQLite 记忆库的智能体, 输入编号即可。重名时可用同时显示的 ID 区分,Ctrl+C 可退出选择,不会触发整理。 已用 octop agent use 选择默认智能体时会沿用该选择,执行前打印目标 ID。 本地源码也可从 octop-memory 目录执行:

./scripts/memory-slim --online       # 同样支持默认智能体或编号选择
./scripts/memory-slim --online ID    # 指定 ID
./scripts/memory-slim --online --all # 顺序整理所有符合条件的智能体

--all 在启动时获取一次 memory list 的候选列表,范围是当前 OCTOP_HOME 内所有用户的 运行中、使用兼容 SQLite 记忆库的智能体;不启动已停止的 agent,也不扫描其他目录中的离线库。 忽略已保存的默认智能体,但不能与显式 --agent(含根命令参数)或 OCTOP_AGENT 同时使用。 终端显示 [1/3] 名称 [ID] 及该智能体的阶段、耗时和扫描数;每个完成并恢复后才开始下一个。 每个库分别备份、分别显示前后大小。遇到失败或连接中断立即停止批次,报告已完成数和未执行数, 不自动重试。关闭终端后当前已启动的作业仍由宿主完成,后续尚未提交的项目不会继续执行。 octop --json memory slim --all 的进度带 agent_id、index、total_agents,批次终态为 batch_done 或 batch_failed。memory list 可用于提前查看范围,它本身不执行瘦身。

上述终端命令直接触发维护,不是预览。它连接运行中的同一个 OCTOP_HOME 实例,不会启动第二份 Octop; 不指定数据库路径,服务使用该智能体实际打开的 SQLite 文件。 原 octop-memory db slim FILE / scripts/memory-slim FILE 仍然是离线预览入口。

终端和聊天页面显示:等待当前任务结束 → 备份 → 去重历史上下文 → 压缩 → 恢复。 等待期间不强行中断当前对话;120 秒内找不到空闲窗口时失败退出,不迁移。 进入维护后,新 stream/call/HITL resume 在现有 invocation gate 等待;页面两秒轮询状态, 显示经过时间,暂停发送。终端每秒刷新当前阶段及已用时间,去重时显示已扫描/总条数; 输出到文件/管道时,阶段或扫描数变化立即追加一行,其余每五秒追加心跳,方便日志查看。 备份/VACUUM 不提供虚假的百分比或剩余时间;耗时增加仅表示服务连接仍有响应,不代表完成比例。 记忆面板的 RPC 在维护期间返回 AGENT_BUSY,避免同步 SQLite 锁等待阻塞状态轮询;完成后可重试。 成功或失败后释放 gate,发送按钮恢复。其他独立数据库的智能体仍可使用。

备份位于原文件旁,名字为 memory.sqlite.before-slim.<随机ID>.bak,不会自动删除或覆盖。 命令结束显示主文件大小变化及备份路径;octop --json memory slim --agent main 输出逐行 JSON 进度。 JSON 进度包含 elapsed_seconds。octop --json memory list 返回可选列表;JSON 模式无默认智能体且 未指定 --agent 时输出列表后以非零状态退出,不自动选择或等待交互。 关闭终端不会取消已经开始的数据库作业。若服务连接中断,先看页面/日志状态再重试, 不要恢复旧备份覆盖期间新增的数据。

PostgreSQL 提示与维护边界

单个 PostgreSQL 智能体返回独立提示:PG 也可能存在重复数据或空间膨胀,但本命令目前尚未支持 PG 瘦身,只支持 SQLite;本次未执行整理,可以继续聊天。空候选提示同样说明 SQLite 范围和 PG 尚未接入,避免把“命令不支持”误解成“数据库无需维护”。中英文同步。

底层 octop-memory 已有 PG 普通 VACUUM / VACUUM FULL 运维能力,但不是当前对话命令的后端。 普通 VACUUM 主要供库内复用空间;FULL 重写表且阻塞读写。PG checkpoint 表在同一 database 内 可能由多个 agent/用户共享,不能仅暂停当前 agent 就调用 FULL。后续宜先做不阻塞聊天的只读诊断, 再按实际收益和共享范围提供管理员维护操作。本轮只做只读评估和提示修正,没有开启 PG 整理。

2026-09-18 文案回归:memory/slash memory/i18n 117 passed、2 deselected,Ruff/format 和 strict mypy 499 files 通过。未重启正在运行的 Octop;新提示需加载更新后的代码才生效。

实现与一致性边界

从对话触发

登录后的 Octop 网页聊天框或本地 CLI 对话支持以下命令,无需知道 agent 名称:

/memory slim                       查看作用、影响和当前智能体目标
/memory slim --all                 查看自己的全部在线候选和批量整理影响
/memory slim --confirm             确认现在整理当前智能体
/memory slim --all --confirm       确认现在逐个整理自己的全部在线候选
/memory status                     查看最近一次整理的阶段、耗时、扫描条数及结果

这是注册的 slash 命令,不经过模型判断执行;/memory 或错误参数只返回用法。 不带 --confirm 时只展示用途、保留历史、额外备份空间、暂停发送和无法预估耗时的说明,以及 候选名称/ID 和确认命令;不会创建维护任务、备份或预约,不影响聊天。这里是操作说明和范围预览, 不扫描 checkpoint,也不计算预期缩减量。确认执行时重新计算当前符合条件的候选并重新验证权限。 带 --confirm 后立即返回受理回执,宿主持有后台作业,网页沿用维护提示和发送暂停/恢复逻辑。 对话的 --all 与本地管理 CLI 范围不同:只选当前用户自己的 agent,不包含其他用户或共享 agent。 一个宿主同时只允许一个维护任务,整个对话批次期间也互斥;任务执行前及状态读取时重新验证所有权。 每个候选分别备份,依次处理,失败停止并将其余项标为未执行。关闭页面不会取消已受理的后台批次; 服务关闭会等待正在执行的 SQLite 作业结束,不再启动后续候选。状态仅驻留内存,新任务会替换旧状态。 维护期间当前聊天输入框被暂停时可看页面提示,恢复后用 /memory status 查看结果。 维护提示明确覆盖该智能体的所有会话,可切换到其他未维护的智能体。经过 60 秒后补充大库/磁盘 耗时说明;没有虚假的剩余时间。轮询失败时标记当前状态可能过时并持续重试,不把失败视为恢复发送。 API 保留手动维护的 done/failed/skipped 终态(kind=memory_slim),页面明确展示恢复使用或未执行, 停止转圈和计时,用户可点击“知道了”关闭结果提示;下一次维护会重新显示提示。

IM 暂不开放:现有 IM user_id 是用于会话存储的 agent owner,不是发送者的可验证维护身份。 飞书/微信等 IM 输入 /memory 会提示转到网页或本地 CLI,不启动维护;普通聊天、模型回复不会触发。 网页版命令目录和 /help 会自动展示新命令,不需要额外前端 hardcode。

命令目录通过 persist_checkpoint=False 声明维护回执只保存到聊天展示记录,不写入正在整理的 LangGraph checkpointer,以免回执等待 SQLite 锁。 已就绪的控制面历史投影仍保存命令和回复;尚未完成历史迁移的会话只保证当前回执可见,刷新后可能不保留。 这不删除既有历史,也不改变普通聊天的 capture/recall 流程。失败细节写入服务日志,聊天只提示失败, 完成结果显示备份文件名,完整备份路径仍可从本地 CLI 查看。

协调与存储

  • cli/commands/memory.py → infra/agents/memory_slim_control.py 的本机 loopback 通道。 控制端口随机,仅绑定 127.0.0.1;OCTOP_HOME/memory-slim-control.json 包含私有 token, 通过权限为 0600 的临时文件原子发布(Windows 依赖用户目录 ACL)。权限语义沿用本机 CLI 的文件系统信任。 不提供无认证的远程 HTTP 管理入口。该文件随正常退出删除,旧 token 不能调用新进程。
  • launch.py 启动/关闭控制 listener;AgentManager.memory_slim 持有任务协调器,Manager shutdown 先等待维护结束再关闭 Agent。 关闭 listener 后不再接受新作业,服务关闭会等正在执行的 SQLite worker 完成再关闭运行时。
  • 对话复用已有的 SlashCtx.agent_manager,由 handlers/memory.py 调用其 memory_slim → MemorySlimCoordinator.start_chat/chat_status;批次复用同一 _run、空闲预约和 SQLite worker。 后端 catalog 同时供 /help 和网页命令菜单使用;不新增远程管理 HTTP 端点。
  • MemorySlimCoordinator 复用 AgentManager.try_begin_history_backfill/end_history_backfill 的 空闲预约,与既有历史回填互斥;它们已覆盖 stream/call/resume 的 admission。 同一宿主同时只整理一个库。没有自动阈值触发或周期性全量压缩。
  • 仅接受正在运行、具备 CompactSqliteSaver 和独立连接 decoder 的 SQLite agent。 配套 octop-memory 必须提供 application.checkpoint_maintenance.slim_live_checkpoints; 版本不匹配、关闭记忆、PostgreSQL 或未运行的 agent 都会在改写之前失败。
  • 在线库采用 WAL。迁移每批先 BEGIN IMMEDIATE 再读/改行,防止把并发写入覆盖回旧值。 本轮扫描固定 rowid 上界,不无限追逐新增行。内容与引用同事务提交,历史 ID、metadata、 parent、writes 和业务记忆不删除。在线路径不执行历史裁剪、逆向展开或孤立 blob GC。
  • 保留兼容读连接/缓存,已有 SQLite 读快照继续读取一致内容;后台 capture/提取写入由 SQLite 写锁串行协调,不通过关闭连接或跳过 capture 来制造“空闲”。完整备份与校验在改写之前执行。
  • VACUUM 可能等待其他事务。长读事务仍占用 WAL 时,会报告“去重完成但空间回收未完成”; 释放聊天预约,保留可读的混合格式和备份,不伪报全部压缩完成,也不自动回滚。
  • 此模式针对一个运行中的 Octop 管理的库。它不能升级独立运行的旧 reader,不能保证其他进程 使用旧格式 reader 或自定义写库脚本时兼容;部署前需统一升级。共享同库的其他写入仍受 SQLite 锁影响。

验证

2026-09-18 不可整理原因诊断修复:单个 agent 的预览先验证归属,再诊断运行时,明确区分 未运行、未启用记忆、非 SQLite backend(例如 PostgreSQL)以及配套在线整理接口缺失。 修复了“已运行的 PostgreSQL agent 被过滤后只显示没有候选”的误导提示;候选列表也检查 slim_live_checkpoints 能力,避免旧安装包被误报为可在线整理。未自动切换 backend 或更新运行环境。 memory/slash memory/i18n 定向回归 117 passed、2 deselected(本轮排除已有 socket 用例); strict mypy 499 files、Ruff/format 通过。这里只验证 PostgreSQL 拒绝提示,没有新增 PG 瘦身能力。

2026-09-18 确认与维护提示改造:两个仓库从各自当前 HEAD 签出 feature/memory-slim-tool,保留 全部未提交改动。Octop 原分支为 feature/octop-harness-bump,octop-memory 原分支为 main。

  • 上述对话/维护回归加 tests/integration/test_memory_api.py:201 passed,覆盖预览无任务/无改写、 确认后执行、权限和接口终态;uv run --no-sync mypy --strict src/octop:499 files 通过。
  • npm test -- src/pages/Chat/hooks/useMemoryMaintenance.test.ts src/pages/Chat/components/MemoryMaintenanceBanner.test.tsx: 9 passed,覆盖长耗时解释、断连重试、完成/失败恢复发送和可关闭结果;npm run build 通过。
  • 本轮不改库内迁移实现、不重复完整门禁;此前全量门禁限制见下。未提交、部署或执行真实库维护。

2026-09-18 对话入口补充:

PYTHONPATH=../octop-memory/src:src uv run --no-sync pytest tests/unit/agents/test_memory_slim.py tests/unit/gateway/test_slash*.py tests/unit/gateway/test_message_keys.py tests/unit/gateway/test_gateway.py tests/unit/history/test_projection.py tests/unit/i18n -q

178 passed,覆盖真实临时 SQLite 的对话触发、历史保留、用户隔离、批次串行/互斥、所有权变更、 失败和关机停止后续项、IM owner fallback 禁止授权、禁用用户、进度/结果、gateway 注入、 维护回执不访问 checkpointer。strict mypy 499 files、Ruff/format 通过。 随后补充“等待活跃对话结束期间 owner 变更”的检查:取得维护预约后再次验证 owner,6 个 chat 协调器用例定向复跑通过(含新增用例),strict mypy 再次通过;未获授权时不创建备份或改写库。 没有更改前端源文件或库内存储实现;未重复全量门禁,其既有环境限制见下。未部署、重启或整理真实库。

临时数据库验证 reader snapshot、批次间并发替换/新增、迁移故障、备份可读和历史保留。 协调器测试覆盖等待活跃调用、维护期间新调用等待、成功/失败释放、取消时先等待 worker 完成, 本机控制认证/进度及 CLI 中文输出。前端测试覆盖每个阻塞阶段与成功/失败后的发送恢复。

# 从 Octop 仓库运行,加载配套 octop-memory 源码。
PYTHONPATH=../octop-memory/src:src uv run --no-sync pytest tests/unit/agents/test_memory_slim.py tests/unit/i18n -q
cd dashboard
npm test -- src/pages/Chat/hooks/useMemoryMaintenance.test.ts
npm run build

本轮只在临时库测试,未更新正在运行的生产进程、未对用户真实库执行瘦身。

2026-09-18 选择与持续进度补充验证:coordinator/CLI/控制通道/i18n 共 81 passed,覆盖编号选择、 错误编号重新输入、重名识别、空列表、只读发现、JSON 禁止自动选择,以及备份阶段无状态变化时 仍持续发送耗时心跳。strict mypy 498 files 通过;本地脚本 --online --help 和 shell 语法检查通过。 本轮未改动存储迁移/前端代码,未重复全量测试;完整门禁的既有环境限制见下。

2026-09-18 --all 补充验证:上述定向测试更新为 88 passed,新增串行执行、默认项不干扰、 批次及单项进度、人类可读/JSON 输出、失败/断连停止、参数冲突和空列表覆盖。 strict mypy 498 files、Ruff/format、wrapper --online --all --help 通过。没有执行真实库整理。

2026-09-18 验证结果:

  • octop-memory checkpoint compaction:37 passed(含长 reader 与并发写入)。
  • Octop 协调器/本机控制/CLI/记忆面板保护 + 原 memory API 集成 + i18n:90 passed。 本机 socket 测试因默认 sandbox 不允许 bind,放行仅此临时测试后通过;没有使用真实用户库。
  • 更广的 agent manager、启动及 CLI registry 回归:153 passed、1 skipped;唯一初次失败为 上述 socket bind 权限,已在后续放行的测试中通过。
  • Ruff/format、strict mypy(Octop 498 files、octop-memory 107 files)通过; 前端 2 个阶段恢复测试、TypeScript 编译与生产构建通过。
  • 两仓完整门禁均未全绿:octop-memory 的 24 个既有测试访问不可写的默认用户目录失败; Octop 全量在旧 captcha 测试绑定端口时报 PermissionError,确认环境原因后中止全量运行, 复跑该文件定位为 2 passed / 1 error。未把中止结果或 PostgreSQL skip 当成通过。
  • 多 GiB 库/完整生产 IM 端到端/长期磁盘增长未测;本轮没有提交、部署或重启真实 Octop。

2026-09-20 提交前验证与依赖收敛

  • 维护对象由 AgentManager.memory_slim 持有,shutdown 等待维护完成后关闭 Agent; Gateway、SlashCtx、OctopServer 不再增加专用传递字段。CLI 控制入口按请求获取当前 runtime, 支持首次配置完成后加载 AgentManager。
  • /memory 在 catalog 声明 persist_checkpoint=False;processor 统一读取保存策略, 普通命令及别名继续写入 checkpoint 和已就绪的聊天展示记录。
  • UV_CACHE_DIR=/tmp/octop-uv-cache PYTHONPATH=../octop-memory/src:src make all RUN='uv run --no-sync' PYTEST_JOBS=4: 3361 passed、18 skipped;Ruff/format 和 mypy(499 source files)通过。
  • cd dashboard && npm test -- src/pages/Chat/components/MemoryMaintenanceBanner.test.tsx src/pages/Chat/hooks/useMemoryMaintenance.test.ts: 9 passed。提交钩子另执行 change-aware 检查和 npm run build(包含 tsc -b)。
  • 未执行真实记忆库瘦身或 PostgreSQL 维护;在线能力仍明确限定为兼容 SQLite。