@tetrascience-npm/tetrascience-react-ui 0.5.0-beta.39.1 → 0.5.0-beta.41.1

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 (91) hide show
  1. package/dist/components/ai/attachments.cjs +2 -0
  2. package/dist/components/ai/attachments.cjs.map +1 -0
  3. package/dist/components/ai/attachments.js +224 -0
  4. package/dist/components/ai/attachments.js.map +1 -0
  5. package/dist/components/ai/chain-of-thought.cjs +2 -0
  6. package/dist/components/ai/chain-of-thought.cjs.map +1 -0
  7. package/dist/components/ai/chain-of-thought.js +145 -0
  8. package/dist/components/ai/chain-of-thought.js.map +1 -0
  9. package/dist/components/ai/confirmation.cjs +2 -0
  10. package/dist/components/ai/confirmation.cjs.map +1 -0
  11. package/dist/components/ai/confirmation.js +109 -0
  12. package/dist/components/ai/confirmation.js.map +1 -0
  13. package/dist/components/ai/context.cjs +2 -0
  14. package/dist/components/ai/context.cjs.map +1 -0
  15. package/dist/components/ai/context.js +266 -0
  16. package/dist/components/ai/context.js.map +1 -0
  17. package/dist/components/ai/conversation.cjs +4 -0
  18. package/dist/components/ai/conversation.cjs.map +1 -0
  19. package/dist/components/ai/conversation.js +108 -0
  20. package/dist/components/ai/conversation.js.map +1 -0
  21. package/dist/components/ai/inline-citation.cjs +2 -0
  22. package/dist/components/ai/inline-citation.cjs.map +1 -0
  23. package/dist/components/ai/inline-citation.js +182 -0
  24. package/dist/components/ai/inline-citation.js.map +1 -0
  25. package/dist/components/ai/message.cjs +2 -0
  26. package/dist/components/ai/message.cjs.map +1 -0
  27. package/dist/components/ai/message.js +237 -0
  28. package/dist/components/ai/message.js.map +1 -0
  29. package/dist/components/ai/model-selector.cjs +2 -0
  30. package/dist/components/ai/model-selector.cjs.map +1 -0
  31. package/dist/components/ai/model-selector.js +77 -0
  32. package/dist/components/ai/model-selector.js.map +1 -0
  33. package/dist/components/ai/prompt-input.cjs +2 -0
  34. package/dist/components/ai/prompt-input.cjs.map +1 -0
  35. package/dist/components/ai/prompt-input.js +774 -0
  36. package/dist/components/ai/prompt-input.js.map +1 -0
  37. package/dist/components/ai/queue.cjs +2 -0
  38. package/dist/components/ai/queue.cjs.map +1 -0
  39. package/dist/components/ai/queue.js +209 -0
  40. package/dist/components/ai/queue.js.map +1 -0
  41. package/dist/components/ai/reasoning.cjs +2 -0
  42. package/dist/components/ai/reasoning.cjs.map +1 -0
  43. package/dist/components/ai/reasoning.js +129 -0
  44. package/dist/components/ai/reasoning.js.map +1 -0
  45. package/dist/components/ai/shimmer.cjs +2 -0
  46. package/dist/components/ai/shimmer.cjs.map +1 -0
  47. package/dist/components/ai/shimmer.js +49 -0
  48. package/dist/components/ai/shimmer.js.map +1 -0
  49. package/dist/components/ai/sources.cjs +2 -0
  50. package/dist/components/ai/sources.cjs.map +1 -0
  51. package/dist/components/ai/sources.js +54 -0
  52. package/dist/components/ai/sources.js.map +1 -0
  53. package/dist/components/ai/speech-input.cjs +2 -0
  54. package/dist/components/ai/speech-input.cjs.map +1 -0
  55. package/dist/components/ai/speech-input.js +123 -0
  56. package/dist/components/ai/speech-input.js.map +1 -0
  57. package/dist/components/ai/stream-status.cjs +2 -0
  58. package/dist/components/ai/stream-status.cjs.map +1 -0
  59. package/dist/components/ai/stream-status.js +106 -0
  60. package/dist/components/ai/stream-status.js.map +1 -0
  61. package/dist/components/ai/suggestion.cjs +2 -0
  62. package/dist/components/ai/suggestion.cjs.map +1 -0
  63. package/dist/components/ai/suggestion.js +38 -0
  64. package/dist/components/ai/suggestion.js.map +1 -0
  65. package/dist/components/ai/task.cjs +2 -0
  66. package/dist/components/ai/task.cjs.map +1 -0
  67. package/dist/components/ai/task.js +94 -0
  68. package/dist/components/ai/task.js.map +1 -0
  69. package/dist/components/ai/tool.cjs +2 -0
  70. package/dist/components/ai/tool.cjs.map +1 -0
  71. package/dist/components/ai/tool.js +143 -0
  72. package/dist/components/ai/tool.js.map +1 -0
  73. package/dist/components/composed/Chat/Chat.cjs +2 -0
  74. package/dist/components/composed/Chat/Chat.cjs.map +1 -0
  75. package/dist/components/composed/Chat/Chat.js +167 -0
  76. package/dist/components/composed/Chat/Chat.js.map +1 -0
  77. package/dist/components/ui/code-block.cjs +4 -0
  78. package/dist/components/ui/code-block.cjs.map +1 -0
  79. package/dist/components/ui/code-block.js +306 -0
  80. package/dist/components/ui/code-block.js.map +1 -0
  81. package/dist/components/ui/progress.cjs +2 -0
  82. package/dist/components/ui/progress.cjs.map +1 -0
  83. package/dist/components/ui/progress.js +32 -0
  84. package/dist/components/ui/progress.js.map +1 -0
  85. package/dist/index.cjs +1 -1
  86. package/dist/index.css +1 -1
  87. package/dist/index.d.ts +1145 -0
  88. package/dist/index.js +574 -372
  89. package/dist/index.js.map +1 -1
  90. package/dist/index.tailwind.css +1 -1
  91. package/package.json +12 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-input.js","sources":["../../../src/components/ai/prompt-input.tsx"],"sourcesContent":["import {\n CornerDownLeftIcon,\n ImageIcon,\n Monitor,\n PlusIcon,\n SquareIcon,\n XIcon,\n} from \"lucide-react\";\nimport {\n Children,\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport type { ChatStatus, FileUIPart, SourceDocumentUIPart } from \"ai\";\nimport type {\n ChangeEvent,\n ChangeEventHandler,\n ClipboardEventHandler,\n ComponentProps,\n FormEvent,\n FormEventHandler,\n HTMLAttributes,\n KeyboardEventHandler,\n PropsWithChildren,\n ReactNode,\n RefObject,\n} from \"react\";\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 {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { cn } from \"@/lib/utils\";\n\n\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nconst convertBlobUrlToDataUrl = async (url: string): Promise<string | null> => {\n try {\n const response = await fetch(url);\n const blob = await response.blob();\n // FileReader uses callback-based API, wrapping in Promise is necessary\n // oxlint-disable-next-line eslint-plugin-promise(avoid-new)\n return new Promise((resolve) => {\n const reader = new FileReader();\n // oxlint-disable-next-line eslint-plugin-unicorn(prefer-add-event-listener)\n reader.onloadend = () => resolve(reader.result as string);\n // oxlint-disable-next-line eslint-plugin-unicorn(prefer-add-event-listener)\n reader.onerror = () => resolve(null);\n reader.readAsDataURL(blob);\n });\n } catch {\n return null;\n }\n};\n\nconst captureScreenshot = async (): Promise<File | null> => {\n if (\n typeof navigator === \"undefined\" ||\n !navigator.mediaDevices?.getDisplayMedia\n ) {\n return null;\n }\n\n let stream: MediaStream | null = null;\n const video = document.createElement(\"video\");\n video.muted = true;\n video.playsInline = true;\n\n try {\n stream = await navigator.mediaDevices.getDisplayMedia({\n audio: false,\n video: true,\n });\n\n video.srcObject = stream;\n\n // Video element uses callback-based API, wrapping in Promise is necessary\n // oxlint-disable-next-line eslint-plugin-promise(avoid-new)\n await new Promise<void>((resolve, reject) => {\n // oxlint-disable-next-line eslint-plugin-unicorn(prefer-add-event-listener)\n video.onloadedmetadata = () => resolve();\n // oxlint-disable-next-line eslint-plugin-unicorn(prefer-add-event-listener)\n video.onerror = () => reject(new Error(\"Failed to load screen stream\"));\n });\n\n await video.play();\n\n const width = video.videoWidth;\n const height = video.videoHeight;\n if (!width || !height) {\n return null;\n }\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n const context = canvas.getContext(\"2d\");\n if (!context) {\n return null;\n }\n\n context.drawImage(video, 0, 0, width, height);\n // canvas.toBlob uses callback-based API, wrapping in Promise is necessary\n // oxlint-disable-next-line eslint-plugin-promise(avoid-new)\n const blob = await new Promise<Blob | null>((resolve) => {\n canvas.toBlob(resolve, \"image/png\");\n });\n if (!blob) {\n return null;\n }\n\n const timestamp = new Date()\n .toISOString()\n .replace(/[:.]/g, \"-\")\n .replace(\"T\", \"_\")\n .replace(\"Z\", \"\");\n\n return new File([blob], `screenshot-${timestamp}.png`, {\n lastModified: Date.now(),\n type: \"image/png\",\n });\n } finally {\n if (stream) {\n for (const track of stream.getTracks()) {\n track.stop();\n }\n }\n video.pause();\n video.srcObject = null;\n }\n};\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 const 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 // oxlint-disable-next-line eslint(no-empty-function)\n const openRef = useRef<() => void>(() => {});\n\n const add = useCallback((files: File[] | FileList) => {\n const incoming = [...files];\n if (incoming.length === 0) {\n return;\n }\n\n setAttachmentFiles((prev) => [\n ...prev,\n ...incoming.map((file) => ({\n filename: file.name,\n id: crypto.randomUUID(),\n mediaType: file.type,\n type: \"file\" as const,\n url: URL.createObjectURL(file),\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\n useEffect(() => {\n attachmentsRef.current = attachmentFiles;\n }, [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 add,\n clear,\n fileInputRef,\n files: attachmentFiles,\n openFileDialog,\n remove,\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 __registerFileInput,\n attachments,\n textInput: {\n clear: clearInput,\n setInput: setTextInput,\n value: textInput,\n },\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 const handleSelect = useCallback(\n (e: Event) => {\n e.preventDefault();\n attachments.openFileDialog();\n },\n [attachments]\n );\n\n return (\n <DropdownMenuItem {...props} onSelect={handleSelect}>\n <ImageIcon className=\"mr-2 size-4\" /> {label}\n </DropdownMenuItem>\n );\n};\n\nexport type PromptInputActionAddScreenshotProps = ComponentProps<\n typeof DropdownMenuItem\n> & {\n label?: string;\n};\n\nexport const PromptInputActionAddScreenshot = ({\n label = \"Take screenshot\",\n onSelect,\n ...props\n}: PromptInputActionAddScreenshotProps) => {\n const attachments = usePromptInputAttachments();\n\n const handleSelect = useCallback(\n async (event: Event) => {\n onSelect?.(event);\n if (event.defaultPrevented) {\n return;\n }\n\n try {\n const screenshot = await captureScreenshot();\n if (screenshot) {\n attachments.add([screenshot]);\n }\n } catch (error) {\n if (\n error instanceof DOMException &&\n (error.name === \"NotAllowedError\" || error.name === \"AbortError\")\n ) {\n return;\n }\n throw error;\n }\n },\n [onSelect, attachments]\n );\n\n return (\n <DropdownMenuItem {...props} onSelect={handleSelect}>\n <Monitor className=\"mr-2 size-4\" />\n {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 // e.g., \"image/*\" or leave undefined for any\n accept?: string;\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 // bytes\n maxFileSize?: number;\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\n useEffect(() => {\n filesRef.current = files;\n }, [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 // e.g: image/* -> image/\n const prefix = pattern.slice(0, -1);\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 = [...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 filename: file.name,\n id: crypto.randomUUID(),\n mediaType: file.type,\n type: \"file\",\n url: URL.createObjectURL(file),\n });\n }\n return [...prev, ...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 = [...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 // Shared drag-and-drop handlers used by both form-level and document-level effects\n const makeDragHandlers = useCallback(\n (target: HTMLElement | Document, onAddFiles: (files: FileList) => void) => {\n const onDragOver = (e: Event) => {\n const drag = e as DragEvent;\n if (drag.dataTransfer?.types?.includes(\"Files\")) {\n e.preventDefault();\n }\n };\n const onDrop = (e: Event) => {\n const drag = e as DragEvent;\n if (drag.dataTransfer?.types?.includes(\"Files\")) {\n e.preventDefault();\n }\n if (drag.dataTransfer?.files && drag.dataTransfer.files.length > 0) {\n onAddFiles(drag.dataTransfer.files);\n }\n };\n target.addEventListener(\"dragover\", onDragOver);\n target.addEventListener(\"drop\", onDrop);\n return () => {\n target.removeEventListener(\"dragover\", onDragOver);\n target.removeEventListener(\"drop\", onDrop);\n };\n },\n []\n );\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 // when global drop is on, let the document-level handler own drops\n return;\n }\n return makeDragHandlers(form, add);\n }, [add, globalDrop, makeDragHandlers]);\n\n useEffect(() => {\n if (!globalDrop) {\n return;\n }\n return makeDragHandlers(document, add);\n }, [add, globalDrop, makeDragHandlers]);\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 [usingProvider]\n );\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = useCallback(\n (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 [add]\n );\n\n const attachmentsCtx = useMemo<AttachmentsContext>(\n () => ({\n add,\n clear: clearAttachments,\n fileInputRef: inputRef,\n files: files.map((item) => ({ ...item, id: item.id })),\n openFileDialog,\n remove,\n }),\n [files, add, remove, clearAttachments, openFileDialog]\n );\n\n const refsCtx = useMemo<ReferencedSourcesContext>(\n () => ({\n add: (incoming: SourceDocumentUIPart[] | SourceDocumentUIPart) => {\n const array = Array.isArray(incoming) ? incoming : [incoming];\n setReferencedSources((prev) => [\n ...prev,\n ...array.map((s) => ({ ...s, id: crypto.randomUUID() })),\n ]);\n },\n clear: clearReferencedSources,\n remove: (id: string) => {\n setReferencedSources((prev) => prev.filter((s) => s.id !== id));\n },\n sources: referencedSources,\n }),\n [referencedSources, clearReferencedSources]\n );\n\n const handleSubmit: FormEventHandler<HTMLFormElement> = useCallback(\n async (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 try {\n // Convert blob URLs to data URLs asynchronously\n const convertedFiles: FileUIPart[] = await Promise.all(\n files.map(async ({ id: _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\n const result = onSubmit({ files: convertedFiles, text }, event);\n\n // Handle both sync and async onSubmit\n if (result instanceof Promise) {\n try {\n await result;\n clear();\n if (usingProvider) {\n controller.textInput.clear();\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 [usingProvider, controller, files, onSubmit, clear]\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=\"border-border overflow-hidden has-[[data-slot=input-group-control]:focus-visible]:ring-0\">{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> = useCallback(\n (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;\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 [onKeyDown, isComposing, attachments]\n );\n\n const handlePaste: ClipboardEventHandler<HTMLTextAreaElement> = useCallback(\n (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 [attachments]\n );\n\n const handleCompositionEnd = useCallback(() => setIsComposing(false), []);\n const handleCompositionStart = useCallback(() => setIsComposing(true), []);\n\n const controlledProps = controller\n ? {\n onChange: (e: ChangeEvent<HTMLTextAreaElement>) => {\n controller.textInput.setInput(e.currentTarget.value);\n onChange?.(e);\n },\n value: controller.textInput.value,\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={handleCompositionEnd}\n onCompositionStart={handleCompositionStart}\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\n className={cn(\"flex min-w-0 items-center gap-1\", className)}\n {...props}\n />\n);\n\nexport type PromptInputButtonTooltip =\n | string\n | {\n content: ReactNode;\n shortcut?: string;\n side?: ComponentProps<typeof TooltipContent>[\"side\"];\n };\n\nexport type PromptInputButtonProps = ComponentProps<typeof InputGroupButton> & {\n tooltip?: PromptInputButtonTooltip;\n};\n\nexport const PromptInputButton = ({\n variant = \"ghost\",\n className,\n size,\n tooltip,\n ...props\n}: PromptInputButtonProps) => {\n const newSize =\n size ?? (Children.count(props.children) > 1 ? \"sm\" : \"icon-sm\");\n\n const button = (\n <InputGroupButton\n className={cn(className)}\n size={newSize}\n type=\"button\"\n variant={variant}\n {...props}\n />\n );\n\n if (!tooltip) {\n return button;\n }\n\n const tooltipContent =\n typeof tooltip === \"string\" ? tooltip : tooltip.content;\n const shortcut = typeof tooltip === \"string\" ? undefined : tooltip.shortcut;\n const side = typeof tooltip === \"string\" ? \"top\" : (tooltip.side ?? \"top\");\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>{button}</TooltipTrigger>\n <TooltipContent side={side}>\n {tooltipContent}\n {shortcut && (\n <span className=\"ml-2 text-muted-foreground\">{shortcut}</span>\n )}\n </TooltipContent>\n </Tooltip>\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 tooltip,\n \"aria-label\": ariaLabel,\n ...props\n}: PromptInputActionMenuTriggerProps) => {\n const derivedLabel =\n ariaLabel ??\n (typeof tooltip === \"string\"\n ? tooltip\n : typeof tooltip?.content === \"string\"\n ? tooltip.content\n : undefined);\n\n return (\n <DropdownMenuTrigger asChild>\n <PromptInputButton\n aria-label={derivedLabel}\n className={className}\n tooltip={tooltip}\n {...props}\n >\n {children ?? <PlusIcon className=\"size-4\" />}\n </PromptInputButton>\n </DropdownMenuTrigger>\n );\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 = useCallback(\n (e: React.MouseEvent<HTMLButtonElement>) => {\n if (isGenerating && onStop) {\n e.preventDefault();\n onStop();\n return;\n }\n onClick?.(e);\n },\n [isGenerating, onStop, onClick]\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\n// ============================================================================\n// PromptInputSlotSwap\n// ============================================================================\n\nexport type PromptInputSlotSwapProps = {\n /** Shown when show=false (e.g. mic button). */\n a: ReactNode;\n /** Shown when show=true (e.g. submit button). */\n b: ReactNode;\n /** When true, b is visible; when false, a is visible. */\n show: boolean;\n className?: string;\n};\n\nexport const PromptInputSlotSwap = ({\n a,\n b,\n show,\n className,\n}: PromptInputSlotSwapProps) => (\n <div\n className={cn(\"relative inline-flex items-center justify-center\", className)}\n >\n <div\n aria-hidden={show}\n className={cn(\n \"transition-all duration-200 ease-out\",\n show ? \"pointer-events-none scale-75 opacity-0\" : \"scale-100 opacity-100\"\n )}\n >\n {a}\n </div>\n <div\n aria-hidden={!show}\n className={cn(\n \"absolute transition-all duration-200 ease-out\",\n show ? \"scale-100 opacity-100\" : \"pointer-events-none scale-75 opacity-0\"\n )}\n >\n {b}\n </div>\n </div>\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 children,\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 {children}\n </h3>\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"],"names":["convertBlobUrlToDataUrl","url","blob","resolve","reader","captureScreenshot","stream","video","reject","width","height","canvas","context","timestamp","track","PromptInputController","createContext","ProviderAttachmentsContext","usePromptInputController","ctx","useContext","useOptionalPromptInputController","useProviderAttachments","useOptionalProviderAttachments","PromptInputProvider","initialTextInput","children","textInput","setTextInput","useState","clearInput","useCallback","attachmentFiles","setAttachmentFiles","fileInputRef","useRef","openRef","add","files","incoming","prev","file","remove","id","found","f","clear","attachmentsRef","useEffect","openFileDialog","attachments","useMemo","__registerFileInput","ref","open","controller","jsx","LocalAttachmentsContext","usePromptInputAttachments","provider","LocalReferencedSourcesContext","usePromptInputReferencedSources","PromptInputActionAddAttachments","label","props","handleSelect","e","jsxs","DropdownMenuItem","ImageIcon","PromptInputActionAddScreenshot","onSelect","event","screenshot","error","Monitor","PromptInput","className","accept","multiple","globalDrop","syncHiddenInput","maxFiles","maxFileSize","onError","onSubmit","usingProvider","inputRef","formRef","items","setItems","referencedSources","setReferencedSources","filesRef","openFileDialogLocal","matchesAccept","s","pattern","prefix","addLocal","fileList","accepted","withinSize","sized","capacity","capped","next","removeLocal","addWithProviderValidation","currentCount","clearAttachments","clearReferencedSources","makeDragHandlers","target","onAddFiles","onDragOver","onDrop","drag","form","handleChange","attachmentsCtx","item","refsCtx","array","handleSubmit","text","convertedFiles","_id","dataUrl","result","inner","Fragment","cn","InputGroup","withReferencedSources","PromptInputBody","PromptInputTextarea","onChange","onKeyDown","placeholder","isComposing","setIsComposing","handleKeyDown","lastAttachment","handlePaste","handleCompositionEnd","handleCompositionStart","controlledProps","InputGroupTextarea","PromptInputHeader","InputGroupAddon","PromptInputFooter","PromptInputTools","PromptInputButton","variant","size","tooltip","newSize","Children","button","InputGroupButton","tooltipContent","shortcut","side","Tooltip","TooltipTrigger","TooltipContent","PromptInputActionMenu","DropdownMenu","PromptInputActionMenuTrigger","ariaLabel","derivedLabel","DropdownMenuTrigger","PlusIcon","PromptInputActionMenuContent","DropdownMenuContent","PromptInputActionMenuItem","PromptInputSubmit","status","onStop","onClick","isGenerating","Icon","CornerDownLeftIcon","Spinner","SquareIcon","XIcon","handleClick","PromptInputSelect","Select","PromptInputSelectTrigger","SelectTrigger","PromptInputSelectContent","SelectContent","PromptInputSelectItem","SelectItem","PromptInputSelectValue","SelectValue","PromptInputHoverCard","openDelay","closeDelay","HoverCard","PromptInputHoverCardTrigger","HoverCardTrigger","PromptInputHoverCardContent","align","HoverCardContent","PromptInputSlotSwap","a","b","show","PromptInputTabsList","PromptInputTab","PromptInputTabLabel","PromptInputTabBody","PromptInputTabItem","PromptInputCommand","Command","PromptInputCommandInput","CommandInput","PromptInputCommandList","CommandList","PromptInputCommandEmpty","CommandEmpty","PromptInputCommandGroup","CommandGroup","PromptInputCommandItem","CommandItem","PromptInputCommandSeparator","CommandSeparator"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),x=require("lucide-react"),p=require("motion/react"),c=require("react"),Q=require("../ui/button.cjs"),d=require("../ui/collapsible.cjs"),j=require("../ui/scroll-area.cjs"),r=require("../../lib/utils.cjs"),I=({className:t,...e})=>o.jsx("li",{className:r.cn("group flex flex-row items-center gap-2 rounded-md px-3 py-1 text-sm transition-colors hover:bg-muted",t),...e}),v={pending:"border border-muted-foreground/40",loading:"border-2 border-muted-foreground/20 border-t-primary animate-spin",done:"border border-muted-foreground/20 bg-muted-foreground/30",error:"border border-destructive/30 bg-destructive/70"},N=({status:t,completed:e=!1,className:s,...n})=>{const u=t??(e?"done":"pending");return o.jsx("span",{className:r.cn("inline-block size-2.5 shrink-0 rounded-full",v[u],s),...n})},y=({completed:t=!1,className:e,...s})=>o.jsx("span",{className:r.cn("min-w-0 flex-1 truncate",t?"text-muted-foreground/50 line-through":"text-muted-foreground",e),...s}),A=({completed:t=!1,className:e,...s})=>o.jsx("div",{className:r.cn("text-xs",t?"text-muted-foreground/40 line-through":"text-muted-foreground/70",e),...s}),S=({className:t,...e})=>o.jsx("div",{className:r.cn("ml-auto flex shrink-0 gap-1",t),...e}),T=({className:t,...e})=>o.jsx(Q.Button,{className:r.cn("size-auto rounded p-1 text-muted-foreground opacity-0 transition-opacity hover:bg-muted-foreground/10 hover:text-foreground group-hover:opacity-100",t),size:"icon",type:"button",variant:"ghost",...e}),C=({className:t,...e})=>o.jsx("div",{className:r.cn("flex flex-wrap gap-2",t),...e}),w=({className:t,...e})=>o.jsx("img",{alt:"",className:r.cn("size-8 rounded border object-cover",t),height:32,width:32,...e}),q=({children:t,className:e,...s})=>o.jsxs("span",{className:r.cn("flex items-center gap-1 rounded border bg-muted px-2 py-1 text-xs",e),...s,children:[o.jsx(x.PaperclipIcon,{size:12}),o.jsx("span",{className:"max-w-[100px] truncate",children:t})]}),z=({children:t,className:e,...s})=>o.jsx(j.ScrollArea,{className:r.cn("-mb-1 mt-2",e),...s,children:o.jsx("div",{className:"max-h-40 pr-4",children:o.jsx("ul",{className:"flex flex-col gap-0.5",children:t})})}),D=({className:t,defaultOpen:e=!0,...s})=>o.jsx(d.Collapsible,{className:r.cn(t),defaultOpen:e,...s}),E=({children:t,className:e,...s})=>o.jsx(d.CollapsibleTrigger,{asChild:!0,children:o.jsx("button",{className:r.cn("group flex w-full items-center justify-between rounded-md bg-muted/40 px-3 py-2 text-left font-medium text-muted-foreground text-sm transition-colors hover:bg-muted",e),type:"button",...s,children:t})}),O=({count:t,icon:e,className:s,children:n,...u})=>o.jsxs("span",{className:r.cn("flex items-center gap-2",s),...u,children:[o.jsx(x.ChevronDownIcon,{className:"size-4 opacity-0 transition-all group-focus-visible:opacity-100 group-hover:opacity-100 group-data-[state=open]:opacity-100 group-data-[state=closed]:-rotate-90","data-slot":"collapsible-chevron"}),e,o.jsxs("span",{children:[t===void 0?"":`${t} `,n]})]}),R=({className:t,...e})=>o.jsx(d.CollapsibleContent,{className:r.cn(t),...e}),L=1e3,H=({className:t,isStreaming:e=!1,children:s,style:n,id:u,...g})=>{const[i,f]=c.useState(!0),l=c.useRef(e),[m,b]=c.useState(!1);c.useEffect(()=>{e&&(l.current=!0)},[e]),c.useEffect(()=>{if(l.current&&!e&&i&&!m){const a=setTimeout(()=>{f(!1),b(!0)},L);return()=>clearTimeout(a)}},[e,i,m]);const h=Object.fromEntries(Object.entries(g).filter(([a])=>a.startsWith("data-")||a.startsWith("aria-")));return o.jsx(p.AnimatePresence,{children:i&&o.jsx(p.motion.div,{...h,className:r.cn("flex flex-col gap-2 rounded-xl border border-border bg-background px-2 pb-2 pt-2 shadow-xs",t),exit:{opacity:0,height:0,marginTop:0,marginBottom:0,paddingTop:0,paddingBottom:0,overflow:"hidden"},id:u,style:n,transition:{duration:.35,ease:"easeOut"},children:s})})};exports.Queue=H;exports.QueueItem=I;exports.QueueItemAction=T;exports.QueueItemActions=S;exports.QueueItemAttachment=C;exports.QueueItemContent=y;exports.QueueItemDescription=A;exports.QueueItemFile=q;exports.QueueItemImage=w;exports.QueueItemIndicator=N;exports.QueueList=z;exports.QueueSection=D;exports.QueueSectionContent=R;exports.QueueSectionLabel=O;exports.QueueSectionTrigger=E;
