Skip to main content
Glama
README.md
# OpenContinuity

OpenContinuity 是一个 local-first、用户可控的跨 Agent 共享记忆与任务交接层。它通过 MCP 或 HTTP 让不同 Agent 在同一用户身份和明确 scope 下读写同一事实层,并保留来源、版本、权限与审计历史。

当前发布候选为 `1.1.0-beta.1`,定位是 Developer Preview:Lite 本地闭环已可验证,Team 是实现预览,Enterprise 尚未实现。

```mermaid
flowchart LR
  subgraph C[Agent clients]
    A[Agent A]
    B[Agent B]
    D[Agent C]
  end

  subgraph O[OpenContinuity]
    X[MCP / HTTP / CLI]
    P[Identity · scope · policy]
    W[Remember · evolve · audit]
    R[Recall · context · bounded query]
    H[Handoff Capsule]
  end

  subgraph S[Storage Profiles]
    L[Lite · SQLite]
    T[Team · PostgreSQL]
  end

  A & B & D --> X
  X --> P
  P --> W
  P --> R
  P --> H
  W --> L & T
  R --> L & T
  H --> L & T
```

## 为什么它不只是 RAG

RAG、全文检索和 Agentic Retrieval 解决“如何找到内容”;OpenContinuity 还解决:

- **谁的记忆**:稳定用户身份和独立 Agent 身份。
- **谁能看到**:user、task、agent scope 以及 private 策略。
- **如何演化**:版本、CAS、幂等写入、来源和不可变事件历史。
- **如何交接**:结构化 Handoff Capsule,而不是复制整段对话。
- **如何带走**:带校验摘要、与具体数据库解耦的 Memory Package。
- **如何撤销**:查看、审计、遗忘、备份和恢复由用户控制。

支持四类结构化记忆:`user_preference`、`user_fact`、`task_state` 和 `decision`。OpenContinuity 不会自动截取第三方 Agent 的完整对话;Agent 是否主动调用工具仍取决于客户端与模型工具策略。

## 当前可验证能力

| 能力 | 当前证据 |
| --- | --- |
| 跨 Agent 共享记忆与 Handoff | `open-continuity demo` 启动两个真实 MCP stdio 客户端进行隔离验证 |
| Lite 本地运行 | SQLite、FTS5、事务、审计历史、备份与恢复 |
| Agent 接入 | Trae 真实 MCP E2E;Claude Code 和 Codex 连接器自动化测试 |
| 可移植性 | Memory Package 校验、空目标导入和本地身份重绑定 |
| 发布质量 | macOS/Linux、Node.js 22/24 CI,完整测试、审计、打包和安装后冒烟 |

详细边界见[兼容性矩阵](./docs/compatibility.md)与[支持策略](./SUPPORT.md)。

## 5 分钟开始使用

运行环境要求 Node.js 22.13 或更高版本。正式发布后先安装到稳定路径,再连接客户端:

    npm install --global open-continuity
    open-continuity demo
    open-continuity init
    open-continuity connect trae
    open-continuity doctor

`connect` 会拒绝把临时 `npx` 缓存路径写入永久客户端配置;全局安装或项目内持久安装都可以。

`demo` 是不修改真实配置的产品证明:它会启动两个使用不同 Agent 身份的真实 MCP stdio 进程,让 Agent A 向临时 SQLite 写入记忆并创建 Handoff Capsule,关闭 Agent A 后再由 Agent B 读取记忆和恢复交接,最后自动删除临时数据库。它不要求提前执行 `init`,也不会访问 `~/.open-continuity/memories.db`。

从源码体验:

    npm install
    npm run build
    node dist/src/cli.js demo
    node dist/src/cli.js init
    node dist/src/cli.js connect trae
    node dist/src/cli.js doctor

`init` 会生成一个本地用户身份并创建 `~/.open-continuity/memories.db`。不同连接器共享同一个用户身份,同时各自绑定固定 Agent 身份,因此模型不需要猜测 `userId` 或 `agentId`。`connect` 修改客户端配置前会建立备份;已有同名 MCP Server 时默认拒绝覆盖,只有显式传入 `--force` 才会替换。当前连接器支持 `trae`、`claude` 和 `codex`,详细验证状态见 [兼容性矩阵](./docs/compatibility.md)。

