Files
zclaw_openfang/plans/abstract-finding-forest-agent-a5bc2d4e73e72fb27.md
iven ce562e8bfc feat: complete Phase 1-3 architecture optimization
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>
2026-03-21 22:11:50 +08:00

11 KiB
Raw Permalink Blame History

ZCLAW 智能层统一实现方案

概述

本方案旨在消除前后端智能层代码重复,统一使用 Rust 后端 + TypeScript 适配器 (intelligence-backend.ts)。

现状分析

已有的 Rust 后端命令(通过 intelligence-backend.ts 封装)

模块 命令 状态
Memory memory_init, memory_store, memory_get, memory_search, memory_delete, memory_delete_all, memory_stats, memory_export, memory_import, memory_db_path 完整
Heartbeat heartbeat_init, heartbeat_start, heartbeat_stop, heartbeat_tick, heartbeat_get_config, heartbeat_update_config, heartbeat_get_history 完整
Compactor compactor_estimate_tokens, compactor_estimate_messages_tokens, compactor_check_threshold, compactor_compact 完整
Reflection reflection_init, reflection_record_conversation, reflection_should_reflect, reflection_reflect, reflection_get_history, reflection_get_state 完整
Identity identity_get, identity_get_file, identity_build_prompt, identity_update_user_profile, identity_append_user_profile, identity_propose_change, identity_approve_proposal, identity_reject_proposal, identity_get_pending_proposals, identity_update_file, identity_get_snapshots, identity_restore_snapshot, identity_list_agents, identity_delete_agent 完整

需要迁移的前端 TS 实现

文件 代码行数 引用位置
agent-memory.ts ~487行 chatStore, memoryGraphStore, MemoryPanel, memory-extractor, agent-swarm, skill-discovery
agent-identity.ts ~351行 chatStore, reflection-engine, memory-extractor, ReflectionLog
reflection-engine.ts ~678行 chatStore, ReflectionLog
heartbeat-engine.ts ~347行 HeartbeatConfig
context-compactor.ts ~443行 chatStore

类型差异分析

前端 TS 和 Rust 后端的类型有细微差异,需要创建适配层:

前端 MemoryEntry.importance: number (0-10)
后端 PersistentMemory.importance: number (相同)

前端 MemoryEntry.type: MemoryType ('fact' | 'preference' | ...)
后端 PersistentMemory.memory_type: string

前端 MemoryEntry.tags: string[]
后端 PersistentMemory.tags: string (JSON 序列化)

实施计划

Phase 0: 准备工作(环境检测 + 降级策略)

目标: 创建环境检测机制,支持 Tauri/浏览器双环境

修改文件:

  • 新建 desktop/src/lib/intelligence-client.ts

实现内容:

// intelligence-client.ts
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,
};

验证方法:

  • 在 Tauri 桌面端启动,确认 isTauriEnv === true
  • 在浏览器中访问 Vite dev server确认降级逻辑生效

Phase 1: 迁移 Memory 模块(最关键)

优先级: 最高(其他模块都依赖 Memory

修改文件:

文件 修改内容
chatStore.ts getMemoryManager() 替换为 intelligenceClient.memory
memoryGraphStore.ts getMemoryManager() 替换为 intelligenceClient.memory
MemoryPanel.tsx getMemoryManager() 替换为 intelligenceClient.memory
memory-extractor.ts getMemoryManager() 替换为 intelligenceClient.memory
agent-swarm.ts getMemoryManager() 替换为 intelligenceClient.memory
skill-discovery.ts getMemoryManager() 替换为 intelligenceClient.memory

详细修改示例 (chatStore.ts):

// 修改前
import { getMemoryManager } from '../lib/agent-memory';

// 在 sendMessage 中
const memoryMgr = getMemoryManager();
const relevantMemories = await memoryMgr.search(content, {
  agentId,
  limit: 8,
  minImportance: 3,
});

// 修改后
import { intelligenceClient } from '../lib/intelligence-client';

// 在 sendMessage 中
const relevantMemories = await intelligenceClient.memory.search({
  agent_id: agentId,
  query: content,
  limit: 8,
  min_importance: 3,
});

类型适配:

// 创建类型转换函数
function toFrontendMemory(backend: PersistentMemory): MemoryEntry {
  return {
    id: backend.id,
    agentId: backend.agent_id,
    content: backend.content,
    type: backend.memory_type as MemoryType,
    importance: backend.importance,
    source: backend.source as MemorySource,
    tags: JSON.parse(backend.tags || '[]'),
    createdAt: backend.created_at,
    lastAccessedAt: backend.last_accessed_at,
    accessCount: backend.access_count,
    conversationId: backend.conversation_id || undefined,
  };
}

function toBackendMemoryInput(frontend: Omit<MemoryEntry, 'id' | 'createdAt' | 'lastAccessedAt' | 'accessCount'>): MemoryEntryInput {
  return {
    agent_id: frontend.agentId,
    memory_type: frontend.type,
    content: frontend.content,
    importance: frontend.importance,
    source: frontend.source,
    tags: frontend.tags,
    conversation_id: frontend.conversationId,
  };
}

验证方法:

  1. 启动桌面端,发送消息
  2. 检查记忆是否正确存储到 SQLite
  3. 搜索记忆是否返回正确结果
  4. MemoryPanel 组件是否正确显示记忆列表

回滚方案:

  • 保留 agent-memory.ts 文件
  • 通过 feature flag 切换新旧实现

Phase 2: 迁移 Compactor 模块

优先级: 高(依赖 Memory但影响范围较小

修改文件:

文件 修改内容
chatStore.ts getContextCompactor() 替换为 intelligenceClient.compactor

详细修改:

// 修改前
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 }))
);