2
+ //# sourceMappingURL=queue.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.cjs","sources":["../../../src/components/ai/queue.tsx"],"sourcesContent":["import { ChevronDownIcon, PaperclipIcon } from \"lucide-react\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport { useEffect, useRef, useState } from \"react\";\n\nimport type { ComponentProps } from \"react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@/components/ui/collapsible\";\nimport { ScrollArea } from \"@/components/ui/scroll-area\";\nimport { cn } from \"@/lib/utils\";\n\nexport interface QueueMessagePart {\n type: string;\n text?: string;\n url?: string;\n filename?: string;\n mediaType?: string;\n}\n\nexport interface QueueMessage {\n id: string;\n parts: QueueMessagePart[];\n}\n\nexport interface QueueTodo {\n id: string;\n title: string;\n description?: string;\n status?: \"pending\" | \"completed\";\n}\n\n// ---------------------------------------------------------------------------\n// QueueItem\n// ---------------------------------------------------------------------------\n\nexport type QueueItemProps = ComponentProps<\"li\">;\n\nexport const QueueItem = ({ className, ...props }: QueueItemProps) => (\n <li\n className={cn(\n \"group flex flex-row items-center gap-2 rounded-md px-3 py-1 text-sm transition-colors hover:bg-muted\",\n className\n )}\n {...props}\n />\n);\n\n// ---------------------------------------------------------------------------\n// QueueItemIndicator\n// ---------------------------------------------------------------------------\n\nexport type QueueItemStatus = \"pending\" | \"loading\" | \"done\" | \"error\";\n\nexport type QueueItemIndicatorProps = ComponentProps<\"span\"> & {\n /**\n * Visual state of the indicator dot.\n * - `pending` — unfilled muted ring\n * - `loading` — spinning ring (primary accent)\n * - `done` — filled muted dot (task complete)\n * - `error` — filled destructive dot\n */\n status?: QueueItemStatus;\n /** @deprecated Use `status=\"done\"` instead. */\n completed?: boolean;\n};\n\nconst INDICATOR_STATUS: Record<QueueItemStatus, string> = {\n pending: \"border border-muted-foreground/40\",\n loading:\n \"border-2 border-muted-foreground/20 border-t-primary animate-spin\",\n done: \"border border-muted-foreground/20 bg-muted-foreground/30\",\n error: \"border border-destructive/30 bg-destructive/70\",\n};\n\nexport const QueueItemIndicator = ({\n status,\n completed = false,\n className,\n ...props\n}: QueueItemIndicatorProps) => {\n const resolvedStatus: QueueItemStatus =\n status ?? (completed ? \"done\" : \"pending\");\n\n return (\n <span\n className={cn(\n \"inline-block size-2.5 shrink-0 rounded-full\",\n INDICATOR_STATUS[resolvedStatus],\n className\n )}\n {...props}\n />\n );\n};\n\n// ---------------------------------------------------------------------------\n// QueueItemContent\n// ---------------------------------------------------------------------------\n\nexport type QueueItemContentProps = ComponentProps<\"span\"> & {\n completed?: boolean;\n};\n\nexport const QueueItemContent = ({\n completed = false,\n className,\n ...props\n}: QueueItemContentProps) => (\n <span\n className={cn(\n \"min-w-0 flex-1 truncate\",\n completed\n ? \"text-muted-foreground/50 line-through\"\n : \"text-muted-foreground\",\n className\n )}\n {...props}\n />\n);\n\n// ---------------------------------------------------------------------------\n// QueueItemDescription\n// For items with a description, wrap QueueItemContent + QueueItemDescription\n// in a <div className=\"flex flex-col gap-0.5 min-w-0 flex-1\">\n// ---------------------------------------------------------------------------\n\nexport type QueueItemDescriptionProps = ComponentProps<\"div\"> & {\n completed?: boolean;\n};\n\nexport const QueueItemDescription = ({\n completed = false,\n className,\n ...props\n}: QueueItemDescriptionProps) => (\n <div\n className={cn(\n \"text-xs\",\n completed\n ? \"text-muted-foreground/40 line-through\"\n : \"text-muted-foreground/70\",\n className\n )}\n {...props}\n />\n);\n\n// ---------------------------------------------------------------------------\n// QueueItemActions / QueueItemAction\n// ---------------------------------------------------------------------------\n\nexport type QueueItemActionsProps = ComponentProps<\"div\">;\n\nexport const QueueItemActions = ({\n className,\n ...props\n}: QueueItemActionsProps) => (\n <div className={cn(\"ml-auto flex shrink-0 gap-1\", className)} {...props} />\n);\n\nexport type QueueItemActionProps = Omit<\n ComponentProps<typeof Button>,\n \"variant\" | \"size\"\n>;\n\nexport const QueueItemAction = ({\n className,\n ...props\n}: QueueItemActionProps) => (\n <Button\n className={cn(\n \"size-auto rounded p-1 text-muted-foreground opacity-0 transition-opacity hover:bg-muted-foreground/10 hover:text-foreground group-hover:opacity-100\",\n className\n )}\n size=\"icon\"\n type=\"button\"\n variant=\"ghost\"\n {...props}\n />\n);\n\n// ---------------------------------------------------------------------------\n// QueueItemAttachment / QueueItemImage / QueueItemFile\n// ---------------------------------------------------------------------------\n\nexport type QueueItemAttachmentProps = ComponentProps<\"div\">;\n\nexport const QueueItemAttachment = ({\n className,\n ...props\n}: QueueItemAttachmentProps) => (\n <div className={cn(\"flex flex-wrap gap-2\", className)} {...props} />\n);\n\nexport type QueueItemImageProps = ComponentProps<\"img\">;\n\nexport const QueueItemImage = ({\n className,\n ...props\n}: QueueItemImageProps) => (\n <img\n alt=\"\"\n className={cn(\"size-8 rounded border object-cover\", className)}\n height={32}\n width={32}\n {...props}\n />\n);\n\nexport type QueueItemFileProps = ComponentProps<\"span\">;\n\nexport const QueueItemFile = ({\n children,\n className,\n ...props\n}: QueueItemFileProps) => (\n <span\n className={cn(\n \"flex items-center gap-1 rounded border bg-muted px-2 py-1 text-xs\",\n className\n )}\n {...props}\n >\n <PaperclipIcon size={12} />\n <span className=\"max-w-[100px] truncate\">{children}</span>\n </span>\n);\n\n// ---------------------------------------------------------------------------\n// QueueList\n// ---------------------------------------------------------------------------\n\nexport type QueueListProps = ComponentProps<typeof ScrollArea>;\n\nexport const QueueList = ({\n children,\n className,\n ...props\n}: QueueListProps) => (\n <ScrollArea className={cn(\"-mb-1 mt-2\", className)} {...props}>\n <div className=\"max-h-40 pr-4\">\n <ul className=\"flex flex-col gap-0.5\">{children}</ul>\n </div>\n </ScrollArea>\n);\n\n// ---------------------------------------------------------------------------\n// QueueSection / QueueSectionTrigger / QueueSectionLabel / QueueSectionContent\n// ---------------------------------------------------------------------------\n\nexport type QueueSectionProps = ComponentProps<typeof Collapsible>;\n\nexport const QueueSection = ({\n className,\n defaultOpen = true,\n ...props\n}: QueueSectionProps) => (\n <Collapsible className={cn(className)} defaultOpen={defaultOpen} {...props} />\n);\n\nexport type QueueSectionTriggerProps = ComponentProps<\"button\">;\n\nexport const QueueSectionTrigger = ({\n children,\n className,\n ...props\n}: QueueSectionTriggerProps) => (\n <CollapsibleTrigger asChild>\n <button\n className={cn(\n \"group flex w-full items-center justify-between rounded-md bg-muted/40 px-3 py-2 text-left font-medium text-muted-foreground text-sm transition-colors hover:bg-muted\",\n className\n )}\n type=\"button\"\n {...props}\n >\n {children}\n </button>\n </CollapsibleTrigger>\n);\n\nexport type QueueSectionLabelProps = ComponentProps<\"span\"> & {\n count?: number;\n icon?: React.ReactNode;\n};\n\nexport const QueueSectionLabel = ({\n count,\n icon,\n className,\n children,\n ...props\n}: QueueSectionLabelProps) => (\n <span className={cn(\"flex items-center gap-2\", className)} {...props}>\n <ChevronDownIcon\n className=\"size-4 opacity-0 transition-all group-focus-visible:opacity-100 group-hover:opacity-100 group-data-[state=open]:opacity-100 group-data-[state=closed]:-rotate-90\"\n data-slot=\"collapsible-chevron\"\n />\n {icon}\n <span>\n {count === undefined ? \"\" : `${count} `}\n {children}\n </span>\n </span>\n);\n\nexport type QueueSectionContentProps = ComponentProps<typeof CollapsibleContent>;\n\nexport const QueueSectionContent = ({\n className,\n ...props\n}: QueueSectionContentProps) => (\n <CollapsibleContent className={cn(className)} {...props} />\n);\n\n// ---------------------------------------------------------------------------\n// Queue (root)\n// ---------------------------------------------------------------------------\n\nconst AUTO_HIDE_DELAY = 1000;\n\nexport type QueueProps = ComponentProps<\"div\"> & {\n isStreaming?: boolean;\n};\n\nexport const Queue = ({ className, isStreaming = false, children, style, id, ...props }: QueueProps) => {\n const [visible, setVisible] = useState(true);\n const hasEverStreamedRef = useRef(isStreaming);\n const [hasAutoHidden, setHasAutoHidden] = useState(false);\n\n useEffect(() => {\n if (isStreaming) hasEverStreamedRef.current = true;\n }, [isStreaming]);\n\n useEffect(() => {\n if (hasEverStreamedRef.current && !isStreaming && visible && !hasAutoHidden) {\n const timer = setTimeout(() => {\n setVisible(false);\n setHasAutoHidden(true);\n }, AUTO_HIDE_DELAY);\n return () => clearTimeout(timer);\n }\n }, [isStreaming, visible, hasAutoHidden]);\n\n // Spread data-* and aria-* attributes through; drop event handlers to avoid\n // onDrag type conflict between React and framer-motion.\n const passthroughProps = Object.fromEntries(\n Object.entries(props).filter(([k]) => k.startsWith(\"data-\") || k.startsWith(\"aria-\"))\n );\n\n return (\n <AnimatePresence>\n {visible && (\n <motion.div\n {...passthroughProps}\n className={cn(\n \"flex flex-col gap-2 rounded-xl border border-border bg-background px-2 pb-2 pt-2 shadow-xs\",\n className\n )}\n exit={{ opacity: 0, height: 0, marginTop: 0, marginBottom: 0, paddingTop: 0, paddingBottom: 0, overflow: \"hidden\" }}\n id={id}\n style={style}\n transition={{ duration: 0.35, ease: \"easeOut\" }}\n >\n {children}\n </motion.div>\n )}\n </AnimatePresence>\n );\n};\n"],"names":["QueueItem","className","props","jsx","cn","INDICATOR_STATUS","QueueItemIndicator","status","completed","resolvedStatus","QueueItemContent","QueueItemDescription","QueueItemActions","QueueItemAction","Button","QueueItemAttachment","QueueItemImage","QueueItemFile","children","jsxs","PaperclipIcon","QueueList","ScrollArea","QueueSection","defaultOpen","Collapsible","QueueSectionTrigger","CollapsibleTrigger","QueueSectionLabel","count","icon","ChevronDownIcon","QueueSectionContent","CollapsibleContent","AUTO_HIDE_DELAY","Queue","isStreaming","style","id","visible","setVisible","useState","hasEverStreamedRef","useRef","hasAutoHidden","setHasAutoHidden","useEffect","timer","passthroughProps","k","AnimatePresence","motion"],"mappings":"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"}
@@ -0,0 +1,209 @@
1
+ import { jsx as o, jsxs as d } from "react/jsx-runtime";
2
+ import { PaperclipIcon as h, ChevronDownIcon as v } from "lucide-react";
3
+ import { AnimatePresence as N, motion as I } from "motion/react";
4
+ import { useState as m, useRef as y, useEffect as p } from "react";
5
+ import { Button as Q } from "../ui/button.js";
6
+ import { Collapsible as A, CollapsibleContent as w, CollapsibleTrigger as T } from "../ui/collapsible.js";
7
+ import { ScrollArea as C } from "../ui/scroll-area.js";
8
+ import { cn as s } from "../../lib/utils.js";
9
+ const P = ({ className: t, ...e }) => /* @__PURE__ */ o(
10
+ "li",
11
+ {
12
+ className: s(
13
+ "group flex flex-row items-center gap-2 rounded-md px-3 py-1 text-sm transition-colors hover:bg-muted",
14
+ t
15
+ ),
16
+ ...e
17
+ }
18
+ ), S = {
19
+ pending: "border border-muted-foreground/40",
20
+ loading: "border-2 border-muted-foreground/20 border-t-primary animate-spin",
21
+ done: "border border-muted-foreground/20 bg-muted-foreground/30",
22
+ error: "border border-destructive/30 bg-destructive/70"
23
+ }, R = ({
24
+ status: t,
25
+ completed: e = !1,
26
+ className: r,
27
+ ...n
28
+ }) => /* @__PURE__ */ o(
29
+ "span",
30
+ {
31
+ className: s(
32
+ "inline-block size-2.5 shrink-0 rounded-full",
33
+ S[t ?? (e ? "done" : "pending")],
34
+ r
35
+ ),
36
+ ...n
37
+ }
38
+ ), _ = ({
39
+ completed: t = !1,
40
+ className: e,
41
+ ...r
42
+ }) => /* @__PURE__ */ o(
43
+ "span",
44
+ {
45
+ className: s(
46
+ "min-w-0 flex-1 truncate",
47
+ t ? "text-muted-foreground/50 line-through" : "text-muted-foreground",
48
+ e
49
+ ),
50
+ ...r
51
+ }
52
+ ), U = ({
53
+ completed: t = !1,
54
+ className: e,
55
+ ...r
56
+ }) => /* @__PURE__ */ o(
57
+ "div",
58
+ {
59
+ className: s(
60
+ "text-xs",
61
+ t ? "text-muted-foreground/40 line-through" : "text-muted-foreground/70",
62
+ e
63
+ ),
64
+ ...r
65
+ }
66
+ ), W = ({
67
+ className: t,
68
+ ...e
69
+ }) => /* @__PURE__ */ o("div", { className: s("ml-auto flex shrink-0 gap-1", t), ...e }), F = ({
70
+ className: t,
71
+ ...e
72
+ }) => /* @__PURE__ */ o(
73
+ Q,
74
+ {
75
+ className: s(
76
+ "size-auto rounded p-1 text-muted-foreground opacity-0 transition-opacity hover:bg-muted-foreground/10 hover:text-foreground group-hover:opacity-100",
77
+ t
78
+ ),
79
+ size: "icon",
80
+ type: "button",
81
+ variant: "ghost",
82
+ ...e
83
+ }
84
+ ), V = ({
85
+ className: t,
86
+ ...e
87
+ }) => /* @__PURE__ */ o("div", { className: s("flex flex-wrap gap-2", t), ...e }), Y = ({
88
+ className: t,
89
+ ...e
90
+ }) => /* @__PURE__ */ o(
91
+ "img",
92
+ {
93
+ alt: "",
94
+ className: s("size-8 rounded border object-cover", t),
95
+ height: 32,
96
+ width: 32,
97
+ ...e
98
+ }
99
+ ), $ = ({
100
+ children: t,
101
+ className: e,
102
+ ...r
103
+ }) => /* @__PURE__ */ d(
104
+ "span",
105
+ {
106
+ className: s(
107
+ "flex items-center gap-1 rounded border bg-muted px-2 py-1 text-xs",
108
+ e
109
+ ),
110
+ ...r,
111
+ children: [
112
+ /* @__PURE__ */ o(h, { size: 12 }),
113
+ /* @__PURE__ */ o("span", { className: "max-w-[100px] truncate", children: t })
114
+ ]
115
+ }
116
+ ), q = ({
117
+ children: t,
118
+ className: e,
119
+ ...r
120
+ }) => /* @__PURE__ */ o(C, { className: s("-mb-1 mt-2", e), ...r, children: /* @__PURE__ */ o("div", { className: "max-h-40 pr-4", children: /* @__PURE__ */ o("ul", { className: "flex flex-col gap-0.5", children: t }) }) }), G = ({
121
+ className: t,
122
+ defaultOpen: e = !0,
123
+ ...r
124
+ }) => /* @__PURE__ */ o(A, { className: s(t), defaultOpen: e, ...r }), J = ({
125
+ children: t,
126
+ className: e,
127
+ ...r
128
+ }) => /* @__PURE__ */ o(T, { asChild: !0, children: /* @__PURE__ */ o(
129
+ "button",
130
+ {
131
+ className: s(
132
+ "group flex w-full items-center justify-between rounded-md bg-muted/40 px-3 py-2 text-left font-medium text-muted-foreground text-sm transition-colors hover:bg-muted",
133
+ e
134
+ ),
135
+ type: "button",
136
+ ...r,
137
+ children: t
138
+ }
139
+ ) }), K = ({
140
+ count: t,
141
+ icon: e,
142
+ className: r,
143
+ children: n,
144
+ ...a
145
+ }) => /* @__PURE__ */ d("span", { className: s("flex items-center gap-2", r), ...a, children: [
146
+ /* @__PURE__ */ o(
147
+ v,
148
+ {
149
+ className: "size-4 opacity-0 transition-all group-focus-visible:opacity-100 group-hover:opacity-100 group-data-[state=open]:opacity-100 group-data-[state=closed]:-rotate-90",
150
+ "data-slot": "collapsible-chevron"
151
+ }
152
+ ),
153
+ e,
154
+ /* @__PURE__ */ d("span", { children: [
155
+ t === void 0 ? "" : `${t} `,
156
+ n
157
+ ] })
158
+ ] }), M = ({
159
+ className: t,
160
+ ...e
161
+ }) => /* @__PURE__ */ o(w, { className: s(t), ...e }), j = 1e3, X = ({ className: t, isStreaming: e = !1, children: r, style: n, id: a, ...f }) => {
162
+ const [u, g] = m(!0), c = y(e), [l, b] = m(!1);
163
+ p(() => {
164
+ e && (c.current = !0);
165
+ }, [e]), p(() => {
166
+ if (c.current && !e && u && !l) {
167
+ const i = setTimeout(() => {
168
+ g(!1), b(!0);
169
+ }, j);
170
+ return () => clearTimeout(i);
171
+ }
172
+ }, [e, u, l]);
173
+ const x = Object.fromEntries(
174
+ Object.entries(f).filter(([i]) => i.startsWith("data-") || i.startsWith("aria-"))
175
+ );
176
+ return /* @__PURE__ */ o(N, { children: u && /* @__PURE__ */ o(
177
+ I.div,
178
+ {
179
+ ...x,
180
+ className: s(
181
+ "flex flex-col gap-2 rounded-xl border border-border bg-background px-2 pb-2 pt-2 shadow-xs",
182
+ t
183
+ ),
184
+ exit: { opacity: 0, height: 0, marginTop: 0, marginBottom: 0, paddingTop: 0, paddingBottom: 0, overflow: "hidden" },
185
+ id: a,
186
+ style: n,
187
+ transition: { duration: 0.35, ease: "easeOut" },
188
+ children: r
189
+ }
190
+ ) });
191
+ };
192
+ export {
193
+ X as Queue,
194
+ P as QueueItem,
195
+ F as QueueItemAction,
196
+ W as QueueItemActions,
197
+ V as QueueItemAttachment,
198
+ _ as QueueItemContent,
199
+ U as QueueItemDescription,
200
+ $ as QueueItemFile,
201
+ Y as QueueItemImage,
202
+ R as QueueItemIndicator,
203
+ q as QueueList,
204
+ G as QueueSection,
205
+ M as QueueSectionContent,
206
+ K as QueueSectionLabel,
207
+ J as QueueSectionTrigger
208
+ };
209
+ //# sourceMappingURL=queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.js","sources":["../../../src/components/ai/queue.tsx"],"sourcesContent":["import { ChevronDownIcon, PaperclipIcon } from \"lucide-react\";\nimport { AnimatePresence, motion } from \"motion/react\";\nimport { useEffect, useRef, useState } from \"react\";\n\nimport type { ComponentProps } from \"react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@/components/ui/collapsible\";\nimport { ScrollArea } from \"@/components/ui/scroll-area\";\nimport { cn } from \"@/lib/utils\";\n\nexport interface QueueMessagePart {\n type: string;\n text?: string;\n url?: string;\n filename?: string;\n mediaType?: string;\n}\n\nexport interface QueueMessage {\n id: string;\n parts: QueueMessagePart[];\n}\n\nexport interface QueueTodo {\n id: string;\n title: string;\n description?: string;\n status?: \"pending\" | \"completed\";\n}\n\n// ---------------------------------------------------------------------------\n// QueueItem\n// ---------------------------------------------------------------------------\n\nexport type QueueItemProps = ComponentProps<\"li\">;\n\nexport const QueueItem = ({ className, ...props }: QueueItemProps) => (\n <li\n className={cn(\n \"group flex flex-row items-center gap-2 rounded-md px-3 py-1 text-sm transition-colors hover:bg-muted\",\n className\n )}\n {...props}\n />\n);\n\n// ---------------------------------------------------------------------------\n// QueueItemIndicator\n// ---------------------------------------------------------------------------\n\nexport type QueueItemStatus = \"pending\" | \"loading\" | \"done\" | \"error\";\n\nexport type QueueItemIndicatorProps = ComponentProps<\"span\"> & {\n /**\n * Visual state of the indicator dot.\n * - `pending` — unfilled muted ring\n * - `loading` — spinning ring (primary accent)\n * - `done` — filled muted dot (task complete)\n * - `error` — filled destructive dot\n */\n status?: QueueItemStatus;\n /** @deprecated Use `status=\"done\"` instead. */\n completed?: boolean;\n};\n\nconst INDICATOR_STATUS: Record<QueueItemStatus, string> = {\n pending: \"border border-muted-foreground/40\",\n loading:\n \"border-2 border-muted-foreground/20 border-t-primary animate-spin\",\n done: \"border border-muted-foreground/20 bg-muted-foreground/30\",\n error: \"border border-destructive/30 bg-destructive/70\",\n};\n\nexport const QueueItemIndicator = ({\n status,\n completed = false,\n className,\n ...props\n}: QueueItemIndicatorProps) => {\n const resolvedStatus: QueueItemStatus =\n status ?? (completed ? \"done\" : \"pending\");\n\n return (\n <span\n className={cn(\n \"inline-block size-2.5 shrink-0 rounded-full\",\n INDICATOR_STATUS[resolvedStatus],\n className\n )}\n {...props}\n />\n );\n};\n\n// ---------------------------------------------------------------------------\n// QueueItemContent\n// ---------------------------------------------------------------------------\n\nexport type QueueItemContentProps = ComponentProps<\"span\"> & {\n completed?: boolean;\n};\n\nexport const QueueItemContent = ({\n completed = false,\n className,\n ...props\n}: QueueItemContentProps) => (\n <span\n className={cn(\n \"min-w-0 flex-1 truncate\",\n completed\n ? \"text-muted-foreground/50 line-through\"\n : \"text-muted-foreground\",\n className\n )}\n {...props}\n />\n);\n\n// ---------------------------------------------------------------------------\n// QueueItemDescription\n// For items with a description, wrap QueueItemContent + QueueItemDescription\n// in a <div className=\"flex flex-col gap-0.5 min-w-0 flex-1\">\n// ---------------------------------------------------------------------------\n\nexport type QueueItemDescriptionProps = ComponentProps<\"div\"> & {\n completed?: boolean;\n};\n\nexport const QueueItemDescription = ({\n completed = false,\n className,\n ...props\n}: QueueItemDescriptionProps) => (\n <div\n className={cn(\n \"text-xs\",\n completed\n ? \"text-muted-foreground/40 line-through\"\n : \"text-muted-foreground/70\",\n className\n )}\n {...props}\n />\n);\n\n// ---------------------------------------------------------------------------\n// QueueItemActions / QueueItemAction\n// ---------------------------------------------------------------------------\n\nexport type QueueItemActionsProps = ComponentProps<\"div\">;\n\nexport const QueueItemActions = ({\n className,\n ...props\n}: QueueItemActionsProps) => (\n <div className={cn(\"ml-auto flex shrink-0 gap-1\", className)} {...props} />\n);\n\nexport type QueueItemActionProps = Omit<\n ComponentProps<typeof Button>,\n \"variant\" | \"size\"\n>;\n\nexport const QueueItemAction = ({\n className,\n ...props\n}: QueueItemActionProps) => (\n <Button\n className={cn(\n \"size-auto rounded p-1 text-muted-foreground opacity-0 transition-opacity hover:bg-muted-foreground/10 hover:text-foreground group-hover:opacity-100\",\n className\n )}\n size=\"icon\"\n type=\"button\"\n variant=\"ghost\"\n {...props}\n />\n);\n\n// ---------------------------------------------------------------------------\n// QueueItemAttachment / QueueItemImage / QueueItemFile\n// ---------------------------------------------------------------------------\n\nexport type QueueItemAttachmentProps = ComponentProps<\"div\">;\n\nexport const QueueItemAttachment = ({\n className,\n ...props\n}: QueueItemAttachmentProps) => (\n <div className={cn(\"flex flex-wrap gap-2\", className)} {...props} />\n);\n\nexport type QueueItemImageProps = ComponentProps<\"img\">;\n\nexport const QueueItemImage = ({\n className,\n ...props\n}: QueueItemImageProps) => (\n <img\n alt=\"\"\n className={cn(\"size-8 rounded border object-cover\", className)}\n height={32}\n width={32}\n {...props}\n />\n);\n\nexport type QueueItemFileProps = ComponentProps<\"span\">;\n\nexport const QueueItemFile = ({\n children,\n className,\n ...props\n}: QueueItemFileProps) => (\n <span\n className={cn(\n \"flex items-center gap-1 rounded border bg-muted px-2 py-1 text-xs\",\n className\n )}\n {...props}\n >\n <PaperclipIcon size={12} />\n <span className=\"max-w-[100px] truncate\">{children}</span>\n </span>\n);\n\n// ---------------------------------------------------------------------------\n// QueueList\n// ---------------------------------------------------------------------------\n\nexport type QueueListProps = ComponentProps<typeof ScrollArea>;\n\nexport const QueueList = ({\n children,\n className,\n ...props\n}: QueueListProps) => (\n <ScrollArea className={cn(\"-mb-1 mt-2\", className)} {...props}>\n <div className=\"max-h-40 pr-4\">\n <ul className=\"flex flex-col gap-0.5\">{children}</ul>\n </div>\n </ScrollArea>\n);\n\n// ---------------------------------------------------------------------------\n// QueueSection / QueueSectionTrigger / QueueSectionLabel / QueueSectionContent\n// ---------------------------------------------------------------------------\n\nexport type QueueSectionProps = ComponentProps<typeof Collapsible>;\n\nexport const QueueSection = ({\n className,\n defaultOpen = true,\n ...props\n}: QueueSectionProps) => (\n <Collapsible className={cn(className)} defaultOpen={defaultOpen} {...props} />\n);\n\nexport type QueueSectionTriggerProps = ComponentProps<\"button\">;\n\nexport const QueueSectionTrigger = ({\n children,\n className,\n ...props\n}: QueueSectionTriggerProps) => (\n <CollapsibleTrigger asChild>\n <button\n className={cn(\n \"group flex w-full items-center justify-between rounded-md bg-muted/40 px-3 py-2 text-left font-medium text-muted-foreground text-sm transition-colors hover:bg-muted\",\n className\n )}\n type=\"button\"\n {...props}\n >\n {children}\n </button>\n </CollapsibleTrigger>\n);\n\nexport type QueueSectionLabelProps = ComponentProps<\"span\"> & {\n count?: number;\n icon?: React.ReactNode;\n};\n\nexport const QueueSectionLabel = ({\n count,\n icon,\n className,\n children,\n ...props\n}: QueueSectionLabelProps) => (\n <span className={cn(\"flex items-center gap-2\", className)} {...props}>\n <ChevronDownIcon\n className=\"size-4 opacity-0 transition-all group-focus-visible:opacity-100 group-hover:opacity-100 group-data-[state=open]:opacity-100 group-data-[state=closed]:-rotate-90\"\n data-slot=\"collapsible-chevron\"\n />\n {icon}\n <span>\n {count === undefined ? \"\" : `${count} `}\n {children}\n </span>\n </span>\n);\n\nexport type QueueSectionContentProps = ComponentProps<typeof CollapsibleContent>;\n\nexport const QueueSectionContent = ({\n className,\n ...props\n}: QueueSectionContentProps) => (\n <CollapsibleContent className={cn(className)} {...props} />\n);\n\n// ---------------------------------------------------------------------------\n// Queue (root)\n// ---------------------------------------------------------------------------\n\nconst AUTO_HIDE_DELAY = 1000;\n\nexport type QueueProps = ComponentProps<\"div\"> & {\n isStreaming?: boolean;\n};\n\nexport const Queue = ({ className, isStreaming = false, children, style, id, ...props }: QueueProps) => {\n const [visible, setVisible] = useState(true);\n const hasEverStreamedRef = useRef(isStreaming);\n const [hasAutoHidden, setHasAutoHidden] = useState(false);\n\n useEffect(() => {\n if (isStreaming) hasEverStreamedRef.current = true;\n }, [isStreaming]);\n\n useEffect(() => {\n if (hasEverStreamedRef.current && !isStreaming && visible && !hasAutoHidden) {\n const timer = setTimeout(() => {\n setVisible(false);\n setHasAutoHidden(true);\n }, AUTO_HIDE_DELAY);\n return () => clearTimeout(timer);\n }\n }, [isStreaming, visible, hasAutoHidden]);\n\n // Spread data-* and aria-* attributes through; drop event handlers to avoid\n // onDrag type conflict between React and framer-motion.\n const passthroughProps = Object.fromEntries(\n Object.entries(props).filter(([k]) => k.startsWith(\"data-\") || k.startsWith(\"aria-\"))\n );\n\n return (\n <AnimatePresence>\n {visible && (\n <motion.div\n {...passthroughProps}\n className={cn(\n \"flex flex-col gap-2 rounded-xl border border-border bg-background px-2 pb-2 pt-2 shadow-xs\",\n className\n )}\n exit={{ opacity: 0, height: 0, marginTop: 0, marginBottom: 0, paddingTop: 0, paddingBottom: 0, overflow: \"hidden\" }}\n id={id}\n style={style}\n transition={{ duration: 0.35, ease: \"easeOut\" }}\n >\n {children}\n </motion.div>\n )}\n </AnimatePresence>\n );\n};\n"],"names":["QueueItem","className","props","jsx","cn","INDICATOR_STATUS","QueueItemIndicator","status","completed","QueueItemContent","QueueItemDescription","QueueItemActions","QueueItemAction","Button","QueueItemAttachment","QueueItemImage","QueueItemFile","children","jsxs","PaperclipIcon","QueueList","ScrollArea","QueueSection","defaultOpen","Collapsible","QueueSectionTrigger","CollapsibleTrigger","QueueSectionLabel","count","icon","ChevronDownIcon","QueueSectionContent","CollapsibleContent","AUTO_HIDE_DELAY","Queue","isStreaming","style","id","visible","setVisible","useState","hasEverStreamedRef","useRef","hasAutoHidden","setHasAutoHidden","useEffect","timer","passthroughProps","k","AnimatePresence","motion"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("react/jsx-runtime"),j=require("@radix-ui/react-use-controllable-state"),M=require("@streamdown/cjk"),P=require("@streamdown/code"),A=require("@streamdown/math"),I=require("@streamdown/mermaid"),b=require("lucide-react"),t=require("react"),S=require("streamdown"),_=require("./shimmer.cjs"),f=require("../ui/collapsible.cjs"),l=require("../../lib/utils.cjs"),T=t.createContext(null),q=()=>{const o=t.useContext(T);if(!o)throw new Error("Reasoning components must be used within Reasoning");return o},z=1e3,L=1e3,v=t.memo(({className:o,isStreaming:e=!1,open:a,defaultOpen:i,onOpenChange:u,duration:d,children:m,...N})=>{const E=i??e,g=i===!1,[r,s]=j.useControllableState({defaultProp:E,onChange:u,prop:a}),[h,x]=j.useControllableState({defaultProp:void 0,prop:d}),C=t.useRef(e),[R,O]=t.useState(!1),c=t.useRef(null);t.useEffect(()=>{e?(C.current=!0,c.current===null&&(c.current=Date.now())):c.current!==null&&(x(Math.ceil((Date.now()-c.current)/L)),c.current=null)},[e,x]),t.useEffect(()=>{e&&!r&&!g&&s(!0)},[e,r,s,g]),t.useEffect(()=>{if(C.current&&!e&&r&&!R){const p=setTimeout(()=>{s(!1),O(!0)},z);return()=>clearTimeout(p)}},[e,r,s,R]);const k=t.useCallback(p=>{s(p)},[s]),D=t.useMemo(()=>({duration:h,isOpen:r,isStreaming:e,setIsOpen:s}),[h,r,e,s]);return n.jsx(T.Provider,{value:D,children:n.jsx(f.Collapsible,{className:l.cn("not-prose mb-4",o),onOpenChange:k,open:r,...N,children:m})})}),U=(o,e)=>o||e===0?n.jsx(_.Shimmer,{duration:1,children:"Thinking..."}):e===void 0?n.jsx("p",{children:"Thought for a few seconds"}):n.jsxs("p",{children:["Thought for ",e," seconds"]}),w=t.memo(({className:o,children:e,getThinkingMessage:a=U,...i})=>{const{isStreaming:u,isOpen:d,duration:m}=q();return n.jsx(f.CollapsibleTrigger,{className:l.cn("group flex w-full items-center gap-2 text-muted-foreground text-sm transition-colors hover:text-foreground",o),...i,children:e??n.jsxs(n.Fragment,{children:[n.jsx(b.BrainIcon,{className:"size-4"}),a(u,m),n.jsx(b.ChevronDownIcon,{className:l.cn("size-4 opacity-0 transition-all group-focus-visible:opacity-100 group-hover:opacity-100",d?"rotate-180 opacity-100":"rotate-0"),"data-slot":"collapsible-chevron"})]})})}),B={cjk:M.cjk,code:P.code,math:A.math,mermaid:I.mermaid},y=t.memo(({className:o,children:e,...a})=>n.jsx(f.CollapsibleContent,{className:l.cn("mt-4 text-sm","data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-muted-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in",o),...a,children:n.jsx(S.Streamdown,{plugins:B,children:e})}));v.displayName="Reasoning";w.displayName="ReasoningTrigger";y.displayName="ReasoningContent";exports.Reasoning=v;exports.ReasoningContent=y;exports.ReasoningTrigger=w;exports.useReasoning=q;
2
+ //# sourceMappingURL=reasoning.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reasoning.cjs","sources":["../../../src/components/ai/reasoning.tsx"],"sourcesContent":["import { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { cjk } from \"@streamdown/cjk\";\nimport { code } from \"@streamdown/code\";\nimport { math } from \"@streamdown/math\";\nimport { mermaid } from \"@streamdown/mermaid\";\nimport { BrainIcon, ChevronDownIcon } from \"lucide-react\";\nimport {\n createContext,\n memo,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { Streamdown } from \"streamdown\";\n\nimport { Shimmer } from \"./shimmer\";\n\nimport type { ComponentProps, ReactNode } from \"react\";\n\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@/components/ui/collapsible\";\nimport { cn } from \"@/lib/utils\";\n\ninterface ReasoningContextValue {\n isStreaming: boolean;\n isOpen: boolean;\n setIsOpen: (open: boolean) => void;\n duration: number | undefined;\n}\n\nconst ReasoningContext = createContext<ReasoningContextValue | null>(null);\n\nexport const useReasoning = () => {\n const context = useContext(ReasoningContext);\n if (!context) {\n throw new Error(\"Reasoning components must be used within Reasoning\");\n }\n return context;\n};\n\nexport type ReasoningProps = ComponentProps<typeof Collapsible> & {\n isStreaming?: boolean;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n duration?: number;\n};\n\nconst AUTO_CLOSE_DELAY = 1000;\nconst MS_IN_S = 1000;\n\nexport const Reasoning = memo(\n ({\n className,\n isStreaming = false,\n open,\n defaultOpen,\n onOpenChange,\n duration: durationProp,\n children,\n ...props\n }: ReasoningProps) => {\n const resolvedDefaultOpen = defaultOpen ?? isStreaming;\n // Track if defaultOpen was explicitly set to false (to prevent auto-open)\n const isExplicitlyClosed = defaultOpen === false;\n\n const [isOpen, setIsOpen] = useControllableState<boolean>({\n defaultProp: resolvedDefaultOpen,\n onChange: onOpenChange,\n prop: open,\n });\n const [duration, setDuration] = useControllableState<number | undefined>({\n defaultProp: undefined,\n prop: durationProp,\n });\n\n const hasEverStreamedRef = useRef(isStreaming);\n const [hasAutoClosed, setHasAutoClosed] = useState(false);\n const startTimeRef = useRef<number | null>(null);\n\n // Track when streaming starts and compute duration\n useEffect(() => {\n if (isStreaming) {\n hasEverStreamedRef.current = true;\n if (startTimeRef.current === null) {\n startTimeRef.current = Date.now();\n }\n } else if (startTimeRef.current !== null) {\n setDuration(Math.ceil((Date.now() - startTimeRef.current) / MS_IN_S));\n startTimeRef.current = null;\n }\n }, [isStreaming, setDuration]);\n\n // Auto-open when streaming starts (unless explicitly closed)\n useEffect(() => {\n if (isStreaming && !isOpen && !isExplicitlyClosed) {\n setIsOpen(true);\n }\n }, [isStreaming, isOpen, setIsOpen, isExplicitlyClosed]);\n\n // Auto-close when streaming ends (once only, and only if it ever streamed)\n useEffect(() => {\n if (\n hasEverStreamedRef.current &&\n !isStreaming &&\n isOpen &&\n !hasAutoClosed\n ) {\n const timer = setTimeout(() => {\n setIsOpen(false);\n setHasAutoClosed(true);\n }, AUTO_CLOSE_DELAY);\n\n return () => clearTimeout(timer);\n }\n }, [isStreaming, isOpen, setIsOpen, hasAutoClosed]);\n\n const handleOpenChange = useCallback(\n (newOpen: boolean) => {\n setIsOpen(newOpen);\n },\n [setIsOpen]\n );\n\n const contextValue = useMemo(\n () => ({ duration, isOpen, isStreaming, setIsOpen }),\n [duration, isOpen, isStreaming, setIsOpen]\n );\n\n return (\n <ReasoningContext.Provider value={contextValue}>\n <Collapsible\n className={cn(\"not-prose mb-4\", className)}\n onOpenChange={handleOpenChange}\n open={isOpen}\n {...props}\n >\n {children}\n </Collapsible>\n </ReasoningContext.Provider>\n );\n }\n);\n\nexport type ReasoningTriggerProps = ComponentProps<\n typeof CollapsibleTrigger\n> & {\n getThinkingMessage?: (isStreaming: boolean, duration?: number) => ReactNode;\n};\n\nconst defaultGetThinkingMessage = (isStreaming: boolean, duration?: number) => {\n if (isStreaming || duration === 0) {\n return <Shimmer duration={1}>Thinking...</Shimmer>;\n }\n if (duration === undefined) {\n return <p>Thought for a few seconds</p>;\n }\n return <p>Thought for {duration} seconds</p>;\n};\n\nexport const ReasoningTrigger = memo(\n ({\n className,\n children,\n getThinkingMessage = defaultGetThinkingMessage,\n ...props\n }: ReasoningTriggerProps) => {\n const { isStreaming, isOpen, duration } = useReasoning();\n\n return (\n <CollapsibleTrigger\n className={cn(\n \"group flex w-full items-center gap-2 text-muted-foreground text-sm transition-colors hover:text-foreground\",\n className\n )}\n {...props}\n >\n {children ?? (\n <>\n <BrainIcon className=\"size-4\" />\n {getThinkingMessage(isStreaming, duration)}\n <ChevronDownIcon\n className={cn(\n \"size-4 opacity-0 transition-all group-focus-visible:opacity-100 group-hover:opacity-100\",\n isOpen ? \"rotate-180 opacity-100\" : \"rotate-0\"\n )}\n data-slot=\"collapsible-chevron\"\n />\n </>\n )}\n </CollapsibleTrigger>\n );\n }\n);\n\nexport type ReasoningContentProps = ComponentProps<\n typeof CollapsibleContent\n> & {\n children: string;\n};\n\nconst streamdownPlugins = { cjk, code, math, mermaid };\n\nexport const ReasoningContent = memo(\n ({ className, children, ...props }: ReasoningContentProps) => (\n <CollapsibleContent\n className={cn(\n \"mt-4 text-sm\",\n \"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-muted-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in\",\n className\n )}\n {...props}\n >\n <Streamdown plugins={streamdownPlugins}>{children}</Streamdown>\n </CollapsibleContent>\n )\n);\n\nReasoning.displayName = \"Reasoning\";\nReasoningTrigger.displayName = \"ReasoningTrigger\";\nReasoningContent.displayName = \"ReasoningContent\";\n"],"names":["ReasoningContext","createContext","useReasoning","context","useContext","AUTO_CLOSE_DELAY","MS_IN_S","Reasoning","memo","className","isStreaming","open","defaultOpen","onOpenChange","durationProp","children","props","resolvedDefaultOpen","isExplicitlyClosed","isOpen","setIsOpen","useControllableState","duration","setDuration","hasEverStreamedRef","useRef","hasAutoClosed","setHasAutoClosed","useState","startTimeRef","useEffect","timer","handleOpenChange","useCallback","newOpen","contextValue","useMemo","jsx","Collapsible","cn","defaultGetThinkingMessage","Shimmer","ReasoningTrigger","getThinkingMessage","CollapsibleTrigger","jsxs","Fragment","BrainIcon","ChevronDownIcon","streamdownPlugins","cjk","code","math","mermaid","ReasoningContent","CollapsibleContent","Streamdown"],"mappings":"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"}
@@ -0,0 +1,129 @@
1
+ import { jsx as o, jsxs as w, Fragment as k } from "react/jsx-runtime";
2
+ import { useControllableState as v } from "@radix-ui/react-use-controllable-state";
3
+ import { cjk as A } from "@streamdown/cjk";
4
+ import { code as I } from "@streamdown/code";
5
+ import { math as M } from "@streamdown/math";
6
+ import { mermaid as P } from "@streamdown/mermaid";
7
+ import { BrainIcon as _, ChevronDownIcon as j } from "lucide-react";
8
+ import { createContext as z, memo as f, useRef as T, useState as L, useEffect as d, useCallback as B, useMemo as F, useContext as G } from "react";
9
+ import { Streamdown as H } from "streamdown";
10
+ import { Shimmer as U } from "./shimmer.js";
11
+ import { Collapsible as V, CollapsibleTrigger as Y, CollapsibleContent as q } from "../ui/collapsible.js";
12
+ import { cn as l } from "../../lib/utils.js";
13
+ const b = z(null), J = () => {
14
+ const t = G(b);
15
+ if (!t)
16
+ throw new Error("Reasoning components must be used within Reasoning");
17
+ return t;
18
+ }, K = 1e3, Q = 1e3, S = f(
19
+ ({
20
+ className: t,
21
+ isStreaming: e = !1,
22
+ open: s,
23
+ defaultOpen: i,
24
+ onOpenChange: c,
25
+ duration: u,
26
+ children: m,
27
+ ...N
28
+ }) => {
29
+ const y = i ?? e, h = i === !1, [r, n] = v({
30
+ defaultProp: y,
31
+ onChange: c,
32
+ prop: s
33
+ }), [g, C] = v({
34
+ defaultProp: void 0,
35
+ prop: u
36
+ }), x = T(e), [R, O] = L(!1), a = T(null);
37
+ d(() => {
38
+ e ? (x.current = !0, a.current === null && (a.current = Date.now())) : a.current !== null && (C(Math.ceil((Date.now() - a.current) / Q)), a.current = null);
39
+ }, [e, C]), d(() => {
40
+ e && !r && !h && n(!0);
41
+ }, [e, r, n, h]), d(() => {
42
+ if (x.current && !e && r && !R) {
43
+ const p = setTimeout(() => {
44
+ n(!1), O(!0);
45
+ }, K);
46
+ return () => clearTimeout(p);
47
+ }
48
+ }, [e, r, n, R]);
49
+ const D = B(
50
+ (p) => {
51
+ n(p);
52
+ },
53
+ [n]
54
+ ), E = F(
55
+ () => ({ duration: g, isOpen: r, isStreaming: e, setIsOpen: n }),
56
+ [g, r, e, n]
57
+ );
58
+ return /* @__PURE__ */ o(b.Provider, { value: E, children: /* @__PURE__ */ o(
59
+ V,
60
+ {
61
+ className: l("not-prose mb-4", t),
62
+ onOpenChange: D,
63
+ open: r,
64
+ ...N,
65
+ children: m
66
+ }
67
+ ) });
68
+ }
69
+ ), W = (t, e) => t || e === 0 ? /* @__PURE__ */ o(U, { duration: 1, children: "Thinking..." }) : e === void 0 ? /* @__PURE__ */ o("p", { children: "Thought for a few seconds" }) : /* @__PURE__ */ w("p", { children: [
70
+ "Thought for ",
71
+ e,
72
+ " seconds"
73
+ ] }), X = f(
74
+ ({
75
+ className: t,
76
+ children: e,
77
+ getThinkingMessage: s = W,
78
+ ...i
79
+ }) => {
80
+ const { isStreaming: c, isOpen: u, duration: m } = J();
81
+ return /* @__PURE__ */ o(
82
+ Y,
83
+ {
84
+ className: l(
85
+ "group flex w-full items-center gap-2 text-muted-foreground text-sm transition-colors hover:text-foreground",
86
+ t
87
+ ),
88
+ ...i,
89
+ children: e ?? /* @__PURE__ */ w(k, { children: [
90
+ /* @__PURE__ */ o(_, { className: "size-4" }),
91
+ s(c, m),
92
+ /* @__PURE__ */ o(
93
+ j,
94
+ {
95
+ className: l(
96
+ "size-4 opacity-0 transition-all group-focus-visible:opacity-100 group-hover:opacity-100",
97
+ u ? "rotate-180 opacity-100" : "rotate-0"
98
+ ),
99
+ "data-slot": "collapsible-chevron"
100
+ }
101
+ )
102
+ ] })
103
+ }
104
+ );
105
+ }
106
+ ), Z = { cjk: A, code: I, math: M, mermaid: P }, $ = f(
107
+ ({ className: t, children: e, ...s }) => /* @__PURE__ */ o(
108
+ q,
109
+ {
110
+ className: l(
111
+ "mt-4 text-sm",
112
+ "data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-muted-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in",
113
+ t
114
+ ),
115
+ ...s,
116
+ children: /* @__PURE__ */ o(H, { plugins: Z, children: e })
117
+ }
118
+ )
119
+ );
120
+ S.displayName = "Reasoning";
121
+ X.displayName = "ReasoningTrigger";
122
+ $.displayName = "ReasoningContent";
123
+ export {
124
+ S as Reasoning,
125
+ $ as ReasoningContent,
126
+ X as ReasoningTrigger,
127
+ J as useReasoning
128
+ };
129
+ //# sourceMappingURL=reasoning.js.map