@copilotkit/react-ui
Version:
<img src="https://github.com/user-attachments/assets/0a6b64d9-e193-4940-a3f6-60334ac34084" alt="banner" style="border-radius: 12px; border: 2px solid #d6d4fa;" />
184 lines (182 loc) • 5.64 kB
JavaScript
import {
LegacyRenderMessage
} from "./chunk-7OURDQZJ.mjs";
import {
useChatContext
} from "./chunk-IEMQ2SQW.mjs";
import {
__spreadProps,
__spreadValues
} from "./chunk-MRXNTQOX.mjs";
// src/components/chat/Messages.tsx
import { useEffect, useMemo, useRef } from "react";
import { useCopilotChatInternal } from "@copilotkit/react-core";
import { jsx, jsxs } from "react/jsx-runtime";
var Messages = ({
inProgress,
children,
RenderMessage,
AssistantMessage,
UserMessage,
ErrorMessage,
ImageRenderer,
onRegenerate,
onCopy,
onThumbsUp,
onThumbsDown,
messageFeedback,
markdownTagRenderers,
chatError,
// Legacy props
RenderTextMessage,
RenderActionExecutionMessage,
RenderAgentStateMessage,
RenderResultMessage,
RenderImageMessage
}) => {
var _a;
const { labels, icons } = useChatContext();
const { messages: visibleMessages, interrupt } = useCopilotChatInternal();
const initialMessages = useMemo(() => makeInitialMessages(labels.initial), [labels.initial]);
const messages = [...initialMessages, ...visibleMessages];
const { messagesContainerRef, messagesEndRef } = useScrollToBottom(messages);
const hasLegacyProps = !!(RenderTextMessage || RenderActionExecutionMessage || RenderAgentStateMessage || RenderResultMessage || RenderImageMessage);
useEffect(() => {
if (hasLegacyProps) {
console.warn(
"[CopilotKit] Legacy message render props (RenderTextMessage, RenderActionExecutionMessage, etc.) are deprecated. Please use the unified 'RenderMessage' prop instead. See migration guide: https://docs.copilotkit.ai/migration/render-message"
);
}
}, [hasLegacyProps]);
const legacyProps = useMemo(
() => ({
RenderTextMessage,
RenderActionExecutionMessage,
RenderAgentStateMessage,
RenderResultMessage,
RenderImageMessage
}),
[
RenderTextMessage,
RenderActionExecutionMessage,
RenderAgentStateMessage,
RenderResultMessage,
RenderImageMessage
]
);
const MessageRenderer = hasLegacyProps ? (props) => /* @__PURE__ */ jsx(LegacyRenderMessage, __spreadProps(__spreadValues({}, props), { legacyProps })) : RenderMessage;
const LoadingIcon = () => /* @__PURE__ */ jsx("span", { children: icons.activityIcon });
return /* @__PURE__ */ jsxs("div", { className: "copilotKitMessages", ref: messagesContainerRef, children: [
/* @__PURE__ */ jsxs("div", { className: "copilotKitMessagesContainer", children: [
messages.map((message, index) => {
const isCurrentMessage = index === messages.length - 1;
return /* @__PURE__ */ jsx(
MessageRenderer,
{
message,
messages,
inProgress,
index,
isCurrentMessage,
AssistantMessage,
UserMessage,
ImageRenderer,
onRegenerate,
onCopy,
onThumbsUp,
onThumbsDown,
messageFeedback,
markdownTagRenderers
},
index
);
}),
((_a = messages[messages.length - 1]) == null ? void 0 : _a.role) === "user" && inProgress && /* @__PURE__ */ jsx(LoadingIcon, {}),
interrupt,
chatError && ErrorMessage && /* @__PURE__ */ jsx(ErrorMessage, { error: chatError, isCurrentMessage: true })
] }),
/* @__PURE__ */ jsx("footer", { className: "copilotKitMessagesFooter", ref: messagesEndRef, children })
] });
};
function makeInitialMessages(initial) {
if (!initial)
return [];
if (Array.isArray(initial)) {
return initial.map((message) => {
return {
id: message,
role: "assistant",
content: message
};
});
}
return [
{
id: initial,
role: "assistant",
content: initial
}
];
}
function useScrollToBottom(messages) {
const messagesEndRef = useRef(null);
const messagesContainerRef = useRef(null);
const isProgrammaticScrollRef = useRef(false);
const isUserScrollUpRef = useRef(false);
const scrollToBottom = () => {
if (messagesContainerRef.current && messagesEndRef.current) {
isProgrammaticScrollRef.current = true;
messagesContainerRef.current.scrollTop = messagesContainerRef.current.scrollHeight;
}
};
const handleScroll = () => {
if (isProgrammaticScrollRef.current) {
isProgrammaticScrollRef.current = false;
return;
}
if (messagesContainerRef.current) {
const { scrollTop, scrollHeight, clientHeight } = messagesContainerRef.current;
isUserScrollUpRef.current = scrollTop + clientHeight < scrollHeight;
}
};
useEffect(() => {
const container = messagesContainerRef.current;
if (container) {
container.addEventListener("scroll", handleScroll);
}
return () => {
if (container) {
container.removeEventListener("scroll", handleScroll);
}
};
}, []);
useEffect(() => {
const container = messagesContainerRef.current;
if (!container) {
return;
}
const mutationObserver = new MutationObserver(() => {
if (!isUserScrollUpRef.current) {
scrollToBottom();
}
});
mutationObserver.observe(container, {
childList: true,
subtree: true,
characterData: true
});
return () => {
mutationObserver.disconnect();
};
}, []);
useEffect(() => {
isUserScrollUpRef.current = false;
scrollToBottom();
}, [messages.filter((m) => m.role === "user").length]);
return { messagesEndRef, messagesContainerRef };
}
export {
Messages,
useScrollToBottom
};
//# sourceMappingURL=chunk-HIW7RXCD.mjs.map