@humain/ui 2.2.6 → 2.2.9

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 (159) hide show
  1. package/dist/index101.js +2 -2
  2. package/dist/index101.js.map +1 -1
  3. package/dist/index103.js +3 -3
  4. package/dist/index103.js.map +1 -1
  5. package/dist/index108.js +1 -1
  6. package/dist/index108.js.map +1 -1
  7. package/dist/index117.js +1 -1
  8. package/dist/index117.js.map +1 -1
  9. package/dist/index122.js +6 -6
  10. package/dist/index122.js.map +1 -1
  11. package/dist/index126.js +1 -1
  12. package/dist/index126.js.map +1 -1
  13. package/dist/index130.js +2 -2
  14. package/dist/index130.js.map +1 -1
  15. package/dist/index146.js +4 -4
  16. package/dist/index146.js.map +1 -1
  17. package/dist/index152.js +1 -1
  18. package/dist/index152.js.map +1 -1
  19. package/dist/index154.js +2 -2
  20. package/dist/index154.js.map +1 -1
  21. package/dist/index166.js +1 -1
  22. package/dist/index166.js.map +1 -1
  23. package/dist/index168.js +1 -1
  24. package/dist/index168.js.map +1 -1
  25. package/dist/index169.js +1 -1
  26. package/dist/index169.js.map +1 -1
  27. package/dist/index173.js +2 -2
  28. package/dist/index173.js.map +1 -1
  29. package/dist/index175.js +4 -4
  30. package/dist/index175.js.map +1 -1
  31. package/dist/index176.js +2 -2
  32. package/dist/index176.js.map +1 -1
  33. package/dist/index177.js +2 -2
  34. package/dist/index177.js.map +1 -1
  35. package/dist/index184.js +1 -1
  36. package/dist/index184.js.map +1 -1
  37. package/dist/index191.js +3 -3
  38. package/dist/index191.js.map +1 -1
  39. package/dist/index192.js +2 -2
  40. package/dist/index192.js.map +1 -1
  41. package/dist/index201.js +2 -2
  42. package/dist/index201.js.map +1 -1
  43. package/dist/index204.js +4 -4
  44. package/dist/index204.js.map +1 -1
  45. package/dist/index228.js +1 -1
  46. package/dist/index228.js.map +1 -1
  47. package/dist/index229.js +1 -1
  48. package/dist/index229.js.map +1 -1
  49. package/dist/index24.js +2 -2
  50. package/dist/index24.js.map +1 -1
  51. package/dist/index5.js +1 -1
  52. package/dist/index5.js.map +1 -1
  53. package/dist/styles.css +1 -1
  54. package/dist/wc/AICodeBlock.js +41 -41
  55. package/dist/wc/AICodeBlock.js.map +1 -1
  56. package/dist/wc/AIMermaidDiagram.js +7 -7
  57. package/dist/wc/AIMermaidDiagram.js.map +1 -1
  58. package/dist/wc/AIMessage.js +6 -6
  59. package/dist/wc/AIMessage.js.map +1 -1
  60. package/dist/wc/AISource.js +2 -2
  61. package/dist/wc/AISource.js.map +1 -1
  62. package/dist/wc/AIToolCall.js +1 -1
  63. package/dist/wc/AIToolCall.js.map +1 -1
  64. package/dist/wc/Breadcrumb.js +43 -43
  65. package/dist/wc/Breadcrumb.js.map +1 -1
  66. package/dist/wc/DropdownMenu.js +9 -9
  67. package/dist/wc/DropdownMenu.js.map +1 -1
  68. package/dist/wc/Kbd.js +22 -22
  69. package/dist/wc/Kbd.js.map +1 -1
  70. package/dist/wc/button.js +7 -7
  71. package/dist/wc/button.js.map +1 -1
  72. package/dist/wc/close-button.js +19 -19
  73. package/dist/wc/close-button.js.map +1 -1
  74. package/dist/wc/hf-ai-prompt-suggestion.js +14 -14
  75. package/dist/wc/hf-ai-prompt-suggestion.js.map +1 -1
  76. package/dist/wc/hf-ai-reasoning-block.js +13 -13
  77. package/dist/wc/hf-ai-reasoning-block.js.map +1 -1
  78. package/dist/wc/hf-ai-steps.js +53 -53
  79. package/dist/wc/hf-ai-steps.js.map +1 -1
  80. package/dist/wc/hf-ai-system-message.js +26 -26
  81. package/dist/wc/hf-ai-system-message.js.map +1 -1
  82. package/dist/wc/hf-code-snippet.js +35 -35
  83. package/dist/wc/hf-code-snippet.js.map +1 -1
  84. package/dist/wc/hf-command-menu.js +39 -39
  85. package/dist/wc/hf-command-menu.js.map +1 -1
  86. package/dist/wc/hf-data-table.js +3 -3
  87. package/dist/wc/hf-data-table.js.map +1 -1
  88. package/dist/wc/hf-display-value.js +50 -50
  89. package/dist/wc/hf-display-value.js.map +1 -1
  90. package/dist/wc/hf-nav-account-menu.js +5 -5
  91. package/dist/wc/hf-nav-account-menu.js.map +1 -1
  92. package/dist/wc/hf-rich-textarea.js +1 -1
  93. package/dist/wc/hf-rich-textarea.js.map +1 -1
  94. package/dist/wc/hf-steps.js +8 -8
  95. package/dist/wc/hf-steps.js.map +1 -1
  96. package/dist/wc/markdown-renderer.js +1 -1
  97. package/dist/wc/markdown-renderer.js.map +1 -1
  98. package/dist/wc/selection-group.js +26 -26
  99. package/dist/wc/selection-group.js.map +1 -1
  100. package/dist/wc/syntax-highlight.js +4 -4
  101. package/dist/wc/syntax-highlight.js.map +1 -1
  102. package/dist/wc/workflow-step-renderer.js +51 -51
  103. package/dist/wc/workflow-step-renderer.js.map +1 -1
  104. package/dist/wc-react/AICodeBlock.js +17 -17
  105. package/dist/wc-react/AICodeBlock.js.map +1 -1
  106. package/dist/wc-react/AIMermaidDiagram.js +16 -16
  107. package/dist/wc-react/AIMermaidDiagram.js.map +1 -1
  108. package/dist/wc-react/AIMessage.js +7 -7
  109. package/dist/wc-react/AIMessage.js.map +1 -1
  110. package/dist/wc-react/AISource.js +41 -41
  111. package/dist/wc-react/AISource.js.map +1 -1
  112. package/dist/wc-react/AIToolCall.js +6 -6
  113. package/dist/wc-react/AIToolCall.js.map +1 -1
  114. package/dist/wc-react/Breadcrumb.js +18 -18
  115. package/dist/wc-react/Breadcrumb.js.map +1 -1
  116. package/dist/wc-react/DropdownMenu.js +27 -27
  117. package/dist/wc-react/DropdownMenu.js.map +1 -1
  118. package/dist/wc-react/Kbd.js +17 -17
  119. package/dist/wc-react/Kbd.js.map +1 -1
  120. package/dist/wc-react/button.js +12 -12
  121. package/dist/wc-react/button.js.map +1 -1
  122. package/dist/wc-react/close-button.js +19 -19
  123. package/dist/wc-react/close-button.js.map +1 -1
  124. package/dist/wc-react/hf-ai-prompt-suggestion.js +1 -1
  125. package/dist/wc-react/hf-ai-prompt-suggestion.js.map +1 -1
  126. package/dist/wc-react/hf-ai-reasoning-block.js +1 -1
  127. package/dist/wc-react/hf-ai-reasoning-block.js.map +1 -1
  128. package/dist/wc-react/hf-ai-steps.js +33 -33
  129. package/dist/wc-react/hf-ai-steps.js.map +1 -1
  130. package/dist/wc-react/hf-ai-system-message.js +9 -9
  131. package/dist/wc-react/hf-ai-system-message.js.map +1 -1
  132. package/dist/wc-react/hf-code-snippet.js +3 -3
  133. package/dist/wc-react/hf-code-snippet.js.map +1 -1
  134. package/dist/wc-react/hf-command-menu.js +56 -56
  135. package/dist/wc-react/hf-command-menu.js.map +1 -1
  136. package/dist/wc-react/hf-data-table.js +3 -3
  137. package/dist/wc-react/hf-data-table.js.map +1 -1
  138. package/dist/wc-react/hf-display-value.js +58 -58
  139. package/dist/wc-react/hf-display-value.js.map +1 -1
  140. package/dist/wc-react/hf-nav-account-menu.js +7 -7
  141. package/dist/wc-react/hf-nav-account-menu.js.map +1 -1
  142. package/dist/wc-react/hf-rich-textarea.js +5 -5
  143. package/dist/wc-react/hf-rich-textarea.js.map +1 -1
  144. package/dist/wc-react/hf-steps.js +2 -2
  145. package/dist/wc-react/hf-steps.js.map +1 -1
  146. package/dist/wc-react/markdown-renderer.js +1 -1
  147. package/dist/wc-react/markdown-renderer.js.map +1 -1
  148. package/dist/wc-react/selection-group.js +7 -7
  149. package/dist/wc-react/selection-group.js.map +1 -1
  150. package/dist/wc-react/syntax-highlight.js +4 -4
  151. package/dist/wc-react/syntax-highlight.js.map +1 -1
  152. package/dist/wc-react/workflow-step-renderer.js +44 -44
  153. package/dist/wc-react/workflow-step-renderer.js.map +1 -1
  154. package/package.json +1 -1
  155. package/skills/humain-ui/SKILL.md +1 -1
  156. package/skills/humain-ui-wc/SKILL.md +1 -1
  157. package/skills/humain-ui-wc.skill +0 -0
  158. package/skills/humain-ui.skill +0 -0
  159. package/src/tokens.css +4 -0
