@@ -378,30 +163,25 @@ const SessionCreateMenu = ({
);
}
+ const agentLabel = agentLabels[selectedAgent] ?? selectedAgent;
+
+ if (phase === "loading-config") {
+ return (
+
+ );
+ }
+
// Phase 2: config form
const activeModes = modesByAgent[selectedAgent] ?? [];
- const modesLoading = modesLoadingByAgent[selectedAgent] ?? false;
- const modesError = modesErrorByAgent[selectedAgent] ?? null;
- const modelOptions = modelsByAgent[selectedAgent] ?? [];
- const modelsLoading = modelsLoadingByAgent[selectedAgent] ?? false;
- const modelsError = modelsErrorByAgent[selectedAgent] ?? null;
- const defaultModel = defaultModelByAgent[selectedAgent] ?? "";
- const selectedModelId = model || defaultModel;
- const selectedModelObj = modelOptions.find((entry) => entry.id === selectedModelId);
- const variantOptions = selectedModelObj?.variants ?? [];
- const showModelSelect = modelsLoading || Boolean(modelsError) || modelOptions.length > 0;
- const hasModelOptions = modelOptions.length > 0;
- const modelCustom =
- model && hasModelOptions && !modelOptions.some((entry) => entry.id === model);
- const supportsVariants =
- modelsLoading ||
- Boolean(modelsError) ||
- modelOptions.some((entry) => (entry.variants?.length ?? 0) > 0);
- const showVariantSelect =
- supportsVariants && (modelsLoading || Boolean(modelsError) || variantOptions.length > 0);
- const hasVariantOptions = variantOptions.length > 0;
- const variantCustom = variant && hasVariantOptions && !variantOptions.includes(variant);
- const agentLabel = agentLabels[selectedAgent] ?? selectedAgent;
+ const activeModels = modelsByAgent[selectedAgent] ?? [];
return (
@@ -415,330 +195,69 @@ const SessionCreateMenu = ({
Model
- {showModelSelect ? (
-
- ) : (
+ {isCustomModel ? (
setModel(e.target.value)}
- placeholder="Model"
- title="Model"
+ type="text"
+ value={customModel}
+ onChange={(e) => setCustomModel(e.target.value)}
+ placeholder="Enter model name..."
+ autoFocus
/>
- )}
-
-
-
- Mode
-
+ )}
+ {isCustomModel && (
+
+ )}
-
-
- Permission
- setPermissionMode(e.target.value)}
- title="Permission Mode"
- >
-
-
-
-
-
-
- {supportsVariants && (
+ {activeModes.length > 0 && (
- Variant
- {showVariantSelect ? (
- setVariant(e.target.value)}
- title="Variant"
- disabled={modelsLoading || Boolean(modelsError)}
- >
- {modelsLoading ? (
-
- ) : modelsError ? (
-
- ) : (
- <>
-
- {variantCustom && }
- {variantOptions.map((entry) => (
-
- ))}
- >
- )}
-
- ) : (
- setVariant(e.target.value)}
- placeholder="Variant"
- title="Variant"
- />
- )}
+ Mode
+ setAgentMode(e.target.value)}
+ title="Mode"
+ >
+ {activeModes.map((m) => (
+
+ ))}
+
)}
-
- {/* MCP Servers - collapsible */}
-
-
- {mcpExpanded && (
-
- {mcpServers.length > 0 && !isEditingMcp && (
-
- {mcpServers.map((entry, index) => (
-
-
- {entry.name}
- {getServerType(entry.configJson) && (
- {getServerType(entry.configJson)}
- )}
- {getServerSummary(entry.configJson)}
-
-
-
-
-
-
- ))}
-
- )}
- {isEditingMcp ? (
-
- ) : (
-
- )}
- {mcpConfigError && !isEditingMcp && (
-
{mcpConfigError}
- )}
-
- )}
-
-
- {/* Skills - collapsible with source-based list */}
-
-
- {skillsExpanded && (
-
- {skillSources.length > 0 && !isEditingSkill && (
-
- {skillSources.map((entry, index) => (
-
-
{entry.type}
-
{skillSourceSummary(entry)}
-
-
-
-
-
- ))}
-
- )}
- {isEditingSkill ? (
-
- ) : (
-
- )}
-
- )}
-
-
diff --git a/frontend/packages/inspector/src/components/chat/ChatMessages.tsx b/frontend/packages/inspector/src/components/chat/ChatMessages.tsx
index b29a9bc..3c7c2cc 100644
--- a/frontend/packages/inspector/src/components/chat/ChatMessages.tsx
+++ b/frontend/packages/inspector/src/components/chat/ChatMessages.tsx
@@ -1,23 +1,22 @@
import { getAvatarLabel, getMessageClass } from "./messageUtils";
-import renderContentPart from "./renderContentPart";
import type { TimelineEntry } from "./types";
+import { formatJson } from "../../utils/format";
const ChatMessages = ({
entries,
sessionError,
- eventError,
messagesEndRef
}: {
entries: TimelineEntry[];
sessionError: string | null;
- eventError: string | null;
messagesEndRef: React.RefObject
;
}) => {
return (
{entries.map((entry) => {
+ const messageClass = getMessageClass(entry);
+
if (entry.kind === "meta") {
- const messageClass = entry.meta?.severity === "error" ? "error" : "system";
return (
{getAvatarLabel(messageClass)}
@@ -31,53 +30,73 @@ const ChatMessages = ({
);
}
- const item = entry.item;
- if (!item) return null;
- const hasParts = (item.content ?? []).length > 0;
- const isInProgress = item.status === "in_progress";
- const isFailed = item.status === "failed";
- const messageClass = getMessageClass(item);
- const statusValue = item.status ?? "";
- const statusLabel =
- statusValue && statusValue !== "completed" ? statusValue.replace("_", " ") : "";
- const kindLabel = item.kind.replace("_", " ");
-
- return (
-
-
{getAvatarLabel(isFailed ? "error" : messageClass)}
-
- {(item.kind !== "message" || item.status !== "completed") && (
+ if (entry.kind === "reasoning") {
+ return (
+
+
AI
+
- {kindLabel}
- {statusLabel && (
-
- {statusLabel}
+ reasoning - {entry.reasoning?.visibility ?? "public"}
+
+
{entry.reasoning?.text ?? ""}
+
+
+ );
+ }
+
+ if (entry.kind === "tool") {
+ const isComplete = entry.toolStatus === "completed" || entry.toolStatus === "failed";
+ const isFailed = entry.toolStatus === "failed";
+ return (
+
+
{getAvatarLabel(isFailed ? "error" : "tool")}
+
+
+ tool call - {entry.toolName}
+ {entry.toolStatus && entry.toolStatus !== "completed" && (
+
+ {entry.toolStatus.replace("_", " ")}
)}
- )}
- {hasParts ? (
- (item.content ?? []).map(renderContentPart)
- ) : entry.deltaText ? (
-
- {entry.deltaText}
- {isInProgress && }
-
- ) : isInProgress ? (
+ {entry.toolInput &&
{entry.toolInput}}
+ {isComplete && entry.toolOutput && (
+
+
result
+
{entry.toolOutput}
+
+ )}
+ {!isComplete && !entry.toolInput && (
+
+
+
+
+
+ )}
+
+
+ );
+ }
+
+ // Message (user or assistant)
+ return (
+
+
{getAvatarLabel(messageClass)}
+
+ {entry.text ? (
+
{entry.text}
+ ) : (
- ) : (
-
No content yet.
)}
);
})}
{sessionError &&
{sessionError}
}
- {eventError &&
{eventError}
}
);
diff --git a/frontend/packages/inspector/src/components/chat/ChatPanel.tsx b/frontend/packages/inspector/src/components/chat/ChatPanel.tsx
index eef9261..9c64889 100644
--- a/frontend/packages/inspector/src/components/chat/ChatPanel.tsx
+++ b/frontend/packages/inspector/src/components/chat/ChatPanel.tsx
@@ -1,15 +1,9 @@
-import { MessageSquare, Plus, Square, Terminal } from "lucide-react";
+import { CheckSquare, MessageSquare, Plus, Square, Terminal } from "lucide-react";
import { useEffect, useRef, useState } from "react";
-import type { McpServerEntry } from "../../App";
-import type {
- AgentInfo,
- AgentModelInfo,
- AgentModeInfo,
- PermissionEventData,
- QuestionEventData,
- SkillSource
-} from "../../types/legacyApi";
-import ApprovalsTab from "../debug/ApprovalsTab";
+import type { AgentInfo } from "sandbox-agent";
+
+type AgentModeInfo = { id: string; name: string; description: string };
+type AgentModelInfo = { id: string; name?: string };
import SessionCreateMenu, { type SessionConfig } from "../SessionCreateMenu";
import ChatInput from "./ChatInput";
import ChatMessages from "./ChatMessages";
@@ -31,32 +25,11 @@ const ChatPanel = ({
messagesEndRef,
agentLabel,
currentAgentVersion,
- sessionModel,
- sessionVariant,
- sessionPermissionMode,
- sessionMcpServerCount,
- sessionSkillSourceCount,
+ sessionEnded,
onEndSession,
- eventError,
- questionRequests,
- permissionRequests,
- questionSelections,
- onSelectQuestionOption,
- onAnswerQuestion,
- onRejectQuestion,
- onReplyPermission,
modesByAgent,
modelsByAgent,
defaultModelByAgent,
- modesLoadingByAgent,
- modelsLoadingByAgent,
- modesErrorByAgent,
- modelsErrorByAgent,
- mcpServers,
- onMcpServersChange,
- mcpConfigError,
- skillSources,
- onSkillSourcesChange
}: {
sessionId: string;
transcriptEntries: TimelineEntry[];
@@ -66,39 +39,18 @@ const ChatPanel = ({
onSendMessage: () => void;
onKeyDown: (event: React.KeyboardEvent
) => void;
onCreateSession: (agentId: string, config: SessionConfig) => void;
- onSelectAgent: (agentId: string) => void;
+ onSelectAgent: (agentId: string) => Promise;
agents: AgentInfo[];
agentsLoading: boolean;
agentsError: string | null;
messagesEndRef: React.RefObject;
agentLabel: string;
currentAgentVersion?: string | null;
- sessionModel?: string | null;
- sessionVariant?: string | null;
- sessionPermissionMode?: string | null;
- sessionMcpServerCount: number;
- sessionSkillSourceCount: number;
+ sessionEnded: boolean;
onEndSession: () => void;
- eventError: string | null;
- questionRequests: QuestionEventData[];
- permissionRequests: PermissionEventData[];
- questionSelections: Record;
- onSelectQuestionOption: (requestId: string, optionLabel: string) => void;
- onAnswerQuestion: (request: QuestionEventData) => void;
- onRejectQuestion: (requestId: string) => void;
- onReplyPermission: (requestId: string, reply: "once" | "always" | "reject") => void;
modesByAgent: Record;
modelsByAgent: Record;
defaultModelByAgent: Record;
- modesLoadingByAgent: Record;
- modelsLoadingByAgent: Record;
- modesErrorByAgent: Record;
- modelsErrorByAgent: Record;
- mcpServers: McpServerEntry[];
- onMcpServersChange: (servers: McpServerEntry[]) => void;
- mcpConfigError: string | null;
- skillSources: SkillSource[];
- onSkillSourcesChange: (sources: SkillSource[]) => void;
}) => {
const [showAgentMenu, setShowAgentMenu] = useState(false);
const menuRef = useRef(null);
@@ -115,8 +67,6 @@ const ChatPanel = ({
return () => document.removeEventListener("mousedown", handler);
}, [showAgentMenu]);
- const hasApprovals = questionRequests.length > 0 || permissionRequests.length > 0;
-
return (
@@ -127,15 +77,22 @@ const ChatPanel = ({
{sessionId && (
-
-
- End
-
+ sessionEnded ? (
+
+
+ Ended
+
+ ) : (
+
+
+ End
+
+ )
)}
@@ -161,17 +118,8 @@ const ChatPanel = ({
modesByAgent={modesByAgent}
modelsByAgent={modelsByAgent}
defaultModelByAgent={defaultModelByAgent}
- modesLoadingByAgent={modesLoadingByAgent}
- modelsLoadingByAgent={modelsLoadingByAgent}
- modesErrorByAgent={modesErrorByAgent}
- modelsErrorByAgent={modelsErrorByAgent}
- mcpServers={mcpServers}
- onMcpServersChange={onMcpServersChange}
- mcpConfigError={mcpConfigError}
- skillSources={skillSources}
- onSkillSourcesChange={onSkillSourcesChange}
- onSelectAgent={onSelectAgent}
onCreateSession={onCreateSession}
+ onSelectAgent={onSelectAgent}
open={showAgentMenu}
onClose={() => setShowAgentMenu(false)}
/>
@@ -187,27 +135,11 @@ const ChatPanel = ({
)}
- {hasApprovals && (
-
- )}
-
Agent
{agentLabel}
-
- Model
- {sessionModel || "-"}
-
-
- Variant
- {sessionVariant || "-"}
-
-
- Permission
- {sessionPermissionMode || "-"}
-
-
- MCP Servers
- {sessionMcpServerCount}
-
-
- Skills
- {sessionSkillSourceCount}
-
+ {currentAgentVersion && (
+
+ Version
+ {currentAgentVersion}
+
+ )}
)}
diff --git a/frontend/packages/inspector/src/components/chat/messageUtils.ts b/frontend/packages/inspector/src/components/chat/messageUtils.ts
index e09baa2..6abdb7a 100644
--- a/frontend/packages/inspector/src/components/chat/messageUtils.ts
+++ b/frontend/packages/inspector/src/components/chat/messageUtils.ts
@@ -1,11 +1,10 @@
-import type { UniversalItem } from "../../types/legacyApi";
+import type { TimelineEntry } from "./types";
-export const getMessageClass = (item: UniversalItem) => {
- if (item.kind === "tool_call" || item.kind === "tool_result") return "tool";
- if (item.kind === "system" || item.kind === "status") return "system";
- if (item.role === "user") return "user";
- if (item.role === "tool") return "tool";
- if (item.role === "system") return "system";
+export const getMessageClass = (entry: TimelineEntry) => {
+ if (entry.kind === "tool") return "tool";
+ if (entry.kind === "meta") return entry.meta?.severity === "error" ? "error" : "system";
+ if (entry.kind === "reasoning") return "assistant";
+ if (entry.role === "user") return "user";
return "assistant";
};
diff --git a/frontend/packages/inspector/src/components/chat/renderContentPart.tsx b/frontend/packages/inspector/src/components/chat/renderContentPart.tsx
deleted file mode 100644
index a30d564..0000000
--- a/frontend/packages/inspector/src/components/chat/renderContentPart.tsx
+++ /dev/null
@@ -1,93 +0,0 @@
-import type { ContentPart } from "../../types/legacyApi";
-import { formatJson } from "../../utils/format";
-
-const renderContentPart = (part: ContentPart, index: number) => {
- const partType = (part as { type?: string }).type ?? "unknown";
- const key = `${partType}-${index}`;
- switch (partType) {
- case "text":
- return (
-
-
{(part as { text: string }).text}
-
- );
- case "json":
- return (
-
-
json
-
{formatJson((part as { json: unknown }).json)}
-
- );
- case "tool_call": {
- const { name, arguments: args, call_id } = part as {
- name: string;
- arguments: string;
- call_id: string;
- };
- return (
-
-
- tool call - {name}
- {call_id ? ` - ${call_id}` : ""}
-
- {args ?
{args} :
No arguments
}
-
- );
- }
- case "tool_result": {
- const { call_id, output } = part as { call_id: string; output: string };
- return (
-
-
tool result - {call_id}
- {output ?
{output} :
No output
}
-
- );
- }
- case "file_ref": {
- const { path, action, diff } = part as { path: string; action: string; diff?: string | null };
- return (
-
-
file - {action}
-
{path}
- {diff &&
{diff}}
-
- );
- }
- case "reasoning": {
- const { text, visibility } = part as { text: string; visibility: string };
- return (
-
-
reasoning - {visibility}
-
{text}
-
- );
- }
- case "image": {
- const { path, mime } = part as { path: string; mime?: string | null };
- return (
-
-
image {mime ? `- ${mime}` : ""}
-
{path}
-
- );
- }
- case "status": {
- const { label, detail } = part as { label: string; detail?: string | null };
- return (
-
-
status - {label}
- {detail &&
{detail}
}
-
- );
- }
- default:
- return (
-
-
unknown
-
{formatJson(part)}
-
- );
- }
-};
-
-export default renderContentPart;
diff --git a/frontend/packages/inspector/src/components/chat/types.ts b/frontend/packages/inspector/src/components/chat/types.ts
index 7da1c30..bd41778 100644
--- a/frontend/packages/inspector/src/components/chat/types.ts
+++ b/frontend/packages/inspector/src/components/chat/types.ts
@@ -1,14 +1,17 @@
-import type { UniversalItem } from "../../types/legacyApi";
-
export type TimelineEntry = {
id: string;
- kind: "item" | "meta";
+ kind: "message" | "tool" | "meta" | "reasoning";
time: string;
- item?: UniversalItem;
- deltaText?: string;
- meta?: {
- title: string;
- detail?: string;
- severity?: "info" | "error";
- };
+ // For messages:
+ role?: "user" | "assistant";
+ text?: string;
+ // For tool calls:
+ toolName?: string;
+ toolInput?: string;
+ toolOutput?: string;
+ toolStatus?: string;
+ // For reasoning:
+ reasoning?: { text: string; visibility?: string };
+ // For meta:
+ meta?: { title: string; detail?: string; severity?: "info" | "error" };
};
diff --git a/frontend/packages/inspector/src/components/debug/AgentsTab.tsx b/frontend/packages/inspector/src/components/debug/AgentsTab.tsx
index 2030dcd..0f23702 100644
--- a/frontend/packages/inspector/src/components/debug/AgentsTab.tsx
+++ b/frontend/packages/inspector/src/components/debug/AgentsTab.tsx
@@ -1,6 +1,8 @@
import { Download, Loader2, RefreshCw } from "lucide-react";
import { useState } from "react";
-import type { AgentInfo, AgentModeInfo } from "../../types/legacyApi";
+import type { AgentInfo } from "sandbox-agent";
+
+type AgentModeInfo = { id: string; name: string; description: string };
import FeatureCoverageBadges from "../agents/FeatureCoverageBadges";
import { emptyFeatureCoverage } from "../../types/agents";
@@ -52,9 +54,9 @@ const AgentsTab = ({
id,
installed: false,
credentialsAvailable: false,
- version: undefined,
- path: undefined,
- capabilities: emptyFeatureCoverage
+ version: undefined as string | undefined,
+ path: undefined as string | undefined,
+ capabilities: emptyFeatureCoverage as AgentInfo["capabilities"],
}))).map((agent) => {
const isInstalling = installingAgent === agent.id;
return (
diff --git a/frontend/packages/inspector/src/components/debug/ApprovalsTab.tsx b/frontend/packages/inspector/src/components/debug/ApprovalsTab.tsx
deleted file mode 100644
index be35a21..0000000
--- a/frontend/packages/inspector/src/components/debug/ApprovalsTab.tsx
+++ /dev/null
@@ -1,105 +0,0 @@
-import { HelpCircle, Shield } from "lucide-react";
-import type { PermissionEventData, QuestionEventData } from "../../types/legacyApi";
-import { formatJson } from "../../utils/format";
-
-const ApprovalsTab = ({
- questionRequests,
- permissionRequests,
- questionSelections,
- onSelectQuestionOption,
- onAnswerQuestion,
- onRejectQuestion,
- onReplyPermission
-}: {
- questionRequests: QuestionEventData[];
- permissionRequests: PermissionEventData[];
- questionSelections: Record
;
- onSelectQuestionOption: (requestId: string, optionLabel: string) => void;
- onAnswerQuestion: (request: QuestionEventData) => void;
- onRejectQuestion: (requestId: string) => void;
- onReplyPermission: (requestId: string, reply: "once" | "always" | "reject") => void;
-}) => {
- return (
- <>
- {questionRequests.length === 0 && permissionRequests.length === 0 ? (
- No pending approvals.
- ) : (
- <>
- {questionRequests.map((request) => {
- const selections = questionSelections[request.question_id] ?? [];
- const selected = selections[0] ?? [];
- const answered = selected.length > 0;
- return (
-
-
-
-
- Question
-
- Pending
-
-
-
{request.prompt}
-
- {request.options.map((option) => {
- const isSelected = selected.includes(option);
- return (
-
- );
- })}
-
-
-
- onAnswerQuestion(request)}>
- Reply
-
- onRejectQuestion(request.question_id)}>
- Reject
-
-
-
- );
- })}
-
- {permissionRequests.map((request) => (
-
-
-
-
- Permission
-
- Pending
-
-
- {request.action}
-
- {request.metadata !== null && request.metadata !== undefined && (
-
{formatJson(request.metadata)}
- )}
-
- onReplyPermission(request.permission_id, "once")}>
- Allow Once
-
- onReplyPermission(request.permission_id, "always")}>
- Always
-
- onReplyPermission(request.permission_id, "reject")}>
- Reject
-
-
-
- ))}
- >
- )}
- >
- );
-};
-
-export default ApprovalsTab;
diff --git a/frontend/packages/inspector/src/components/debug/DebugPanel.tsx b/frontend/packages/inspector/src/components/debug/DebugPanel.tsx
index f837dc9..f945355 100644
--- a/frontend/packages/inspector/src/components/debug/DebugPanel.tsx
+++ b/frontend/packages/inspector/src/components/debug/DebugPanel.tsx
@@ -1,19 +1,21 @@
-import { Cloud, PlayCircle, Terminal } from "lucide-react";
-import type { AgentInfo, AgentModeInfo, UniversalEvent } from "../../types/legacyApi";
+import { Cloud, PlayCircle, Server, Terminal, Wrench } from "lucide-react";
+import type { AgentInfo, SandboxAgent, SessionEvent } from "sandbox-agent";
+
+type AgentModeInfo = { id: string; name: string; description: string };
import AgentsTab from "./AgentsTab";
import EventsTab from "./EventsTab";
+import McpTab from "./McpTab";
+import SkillsTab from "./SkillsTab";
import RequestLogTab from "./RequestLogTab";
import type { RequestLog } from "../../types/requestLog";
-export type DebugTab = "log" | "events" | "agents";
+export type DebugTab = "log" | "events" | "agents" | "mcp" | "skills";
const DebugPanel = ({
debugTab,
onDebugTabChange,
events,
- offset,
onResetEvents,
- eventsError,
requestLog,
copiedLogId,
onClearRequestLog,
@@ -24,14 +26,13 @@ const DebugPanel = ({
onRefreshAgents,
onInstallAgent,
agentsLoading,
- agentsError
+ agentsError,
+ getClient,
}: {
debugTab: DebugTab;
onDebugTabChange: (tab: DebugTab) => void;
- events: UniversalEvent[];
- offset: number;
+ events: SessionEvent[];
onResetEvents: () => void;
- eventsError: string | null;
requestLog: RequestLog[];
copiedLogId: number | null;
onClearRequestLog: () => void;
@@ -43,6 +44,7 @@ const DebugPanel = ({
onInstallAgent: (agentId: string, reinstall: boolean) => Promise;
agentsLoading: boolean;
agentsError: string | null;
+ getClient: () => SandboxAgent;
}) => {
return (
@@ -60,6 +62,14 @@ const DebugPanel = ({
Agents
+ onDebugTabChange("mcp")}>
+
+ MCP
+
+ onDebugTabChange("skills")}>
+
+ Skills
+
@@ -75,9 +85,7 @@ const DebugPanel = ({
{debugTab === "events" && (
)}
@@ -92,6 +100,14 @@ const DebugPanel = ({
error={agentsError}
/>
)}
+
+ {debugTab === "mcp" && (
+
+ )}
+
+ {debugTab === "skills" && (
+
+ )}
);
diff --git a/frontend/packages/inspector/src/components/debug/EventsTab.tsx b/frontend/packages/inspector/src/components/debug/EventsTab.tsx
index 1a741ba..1568717 100644
--- a/frontend/packages/inspector/src/components/debug/EventsTab.tsx
+++ b/frontend/packages/inspector/src/components/debug/EventsTab.tsx
@@ -1,19 +1,119 @@
-import { ChevronDown, ChevronRight } from "lucide-react";
+import {
+ Ban,
+ Bot,
+ Brain,
+ ChevronDown,
+ ChevronRight,
+ Circle,
+ CircleX,
+ Command,
+ CornerDownLeft,
+ FilePen,
+ FileText,
+ FolderOpen,
+ Hourglass,
+ KeyRound,
+ ListChecks,
+ MessageSquare,
+ Plug,
+ Radio,
+ ScrollText,
+ Settings,
+ ShieldCheck,
+ SquarePlus,
+ SquareTerminal,
+ ToggleLeft,
+ Trash2,
+ Unplug,
+ Wrench,
+ type LucideIcon,
+} from "lucide-react";
import { useEffect, useState } from "react";
-import type { UniversalEvent } from "../../types/legacyApi";
+import type { SessionEvent } from "sandbox-agent";
import { formatJson, formatTime } from "../../utils/format";
-import { getEventCategory, getEventClass, getEventIcon, getEventKey, getEventType } from "./eventUtils";
+
+type EventIconInfo = { Icon: LucideIcon; category: string };
+
+function getEventIcon(method: string, payload: Record