{"version":3,"file":"CopilotChatMessageView.cjs","names":["React","useRenderCustomMessages","useRenderActivityMessage","useCopilotKit","useCopilotChatConfiguration","CopilotChatAssistantMessage","isReactComponentType","CopilotChatUserMessage","CopilotChatReasoningMessage","renderSlot"],"sources":["../../../src/components/chat/CopilotChatMessageView.tsx"],"sourcesContent":["import React, { useEffect, useReducer, useState } from \"react\";\nimport { WithSlots, renderSlot, isReactComponentType } from \"@/lib/slots\";\nimport CopilotChatAssistantMessage from \"./CopilotChatAssistantMessage\";\nimport CopilotChatUserMessage from \"./CopilotChatUserMessage\";\nimport CopilotChatReasoningMessage from \"./CopilotChatReasoningMessage\";\nimport {\n  ActivityMessage,\n  AssistantMessage,\n  Message,\n  ReasoningMessage,\n  UserMessage,\n} from \"@ag-ui/core\";\nimport { twMerge } from \"tailwind-merge\";\nimport { useRenderActivityMessage, useRenderCustomMessages } from \"@/hooks\";\nimport { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport { useCopilotChatConfiguration } from \"@/providers/CopilotChatConfigurationProvider\";\n\n/**\n * Memoized wrapper for assistant messages to prevent re-renders when other messages change.\n */\nconst MemoizedAssistantMessage = React.memo(\n  function MemoizedAssistantMessage({\n    message,\n    messages,\n    isRunning,\n    AssistantMessageComponent,\n    slotProps,\n  }: {\n    message: AssistantMessage;\n    messages: Message[];\n    isRunning: boolean;\n    AssistantMessageComponent: typeof CopilotChatAssistantMessage;\n    slotProps?: Partial<\n      React.ComponentProps<typeof CopilotChatAssistantMessage>\n    >;\n  }) {\n    return (\n      <AssistantMessageComponent\n        message={message}\n        messages={messages}\n        isRunning={isRunning}\n        {...slotProps}\n      />\n    );\n  },\n  (prevProps, nextProps) => {\n    // Only re-render if this specific message changed\n    if (prevProps.message.id !== nextProps.message.id) return false;\n    if (prevProps.message.content !== nextProps.message.content) return false;\n\n    // Compare tool calls if present\n    const prevToolCalls = prevProps.message.toolCalls;\n    const nextToolCalls = nextProps.message.toolCalls;\n    if (prevToolCalls?.length !== nextToolCalls?.length) return false;\n    if (prevToolCalls && nextToolCalls) {\n      for (let i = 0; i < prevToolCalls.length; i++) {\n        const prevTc = prevToolCalls[i];\n        const nextTc = nextToolCalls[i];\n        if (!prevTc || !nextTc) return false;\n        if (prevTc.id !== nextTc.id) return false;\n        if (prevTc.function.arguments !== nextTc.function.arguments)\n          return false;\n      }\n    }\n\n    // Check if tool results changed for this message's tool calls\n    // Tool results are separate messages with role=\"tool\" that reference tool call IDs\n    if (prevToolCalls && prevToolCalls.length > 0) {\n      const toolCallIds = new Set(prevToolCalls.map((tc) => tc.id));\n\n      const prevToolResults = prevProps.messages.filter(\n        (m) => m.role === \"tool\" && toolCallIds.has((m as any).toolCallId),\n      );\n      const nextToolResults = nextProps.messages.filter(\n        (m) => m.role === \"tool\" && toolCallIds.has((m as any).toolCallId),\n      );\n\n      // If number of tool results changed, re-render\n      if (prevToolResults.length !== nextToolResults.length) return false;\n\n      // If any tool result content changed, re-render\n      for (let i = 0; i < prevToolResults.length; i++) {\n        if (\n          (prevToolResults[i] as any).content !==\n          (nextToolResults[i] as any).content\n        )\n          return false;\n      }\n    }\n\n    // Only care about isRunning if this message is CURRENTLY the latest\n    // (we don't need to re-render just because a message stopped being the latest)\n    const nextIsLatest =\n      nextProps.messages[nextProps.messages.length - 1]?.id ===\n      nextProps.message.id;\n    if (nextIsLatest && prevProps.isRunning !== nextProps.isRunning)\n      return false;\n\n    // Check if component reference changed\n    if (\n      prevProps.AssistantMessageComponent !==\n      nextProps.AssistantMessageComponent\n    )\n      return false;\n\n    // Check if slot props changed\n    if (prevProps.slotProps !== nextProps.slotProps) return false;\n\n    return true;\n  },\n);\n\n/**\n * Memoized wrapper for user messages to prevent re-renders when other messages change.\n */\nconst MemoizedUserMessage = React.memo(\n  function MemoizedUserMessage({\n    message,\n    UserMessageComponent,\n    slotProps,\n  }: {\n    message: UserMessage;\n    UserMessageComponent: typeof CopilotChatUserMessage;\n    slotProps?: Partial<React.ComponentProps<typeof CopilotChatUserMessage>>;\n  }) {\n    return <UserMessageComponent message={message} {...slotProps} />;\n  },\n  (prevProps, nextProps) => {\n    // Only re-render if this specific message changed\n    if (prevProps.message.id !== nextProps.message.id) return false;\n    if (prevProps.message.content !== nextProps.message.content) return false;\n    if (prevProps.UserMessageComponent !== nextProps.UserMessageComponent)\n      return false;\n    // Check if slot props changed\n    if (prevProps.slotProps !== nextProps.slotProps) return false;\n    return true;\n  },\n);\n\n/**\n * Memoized wrapper for activity messages to prevent re-renders when other messages change.\n */\nconst MemoizedActivityMessage = React.memo(\n  function MemoizedActivityMessage({\n    message,\n    renderActivityMessage,\n  }: {\n    message: ActivityMessage;\n    renderActivityMessage: (\n      message: ActivityMessage,\n    ) => React.ReactElement | null;\n  }) {\n    return renderActivityMessage(message);\n  },\n  (prevProps, nextProps) => {\n    // Message ID changed = different message, must re-render\n    if (prevProps.message.id !== nextProps.message.id) return false;\n\n    // Activity type changed = must re-render\n    if (prevProps.message.activityType !== nextProps.message.activityType)\n      return false;\n\n    // Compare content using JSON.stringify (native code, handles deep comparison)\n    if (\n      JSON.stringify(prevProps.message.content) !==\n      JSON.stringify(nextProps.message.content)\n    )\n      return false;\n\n    return true;\n  },\n);\n\n/**\n * Memoized wrapper for reasoning messages to prevent re-renders when other messages change.\n */\nconst MemoizedReasoningMessage = React.memo(\n  function MemoizedReasoningMessage({\n    message,\n    messages,\n    isRunning,\n    ReasoningMessageComponent,\n    slotProps,\n  }: {\n    message: ReasoningMessage;\n    messages: Message[];\n    isRunning: boolean;\n    ReasoningMessageComponent: typeof CopilotChatReasoningMessage;\n    slotProps?: Partial<\n      React.ComponentProps<typeof CopilotChatReasoningMessage>\n    >;\n  }) {\n    return (\n      <ReasoningMessageComponent\n        message={message}\n        messages={messages}\n        isRunning={isRunning}\n        {...slotProps}\n      />\n    );\n  },\n  (prevProps, nextProps) => {\n    // Only re-render if this specific message changed\n    if (prevProps.message.id !== nextProps.message.id) return false;\n    if (prevProps.message.content !== nextProps.message.content) return false;\n\n    // Re-render when \"latest\" status changes (e.g. reasoning message is no longer the last message\n    // because a text message was added after it — this transitions isStreaming from true to false)\n    const prevIsLatest =\n      prevProps.messages[prevProps.messages.length - 1]?.id ===\n      prevProps.message.id;\n    const nextIsLatest =\n      nextProps.messages[nextProps.messages.length - 1]?.id ===\n      nextProps.message.id;\n    if (prevIsLatest !== nextIsLatest) return false;\n\n    // Only care about isRunning if this message is CURRENTLY the latest\n    if (nextIsLatest && prevProps.isRunning !== nextProps.isRunning)\n      return false;\n\n    // Check if component reference changed\n    if (\n      prevProps.ReasoningMessageComponent !==\n      nextProps.ReasoningMessageComponent\n    )\n      return false;\n\n    // Check if slot props changed\n    if (prevProps.slotProps !== nextProps.slotProps) return false;\n\n    return true;\n  },\n);\n\n/**\n * Memoized wrapper for custom messages to prevent re-renders when other messages change.\n */\nconst MemoizedCustomMessage = React.memo(\n  function MemoizedCustomMessage({\n    message,\n    position,\n    renderCustomMessage,\n  }: {\n    message: Message;\n    position: \"before\" | \"after\";\n    renderCustomMessage: (params: {\n      message: Message;\n      position: \"before\" | \"after\";\n    }) => React.ReactElement | null;\n    stateSnapshot?: unknown;\n  }) {\n    return renderCustomMessage({ message, position });\n  },\n  (prevProps, nextProps) => {\n    // Only re-render if the message or position changed\n    if (prevProps.message.id !== nextProps.message.id) return false;\n    if (prevProps.position !== nextProps.position) return false;\n    // Compare message content - for assistant messages this is a string, for others may differ\n    if (prevProps.message.content !== nextProps.message.content) return false;\n    if (prevProps.message.role !== nextProps.message.role) return false;\n    // Compare state snapshot - custom renderers may depend on state\n    if (\n      JSON.stringify(prevProps.stateSnapshot) !==\n      JSON.stringify(nextProps.stateSnapshot)\n    )\n      return false;\n    // Note: We don't compare renderCustomMessage function reference because it changes\n    // frequently. The message and state comparison is sufficient to determine if a re-render is needed.\n    return true;\n  },\n);\n\nexport type CopilotChatMessageViewProps = Omit<\n  WithSlots<\n    {\n      assistantMessage: typeof CopilotChatAssistantMessage;\n      userMessage: typeof CopilotChatUserMessage;\n      reasoningMessage: typeof CopilotChatReasoningMessage;\n      cursor: typeof CopilotChatMessageView.Cursor;\n    },\n    {\n      isRunning?: boolean;\n      messages?: Message[];\n    } & React.HTMLAttributes<HTMLDivElement>\n  >,\n  \"children\"\n> & {\n  children?: (props: {\n    isRunning: boolean;\n    messages: Message[];\n    messageElements: React.ReactElement[];\n    interruptElement: React.ReactElement | null;\n  }) => React.ReactElement;\n};\n\nexport function CopilotChatMessageView({\n  messages = [],\n  assistantMessage,\n  userMessage,\n  reasoningMessage,\n  cursor,\n  isRunning = false,\n  children,\n  className,\n  ...props\n}: CopilotChatMessageViewProps) {\n  const renderCustomMessage = useRenderCustomMessages();\n  const { renderActivityMessage } = useRenderActivityMessage();\n  const { copilotkit } = useCopilotKit();\n  const config = useCopilotChatConfiguration();\n  const [, forceUpdate] = useReducer((x) => x + 1, 0);\n\n  // Subscribe to state changes so custom message renderers re-render when state updates.\n  useEffect(() => {\n    if (!config?.agentId) return;\n    const agent = copilotkit.getAgent(config.agentId);\n    if (!agent) return;\n\n    const subscription = agent.subscribe({\n      onStateChanged: forceUpdate,\n    });\n    return () => subscription.unsubscribe();\n  }, [config?.agentId, copilotkit, forceUpdate]);\n\n  // Subscribe to interrupt element changes for in-chat rendering.\n  const [interruptElement, setInterruptElement] =\n    useState<React.ReactElement | null>(null);\n  useEffect(() => {\n    setInterruptElement(copilotkit.interruptElement);\n    const subscription = copilotkit.subscribe({\n      onInterruptElementChanged: ({ interruptElement }) => {\n        setInterruptElement(interruptElement);\n      },\n    });\n    return () => subscription.unsubscribe();\n  }, [copilotkit]);\n\n  // Helper to get state snapshot for a message (used for memoization)\n  const getStateSnapshotForMessage = (messageId: string): unknown => {\n    if (!config) return undefined;\n    const resolvedRunId =\n      copilotkit.getRunIdForMessage(\n        config.agentId,\n        config.threadId,\n        messageId,\n      ) ??\n      copilotkit\n        .getRunIdsForThread(config.agentId, config.threadId)\n        .slice(-1)[0];\n    if (!resolvedRunId) return undefined;\n    return copilotkit.getStateByRun(\n      config.agentId,\n      config.threadId,\n      resolvedRunId,\n    );\n  };\n\n  // Deduplicate messages by id, keeping the last occurrence of each.\n  // During streaming, AbstractAgent.addMessage() can push duplicate messages\n  // (same id) which causes React \"duplicate key\" warnings and rendering glitches.\n  const deduplicatedMessages = [\n    ...new Map(messages.map((m) => [m.id, m])).values(),\n  ];\n\n  if (\n    process.env.NODE_ENV === \"development\" &&\n    deduplicatedMessages.length < messages.length\n  ) {\n    console.warn(\n      `CopilotChatMessageView: Deduplicated ${messages.length - deduplicatedMessages.length} message(s) with duplicate IDs.`,\n    );\n  }\n\n  const messageElements: React.ReactElement[] = deduplicatedMessages\n    .flatMap((message) => {\n      const elements: (React.ReactElement | null | undefined)[] = [];\n      const stateSnapshot = getStateSnapshotForMessage(message.id);\n\n      // Render custom message before (using memoized wrapper)\n      if (renderCustomMessage) {\n        elements.push(\n          <MemoizedCustomMessage\n            key={`${message.id}-custom-before`}\n            message={message}\n            position=\"before\"\n            renderCustomMessage={renderCustomMessage}\n            stateSnapshot={stateSnapshot}\n          />,\n        );\n      }\n\n      // Render the main message using memoized wrappers to prevent unnecessary re-renders\n      if (message.role === \"assistant\") {\n        // Determine the component and props from slot value\n        let AssistantComponent = CopilotChatAssistantMessage;\n        let assistantSlotProps:\n          | Partial<React.ComponentProps<typeof CopilotChatAssistantMessage>>\n          | undefined;\n\n        if (isReactComponentType(assistantMessage)) {\n          // Custom component (function, forwardRef, memo, etc.)\n          AssistantComponent =\n            assistantMessage as typeof CopilotChatAssistantMessage;\n        } else if (typeof assistantMessage === \"string\") {\n          // className string\n          assistantSlotProps = { className: assistantMessage };\n        } else if (assistantMessage && typeof assistantMessage === \"object\") {\n          // Props object\n          assistantSlotProps = assistantMessage as Partial<\n            React.ComponentProps<typeof CopilotChatAssistantMessage>\n          >;\n        }\n\n        elements.push(\n          <MemoizedAssistantMessage\n            key={message.id}\n            message={message as AssistantMessage}\n            messages={messages}\n            isRunning={isRunning}\n            AssistantMessageComponent={AssistantComponent}\n            slotProps={assistantSlotProps}\n          />,\n        );\n      } else if (message.role === \"user\") {\n        // Determine the component and props from slot value\n        let UserComponent = CopilotChatUserMessage;\n        let userSlotProps:\n          | Partial<React.ComponentProps<typeof CopilotChatUserMessage>>\n          | undefined;\n\n        if (isReactComponentType(userMessage)) {\n          // Custom component (function, forwardRef, memo, etc.)\n          UserComponent = userMessage as typeof CopilotChatUserMessage;\n        } else if (typeof userMessage === \"string\") {\n          // className string\n          userSlotProps = { className: userMessage };\n        } else if (userMessage && typeof userMessage === \"object\") {\n          // Props object\n          userSlotProps = userMessage as Partial<\n            React.ComponentProps<typeof CopilotChatUserMessage>\n          >;\n        }\n\n        elements.push(\n          <MemoizedUserMessage\n            key={message.id}\n            message={message as UserMessage}\n            UserMessageComponent={UserComponent}\n            slotProps={userSlotProps}\n          />,\n        );\n      } else if (message.role === \"activity\") {\n        // Use memoized wrapper to prevent re-renders when other messages change\n        const activityMsg = message as ActivityMessage;\n        elements.push(\n          <MemoizedActivityMessage\n            key={message.id}\n            message={activityMsg}\n            renderActivityMessage={renderActivityMessage}\n          />,\n        );\n      } else if (message.role === \"reasoning\") {\n        // Determine the component and props from slot value\n        let ReasoningComponent = CopilotChatReasoningMessage;\n        let reasoningSlotProps:\n          | Partial<React.ComponentProps<typeof CopilotChatReasoningMessage>>\n          | undefined;\n\n        if (isReactComponentType(reasoningMessage)) {\n          ReasoningComponent =\n            reasoningMessage as typeof CopilotChatReasoningMessage;\n        } else if (typeof reasoningMessage === \"string\") {\n          reasoningSlotProps = { className: reasoningMessage };\n        } else if (reasoningMessage && typeof reasoningMessage === \"object\") {\n          reasoningSlotProps = reasoningMessage as Partial<\n            React.ComponentProps<typeof CopilotChatReasoningMessage>\n          >;\n        }\n\n        elements.push(\n          <MemoizedReasoningMessage\n            key={message.id}\n            message={message as ReasoningMessage}\n            messages={messages}\n            isRunning={isRunning}\n            ReasoningMessageComponent={ReasoningComponent}\n            slotProps={reasoningSlotProps}\n          />,\n        );\n      }\n\n      // Render custom message after (using memoized wrapper)\n      if (renderCustomMessage) {\n        elements.push(\n          <MemoizedCustomMessage\n            key={`${message.id}-custom-after`}\n            message={message}\n            position=\"after\"\n            renderCustomMessage={renderCustomMessage}\n            stateSnapshot={stateSnapshot}\n          />,\n        );\n      }\n\n      return elements;\n    })\n    .filter(Boolean) as React.ReactElement[];\n\n  if (children) {\n    return (\n      <div data-copilotkit style={{ display: \"contents\" }}>\n        {children({ messageElements, messages, isRunning, interruptElement })}\n      </div>\n    );\n  }\n\n  // Hide the chat-level loading cursor when the last message is a reasoning\n  // message — the reasoning card already shows its own loading indicator.\n  const lastMessage = messages[messages.length - 1];\n  const showCursor = isRunning && lastMessage?.role !== \"reasoning\";\n\n  return (\n    <div\n      data-copilotkit\n      data-testid=\"copilot-message-list\"\n      className={twMerge(\"copilotKitMessages cpk:flex cpk:flex-col\", className)}\n      {...props}\n    >\n      {messageElements}\n      {interruptElement}\n      {showCursor && (\n        <div className=\"cpk:mt-2\">\n          {renderSlot(cursor, CopilotChatMessageView.Cursor, {})}\n        </div>\n      )}\n    </div>\n  );\n}\n\nCopilotChatMessageView.Cursor = function Cursor({\n  className,\n  ...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n  return (\n    <div\n      data-testid=\"copilot-loading-cursor\"\n      className={twMerge(\n        \"cpk:w-[11px] cpk:h-[11px] cpk:rounded-full cpk:bg-foreground cpk:animate-pulse-cursor cpk:ml-1\",\n        className,\n      )}\n      {...props}\n    />\n  );\n};\n\nexport default CopilotChatMessageView;\n"],"mappings":"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"}