常用管理命令:

    open-continuity database check
    open-continuity database backup --output ./memories-backup.db
    open-continuity database restore ./memories-backup.db --yes
    open-continuity memories list
    open-continuity memories list --query "test runner"
    open-continuity memories show <memory-id>
    open-continuity memories history <memory-id>
    open-continuity memories forget <memory-id> --yes
    open-continuity export --output ./memory-package
    open-continuity import ./memory-package

恢复和删除操作必须显式添加 `--yes`。恢复会写入一个新的数据库文件并原子切换本地配置,旧数据库不被覆盖;此前连接的 Agent 需要执行 `open-continuity connect <agent> --force` 并重启客户端,才能使用新库。CLI 导出只包含当前本地用户的数据;导入只接受通过校验且目标数据库为空的 Memory Package,并将来源用户身份重新绑定到当前本地用户,不会静默合并或覆盖现有记忆。

## 源码开发

    npm install
    npm run typecheck
    npm test
    npm run build
    npm run dev
    npm run benchmark:lite -- --memories=1000 --iterations=20

HTTP 服务默认监听 http://127.0.0.1:8787。MCP Server 使用 stdio transport,适合配置到支持 MCP 的 Agent 中。默认使用 Node 内置 SQLite,数据保存到 `~/.open-continuity/memories.db`,无需安装独立数据库服务;团队部署可切换到 PostgreSQL。运行环境要求 Node.js 22.13 或更高版本。

准备 Developer Preview 时运行 `npm run release:check`;该命令会完成类型检查、完整测试、生产依赖审计、包内容检查,以及从真实 tarball 隔离安装后的双 Agent MCP 演示。性能基准说明见 [Lite benchmark](./docs/benchmarking.md),外部发布步骤和权限边界见[发布检查清单](./docs/release-checklist.md)。版本变化记录在 [CHANGELOG](./CHANGELOG.md)。

直接启动 MCP:

    npm run build
    npm run start:mcp

以 Codex、Claude Code 等客户端为例,配置一个 MCP Server:

    {
      "mcpServers": {
        "open-continuity": {
          "command": "node",
            "args": ["/Users/you/personal/open-continuity/dist/src/server.js", "--mcp"],
          "env": {
            "OPEN_CONTINUITY_PROFILE": "lite",
            "OPEN_CONTINUITY_STORE": "sqlite",
            "OPEN_CONTINUITY_SQLITE_PATH": "/Users/you/.open-continuity/memories.db",
            "OPEN_CONTINUITY_USER_ID": "local-shared-user",
            "OPEN_CONTINUITY_AGENT_ID": "claude"
          }
        }
      }
    }

手动配置多个客户端时,必须保持 `OPEN_CONTINUITY_USER_ID` 相同,并为每个客户端设置不同的 `OPEN_CONTINUITY_AGENT_ID`。优先使用 CLI 连接器自动生成和管理这两个身份。

客户端接入后会发现九个工具:原有的 `memory_capabilities`、`memory_remember`、`memory_recall`、`memory_context`、`memory_query`、`memory_history`、`memory_forget`,以及 `memory_handoff_create` 和 `memory_handoff_resume`。`memory_capabilities` 用于发现当前 Profile 和可用能力;`memory_context` 用于一次检索后生成 Context Pack;`memory_query` 用于有预算的多步检索。Agent 是否主动调用这些工具仍由客户端/模型的工具策略决定;当前不自动拦截每一轮完整对话。

## Handoff Capsule

用户明确说“交接一下”时,Agent 可以调用 `memory_handoff_create`,保存任务摘要、状态、关键决策、下一步、产物和阻塞项。另一个 Agent 通过 `memory_handoff_resume` 按 `taskId` 恢复最新的未过期交接包。交接包使用 task scope,不会混入其他任务,并可配置 `expiresAt`。它解决的是一次工作的可靠续接,不等同于永久用户画像。

