@assistant-ui/react
Version:
TypeScript/React library for AI Chat
110 lines • 4.47 kB
JavaScript
"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