{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "chat-tool",
  "type": "registry:component",
  "title": "Chat Tool",
  "description": "A chat tool component that displays tool calls and their results.",
  "dependencies": [
    "ai",
    "@radix-ui/react-accordion",
    "lucide-react"
  ],
  "registryDependencies": [
    "accordion"
  ],
  "files": [
    {
      "path": "registry/new-york/blocks/chat-tool/chat-tool.tsx",
      "content": "import {\n  Accordion,\n  AccordionContent,\n  AccordionItem,\n  AccordionTrigger,\n} from \"@/components/ui/accordion\";\nimport { DynamicToolUIPart, ToolUIPart } from \"ai\";\nimport { cn } from \"@/lib/utils\";\nimport { Wrench, Loader2, Check, AlertCircle } from \"lucide-react\";\n\n// Helper function to get state information\nfunction getStateInfo(state: string) {\n  switch (state) {\n    case \"input-streaming\":\n      return {\n        icon: Wrench,\n        label: \"Using \",\n        color: \"text-muted-foreground\",\n      };\n    case \"input-available\":\n      return {\n        icon: Loader2,\n        label: \"Using \",\n        color: \"text-muted-foreground\",\n      };\n    case \"output-available\":\n      return {\n        icon: Check,\n        label: \"Used \",\n        color: \"text-success\",\n      };\n    case \"output-error\":\n      return {\n        icon: AlertCircle,\n        label: \"Failed to use\",\n        color: \"text-destructive\",\n      };\n    default:\n      return {\n        icon: Wrench,\n        label: \"Using\",\n        color: \"text-muted-foreground\",\n      };\n  }\n}\n\n// Helper function to safely render unknown values\nfunction renderValue(value: unknown): React.ReactNode {\n  if (typeof value === \"string\") {\n    return value;\n  }\n  return JSON.stringify(value, null, 2);\n}\n\nexport default function ChatTool({\n  toolMessagePart,\n  className,\n}: {\n  toolMessagePart: ToolUIPart | DynamicToolUIPart;\n  className?: string;\n}) {\n  const toolName =\n    toolMessagePart.type === \"dynamic-tool\"\n      ? toolMessagePart.toolName\n      : toolMessagePart.type.replace(\"tool-\", \"\");\n\n  const stateInfo = getStateInfo(toolMessagePart.state);\n  const StateIcon = stateInfo.icon;\n\n  return (\n    <Accordion type=\"single\" collapsible className=\"w-full\">\n      <AccordionItem\n        value=\"tool\"\n        className={cn(\n          \"px-2 border rounded-xl hover:no-underline py-2 w-full last:border-b shadow-xs\",\n          className\n        )}\n      >\n        <AccordionTrigger className={cn(\"py-0 hover:no-underline hover:opacity-70 transition-all\")}>\n          <span className=\"flex items-center gap-2\">\n            <StateIcon\n              className={cn(\n                \"w-4 h-4\",\n                stateInfo.color,\n                toolMessagePart.state === \"input-available\" && \"animate-spin\"\n              )}\n            />\n            <span className=\"text-sm\">\n              {stateInfo.label} {toolName}\n            </span>\n          </span>\n        </AccordionTrigger>\n        <AccordionContent className=\"pb-0\">\n          <div className=\"flex flex-col gap-3 w-full pt-2\">\n            {/* Error Section - show for failed executions */}\n            {toolMessagePart.state === \"output-error\" && toolMessagePart.errorText && (\n              <div className=\"bg-destructive/5 border rounded-md p-2 text-sm overflow-x-auto whitespace-pre-wrap text-destructive w-full\">\n                {toolMessagePart.errorText}\n              </div>\n            )}\n            {/* Input Section - always show if available */}\n            {\"input\" in toolMessagePart &&\n            toolMessagePart.input !== undefined &&\n            toolMessagePart.input !== null ? (\n              <div className=\"w-full\">\n                <div className=\"text-xs font-semibold text-muted-foreground mb-1\">Input</div>\n                <pre className=\"bg-muted rounded-md p-2 text-sm overflow-x-auto whitespace-pre-wrap w-full\">\n                  {renderValue(toolMessagePart.input)}\n                </pre>\n              </div>\n            ) : (\n              <div className=\"text-xs text-muted-foreground\">No input</div>\n            )}\n\n            {/* Output Section - show for successful completion */}\n            {toolMessagePart.state === \"output-available\" &&\n              \"output\" in toolMessagePart &&\n              toolMessagePart.output !== undefined &&\n              toolMessagePart.output !== null && (\n                <div className=\"w-full\">\n                  <div className=\"text-xs font-semibold text-muted-foreground mb-1\">Output</div>\n                  <pre className=\"bg-muted rounded-md p-2 text-sm overflow-x-auto whitespace-pre-wrap w-full\">\n                    {renderValue(toolMessagePart.output)}\n                  </pre>\n                </div>\n              )}\n          </div>\n        </AccordionContent>\n      </AccordionItem>\n    </Accordion>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/chat/chat-tool.tsx"
    }
  ]
}