Files
zclaw_openfang/plans/virtual-conjuring-stardust.md
iven 26e64a3fff fix(hands): use hand.id instead of hand.name for API calls
- Fix HandTaskPanel to use hand.id when loading runs and triggering
- Fix HandsPanel to use hand.id for getHandDetails and triggerHand
- Fix WorkflowEditor to use hand.id as option value

The API expects hand identifiers, not names. This ensures correct
hand execution and run history loading.

Also clean up old plan files and add Gateway stability plan.

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

5.5 KiB
Raw Blame History

ZCLAW Gateway 连接稳定性与 API 修复计划

Context

问题背景: 用户报告"Gateway 连接不稳定",通过 Chrome DevTools 诊断发现:

  • WebSocket 连接和聊天功能实际正常工作
  • 真正的问题是 6 个 API 端点返回 404,大量错误日志被误认为是连接问题

诊断结果:

项目 状态
WebSocket 连接 正常
消息发送/流式响应 正常
核心 API (agents, hands, workflows) 正常
6 个 API 端点 404 错误

目标:

  1. P0: 修复 6 个 404 API 端点(通过前端 fallback 降级)
  2. P1: 增强连接稳定性(心跳机制 + 改进重连策略)

Phase 1: P0 - API Fallback 降级处理

1.1 创建 API Fallback 模块

新建文件: desktop/src/lib/api-fallbacks.ts

// 提供 6 个 404 API 的降级数据
export interface QuickConfigFallback { ... }
export interface WorkspaceInfoFallback { ... }
export interface UsageStatsFallback { ... }
export interface PluginStatusFallback { ... }
export interface ScheduledTaskFallback { ... }

export function getQuickConfigFallback(): QuickConfigFallback { ... }
export function getWorkspaceInfoFallback(): WorkspaceInfoFallback { ... }
export function getUsageStatsFallback(sessions: Session[]): UsageStatsFallback { ... }
export function getPluginStatusFallback(skills: SkillInfo[]): PluginStatusFallback { ... }
export function getScheduledTasksFallback(triggers: Trigger[]): ScheduledTaskFallback[] { ... }

1.2 更新 gateway-client.ts

为每个 404 API 添加结构化 fallback

async getQuickConfig(): Promise<any> {
  try {
    return await this.restGet('/api/config/quick');
  } catch (error) {
    if ((error as any).status === 404) {
      return { quickConfig: getQuickConfigFallback() };
    }
    throw error;
  }
}

1.3 更新 gatewayStore.ts

在数据加载时使用 fallback

loadUsageStats: async () => {
  try {
    const stats = await get().client.getUsageStats();
    set({ usageStats: stats });
  } catch {
    const fallback = getUsageStatsFallback(get().sessions);
    set({ usageStats: fallback });
  }
},

Phase 2: P1 - 心跳机制

2.1 添加心跳字段

修改文件: desktop/src/lib/gateway-client.ts

// 新增私有字段
private heartbeatInterval: number | null = null;
private heartbeatTimeout: number | null = null;
private missedHeartbeats: number = 0;
private static readonly HEARTBEAT_INTERVAL = 30000; // 30秒
private static readonly HEARTBEAT_TIMEOUT = 10000;  // 10秒
private static readonly MAX_MISSED_HEARTBEATS = 3;

2.2 心跳方法

private startHeartbeat(): void { ... }
private stopHeartbeat(): void { ... }
private sendHeartbeat(): void { ... }
private handlePong(): void { ... }

2.3 集成到连接流程

  • connect() 成功后调用 startHeartbeat()
  • cleanup() 时调用 stopHeartbeat()
  • handleFrame() 处理 pong 响应

Phase 3: P1 - 改进重连策略

3.1 新增配置选项

interface GatewayClientOptions {
  maxReconnectAttempts?: number; // -1=无限, 0=禁用, 默认10
  reconnectBackoff?: 'linear' | 'exponential' | 'fixed';
}

3.2 更新 scheduleReconnect

  • 支持无限重连模式 (maxReconnectAttempts: -1)
  • 添加重连事件通知 (reconnecting, reconnect_failed)
  • 改进退避算法

3.3 流式 WebSocket 重连

openfangWs 添加重连逻辑:

private streamState = { agentId: null, sessionId: null, lastMessage: null };
private scheduleStreamReconnect(runId: string): void { ... }

Phase 4: UI 集成

4.1 创建 ConnectionStatus 组件

新建文件: desktop/src/components/ConnectionStatus.tsx

export function ConnectionStatus() {
  const { connectionState } = useGatewayStore();

  const statusConfig = {
    disconnected: { color: 'red', label: '已断开', icon: WifiOff },
    connecting: { color: 'yellow', label: '连接中...', icon: Loader2 },
    connected: { color: 'green', label: '已连接', icon: Wifi },
    reconnecting: { color: 'orange', label: '重连中...', icon: RefreshCw },
  };
  // ...
}

4.2 集成到 ChatArea

在聊天区域顶部显示连接状态指示器。


关键文件

文件 修改类型 说明
desktop/src/lib/api-fallbacks.ts 新建 API 降级数据
desktop/src/lib/gateway-client.ts 修改 心跳 + 重连 + fallback
desktop/src/store/gatewayStore.ts 修改 使用 fallback
desktop/src/components/ConnectionStatus.tsx 新建 连接状态 UI
desktop/src/components/ChatArea.tsx 修改 集成状态指示器
tests/desktop/gatewayStore.test.ts 修改 测试覆盖

Verification

测试清单

P0 - API Fallback:

  • 启动应用,检查控制台无 404 错误
  • 用量统计面板显示数据(即使 API 404
  • 设置页面显示配置(即使 API 404

P1 - 心跳:

  • 连接后空闲 5 分钟,连接保持
  • 检查 WebSocket 流量有 ping/pong 帧

P1 - 重连:

  • 关闭 OpenFang显示"重连中"
  • 重启 OpenFang自动重连成功
  • 聊天中断开后自动恢复

运行测试

pnpm vitest run tests/desktop/gatewayStore.test.ts

Implementation Sequence

  1. Day 1: Phase 1 - API Fallbacks
  2. Day 2: Phase 2 - Heartbeat + Phase 3 - Reconnection
  3. Day 3: Phase 4 - UI Integration + Testing