## 隐私边界

- Lite 默认只在本机 SQLite 中保存数据,不调用外部 embedding 或生成模型。
- OpenContinuity 不会自动截取完整对话,只处理 Agent 明确调用工具时提交的结构化记忆。
- MCP Server 会向支持说明字段的客户端声明:不得保存凭据、秘密或完整对话。
- private 记忆默认无法读取;启用前需要显式调整运行时策略。
- 用户可以查看历史、删除记忆并导出完整事件链。

## Runtime Profile

推荐优先配置 Profile,而不是只配置存储:

    OPEN_CONTINUITY_PROFILE=lite

| Profile | 默认存储 | 每通道候选预算 | Context Pack 默认/最大预算 | 最多记忆数 | 当前状态 |
| --- | --- | --- | --- | --- | --- |
| Lite | SQLite | 50 | 1024 / 4096 tokens | 20 | 已实现 |
| Team | PostgreSQL | 100 | 4096 / 16384 tokens | 50 | 基础版本已实现 |
| Enterprise | 尚未固定 | 尚未固定 | 尚未固定 | 尚未固定 | 未实现,启动时明确报错 |

没有设置 `OPEN_CONTINUITY_PROFILE` 时会兼容旧配置:SQLite 或 JSON 自动推导为 Lite,PostgreSQL 自动推导为 Team。显式 Profile 与 Store 冲突时会拒绝启动,例如 `team + sqlite` 或 `lite + postgres`。JSON 只能作为 Lite 的 legacy compatibility mode。

Lite 启动示例:

    OPEN_CONTINUITY_PROFILE=lite npm run start

Team 启动示例:

    OPEN_CONTINUITY_PROFILE=team \
    OPEN_CONTINUITY_DATABASE_URL="$YOUR_POSTGRES_URL" \
    npm run start

HTTP 可通过 `GET /health` 和 `GET /v1/capabilities` 发现当前 Profile。MCP 客户端可调用 `memory_capabilities` 获取相同信息,包括存储类型、检索通道、候选预算、Context Pack 预算,以及 semantic、rerank、agentic、graph 是否可用。

Agentic Query 的默认/最大预算如下:

| Profile | 默认/最大步骤 | 默认/最大超时 | 最大子查询 | 历史事件预算 |
| --- | --- | --- | --- | --- |
| Lite | 3 / 4 | 1500 / 5000 ms | 3 | 50 |
| Team | 5 / 8 | 3000 / 10000 ms | 8 | 100 |

## 存储模式

Lite 默认使用单文件 SQLite:

    OPEN_CONTINUITY_STORE=sqlite
    OPEN_CONTINUITY_SQLITE_PATH=/Users/you/.open-continuity/memories.db

SQLite 启用 WAL、写入等待和事务,支持多个本机 Agent 进程共享;`query` 查询使用 FTS5 trigram 索引,两个字符以内的短查询回退为普通子串匹配。FTS 只是可重建索引,事实和历史仍保存在 `memories_current` 与 `memory_events` 两张表中。

需要显式创建或升级 SQLite schema 时可以运行:

    OPEN_CONTINUITY_SQLITE_PATH=/Users/you/.open-continuity/memories.db npm run db:migrate:sqlite

日常维护建议先停止或重启正在连接该数据库的 Agent 客户端:

    open-continuity database check
    open-continuity database backup --output ./memories-backup.db
    open-continuity database restore ./memories-backup.db --yes

`database check` 执行 SQLite 完整性检查并报告 schema 版本、当前记忆数和事件数。备份使用 SQLite `VACUUM INTO` 产生独立、一致的数据库文件。恢复会先完整校验来源,再写入一个全新文件并原子更新本地配置;原数据库保留为回滚点,避免覆盖正在被旧 Agent 进程使用的文件。恢复结果会列出需要 `connect --force` 后重启的 Agent,`doctor` 也会把仍指向旧数据库的连接标记为未就绪。

