Files
zclaw_openfang/plans/nifty-inventing-valiant.md
iven 3ff08faa56 release(v0.2.0): streaming, MCP protocol, Browser Hand, security enhancements
## Major Features

### Streaming Response System
- Implement LlmDriver trait with `stream()` method returning async Stream
- Add SSE parsing for Anthropic and OpenAI API streaming
- Integrate Tauri event system for frontend streaming (`stream:chunk` events)
- Add StreamChunk types: Delta, ToolStart, ToolEnd, Complete, Error

### MCP Protocol Implementation
- Add MCP JSON-RPC 2.0 types (mcp_types.rs)
- Implement stdio-based MCP transport (mcp_transport.rs)
- Support tool discovery, execution, and resource operations

### Browser Hand Implementation
- Complete browser automation with Playwright-style actions
- Support Navigate, Click, Type, Scrape, Screenshot, Wait actions
- Add educational Hands: Whiteboard, Slideshow, Speech, Quiz

### Security Enhancements
- Implement command whitelist/blacklist for shell_exec tool
- Add SSRF protection with private IP blocking
- Create security.toml configuration file

## Test Improvements
- Fix test import paths (security-utils, setup)
- Fix vi.mock hoisting issues with vi.hoisted()
- Update test expectations for validateUrl and sanitizeFilename
- Add getUnsupportedLocalGatewayStatus mock

## Documentation Updates
- Update architecture documentation
- Improve configuration reference
- Add quick-start guide updates

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 03:24:24 +08:00

304 lines
9.0 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.