@@ -1 +1 @@
1
- {"version":3,"file":"AIMessage.js","names":[],"sources":["../../src/components/organisms/ai/AIMessage/AIMessage.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { Check, Copy, List, ThumbsDown, ThumbsUp } from 'lucide-react';\nimport * as React from 'react';\nimport { forwardRef, type HTMLAttributes } from 'react';\nimport { Avatar, type AvatarProps } from '@/components/molecules/data/Avatar';\nimport { FileTypeIcon } from '@/components/molecules/files/FileTypeIcon';\nimport type { AIInteractionEvent } from '@/components/organisms/ai/_shared/interaction-context';\nimport { AIInteractionProvider } from '@/components/organisms/ai/_shared/interaction-context';\nimport { MarkdownRenderer } from '@/components/organisms/ai/_shared/markdown-renderer';\nimport { AITypingIndicator } from '@/components/organisms/ai/AITypingIndicator';\nimport { createSafeContext } from '@/lib/create-safe-context';\nimport { cn } from '@/lib/utils';\n\n// =============================================================================\n// Message Variants\n// =============================================================================\n\nconst messageVariants = cva('flex items-start w-full', {\n variants: {\n type: {\n received: 'justify-start',\n sent: 'justify-end',\n },\n },\n defaultVariants: {\n type: 'received',\n },\n});\n\nconst messageOverflowWrapClasses =\n 'min-w-0 max-w-full break-words [overflow-wrap:anywhere]';\n\nconst messageBubbleVariants = cva(\n 'flex min-w-0 max-w-[min(720px,100%)] flex-col gap-1 overflow-hidden px-4 py-3 rounded-2xl',\n {\n variants: {\n type: {\n received: 'bg-muted rounded-es-sm',\n sent: 'bg-primary text-primary-foreground rounded-ee-sm',\n },\n },\n defaultVariants: {\n type: 'received',\n },\n },\n);\n\n// =============================================================================\n// Context for Composable API\n// =============================================================================\n\ninterface AIMessageContextValue {\n /** Message type */\n type: 'received' | 'sent';\n /** Whether sender is an AI agent */\n isAgent: boolean;\n /** Whether in compact mode */\n compact: boolean;\n /** Whether AI is typing */\n isTyping: boolean;\n /** Callback when thumbs up is clicked */\n onThumbsUp?: () => void;\n /** Callback when thumbs down is clicked */\n onThumbsDown?: () => void;\n /** Callback when copy is clicked */\n onCopy?: () => void;\n /** Callback when list/expand is clicked */\n onShowList?: () => void;\n /** Whether thumbs up is active */\n thumbsUpActive?: boolean;\n /** Whether thumbs down is active */\n thumbsDownActive?: boolean;\n}\n\nconst [AIMessageContext, useAIMessageContext] =\n createSafeContext<AIMessageContextValue>('AIMessage');\n\n// =============================================================================\n// AIMessage.Bubble - Bubble wrapper for header + content\n// =============================================================================\n\nexport interface AIMessageBubbleProps {\n /** Children (Header, Content, TypingIndicator) */\n children?: React.ReactNode;\n /** Additional class name */\n className?: string;\n}\n\nfunction AIMessageBubble({ children, className }: AIMessageBubbleProps) {\n const ctx = React.useContext(AIMessageContext);\n const type = ctx?.type ?? 'received';\n\n return (\n <div\n data-slot=\"ai-message-bubble\"\n data-message-type={type}\n className={cn(messageBubbleVariants({ type }), className)}\n >\n {children}\n </div>\n );\n}\n\nAIMessageBubble.displayName = 'AIMessage.Bubble';\n\n// =============================================================================\n// Reaction Button (Internal)\n// =============================================================================\n\ninterface ReactionButtonProps {\n icon: React.ReactNode;\n onClick?: () => void;\n active?: boolean;\n count?: number;\n /** Accessible label for the button */\n label?: string;\n className?: string;\n}\n\nfunction ReactionButton({\n icon,\n onClick,\n active,\n count,\n label,\n className,\n}: ReactionButtonProps) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n aria-label={label}\n aria-pressed={active}\n className={cn(\n 'flex items-center justify-center gap-1 px-2.5 py-2 min-w-11 min-h-11 rounded-full bg-muted hover:bg-accent delight-click-ripple transition-all duration-150 ease-out hover:scale-110 active:scale-95 motion-reduce:hover:scale-100 motion-reduce:active:scale-100 focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-ring',\n active &&\n 'bg-primary/10 text-primary delight-check-bounce motion-reduce:!animate-none',\n className,\n )}\n >\n {icon}\n {count !== undefined && count > 0 && (\n <span className=\"text-xs font-medium text-muted-foreground\">\n {count}\n </span>\n )}\n </button>\n );\n}\n\n// =============================================================================\n// Emoji Reaction Types\n// =============================================================================\n\nexport interface EmojiReaction {\n emoji: string;\n count: number;\n reacted?: boolean;\n}\n\n// =============================================================================\n// AIMessage.Reactions - Emoji reactions display\n// =============================================================================\n\nexport interface AIMessageReactionsProps {\n /** Emoji reactions to display */\n reactions: EmojiReaction[];\n /** Callback when reaction is clicked */\n onReactionClick?: (emoji: string) => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction AIMessageReactions({\n reactions,\n onReactionClick,\n className,\n}: AIMessageReactionsProps) {\n if (!reactions?.length) return null;\n\n return (\n <div\n data-slot=\"ai-message-reactions\"\n className={cn('flex items-center gap-1', className)}\n >\n {reactions.map((reaction) => (\n <button\n key={reaction.emoji}\n type=\"button\"\n onClick={() => onReactionClick?.(reaction.emoji)}\n aria-label={`React with ${reaction.emoji}${reaction.count > 1 ? `, ${reaction.count} reactions` : ''}`}\n aria-pressed={reaction.reacted}\n className={cn(\n 'flex items-center gap-1 px-2.5 py-1.5 min-h-11 rounded-full bg-muted hover:bg-accent text-sm transition-colors focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-ring',\n reaction.reacted && 'bg-primary/10',\n )}\n >\n <span aria-hidden=\"true\">{reaction.emoji}</span>\n {reaction.count > 1 && (\n <span className=\"text-xs text-muted-foreground\">\n {reaction.count}\n </span>\n )}\n </button>\n ))}\n </div>\n );\n}\n\nAIMessageReactions.displayName = 'AIMessage.Reactions';\n\n// =============================================================================\n// AIMessage.ThumbsUp - Thumbs up button\n// =============================================================================\n\nexport interface AIMessageThumbsUpProps {\n /** Click handler */\n onClick?: () => void;\n /** Whether active */\n active?: boolean;\n /** Additional class name */\n className?: string;\n}\n\nfunction AIMessageThumbsUp({\n onClick,\n active,\n className,\n}: AIMessageThumbsUpProps) {\n return (\n <ReactionButton\n icon={\n <ThumbsUp className=\"size-4 text-text-quaternary\" aria-hidden=\"true\" />\n }\n onClick={onClick}\n active={active}\n label=\"Thumbs up\"\n className={className}\n />\n );\n}\n\nAIMessageThumbsUp.displayName = 'AIMessage.ThumbsUp';\n\n// =============================================================================\n// AIMessage.ThumbsDown - Thumbs down button\n// =============================================================================\n\nexport interface AIMessageThumbsDownProps {\n /** Click handler */\n onClick?: () => void;\n /** Whether active */\n active?: boolean;\n /** Additional class name */\n className?: string;\n}\n\nfunction AIMessageThumbsDown({\n onClick,\n active,\n className,\n}: AIMessageThumbsDownProps) {\n return (\n <ReactionButton\n icon={\n <ThumbsDown\n className=\"size-4 text-text-quaternary\"\n aria-hidden=\"true\"\n />\n }\n onClick={onClick}\n active={active}\n label=\"Thumbs down\"\n className={className}\n />\n );\n}\n\nAIMessageThumbsDown.displayName = 'AIMessage.ThumbsDown';\n\n// =============================================================================\n// AIMessage.CopyButton - Copy button\n// =============================================================================\n\nexport interface AIMessageCopyButtonProps {\n /** Click handler */\n onClick?: () => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction AIMessageCopyButton({ onClick, className }: AIMessageCopyButtonProps) {\n const [copied, setCopied] = React.useState(false);\n const timerRef = React.useRef<ReturnType<typeof setTimeout>>(undefined);\n\n React.useEffect(() => () => clearTimeout(timerRef.current), []);\n\n const handleClick = React.useCallback(() => {\n onClick?.();\n setCopied(true);\n clearTimeout(timerRef.current);\n timerRef.current = setTimeout(() => setCopied(false), 2000);\n }, [onClick]);\n\n return (\n <ReactionButton\n icon={\n copied ? (\n <Check\n className=\"size-4 text-success delight-bounce-in motion-reduce:animate-none\"\n aria-hidden=\"true\"\n />\n ) : (\n <Copy\n className=\"size-4 text-secondary-foreground\"\n aria-hidden=\"true\"\n />\n )\n }\n onClick={handleClick}\n label={copied ? 'Copied to clipboard' : 'Copy message'}\n className={className}\n />\n );\n}\n\nAIMessageCopyButton.displayName = 'AIMessage.CopyButton';\n\n// =============================================================================\n// AIMessage.ListButton - List/expand button\n// =============================================================================\n\nexport interface AIMessageListButtonProps {\n /** Click handler */\n onClick?: () => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction AIMessageListButton({ onClick, className }: AIMessageListButtonProps) {\n return (\n <ReactionButton\n icon={\n <List className=\"size-4 text-secondary-foreground\" aria-hidden=\"true\" />\n }\n onClick={onClick}\n label=\"Show list\"\n className={className}\n />\n );\n}\n\nAIMessageListButton.displayName = 'AIMessage.ListButton';\n\n// =============================================================================\n// AIMessage.Actions - Action toolbar container\n// =============================================================================\n\nexport interface AIMessageActionsProps {\n /** Children (action buttons) */\n children?: React.ReactNode;\n /** Additional class name */\n className?: string;\n}\n\nfunction AIMessageActions({ children, className }: AIMessageActionsProps) {\n const ctx = React.useContext(AIMessageContext);\n\n return (\n <div\n data-slot=\"ai-message-actions\"\n role=\"toolbar\"\n aria-label=\"Message actions\"\n className={cn(\n 'flex items-center gap-0.5 rounded-full overflow-hidden',\n className,\n )}\n >\n {children ??\n (ctx && (\n <>\n <AIMessageThumbsUp\n onClick={ctx.onThumbsUp}\n active={ctx.thumbsUpActive}\n />\n <AIMessageThumbsDown\n onClick={ctx.onThumbsDown}\n active={ctx.thumbsDownActive}\n />\n <AIMessageCopyButton onClick={ctx.onCopy} />\n <AIMessageListButton onClick={ctx.onShowList} />\n </>\n ))}\n </div>\n );\n}\n\nAIMessageActions.displayName = 'AIMessage.Actions';\n\n// =============================================================================\n// AIMessage.TypingIndicator - Bouncing dots\n// =============================================================================\n\nexport interface AIMessageTypingIndicatorProps {\n /** Additional class name */\n className?: string;\n}\n\nfunction AIMessageTypingIndicator({\n className,\n}: AIMessageTypingIndicatorProps) {\n return (\n <div\n data-slot=\"ai-message-typing-indicator\"\n className={cn(\n 'flex items-center gap-1 motion-reduce:animate-none',\n className,\n )}\n >\n <AITypingIndicator size=\"sm\" color=\"var(--muted-foreground)\" />\n </div>\n );\n}\n\nAIMessageTypingIndicator.displayName = 'AIMessage.TypingIndicator';\n\n// =============================================================================\n// Attachment Types\n// =============================================================================\n\nexport interface Attachment {\n id: string;\n name: string;\n size: string;\n /** File extension (e.g., 'pdf', 'jpg', 'doc') */\n extension?: string;\n url?: string;\n thumbnailUrl?: string;\n}\n\n// =============================================================================\n// AIMessage.AttachmentPreview - Single attachment preview\n// =============================================================================\n\nexport interface AIMessageAttachmentPreviewProps {\n /** Attachment data */\n attachment: Attachment;\n /** Message type for styling */\n messageType?: 'received' | 'sent';\n /** Click handler */\n onClick?: () => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction AIMessageAttachmentPreview({\n attachment,\n messageType = 'received',\n onClick,\n className,\n}: AIMessageAttachmentPreviewProps) {\n // Derive extension from attachment.extension or extract from filename\n const getExtension = () => {\n if (attachment.extension) {\n return attachment.extension;\n }\n const parts = attachment.name.split('.');\n if (parts.length > 1) {\n return parts[parts.length - 1];\n }\n return '';\n };\n\n const extension = getExtension();\n\n const bubbleClasses =\n messageType === 'sent'\n ? 'bg-primary/10 border border-primary-foreground/20 rounded-2xl'\n : 'bg-muted rounded-2xl';\n\n return (\n <button\n type=\"button\"\n data-slot=\"ai-message-attachment-preview\"\n onClick={onClick}\n aria-label={`Attachment: ${attachment.name}, ${attachment.size}`}\n className={cn(\n 'flex items-center gap-3 p-3 min-h-11 hover:bg-accent transition-colors w-full max-w-[320px] focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-ring',\n bubbleClasses,\n className,\n )}\n >\n {attachment.thumbnailUrl ? (\n <img\n src={attachment.thumbnailUrl}\n alt={attachment.name}\n className=\"size-10 rounded-md object-cover\"\n />\n ) : (\n <FileTypeIcon extension={extension} size=\"md\" className=\"shrink-0\" />\n )}\n <div className=\"flex flex-col items-start min-w-0\">\n <span className=\"text-sm font-medium text-secondary-foreground truncate w-full\">\n {attachment.name}\n </span>\n <span className=\"text-sm text-muted-foreground\">{attachment.size}</span>\n </div>\n </button>\n );\n}\n\nAIMessageAttachmentPreview.displayName = 'AIMessage.AttachmentPreview';\n\n// =============================================================================\n// AIMessage.Attachments - Attachments container\n// =============================================================================\n\nexport interface AIMessageAttachmentsProps {\n /** Attachments to display */\n attachments: Attachment[];\n /** Message type for styling */\n messageType?: 'received' | 'sent';\n /** Callback when attachment is clicked */\n onAttachmentClick?: (attachment: Attachment) => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction AIMessageAttachments({\n attachments,\n messageType = 'received',\n onAttachmentClick,\n className,\n}: AIMessageAttachmentsProps) {\n if (!attachments?.length) return null;\n\n return (\n <div\n data-slot=\"ai-message-attachments\"\n className={cn('flex flex-col gap-2 mt-1', className)}\n >\n {attachments.map((attachment) => (\n <AIMessageAttachmentPreview\n key={attachment.id}\n attachment={attachment}\n messageType={messageType}\n onClick={() => onAttachmentClick?.(attachment)}\n />\n ))}\n </div>\n );\n}\n\nAIMessageAttachments.displayName = 'AIMessage.Attachments';\n\n// =============================================================================\n// AIMessage.Avatar - Avatar with agent indicator\n// =============================================================================\n\nexport interface AIMessageAvatarProps extends AvatarProps {\n /** Whether sender is an agent */\n isAgent?: boolean;\n}\n\nfunction AIMessageAvatar({ isAgent, ...props }: AIMessageAvatarProps) {\n return (\n <Avatar\n data-slot=\"ai-message-avatar\"\n {...props}\n size=\"md\"\n indicator={isAgent ? 'verified' : props.indicator}\n />\n );\n}\n\nAIMessageAvatar.displayName = 'AIMessage.Avatar';\n\n// =============================================================================\n// AIMessage.Content - Message content with markdown support\n// =============================================================================\n\nexport interface AIMessageContentProps {\n /** Message content */\n children?: React.ReactNode;\n /** Content as string (alternative to children) */\n content?: string;\n /** Whether to render content as markdown. Defaults to true for received, false for sent. */\n markdown?: boolean;\n /** Callback for interactive component events */\n onInteraction?: (event: AIInteractionEvent) => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction AIMessageContent({\n children,\n content,\n markdown,\n onInteraction,\n className,\n}: AIMessageContentProps) {\n const ctx = React.useContext(AIMessageContext);\n const type = ctx?.type ?? 'received';\n const isSent = type === 'sent';\n\n const shouldRenderMarkdown = markdown ?? type === 'received';\n const textContent = content ?? (typeof children === 'string' ? children : '');\n const variant = isSent ? 'inverted' : 'default';\n\n return (\n <div\n data-slot=\"ai-message-content\"\n className={cn('w-full', messageOverflowWrapClasses, className)}\n >\n {shouldRenderMarkdown && textContent ? (\n <AIInteractionProvider onInteraction={onInteraction}>\n <MarkdownRenderer\n variant={variant}\n className={cn(\n 'text-base',\n isSent ? 'text-primary-foreground' : 'text-foreground',\n )}\n >\n {textContent}\n </MarkdownRenderer>\n </AIInteractionProvider>\n ) : textContent ? (\n <p\n className={cn(\n 'text-sm leading-5 whitespace-pre-wrap',\n messageOverflowWrapClasses,\n isSent ? 'text-primary-foreground' : 'text-foreground',\n )}\n >\n {textContent}\n </p>\n ) : (\n children\n )}\n </div>\n );\n}\n\nAIMessageContent.displayName = 'AIMessage.Content';\n\n// =============================================================================\n// AIMessage.Header - Header with name and timestamp\n// =============================================================================\n\nexport interface AIMessageHeaderProps {\n /** Sender name */\n senderName?: string;\n /** Timestamp string */\n timestamp?: string;\n /** Show avatar slot */\n avatar?: React.ReactNode;\n /** Additional class name */\n className?: string;\n}\n\nfunction AIMessageHeader({\n senderName,\n timestamp,\n avatar,\n className,\n}: AIMessageHeaderProps) {\n const ctx = React.useContext(AIMessageContext);\n const isSent = ctx?.type === 'sent';\n const compact = ctx?.compact ?? false;\n\n if (compact) return null;\n\n return (\n <div\n data-slot=\"ai-message-header\"\n className={cn('flex items-center justify-between w-full', className)}\n >\n <div className=\"flex items-center gap-2 min-w-0 flex-1\">\n {avatar && <div className=\"shrink-0\">{avatar}</div>}\n <span\n className={cn(\n 'text-sm font-medium truncate',\n isSent ? 'text-primary-foreground' : 'text-secondary-foreground',\n )}\n >\n {isSent ? (senderName ?? 'You') : senderName}\n </span>\n </div>\n {timestamp && (\n <span\n className={cn(\n 'text-xs shrink-0',\n isSent ? 'text-primary-foreground/90' : 'text-muted-foreground',\n )}\n >\n {timestamp}\n </span>\n )}\n </div>\n );\n}\n\nAIMessageHeader.displayName = 'AIMessage.Header';\n\n// =============================================================================\n// AIMessage.Root - Root container for composable API\n// =============================================================================\n\nexport interface AIMessageRootProps\n extends Omit<HTMLAttributes<HTMLDivElement>, 'content'> {\n /** Message type */\n type?: 'received' | 'sent';\n /** Whether sender is an AI agent */\n isAgent?: boolean;\n /** Whether in compact mode */\n compact?: boolean;\n /** Whether AI is typing */\n isTyping?: boolean;\n /** Callback when thumbs up is clicked */\n onThumbsUp?: () => void;\n /** Callback when thumbs down is clicked */\n onThumbsDown?: () => void;\n /** Callback when copy is clicked */\n onCopy?: () => void;\n /** Callback when list/expand is clicked */\n onShowList?: () => void;\n /** Whether thumbs up is active */\n thumbsUpActive?: boolean;\n /** Whether thumbs down is active */\n thumbsDownActive?: boolean;\n /** Children */\n children?: React.ReactNode;\n /** Additional class name */\n className?: string;\n}\n\nconst AIMessageRoot = forwardRef<HTMLDivElement, AIMessageRootProps>(\n (\n {\n type = 'received',\n isAgent = false,\n compact = false,\n isTyping = false,\n onThumbsUp,\n onThumbsDown,\n onCopy,\n onShowList,\n thumbsUpActive,\n thumbsDownActive,\n children,\n className,\n ...props\n },\n ref,\n ) => {\n const isSent = type === 'sent';\n\n const contextValue = React.useMemo<AIMessageContextValue>(\n () => ({\n type,\n isAgent,\n compact,\n isTyping,\n onThumbsUp,\n onThumbsDown,\n onCopy,\n onShowList,\n thumbsUpActive,\n thumbsDownActive,\n }),\n [\n type,\n isAgent,\n compact,\n isTyping,\n onThumbsUp,\n onThumbsDown,\n onCopy,\n onShowList,\n thumbsUpActive,\n thumbsDownActive,\n ],\n );\n\n return (\n <AIMessageContext.Provider value={contextValue}>\n <div\n ref={ref}\n data-slot=\"ai-message\"\n className={cn(\n messageVariants({ type }),\n isSent ? 'pe-2' : 'ps-0',\n isSent ? 'delight-slide-in-end' : 'delight-slide-up',\n className,\n )}\n {...props}\n >\n <div\n className={cn(\n 'flex min-w-0 max-w-full flex-col gap-1.5 items-start',\n isSent && 'items-end',\n )}\n >\n {children}\n </div>\n </div>\n </AIMessageContext.Provider>\n );\n },\n);\n\nAIMessageRoot.displayName = 'AIMessage.Root';\n\n// =============================================================================\n// Main AIMessage Component (Monolithic API)\n// =============================================================================\n\nexport interface AIMessageProps\n extends VariantProps<typeof messageVariants>,\n Omit<HTMLAttributes<HTMLDivElement>, 'content'> {\n /** Message type - 'received' for incoming, 'sent' for outgoing messages */\n type?: 'received' | 'sent';\n /** Message content */\n content?: string;\n /** Sender name */\n senderName?: string;\n /** Timestamp */\n timestamp?: string;\n /** Avatar — pass AvatarProps object or a React element */\n avatar?: AvatarProps | React.ReactElement;\n /** Whether the sender is an AI agent */\n isAgent?: boolean;\n /** Whether message is in compact mode (no avatar on subsequent messages) */\n compact?: boolean;\n /** Whether the AI is currently typing */\n isTyping?: boolean;\n /** Whether to render content as markdown. Defaults to true for received, false for sent. */\n markdown?: boolean;\n /** Callback when an interactive component triggers an interaction */\n onInteraction?: (event: AIInteractionEvent) => void;\n /** Attachments */\n attachments?: Attachment[];\n /** Emoji reactions */\n reactions?: EmojiReaction[];\n /** Whether to show action toolbar (for agent messages) */\n showActions?: boolean;\n /** Callback when thumbs up is clicked */\n onThumbsUp?: () => void;\n /** Callback when thumbs down is clicked */\n onThumbsDown?: () => void;\n /** Callback when copy is clicked */\n onCopy?: () => void;\n /** Callback when list/expand is clicked */\n onShowList?: () => void;\n /** Callback when emoji reaction is clicked */\n onReactionClick?: (emoji: string) => void;\n /** Callback when attachment is clicked */\n onAttachmentClick?: (attachment: Attachment) => void;\n /** Whether thumbs up is active */\n thumbsUpActive?: boolean;\n /** Whether thumbs down is active */\n thumbsDownActive?: boolean;\n /** Additional class name */\n className?: string;\n}\n\nconst AIMessageDefault = forwardRef<HTMLDivElement, AIMessageProps>(\n (\n {\n type = 'received',\n content,\n senderName,\n timestamp,\n avatar,\n isAgent = false,\n compact = false,\n isTyping = false,\n markdown,\n onInteraction,\n attachments,\n reactions,\n showActions = false,\n onThumbsUp,\n onThumbsDown,\n onCopy,\n onShowList,\n onReactionClick,\n onAttachmentClick,\n thumbsUpActive,\n thumbsDownActive,\n className,\n ...props\n },\n ref,\n ) => {\n return (\n <AIMessageRoot\n ref={ref}\n type={type}\n isAgent={isAgent}\n compact={compact}\n isTyping={isTyping}\n onThumbsUp={onThumbsUp}\n onThumbsDown={onThumbsDown}\n onCopy={onCopy}\n onShowList={onShowList}\n thumbsUpActive={thumbsUpActive}\n thumbsDownActive={thumbsDownActive}\n className={className}\n {...props}\n >\n {type !== 'sent' &&\n !compact &&\n avatar &&\n (React.isValidElement(avatar) ? (\n avatar\n ) : (\n <AIMessageAvatar {...(avatar as AvatarProps)} isAgent={isAgent} />\n ))}\n\n <AIMessageBubble>\n {(type !== 'sent' || senderName || timestamp) && (\n <AIMessageHeader senderName={senderName} timestamp={timestamp} />\n )}\n\n {isTyping ? (\n <AIMessageTypingIndicator />\n ) : (\n content && (\n <AIMessageContent\n content={content}\n markdown={markdown}\n onInteraction={onInteraction}\n />\n )\n )}\n </AIMessageBubble>\n\n {!isTyping && attachments && attachments.length > 0 && (\n <AIMessageAttachments\n attachments={attachments}\n messageType={type ?? 'received'}\n onAttachmentClick={onAttachmentClick}\n />\n )}\n\n {!isTyping && (showActions || reactions?.length) && (\n <div className=\"flex items-center gap-1\">\n {showActions && isAgent && <AIMessageActions />}\n {reactions && reactions.length > 0 && (\n <AIMessageReactions\n reactions={reactions}\n onReactionClick={onReactionClick}\n />\n )}\n </div>\n )}\n </AIMessageRoot>\n );\n },\n);\n\nAIMessageDefault.displayName = 'AIMessage';\n\n// =============================================================================\n// Compound Component (Dual-API via Object.assign)\n// =============================================================================\n\n/**\n * AIMessage - Dual-API component for AI chat messages.\n *\n * Supports two usage patterns:\n *\n * 1. **Monolithic API (batteries-included)**:\n * ```tsx\n * <AIMessage\n * content=\"Hello!\"\n * senderName=\"Assistant\"\n * avatar={{ src: '...' }}\n * isAgent\n * showActions\n * />\n * ```\n *\n * 2. **Composable API (full customization)**:\n * ```tsx\n * <AIMessage.Root type=\"received\" isAgent>\n * <AIMessage.Avatar src=\"...\" isAgent />\n * <AIMessage.Bubble>\n * <AIMessage.Header senderName=\"Assistant\" timestamp=\"Now\" />\n * <AIMessage.Content markdown>\n * Hello!\n * </AIMessage.Content>\n * </AIMessage.Bubble>\n * <AIMessage.Actions>\n * <AIMessage.ThumbsUp onClick={...} />\n * <AIMessage.ThumbsDown onClick={...} />\n * <AIMessage.CopyButton onClick={...} />\n * </AIMessage.Actions>\n * </AIMessage.Root>\n * ```\n */\nconst AIMessage = Object.assign(AIMessageDefault, {\n Root: AIMessageRoot,\n Bubble: AIMessageBubble,\n Header: AIMessageHeader,\n Avatar: AIMessageAvatar,\n Content: AIMessageContent,\n Actions: AIMessageActions,\n Reactions: AIMessageReactions,\n Attachments: AIMessageAttachments,\n AttachmentPreview: AIMessageAttachmentPreview,\n TypingIndicator: AIMessageTypingIndicator,\n CopyButton: AIMessageCopyButton,\n ThumbsUp: AIMessageThumbsUp,\n ThumbsDown: AIMessageThumbsDown,\n ListButton: AIMessageListButton,\n});\n\n// =============================================================================\n// Named Exports\n// =============================================================================\n\n// Type exports\nexport type { AIMessageRootProps as AIMessageComposableProps };\nexport {\n AIMessage,\n AIMessageActions,\n AIMessageAttachmentPreview,\n AIMessageAttachments,\n AIMessageAvatar,\n AIMessageBubble,\n AIMessageContent,\n AIMessageCopyButton,\n AIMessageHeader,\n AIMessageListButton,\n AIMessageReactions,\n // Composable subcomponents\n AIMessageRoot,\n AIMessageThumbsDown,\n AIMessageThumbsUp,\n AIMessageTypingIndicator,\n // Variants\n messageBubbleVariants,\n messageVariants,\n // Context hook for custom subcomponents\n useAIMessageContext,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"AIMessage.js","names":[],"sources":["../../src/components/organisms/ai/AIMessage/AIMessage.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { Check, Copy, List, ThumbsDown, ThumbsUp } from 'lucide-react';\nimport * as React from 'react';\nimport { forwardRef, type HTMLAttributes } from 'react';\nimport { Avatar, type AvatarProps } from '@/components/molecules/data/Avatar';\nimport { FileTypeIcon } from '@/components/molecules/files/FileTypeIcon';\nimport type { AIInteractionEvent } from '@/components/organisms/ai/_shared/interaction-context';\nimport { AIInteractionProvider } from '@/components/organisms/ai/_shared/interaction-context';\nimport { MarkdownRenderer } from '@/components/organisms/ai/_shared/markdown-renderer';\nimport { AITypingIndicator } from '@/components/organisms/ai/AITypingIndicator';\nimport { createSafeContext } from '@/lib/create-safe-context';\nimport { cn } from '@/lib/utils';\n\n// =============================================================================\n// Message Variants\n// =============================================================================\n\nconst messageVariants = cva('flex items-start w-full', {\n variants: {\n type: {\n received: 'justify-start',\n sent: 'justify-end',\n },\n },\n defaultVariants: {\n type: 'received',\n },\n});\n\nconst messageOverflowWrapClasses =\n 'min-w-0 max-w-full break-words [overflow-wrap:anywhere]';\n\nconst messageBubbleVariants = cva(\n 'flex min-w-0 max-w-[min(720px,100%)] flex-col gap-1 overflow-hidden px-4 py-3 rounded-2xl',\n {\n variants: {\n type: {\n received: 'bg-muted rounded-es-sm',\n sent: 'bg-primary text-primary-foreground rounded-ee-sm',\n },\n },\n defaultVariants: {\n type: 'received',\n },\n },\n);\n\n// =============================================================================\n// Context for Composable API\n// =============================================================================\n\ninterface AIMessageContextValue {\n /** Message type */\n type: 'received' | 'sent';\n /** Whether sender is an AI agent */\n isAgent: boolean;\n /** Whether in compact mode */\n compact: boolean;\n /** Whether AI is typing */\n isTyping: boolean;\n /** Callback when thumbs up is clicked */\n onThumbsUp?: () => void;\n /** Callback when thumbs down is clicked */\n onThumbsDown?: () => void;\n /** Callback when copy is clicked */\n onCopy?: () => void;\n /** Callback when list/expand is clicked */\n onShowList?: () => void;\n /** Whether thumbs up is active */\n thumbsUpActive?: boolean;\n /** Whether thumbs down is active */\n thumbsDownActive?: boolean;\n}\n\nconst [AIMessageContext, useAIMessageContext] =\n createSafeContext<AIMessageContextValue>('AIMessage');\n\n// =============================================================================\n// AIMessage.Bubble - Bubble wrapper for header + content\n// =============================================================================\n\nexport interface AIMessageBubbleProps {\n /** Children (Header, Content, TypingIndicator) */\n children?: React.ReactNode;\n /** Additional class name */\n className?: string;\n}\n\nfunction AIMessageBubble({ children, className }: AIMessageBubbleProps) {\n const ctx = React.useContext(AIMessageContext);\n const type = ctx?.type ?? 'received';\n\n return (\n <div\n data-slot=\"ai-message-bubble\"\n data-message-type={type}\n className={cn(messageBubbleVariants({ type }), className)}\n >\n {children}\n </div>\n );\n}\n\nAIMessageBubble.displayName = 'AIMessage.Bubble';\n\n// =============================================================================\n// Reaction Button (Internal)\n// =============================================================================\n\ninterface ReactionButtonProps {\n icon: React.ReactNode;\n onClick?: () => void;\n active?: boolean;\n count?: number;\n /** Accessible label for the button */\n label?: string;\n className?: string;\n}\n\nfunction ReactionButton({\n icon,\n onClick,\n active,\n count,\n label,\n className,\n}: ReactionButtonProps) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n aria-label={label}\n aria-pressed={active}\n className={cn(\n 'flex items-center justify-center gap-1 px-2.5 py-2 min-w-11 min-h-11 rounded-full bg-muted hover:bg-accent delight-click-ripple transition-all duration-150 ease-out hover:scale-110 active:scale-95 motion-reduce:hover:scale-100 motion-reduce:active:scale-100 focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-ring',\n active &&\n 'bg-primary/10 text-primary delight-check-bounce motion-reduce:!animate-none',\n className,\n )}\n >\n {icon}\n {count !== undefined && count > 0 && (\n <span className=\"text-xs font-medium text-muted-foreground\">\n {count}\n </span>\n )}\n </button>\n );\n}\n\n// =============================================================================\n// Emoji Reaction Types\n// =============================================================================\n\nexport interface EmojiReaction {\n emoji: string;\n count: number;\n reacted?: boolean;\n}\n\n// =============================================================================\n// AIMessage.Reactions - Emoji reactions display\n// =============================================================================\n\nexport interface AIMessageReactionsProps {\n /** Emoji reactions to display */\n reactions: EmojiReaction[];\n /** Callback when reaction is clicked */\n onReactionClick?: (emoji: string) => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction AIMessageReactions({\n reactions,\n onReactionClick,\n className,\n}: AIMessageReactionsProps) {\n if (!reactions?.length) return null;\n\n return (\n <div\n data-slot=\"ai-message-reactions\"\n className={cn('flex items-center gap-1', className)}\n >\n {reactions.map((reaction) => (\n <button\n key={reaction.emoji}\n type=\"button\"\n onClick={() => onReactionClick?.(reaction.emoji)}\n aria-label={`React with ${reaction.emoji}${reaction.count > 1 ? `, ${reaction.count} reactions` : ''}`}\n aria-pressed={reaction.reacted}\n className={cn(\n 'flex items-center gap-1 px-2.5 py-1.5 min-h-11 rounded-full bg-muted hover:bg-accent text-sm transition-colors focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-ring',\n reaction.reacted && 'bg-primary/10',\n )}\n >\n <span aria-hidden=\"true\">{reaction.emoji}</span>\n {reaction.count > 1 && (\n <span className=\"text-xs text-muted-foreground\">\n {reaction.count}\n </span>\n )}\n </button>\n ))}\n </div>\n );\n}\n\nAIMessageReactions.displayName = 'AIMessage.Reactions';\n\n// =============================================================================\n// AIMessage.ThumbsUp - Thumbs up button\n// =============================================================================\n\nexport interface AIMessageThumbsUpProps {\n /** Click handler */\n onClick?: () => void;\n /** Whether active */\n active?: boolean;\n /** Additional class name */\n className?: string;\n}\n\nfunction AIMessageThumbsUp({\n onClick,\n active,\n className,\n}: AIMessageThumbsUpProps) {\n return (\n <ReactionButton\n icon={\n <ThumbsUp className=\"size-4 text-muted-foreground\" aria-hidden=\"true\" />\n }\n onClick={onClick}\n active={active}\n label=\"Thumbs up\"\n className={className}\n />\n );\n}\n\nAIMessageThumbsUp.displayName = 'AIMessage.ThumbsUp';\n\n// =============================================================================\n// AIMessage.ThumbsDown - Thumbs down button\n// =============================================================================\n\nexport interface AIMessageThumbsDownProps {\n /** Click handler */\n onClick?: () => void;\n /** Whether active */\n active?: boolean;\n /** Additional class name */\n className?: string;\n}\n\nfunction AIMessageThumbsDown({\n onClick,\n active,\n className,\n}: AIMessageThumbsDownProps) {\n return (\n <ReactionButton\n icon={\n <ThumbsDown\n className=\"size-4 text-muted-foreground\"\n aria-hidden=\"true\"\n />\n }\n onClick={onClick}\n active={active}\n label=\"Thumbs down\"\n className={className}\n />\n );\n}\n\nAIMessageThumbsDown.displayName = 'AIMessage.ThumbsDown';\n\n// =============================================================================\n// AIMessage.CopyButton - Copy button\n// =============================================================================\n\nexport interface AIMessageCopyButtonProps {\n /** Click handler */\n onClick?: () => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction AIMessageCopyButton({ onClick, className }: AIMessageCopyButtonProps) {\n const [copied, setCopied] = React.useState(false);\n const timerRef = React.useRef<ReturnType<typeof setTimeout>>(undefined);\n\n React.useEffect(() => () => clearTimeout(timerRef.current), []);\n\n const handleClick = React.useCallback(() => {\n onClick?.();\n setCopied(true);\n clearTimeout(timerRef.current);\n timerRef.current = setTimeout(() => setCopied(false), 2000);\n }, [onClick]);\n\n return (\n <ReactionButton\n icon={\n copied ? (\n <Check\n className=\"size-4 text-success delight-bounce-in motion-reduce:animate-none\"\n aria-hidden=\"true\"\n />\n ) : (\n <Copy\n className=\"size-4 text-secondary-foreground\"\n aria-hidden=\"true\"\n />\n )\n }\n onClick={handleClick}\n label={copied ? 'Copied to clipboard' : 'Copy message'}\n className={className}\n />\n );\n}\n\nAIMessageCopyButton.displayName = 'AIMessage.CopyButton';\n\n// =============================================================================\n// AIMessage.ListButton - List/expand button\n// =============================================================================\n\nexport interface AIMessageListButtonProps {\n /** Click handler */\n onClick?: () => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction AIMessageListButton({ onClick, className }: AIMessageListButtonProps) {\n return (\n <ReactionButton\n icon={\n <List className=\"size-4 text-secondary-foreground\" aria-hidden=\"true\" />\n }\n onClick={onClick}\n label=\"Show list\"\n className={className}\n />\n );\n}\n\nAIMessageListButton.displayName = 'AIMessage.ListButton';\n\n// =============================================================================\n// AIMessage.Actions - Action toolbar container\n// =============================================================================\n\nexport interface AIMessageActionsProps {\n /** Children (action buttons) */\n children?: React.ReactNode;\n /** Additional class name */\n className?: string;\n}\n\nfunction AIMessageActions({ children, className }: AIMessageActionsProps) {\n const ctx = React.useContext(AIMessageContext);\n\n return (\n <div\n data-slot=\"ai-message-actions\"\n role=\"toolbar\"\n aria-label=\"Message actions\"\n className={cn(\n 'flex items-center gap-0.5 rounded-full overflow-hidden',\n className,\n )}\n >\n {children ??\n (ctx && (\n <>\n <AIMessageThumbsUp\n onClick={ctx.onThumbsUp}\n active={ctx.thumbsUpActive}\n />\n <AIMessageThumbsDown\n onClick={ctx.onThumbsDown}\n active={ctx.thumbsDownActive}\n />\n <AIMessageCopyButton onClick={ctx.onCopy} />\n <AIMessageListButton onClick={ctx.onShowList} />\n </>\n ))}\n </div>\n );\n}\n\nAIMessageActions.displayName = 'AIMessage.Actions';\n\n// =============================================================================\n// AIMessage.TypingIndicator - Bouncing dots\n// =============================================================================\n\nexport interface AIMessageTypingIndicatorProps {\n /** Additional class name */\n className?: string;\n}\n\nfunction AIMessageTypingIndicator({\n className,\n}: AIMessageTypingIndicatorProps) {\n return (\n <div\n data-slot=\"ai-message-typing-indicator\"\n className={cn(\n 'flex items-center gap-1 motion-reduce:animate-none',\n className,\n )}\n >\n <AITypingIndicator size=\"sm\" color=\"var(--muted-foreground)\" />\n </div>\n );\n}\n\nAIMessageTypingIndicator.displayName = 'AIMessage.TypingIndicator';\n\n// =============================================================================\n// Attachment Types\n// =============================================================================\n\nexport interface Attachment {\n id: string;\n name: string;\n size: string;\n /** File extension (e.g., 'pdf', 'jpg', 'doc') */\n extension?: string;\n url?: string;\n thumbnailUrl?: string;\n}\n\n// =============================================================================\n// AIMessage.AttachmentPreview - Single attachment preview\n// =============================================================================\n\nexport interface AIMessageAttachmentPreviewProps {\n /** Attachment data */\n attachment: Attachment;\n /** Message type for styling */\n messageType?: 'received' | 'sent';\n /** Click handler */\n onClick?: () => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction AIMessageAttachmentPreview({\n attachment,\n messageType = 'received',\n onClick,\n className,\n}: AIMessageAttachmentPreviewProps) {\n // Derive extension from attachment.extension or extract from filename\n const getExtension = () => {\n if (attachment.extension) {\n return attachment.extension;\n }\n const parts = attachment.name.split('.');\n if (parts.length > 1) {\n return parts[parts.length - 1];\n }\n return '';\n };\n\n const extension = getExtension();\n\n const bubbleClasses =\n messageType === 'sent'\n ? 'bg-primary/10 border border-primary-foreground/20 rounded-2xl'\n : 'bg-muted rounded-2xl';\n\n return (\n <button\n type=\"button\"\n data-slot=\"ai-message-attachment-preview\"\n onClick={onClick}\n aria-label={`Attachment: ${attachment.name}, ${attachment.size}`}\n className={cn(\n 'flex items-center gap-3 p-3 min-h-11 hover:bg-accent transition-colors w-full max-w-[320px] focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-ring',\n bubbleClasses,\n className,\n )}\n >\n {attachment.thumbnailUrl ? (\n <img\n src={attachment.thumbnailUrl}\n alt={attachment.name}\n className=\"size-10 rounded-md object-cover\"\n />\n ) : (\n <FileTypeIcon extension={extension} size=\"md\" className=\"shrink-0\" />\n )}\n <div className=\"flex flex-col items-start min-w-0\">\n <span className=\"text-sm font-medium text-secondary-foreground truncate w-full\">\n {attachment.name}\n </span>\n <span className=\"text-sm text-muted-foreground\">{attachment.size}</span>\n </div>\n </button>\n );\n}\n\nAIMessageAttachmentPreview.displayName = 'AIMessage.AttachmentPreview';\n\n// =============================================================================\n// AIMessage.Attachments - Attachments container\n// =============================================================================\n\nexport interface AIMessageAttachmentsProps {\n /** Attachments to display */\n attachments: Attachment[];\n /** Message type for styling */\n messageType?: 'received' | 'sent';\n /** Callback when attachment is clicked */\n onAttachmentClick?: (attachment: Attachment) => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction AIMessageAttachments({\n attachments,\n messageType = 'received',\n onAttachmentClick,\n className,\n}: AIMessageAttachmentsProps) {\n if (!attachments?.length) return null;\n\n return (\n <div\n data-slot=\"ai-message-attachments\"\n className={cn('flex flex-col gap-2 mt-1', className)}\n >\n {attachments.map((attachment) => (\n <AIMessageAttachmentPreview\n key={attachment.id}\n attachment={attachment}\n messageType={messageType}\n onClick={() => onAttachmentClick?.(attachment)}\n />\n ))}\n </div>\n );\n}\n\nAIMessageAttachments.displayName = 'AIMessage.Attachments';\n\n// =============================================================================\n// AIMessage.Avatar - Avatar with agent indicator\n// =============================================================================\n\nexport interface AIMessageAvatarProps extends AvatarProps {\n /** Whether sender is an agent */\n isAgent?: boolean;\n}\n\nfunction AIMessageAvatar({ isAgent, ...props }: AIMessageAvatarProps) {\n return (\n <Avatar\n data-slot=\"ai-message-avatar\"\n {...props}\n size=\"md\"\n indicator={isAgent ? 'verified' : props.indicator}\n />\n );\n}\n\nAIMessageAvatar.displayName = 'AIMessage.Avatar';\n\n// =============================================================================\n// AIMessage.Content - Message content with markdown support\n// =============================================================================\n\nexport interface AIMessageContentProps {\n /** Message content */\n children?: React.ReactNode;\n /** Content as string (alternative to children) */\n content?: string;\n /** Whether to render content as markdown. Defaults to true for received, false for sent. */\n markdown?: boolean;\n /** Callback for interactive component events */\n onInteraction?: (event: AIInteractionEvent) => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction AIMessageContent({\n children,\n content,\n markdown,\n onInteraction,\n className,\n}: AIMessageContentProps) {\n const ctx = React.useContext(AIMessageContext);\n const type = ctx?.type ?? 'received';\n const isSent = type === 'sent';\n\n const shouldRenderMarkdown = markdown ?? type === 'received';\n const textContent = content ?? (typeof children === 'string' ? children : '');\n const variant = isSent ? 'inverted' : 'default';\n\n return (\n <div\n data-slot=\"ai-message-content\"\n className={cn('w-full', messageOverflowWrapClasses, className)}\n >\n {shouldRenderMarkdown && textContent ? (\n <AIInteractionProvider onInteraction={onInteraction}>\n <MarkdownRenderer\n variant={variant}\n className={cn(\n 'text-base',\n isSent ? 'text-primary-foreground' : 'text-foreground',\n )}\n >\n {textContent}\n </MarkdownRenderer>\n </AIInteractionProvider>\n ) : textContent ? (\n <p\n className={cn(\n 'text-sm leading-5 whitespace-pre-wrap',\n messageOverflowWrapClasses,\n isSent ? 'text-primary-foreground' : 'text-foreground',\n )}\n >\n {textContent}\n </p>\n ) : (\n children\n )}\n </div>\n );\n}\n\nAIMessageContent.displayName = 'AIMessage.Content';\n\n// =============================================================================\n// AIMessage.Header - Header with name and timestamp\n// =============================================================================\n\nexport interface AIMessageHeaderProps {\n /** Sender name */\n senderName?: string;\n /** Timestamp string */\n timestamp?: string;\n /** Show avatar slot */\n avatar?: React.ReactNode;\n /** Additional class name */\n className?: string;\n}\n\nfunction AIMessageHeader({\n senderName,\n timestamp,\n avatar,\n className,\n}: AIMessageHeaderProps) {\n const ctx = React.useContext(AIMessageContext);\n const isSent = ctx?.type === 'sent';\n const compact = ctx?.compact ?? false;\n\n if (compact) return null;\n\n return (\n <div\n data-slot=\"ai-message-header\"\n className={cn('flex items-center justify-between w-full', className)}\n >\n <div className=\"flex items-center gap-2 min-w-0 flex-1\">\n {avatar && <div className=\"shrink-0\">{avatar}</div>}\n <span\n className={cn(\n 'text-sm font-medium truncate',\n isSent ? 'text-primary-foreground' : 'text-secondary-foreground',\n )}\n >\n {isSent ? (senderName ?? 'You') : senderName}\n </span>\n </div>\n {timestamp && (\n <span\n className={cn(\n 'text-xs shrink-0',\n isSent ? 'text-primary-foreground/90' : 'text-muted-foreground',\n )}\n >\n {timestamp}\n </span>\n )}\n </div>\n );\n}\n\nAIMessageHeader.displayName = 'AIMessage.Header';\n\n// =============================================================================\n// AIMessage.Root - Root container for composable API\n// =============================================================================\n\nexport interface AIMessageRootProps\n extends Omit<HTMLAttributes<HTMLDivElement>, 'content'> {\n /** Message type */\n type?: 'received' | 'sent';\n /** Whether sender is an AI agent */\n isAgent?: boolean;\n /** Whether in compact mode */\n compact?: boolean;\n /** Whether AI is typing */\n isTyping?: boolean;\n /** Callback when thumbs up is clicked */\n onThumbsUp?: () => void;\n /** Callback when thumbs down is clicked */\n onThumbsDown?: () => void;\n /** Callback when copy is clicked */\n onCopy?: () => void;\n /** Callback when list/expand is clicked */\n onShowList?: () => void;\n /** Whether thumbs up is active */\n thumbsUpActive?: boolean;\n /** Whether thumbs down is active */\n thumbsDownActive?: boolean;\n /** Children */\n children?: React.ReactNode;\n /** Additional class name */\n className?: string;\n}\n\nconst AIMessageRoot = forwardRef<HTMLDivElement, AIMessageRootProps>(\n (\n {\n type = 'received',\n isAgent = false,\n compact = false,\n isTyping = false,\n onThumbsUp,\n onThumbsDown,\n onCopy,\n onShowList,\n thumbsUpActive,\n thumbsDownActive,\n children,\n className,\n ...props\n },\n ref,\n ) => {\n const isSent = type === 'sent';\n\n const contextValue = React.useMemo<AIMessageContextValue>(\n () => ({\n type,\n isAgent,\n compact,\n isTyping,\n onThumbsUp,\n onThumbsDown,\n onCopy,\n onShowList,\n thumbsUpActive,\n thumbsDownActive,\n }),\n [\n type,\n isAgent,\n compact,\n isTyping,\n onThumbsUp,\n onThumbsDown,\n onCopy,\n onShowList,\n thumbsUpActive,\n thumbsDownActive,\n ],\n );\n\n return (\n <AIMessageContext.Provider value={contextValue}>\n <div\n ref={ref}\n data-slot=\"ai-message\"\n className={cn(\n messageVariants({ type }),\n isSent ? 'pe-2' : 'ps-0',\n isSent ? 'delight-slide-in-end' : 'delight-slide-up',\n className,\n )}\n {...props}\n >\n <div\n className={cn(\n 'flex min-w-0 max-w-full flex-col gap-1.5 items-start',\n isSent && 'items-end',\n )}\n >\n {children}\n </div>\n </div>\n </AIMessageContext.Provider>\n );\n },\n);\n\nAIMessageRoot.displayName = 'AIMessage.Root';\n\n// =============================================================================\n// Main AIMessage Component (Monolithic API)\n// =============================================================================\n\nexport interface AIMessageProps\n extends VariantProps<typeof messageVariants>,\n Omit<HTMLAttributes<HTMLDivElement>, 'content'> {\n /** Message type - 'received' for incoming, 'sent' for outgoing messages */\n type?: 'received' | 'sent';\n /** Message content */\n content?: string;\n /** Sender name */\n senderName?: string;\n /** Timestamp */\n timestamp?: string;\n /** Avatar — pass AvatarProps object or a React element */\n avatar?: AvatarProps | React.ReactElement;\n /** Whether the sender is an AI agent */\n isAgent?: boolean;\n /** Whether message is in compact mode (no avatar on subsequent messages) */\n compact?: boolean;\n /** Whether the AI is currently typing */\n isTyping?: boolean;\n /** Whether to render content as markdown. Defaults to true for received, false for sent. */\n markdown?: boolean;\n /** Callback when an interactive component triggers an interaction */\n onInteraction?: (event: AIInteractionEvent) => void;\n /** Attachments */\n attachments?: Attachment[];\n /** Emoji reactions */\n reactions?: EmojiReaction[];\n /** Whether to show action toolbar (for agent messages) */\n showActions?: boolean;\n /** Callback when thumbs up is clicked */\n onThumbsUp?: () => void;\n /** Callback when thumbs down is clicked */\n onThumbsDown?: () => void;\n /** Callback when copy is clicked */\n onCopy?: () => void;\n /** Callback when list/expand is clicked */\n onShowList?: () => void;\n /** Callback when emoji reaction is clicked */\n onReactionClick?: (emoji: string) => void;\n /** Callback when attachment is clicked */\n onAttachmentClick?: (attachment: Attachment) => void;\n /** Whether thumbs up is active */\n thumbsUpActive?: boolean;\n /** Whether thumbs down is active */\n thumbsDownActive?: boolean;\n /** Additional class name */\n className?: string;\n}\n\nconst AIMessageDefault = forwardRef<HTMLDivElement, AIMessageProps>(\n (\n {\n type = 'received',\n content,\n senderName,\n timestamp,\n avatar,\n isAgent = false,\n compact = false,\n isTyping = false,\n markdown,\n onInteraction,\n attachments,\n reactions,\n showActions = false,\n onThumbsUp,\n onThumbsDown,\n onCopy,\n onShowList,\n onReactionClick,\n onAttachmentClick,\n thumbsUpActive,\n thumbsDownActive,\n className,\n ...props\n },\n ref,\n ) => {\n return (\n <AIMessageRoot\n ref={ref}\n type={type}\n isAgent={isAgent}\n compact={compact}\n isTyping={isTyping}\n onThumbsUp={onThumbsUp}\n onThumbsDown={onThumbsDown}\n onCopy={onCopy}\n onShowList={onShowList}\n thumbsUpActive={thumbsUpActive}\n thumbsDownActive={thumbsDownActive}\n className={className}\n {...props}\n >\n {type !== 'sent' &&\n !compact &&\n avatar &&\n (React.isValidElement(avatar) ? (\n avatar\n ) : (\n <AIMessageAvatar {...(avatar as AvatarProps)} isAgent={isAgent} />\n ))}\n\n <AIMessageBubble>\n {(type !== 'sent' || senderName || timestamp) && (\n <AIMessageHeader senderName={senderName} timestamp={timestamp} />\n )}\n\n {isTyping ? (\n <AIMessageTypingIndicator />\n ) : (\n content && (\n <AIMessageContent\n content={content}\n markdown={markdown}\n onInteraction={onInteraction}\n />\n )\n )}\n </AIMessageBubble>\n\n {!isTyping && attachments && attachments.length > 0 && (\n <AIMessageAttachments\n attachments={attachments}\n messageType={type ?? 'received'}\n onAttachmentClick={onAttachmentClick}\n />\n )}\n\n {!isTyping && (showActions || reactions?.length) && (\n <div className=\"flex items-center gap-1\">\n {showActions && isAgent && <AIMessageActions />}\n {reactions && reactions.length > 0 && (\n <AIMessageReactions\n reactions={reactions}\n onReactionClick={onReactionClick}\n />\n )}\n </div>\n )}\n </AIMessageRoot>\n );\n },\n);\n\nAIMessageDefault.displayName = 'AIMessage';\n\n// =============================================================================\n// Compound Component (Dual-API via Object.assign)\n// =============================================================================\n\n/**\n * AIMessage - Dual-API component for AI chat messages.\n *\n * Supports two usage patterns:\n *\n * 1. **Monolithic API (batteries-included)**:\n * ```tsx\n * <AIMessage\n * content=\"Hello!\"\n * senderName=\"Assistant\"\n * avatar={{ src: '...' }}\n * isAgent\n * showActions\n * />\n * ```\n *\n * 2. **Composable API (full customization)**:\n * ```tsx\n * <AIMessage.Root type=\"received\" isAgent>\n * <AIMessage.Avatar src=\"...\" isAgent />\n * <AIMessage.Bubble>\n * <AIMessage.Header senderName=\"Assistant\" timestamp=\"Now\" />\n * <AIMessage.Content markdown>\n * Hello!\n * </AIMessage.Content>\n * </AIMessage.Bubble>\n * <AIMessage.Actions>\n * <AIMessage.ThumbsUp onClick={...} />\n * <AIMessage.ThumbsDown onClick={...} />\n * <AIMessage.CopyButton onClick={...} />\n * </AIMessage.Actions>\n * </AIMessage.Root>\n * ```\n */\nconst AIMessage = Object.assign(AIMessageDefault, {\n Root: AIMessageRoot,\n Bubble: AIMessageBubble,\n Header: AIMessageHeader,\n Avatar: AIMessageAvatar,\n Content: AIMessageContent,\n Actions: AIMessageActions,\n Reactions: AIMessageReactions,\n Attachments: AIMessageAttachments,\n AttachmentPreview: AIMessageAttachmentPreview,\n TypingIndicator: AIMessageTypingIndicator,\n CopyButton: AIMessageCopyButton,\n ThumbsUp: AIMessageThumbsUp,\n ThumbsDown: AIMessageThumbsDown,\n ListButton: AIMessageListButton,\n});\n\n// =============================================================================\n// Named Exports\n// =============================================================================\n\n// Type exports\nexport type { AIMessageRootProps as AIMessageComposableProps };\nexport {\n AIMessage,\n AIMessageActions,\n AIMessageAttachmentPreview,\n AIMessageAttachments,\n AIMessageAvatar,\n AIMessageBubble,\n AIMessageContent,\n AIMessageCopyButton,\n AIMessageHeader,\n AIMessageListButton,\n AIMessageReactions,\n // Composable subcomponents\n AIMessageRoot,\n AIMessageThumbsDown,\n AIMessageThumbsUp,\n AIMessageTypingIndicator,\n // Variants\n messageBubbleVariants,\n messageVariants,\n // Context hook for custom subcomponents\n useAIMessageContext,\n};\n"],"mappings":"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"}
@@ -116,7 +116,7 @@ function g({ source: e, className: t }) {
116
116
  className: "text-sm font-medium text-foreground truncate",
117
117
  children: e.title || a
118
118
  }), /* @__PURE__ */ (0, r.jsx)("p", {
119
- className: "text-xs text-text-quaternary truncate",
119
+ className: "text-xs text-secondary-foreground truncate",
120
120
  children: a
121
121
  })]