V0.4 JSON 模式继续作为显式兼容选项:

    OPEN_CONTINUITY_STORE=json
    OPEN_CONTINUITY_DATA_FILE=/Users/you/.open-continuity/memories.json

从旧 JSON ledger 迁移到一个空的 SQLite 数据库:

    npm run data:import-json -- \
      --input /Users/you/.open-continuity/memories.json \
      --database /Users/you/.open-continuity/memories.db

导出 SQLite 中的完整事件历史:

    npm run data:export-json -- \
      --database /Users/you/.open-continuity/memories.db \
      --output ./open-continuity-export.json

导入命令只接受 OpenContinuity 事件 ledger,且目标数据库必须为空,因此不会静默合并或覆盖已有记忆。V0.4 升级后默认存储由 JSON 改为 SQLite;已有用户应先执行上述显式迁移,原 JSON 文件不会被自动删除或修改。

PostgreSQL 模式:

    OPEN_CONTINUITY_STORE=postgres
    OPEN_CONTINUITY_DATABASE_URL="$YOUR_POSTGRES_URL"
    OPEN_CONTINUITY_AUTO_MIGRATE=true
    npm run start

运行时默认会在启动前执行幂等迁移,并使用 PostgreSQL advisory lock 避免多个 Agent 进程首次启动时并发建表。也可以单独执行:

    OPEN_CONTINUITY_DATABASE_URL="$YOUR_POSTGRES_URL" npm run db:migrate:postgres

PostgreSQL 使用两张核心表:

- `memories_current`:当前有效记忆,供 `memory_recall` 快速查询。
- `memory_events`:不可变事件历史,供 `memory_history` 审计查询。

当前 Team Profile 尚未启用 pgvector,语义向量检索属于下一阶段;V1.0 的 Context Pack 和 Agentic Query 仍使用确定性混合检索,不引入外部 embedding 或生成模型。

## 产品分层

OpenContinuity 使用同一套记忆协议和数据语义,提供三种部署 Profile;它们不是三套互不兼容的产品。

| Profile | 面向场景 | 正式存储 | 默认检索 | 状态 |
| --- | --- | --- | --- | --- |
| Lite | 个人、本地 Agent | SQLite | 精确匹配、结构化过滤、FTS5 全文检索 | V1.0 已实现 |
| Team | 团队、多 Agent、多进程 | PostgreSQL + 可选 pgvector | 精确/结构化/全文融合,后续可加向量与重排 | PostgreSQL 与基础混合检索已实现,向量待实现 |
| Enterprise | 企业、多租户与复杂知识关系 | PostgreSQL、对象存储、可选图存储 | 自适应查询规划、多路召回、图谱多跳与证据验证 | 远期计划 |

JSON 会继续作为演示、调试、兼容和导入导出格式,但不会作为个人版的长期正式存储。不同 Profile 共享 MCP/HTTP 契约、Memory 数据模型、scope/权限语义和事件历史,避免接入方随部署规模增长而重写集成。标准化的 Memory Package 仍是后续能力。

检索强度不只由数据量决定,还由问题复杂度、延迟预算、token 预算、隐私边界和计算成本决定。简单的偏好查询应直接命中结构化记忆;只有需要跨时间、跨实体或多跳证据的问题才进入 Agentic Retrieval。

详细架构边界、差异化能力和版本验收标准见 [架构与路线图](./docs/architecture-and-roadmap.md)。

## 查询契约

`memory_recall` 只返回当前有效记忆,不再携带全部事件历史。支持 `key`、`kind`、`scope`、`taskId`、`query` 过滤,以及 `limit` 和不透明 `cursor` 分页;默认 20 条,最多 100 条。

不传 `query` 时,响应保持 V0.5 的确定性结构化查询格式。传入 `query` 时,响应会额外包含检索回执:

    {
      "memories": [
        {
          "key": "response_style",
          "retrieval": {
            "score": 0.0327868852,
            "channels": ["exact", "full_text"],
            "ranks": { "exact": 1, "full_text": 1 }
          }
        }
      ],
      "nextCursor": null,
      "retrieval": {
        "mode": "hybrid",
        "channels": ["exact", "full_text"],
        "candidateCount": 1,
        "candidateLimit": 50
      }
    }