# ZCLAW 自我进化系统审查与修复计划
## 背景
自我进化系统是 ZCLAW 的核心能力,包括四个组件:
- **心跳引擎** - 定期主动检查
- **反思引擎** - 分析模式并生成改进建议
- **身份管理** - 管理人格文件和变更提案
- **记忆存储** - 持久化对话和经验
---
## 审查结果摘要
### 实现状态
| 组件 | 函数/功能 | 状态 |
|------|----------|------|
| **心跳引擎** | check_pending_tasks | ✅ 完整 |
| | check_memory_health | ✅ 完整 |
| | check_correction_patterns | ✅ 完整 |
| | check_learning_opportunities | ✅ 完整 |
| | check_idle_greeting | ⚠️ 占位符 |
| **反思引擎** | analyze_patterns | ✅ 完整 |
| | generate_improvements | ✅ 完整 |
| | propose_identity_changes | ✅ 完整 |
| **身份管理** | 提案处理 | ✅ 完整 |
| | 持久化 | ✅ 完整 |
| **前端** | Intelligence Client | ✅ 完整 |
| | IdentityChangeProposal UI | ✅ 完整 |
| | 提案通知系统 | ✅ 存在 |
### 发现的问题
| 优先级 | 问题 | 影响 |
|--------|------|------|
| HIGH | MemoryStatsCache 同步问题 | 心跳检查依赖前端主动更新,可能跳过检查 |
| HIGH | API 命名不一致 | `updateMemoryStats` 参数名不匹配camelCase vs snake_case |
| MEDIUM | check_idle_greeting 占位符 | 空闲问候功能不可用 |
| MEDIUM | 类型定义不一致 | `totalEntries` vs `total_memories` 命名不统一 |
| MEDIUM | 提案审批错误处理 | 缺少详细的错误反馈 |
| LOW | storageSizeBytes fallback 为 0 | localStorage 模式下无法计算 |
| LOW | 硬编码配置值 | 历史限制、快照数量不可配置 |
---
## 修复计划
### Phase 1: 修复 HIGH 优先级问题
#### Fix 1.1: API 参数命名修正 ⚡ 5分钟
**文件**: [intelligence-client.ts](desktop/src/lib/intelligence-client.ts)
**问题**: `updateMemoryStats` 使用 camelCase 参数,但 Rust 后端期望 snake_case
**修改位置**: 第 989-1011 行
```typescript
// 修改前
await invoke('heartbeat_update_memory_stats', {
agentId,
taskCount,
totalEntries,
storageSizeBytes,
});
// 修改后
await invoke('heartbeat_update_memory_stats', {
agent_id: agentId,
task_count: taskCount,
total_entries: totalEntries,
storage_size_bytes: storageSizeBytes,
});
```
#### Fix 1.2: 添加周期性记忆统计同步 ⚡ 15分钟
**文件**: [App.tsx](desktop/src/App.tsx)
**问题**: 记忆统计仅在启动时同步一次,之后数据可能陈旧
**修改位置**: 第 213 行后heartbeat.start 之后)
```typescript
// 添加周期性同步(每 5 分钟)
const MEMORY_STATS_SYNC_INTERVAL = 5 * 60 * 1000;
const statsSyncInterval = setInterval(async () => {
try {
const stats = await intelligenceClient.memory.stats();
const taskCount = stats.byType?.['task'] || 0;
await intelligenceClient.heartbeat.updateMemoryStats(
defaultAgentId,
taskCount,
stats.totalEntries,
stats.storageSizeBytes
);
console.log('[App] Memory stats synced (periodic)');
} catch (err) {
console.warn('[App] Periodic memory stats sync failed:', err);
}
}, MEMORY_STATS_SYNC_INTERVAL);
```
#### Fix 1.3: 心跳检查容错处理 ⚡ 20分钟
**文件**: [heartbeat.rs](desktop/src-tauri/src/intelligence/heartbeat.rs)
**问题**: 当缓存为空时,检查函数直接跳过,无告警
**修改**: 在 `check_pending_tasks``check_memory_health` 中添加缓存缺失告警
```rust
fn check_pending_tasks(agent_id: &str) -> Option<HeartbeatAlert> {
match get_cached_memory_stats(agent_id) {
Some(stats) if stats.task_count >= 5 => { /* 现有逻辑 */ },
Some(_) => None,
None => Some(HeartbeatAlert {
title: "记忆统计未同步".to_string(),
content: "心跳引擎未能获取记忆统计信息,部分检查被跳过".to_string(),
urgency: Urgency::Low,
source: "pending-tasks".to_string(),
timestamp: chrono::Utc::now().to_rfc3339(),
}),
}
}
```
### Phase 2: 修复 MEDIUM 优先级问题
#### Fix 2.1: 统一类型定义命名 ⚡ 10分钟
**文件**: [intelligence-backend.ts](desktop/src/lib/intelligence-backend.ts)
**问题**: 前端使用 `totalEntries`,后端返回 `total_memories`
**修改**: 更新接口定义以匹配后端
```typescript
export interface MemoryStats {
total_entries: number; // 匹配后端
by_type: Record<string, number>;
by_agent: Record<string, number>;
oldest_entry: string | null;
newest_entry: string | null;
storage_size_bytes: number;
}
```
**同时更新** [intelligence-client.ts](desktop/src/lib/intelligence-client.ts) 中的转换函数
#### Fix 2.2: 增强提案审批错误处理 ⚡ 10分钟
**文件**: [IdentityChangeProposal.tsx](desktop/src/components/IdentityChangeProposal.tsx)
**添加错误解析函数**:
```typescript
function parseProposalError(err: unknown, operation: 'approval' | 'rejection' | 'restore'): string {
const errorMessage = err instanceof Error ? err.message : String(err);
if (errorMessage.includes('not found')) {
return `提案不存在或已被处理`;
}
if (errorMessage.includes('not pending')) {
return '该提案已被处理,请刷新页面';
}
if (errorMessage.includes('network') || errorMessage.includes('fetch')) {
return '网络连接失败,请检查网络后重试';
}
return `${operation === 'approval' ? '审批' : operation === 'rejection' ? '拒绝' : '恢复'}失败: ${errorMessage}`;
}
```
#### Fix 2.3: 实现 check_idle_greeting可选⚡ 30分钟
**文件**: [heartbeat.rs](desktop/src-tauri/src/intelligence/heartbeat.rs)
**添加最后交互时间追踪**:
```rust
static LAST_INTERACTION: OnceLock<RwLock<StdHashMap<String, String>>> = OnceLock::new();
pub fn record_interaction(agent_id: &str) {
let map = get_last_interaction_map();
if let Ok(mut map) = map.write() {
map.insert(agent_id.to_string(), chrono::Utc::now().to_rfc3339());
}
}
fn check_idle_greeting(agent_id: &str) -> Option<HeartbeatAlert> {
let map = get_last_interaction_map();
let last_interaction = map.read().ok()?.get(agent_id).cloned()?;
let last_time = chrono::DateTime::parse_from_rfc3339(&last_interaction).ok()?;
let idle_hours = (chrono::Utc::now() - last_time).num_hours();
if idle_hours >= 24 {
Some(HeartbeatAlert {
title: "用户长时间未互动".to_string(),
content: format!("距离上次互动已过去 {} 小时", idle_hours),
urgency: Urgency::Low,
source: "idle-greeting".to_string(),
timestamp: chrono::Utc::now().to_rfc3339(),
})
} else {
None
}
}
```
**同时添加 Tauri 命令**:
```rust
#[tauri::command]
pub async fn heartbeat_record_interaction(agent_id: String) -> Result<(), String>
```
### Phase 3: 修复 LOW 优先级问题(可选)
#### Fix 3.1: localStorage fallback 存储大小计算
**文件**: [intelligence-client.ts](desktop/src/lib/intelligence-client.ts)
```typescript
// 在 fallbackMemory.stats() 中添加
let storageSizeBytes = 0;
try {
const serialized = JSON.stringify(store.memories);
storageSizeBytes = new Blob([serialized]).size;
} catch { /* ignore */ }
```
---
## 实现顺序
| 顺序 | 修复项 | 优先级 | 预估时间 |
|------|--------|--------|----------|
| 1 | Fix 1.1 - API 参数命名 | HIGH | 5 分钟 |
| 2 | Fix 1.2 - 周期性同步 | HIGH | 15 分钟 |
| 3 | Fix 1.3 - 心跳容错 | HIGH | 20 分钟 |
| 4 | Fix 2.1 - 类型统一 | MEDIUM | 10 分钟 |
| 5 | Fix 2.2 - 错误处理 | MEDIUM | 10 分钟 |
| 6 | Fix 2.3 - 空闲问候 | MEDIUM | 30 分钟 |
| 7 | Fix 3.1 - 存储大小 | LOW | 5 分钟 |
**总计**: 约 1.5 小时(不含可选项)
---
## 关键文件
| 文件 | 修改内容 |
|------|----------|
| [intelligence-client.ts](desktop/src/lib/intelligence-client.ts) | API 参数命名、类型转换、存储大小计算 |
| [App.tsx](desktop/src/App.tsx) | 周期性记忆统计同步 |
| [heartbeat.rs](desktop/src-tauri/src/intelligence/heartbeat.rs) | 缓存容错、空闲问候 |
| [intelligence-backend.ts](desktop/src/lib/intelligence-backend.ts) | 类型定义统一 |
| [IdentityChangeProposal.tsx](desktop/src/components/IdentityChangeProposal.tsx) | 错误处理增强 |
| [lib.rs](desktop/src-tauri/src/lib.rs) | 注册新 Tauri 命令(如实现 Fix 2.3 |
---
## 验证方法
### Fix 1.1 验证
```bash
# 启动应用,检查控制台
pnpm start:dev
# 观察 Tauri invoke 调用参数是否正确
```
### Fix 1.2 验证
```bash
# 启动后等待 5 分钟,检查控制台
# 应看到 "[App] Memory stats synced (periodic)" 日志
```
### Fix 1.3 验证
```bash
# 清除缓存后触发心跳
# 应看到 "记忆统计未同步" 告警
```
### 全量验证
```bash
# TypeScript 类型检查
pnpm tsc --noEmit
# 运行测试
pnpm vitest run
# 启动开发环境
pnpm start:dev
```
### 人工验证清单
- [ ] 应用启动无错误
- [ ] 心跳引擎正常初始化
- [ ] 记忆统计同步正常(启动 + 周期)
- [ ] 提案审批流程正常
- [ ] 错误信息清晰可读