验证方法:

  1. 发送大量消息触发 compaction 阈值
  2. 检查是否正确压缩上下文
  3. 验证压缩后消息正常显示

Phase 3: 迁移 Reflection + Identity 模块

优先级: 中(关联紧密,需要一起迁移)

修改文件:

文件 修改内容
chatStore.ts getReflectionEngine() 替换为 intelligenceClient.reflection
ReflectionLog.tsx ReflectionEnginegetAgentIdentityManager() 替换为 intelligenceClient
memory-extractor.ts getAgentIdentityManager() 替换为 intelligenceClient.identity

详细修改:

// 修改前 (chatStore.ts)
import { getReflectionEngine } from '../lib/reflection-engine';

const reflectionEngine = getReflectionEngine();
reflectionEngine.recordConversation();
if (reflectionEngine.shouldReflect()) {
  reflectionEngine.reflect(agentId);
}

// 修改后
import { intelligenceClient } from '../lib/intelligence-client';

await intelligenceClient.reflection.recordConversation();
if (await intelligenceClient.reflection.shouldReflect()) {
  const memories = await intelligenceClient.memory.search({ agent_id: agentId, limit: 100 });
  await intelligenceClient.reflection.reflect(agentId, memories.map(m => ({
    memory_type: m.memory_type,
    content: m.content,
    importance: m.importance,
    access_count: m.access_count,
    tags: JSON.parse(m.tags || '[]'),
  })));
}

验证方法:

  1. 完成多轮对话后检查 reflection 是否触发
  2. 检查 ReflectionLog 组件是否正确显示反思历史
  3. 验证身份变更提案的审批流程

Phase 4: 迁移 Heartbeat 模块

优先级: 低(独立模块,无依赖)

修改文件:

文件 修改内容
HeartbeatConfig.tsx HeartbeatEngine 替换为 intelligenceClient.heartbeat
SettingsLayout.tsx 如有引用,同样替换

详细修改:

// 修改前
import { HeartbeatEngine, DEFAULT_HEARTBEAT_CONFIG } from '../lib/heartbeat-engine';

const engine = new HeartbeatEngine(agentId, config);
engine.start();

// 修改后
import { intelligenceClient } from '../lib/intelligence-client';
import type { HeartbeatConfig } from '../lib/intelligence-backend';

await intelligenceClient.heartbeat.init(agentId, config);
await intelligenceClient.heartbeat.start(agentId);

验证方法:

  1. 在 HeartbeatConfig 面板中启用心跳
  2. 等待心跳触发,检查是否生成 alert
  3. 验证配置更新是否正确持久化

Phase 5: 清理遗留代码

优先级: 最低(在所有迁移验证完成后)

删除文件:

  • 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 (agent-memory 的依赖)

更新文档:

  • 更新 CLAUDE.md 中的架构说明
  • 更新相关组件的注释

风险与缓解措施

风险 缓解措施
Tauri invoke 失败 实现完整的降级策略fallback 到 localStorage
类型不匹配 创建类型转换层,隔离前后端类型差异
性能差异 Rust 后端应该更快,但需要测试 SQLite 查询性能
数据迁移 提供 localStorage -> SQLite 迁移工具
回滚困难 使用 feature flag可快速切换回旧实现

测试检查清单

每个阶段必须验证

  • TypeScript 编译通过 (pnpm tsc --noEmit)
  • 相关单元测试通过 (pnpm vitest run)
  • 桌面端启动正常
  • 聊天功能正常
  • 记忆存储/搜索正常
  • 无控制台错误

Phase 1 额外验证

  • MemoryPanel 正确显示记忆列表
  • 记忆图谱正确渲染
  • skill-discovery 推荐功能正常

Phase 3 额外验证

  • ReflectionLog 正确显示反思历史
  • 身份变更提案审批流程正常
  • USER.md 自动更新正常

时间估算

阶段 预计时间 累计
Phase 0 2h 2h
Phase 1 4h 6h
Phase 2 1h 7h
Phase 3 3h 10h
Phase 4 1h 11h
Phase 5 1h 12h
测试与修复 3h 15h

总计: 约 2 个工作日


执行顺序建议

  1. 先完成 Phase 0 - 这是所有后续工作的基础
  2. 然后 Phase 1 - Memory 是核心依赖
  3. 接着 Phase 2 - Compactor 依赖 Memory
  4. 然后 Phase 3 - Reflection + Identity 关联紧密
  5. 然后 Phase 4 - Heartbeat 独立,可最后处理
  6. 最后 Phase 5 - 确认一切正常后再删除旧代码

每个阶段完成后都应该进行完整的功能验证,确保没有引入 bug。