fix: subagent unique ID matching + AgentState serialization + pre-existing TS errors
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled

- S-3: Thread task_id (UUID) through all 6 layers (LoopEvent → StreamChatEvent → kernel-types → gateway-client → streamStore) so subtasks are matched by ID, not description string
- AgentState: Add #[serde(rename_all = "lowercase")] to fix PascalCase serialization ("Running" → "running"), update frontend matcher
- S-1: Remove unused onClose prop from ArtifactPanel + ChatArea call site
- Fix hooks/index.ts: remove orphaned useAutomationEvents re-exports (module deleted)
- Fix types/index.ts: remove orphaned automation type/value re-exports (module deleted)
- Fix ChatArea.tsx: framer-motion 12 + React 19 type compat — use createElement + explicit any return type to avoid unknown-in-JSX-child error

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
iven
2026-04-06 22:30:16 +08:00
parent bbbcd7725b
commit 02c69bb3cf
13 changed files with 37 additions and 66 deletions

View File

@@ -1,4 +1,4 @@
import { useState, useEffect, useRef, useCallback, useMemo, type MutableRefObject, type RefObject, type CSSProperties } from 'react';
import { useState, useEffect, useRef, useCallback, useMemo, type MutableRefObject, type RefObject, type CSSProperties, createElement } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { List, type ListImperativeAPI } from 'react-window';
import { useChatStore, type Message } from '../store/chatStore';
@@ -262,7 +262,6 @@ export function ChatArea() {
artifacts={artifacts}
selectedId={selectedArtifactId}
onSelect={selectArtifact}
onClose={() => setArtifactPanelOpen(false)}
/>
);
@@ -609,18 +608,21 @@ function MessageBubble({ message, setInput }: { message: Message; setInput: (tex
const isUser = message.role === 'user';
const isThinking = message.streaming && !message.content;
// Extract typed arrays for JSX rendering (avoids TS2322 from && chain producing unknown)
// Extract typed arrays for JSX rendering
const toolCallSteps: ToolCallStep[] | undefined = message.toolSteps;
const subtaskList: Subtask[] | undefined = message.subtasks;
const renderToolSteps = (): React.ReactNode => {
// framer-motion 12 + React 19 type compat: motion.span/div return types resolve to `unknown`.
// Use createElement to bypass JSX child-context type inference.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const renderToolChain = (): any => {
if (isUser || !toolCallSteps || toolCallSteps.length === 0) return null;
return <ToolCallChain steps={toolCallSteps} isStreaming={!!message.streaming} />;
return createElement(ToolCallChain, { steps: toolCallSteps, isStreaming: !!message.streaming });
};
const renderSubtasks = (): React.ReactNode => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const renderSubtasks = (): any => {
if (isUser || !subtaskList || subtaskList.length === 0) return null;
return <TaskProgress tasks={subtaskList} className="mb-3" />;
return createElement(TaskProgress, { tasks: subtaskList, className: 'mb-3' });
};
// Download message as Markdown file
@@ -669,7 +671,7 @@ function MessageBubble({ message, setInput }: { message: Message; setInput: (tex
/>
)}
{/* Tool call steps chain (DeerFlow-inspired) */}
{renderToolSteps()}
{renderToolChain()}
{/* Subtask tracking (DeerFlow-inspired) */}
{renderSubtasks()}
{/* Message content with streaming support */}

View File

@@ -28,7 +28,6 @@ interface ArtifactPanelProps {
artifacts: ArtifactFile[];
selectedId?: string | null;
onSelect: (id: string) => void;
onClose?: () => void;
className?: string;
}
@@ -74,7 +73,6 @@ export function ArtifactPanel({
artifacts,
selectedId,
onSelect,
onClose: _onClose,
className = '',
}: ArtifactPanelProps) {
const [viewMode, setViewMode] = useState<'preview' | 'code'>('preview');