rdesign/frontend/node_modules/@copilotkitnext/react/dist/components/chat/CopilotChatMessageView.cjs

246 lines
12 KiB
JavaScript

const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
const require_CopilotChatConfigurationProvider = require('../../providers/CopilotChatConfigurationProvider.cjs');
const require_slots = require('../../lib/slots.cjs');
const require_CopilotKitProvider = require('../../providers/CopilotKitProvider.cjs');
const require_use_render_custom_messages = require('../../hooks/use-render-custom-messages.cjs');
const require_use_render_activity_message = require('../../hooks/use-render-activity-message.cjs');
require('../../hooks/index.cjs');
const require_CopilotChatAssistantMessage = require('./CopilotChatAssistantMessage.cjs');
const require_CopilotChatUserMessage = require('./CopilotChatUserMessage.cjs');
const require_CopilotChatReasoningMessage = require('./CopilotChatReasoningMessage.cjs');
let react = require("react");
react = require_runtime.__toESM(react);
let tailwind_merge = require("tailwind-merge");
let react_jsx_runtime = require("react/jsx-runtime");
//#region src/components/chat/CopilotChatMessageView.tsx
/**
* Memoized wrapper for assistant messages to prevent re-renders when other messages change.
*/
const MemoizedAssistantMessage = react.default.memo(function MemoizedAssistantMessage({ message, messages, isRunning, AssistantMessageComponent, slotProps }) {
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AssistantMessageComponent, {
message,
messages,
isRunning,
...slotProps
});
}, (prevProps, nextProps) => {
if (prevProps.message.id !== nextProps.message.id) return false;
if (prevProps.message.content !== nextProps.message.content) return false;
const prevToolCalls = prevProps.message.toolCalls;
const nextToolCalls = nextProps.message.toolCalls;
if (prevToolCalls?.length !== nextToolCalls?.length) return false;
if (prevToolCalls && nextToolCalls) for (let i = 0; i < prevToolCalls.length; i++) {
const prevTc = prevToolCalls[i];
const nextTc = nextToolCalls[i];
if (!prevTc || !nextTc) return false;
if (prevTc.id !== nextTc.id) return false;
if (prevTc.function.arguments !== nextTc.function.arguments) return false;
}
if (prevToolCalls && prevToolCalls.length > 0) {
const toolCallIds = new Set(prevToolCalls.map((tc) => tc.id));
const prevToolResults = prevProps.messages.filter((m) => m.role === "tool" && toolCallIds.has(m.toolCallId));
const nextToolResults = nextProps.messages.filter((m) => m.role === "tool" && toolCallIds.has(m.toolCallId));
if (prevToolResults.length !== nextToolResults.length) return false;
for (let i = 0; i < prevToolResults.length; i++) if (prevToolResults[i].content !== nextToolResults[i].content) return false;
}
if (nextProps.messages[nextProps.messages.length - 1]?.id === nextProps.message.id && prevProps.isRunning !== nextProps.isRunning) return false;
if (prevProps.AssistantMessageComponent !== nextProps.AssistantMessageComponent) return false;
if (prevProps.slotProps !== nextProps.slotProps) return false;
return true;
});
/**
* Memoized wrapper for user messages to prevent re-renders when other messages change.
*/
const MemoizedUserMessage = react.default.memo(function MemoizedUserMessage({ message, UserMessageComponent, slotProps }) {
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UserMessageComponent, {
message,
...slotProps
});
}, (prevProps, nextProps) => {
if (prevProps.message.id !== nextProps.message.id) return false;
if (prevProps.message.content !== nextProps.message.content) return false;
if (prevProps.UserMessageComponent !== nextProps.UserMessageComponent) return false;
if (prevProps.slotProps !== nextProps.slotProps) return false;
return true;
});
/**
* Memoized wrapper for activity messages to prevent re-renders when other messages change.
*/
const MemoizedActivityMessage = react.default.memo(function MemoizedActivityMessage({ message, renderActivityMessage }) {
return renderActivityMessage(message);
}, (prevProps, nextProps) => {
if (prevProps.message.id !== nextProps.message.id) return false;
if (prevProps.message.activityType !== nextProps.message.activityType) return false;
if (JSON.stringify(prevProps.message.content) !== JSON.stringify(nextProps.message.content)) return false;
return true;
});
/**
* Memoized wrapper for reasoning messages to prevent re-renders when other messages change.
*/
const MemoizedReasoningMessage = react.default.memo(function MemoizedReasoningMessage({ message, messages, isRunning, ReasoningMessageComponent, slotProps }) {
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReasoningMessageComponent, {
message,
messages,
isRunning,
...slotProps
});
}, (prevProps, nextProps) => {
if (prevProps.message.id !== nextProps.message.id) return false;
if (prevProps.message.content !== nextProps.message.content) return false;
const prevIsLatest = prevProps.messages[prevProps.messages.length - 1]?.id === prevProps.message.id;
const nextIsLatest = nextProps.messages[nextProps.messages.length - 1]?.id === nextProps.message.id;
if (prevIsLatest !== nextIsLatest) return false;
if (nextIsLatest && prevProps.isRunning !== nextProps.isRunning) return false;
if (prevProps.ReasoningMessageComponent !== nextProps.ReasoningMessageComponent) return false;
if (prevProps.slotProps !== nextProps.slotProps) return false;
return true;
});
/**
* Memoized wrapper for custom messages to prevent re-renders when other messages change.
*/
const MemoizedCustomMessage = react.default.memo(function MemoizedCustomMessage({ message, position, renderCustomMessage }) {
return renderCustomMessage({
message,
position
});
}, (prevProps, nextProps) => {
if (prevProps.message.id !== nextProps.message.id) return false;
if (prevProps.position !== nextProps.position) return false;
if (prevProps.message.content !== nextProps.message.content) return false;
if (prevProps.message.role !== nextProps.message.role) return false;
if (JSON.stringify(prevProps.stateSnapshot) !== JSON.stringify(nextProps.stateSnapshot)) return false;
return true;
});
function CopilotChatMessageView({ messages = [], assistantMessage, userMessage, reasoningMessage, cursor, isRunning = false, children, className, ...props }) {
const renderCustomMessage = require_use_render_custom_messages.useRenderCustomMessages();
const { renderActivityMessage } = require_use_render_activity_message.useRenderActivityMessage();
const { copilotkit } = require_CopilotKitProvider.useCopilotKit();
const config = require_CopilotChatConfigurationProvider.useCopilotChatConfiguration();
const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
(0, react.useEffect)(() => {
if (!config?.agentId) return;
const agent = copilotkit.getAgent(config.agentId);
if (!agent) return;
const subscription = agent.subscribe({ onStateChanged: forceUpdate });
return () => subscription.unsubscribe();
}, [
config?.agentId,
copilotkit,
forceUpdate
]);
const [interruptElement, setInterruptElement] = (0, react.useState)(null);
(0, react.useEffect)(() => {
setInterruptElement(copilotkit.interruptElement);
const subscription = copilotkit.subscribe({ onInterruptElementChanged: ({ interruptElement }) => {
setInterruptElement(interruptElement);
} });
return () => subscription.unsubscribe();
}, [copilotkit]);
const getStateSnapshotForMessage = (messageId) => {
if (!config) return void 0;
const resolvedRunId = copilotkit.getRunIdForMessage(config.agentId, config.threadId, messageId) ?? copilotkit.getRunIdsForThread(config.agentId, config.threadId).slice(-1)[0];
if (!resolvedRunId) return void 0;
return copilotkit.getStateByRun(config.agentId, config.threadId, resolvedRunId);
};
const deduplicatedMessages = [...new Map(messages.map((m) => [m.id, m])).values()];
if (process.env.NODE_ENV === "development" && deduplicatedMessages.length < messages.length) console.warn(`CopilotChatMessageView: Deduplicated ${messages.length - deduplicatedMessages.length} message(s) with duplicate IDs.`);
const messageElements = deduplicatedMessages.flatMap((message) => {
const elements = [];
const stateSnapshot = getStateSnapshotForMessage(message.id);
if (renderCustomMessage) elements.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MemoizedCustomMessage, {
message,
position: "before",
renderCustomMessage,
stateSnapshot
}, `${message.id}-custom-before`));
if (message.role === "assistant") {
let AssistantComponent = require_CopilotChatAssistantMessage.default;
let assistantSlotProps;
if (require_slots.isReactComponentType(assistantMessage)) AssistantComponent = assistantMessage;
else if (typeof assistantMessage === "string") assistantSlotProps = { className: assistantMessage };
else if (assistantMessage && typeof assistantMessage === "object") assistantSlotProps = assistantMessage;
elements.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MemoizedAssistantMessage, {
message,
messages,
isRunning,
AssistantMessageComponent: AssistantComponent,
slotProps: assistantSlotProps
}, message.id));
} else if (message.role === "user") {
let UserComponent = require_CopilotChatUserMessage.default;
let userSlotProps;
if (require_slots.isReactComponentType(userMessage)) UserComponent = userMessage;
else if (typeof userMessage === "string") userSlotProps = { className: userMessage };
else if (userMessage && typeof userMessage === "object") userSlotProps = userMessage;
elements.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MemoizedUserMessage, {
message,
UserMessageComponent: UserComponent,
slotProps: userSlotProps
}, message.id));
} else if (message.role === "activity") {
const activityMsg = message;
elements.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MemoizedActivityMessage, {
message: activityMsg,
renderActivityMessage
}, message.id));
} else if (message.role === "reasoning") {
let ReasoningComponent = require_CopilotChatReasoningMessage.default;
let reasoningSlotProps;
if (require_slots.isReactComponentType(reasoningMessage)) ReasoningComponent = reasoningMessage;
else if (typeof reasoningMessage === "string") reasoningSlotProps = { className: reasoningMessage };
else if (reasoningMessage && typeof reasoningMessage === "object") reasoningSlotProps = reasoningMessage;
elements.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MemoizedReasoningMessage, {
message,
messages,
isRunning,
ReasoningMessageComponent: ReasoningComponent,
slotProps: reasoningSlotProps
}, message.id));
}
if (renderCustomMessage) elements.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MemoizedCustomMessage, {
message,
position: "after",
renderCustomMessage,
stateSnapshot
}, `${message.id}-custom-after`));
return elements;
}).filter(Boolean);
if (children) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
"data-copilotkit": true,
style: { display: "contents" },
children: children({
messageElements,
messages,
isRunning,
interruptElement
})
});
const lastMessage = messages[messages.length - 1];
const showCursor = isRunning && lastMessage?.role !== "reasoning";
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
"data-copilotkit": true,
"data-testid": "copilot-message-list",
className: (0, tailwind_merge.twMerge)("copilotKitMessages cpk:flex cpk:flex-col", className),
...props,
children: [
messageElements,
interruptElement,
showCursor && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
className: "cpk:mt-2",
children: require_slots.renderSlot(cursor, CopilotChatMessageView.Cursor, {})
})
]
});
}
CopilotChatMessageView.Cursor = function Cursor({ className, ...props }) {
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
"data-testid": "copilot-loading-cursor",
className: (0, tailwind_merge.twMerge)("cpk:w-[11px] cpk:h-[11px] cpk:rounded-full cpk:bg-foreground cpk:animate-pulse-cursor cpk:ml-1", className),
...props
});
};
//#endregion
exports.default = CopilotChatMessageView;
//# sourceMappingURL=CopilotChatMessageView.cjs.map