122
122
  })]
@@ -168,7 +168,7 @@ function T({ sources: e, maxVisible: t = 3, showAll: a = !1, onShowMore: i, clas
168
168
  className: l("flex flex-wrap items-center gap-2", s),
169
169
  children: [
170
170
  /* @__PURE__ */ (0, r.jsx)("span", {
171
- className: "text-xs text-text-quaternary",
171
+ className: "text-xs text-secondary-foreground",
172
172
  children: "Sources:"
173
173
  }),
174
174
  c.map((x, p) => /* @__PURE__ */ (0, r.jsx)("span", {
@@ -1 +1 @@
1
- {"version":3,"file":"AISource.js","names":["__iconNode"],"sources":["../../../../../../../../../../../Users/akarim/Documents/test/humain_foundation_ui/node_modules/.bun/lucide-react@1.27.0+0f58469d5b3bd39f/node_modules/lucide-react/dist/esm/icons/external-link.mjs","../../../../../../../../../../../Users/akarim/Documents/test/humain_foundation_ui/node_modules/.bun/lucide-react@1.27.0+0f58469d5b3bd39f/node_modules/lucide-react/dist/esm/icons/globe.mjs","../../src/components/organisms/ai/AISource/AISource.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.27.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M15 3h6v6\", key: \"1q9fwt\" }],\n [\"path\", { d: \"M10 14 21 3\", key: \"gplh6r\" }],\n [\"path\", { d: \"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\", key: \"a6xqqp\" }]\n];\nconst ExternalLink = createLucideIcon(\"external-link\", __iconNode);\n\nexport { __iconNode, ExternalLink as default };\n//# sourceMappingURL=external-link.mjs.map\n","/**\n * @license lucide-react v1.27.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"path\", { d: \"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20\", key: \"13o1zl\" }],\n [\"path\", { d: \"M2 12h20\", key: \"9i4pu4\" }]\n];\nconst Globe = createLucideIcon(\"globe\", __iconNode);\n\nexport { __iconNode, Globe as default };\n//# sourceMappingURL=globe.mjs.map\n","import { cva, type VariantProps } from 'class-variance-authority';\nimport { ExternalLink, Globe } from 'lucide-react';\nimport * as React from 'react';\nimport { Tooltip, TooltipPopup, TooltipTrigger } from '@/components/ui/tooltip';\nimport { cn } from '@/lib/utils';\n\n// =============================================================================\n// Variants\n// =============================================================================\n\nconst sourceVariants = cva(\n 'inline-flex items-center gap-1.5 transition-colors cursor-pointer focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring',\n {\n variants: {\n variant: {\n default:\n 'text-sm text-primary hover:text-primary underline underline-offset-2 rounded-sm',\n pill: 'px-2.5 py-1 rounded-full bg-accent hover:bg-surface-2 text-xs text-secondary-foreground delight-selection-press',\n minimal:\n 'text-xs text-secondary-foreground hover:text-foreground rounded-sm',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n);\n\nconst DEFAULT_MAX_VISIBLE_SOURCES = 3;\n\nfunction getMaxVisibleSources(maxVisible: number): number {\n return Number.isFinite(maxVisible) && maxVisible >= 0\n ? Math.floor(maxVisible)\n : DEFAULT_MAX_VISIBLE_SOURCES;\n}\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface SourceData {\n /** Source URL */\n url: string;\n /** Display title */\n title?: string;\n /** Source description */\n description?: string;\n /** Favicon URL */\n favicon?: string;\n /** Site name */\n siteName?: string;\n}\n\n// =============================================================================\n// Source Favicon\n// =============================================================================\n\ninterface SourceFaviconProps {\n url: string;\n favicon?: string;\n className?: string;\n}\n\nfunction SourceFavicon({ url, favicon, className }: SourceFaviconProps) {\n const [hasError, setHasError] = React.useState(false);\n\n // Generate favicon URL from domain if not provided\n const faviconUrl = React.useMemo(() => {\n if (favicon) return favicon;\n try {\n const domain = new URL(url).hostname;\n return `https://www.google.com/s2/favicons?domain=${domain}&sz=32`;\n } catch {\n return null;\n }\n }, [url, favicon]);\n\n if (!faviconUrl || hasError) {\n return <Globe className={cn('size-4 text-muted-foreground', className)} />;\n }\n\n return (\n <img\n src={faviconUrl}\n alt=\"\"\n className={cn(\n 'size-4 rounded delight-fade-in motion-reduce:!animate-none',\n className,\n )}\n onError={() => setHasError(true)}\n />\n );\n}\n\nSourceFavicon.displayName = 'SourceFavicon';\n\n// =============================================================================\n// Source Trigger (Clickable element)\n// =============================================================================\n\nexport interface AISourceTriggerProps\n extends VariantProps<typeof sourceVariants> {\n /** Source data */\n source: SourceData;\n /** Whether to show favicon */\n showFavicon?: boolean;\n /** Additional class name */\n className?: string;\n /** Click handler */\n onClick?: () => void;\n}\n\nfunction AISourceTrigger({\n source,\n variant,\n showFavicon = true,\n className,\n onClick,\n}: AISourceTriggerProps) {\n const displayText = source.title || source.siteName || source.url;\n\n const sharedClassName = cn(sourceVariants({ variant }), className);\n const sharedChildren = (\n <>\n {showFavicon && (\n <SourceFavicon url={source.url} favicon={source.favicon} />\n )}\n <span className=\"truncate max-w-[200px]\">{displayText}</span>\n {variant === 'default' && (\n <ExternalLink className=\"size-3 shrink-0\" aria-hidden=\"true\" />\n )}\n </>\n );\n\n // Render as <a> when navigating to URL (proper semantics)\n if (!onClick) {\n return (\n <a\n data-slot=\"ai-source-trigger\"\n href={source.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={sharedClassName}\n aria-label={`Source: ${displayText}`}\n >\n {sharedChildren}\n </a>\n );\n }\n\n // Render as <button> when custom click handler is provided\n return (\n <button\n type=\"button\"\n data-slot=\"ai-source-trigger\"\n onClick={onClick}\n className={sharedClassName}\n aria-label={`Source: ${displayText}`}\n >\n {sharedChildren}\n </button>\n );\n}\n\nAISourceTrigger.displayName = 'AISourceTrigger';\n\n// =============================================================================\n// Source Content (Tooltip/Popover content)\n// =============================================================================\n\nexport interface AISourceContentProps {\n /** Source data */\n source: SourceData;\n /** Additional class name */\n className?: string;\n}\n\nfunction AISourceContent({ source, className }: AISourceContentProps) {\n const domain = React.useMemo(() => {\n try {\n return new URL(source.url).hostname;\n } catch {\n return source.url;\n }\n }, [source.url]);\n\n return (\n <div className={cn('p-3 max-w-xs space-y-2', className)}>\n <div className=\"flex items-start gap-2\">\n <SourceFavicon\n url={source.url}\n favicon={source.favicon}\n className=\"mt-0.5\"\n />\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-foreground truncate\">\n {source.title || domain}\n </p>\n <p className=\"text-xs text-text-quaternary truncate\">{domain}</p>\n </div>\n </div>\n {source.description && (\n <p className=\"text-xs text-muted-foreground line-clamp-2\">\n {source.description}\n </p>\n )}\n <a\n href={source.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-1 text-xs text-primary hover:text-primary\"\n >\n Visit source\n <ExternalLink className=\"size-3\" />\n </a>\n </div>\n );\n}\n\nAISourceContent.displayName = 'AISourceContent';\n\n// =============================================================================\n// Main AISource Component (with built-in tooltip)\n// =============================================================================\n\nexport interface AISourceProps extends VariantProps<typeof sourceVariants> {\n /** Source data */\n source: SourceData;\n /** Whether to show favicon */\n showFavicon?: boolean;\n /** Whether to show tooltip on hover */\n showTooltip?: boolean;\n /** Additional class name */\n className?: string;\n}\n\nfunction AISource({\n source,\n variant,\n showFavicon = true,\n showTooltip = true,\n className,\n}: AISourceProps) {\n if (!showTooltip) {\n return (\n <span data-slot=\"ai-source\">\n <AISourceTrigger\n source={source}\n variant={variant}\n showFavicon={showFavicon}\n className={className}\n />\n </span>\n );\n }\n\n return (\n <Tooltip>\n <TooltipTrigger\n render={\n <span data-slot=\"ai-source\">\n <AISourceTrigger\n source={source}\n variant={variant}\n showFavicon={showFavicon}\n className={className}\n />\n </span>\n }\n />\n <TooltipPopup side=\"top\" className=\"p-0\">\n <AISourceContent source={source} />\n </TooltipPopup>\n </Tooltip>\n );\n}\n\nAISource.displayName = 'AISource';\n\n// =============================================================================\n// Source List Component\n// =============================================================================\n\nexport interface AISourceListProps {\n /** Array of sources */\n sources: SourceData[];\n /** Maximum sources to show before truncating */\n maxVisible?: number;\n /** Whether to show expanded list */\n showAll?: boolean;\n /** Callback when \"show more\" is clicked */\n onShowMore?: () => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction AISourceList({\n sources,\n maxVisible = 3,\n showAll = false,\n onShowMore,\n className,\n}: AISourceListProps) {\n const safeMaxVisible = getMaxVisibleSources(maxVisible);\n const visibleSources = showAll ? sources : sources.slice(0, safeMaxVisible);\n const remainingCount = Math.max(0, sources.length - safeMaxVisible);\n\n return (\n <nav\n data-slot=\"ai-source-list\"\n aria-label=\"Sources\"\n className={cn('flex flex-wrap items-center gap-2', className)}\n >\n <span className=\"text-xs text-text-quaternary\">Sources:</span>\n {visibleSources.map((source, index) => (\n <span\n key={`${source.url}-${index}`}\n className=\"delight-stagger motion-reduce:!animate-none\"\n style={\n { '--delight-delay': `${index * 50}ms` } as React.CSSProperties\n }\n >\n <AISource source={source} variant=\"pill\" />\n </span>\n ))}\n {!showAll && remainingCount > 0 && (\n <button\n type=\"button\"\n onClick={onShowMore}\n aria-label={`Show ${remainingCount} more sources`}\n className=\"px-2.5 py-1 rounded-full bg-accent hover:bg-surface-2 text-xs text-secondary-foreground transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring delight-selection-press\"\n >\n +{remainingCount} more\n </button>\n )}\n </nav>\n );\n}\n\nAISourceList.displayName = 'AISourceList';\n\nexport {\n AISource,\n AISourceContent,\n AISourceList,\n AISourceTrigger,\n SourceFavicon,\n sourceVariants,\n};\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
1
+ {"version":3,"file":"AISource.js","names":["__iconNode"],"sources":["../../../../../../../../../../../Users/akarim/Documents/test/humain_foundation_ui/node_modules/.bun/lucide-react@1.27.0+0f58469d5b3bd39f/node_modules/lucide-react/dist/esm/icons/external-link.mjs","../../../../../../../../../../../Users/akarim/Documents/test/humain_foundation_ui/node_modules/.bun/lucide-react@1.27.0+0f58469d5b3bd39f/node_modules/lucide-react/dist/esm/icons/globe.mjs","../../src/components/organisms/ai/AISource/AISource.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.27.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M15 3h6v6\", key: \"1q9fwt\" }],\n [\"path\", { d: \"M10 14 21 3\", key: \"gplh6r\" }],\n [\"path\", { d: \"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\", key: \"a6xqqp\" }]\n];\nconst ExternalLink = createLucideIcon(\"external-link\", __iconNode);\n\nexport { __iconNode, ExternalLink as default };\n//# sourceMappingURL=external-link.mjs.map\n","/**\n * @license lucide-react v1.27.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"path\", { d: \"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20\", key: \"13o1zl\" }],\n [\"path\", { d: \"M2 12h20\", key: \"9i4pu4\" }]\n];\nconst Globe = createLucideIcon(\"globe\", __iconNode);\n\nexport { __iconNode, Globe as default };\n//# sourceMappingURL=globe.mjs.map\n","import { cva, type VariantProps } from 'class-variance-authority';\nimport { ExternalLink, Globe } from 'lucide-react';\nimport * as React from 'react';\nimport { Tooltip, TooltipPopup, TooltipTrigger } from '@/components/ui/tooltip';\nimport { cn } from '@/lib/utils';\n\n// =============================================================================\n// Variants\n// =============================================================================\n\nconst sourceVariants = cva(\n 'inline-flex items-center gap-1.5 transition-colors cursor-pointer focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring',\n {\n variants: {\n variant: {\n default:\n 'text-sm text-primary hover:text-primary underline underline-offset-2 rounded-sm',\n pill: 'px-2.5 py-1 rounded-full bg-accent hover:bg-surface-2 text-xs text-secondary-foreground delight-selection-press',\n minimal:\n 'text-xs text-secondary-foreground hover:text-foreground rounded-sm',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n);\n\nconst DEFAULT_MAX_VISIBLE_SOURCES = 3;\n\nfunction getMaxVisibleSources(maxVisible: number): number {\n return Number.isFinite(maxVisible) && maxVisible >= 0\n ? Math.floor(maxVisible)\n : DEFAULT_MAX_VISIBLE_SOURCES;\n}\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface SourceData {\n /** Source URL */\n url: string;\n /** Display title */\n title?: string;\n /** Source description */\n description?: string;\n /** Favicon URL */\n favicon?: string;\n /** Site name */\n siteName?: string;\n}\n\n// =============================================================================\n// Source Favicon\n// =============================================================================\n\ninterface SourceFaviconProps {\n url: string;\n favicon?: string;\n className?: string;\n}\n\nfunction SourceFavicon({ url, favicon, className }: SourceFaviconProps) {\n const [hasError, setHasError] = React.useState(false);\n\n // Generate favicon URL from domain if not provided\n const faviconUrl = React.useMemo(() => {\n if (favicon) return favicon;\n try {\n const domain = new URL(url).hostname;\n return `https://www.google.com/s2/favicons?domain=${domain}&sz=32`;\n } catch {\n return null;\n }\n }, [url, favicon]);\n\n if (!faviconUrl || hasError) {\n return <Globe className={cn('size-4 text-muted-foreground', className)} />;\n }\n\n return (\n <img\n src={faviconUrl}\n alt=\"\"\n className={cn(\n 'size-4 rounded delight-fade-in motion-reduce:!animate-none',\n className,\n )}\n onError={() => setHasError(true)}\n />\n );\n}\n\nSourceFavicon.displayName = 'SourceFavicon';\n\n// =============================================================================\n// Source Trigger (Clickable element)\n// =============================================================================\n\nexport interface AISourceTriggerProps\n extends VariantProps<typeof sourceVariants> {\n /** Source data */\n source: SourceData;\n /** Whether to show favicon */\n showFavicon?: boolean;\n /** Additional class name */\n className?: string;\n /** Click handler */\n onClick?: () => void;\n}\n\nfunction AISourceTrigger({\n source,\n variant,\n showFavicon = true,\n className,\n onClick,\n}: AISourceTriggerProps) {\n const displayText = source.title || source.siteName || source.url;\n\n const sharedClassName = cn(sourceVariants({ variant }), className);\n const sharedChildren = (\n <>\n {showFavicon && (\n <SourceFavicon url={source.url} favicon={source.favicon} />\n )}\n <span className=\"truncate max-w-[200px]\">{displayText}</span>\n {variant === 'default' && (\n <ExternalLink className=\"size-3 shrink-0\" aria-hidden=\"true\" />\n )}\n </>\n );\n\n // Render as <a> when navigating to URL (proper semantics)\n if (!onClick) {\n return (\n <a\n data-slot=\"ai-source-trigger\"\n href={source.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={sharedClassName}\n aria-label={`Source: ${displayText}`}\n >\n {sharedChildren}\n </a>\n );\n }\n\n // Render as <button> when custom click handler is provided\n return (\n <button\n type=\"button\"\n data-slot=\"ai-source-trigger\"\n onClick={onClick}\n className={sharedClassName}\n aria-label={`Source: ${displayText}`}\n >\n {sharedChildren}\n </button>\n );\n}\n\nAISourceTrigger.displayName = 'AISourceTrigger';\n\n// =============================================================================\n// Source Content (Tooltip/Popover content)\n// =============================================================================\n\nexport interface AISourceContentProps {\n /** Source data */\n source: SourceData;\n /** Additional class name */\n className?: string;\n}\n\nfunction AISourceContent({ source, className }: AISourceContentProps) {\n const domain = React.useMemo(() => {\n try {\n return new URL(source.url).hostname;\n } catch {\n return source.url;\n }\n }, [source.url]);\n\n return (\n <div className={cn('p-3 max-w-xs space-y-2', className)}>\n <div className=\"flex items-start gap-2\">\n <SourceFavicon\n url={source.url}\n favicon={source.favicon}\n className=\"mt-0.5\"\n />\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-foreground truncate\">\n {source.title || domain}\n </p>\n <p className=\"text-xs text-secondary-foreground truncate\">{domain}</p>\n </div>\n </div>\n {source.description && (\n <p className=\"text-xs text-muted-foreground line-clamp-2\">\n {source.description}\n </p>\n )}\n <a\n href={source.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-1 text-xs text-primary hover:text-primary\"\n >\n Visit source\n <ExternalLink className=\"size-3\" />\n </a>\n </div>\n );\n}\n\nAISourceContent.displayName = 'AISourceContent';\n\n// =============================================================================\n// Main AISource Component (with built-in tooltip)\n// =============================================================================\n\nexport interface AISourceProps extends VariantProps<typeof sourceVariants> {\n /** Source data */\n source: SourceData;\n /** Whether to show favicon */\n showFavicon?: boolean;\n /** Whether to show tooltip on hover */\n showTooltip?: boolean;\n /** Additional class name */\n className?: string;\n}\n\nfunction AISource({\n source,\n variant,\n showFavicon = true,\n showTooltip = true,\n className,\n}: AISourceProps) {\n if (!showTooltip) {\n return (\n <span data-slot=\"ai-source\">\n <AISourceTrigger\n source={source}\n variant={variant}\n showFavicon={showFavicon}\n className={className}\n />\n </span>\n );\n }\n\n return (\n <Tooltip>\n <TooltipTrigger\n render={\n <span data-slot=\"ai-source\">\n <AISourceTrigger\n source={source}\n variant={variant}\n showFavicon={showFavicon}\n className={className}\n />\n </span>\n }\n />\n <TooltipPopup side=\"top\" className=\"p-0\">\n <AISourceContent source={source} />\n </TooltipPopup>\n </Tooltip>\n );\n}\n\nAISource.displayName = 'AISource';\n\n// =============================================================================\n// Source List Component\n// =============================================================================\n\nexport interface AISourceListProps {\n /** Array of sources */\n sources: SourceData[];\n /** Maximum sources to show before truncating */\n maxVisible?: number;\n /** Whether to show expanded list */\n showAll?: boolean;\n /** Callback when \"show more\" is clicked */\n onShowMore?: () => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction AISourceList({\n sources,\n maxVisible = 3,\n showAll = false,\n onShowMore,\n className,\n}: AISourceListProps) {\n const safeMaxVisible = getMaxVisibleSources(maxVisible);\n const visibleSources = showAll ? sources : sources.slice(0, safeMaxVisible);\n const remainingCount = Math.max(0, sources.length - safeMaxVisible);\n\n return (\n <nav\n data-slot=\"ai-source-list\"\n aria-label=\"Sources\"\n className={cn('flex flex-wrap items-center gap-2', className)}\n >\n <span className=\"text-xs text-secondary-foreground\">Sources:</span>\n {visibleSources.map((source, index) => (\n <span\n key={`${source.url}-${index}`}\n className=\"delight-stagger motion-reduce:!animate-none\"\n style={\n { '--delight-delay': `${index * 50}ms` } as React.CSSProperties\n }\n >\n <AISource source={source} variant=\"pill\" />\n </span>\n ))}\n {!showAll && remainingCount > 0 && (\n <button\n type=\"button\"\n onClick={onShowMore}\n aria-label={`Show ${remainingCount} more sources`}\n className=\"px-2.5 py-1 rounded-full bg-accent hover:bg-surface-2 text-xs text-secondary-foreground transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring delight-selection-press\"\n >\n +{remainingCount} more\n </button>\n )}\n </nav>\n );\n}\n\nAISourceList.displayName = 'AISourceList';\n\nexport {\n AISource,\n AISourceContent,\n AISourceList,\n AISourceTrigger,\n SourceFavicon,\n sourceVariants,\n};\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
@@ -92,7 +92,7 @@ function f({ title: e, icon: a, children: t, className: n }) {
92
92
  return /* @__PURE__ */ (0, s.jsxs)("div", {
93
93
  className: o("space-y-2", n),
94
94
  children: [/* @__PURE__ */ (0, s.jsxs)("div", {
95
- className: "flex items-center gap-2 text-xs font-medium text-text-quaternary uppercase tracking-wide",
95
+ className: "flex items-center gap-2 text-xs font-medium text-secondary-foreground uppercase tracking-wide",
96
96
  children: [a, e]
97
97
  }), t]
98
98
  });
@@ -1 +1 @@
1
- {"version":3,"file":"AIToolCall.js","names":["__iconNode"],"sources":["../../../../../../../../../../../Users/akarim/Documents/test/humain_foundation_ui/node_modules/.bun/lucide-react@1.27.0+0f58469d5b3bd39f/node_modules/lucide-react/dist/esm/icons/code.mjs","../../../../../../../../../../../Users/akarim/Documents/test/humain_foundation_ui/node_modules/.bun/lucide-react@1.27.0+0f58469d5b3bd39f/node_modules/lucide-react/dist/esm/icons/wrench.mjs","../../src/components/organisms/ai/AIToolCall/AIToolCall.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.27.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"m16 18 6-6-6-6\", key: \"eg8j8\" }],\n [\"path\", { d: \"m8 6-6 6 6 6\", key: \"ppft3o\" }]\n];\nconst Code = createLucideIcon(\"code\", __iconNode);\n\nexport { __iconNode, Code as default };\n//# sourceMappingURL=code.mjs.map\n","/**\n * @license lucide-react v1.27.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z\",\n key: \"1ngwbx\"\n }\n ]\n];\nconst Wrench = createLucideIcon(\"wrench\", __iconNode);\n\nexport { __iconNode, Wrench as default };\n//# sourceMappingURL=wrench.mjs.map\n","import { cva, type VariantProps } from 'class-variance-authority';\nimport {\n AlertCircle,\n Check,\n ChevronDown,\n ChevronRight,\n Clock,\n Code,\n Wrench,\n} from 'lucide-react';\nimport { AnimatePresence, motion } from 'motion/react';\nimport * as React from 'react';\nimport { AICodeBlock } from '@/components/organisms/ai/AICodeBlock';\nimport { useControllableState } from '@/hooks/use-controllable-state';\nimport { cn } from '@/lib/utils';\n\n// =============================================================================\n// Variants\n// =============================================================================\n\nconst toolCallVariants = cva(\n 'overflow-hidden rounded-xl border transition-colors',\n {\n variants: {\n status: {\n pending: 'border-border bg-muted',\n running: 'border-primary bg-primary/10',\n success: 'border-success/50 bg-success/10',\n error: 'border-destructive/50 bg-destructive/10',\n },\n },\n defaultVariants: {\n status: 'pending',\n },\n },\n);\n\nconst statusIconVariants = cva('size-4', {\n variants: {\n status: {\n pending: 'text-muted-foreground',\n running: 'text-primary animate-spin motion-reduce:animate-none',\n success: 'text-success',\n error: 'text-destructive',\n },\n },\n defaultVariants: {\n status: 'pending',\n },\n});\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type ToolCallStatus = 'pending' | 'running' | 'success' | 'error';\n\nexport interface ToolCallPart {\n /** Unique tool call ID */\n toolCallId: string;\n /** Tool name */\n toolName: string;\n /** Tool input/arguments */\n args?: Record<string, unknown>;\n /** Tool output/result */\n result?: unknown;\n /** Tool status */\n status?: ToolCallStatus;\n /** Error message if status is error */\n error?: string;\n}\n\n// =============================================================================\n// Status Icon Component\n// =============================================================================\n\ninterface StatusIconProps {\n status: ToolCallStatus;\n className?: string;\n}\n\nfunction StatusIcon({ status, className }: StatusIconProps) {\n const iconClass = cn(statusIconVariants({ status }), className);\n\n switch (status) {\n case 'running':\n return <Clock className={iconClass} />;\n case 'success':\n return (\n <Check\n className={cn(\n iconClass,\n 'delight-check-bounce motion-reduce:!animate-none',\n )}\n />\n );\n case 'error':\n return (\n <AlertCircle\n className={cn(iconClass, 'delight-shake motion-reduce:!animate-none')}\n />\n );\n default:\n return <Wrench className={iconClass} />;\n }\n}\n\nStatusIcon.displayName = 'StatusIcon';\n\n// =============================================================================\n// Tool Call Header\n// =============================================================================\n\ninterface AIToolCallHeaderProps {\n toolName: string;\n status: ToolCallStatus;\n isOpen: boolean;\n onToggle: () => void;\n className?: string;\n}\n\nfunction AIToolCallHeader({\n toolName,\n status,\n isOpen,\n onToggle,\n className,\n}: AIToolCallHeaderProps) {\n const statusLabel = {\n pending: 'Pending',\n running: 'Running...',\n success: 'Completed',\n error: 'Failed',\n };\n\n return (\n <button\n type=\"button\"\n onClick={onToggle}\n aria-expanded={isOpen}\n className={cn(\n 'flex items-center justify-between w-full px-4 py-3 transition-colors hover:bg-foreground/5 focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-ring',\n className,\n )}\n >\n <div className=\"flex items-center gap-3\">\n <StatusIcon status={status} aria-hidden=\"true\" />\n <div className=\"flex flex-col items-start\">\n <span className=\"text-sm font-medium text-foreground\">\n {toolName}\n </span>\n <span className=\"text-xs text-secondary-foreground\">\n {statusLabel[status]}\n </span>\n </div>\n </div>\n {isOpen ? (\n <ChevronDown\n className=\"size-4 text-muted-foreground\"\n aria-hidden=\"true\"\n />\n ) : (\n <ChevronRight\n className=\"size-4 text-muted-foreground rtl:rotate-180\"\n aria-hidden=\"true\"\n />\n )}\n </button>\n );\n}\n\nAIToolCallHeader.displayName = 'AIToolCallHeader';\n\n// =============================================================================\n// Tool Call Section\n// =============================================================================\n\ninterface ToolCallSectionProps {\n title: string;\n icon: React.ReactNode;\n children: React.ReactNode;\n className?: string;\n}\n\nfunction ToolCallSection({\n title,\n icon,\n children,\n className,\n}: ToolCallSectionProps) {\n return (\n <div className={cn('space-y-2', className)}>\n <div className=\"flex items-center gap-2 text-xs font-medium text-text-quaternary uppercase tracking-wide\">\n {icon}\n {title}\n </div>\n {children}\n </div>\n );\n}\n\nToolCallSection.displayName = 'ToolCallSection';\n\n// =============================================================================\n// Main AIToolCall Component\n// =============================================================================\n\nexport interface AIToolCallProps extends VariantProps<typeof toolCallVariants> {\n /** Tool call data */\n toolPart: ToolCallPart;\n /** Whether to expand by default */\n defaultOpen?: boolean;\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction formatValue(value: unknown): string {\n if (typeof value === 'string') return value;\n return JSON.stringify(value, null, 2);\n}\n\nfunction AIToolCall({\n toolPart,\n defaultOpen = false,\n open: controlledOpen,\n onOpenChange,\n className,\n}: AIToolCallProps) {\n const [isOpen, setIsOpen] = useControllableState({\n value: controlledOpen,\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n });\n\n const status = toolPart.status || 'pending';\n\n const handleToggle = () => {\n setIsOpen(!isOpen);\n };\n\n return (\n <div\n data-slot=\"ai-tool-call\"\n className={cn(toolCallVariants({ status }), className)}\n >\n <AIToolCallHeader\n toolName={toolPart.toolName}\n status={status}\n isOpen={isOpen}\n onToggle={handleToggle}\n />\n\n <AnimatePresence>\n {isOpen && (\n <motion.div\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: 'auto', opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n transition={{ duration: 0.2 }}\n className=\"overflow-hidden\"\n >\n <div className=\"px-4 pb-4 space-y-4\">\n {/* Tool Call ID */}\n <div className=\"text-xs text-muted-foreground font-mono\">\n ID: {toolPart.toolCallId}\n </div>\n\n {/* Input Section */}\n {toolPart.args && Object.keys(toolPart.args).length > 0 && (\n <ToolCallSection\n title=\"Input\"\n icon={<Code className=\"size-3\" />}\n >\n <AICodeBlock\n code={formatValue(toolPart.args)}\n language=\"json\"\n showHeader={false}\n showCopyButton={true}\n size=\"sm\"\n />\n </ToolCallSection>\n )}\n\n {/* Output Section */}\n {toolPart.result !== undefined && (\n <ToolCallSection\n title=\"Output\"\n icon={<Code className=\"size-3\" />}\n >\n <AICodeBlock\n code={formatValue(toolPart.result)}\n language=\"json\"\n showHeader={false}\n showCopyButton={true}\n size=\"sm\"\n />\n </ToolCallSection>\n )}\n\n {/* Error Section */}\n {toolPart.error && (\n <div className=\"p-3 rounded-lg bg-destructive/20 border border-destructive/50\">\n <div className=\"flex items-start gap-2\">\n <AlertCircle className=\"size-4 text-destructive mt-0.5 shrink-0\" />\n <p className=\"text-sm text-destructive\">{toolPart.error}</p>\n </div>\n </div>\n )}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n}\n\nAIToolCall.displayName = 'AIToolCall';\n\n// =============================================================================\n// Tool Call List Component\n// =============================================================================\n\nexport interface AIToolCallListProps {\n /** Array of tool calls */\n toolCalls: readonly ToolCallPart[];\n /** Whether to expand all by default */\n defaultAllOpen?: boolean;\n /** Tool-call IDs to expand initially in uncontrolled mode */\n defaultOpenToolCallIds?: readonly string[];\n /** Controlled expanded tool-call IDs */\n openToolCallIds?: readonly string[];\n /** Called with expanded IDs in current tool-call order */\n onOpenToolCallIdsChange?: (ids: readonly string[]) => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction normalizeOpenToolCallIds(\n ids: readonly string[],\n toolCalls: readonly ToolCallPart[],\n): string[] {\n const requested = new Set(ids);\n return toolCalls.flatMap((toolCall) =>\n requested.has(toolCall.toolCallId) ? [toolCall.toolCallId] : [],\n );\n}\n\nfunction areToolCallIdsEqual(\n left: readonly string[],\n right: readonly string[],\n): boolean {\n return (\n left.length === right.length &&\n left.every((id, index) => id === right[index])\n );\n}\n\nfunction AIToolCallList({\n toolCalls,\n defaultAllOpen = false,\n defaultOpenToolCallIds = [],\n openToolCallIds: controlledOpenToolCallIds,\n onOpenToolCallIdsChange,\n className,\n}: AIToolCallListProps) {\n const isControlled = controlledOpenToolCallIds !== undefined;\n const [uncontrolledOpenToolCallIds, setUncontrolledOpenToolCallIds] =\n React.useState<readonly string[]>(() =>\n normalizeOpenToolCallIds(\n defaultAllOpen\n ? toolCalls.map((toolCall) => toolCall.toolCallId)\n : defaultOpenToolCallIds,\n toolCalls,\n ),\n );\n const rawOpenToolCallIds = isControlled\n ? controlledOpenToolCallIds\n : uncontrolledOpenToolCallIds;\n const visibleOpenToolCallIds = normalizeOpenToolCallIds(\n rawOpenToolCallIds,\n toolCalls,\n );\n const openSet = new Set(visibleOpenToolCallIds);\n\n React.useLayoutEffect(() => {\n if (isControlled) return;\n setUncontrolledOpenToolCallIds((current) => {\n const normalized = normalizeOpenToolCallIds(current, toolCalls);\n return areToolCallIdsEqual(current, normalized) ? current : normalized;\n });\n }, [isControlled, toolCalls]);\n\n const setToolCallOpen = (toolCallId: string, open: boolean) => {\n const next = new Set(visibleOpenToolCallIds);\n if (open) next.add(toolCallId);\n else next.delete(toolCallId);\n const normalized = normalizeOpenToolCallIds([...next], toolCalls);\n if (!isControlled) {\n setUncontrolledOpenToolCallIds(normalized);\n }\n onOpenToolCallIdsChange?.([...normalized]);\n };\n\n return (\n <div data-slot=\"ai-tool-call-list\" className={cn('space-y-2', className)}>\n {toolCalls.map((toolCall) => (\n <AIToolCall\n key={toolCall.toolCallId}\n toolPart={toolCall}\n open={openSet.has(toolCall.toolCallId)}\n onOpenChange={(open) => setToolCallOpen(toolCall.toolCallId, open)}\n />\n ))}\n </div>\n );\n}\n\nAIToolCallList.displayName = 'AIToolCallList';\n\nexport {\n AIToolCall,\n AIToolCallHeader,\n AIToolCallList,\n StatusIcon,\n statusIconVariants,\n ToolCallSection,\n toolCallVariants,\n};\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
1
+ {"version":3,"file":"AIToolCall.js","names":["__iconNode"],"sources":["../../../../../../../../../../../Users/akarim/Documents/test/humain_foundation_ui/node_modules/.bun/lucide-react@1.27.0+0f58469d5b3bd39f/node_modules/lucide-react/dist/esm/icons/code.mjs","../../../../../../../../../../../Users/akarim/Documents/test/humain_foundation_ui/node_modules/.bun/lucide-react@1.27.0+0f58469d5b3bd39f/node_modules/lucide-react/dist/esm/icons/wrench.mjs","../../src/components/organisms/ai/AIToolCall/AIToolCall.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.27.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"m16 18 6-6-6-6\", key: \"eg8j8\" }],\n [\"path\", { d: \"m8 6-6 6 6 6\", key: \"ppft3o\" }]\n];\nconst Code = createLucideIcon(\"code\", __iconNode);\n\nexport { __iconNode, Code as default };\n//# sourceMappingURL=code.mjs.map\n","/**\n * @license lucide-react v1.27.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z\",\n key: \"1ngwbx\"\n }\n ]\n];\nconst Wrench = createLucideIcon(\"wrench\", __iconNode);\n\nexport { __iconNode, Wrench as default };\n//# sourceMappingURL=wrench.mjs.map\n","import { cva, type VariantProps } from 'class-variance-authority';\nimport {\n AlertCircle,\n Check,\n ChevronDown,\n ChevronRight,\n Clock,\n Code,\n Wrench,\n} from 'lucide-react';\nimport { AnimatePresence, motion } from 'motion/react';\nimport * as React from 'react';\nimport { AICodeBlock } from '@/components/organisms/ai/AICodeBlock';\nimport { useControllableState } from '@/hooks/use-controllable-state';\nimport { cn } from '@/lib/utils';\n\n// =============================================================================\n// Variants\n// =============================================================================\n\nconst toolCallVariants = cva(\n 'overflow-hidden rounded-xl border transition-colors',\n {\n variants: {\n status: {\n pending: 'border-border bg-muted',\n running: 'border-primary bg-primary/10',\n success: 'border-success/50 bg-success/10',\n error: 'border-destructive/50 bg-destructive/10',\n },\n },\n defaultVariants: {\n status: 'pending',\n },\n },\n);\n\nconst statusIconVariants = cva('size-4', {\n variants: {\n status: {\n pending: 'text-muted-foreground',\n running: 'text-primary animate-spin motion-reduce:animate-none',\n success: 'text-success',\n error: 'text-destructive',\n },\n },\n defaultVariants: {\n status: 'pending',\n },\n});\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type ToolCallStatus = 'pending' | 'running' | 'success' | 'error';\n\nexport interface ToolCallPart {\n /** Unique tool call ID */\n toolCallId: string;\n /** Tool name */\n toolName: string;\n /** Tool input/arguments */\n args?: Record<string, unknown>;\n /** Tool output/result */\n result?: unknown;\n /** Tool status */\n status?: ToolCallStatus;\n /** Error message if status is error */\n error?: string;\n}\n\n// =============================================================================\n// Status Icon Component\n// =============================================================================\n\ninterface StatusIconProps {\n status: ToolCallStatus;\n className?: string;\n}\n\nfunction StatusIcon({ status, className }: StatusIconProps) {\n const iconClass = cn(statusIconVariants({ status }), className);\n\n switch (status) {\n case 'running':\n return <Clock className={iconClass} />;\n case 'success':\n return (\n <Check\n className={cn(\n iconClass,\n 'delight-check-bounce motion-reduce:!animate-none',\n )}\n />\n );\n case 'error':\n return (\n <AlertCircle\n className={cn(iconClass, 'delight-shake motion-reduce:!animate-none')}\n />\n );\n default:\n return <Wrench className={iconClass} />;\n }\n}\n\nStatusIcon.displayName = 'StatusIcon';\n\n// =============================================================================\n// Tool Call Header\n// =============================================================================\n\ninterface AIToolCallHeaderProps {\n toolName: string;\n status: ToolCallStatus;\n isOpen: boolean;\n onToggle: () => void;\n className?: string;\n}\n\nfunction AIToolCallHeader({\n toolName,\n status,\n isOpen,\n onToggle,\n className,\n}: AIToolCallHeaderProps) {\n const statusLabel = {\n pending: 'Pending',\n running: 'Running...',\n success: 'Completed',\n error: 'Failed',\n };\n\n return (\n <button\n type=\"button\"\n onClick={onToggle}\n aria-expanded={isOpen}\n className={cn(\n 'flex items-center justify-between w-full px-4 py-3 transition-colors hover:bg-foreground/5 focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-ring',\n className,\n )}\n >\n <div className=\"flex items-center gap-3\">\n <StatusIcon status={status} aria-hidden=\"true\" />\n <div className=\"flex flex-col items-start\">\n <span className=\"text-sm font-medium text-foreground\">\n {toolName}\n </span>\n <span className=\"text-xs text-secondary-foreground\">\n {statusLabel[status]}\n </span>\n </div>\n </div>\n {isOpen ? (\n <ChevronDown\n className=\"size-4 text-muted-foreground\"\n aria-hidden=\"true\"\n />\n ) : (\n <ChevronRight\n className=\"size-4 text-muted-foreground rtl:rotate-180\"\n aria-hidden=\"true\"\n />\n )}\n </button>\n );\n}\n\nAIToolCallHeader.displayName = 'AIToolCallHeader';\n\n// =============================================================================\n// Tool Call Section\n// =============================================================================\n\ninterface ToolCallSectionProps {\n title: string;\n icon: React.ReactNode;\n children: React.ReactNode;\n className?: string;\n}\n\nfunction ToolCallSection({\n title,\n icon,\n children,\n className,\n}: ToolCallSectionProps) {\n return (\n <div className={cn('space-y-2', className)}>\n <div className=\"flex items-center gap-2 text-xs font-medium text-secondary-foreground uppercase tracking-wide\">\n {icon}\n {title}\n </div>\n {children}\n </div>\n );\n}\n\nToolCallSection.displayName = 'ToolCallSection';\n\n// =============================================================================\n// Main AIToolCall Component\n// =============================================================================\n\nexport interface AIToolCallProps extends VariantProps<typeof toolCallVariants> {\n /** Tool call data */\n toolPart: ToolCallPart;\n /** Whether to expand by default */\n defaultOpen?: boolean;\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction formatValue(value: unknown): string {\n if (typeof value === 'string') return value;\n return JSON.stringify(value, null, 2);\n}\n\nfunction AIToolCall({\n toolPart,\n defaultOpen = false,\n open: controlledOpen,\n onOpenChange,\n className,\n}: AIToolCallProps) {\n const [isOpen, setIsOpen] = useControllableState({\n value: controlledOpen,\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n });\n\n const status = toolPart.status || 'pending';\n\n const handleToggle = () => {\n setIsOpen(!isOpen);\n };\n\n return (\n <div\n data-slot=\"ai-tool-call\"\n className={cn(toolCallVariants({ status }), className)}\n >\n <AIToolCallHeader\n toolName={toolPart.toolName}\n status={status}\n isOpen={isOpen}\n onToggle={handleToggle}\n />\n\n <AnimatePresence>\n {isOpen && (\n <motion.div\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: 'auto', opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n transition={{ duration: 0.2 }}\n className=\"overflow-hidden\"\n >\n <div className=\"px-4 pb-4 space-y-4\">\n {/* Tool Call ID */}\n <div className=\"text-xs text-muted-foreground font-mono\">\n ID: {toolPart.toolCallId}\n </div>\n\n {/* Input Section */}\n {toolPart.args && Object.keys(toolPart.args).length > 0 && (\n <ToolCallSection\n title=\"Input\"\n icon={<Code className=\"size-3\" />}\n >\n <AICodeBlock\n code={formatValue(toolPart.args)}\n language=\"json\"\n showHeader={false}\n showCopyButton={true}\n size=\"sm\"\n />\n </ToolCallSection>\n )}\n\n {/* Output Section */}\n {toolPart.result !== undefined && (\n <ToolCallSection\n title=\"Output\"\n icon={<Code className=\"size-3\" />}\n >\n <AICodeBlock\n code={formatValue(toolPart.result)}\n language=\"json\"\n showHeader={false}\n showCopyButton={true}\n size=\"sm\"\n />\n </ToolCallSection>\n )}\n\n {/* Error Section */}\n {toolPart.error && (\n <div className=\"p-3 rounded-lg bg-destructive/20 border border-destructive/50\">\n <div className=\"flex items-start gap-2\">\n <AlertCircle className=\"size-4 text-destructive mt-0.5 shrink-0\" />\n <p className=\"text-sm text-destructive\">{toolPart.error}</p>\n </div>\n </div>\n )}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n}\n\nAIToolCall.displayName = 'AIToolCall';\n\n// =============================================================================\n// Tool Call List Component\n// =============================================================================\n\nexport interface AIToolCallListProps {\n /** Array of tool calls */\n toolCalls: readonly ToolCallPart[];\n /** Whether to expand all by default */\n defaultAllOpen?: boolean;\n /** Tool-call IDs to expand initially in uncontrolled mode */\n defaultOpenToolCallIds?: readonly string[];\n /** Controlled expanded tool-call IDs */\n openToolCallIds?: readonly string[];\n /** Called with expanded IDs in current tool-call order */\n onOpenToolCallIdsChange?: (ids: readonly string[]) => void;\n /** Additional class name */\n className?: string;\n}\n\nfunction normalizeOpenToolCallIds(\n ids: readonly string[],\n toolCalls: readonly ToolCallPart[],\n): string[] {\n const requested = new Set(ids);\n return toolCalls.flatMap((toolCall) =>\n requested.has(toolCall.toolCallId) ? [toolCall.toolCallId] : [],\n );\n}\n\nfunction areToolCallIdsEqual(\n left: readonly string[],\n right: readonly string[],\n): boolean {\n return (\n left.length === right.length &&\n left.every((id, index) => id === right[index])\n );\n}\n\nfunction AIToolCallList({\n toolCalls,\n defaultAllOpen = false,\n defaultOpenToolCallIds = [],\n openToolCallIds: controlledOpenToolCallIds,\n onOpenToolCallIdsChange,\n className,\n}: AIToolCallListProps) {\n const isControlled = controlledOpenToolCallIds !== undefined;\n const [uncontrolledOpenToolCallIds, setUncontrolledOpenToolCallIds] =\n React.useState<readonly string[]>(() =>\n normalizeOpenToolCallIds(\n defaultAllOpen\n ? toolCalls.map((toolCall) => toolCall.toolCallId)\n : defaultOpenToolCallIds,\n toolCalls,\n ),\n );\n const rawOpenToolCallIds = isControlled\n ? controlledOpenToolCallIds\n : uncontrolledOpenToolCallIds;\n const visibleOpenToolCallIds = normalizeOpenToolCallIds(\n rawOpenToolCallIds,\n toolCalls,\n );\n const openSet = new Set(visibleOpenToolCallIds);\n\n React.useLayoutEffect(() => {\n if (isControlled) return;\n setUncontrolledOpenToolCallIds((current) => {\n const normalized = normalizeOpenToolCallIds(current, toolCalls);\n return areToolCallIdsEqual(current, normalized) ? current : normalized;\n });\n }, [isControlled, toolCalls]);\n\n const setToolCallOpen = (toolCallId: string, open: boolean) => {\n const next = new Set(visibleOpenToolCallIds);\n if (open) next.add(toolCallId);\n else next.delete(toolCallId);\n const normalized = normalizeOpenToolCallIds([...next], toolCalls);\n if (!isControlled) {\n setUncontrolledOpenToolCallIds(normalized);\n }\n onOpenToolCallIdsChange?.([...normalized]);\n };\n\n return (\n <div data-slot=\"ai-tool-call-list\" className={cn('space-y-2', className)}>\n {toolCalls.map((toolCall) => (\n <AIToolCall\n key={toolCall.toolCallId}\n toolPart={toolCall}\n open={openSet.has(toolCall.toolCallId)}\n onOpenChange={(open) => setToolCallOpen(toolCall.toolCallId, open)}\n />\n ))}\n </div>\n );\n}\n\nAIToolCallList.displayName = 'AIToolCallList';\n\nexport {\n AIToolCall,\n AIToolCallHeader,\n AIToolCallList,\n StatusIcon,\n statusIconVariants,\n ToolCallSection,\n toolCallVariants,\n};\n"],"x_google_ignoreList":[0,1],"mappings":"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"}