import { type JSX, splitProps, createSignal, Show, For } from 'solid-js'; import { cn } from '../utils/cn'; import { Collapsible, CollapsibleTrigger, CollapsibleContent } from '../ui/collapsible'; import { Button } from '../ui/button'; import { CheckCircle, ChevronDown, Loader2, Settings, XCircle } from 'lucide-solid'; export interface ToolPart { type: string; state: 'input-streaming' | 'input-available' | 'output-available' | 'output-error'; input?: Record; output?: Record; toolCallId?: string; errorText?: string; } export interface ToolProps { toolPart: ToolPart; defaultOpen?: boolean; class?: string; } function formatValue(value: unknown): string { if (value === null) return 'null'; if (value === undefined) return 'undefined'; if (typeof value === 'string') return value; if (typeof value === 'object') return JSON.stringify(value, null, 2); return String(value); } function ToolStateIcon(props: { state: ToolPart['state'] }) { return ( <> ); } // Status chips: a hue as text over a 15% translucent fill of the same hue // (mirroring the inline-code chip). The TEXT color comes from a theme token // (--color-tool-*) whose light value is darkened so it reaches WCAG AA (4.5:1) // on the faint fill, while dark mode keeps a brighter hue for AA on the dark // surface — both modes resolve via the token's `.dark` override. The FILL keeps // a fixed bright hue so the chip's colored tint looks the same in both modes. const STATE_TOKEN: Record = { 'input-streaming': 'var(--color-tool-blue)', 'input-available': 'var(--color-tool-amber)', 'output-available': 'var(--color-tool-green)', 'output-error': 'var(--color-tool-red)', }; const STATE_FILL: Record = { 'input-streaming': 'hsl(217 91% 60%)', // blue 'input-available': 'hsl(38 92% 50%)', // amber 'output-available': 'hsl(142 71% 45%)', // green 'output-error': 'hsl(0 84% 60%)', // red }; function stateChip(state: ToolPart['state']): JSX.CSSProperties { return { color: STATE_TOKEN[state], background: `color-mix(in oklab, ${STATE_FILL[state]} 15%, transparent)`, }; } function ToolStateBadge(props: { state: ToolPart['state'] }) { const baseClasses = 'px-2 py-1 rounded-full text-xs font-medium'; return ( <> Processing Ready Completed Error ); } function Tool(props: ToolProps) { const [local, rest] = splitProps(props, ['toolPart', 'defaultOpen', 'class']); const [isOpen, setIsOpen] = createSignal(local.defaultOpen ?? false); const state = () => local.toolPart.state; const input = () => local.toolPart.input; const output = () => local.toolPart.output; return (
) => ( )} />
0}>

Input

{([key, value]) => (
{key}:{' '} {formatValue(value)}
)}

Output

{formatValue(output())}

Error

{local.toolPart.errorText}
Processing tool call...
Call ID: {local.toolPart.toolCallId}
); } export { Tool };