@cloudbase/agent-react-ui 0.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/README.md +135 -0
  2. package/components.json +21 -0
  3. package/dist/index.css +4241 -0
  4. package/dist/index.css.map +1 -0
  5. package/dist/index.d.mts +59 -0
  6. package/dist/index.d.ts +59 -0
  7. package/dist/index.js +2169 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/index.mjs +2182 -0
  10. package/dist/index.mjs.map +1 -0
  11. package/example/.env.sample +2 -0
  12. package/example/App.tsx +368 -0
  13. package/example/app.css +1 -0
  14. package/example/index.html +12 -0
  15. package/example/main.tsx +9 -0
  16. package/example/vite.config.ts +34 -0
  17. package/package.json +75 -0
  18. package/postcss.config.cjs +3 -0
  19. package/src/components/ai-elements/agent.tsx +140 -0
  20. package/src/components/ai-elements/artifact.tsx +147 -0
  21. package/src/components/ai-elements/attachments.tsx +421 -0
  22. package/src/components/ai-elements/audio-player.tsx +228 -0
  23. package/src/components/ai-elements/canvas.tsx +22 -0
  24. package/src/components/ai-elements/chain-of-thought.tsx +228 -0
  25. package/src/components/ai-elements/checkpoint.tsx +71 -0
  26. package/src/components/ai-elements/code-block.tsx +532 -0
  27. package/src/components/ai-elements/commit.tsx +448 -0
  28. package/src/components/ai-elements/confirmation.tsx +176 -0
  29. package/src/components/ai-elements/connection.tsx +28 -0
  30. package/src/components/ai-elements/context.tsx +408 -0
  31. package/src/components/ai-elements/controls.tsx +18 -0
  32. package/src/components/ai-elements/conversation.tsx +100 -0
  33. package/src/components/ai-elements/edge.tsx +140 -0
  34. package/src/components/ai-elements/environment-variables.tsx +295 -0
  35. package/src/components/ai-elements/file-tree.tsx +258 -0
  36. package/src/components/ai-elements/image.tsx +24 -0
  37. package/src/components/ai-elements/inline-citation.tsx +287 -0
  38. package/src/components/ai-elements/message.tsx +336 -0
  39. package/src/components/ai-elements/mic-selector.tsx +370 -0
  40. package/src/components/ai-elements/model-selector.tsx +211 -0
  41. package/src/components/ai-elements/node.tsx +71 -0
  42. package/src/components/ai-elements/open-in-chat.tsx +365 -0
  43. package/src/components/ai-elements/package-info.tsx +233 -0
  44. package/src/components/ai-elements/panel.tsx +15 -0
  45. package/src/components/ai-elements/persona.tsx +270 -0
  46. package/src/components/ai-elements/plan.tsx +142 -0
  47. package/src/components/ai-elements/prompt-input.tsx +1263 -0
  48. package/src/components/ai-elements/queue.tsx +274 -0
  49. package/src/components/ai-elements/reasoning.tsx +193 -0
  50. package/src/components/ai-elements/sandbox.tsx +126 -0
  51. package/src/components/ai-elements/schema-display.tsx +458 -0
  52. package/src/components/ai-elements/shimmer.tsx +64 -0
  53. package/src/components/ai-elements/snippet.tsx +139 -0
  54. package/src/components/ai-elements/sources.tsx +77 -0
  55. package/src/components/ai-elements/speech-input.tsx +301 -0
  56. package/src/components/ai-elements/stack-trace.tsx +482 -0
  57. package/src/components/ai-elements/suggestion.tsx +53 -0
  58. package/src/components/ai-elements/task.tsx +87 -0
  59. package/src/components/ai-elements/terminal.tsx +261 -0
  60. package/src/components/ai-elements/test-results.tsx +485 -0
  61. package/src/components/ai-elements/tool.tsx +174 -0
  62. package/src/components/ai-elements/toolbar.tsx +16 -0
  63. package/src/components/ai-elements/transcription.tsx +124 -0
  64. package/src/components/ai-elements/voice-selector.tsx +479 -0
  65. package/src/components/ai-elements/web-preview.tsx +263 -0
  66. package/src/components/chat/Chat.tsx +178 -0
  67. package/src/components/chat/Input.tsx +98 -0
  68. package/src/components/chat/Message.tsx +276 -0
  69. package/src/components/chat/index.ts +2 -0
  70. package/src/components/index.ts +1 -0
  71. package/src/components/ui/accordion.tsx +64 -0
  72. package/src/components/ui/alert.tsx +66 -0
  73. package/src/components/ui/avatar.tsx +107 -0
  74. package/src/components/ui/badge.tsx +48 -0
  75. package/src/components/ui/button-group.tsx +83 -0
  76. package/src/components/ui/button.tsx +64 -0
  77. package/src/components/ui/card.tsx +92 -0
  78. package/src/components/ui/carousel.tsx +239 -0
  79. package/src/components/ui/collapsible.tsx +31 -0
  80. package/src/components/ui/command.tsx +184 -0
  81. package/src/components/ui/dialog.tsx +158 -0
  82. package/src/components/ui/dropdown-menu.tsx +257 -0
  83. package/src/components/ui/hover-card.tsx +42 -0
  84. package/src/components/ui/input-group.tsx +168 -0
  85. package/src/components/ui/input.tsx +21 -0
  86. package/src/components/ui/popover.tsx +87 -0
  87. package/src/components/ui/progress.tsx +31 -0
  88. package/src/components/ui/scroll-area.tsx +56 -0
  89. package/src/components/ui/select.tsx +190 -0
  90. package/src/components/ui/separator.tsx +28 -0
  91. package/src/components/ui/spinner.tsx +16 -0
  92. package/src/components/ui/switch.tsx +33 -0
  93. package/src/components/ui/tabs.tsx +91 -0
  94. package/src/components/ui/textarea.tsx +18 -0
  95. package/src/components/ui/tooltip.tsx +61 -0
  96. package/src/css/global.css +123 -0
  97. package/src/css/index.css +1 -0
  98. package/src/hooks/index.ts +1 -0
  99. package/src/hooks/use-copy-to-clipboard.ts +31 -0
  100. package/src/index.ts +4 -0
  101. package/src/lib/utils.ts +6 -0
  102. package/src/locales/context.ts +8 -0
  103. package/src/locales/hooks.ts +20 -0
  104. package/src/locales/index.ts +3 -0
  105. package/src/locales/langs/en.ts +17 -0
  106. package/src/locales/langs/index.ts +12 -0
  107. package/src/locales/langs/zh-cn.ts +18 -0
  108. package/tsconfig.json +21 -0
  109. package/tsup.config.ts +21 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ui/button.tsx","../src/lib/utils.ts","../src/components/ui/hover-card.tsx","../src/components/ai-elements/attachments.tsx","../src/components/ui/command.tsx","../src/components/ui/dialog.tsx","../src/components/ui/dropdown-menu.tsx","../src/components/ui/input-group.tsx","../src/components/ui/input.tsx","../src/components/ui/textarea.tsx","../src/components/ui/select.tsx","../src/components/ui/spinner.tsx","../src/components/ai-elements/prompt-input.tsx","../src/locales/context.ts","../src/locales/hooks.ts","../src/locales/langs/zh-cn.ts","../src/locales/langs/en.ts","../src/locales/langs/index.ts","../src/components/chat/Input.tsx","../src/components/chat/Chat.tsx","../src/components/ui/button-group.tsx","../src/components/ui/separator.tsx","../src/components/ui/tooltip.tsx","../src/components/ai-elements/message.tsx","../src/components/ui/badge.tsx","../src/components/ui/collapsible.tsx","../src/components/ai-elements/tool.tsx","../src/components/ai-elements/code-block.tsx","../src/hooks/use-copy-to-clipboard.ts","../src/components/chat/Message.tsx","../src/components/ui/scroll-area.tsx","../src/components/ai-elements/suggestion.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { Slot } from \"radix-ui\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n outline:\n \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n ghost:\n \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n xs: \"h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3\",\n sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n icon: \"size-9\",\n \"icon-xs\": \"size-6 rounded-md [&_svg:not([class*='size-'])]:size-3\",\n \"icon-sm\": \"size-8\",\n \"icon-lg\": \"size-10\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n);\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n }) {\n const Comp = asChild ? Slot.Root : \"button\";\n\n return (\n <Comp\n data-slot=\"button\"\n data-variant={variant}\n data-size={size}\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n );\n}\n\nexport { Button, buttonVariants };\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\nimport { HoverCard as HoverCardPrimitive } from \"radix-ui\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction HoverCard({\n ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Root>) {\n return <HoverCardPrimitive.Root data-slot=\"hover-card\" {...props} />;\n}\n\nfunction HoverCardTrigger({\n ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) {\n return (\n <HoverCardPrimitive.Trigger data-slot=\"hover-card-trigger\" {...props} />\n );\n}\n\nfunction HoverCardContent({\n className,\n align = \"center\",\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof HoverCardPrimitive.Content>) {\n return (\n <HoverCardPrimitive.Portal data-slot=\"hover-card-portal\">\n <HoverCardPrimitive.Content\n data-slot=\"hover-card-content\"\n align={align}\n sideOffset={sideOffset}\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden\",\n className\n )}\n {...props}\n />\n </HoverCardPrimitive.Portal>\n );\n}\n\nexport { HoverCard, HoverCardTrigger, HoverCardContent };\n","\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n HoverCard,\n HoverCardContent,\n HoverCardTrigger,\n} from \"@/components/ui/hover-card\";\nimport { cn } from \"@/lib/utils\";\nimport type { FileUIPart, SourceDocumentUIPart } from \"ai\";\nimport {\n FileTextIcon,\n GlobeIcon,\n ImageIcon,\n Music2Icon,\n PaperclipIcon,\n VideoIcon,\n XIcon,\n} from \"lucide-react\";\nimport type { ComponentProps, HTMLAttributes, ReactNode } from \"react\";\nimport { createContext, useContext, useMemo } from \"react\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type AttachmentData =\n | (FileUIPart & { id: string })\n | (SourceDocumentUIPart & { id: string });\n\nexport type AttachmentMediaCategory =\n | \"image\"\n | \"video\"\n | \"audio\"\n | \"document\"\n | \"source\"\n | \"unknown\";\n\nexport type AttachmentVariant = \"grid\" | \"inline\" | \"list\";\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\nexport const getMediaCategory = (\n data: AttachmentData\n): AttachmentMediaCategory => {\n if (data.type === \"source-document\") {\n return \"source\";\n }\n\n const mediaType = data.mediaType ?? \"\";\n\n if (mediaType.startsWith(\"image/\")) {\n return \"image\";\n }\n if (mediaType.startsWith(\"video/\")) {\n return \"video\";\n }\n if (mediaType.startsWith(\"audio/\")) {\n return \"audio\";\n }\n if (mediaType.startsWith(\"application/\") || mediaType.startsWith(\"text/\")) {\n return \"document\";\n }\n\n return \"unknown\";\n};\n\nexport const getAttachmentLabel = (data: AttachmentData): string => {\n if (data.type === \"source-document\") {\n return data.title || data.filename || \"Source\";\n }\n\n const category = getMediaCategory(data);\n return data.filename || (category === \"image\" ? \"Image\" : \"Attachment\");\n};\n\n// ============================================================================\n// Contexts\n// ============================================================================\n\ninterface AttachmentsContextValue {\n variant: AttachmentVariant;\n}\n\nconst AttachmentsContext = createContext<AttachmentsContextValue | null>(null);\n\ninterface AttachmentContextValue {\n data: AttachmentData;\n mediaCategory: AttachmentMediaCategory;\n onRemove?: () => void;\n variant: AttachmentVariant;\n}\n\nconst AttachmentContext = createContext<AttachmentContextValue | null>(null);\n\n// ============================================================================\n// Hooks\n// ============================================================================\n\nexport const useAttachmentsContext = () =>\n useContext(AttachmentsContext) ?? { variant: \"grid\" as const };\n\nexport const useAttachmentContext = () => {\n const ctx = useContext(AttachmentContext);\n if (!ctx) {\n throw new Error(\"Attachment components must be used within <Attachment>\");\n }\n return ctx;\n};\n\n// ============================================================================\n// Attachments - Container\n// ============================================================================\n\nexport type AttachmentsProps = HTMLAttributes<HTMLDivElement> & {\n variant?: AttachmentVariant;\n};\n\nexport const Attachments = ({\n variant = \"grid\",\n className,\n children,\n ...props\n}: AttachmentsProps) => {\n const contextValue = useMemo(() => ({ variant }), [variant]);\n\n return (\n <AttachmentsContext.Provider value={contextValue}>\n <div\n className={cn(\n \"flex items-start\",\n variant === \"list\" ? \"flex-col gap-2\" : \"flex-wrap gap-2\",\n variant === \"grid\" && \"ml-auto w-fit\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n </AttachmentsContext.Provider>\n );\n};\n\n// ============================================================================\n// Attachment - Item\n// ============================================================================\n\nexport type AttachmentProps = HTMLAttributes<HTMLDivElement> & {\n data: AttachmentData;\n onRemove?: () => void;\n};\n\nexport const Attachment = ({\n data,\n onRemove,\n className,\n children,\n ...props\n}: AttachmentProps) => {\n const { variant } = useAttachmentsContext();\n const mediaCategory = getMediaCategory(data);\n\n const contextValue = useMemo<AttachmentContextValue>(\n () => ({ data, mediaCategory, onRemove, variant }),\n [data, mediaCategory, onRemove, variant]\n );\n\n return (\n <AttachmentContext.Provider value={contextValue}>\n <div\n className={cn(\n \"group relative\",\n variant === \"grid\" && \"size-24 overflow-hidden rounded-lg\",\n variant === \"inline\" && [\n \"flex h-8 cursor-pointer select-none items-center gap-1.5\",\n \"rounded-md border border-border px-1.5\",\n \"font-medium text-sm transition-all\",\n \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n ],\n variant === \"list\" && [\n \"flex w-full items-center gap-3 rounded-lg border p-3\",\n \"hover:bg-accent/50\",\n ],\n className\n )}\n {...props}\n >\n {children}\n </div>\n </AttachmentContext.Provider>\n );\n};\n\n// ============================================================================\n// AttachmentPreview - Media preview\n// ============================================================================\n\nexport type AttachmentPreviewProps = HTMLAttributes<HTMLDivElement> & {\n fallbackIcon?: ReactNode;\n};\n\nexport const AttachmentPreview = ({\n fallbackIcon,\n className,\n ...props\n}: AttachmentPreviewProps) => {\n const { data, mediaCategory, variant } = useAttachmentContext();\n\n const iconSize = variant === \"inline\" ? \"size-3\" : \"size-4\";\n\n const renderImage = (\n url: string,\n filename: string | undefined,\n isGrid: boolean\n ) =>\n isGrid ? (\n <img\n alt={filename || \"Image\"}\n className=\"size-full object-cover\"\n height={96}\n src={url}\n width={96}\n />\n ) : (\n <img\n alt={filename || \"Image\"}\n className=\"size-full rounded object-cover\"\n height={20}\n src={url}\n width={20}\n />\n );\n\n const renderIcon = (Icon: typeof ImageIcon) => (\n <Icon className={cn(iconSize, \"text-muted-foreground\")} />\n );\n\n const renderContent = () => {\n if (mediaCategory === \"image\" && data.type === \"file\" && data.url) {\n return renderImage(data.url, data.filename, variant === \"grid\");\n }\n\n if (mediaCategory === \"video\" && data.type === \"file\" && data.url) {\n return <video className=\"size-full object-cover\" muted src={data.url} />;\n }\n\n const iconMap: Record<AttachmentMediaCategory, typeof ImageIcon> = {\n image: ImageIcon,\n video: VideoIcon,\n audio: Music2Icon,\n source: GlobeIcon,\n document: FileTextIcon,\n unknown: PaperclipIcon,\n };\n\n const Icon = iconMap[mediaCategory];\n return fallbackIcon ?? renderIcon(Icon);\n };\n\n return (\n <div\n className={cn(\n \"flex shrink-0 items-center justify-center overflow-hidden\",\n variant === \"grid\" && \"size-full bg-muted\",\n variant === \"inline\" && \"size-5 rounded bg-background\",\n variant === \"list\" && \"size-12 rounded bg-muted\",\n className\n )}\n {...props}\n >\n {renderContent()}\n </div>\n );\n};\n\n// ============================================================================\n// AttachmentInfo - Name and type display\n// ============================================================================\n\nexport type AttachmentInfoProps = HTMLAttributes<HTMLDivElement> & {\n showMediaType?: boolean;\n};\n\nexport const AttachmentInfo = ({\n showMediaType = false,\n className,\n ...props\n}: AttachmentInfoProps) => {\n const { data, variant } = useAttachmentContext();\n const label = getAttachmentLabel(data);\n\n if (variant === \"grid\") {\n return null;\n }\n\n return (\n <div className={cn(\"min-w-0 flex-1\", className)} {...props}>\n <span className=\"block truncate\">{label}</span>\n {showMediaType && data.mediaType && (\n <span className=\"block truncate text-muted-foreground text-xs\">\n {data.mediaType}\n </span>\n )}\n </div>\n );\n};\n\n// ============================================================================\n// AttachmentRemove - Remove button\n// ============================================================================\n\nexport type AttachmentRemoveProps = ComponentProps<typeof Button> & {\n label?: string;\n};\n\nexport const AttachmentRemove = ({\n label = \"Remove\",\n className,\n children,\n ...props\n}: AttachmentRemoveProps) => {\n const { onRemove, variant } = useAttachmentContext();\n\n if (!onRemove) {\n return null;\n }\n\n return (\n <Button\n aria-label={label}\n className={cn(\n variant === \"grid\" && [\n \"absolute top-2 right-2 size-6 rounded-full p-0\",\n \"bg-background/80 backdrop-blur-sm\",\n \"opacity-0 transition-opacity group-hover:opacity-100\",\n \"hover:bg-background\",\n \"[&>svg]:size-3\",\n ],\n variant === \"inline\" && [\n \"size-5 rounded p-0\",\n \"opacity-0 transition-opacity group-hover:opacity-100\",\n \"[&>svg]:size-2.5\",\n ],\n variant === \"list\" && [\"size-8 shrink-0 rounded p-0\", \"[&>svg]:size-4\"],\n className\n )}\n onClick={(e) => {\n e.stopPropagation();\n onRemove();\n }}\n type=\"button\"\n variant=\"ghost\"\n {...props}\n >\n {children ?? <XIcon />}\n <span className=\"sr-only\">{label}</span>\n </Button>\n );\n};\n\n// ============================================================================\n// AttachmentHoverCard - Hover preview\n// ============================================================================\n\nexport type AttachmentHoverCardProps = ComponentProps<typeof HoverCard>;\n\nexport const AttachmentHoverCard = ({\n openDelay = 0,\n closeDelay = 0,\n ...props\n}: AttachmentHoverCardProps) => (\n <HoverCard closeDelay={closeDelay} openDelay={openDelay} {...props} />\n);\n\nexport type AttachmentHoverCardTriggerProps = ComponentProps<\n typeof HoverCardTrigger\n>;\n\nexport const AttachmentHoverCardTrigger = (\n props: AttachmentHoverCardTriggerProps\n) => <HoverCardTrigger {...props} />;\n\nexport type AttachmentHoverCardContentProps = ComponentProps<\n typeof HoverCardContent\n>;\n\nexport const AttachmentHoverCardContent = ({\n align = \"start\",\n className,\n ...props\n}: AttachmentHoverCardContentProps) => (\n <HoverCardContent\n align={align}\n className={cn(\"w-auto p-2\", className)}\n {...props}\n />\n);\n\n// ============================================================================\n// AttachmentEmpty - Empty state\n// ============================================================================\n\nexport type AttachmentEmptyProps = HTMLAttributes<HTMLDivElement>;\n\nexport const AttachmentEmpty = ({\n className,\n children,\n ...props\n}: AttachmentEmptyProps) => (\n <div\n className={cn(\n \"flex items-center justify-center p-4 text-muted-foreground text-sm\",\n className\n )}\n {...props}\n >\n {children ?? \"No attachments\"}\n </div>\n);\n","\"use client\";\n\nimport * as React from \"react\";\nimport { Command as CommandPrimitive } from \"cmdk\";\nimport { SearchIcon } from \"lucide-react\";\n\nimport { cn } from \"@/lib/utils\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from \"@/components/ui/dialog\";\n\nfunction Command({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive>) {\n return (\n <CommandPrimitive\n data-slot=\"command\"\n className={cn(\n \"bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction CommandDialog({\n title = \"Command Palette\",\n description = \"Search for a command to run...\",\n children,\n className,\n showCloseButton = true,\n ...props\n}: React.ComponentProps<typeof Dialog> & {\n title?: string;\n description?: string;\n className?: string;\n showCloseButton?: boolean;\n}) {\n return (\n <Dialog {...props}>\n <DialogHeader className=\"sr-only\">\n <DialogTitle>{title}</DialogTitle>\n <DialogDescription>{description}</DialogDescription>\n </DialogHeader>\n <DialogContent\n className={cn(\"overflow-hidden p-0\", className)}\n showCloseButton={showCloseButton}\n >\n <Command className=\"[&_[cmdk-group-heading]]:text-muted-foreground **:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5\">\n {children}\n </Command>\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction CommandInput({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Input>) {\n return (\n <div\n data-slot=\"command-input-wrapper\"\n className=\"flex h-9 items-center gap-2 border-b px-3\"\n >\n <SearchIcon className=\"size-4 shrink-0 opacity-50\" />\n <CommandPrimitive.Input\n data-slot=\"command-input\"\n className={cn(\n \"placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n {...props}\n />\n </div>\n );\n}\n\nfunction CommandList({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.List>) {\n return (\n <CommandPrimitive.List\n data-slot=\"command-list\"\n className={cn(\n \"max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction CommandEmpty({\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n return (\n <CommandPrimitive.Empty\n data-slot=\"command-empty\"\n className=\"py-6 text-center text-sm\"\n {...props}\n />\n );\n}\n\nfunction CommandGroup({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Group>) {\n return (\n <CommandPrimitive.Group\n data-slot=\"command-group\"\n className={cn(\n \"text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction CommandSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n return (\n <CommandPrimitive.Separator\n data-slot=\"command-separator\"\n className={cn(\"bg-border -mx-1 h-px\", className)}\n {...props}\n />\n );\n}\n\nfunction CommandItem({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Item>) {\n return (\n <CommandPrimitive.Item\n data-slot=\"command-item\"\n className={cn(\n \"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction CommandShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"command-shortcut\"\n className={cn(\n \"text-muted-foreground ml-auto text-xs tracking-widest\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport {\n Command,\n CommandDialog,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandShortcut,\n CommandSeparator,\n};\n","\"use client\";\n\nimport * as React from \"react\";\nimport { XIcon } from \"lucide-react\";\nimport { Dialog as DialogPrimitive } from \"radix-ui\";\n\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\n\nfunction Dialog({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Root>) {\n return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />;\n}\n\nfunction DialogTrigger({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />;\n}\n\nfunction DialogPortal({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />;\n}\n\nfunction DialogClose({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Close>) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />;\n}\n\nfunction DialogOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n return (\n <DialogPrimitive.Overlay\n data-slot=\"dialog-overlay\"\n className={cn(\n \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction DialogContent({\n className,\n children,\n showCloseButton = true,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content> & {\n showCloseButton?: boolean;\n}) {\n return (\n <DialogPortal data-slot=\"dialog-portal\">\n <DialogOverlay />\n <DialogPrimitive.Content\n data-slot=\"dialog-content\"\n className={cn(\n \"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 outline-none sm:max-w-lg\",\n className\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <DialogPrimitive.Close\n data-slot=\"dialog-close\"\n className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\"\n >\n <XIcon />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Content>\n </DialogPortal>\n );\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n {...props}\n />\n );\n}\n\nfunction DialogFooter({\n className,\n showCloseButton = false,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n showCloseButton?: boolean;\n}) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n className\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <DialogPrimitive.Close asChild>\n <Button variant=\"outline\">Close</Button>\n </DialogPrimitive.Close>\n )}\n </div>\n );\n}\n\nfunction DialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn(\"text-lg leading-none font-semibold\", className)}\n {...props}\n />\n );\n}\n\nfunction DialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n );\n}\n\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n};\n","\"use client\";\n\nimport * as React from \"react\";\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\";\nimport { DropdownMenu as DropdownMenuPrimitive } from \"radix-ui\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction DropdownMenu({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />;\n}\n\nfunction DropdownMenuPortal({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n return (\n <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n );\n}\n\nfunction DropdownMenuTrigger({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n return (\n <DropdownMenuPrimitive.Trigger\n data-slot=\"dropdown-menu-trigger\"\n {...props}\n />\n );\n}\n\nfunction DropdownMenuContent({\n className,\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-slot=\"dropdown-menu-content\"\n sideOffset={sideOffset}\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md\",\n className\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n );\n}\n\nfunction DropdownMenuGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n return (\n <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n );\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean;\n variant?: \"default\" | \"destructive\";\n}) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n );\n}\n\nfunction DropdownMenuRadioGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n return (\n <DropdownMenuPrimitive.RadioGroup\n data-slot=\"dropdown-menu-radio-group\"\n {...props}\n />\n );\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n return (\n <DropdownMenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CircleIcon className=\"size-2 fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n );\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\n \"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\n \"text-muted-foreground ml-auto text-xs tracking-widest\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSub({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />;\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto size-4\" />\n </DropdownMenuPrimitive.SubTrigger>\n );\n}\n\nfunction DropdownMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport {\n DropdownMenu,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n};\n","import * as React from \"react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport { Textarea } from \"@/components/ui/textarea\";\n\nfunction InputGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"input-group\"\n role=\"group\"\n className={cn(\n \"group/input-group border-input dark:bg-input/30 relative flex w-full items-center rounded-md border shadow-xs transition-[color,box-shadow] outline-none\",\n \"h-9 min-w-0 has-[>textarea]:h-auto\",\n\n // Variants based on alignment.\n \"has-[>[data-align=inline-start]]:[&>input]:pl-2\",\n \"has-[>[data-align=inline-end]]:[&>input]:pr-2\",\n \"has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3\",\n \"has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3\",\n\n // Focus state.\n \"has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot=input-group-control]:focus-visible]:ring-[3px]\",\n\n // Error state.\n \"has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40\",\n\n className\n )}\n {...props}\n />\n );\n}\n\nconst inputGroupAddonVariants = cva(\n \"text-muted-foreground flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium select-none [&>svg:not([class*='size-'])]:size-4 [&>kbd]:rounded-[calc(var(--radius)-5px)] group-data-[disabled=true]/input-group:opacity-50\",\n {\n variants: {\n align: {\n \"inline-start\":\n \"order-first pl-3 has-[>button]:ml-[-0.45rem] has-[>kbd]:ml-[-0.35rem]\",\n \"inline-end\":\n \"order-last pr-3 has-[>button]:mr-[-0.45rem] has-[>kbd]:mr-[-0.35rem]\",\n \"block-start\":\n \"order-first w-full justify-start px-3 pt-3 [.border-b]:pb-3 group-has-[>input]/input-group:pt-2.5\",\n \"block-end\":\n \"order-last w-full justify-start px-3 pb-3 [.border-t]:pt-3 group-has-[>input]/input-group:pb-2.5\",\n },\n },\n defaultVariants: {\n align: \"inline-start\",\n },\n }\n);\n\nfunction InputGroupAddon({\n className,\n align = \"inline-start\",\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof inputGroupAddonVariants>) {\n return (\n <div\n role=\"group\"\n data-slot=\"input-group-addon\"\n data-align={align}\n className={cn(inputGroupAddonVariants({ align }), className)}\n onClick={(e) => {\n if ((e.target as HTMLElement).closest(\"button\")) {\n return;\n }\n e.currentTarget.parentElement?.querySelector(\"input\")?.focus();\n }}\n {...props}\n />\n );\n}\n\nconst inputGroupButtonVariants = cva(\n \"text-sm shadow-none flex gap-2 items-center\",\n {\n variants: {\n size: {\n xs: \"h-6 gap-1 px-2 rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-3.5 has-[>svg]:px-2\",\n sm: \"h-8 px-2.5 gap-1.5 rounded-md has-[>svg]:px-2.5\",\n \"icon-xs\":\n \"size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0\",\n \"icon-sm\": \"size-8 p-0 has-[>svg]:p-0\",\n },\n },\n defaultVariants: {\n size: \"xs\",\n },\n }\n);\n\nfunction InputGroupButton({\n className,\n type = \"button\",\n variant = \"ghost\",\n size = \"xs\",\n ...props\n}: Omit<React.ComponentProps<typeof Button>, \"size\"> &\n VariantProps<typeof inputGroupButtonVariants>) {\n return (\n <Button\n type={type}\n data-size={size}\n variant={variant}\n className={cn(inputGroupButtonVariants({ size }), className)}\n {...props}\n />\n );\n}\n\nfunction InputGroupText({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n <span\n className={cn(\n \"text-muted-foreground flex items-center gap-2 text-sm [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction InputGroupInput({\n className,\n ...props\n}: React.ComponentProps<\"input\">) {\n return (\n <Input\n data-slot=\"input-group-control\"\n className={cn(\n \"flex-1 rounded-none border-0 bg-transparent shadow-none focus-visible:ring-0 dark:bg-transparent\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction InputGroupTextarea({\n className,\n ...props\n}: React.ComponentProps<\"textarea\">) {\n return (\n <Textarea\n data-slot=\"input-group-control\"\n className={cn(\n \"flex-1 resize-none rounded-none border-0 bg-transparent py-3 shadow-none focus-visible:ring-0 dark:bg-transparent\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n InputGroupText,\n InputGroupInput,\n InputGroupTextarea,\n};\n","import * as React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n return (\n <input\n type={type}\n data-slot=\"input\"\n className={cn(\n \"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n \"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n \"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport { Input };\n","import * as React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction Textarea({ className, ...props }: React.ComponentProps<\"textarea\">) {\n return (\n <textarea\n data-slot=\"textarea\"\n className={cn(\n \"border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport { Textarea };\n","\"use client\";\n\nimport * as React from \"react\";\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\";\nimport { Select as SelectPrimitive } from \"radix-ui\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction Select({\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Root>) {\n return <SelectPrimitive.Root data-slot=\"select\" {...props} />;\n}\n\nfunction SelectGroup({\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Group>) {\n return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />;\n}\n\nfunction SelectValue({\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Value>) {\n return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />;\n}\n\nfunction SelectTrigger({\n className,\n size = \"default\",\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n size?: \"sm\" | \"default\";\n}) {\n return (\n <SelectPrimitive.Trigger\n data-slot=\"select-trigger\"\n data-size={size}\n className={cn(\n \"border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDownIcon className=\"size-4 opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n );\n}\n\nfunction SelectContent({\n className,\n children,\n position = \"item-aligned\",\n align = \"center\",\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n return (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n data-slot=\"select-content\"\n className={cn(\n \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md\",\n position === \"popper\" &&\n \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n className\n )}\n position={position}\n align={align}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport\n className={cn(\n \"p-1\",\n position === \"popper\" &&\n \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1\"\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n );\n}\n\nfunction SelectLabel({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Label>) {\n return (\n <SelectPrimitive.Label\n data-slot=\"select-label\"\n className={cn(\"text-muted-foreground px-2 py-1.5 text-xs\", className)}\n {...props}\n />\n );\n}\n\nfunction SelectItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n return (\n <SelectPrimitive.Item\n data-slot=\"select-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n className\n )}\n {...props}\n >\n <span\n data-slot=\"select-item-indicator\"\n className=\"absolute right-2 flex size-3.5 items-center justify-center\"\n >\n <SelectPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n );\n}\n\nfunction SelectSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n return (\n <SelectPrimitive.Separator\n data-slot=\"select-separator\"\n className={cn(\"bg-border pointer-events-none -mx-1 my-1 h-px\", className)}\n {...props}\n />\n );\n}\n\nfunction SelectScrollUpButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n return (\n <SelectPrimitive.ScrollUpButton\n data-slot=\"select-scroll-up-button\"\n className={cn(\n \"flex cursor-default items-center justify-center py-1\",\n className\n )}\n {...props}\n >\n <ChevronUpIcon className=\"size-4\" />\n </SelectPrimitive.ScrollUpButton>\n );\n}\n\nfunction SelectScrollDownButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n return (\n <SelectPrimitive.ScrollDownButton\n data-slot=\"select-scroll-down-button\"\n className={cn(\n \"flex cursor-default items-center justify-center py-1\",\n className\n )}\n {...props}\n >\n <ChevronDownIcon className=\"size-4\" />\n </SelectPrimitive.ScrollDownButton>\n );\n}\n\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n};\n","import { Loader2Icon } from \"lucide-react\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction Spinner({ className, ...props }: React.ComponentProps<\"svg\">) {\n return (\n <Loader2Icon\n role=\"status\"\n aria-label=\"Loading\"\n className={cn(\"size-4 animate-spin\", className)}\n {...props}\n />\n );\n}\n\nexport { Spinner };\n","\"use client\";\n\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n} from \"@/components/ui/command\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport {\n HoverCard,\n HoverCardContent,\n HoverCardTrigger,\n} from \"@/components/ui/hover-card\";\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n InputGroupTextarea,\n} from \"@/components/ui/input-group\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport { Spinner } from \"@/components/ui/spinner\";\nimport { cn } from \"@/lib/utils\";\nimport type { ChatStatus, FileUIPart, SourceDocumentUIPart } from \"ai\";\nimport {\n CornerDownLeftIcon,\n ImageIcon,\n PlusIcon,\n SquareIcon,\n XIcon,\n} from \"lucide-react\";\nimport { nanoid } from \"nanoid\";\nimport {\n type ChangeEvent,\n type ChangeEventHandler,\n Children,\n type ClipboardEventHandler,\n type ComponentProps,\n createContext,\n type FormEvent,\n type FormEventHandler,\n type HTMLAttributes,\n type KeyboardEventHandler,\n type PropsWithChildren,\n type RefObject,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\n// ============================================================================\n// Provider Context & Types\n// ============================================================================\n\nexport interface AttachmentsContext {\n files: (FileUIPart & { id: string })[];\n add: (files: File[] | FileList) => void;\n remove: (id: string) => void;\n clear: () => void;\n openFileDialog: () => void;\n fileInputRef: RefObject<HTMLInputElement | null>;\n}\n\nexport interface TextInputContext {\n value: string;\n setInput: (v: string) => void;\n clear: () => void;\n}\n\nexport interface PromptInputControllerProps {\n textInput: TextInputContext;\n attachments: AttachmentsContext;\n /** INTERNAL: Allows PromptInput to register its file textInput + \"open\" callback */\n __registerFileInput: (\n ref: RefObject<HTMLInputElement | null>,\n open: () => void\n ) => void;\n}\n\nconst PromptInputController = createContext<PromptInputControllerProps | null>(\n null\n);\nconst ProviderAttachmentsContext = createContext<AttachmentsContext | null>(\n null\n);\n\nexport const usePromptInputController = () => {\n const ctx = useContext(PromptInputController);\n if (!ctx) {\n throw new Error(\n \"Wrap your component inside <PromptInputProvider> to use usePromptInputController().\"\n );\n }\n return ctx;\n};\n\n// Optional variants (do NOT throw). Useful for dual-mode components.\nconst useOptionalPromptInputController = () =>\n useContext(PromptInputController);\n\nexport const useProviderAttachments = () => {\n const ctx = useContext(ProviderAttachmentsContext);\n if (!ctx) {\n throw new Error(\n \"Wrap your component inside <PromptInputProvider> to use useProviderAttachments().\"\n );\n }\n return ctx;\n};\n\nconst useOptionalProviderAttachments = () =>\n useContext(ProviderAttachmentsContext);\n\nexport type PromptInputProviderProps = PropsWithChildren<{\n initialInput?: string;\n}>;\n\n/**\n * Optional global provider that lifts PromptInput state outside of PromptInput.\n * If you don't use it, PromptInput stays fully self-managed.\n */\nexport function PromptInputProvider({\n initialInput: initialTextInput = \"\",\n children,\n}: PromptInputProviderProps) {\n // ----- textInput state\n const [textInput, setTextInput] = useState(initialTextInput);\n const clearInput = useCallback(() => setTextInput(\"\"), []);\n\n // ----- attachments state (global when wrapped)\n const [attachmentFiles, setAttachmentFiles] = useState<\n (FileUIPart & { id: string })[]\n >([]);\n const fileInputRef = useRef<HTMLInputElement | null>(null);\n const openRef = useRef<() => void>(() => undefined);\n\n const add = useCallback((files: File[] | FileList) => {\n const incoming = Array.from(files);\n if (incoming.length === 0) {\n return;\n }\n\n setAttachmentFiles((prev) =>\n prev.concat(\n incoming.map((file) => ({\n id: nanoid(),\n type: \"file\" as const,\n url: URL.createObjectURL(file),\n mediaType: file.type,\n filename: file.name,\n }))\n )\n );\n }, []);\n\n const remove = useCallback((id: string) => {\n setAttachmentFiles((prev) => {\n const found = prev.find((f) => f.id === id);\n if (found?.url) {\n URL.revokeObjectURL(found.url);\n }\n return prev.filter((f) => f.id !== id);\n });\n }, []);\n\n const clear = useCallback(() => {\n setAttachmentFiles((prev) => {\n for (const f of prev) {\n if (f.url) {\n URL.revokeObjectURL(f.url);\n }\n }\n return [];\n });\n }, []);\n\n // Keep a ref to attachments for cleanup on unmount (avoids stale closure)\n const attachmentsRef = useRef(attachmentFiles);\n attachmentsRef.current = attachmentFiles;\n\n // Cleanup blob URLs on unmount to prevent memory leaks\n useEffect(\n () => () => {\n for (const f of attachmentsRef.current) {\n if (f.url) {\n URL.revokeObjectURL(f.url);\n }\n }\n },\n []\n );\n\n const openFileDialog = useCallback(() => {\n openRef.current?.();\n }, []);\n\n const attachments = useMemo<AttachmentsContext>(\n () => ({\n files: attachmentFiles,\n add,\n remove,\n clear,\n openFileDialog,\n fileInputRef,\n }),\n [attachmentFiles, add, remove, clear, openFileDialog]\n );\n\n const __registerFileInput = useCallback(\n (ref: RefObject<HTMLInputElement | null>, open: () => void) => {\n fileInputRef.current = ref.current;\n openRef.current = open;\n },\n []\n );\n\n const controller = useMemo<PromptInputControllerProps>(\n () => ({\n textInput: {\n value: textInput,\n setInput: setTextInput,\n clear: clearInput,\n },\n attachments,\n __registerFileInput,\n }),\n [textInput, clearInput, attachments, __registerFileInput]\n );\n\n return (\n <PromptInputController.Provider value={controller}>\n <ProviderAttachmentsContext.Provider value={attachments}>\n {children}\n </ProviderAttachmentsContext.Provider>\n </PromptInputController.Provider>\n );\n}\n\n// ============================================================================\n// Component Context & Hooks\n// ============================================================================\n\nconst LocalAttachmentsContext = createContext<AttachmentsContext | null>(null);\n\nexport const usePromptInputAttachments = () => {\n // Prefer local context (inside PromptInput) as it has validation, fall back to provider\n const provider = useOptionalProviderAttachments();\n const local = useContext(LocalAttachmentsContext);\n const context = local ?? provider;\n if (!context) {\n throw new Error(\n \"usePromptInputAttachments must be used within a PromptInput or PromptInputProvider\"\n );\n }\n return context;\n};\n\n// ============================================================================\n// Referenced Sources (Local to PromptInput)\n// ============================================================================\n\nexport interface ReferencedSourcesContext {\n sources: (SourceDocumentUIPart & { id: string })[];\n add: (sources: SourceDocumentUIPart[] | SourceDocumentUIPart) => void;\n remove: (id: string) => void;\n clear: () => void;\n}\n\nexport const LocalReferencedSourcesContext =\n createContext<ReferencedSourcesContext | null>(null);\n\nexport const usePromptInputReferencedSources = () => {\n const ctx = useContext(LocalReferencedSourcesContext);\n if (!ctx) {\n throw new Error(\n \"usePromptInputReferencedSources must be used within a LocalReferencedSourcesContext.Provider\"\n );\n }\n return ctx;\n};\n\nexport type PromptInputActionAddAttachmentsProps = ComponentProps<\n typeof DropdownMenuItem\n> & {\n label?: string;\n};\n\nexport const PromptInputActionAddAttachments = ({\n label = \"Add photos or files\",\n ...props\n}: PromptInputActionAddAttachmentsProps) => {\n const attachments = usePromptInputAttachments();\n\n return (\n <DropdownMenuItem\n {...props}\n onSelect={(e) => {\n e.preventDefault();\n attachments.openFileDialog();\n }}\n >\n <ImageIcon className=\"mr-2 size-4\" /> {label}\n </DropdownMenuItem>\n );\n};\n\nexport interface PromptInputMessage {\n text: string;\n files: FileUIPart[];\n}\n\nexport type PromptInputProps = Omit<\n HTMLAttributes<HTMLFormElement>,\n \"onSubmit\" | \"onError\"\n> & {\n accept?: string; // e.g., \"image/*\" or leave undefined for any\n multiple?: boolean;\n // When true, accepts drops anywhere on document. Default false (opt-in).\n globalDrop?: boolean;\n // Render a hidden input with given name and keep it in sync for native form posts. Default false.\n syncHiddenInput?: boolean;\n // Minimal constraints\n maxFiles?: number;\n maxFileSize?: number; // bytes\n onError?: (err: {\n code: \"max_files\" | \"max_file_size\" | \"accept\";\n message: string;\n }) => void;\n onSubmit: (\n message: PromptInputMessage,\n event: FormEvent<HTMLFormElement>\n ) => void | Promise<void>;\n};\n\nexport const PromptInput = ({\n className,\n accept,\n multiple,\n globalDrop,\n syncHiddenInput,\n maxFiles,\n maxFileSize,\n onError,\n onSubmit,\n children,\n ...props\n}: PromptInputProps) => {\n // Try to use a provider controller if present\n const controller = useOptionalPromptInputController();\n const usingProvider = !!controller;\n\n // Refs\n const inputRef = useRef<HTMLInputElement | null>(null);\n const formRef = useRef<HTMLFormElement | null>(null);\n\n // ----- Local attachments (only used when no provider)\n const [items, setItems] = useState<(FileUIPart & { id: string })[]>([]);\n const files = usingProvider ? controller.attachments.files : items;\n\n // ----- Local referenced sources (always local to PromptInput)\n const [referencedSources, setReferencedSources] = useState<\n (SourceDocumentUIPart & { id: string })[]\n >([]);\n\n // Keep a ref to files for cleanup on unmount (avoids stale closure)\n const filesRef = useRef(files);\n filesRef.current = files;\n\n const openFileDialogLocal = useCallback(() => {\n inputRef.current?.click();\n }, []);\n\n const matchesAccept = useCallback(\n (f: File) => {\n if (!accept || accept.trim() === \"\") {\n return true;\n }\n\n const patterns = accept\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n\n return patterns.some((pattern) => {\n if (pattern.endsWith(\"/*\")) {\n const prefix = pattern.slice(0, -1); // e.g: image/* -> image/\n return f.type.startsWith(prefix);\n }\n return f.type === pattern;\n });\n },\n [accept]\n );\n\n const addLocal = useCallback(\n (fileList: File[] | FileList) => {\n const incoming = Array.from(fileList);\n const accepted = incoming.filter((f) => matchesAccept(f));\n if (incoming.length && accepted.length === 0) {\n onError?.({\n code: \"accept\",\n message: \"No files match the accepted types.\",\n });\n return;\n }\n const withinSize = (f: File) =>\n maxFileSize ? f.size <= maxFileSize : true;\n const sized = accepted.filter(withinSize);\n if (accepted.length > 0 && sized.length === 0) {\n onError?.({\n code: \"max_file_size\",\n message: \"All files exceed the maximum size.\",\n });\n return;\n }\n\n setItems((prev) => {\n const capacity =\n typeof maxFiles === \"number\"\n ? Math.max(0, maxFiles - prev.length)\n : undefined;\n const capped =\n typeof capacity === \"number\" ? sized.slice(0, capacity) : sized;\n if (typeof capacity === \"number\" && sized.length > capacity) {\n onError?.({\n code: \"max_files\",\n message: \"Too many files. Some were not added.\",\n });\n }\n const next: (FileUIPart & { id: string })[] = [];\n for (const file of capped) {\n next.push({\n id: nanoid(),\n type: \"file\",\n url: URL.createObjectURL(file),\n mediaType: file.type,\n filename: file.name,\n });\n }\n return prev.concat(next);\n });\n },\n [matchesAccept, maxFiles, maxFileSize, onError]\n );\n\n const removeLocal = useCallback(\n (id: string) =>\n setItems((prev) => {\n const found = prev.find((file) => file.id === id);\n if (found?.url) {\n URL.revokeObjectURL(found.url);\n }\n return prev.filter((file) => file.id !== id);\n }),\n []\n );\n\n // Wrapper that validates files before calling provider's add\n const addWithProviderValidation = useCallback(\n (fileList: File[] | FileList) => {\n const incoming = Array.from(fileList);\n const accepted = incoming.filter((f) => matchesAccept(f));\n if (incoming.length && accepted.length === 0) {\n onError?.({\n code: \"accept\",\n message: \"No files match the accepted types.\",\n });\n return;\n }\n const withinSize = (f: File) =>\n maxFileSize ? f.size <= maxFileSize : true;\n const sized = accepted.filter(withinSize);\n if (accepted.length > 0 && sized.length === 0) {\n onError?.({\n code: \"max_file_size\",\n message: \"All files exceed the maximum size.\",\n });\n return;\n }\n\n const currentCount = files.length;\n const capacity =\n typeof maxFiles === \"number\"\n ? Math.max(0, maxFiles - currentCount)\n : undefined;\n const capped =\n typeof capacity === \"number\" ? sized.slice(0, capacity) : sized;\n if (typeof capacity === \"number\" && sized.length > capacity) {\n onError?.({\n code: \"max_files\",\n message: \"Too many files. Some were not added.\",\n });\n }\n\n if (capped.length > 0) {\n controller?.attachments.add(capped);\n }\n },\n [matchesAccept, maxFileSize, maxFiles, onError, files.length, controller]\n );\n\n const clearAttachments = useCallback(\n () =>\n usingProvider\n ? controller?.attachments.clear()\n : setItems((prev) => {\n for (const file of prev) {\n if (file.url) {\n URL.revokeObjectURL(file.url);\n }\n }\n return [];\n }),\n [usingProvider, controller]\n );\n\n const clearReferencedSources = useCallback(\n () => setReferencedSources([]),\n []\n );\n\n const add = usingProvider ? addWithProviderValidation : addLocal;\n const remove = usingProvider ? controller.attachments.remove : removeLocal;\n const openFileDialog = usingProvider\n ? controller.attachments.openFileDialog\n : openFileDialogLocal;\n\n const clear = useCallback(() => {\n clearAttachments();\n clearReferencedSources();\n }, [clearAttachments, clearReferencedSources]);\n\n // Let provider know about our hidden file input so external menus can call openFileDialog()\n useEffect(() => {\n if (!usingProvider) {\n return;\n }\n controller.__registerFileInput(inputRef, () => inputRef.current?.click());\n }, [usingProvider, controller]);\n\n // Note: File input cannot be programmatically set for security reasons\n // The syncHiddenInput prop is no longer functional\n useEffect(() => {\n if (syncHiddenInput && inputRef.current && files.length === 0) {\n inputRef.current.value = \"\";\n }\n }, [files, syncHiddenInput]);\n\n // Attach drop handlers on nearest form and document (opt-in)\n useEffect(() => {\n const form = formRef.current;\n if (!form) {\n return;\n }\n if (globalDrop) {\n return; // when global drop is on, let the document-level handler own drops\n }\n\n const onDragOver = (e: DragEvent) => {\n if (e.dataTransfer?.types?.includes(\"Files\")) {\n e.preventDefault();\n }\n };\n const onDrop = (e: DragEvent) => {\n if (e.dataTransfer?.types?.includes(\"Files\")) {\n e.preventDefault();\n }\n if (e.dataTransfer?.files && e.dataTransfer.files.length > 0) {\n add(e.dataTransfer.files);\n }\n };\n form.addEventListener(\"dragover\", onDragOver);\n form.addEventListener(\"drop\", onDrop);\n return () => {\n form.removeEventListener(\"dragover\", onDragOver);\n form.removeEventListener(\"drop\", onDrop);\n };\n }, [add, globalDrop]);\n\n useEffect(() => {\n if (!globalDrop) {\n return;\n }\n\n const onDragOver = (e: DragEvent) => {\n if (e.dataTransfer?.types?.includes(\"Files\")) {\n e.preventDefault();\n }\n };\n const onDrop = (e: DragEvent) => {\n if (e.dataTransfer?.types?.includes(\"Files\")) {\n e.preventDefault();\n }\n if (e.dataTransfer?.files && e.dataTransfer.files.length > 0) {\n add(e.dataTransfer.files);\n }\n };\n document.addEventListener(\"dragover\", onDragOver);\n document.addEventListener(\"drop\", onDrop);\n return () => {\n document.removeEventListener(\"dragover\", onDragOver);\n document.removeEventListener(\"drop\", onDrop);\n };\n }, [add, globalDrop]);\n\n useEffect(\n () => () => {\n if (!usingProvider) {\n for (const f of filesRef.current) {\n if (f.url) {\n URL.revokeObjectURL(f.url);\n }\n }\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps -- cleanup only on unmount; filesRef always current\n [usingProvider]\n );\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = (event) => {\n if (event.currentTarget.files) {\n add(event.currentTarget.files);\n }\n // Reset input value to allow selecting files that were previously removed\n event.currentTarget.value = \"\";\n };\n\n const convertBlobUrlToDataUrl = async (\n url: string\n ): Promise<string | null> => {\n try {\n const response = await fetch(url);\n const blob = await response.blob();\n return new Promise((resolve) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result as string);\n reader.onerror = () => resolve(null);\n reader.readAsDataURL(blob);\n });\n } catch {\n return null;\n }\n };\n\n const attachmentsCtx = useMemo<AttachmentsContext>(\n () => ({\n files: files.map((item) => ({ ...item, id: item.id })),\n add,\n remove,\n clear: clearAttachments,\n openFileDialog,\n fileInputRef: inputRef,\n }),\n [files, add, remove, clearAttachments, openFileDialog]\n );\n\n const refsCtx = useMemo<ReferencedSourcesContext>(\n () => ({\n sources: referencedSources,\n add: (incoming: SourceDocumentUIPart[] | SourceDocumentUIPart) => {\n const array = Array.isArray(incoming) ? incoming : [incoming];\n setReferencedSources((prev) =>\n prev.concat(array.map((s) => ({ ...s, id: nanoid() })))\n );\n },\n remove: (id: string) => {\n setReferencedSources((prev) => prev.filter((s) => s.id !== id));\n },\n clear: clearReferencedSources,\n }),\n [referencedSources, clearReferencedSources]\n );\n\n const handleSubmit: FormEventHandler<HTMLFormElement> = (event) => {\n event.preventDefault();\n\n const form = event.currentTarget;\n const text = usingProvider\n ? controller.textInput.value\n : (() => {\n const formData = new FormData(form);\n return (formData.get(\"message\") as string) || \"\";\n })();\n\n // Reset form immediately after capturing text to avoid race condition\n // where user input during async blob conversion would be lost\n if (!usingProvider) {\n form.reset();\n }\n\n // Convert blob URLs to data URLs asynchronously\n Promise.all(\n files.map(async ({ id, ...item }) => {\n if (item.url?.startsWith(\"blob:\")) {\n const dataUrl = await convertBlobUrlToDataUrl(item.url);\n // If conversion failed, keep the original blob URL\n return {\n ...item,\n url: dataUrl ?? item.url,\n };\n }\n return item;\n })\n )\n .then((convertedFiles: FileUIPart[]) => {\n try {\n const result = onSubmit({ text, files: convertedFiles }, event);\n\n // Handle both sync and async onSubmit\n if (result instanceof Promise) {\n result\n .then(() => {\n clear();\n if (usingProvider) {\n controller.textInput.clear();\n }\n })\n .catch(() => {\n // Don't clear on error - user may want to retry\n });\n } else {\n // Sync function completed without throwing, clear inputs\n clear();\n if (usingProvider) {\n controller.textInput.clear();\n }\n }\n } catch {\n // Don't clear on error - user may want to retry\n }\n })\n .catch(() => {\n // Don't clear on error - user may want to retry\n });\n };\n\n // Render with or without local provider\n const inner = (\n <>\n <input\n accept={accept}\n aria-label=\"Upload files\"\n className=\"hidden\"\n multiple={multiple}\n onChange={handleChange}\n ref={inputRef}\n title=\"Upload files\"\n type=\"file\"\n />\n <form\n className={cn(\"w-full\", className)}\n onSubmit={handleSubmit}\n ref={formRef}\n {...props}\n >\n <InputGroup className=\"overflow-hidden\">{children}</InputGroup>\n </form>\n </>\n );\n\n const withReferencedSources = (\n <LocalReferencedSourcesContext.Provider value={refsCtx}>\n {inner}\n </LocalReferencedSourcesContext.Provider>\n );\n\n // Always provide LocalAttachmentsContext so children get validated add function\n return (\n <LocalAttachmentsContext.Provider value={attachmentsCtx}>\n {withReferencedSources}\n </LocalAttachmentsContext.Provider>\n );\n};\n\nexport type PromptInputBodyProps = HTMLAttributes<HTMLDivElement>;\n\nexport const PromptInputBody = ({\n className,\n ...props\n}: PromptInputBodyProps) => (\n <div className={cn(\"contents\", className)} {...props} />\n);\n\nexport type PromptInputTextareaProps = ComponentProps<\n typeof InputGroupTextarea\n>;\n\nexport const PromptInputTextarea = ({\n onChange,\n onKeyDown,\n className,\n placeholder = \"What would you like to know?\",\n ...props\n}: PromptInputTextareaProps) => {\n const controller = useOptionalPromptInputController();\n const attachments = usePromptInputAttachments();\n const [isComposing, setIsComposing] = useState(false);\n\n const handleKeyDown: KeyboardEventHandler<HTMLTextAreaElement> = (e) => {\n // Call the external onKeyDown handler first\n onKeyDown?.(e);\n\n // If the external handler prevented default, don't run internal logic\n if (e.defaultPrevented) {\n return;\n }\n\n if (e.key === \"Enter\") {\n if (isComposing || e.nativeEvent.isComposing) {\n return;\n }\n if (e.shiftKey) {\n return;\n }\n e.preventDefault();\n\n // Check if the submit button is disabled before submitting\n const form = e.currentTarget.form;\n const submitButton = form?.querySelector(\n 'button[type=\"submit\"]'\n ) as HTMLButtonElement | null;\n if (submitButton?.disabled) {\n return;\n }\n\n form?.requestSubmit();\n }\n\n // Remove last attachment when Backspace is pressed and textarea is empty\n if (\n e.key === \"Backspace\" &&\n e.currentTarget.value === \"\" &&\n attachments.files.length > 0\n ) {\n e.preventDefault();\n const lastAttachment = attachments.files[attachments.files.length - 1];\n if (lastAttachment) {\n attachments.remove(lastAttachment.id);\n }\n }\n };\n\n const handlePaste: ClipboardEventHandler<HTMLTextAreaElement> = (event) => {\n const items = event.clipboardData?.items;\n\n if (!items) {\n return;\n }\n\n const files: File[] = [];\n\n for (const item of items) {\n if (item.kind === \"file\") {\n const file = item.getAsFile();\n if (file) {\n files.push(file);\n }\n }\n }\n\n if (files.length > 0) {\n event.preventDefault();\n attachments.add(files);\n }\n };\n\n const controlledProps = controller\n ? {\n value: controller.textInput.value,\n onChange: (e: ChangeEvent<HTMLTextAreaElement>) => {\n controller.textInput.setInput(e.currentTarget.value);\n onChange?.(e);\n },\n }\n : {\n onChange,\n };\n\n return (\n <InputGroupTextarea\n className={cn(\"field-sizing-content max-h-48 min-h-16\", className)}\n name=\"message\"\n onCompositionEnd={() => setIsComposing(false)}\n onCompositionStart={() => setIsComposing(true)}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n placeholder={placeholder}\n {...props}\n {...controlledProps}\n />\n );\n};\n\nexport type PromptInputHeaderProps = Omit<\n ComponentProps<typeof InputGroupAddon>,\n \"align\"\n>;\n\nexport const PromptInputHeader = ({\n className,\n ...props\n}: PromptInputHeaderProps) => (\n <InputGroupAddon\n align=\"block-end\"\n className={cn(\"order-first flex-wrap gap-1\", className)}\n {...props}\n />\n);\n\nexport type PromptInputFooterProps = Omit<\n ComponentProps<typeof InputGroupAddon>,\n \"align\"\n>;\n\nexport const PromptInputFooter = ({\n className,\n ...props\n}: PromptInputFooterProps) => (\n <InputGroupAddon\n align=\"block-end\"\n className={cn(\"justify-between gap-1\", className)}\n {...props}\n />\n);\n\nexport type PromptInputToolsProps = HTMLAttributes<HTMLDivElement>;\n\nexport const PromptInputTools = ({\n className,\n ...props\n}: PromptInputToolsProps) => (\n <div className={cn(\"flex items-center gap-1\", className)} {...props} />\n);\n\nexport type PromptInputButtonProps = ComponentProps<typeof InputGroupButton>;\n\nexport const PromptInputButton = ({\n variant = \"ghost\",\n className,\n size,\n ...props\n}: PromptInputButtonProps) => {\n const newSize =\n size ?? (Children.count(props.children) > 1 ? \"sm\" : \"icon-sm\");\n\n return (\n <InputGroupButton\n className={cn(className)}\n size={newSize}\n type=\"button\"\n variant={variant}\n {...props}\n />\n );\n};\n\nexport type PromptInputActionMenuProps = ComponentProps<typeof DropdownMenu>;\nexport const PromptInputActionMenu = (props: PromptInputActionMenuProps) => (\n <DropdownMenu {...props} />\n);\n\nexport type PromptInputActionMenuTriggerProps = PromptInputButtonProps;\n\nexport const PromptInputActionMenuTrigger = ({\n className,\n children,\n ...props\n}: PromptInputActionMenuTriggerProps) => (\n <DropdownMenuTrigger asChild>\n <PromptInputButton className={className} {...props}>\n {children ?? <PlusIcon className=\"size-4\" />}\n </PromptInputButton>\n </DropdownMenuTrigger>\n);\n\nexport type PromptInputActionMenuContentProps = ComponentProps<\n typeof DropdownMenuContent\n>;\nexport const PromptInputActionMenuContent = ({\n className,\n ...props\n}: PromptInputActionMenuContentProps) => (\n <DropdownMenuContent align=\"start\" className={cn(className)} {...props} />\n);\n\nexport type PromptInputActionMenuItemProps = ComponentProps<\n typeof DropdownMenuItem\n>;\nexport const PromptInputActionMenuItem = ({\n className,\n ...props\n}: PromptInputActionMenuItemProps) => (\n <DropdownMenuItem className={cn(className)} {...props} />\n);\n\n// Note: Actions that perform side-effects (like opening a file dialog)\n// are provided in opt-in modules (e.g., prompt-input-attachments).\n\nexport type PromptInputSubmitProps = ComponentProps<typeof InputGroupButton> & {\n status?: ChatStatus;\n onStop?: () => void;\n};\n\nexport const PromptInputSubmit = ({\n className,\n variant = \"default\",\n size = \"icon-sm\",\n status,\n onStop,\n onClick,\n children,\n ...props\n}: PromptInputSubmitProps) => {\n const isGenerating = status === \"submitted\" || status === \"streaming\";\n\n let Icon = <CornerDownLeftIcon className=\"size-4\" />;\n\n if (status === \"submitted\") {\n Icon = <Spinner />;\n } else if (status === \"streaming\") {\n Icon = <SquareIcon className=\"size-4\" />;\n } else if (status === \"error\") {\n Icon = <XIcon className=\"size-4\" />;\n }\n\n const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {\n if (isGenerating && onStop) {\n e.preventDefault();\n onStop();\n return;\n }\n onClick?.(e);\n };\n\n return (\n <InputGroupButton\n aria-label={isGenerating ? \"Stop\" : \"Submit\"}\n className={cn(className)}\n onClick={handleClick}\n size={size}\n type={isGenerating && onStop ? \"button\" : \"submit\"}\n variant={variant}\n {...props}\n >\n {children ?? Icon}\n </InputGroupButton>\n );\n};\n\nexport type PromptInputSelectProps = ComponentProps<typeof Select>;\n\nexport const PromptInputSelect = (props: PromptInputSelectProps) => (\n <Select {...props} />\n);\n\nexport type PromptInputSelectTriggerProps = ComponentProps<\n typeof SelectTrigger\n>;\n\nexport const PromptInputSelectTrigger = ({\n className,\n ...props\n}: PromptInputSelectTriggerProps) => (\n <SelectTrigger\n className={cn(\n \"border-none bg-transparent font-medium text-muted-foreground shadow-none transition-colors\",\n \"hover:bg-accent hover:text-foreground aria-expanded:bg-accent aria-expanded:text-foreground\",\n className\n )}\n {...props}\n />\n);\n\nexport type PromptInputSelectContentProps = ComponentProps<\n typeof SelectContent\n>;\n\nexport const PromptInputSelectContent = ({\n className,\n ...props\n}: PromptInputSelectContentProps) => (\n <SelectContent className={cn(className)} {...props} />\n);\n\nexport type PromptInputSelectItemProps = ComponentProps<typeof SelectItem>;\n\nexport const PromptInputSelectItem = ({\n className,\n ...props\n}: PromptInputSelectItemProps) => (\n <SelectItem className={cn(className)} {...props} />\n);\n\nexport type PromptInputSelectValueProps = ComponentProps<typeof SelectValue>;\n\nexport const PromptInputSelectValue = ({\n className,\n ...props\n}: PromptInputSelectValueProps) => (\n <SelectValue className={cn(className)} {...props} />\n);\n\nexport type PromptInputHoverCardProps = ComponentProps<typeof HoverCard>;\n\nexport const PromptInputHoverCard = ({\n openDelay = 0,\n closeDelay = 0,\n ...props\n}: PromptInputHoverCardProps) => (\n <HoverCard closeDelay={closeDelay} openDelay={openDelay} {...props} />\n);\n\nexport type PromptInputHoverCardTriggerProps = ComponentProps<\n typeof HoverCardTrigger\n>;\n\nexport const PromptInputHoverCardTrigger = (\n props: PromptInputHoverCardTriggerProps\n) => <HoverCardTrigger {...props} />;\n\nexport type PromptInputHoverCardContentProps = ComponentProps<\n typeof HoverCardContent\n>;\n\nexport const PromptInputHoverCardContent = ({\n align = \"start\",\n ...props\n}: PromptInputHoverCardContentProps) => (\n <HoverCardContent align={align} {...props} />\n);\n\nexport type PromptInputTabsListProps = HTMLAttributes<HTMLDivElement>;\n\nexport const PromptInputTabsList = ({\n className,\n ...props\n}: PromptInputTabsListProps) => <div className={cn(className)} {...props} />;\n\nexport type PromptInputTabProps = HTMLAttributes<HTMLDivElement>;\n\nexport const PromptInputTab = ({\n className,\n ...props\n}: PromptInputTabProps) => <div className={cn(className)} {...props} />;\n\nexport type PromptInputTabLabelProps = HTMLAttributes<HTMLHeadingElement>;\n\nexport const PromptInputTabLabel = ({\n className,\n ...props\n}: PromptInputTabLabelProps) => (\n <h3\n className={cn(\n \"mb-2 px-3 font-medium text-muted-foreground text-xs\",\n className\n )}\n {...props}\n />\n);\n\nexport type PromptInputTabBodyProps = HTMLAttributes<HTMLDivElement>;\n\nexport const PromptInputTabBody = ({\n className,\n ...props\n}: PromptInputTabBodyProps) => (\n <div className={cn(\"space-y-1\", className)} {...props} />\n);\n\nexport type PromptInputTabItemProps = HTMLAttributes<HTMLDivElement>;\n\nexport const PromptInputTabItem = ({\n className,\n ...props\n}: PromptInputTabItemProps) => (\n <div\n className={cn(\n \"flex items-center gap-2 px-3 py-2 text-xs hover:bg-accent\",\n className\n )}\n {...props}\n />\n);\n\nexport type PromptInputCommandProps = ComponentProps<typeof Command>;\n\nexport const PromptInputCommand = ({\n className,\n ...props\n}: PromptInputCommandProps) => <Command className={cn(className)} {...props} />;\n\nexport type PromptInputCommandInputProps = ComponentProps<typeof CommandInput>;\n\nexport const PromptInputCommandInput = ({\n className,\n ...props\n}: PromptInputCommandInputProps) => (\n <CommandInput className={cn(className)} {...props} />\n);\n\nexport type PromptInputCommandListProps = ComponentProps<typeof CommandList>;\n\nexport const PromptInputCommandList = ({\n className,\n ...props\n}: PromptInputCommandListProps) => (\n <CommandList className={cn(className)} {...props} />\n);\n\nexport type PromptInputCommandEmptyProps = ComponentProps<typeof CommandEmpty>;\n\nexport const PromptInputCommandEmpty = ({\n className,\n ...props\n}: PromptInputCommandEmptyProps) => (\n <CommandEmpty className={cn(className)} {...props} />\n);\n\nexport type PromptInputCommandGroupProps = ComponentProps<typeof CommandGroup>;\n\nexport const PromptInputCommandGroup = ({\n className,\n ...props\n}: PromptInputCommandGroupProps) => (\n <CommandGroup className={cn(className)} {...props} />\n);\n\nexport type PromptInputCommandItemProps = ComponentProps<typeof CommandItem>;\n\nexport const PromptInputCommandItem = ({\n className,\n ...props\n}: PromptInputCommandItemProps) => (\n <CommandItem className={cn(className)} {...props} />\n);\n\nexport type PromptInputCommandSeparatorProps = ComponentProps<\n typeof CommandSeparator\n>;\n\nexport const PromptInputCommandSeparator = ({\n className,\n ...props\n}: PromptInputCommandSeparatorProps) => (\n <CommandSeparator className={cn(className)} {...props} />\n);\n","import { createContext } from \"react\";\nimport { LocaleCode } from \"./langs\";\n\nexport type LocaleContextProps = { locale: LocaleCode };\n\nexport const LocaleContext = createContext<LocaleContextProps>({\n locale: \"zh-CN\",\n});\n","import { useContext, useMemo } from \"react\";\nimport { Locale, LocaleCode, LocaleComponentName, locales } from \"./langs\";\nimport { LocaleContext } from \"./context\";\n\nexport function useLocale(): { locale: Locale; localeCode: LocaleCode };\nexport function useLocale<T extends LocaleComponentName>(\n name: T\n): { locale: Locale[T]; localeCode: LocaleCode };\nexport function useLocale<T extends LocaleComponentName>(\n name?: T\n): { locale: Locale | Locale[T]; localeCode: LocaleCode } {\n const { locale: localeCode } = useContext(LocaleContext);\n\n const locale = useMemo(() => {\n const fullLocale = locales[localeCode] ?? locales[\"zh-CN\"];\n return name ? fullLocale[name] : fullLocale;\n }, [localeCode, name]);\n\n return { locale: locale as any, localeCode };\n}\n","export const zhCN = {\n chat: {\n emptyTitle: \"有什么我可以帮到你?\",\n },\n input: {\n placeholder: \"请输入消息...\",\n disclaimer: \"内容由 AI 生成,仅供参考\",\n },\n message: {\n copy: \"复制\",\n copied: \"已复制\",\n copyToClipboard: \"复制\",\n paused: \"已暂停生成\",\n },\n};\n\nexport type Locale = typeof zhCN;\nexport type LocaleComponentName = keyof Locale;\n","import type { Locale } from \".\";\n\nexport const en: Locale = {\n chat: {\n emptyTitle: \"How can I help you?\",\n },\n input: {\n placeholder: \"Type your message...\",\n disclaimer: \"AI-generated content, for reference only\",\n },\n message: {\n copy: \"Copy\",\n copied: \"Copied!\",\n copyToClipboard: \"Copy to clipboard\",\n paused: \"Generation paused\",\n },\n};\n","import type { Locale, LocaleComponentName } from \"./zh-cn\";\nimport { zhCN } from \"./zh-cn\";\nimport { en } from \"./en\";\n\nexport { Locale, LocaleComponentName };\n\nexport const locales = {\n \"zh-CN\": zhCN,\n \"en-US\": en,\n};\n\nexport type LocaleCode = keyof typeof locales;\n","import {\n Attachment,\n AttachmentPreview,\n AttachmentRemove,\n Attachments,\n} from \"@/components/ai-elements/attachments\";\nimport {\n PromptInput,\n PromptInputBody,\n PromptInputFooter,\n type PromptInputMessage,\n PromptInputProvider,\n PromptInputSubmit,\n PromptInputTextarea,\n PromptInputTools,\n usePromptInputAttachments,\n} from \"@/components/ai-elements/prompt-input\";\nimport { useLocale } from \"@/locales\";\n\nexport interface InputProps {\n onSend?: (message: PromptInputMessage) => void;\n onStop?: () => void;\n placeholder?: string;\n streaming?: boolean;\n}\n\nconst PromptInputAttachmentsDisplay = () => {\n const attachments = usePromptInputAttachments();\n\n if (attachments.files.length === 0) {\n return null;\n }\n\n return (\n <Attachments variant=\"inline\">\n {attachments.files.map((attachment) => (\n <Attachment\n data={attachment}\n key={attachment.id}\n onRemove={() => attachments.remove(attachment.id)}\n >\n <AttachmentPreview />\n <AttachmentRemove />\n </Attachment>\n ))}\n </Attachments>\n );\n};\n\nexport function Input({\n onSend,\n onStop,\n placeholder,\n streaming = false,\n}: InputProps) {\n const { locale } = useLocale(\"input\");\n const status: \"submitted\" | \"streaming\" | \"ready\" | \"error\" = streaming\n ? \"streaming\"\n : \"ready\";\n\n const handleSubmit = (message: PromptInputMessage) => {\n const text = message.text.trim();\n const hasText = Boolean(text);\n const hasAttachments = Boolean(message.files?.length);\n\n if (!(hasText || hasAttachments)) {\n return;\n }\n\n // Trigger onSend callback when submitting message\n onSend?.({\n ...message,\n text,\n });\n };\n\n return (\n <div className=\"pb-4\">\n <PromptInputProvider>\n <PromptInput globalDrop multiple onSubmit={handleSubmit}>\n <PromptInputAttachmentsDisplay />\n <PromptInputBody>\n <PromptInputTextarea\n placeholder={placeholder ?? locale.placeholder}\n />\n </PromptInputBody>\n <PromptInputFooter>\n <PromptInputTools></PromptInputTools>\n <PromptInputSubmit status={status} onStop={onStop} />\n </PromptInputFooter>\n </PromptInput>\n <div className=\"text-center text-xs opacity-50 mt-3\">\n {locale.disclaimer}\n </div>\n </PromptInputProvider>\n </div>\n );\n}\n","import { Input } from \"./Input\";\nimport { useChat } from \"@cloudbase/agent-react-core\";\nimport { ChatMessage } from \"./Message\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { LocaleContext, type LocaleCode, useLocale } from \"@/locales\";\nimport { useMemo } from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport { Suggestion, Suggestions } from \"@/components/ai-elements/suggestion\";\n\nexport interface AgKitUIProps {\n /** Optional class name for the container */\n className?: string;\n /** Optional extra class name for the root container */\n containerClassName?: string;\n /** Optional class name for the message list container */\n messagesClassName?: string;\n /** Optional class name for the input wrapper */\n inputClassName?: string;\n /** Optional class name for the empty title */\n emptyTitleClassName?: string;\n /** Optional placeholder for the input */\n inputPlaceholder?: string;\n /** Optional suggested prompts shown above input when chat is empty */\n suggestions?: string[];\n /** Optional locale code for built-in UI copy */\n locale?: LocaleCode;\n /** Optional callback when a suggestion is clicked */\n onSuggestionClick?: (suggestion: string) => void;\n}\n\nexport function AgKitUI({\n className = \"h-full min-h-0 mx-auto max-w-225 flex flex-col overflow-hidden px-4\",\n containerClassName,\n messagesClassName,\n inputClassName,\n emptyTitleClassName,\n inputPlaceholder,\n suggestions,\n onSuggestionClick,\n locale = \"zh-CN\",\n}: AgKitUIProps) {\n const contextValue = useMemo(() => ({ locale }), [locale]);\n\n return (\n <LocaleContext.Provider value={contextValue}>\n <AgKitUIContent\n className={className}\n containerClassName={containerClassName}\n messagesClassName={messagesClassName}\n inputClassName={inputClassName}\n emptyTitleClassName={emptyTitleClassName}\n inputPlaceholder={inputPlaceholder}\n suggestions={suggestions}\n onSuggestionClick={onSuggestionClick}\n />\n </LocaleContext.Provider>\n );\n}\n\ninterface AgKitUIContentProps {\n className?: string;\n containerClassName?: string;\n messagesClassName?: string;\n inputClassName?: string;\n emptyTitleClassName?: string;\n inputPlaceholder?: string;\n suggestions?: string[];\n onSuggestionClick?: (suggestion: string) => void;\n}\n\nfunction AgKitUIContent({\n className,\n containerClassName,\n messagesClassName,\n inputClassName,\n emptyTitleClassName,\n inputPlaceholder,\n suggestions,\n onSuggestionClick,\n}: AgKitUIContentProps) {\n const { locale } = useLocale(\"chat\");\n const { uiMessages, streaming, sendMessage, actions, abort } = useChat();\n\n // Handle tool response\n const handleRespond = (toolCallId: string, result: string) => {\n sendMessage({\n id: uuidv4(),\n role: \"tool\",\n content: result,\n toolCallId,\n });\n };\n\n const visibleMessages = uiMessages.filter(\n (message) => message.role === \"user\" || message.role === \"assistant\"\n );\n const isEmpty = visibleMessages.length === 0;\n\n const inputNode = (\n <div className={inputClassName}>\n {isEmpty && suggestions && suggestions.length > 0 && (\n <Suggestions className=\"mb-3\">\n {suggestions\n .map((suggestion) => suggestion.trim())\n .filter(Boolean)\n .map((suggestion, index) => (\n <Suggestion\n key={`${suggestion}-${index}`}\n suggestion={suggestion}\n variant=\"ghost\"\n className=\"max-w-full border border-border/80 text-muted-foreground\"\n disabled={streaming}\n onClick={(value) => {\n onSuggestionClick?.(value);\n sendMessage(value);\n }}\n />\n ))}\n </Suggestions>\n )}\n <Input\n placeholder={inputPlaceholder}\n streaming={streaming}\n onStop={() => {\n if (!streaming) return;\n abort();\n }}\n onSend={(message) => {\n sendMessage(message.text);\n }}\n />\n </div>\n );\n\n return (\n <div\n className={cn(\n \"bg-background text-foreground h-full min-h-0 w-full\",\n containerClassName\n )}\n >\n <div className={cn(className)}>\n {isEmpty ? (\n <div className=\"flex min-h-0 flex-1 items-center justify-center\">\n <div className=\"w-full\">\n <div\n className={cn(\n \"mb-5 text-center text-xl font-medium text-foreground\",\n emptyTitleClassName\n )}\n >\n {locale.emptyTitle}\n </div>\n {inputNode}\n </div>\n </div>\n ) : (\n <>\n <div\n className={cn(\n \"min-h-0 flex-1 overflow-y-auto py-4\",\n messagesClassName\n )}\n >\n <ChatMessage\n messages={uiMessages}\n isLoading={streaming}\n actions={actions}\n onRespond={handleRespond}\n />\n </div>\n {inputNode}\n </>\n )}\n </div>\n </div>\n );\n}\n","import { cva, type VariantProps } from \"class-variance-authority\";\nimport { Slot } from \"radix-ui\";\n\nimport { cn } from \"@/lib/utils\";\nimport { Separator } from \"@/components/ui/separator\";\n\nconst buttonGroupVariants = cva(\n \"flex w-fit items-stretch [&>*]:focus-visible:z-10 [&>*]:focus-visible:relative [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md has-[>[data-slot=button-group]]:gap-2\",\n {\n variants: {\n orientation: {\n horizontal:\n \"[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none\",\n vertical:\n \"flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none\",\n },\n },\n defaultVariants: {\n orientation: \"horizontal\",\n },\n }\n);\n\nfunction ButtonGroup({\n className,\n orientation,\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof buttonGroupVariants>) {\n return (\n <div\n role=\"group\"\n data-slot=\"button-group\"\n data-orientation={orientation}\n className={cn(buttonGroupVariants({ orientation }), className)}\n {...props}\n />\n );\n}\n\nfunction ButtonGroupText({\n className,\n asChild = false,\n ...props\n}: React.ComponentProps<\"div\"> & {\n asChild?: boolean;\n}) {\n const Comp = asChild ? Slot.Root : \"div\";\n\n return (\n <Comp\n className={cn(\n \"bg-muted flex items-center gap-2 rounded-md border px-4 text-sm font-medium shadow-xs [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction ButtonGroupSeparator({\n className,\n orientation = \"vertical\",\n ...props\n}: React.ComponentProps<typeof Separator>) {\n return (\n <Separator\n data-slot=\"button-group-separator\"\n orientation={orientation}\n className={cn(\n \"bg-input relative !m-0 self-stretch data-[orientation=vertical]:h-auto\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport {\n ButtonGroup,\n ButtonGroupSeparator,\n ButtonGroupText,\n buttonGroupVariants,\n};\n","\"use client\";\n\nimport * as React from \"react\";\nimport { Separator as SeparatorPrimitive } from \"radix-ui\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction Separator({\n className,\n orientation = \"horizontal\",\n decorative = true,\n ...props\n}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {\n return (\n <SeparatorPrimitive.Root\n data-slot=\"separator\"\n decorative={decorative}\n orientation={orientation}\n className={cn(\n \"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport { Separator };\n","\"use client\";\n\nimport * as React from \"react\";\nimport { Tooltip as TooltipPrimitive } from \"radix-ui\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction TooltipProvider({\n delayDuration = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delayDuration={delayDuration}\n {...props}\n />\n );\n}\n\nfunction Tooltip({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n return (\n <TooltipProvider>\n <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n </TooltipProvider>\n );\n}\n\nfunction TooltipTrigger({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />;\n}\n\nfunction TooltipContent({\n className,\n sideOffset = 0,\n children,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n \"bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance\",\n className\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]\" />\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n );\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };\n","\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { ButtonGroup, ButtonGroupText } from \"@/components/ui/button-group\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { cn } from \"@/lib/utils\";\nimport { cjk } from \"@streamdown/cjk\";\nimport { code } from \"@streamdown/code\";\nimport { math } from \"@streamdown/math\";\nimport { mermaid } from \"@streamdown/mermaid\";\nimport type { UIMessage } from \"ai\";\nimport { ChevronLeftIcon, ChevronRightIcon } from \"lucide-react\";\nimport type { ComponentProps, HTMLAttributes, ReactElement } from \"react\";\nimport { createContext, memo, useContext, useEffect, useState } from \"react\";\nimport { Streamdown } from \"streamdown\";\n\nexport type MessageProps = HTMLAttributes<HTMLDivElement> & {\n from: UIMessage[\"role\"];\n};\n\nexport const Message = ({ className, from, ...props }: MessageProps) => (\n <div\n className={cn(\n \"group flex w-full max-w-[95%] flex-col gap-2\",\n from === \"user\" ? \"is-user ml-auto justify-end\" : \"is-assistant\",\n className\n )}\n {...props}\n />\n);\n\nexport type MessageContentProps = HTMLAttributes<HTMLDivElement>;\n\nexport const MessageContent = ({\n children,\n className,\n ...props\n}: MessageContentProps) => (\n <div\n className={cn(\n \"is-user:dark flex w-fit min-w-0 max-w-full flex-col gap-2 overflow-hidden text-sm\",\n \"group-[.is-user]:ml-auto group-[.is-user]:rounded-lg group-[.is-user]:bg-secondary group-[.is-user]:px-4 group-[.is-user]:py-3 group-[.is-user]:text-foreground\",\n \"group-[.is-assistant]:text-foreground\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n);\n\nexport type MessageActionsProps = ComponentProps<\"div\">;\n\nexport const MessageActions = ({\n className,\n children,\n ...props\n}: MessageActionsProps) => (\n <div className={cn(\"flex items-center gap-1\", className)} {...props}>\n {children}\n </div>\n);\n\nexport type MessageActionProps = ComponentProps<typeof Button> & {\n tooltip?: string;\n label?: string;\n};\n\nexport const MessageAction = ({\n tooltip,\n children,\n label,\n variant = \"ghost\",\n size = \"icon-sm\",\n ...props\n}: MessageActionProps) => {\n const button = (\n <Button size={size} type=\"button\" variant={variant} {...props}>\n {children}\n <span className=\"sr-only\">{label || tooltip}</span>\n </Button>\n );\n\n if (tooltip) {\n return (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>{button}</TooltipTrigger>\n <TooltipContent>\n <p>{tooltip}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n }\n\n return button;\n};\n\ninterface MessageBranchContextType {\n currentBranch: number;\n totalBranches: number;\n goToPrevious: () => void;\n goToNext: () => void;\n branches: ReactElement[];\n setBranches: (branches: ReactElement[]) => void;\n}\n\nconst MessageBranchContext = createContext<MessageBranchContextType | null>(\n null\n);\n\nconst useMessageBranch = () => {\n const context = useContext(MessageBranchContext);\n\n if (!context) {\n throw new Error(\n \"MessageBranch components must be used within MessageBranch\"\n );\n }\n\n return context;\n};\n\nexport type MessageBranchProps = HTMLAttributes<HTMLDivElement> & {\n defaultBranch?: number;\n onBranchChange?: (branchIndex: number) => void;\n};\n\nexport const MessageBranch = ({\n defaultBranch = 0,\n onBranchChange,\n className,\n ...props\n}: MessageBranchProps) => {\n const [currentBranch, setCurrentBranch] = useState(defaultBranch);\n const [branches, setBranches] = useState<ReactElement[]>([]);\n\n const handleBranchChange = (newBranch: number) => {\n setCurrentBranch(newBranch);\n onBranchChange?.(newBranch);\n };\n\n const goToPrevious = () => {\n const newBranch =\n currentBranch > 0 ? currentBranch - 1 : branches.length - 1;\n handleBranchChange(newBranch);\n };\n\n const goToNext = () => {\n const newBranch =\n currentBranch < branches.length - 1 ? currentBranch + 1 : 0;\n handleBranchChange(newBranch);\n };\n\n const contextValue: MessageBranchContextType = {\n currentBranch,\n totalBranches: branches.length,\n goToPrevious,\n goToNext,\n branches,\n setBranches,\n };\n\n return (\n <MessageBranchContext.Provider value={contextValue}>\n <div\n className={cn(\"grid w-full gap-2 [&>div]:pb-0\", className)}\n {...props}\n />\n </MessageBranchContext.Provider>\n );\n};\n\nexport type MessageBranchContentProps = HTMLAttributes<HTMLDivElement>;\n\nexport const MessageBranchContent = ({\n children,\n ...props\n}: MessageBranchContentProps) => {\n const { currentBranch, setBranches, branches } = useMessageBranch();\n const childrenArray = Array.isArray(children) ? children : [children];\n\n // Use useEffect to update branches when they change\n useEffect(() => {\n if (branches.length !== childrenArray.length) {\n setBranches(childrenArray);\n }\n }, [childrenArray, branches, setBranches]);\n\n return childrenArray.map((branch, index) => (\n <div\n className={cn(\n \"grid gap-2 overflow-hidden [&>div]:pb-0\",\n index === currentBranch ? \"block\" : \"hidden\"\n )}\n key={branch.key}\n {...props}\n >\n {branch}\n </div>\n ));\n};\n\nexport type MessageBranchSelectorProps = HTMLAttributes<HTMLDivElement> & {\n from: UIMessage[\"role\"];\n};\n\nexport const MessageBranchSelector = ({\n className,\n from,\n ...props\n}: MessageBranchSelectorProps) => {\n const { totalBranches } = useMessageBranch();\n\n // Don't render if there's only one branch\n if (totalBranches <= 1) {\n return null;\n }\n\n return (\n <ButtonGroup\n className=\"[&>*:not(:first-child)]:rounded-l-md [&>*:not(:last-child)]:rounded-r-md\"\n orientation=\"horizontal\"\n {...props}\n />\n );\n};\n\nexport type MessageBranchPreviousProps = ComponentProps<typeof Button>;\n\nexport const MessageBranchPrevious = ({\n children,\n ...props\n}: MessageBranchPreviousProps) => {\n const { goToPrevious, totalBranches } = useMessageBranch();\n\n return (\n <Button\n aria-label=\"Previous branch\"\n disabled={totalBranches <= 1}\n onClick={goToPrevious}\n size=\"icon-sm\"\n type=\"button\"\n variant=\"ghost\"\n {...props}\n >\n {children ?? <ChevronLeftIcon size={14} />}\n </Button>\n );\n};\n\nexport type MessageBranchNextProps = ComponentProps<typeof Button>;\n\nexport const MessageBranchNext = ({\n children,\n ...props\n}: MessageBranchNextProps) => {\n const { goToNext, totalBranches } = useMessageBranch();\n\n return (\n <Button\n aria-label=\"Next branch\"\n disabled={totalBranches <= 1}\n onClick={goToNext}\n size=\"icon-sm\"\n type=\"button\"\n variant=\"ghost\"\n {...props}\n >\n {children ?? <ChevronRightIcon size={14} />}\n </Button>\n );\n};\n\nexport type MessageBranchPageProps = HTMLAttributes<HTMLSpanElement>;\n\nexport const MessageBranchPage = ({\n className,\n ...props\n}: MessageBranchPageProps) => {\n const { currentBranch, totalBranches } = useMessageBranch();\n\n return (\n <ButtonGroupText\n className={cn(\n \"border-none bg-transparent text-muted-foreground shadow-none\",\n className\n )}\n {...props}\n >\n {currentBranch + 1} of {totalBranches}\n </ButtonGroupText>\n );\n};\n\nexport type MessageResponseProps = ComponentProps<typeof Streamdown>;\n\nexport const MessageResponse = memo(\n ({ className, ...props }: MessageResponseProps) => (\n <Streamdown\n className={cn(\n \"size-full [&>*:first-child]:mt-0 [&>*:last-child]:mb-0\",\n className\n )}\n plugins={{ code, mermaid, math, cjk }}\n {...props}\n />\n ),\n (prevProps, nextProps) => prevProps.children === nextProps.children\n);\n\nMessageResponse.displayName = \"MessageResponse\";\n\nexport type MessageToolbarProps = ComponentProps<\"div\">;\n\nexport const MessageToolbar = ({\n className,\n children,\n ...props\n}: MessageToolbarProps) => (\n <div\n className={cn(\n \"mt-4 flex w-full items-center justify-between gap-4\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n);\n","import * as React from \"react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { Slot } from \"radix-ui\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst badgeVariants = cva(\n \"inline-flex items-center justify-center rounded-full border border-transparent px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground [a&]:hover:bg-primary/90\",\n secondary:\n \"bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90\",\n destructive:\n \"bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n outline:\n \"border-border text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground\",\n ghost: \"[a&]:hover:bg-accent [a&]:hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 [a&]:hover:underline\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n);\n\nfunction Badge({\n className,\n variant = \"default\",\n asChild = false,\n ...props\n}: React.ComponentProps<\"span\"> &\n VariantProps<typeof badgeVariants> & { asChild?: boolean }) {\n const Comp = asChild ? Slot.Root : \"span\";\n\n return (\n <Comp\n data-slot=\"badge\"\n data-variant={variant}\n className={cn(badgeVariants({ variant }), className)}\n {...props}\n />\n );\n}\n\nexport { Badge, badgeVariants };\n","import { Collapsible as CollapsiblePrimitive } from \"radix-ui\";\n\nfunction Collapsible({\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />;\n}\n\nfunction CollapsibleTrigger({\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n return (\n <CollapsiblePrimitive.CollapsibleTrigger\n data-slot=\"collapsible-trigger\"\n {...props}\n />\n );\n}\n\nfunction CollapsibleContent({\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n return (\n <CollapsiblePrimitive.CollapsibleContent\n data-slot=\"collapsible-content\"\n {...props}\n />\n );\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent };\n","\"use client\";\n\nimport { Badge } from \"@/components/ui/badge\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@/components/ui/collapsible\";\nimport { cn } from \"@/lib/utils\";\nimport type { DynamicToolUIPart, ToolUIPart } from \"ai\";\nimport {\n CheckCircleIcon,\n ChevronDownIcon,\n CircleIcon,\n ClockIcon,\n WrenchIcon,\n XCircleIcon,\n} from \"lucide-react\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport { isValidElement } from \"react\";\nimport { CodeBlock } from \"./code-block\";\n\nexport type ToolProps = ComponentProps<typeof Collapsible>;\n\nexport const Tool = ({ className, ...props }: ToolProps) => (\n <Collapsible\n className={cn(\"group not-prose mb-4 w-full rounded-md border\", className)}\n {...props}\n />\n);\n\nexport type ToolPart = ToolUIPart | DynamicToolUIPart;\n\nexport type ToolHeaderProps = {\n title?: string;\n className?: string;\n} & (\n | { type: ToolUIPart[\"type\"]; state: ToolUIPart[\"state\"]; toolName?: never }\n | {\n type: DynamicToolUIPart[\"type\"];\n state: DynamicToolUIPart[\"state\"];\n toolName: string;\n }\n);\n\nexport const getStatusBadge = (status: ToolPart[\"state\"]) => {\n const labels: Record<ToolPart[\"state\"], string> = {\n \"input-streaming\": \"Pending\",\n \"input-available\": \"Running\",\n \"approval-requested\": \"Awaiting Approval\",\n \"approval-responded\": \"Responded\",\n \"output-available\": \"Completed\",\n \"output-error\": \"Error\",\n \"output-denied\": \"Denied\",\n };\n\n const icons: Record<ToolPart[\"state\"], ReactNode> = {\n \"input-streaming\": <CircleIcon className=\"size-4\" />,\n \"input-available\": <ClockIcon className=\"size-4 animate-pulse\" />,\n \"approval-requested\": <ClockIcon className=\"size-4 text-yellow-600\" />,\n \"approval-responded\": <CheckCircleIcon className=\"size-4 text-blue-600\" />,\n \"output-available\": <CheckCircleIcon className=\"size-4 text-green-600\" />,\n \"output-error\": <XCircleIcon className=\"size-4 text-red-600\" />,\n \"output-denied\": <XCircleIcon className=\"size-4 text-orange-600\" />,\n };\n\n return (\n <Badge className=\"gap-1.5 rounded-full text-xs\" variant=\"secondary\">\n {icons[status]}\n {labels[status]}\n </Badge>\n );\n};\n\nexport const ToolHeader = ({\n className,\n title,\n type,\n state,\n toolName,\n ...props\n}: ToolHeaderProps) => {\n const derivedName =\n type === \"dynamic-tool\" ? toolName : type.split(\"-\").slice(1).join(\"-\");\n\n return (\n <CollapsibleTrigger\n className={cn(\n \"flex w-full items-center justify-between gap-4 p-3\",\n className\n )}\n {...props}\n >\n <div className=\"flex items-center gap-2\">\n <WrenchIcon className=\"size-4 text-muted-foreground\" />\n <span className=\"font-medium text-sm\">{title ?? derivedName}</span>\n {getStatusBadge(state)}\n </div>\n <ChevronDownIcon className=\"size-4 text-muted-foreground transition-transform group-data-[state=open]:rotate-180\" />\n </CollapsibleTrigger>\n );\n};\n\nexport type ToolContentProps = ComponentProps<typeof CollapsibleContent>;\n\nexport const ToolContent = ({ className, ...props }: ToolContentProps) => (\n <CollapsibleContent\n className={cn(\n \"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 space-y-4 p-4 text-popover-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in\",\n className\n )}\n {...props}\n />\n);\n\nexport type ToolInputProps = ComponentProps<\"div\"> & {\n input: ToolPart[\"input\"];\n};\n\nexport const ToolInput = ({ className, input, ...props }: ToolInputProps) => (\n <div className={cn(\"space-y-2 overflow-hidden\", className)} {...props}>\n <h4 className=\"font-medium text-muted-foreground text-xs uppercase tracking-wide\">\n Parameters\n </h4>\n <div className=\"rounded-md bg-muted/50\">\n <CodeBlock code={JSON.stringify(input, null, 2)} language=\"json\" />\n </div>\n </div>\n);\n\nexport type ToolOutputProps = ComponentProps<\"div\"> & {\n output: ToolPart[\"output\"];\n errorText: ToolPart[\"errorText\"];\n};\n\nexport const ToolOutput = ({\n className,\n output,\n errorText,\n ...props\n}: ToolOutputProps) => {\n if (!(output || errorText)) {\n return null;\n }\n\n let Output = <div>{output as ReactNode}</div>;\n\n if (typeof output === \"object\" && !isValidElement(output)) {\n Output = (\n <CodeBlock code={JSON.stringify(output, null, 2)} language=\"json\" />\n );\n } else if (typeof output === \"string\") {\n Output = <CodeBlock code={output} language=\"json\" />;\n }\n\n return (\n <div className={cn(\"space-y-2\", className)} {...props}>\n <h4 className=\"font-medium text-muted-foreground text-xs uppercase tracking-wide\">\n {errorText ? \"Error\" : \"Result\"}\n </h4>\n <div\n className={cn(\n \"overflow-x-auto rounded-md text-xs [&_table]:w-full\",\n errorText\n ? \"bg-destructive/10 text-destructive\"\n : \"bg-muted/50 text-foreground\"\n )}\n >\n {errorText && <div>{errorText}</div>}\n {Output}\n </div>\n </div>\n );\n};\n","\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@/components/ui/select\";\nimport { cn } from \"@/lib/utils\";\nimport { CheckIcon, CopyIcon } from \"lucide-react\";\nimport {\n type ComponentProps,\n type CSSProperties,\n createContext,\n type HTMLAttributes,\n memo,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n type BundledLanguage,\n type BundledTheme,\n createHighlighter,\n type HighlighterGeneric,\n type ThemedToken,\n} from \"shiki\";\n\n// Shiki uses bitflags for font styles: 1=italic, 2=bold, 4=underline\n// biome-ignore lint/suspicious/noBitwiseOperators: shiki bitflag check\nconst isItalic = (fontStyle: number | undefined) => fontStyle && fontStyle & 1;\n// biome-ignore lint/suspicious/noBitwiseOperators: shiki bitflag check\nconst isBold = (fontStyle: number | undefined) => fontStyle && fontStyle & 2;\nconst isUnderline = (fontStyle: number | undefined) =>\n // biome-ignore lint/suspicious/noBitwiseOperators: shiki bitflag check\n fontStyle && fontStyle & 4;\n\n// Transform tokens to include pre-computed keys to avoid noArrayIndexKey lint\ninterface KeyedToken {\n token: ThemedToken;\n key: string;\n}\ninterface KeyedLine {\n tokens: KeyedToken[];\n key: string;\n}\n\nconst addKeysToTokens = (lines: ThemedToken[][]): KeyedLine[] =>\n lines.map((line, lineIdx) => ({\n key: `line-${lineIdx}`,\n tokens: line.map((token, tokenIdx) => ({\n token,\n key: `line-${lineIdx}-${tokenIdx}`,\n })),\n }));\n\n// Token rendering component\nconst TokenSpan = ({ token }: { token: ThemedToken }) => (\n <span\n className=\"dark:!bg-[var(--shiki-dark-bg)] dark:!text-[var(--shiki-dark)]\"\n style={\n {\n color: token.color,\n backgroundColor: token.bgColor,\n ...token.htmlStyle,\n fontStyle: isItalic(token.fontStyle) ? \"italic\" : undefined,\n fontWeight: isBold(token.fontStyle) ? \"bold\" : undefined,\n textDecoration: isUnderline(token.fontStyle) ? \"underline\" : undefined,\n } as CSSProperties\n }\n >\n {token.content}\n </span>\n);\n\n// Line rendering component\nconst LineSpan = ({\n keyedLine,\n showLineNumbers,\n}: {\n keyedLine: KeyedLine;\n showLineNumbers: boolean;\n}) => (\n <span className={showLineNumbers ? LINE_NUMBER_CLASSES : \"block\"}>\n {keyedLine.tokens.length === 0\n ? \"\\n\"\n : keyedLine.tokens.map(({ token, key }) => (\n <TokenSpan key={key} token={token} />\n ))}\n </span>\n);\n\n// Types\ntype CodeBlockProps = HTMLAttributes<HTMLDivElement> & {\n code: string;\n language: BundledLanguage;\n showLineNumbers?: boolean;\n};\n\ninterface TokenizedCode {\n tokens: ThemedToken[][];\n fg: string;\n bg: string;\n}\n\ninterface CodeBlockContextType {\n code: string;\n}\n\n// Context\nconst CodeBlockContext = createContext<CodeBlockContextType>({\n code: \"\",\n});\n\n// Highlighter cache (singleton per language)\nconst highlighterCache = new Map<\n string,\n Promise<HighlighterGeneric<BundledLanguage, BundledTheme>>\n>();\n\n// Token cache\nconst tokensCache = new Map<string, TokenizedCode>();\n\n// Subscribers for async token updates\nconst subscribers = new Map<string, Set<(result: TokenizedCode) => void>>();\n\nconst getTokensCacheKey = (code: string, language: BundledLanguage) => {\n const start = code.slice(0, 100);\n const end = code.length > 100 ? code.slice(-100) : \"\";\n return `${language}:${code.length}:${start}:${end}`;\n};\n\nconst getHighlighter = (\n language: BundledLanguage\n): Promise<HighlighterGeneric<BundledLanguage, BundledTheme>> => {\n const cached = highlighterCache.get(language);\n if (cached) {\n return cached;\n }\n\n const highlighterPromise = createHighlighter({\n themes: [\"github-light\", \"github-dark\"],\n langs: [language],\n });\n\n highlighterCache.set(language, highlighterPromise);\n return highlighterPromise;\n};\n\n// Create raw tokens for immediate display while highlighting loads\nconst createRawTokens = (code: string): TokenizedCode => ({\n tokens: code.split(\"\\n\").map((line) =>\n line === \"\"\n ? []\n : [\n {\n content: line,\n color: \"inherit\",\n } as ThemedToken,\n ]\n ),\n fg: \"inherit\",\n bg: \"transparent\",\n});\n\n// Synchronous highlight with callback for async results\nexport function highlightCode(\n code: string,\n language: BundledLanguage,\n callback?: (result: TokenizedCode) => void\n): TokenizedCode | null {\n const tokensCacheKey = getTokensCacheKey(code, language);\n\n // Return cached result if available\n const cached = tokensCache.get(tokensCacheKey);\n if (cached) {\n return cached;\n }\n\n // Subscribe callback if provided\n if (callback) {\n if (!subscribers.has(tokensCacheKey)) {\n subscribers.set(tokensCacheKey, new Set());\n }\n subscribers.get(tokensCacheKey)?.add(callback);\n }\n\n // Start highlighting in background\n getHighlighter(language)\n .then((highlighter) => {\n const availableLangs = highlighter.getLoadedLanguages();\n const langToUse = availableLangs.includes(language) ? language : \"text\";\n\n const result = highlighter.codeToTokens(code, {\n lang: langToUse,\n themes: {\n light: \"github-light\",\n dark: \"github-dark\",\n },\n });\n\n const tokenized: TokenizedCode = {\n tokens: result.tokens,\n fg: result.fg ?? \"inherit\",\n bg: result.bg ?? \"transparent\",\n };\n\n // Cache the result\n tokensCache.set(tokensCacheKey, tokenized);\n\n // Notify all subscribers\n const subs = subscribers.get(tokensCacheKey);\n if (subs) {\n for (const sub of subs) {\n sub(tokenized);\n }\n subscribers.delete(tokensCacheKey);\n }\n })\n .catch((error) => {\n console.error(\"Failed to highlight code:\", error);\n subscribers.delete(tokensCacheKey);\n });\n\n return null;\n}\n\n// Line number styles using CSS counters\nconst LINE_NUMBER_CLASSES = cn(\n \"block\",\n \"before:content-[counter(line)]\",\n \"before:inline-block\",\n \"before:[counter-increment:line]\",\n \"before:w-8\",\n \"before:mr-4\",\n \"before:text-right\",\n \"before:text-muted-foreground/50\",\n \"before:font-mono\",\n \"before:select-none\"\n);\n\nconst CodeBlockBody = memo(\n ({\n tokenized,\n showLineNumbers,\n className,\n }: {\n tokenized: TokenizedCode;\n showLineNumbers: boolean;\n className?: string;\n }) => {\n const preStyle = useMemo(\n () => ({\n backgroundColor: tokenized.bg,\n color: tokenized.fg,\n }),\n [tokenized.bg, tokenized.fg]\n );\n\n const keyedLines = useMemo(\n () => addKeysToTokens(tokenized.tokens),\n [tokenized.tokens]\n );\n\n return (\n <pre\n className={cn(\n \"dark:!bg-[var(--shiki-dark-bg)] dark:!text-[var(--shiki-dark)] m-0 p-4 text-sm\",\n className\n )}\n style={preStyle}\n >\n <code\n className={cn(\n \"font-mono text-sm\",\n showLineNumbers && \"[counter-increment:line_0] [counter-reset:line]\"\n )}\n >\n {keyedLines.map((keyedLine) => (\n <LineSpan\n key={keyedLine.key}\n keyedLine={keyedLine}\n showLineNumbers={showLineNumbers}\n />\n ))}\n </code>\n </pre>\n );\n },\n (prevProps, nextProps) =>\n prevProps.tokenized === nextProps.tokenized &&\n prevProps.showLineNumbers === nextProps.showLineNumbers &&\n prevProps.className === nextProps.className\n);\n\nexport const CodeBlockContainer = ({\n className,\n language,\n style,\n ...props\n}: HTMLAttributes<HTMLDivElement> & { language: string }) => (\n <div\n className={cn(\n \"group relative w-full overflow-hidden rounded-md border bg-background text-foreground\",\n className\n )}\n data-language={language}\n style={{\n contentVisibility: \"auto\",\n containIntrinsicSize: \"auto 200px\",\n ...style,\n }}\n {...props}\n />\n);\n\nexport const CodeBlockHeader = ({\n children,\n className,\n ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex items-center justify-between border-b bg-muted/80 px-3 py-2 text-muted-foreground text-xs\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n);\n\nexport const CodeBlockTitle = ({\n children,\n className,\n ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n <div className={cn(\"flex items-center gap-2\", className)} {...props}>\n {children}\n </div>\n);\n\nexport const CodeBlockFilename = ({\n children,\n className,\n ...props\n}: HTMLAttributes<HTMLSpanElement>) => (\n <span className={cn(\"font-mono\", className)} {...props}>\n {children}\n </span>\n);\n\nexport const CodeBlockActions = ({\n children,\n className,\n ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\"-my-1 -mr-1 flex items-center gap-2\", className)}\n {...props}\n >\n {children}\n </div>\n);\n\nexport const CodeBlockContent = ({\n code,\n language,\n showLineNumbers = false,\n}: {\n code: string;\n language: BundledLanguage;\n showLineNumbers?: boolean;\n}) => {\n // Memoized raw tokens for immediate display\n const rawTokens = useMemo(() => createRawTokens(code), [code]);\n\n // Try to get cached result synchronously, otherwise use raw tokens\n const [tokenized, setTokenized] = useState<TokenizedCode>(\n () => highlightCode(code, language) ?? rawTokens\n );\n\n useEffect(() => {\n // Reset to raw tokens when code changes (shows current code, not stale tokens)\n setTokenized(highlightCode(code, language) ?? rawTokens);\n\n // Subscribe to async highlighting result\n highlightCode(code, language, setTokenized);\n }, [code, language, rawTokens]);\n\n return (\n <div className=\"relative overflow-auto\">\n <CodeBlockBody showLineNumbers={showLineNumbers} tokenized={tokenized} />\n </div>\n );\n};\n\nexport const CodeBlock = ({\n code,\n language,\n showLineNumbers = false,\n className,\n children,\n ...props\n}: CodeBlockProps) => (\n <CodeBlockContext.Provider value={{ code }}>\n <CodeBlockContainer className={className} language={language} {...props}>\n {children}\n <CodeBlockContent\n code={code}\n language={language}\n showLineNumbers={showLineNumbers}\n />\n </CodeBlockContainer>\n </CodeBlockContext.Provider>\n);\n\nexport type CodeBlockCopyButtonProps = ComponentProps<typeof Button> & {\n onCopy?: () => void;\n onError?: (error: Error) => void;\n timeout?: number;\n};\n\nexport const CodeBlockCopyButton = ({\n onCopy,\n onError,\n timeout = 2000,\n children,\n className,\n ...props\n}: CodeBlockCopyButtonProps) => {\n const [isCopied, setIsCopied] = useState(false);\n const timeoutRef = useRef<number>(0);\n const { code } = useContext(CodeBlockContext);\n\n const copyToClipboard = async () => {\n if (typeof window === \"undefined\" || !navigator?.clipboard?.writeText) {\n onError?.(new Error(\"Clipboard API not available\"));\n return;\n }\n\n try {\n if (!isCopied) {\n await navigator.clipboard.writeText(code);\n setIsCopied(true);\n onCopy?.();\n timeoutRef.current = window.setTimeout(\n () => setIsCopied(false),\n timeout\n );\n }\n } catch (error) {\n onError?.(error as Error);\n }\n };\n\n useEffect(\n () => () => {\n window.clearTimeout(timeoutRef.current);\n },\n []\n );\n\n const Icon = isCopied ? CheckIcon : CopyIcon;\n\n return (\n <Button\n className={cn(\"shrink-0\", className)}\n onClick={copyToClipboard}\n size=\"icon\"\n variant=\"ghost\"\n {...props}\n >\n {children ?? <Icon size={14} />}\n </Button>\n );\n};\n\nexport type CodeBlockLanguageSelectorProps = ComponentProps<typeof Select>;\n\nexport const CodeBlockLanguageSelector = (\n props: CodeBlockLanguageSelectorProps\n) => <Select {...props} />;\n\nexport type CodeBlockLanguageSelectorTriggerProps = ComponentProps<\n typeof SelectTrigger\n>;\n\nexport const CodeBlockLanguageSelectorTrigger = ({\n className,\n ...props\n}: CodeBlockLanguageSelectorTriggerProps) => (\n <SelectTrigger\n className={cn(\n \"h-7 border-none bg-transparent px-2 text-xs shadow-none\",\n className\n )}\n size=\"sm\"\n {...props}\n />\n);\n\nexport type CodeBlockLanguageSelectorValueProps = ComponentProps<\n typeof SelectValue\n>;\n\nexport const CodeBlockLanguageSelectorValue = (\n props: CodeBlockLanguageSelectorValueProps\n) => <SelectValue {...props} />;\n\nexport type CodeBlockLanguageSelectorContentProps = ComponentProps<\n typeof SelectContent\n>;\n\nexport const CodeBlockLanguageSelectorContent = ({\n align = \"end\",\n ...props\n}: CodeBlockLanguageSelectorContentProps) => (\n <SelectContent align={align} {...props} />\n);\n\nexport type CodeBlockLanguageSelectorItemProps = ComponentProps<\n typeof SelectItem\n>;\n\nexport const CodeBlockLanguageSelectorItem = (\n props: CodeBlockLanguageSelectorItemProps\n) => <SelectItem {...props} />;\n","import { useState } from \"react\";\n\nexport interface useCopyToClipboardProps {\n timeout?: number;\n}\n\nexport function useCopyToClipboard({\n timeout = 2000,\n}: useCopyToClipboardProps = {}) {\n const [isCopied, setIsCopied] = useState<Boolean>(false);\n\n const copyToClipboard = (value: string) => {\n if (typeof window === \"undefined\" || !navigator.clipboard?.writeText) {\n return;\n }\n\n if (!value) {\n return;\n }\n\n navigator.clipboard.writeText(value).then(() => {\n setIsCopied(true);\n\n setTimeout(() => {\n setIsCopied(false);\n }, timeout);\n });\n };\n\n return { isCopied, copyToClipboard };\n}\n","import {\n Message,\n MessageAction,\n MessageActions,\n MessageContent,\n MessageResponse,\n} from \"@/components/ai-elements/message\";\nimport {\n Tool,\n ToolContent,\n ToolHeader,\n ToolInput,\n ToolOutput,\n} from \"@/components/ai-elements/tool\";\nimport { useCopyToClipboard } from \"@/hooks/use-copy-to-clipboard\";\nimport { CheckIcon, CopyIcon } from \"lucide-react\";\nimport { memo, type ReactElement, type SVGProps } from \"react\";\nimport { type UIMessage, type ToolPart, type Action } from \"@cloudbase/agent-react-core\";\nimport { useLocale } from \"@/locales\";\n\ninterface CopyActionProps {\n content: string;\n}\n\nconst CopyAction = memo(({ content }: CopyActionProps) => {\n const { locale } = useLocale(\"message\");\n const { isCopied, copyToClipboard } = useCopyToClipboard();\n\n return (\n <MessageAction\n label={locale.copy}\n onClick={() => copyToClipboard(content)}\n tooltip={isCopied ? locale.copied : locale.copyToClipboard}\n >\n {isCopied ? (\n <CheckIcon className=\"size-4\" />\n ) : (\n <CopyIcon className=\"size-4\" />\n )}\n </MessageAction>\n );\n});\n\nCopyAction.displayName = \"CopyAction\";\n\n// Map ToolCallStatus to Tool component state\nconst mapToolStatus = (status: ToolPart[\"status\"]) => {\n const statusMap: Record<\n ToolPart[\"status\"],\n \"input-streaming\" | \"input-available\" | \"output-available\" | \"output-error\"\n > = {\n pending: \"input-streaming\",\n ready: \"input-available\",\n executing: \"input-available\",\n completed: \"output-available\",\n failed: \"output-error\",\n };\n return statusMap[status];\n};\n\ninterface ToolCallRendererProps {\n toolPart: ToolPart;\n actions?: Record<string, Action>;\n onRespond?: (toolCallId: string, result: string) => void;\n}\n\nconst ToolCallRenderer = memo(\n ({ toolPart, actions, onRespond }: ToolCallRendererProps) => {\n // Check if there's a custom render function for this tool\n const action = actions?.[toolPart.name];\n\n if (\n action &&\n ((action.type === \"client-tool\" && action.render) ||\n action.type === \"tool-call\")\n ) {\n const respond = (result: string) => {\n onRespond?.(toolPart.toolCallId, result);\n };\n const render = action.render;\n const rendered = render?.({\n toolCall: toolPart,\n respond,\n });\n if (typeof rendered === \"string\") {\n return <div>{rendered}</div>;\n }\n return rendered as ReactElement;\n }\n\n // Default Tool component rendering\n const state = mapToolStatus(toolPart.status);\n\n return (\n <Tool>\n <ToolHeader\n type=\"dynamic-tool\"\n state={state}\n toolName={toolPart.name}\n />\n <ToolContent>\n <ToolInput input={toolPart.args} />\n {(toolPart.status === \"completed\" ||\n toolPart.status === \"failed\") && (\n <ToolOutput\n output={toolPart.result}\n errorText={toolPart.error?.message}\n />\n )}\n </ToolContent>\n </Tool>\n );\n }\n);\n\nToolCallRenderer.displayName = \"ToolCallRenderer\";\n\nexport interface ChatMessageProps {\n messages: UIMessage[];\n isLoading?: boolean;\n actions?: Record<string, Action>;\n onRespond?: (toolCallId: string, result: string) => void;\n}\n\nexport function ChatMessage({\n messages,\n isLoading = false,\n actions,\n onRespond,\n}: ChatMessageProps) {\n const { locale } = useLocale(\"message\");\n const visibleMessages = messages.filter(\n (message) => message.role === \"user\" || message.role === \"assistant\"\n );\n const lastVisibleMessage = visibleMessages[visibleMessages.length - 1];\n const shouldRenderAssistantPlaceholder =\n isLoading && (!lastVisibleMessage || lastVisibleMessage.role === \"user\");\n\n return (\n <div className=\"flex flex-col gap-4\">\n {visibleMessages.map((message) => {\n const role = message.role as \"user\" | \"assistant\";\n const isLoadingAssistantMessage =\n isLoading &&\n role === \"assistant\" &&\n message.id === lastVisibleMessage?.id;\n\n // Get all text content for copy action\n const allTextContent = message.parts\n .filter((part) => part.type === \"text\")\n .map((part) => (part as { type: \"text\"; text: string }).text)\n .join(\"\");\n const hasAssistantText =\n role === \"assistant\" && allTextContent.trim().length > 0;\n const isPausedAssistantNoText =\n role === \"assistant\" && Boolean(message.paused) && !hasAssistantText;\n const copyContent =\n allTextContent || (isPausedAssistantNoText ? locale.paused : \"\");\n\n return (\n <Message from={role} key={message.id}>\n {/* Render parts in order */}\n {message.parts.map((part) => {\n if (part.type === \"text\") {\n const textPart = part as {\n type: \"text\";\n text: string;\n id: string;\n };\n return (\n <MessageContent key={textPart.id}>\n {role === \"assistant\" ? (\n <MessageResponse>{textPart.text}</MessageResponse>\n ) : (\n textPart.text\n )}\n </MessageContent>\n );\n }\n\n if (part.type === \"tool\") {\n const toolPart = part as ToolPart;\n return (\n <ToolCallRenderer\n key={toolPart.id}\n toolPart={toolPart}\n actions={actions}\n onRespond={onRespond}\n />\n );\n }\n\n return null;\n })}\n\n {/* Loading state for the active assistant message */}\n {isLoadingAssistantMessage && (\n <MessageContent>\n <div className=\"inline-flex items-center text-muted-foreground\">\n <SvgSpinners3DotsFade className=\"text-xl\" />\n </div>\n </MessageContent>\n )}\n\n {isPausedAssistantNoText && !isLoadingAssistantMessage && (\n <MessageContent>\n <div className=\"text-muted-foreground\">{locale.paused}</div>\n </MessageContent>\n )}\n\n {/* Copy action for assistant messages with text */}\n {role === \"assistant\" &&\n copyContent &&\n !isLoadingAssistantMessage && (\n <MessageActions>\n <CopyAction content={copyContent} />\n </MessageActions>\n )}\n </Message>\n );\n })}\n\n {shouldRenderAssistantPlaceholder && (\n <Message from=\"assistant\">\n <MessageContent>\n <div className=\"inline-flex items-center text-muted-foreground\">\n <SvgSpinners3DotsFade className=\"text-xl\" />\n </div>\n </MessageContent>\n </Message>\n )}\n </div>\n );\n}\n\nexport function SvgSpinners3DotsFade(props: SVGProps<SVGSVGElement>) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"1em\"\n height=\"1em\"\n viewBox=\"0 0 24 24\"\n {...props}\n >\n <circle cx=\"4\" cy=\"12\" r=\"3\" fill=\"currentColor\">\n <animate\n id=\"dotFadeFirst\"\n fill=\"freeze\"\n attributeName=\"opacity\"\n begin=\"0;dotFadeThird.end-0.25s\"\n dur=\"0.75s\"\n values=\"1;.2\"\n />\n </circle>\n <circle cx=\"12\" cy=\"12\" r=\"3\" fill=\"currentColor\" opacity=\".4\">\n <animate\n fill=\"freeze\"\n attributeName=\"opacity\"\n begin=\"dotFadeFirst.begin+0.15s\"\n dur=\"0.75s\"\n values=\"1;.2\"\n />\n </circle>\n <circle cx=\"20\" cy=\"12\" r=\"3\" fill=\"currentColor\" opacity=\".3\">\n <animate\n id=\"dotFadeThird\"\n fill=\"freeze\"\n attributeName=\"opacity\"\n begin=\"dotFadeFirst.begin+0.3s\"\n dur=\"0.75s\"\n values=\"1;.2\"\n />\n </circle>\n </svg>\n );\n}\n","import * as React from \"react\";\nimport { ScrollArea as ScrollAreaPrimitive } from \"radix-ui\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction ScrollArea({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {\n return (\n <ScrollAreaPrimitive.Root\n data-slot=\"scroll-area\"\n className={cn(\"relative\", className)}\n {...props}\n >\n <ScrollAreaPrimitive.Viewport\n data-slot=\"scroll-area-viewport\"\n className=\"focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1\"\n >\n {children}\n </ScrollAreaPrimitive.Viewport>\n <ScrollBar />\n <ScrollAreaPrimitive.Corner />\n </ScrollAreaPrimitive.Root>\n );\n}\n\nfunction ScrollBar({\n className,\n orientation = \"vertical\",\n ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {\n return (\n <ScrollAreaPrimitive.ScrollAreaScrollbar\n data-slot=\"scroll-area-scrollbar\"\n orientation={orientation}\n className={cn(\n \"flex touch-none p-px transition-colors select-none\",\n orientation === \"vertical\" &&\n \"h-full w-2.5 border-l border-l-transparent\",\n orientation === \"horizontal\" &&\n \"h-2.5 flex-col border-t border-t-transparent\",\n className\n )}\n {...props}\n >\n <ScrollAreaPrimitive.ScrollAreaThumb\n data-slot=\"scroll-area-thumb\"\n className=\"bg-border relative flex-1 rounded-full\"\n />\n </ScrollAreaPrimitive.ScrollAreaScrollbar>\n );\n}\n\nexport { ScrollArea, ScrollBar };\n","\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { ScrollArea, ScrollBar } from \"@/components/ui/scroll-area\";\nimport { cn } from \"@/lib/utils\";\nimport type { ComponentProps } from \"react\";\n\nexport type SuggestionsProps = ComponentProps<typeof ScrollArea>;\n\nexport const Suggestions = ({\n className,\n children,\n ...props\n}: SuggestionsProps) => (\n <ScrollArea className=\"w-full overflow-x-auto whitespace-nowrap\" {...props}>\n <div className={cn(\"flex w-max flex-nowrap items-center gap-2\", className)}>\n {children}\n </div>\n <ScrollBar className=\"hidden\" orientation=\"horizontal\" />\n </ScrollArea>\n);\n\nexport type SuggestionProps = Omit<ComponentProps<typeof Button>, \"onClick\"> & {\n suggestion: string;\n onClick?: (suggestion: string) => void;\n};\n\nexport const Suggestion = ({\n suggestion,\n onClick,\n className,\n variant = \"outline\",\n size = \"sm\",\n children,\n ...props\n}: SuggestionProps) => {\n const handleClick = () => {\n onClick?.(suggestion);\n };\n\n return (\n <Button\n className={cn(\"cursor-pointer rounded-full px-4\", className)}\n onClick={handleClick}\n size={size}\n type=\"button\"\n variant={variant}\n {...props}\n >\n {children || suggestion}\n </Button>\n );\n};\n"],"mappings":"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","names":["jsx","jsx","jsx","jsx","XIcon","jsx","jsxs","jsx","jsxs","jsx","jsxs","cva","jsx","jsx","jsx","cva","jsx","CheckIcon","jsx","jsxs","jsx","ImageIcon","XIcon","createContext","useContext","useMemo","jsx","jsxs","useContext","useContext","useMemo","jsx","createContext","useMemo","jsxs","jsx","jsx","jsx","XIcon","createContext","useContext","useMemo","useContext","useMemo","jsx","jsxs","Input","cva","Slot","jsx","jsx","cva","jsx","jsxs","ChevronRightIcon","createContext","useContext","useEffect","useState","jsx","jsxs","jsx","cva","Slot","jsx","cva","Slot","jsx","ChevronDownIcon","CircleIcon","CheckIcon","createContext","memo","useContext","useEffect","useMemo","useRef","useState","jsx","jsxs","code","code","useMemo","useState","useEffect","jsx","jsxs","jsx","jsxs","CircleIcon","ChevronDownIcon","useState","CheckIcon","CopyIcon","memo","jsx","jsxs","memo","CheckIcon","CopyIcon","useMemo","jsx","jsxs","jsx","jsxs","Fragment","jsx","jsxs","useMemo","Input"]}
@@ -0,0 +1,2 @@
1
+ VITE_AGENT_ID='your-agent-id'
2
+ VITE_ENV='your-env-id'