UNPKG

@assistant-ui/react

Version:

TypeScript/React library for AI Chat

110 lines 4.47 kB
"use client"; import { jsx as _jsx } from "react/jsx-runtime"; import { memo, useMemo } from "react"; import { useAssistantState, MessageByIndexProvider } from "../../context/index.js"; const isComponentsSame = (prev, next) => { return (prev.Message === next.Message && prev.EditComposer === next.EditComposer && prev.UserEditComposer === next.UserEditComposer && prev.AssistantEditComposer === next.AssistantEditComposer && prev.SystemEditComposer === next.SystemEditComposer && prev.UserMessage === next.UserMessage && prev.AssistantMessage === next.AssistantMessage && prev.SystemMessage === next.SystemMessage); }; const DEFAULT_SYSTEM_MESSAGE = () => null; const getComponent = (components, role, isEditing) => { switch (role) { case "user": if (isEditing) { return (components.UserEditComposer ?? components.EditComposer ?? components.UserMessage ?? components.Message); } else { return components.UserMessage ?? components.Message; } case "assistant": if (isEditing) { return (components.AssistantEditComposer ?? components.EditComposer ?? components.AssistantMessage ?? components.Message); } else { return (components.AssistantMessage ?? components.Message); } case "system": if (isEditing) { return (components.SystemEditComposer ?? components.EditComposer ?? components.SystemMessage ?? components.Message); } else { return components.SystemMessage ?? DEFAULT_SYSTEM_MESSAGE; } default: const _exhaustiveCheck = role; throw new Error(`Unknown message role: ${_exhaustiveCheck}`); } }; const ThreadMessageComponent = ({ components, }) => { const role = useAssistantState(({ message }) => message.role); const isEditing = useAssistantState(({ message }) => message.composer.isEditing); const Component = getComponent(components, role, isEditing); return _jsx(Component, {}); }; /** * Renders a single message at the specified index in the current thread. * * This component provides message context for a specific message in the thread * and renders it using the provided component configuration. * * @example * ```tsx * <ThreadPrimitive.MessageByIndex * index={0} * components={{ * UserMessage: MyUserMessage, * AssistantMessage: MyAssistantMessage * }} * /> * ``` */ export const ThreadPrimitiveMessageByIndex = memo(({ index, components }) => { return (_jsx(MessageByIndexProvider, { index: index, children: _jsx(ThreadMessageComponent, { components: components }) })); }, (prev, next) => prev.index === next.index && isComponentsSame(prev.components, next.components)); ThreadPrimitiveMessageByIndex.displayName = "ThreadPrimitive.MessageByIndex"; /** * Renders all messages in the current thread using the provided component configuration. * * This component automatically renders all messages in the thread, providing the appropriate * message context for each message. It handles different message types (user, assistant, system) * and supports editing mode through the provided edit composer components. * * @example * ```tsx * <ThreadPrimitive.Messages * components={{ * UserMessage: MyUserMessage, * AssistantMessage: MyAssistantMessage, * EditComposer: MyEditComposer * }} * /> * ``` */ export const ThreadPrimitiveMessagesImpl = ({ components, }) => { const messagesLength = useAssistantState(({ thread }) => thread.messages.length); const messageElements = useMemo(() => { if (messagesLength === 0) return null; return Array.from({ length: messagesLength }, (_, index) => (_jsx(ThreadPrimitiveMessageByIndex, { index: index, components: components }, index))); }, [messagesLength, components]); return messageElements; }; ThreadPrimitiveMessagesImpl.displayName = "ThreadPrimitive.Messages"; export const ThreadPrimitiveMessages = memo(ThreadPrimitiveMessagesImpl, (prev, next) => isComponentsSame(prev.components, next.components)); //# sourceMappingURL=ThreadMessages.js.map