Files
persistent-chat-plugin/docs/ARCHITECTURE.md
2026-06-26 18:51:01 +08:00

9.3 KiB
Raw Permalink Blame History

架构ARCHITECTURE.md

持久对话 MCP 插件的完整技术架构


1. 整体拓扑

┌────────────────────┐
│   Trae / Cursor    │  IDESOLO Agent 窗口)
│   (MCP client)     │
└─────────┬──────────┘
          │ stdio JSON-RPC
          │ 4 tools: init / select / wait / merge
          ▼
┌────────────────────┐
│  ensure-hub.sh     │  stdio → HTTP 桥接
│  (MCP server)      │
└─────────┬──────────┘
          │ HTTP (13458)
          ▼
┌────────────────────┐
│   hub.js (主)      │  ┌─ 远端主链: 192.168.110.101:13458
│   Node 22 + HTTP   │  └─ 本地兜底: 127.0.0.1:13458
└─────────┬──────────┘
          │ 短轮询10s
          ▼
┌────────────────────┐
│   sessions.json    │  持久化层
│   bindings.json    │  - sessions: ct_xxx → 状态
│   plan-bindings    │  - bindings: workspace::title@ip → ct_
│   thread-bindings/ │  - plan: planName → ct_
└────────────────────┘  - thread: threadId → ct_

        ↓ 周期同步(可选)
┌────────────────────┐
│   MongoDB          │  远端数据库
│   karuo_site       │  (port 27017)
└────────────────────┘

2. 核心数据流

2.1 初始化

Agent → init_conversation(cursorTitle=标签, newPlan=true, planLabel=xxx)
  → ensure-hub.sh → POST /api/init
  → hub.js 创建 sessionct_xxx
  → 写入 sessions.json
  → 写 bindingworkspace::title@ip → ct_xxx
  → 返回 { token: ct_xxx, status: holding }

2.2 选择已有

Agent → select_conversation(token=ct_xxx, cursorTitle=标签)
  → ensure-hub.sh → POST /api/select
  → hub.js 验证垂直绑定workspace::title@ip 三件指纹)
  → 不匹配 → 403 BINDING_REJECTED
  → 匹配 → 复用 session

2.3 真挂起

Agent → wait_for_user_input(token, message, timeout)
  → ensure-hub.sh → POST /api/wait/register
  → hub.js 设置 session.status = "waiting"
  → 注册到 pendingWaits[token]
  → 长连接(短轮询 10s 续约)
  → 收到 reply
       a. 用户发消息 → deliverReply → 返回
       b. timedReply 触发10s 间隔)→ deliverReply("保活续跑") → 返回
       c. POLL_TIMEOUT_MS=10s → renewal → 继续轮询
  → Agent 端按 status 决定:
       - "replied" → 返回 text
       - "renewal" → 继续 poll
       - "gone" → 重新 register

2.4 合并

Agent → merge_conversation(fromToken, toToken, cursorTitle)
  → ensure-hub.sh → POST /api/merge
  → hub.js 把 fromToken 的 messages 追加到 toToken
  → fromToken 标记 archived
  → 增量保存 sessions.json

3. 垂直绑定

3.1 绑定指纹

bindingKey = `${workspace}::${cursorTitle}@${hostIp}`

