{"version":3,"file":"AiChat.cjs","sources":["../../src/components/AiChat.tsx"],"sourcesContent":["import type {\n  AiKnowledgeSource,\n  AiOpaqueToolDefinition,\n  CopilotId,\n  MessageId,\n} from \"@liveblocks/core\";\nimport {\n  RegisterAiKnowledge,\n  RegisterAiTool,\n  useAiChatMessages,\n} from \"@liveblocks/react\";\nimport { useLatest } from \"@liveblocks/react/_private\";\nimport {\n  type ComponentProps,\n  type ComponentType,\n  forwardRef,\n  type MutableRefObject,\n  useEffect,\n  useImperativeHandle,\n  useRef,\n  useState,\n} from \"react\";\n\nimport type { GlobalComponents } from \"../components\";\nimport { ArrowDownIcon } from \"../icons/ArrowDown\";\nimport { SpinnerIcon } from \"../icons/Spinner\";\nimport {\n  type AiChatMessageOverrides,\n  type AiChatOverrides,\n  type AiComposerOverrides,\n  type GlobalOverrides,\n  useOverrides,\n} from \"../overrides\";\nimport type { MarkdownComponents } from \"../primitives/Markdown\";\nimport { cn } from \"../utils/cn\";\nimport { useIntersectionCallback } from \"../utils/use-visible\";\nimport {\n  AiChatAssistantMessage,\n  type AiChatAssistantMessageProps,\n} from \"./internal/AiChatAssistantMessage\";\nimport { AiChatUserMessage } from \"./internal/AiChatUserMessage\";\nimport { AiComposer, type AiComposerProps } from \"./internal/AiComposer\";\n\n/**\n * The minimum number of pixels from the bottom of the scrollable area\n * before showing the scroll to bottom indicator.\n */\nconst MIN_DISTANCE_BOTTOM_SCROLL_INDICATOR = 60;\n\nexport type AiChatComponentsEmptyProps = {\n  /**\n   * The chat ID provided to the `AiChat` component.\n   */\n  chatId: string;\n\n  /**\n   * The copilot ID provided to the `AiChat` component.\n   */\n  copilotId?: string;\n};\n\nexport type AiChatComponentsLoadingProps = Record<string, never>;\n\nexport type AiChatComponents = {\n  /**\n   * The component used to render the empty state of the chat.\n   */\n  Empty: ComponentType<AiChatComponentsEmptyProps>;\n\n  /**\n   * The component used to render the loading state of the chat.\n   */\n  Loading: ComponentType<AiChatComponentsLoadingProps>;\n\n  /**\n   * The components used to render Markdown content.\n   */\n  markdown?: Partial<MarkdownComponents>;\n};\n\nexport interface AiChatProps extends ComponentProps<\"div\"> {\n  /**\n   * The ID of the chat the composer belongs to.\n   */\n  chatId: string;\n\n  /**\n   * Whether to focus the chat composer on mount.\n   */\n  autoFocus?: boolean;\n\n  /**\n   * The ID of the copilot to use to send the message.\n   */\n  copilotId?: string;\n\n  /**\n   * The contextual knowledge to include in the chat. May be used by the\n   * assistant when generating responses. In addition to the knowledge passed\n   * in via this prop, the AiChat instance will also have access to any\n   * globally registered knowledge via <RegisterAiKnowledge />.\n   */\n  knowledge?: AiKnowledgeSource[];\n\n  /**\n   * Tool definitions to make available within this chat. May be used by the assistant when generating responses.\n   */\n  tools?: Record<string, AiOpaqueToolDefinition>;\n\n  /**\n   * The event handler called when the composer is submitted.\n   */\n  onComposerSubmit?: AiComposerProps[\"onComposerSubmit\"];\n\n  /**\n   * The layout of the chat and its composer.\n   */\n  layout?: \"inset\" | \"compact\";\n\n  /**\n   * How to show or hide reasoning.\n   */\n  showReasoning?: AiChatAssistantMessageProps[\"showReasoning\"];\n\n  /**\n   * How to show or hide retrievals.\n   */\n  showRetrievals?: AiChatAssistantMessageProps[\"showRetrievals\"];\n\n  /**\n   * Whether to show sources\n   */\n  showSources?: AiChatAssistantMessageProps[\"showSources\"];\n\n  /**\n   * The time, in milliseconds, before an AI response will timeout.\n   */\n  responseTimeout?: number;\n\n  /**\n   * Override the component's strings.\n   */\n  overrides?: Partial<\n    GlobalOverrides &\n      AiComposerOverrides &\n      AiChatMessageOverrides &\n      AiChatOverrides\n  >;\n\n  /**\n   * Override the component's components.\n   */\n  components?: Partial<GlobalComponents & AiChatComponents>;\n}\n\ninterface AiChatMessagesProps extends ComponentProps<\"div\"> {\n  messages: NonNullable<ReturnType<typeof useAiChatMessages>[\"messages\"]>;\n  overrides: AiChatProps[\"overrides\"];\n  components: AiChatProps[\"components\"];\n  showReasoning: AiChatProps[\"showReasoning\"];\n  showRetrievals: AiChatProps[\"showRetrievals\"];\n  showSources: AiChatProps[\"showSources\"];\n  lastSentMessageId: MessageId | null;\n  scrollToBottom: MutableRefObject<\n    (behavior: \"instant\" | \"smooth\", includeTrailingSpace?: boolean) => void\n  >;\n  onScrollAtBottomChange: MutableRefObject<\n    (isScrollAtBottom: boolean | null) => void\n  >;\n  containerRef: MutableRefObject<HTMLDivElement | null>;\n  footerRef: MutableRefObject<HTMLDivElement | null>;\n  messagesRef: MutableRefObject<HTMLDivElement | null>;\n  bottomTrailingMarkerRef: MutableRefObject<HTMLDivElement | null>;\n  trailingSpacerRef: MutableRefObject<HTMLDivElement | null>;\n}\n\nconst defaultComponents: AiChatComponents = {\n  Empty: () => null,\n  Loading: () => (\n    <div className=\"lb-loading lb-ai-chat-loading\">\n      <SpinnerIcon />\n    </div>\n  ),\n};\n\nconst AiChatMessages = forwardRef<HTMLDivElement, AiChatMessagesProps>(\n  (\n    {\n      messages,\n      overrides,\n      components,\n      showReasoning,\n      showRetrievals,\n      showSources,\n      lastSentMessageId,\n      scrollToBottom,\n      onScrollAtBottomChange,\n      containerRef,\n      footerRef,\n      messagesRef,\n      bottomTrailingMarkerRef,\n      trailingSpacerRef,\n      className,\n      ...props\n    },\n    forwardedRef\n  ) => {\n    const hasLastSentMessage = lastSentMessageId !== null;\n\n    /**\n     * Every time the container, footer, or messages list change size,\n     * we calculate the trailing space that would allow the penultimate\n     * message to be at the top of the viewport, and apply it.\n     *\n     *   ┌─────────────────────────────────────────┐▲   A = The `scroll-margin-top`\n     *   │            ┌─────────────────────────┐  │▼▲  value of the penultimate message\n     *   │            │ The penultimate message │  │ │\n     *   │            └─────────────────────────┘  │ │  B = The height from the top of\n     *   │                                         │ │  the penultimate message to the\n     *   │ ┌─────────────────────────┐             │ │  bottom of the messages list,\n     *   │ │ The last message        │             │ │  including the messages' heights,\n     *   │ └─────────────────────────┘             │ │  and any padding, gap, etc\n     *   │                                         │ │\n     *   ├ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┤▲▼\n     *   │                                         ││   The trailing space needed to\n     *   │    = container height - (A + B + C)     ││   allow the penultimate message\n     *   │                                         ││   to be at the top of the viewport\n     *   ├ ┬─────────────────────────────────────┬ ┤▼▲\n     *   │ │                                     │ │ │\n     *   │ │                                     │ │ │  C = The footer's height,\n     *   │ │                                     │ │ │  including any padding\n     *   │ └─────────────────────────────────────┘ │ │\n     *   └─────────────────────────────────────────┘ ▼\n     */\n    useEffect(\n      () => {\n        if (!hasLastSentMessage) {\n          return;\n        }\n\n        const container = containerRef.current;\n        const footer = footerRef.current;\n        const messages = messagesRef.current;\n\n        if (!container || !footer || !messages) {\n          return;\n        }\n\n        const trailingSpacer = trailingSpacerRef.current;\n        const bottomTrailingMarker = bottomTrailingMarkerRef.current;\n\n        let containerHeight: number | undefined = undefined;\n        let footerHeight: number | undefined = undefined;\n        let messagesHeight: number | undefined = undefined;\n\n        const resetTrailingSpace = () => {\n          trailingSpacer?.style.removeProperty(\"height\");\n          bottomTrailingMarker?.style.removeProperty(\"top\");\n        };\n\n        const updateTrailingSpace = (\n          updatedContainerHeight?: number,\n          updatedFooterHeight?: number,\n          updatedMessagesHeight?: number\n        ) => {\n          if (!trailingSpacer || !bottomTrailingMarker) {\n            return;\n          }\n\n          const lastMessage = messages.lastElementChild;\n          const penultimateMessage = lastMessage?.previousElementSibling;\n\n          if (updatedContainerHeight === undefined) {\n            updatedContainerHeight = container.getBoundingClientRect().height;\n          }\n\n          if (updatedFooterHeight === undefined) {\n            updatedFooterHeight = footer.getBoundingClientRect().height;\n          }\n\n          if (updatedMessagesHeight === undefined) {\n            updatedMessagesHeight = messages.getBoundingClientRect().height;\n          }\n\n          // If the heights haven't changed, there's no need to update the trailing space.\n          if (\n            updatedContainerHeight === containerHeight &&\n            updatedFooterHeight === footerHeight &&\n            updatedMessagesHeight === messagesHeight\n          ) {\n            if (\n              !lastMessage ||\n              !penultimateMessage ||\n              container.scrollHeight === container.clientHeight\n            ) {\n              resetTrailingSpace();\n            }\n            return;\n          }\n\n          // Now that we have compared them, we can update the heights.\n          containerHeight = updatedContainerHeight;\n          footerHeight = updatedFooterHeight;\n          messagesHeight = updatedMessagesHeight;\n\n          // If there's no last pair of messages, there's no need for any trailing space.\n          if (!lastMessage || !penultimateMessage) {\n            resetTrailingSpace();\n            return;\n          }\n\n          // If the container isn't scrollable, there's no need for trailing space.\n          if (container.scrollHeight === container.clientHeight) {\n            resetTrailingSpace();\n            return;\n          }\n\n          // A\n          const penultimateMessageScrollMarginTop = Number.parseFloat(\n            getComputedStyle(penultimateMessage as HTMLElement).scrollMarginTop\n          );\n\n          // B\n          const messagesRect = messages.getBoundingClientRect();\n          const penultimateMessageRect =\n            penultimateMessage.getBoundingClientRect();\n          const heightFromPenultimateMessageTopToMessagesListBottom =\n            messagesRect.bottom - penultimateMessageRect.top;\n\n          // A + B + C\n          const differenceHeight =\n            penultimateMessageScrollMarginTop +\n            heightFromPenultimateMessageTopToMessagesListBottom +\n            (footerHeight ?? 0);\n\n          // = container height - (A + B + C)\n          const trailingSpace = Math.max(containerHeight - differenceHeight, 0);\n\n          // Update the trailing space.\n          trailingSpacer.style.height = `${trailingSpace}px`;\n\n          // Offset what \"the bottom\" is to the \"scroll at the bottom\" detection logic,\n          // so that it doesn't include the trailing space.\n          bottomTrailingMarker.style.top = `${-trailingSpace}px`;\n        };\n\n        const resizeObserver = new ResizeObserver((entries) => {\n          let updatedContainerHeight: number | undefined = containerHeight;\n          let updatedFooterHeight: number | undefined = footerHeight;\n          let updatedMessagesHeight: number | undefined = messagesHeight;\n\n          for (const entry of entries) {\n            const entryHeight =\n              entry.borderBoxSize?.[0]?.blockSize ?? entry.contentRect.height;\n\n            if (entry.target === container) {\n              updatedContainerHeight = entryHeight;\n            } else if (entry.target === footer) {\n              updatedFooterHeight = entryHeight;\n            } else if (entry.target === messages) {\n              updatedMessagesHeight = entryHeight;\n            }\n          }\n\n          updateTrailingSpace(\n            updatedContainerHeight,\n            updatedFooterHeight,\n            updatedMessagesHeight\n          );\n        });\n\n        resizeObserver.observe(container);\n        resizeObserver.observe(footer);\n        resizeObserver.observe(messages);\n\n        // Initialize before the first resize.\n        requestAnimationFrame(() => updateTrailingSpace());\n\n        return () => {\n          resizeObserver.disconnect();\n          resetTrailingSpace();\n        };\n      },\n      // This effect only uses stable refs.\n      [hasLastSentMessage] // eslint-disable-line react-hooks/exhaustive-deps\n    );\n\n    /**\n     * Update the \"scroll at bottom\" state when needed.\n     */\n    useIntersectionCallback(\n      bottomTrailingMarkerRef,\n      (isIntersecting) => {\n        onScrollAtBottomChange.current(isIntersecting);\n      },\n      { root: containerRef, rootMargin: MIN_DISTANCE_BOTTOM_SCROLL_INDICATOR }\n    );\n\n    /**\n     * Instantly scroll to the bottom for the initial state.\n     */\n    useEffect(\n      () => {\n        scrollToBottom.current(\"instant\");\n      },\n      // `scrollToBottom` is a stable ref containing the callback.\n      [] // eslint-disable-line react-hooks/exhaustive-deps\n    );\n\n    /**\n     * Scroll to new messages when sending them.\n     */\n    useEffect(\n      () => {\n        if (lastSentMessageId) {\n          scrollToBottom.current(\"smooth\", true);\n        }\n      },\n      // `scrollToBottom` is a stable ref containing the callback.\n      [lastSentMessageId] // eslint-disable-line react-hooks/exhaustive-deps\n    );\n\n    /**\n     * Reset the \"scroll at bottom\" state when the component unmounts.\n     */\n    useEffect(\n      () => {\n        const onScrollAtBottomChangeCallback = onScrollAtBottomChange.current;\n\n        return () => {\n          onScrollAtBottomChangeCallback(null);\n        };\n      },\n      // `onScrollAtBottomChange` is a stable ref containing the callback.\n      [] // eslint-disable-line react-hooks/exhaustive-deps\n    );\n\n    return (\n      <div\n        className={cn(\"lb-ai-chat-messages\", className)}\n        ref={forwardedRef}\n        {...props}\n      >\n        {messages.map((message) => {\n          if (message.role === \"user\") {\n            return (\n              <AiChatUserMessage\n                key={message.id}\n                message={message}\n                overrides={overrides}\n                components={components}\n              />\n            );\n          } else if (message.role === \"assistant\") {\n            return (\n              <AiChatAssistantMessage\n                key={message.id}\n                message={message}\n                overrides={overrides}\n                components={components}\n                showReasoning={showReasoning}\n                showRetrievals={showRetrievals}\n                showSources={showSources}\n              />\n            );\n          } else {\n            return null;\n          }\n        })}\n      </div>\n    );\n  }\n);\n\n// Call `Element.scrollIntoView()` unless the element is not displayed.\n// (with `display: none` or nested within elements with `display: none`)\n// https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView\n//\n// This avoids browser quirks where they still attempt to scroll to the\n// element but it results in a scroll to the document's top.\nfunction scrollIntoView(\n  element: HTMLElement | null,\n  options?: ScrollIntoViewOptions\n) {\n  if (!element) {\n    return;\n  }\n\n  // Checking for at least one client rect allows 0 width/height elements,\n  // unlike checking if the width/height is 0 with `getBoundingClientRect`.\n  if (element.getClientRects().length === 0) {\n    return;\n  }\n\n  element.scrollIntoView(options);\n}\n\nexport const AiChat = forwardRef<HTMLDivElement, AiChatProps>(\n  (\n    {\n      chatId,\n      copilotId,\n      autoFocus,\n      overrides,\n      knowledge: localKnowledge,\n      tools = {},\n      onComposerSubmit,\n      layout = \"inset\",\n      showReasoning,\n      showRetrievals,\n      showSources,\n      components,\n      className,\n      responseTimeout,\n      ...props\n    },\n    forwardedRef\n  ) => {\n    const { messages, isLoading, error } = useAiChatMessages(chatId);\n    const [lastSentMessageId, setLastSentMessageId] =\n      useState<MessageId | null>(null);\n\n    const $ = useOverrides(overrides);\n    const Empty = components?.Empty ?? defaultComponents.Empty;\n    const Loading = components?.Loading ?? defaultComponents.Loading;\n\n    const containerRef = useRef<HTMLDivElement | null>(null);\n    const messagesRef = useRef<HTMLDivElement | null>(null);\n    const footerRef = useRef<HTMLDivElement | null>(null);\n    const bottomMarkerRef = useRef<HTMLDivElement | null>(null);\n    const bottomTrailingMarkerRef = useRef<HTMLDivElement | null>(null);\n    const trailingSpacerRef = useRef<HTMLDivElement | null>(null);\n\n    const [isScrollAtBottom, setScrollAtBottom] = useState<boolean | null>(\n      null\n    );\n    // `useState`'s setter is stable but this is for clarity in the places it's used.\n    const onScrollAtBottomChange = useLatest(setScrollAtBottom);\n    const isScrollIndicatorVisible =\n      messages && isScrollAtBottom !== null ? !isScrollAtBottom : false;\n\n    useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(\n      forwardedRef,\n      () => containerRef.current,\n      []\n    );\n\n    const scrollToBottom = useLatest(\n      (behavior: \"instant\" | \"smooth\", includeTrailingSpace = false) => {\n        if (includeTrailingSpace) {\n          // Scroll to the bottom marker to include the trailing space,\n          // but wait for the next tick in case the trailing space hasn't\n          // been updated yet. (e.g. when sending a new message)\n          setTimeout(() => {\n            scrollIntoView(bottomMarkerRef.current, {\n              behavior,\n              block: \"end\",\n            });\n          }, 0);\n        } else {\n          // Scroll to the trailing space marker to only scroll to the\n          // bottom of the messages, without including the trailing space.\n          scrollIntoView(bottomTrailingMarkerRef.current, {\n            behavior,\n            block: \"end\",\n          });\n        }\n      }\n    );\n\n    return (\n      <div\n        ref={containerRef}\n        {...props}\n        className={cn(\n          \"lb-root lb-ai-chat\",\n          `lb-ai-chat:layout-${layout}`,\n          className\n        )}\n      >\n        {Object.entries(tools).map(([name, tool]) => (\n          <RegisterAiTool key={name} chatId={chatId} name={name} tool={tool} />\n        ))}\n\n        {localKnowledge\n          ? localKnowledge.map((knowledge, index) => (\n              <RegisterAiKnowledge\n                key={`${index}:${knowledge.description}`}\n                chatId={chatId}\n                {...knowledge}\n              />\n            ))\n          : null}\n\n        <div className=\"lb-ai-chat-content\">\n          {isLoading ? (\n            <Loading />\n          ) : error !== undefined ? (\n            <div className=\"lb-error lb-ai-chat-error\">\n              {$.AI_CHAT_MESSAGES_ERROR(error)}\n            </div>\n          ) : messages.length === 0 ? (\n            <Empty chatId={chatId} copilotId={copilotId} />\n          ) : (\n            <>\n              <AiChatMessages\n                messages={messages}\n                overrides={overrides}\n                components={components}\n                showReasoning={showReasoning}\n                showRetrievals={showRetrievals}\n                showSources={showSources}\n                lastSentMessageId={lastSentMessageId}\n                scrollToBottom={scrollToBottom}\n                onScrollAtBottomChange={onScrollAtBottomChange}\n                containerRef={containerRef}\n                footerRef={footerRef}\n                messagesRef={messagesRef}\n                bottomTrailingMarkerRef={bottomTrailingMarkerRef}\n                trailingSpacerRef={trailingSpacerRef}\n                ref={forwardedRef}\n              />\n\n              {/**\n               * This trailing spacer is used to extend the scrollable area beyond its actual\n               * content, to allow messages to appear at the top of the viewport for example.\n               */}\n              <div\n                ref={trailingSpacerRef}\n                data-trailing-spacer=\"\"\n                style={{\n                  pointerEvents: \"none\",\n                  height: 0,\n                }}\n                aria-hidden\n              />\n            </>\n          )}\n        </div>\n\n        <div className=\"lb-ai-chat-footer\" ref={footerRef}>\n          <div className=\"lb-ai-chat-footer-actions\">\n            <div\n              className=\"lb-root lb-elevation lb-elevation-moderate lb-ai-chat-scroll-indicator\"\n              data-visible={isScrollIndicatorVisible ? \"\" : undefined}\n            >\n              <button\n                className=\"lb-ai-chat-scroll-indicator-button\"\n                tabIndex={isScrollIndicatorVisible ? 0 : -1}\n                aria-hidden={!isScrollIndicatorVisible}\n                onClick={() => scrollToBottom.current(\"smooth\")}\n              >\n                <span className=\"lb-icon-container\">\n                  <ArrowDownIcon />\n                </span>\n              </button>\n            </div>\n          </div>\n          <AiComposer\n            key={chatId}\n            chatId={chatId}\n            copilotId={copilotId as CopilotId}\n            overrides={overrides}\n            autoFocus={autoFocus}\n            responseTimeout={responseTimeout}\n            onComposerSubmit={onComposerSubmit}\n            onComposerSubmitted={({ id }) => setLastSentMessageId(id)}\n            className={cn(\n              \"lb-ai-chat-composer\",\n              layout === \"inset\"\n                ? \"lb-elevation lb-elevation-moderate\"\n                : undefined\n            )}\n          />\n        </div>\n\n        {/**\n         * This invisible marker is a trick which allows us to use IntersectionObserver to detect when the\n         * scrollable area is fully scrolled to the bottom instead of manually tracking the scroll position\n         * and having to deal with resizes, etc.\n         *\n         * It's positioned at the bottom of the scrollable area and reliably only becomes \"visible\" to the\n         * IntersectionObserver when the scrollable area is scrolled to the bottom.\n         */}\n        {messages && messages.length > 0 ? (\n          <div\n            ref={bottomMarkerRef}\n            style={{ position: \"sticky\", height: 0 }}\n            aria-hidden\n            data-bottom-marker=\"\"\n          >\n            {/**\n             * This inner marker is absolutely offset by the same distance as the trailing space so its\n             * visibility means the scrollable area is at the bottom of the messages, not the full bottom.\n             */}\n            <div\n              ref={bottomTrailingMarkerRef}\n              style={{\n                position: \"absolute\",\n                height: 0,\n              }}\n              data-bottom-trailing-marker=\"\"\n            />\n          </div>\n        ) : null}\n      </div>\n    );\n  }\n);\n"],"names":["jsx","SpinnerIcon","forwardRef","useEffect","messages","useIntersectionCallback","cn","AiChatUserMessage","AiChatAssistantMessage","overrides","useAiChatMessages","useState","useOverrides","useRef","useLatest","useImperativeHandle","jsxs","RegisterAiTool","RegisterAiKnowledge","Fragment","ArrowDownIcon","AiComposer"],"mappings":"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"}