rdesign/frontend/node_modules/@copilotkitnext/react/dist/components/chat/CopilotChatReasoningMessage...

135 lines
6.2 KiB
JavaScript

const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
const require_slots = require('../../lib/slots.cjs');
let react = require("react");
let tailwind_merge = require("tailwind-merge");
let lucide_react = require("lucide-react");
let react_jsx_runtime = require("react/jsx-runtime");
let streamdown = require("streamdown");
//#region src/components/chat/CopilotChatReasoningMessage.tsx
/**
* Formats an elapsed duration (in seconds) to a human-readable string.
*/
function formatDuration(seconds) {
if (seconds < 1) return "a few seconds";
if (seconds < 60) return `${Math.round(seconds)} seconds`;
const mins = Math.floor(seconds / 60);
const secs = Math.round(seconds % 60);
if (secs === 0) return `${mins} minute${mins > 1 ? "s" : ""}`;
return `${mins}m ${secs}s`;
}
function CopilotChatReasoningMessage({ message, messages, isRunning, header, contentView, toggle, children, className, ...props }) {
const isLatest = messages?.[messages.length - 1]?.id === message.id;
const isStreaming = !!(isRunning && isLatest);
const hasContent = !!(message.content && message.content.length > 0);
const startTimeRef = (0, react.useRef)(null);
const [elapsed, setElapsed] = (0, react.useState)(0);
(0, react.useEffect)(() => {
if (isStreaming && startTimeRef.current === null) startTimeRef.current = Date.now();
if (!isStreaming && startTimeRef.current !== null) {
setElapsed((Date.now() - startTimeRef.current) / 1e3);
return;
}
if (!isStreaming) return;
const timer = setInterval(() => {
if (startTimeRef.current !== null) setElapsed((Date.now() - startTimeRef.current) / 1e3);
}, 1e3);
return () => clearInterval(timer);
}, [isStreaming]);
const [isOpen, setIsOpen] = (0, react.useState)(isStreaming);
(0, react.useEffect)(() => {
if (isStreaming) setIsOpen(true);
else setIsOpen(false);
}, [isStreaming]);
const label = isStreaming ? "Thinking…" : `Thought for ${formatDuration(elapsed)}`;
const boundHeader = require_slots.renderSlot(header, CopilotChatReasoningMessage.Header, {
isOpen,
label,
hasContent,
isStreaming,
onClick: hasContent ? () => setIsOpen((prev) => !prev) : void 0
});
const boundContent = require_slots.renderSlot(contentView, CopilotChatReasoningMessage.Content, {
isStreaming,
hasContent,
children: message.content
});
const boundToggle = require_slots.renderSlot(toggle, CopilotChatReasoningMessage.Toggle, {
isOpen,
children: boundContent
});
if (children) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
"data-copilotkit": true,
style: { display: "contents" },
children: children({
header: boundHeader,
contentView: boundContent,
toggle: boundToggle,
message,
messages,
isRunning
})
});
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
className: (0, tailwind_merge.twMerge)("cpk:my-1", className),
"data-message-id": message.id,
...props,
children: [boundHeader, boundToggle]
});
}
(function(_CopilotChatReasoningMessage) {
_CopilotChatReasoningMessage.Header = ({ isOpen, label = "Thoughts", hasContent, isStreaming, className, children: headerChildren, ...headerProps }) => {
const isExpandable = !!hasContent;
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
type: "button",
className: (0, tailwind_merge.twMerge)("cpk:inline-flex cpk:items-center cpk:gap-1 cpk:py-1 cpk:text-sm cpk:text-muted-foreground cpk:transition-colors cpk:select-none", isExpandable ? "cpk:hover:text-foreground cpk:cursor-pointer" : "cpk:cursor-default", className),
"aria-expanded": isExpandable ? isOpen : void 0,
...headerProps,
children: [
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
className: "cpk:font-medium",
children: label
}),
isStreaming && !hasContent && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
className: "cpk:inline-flex cpk:items-center cpk:ml-1",
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "cpk:w-1.5 cpk:h-1.5 cpk:rounded-full cpk:bg-muted-foreground cpk:animate-pulse" })
}),
headerChildren,
isExpandable && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronRight, { className: (0, tailwind_merge.twMerge)("cpk:size-3.5 cpk:shrink-0 cpk:transition-transform cpk:duration-200", isOpen && "cpk:rotate-90") })
]
});
};
_CopilotChatReasoningMessage.Content = ({ isStreaming, hasContent, className, children: contentChildren, ...contentProps }) => {
if (!hasContent && !isStreaming) return null;
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
className: (0, tailwind_merge.twMerge)("cpk:pb-2 cpk:pt-1", className),
...contentProps,
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
className: "cpk:text-sm cpk:text-muted-foreground",
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(streamdown.Streamdown, { children: typeof contentChildren === "string" ? contentChildren : "" }), isStreaming && hasContent && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
className: "cpk:inline-flex cpk:items-center cpk:ml-1 cpk:align-middle",
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "cpk:w-2 cpk:h-2 cpk:rounded-full cpk:bg-muted-foreground cpk:animate-pulse-cursor" })
})]
})
});
};
_CopilotChatReasoningMessage.Toggle = ({ isOpen, className, children: toggleChildren, ...toggleProps }) => {
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
className: (0, tailwind_merge.twMerge)("cpk:grid cpk:transition-[grid-template-rows] cpk:duration-200 cpk:ease-in-out", className),
style: { gridTemplateRows: isOpen ? "1fr" : "0fr" },
...toggleProps,
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
className: "cpk:overflow-hidden",
children: toggleChildren
})
});
};
})(CopilotChatReasoningMessage || (CopilotChatReasoningMessage = {}));
CopilotChatReasoningMessage.Header.displayName = "CopilotChatReasoningMessage.Header";
CopilotChatReasoningMessage.Content.displayName = "CopilotChatReasoningMessage.Content";
CopilotChatReasoningMessage.Toggle.displayName = "CopilotChatReasoningMessage.Toggle";
var CopilotChatReasoningMessage_default = CopilotChatReasoningMessage;
//#endregion
exports.default = CopilotChatReasoningMessage_default;
//# sourceMappingURL=CopilotChatReasoningMessage.cjs.map