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

341 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 架构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 改标签自动迁移
```javascript
// 用户在 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`:连续"用户不发消息"的轮次计数
- `keepAlive`Hub 在 autoStreak 超阈值时主动推"保活续跑"消息
### 5.2 真挂起模式(推荐)
```json
POST /api/session/config
{
"sessionAutoContinue": false,
"timedReplyEnabled": false,
"timedReplyIntervalMs": 0
}
```
**效果**
- 关闭 timedReply → 不会主动推"保活续跑"
- 关闭 autoContinue → 不会因为 idle 触发续跑
- wait 唯一返回源 = 用户真消息
- MCP 工具调用一直阻塞agent turn 不会结束
### 5.3 自动模式(不推荐,会顶回 wait
```json
{
"sessionAutoContinue": true,
"timedReplyEnabled": true,
"timedReplyIntervalMs": 10000
}
```
**效果**
- 每 10s 推"保活续跑"
- wait 立即返回
- agent turn 结束UI 显示"任务完成"
---
## 6. 短轮询 vs 长连接
| 方案 | 优点 | 缺点 | 采用 |
|:---|:---|:---|:---|
| 短轮询10s | 简单、跨网段友好、稳 | 续约频繁 | ✅ |
| WebSocket | 实时、省资源 | 需配 wss、断线重连复杂 | ❌ |
| Server-Sent Events | 单向实时 | 不支持双向 | ❌ |
| Long Polling | 接近实时 | 服务器维护成本 | ❌(短轮询已够) |
短轮询间隔:`POLL_TIMEOUT_MS = 10000`10s可在 `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 格式
```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`
```python
# 触发
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