diff --git a/core/frontend/src/components/NodeDetailPanel.tsx b/core/frontend/src/components/NodeDetailPanel.tsx deleted file mode 100644 index 34577c55..00000000 --- a/core/frontend/src/components/NodeDetailPanel.tsx +++ /dev/null @@ -1,551 +0,0 @@ -import { useState, useEffect, useRef } from "react"; -import { X, Cpu, Zap, Clock, RotateCcw, CheckCircle2, AlertCircle, Loader2, ChevronDown, ChevronRight, Copy, Check, Terminal, Wrench, BookOpen, GitBranch, Bot } from "lucide-react"; -import type { GraphNode, NodeStatus } from "./graph-types"; -import type { NodeSpec, ToolInfo, NodeCriteria } from "../api/types"; -import { workersApi } from "../api/workers"; -import { logsApi } from "../api/logs"; -import MarkdownContent from "./MarkdownContent"; - -interface Tool { - name: string; - description: string; - icon: string; - credentials?: ToolCredential[]; -} - -interface ToolCredential { - key: string; - label: string; - connected: boolean; - value?: string; -} - -export interface SubagentReport { - subagent_id: string; - message: string; - data?: Record; - timestamp: string; - status?: "running" | "complete" | "error"; -} - -interface ContextUsage { - usagePct: number; - messageCount: number; - estimatedTokens: number; - maxTokens: number; -} - -interface NodeDetailPanelProps { - node: GraphNode | null; - nodeSpec?: NodeSpec | null; - allNodeSpecs?: NodeSpec[]; - subagentReports?: SubagentReport[]; - sessionId?: string; - colonyId?: string; - workerSessionId?: string | null; - nodeLogs?: string[]; - actionPlan?: string; - contextUsage?: ContextUsage; - onClose: () => void; -} - -const statusConfig: Record }> = { - running: { label: "Running", color: "hsl(45,95%,58%)", Icon: ({ className }) => }, - looping: { label: "Looping", color: "hsl(38,90%,55%)", Icon: ({ className }) => }, - complete: { label: "Complete", color: "hsl(43,70%,45%)", Icon: ({ className }) => }, - pending: { label: "Pending", color: "hsl(220,15%,45%)", Icon: ({ className }) => }, - error: { label: "Error", color: "hsl(0,65%,55%)", Icon: ({ className }) => }, -}; - -function formatNodeId(id: string): string { - return id.split("-").map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(" "); -} - -function CredentialRow({ cred }: { cred: ToolCredential }) { - return ( -
-
- - {cred.label} -
- {cred.connected ? ( - Connected - ) : ( - - )} -
- ); -} - -function ToolRow({ tool }: { tool: Tool }) { - const [expanded, setExpanded] = useState(false); - const hasCreds = tool.credentials && tool.credentials.length > 0; - - return ( -
- - {expanded && hasCreds && ( -
-

Credentials

- {tool.credentials!.map(cred => ( - - ))} -
- )} -
- ); -} - -function LogsTab({ nodeId, isActive: _isActive, sessionId, colonyId, workerSessionId, nodeLogs }: { nodeId: string; isActive: boolean; sessionId?: string; colonyId?: string; workerSessionId?: string | null; nodeLogs?: string[] }) { - const [historicalLines, setHistoricalLines] = useState([]); - const bottomRef = useRef(null); - - // Fetch historical logs when session is available (post-execution viewing) - useEffect(() => { - if (sessionId && colonyId && workerSessionId) { - logsApi.nodeLogs(sessionId, colonyId, nodeId, workerSessionId) - .then(r => { - const realLines: string[] = []; - if (r.details) { - for (const d of r.details) { - realLines.push(`[LOG] ${d.node_name} — ${d.success ? "SUCCESS" : "FAILED"}${d.error ? ` (${d.error})` : ""} — ${d.total_steps} steps`); - } - } - if (r.tool_logs) { - for (const s of r.tool_logs) { - realLines.push(`[STEP ${s.step_index}] ${s.llm_text.slice(0, 120)}${s.llm_text.length > 120 ? "..." : ""}`); - } - } - if (realLines.length > 0) { - setHistoricalLines(realLines); - } - }) - .catch(() => { /* keep fallback on error */ }); - } - }, [sessionId, colonyId, nodeId, workerSessionId]); - - // Resolve which lines to display: live SSE logs > historical > default - const lines = (nodeLogs && nodeLogs.length > 0) - ? nodeLogs - : historicalLines.length > 0 - ? historicalLines - : ["[--:--:--] INFO Awaiting execution..."]; - - useEffect(() => { - bottomRef.current?.scrollIntoView({ behavior: "smooth" }); - }, [lines]); - - return ( -
- {lines.map((line, i) => { - const isWarn = line.includes(" WARN "); - const isErr = line.includes(" ERROR "); - const isDebug = line.includes(" DEBUG "); - return ( -
- {line} -
- ); - })} -
-
- ); -} - -function SystemPromptTab({ systemPrompt }: { systemPrompt?: string }) { - const prompt = systemPrompt || ""; - const [copied, setCopied] = useState(false); - - const handleCopy = () => { - navigator.clipboard.writeText(prompt); - setCopied(true); - setTimeout(() => setCopied(false), 1500); - }; - - if (!prompt) { - return ( -
-

No system prompt configured

-
- ); - } - - return ( -
-
-

System Prompt

- -
-