From e13401295529e341dbbcf247a3c3e546e7e1e782 Mon Sep 17 00:00:00 2001 From: NicholasKissel <28816635+NicholasKissel@users.noreply.github.com> Date: Fri, 13 Feb 2026 05:54:53 +0000 Subject: [PATCH] feat(inspector): improve session UI, skills dropdown, and visual polish (#179) - Add delete button on ended sessions (visible on hover) - Darken ended sessions with opacity and "ended" pill badge - Sort ended sessions to bottom of list - Add token usage pill in chat header - Disable input when session ended - Add Official Skills dropdown with SDK and Rivet presets - Format session IDs shorter with full ID on hover - Add arrow icon to "Configure persistence" link - Add agent logo SVGs --- frontend/packages/inspector/index.html | 755 ++++++++++++++++-- .../packages/inspector/public/logos/amp.svg | 1 + .../inspector/public/logos/claude.svg | 7 + .../inspector/public/logos/openai.svg | 2 + .../inspector/public/logos/opencode.svg | 1 + .../packages/inspector/public/logos/pi.svg | 22 + frontend/packages/inspector/src/App.tsx | 656 +++++++++++++-- .../src/components/SessionCreateMenu.tsx | 138 ++-- .../src/components/SessionSidebar.tsx | 106 ++- .../src/components/chat/ChatMessages.tsx | 335 +++++--- .../src/components/chat/ChatPanel.tsx | 171 +++- .../src/components/chat/messageUtils.tsx | 4 +- .../inspector/src/components/chat/types.ts | 1 + .../src/components/debug/AgentsTab.tsx | 22 +- .../src/components/debug/DebugPanel.tsx | 6 + .../src/components/debug/EventsTab.tsx | 39 +- .../inspector/src/components/debug/McpTab.tsx | 81 +- .../src/components/debug/SkillsTab.tsx | 197 ++++- .../packages/inspector/src/utils/format.ts | 6 + frontend/packages/inspector/vite.config.ts | 4 - sdks/acp-http-client/src/index.ts | 41 +- sdks/typescript/src/client.ts | 83 +- 22 files changed, 2283 insertions(+), 395 deletions(-) create mode 100644 frontend/packages/inspector/public/logos/amp.svg create mode 100644 frontend/packages/inspector/public/logos/claude.svg create mode 100644 frontend/packages/inspector/public/logos/openai.svg create mode 100644 frontend/packages/inspector/public/logos/opencode.svg create mode 100644 frontend/packages/inspector/public/logos/pi.svg diff --git a/frontend/packages/inspector/index.html b/frontend/packages/inspector/index.html index 259bce8..b9ebbdb 100644 --- a/frontend/packages/inspector/index.html +++ b/frontend/packages/inspector/index.html @@ -12,23 +12,23 @@
diff --git a/frontend/packages/inspector/public/logos/amp.svg b/frontend/packages/inspector/public/logos/amp.svg new file mode 100644 index 0000000..624c311 --- /dev/null +++ b/frontend/packages/inspector/public/logos/amp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/packages/inspector/public/logos/claude.svg b/frontend/packages/inspector/public/logos/claude.svg new file mode 100644 index 0000000..879ad81 --- /dev/null +++ b/frontend/packages/inspector/public/logos/claude.svg @@ -0,0 +1,7 @@ + + + diff --git a/frontend/packages/inspector/public/logos/openai.svg b/frontend/packages/inspector/public/logos/openai.svg new file mode 100644 index 0000000..ee3125f --- /dev/null +++ b/frontend/packages/inspector/public/logos/openai.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/frontend/packages/inspector/public/logos/opencode.svg b/frontend/packages/inspector/public/logos/opencode.svg new file mode 100644 index 0000000..c2404f2 --- /dev/null +++ b/frontend/packages/inspector/public/logos/opencode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/packages/inspector/public/logos/pi.svg b/frontend/packages/inspector/public/logos/pi.svg new file mode 100644 index 0000000..ed14b63 --- /dev/null +++ b/frontend/packages/inspector/public/logos/pi.svg @@ -0,0 +1,22 @@ + + diff --git a/frontend/packages/inspector/src/App.tsx b/frontend/packages/inspector/src/App.tsx index b99bc72..bb73af5 100644 --- a/frontend/packages/inspector/src/App.tsx +++ b/frontend/packages/inspector/src/App.tsx @@ -50,11 +50,15 @@ type SessionListItem = { sessionId: string; agent: string; ended: boolean; + archived: boolean; }; const ERROR_TOAST_MS = 6000; const MAX_ERROR_TOASTS = 3; +const CREATE_SESSION_SLOW_WARNING_MS = 90_000; const HTTP_ERROR_EVENT = "inspector-http-error"; +const ARCHIVED_SESSIONS_KEY = "sandbox-agent-inspector-archived-sessions"; +const SESSION_MODELS_KEY = "sandbox-agent-inspector-session-models"; const DEFAULT_ENDPOINT = "http://localhost:2468"; @@ -112,6 +116,31 @@ const getHttpErrorMessage = (status: number, statusText: string, responseBody: s return `${base}: ${clippedBody}`; }; +const shouldIgnoreGlobalError = (value: unknown): boolean => { + const name = value instanceof Error ? value.name : ""; + const message = (() => { + if (typeof value === "string") return value; + if (value instanceof Error) return value.message; + if (value && typeof value === "object" && "message" in value && typeof (value as { message?: unknown }).message === "string") { + return (value as { message: string }).message; + } + return ""; + })().toLowerCase(); + + if (name === "AbortError") return true; + if (!message) return false; + + return ( + message.includes("aborterror") || + message.includes("the operation was aborted") || + message.includes("signal is aborted") || + message.includes("acp client is closed") || + (message.includes("method not found") && message.includes("unstable/set_session_model")) || + message.includes("resizeobserver loop limit exceeded") || + message.includes("resizeobserver loop completed with undelivered notifications") + ); +}; + const getSessionIdFromPath = (): string => { const basePath = import.meta.env.BASE_URL; const path = window.location.pathname; @@ -120,6 +149,50 @@ const getSessionIdFromPath = (): string => { return match ? match[1] : ""; }; +const getArchivedSessionIds = (): Set