feat: show rawResponse in cards

This commit is contained in:
Simon
2026-01-20 20:38:02 +08:00
parent a47dfef659
commit f500445965
4 changed files with 59 additions and 9 deletions

View File

@@ -6,7 +6,7 @@
"scripts": { "scripts": {
"dev": "wxt", "dev": "wxt",
"dev:firefox": "wxt -b firefox", "dev:firefox": "wxt -b firefox",
"build": "wxt build", "build:ext": "wxt build",
"build:firefox": "wxt build -b firefox", "build:firefox": "wxt build -b firefox",
"zip": "wxt zip", "zip": "wxt zip",
"zip:firefox": "wxt zip -b firefox", "zip:firefox": "wxt zip -b firefox",

View File

@@ -1,6 +1,8 @@
import { import {
ArrowRight, ArrowRight,
CheckCircle, CheckCircle,
ChevronDown,
ChevronRight,
Loader2, Loader2,
MessageSquare, MessageSquare,
Send, Send,
@@ -103,7 +105,15 @@ function ConfigPanel({ onClose }: { onClose: () => void }) {
} }
// Result card for done action // Result card for done action
function ResultCard({ success, text }: { success: boolean; text: string }) { function ResultCard({
success,
text,
children,
}: {
success: boolean
text: string
children?: React.ReactNode
}) {
return ( return (
<div <div
className={cn( className={cn(
@@ -127,6 +137,7 @@ function ResultCard({ success, text }: { success: boolean; text: string }) {
</span> </span>
</div> </div>
<p className="text-xs text-muted-foreground pl-5 whitespace-pre-wrap">{text}</p> <p className="text-xs text-muted-foreground pl-5 whitespace-pre-wrap">{text}</p>
{children}
</div> </div>
) )
} }
@@ -166,16 +177,46 @@ function ReflectionSection({
) )
} }
// Raw response section (collapsible, for debugging)
function RawResponseSection({ rawResponse }: { rawResponse: unknown }) {
const [expanded, setExpanded] = useState(false)
return (
<div className="mt-2 border-t border-dashed pt-2">
<button
type="button"
onClick={() => setExpanded(!expanded)}
className="flex items-center gap-1 text-[10px] text-muted-foreground hover:text-foreground transition-colors"
>
{expanded ? <ChevronDown className="size-3" /> : <ChevronRight className="size-3" />}
<span>Raw Response</span>
</button>
{expanded && (
<pre
className="mt-1.5 p-2 text-[10px] bg-muted/50 rounded overflow-x-auto max-h-60 overflow-y-auto select-all"
style={{ userSelect: 'all' }}
>
{JSON.stringify(rawResponse, null, 4)}
</pre>
)}
</div>
)
}
// History event card component // History event card component
function EventCard({ event }: { event: HistoricalEvent }) { function EventCard({ event }: { event: HistoricalEvent }) {
// Done action - show as result card // Done action - show as result card
if (event.type === 'step' && event.action?.name === 'done') { if (event.type === 'step' && event.action?.name === 'done') {
const input = event.action.input as { text?: string; success?: boolean } const input = event.action.input as { text?: string; success?: boolean }
return ( return (
<ResultCard <div>
success={input?.success ?? true} <ResultCard
text={input?.text || event.action.output || ''} success={input?.success ?? true}
/> text={input?.text || event.action.output || ''}
>
{!event.rawResponse || <RawResponseSection rawResponse={event.rawResponse as any} />}
</ResultCard>
</div>
) )
} }
@@ -202,6 +243,9 @@ function EventCard({ event }: { event: HistoricalEvent }) {
</div> </div>
</div> </div>
)} )}
{/* Raw Response */}
{!event.rawResponse || <RawResponseSection rawResponse={event.rawResponse as any} />}
</div> </div>
) )
} }
@@ -217,9 +261,12 @@ function EventCard({ event }: { event: HistoricalEvent }) {
if (event.type === 'error') { if (event.type === 'error') {
return ( return (
<div className="flex items-start gap-1.5 rounded-lg border border-destructive/30 bg-destructive/10 p-2.5"> <div className="rounded-lg border border-destructive/30 bg-destructive/10 p-2.5">
<XCircle className="size-3 text-destructive shrink-0 mt-0.5" /> <div className="flex items-start gap-1.5">
<span className="text-xs text-destructive">{event.message}</span> <XCircle className="size-3 text-destructive shrink-0 mt-0.5" />
<span className="text-xs text-destructive">{event.message}</span>
</div>
{!event.rawResponse || <RawResponseSection rawResponse={event.rawResponse as any} />}
</div> </div>
) )
} }

View File

@@ -72,6 +72,8 @@ export interface HistoricalEvent {
// For 'error' type // For 'error' type
errorType?: 'retry' | 'error' errorType?: 'retry' | 'error'
message?: string message?: string
// Raw LLM response for debugging (step and error types)
rawResponse?: unknown
} }
/** Agent state snapshot */ /** Agent state snapshot */

View File

@@ -5,6 +5,7 @@
"useDefineForClassFields": true, "useDefineForClassFields": true,
"noEmit": false, "noEmit": false,
"allowImportingTsExtensions": false, "allowImportingTsExtensions": false,
"strictNullChecks": true,
"jsx": "react-jsx", "jsx": "react-jsx",
"baseUrl": ".", "baseUrl": ".",
"paths": { "paths": {