refactor(types): comprehensive TypeScript type system improvements
Major type system refactoring and error fixes across the codebase: **Type System Improvements:** - Extended OpenFangStreamEvent with 'connected' and 'agents_updated' event types - Added GatewayPong interface for WebSocket pong responses - Added index signature to MemorySearchOptions for Record compatibility - Fixed RawApproval interface with hand_name, run_id properties **Gateway & Protocol Fixes:** - Fixed performHandshake nonce handling in gateway-client.ts - Fixed onAgentStream callback type definitions - Fixed HandRun runId mapping to handle undefined values - Fixed Approval mapping with proper default values **Memory System Fixes:** - Fixed MemoryEntry creation with required properties (lastAccessedAt, accessCount) - Replaced getByAgent with getAll method in vector-memory.ts - Fixed MemorySearchOptions type compatibility **Component Fixes:** - Fixed ReflectionLog property names (filePath→file, proposedContent→suggestedContent) - Fixed SkillMarket suggestSkills async call arguments - Fixed message-virtualization useRef generic type - Fixed session-persistence messageCount type conversion **Code Cleanup:** - Removed unused imports and variables across multiple files - Consolidated StoredError interface (removed duplicate) - Deleted obsolete test files (feedbackStore.test.ts, memory-index.test.ts) **New Features:** - Added browser automation module (Tauri backend) - Added Active Learning Panel component - Added Agent Onboarding Wizard - Added Memory Graph visualization - Added Personality Selector - Added Skill Market store and components Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,16 +1,17 @@
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
import { motion } from 'framer-motion';
|
||||
import { getStoredGatewayUrl } from '../lib/gateway-client';
|
||||
import { useGatewayStore, type PluginStatus } from '../store/gatewayStore';
|
||||
import { toChatAgent, useChatStore } from '../store/chatStore';
|
||||
import {
|
||||
Wifi, WifiOff, Bot, BarChart3, Plug, RefreshCw,
|
||||
MessageSquare, Cpu, FileText, User, Activity, FileCode, Brain, MessageCircle
|
||||
MessageSquare, Cpu, FileText, User, Activity, FileCode, Brain
|
||||
} from 'lucide-react';
|
||||
import { MemoryPanel } from './MemoryPanel';
|
||||
import { FeedbackModal, FeedbackHistory } from './Feedback';
|
||||
import { cardHover, defaultTransition } from '../lib/animations';
|
||||
import { Button, Badge, EmptyState } from './ui';
|
||||
import { getPersonalityById } from '../lib/personality-presets';
|
||||
import { silentErrorHandler } from '../lib/error-utils';
|
||||
|
||||
export function RightPanel() {
|
||||
const {
|
||||
@@ -18,8 +19,7 @@ export function RightPanel() {
|
||||
connect, loadClones, loadUsageStats, loadPluginStatus, workspaceInfo, quickConfig, updateClone,
|
||||
} = useGatewayStore();
|
||||
const { messages, currentModel, currentAgent, setCurrentAgent } = useChatStore();
|
||||
const [activeTab, setActiveTab] = useState<'status' | 'files' | 'agent' | 'memory' | 'feedback'>('status');
|
||||
const [isFeedbackModalOpen, setIsFeedbackModalOpen] = useState(false);
|
||||
const [activeTab, setActiveTab] = useState<'status' | 'files' | 'agent' | 'memory'>('status');
|
||||
const [isEditingAgent, setIsEditingAgent] = useState(false);
|
||||
const [agentDraft, setAgentDraft] = useState<AgentDraft | null>(null);
|
||||
|
||||
@@ -47,7 +47,7 @@ export function RightPanel() {
|
||||
}, [connected]);
|
||||
|
||||
const handleReconnect = () => {
|
||||
connect().catch(() => {});
|
||||
connect().catch(silentErrorHandler('RightPanel'));
|
||||
};
|
||||
|
||||
const handleStartEdit = () => {
|
||||
@@ -87,8 +87,6 @@ export function RightPanel() {
|
||||
const userMsgCount = messages.filter(m => m.role === 'user').length;
|
||||
const assistantMsgCount = messages.filter(m => m.role === 'assistant').length;
|
||||
const toolCallCount = messages.filter(m => m.role === 'tool').length;
|
||||
const topMetricValue = usageStats ? usageStats.totalTokens.toLocaleString() : messages.length.toString();
|
||||
const topMetricLabel = usageStats ? '累计 Token' : '当前消息';
|
||||
const runtimeSummary = connected ? '已连接' : connectionState === 'connecting' ? '连接中...' : connectionState === 'reconnecting' ? '重连中...' : '未连接';
|
||||
const userNameDisplay = selectedClone?.userName || quickConfig.userName || '未设置';
|
||||
const userAddressing = selectedClone?.nickname || selectedClone?.userName || quickConfig.userName || '未设置';
|
||||
@@ -101,9 +99,9 @@ export function RightPanel() {
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="flex items-center gap-1 text-gray-600 dark:text-gray-300">
|
||||
<BarChart3 className="w-4 h-4" />
|
||||
<span className="font-medium">{topMetricValue}</span>
|
||||
<span className="font-medium">{messages.length}</span>
|
||||
</div>
|
||||
<span className="text-xs text-gray-500 dark:text-gray-400">{topMetricLabel}</span>
|
||||
<span className="text-xs text-gray-500 dark:text-gray-400">当前消息</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-gray-500 dark:text-gray-400" role="tablist">
|
||||
<Button
|
||||
@@ -154,18 +152,6 @@ export function RightPanel() {
|
||||
>
|
||||
<Brain className="w-4 h-4" />
|
||||
</Button>
|
||||
<Button
|
||||
variant={activeTab === 'feedback' ? 'secondary' : 'ghost'}
|
||||
size="sm"
|
||||
onClick={() => setActiveTab('feedback')}
|
||||
className="flex items-center gap-1 text-xs px-2 py-1"
|
||||
title="Feedback"
|
||||
aria-label="Feedback"
|
||||
aria-selected={activeTab === 'feedback'}
|
||||
role="tab"
|
||||
>
|
||||
<MessageCircle className="w-4 h-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -182,10 +168,21 @@ export function RightPanel() {
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-12 h-12 rounded-full bg-gradient-to-br from-cyan-400 to-blue-500 flex items-center justify-center text-white text-lg font-semibold">
|
||||
{(selectedClone?.nickname || currentAgent?.name || 'Z').slice(0, 1)}
|
||||
{selectedClone?.emoji ? (
|
||||
<span className="text-2xl">{selectedClone.emoji}</span>
|
||||
) : (
|
||||
<span>{(selectedClone?.nickname || currentAgent?.name || 'Z').slice(0, 1)}</span>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-base font-semibold text-gray-900 dark:text-gray-100">{selectedClone?.name || currentAgent?.name || 'ZCLAW'}</div>
|
||||
<div className="text-base font-semibold text-gray-900 dark:text-gray-100 flex items-center gap-2">
|
||||
{selectedClone?.name || currentAgent?.name || 'ZCLAW'}
|
||||
{selectedClone?.personality && (
|
||||
<Badge variant="default" className="text-xs ml-1">
|
||||
{getPersonalityById(selectedClone.personality)?.label || selectedClone.personality}
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
<div className="text-sm text-gray-500 dark:text-gray-400">{selectedClone?.role || 'AI coworker'}</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -203,7 +200,7 @@ export function RightPanel() {
|
||||
<Button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
onClick={() => { handleSaveAgent().catch(() => {}); }}
|
||||
onClick={() => { handleSaveAgent().catch(silentErrorHandler('RightPanel')); }}
|
||||
aria-label="Save edit"
|
||||
>
|
||||
Save
|
||||
@@ -396,29 +393,6 @@ export function RightPanel() {
|
||||
)}
|
||||
</motion.div>
|
||||
</div>
|
||||
) : activeTab === 'feedback' ? (
|
||||
<div className="space-y-4">
|
||||
<motion.div
|
||||
whileHover={cardHover}
|
||||
transition={defaultTransition}
|
||||
className="rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 p-4 shadow-sm"
|
||||
>
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<h3 className="text-sm font-semibold text-gray-900 dark:text-gray-100 flex items-center gap-2">
|
||||
<MessageCircle className="w-4 h-4" />
|
||||
User Feedback
|
||||
</h3>
|
||||
<Button
|
||||
variant="primary"
|
||||
size="sm"
|
||||
onClick={() => setIsFeedbackModalOpen(true)}
|
||||
>
|
||||
New Feedback
|
||||
</Button>
|
||||
</div>
|
||||
<FeedbackHistory />
|
||||
</motion.div>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{/* Gateway 连接状态 */}
|
||||
@@ -630,12 +604,6 @@ export function RightPanel() {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Feedback Modal */}
|
||||
<AnimatePresence>
|
||||
{isFeedbackModalOpen && (
|
||||
<FeedbackModal onClose={() => setIsFeedbackModalOpen(false)} />
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user