"use client"; (function(global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@ag-ui/client'), require('react'), require('tailwind-merge'), require('lucide-react'), require('@copilotkitnext/shared'), require('react/jsx-runtime'), require('@radix-ui/react-slot'), require('class-variance-authority'), require('clsx'), require('@radix-ui/react-tooltip'), require('@radix-ui/react-dropdown-menu'), require('streamdown'), require('@copilotkitnext/core'), require('zod'), require('@lit-labs/react'), require('@copilotkit/a2ui-renderer'), require('use-stick-to-bottom'), require('ts-deepmerge')) : typeof define === 'function' && define.amd ? define(['exports', '@ag-ui/client', 'react', 'tailwind-merge', 'lucide-react', '@copilotkitnext/shared', 'react/jsx-runtime', '@radix-ui/react-slot', 'class-variance-authority', 'clsx', '@radix-ui/react-tooltip', '@radix-ui/react-dropdown-menu', 'streamdown', '@copilotkitnext/core', 'zod', '@lit-labs/react', '@copilotkit/a2ui-renderer', 'use-stick-to-bottom', 'ts-deepmerge'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.CopilotKitNextReact = {}), global.AgUIClient,global.React,global.tailwindMerge,global.lucideReact,global.CopilotKitNextShared,global.ReactJsxRuntime,global.RadixReactSlot,global.classVarianceAuthority,global.clsx,global.RadixReactTooltip,global.RadixReactDropdownMenu,global.streamdown,global.CopilotKitNextCore,global.Zod,global.LitLabsReact,global.CopilotKitA2UIRenderer,global.useStickToBottom,global.tsDeepmerge)); })(this, function(exports, _ag_ui_client, react, tailwind_merge, lucide_react, _copilotkitnext_shared, react_jsx_runtime, _radix_ui_react_slot, class_variance_authority, clsx, _radix_ui_react_tooltip, _radix_ui_react_dropdown_menu, streamdown, _copilotkitnext_core, zod, _lit_labs_react, _copilotkit_a2ui_renderer, use_stick_to_bottom, ts_deepmerge) { Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); //#region \0rolldown/runtime.js var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) { key = keys[i]; if (!__hasOwnProp.call(to, key) && key !== except) { __defProp(to, key, { get: ((k) => from[k]).bind(null, key), enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } } } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); //#endregion react = __toESM(react); _radix_ui_react_tooltip = __toESM(_radix_ui_react_tooltip); _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu); //#region src/providers/CopilotChatConfigurationProvider.tsx const CopilotChatDefaultLabels = { chatInputPlaceholder: "Type a message...", chatInputToolbarStartTranscribeButtonLabel: "Transcribe", chatInputToolbarCancelTranscribeButtonLabel: "Cancel", chatInputToolbarFinishTranscribeButtonLabel: "Finish", chatInputToolbarAddButtonLabel: "Add photos or files", chatInputToolbarToolsButtonLabel: "Tools", assistantMessageToolbarCopyCodeLabel: "Copy", assistantMessageToolbarCopyCodeCopiedLabel: "Copied", assistantMessageToolbarCopyMessageLabel: "Copy", assistantMessageToolbarThumbsUpLabel: "Good response", assistantMessageToolbarThumbsDownLabel: "Bad response", assistantMessageToolbarReadAloudLabel: "Read aloud", assistantMessageToolbarRegenerateLabel: "Regenerate", userMessageToolbarCopyMessageLabel: "Copy", userMessageToolbarEditMessageLabel: "Edit", chatDisclaimerText: "AI can make mistakes. Please verify important information.", chatToggleOpenLabel: "Open chat", chatToggleCloseLabel: "Close chat", modalHeaderTitle: "CopilotKit Chat", welcomeMessageText: "How can I help you today?" }; const CopilotChatConfiguration = (0, react.createContext)(null); const CopilotChatConfigurationProvider = ({ children, labels, agentId, threadId, isModalDefaultOpen }) => { var _ref, _parentConfig$isModal, _parentConfig$setModa; const parentConfig = (0, react.useContext)(CopilotChatConfiguration); const mergedLabels = (0, react.useMemo)(() => { var _parentConfig$labels; return { ...CopilotChatDefaultLabels, ...(_parentConfig$labels = parentConfig === null || parentConfig === void 0 ? void 0 : parentConfig.labels) !== null && _parentConfig$labels !== void 0 ? _parentConfig$labels : {}, ...labels !== null && labels !== void 0 ? labels : {} }; }, [labels, parentConfig === null || parentConfig === void 0 ? void 0 : parentConfig.labels]); const resolvedAgentId = (_ref = agentId !== null && agentId !== void 0 ? agentId : parentConfig === null || parentConfig === void 0 ? void 0 : parentConfig.agentId) !== null && _ref !== void 0 ? _ref : _copilotkitnext_shared.DEFAULT_AGENT_ID; const resolvedThreadId = (0, react.useMemo)(() => { if (threadId) return threadId; if (parentConfig === null || parentConfig === void 0 ? void 0 : parentConfig.threadId) return parentConfig.threadId; return (0, _copilotkitnext_shared.randomUUID)(); }, [threadId, parentConfig === null || parentConfig === void 0 ? void 0 : parentConfig.threadId]); const [internalModalOpen, setInternalModalOpen] = (0, react.useState)(isModalDefaultOpen !== null && isModalDefaultOpen !== void 0 ? isModalDefaultOpen : true); const resolvedIsModalOpen = (_parentConfig$isModal = parentConfig === null || parentConfig === void 0 ? void 0 : parentConfig.isModalOpen) !== null && _parentConfig$isModal !== void 0 ? _parentConfig$isModal : internalModalOpen; const resolvedSetModalOpen = (_parentConfig$setModa = parentConfig === null || parentConfig === void 0 ? void 0 : parentConfig.setModalOpen) !== null && _parentConfig$setModa !== void 0 ? _parentConfig$setModa : setInternalModalOpen; const configurationValue = (0, react.useMemo)(() => ({ labels: mergedLabels, agentId: resolvedAgentId, threadId: resolvedThreadId, isModalOpen: resolvedIsModalOpen, setModalOpen: resolvedSetModalOpen }), [ mergedLabels, resolvedAgentId, resolvedThreadId, resolvedIsModalOpen, resolvedSetModalOpen ]); return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatConfiguration.Provider, { value: configurationValue, children }); }; const useCopilotChatConfiguration = () => { return (0, react.useContext)(CopilotChatConfiguration); }; //#endregion //#region src/lib/utils.ts const twMerge$8 = (0, tailwind_merge.extendTailwindMerge)({ prefix: "cpk" }); function cn(...inputs) { return twMerge$8((0, clsx.clsx)(inputs)); } //#endregion //#region src/components/ui/button.tsx const buttonVariants = (0, class_variance_authority.cva)("cpk:inline-flex cpk:items-center cpk:justify-center cpk:gap-2 cpk:whitespace-nowrap cpk:rounded-md cpk:text-sm cpk:font-medium cpk:transition-all cpk:disabled:pointer-events-none cpk:disabled:opacity-50 cpk:[&_svg]:pointer-events-none cpk:[&_svg:not([class*='size-'])]:size-4 cpk:shrink-0 cpk:[&_svg]:shrink-0 cpk:outline-none cpk:focus-visible:border-ring cpk:focus-visible:ring-ring/50 cpk:focus-visible:ring-[3px] cpk:aria-invalid:ring-destructive/20 cpk:dark:aria-invalid:ring-destructive/40 cpk:aria-invalid:border-destructive", { variants: { variant: { default: "cpk:bg-primary cpk:text-primary-foreground cpk:shadow-xs cpk:hover:bg-primary/90", destructive: "cpk:bg-destructive cpk:text-white cpk:shadow-xs cpk:hover:bg-destructive/90 cpk:focus-visible:ring-destructive/20 cpk:dark:focus-visible:ring-destructive/40 cpk:dark:bg-destructive/60", outline: "cpk:border cpk:bg-background cpk:shadow-xs cpk:hover:bg-accent cpk:hover:text-accent-foreground cpk:dark:bg-input/30 cpk:dark:border-input cpk:dark:hover:bg-input/50", secondary: "cpk:bg-secondary cpk:text-secondary-foreground cpk:shadow-xs cpk:hover:bg-secondary/80", ghost: "cpk:hover:bg-accent cpk:hover:text-accent-foreground cpk:dark:hover:bg-accent/50 cpk:cursor-pointer", link: "cpk:text-primary cpk:underline-offset-4 cpk:hover:underline", assistantMessageToolbarButton: [ "cpk:cursor-pointer", "cpk:p-0 cpk:text-[rgb(93,93,93)] cpk:hover:bg-[#E8E8E8]", "cpk:dark:text-[rgb(243,243,243)] cpk:dark:hover:bg-[#303030]", "cpk:h-8 cpk:w-8", "cpk:transition-colors", "cpk:hover:text-[rgb(93,93,93)]", "cpk:dark:hover:text-[rgb(243,243,243)]" ], chatInputToolbarPrimary: [ "cpk:cursor-pointer", "cpk:bg-black cpk:text-white", "cpk:dark:bg-white cpk:dark:text-black cpk:dark:focus-visible:outline-white", "cpk:rounded-full", "cpk:transition-colors", "cpk:focus:outline-none", "cpk:hover:opacity-70 cpk:disabled:hover:opacity-100", "cpk:disabled:cursor-not-allowed cpk:disabled:bg-[#00000014] cpk:disabled:text-[rgb(13,13,13)]", "cpk:dark:disabled:bg-[#454545] cpk:dark:disabled:text-white " ], chatInputToolbarSecondary: [ "cpk:cursor-pointer", "cpk:bg-transparent cpk:text-[#444444]", "cpk:dark:text-white cpk:dark:border-[#404040]", "cpk:rounded-full", "cpk:transition-colors", "cpk:focus:outline-none", "cpk:hover:bg-[#f8f8f8] cpk:hover:text-[#333333]", "cpk:dark:hover:bg-[#404040] cpk:dark:hover:text-[#FFFFFF]", "cpk:disabled:cursor-not-allowed cpk:disabled:opacity-50", "cpk:disabled:hover:bg-transparent cpk:disabled:hover:text-[#444444]", "cpk:dark:disabled:hover:bg-transparent cpk:dark:disabled:hover:text-[#CCCCCC]" ] }, size: { default: "cpk:h-9 cpk:px-4 cpk:py-2 cpk:has-[>svg]:px-3", sm: "cpk:h-8 cpk:rounded-md cpk:gap-1.5 cpk:px-3 cpk:has-[>svg]:px-2.5", lg: "cpk:h-10 cpk:rounded-md cpk:px-6 cpk:has-[>svg]:px-4", icon: "cpk:size-9", chatInputToolbarIcon: ["cpk:h-9 cpk:w-9 cpk:rounded-full"], chatInputToolbarIconLabel: [ "cpk:h-9 cpk:px-3 cpk:rounded-full", "cpk:gap-2", "cpk:font-normal" ] } }, defaultVariants: { variant: "default", size: "default" } }); function Button({ className, variant, size, asChild = false, ...props }) { return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(asChild ? _radix_ui_react_slot.Slot : "button", { "data-slot": "button", className: cn(buttonVariants({ variant, size, className })), ...props }); } //#endregion //#region src/components/ui/tooltip.tsx function TooltipProvider({ delayDuration = 0, ...props }) { return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_tooltip.Provider, { "data-slot": "tooltip-provider", delayDuration, ...props }); } function Tooltip({ ...props }) { return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_tooltip.Root, { "data-slot": "tooltip", ...props }) }); } function TooltipTrigger({ ...props }) { return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_tooltip.Trigger, { "data-slot": "tooltip-trigger", ...props }); } function TooltipContent({ className, sideOffset = 0, children, ...props }) { return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_tooltip.Portal, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_radix_ui_react_tooltip.Content, { "data-copilotkit": true, "data-slot": "tooltip-content", sideOffset, className: cn("cpk:bg-primary cpk:text-primary-foreground cpk:animate-in cpk:fade-in-0 cpk:zoom-in-95 cpk:data-[state=closed]:animate-out cpk:data-[state=closed]:fade-out-0 cpk:data-[state=closed]:zoom-out-95 cpk:data-[side=bottom]:slide-in-from-top-2 cpk:data-[side=left]:slide-in-from-right-2 cpk:data-[side=right]:slide-in-from-left-2 cpk:data-[side=top]:slide-in-from-bottom-2 cpk:z-50 cpk:w-fit cpk:origin-(--radix-tooltip-content-transform-origin) cpk:rounded-md cpk:px-3 cpk:py-1.5 cpk:text-xs cpk:text-balance", className), ...props, children: [children, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_tooltip.Arrow, { className: "cpk:bg-primary cpk:fill-primary cpk:z-50 cpk:size-2.5 cpk:translate-y-[calc(-50%_-_2px)] cpk:rotate-45 cpk:rounded-[2px]" })] }) }); } //#endregion //#region src/components/ui/dropdown-menu.tsx function DropdownMenu({ ...props }) { return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_dropdown_menu.Root, { "data-slot": "dropdown-menu", ...props }); } function DropdownMenuTrigger({ ...props }) { return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_dropdown_menu.Trigger, { "data-slot": "dropdown-menu-trigger", ...props }); } function DropdownMenuContent({ className, sideOffset = 4, ...props }) { return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_dropdown_menu.Portal, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_dropdown_menu.Content, { "data-copilotkit": true, "data-slot": "dropdown-menu-content", sideOffset, className: cn("cpk:bg-popover cpk:text-popover-foreground cpk:data-[state=open]:animate-in cpk:data-[state=closed]:animate-out cpk:data-[state=closed]:fade-out-0 cpk:data-[state=open]:fade-in-0 cpk:data-[state=closed]:zoom-out-95 cpk:data-[state=open]:zoom-in-95 cpk:data-[side=bottom]:slide-in-from-top-2 cpk:data-[side=left]:slide-in-from-right-2 cpk:data-[side=right]:slide-in-from-left-2 cpk:data-[side=top]:slide-in-from-bottom-2 cpk:z-50 cpk:max-h-(--radix-dropdown-menu-content-available-height) cpk:min-w-[8rem] cpk:origin-(--radix-dropdown-menu-content-transform-origin) cpk:overflow-x-hidden cpk:overflow-y-auto cpk:rounded-md cpk:border cpk:p-1 cpk:shadow-md", className), ...props }) }); } function DropdownMenuItem({ className, inset, variant = "default", ...props }) { return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_dropdown_menu.Item, { "data-slot": "dropdown-menu-item", "data-inset": inset, "data-variant": variant, className: cn("cpk:focus:bg-accent cpk:focus:text-accent-foreground cpk:data-[variant=destructive]:text-destructive cpk:data-[variant=destructive]:focus:bg-destructive/10 cpk:dark:data-[variant=destructive]:focus:bg-destructive/20 cpk:data-[variant=destructive]:focus:text-destructive cpk:data-[variant=destructive]:*:[svg]:!text-destructive cpk:[&_svg:not([class*='text-'])]:text-muted-foreground cpk:relative cpk:flex cpk:cursor-default cpk:items-center cpk:gap-2 cpk:rounded-sm cpk:px-2 cpk:py-1.5 cpk:text-sm cpk:outline-hidden cpk:select-none cpk:data-[disabled]:pointer-events-none cpk:data-[disabled]:opacity-50 cpk:data-[inset]:pl-8 cpk:[&_svg]:pointer-events-none cpk:[&_svg]:shrink-0 cpk:[&_svg:not([class*='size-'])]:size-4", className), ...props }); } function DropdownMenuSeparator({ className, ...props }) { return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_dropdown_menu.Separator, { "data-slot": "dropdown-menu-separator", className: cn("cpk:bg-border cpk:-mx-1 cpk:my-1 cpk:h-px", className), ...props }); } function DropdownMenuSub({ ...props }) { return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_dropdown_menu.Sub, { "data-slot": "dropdown-menu-sub", ...props }); } function DropdownMenuSubTrigger({ className, inset, children, ...props }) { return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_radix_ui_react_dropdown_menu.SubTrigger, { "data-slot": "dropdown-menu-sub-trigger", "data-inset": inset, className: cn("cpk:focus:bg-accent cpk:focus:text-accent-foreground cpk:data-[state=open]:bg-accent cpk:data-[state=open]:text-accent-foreground cpk:flex cpk:cursor-default cpk:items-center cpk:rounded-sm cpk:px-2 cpk:py-1.5 cpk:text-sm cpk:outline-hidden cpk:select-none cpk:data-[inset]:pl-8", className), ...props, children: [children, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronRightIcon, { className: "cpk:ml-auto cpk:size-4" })] }); } function DropdownMenuSubContent({ className, ...props }) { return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_dropdown_menu.SubContent, { "data-slot": "dropdown-menu-sub-content", className: cn("cpk:bg-popover cpk:text-popover-foreground cpk:data-[state=open]:animate-in cpk:data-[state=closed]:animate-out cpk:data-[state=closed]:fade-out-0 cpk:data-[state=open]:fade-in-0 cpk:data-[state=closed]:zoom-out-95 cpk:data-[state=open]:zoom-in-95 cpk:data-[side=bottom]:slide-in-from-top-2 cpk:data-[side=left]:slide-in-from-right-2 cpk:data-[side=right]:slide-in-from-left-2 cpk:data-[side=top]:slide-in-from-bottom-2 cpk:z-50 cpk:min-w-[8rem] cpk:origin-(--radix-dropdown-menu-content-transform-origin) cpk:overflow-hidden cpk:rounded-md cpk:border cpk:p-1 cpk:shadow-lg", className), ...props }); } //#endregion //#region src/components/chat/CopilotChatAudioRecorder.tsx /** Error subclass so callers can `instanceof`-guard recorder failures */ var AudioRecorderError = class extends Error { constructor(message) { super(message); this.name = "AudioRecorderError"; } }; const CopilotChatAudioRecorder = (0, react.forwardRef)((props, ref) => { const { className, ...divProps } = props; const canvasRef = (0, react.useRef)(null); const [recorderState, setRecorderState] = (0, react.useState)("idle"); const mediaRecorderRef = (0, react.useRef)(null); const audioChunksRef = (0, react.useRef)([]); const streamRef = (0, react.useRef)(null); const analyserRef = (0, react.useRef)(null); const audioContextRef = (0, react.useRef)(null); const animationIdRef = (0, react.useRef)(null); const amplitudeHistoryRef = (0, react.useRef)([]); const frameCountRef = (0, react.useRef)(0); const scrollOffsetRef = (0, react.useRef)(0); const smoothedAmplitudeRef = (0, react.useRef)(0); const fadeOpacityRef = (0, react.useRef)(0); const cleanup = (0, react.useCallback)(() => { if (animationIdRef.current) { cancelAnimationFrame(animationIdRef.current); animationIdRef.current = null; } if (mediaRecorderRef.current && mediaRecorderRef.current.state !== "inactive") try { mediaRecorderRef.current.stop(); } catch (_unused) {} if (streamRef.current) { streamRef.current.getTracks().forEach((track) => track.stop()); streamRef.current = null; } if (audioContextRef.current && audioContextRef.current.state !== "closed") { audioContextRef.current.close().catch(() => {}); audioContextRef.current = null; } mediaRecorderRef.current = null; analyserRef.current = null; audioChunksRef.current = []; amplitudeHistoryRef.current = []; frameCountRef.current = 0; scrollOffsetRef.current = 0; smoothedAmplitudeRef.current = 0; fadeOpacityRef.current = 0; }, []); const start = (0, react.useCallback)(async () => { if (recorderState !== "idle") throw new AudioRecorderError("Recorder is already active"); try { const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); streamRef.current = stream; const audioContext = new AudioContext(); audioContextRef.current = audioContext; const source = audioContext.createMediaStreamSource(stream); const analyser = audioContext.createAnalyser(); analyser.fftSize = 2048; source.connect(analyser); analyserRef.current = analyser; const mimeType = MediaRecorder.isTypeSupported("audio/webm;codecs=opus") ? "audio/webm;codecs=opus" : MediaRecorder.isTypeSupported("audio/webm") ? "audio/webm" : MediaRecorder.isTypeSupported("audio/mp4") ? "audio/mp4" : ""; const options = mimeType ? { mimeType } : {}; const mediaRecorder = new MediaRecorder(stream, options); mediaRecorderRef.current = mediaRecorder; audioChunksRef.current = []; mediaRecorder.ondataavailable = (event) => { if (event.data.size > 0) audioChunksRef.current.push(event.data); }; mediaRecorder.start(100); setRecorderState("recording"); } catch (error) { cleanup(); if (error instanceof Error && error.name === "NotAllowedError") throw new AudioRecorderError("Microphone permission denied"); if (error instanceof Error && error.name === "NotFoundError") throw new AudioRecorderError("No microphone found"); throw new AudioRecorderError(error instanceof Error ? error.message : "Failed to start recording"); } }, [recorderState, cleanup]); const stop = (0, react.useCallback)(() => { return new Promise((resolve, reject) => { const mediaRecorder = mediaRecorderRef.current; if (!mediaRecorder || recorderState !== "recording") { reject(new AudioRecorderError("No active recording")); return; } setRecorderState("processing"); mediaRecorder.onstop = () => { const mimeType = mediaRecorder.mimeType || "audio/webm"; const audioBlob = new Blob(audioChunksRef.current, { type: mimeType }); cleanup(); setRecorderState("idle"); resolve(audioBlob); }; mediaRecorder.onerror = () => { cleanup(); setRecorderState("idle"); reject(new AudioRecorderError("Recording failed")); }; mediaRecorder.stop(); }); }, [recorderState, cleanup]); const calculateAmplitude = (dataArray) => { let sum = 0; for (let i = 0; i < dataArray.length; i++) { var _dataArray$i; const sample = ((_dataArray$i = dataArray[i]) !== null && _dataArray$i !== void 0 ? _dataArray$i : 128) / 128 - 1; sum += sample * sample; } return Math.sqrt(sum / dataArray.length); }; (0, react.useEffect)(() => { const canvas = canvasRef.current; if (!canvas) return; const ctx = canvas.getContext("2d"); if (!ctx) return; const barWidth = 2; const barSpacing = barWidth + 1; const scrollSpeed = 1 / 3; const draw = () => { const rect = canvas.getBoundingClientRect(); const dpr = window.devicePixelRatio || 1; if (canvas.width !== rect.width * dpr || canvas.height !== rect.height * dpr) { canvas.width = rect.width * dpr; canvas.height = rect.height * dpr; ctx.scale(dpr, dpr); } const maxBars = Math.floor(rect.width / barSpacing) + 2; if (analyserRef.current && recorderState === "recording") { if (amplitudeHistoryRef.current.length === 0) amplitudeHistoryRef.current = new Array(maxBars).fill(0); if (fadeOpacityRef.current < 1) fadeOpacityRef.current = Math.min(1, fadeOpacityRef.current + .03); scrollOffsetRef.current += scrollSpeed; const bufferLength = analyserRef.current.fftSize; const dataArray = new Uint8Array(bufferLength); analyserRef.current.getByteTimeDomainData(dataArray); const rawAmplitude = calculateAmplitude(dataArray); const speed = rawAmplitude > smoothedAmplitudeRef.current ? .12 : .08; smoothedAmplitudeRef.current += (rawAmplitude - smoothedAmplitudeRef.current) * speed; if (scrollOffsetRef.current >= barSpacing) { scrollOffsetRef.current -= barSpacing; amplitudeHistoryRef.current.push(smoothedAmplitudeRef.current); if (amplitudeHistoryRef.current.length > maxBars) amplitudeHistoryRef.current = amplitudeHistoryRef.current.slice(-maxBars); } } ctx.clearRect(0, 0, rect.width, rect.height); ctx.fillStyle = getComputedStyle(canvas).color; ctx.globalAlpha = fadeOpacityRef.current; const centerY = rect.height / 2; const maxAmplitude = rect.height / 2 - 2; const history = amplitudeHistoryRef.current; if (history.length > 0) { const offset = scrollOffsetRef.current; const edgeFadeWidth = 12; for (let i = 0; i < history.length; i++) { var _history$i; const amplitude = (_history$i = history[i]) !== null && _history$i !== void 0 ? _history$i : 0; const scaledAmplitude = Math.min(amplitude * 4, 1); const barHeight = Math.max(2, scaledAmplitude * maxAmplitude * 2); const x = rect.width - (history.length - i) * barSpacing - offset; const y = centerY - barHeight / 2; if (x + barWidth > 0 && x < rect.width) { let edgeOpacity = 1; if (x < edgeFadeWidth) edgeOpacity = Math.max(0, x / edgeFadeWidth); else if (x > rect.width - edgeFadeWidth) edgeOpacity = Math.max(0, (rect.width - x) / edgeFadeWidth); ctx.globalAlpha = fadeOpacityRef.current * edgeOpacity; ctx.fillRect(x, y, barWidth, barHeight); } } } animationIdRef.current = requestAnimationFrame(draw); }; draw(); return () => { if (animationIdRef.current) cancelAnimationFrame(animationIdRef.current); }; }, [recorderState]); (0, react.useEffect)(() => { return cleanup; }, [cleanup]); (0, react.useImperativeHandle)(ref, () => ({ get state() { return recorderState; }, start, stop, dispose: cleanup }), [ recorderState, start, stop, cleanup ]); return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: (0, tailwind_merge.twMerge)("cpk:w-full cpk:py-3 cpk:px-5", className), ...divProps, children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("canvas", { ref: canvasRef, className: "cpk:block cpk:w-full cpk:h-[26px]" }) }); }); CopilotChatAudioRecorder.displayName = "CopilotChatAudioRecorder"; //#endregion //#region src/lib/slots.tsx /** * Shallow equality comparison for objects. */ function shallowEqual(obj1, obj2) { const keys1 = Object.keys(obj1); const keys2 = Object.keys(obj2); if (keys1.length !== keys2.length) return false; for (const key of keys1) if (obj1[key] !== obj2[key]) return false; return true; } /** * Check if a value is a React component type (function, class, forwardRef, memo, etc.) */ function isReactComponentType(value) { if (typeof value === "function") return true; if (value && typeof value === "object" && "$$typeof" in value && !react.default.isValidElement(value)) return true; return false; } /** * Internal function to render a slot value as a React element (non-memoized). */ function renderSlotElement(slot, DefaultComponent, props) { if (typeof slot === "string") { const existingClassName = props.className; return react.default.createElement(DefaultComponent, { ...props, className: (0, tailwind_merge.twMerge)(existingClassName, slot) }); } if (isReactComponentType(slot)) return react.default.createElement(slot, props); if (slot && typeof slot === "object" && !react.default.isValidElement(slot)) return react.default.createElement(DefaultComponent, { ...props, ...slot }); return react.default.createElement(DefaultComponent, props); } /** * Internal memoized wrapper component for renderSlot. * Uses forwardRef to support ref forwarding. */ const MemoizedSlotWrapper = react.default.memo(react.default.forwardRef(function MemoizedSlotWrapper(props, ref) { const { $slot, $component, ...rest } = props; return renderSlotElement($slot, $component, ref !== null ? { ...rest, ref } : rest); }), (prev, next) => { if (prev.$slot !== next.$slot) return false; if (prev.$component !== next.$component) return false; const { $slot: _ps, $component: _pc, ...prevRest } = prev; const { $slot: _ns, $component: _nc, ...nextRest } = next; return shallowEqual(prevRest, nextRest); }); /** * Renders a slot value as a memoized React element. * Automatically prevents unnecessary re-renders using shallow prop comparison. * Supports ref forwarding. * * @example * renderSlot(customInput, CopilotChatInput, { onSubmit: handleSubmit }) */ function renderSlot(slot, DefaultComponent, props) { return react.default.createElement(MemoizedSlotWrapper, { ...props, $slot: slot, $component: DefaultComponent }); } //#endregion //#region src/components/chat/CopilotChatInput.tsx const SLASH_MENU_MAX_VISIBLE_ITEMS = 5; const SLASH_MENU_ITEM_HEIGHT_PX = 40; function CopilotChatInput({ mode = "input", onSubmitMessage, onStop, isRunning = false, onStartTranscribe, onCancelTranscribe, onFinishTranscribe, onFinishTranscribeWithAudio, onAddFile, onChange, value, toolsMenu, autoFocus = true, positioning = "static", keyboardHeight = 0, containerRef, showDisclaimer, textArea, sendButton, startTranscribeButton, cancelTranscribeButton, finishTranscribeButton, addMenuButton, audioRecorder, disclaimer, children, className, ...props }) { var _config$labels; const isControlled = value !== void 0; const [internalValue, setInternalValue] = (0, react.useState)(() => value !== null && value !== void 0 ? value : ""); (0, react.useEffect)(() => { if (!isControlled && value !== void 0) setInternalValue(value); }, [isControlled, value]); const resolvedValue = isControlled ? value !== null && value !== void 0 ? value : "" : internalValue; const [layout, setLayout] = (0, react.useState)("compact"); const ignoreResizeRef = (0, react.useRef)(false); const resizeEvaluationRafRef = (0, react.useRef)(null); const isExpanded = mode === "input" && layout === "expanded"; const [commandQuery, setCommandQuery] = (0, react.useState)(null); const [slashHighlightIndex, setSlashHighlightIndex] = (0, react.useState)(0); const inputRef = (0, react.useRef)(null); const gridRef = (0, react.useRef)(null); const addButtonContainerRef = (0, react.useRef)(null); const actionsContainerRef = (0, react.useRef)(null); const audioRecorderRef = (0, react.useRef)(null); const slashMenuRef = (0, react.useRef)(null); const config = useCopilotChatConfiguration(); const labels = (_config$labels = config === null || config === void 0 ? void 0 : config.labels) !== null && _config$labels !== void 0 ? _config$labels : CopilotChatDefaultLabels; const previousModalStateRef = (0, react.useRef)(void 0); const measurementCanvasRef = (0, react.useRef)(null); const measurementsRef = (0, react.useRef)({ singleLineHeight: 0, maxHeight: 0, paddingLeft: 0, paddingRight: 0 }); const commandItems = (0, react.useMemo)(() => { const entries = []; const seen = /* @__PURE__ */ new Set(); const pushItem = (item) => { if (item === "-") return; if (item.items && item.items.length > 0) { for (const nested of item.items) pushItem(nested); return; } if (!seen.has(item.label)) { seen.add(item.label); entries.push(item); } }; if (onAddFile) pushItem({ label: labels.chatInputToolbarAddButtonLabel, action: onAddFile }); if (toolsMenu && toolsMenu.length > 0) for (const item of toolsMenu) pushItem(item); return entries; }, [ labels.chatInputToolbarAddButtonLabel, onAddFile, toolsMenu ]); const filteredCommands = (0, react.useMemo)(() => { if (commandQuery === null) return []; if (commandItems.length === 0) return []; const query = commandQuery.trim().toLowerCase(); if (query.length === 0) return commandItems; const startsWith = []; const contains = []; for (const item of commandItems) { const label = item.label.toLowerCase(); if (label.startsWith(query)) startsWith.push(item); else if (label.includes(query)) contains.push(item); } return [...startsWith, ...contains]; }, [commandItems, commandQuery]); (0, react.useEffect)(() => { if (!autoFocus) { previousModalStateRef.current = config === null || config === void 0 ? void 0 : config.isModalOpen; return; } if ((config === null || config === void 0 ? void 0 : config.isModalOpen) && !previousModalStateRef.current) { var _inputRef$current; (_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 || _inputRef$current.focus(); } previousModalStateRef.current = config === null || config === void 0 ? void 0 : config.isModalOpen; }, [config === null || config === void 0 ? void 0 : config.isModalOpen, autoFocus]); (0, react.useEffect)(() => { if (commandItems.length === 0 && commandQuery !== null) setCommandQuery(null); }, [commandItems.length, commandQuery]); const previousCommandQueryRef = (0, react.useRef)(null); (0, react.useEffect)(() => { if (commandQuery !== null && commandQuery !== previousCommandQueryRef.current && filteredCommands.length > 0) setSlashHighlightIndex(0); previousCommandQueryRef.current = commandQuery; }, [commandQuery, filteredCommands.length]); (0, react.useEffect)(() => { if (commandQuery === null) { setSlashHighlightIndex(0); return; } if (filteredCommands.length === 0) setSlashHighlightIndex(-1); else if (slashHighlightIndex < 0 || slashHighlightIndex >= filteredCommands.length) setSlashHighlightIndex(0); }, [ commandQuery, filteredCommands, slashHighlightIndex ]); (0, react.useEffect)(() => { const recorder = audioRecorderRef.current; if (!recorder) return; if (mode === "transcribe") recorder.start().catch(console.error); else if (recorder.state === "recording") recorder.stop().catch(console.error); }, [mode]); (0, react.useEffect)(() => { if (mode !== "input") { setLayout("compact"); setCommandQuery(null); } }, [mode]); const updateSlashState = (0, react.useCallback)((value) => { if (commandItems.length === 0) { setCommandQuery((prev) => prev === null ? prev : null); return; } if (value.startsWith("/")) { var _value$split$; const query = ((_value$split$ = value.split(/\r?\n/, 1)[0]) !== null && _value$split$ !== void 0 ? _value$split$ : "").slice(1); setCommandQuery((prev) => prev === query ? prev : query); } else setCommandQuery((prev) => prev === null ? prev : null); }, [commandItems.length]); (0, react.useEffect)(() => { updateSlashState(resolvedValue); }, [resolvedValue, updateSlashState]); const handleChange = (e) => { const nextValue = e.target.value; if (!isControlled) setInternalValue(nextValue); onChange === null || onChange === void 0 || onChange(nextValue); updateSlashState(nextValue); }; const clearInputValue = (0, react.useCallback)(() => { if (!isControlled) setInternalValue(""); if (onChange) onChange(""); }, [isControlled, onChange]); const runCommand = (0, react.useCallback)((item) => { var _item$action; clearInputValue(); (_item$action = item.action) === null || _item$action === void 0 || _item$action.call(item); setCommandQuery(null); setSlashHighlightIndex(0); requestAnimationFrame(() => { var _inputRef$current2; (_inputRef$current2 = inputRef.current) === null || _inputRef$current2 === void 0 || _inputRef$current2.focus(); }); }, [clearInputValue]); const handleKeyDown = (e) => { if (commandQuery !== null && mode === "input") { if (e.key === "ArrowDown") { if (filteredCommands.length > 0) { e.preventDefault(); setSlashHighlightIndex((prev) => { if (filteredCommands.length === 0) return prev; return prev === -1 ? 0 : (prev + 1) % filteredCommands.length; }); } return; } if (e.key === "ArrowUp") { if (filteredCommands.length > 0) { e.preventDefault(); setSlashHighlightIndex((prev) => { if (filteredCommands.length === 0) return prev; if (prev === -1) return filteredCommands.length - 1; return prev <= 0 ? filteredCommands.length - 1 : prev - 1; }); } return; } if (e.key === "Enter") { const selected = slashHighlightIndex >= 0 ? filteredCommands[slashHighlightIndex] : void 0; if (selected) { e.preventDefault(); runCommand(selected); return; } } if (e.key === "Escape") { e.preventDefault(); setCommandQuery(null); return; } } if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); if (isProcessing) onStop === null || onStop === void 0 || onStop(); else send(); } }; const send = () => { if (!onSubmitMessage) return; const trimmed = resolvedValue.trim(); if (!trimmed) return; onSubmitMessage(trimmed); if (!isControlled) { setInternalValue(""); onChange === null || onChange === void 0 || onChange(""); } if (inputRef.current) inputRef.current.focus(); }; const BoundTextArea = renderSlot(textArea, CopilotChatInput.TextArea, { ref: inputRef, value: resolvedValue, onChange: handleChange, onKeyDown: handleKeyDown, autoFocus, className: (0, tailwind_merge.twMerge)("cpk:w-full cpk:py-3", isExpanded ? "cpk:px-5" : "cpk:pr-5") }); const isProcessing = mode !== "transcribe" && isRunning; const canSend = resolvedValue.trim().length > 0 && !!onSubmitMessage; const canStop = !!onStop; const handleSendButtonClick = () => { if (isProcessing) { onStop === null || onStop === void 0 || onStop(); return; } send(); }; const BoundAudioRecorder = renderSlot(audioRecorder, CopilotChatAudioRecorder, { ref: audioRecorderRef }); const BoundSendButton = renderSlot(sendButton, CopilotChatInput.SendButton, { onClick: handleSendButtonClick, disabled: isProcessing ? !canStop : !canSend, children: isProcessing && canStop ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Square, { className: "cpk:size-[18px] cpk:fill-current" }) : void 0 }); const BoundStartTranscribeButton = renderSlot(startTranscribeButton, CopilotChatInput.StartTranscribeButton, { onClick: onStartTranscribe }); const BoundCancelTranscribeButton = renderSlot(cancelTranscribeButton, CopilotChatInput.CancelTranscribeButton, { onClick: onCancelTranscribe }); const handleFinishTranscribe = (0, react.useCallback)(async () => { const recorder = audioRecorderRef.current; if (recorder && recorder.state === "recording") try { const audioBlob = await recorder.stop(); if (onFinishTranscribeWithAudio) await onFinishTranscribeWithAudio(audioBlob); } catch (error) { console.error("Failed to stop recording:", error); } onFinishTranscribe === null || onFinishTranscribe === void 0 || onFinishTranscribe(); }, [onFinishTranscribe, onFinishTranscribeWithAudio]); const BoundFinishTranscribeButton = renderSlot(finishTranscribeButton, CopilotChatInput.FinishTranscribeButton, { onClick: handleFinishTranscribe }); const BoundAddMenuButton = renderSlot(addMenuButton, CopilotChatInput.AddMenuButton, { disabled: mode === "transcribe", onAddFile, toolsMenu }); const BoundDisclaimer = renderSlot(disclaimer, CopilotChatInput.Disclaimer, {}); const shouldShowDisclaimer = showDisclaimer !== null && showDisclaimer !== void 0 ? showDisclaimer : positioning === "absolute"; if (children) { const childProps = { textArea: BoundTextArea, audioRecorder: BoundAudioRecorder, sendButton: BoundSendButton, startTranscribeButton: BoundStartTranscribeButton, cancelTranscribeButton: BoundCancelTranscribeButton, finishTranscribeButton: BoundFinishTranscribeButton, addMenuButton: BoundAddMenuButton, disclaimer: BoundDisclaimer, onSubmitMessage, onStop, isRunning, onStartTranscribe, onCancelTranscribe, onFinishTranscribe, onAddFile, mode, toolsMenu, autoFocus, positioning, keyboardHeight, showDisclaimer: shouldShowDisclaimer }; return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { "data-copilotkit": true, style: { display: "contents" }, children: children(childProps) }); } const handleContainerClick = (e) => { const target = e.target; if (target.tagName !== "BUTTON" && !target.closest("button") && inputRef.current && mode === "input") inputRef.current.focus(); }; const ensureMeasurements = (0, react.useCallback)(() => { const textarea = inputRef.current; if (!textarea) return; const previousValue = textarea.value; const previousHeight = textarea.style.height; textarea.style.height = "auto"; const computedStyle = window.getComputedStyle(textarea); const paddingLeft = parseFloat(computedStyle.paddingLeft) || 0; const paddingRight = parseFloat(computedStyle.paddingRight) || 0; const paddingTop = parseFloat(computedStyle.paddingTop) || 0; const paddingBottom = parseFloat(computedStyle.paddingBottom) || 0; textarea.value = ""; const singleLineHeight = textarea.scrollHeight; textarea.value = previousValue; const maxHeight = (singleLineHeight - paddingTop - paddingBottom) * 5 + paddingTop + paddingBottom; measurementsRef.current = { singleLineHeight, maxHeight, paddingLeft, paddingRight }; textarea.style.height = previousHeight; textarea.style.maxHeight = `${maxHeight}px`; }, []); const adjustTextareaHeight = (0, react.useCallback)(() => { const textarea = inputRef.current; if (!textarea) return 0; if (measurementsRef.current.singleLineHeight === 0) ensureMeasurements(); const { maxHeight } = measurementsRef.current; if (maxHeight) textarea.style.maxHeight = `${maxHeight}px`; textarea.style.height = "auto"; const scrollHeight = textarea.scrollHeight; if (maxHeight) textarea.style.height = `${Math.min(scrollHeight, maxHeight)}px`; else textarea.style.height = `${scrollHeight}px`; return scrollHeight; }, [ensureMeasurements]); const updateLayout = (0, react.useCallback)((nextLayout) => { setLayout((prev) => { if (prev === nextLayout) return prev; ignoreResizeRef.current = true; return nextLayout; }); }, []); const evaluateLayout = (0, react.useCallback)(() => { if (mode !== "input") { updateLayout("compact"); return; } if (typeof window !== "undefined" && typeof window.matchMedia === "function") { if (window.matchMedia("(max-width: 767px)").matches) { ensureMeasurements(); adjustTextareaHeight(); updateLayout("expanded"); return; } } const textarea = inputRef.current; const grid = gridRef.current; const addContainer = addButtonContainerRef.current; const actionsContainer = actionsContainerRef.current; if (!textarea || !grid || !addContainer || !actionsContainer) return; if (measurementsRef.current.singleLineHeight === 0) ensureMeasurements(); const scrollHeight = adjustTextareaHeight(); const baseline = measurementsRef.current.singleLineHeight; const hasExplicitBreak = resolvedValue.includes("\n"); const renderedMultiline = baseline > 0 ? scrollHeight > baseline + 1 : false; let shouldExpand = hasExplicitBreak || renderedMultiline; if (!shouldExpand) { const gridStyles = window.getComputedStyle(grid); const paddingLeft = parseFloat(gridStyles.paddingLeft) || 0; const paddingRight = parseFloat(gridStyles.paddingRight) || 0; const columnGap = parseFloat(gridStyles.columnGap) || 0; const gridAvailableWidth = grid.clientWidth - paddingLeft - paddingRight; if (gridAvailableWidth > 0) { var _measurementCanvasRef; const addWidth = addContainer.getBoundingClientRect().width; const actionsWidth = actionsContainer.getBoundingClientRect().width; const compactWidth = Math.max(gridAvailableWidth - addWidth - actionsWidth - columnGap * 2, 0); const canvas = (_measurementCanvasRef = measurementCanvasRef.current) !== null && _measurementCanvasRef !== void 0 ? _measurementCanvasRef : document.createElement("canvas"); if (!measurementCanvasRef.current) measurementCanvasRef.current = canvas; const context = canvas.getContext("2d"); if (context) { const textareaStyles = window.getComputedStyle(textarea); context.font = textareaStyles.font || `${textareaStyles.fontStyle} ${textareaStyles.fontVariant} ${textareaStyles.fontWeight} ${textareaStyles.fontSize}/${textareaStyles.lineHeight} ${textareaStyles.fontFamily}`; const compactInnerWidth = Math.max(compactWidth - (measurementsRef.current.paddingLeft || 0) - (measurementsRef.current.paddingRight || 0), 0); if (compactInnerWidth > 0) { const lines = resolvedValue.length > 0 ? resolvedValue.split("\n") : [""]; let longestWidth = 0; for (const line of lines) { const metrics = context.measureText(line || " "); if (metrics.width > longestWidth) longestWidth = metrics.width; } if (longestWidth > compactInnerWidth) shouldExpand = true; } } } } updateLayout(shouldExpand ? "expanded" : "compact"); }, [ adjustTextareaHeight, ensureMeasurements, mode, resolvedValue, updateLayout ]); (0, react.useLayoutEffect)(() => { evaluateLayout(); }, [evaluateLayout]); (0, react.useEffect)(() => { if (typeof ResizeObserver === "undefined") return; const textarea = inputRef.current; const grid = gridRef.current; const addContainer = addButtonContainerRef.current; const actionsContainer = actionsContainerRef.current; if (!textarea || !grid || !addContainer || !actionsContainer) return; const scheduleEvaluation = () => { if (ignoreResizeRef.current) { ignoreResizeRef.current = false; return; } if (typeof window === "undefined") { evaluateLayout(); return; } if (resizeEvaluationRafRef.current !== null) cancelAnimationFrame(resizeEvaluationRafRef.current); resizeEvaluationRafRef.current = window.requestAnimationFrame(() => { resizeEvaluationRafRef.current = null; evaluateLayout(); }); }; const observer = new ResizeObserver(() => { scheduleEvaluation(); }); observer.observe(grid); observer.observe(addContainer); observer.observe(actionsContainer); observer.observe(textarea); return () => { observer.disconnect(); if (typeof window !== "undefined" && resizeEvaluationRafRef.current !== null) { cancelAnimationFrame(resizeEvaluationRafRef.current); resizeEvaluationRafRef.current = null; } }; }, [evaluateLayout]); const slashMenuVisible = commandQuery !== null && commandItems.length > 0; (0, react.useEffect)(() => { var _slashMenuRef$current; if (!slashMenuVisible || slashHighlightIndex < 0) return; const active = (_slashMenuRef$current = slashMenuRef.current) === null || _slashMenuRef$current === void 0 ? void 0 : _slashMenuRef$current.querySelector(`[data-slash-index="${slashHighlightIndex}"]`); active === null || active === void 0 || active.scrollIntoView({ block: "nearest" }); }, [slashMenuVisible, slashHighlightIndex]); const slashMenu = slashMenuVisible ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { "data-testid": "copilot-slash-menu", role: "listbox", "aria-label": "Slash commands", ref: slashMenuRef, className: "cpk:absolute cpk:bottom-full cpk:left-0 cpk:right-0 cpk:z-30 cpk:mb-2 cpk:max-h-64 cpk:overflow-y-auto cpk:rounded-lg cpk:border cpk:border-border cpk:bg-white cpk:shadow-lg cpk:dark:border-[#3a3a3a] cpk:dark:bg-[#1f1f1f]", style: { maxHeight: `${SLASH_MENU_MAX_VISIBLE_ITEMS * SLASH_MENU_ITEM_HEIGHT_PX}px` }, children: filteredCommands.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "cpk:px-3 cpk:py-2 cpk:text-sm cpk:text-muted-foreground", children: "No commands found" }) : filteredCommands.map((item, index) => { const isActive = index === slashHighlightIndex; return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", { type: "button", role: "option", "aria-selected": isActive, "data-active": isActive ? "true" : void 0, "data-slash-index": index, className: (0, tailwind_merge.twMerge)("cpk:w-full cpk:px-3 cpk:py-2 cpk:text-left cpk:text-sm cpk:transition-colors", "cpk:hover:bg-muted cpk:dark:hover:bg-[#2f2f2f]", isActive ? "cpk:bg-muted cpk:dark:bg-[#2f2f2f]" : "cpk:bg-transparent"), onMouseEnter: () => setSlashHighlightIndex(index), onMouseDown: (event) => { event.preventDefault(); runCommand(item); }, children: item.label }, `${item.label}-${index}`); }) }) : null; const inputPill = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { "data-testid": "copilot-chat-input", className: (0, tailwind_merge.twMerge)("copilotKitInput", "cpk:flex cpk:w-full cpk:flex-col cpk:items-center cpk:justify-center", "cpk:cursor-text", "cpk:overflow-visible cpk:bg-clip-padding cpk:contain-inline-size", "cpk:bg-white cpk:dark:bg-[#303030]", "cpk:shadow-[0_4px_4px_0_#0000000a,0_0_1px_0_#0000009e] cpk:rounded-[28px]"), onClick: handleContainerClick, "data-layout": isExpanded ? "expanded" : "compact", children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { ref: gridRef, className: (0, tailwind_merge.twMerge)("cpk:grid cpk:w-full cpk:gap-x-3 cpk:gap-y-3 cpk:px-3 cpk:py-2", isExpanded ? "cpk:grid-cols-[auto_minmax(0,1fr)_auto] cpk:grid-rows-[auto_auto]" : "cpk:grid-cols-[auto_minmax(0,1fr)_auto] cpk:items-center"), "data-layout": isExpanded ? "expanded" : "compact", children: [ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { ref: addButtonContainerRef, className: (0, tailwind_merge.twMerge)("cpk:flex cpk:items-center", isExpanded ? "cpk:row-start-2" : "cpk:row-start-1", "cpk:col-start-1"), children: BoundAddMenuButton }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: (0, tailwind_merge.twMerge)("cpk:relative cpk:flex cpk:min-w-0 cpk:flex-col cpk:min-h-[50px] cpk:justify-center", isExpanded ? "cpk:col-span-3 cpk:row-start-1" : "cpk:col-start-2 cpk:row-start-1"), children: mode === "transcribe" ? BoundAudioRecorder : mode === "processing" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "cpk:flex cpk:w-full cpk:items-center cpk:justify-center cpk:py-3 cpk:px-5", children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Loader2, { className: "cpk:size-[26px] cpk:animate-spin cpk:text-muted-foreground" }) }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [BoundTextArea, slashMenu] }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { ref: actionsContainerRef, className: (0, tailwind_merge.twMerge)("cpk:flex cpk:items-center cpk:justify-end cpk:gap-2", isExpanded ? "cpk:col-start-3 cpk:row-start-2" : "cpk:col-start-3 cpk:row-start-1"), children: mode === "transcribe" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [onCancelTranscribe && BoundCancelTranscribeButton, onFinishTranscribe && BoundFinishTranscribeButton] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [onStartTranscribe && BoundStartTranscribeButton, BoundSendButton] }) }) ] }) }); return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { "data-copilotkit": true, ref: containerRef, className: cn(positioning === "absolute" && "cpk:absolute cpk:bottom-0 cpk:left-0 cpk:right-0 cpk:z-20 cpk:pointer-events-none", className), style: { transform: keyboardHeight > 0 ? `translateY(-${keyboardHeight}px)` : void 0, transition: "transform 0.2s ease-out" }, ...props, children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "cpk:max-w-3xl cpk:mx-auto cpk:py-0 cpk:px-4 cpk:sm:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-4 cpk:pointer-events-auto", children: inputPill }), shouldShowDisclaimer && BoundDisclaimer] }); } (function(_CopilotChatInput) { _CopilotChatInput.SendButton = ({ className, children, ...props }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "cpk:mr-[10px]", children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, { type: "button", "data-testid": "copilot-send-button", variant: "chatInputToolbarPrimary", size: "chatInputToolbarIcon", className, ...props, children: children !== null && children !== void 0 ? children : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ArrowUp, { className: "cpk:size-[18px]" }) }) }); const ToolbarButton = _CopilotChatInput.ToolbarButton = ({ icon, labelKey, defaultClassName, className, ...props }) => { var _config$labels2; const config = useCopilotChatConfiguration(); const labels = (_config$labels2 = config === null || config === void 0 ? void 0 : config.labels) !== null && _config$labels2 !== void 0 ? _config$labels2 : CopilotChatDefaultLabels; return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Tooltip, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, { type: "button", variant: "chatInputToolbarSecondary", size: "chatInputToolbarIcon", className: (0, tailwind_merge.twMerge)(defaultClassName, className), ...props, children: icon }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TooltipContent, { side: "bottom", children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: labels[labelKey] }) })] }); }; _CopilotChatInput.StartTranscribeButton = (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, { "data-testid": "copilot-start-transcribe-button", icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Mic, { className: "cpk:size-[18px]" }), labelKey: "chatInputToolbarStartTranscribeButtonLabel", defaultClassName: "cpk:mr-2", ...props }); _CopilotChatInput.CancelTranscribeButton = (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, { "data-testid": "copilot-cancel-transcribe-button", icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.X, { className: "cpk:size-[18px]" }), labelKey: "chatInputToolbarCancelTranscribeButtonLabel", defaultClassName: "cpk:mr-2", ...props }); _CopilotChatInput.FinishTranscribeButton = (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, { "data-testid": "copilot-finish-transcribe-button", icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Check, { className: "cpk:size-[18px]" }), labelKey: "chatInputToolbarFinishTranscribeButtonLabel", defaultClassName: "cpk:mr-[10px]", ...props }); _CopilotChatInput.AddMenuButton = ({ className, toolsMenu, onAddFile, disabled, ...props }) => { var _config$labels3; const config = useCopilotChatConfiguration(); const labels = (_config$labels3 = config === null || config === void 0 ? void 0 : config.labels) !== null && _config$labels3 !== void 0 ? _config$labels3 : CopilotChatDefaultLabels; const menuItems = (0, react.useMemo)(() => { const items = []; if (onAddFile) items.push({ label: labels.chatInputToolbarAddButtonLabel, action: onAddFile }); if (toolsMenu && toolsMenu.length > 0) { if (items.length > 0) items.push("-"); for (const item of toolsMenu) if (item === "-") { if (items.length === 0 || items[items.length - 1] === "-") continue; items.push(item); } else items.push(item); while (items.length > 0 && items[items.length - 1] === "-") items.pop(); } return items; }, [ onAddFile, toolsMenu, labels.chatInputToolbarAddButtonLabel ]); const renderMenuItems = (0, react.useCallback)((items) => items.map((item, index) => { if (item === "-") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DropdownMenuSeparator, {}, `separator-${index}`); if (item.items && item.items.length > 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(DropdownMenuSub, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(DropdownMenuSubTrigger, { children: item.label }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DropdownMenuSubContent, { children: renderMenuItems(item.items) })] }, `group-${index}`); return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DropdownMenuItem, { onClick: item.action, children: item.label }, `item-${index}`); }), []); const hasMenuItems = menuItems.length > 0; const isDisabled = disabled || !hasMenuItems; return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(DropdownMenu, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Tooltip, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, { type: "button", "data-testid": "copilot-add-menu-button", variant: "chatInputToolbarSecondary", size: "chatInputToolbarIcon", className: (0, tailwind_merge.twMerge)("cpk:ml-1", className), disabled: isDisabled, ...props, children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Plus, { className: "cpk:size-[20px]" }) }) }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TooltipContent, { side: "bottom", children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", { className: "cpk:flex cpk:items-center cpk:gap-1 cpk:text-xs cpk:font-medium", children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Add files and more" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { className: "cpk:rounded cpk:bg-[#4a4a4a] cpk:px-1 cpk:py-[1px] cpk:font-mono cpk:text-[11px] cpk:text-white cpk:dark:bg-[#e0e0e0] cpk:dark:text-black", children: "/" })] }) })] }), hasMenuItems && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DropdownMenuContent, { side: "top", align: "start", children: renderMenuItems(menuItems) })] }); }; _CopilotChatInput.TextArea = (0, react.forwardRef)(function TextArea({ style, className, autoFocus, placeholder, ...props }, ref) { var _config$labels4; const internalTextareaRef = (0, react.useRef)(null); const config = useCopilotChatConfiguration(); const labels = (_config$labels4 = config === null || config === void 0 ? void 0 : config.labels) !== null && _config$labels4 !== void 0 ? _config$labels4 : CopilotChatDefaultLabels; (0, react.useImperativeHandle)(ref, () => internalTextareaRef.current); (0, react.useEffect)(() => { const textarea = internalTextareaRef.current; if (!textarea) return; const handleFocus = () => { setTimeout(() => { textarea.scrollIntoView({ behavior: "smooth", block: "nearest" }); }, 300); }; textarea.addEventListener("focus", handleFocus); return () => textarea.removeEventListener("focus", handleFocus); }, []); (0, react.useEffect)(() => { if (autoFocus) { var _internalTextareaRef$; (_internalTextareaRef$ = internalTextareaRef.current) === null || _internalTextareaRef$ === void 0 || _internalTextareaRef$.focus(); } }, [autoFocus]); return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", { ref: internalTextareaRef, "data-testid": "copilot-chat-textarea", placeholder: placeholder !== null && placeholder !== void 0 ? placeholder : labels.chatInputPlaceholder, className: (0, tailwind_merge.twMerge)("cpk:bg-transparent cpk:outline-none cpk:antialiased cpk:font-regular cpk:leading-relaxed cpk:text-[16px] cpk:placeholder:text-[#00000077] cpk:dark:placeholder:text-[#fffc]", className), style: { overflow: "auto", resize: "none", ...style }, rows: 1, ...props }); }); _CopilotChatInput.AudioRecorder = CopilotChatAudioRecorder; _CopilotChatInput.Disclaimer = ({ className, ...props }) => { var _config$labels5; const config = useCopilotChatConfiguration(); const labels = (_config$labels5 = config === null || config === void 0 ? void 0 : config.labels) !== null && _config$labels5 !== void 0 ? _config$labels5 : CopilotChatDefaultLabels; return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: cn("cpk:text-center cpk:text-xs cpk:text-muted-foreground cpk:py-3 cpk:px-4 cpk:max-w-3xl cpk:mx-auto", className), ...props, children: labels.chatDisclaimerText }); }; })(CopilotChatInput || (CopilotChatInput = {})); CopilotChatInput.TextArea.displayName = "CopilotChatInput.TextArea"; CopilotChatInput.SendButton.displayName = "CopilotChatInput.SendButton"; CopilotChatInput.ToolbarButton.displayName = "CopilotChatInput.ToolbarButton"; CopilotChatInput.StartTranscribeButton.displayName = "CopilotChatInput.StartTranscribeButton"; CopilotChatInput.CancelTranscribeButton.displayName = "CopilotChatInput.CancelTranscribeButton"; CopilotChatInput.FinishTranscribeButton.displayName = "CopilotChatInput.FinishTranscribeButton"; CopilotChatInput.AddMenuButton.displayName = "CopilotChatInput.AddMenuButton"; CopilotChatInput.Disclaimer.displayName = "CopilotChatInput.Disclaimer"; var CopilotChatInput_default = CopilotChatInput; //#endregion //#region src/hooks/useKatexStyles.ts let injected = false; /** * Dynamically injects KaTeX CSS at runtime to avoid the Next.js * "Global CSS cannot be imported from within node_modules" build error. * * Uses a singleton flag so the stylesheet is only injected once. */ function useKatexStyles() { (0, react.useEffect)(() => { if (injected || typeof document === "undefined") return; injected = true; import("katex/dist/katex.min.css").catch(() => {}); }, []); } //#endregion //#region src/components/CopilotKitInspector.tsx const CopilotKitInspector = ({ core, ...rest }) => { const [InspectorComponent, setInspectorComponent] = react.useState(null); react.useEffect(() => { let mounted = true; import("@copilotkitnext/web-inspector").then((mod) => { var _mod$defineWebInspect; (_mod$defineWebInspect = mod.defineWebInspector) === null || _mod$defineWebInspect === void 0 || _mod$defineWebInspect.call(mod); const Component = (0, _lit_labs_react.createComponent)({ tagName: mod.WEB_INSPECTOR_TAG, elementClass: mod.WebInspectorElement, react }); if (mounted) setInspectorComponent(() => Component); }); return () => { mounted = false; }; }, []); if (!InspectorComponent) return null; return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InspectorComponent, { ...rest, core: core !== null && core !== void 0 ? core : null }); }; CopilotKitInspector.displayName = "CopilotKitInspector"; //#endregion //#region \0@oxc-project+runtime@0.112.0/helpers/typeof.js function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) { return typeof o; } : function(o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } //#endregion //#region \0@oxc-project+runtime@0.112.0/helpers/toPrimitive.js function toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } //#endregion //#region \0@oxc-project+runtime@0.112.0/helpers/toPropertyKey.js function toPropertyKey(t) { var i = toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } //#endregion //#region \0@oxc-project+runtime@0.112.0/helpers/defineProperty.js function _defineProperty(e, r, t) { return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } //#endregion //#region src/components/MCPAppsActivityRenderer.tsx const PROTOCOL_VERSION = "2025-06-18"; function buildSandboxHTML(extraCspDomains) { const baseScriptSrc = "'self' 'wasm-unsafe-eval' 'unsafe-inline' 'unsafe-eval' blob: data: http://localhost:* https://localhost:*"; const baseFrameSrc = "* blob: data: http://localhost:* https://localhost:*"; const extra = (extraCspDomains === null || extraCspDomains === void 0 ? void 0 : extraCspDomains.length) ? " " + extraCspDomains.join(" ") : ""; return `