@liveblocks/react-ui 3.4.0 → 3.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24,7 +24,6 @@ const defaultComponents = {
24
24
  const AiChatMessages = react.forwardRef(
25
25
  ({
26
26
  messages,
27
- copilotId,
28
27
  overrides,
29
28
  components,
30
29
  lastSentMessageId,
@@ -162,8 +161,7 @@ const AiChatMessages = react.forwardRef(
162
161
  return /* @__PURE__ */ jsxRuntime.jsx(AiChatAssistantMessage.AiChatAssistantMessage, {
163
162
  message,
164
163
  overrides,
165
- components,
166
- copilotId
164
+ components
167
165
  }, message.id);
168
166
  } else {
169
167
  return null;
@@ -250,7 +248,6 @@ const AiChat = react.forwardRef(
250
248
  children: [
251
249
  /* @__PURE__ */ jsxRuntime.jsx(AiChatMessages, {
252
250
  ref: messagesRef,
253
- copilotId,
254
251
  messages,
255
252
  overrides: overrides$1,
256
253
  components,
@@ -1 +1 @@
1
- {"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 { RegisterAiTool, useAiChatMessages } 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 { AiChatAssistantMessage } 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 * 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 copilotId: AiChatProps[\"copilotId\"];\n overrides: AiChatProps[\"overrides\"];\n components: AiChatProps[\"components\"];\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 copilotId,\n overrides,\n components,\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 | null = null;\n let footerHeight: number | null = null;\n let messagesHeight: number | null = null;\n\n const resetTrailingSpace = () => {\n trailingSpacer?.style.removeProperty(\"height\");\n bottomTrailingMarker?.style.removeProperty(\"top\");\n };\n\n const resizeObserver = new ResizeObserver((entries) => {\n if (!trailingSpacer || !bottomTrailingMarker) {\n return;\n }\n\n const lastMessage = messages.lastElementChild;\n const penultimateMessage = lastMessage?.previousElementSibling;\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's height is based on its content, the container isn't scrollable and there's no need for any trailing space.\n if (container.scrollHeight === container.clientHeight) {\n resetTrailingSpace();\n return;\n }\n\n let updatedContainerHeight: number | null = containerHeight;\n let updatedFooterHeight: number | null = footerHeight;\n let updatedMessagesHeight: number | null = 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 ?? null;\n } else if (entry.target === footer) {\n updatedFooterHeight = entryHeight ?? null;\n } else if (entry.target === messages) {\n updatedMessagesHeight = entryHeight ?? null;\n }\n }\n\n // If we don't have all the heights, we can't compute the trailing space.\n if (\n updatedContainerHeight === null ||\n updatedFooterHeight === null ||\n updatedMessagesHeight === null\n ) {\n resetTrailingSpace();\n return;\n }\n\n // If none of the heights have changed, we don't need to do anything.\n if (\n updatedContainerHeight === containerHeight &&\n updatedFooterHeight === footerHeight &&\n updatedMessagesHeight === messagesHeight\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 // 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 resizeObserver.observe(container);\n resizeObserver.observe(footer);\n resizeObserver.observe(messages);\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 copilotId={copilotId}\n />\n );\n } else {\n return null;\n }\n })}\n </div>\n );\n }\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 components,\n className,\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 // and wait for a frame in case the trailing space hasn't\n // been updated yet. (e.g. when sending a new message)\n requestAnimationFrame(() => {\n bottomMarkerRef.current?.scrollIntoView({\n behavior,\n block: \"end\",\n });\n });\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 bottomTrailingMarkerRef.current?.scrollIntoView({\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 <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 ref={messagesRef}\n copilotId={copilotId}\n messages={messages}\n overrides={overrides}\n components={components}\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 />\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 }}\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 knowledge={localKnowledge}\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","Fragment","ArrowDownIcon","AiComposer"],"mappings":"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"}
1
+ {"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 { RegisterAiTool, useAiChatMessages } 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 { AiChatAssistantMessage } 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 * 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 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 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 | null = null;\n let footerHeight: number | null = null;\n let messagesHeight: number | null = null;\n\n const resetTrailingSpace = () => {\n trailingSpacer?.style.removeProperty(\"height\");\n bottomTrailingMarker?.style.removeProperty(\"top\");\n };\n\n const resizeObserver = new ResizeObserver((entries) => {\n if (!trailingSpacer || !bottomTrailingMarker) {\n return;\n }\n\n const lastMessage = messages.lastElementChild;\n const penultimateMessage = lastMessage?.previousElementSibling;\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's height is based on its content, the container isn't scrollable and there's no need for any trailing space.\n if (container.scrollHeight === container.clientHeight) {\n resetTrailingSpace();\n return;\n }\n\n let updatedContainerHeight: number | null = containerHeight;\n let updatedFooterHeight: number | null = footerHeight;\n let updatedMessagesHeight: number | null = 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 ?? null;\n } else if (entry.target === footer) {\n updatedFooterHeight = entryHeight ?? null;\n } else if (entry.target === messages) {\n updatedMessagesHeight = entryHeight ?? null;\n }\n }\n\n // If we don't have all the heights, we can't compute the trailing space.\n if (\n updatedContainerHeight === null ||\n updatedFooterHeight === null ||\n updatedMessagesHeight === null\n ) {\n resetTrailingSpace();\n return;\n }\n\n // If none of the heights have changed, we don't need to do anything.\n if (\n updatedContainerHeight === containerHeight &&\n updatedFooterHeight === footerHeight &&\n updatedMessagesHeight === messagesHeight\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 // 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 resizeObserver.observe(container);\n resizeObserver.observe(footer);\n resizeObserver.observe(messages);\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 />\n );\n } else {\n return null;\n }\n })}\n </div>\n );\n }\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 components,\n className,\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 // and wait for a frame in case the trailing space hasn't\n // been updated yet. (e.g. when sending a new message)\n requestAnimationFrame(() => {\n bottomMarkerRef.current?.scrollIntoView({\n behavior,\n block: \"end\",\n });\n });\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 bottomTrailingMarkerRef.current?.scrollIntoView({\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 <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 ref={messagesRef}\n messages={messages}\n overrides={overrides}\n components={components}\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 />\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 }}\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 knowledge={localKnowledge}\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","Fragment","ArrowDownIcon","AiComposer"],"mappings":"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"}
@@ -22,7 +22,6 @@ const defaultComponents = {
22
22
  const AiChatMessages = forwardRef(
23
23
  ({
24
24
  messages,
25
- copilotId,
26
25
  overrides,
27
26
  components,
28
27
  lastSentMessageId,
@@ -160,8 +159,7 @@ const AiChatMessages = forwardRef(
160
159
  return /* @__PURE__ */ jsx(AiChatAssistantMessage, {
161
160
  message,
162
161
  overrides,
163
- components,
164
- copilotId
162
+ components
165
163
  }, message.id);
166
164
  } else {
167
165
  return null;
@@ -248,7 +246,6 @@ const AiChat = forwardRef(
248
246
  children: [
249
247
  /* @__PURE__ */ jsx(AiChatMessages, {
250
248
  ref: messagesRef,
251
- copilotId,
252
249
  messages,
253
250
  overrides,
254
251
  components,
@@ -1 +1 @@
1
- {"version":3,"file":"AiChat.js","sources":["../../src/components/AiChat.tsx"],"sourcesContent":["import type {\n AiKnowledgeSource,\n AiOpaqueToolDefinition,\n CopilotId,\n MessageId,\n} from \"@liveblocks/core\";\nimport { RegisterAiTool, useAiChatMessages } 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 { AiChatAssistantMessage } 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 * 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 copilotId: AiChatProps[\"copilotId\"];\n overrides: AiChatProps[\"overrides\"];\n components: AiChatProps[\"components\"];\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 copilotId,\n overrides,\n components,\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 | null = null;\n let footerHeight: number | null = null;\n let messagesHeight: number | null = null;\n\n const resetTrailingSpace = () => {\n trailingSpacer?.style.removeProperty(\"height\");\n bottomTrailingMarker?.style.removeProperty(\"top\");\n };\n\n const resizeObserver = new ResizeObserver((entries) => {\n if (!trailingSpacer || !bottomTrailingMarker) {\n return;\n }\n\n const lastMessage = messages.lastElementChild;\n const penultimateMessage = lastMessage?.previousElementSibling;\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's height is based on its content, the container isn't scrollable and there's no need for any trailing space.\n if (container.scrollHeight === container.clientHeight) {\n resetTrailingSpace();\n return;\n }\n\n let updatedContainerHeight: number | null = containerHeight;\n let updatedFooterHeight: number | null = footerHeight;\n let updatedMessagesHeight: number | null = 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 ?? null;\n } else if (entry.target === footer) {\n updatedFooterHeight = entryHeight ?? null;\n } else if (entry.target === messages) {\n updatedMessagesHeight = entryHeight ?? null;\n }\n }\n\n // If we don't have all the heights, we can't compute the trailing space.\n if (\n updatedContainerHeight === null ||\n updatedFooterHeight === null ||\n updatedMessagesHeight === null\n ) {\n resetTrailingSpace();\n return;\n }\n\n // If none of the heights have changed, we don't need to do anything.\n if (\n updatedContainerHeight === containerHeight &&\n updatedFooterHeight === footerHeight &&\n updatedMessagesHeight === messagesHeight\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 // 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 resizeObserver.observe(container);\n resizeObserver.observe(footer);\n resizeObserver.observe(messages);\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 copilotId={copilotId}\n />\n );\n } else {\n return null;\n }\n })}\n </div>\n );\n }\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 components,\n className,\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 // and wait for a frame in case the trailing space hasn't\n // been updated yet. (e.g. when sending a new message)\n requestAnimationFrame(() => {\n bottomMarkerRef.current?.scrollIntoView({\n behavior,\n block: \"end\",\n });\n });\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 bottomTrailingMarkerRef.current?.scrollIntoView({\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 <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 ref={messagesRef}\n copilotId={copilotId}\n messages={messages}\n overrides={overrides}\n components={components}\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 />\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 }}\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 knowledge={localKnowledge}\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":["messages"],"mappings":"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"}
1
+ {"version":3,"file":"AiChat.js","sources":["../../src/components/AiChat.tsx"],"sourcesContent":["import type {\n AiKnowledgeSource,\n AiOpaqueToolDefinition,\n CopilotId,\n MessageId,\n} from \"@liveblocks/core\";\nimport { RegisterAiTool, useAiChatMessages } 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 { AiChatAssistantMessage } 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 * 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 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 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 | null = null;\n let footerHeight: number | null = null;\n let messagesHeight: number | null = null;\n\n const resetTrailingSpace = () => {\n trailingSpacer?.style.removeProperty(\"height\");\n bottomTrailingMarker?.style.removeProperty(\"top\");\n };\n\n const resizeObserver = new ResizeObserver((entries) => {\n if (!trailingSpacer || !bottomTrailingMarker) {\n return;\n }\n\n const lastMessage = messages.lastElementChild;\n const penultimateMessage = lastMessage?.previousElementSibling;\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's height is based on its content, the container isn't scrollable and there's no need for any trailing space.\n if (container.scrollHeight === container.clientHeight) {\n resetTrailingSpace();\n return;\n }\n\n let updatedContainerHeight: number | null = containerHeight;\n let updatedFooterHeight: number | null = footerHeight;\n let updatedMessagesHeight: number | null = 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 ?? null;\n } else if (entry.target === footer) {\n updatedFooterHeight = entryHeight ?? null;\n } else if (entry.target === messages) {\n updatedMessagesHeight = entryHeight ?? null;\n }\n }\n\n // If we don't have all the heights, we can't compute the trailing space.\n if (\n updatedContainerHeight === null ||\n updatedFooterHeight === null ||\n updatedMessagesHeight === null\n ) {\n resetTrailingSpace();\n return;\n }\n\n // If none of the heights have changed, we don't need to do anything.\n if (\n updatedContainerHeight === containerHeight &&\n updatedFooterHeight === footerHeight &&\n updatedMessagesHeight === messagesHeight\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 // 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 resizeObserver.observe(container);\n resizeObserver.observe(footer);\n resizeObserver.observe(messages);\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 />\n );\n } else {\n return null;\n }\n })}\n </div>\n );\n }\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 components,\n className,\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 // and wait for a frame in case the trailing space hasn't\n // been updated yet. (e.g. when sending a new message)\n requestAnimationFrame(() => {\n bottomMarkerRef.current?.scrollIntoView({\n behavior,\n block: \"end\",\n });\n });\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 bottomTrailingMarkerRef.current?.scrollIntoView({\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 <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 ref={messagesRef}\n messages={messages}\n overrides={overrides}\n components={components}\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 />\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 }}\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 knowledge={localKnowledge}\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":["messages"],"mappings":"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"}
@@ -14,7 +14,7 @@ var Prose = require('./Prose.cjs');
14
14
 
15
15
  const AiChatAssistantMessage = react.memo(
16
16
  react.forwardRef(
17
- ({ message, className, overrides: overrides$1, components, copilotId, ...props }, forwardedRef) => {
17
+ ({ message, className, overrides: overrides$1, components, ...props }, forwardedRef) => {
18
18
  const $ = overrides.useOverrides(overrides$1);
19
19
  let children = null;
20
20
  if (message.deletedAt !== void 0) {
@@ -31,30 +31,26 @@ const AiChatAssistantMessage = react.memo(
31
31
  } else {
32
32
  children = /* @__PURE__ */ jsxRuntime.jsx(AssistantMessageContent, {
33
33
  message,
34
- components,
35
- copilotId
34
+ components
36
35
  });
37
36
  }
38
37
  } else if (message.status === "completed") {
39
38
  children = /* @__PURE__ */ jsxRuntime.jsx(AssistantMessageContent, {
40
39
  message,
41
- components,
42
- copilotId
40
+ components
43
41
  });
44
42
  } else if (message.status === "failed") {
45
43
  if (message.errorReason === "Aborted by user") {
46
44
  children = /* @__PURE__ */ jsxRuntime.jsx(AssistantMessageContent, {
47
45
  message,
48
- components,
49
- copilotId
46
+ components
50
47
  });
51
48
  } else {
52
49
  children = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
53
50
  children: [
54
51
  /* @__PURE__ */ jsxRuntime.jsx(AssistantMessageContent, {
55
52
  message,
56
- components,
57
- copilotId
53
+ components
58
54
  }),
59
55
  /* @__PURE__ */ jsxRuntime.jsxs("div", {
60
56
  className: "lb-ai-chat-message-error",
@@ -87,8 +83,7 @@ const AiChatAssistantMessage = react.memo(
87
83
  );
88
84
  function AssistantMessageContent({
89
85
  message,
90
- components,
91
- copilotId
86
+ components
92
87
  }) {
93
88
  return /* @__PURE__ */ jsxRuntime.jsx(index.Content, {
94
89
  message,
@@ -103,7 +98,6 @@ function AssistantMessageContent({
103
98
  }),
104
99
  ToolInvocationPart
105
100
  },
106
- copilotId,
107
101
  className: "lb-ai-chat-message-content"
108
102
  });
109
103
  }
@@ -153,8 +147,7 @@ function ReasoningPart({ part, isStreaming, components }) {
153
147
  }
154
148
  function ToolInvocationPart({
155
149
  part,
156
- message,
157
- copilotId
150
+ message
158
151
  }) {
159
152
  return /* @__PURE__ */ jsxRuntime.jsx("div", {
160
153
  className: "lb-ai-chat-message-tool-invocation",
@@ -179,8 +172,7 @@ function ToolInvocationPart({
179
172
  }),
180
173
  children: /* @__PURE__ */ jsxRuntime.jsx(toolInvocation.AiMessageToolInvocation, {
181
174
  part,
182
- message,
183
- copilotId
175
+ message
184
176
  })
185
177
  })
186
178
  });
@@ -1 +1 @@
1
- {"version":3,"file":"AiChatAssistantMessage.cjs","sources":["../../../src/components/internal/AiChatAssistantMessage.tsx"],"sourcesContent":["import type { AiAssistantMessage, WithNavigation } from \"@liveblocks/core\";\nimport {\n type ComponentProps,\n forwardRef,\n memo,\n type ReactNode,\n useEffect,\n useState,\n} from \"react\";\n\nimport { type GlobalComponents } from \"../../components\";\nimport { ChevronRightIcon } from \"../../icons/ChevronRight\";\nimport { WarningIcon } from \"../../icons/Warning\";\nimport {\n type AiChatMessageOverrides,\n type GlobalOverrides,\n OverridesProvider,\n useOverrides,\n} from \"../../overrides\";\nimport * as AiMessage from \"../../primitives/AiMessage\";\nimport { AiMessageToolInvocation } from \"../../primitives/AiMessage/tool-invocation\";\nimport type {\n AiMessageContentReasoningPartProps,\n AiMessageContentTextPartProps,\n AiMessageContentToolInvocationPartProps,\n} from \"../../primitives/AiMessage/types\";\nimport * as Collapsible from \"../../primitives/Collapsible\";\nimport type { MarkdownComponents } from \"../../primitives/Markdown\";\nimport { cn } from \"../../utils/cn\";\nimport { ErrorBoundary } from \"../../utils/ErrorBoundary\";\nimport { Prose } from \"./Prose\";\n\ntype UiAssistantMessage = WithNavigation<AiAssistantMessage>;\n\ntype AiChatAssistantMessageComponents = {\n /**\n * The components used to render Markdown content.\n */\n markdown?: Partial<MarkdownComponents>;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AiChatAssistantMessage\n * -----------------------------------------------------------------------------------------------*/\nexport interface AiChatAssistantMessageProps extends ComponentProps<\"div\"> {\n /**\n * The message to display.\n */\n message: UiAssistantMessage;\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<GlobalOverrides & AiChatMessageOverrides>;\n\n /**\n * @internal\n * The id of the copilot to use to set tool call result.\n */\n copilotId?: string;\n\n /**\n * Override the component's components.\n */\n components?: Partial<GlobalComponents & AiChatAssistantMessageComponents>;\n}\n\ninterface TextPartProps extends AiMessageContentTextPartProps {\n components?: Partial<GlobalComponents & AiChatAssistantMessageComponents>;\n}\n\ninterface ReasoningPartProps extends AiMessageContentReasoningPartProps {\n components?: Partial<GlobalComponents & AiChatAssistantMessageComponents>;\n}\n\nexport const AiChatAssistantMessage = memo(\n forwardRef<HTMLDivElement, AiChatAssistantMessageProps>(\n (\n { message, className, overrides, components, copilotId, ...props },\n forwardedRef\n ) => {\n const $ = useOverrides(overrides);\n\n let children: ReactNode = null;\n\n if (message.deletedAt !== undefined) {\n children = (\n <div className=\"lb-ai-chat-message-deleted\">\n {$.AI_CHAT_MESSAGE_DELETED}\n </div>\n );\n } else if (\n message.status === \"generating\" ||\n message.status === \"awaiting-tool\"\n ) {\n if (message.contentSoFar.length === 0) {\n children = (\n <div className=\"lb-ai-chat-message-thinking lb-ai-chat-pending\">\n {$.AI_CHAT_MESSAGE_THINKING}\n </div>\n );\n } else {\n children = (\n <AssistantMessageContent\n message={message}\n components={components}\n copilotId={copilotId}\n />\n );\n }\n } else if (message.status === \"completed\") {\n children = (\n <AssistantMessageContent\n message={message}\n components={components}\n copilotId={copilotId}\n />\n );\n } else if (message.status === \"failed\") {\n // Do not include the error message if the user aborted the request.\n if (message.errorReason === \"Aborted by user\") {\n children = (\n <AssistantMessageContent\n message={message}\n components={components}\n copilotId={copilotId}\n />\n );\n } else {\n children = (\n <>\n <AssistantMessageContent\n message={message}\n components={components}\n copilotId={copilotId}\n />\n\n <div className=\"lb-ai-chat-message-error\">\n <span className=\"lb-icon-container\">\n <WarningIcon />\n </span>\n {message.errorReason}\n </div>\n </>\n );\n }\n }\n\n return (\n <div\n className={cn(\n \"lb-ai-chat-message lb-ai-chat-assistant-message\",\n className\n )}\n {...props}\n ref={forwardedRef}\n >\n <OverridesProvider overrides={overrides}>\n {children}\n </OverridesProvider>\n </div>\n );\n }\n )\n);\n\nfunction AssistantMessageContent({\n message,\n components,\n copilotId,\n}: {\n message: UiAssistantMessage;\n components?: Partial<GlobalComponents & AiChatAssistantMessageComponents>;\n copilotId?: string;\n}) {\n return (\n <AiMessage.Content\n message={message}\n components={{\n TextPart: (props) => <TextPart {...props} components={components} />,\n ReasoningPart: (props) => (\n <ReasoningPart {...props} components={components} />\n ),\n ToolInvocationPart,\n }}\n copilotId={copilotId}\n className=\"lb-ai-chat-message-content\"\n />\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * TextPart\n * -----------------------------------------------------------------------------------------------*/\nfunction TextPart({ part, components }: TextPartProps) {\n return (\n <Prose\n content={part.text}\n className=\"lb-ai-chat-message-text\"\n components={components}\n />\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * ReasoningPart\n * -----------------------------------------------------------------------------------------------*/\nfunction ReasoningPart({ part, isStreaming, components }: ReasoningPartProps) {\n // Start collapsed if reasoning is already done.\n const [isOpen, setIsOpen] = useState(isStreaming);\n const $ = useOverrides();\n\n // Auto-collapse when reasoning is done, while still allowing the user to\n // open/collapse it manually during and after it's done.\n useEffect(() => {\n if (!isStreaming) {\n setIsOpen(false);\n }\n }, [isStreaming]);\n\n return (\n <Collapsible.Root\n className=\"lb-collapsible lb-ai-chat-message-reasoning\"\n open={isOpen}\n onOpenChange={setIsOpen}\n >\n <Collapsible.Trigger\n className={cn(\n \"lb-collapsible-trigger\",\n isStreaming && \"lb-ai-chat-pending\"\n )}\n >\n {/* TODO: Show duration as \"Reasoned for x seconds\"? */}\n {$.AI_CHAT_MESSAGE_REASONING(isStreaming)}\n <span className=\"lb-collapsible-chevron lb-icon-container\">\n <ChevronRightIcon />\n </span>\n </Collapsible.Trigger>\n\n <Collapsible.Content className=\"lb-collapsible-content\">\n <Prose\n content={part.text}\n partial={isStreaming}\n components={components}\n />\n </Collapsible.Content>\n </Collapsible.Root>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * ToolInvocationPart\n * -----------------------------------------------------------------------------------------------*/\nfunction ToolInvocationPart({\n part,\n message,\n copilotId,\n}: AiMessageContentToolInvocationPartProps) {\n return (\n <div className=\"lb-ai-chat-message-tool-invocation\">\n <ErrorBoundary\n fallback={\n <div className=\"lb-ai-chat-message-error\">\n <span className=\"lb-icon-container\">\n <WarningIcon />\n </span>\n <p>\n Failed to render tool call result for <code>{part.name}</code>.\n See console for details.\n </p>\n </div>\n }\n >\n <AiMessageToolInvocation\n part={part}\n message={message}\n copilotId={copilotId}\n />\n </ErrorBoundary>\n </div>\n );\n}\n"],"names":["memo","forwardRef","overrides","useOverrides","jsx","jsxs","Fragment","WarningIcon","cn","OverridesProvider","AiMessage.Content","Prose","useState","useEffect","Collapsible.Root","Collapsible.Trigger","ChevronRightIcon","Collapsible.Content","ErrorBoundary","AiMessageToolInvocation"],"mappings":";;;;;;;;;;;;;;AA2EO,MAAM,sBAAyB,GAAAA,UAAA;AAAA,EACpCC,gBAAA;AAAA,IACE,CACE,EAAE,OAAS,EAAA,SAAA,aAAWC,aAAW,UAAY,EAAA,SAAA,EAAA,GAAc,KAAM,EAAA,EACjE,YACG,KAAA;AACH,MAAM,MAAA,CAAA,GAAIC,uBAAaD,WAAS,CAAA,CAAA;AAEhC,MAAA,IAAI,QAAsB,GAAA,IAAA,CAAA;AAE1B,MAAI,IAAA,OAAA,CAAQ,cAAc,KAAW,CAAA,EAAA;AACnC,QAAA,QAAA,mBACGE,cAAA,CAAA,KAAA,EAAA;AAAA,UAAI,SAAU,EAAA,4BAAA;AAAA,UACZ,QAAE,EAAA,CAAA,CAAA,uBAAA;AAAA,SACL,CAAA,CAAA;AAAA,iBAGF,OAAQ,CAAA,MAAA,KAAW,YACnB,IAAA,OAAA,CAAQ,WAAW,eACnB,EAAA;AACA,QAAI,IAAA,OAAA,CAAQ,YAAa,CAAA,MAAA,KAAW,CAAG,EAAA;AACrC,UAAA,QAAA,mBACGA,cAAA,CAAA,KAAA,EAAA;AAAA,YAAI,SAAU,EAAA,gDAAA;AAAA,YACZ,QAAE,EAAA,CAAA,CAAA,wBAAA;AAAA,WACL,CAAA,CAAA;AAAA,SAEG,MAAA;AACL,UAAA,QAAA,mBACGA,cAAA,CAAA,uBAAA,EAAA;AAAA,YACC,OAAA;AAAA,YACA,UAAA;AAAA,YACA,SAAA;AAAA,WACF,CAAA,CAAA;AAAA,SAEJ;AAAA,OACF,MAAA,IAAW,OAAQ,CAAA,MAAA,KAAW,WAAa,EAAA;AACzC,QAAA,QAAA,mBACGA,cAAA,CAAA,uBAAA,EAAA;AAAA,UACC,OAAA;AAAA,UACA,UAAA;AAAA,UACA,SAAA;AAAA,SACF,CAAA,CAAA;AAAA,OAEJ,MAAA,IAAW,OAAQ,CAAA,MAAA,KAAW,QAAU,EAAA;AAEtC,QAAI,IAAA,OAAA,CAAQ,gBAAgB,iBAAmB,EAAA;AAC7C,UAAA,QAAA,mBACGA,cAAA,CAAA,uBAAA,EAAA;AAAA,YACC,OAAA;AAAA,YACA,UAAA;AAAA,YACA,SAAA;AAAA,WACF,CAAA,CAAA;AAAA,SAEG,MAAA;AACL,UACE,QAAA,mBAAAC,eAAA,CAAAC,mBAAA,EAAA;AAAA,YACE,QAAA,EAAA;AAAA,8BAACF,cAAA,CAAA,uBAAA,EAAA;AAAA,gBACC,OAAA;AAAA,gBACA,UAAA;AAAA,gBACA,SAAA;AAAA,eACF,CAAA;AAAA,8BAECC,eAAA,CAAA,KAAA,EAAA;AAAA,gBAAI,SAAU,EAAA,0BAAA;AAAA,gBACb,QAAA,EAAA;AAAA,kCAACD,cAAA,CAAA,MAAA,EAAA;AAAA,oBAAK,SAAU,EAAA,mBAAA;AAAA,oBACd,yCAACG,mBAAY,EAAA,EAAA,CAAA;AAAA,mBACf,CAAA;AAAA,kBACC,OAAQ,CAAA,WAAA;AAAA,iBAAA;AAAA,eACX,CAAA;AAAA,aAAA;AAAA,WACF,CAAA,CAAA;AAAA,SAEJ;AAAA,OACF;AAEA,MAAA,uBACGH,cAAA,CAAA,KAAA,EAAA;AAAA,QACC,SAAW,EAAAI,KAAA;AAAA,UACT,iDAAA;AAAA,UACA,SAAA;AAAA,SACF;AAAA,QACC,GAAG,KAAA;AAAA,QACJ,GAAK,EAAA,YAAA;AAAA,QAEL,QAAC,kBAAAJ,cAAA,CAAAK,2BAAA,EAAA;AAAA,qBAAkBP,WAAA;AAAA,UAChB,QAAA;AAAA,SACH,CAAA;AAAA,OACF,CAAA,CAAA;AAAA,KAEJ;AAAA,GACF;AACF,EAAA;AAEA,SAAS,uBAAwB,CAAA;AAAA,EAC/B,OAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AACF,CAIG,EAAA;AACD,EACE,uBAAAE,cAAA,CAACM,aAAA,EAAA;AAAA,IACC,OAAA;AAAA,IACA,UAAY,EAAA;AAAA,MACV,QAAA,EAAU,CAAC,KAAA,qBAAWN,cAAA,CAAA,QAAA,EAAA;AAAA,QAAU,GAAG,KAAA;AAAA,QAAO,UAAA;AAAA,OAAwB,CAAA;AAAA,MAClE,aAAA,EAAe,CAAC,KAAA,qBACbA,cAAA,CAAA,aAAA,EAAA;AAAA,QAAe,GAAG,KAAA;AAAA,QAAO,UAAA;AAAA,OAAwB,CAAA;AAAA,MAEpD,kBAAA;AAAA,KACF;AAAA,IACA,SAAA;AAAA,IACA,SAAU,EAAA,4BAAA;AAAA,GACZ,CAAA,CAAA;AAEJ,CAAA;AAKA,SAAS,QAAS,CAAA,EAAE,IAAM,EAAA,UAAA,EAA6B,EAAA;AACrD,EAAA,uBACGA,cAAA,CAAAO,WAAA,EAAA;AAAA,IACC,SAAS,IAAK,CAAA,IAAA;AAAA,IACd,SAAU,EAAA,yBAAA;AAAA,IACV,UAAA;AAAA,GACF,CAAA,CAAA;AAEJ,CAAA;AAKA,SAAS,aAAc,CAAA,EAAE,IAAM,EAAA,WAAA,EAAa,YAAkC,EAAA;AAE5E,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIC,eAAS,WAAW,CAAA,CAAA;AAChD,EAAA,MAAM,IAAIT,sBAAa,EAAA,CAAA;AAIvB,EAAAU,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,WAAa,EAAA;AAChB,MAAA,SAAA,CAAU,KAAK,CAAA,CAAA;AAAA,KACjB;AAAA,GACF,EAAG,CAAC,WAAW,CAAC,CAAA,CAAA;AAEhB,EACE,uBAAAR,eAAA,CAACS,YAAA,EAAA;AAAA,IACC,SAAU,EAAA,6CAAA;AAAA,IACV,IAAM,EAAA,MAAA;AAAA,IACN,YAAc,EAAA,SAAA;AAAA,IAEd,QAAA,EAAA;AAAA,sBAAAT,eAAA,CAACU,eAAA,EAAA;AAAA,QACC,SAAW,EAAAP,KAAA;AAAA,UACT,wBAAA;AAAA,UACA,WAAe,IAAA,oBAAA;AAAA,SACjB;AAAA,QAGC,QAAA,EAAA;AAAA,UAAA,CAAA,CAAE,0BAA0B,WAAW,CAAA;AAAA,0BACvCJ,cAAA,CAAA,MAAA,EAAA;AAAA,YAAK,SAAU,EAAA,0CAAA;AAAA,YACd,yCAACY,6BAAiB,EAAA,EAAA,CAAA;AAAA,WACpB,CAAA;AAAA,SAAA;AAAA,OACF,CAAA;AAAA,sBAEAZ,cAAA,CAACa,eAAA,EAAA;AAAA,QAAoB,SAAU,EAAA,wBAAA;AAAA,QAC7B,QAAC,kBAAAb,cAAA,CAAAO,WAAA,EAAA;AAAA,UACC,SAAS,IAAK,CAAA,IAAA;AAAA,UACd,OAAS,EAAA,WAAA;AAAA,UACT,UAAA;AAAA,SACF,CAAA;AAAA,OACF,CAAA;AAAA,KAAA;AAAA,GACF,CAAA,CAAA;AAEJ,CAAA;AAKA,SAAS,kBAAmB,CAAA;AAAA,EAC1B,IAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AACF,CAA4C,EAAA;AAC1C,EAAA,uBACGP,cAAA,CAAA,KAAA,EAAA;AAAA,IAAI,SAAU,EAAA,oCAAA;AAAA,IACb,QAAC,kBAAAA,cAAA,CAAAc,2BAAA,EAAA;AAAA,MACC,0BACGb,eAAA,CAAA,KAAA,EAAA;AAAA,QAAI,SAAU,EAAA,0BAAA;AAAA,QACb,QAAA,EAAA;AAAA,0BAACD,cAAA,CAAA,MAAA,EAAA;AAAA,YAAK,SAAU,EAAA,mBAAA;AAAA,YACd,yCAACG,mBAAY,EAAA,EAAA,CAAA;AAAA,WACf,CAAA;AAAA,0BACCF,eAAA,CAAA,GAAA,EAAA;AAAA,YAAE,QAAA,EAAA;AAAA,cAAA,wCAAA;AAAA,8BACsCD,cAAA,CAAA,MAAA,EAAA;AAAA,gBAAM,QAAK,EAAA,IAAA,CAAA,IAAA;AAAA,eAAK,CAAA;AAAA,cAAO,4BAAA;AAAA,aAAA;AAAA,WAEhE,CAAA;AAAA,SAAA;AAAA,OACF,CAAA;AAAA,MAGF,QAAC,kBAAAA,cAAA,CAAAe,sCAAA,EAAA;AAAA,QACC,IAAA;AAAA,QACA,OAAA;AAAA,QACA,SAAA;AAAA,OACF,CAAA;AAAA,KACF,CAAA;AAAA,GACF,CAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"AiChatAssistantMessage.cjs","sources":["../../../src/components/internal/AiChatAssistantMessage.tsx"],"sourcesContent":["import type { AiAssistantMessage, WithNavigation } from \"@liveblocks/core\";\nimport {\n type ComponentProps,\n forwardRef,\n memo,\n type ReactNode,\n useEffect,\n useState,\n} from \"react\";\n\nimport { type GlobalComponents } from \"../../components\";\nimport { ChevronRightIcon } from \"../../icons/ChevronRight\";\nimport { WarningIcon } from \"../../icons/Warning\";\nimport {\n type AiChatMessageOverrides,\n type GlobalOverrides,\n OverridesProvider,\n useOverrides,\n} from \"../../overrides\";\nimport * as AiMessage from \"../../primitives/AiMessage\";\nimport { AiMessageToolInvocation } from \"../../primitives/AiMessage/tool-invocation\";\nimport type {\n AiMessageContentReasoningPartProps,\n AiMessageContentTextPartProps,\n AiMessageContentToolInvocationPartProps,\n} from \"../../primitives/AiMessage/types\";\nimport * as Collapsible from \"../../primitives/Collapsible\";\nimport type { MarkdownComponents } from \"../../primitives/Markdown\";\nimport { cn } from \"../../utils/cn\";\nimport { ErrorBoundary } from \"../../utils/ErrorBoundary\";\nimport { Prose } from \"./Prose\";\n\ntype UiAssistantMessage = WithNavigation<AiAssistantMessage>;\n\ntype AiChatAssistantMessageComponents = {\n /**\n * The components used to render Markdown content.\n */\n markdown?: Partial<MarkdownComponents>;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AiChatAssistantMessage\n * -----------------------------------------------------------------------------------------------*/\nexport interface AiChatAssistantMessageProps extends ComponentProps<\"div\"> {\n /**\n * The message to display.\n */\n message: UiAssistantMessage;\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<GlobalOverrides & AiChatMessageOverrides>;\n\n /**\n * Override the component's components.\n */\n components?: Partial<GlobalComponents & AiChatAssistantMessageComponents>;\n}\n\ninterface TextPartProps extends AiMessageContentTextPartProps {\n components?: Partial<GlobalComponents & AiChatAssistantMessageComponents>;\n}\n\ninterface ReasoningPartProps extends AiMessageContentReasoningPartProps {\n components?: Partial<GlobalComponents & AiChatAssistantMessageComponents>;\n}\n\nexport const AiChatAssistantMessage = memo(\n forwardRef<HTMLDivElement, AiChatAssistantMessageProps>(\n ({ message, className, overrides, components, ...props }, forwardedRef) => {\n const $ = useOverrides(overrides);\n\n let children: ReactNode = null;\n\n if (message.deletedAt !== undefined) {\n children = (\n <div className=\"lb-ai-chat-message-deleted\">\n {$.AI_CHAT_MESSAGE_DELETED}\n </div>\n );\n } else if (\n message.status === \"generating\" ||\n message.status === \"awaiting-tool\"\n ) {\n if (message.contentSoFar.length === 0) {\n children = (\n <div className=\"lb-ai-chat-message-thinking lb-ai-chat-pending\">\n {$.AI_CHAT_MESSAGE_THINKING}\n </div>\n );\n } else {\n children = (\n <AssistantMessageContent\n message={message}\n components={components}\n />\n );\n }\n } else if (message.status === \"completed\") {\n children = (\n <AssistantMessageContent message={message} components={components} />\n );\n } else if (message.status === \"failed\") {\n // Do not include the error message if the user aborted the request.\n if (message.errorReason === \"Aborted by user\") {\n children = (\n <AssistantMessageContent\n message={message}\n components={components}\n />\n );\n } else {\n children = (\n <>\n <AssistantMessageContent\n message={message}\n components={components}\n />\n\n <div className=\"lb-ai-chat-message-error\">\n <span className=\"lb-icon-container\">\n <WarningIcon />\n </span>\n {message.errorReason}\n </div>\n </>\n );\n }\n }\n\n return (\n <div\n className={cn(\n \"lb-ai-chat-message lb-ai-chat-assistant-message\",\n className\n )}\n {...props}\n ref={forwardedRef}\n >\n <OverridesProvider overrides={overrides}>\n {children}\n </OverridesProvider>\n </div>\n );\n }\n )\n);\n\nfunction AssistantMessageContent({\n message,\n components,\n}: {\n message: UiAssistantMessage;\n components?: Partial<GlobalComponents & AiChatAssistantMessageComponents>;\n}) {\n return (\n <AiMessage.Content\n message={message}\n components={{\n TextPart: (props) => <TextPart {...props} components={components} />,\n ReasoningPart: (props) => (\n <ReasoningPart {...props} components={components} />\n ),\n ToolInvocationPart,\n }}\n className=\"lb-ai-chat-message-content\"\n />\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * TextPart\n * -----------------------------------------------------------------------------------------------*/\nfunction TextPart({ part, components }: TextPartProps) {\n return (\n <Prose\n content={part.text}\n className=\"lb-ai-chat-message-text\"\n components={components}\n />\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * ReasoningPart\n * -----------------------------------------------------------------------------------------------*/\nfunction ReasoningPart({ part, isStreaming, components }: ReasoningPartProps) {\n // Start collapsed if reasoning is already done.\n const [isOpen, setIsOpen] = useState(isStreaming);\n const $ = useOverrides();\n\n // Auto-collapse when reasoning is done, while still allowing the user to\n // open/collapse it manually during and after it's done.\n useEffect(() => {\n if (!isStreaming) {\n setIsOpen(false);\n }\n }, [isStreaming]);\n\n return (\n <Collapsible.Root\n className=\"lb-collapsible lb-ai-chat-message-reasoning\"\n open={isOpen}\n onOpenChange={setIsOpen}\n >\n <Collapsible.Trigger\n className={cn(\n \"lb-collapsible-trigger\",\n isStreaming && \"lb-ai-chat-pending\"\n )}\n >\n {/* TODO: Show duration as \"Reasoned for x seconds\"? */}\n {$.AI_CHAT_MESSAGE_REASONING(isStreaming)}\n <span className=\"lb-collapsible-chevron lb-icon-container\">\n <ChevronRightIcon />\n </span>\n </Collapsible.Trigger>\n\n <Collapsible.Content className=\"lb-collapsible-content\">\n <Prose\n content={part.text}\n partial={isStreaming}\n components={components}\n />\n </Collapsible.Content>\n </Collapsible.Root>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * ToolInvocationPart\n * -----------------------------------------------------------------------------------------------*/\nfunction ToolInvocationPart({\n part,\n message,\n}: AiMessageContentToolInvocationPartProps) {\n return (\n <div className=\"lb-ai-chat-message-tool-invocation\">\n <ErrorBoundary\n fallback={\n <div className=\"lb-ai-chat-message-error\">\n <span className=\"lb-icon-container\">\n <WarningIcon />\n </span>\n <p>\n Failed to render tool call result for <code>{part.name}</code>.\n See console for details.\n </p>\n </div>\n }\n >\n <AiMessageToolInvocation part={part} message={message} />\n </ErrorBoundary>\n </div>\n );\n}\n"],"names":["memo","forwardRef","overrides","useOverrides","jsx","jsxs","Fragment","WarningIcon","cn","OverridesProvider","AiMessage.Content","Prose","useState","useEffect","Collapsible.Root","Collapsible.Trigger","ChevronRightIcon","Collapsible.Content","ErrorBoundary","AiMessageToolInvocation"],"mappings":"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"}
@@ -12,7 +12,7 @@ import { Prose } from './Prose.js';
12
12
 
13
13
  const AiChatAssistantMessage = memo(
14
14
  forwardRef(
15
- ({ message, className, overrides, components, copilotId, ...props }, forwardedRef) => {
15
+ ({ message, className, overrides, components, ...props }, forwardedRef) => {
16
16
  const $ = useOverrides(overrides);
17
17
  let children = null;
18
18
  if (message.deletedAt !== void 0) {
@@ -29,30 +29,26 @@ const AiChatAssistantMessage = memo(
29
29
  } else {
30
30
  children = /* @__PURE__ */ jsx(AssistantMessageContent, {
31
31
  message,
32
- components,
33
- copilotId
32
+ components
34
33
  });
35
34
  }
36
35
  } else if (message.status === "completed") {
37
36
  children = /* @__PURE__ */ jsx(AssistantMessageContent, {
38
37
  message,
39
- components,
40
- copilotId
38
+ components
41
39
  });
42
40
  } else if (message.status === "failed") {
43
41
  if (message.errorReason === "Aborted by user") {
44
42
  children = /* @__PURE__ */ jsx(AssistantMessageContent, {
45
43
  message,
46
- components,
47
- copilotId
44
+ components
48
45
  });
49
46
  } else {
50
47
  children = /* @__PURE__ */ jsxs(Fragment, {
51
48
  children: [
52
49
  /* @__PURE__ */ jsx(AssistantMessageContent, {
53
50
  message,
54
- components,
55
- copilotId
51
+ components
56
52
  }),
57
53
  /* @__PURE__ */ jsxs("div", {
58
54
  className: "lb-ai-chat-message-error",
@@ -85,8 +81,7 @@ const AiChatAssistantMessage = memo(
85
81
  );
86
82
  function AssistantMessageContent({
87
83
  message,
88
- components,
89
- copilotId
84
+ components
90
85
  }) {
91
86
  return /* @__PURE__ */ jsx(AiMessageContent, {
92
87
  message,
@@ -101,7 +96,6 @@ function AssistantMessageContent({
101
96
  }),
102
97
  ToolInvocationPart
103
98
  },
104
- copilotId,
105
99
  className: "lb-ai-chat-message-content"
106
100
  });
107
101
  }
@@ -151,8 +145,7 @@ function ReasoningPart({ part, isStreaming, components }) {
151
145
  }
152
146
  function ToolInvocationPart({
153
147
  part,
154
- message,
155
- copilotId
148
+ message
156
149
  }) {
157
150
  return /* @__PURE__ */ jsx("div", {
158
151
  className: "lb-ai-chat-message-tool-invocation",
@@ -177,8 +170,7 @@ function ToolInvocationPart({
177
170
  }),
178
171
  children: /* @__PURE__ */ jsx(AiMessageToolInvocation, {
179
172
  part,
180
- message,
181
- copilotId
173
+ message
182
174
  })
183
175
  })
184
176
  });
@@ -1 +1 @@
1
- {"version":3,"file":"AiChatAssistantMessage.js","sources":["../../../src/components/internal/AiChatAssistantMessage.tsx"],"sourcesContent":["import type { AiAssistantMessage, WithNavigation } from \"@liveblocks/core\";\nimport {\n type ComponentProps,\n forwardRef,\n memo,\n type ReactNode,\n useEffect,\n useState,\n} from \"react\";\n\nimport { type GlobalComponents } from \"../../components\";\nimport { ChevronRightIcon } from \"../../icons/ChevronRight\";\nimport { WarningIcon } from \"../../icons/Warning\";\nimport {\n type AiChatMessageOverrides,\n type GlobalOverrides,\n OverridesProvider,\n useOverrides,\n} from \"../../overrides\";\nimport * as AiMessage from \"../../primitives/AiMessage\";\nimport { AiMessageToolInvocation } from \"../../primitives/AiMessage/tool-invocation\";\nimport type {\n AiMessageContentReasoningPartProps,\n AiMessageContentTextPartProps,\n AiMessageContentToolInvocationPartProps,\n} from \"../../primitives/AiMessage/types\";\nimport * as Collapsible from \"../../primitives/Collapsible\";\nimport type { MarkdownComponents } from \"../../primitives/Markdown\";\nimport { cn } from \"../../utils/cn\";\nimport { ErrorBoundary } from \"../../utils/ErrorBoundary\";\nimport { Prose } from \"./Prose\";\n\ntype UiAssistantMessage = WithNavigation<AiAssistantMessage>;\n\ntype AiChatAssistantMessageComponents = {\n /**\n * The components used to render Markdown content.\n */\n markdown?: Partial<MarkdownComponents>;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AiChatAssistantMessage\n * -----------------------------------------------------------------------------------------------*/\nexport interface AiChatAssistantMessageProps extends ComponentProps<\"div\"> {\n /**\n * The message to display.\n */\n message: UiAssistantMessage;\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<GlobalOverrides & AiChatMessageOverrides>;\n\n /**\n * @internal\n * The id of the copilot to use to set tool call result.\n */\n copilotId?: string;\n\n /**\n * Override the component's components.\n */\n components?: Partial<GlobalComponents & AiChatAssistantMessageComponents>;\n}\n\ninterface TextPartProps extends AiMessageContentTextPartProps {\n components?: Partial<GlobalComponents & AiChatAssistantMessageComponents>;\n}\n\ninterface ReasoningPartProps extends AiMessageContentReasoningPartProps {\n components?: Partial<GlobalComponents & AiChatAssistantMessageComponents>;\n}\n\nexport const AiChatAssistantMessage = memo(\n forwardRef<HTMLDivElement, AiChatAssistantMessageProps>(\n (\n { message, className, overrides, components, copilotId, ...props },\n forwardedRef\n ) => {\n const $ = useOverrides(overrides);\n\n let children: ReactNode = null;\n\n if (message.deletedAt !== undefined) {\n children = (\n <div className=\"lb-ai-chat-message-deleted\">\n {$.AI_CHAT_MESSAGE_DELETED}\n </div>\n );\n } else if (\n message.status === \"generating\" ||\n message.status === \"awaiting-tool\"\n ) {\n if (message.contentSoFar.length === 0) {\n children = (\n <div className=\"lb-ai-chat-message-thinking lb-ai-chat-pending\">\n {$.AI_CHAT_MESSAGE_THINKING}\n </div>\n );\n } else {\n children = (\n <AssistantMessageContent\n message={message}\n components={components}\n copilotId={copilotId}\n />\n );\n }\n } else if (message.status === \"completed\") {\n children = (\n <AssistantMessageContent\n message={message}\n components={components}\n copilotId={copilotId}\n />\n );\n } else if (message.status === \"failed\") {\n // Do not include the error message if the user aborted the request.\n if (message.errorReason === \"Aborted by user\") {\n children = (\n <AssistantMessageContent\n message={message}\n components={components}\n copilotId={copilotId}\n />\n );\n } else {\n children = (\n <>\n <AssistantMessageContent\n message={message}\n components={components}\n copilotId={copilotId}\n />\n\n <div className=\"lb-ai-chat-message-error\">\n <span className=\"lb-icon-container\">\n <WarningIcon />\n </span>\n {message.errorReason}\n </div>\n </>\n );\n }\n }\n\n return (\n <div\n className={cn(\n \"lb-ai-chat-message lb-ai-chat-assistant-message\",\n className\n )}\n {...props}\n ref={forwardedRef}\n >\n <OverridesProvider overrides={overrides}>\n {children}\n </OverridesProvider>\n </div>\n );\n }\n )\n);\n\nfunction AssistantMessageContent({\n message,\n components,\n copilotId,\n}: {\n message: UiAssistantMessage;\n components?: Partial<GlobalComponents & AiChatAssistantMessageComponents>;\n copilotId?: string;\n}) {\n return (\n <AiMessage.Content\n message={message}\n components={{\n TextPart: (props) => <TextPart {...props} components={components} />,\n ReasoningPart: (props) => (\n <ReasoningPart {...props} components={components} />\n ),\n ToolInvocationPart,\n }}\n copilotId={copilotId}\n className=\"lb-ai-chat-message-content\"\n />\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * TextPart\n * -----------------------------------------------------------------------------------------------*/\nfunction TextPart({ part, components }: TextPartProps) {\n return (\n <Prose\n content={part.text}\n className=\"lb-ai-chat-message-text\"\n components={components}\n />\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * ReasoningPart\n * -----------------------------------------------------------------------------------------------*/\nfunction ReasoningPart({ part, isStreaming, components }: ReasoningPartProps) {\n // Start collapsed if reasoning is already done.\n const [isOpen, setIsOpen] = useState(isStreaming);\n const $ = useOverrides();\n\n // Auto-collapse when reasoning is done, while still allowing the user to\n // open/collapse it manually during and after it's done.\n useEffect(() => {\n if (!isStreaming) {\n setIsOpen(false);\n }\n }, [isStreaming]);\n\n return (\n <Collapsible.Root\n className=\"lb-collapsible lb-ai-chat-message-reasoning\"\n open={isOpen}\n onOpenChange={setIsOpen}\n >\n <Collapsible.Trigger\n className={cn(\n \"lb-collapsible-trigger\",\n isStreaming && \"lb-ai-chat-pending\"\n )}\n >\n {/* TODO: Show duration as \"Reasoned for x seconds\"? */}\n {$.AI_CHAT_MESSAGE_REASONING(isStreaming)}\n <span className=\"lb-collapsible-chevron lb-icon-container\">\n <ChevronRightIcon />\n </span>\n </Collapsible.Trigger>\n\n <Collapsible.Content className=\"lb-collapsible-content\">\n <Prose\n content={part.text}\n partial={isStreaming}\n components={components}\n />\n </Collapsible.Content>\n </Collapsible.Root>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * ToolInvocationPart\n * -----------------------------------------------------------------------------------------------*/\nfunction ToolInvocationPart({\n part,\n message,\n copilotId,\n}: AiMessageContentToolInvocationPartProps) {\n return (\n <div className=\"lb-ai-chat-message-tool-invocation\">\n <ErrorBoundary\n fallback={\n <div className=\"lb-ai-chat-message-error\">\n <span className=\"lb-icon-container\">\n <WarningIcon />\n </span>\n <p>\n Failed to render tool call result for <code>{part.name}</code>.\n See console for details.\n </p>\n </div>\n }\n >\n <AiMessageToolInvocation\n part={part}\n message={message}\n copilotId={copilotId}\n />\n </ErrorBoundary>\n </div>\n );\n}\n"],"names":["AiMessage.Content","Collapsible.Root","Collapsible.Trigger","Collapsible.Content"],"mappings":"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"}
1
+ {"version":3,"file":"AiChatAssistantMessage.js","sources":["../../../src/components/internal/AiChatAssistantMessage.tsx"],"sourcesContent":["import type { AiAssistantMessage, WithNavigation } from \"@liveblocks/core\";\nimport {\n type ComponentProps,\n forwardRef,\n memo,\n type ReactNode,\n useEffect,\n useState,\n} from \"react\";\n\nimport { type GlobalComponents } from \"../../components\";\nimport { ChevronRightIcon } from \"../../icons/ChevronRight\";\nimport { WarningIcon } from \"../../icons/Warning\";\nimport {\n type AiChatMessageOverrides,\n type GlobalOverrides,\n OverridesProvider,\n useOverrides,\n} from \"../../overrides\";\nimport * as AiMessage from \"../../primitives/AiMessage\";\nimport { AiMessageToolInvocation } from \"../../primitives/AiMessage/tool-invocation\";\nimport type {\n AiMessageContentReasoningPartProps,\n AiMessageContentTextPartProps,\n AiMessageContentToolInvocationPartProps,\n} from \"../../primitives/AiMessage/types\";\nimport * as Collapsible from \"../../primitives/Collapsible\";\nimport type { MarkdownComponents } from \"../../primitives/Markdown\";\nimport { cn } from \"../../utils/cn\";\nimport { ErrorBoundary } from \"../../utils/ErrorBoundary\";\nimport { Prose } from \"./Prose\";\n\ntype UiAssistantMessage = WithNavigation<AiAssistantMessage>;\n\ntype AiChatAssistantMessageComponents = {\n /**\n * The components used to render Markdown content.\n */\n markdown?: Partial<MarkdownComponents>;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * AiChatAssistantMessage\n * -----------------------------------------------------------------------------------------------*/\nexport interface AiChatAssistantMessageProps extends ComponentProps<\"div\"> {\n /**\n * The message to display.\n */\n message: UiAssistantMessage;\n\n /**\n * Override the component's strings.\n */\n overrides?: Partial<GlobalOverrides & AiChatMessageOverrides>;\n\n /**\n * Override the component's components.\n */\n components?: Partial<GlobalComponents & AiChatAssistantMessageComponents>;\n}\n\ninterface TextPartProps extends AiMessageContentTextPartProps {\n components?: Partial<GlobalComponents & AiChatAssistantMessageComponents>;\n}\n\ninterface ReasoningPartProps extends AiMessageContentReasoningPartProps {\n components?: Partial<GlobalComponents & AiChatAssistantMessageComponents>;\n}\n\nexport const AiChatAssistantMessage = memo(\n forwardRef<HTMLDivElement, AiChatAssistantMessageProps>(\n ({ message, className, overrides, components, ...props }, forwardedRef) => {\n const $ = useOverrides(overrides);\n\n let children: ReactNode = null;\n\n if (message.deletedAt !== undefined) {\n children = (\n <div className=\"lb-ai-chat-message-deleted\">\n {$.AI_CHAT_MESSAGE_DELETED}\n </div>\n );\n } else if (\n message.status === \"generating\" ||\n message.status === \"awaiting-tool\"\n ) {\n if (message.contentSoFar.length === 0) {\n children = (\n <div className=\"lb-ai-chat-message-thinking lb-ai-chat-pending\">\n {$.AI_CHAT_MESSAGE_THINKING}\n </div>\n );\n } else {\n children = (\n <AssistantMessageContent\n message={message}\n components={components}\n />\n );\n }\n } else if (message.status === \"completed\") {\n children = (\n <AssistantMessageContent message={message} components={components} />\n );\n } else if (message.status === \"failed\") {\n // Do not include the error message if the user aborted the request.\n if (message.errorReason === \"Aborted by user\") {\n children = (\n <AssistantMessageContent\n message={message}\n components={components}\n />\n );\n } else {\n children = (\n <>\n <AssistantMessageContent\n message={message}\n components={components}\n />\n\n <div className=\"lb-ai-chat-message-error\">\n <span className=\"lb-icon-container\">\n <WarningIcon />\n </span>\n {message.errorReason}\n </div>\n </>\n );\n }\n }\n\n return (\n <div\n className={cn(\n \"lb-ai-chat-message lb-ai-chat-assistant-message\",\n className\n )}\n {...props}\n ref={forwardedRef}\n >\n <OverridesProvider overrides={overrides}>\n {children}\n </OverridesProvider>\n </div>\n );\n }\n )\n);\n\nfunction AssistantMessageContent({\n message,\n components,\n}: {\n message: UiAssistantMessage;\n components?: Partial<GlobalComponents & AiChatAssistantMessageComponents>;\n}) {\n return (\n <AiMessage.Content\n message={message}\n components={{\n TextPart: (props) => <TextPart {...props} components={components} />,\n ReasoningPart: (props) => (\n <ReasoningPart {...props} components={components} />\n ),\n ToolInvocationPart,\n }}\n className=\"lb-ai-chat-message-content\"\n />\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * TextPart\n * -----------------------------------------------------------------------------------------------*/\nfunction TextPart({ part, components }: TextPartProps) {\n return (\n <Prose\n content={part.text}\n className=\"lb-ai-chat-message-text\"\n components={components}\n />\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * ReasoningPart\n * -----------------------------------------------------------------------------------------------*/\nfunction ReasoningPart({ part, isStreaming, components }: ReasoningPartProps) {\n // Start collapsed if reasoning is already done.\n const [isOpen, setIsOpen] = useState(isStreaming);\n const $ = useOverrides();\n\n // Auto-collapse when reasoning is done, while still allowing the user to\n // open/collapse it manually during and after it's done.\n useEffect(() => {\n if (!isStreaming) {\n setIsOpen(false);\n }\n }, [isStreaming]);\n\n return (\n <Collapsible.Root\n className=\"lb-collapsible lb-ai-chat-message-reasoning\"\n open={isOpen}\n onOpenChange={setIsOpen}\n >\n <Collapsible.Trigger\n className={cn(\n \"lb-collapsible-trigger\",\n isStreaming && \"lb-ai-chat-pending\"\n )}\n >\n {/* TODO: Show duration as \"Reasoned for x seconds\"? */}\n {$.AI_CHAT_MESSAGE_REASONING(isStreaming)}\n <span className=\"lb-collapsible-chevron lb-icon-container\">\n <ChevronRightIcon />\n </span>\n </Collapsible.Trigger>\n\n <Collapsible.Content className=\"lb-collapsible-content\">\n <Prose\n content={part.text}\n partial={isStreaming}\n components={components}\n />\n </Collapsible.Content>\n </Collapsible.Root>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * ToolInvocationPart\n * -----------------------------------------------------------------------------------------------*/\nfunction ToolInvocationPart({\n part,\n message,\n}: AiMessageContentToolInvocationPartProps) {\n return (\n <div className=\"lb-ai-chat-message-tool-invocation\">\n <ErrorBoundary\n fallback={\n <div className=\"lb-ai-chat-message-error\">\n <span className=\"lb-icon-container\">\n <WarningIcon />\n </span>\n <p>\n Failed to render tool call result for <code>{part.name}</code>.\n See console for details.\n </p>\n </div>\n }\n >\n <AiMessageToolInvocation part={part} message={message} />\n </ErrorBoundary>\n </div>\n );\n}\n"],"names":["AiMessage.Content","Collapsible.Root","Collapsible.Trigger","Collapsible.Content"],"mappings":"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"}
@@ -30,7 +30,7 @@ const defaultMessageContentComponents = {
30
30
  }
31
31
  };
32
32
  const AiMessageContent = react.forwardRef(
33
- ({ message, components, asChild, copilotId, ...props }, forwardedRef) => {
33
+ ({ message, components, asChild, ...props }, forwardedRef) => {
34
34
  const Component = asChild ? reactSlot.Slot : "div";
35
35
  const { TextPart, ReasoningPart, ToolInvocationPart } = react.useMemo(
36
36
  () => ({ ...defaultMessageContentComponents, ...components }),
@@ -60,8 +60,7 @@ const AiMessageContent = react.forwardRef(
60
60
  return /* @__PURE__ */ jsxRuntime.jsx(ToolInvocationPart, {
61
61
  part,
62
62
  ...extra,
63
- message,
64
- copilotId
63
+ message
65
64
  }, index);
66
65
  default:
67
66
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../../src/primitives/AiMessage/index.tsx"],"sourcesContent":["import { Slot } from \"@radix-ui/react-slot\";\nimport { forwardRef, useMemo } from \"react\";\n\nimport { ErrorBoundary } from \"../../utils/ErrorBoundary\";\nimport { Markdown } from \"../Markdown\";\nimport { AiMessageToolInvocation } from \"./tool-invocation\";\nimport type {\n AiMessageContentComponents,\n AiMessageContentProps,\n} from \"./types\";\n\nconst AI_MESSAGE_CONTENT_NAME = \"AiMessageContent\";\n\nconst defaultMessageContentComponents: AiMessageContentComponents = {\n TextPart: ({ part }) => {\n return <Markdown content={part.text} />;\n },\n ReasoningPart: ({ part }) => {\n return <Markdown content={part.text} />;\n },\n ToolInvocationPart: ({ part, message }) => {\n return (\n <ErrorBoundary fallback={null}>\n <AiMessageToolInvocation part={part} message={message} />\n </ErrorBoundary>\n );\n },\n};\n\n/**\n * --------------------------------------------------------------------------\n * @private The API for this component is not yet stable.\n * --------------------------------------------------------------------------\n *\n * Primitive to help display an user or assistant message’s content, which is\n * an array of parts.\n *\n * @example\n * <AiMessage.Content message={message} components={{ TextPart }} />\n */\nconst AiMessageContent = forwardRef<HTMLDivElement, AiMessageContentProps>(\n ({ message, components, asChild, copilotId, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"div\";\n const { TextPart, ReasoningPart, ToolInvocationPart } = useMemo(\n () => ({ ...defaultMessageContentComponents, ...components }),\n [components]\n );\n\n const content = message.content ?? message.contentSoFar;\n const numParts = content.length;\n const isGenerating =\n message.role === \"assistant\" && message.status === \"generating\";\n return (\n <Component {...props} ref={forwardedRef}>\n {content.map((part, index) => {\n // A part is considered to be still \"streaming in\" if it's the last\n // part in the content array, and the message is in \"generating\"\n // state.\n const isStreaming = isGenerating && index === numParts - 1;\n const extra = { index, isStreaming };\n switch (part.type) {\n case \"text\":\n return <TextPart key={index} part={part} {...extra} />;\n case \"reasoning\":\n return <ReasoningPart key={index} part={part} {...extra} />;\n case \"tool-invocation\":\n return (\n <ToolInvocationPart\n key={index}\n part={part}\n {...extra}\n message={message}\n copilotId={copilotId}\n />\n );\n default:\n return null;\n }\n })}\n </Component>\n );\n }\n);\n\nif (process.env.NODE_ENV !== \"production\") {\n AiMessageContent.displayName = AI_MESSAGE_CONTENT_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as AiMessage.*\nexport { AiMessageContent as Content };\n"],"names":["jsx","Markdown","ErrorBoundary","AiMessageToolInvocation","forwardRef","Slot","useMemo"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../../../src/primitives/AiMessage/index.tsx"],"sourcesContent":["import { Slot } from \"@radix-ui/react-slot\";\nimport { forwardRef, useMemo } from \"react\";\n\nimport { ErrorBoundary } from \"../../utils/ErrorBoundary\";\nimport { Markdown } from \"../Markdown\";\nimport { AiMessageToolInvocation } from \"./tool-invocation\";\nimport type {\n AiMessageContentComponents,\n AiMessageContentProps,\n} from \"./types\";\n\nconst AI_MESSAGE_CONTENT_NAME = \"AiMessageContent\";\n\nconst defaultMessageContentComponents: AiMessageContentComponents = {\n TextPart: ({ part }) => {\n return <Markdown content={part.text} />;\n },\n ReasoningPart: ({ part }) => {\n return <Markdown content={part.text} />;\n },\n ToolInvocationPart: ({ part, message }) => {\n return (\n <ErrorBoundary fallback={null}>\n <AiMessageToolInvocation part={part} message={message} />\n </ErrorBoundary>\n );\n },\n};\n\n/**\n * --------------------------------------------------------------------------\n * @private The API for this component is not yet stable.\n * --------------------------------------------------------------------------\n *\n * Primitive to help display an user or assistant message’s content, which is\n * an array of parts.\n *\n * @example\n * <AiMessage.Content message={message} components={{ TextPart }} />\n */\nconst AiMessageContent = forwardRef<HTMLDivElement, AiMessageContentProps>(\n ({ message, components, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"div\";\n const { TextPart, ReasoningPart, ToolInvocationPart } = useMemo(\n () => ({ ...defaultMessageContentComponents, ...components }),\n [components]\n );\n\n const content = message.content ?? message.contentSoFar;\n const numParts = content.length;\n const isGenerating =\n message.role === \"assistant\" && message.status === \"generating\";\n return (\n <Component {...props} ref={forwardedRef}>\n {content.map((part, index) => {\n // A part is considered to be still \"streaming in\" if it's the last\n // part in the content array, and the message is in \"generating\"\n // state.\n const isStreaming = isGenerating && index === numParts - 1;\n const extra = { index, isStreaming };\n switch (part.type) {\n case \"text\":\n return <TextPart key={index} part={part} {...extra} />;\n case \"reasoning\":\n return <ReasoningPart key={index} part={part} {...extra} />;\n case \"tool-invocation\":\n return (\n <ToolInvocationPart\n key={index}\n part={part}\n {...extra}\n message={message}\n />\n );\n default:\n return null;\n }\n })}\n </Component>\n );\n }\n);\n\nif (process.env.NODE_ENV !== \"production\") {\n AiMessageContent.displayName = AI_MESSAGE_CONTENT_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as AiMessage.*\nexport { AiMessageContent as Content };\n"],"names":["jsx","Markdown","ErrorBoundary","AiMessageToolInvocation","forwardRef","Slot","useMemo"],"mappings":";;;;;;;;;AAWA,MAAM,uBAA0B,GAAA,kBAAA,CAAA;AAEhC,MAAM,+BAA8D,GAAA;AAAA,EAClE,QAAU,EAAA,CAAC,EAAE,IAAA,EAAW,KAAA;AACtB,IAAA,uBAAQA,cAAA,CAAAC,iBAAA,EAAA;AAAA,MAAS,SAAS,IAAK,CAAA,IAAA;AAAA,KAAM,CAAA,CAAA;AAAA,GACvC;AAAA,EACA,aAAe,EAAA,CAAC,EAAE,IAAA,EAAW,KAAA;AAC3B,IAAA,uBAAQD,cAAA,CAAAC,iBAAA,EAAA;AAAA,MAAS,SAAS,IAAK,CAAA,IAAA;AAAA,KAAM,CAAA,CAAA;AAAA,GACvC;AAAA,EACA,kBAAoB,EAAA,CAAC,EAAE,IAAA,EAAM,SAAc,KAAA;AACzC,IAAA,uBACGD,cAAA,CAAAE,2BAAA,EAAA;AAAA,MAAc,QAAU,EAAA,IAAA;AAAA,MACvB,QAAC,kBAAAF,cAAA,CAAAG,sCAAA,EAAA;AAAA,QAAwB,IAAA;AAAA,QAAY,OAAA;AAAA,OAAkB,CAAA;AAAA,KACzD,CAAA,CAAA;AAAA,GAEJ;AACF,CAAA,CAAA;AAaA,MAAM,gBAAmB,GAAAC,gBAAA;AAAA,EACvB,CAAC,EAAE,OAAA,EAAS,YAAY,OAAY,EAAA,GAAA,KAAA,IAAS,YAAiB,KAAA;AAC5D,IAAM,MAAA,SAAA,GAAY,UAAUC,cAAO,GAAA,KAAA,CAAA;AACnC,IAAA,MAAM,EAAE,QAAA,EAAU,aAAe,EAAA,kBAAA,EAAuB,GAAAC,aAAA;AAAA,MACtD,OAAO,EAAE,GAAG,+BAAA,EAAiC,GAAG,UAAW,EAAA,CAAA;AAAA,MAC3D,CAAC,UAAU,CAAA;AAAA,KACb,CAAA;AAEA,IAAM,MAAA,OAAA,GAAU,OAAQ,CAAA,OAAA,IAAW,OAAQ,CAAA,YAAA,CAAA;AAC3C,IAAA,MAAM,WAAW,OAAQ,CAAA,MAAA,CAAA;AACzB,IAAA,MAAM,YACJ,GAAA,OAAA,CAAQ,IAAS,KAAA,WAAA,IAAe,QAAQ,MAAW,KAAA,YAAA,CAAA;AACrD,IAAA,uBACGN,cAAA,CAAA,SAAA,EAAA;AAAA,MAAW,GAAG,KAAA;AAAA,MAAO,GAAK,EAAA,YAAA;AAAA,MACxB,QAAQ,EAAA,OAAA,CAAA,GAAA,CAAI,CAAC,IAAA,EAAM,KAAU,KAAA;AAI5B,QAAM,MAAA,WAAA,GAAc,YAAgB,IAAA,KAAA,KAAU,QAAW,GAAA,CAAA,CAAA;AACzD,QAAM,MAAA,KAAA,GAAQ,EAAE,KAAA,EAAO,WAAY,EAAA,CAAA;AACnC,QAAA,QAAQ,KAAK,IAAM;AAAA,UACjB,KAAK,MAAA;AACH,YAAA,uBAAQA,cAAA,CAAA,QAAA,EAAA;AAAA,cAAqB,IAAA;AAAA,cAAa,GAAG,KAAA;AAAA,aAAA,EAAvB,KAA8B,CAAA,CAAA;AAAA,UACtD,KAAK,WAAA;AACH,YAAA,uBAAQA,cAAA,CAAA,aAAA,EAAA;AAAA,cAA0B,IAAA;AAAA,cAAa,GAAG,KAAA;AAAA,aAAA,EAAvB,KAA8B,CAAA,CAAA;AAAA,UAC3D,KAAK,iBAAA;AACH,YAAA,uBACGA,cAAA,CAAA,kBAAA,EAAA;AAAA,cAEC,IAAA;AAAA,cACC,GAAG,KAAA;AAAA,cACJ,OAAA;AAAA,aAAA,EAHK,KAIP,CAAA,CAAA;AAAA,UAEJ;AACE,YAAO,OAAA,IAAA,CAAA;AAAA,SACX;AAAA,OACD,CAAA;AAAA,KACH,CAAA,CAAA;AAAA,GAEJ;AACF,EAAA;AAEA,IAAI,OAAA,CAAQ,GAAI,CAAA,QAAA,KAAa,YAAc,EAAA;AACzC,EAAA,gBAAA,CAAiB,WAAc,GAAA,uBAAA,CAAA;AACjC;;;;"}
@@ -28,7 +28,7 @@ const defaultMessageContentComponents = {
28
28
  }
29
29
  };
30
30
  const AiMessageContent = forwardRef(
31
- ({ message, components, asChild, copilotId, ...props }, forwardedRef) => {
31
+ ({ message, components, asChild, ...props }, forwardedRef) => {
32
32
  const Component = asChild ? Slot : "div";
33
33
  const { TextPart, ReasoningPart, ToolInvocationPart } = useMemo(
34
34
  () => ({ ...defaultMessageContentComponents, ...components }),
@@ -58,8 +58,7 @@ const AiMessageContent = forwardRef(
58
58
  return /* @__PURE__ */ jsx(ToolInvocationPart, {
59
59
  part,
60
60
  ...extra,
61
- message,
62
- copilotId
61
+ message
63
62
  }, index);
64
63
  default:
65
64
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/primitives/AiMessage/index.tsx"],"sourcesContent":["import { Slot } from \"@radix-ui/react-slot\";\nimport { forwardRef, useMemo } from \"react\";\n\nimport { ErrorBoundary } from \"../../utils/ErrorBoundary\";\nimport { Markdown } from \"../Markdown\";\nimport { AiMessageToolInvocation } from \"./tool-invocation\";\nimport type {\n AiMessageContentComponents,\n AiMessageContentProps,\n} from \"./types\";\n\nconst AI_MESSAGE_CONTENT_NAME = \"AiMessageContent\";\n\nconst defaultMessageContentComponents: AiMessageContentComponents = {\n TextPart: ({ part }) => {\n return <Markdown content={part.text} />;\n },\n ReasoningPart: ({ part }) => {\n return <Markdown content={part.text} />;\n },\n ToolInvocationPart: ({ part, message }) => {\n return (\n <ErrorBoundary fallback={null}>\n <AiMessageToolInvocation part={part} message={message} />\n </ErrorBoundary>\n );\n },\n};\n\n/**\n * --------------------------------------------------------------------------\n * @private The API for this component is not yet stable.\n * --------------------------------------------------------------------------\n *\n * Primitive to help display an user or assistant message’s content, which is\n * an array of parts.\n *\n * @example\n * <AiMessage.Content message={message} components={{ TextPart }} />\n */\nconst AiMessageContent = forwardRef<HTMLDivElement, AiMessageContentProps>(\n ({ message, components, asChild, copilotId, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"div\";\n const { TextPart, ReasoningPart, ToolInvocationPart } = useMemo(\n () => ({ ...defaultMessageContentComponents, ...components }),\n [components]\n );\n\n const content = message.content ?? message.contentSoFar;\n const numParts = content.length;\n const isGenerating =\n message.role === \"assistant\" && message.status === \"generating\";\n return (\n <Component {...props} ref={forwardedRef}>\n {content.map((part, index) => {\n // A part is considered to be still \"streaming in\" if it's the last\n // part in the content array, and the message is in \"generating\"\n // state.\n const isStreaming = isGenerating && index === numParts - 1;\n const extra = { index, isStreaming };\n switch (part.type) {\n case \"text\":\n return <TextPart key={index} part={part} {...extra} />;\n case \"reasoning\":\n return <ReasoningPart key={index} part={part} {...extra} />;\n case \"tool-invocation\":\n return (\n <ToolInvocationPart\n key={index}\n part={part}\n {...extra}\n message={message}\n copilotId={copilotId}\n />\n );\n default:\n return null;\n }\n })}\n </Component>\n );\n }\n);\n\nif (process.env.NODE_ENV !== \"production\") {\n AiMessageContent.displayName = AI_MESSAGE_CONTENT_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as AiMessage.*\nexport { AiMessageContent as Content };\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/primitives/AiMessage/index.tsx"],"sourcesContent":["import { Slot } from \"@radix-ui/react-slot\";\nimport { forwardRef, useMemo } from \"react\";\n\nimport { ErrorBoundary } from \"../../utils/ErrorBoundary\";\nimport { Markdown } from \"../Markdown\";\nimport { AiMessageToolInvocation } from \"./tool-invocation\";\nimport type {\n AiMessageContentComponents,\n AiMessageContentProps,\n} from \"./types\";\n\nconst AI_MESSAGE_CONTENT_NAME = \"AiMessageContent\";\n\nconst defaultMessageContentComponents: AiMessageContentComponents = {\n TextPart: ({ part }) => {\n return <Markdown content={part.text} />;\n },\n ReasoningPart: ({ part }) => {\n return <Markdown content={part.text} />;\n },\n ToolInvocationPart: ({ part, message }) => {\n return (\n <ErrorBoundary fallback={null}>\n <AiMessageToolInvocation part={part} message={message} />\n </ErrorBoundary>\n );\n },\n};\n\n/**\n * --------------------------------------------------------------------------\n * @private The API for this component is not yet stable.\n * --------------------------------------------------------------------------\n *\n * Primitive to help display an user or assistant message’s content, which is\n * an array of parts.\n *\n * @example\n * <AiMessage.Content message={message} components={{ TextPart }} />\n */\nconst AiMessageContent = forwardRef<HTMLDivElement, AiMessageContentProps>(\n ({ message, components, asChild, ...props }, forwardedRef) => {\n const Component = asChild ? Slot : \"div\";\n const { TextPart, ReasoningPart, ToolInvocationPart } = useMemo(\n () => ({ ...defaultMessageContentComponents, ...components }),\n [components]\n );\n\n const content = message.content ?? message.contentSoFar;\n const numParts = content.length;\n const isGenerating =\n message.role === \"assistant\" && message.status === \"generating\";\n return (\n <Component {...props} ref={forwardedRef}>\n {content.map((part, index) => {\n // A part is considered to be still \"streaming in\" if it's the last\n // part in the content array, and the message is in \"generating\"\n // state.\n const isStreaming = isGenerating && index === numParts - 1;\n const extra = { index, isStreaming };\n switch (part.type) {\n case \"text\":\n return <TextPart key={index} part={part} {...extra} />;\n case \"reasoning\":\n return <ReasoningPart key={index} part={part} {...extra} />;\n case \"tool-invocation\":\n return (\n <ToolInvocationPart\n key={index}\n part={part}\n {...extra}\n message={message}\n />\n );\n default:\n return null;\n }\n })}\n </Component>\n );\n }\n);\n\nif (process.env.NODE_ENV !== \"production\") {\n AiMessageContent.displayName = AI_MESSAGE_CONTENT_NAME;\n}\n\n// NOTE: Every export from this file will be available publicly as AiMessage.*\nexport { AiMessageContent as Content };\n"],"names":[],"mappings":";;;;;;;AAWA,MAAM,uBAA0B,GAAA,kBAAA,CAAA;AAEhC,MAAM,+BAA8D,GAAA;AAAA,EAClE,QAAU,EAAA,CAAC,EAAE,IAAA,EAAW,KAAA;AACtB,IAAA,uBAAQ,GAAA,CAAA,QAAA,EAAA;AAAA,MAAS,SAAS,IAAK,CAAA,IAAA;AAAA,KAAM,CAAA,CAAA;AAAA,GACvC;AAAA,EACA,aAAe,EAAA,CAAC,EAAE,IAAA,EAAW,KAAA;AAC3B,IAAA,uBAAQ,GAAA,CAAA,QAAA,EAAA;AAAA,MAAS,SAAS,IAAK,CAAA,IAAA;AAAA,KAAM,CAAA,CAAA;AAAA,GACvC;AAAA,EACA,kBAAoB,EAAA,CAAC,EAAE,IAAA,EAAM,SAAc,KAAA;AACzC,IAAA,uBACG,GAAA,CAAA,aAAA,EAAA;AAAA,MAAc,QAAU,EAAA,IAAA;AAAA,MACvB,QAAC,kBAAA,GAAA,CAAA,uBAAA,EAAA;AAAA,QAAwB,IAAA;AAAA,QAAY,OAAA;AAAA,OAAkB,CAAA;AAAA,KACzD,CAAA,CAAA;AAAA,GAEJ;AACF,CAAA,CAAA;AAaA,MAAM,gBAAmB,GAAA,UAAA;AAAA,EACvB,CAAC,EAAE,OAAA,EAAS,YAAY,OAAY,EAAA,GAAA,KAAA,IAAS,YAAiB,KAAA;AAC5D,IAAM,MAAA,SAAA,GAAY,UAAU,IAAO,GAAA,KAAA,CAAA;AACnC,IAAA,MAAM,EAAE,QAAA,EAAU,aAAe,EAAA,kBAAA,EAAuB,GAAA,OAAA;AAAA,MACtD,OAAO,EAAE,GAAG,+BAAA,EAAiC,GAAG,UAAW,EAAA,CAAA;AAAA,MAC3D,CAAC,UAAU,CAAA;AAAA,KACb,CAAA;AAEA,IAAM,MAAA,OAAA,GAAU,OAAQ,CAAA,OAAA,IAAW,OAAQ,CAAA,YAAA,CAAA;AAC3C,IAAA,MAAM,WAAW,OAAQ,CAAA,MAAA,CAAA;AACzB,IAAA,MAAM,YACJ,GAAA,OAAA,CAAQ,IAAS,KAAA,WAAA,IAAe,QAAQ,MAAW,KAAA,YAAA,CAAA;AACrD,IAAA,uBACG,GAAA,CAAA,SAAA,EAAA;AAAA,MAAW,GAAG,KAAA;AAAA,MAAO,GAAK,EAAA,YAAA;AAAA,MACxB,QAAQ,EAAA,OAAA,CAAA,GAAA,CAAI,CAAC,IAAA,EAAM,KAAU,KAAA;AAI5B,QAAM,MAAA,WAAA,GAAc,YAAgB,IAAA,KAAA,KAAU,QAAW,GAAA,CAAA,CAAA;AACzD,QAAM,MAAA,KAAA,GAAQ,EAAE,KAAA,EAAO,WAAY,EAAA,CAAA;AACnC,QAAA,QAAQ,KAAK,IAAM;AAAA,UACjB,KAAK,MAAA;AACH,YAAA,uBAAQ,GAAA,CAAA,QAAA,EAAA;AAAA,cAAqB,IAAA;AAAA,cAAa,GAAG,KAAA;AAAA,aAAA,EAAvB,KAA8B,CAAA,CAAA;AAAA,UACtD,KAAK,WAAA;AACH,YAAA,uBAAQ,GAAA,CAAA,aAAA,EAAA;AAAA,cAA0B,IAAA;AAAA,cAAa,GAAG,KAAA;AAAA,aAAA,EAAvB,KAA8B,CAAA,CAAA;AAAA,UAC3D,KAAK,iBAAA;AACH,YAAA,uBACG,GAAA,CAAA,kBAAA,EAAA;AAAA,cAEC,IAAA;AAAA,cACC,GAAG,KAAA;AAAA,cACJ,OAAA;AAAA,aAAA,EAHK,KAIP,CAAA,CAAA;AAAA,UAEJ;AACE,YAAO,OAAA,IAAA,CAAA;AAAA,SACX;AAAA,OACD,CAAA;AAAA,KACH,CAAA,CAAA;AAAA,GAEJ;AACF,EAAA;AAEA,IAAI,OAAA,CAAQ,GAAI,CAAA,QAAA,KAAa,YAAc,EAAA;AACzC,EAAA,gBAAA,CAAiB,WAAc,GAAA,uBAAA,CAAA;AACjC;;;;"}
@@ -12,8 +12,7 @@ function StableRenderFn(props) {
12
12
  }
13
13
  function AiMessageToolInvocation({
14
14
  message,
15
- part,
16
- copilotId
15
+ part
17
16
  }) {
18
17
  const client = react.useClient();
19
18
  const ai = client[core.kInternal].ai;
@@ -32,7 +31,7 @@ function AiMessageToolInvocation({
32
31
  message.id,
33
32
  part.invocationId,
34
33
  result ?? { data: {} },
35
- { copilotId }
34
+ { copilotId: message.copilotId }
36
35
  );
37
36
  }
38
37
  },
@@ -44,7 +43,7 @@ function AiMessageToolInvocation({
44
43
  part.invocationId,
45
44
  part.name,
46
45
  part.stage,
47
- copilotId
46
+ message.copilotId
48
47
  ]
49
48
  );
50
49
  const partialArgs = part?.partialArgs;
@@ -1 +1 @@
1
- {"version":3,"file":"tool-invocation.cjs","sources":["../../../src/primitives/AiMessage/tool-invocation.tsx"],"sourcesContent":["import type {\n AiChatMessage,\n AiToolInvocationPart,\n AiToolInvocationProps,\n CopilotId,\n JsonObject,\n ToolResultResponse,\n} from \"@liveblocks/core\";\nimport { kInternal } from \"@liveblocks/core\";\nimport { useClient } from \"@liveblocks/react\";\nimport { useSignal } from \"@liveblocks/react/_private\";\nimport { type FunctionComponent, useCallback, useMemo } from \"react\";\n\nimport { AiToolInvocationContext } from \"./contexts\";\n\ntype OpaqueAiToolInvocationProps = AiToolInvocationProps<\n JsonObject,\n JsonObject\n>;\n\nfunction StableRenderFn(props: {\n renderFn: FunctionComponent<OpaqueAiToolInvocationProps>;\n props: OpaqueAiToolInvocationProps;\n}) {\n return props.renderFn(props.props);\n}\n\n/**\n * @internal\n *\n * This could become publicly exposed as <AiMessage.ToolInvocation /> in the future,\n * but because namespace exports can't be marked `@internal`, we're keeping it in its\n * own file for now.\n */\nexport function AiMessageToolInvocation({\n message,\n part,\n copilotId,\n}: {\n message: AiChatMessage;\n part: AiToolInvocationPart;\n copilotId?: string;\n}) {\n const client = useClient();\n const ai = client[kInternal].ai;\n const tool = useSignal(ai.signals.getToolΣ(part.name, message.chatId));\n\n const respond = useCallback(\n (result: ToolResultResponse | undefined) => {\n if (message.status !== \"awaiting-tool\") {\n // console.log(\"Ignoring respond(): message not awaiting tool result\");\n } else if (part.stage === \"receiving\") {\n // console.log(\n // `Ignoring respond(): tool '${part.name}' (${part.invocationId}) is still receiving`\n // );\n } else if (part.stage === \"executed\") {\n console.log(\n `Ignoring respond(): tool '${part.name}' (${part.invocationId}) has already executed`\n );\n } else {\n ai.setToolResult(\n message.chatId,\n message.id,\n part.invocationId,\n result ?? { data: {} },\n { copilotId: copilotId as CopilotId }\n );\n }\n },\n [\n ai,\n message.chatId,\n message.id,\n message.status,\n part.invocationId,\n part.name,\n part.stage,\n copilotId,\n ]\n );\n\n const partialArgs = part?.partialArgs;\n const props = useMemo(() => {\n // NOTE: Not really used, but necessary to trick useMemo into re-evaluating\n // when it changes. Without this trick, tool call streaming won't\n // re-render. The reason this is needed is that `part` gets mutated\n // in-place by the delta handling, rather than part being replaced by a new\n // object on every chunk.\n partialArgs;\n\n const { type: _, ...rest } = part;\n return {\n ...rest,\n respond,\n types: undefined as never,\n [kInternal]: {\n execute: tool?.execute,\n messageStatus: message.status,\n },\n };\n }, [part, respond, tool?.execute, message.status, partialArgs]);\n\n if (tool?.render === undefined) return null;\n return (\n <AiToolInvocationContext.Provider value={props}>\n <StableRenderFn\n renderFn={tool.render as FunctionComponent<OpaqueAiToolInvocationProps>}\n props={props}\n />\n </AiToolInvocationContext.Provider>\n );\n}\n"],"names":["useClient","kInternal","useSignal","useCallback","useMemo","jsx","AiToolInvocationContext"],"mappings":";;;;;;;;;AAoBA,SAAS,eAAe,KAGrB,EAAA;AACD,EAAO,OAAA,KAAA,CAAM,QAAS,CAAA,KAAA,CAAM,KAAK,CAAA,CAAA;AACnC,CAAA;AASO,SAAS,uBAAwB,CAAA;AAAA,EACtC,OAAA;AAAA,EACA,IAAA;AAAA,EACA,SAAA;AACF,CAIG,EAAA;AACD,EAAA,MAAM,SAASA,eAAU,EAAA,CAAA;AACzB,EAAM,MAAA,EAAA,GAAK,OAAOC,cAAW,CAAA,CAAA,EAAA,CAAA;AAC7B,EAAM,MAAA,IAAA,GAAOC,mBAAU,EAAG,CAAA,OAAA,CAAQ,cAAS,IAAK,CAAA,IAAA,EAAM,OAAQ,CAAA,MAAM,CAAC,CAAA,CAAA;AAErE,EAAA,MAAM,OAAU,GAAAC,mBAAA;AAAA,IACd,CAAC,MAA2C,KAAA;AAC1C,MAAI,IAAA,OAAA,CAAQ,WAAW,eAAiB,EAAA;AAAA,OAExC,MAAA,IAAW,IAAK,CAAA,KAAA,KAAU,WAAa,EAAA;AAAA,OAIvC,MAAA,IAAW,IAAK,CAAA,KAAA,KAAU,UAAY,EAAA;AACpC,QAAQ,OAAA,CAAA,GAAA;AAAA,UACN,CAAA,0BAAA,EAA6B,IAAK,CAAA,IAAA,CAAA,GAAA,EAAU,IAAK,CAAA,YAAA,CAAA,sBAAA,CAAA;AAAA,SACnD,CAAA;AAAA,OACK,MAAA;AACL,QAAG,EAAA,CAAA,aAAA;AAAA,UACD,OAAQ,CAAA,MAAA;AAAA,UACR,OAAQ,CAAA,EAAA;AAAA,UACR,IAAK,CAAA,YAAA;AAAA,UACL,MAAU,IAAA,EAAE,IAAM,EAAA,EAAG,EAAA;AAAA,UACrB,EAAE,SAAkC,EAAA;AAAA,SACtC,CAAA;AAAA,OACF;AAAA,KACF;AAAA,IACA;AAAA,MACE,EAAA;AAAA,MACA,OAAQ,CAAA,MAAA;AAAA,MACR,OAAQ,CAAA,EAAA;AAAA,MACR,OAAQ,CAAA,MAAA;AAAA,MACR,IAAK,CAAA,YAAA;AAAA,MACL,IAAK,CAAA,IAAA;AAAA,MACL,IAAK,CAAA,KAAA;AAAA,MACL,SAAA;AAAA,KACF;AAAA,GACF,CAAA;AAEA,EAAA,MAAM,cAAc,IAAM,EAAA,WAAA,CAAA;AAC1B,EAAM,MAAA,KAAA,GAAQC,gBAAQ,MAAM;AAM1B,IAAA,WAAA,CAAA;AAEA,IAAA,MAAM,EAAE,IAAA,EAAM,CAAM,EAAA,GAAA,IAAA,EAAS,GAAA,IAAA,CAAA;AAC7B,IAAO,OAAA;AAAA,MACL,GAAG,IAAA;AAAA,MACH,OAAA;AAAA,MACA,KAAO,EAAA,KAAA,CAAA;AAAA,MACP,CAACH,cAAY,GAAA;AAAA,QACX,SAAS,IAAM,EAAA,OAAA;AAAA,QACf,eAAe,OAAQ,CAAA,MAAA;AAAA,OACzB;AAAA,KACF,CAAA;AAAA,GACF,EAAG,CAAC,IAAM,EAAA,OAAA,EAAS,MAAM,OAAS,EAAA,OAAA,CAAQ,MAAQ,EAAA,WAAW,CAAC,CAAA,CAAA;AAE9D,EAAA,IAAI,MAAM,MAAW,KAAA,KAAA,CAAA;AAAW,IAAO,OAAA,IAAA,CAAA;AACvC,EACE,uBAAAI,cAAA,CAACC,iCAAwB,QAAxB,EAAA;AAAA,IAAiC,KAAO,EAAA,KAAA;AAAA,IACvC,QAAC,kBAAAD,cAAA,CAAA,cAAA,EAAA;AAAA,MACC,UAAU,IAAK,CAAA,MAAA;AAAA,MACf,KAAA;AAAA,KACF,CAAA;AAAA,GACF,CAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"tool-invocation.cjs","sources":["../../../src/primitives/AiMessage/tool-invocation.tsx"],"sourcesContent":["import type {\n AiChatMessage,\n AiToolInvocationPart,\n AiToolInvocationProps,\n JsonObject,\n ToolResultResponse,\n} from \"@liveblocks/core\";\nimport { kInternal } from \"@liveblocks/core\";\nimport { useClient } from \"@liveblocks/react\";\nimport { useSignal } from \"@liveblocks/react/_private\";\nimport { type FunctionComponent, useCallback, useMemo } from \"react\";\n\nimport { AiToolInvocationContext } from \"./contexts\";\n\ntype OpaqueAiToolInvocationProps = AiToolInvocationProps<\n JsonObject,\n JsonObject\n>;\n\nfunction StableRenderFn(props: {\n renderFn: FunctionComponent<OpaqueAiToolInvocationProps>;\n props: OpaqueAiToolInvocationProps;\n}) {\n return props.renderFn(props.props);\n}\n\n/**\n * @internal\n *\n * This could become publicly exposed as <AiMessage.ToolInvocation /> in the future,\n * but because namespace exports can't be marked `@internal`, we're keeping it in its\n * own file for now.\n */\nexport function AiMessageToolInvocation({\n message,\n part,\n}: {\n message: AiChatMessage;\n part: AiToolInvocationPart;\n}) {\n const client = useClient();\n const ai = client[kInternal].ai;\n const tool = useSignal(ai.signals.getToolΣ(part.name, message.chatId));\n\n const respond = useCallback(\n (result: ToolResultResponse | undefined) => {\n if (message.status !== \"awaiting-tool\") {\n // console.log(\"Ignoring respond(): message not awaiting tool result\");\n } else if (part.stage === \"receiving\") {\n // console.log(\n // `Ignoring respond(): tool '${part.name}' (${part.invocationId}) is still receiving`\n // );\n } else if (part.stage === \"executed\") {\n console.log(\n `Ignoring respond(): tool '${part.name}' (${part.invocationId}) has already executed`\n );\n } else {\n ai.setToolResult(\n message.chatId,\n message.id,\n part.invocationId,\n result ?? { data: {} },\n { copilotId: message.copilotId }\n );\n }\n },\n [\n ai,\n message.chatId,\n message.id,\n message.status,\n part.invocationId,\n part.name,\n part.stage,\n message.copilotId,\n ]\n );\n\n const partialArgs = part?.partialArgs;\n const props = useMemo(() => {\n // NOTE: Not really used, but necessary to trick useMemo into re-evaluating\n // when it changes. Without this trick, tool call streaming won't\n // re-render. The reason this is needed is that `part` gets mutated\n // in-place by the delta handling, rather than part being replaced by a new\n // object on every chunk.\n partialArgs;\n\n const { type: _, ...rest } = part;\n return {\n ...rest,\n respond,\n types: undefined as never,\n [kInternal]: {\n execute: tool?.execute,\n messageStatus: message.status,\n },\n };\n }, [part, respond, tool?.execute, message.status, partialArgs]);\n\n if (tool?.render === undefined) return null;\n return (\n <AiToolInvocationContext.Provider value={props}>\n <StableRenderFn\n renderFn={tool.render as FunctionComponent<OpaqueAiToolInvocationProps>}\n props={props}\n />\n </AiToolInvocationContext.Provider>\n );\n}\n"],"names":["useClient","kInternal","useSignal","useCallback","useMemo","jsx","AiToolInvocationContext"],"mappings":";;;;;;;;;AAmBA,SAAS,eAAe,KAGrB,EAAA;AACD,EAAO,OAAA,KAAA,CAAM,QAAS,CAAA,KAAA,CAAM,KAAK,CAAA,CAAA;AACnC,CAAA;AASO,SAAS,uBAAwB,CAAA;AAAA,EACtC,OAAA;AAAA,EACA,IAAA;AACF,CAGG,EAAA;AACD,EAAA,MAAM,SAASA,eAAU,EAAA,CAAA;AACzB,EAAM,MAAA,EAAA,GAAK,OAAOC,cAAW,CAAA,CAAA,EAAA,CAAA;AAC7B,EAAM,MAAA,IAAA,GAAOC,mBAAU,EAAG,CAAA,OAAA,CAAQ,cAAS,IAAK,CAAA,IAAA,EAAM,OAAQ,CAAA,MAAM,CAAC,CAAA,CAAA;AAErE,EAAA,MAAM,OAAU,GAAAC,mBAAA;AAAA,IACd,CAAC,MAA2C,KAAA;AAC1C,MAAI,IAAA,OAAA,CAAQ,WAAW,eAAiB,EAAA;AAAA,OAExC,MAAA,IAAW,IAAK,CAAA,KAAA,KAAU,WAAa,EAAA;AAAA,OAIvC,MAAA,IAAW,IAAK,CAAA,KAAA,KAAU,UAAY,EAAA;AACpC,QAAQ,OAAA,CAAA,GAAA;AAAA,UACN,CAAA,0BAAA,EAA6B,IAAK,CAAA,IAAA,CAAA,GAAA,EAAU,IAAK,CAAA,YAAA,CAAA,sBAAA,CAAA;AAAA,SACnD,CAAA;AAAA,OACK,MAAA;AACL,QAAG,EAAA,CAAA,aAAA;AAAA,UACD,OAAQ,CAAA,MAAA;AAAA,UACR,OAAQ,CAAA,EAAA;AAAA,UACR,IAAK,CAAA,YAAA;AAAA,UACL,MAAU,IAAA,EAAE,IAAM,EAAA,EAAG,EAAA;AAAA,UACrB,EAAE,SAAW,EAAA,OAAA,CAAQ,SAAU,EAAA;AAAA,SACjC,CAAA;AAAA,OACF;AAAA,KACF;AAAA,IACA;AAAA,MACE,EAAA;AAAA,MACA,OAAQ,CAAA,MAAA;AAAA,MACR,OAAQ,CAAA,EAAA;AAAA,MACR,OAAQ,CAAA,MAAA;AAAA,MACR,IAAK,CAAA,YAAA;AAAA,MACL,IAAK,CAAA,IAAA;AAAA,MACL,IAAK,CAAA,KAAA;AAAA,MACL,OAAQ,CAAA,SAAA;AAAA,KACV;AAAA,GACF,CAAA;AAEA,EAAA,MAAM,cAAc,IAAM,EAAA,WAAA,CAAA;AAC1B,EAAM,MAAA,KAAA,GAAQC,gBAAQ,MAAM;AAM1B,IAAA,WAAA,CAAA;AAEA,IAAA,MAAM,EAAE,IAAA,EAAM,CAAM,EAAA,GAAA,IAAA,EAAS,GAAA,IAAA,CAAA;AAC7B,IAAO,OAAA;AAAA,MACL,GAAG,IAAA;AAAA,MACH,OAAA;AAAA,MACA,KAAO,EAAA,KAAA,CAAA;AAAA,MACP,CAACH,cAAY,GAAA;AAAA,QACX,SAAS,IAAM,EAAA,OAAA;AAAA,QACf,eAAe,OAAQ,CAAA,MAAA;AAAA,OACzB;AAAA,KACF,CAAA;AAAA,GACF,EAAG,CAAC,IAAM,EAAA,OAAA,EAAS,MAAM,OAAS,EAAA,OAAA,CAAQ,MAAQ,EAAA,WAAW,CAAC,CAAA,CAAA;AAE9D,EAAA,IAAI,MAAM,MAAW,KAAA,KAAA,CAAA;AAAW,IAAO,OAAA,IAAA,CAAA;AACvC,EACE,uBAAAI,cAAA,CAACC,iCAAwB,QAAxB,EAAA;AAAA,IAAiC,KAAO,EAAA,KAAA;AAAA,IACvC,QAAC,kBAAAD,cAAA,CAAA,cAAA,EAAA;AAAA,MACC,UAAU,IAAK,CAAA,MAAA;AAAA,MACf,KAAA;AAAA,KACF,CAAA;AAAA,GACF,CAAA,CAAA;AAEJ;;;;"}
@@ -10,8 +10,7 @@ function StableRenderFn(props) {
10
10
  }
11
11
  function AiMessageToolInvocation({
12
12
  message,
13
- part,
14
- copilotId
13
+ part
15
14
  }) {
16
15
  const client = useClient();
17
16
  const ai = client[kInternal].ai;
@@ -30,7 +29,7 @@ function AiMessageToolInvocation({
30
29
  message.id,
31
30
  part.invocationId,
32
31
  result ?? { data: {} },
33
- { copilotId }
32
+ { copilotId: message.copilotId }
34
33
  );
35
34
  }
36
35
  },
@@ -42,7 +41,7 @@ function AiMessageToolInvocation({
42
41
  part.invocationId,
43
42
  part.name,
44
43
  part.stage,
45
- copilotId
44
+ message.copilotId
46
45
  ]
47
46
  );
48
47
  const partialArgs = part?.partialArgs;
@@ -1 +1 @@
1
- {"version":3,"file":"tool-invocation.js","sources":["../../../src/primitives/AiMessage/tool-invocation.tsx"],"sourcesContent":["import type {\n AiChatMessage,\n AiToolInvocationPart,\n AiToolInvocationProps,\n CopilotId,\n JsonObject,\n ToolResultResponse,\n} from \"@liveblocks/core\";\nimport { kInternal } from \"@liveblocks/core\";\nimport { useClient } from \"@liveblocks/react\";\nimport { useSignal } from \"@liveblocks/react/_private\";\nimport { type FunctionComponent, useCallback, useMemo } from \"react\";\n\nimport { AiToolInvocationContext } from \"./contexts\";\n\ntype OpaqueAiToolInvocationProps = AiToolInvocationProps<\n JsonObject,\n JsonObject\n>;\n\nfunction StableRenderFn(props: {\n renderFn: FunctionComponent<OpaqueAiToolInvocationProps>;\n props: OpaqueAiToolInvocationProps;\n}) {\n return props.renderFn(props.props);\n}\n\n/**\n * @internal\n *\n * This could become publicly exposed as <AiMessage.ToolInvocation /> in the future,\n * but because namespace exports can't be marked `@internal`, we're keeping it in its\n * own file for now.\n */\nexport function AiMessageToolInvocation({\n message,\n part,\n copilotId,\n}: {\n message: AiChatMessage;\n part: AiToolInvocationPart;\n copilotId?: string;\n}) {\n const client = useClient();\n const ai = client[kInternal].ai;\n const tool = useSignal(ai.signals.getToolΣ(part.name, message.chatId));\n\n const respond = useCallback(\n (result: ToolResultResponse | undefined) => {\n if (message.status !== \"awaiting-tool\") {\n // console.log(\"Ignoring respond(): message not awaiting tool result\");\n } else if (part.stage === \"receiving\") {\n // console.log(\n // `Ignoring respond(): tool '${part.name}' (${part.invocationId}) is still receiving`\n // );\n } else if (part.stage === \"executed\") {\n console.log(\n `Ignoring respond(): tool '${part.name}' (${part.invocationId}) has already executed`\n );\n } else {\n ai.setToolResult(\n message.chatId,\n message.id,\n part.invocationId,\n result ?? { data: {} },\n { copilotId: copilotId as CopilotId }\n );\n }\n },\n [\n ai,\n message.chatId,\n message.id,\n message.status,\n part.invocationId,\n part.name,\n part.stage,\n copilotId,\n ]\n );\n\n const partialArgs = part?.partialArgs;\n const props = useMemo(() => {\n // NOTE: Not really used, but necessary to trick useMemo into re-evaluating\n // when it changes. Without this trick, tool call streaming won't\n // re-render. The reason this is needed is that `part` gets mutated\n // in-place by the delta handling, rather than part being replaced by a new\n // object on every chunk.\n partialArgs;\n\n const { type: _, ...rest } = part;\n return {\n ...rest,\n respond,\n types: undefined as never,\n [kInternal]: {\n execute: tool?.execute,\n messageStatus: message.status,\n },\n };\n }, [part, respond, tool?.execute, message.status, partialArgs]);\n\n if (tool?.render === undefined) return null;\n return (\n <AiToolInvocationContext.Provider value={props}>\n <StableRenderFn\n renderFn={tool.render as FunctionComponent<OpaqueAiToolInvocationProps>}\n props={props}\n />\n </AiToolInvocationContext.Provider>\n );\n}\n"],"names":[],"mappings":";;;;;;;AAoBA,SAAS,eAAe,KAGrB,EAAA;AACD,EAAO,OAAA,KAAA,CAAM,QAAS,CAAA,KAAA,CAAM,KAAK,CAAA,CAAA;AACnC,CAAA;AASO,SAAS,uBAAwB,CAAA;AAAA,EACtC,OAAA;AAAA,EACA,IAAA;AAAA,EACA,SAAA;AACF,CAIG,EAAA;AACD,EAAA,MAAM,SAAS,SAAU,EAAA,CAAA;AACzB,EAAM,MAAA,EAAA,GAAK,OAAO,SAAW,CAAA,CAAA,EAAA,CAAA;AAC7B,EAAM,MAAA,IAAA,GAAO,UAAU,EAAG,CAAA,OAAA,CAAQ,cAAS,IAAK,CAAA,IAAA,EAAM,OAAQ,CAAA,MAAM,CAAC,CAAA,CAAA;AAErE,EAAA,MAAM,OAAU,GAAA,WAAA;AAAA,IACd,CAAC,MAA2C,KAAA;AAC1C,MAAI,IAAA,OAAA,CAAQ,WAAW,eAAiB,EAAA;AAAA,OAExC,MAAA,IAAW,IAAK,CAAA,KAAA,KAAU,WAAa,EAAA;AAAA,OAIvC,MAAA,IAAW,IAAK,CAAA,KAAA,KAAU,UAAY,EAAA;AACpC,QAAQ,OAAA,CAAA,GAAA;AAAA,UACN,CAAA,0BAAA,EAA6B,IAAK,CAAA,IAAA,CAAA,GAAA,EAAU,IAAK,CAAA,YAAA,CAAA,sBAAA,CAAA;AAAA,SACnD,CAAA;AAAA,OACK,MAAA;AACL,QAAG,EAAA,CAAA,aAAA;AAAA,UACD,OAAQ,CAAA,MAAA;AAAA,UACR,OAAQ,CAAA,EAAA;AAAA,UACR,IAAK,CAAA,YAAA;AAAA,UACL,MAAU,IAAA,EAAE,IAAM,EAAA,EAAG,EAAA;AAAA,UACrB,EAAE,SAAkC,EAAA;AAAA,SACtC,CAAA;AAAA,OACF;AAAA,KACF;AAAA,IACA;AAAA,MACE,EAAA;AAAA,MACA,OAAQ,CAAA,MAAA;AAAA,MACR,OAAQ,CAAA,EAAA;AAAA,MACR,OAAQ,CAAA,MAAA;AAAA,MACR,IAAK,CAAA,YAAA;AAAA,MACL,IAAK,CAAA,IAAA;AAAA,MACL,IAAK,CAAA,KAAA;AAAA,MACL,SAAA;AAAA,KACF;AAAA,GACF,CAAA;AAEA,EAAA,MAAM,cAAc,IAAM,EAAA,WAAA,CAAA;AAC1B,EAAM,MAAA,KAAA,GAAQ,QAAQ,MAAM;AAM1B,IAAA,WAAA,CAAA;AAEA,IAAA,MAAM,EAAE,IAAA,EAAM,CAAM,EAAA,GAAA,IAAA,EAAS,GAAA,IAAA,CAAA;AAC7B,IAAO,OAAA;AAAA,MACL,GAAG,IAAA;AAAA,MACH,OAAA;AAAA,MACA,KAAO,EAAA,KAAA,CAAA;AAAA,MACP,CAAC,SAAY,GAAA;AAAA,QACX,SAAS,IAAM,EAAA,OAAA;AAAA,QACf,eAAe,OAAQ,CAAA,MAAA;AAAA,OACzB;AAAA,KACF,CAAA;AAAA,GACF,EAAG,CAAC,IAAM,EAAA,OAAA,EAAS,MAAM,OAAS,EAAA,OAAA,CAAQ,MAAQ,EAAA,WAAW,CAAC,CAAA,CAAA;AAE9D,EAAA,IAAI,MAAM,MAAW,KAAA,KAAA,CAAA;AAAW,IAAO,OAAA,IAAA,CAAA;AACvC,EACE,uBAAA,GAAA,CAAC,wBAAwB,QAAxB,EAAA;AAAA,IAAiC,KAAO,EAAA,KAAA;AAAA,IACvC,QAAC,kBAAA,GAAA,CAAA,cAAA,EAAA;AAAA,MACC,UAAU,IAAK,CAAA,MAAA;AAAA,MACf,KAAA;AAAA,KACF,CAAA;AAAA,GACF,CAAA,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"tool-invocation.js","sources":["../../../src/primitives/AiMessage/tool-invocation.tsx"],"sourcesContent":["import type {\n AiChatMessage,\n AiToolInvocationPart,\n AiToolInvocationProps,\n JsonObject,\n ToolResultResponse,\n} from \"@liveblocks/core\";\nimport { kInternal } from \"@liveblocks/core\";\nimport { useClient } from \"@liveblocks/react\";\nimport { useSignal } from \"@liveblocks/react/_private\";\nimport { type FunctionComponent, useCallback, useMemo } from \"react\";\n\nimport { AiToolInvocationContext } from \"./contexts\";\n\ntype OpaqueAiToolInvocationProps = AiToolInvocationProps<\n JsonObject,\n JsonObject\n>;\n\nfunction StableRenderFn(props: {\n renderFn: FunctionComponent<OpaqueAiToolInvocationProps>;\n props: OpaqueAiToolInvocationProps;\n}) {\n return props.renderFn(props.props);\n}\n\n/**\n * @internal\n *\n * This could become publicly exposed as <AiMessage.ToolInvocation /> in the future,\n * but because namespace exports can't be marked `@internal`, we're keeping it in its\n * own file for now.\n */\nexport function AiMessageToolInvocation({\n message,\n part,\n}: {\n message: AiChatMessage;\n part: AiToolInvocationPart;\n}) {\n const client = useClient();\n const ai = client[kInternal].ai;\n const tool = useSignal(ai.signals.getToolΣ(part.name, message.chatId));\n\n const respond = useCallback(\n (result: ToolResultResponse | undefined) => {\n if (message.status !== \"awaiting-tool\") {\n // console.log(\"Ignoring respond(): message not awaiting tool result\");\n } else if (part.stage === \"receiving\") {\n // console.log(\n // `Ignoring respond(): tool '${part.name}' (${part.invocationId}) is still receiving`\n // );\n } else if (part.stage === \"executed\") {\n console.log(\n `Ignoring respond(): tool '${part.name}' (${part.invocationId}) has already executed`\n );\n } else {\n ai.setToolResult(\n message.chatId,\n message.id,\n part.invocationId,\n result ?? { data: {} },\n { copilotId: message.copilotId }\n );\n }\n },\n [\n ai,\n message.chatId,\n message.id,\n message.status,\n part.invocationId,\n part.name,\n part.stage,\n message.copilotId,\n ]\n );\n\n const partialArgs = part?.partialArgs;\n const props = useMemo(() => {\n // NOTE: Not really used, but necessary to trick useMemo into re-evaluating\n // when it changes. Without this trick, tool call streaming won't\n // re-render. The reason this is needed is that `part` gets mutated\n // in-place by the delta handling, rather than part being replaced by a new\n // object on every chunk.\n partialArgs;\n\n const { type: _, ...rest } = part;\n return {\n ...rest,\n respond,\n types: undefined as never,\n [kInternal]: {\n execute: tool?.execute,\n messageStatus: message.status,\n },\n };\n }, [part, respond, tool?.execute, message.status, partialArgs]);\n\n if (tool?.render === undefined) return null;\n return (\n <AiToolInvocationContext.Provider value={props}>\n <StableRenderFn\n renderFn={tool.render as FunctionComponent<OpaqueAiToolInvocationProps>}\n props={props}\n />\n </AiToolInvocationContext.Provider>\n );\n}\n"],"names":[],"mappings":";;;;;;;AAmBA,SAAS,eAAe,KAGrB,EAAA;AACD,EAAO,OAAA,KAAA,CAAM,QAAS,CAAA,KAAA,CAAM,KAAK,CAAA,CAAA;AACnC,CAAA;AASO,SAAS,uBAAwB,CAAA;AAAA,EACtC,OAAA;AAAA,EACA,IAAA;AACF,CAGG,EAAA;AACD,EAAA,MAAM,SAAS,SAAU,EAAA,CAAA;AACzB,EAAM,MAAA,EAAA,GAAK,OAAO,SAAW,CAAA,CAAA,EAAA,CAAA;AAC7B,EAAM,MAAA,IAAA,GAAO,UAAU,EAAG,CAAA,OAAA,CAAQ,cAAS,IAAK,CAAA,IAAA,EAAM,OAAQ,CAAA,MAAM,CAAC,CAAA,CAAA;AAErE,EAAA,MAAM,OAAU,GAAA,WAAA;AAAA,IACd,CAAC,MAA2C,KAAA;AAC1C,MAAI,IAAA,OAAA,CAAQ,WAAW,eAAiB,EAAA;AAAA,OAExC,MAAA,IAAW,IAAK,CAAA,KAAA,KAAU,WAAa,EAAA;AAAA,OAIvC,MAAA,IAAW,IAAK,CAAA,KAAA,KAAU,UAAY,EAAA;AACpC,QAAQ,OAAA,CAAA,GAAA;AAAA,UACN,CAAA,0BAAA,EAA6B,IAAK,CAAA,IAAA,CAAA,GAAA,EAAU,IAAK,CAAA,YAAA,CAAA,sBAAA,CAAA;AAAA,SACnD,CAAA;AAAA,OACK,MAAA;AACL,QAAG,EAAA,CAAA,aAAA;AAAA,UACD,OAAQ,CAAA,MAAA;AAAA,UACR,OAAQ,CAAA,EAAA;AAAA,UACR,IAAK,CAAA,YAAA;AAAA,UACL,MAAU,IAAA,EAAE,IAAM,EAAA,EAAG,EAAA;AAAA,UACrB,EAAE,SAAW,EAAA,OAAA,CAAQ,SAAU,EAAA;AAAA,SACjC,CAAA;AAAA,OACF;AAAA,KACF;AAAA,IACA;AAAA,MACE,EAAA;AAAA,MACA,OAAQ,CAAA,MAAA;AAAA,MACR,OAAQ,CAAA,EAAA;AAAA,MACR,OAAQ,CAAA,MAAA;AAAA,MACR,IAAK,CAAA,YAAA;AAAA,MACL,IAAK,CAAA,IAAA;AAAA,MACL,IAAK,CAAA,KAAA;AAAA,MACL,OAAQ,CAAA,SAAA;AAAA,KACV;AAAA,GACF,CAAA;AAEA,EAAA,MAAM,cAAc,IAAM,EAAA,WAAA,CAAA;AAC1B,EAAM,MAAA,KAAA,GAAQ,QAAQ,MAAM;AAM1B,IAAA,WAAA,CAAA;AAEA,IAAA,MAAM,EAAE,IAAA,EAAM,CAAM,EAAA,GAAA,IAAA,EAAS,GAAA,IAAA,CAAA;AAC7B,IAAO,OAAA;AAAA,MACL,GAAG,IAAA;AAAA,MACH,OAAA;AAAA,MACA,KAAO,EAAA,KAAA,CAAA;AAAA,MACP,CAAC,SAAY,GAAA;AAAA,QACX,SAAS,IAAM,EAAA,OAAA;AAAA,QACf,eAAe,OAAQ,CAAA,MAAA;AAAA,OACzB;AAAA,KACF,CAAA;AAAA,GACF,EAAG,CAAC,IAAM,EAAA,OAAA,EAAS,MAAM,OAAS,EAAA,OAAA,CAAQ,MAAQ,EAAA,WAAW,CAAC,CAAA,CAAA;AAE9D,EAAA,IAAI,MAAM,MAAW,KAAA,KAAA,CAAA;AAAW,IAAO,OAAA,IAAA,CAAA;AACvC,EACE,uBAAA,GAAA,CAAC,wBAAwB,QAAxB,EAAA;AAAA,IAAiC,KAAO,EAAA,KAAA;AAAA,IACvC,QAAC,kBAAA,GAAA,CAAA,cAAA,EAAA;AAAA,MACC,UAAU,IAAK,CAAA,MAAA;AAAA,MACf,KAAA;AAAA,KACF,CAAA;AAAA,GACF,CAAA,CAAA;AAEJ;;;;"}
package/dist/version.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const PKG_NAME = "@liveblocks/react-ui";
4
- const PKG_VERSION = typeof "3.4.0" === "string" && "3.4.0";
4
+ const PKG_VERSION = typeof "3.4.1" === "string" && "3.4.1";
5
5
  const PKG_FORMAT = typeof "cjs" === "string" && "cjs";
6
6
 
7
7
  exports.PKG_FORMAT = PKG_FORMAT;
package/dist/version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  const PKG_NAME = "@liveblocks/react-ui";
2
- const PKG_VERSION = typeof "3.4.0" === "string" && "3.4.0";
2
+ const PKG_VERSION = typeof "3.4.1" === "string" && "3.4.1";
3
3
  const PKG_FORMAT = typeof "esm" === "string" && "esm";
4
4
 
5
5
  export { PKG_FORMAT, PKG_NAME, PKG_VERSION };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liveblocks/react-ui",
3
- "version": "3.4.0",
3
+ "version": "3.4.1",
4
4
  "description": "A set of React pre-built components for the Liveblocks products. Liveblocks is the all-in-one toolkit to build collaborative products like Figma, Notion, and more.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -76,9 +76,9 @@
76
76
  },
77
77
  "dependencies": {
78
78
  "@floating-ui/react-dom": "^2.1.2",
79
- "@liveblocks/client": "3.4.0",
80
- "@liveblocks/core": "3.4.0",
81
- "@liveblocks/react": "3.4.0",
79
+ "@liveblocks/client": "3.4.1",
80
+ "@liveblocks/core": "3.4.1",
81
+ "@liveblocks/react": "3.4.1",
82
82
  "@radix-ui/react-dropdown-menu": "^2.1.2",
83
83
  "@radix-ui/react-popover": "^1.1.2",
84
84
  "@radix-ui/react-slot": "^1.1.0",