From d7b17facb6e59ddbe984fcb0f0639bd75dde31b2 Mon Sep 17 00:00:00 2001 From: Simon <10131203+gaomeng1900@users.noreply.github.com> Date: Wed, 28 Jan 2026 15:26:11 +0800 Subject: [PATCH] feat(ext): UI for debugging --- .../src/entrypoints/sidepanel/App.tsx | 1 + .../sidepanel/components/cards.tsx | 122 ++++++++++++++---- 2 files changed, 98 insertions(+), 25 deletions(-) diff --git a/packages/extension/src/entrypoints/sidepanel/App.tsx b/packages/extension/src/entrypoints/sidepanel/App.tsx index 3fc4604..5f513ca 100644 --- a/packages/extension/src/entrypoints/sidepanel/App.tsx +++ b/packages/extension/src/entrypoints/sidepanel/App.tsx @@ -105,6 +105,7 @@ export default function App() { {showEmptyState && } {history.map((event, index) => ( + // eslint-disable-next-line react-x/no-array-index-key ))} diff --git a/packages/extension/src/entrypoints/sidepanel/components/cards.tsx b/packages/extension/src/entrypoints/sidepanel/components/cards.tsx index bebb6ab..296d6fb 100644 --- a/packages/extension/src/entrypoints/sidepanel/components/cards.tsx +++ b/packages/extension/src/entrypoints/sidepanel/components/cards.tsx @@ -8,8 +8,6 @@ import type { } from '@page-agent/core' import { CheckCircle, - ChevronDown, - ChevronRight, Eye, Globe, Keyboard, @@ -125,27 +123,96 @@ function ActionIcon({ name, className }: { name: string; className?: string }) { return icons[name] || } -// Raw response section (collapsible, for debugging) -function RawResponseSection({ rawResponse }: { rawResponse: unknown }) { - const [expanded, setExpanded] = useState(false) +// Copy button with "Copied!" feedback +function CopyButton({ text, label }: { text: string; label: string }) { + const [copied, setCopied] = useState(false) + + return ( + + ) +} + +// Extract message content by role from raw request +function extractPrompt(rawRequest: unknown, role: 'system' | 'user'): string | null { + const messages = (rawRequest as { messages?: { role: string; content?: unknown }[] })?.messages + if (!messages) return null + const msg = + role === 'system' + ? messages.find((m) => m.role === role) + : messages.findLast((m) => m.role === role) + if (!msg?.content) return null + return typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content, null, 2) +} + +// Raw request/response section (collapsible tabs, for debugging) +function RawSection({ rawRequest, rawResponse }: { rawRequest?: unknown; rawResponse?: unknown }) { + const [activeTab, setActiveTab] = useState<'request' | 'response' | null>(null) + + if (!rawRequest && !rawResponse) return null + + const handleTabClick = (tab: 'request' | 'response') => { + setActiveTab(activeTab === tab ? null : tab) + } + + const content = + activeTab === 'request' ? rawRequest : activeTab === 'response' ? rawResponse : null + + const systemPrompt = activeTab === 'request' ? extractPrompt(rawRequest, 'system') : null + const userPrompt = activeTab === 'request' ? extractPrompt(rawRequest, 'user') : null return (
- - {expanded && ( -
-					{JSON.stringify(rawResponse, null, 4)}
-				
+
+ {rawRequest != null && ( + + )} + {rawResponse != null && ( + + )} +
+ {content != null && ( +
+
+ {systemPrompt && } + {userPrompt && } + +
+
+						{JSON.stringify(content, null, 4)}
+					
+
)}
) @@ -173,7 +240,7 @@ function StepCard({ event }: { event: AgentStepEvent }) { className="size-3.5 text-blue-500 shrink-0 mt-0.5" />
-

+

{event.action.name} {event.action.name !== 'done' && ( @@ -181,14 +248,19 @@ function StepCard({ event }: { event: AgentStepEvent }) { )}

-

└ {event.action.output}

+

+

+
+ {event.action.output} +
+

)} {/* Raw Response */} - {!event.rawResponse || } + ) } @@ -227,7 +299,7 @@ function ErrorCard({ event }: { event: AgentErrorEvent }) { {event.message} - {!event.rawResponse || } + ) } @@ -244,7 +316,7 @@ export function EventCard({ event }: { event: HistoricalEvent }) { success={input?.success ?? true} text={input?.text || event.action.output || ''} > - {!event.rawResponse || } + )