示例(默认公示用主链 IP

/Users/karuo/Documents/个人::持久对话永久续跑-20260626@192.168.110.101

3.2 验证时机

触发 验证
select_conversation 严校验(必须完全匹配)
init_conversation 宽校验(可换 title 重新绑定)
wait_for_user_input 中校验(容许 title 改名)
merge_conversation 严校验(不匹配拒绝)

3.3 改标签自动迁移

// 用户在 Trae 改了标签 "A" → "B"
// wait 时传入新 title "B"
// hub.js 检测到旧 binding 有 token旧 bindingKey 不匹配
// 允许迁移:把 bindingKey 改成新值token 复用

4. session 状态机

   init
    │
    ▼
  holding ──────┐
    │            │ (每 10s 续约 / 接收新消息)
    │            │
    ▼            │
  waiting ───────┤
    │            │
    │ (用户发消息)│
    ▼            │
  replied ───────┘
    │
    │ (autoStreak 累加)
    ▼
  running
    │
    │ (merge / 结束持久对话)
    ▼
  merged / archived

5. autoStreak 与 keepAlive

5.1 概念

  • autoStreak:连续"用户不发消息"的轮次计数
  • keepAliveHub 在 autoStreak 超阈值时主动推"保活续跑"消息

5.2 真挂起模式(推荐)

POST /api/session/config
{
  "sessionAutoContinue": false,
  "timedReplyEnabled": false,
  "timedReplyIntervalMs": 0
}

效果

  • 关闭 timedReply → 不会主动推"保活续跑"
  • 关闭 autoContinue → 不会因为 idle 触发续跑
  • wait 唯一返回源 = 用户真消息
  • MCP 工具调用一直阻塞agent turn 不会结束

5.3 自动模式(不推荐,会顶回 wait

{
  "sessionAutoContinue": true,
  "timedReplyEnabled": true,
  "timedReplyIntervalMs": 10000
}

效果

  • 每 10s 推"保活续跑"
  • wait 立即返回
  • agent turn 结束UI 显示"任务完成"

6. 短轮询 vs 长连接

方案 优点 缺点 采用
短轮询10s 简单、跨网段友好、稳 续约频繁
WebSocket 实时、省资源 需配 wss、断线重连复杂
Server-Sent Events 单向实时 不支持双向
Long Polling 接近实时 服务器维护成本 (短轮询已够)

短轮询间隔:POLL_TIMEOUT_MS = 1000010s可在 hub.js 改。


7. 数据持久化

7.1 文件布局

~/.persistent-chat-local/
├── sessions.json              # 主 session 数据
├── bindings.json              # workspace::title@ip → ct_
├── plan-bindings.json         # planName → ct_
├── thread-bindings/           # threadId → ct_  (mkdir)
├── archive/                   # 归档 session
│   └── 2026-06/
│       └── ct_xxx.json
├── replies/                   # 历史用户回复缓存
├── logs/
│   ├── hub.log                # Hub 主日志
│   ├── launchd.log            # macOS launchd 日志
│   └── launchd.err
├── templates/                 # 面板模板
├── server.js                  # MCP server41KB
├── hub.js                     # Hub 主服务89KB
├── panel.html                 # 浏览器面板84KB
├── cursor-title.js            # 标签解析器4KB
├── ensure-hub.sh              # 启动器
└── mongo_sync.py              # → MongoDB 同步

7.2 sessions.json 格式

{
  "ct_xxxx": {
    "token": "ct_xxxx",
    "title": "永久续跑三段式",
    "displayTitle": "",
    "status": "holding",
    "workspace": "/Users/karuo/Documents/个人",
    "createdAt": 1782448693854,
    "lastActiveAt": 1782449356228,
    "msgCount": 10,
    "autoStreak": 1,
    "bindingKey": "/Users/karuo/Documents/个人::标签@192.168.110.101",
    "hostIp": "192.168.110.101",
    "hub": "192.168.110.101:13458",
    "bindingCheckCount": 17,
    "continueMode": "optimize",
    "sessionAutoContinue": false,
    "timedReplyEnabled": false,
    "timedReplyIntervalMs": 0,
    "messages": [
      { "role": "user", "content": "...", "at": 1782448794716, "auto": false },
      { "role": "assistant", "content": "...", "at": 1782449116363, "auto": false }
    ],
    "lastReview": {
      "hasReview": false,
      "completionPct": null,
      "nextStep": "",
      "isIdleNext": true
    }
  }
}

7.3 周期保存

  • 每次 register / deliverReply / merge 后 saveSessions()
  • 写盘:原子 rename先写 .tmp再 rename
  • 加载:启动时一次 loadSessions(),之后只内存操作

8. 与 MongoDB 同步(可选)

mongo_sync.py 把 sessions.json 周期同步到 MongoDB karuo_site.sessions

# 触发
python3 mongo_sync.py
# 或 cron 每 5 分钟
*/5 * * * * cd ~/.persistent-chat-local && python3 mongo_sync.py

用途:

  • 多机同步(局域网内多 Hub
  • 长期归档(超过 1000 个 session 不卡)
  • 跨平台Mac / NAS / Linux

9. 安全性

维度 措施
端口 13458 默认仅 LAN 监听,不暴露公网
鉴权 垂直绑定(三件指纹),无 token → 拒绝
数据 sessions.json 落在 ~/.persistent-chat-local/,权限 600
跨网段 靠 SSH 隧道 / VPN
日志 不记录用户隐私内容(只记 metadata
卡密激活 已删除v1.6.37 不再有 license 校验)

10. 性能

指标
Hub 内存 ~50MB1000 个 session
Hub CPU < 1%(空闲)
单 session 占内存 ~5KB仅 metadata
单消息占内存 ~1KB
短轮询带宽 ~1KB/10s/session
启动时间 < 1sNode 22
sessions.json 加载 10000 个 session < 500ms

11. 版本演进

版本 日期 关键变化
v1.1 2025-12 初版(仅 hub.js
v1.5 2026-03 加 server.js / MCP 4 工具
v1.6.30 2026-05 autoStreak / timedReply
v1.6.37 2026-06-07 删除卡密激活 / 加 MongoDB 同步
v1.6.68 2026-06-20 本地增强VSIX 4.6 兼容)

最后更新2026-06-26 · 卡若AI