{"version":3,"file":"CopilotChatAssistantMessage.cjs","names":["renderSlot","CopilotChatToolCallsView","Streamdown","Tooltip","TooltipTrigger","Button","TooltipContent","useCopilotChatConfiguration","CopilotChatDefaultLabels","Check","Copy","ThumbsUp","ThumbsDown","Volume2","RefreshCw"],"sources":["../../../src/components/chat/CopilotChatAssistantMessage.tsx"],"sourcesContent":["import { AssistantMessage, Message } from \"@ag-ui/core\";\nimport { useState } from \"react\";\nimport {\n  Copy,\n  Check,\n  ThumbsUp,\n  ThumbsDown,\n  Volume2,\n  RefreshCw,\n} from \"lucide-react\";\nimport {\n  useCopilotChatConfiguration,\n  CopilotChatDefaultLabels,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport { twMerge } from \"tailwind-merge\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n  Tooltip,\n  TooltipContent,\n  TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { useKatexStyles } from \"@/hooks/useKatexStyles\";\nimport { WithSlots, renderSlot } from \"@/lib/slots\";\nimport { Streamdown } from \"streamdown\";\nimport CopilotChatToolCallsView from \"./CopilotChatToolCallsView\";\n\nexport type CopilotChatAssistantMessageProps = WithSlots<\n  {\n    markdownRenderer: typeof CopilotChatAssistantMessage.MarkdownRenderer;\n    toolbar: typeof CopilotChatAssistantMessage.Toolbar;\n    copyButton: typeof CopilotChatAssistantMessage.CopyButton;\n    thumbsUpButton: typeof CopilotChatAssistantMessage.ThumbsUpButton;\n    thumbsDownButton: typeof CopilotChatAssistantMessage.ThumbsDownButton;\n    readAloudButton: typeof CopilotChatAssistantMessage.ReadAloudButton;\n    regenerateButton: typeof CopilotChatAssistantMessage.RegenerateButton;\n    toolCallsView: typeof CopilotChatToolCallsView;\n  },\n  {\n    onThumbsUp?: (message: AssistantMessage) => void;\n    onThumbsDown?: (message: AssistantMessage) => void;\n    onReadAloud?: (message: AssistantMessage) => void;\n    onRegenerate?: (message: AssistantMessage) => void;\n    message: AssistantMessage;\n    messages?: Message[];\n    isRunning?: boolean;\n    additionalToolbarItems?: React.ReactNode;\n    toolbarVisible?: boolean;\n  } & React.HTMLAttributes<HTMLDivElement>\n>;\n\nexport function CopilotChatAssistantMessage({\n  message,\n  messages,\n  isRunning,\n  onThumbsUp,\n  onThumbsDown,\n  onReadAloud,\n  onRegenerate,\n  additionalToolbarItems,\n  toolbarVisible = true,\n  markdownRenderer,\n  toolbar,\n  copyButton,\n  thumbsUpButton,\n  thumbsDownButton,\n  readAloudButton,\n  regenerateButton,\n  toolCallsView,\n  children,\n  className,\n  ...props\n}: CopilotChatAssistantMessageProps) {\n  useKatexStyles();\n\n  const boundMarkdownRenderer = renderSlot(\n    markdownRenderer,\n    CopilotChatAssistantMessage.MarkdownRenderer,\n    {\n      content: message.content || \"\",\n    },\n  );\n\n  const boundCopyButton = renderSlot(\n    copyButton,\n    CopilotChatAssistantMessage.CopyButton,\n    {\n      onClick: async () => {\n        if (message.content) {\n          try {\n            await navigator.clipboard.writeText(message.content);\n          } catch (err) {\n            console.error(\"Failed to copy message:\", err);\n          }\n        }\n      },\n    },\n  );\n\n  const boundThumbsUpButton = renderSlot(\n    thumbsUpButton,\n    CopilotChatAssistantMessage.ThumbsUpButton,\n    {\n      onClick: onThumbsUp,\n    },\n  );\n\n  const boundThumbsDownButton = renderSlot(\n    thumbsDownButton,\n    CopilotChatAssistantMessage.ThumbsDownButton,\n    {\n      onClick: onThumbsDown,\n    },\n  );\n\n  const boundReadAloudButton = renderSlot(\n    readAloudButton,\n    CopilotChatAssistantMessage.ReadAloudButton,\n    {\n      onClick: onReadAloud,\n    },\n  );\n\n  const boundRegenerateButton = renderSlot(\n    regenerateButton,\n    CopilotChatAssistantMessage.RegenerateButton,\n    {\n      onClick: onRegenerate,\n    },\n  );\n\n  const boundToolbar = renderSlot(\n    toolbar,\n    CopilotChatAssistantMessage.Toolbar,\n    {\n      children: (\n        <div className=\"cpk:flex cpk:items-center cpk:gap-1\">\n          {boundCopyButton}\n          {(onThumbsUp || thumbsUpButton) && boundThumbsUpButton}\n          {(onThumbsDown || thumbsDownButton) && boundThumbsDownButton}\n          {(onReadAloud || readAloudButton) && boundReadAloudButton}\n          {(onRegenerate || regenerateButton) && boundRegenerateButton}\n          {additionalToolbarItems}\n        </div>\n      ),\n    },\n  );\n\n  const boundToolCallsView = renderSlot(\n    toolCallsView,\n    CopilotChatToolCallsView,\n    {\n      message,\n      messages,\n    },\n  );\n\n  // Don't show toolbar if message has no content (only tool calls)\n  const hasContent = !!(message.content && message.content.trim().length > 0);\n  const isLatestAssistantMessage =\n    message.role === \"assistant\" &&\n    messages?.[messages.length - 1]?.id === message.id;\n  const shouldShowToolbar =\n    toolbarVisible && hasContent && !(isRunning && isLatestAssistantMessage);\n\n  if (children) {\n    return (\n      <div data-copilotkit style={{ display: \"contents\" }}>\n        {children({\n          markdownRenderer: boundMarkdownRenderer,\n          toolbar: boundToolbar,\n          toolCallsView: boundToolCallsView,\n          copyButton: boundCopyButton,\n          thumbsUpButton: boundThumbsUpButton,\n          thumbsDownButton: boundThumbsDownButton,\n          readAloudButton: boundReadAloudButton,\n          regenerateButton: boundRegenerateButton,\n          message,\n          messages,\n          isRunning,\n          onThumbsUp,\n          onThumbsDown,\n          onReadAloud,\n          onRegenerate,\n          additionalToolbarItems,\n          toolbarVisible: shouldShowToolbar,\n        })}\n      </div>\n    );\n  }\n\n  return (\n    <div\n      data-copilotkit\n      data-testid=\"copilot-assistant-message\"\n      className={twMerge(\n        \"copilotKitMessage copilotKitAssistantMessage\",\n        className,\n      )}\n      {...props}\n      data-message-id={message.id}\n    >\n      <div className=\"cpk:prose cpk:max-w-full cpk:break-words cpk:dark:prose-invert\">\n        {boundMarkdownRenderer}\n      </div>\n      {boundToolCallsView}\n      {shouldShowToolbar && boundToolbar}\n    </div>\n  );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotChatAssistantMessage {\n  export const MarkdownRenderer: React.FC<\n    Omit<React.ComponentProps<typeof Streamdown>, \"children\"> & {\n      content: string;\n    }\n  > = ({ content, className, ...props }) => (\n    <Streamdown className={className} {...props}>\n      {content ?? \"\"}\n    </Streamdown>\n  );\n\n  export const Toolbar: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n    className,\n    ...props\n  }) => (\n    <div\n      data-testid=\"copilot-assistant-toolbar\"\n      className={twMerge(\n        \"cpk:w-full cpk:bg-transparent cpk:flex cpk:items-center cpk:-ml-[5px] cpk:-mt-[0px]\",\n        className,\n      )}\n      {...props}\n    />\n  );\n\n  export const ToolbarButton: React.FC<\n    React.ButtonHTMLAttributes<HTMLButtonElement> & {\n      title: string;\n      children: React.ReactNode;\n    }\n  > = ({ title, children, ...props }) => {\n    return (\n      <Tooltip>\n        <TooltipTrigger asChild>\n          <Button\n            type=\"button\"\n            variant=\"assistantMessageToolbarButton\"\n            aria-label={title}\n            {...props}\n          >\n            {children}\n          </Button>\n        </TooltipTrigger>\n        <TooltipContent side=\"bottom\">\n          <p>{title}</p>\n        </TooltipContent>\n      </Tooltip>\n    );\n  };\n\n  export const CopyButton: React.FC<\n    React.ButtonHTMLAttributes<HTMLButtonElement>\n  > = ({ className, title, onClick, ...props }) => {\n    const config = useCopilotChatConfiguration();\n    const labels = config?.labels ?? CopilotChatDefaultLabels;\n    const [copied, setCopied] = useState(false);\n\n    const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n      setCopied(true);\n      setTimeout(() => setCopied(false), 2000);\n\n      if (onClick) {\n        onClick(event);\n      }\n    };\n\n    return (\n      <ToolbarButton\n        data-testid=\"copilot-copy-button\"\n        title={title || labels.assistantMessageToolbarCopyMessageLabel}\n        onClick={handleClick}\n        className={className}\n        {...props}\n      >\n        {copied ? (\n          <Check className=\"cpk:size-[18px]\" />\n        ) : (\n          <Copy className=\"cpk:size-[18px]\" />\n        )}\n      </ToolbarButton>\n    );\n  };\n\n  export const ThumbsUpButton: React.FC<\n    React.ButtonHTMLAttributes<HTMLButtonElement>\n  > = ({ title, ...props }) => {\n    const config = useCopilotChatConfiguration();\n    const labels = config?.labels ?? CopilotChatDefaultLabels;\n    return (\n      <ToolbarButton\n        data-testid=\"copilot-thumbs-up-button\"\n        title={title || labels.assistantMessageToolbarThumbsUpLabel}\n        {...props}\n      >\n        <ThumbsUp className=\"cpk:size-[18px]\" />\n      </ToolbarButton>\n    );\n  };\n\n  export const ThumbsDownButton: React.FC<\n    React.ButtonHTMLAttributes<HTMLButtonElement>\n  > = ({ title, ...props }) => {\n    const config = useCopilotChatConfiguration();\n    const labels = config?.labels ?? CopilotChatDefaultLabels;\n    return (\n      <ToolbarButton\n        data-testid=\"copilot-thumbs-down-button\"\n        title={title || labels.assistantMessageToolbarThumbsDownLabel}\n        {...props}\n      >\n        <ThumbsDown className=\"cpk:size-[18px]\" />\n      </ToolbarButton>\n    );\n  };\n\n  export const ReadAloudButton: React.FC<\n    React.ButtonHTMLAttributes<HTMLButtonElement>\n  > = ({ title, ...props }) => {\n    const config = useCopilotChatConfiguration();\n    const labels = config?.labels ?? CopilotChatDefaultLabels;\n    return (\n      <ToolbarButton\n        data-testid=\"copilot-read-aloud-button\"\n        title={title || labels.assistantMessageToolbarReadAloudLabel}\n        {...props}\n      >\n        <Volume2 className=\"cpk:size-[20px]\" />\n      </ToolbarButton>\n    );\n  };\n\n  export const RegenerateButton: React.FC<\n    React.ButtonHTMLAttributes<HTMLButtonElement>\n  > = ({ title, ...props }) => {\n    const config = useCopilotChatConfiguration();\n    const labels = config?.labels ?? CopilotChatDefaultLabels;\n    return (\n      <ToolbarButton\n        data-testid=\"copilot-regenerate-button\"\n        title={title || labels.assistantMessageToolbarRegenerateLabel}\n        {...props}\n      >\n        <RefreshCw className=\"cpk:size-[18px]\" />\n      </ToolbarButton>\n    );\n  };\n}\n\nCopilotChatAssistantMessage.MarkdownRenderer.displayName =\n  \"CopilotChatAssistantMessage.MarkdownRenderer\";\nCopilotChatAssistantMessage.Toolbar.displayName =\n  \"CopilotChatAssistantMessage.Toolbar\";\nCopilotChatAssistantMessage.CopyButton.displayName =\n  \"CopilotChatAssistantMessage.CopyButton\";\nCopilotChatAssistantMessage.ThumbsUpButton.displayName =\n  \"CopilotChatAssistantMessage.ThumbsUpButton\";\nCopilotChatAssistantMessage.ThumbsDownButton.displayName =\n  \"CopilotChatAssistantMessage.ThumbsDownButton\";\nCopilotChatAssistantMessage.ReadAloudButton.displayName =\n  \"CopilotChatAssistantMessage.ReadAloudButton\";\nCopilotChatAssistantMessage.RegenerateButton.displayName =\n  \"CopilotChatAssistantMessage.RegenerateButton\";\n\nexport default CopilotChatAssistantMessage;\n"],"mappings":"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"}