检索游标绑定完整查询条件,不能跨 query、用户、Agent 或 scope 复用;非法或错配游标会返回 `VALIDATION_ERROR`。回执中的 `channels` 只包含实际产生候选的通道;当前 RRF 的 `k=60`,分数用于稳定排序和解释,不代表概率或事实置信度。`candidateLimit` 是每个检索通道的候选预算,不是最终返回条数;最终返回条数仍由请求的 `limit` 控制。

    {
      "memories": [],
      "nextCursor": null
    }

## Context Pack 契约

`memory_context` 和 HTTP `POST /v1/context-pack` 在 `memory_recall` 之上完成面向消费 Agent 的二次选择。请求必须包含 `userId`、`agentId` 和非空 `query`,还可以指定 `taskId`、`purpose`、`tokenBudget` 与 `maxMemories`:

    {
      "userId": "u1",
      "agentId": "claude",
      "query": "open-continuity implementation",
      "taskId": "task-42",
      "purpose": "coding",
      "tokenBudget": 1024,
      "maxMemories": 10
    }

`purpose` 支持 `general`、`coding`、`research` 和 `browser`。Builder 先复用当前 Profile 的检索管线,再综合检索分数、task/agent scope、用户确认状态和 purpose 对 memory kind 的偏好进行稳定排序。响应包含:

- `context`:逐行 JSON,可直接作为一段结构化上下文注入 Agent。
- `items`:入选记忆、估算 token、排序分数和选择原因。
- `omitted`:因 `token_budget` 或 `max_memories` 未进入上下文的完整记忆引用。
- `budget`:请求预算、实际使用、剩余预算和估算方法。
- `retrieval`:底层混合检索的通道和候选回执。

V0.8 使用确定性的 `utf8_bytes_v1` 估算,即 UTF-8 字节数除以 4 后向上取整。它不是特定模型 tokenizer 的精确计数。为避免改变事实语义,单条记忆放不下时会整条省略,不会截断或调用模型压缩;调用方可从 `omitted` 看到原因。Context Pack 继续遵守原有 user/task/agent scope 和 private 策略,不会扩大底层检索权限。

## Agentic Query 契约

`memory_query` 和 HTTP `POST /v1/query` 是独立于 `memory_recall` 的增强查询入口。调用方可以只提供自然语言查询,也可以显式提供更可靠的 `subqueries`:

    {
      "userId": "u1",
      "agentId": "claude",
      "query": "项目技术决策的演化",
      "strategy": "multi_step",
      "subqueries": ["TypeScript", "Vitest"],
      "includeHistory": true,
      "maxSteps": 3,
      "timeoutMs": 1000,
      "minEvidence": 2
    }

响应包含 `plan`、逐步 `steps`、去重融合后的 `evidence`、可直接消费的 `contextPack`、`sufficiency`、实际执行预算以及 `fallback`。复杂度分为 L0-L3:L0 是显式 key,L1 是单次混合检索,L2 是多子查询或历史扩展;L3 表示需要关系或语义多跳,V1.0 只做尽力召回并返回 `unsupported_complexity`,不会声称已经完成图谱推理。

规划器是 `deterministic_v1`。显式 `subqueries` 最可靠;自动拆分只识别有限的中英文连接词。`direct` 强制只执行一次 recall,不能与 `includeHistory=true` 同用。显式子查询超过当前 Profile 上限会返回 `VALIDATION_ERROR`,自动拆分超限会截断并返回 `subquery_limit`。历史扩展按排名靠前的候选 memoryId 定向读取,最多展开 `maxSubqueries` 个候选,并共享当前 Profile 的历史事件预算;发生截断时会标记 `history_limit` 和 `history.truncated=true`。整体超时基于 `Promise.race`:结果会停止等待并确定性降级,但底层只读数据库调用无法被强制取消,其迟到结果会被忽略。

