Phase 1 - Security: - Add AES-GCM encryption for localStorage fallback - Enforce WSS protocol for non-localhost WebSocket connections - Add URL sanitization to prevent XSS in markdown links Phase 2 - Domain Reorganization: - Create Intelligence Domain with Valtio store and caching - Add unified intelligence-client for Rust backend integration - Migrate from legacy agent-memory, heartbeat, reflection modules Phase 3 - Core Optimization: - Add virtual scrolling for ChatArea with react-window - Implement LRU cache with TTL for intelligence operations - Add message virtualization utilities Additional: - Add OpenFang compatibility test suite - Update E2E test fixtures - Add audit logging infrastructure - Update project documentation and plans Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
262 lines
7.3 KiB
Markdown
262 lines
7.3 KiB
Markdown
# ZCLAW 智能层统一实现计划
|
||
|
||
## Context
|
||
|
||
ZCLAW 项目存在前后端智能层代码重复问题。TypeScript 前端实现了记忆、反思、心跳、压缩等智能层功能,同时 Rust 后端也完整实现了相同功能。这导致:
|
||
1. 维护成本加倍(两份代码需同步更新)
|
||
2. 功能受限(前端 localStorage 在应用关闭后无法运行)
|
||
3. 数据不持久(localStorage 有 5MB 限制)
|
||
|
||
**解决方案**:删除前端 TS 智能层代码,统一使用 Rust 后端 + TypeScript 适配器 (`intelligence-backend.ts`)。
|
||
|
||
---
|
||
|
||
## 关键文件
|
||
|
||
### 已有的 Rust 后端(保留)
|
||
- `desktop/src-tauri/src/intelligence/heartbeat.rs` - 心跳引擎
|
||
- `desktop/src-tauri/src/intelligence/compactor.rs` - 上下文压缩
|
||
- `desktop/src-tauri/src/intelligence/reflection.rs` - 自我反思
|
||
- `desktop/src-tauri/src/intelligence/identity.rs` - 身份管理
|
||
- `desktop/src-tauri/src/memory/persistent.rs` - 记忆持久化
|
||
- `desktop/src/lib/intelligence-backend.ts` - **TypeScript 适配器(已完整实现)**
|
||
|
||
### 需要删除的 TS 实现
|
||
- `desktop/src/lib/agent-memory.ts` (~487行)
|
||
- `desktop/src/lib/agent-identity.ts` (~351行)
|
||
- `desktop/src/lib/reflection-engine.ts` (~678行)
|
||
- `desktop/src/lib/heartbeat-engine.ts` (~347行)
|
||
- `desktop/src/lib/context-compactor.ts` (~443行)
|
||
- `desktop/src/lib/memory-index.ts` (~150行)
|
||
|
||
### 需要修改的消费者文件
|
||
| 文件 | 使用的旧模块 |
|
||
|------|--------------|
|
||
| `desktop/src/store/chatStore.ts` | memory, identity, compactor, reflection |
|
||
| `desktop/src/store/memoryGraphStore.ts` | memory |
|
||
| `desktop/src/components/MemoryPanel.tsx` | memory |
|
||
| `desktop/src/components/ReflectionLog.tsx` | reflection, identity |
|
||
| `desktop/src/components/HeartbeatConfig.tsx` | heartbeat |
|
||
| `desktop/src/lib/memory-extractor.ts` | memory, identity |
|
||
| `desktop/src/lib/agent-swarm.ts` | memory |
|
||
| `desktop/src/lib/skill-discovery.ts` | memory |
|
||
|
||
---
|
||
|
||
## Implementation Plan
|
||
|
||
### Phase 0: 创建统一客户端(约 2h)
|
||
|
||
**目标**: 创建环境检测机制,支持 Tauri/浏览器双环境
|
||
|
||
**新建文件**: `desktop/src/lib/intelligence-client.ts`
|
||
|
||
**实现内容**:
|
||
```typescript
|
||
import { intelligence } from './intelligence-backend';
|
||
|
||
// 检测是否在 Tauri 环境中
|
||
const isTauriEnv = typeof window !== 'undefined' && '__TAURI__' in window;
|
||
|
||
// 降级策略:非 Tauri 环境使用 localStorage 模拟
|
||
const fallbackMemory = {
|
||
store: async (entry) => { /* localStorage 模拟 */ },
|
||
search: async (options) => { /* localStorage 模拟 */ },
|
||
// ... 其他方法
|
||
};
|
||
|
||
export const intelligenceClient = {
|
||
memory: isTauriEnv ? intelligence.memory : fallbackMemory,
|
||
heartbeat: isTauriEnv ? intelligence.heartbeat : fallbackHeartbeat,
|
||
compactor: isTauriEnv ? intelligence.compactor : fallbackCompactor,
|
||
reflection: isTauriEnv ? intelligence.reflection : fallbackReflection,
|
||
identity: isTauriEnv ? intelligence.identity : fallbackIdentity,
|
||
};
|
||
```
|
||
|
||
**验证**:
|
||
- `pnpm tsc --noEmit` 编译通过
|
||
- Tauri 环境检测正确
|
||
|
||
---
|
||
|
||
### Phase 1: 迁移 Memory 模块(约 4h)
|
||
|
||
**优先级**: 最高(其他模块都依赖 Memory)
|
||
|
||
**修改文件**:
|
||
|
||
1. **chatStore.ts**
|
||
```typescript
|
||
// 修改前
|
||
import { getMemoryManager } from '../lib/agent-memory';
|
||
const memoryMgr = getMemoryManager();
|
||
const relevantMemories = await memoryMgr.search(content, { agentId, limit: 8 });
|
||
|
||
// 修改后
|
||
import { intelligenceClient } from '../lib/intelligence-client';
|
||
const relevantMemories = await intelligenceClient.memory.search({
|
||
agent_id: agentId,
|
||
query: content,
|
||
limit: 8,
|
||
});
|
||
```
|
||
|
||
2. **memoryGraphStore.ts** - 替换 `getMemoryManager()`
|
||
3. **MemoryPanel.tsx** - 替换 `getMemoryManager()`
|
||
4. **memory-extractor.ts** - 替换 `getMemoryManager()`
|
||
5. **agent-swarm.ts** - 替换 `getMemoryManager()`
|
||
6. **skill-discovery.ts** - 替换 `getMemoryManager()`
|
||
|
||
**类型适配层** (添加到 intelligence-client.ts):
|
||
```typescript
|
||
function toFrontendMemory(backend: PersistentMemory): MemoryEntry {
|
||
return {
|
||
id: backend.id,
|
||
agentId: backend.agent_id,
|
||
type: backend.memory_type as MemoryType,
|
||
tags: JSON.parse(backend.tags || '[]'),
|
||
// ...
|
||
};
|
||
}
|
||
```
|
||
|
||
**验证**:
|
||
- `pnpm vitest run` 测试通过
|
||
- 桌面端启动,发送消息,检查记忆存储
|
||
- MemoryPanel 正确显示记忆列表
|
||
|
||
---
|
||
|
||
### Phase 2: 迁移 Compactor 模块(约 1h)
|
||
|
||
**修改文件**: `chatStore.ts`
|
||
|
||
```typescript
|
||
// 修改前
|
||
import { getContextCompactor } from '../lib/context-compactor';
|
||
const compactor = getContextCompactor();
|
||
const check = compactor.checkThreshold(messages);
|
||
|
||
// 修改后
|
||
import { intelligenceClient } from '../lib/intelligence-client';
|
||
const check = await intelligenceClient.compactor.checkThreshold(
|
||
messages.map(m => ({ role: m.role, content: m.content }))
|
||
);
|
||
```
|
||
|
||
**验证**:
|
||
- 发送大量消息触发 compaction
|
||
- 检查压缩后消息正常显示
|
||
|
||
---
|
||
|
||
### Phase 3: 迁移 Reflection + Identity 模块(约 3h)
|
||
|
||
**修改文件**:
|
||
|
||
1. **chatStore.ts**
|
||
```typescript
|
||
// 修改前
|
||
import { getReflectionEngine } from '../lib/reflection-engine';
|
||
const reflectionEngine = getReflectionEngine();
|
||
reflectionEngine.recordConversation();
|
||
|
||
// 修改后
|
||
import { intelligenceClient } from '../lib/intelligence-client';
|
||
await intelligenceClient.reflection.recordConversation();
|
||
```
|
||
|
||
2. **ReflectionLog.tsx** - 替换 `ReflectionEngine` 和 `getAgentIdentityManager()`
|
||
3. **memory-extractor.ts** - 替换 `getAgentIdentityManager()`
|
||
|
||
**验证**:
|
||
- 完成多轮对话后检查 reflection 触发
|
||
- ReflectionLog 组件正确显示历史
|
||
- 身份变更提案审批流程正常
|
||
|
||
---
|
||
|
||
### Phase 4: 迁移 Heartbeat 模块(约 1h)
|
||
|
||
**修改文件**: `HeartbeatConfig.tsx`
|
||
|
||
```typescript
|
||
// 修改前
|
||
import { HeartbeatEngine } from '../lib/heartbeat-engine';
|
||
const engine = new HeartbeatEngine(agentId, config);
|
||
engine.start();
|
||
|
||
// 修改后
|
||
import { intelligenceClient } from '../lib/intelligence-client';
|
||
await intelligenceClient.heartbeat.init(agentId, config);
|
||
await intelligenceClient.heartbeat.start(agentId);
|
||
```
|
||
|
||
**验证**:
|
||
- HeartbeatConfig 面板启用心跳
|
||
- 等待心跳触发,检查 alert 生成
|
||
|
||
---
|
||
|
||
### Phase 5: 清理遗留代码(约 1h)
|
||
|
||
**删除文件**:
|
||
- `desktop/src/lib/agent-memory.ts`
|
||
- `desktop/src/lib/agent-identity.ts`
|
||
- `desktop/src/lib/reflection-engine.ts`
|
||
- `desktop/src/lib/heartbeat-engine.ts`
|
||
- `desktop/src/lib/context-compactor.ts`
|
||
- `desktop/src/lib/memory-index.ts`
|
||
|
||
**更新文档**:
|
||
- 更新 `CLAUDE.md` 架构说明
|
||
|
||
---
|
||
|
||
## Verification
|
||
|
||
每个阶段完成后执行:
|
||
|
||
```bash
|
||
# 1. TypeScript 编译检查
|
||
pnpm tsc --noEmit
|
||
|
||
# 2. 单元测试
|
||
pnpm vitest run
|
||
|
||
# 3. 启动桌面端
|
||
pnpm tauri:dev
|
||
|
||
# 4. 功能验证
|
||
# - 发送消息,检查记忆存储
|
||
# - 触发长对话,检查压缩
|
||
# - 检查心跳和反思功能
|
||
```
|
||
|
||
---
|
||
|
||
## Risk & Mitigation
|
||
|
||
| 风险 | 缓解措施 |
|
||
|------|----------|
|
||
| Tauri invoke 失败 | fallback 到 localStorage |
|
||
| 类型不匹配 | 类型转换层隔离差异 |
|
||
| 数据迁移 | 提供 localStorage → SQLite 迁移工具 |
|
||
| 回滚困难 | 使用 feature flag 快速切换 |
|
||
|
||
---
|
||
|
||
## Estimated Time
|
||
|
||
| 阶段 | 时间 |
|
||
|------|------|
|
||
| Phase 0: 创建客户端 | 2h |
|
||
| Phase 1: Memory 迁移 | 4h |
|
||
| Phase 2: Compactor 迁移 | 1h |
|
||
| Phase 3: Reflection+Identity | 3h |
|
||
| Phase 4: Heartbeat 迁移 | 1h |
|
||
| Phase 5: 清理代码 | 1h |
|
||
| 测试与修复 | 3h |
|
||
| **总计** | **约 15h(2个工作日)** |
|