`sufficiency.status` 的语义是:`sufficient` 表示查询覆盖、最小证据、历史要求和执行预算全部满足;有部分证据时为 `partial`;完全没有证据时为 `insufficient`。无论走几步,scope、task、Agent 私有范围和 private 策略都不会被放宽。

## 记忆演化契约

`memory_remember` 和 HTTP `POST /v1/memories` 继续兼容 V0.8 请求;不传演化字段时仍采用 `replace + last_write_wins`。需要防止多个 Agent 基于旧状态互相覆盖时,可以传 `expectedVersion`:

    {
      "userId": "u1",
      "agentId": "claude",
      "key": "coding_preferences",
      "value": { "formatting": { "quotes": "single" } },
      "kind": "user_preference",
      "writeMode": "merge",
      "expectedVersion": 1,
      "confidence": 0.8,
      "confidenceBasis": "source_supported",
      "idempotencyKey": "update-42"
    }

- `expectedVersion=0` 表示仅当该逻辑 key 尚不存在时创建;大于 0 时要求当前版本完全匹配,否则返回 HTTP 409 / `VERSION_CONFLICT`。
- `writeMode=replace` 整体替换值;`writeMode=merge` 只接受 JSON 对象并确定性深度归并。数组和标量不会智能合并。
- 成功回执的 `evolution` 包含 `created/replaced/merged`、新版本、并发模式及 `supersedes`。
- `confidence` 必须与 `confidenceBasis` 一起提交;依据可以是 `user_asserted`、`agent_inferred` 或 `source_supported`。`user_asserted` 还要求 `userConfirmed=true`。系统不会自行生成一个看似精确的置信度。
- 当前记忆、历史事件和 Context Pack 都会保留 `version`、`supersedes` 与 `confidence`。历史事件同时记录归并前的输入补丁和归并后的最终值。

V0.9 的 `merge` 是可复现的数据操作,不是模型自动解决语义冲突。例如“默认喜欢详细解释”和“编码时喜欢简短回答”仍应由调用方写成不同 scope/key 或条件化对象;自动冲突判断、语义归并和归并撤销仍属于后续能力。

审计历史通过 `memory_history` 或 HTTP `GET /v1/memory-events` 单独查询:

    {
      "events": [],
      "nextCursor": null
    }

scope 语义如下:

- `user`:同一用户的不同 Agent 都可读取。
- `task`:写入时必须指定 `taskId`,读取和删除时必须进入相同任务。
- `agent`:只对创建该记忆的 Agent 可见。

## 本地安全配置

默认不配置 API Key,保持本地开发的零配置体验。需要限制 HTTP 调用方时,在环境变量中设置:

    OPEN_CONTINUITY_API_KEY=replace-with-a-local-secret
    OPEN_CONTINUITY_ALLOWED_AGENTS=codex,claude,glm
    OPEN_CONTINUITY_ALLOW_PRIVATE=false

HTTP 请求可以使用以下任一方式携带 API Key:

    x-open-continuity-api-key: replace-with-a-local-secret
    Authorization: Bearer replace-with-a-local-secret

当配置 Agent 白名单后,`agentId` 不在白名单中的请求会返回 403。private 记忆默认不能通过接口读取;只有明确设置 `OPEN_CONTINUITY_ALLOW_PRIVATE=true` 后,调用方传 `includePrivate=true` 才会返回。

HTTP 和 MCP 错误都遵循统一结构:

    {
      "error": {
        "code": "VALIDATION_ERROR",
        "message": "Request validation failed",
        "details": []
      }
    }

测试中的 MemoryService 默认使用内存存储;HTTP/MCP 运行时通过 `OPEN_CONTINUITY_STORE` 选择 SQLite、JSON 或 PostgreSQL。SQLite 是个人版默认模式;JSON ledger 保留文件锁与原子替换以兼容 V0.4;PostgreSQL 使用事务、唯一约束和索引,适合多进程和后续多实例部署。语义 planner、pgvector、图遍历、Outbox、OAuth、多租户和完整 Handoff 放在后续版本。

Maintenance

ActivityMaintained
ResponsivenessNo issues