UNPKG

@copilotkit/react-core

Version:

<img src="https://github.com/user-attachments/assets/0a6b64d9-e193-4940-a3f6-60334ac34084" alt="banner" style="border-radius: 12px; border: 2px solid #d6d4fa;" />

11,957 lines 457 kB
import * as React$1 from "react";
import React, { createContext, forwardRef, memo, useCallback, useContext, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useReducer, useRef, useState, useSyncExternalStore } from "react";
import { CopilotKitCore, CopilotKitCoreRuntimeConnectionStatus, ProxiedCopilotRuntimeAgent, ToolCallStatus, isRunCompletionAware, ɵInterruptState, ɵcreateThreadStore, ɵselectFetchMoreError, ɵselectHasNextPage, ɵselectIsFetchingNextPage, ɵselectIsMutating, ɵselectMemories, ɵselectMemoriesAvailable, ɵselectMemoriesError, ɵselectMemoriesIsLoading, ɵselectMemoriesRealtimeStatus, ɵselectThreads, ɵselectThreadsError, ɵselectThreadsIsLoading } from "@copilotkit/core";
import { HttpAgent, randomUUID } from "@ag-ui/client";
import { extendTailwindMerge, twMerge } from "tailwind-merge";
import { ArrowUp, Check, ChevronDown, ChevronLeft, ChevronRight, ChevronRightIcon, Copy, Edit, Loader2, MessageCircle, Mic, PanelLeftOpen, Play, Plus, RefreshCw, Square, ThumbsDown, ThumbsUp, Upload, Volume2, X } from "lucide-react";
import { A2UI_DEFAULT_DESIGN_GUIDELINES, A2UI_DEFAULT_GENERATION_GUIDELINES, COPILOT_CLOUD_API_URL, COPILOT_CLOUD_CHAT_URL, COPILOT_CLOUD_PUBLIC_API_KEY_HEADER, ConfigurationError, CopilotKitAgentDiscoveryError, CopilotKitApiDiscoveryError, CopilotKitError, CopilotKitErrorCode, CopilotKitLowLevelError, CopilotKitRemoteEndpointDiscoveryError, DEFAULT_AGENT_ID, ErrorVisibility, MissingPublicApiKeyError, Severity, TranscriptionErrorCode, TranscriptionErrorCode as TranscriptionErrorCode$1, copyToClipboard, createLicenseContextValue, dataToUUID, exceedsMaxSize, formatFileSize, generateVideoThumbnail, getDocumentIcon, getModalityFromMimeType, getSourceUrl, matchesAcceptFilter, parseJson, partialJSONParse, randomId, randomUUID as randomUUID$1, readFileAsBase64, schemaToJsonSchema } from "@copilotkit/shared";
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
import { Slot } from "@radix-ui/react-slot";
import { cva } from "class-variance-authority";
import { clsx } from "clsx";
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
import { Streamdown } from "streamdown";
import { CopilotKitContext, LicenseContext, useCopilotKit, useCopilotKit as useCopilotKit$1, useLicenseContext, useLicenseContext as useLicenseContext$1 } from "@copilotkit/react-core/v2/context";
import { z } from "zod";
import { createComponent } from "@lit-labs/react";
import { A2UIProvider, A2UIRenderer, A2UI_SCHEMA_CONTEXT_DESCRIPTION, Catalog, DEFAULT_SURFACE_ID, buildCatalogContextValue, extractCatalogComponentSchemas, filterCatalog, initializeDefaultCatalog, injectStyles, useA2UIActions, useA2UIError, viewerTheme } from "@copilotkit/a2ui-renderer";
import { zodToJsonSchema } from "zod-to-json-schema";
import { createPortal, flushSync } from "react-dom";
import { useVirtualizer } from "@tanstack/react-virtual";
import { StickToBottom, useStickToBottomContext } from "use-stick-to-bottom";
import { COPILOTKIT_THREADS_DRAWER_TAG, defineCopilotKitThreadsDrawer } from "@copilotkit/web-components/threads-drawer";
import ReactMarkdown from "react-markdown";

//#region src/v2/lib/shallow-stable-ref.ts
/**
* 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;
}
/**
* Returns true only for plain JS objects (`{}`), excluding arrays, Dates,
* class instances, and other exotic objects that happen to have typeof "object".
*/
function isPlainObject(obj) {
	return obj !== null && typeof obj === "object" && Object.prototype.toString.call(obj) === "[object Object]";
}
/**
* Returns the same reference as long as the value is shallowly equal to the
* previous render's value.
*
* - Identical references bail out immediately (O(1)).
* - Plain objects ({}) are shallow-compared key-by-key.
* - Arrays, Dates, class instances, functions, and primitives are compared by
*   reference only — shallowEqual is never called on non-plain objects, which
*   avoids incorrect equality for e.g. [1,2] vs [1,2] (different arrays).
*
* Typical use: stabilize inline slot props so MemoizedSlotWrapper's shallow
* equality check isn't defeated by a new object reference on every render.
*/
function useShallowStableRef(value) {
	const ref = useRef(value);
	if (ref.current === value) return ref.current;
	if (isPlainObject(ref.current) && isPlainObject(value)) {
		if (shallowEqual(ref.current, value)) return ref.current;
	}
	ref.current = value;
	return ref.current;
}

//#endregion
//#region src/v2/providers/CopilotChatConfigurationProvider.tsx
const CopilotChatDefaultLabels = {
	chatInputPlaceholder: "Type a message...",
	chatInputToolbarStartTranscribeButtonLabel: "Transcribe",
	chatInputToolbarCancelTranscribeButtonLabel: "Cancel",
	chatInputToolbarFinishTranscribeButtonLabel: "Finish",
	chatInputToolbarAddButtonLabel: "Add attachments",
	chatInputToolbarToolsButtonLabel: "Tools",
	assistantMessageToolbarCopyCodeLabel: "Copy",
	assistantMessageToolbarCopyCodeCopiedLabel: "Copied",
	assistantMessageToolbarCopyMessageLabel: "Copy",
	assistantMessageToolbarInspectorLabel: "View in Inspector",
	assistantMessageToolbarInspectorLocalOnlyLabel: "Local Only",
	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?"
};
/**
* Mobile breakpoint below which the chat modal and the thread-list drawer are
* mutually exclusive. At or above this width both surfaces may coexist. This
* mirrors the `(max-width: 767px)` / `(min-width: 768px)` split already used by
* CopilotChatInput and CopilotSidebarView.
*/
const MOBILE_MAX_WIDTH_PX = 767;
/**
* Reports whether the current viewport is in the mobile range (`<768px`), where
* the chat modal and drawer must not be open simultaneously. SSR-safe and
* defensive against environments without `matchMedia` (treated as desktop, so
* no mutual-exclusion constraint is applied).
*
* @returns `true` when the viewport is mobile-width, `false` otherwise.
*/
function isMobileViewport() {
	if (typeof window === "undefined" || typeof window.matchMedia !== "function") return false;
	return window.matchMedia(`(max-width: ${MOBILE_MAX_WIDTH_PX}px)`).matches;
}
const CopilotChatConfiguration = createContext(null);
const CopilotChatConfigurationProvider = ({ children, labels, agentId, threadId, hasExplicitThreadId, isModalDefaultOpen }) => {
	const parentConfig = useContext(CopilotChatConfiguration);
	const stableLabels = useShallowStableRef(labels);
	const mergedLabels = useMemo(() => ({
		...CopilotChatDefaultLabels,
		...parentConfig?.labels,
		...stableLabels
	}), [stableLabels, parentConfig?.labels]);
	const resolvedAgentId = agentId ?? parentConfig?.agentId ?? DEFAULT_AGENT_ID;
	const threadIdPropIsAuthoritative = threadId !== void 0 && hasExplicitThreadId !== false;
	const isThreadIdControlled = threadIdPropIsAuthoritative;
	const [activeThreadOverride, setActiveThreadOverride] = useState(null);
	const resolvedThreadId = useMemo(() => {
		if (threadIdPropIsAuthoritative) return threadId;
		if (activeThreadOverride) return activeThreadOverride.threadId;
		if (parentConfig?.threadId) return parentConfig.threadId;
		if (threadId) return threadId;
		return randomUUID$1();
	}, [
		threadIdPropIsAuthoritative,
		threadId,
		parentConfig?.threadId,
		activeThreadOverride
	]);
	const resolvedHasExplicitThreadId = (threadIdPropIsAuthoritative ? true : activeThreadOverride?.explicit ?? hasExplicitThreadId ?? false) || !!parentConfig?.hasExplicitThreadId;
	const [internalModalOpen, setInternalModalOpen] = useState(isModalDefaultOpen ?? true);
	const hasExplicitDefault = isModalDefaultOpen !== void 0;
	const setAndSync = useCallback((open) => {
		setInternalModalOpen(open);
		parentConfig?.setModalOpen(open);
	}, [parentConfig?.setModalOpen]);
	const isMounted = useRef(false);
	useEffect(() => {
		if (!hasExplicitDefault) return;
		if (!isMounted.current) {
			isMounted.current = true;
			return;
		}
		if (parentConfig?.isModalOpen === void 0) return;
		setInternalModalOpen(parentConfig.isModalOpen);
	}, [parentConfig?.isModalOpen, hasExplicitDefault]);
	const resolvedIsModalOpen = hasExplicitDefault ? internalModalOpen : parentConfig?.isModalOpen ?? internalModalOpen;
	const resolvedSetModalOpen = hasExplicitDefault ? setAndSync : parentConfig?.setModalOpen ?? setInternalModalOpen;
	const [ownDrawerOpen, setOwnDrawerOpen] = useState(false);
	const [ownDrawerCount, setOwnDrawerCount] = useState(0);
	const modalCloseRef = useRef(() => {});
	modalCloseRef.current = resolvedSetModalOpen;
	const registeredModalClosersRef = useRef([]);
	const ownRegisterModalCloser = useCallback((closeModal) => {
		registeredModalClosersRef.current.push(closeModal);
		return () => {
			registeredModalClosersRef.current = registeredModalClosersRef.current.filter((entry) => entry !== closeModal);
		};
	}, []);
	const ownSetDrawerOpen = useCallback((open) => {
		setOwnDrawerOpen(open);
		if (open && isMobileViewport()) {
			const registered = registeredModalClosersRef.current;
			(registered.length > 0 ? registered[registered.length - 1] : modalCloseRef.current)(false);
		}
	}, []);
	const ownRegisterDrawer = useCallback(() => {
		setOwnDrawerCount((count) => count + 1);
		return () => {
			setOwnDrawerCount((count) => Math.max(0, count - 1));
		};
	}, []);
	const resolvedDrawerOpen = parentConfig ? parentConfig.drawerOpen : ownDrawerOpen;
	const resolvedSetDrawerOpen = parentConfig ? parentConfig.setDrawerOpen : ownSetDrawerOpen;
	const resolvedDrawerRegistered = parentConfig ? parentConfig.drawerRegistered : ownDrawerCount > 0;
	const resolvedRegisterDrawer = parentConfig ? parentConfig.registerDrawer : ownRegisterDrawer;
	const resolvedRegisterModalCloser = parentConfig ? parentConfig.ɵregisterModalCloser : ownRegisterModalCloser;
	useEffect(() => {
		if (!hasExplicitDefault) return;
		return resolvedRegisterModalCloser(resolvedSetModalOpen);
	}, [
		hasExplicitDefault,
		resolvedRegisterModalCloser,
		resolvedSetModalOpen
	]);
	const isThreadIdControlledRef = useRef(isThreadIdControlled);
	isThreadIdControlledRef.current = isThreadIdControlled;
	const ownSetActiveThreadId = useCallback((id, options) => {
		setActiveThreadOverride({
			threadId: id,
			explicit: options?.explicit ?? true
		});
	}, []);
	const ownStartNewThread = useCallback(() => {
		setActiveThreadOverride({
			threadId: randomUUID$1(),
			explicit: false
		});
	}, []);
	const parentSetActiveThreadId = parentConfig?.setActiveThreadId;
	const parentStartNewThread = parentConfig?.startNewThread;
	const resolvedSetActiveThreadId = useCallback((id, options) => {
		if (isThreadIdControlledRef.current) {
			console.warn("[CopilotKit] Ignoring setActiveThreadId(): threadId is controlled via the `threadId` prop on CopilotChatConfigurationProvider.");
			return;
		}
		if (parentSetActiveThreadId) {
			parentSetActiveThreadId(id, options);
			return;
		}
		ownSetActiveThreadId(id, options);
	}, [parentSetActiveThreadId, ownSetActiveThreadId]);
	const resolvedStartNewThread = useCallback(() => {
		if (isThreadIdControlledRef.current) {
			console.warn("[CopilotKit] Ignoring startNewThread(): threadId is controlled via the `threadId` prop on CopilotChatConfigurationProvider.");
			return;
		}
		if (parentStartNewThread) {
			parentStartNewThread();
			return;
		}
		ownStartNewThread();
	}, [parentStartNewThread, ownStartNewThread]);
	const setModalOpenWithDrawerExclusion = useCallback((open) => {
		if (open && isMobileViewport()) resolvedSetDrawerOpen(false);
		resolvedSetModalOpen(open);
	}, [resolvedSetModalOpen, resolvedSetDrawerOpen]);
	const configurationValue = useMemo(() => ({
		labels: mergedLabels,
		agentId: resolvedAgentId,
		threadId: resolvedThreadId,
		hasExplicitThreadId: resolvedHasExplicitThreadId,
		isModalOpen: resolvedIsModalOpen,
		setModalOpen: setModalOpenWithDrawerExclusion,
		drawerOpen: resolvedDrawerOpen,
		setDrawerOpen: resolvedSetDrawerOpen,
		drawerRegistered: resolvedDrawerRegistered,
		registerDrawer: resolvedRegisterDrawer,
		ɵregisterModalCloser: resolvedRegisterModalCloser,
		setActiveThreadId: resolvedSetActiveThreadId,
		startNewThread: resolvedStartNewThread
	}), [
		mergedLabels,
		resolvedAgentId,
		resolvedThreadId,
		resolvedHasExplicitThreadId,
		resolvedIsModalOpen,
		setModalOpenWithDrawerExclusion,
		resolvedDrawerOpen,
		resolvedSetDrawerOpen,
		resolvedDrawerRegistered,
		resolvedRegisterDrawer,
		resolvedRegisterModalCloser,
		resolvedSetActiveThreadId,
		resolvedStartNewThread
	]);
	return /* @__PURE__ */ jsx(CopilotChatConfiguration.Provider, {
		value: configurationValue,
		children
	});
};
const useCopilotChatConfiguration = () => {
	return useContext(CopilotChatConfiguration);
};

//#endregion
//#region src/v2/lib/utils.ts
const twMerge$1 = extendTailwindMerge({ prefix: "cpk" });
function cn(...inputs) {
	return twMerge$1(clsx(inputs));
}

//#endregion
//#region src/v2/components/ui/button.tsx
const buttonVariants = 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"
	}
});
const Button = React$1.forwardRef(function Button({ className, variant, size, asChild = false, ...props }, ref) {
	return /* @__PURE__ */ jsx(asChild ? Slot : "button", {
		ref,
		"data-slot": "button",
		className: cn(buttonVariants({
			variant,
			size,
			className
		})),
		...props
	});
});

//#endregion
//#region src/v2/components/ui/tooltip.tsx
function TooltipProvider({ delayDuration = 0, ...props }) {
	return /* @__PURE__ */ jsx(TooltipPrimitive.Provider, {
		"data-slot": "tooltip-provider",
		delayDuration,
		...props
	});
}
function Tooltip({ ...props }) {
	return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsx(TooltipPrimitive.Root, {
		"data-slot": "tooltip",
		...props
	}) });
}
const TooltipTrigger = React$1.forwardRef(function TooltipTrigger({ ...props }, ref) {
	return /* @__PURE__ */ jsx(TooltipPrimitive.Trigger, {
		ref,
		"data-slot": "tooltip-trigger",
		...props
	});
});
function TooltipContent({ className, sideOffset = 0, children, ...props }) {
	return /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsxs(TooltipPrimitive.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__ */ jsx(TooltipPrimitive.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/v2/components/ui/dropdown-menu.tsx
function DropdownMenu({ ...props }) {
	return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Root, {
		"data-slot": "dropdown-menu",
		...props
	});
}
const DropdownMenuTrigger = React$1.forwardRef(function DropdownMenuTrigger({ ...props }, ref) {
	return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Trigger, {
		ref,
		"data-slot": "dropdown-menu-trigger",
		...props
	});
});
function DropdownMenuContent({ className, sideOffset = 4, ...props }) {
	return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.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__ */ jsx(DropdownMenuPrimitive.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__ */ jsx(DropdownMenuPrimitive.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__ */ jsx(DropdownMenuPrimitive.Sub, {
		"data-slot": "dropdown-menu-sub",
		...props
	});
}
function DropdownMenuSubTrigger({ className, inset, children, ...props }) {
	return /* @__PURE__ */ jsxs(DropdownMenuPrimitive.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__ */ jsx(ChevronRightIcon, { className: "cpk:ml-auto cpk:size-4" })]
	});
}
function DropdownMenuSubContent({ className, ...props }) {
	return /* @__PURE__ */ jsx(DropdownMenuPrimitive.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/v2/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 = forwardRef((props, ref) => {
	const { className, ...divProps } = props;
	const canvasRef = useRef(null);
	const [recorderState, setRecorderState] = useState("idle");
	const mediaRecorderRef = useRef(null);
	const audioChunksRef = useRef([]);
	const streamRef = useRef(null);
	const analyserRef = useRef(null);
	const audioContextRef = useRef(null);
	const animationIdRef = useRef(null);
	const amplitudeHistoryRef = useRef([]);
	const frameCountRef = useRef(0);
	const scrollOffsetRef = useRef(0);
	const smoothedAmplitudeRef = useRef(0);
	const fadeOpacityRef = useRef(0);
	const cleanup = useCallback(() => {
		if (animationIdRef.current) {
			cancelAnimationFrame(animationIdRef.current);
			animationIdRef.current = null;
		}
		if (mediaRecorderRef.current && mediaRecorderRef.current.state !== "inactive") try {
			mediaRecorderRef.current.stop();
		} catch {}
		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 = 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 = 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++) {
			const sample = (dataArray[i] ?? 128) / 128 - 1;
			sum += sample * sample;
		}
		return Math.sqrt(sum / dataArray.length);
	};
	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++) {
					const amplitude = 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]);
	useEffect(() => {
		return cleanup;
	}, [cleanup]);
	useImperativeHandle(ref, () => ({
		get state() {
			return recorderState;
		},
		start,
		stop,
		dispose: cleanup
	}), [
		recorderState,
		start,
		stop,
		cleanup
	]);
	return /* @__PURE__ */ jsx("div", {
		className: twMerge("cpk:w-full cpk:py-3 cpk:px-5", className),
		...divProps,
		children: /* @__PURE__ */ jsx("canvas", {
			ref: canvasRef,
			className: "cpk:block cpk:w-full cpk:h-[26px]"
		})
	});
});
CopilotChatAudioRecorder.displayName = "CopilotChatAudioRecorder";

//#endregion
//#region src/v2/lib/slots.tsx
/**
* 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.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.createElement(DefaultComponent, {
			...props,
			className: twMerge(existingClassName, slot)
		});
	}
	if (isReactComponentType(slot)) return React.createElement(slot, props);
	if (slot && typeof slot === "object" && !React.isValidElement(slot)) return React.createElement(DefaultComponent, {
		...props,
		...slot
	});
	return React.createElement(DefaultComponent, props);
}
/**
* Internal memoized wrapper component for renderSlot.
* Uses forwardRef to support ref forwarding.
*/
const MemoizedSlotWrapper = React.memo(React.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.createElement(MemoizedSlotWrapper, {
		...props,
		$slot: slot,
		$component: DefaultComponent
	});
}

//#endregion
//#region src/v2/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 = false, positioning = "static", keyboardHeight = 0, containerRef, showDisclaimer, bottomAnchored = false, textArea, sendButton, startTranscribeButton, cancelTranscribeButton, finishTranscribeButton, addMenuButton, audioRecorder, disclaimer, children, className, ...props }) {
	const isControlled = value !== void 0;
	const [internalValue, setInternalValue] = useState(() => value ?? "");
	useEffect(() => {
		if (!isControlled && value !== void 0) setInternalValue(value);
	}, [isControlled, value]);
	const resolvedValue = isControlled ? value ?? "" : internalValue;
	const [layout, setLayout] = useState("compact");
	const ignoreResizeRef = useRef(false);
	const resizeEvaluationRafRef = useRef(null);
	const isExpanded = mode === "input" && layout === "expanded";
	const [commandQuery, setCommandQuery] = useState(null);
	const [slashHighlightIndex, setSlashHighlightIndex] = useState(0);
	const inputRef = useRef(null);
	const gridRef = useRef(null);
	const addButtonContainerRef = useRef(null);
	const actionsContainerRef = useRef(null);
	const audioRecorderRef = useRef(null);
	const slashMenuRef = useRef(null);
	const config = useCopilotChatConfiguration();
	const labels = config?.labels ?? CopilotChatDefaultLabels;
	const previousModalStateRef = useRef(void 0);
	const measurementCanvasRef = useRef(null);
	const measurementsRef = useRef({
		singleLineHeight: 0,
		maxHeight: 0,
		paddingLeft: 0,
		paddingRight: 0
	});
	const containerCacheRef = useRef(null);
	const commandItems = 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 = 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]);
	useEffect(() => {
		if (!autoFocus) {
			previousModalStateRef.current = config?.isModalOpen;
			return;
		}
		if (config?.isModalOpen && !previousModalStateRef.current) inputRef.current?.focus({ preventScroll: true });
		previousModalStateRef.current = config?.isModalOpen;
	}, [config?.isModalOpen, autoFocus]);
	useEffect(() => {
		if (commandItems.length === 0 && commandQuery !== null) setCommandQuery(null);
	}, [commandItems.length, commandQuery]);
	const previousCommandQueryRef = useRef(null);
	useEffect(() => {
		if (commandQuery !== null && commandQuery !== previousCommandQueryRef.current && filteredCommands.length > 0) setSlashHighlightIndex(0);
		previousCommandQueryRef.current = commandQuery;
	}, [commandQuery, filteredCommands.length]);
	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
	]);
	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]);
	useEffect(() => {
		if (mode !== "input") {
			setLayout("compact");
			setCommandQuery(null);
		}
	}, [mode]);
	const updateSlashState = useCallback((value) => {
		if (commandItems.length === 0) {
			setCommandQuery((prev) => prev === null ? prev : null);
			return;
		}
		if (value.startsWith("/")) {
			const query = (value.split(/\r?\n/, 1)[0] ?? "").slice(1);
			setCommandQuery((prev) => prev === query ? prev : query);
		} else setCommandQuery((prev) => prev === null ? prev : null);
	}, [commandItems.length]);
	useEffect(() => {
		updateSlashState(resolvedValue);
	}, [resolvedValue, updateSlashState]);
	const handleChange = (e) => {
		const nextValue = e.target.value;
		if (!isControlled) setInternalValue(nextValue);
		onChange?.(nextValue);
		updateSlashState(nextValue);
	};
	const clearInputValue = useCallback(() => {
		if (!isControlled) setInternalValue("");
		if (onChange) onChange("");
	}, [isControlled, onChange]);
	const runCommand = useCallback((item) => {
		clearInputValue();
		item.action?.();
		setCommandQuery(null);
		setSlashHighlightIndex(0);
		requestAnimationFrame(() => {
			inputRef.current?.focus();
		});
	}, [clearInputValue]);
	const handleKeyDown = (e) => {
		if (e.nativeEvent.isComposing || e.keyCode === 229) return;
		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 && !canSend) onStop?.();
			else send();
		}
	};
	const send = () => {
		if (!onSubmitMessage) return;
		const trimmed = resolvedValue.trim();
		if (!trimmed) return;
		onSubmitMessage(trimmed);
		if (!isControlled) setInternalValue("");
		onChange?.("");
		if (inputRef.current) inputRef.current.focus();
	};
	const BoundTextArea = renderSlot(textArea, CopilotChatInput.TextArea, {
		ref: inputRef,
		value: resolvedValue,
		onChange: handleChange,
		onKeyDown: handleKeyDown,
		onCompositionStart: () => {
			isComposingRef.current = true;
		},
		onCompositionEnd: () => {
			isComposingRef.current = false;
		},
		autoFocus,
		className: 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?.();
			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__ */ jsx(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 = 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?.();
	}, [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 ?? 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,
			containerRef
		};
		return /* @__PURE__ */ 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 isComposingRef = useRef(false);
	const ensureMeasurements = useCallback(() => {
		const textarea = inputRef.current;
		if (!textarea || isComposingRef.current) 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 = 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 = useCallback((nextLayout) => {
		setLayout((prev) => {
			if (prev === nextLayout) return prev;
			ignoreResizeRef.current = true;
			return nextLayout;
		});
	}, []);
	const updateContainerCache = useCallback(() => {
		const grid = gridRef.current;
		const addContainer = addButtonContainerRef.current;
		const actionsContainer = actionsContainerRef.current;
		if (!grid || !addContainer || !actionsContainer) return null;
		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) return null;
		const addWidth = addContainer.getBoundingClientRect().width;
		const actionsWidth = actionsContainer.getBoundingClientRect().width;
		const compactWidth = Math.max(gridAvailableWidth - addWidth - actionsWidth - columnGap * 2, 0);
		if (compactWidth <= 0) return null;
		const result = { compactWidth };
		containerCacheRef.current = result;
		return result;
	}, []);
	const evaluateLayout = useCallback(() => {
		if (mode !== "input") {
			updateLayout("compact");
			return;
		}
		if (typeof window !== "undefined" && typeof window.matchMedia === "function") {
			if (window.matchMedia("(max-width: 767px)").matches) {
				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 cache = containerCacheRef.current ?? updateContainerCache();
			if (cache && cache.compactWidth > 0) {
				const compactInnerWidth = Math.max(cache.compactWidth - (measurementsRef.current.paddingLeft || 0) - (measurementsRef.current.paddingRight || 0), 0);
				if (compactInnerWidth > 0) {
					const textareaStyles = window.getComputedStyle(textarea);
					let font = textareaStyles.font;
					if (!font) {
						const { fontStyle, fontVariant, fontWeight, fontSize, lineHeight, fontFamily } = textareaStyles;
						if (fontSize && fontFamily) font = `${fontStyle} ${fontVariant} ${fontWeight} ${fontSize}/${lineHeight} ${fontFamily}`;
					}
					if (font?.trim()) {
						const canvas = measurementCanvasRef.current ?? document.createElement("canvas");
						if (!measurementCanvasRef.current) measurementCanvasRef.current = canvas;
						const context = canvas.getContext("2d");
						if (context) {
							context.font = font;
							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;
						} else if (process.env.NODE_ENV !== "production") console.warn("[CopilotChatInput] canvas.getContext('2d') returned null. Text-width-based expansion will be unavailable.");
					} else if (process.env.NODE_ENV !== "production") console.warn("[CopilotChatInput] Could not resolve textarea font for layout measurement. Text-width-based expansion will be skipped until the next evaluation.");
				}
			}
		}
		updateLayout(shouldExpand ? "expanded" : "compact");
	}, [
		adjustTextareaHeight,
		ensureMeasurements,
		mode,
		resolvedValue,
		updateContainerCache,
		updateLayout
	]);
	useLayoutEffect(() => {
		evaluateLayout();
	}, [evaluateLayout]);
	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 containerTargets = new Set([
			grid,
			addContainer,
			actionsContainer
		]);
		const scheduleEvaluation = (invalidateCache) => {
			if (ignoreResizeRef.current) {
				ignoreResizeRef.current = false;
				return;
			}
			if (invalidateCache) containerCacheRef.current = null;
			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((entries) => {
			let shouldInvalidate = false;
			for (const entry of entries) if (containerTargets.has(entry.target)) {
				shouldInvalidate = true;
				break;
			}
			scheduleEvaluation(shouldInvalidate);
		});
		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;
	useEffect(() => {
		if (!slashMenuVisible || slashHighlightIndex < 0) return;
		(slashMenuRef.current?.querySelector(`[data-slash-index="${slashHighlightIndex}"]`))?.scrollIntoView({ block: "nearest" });
	}, [slashMenuVisible, slashHighlightIndex]);
	const slashMenu = slashMenuVisible ? /* @__PURE__ */ 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__ */ 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__ */ jsx("button", {
				type: "button",
				role: "option",
				"aria-selected": isActive,
				"data-active": isActive ? "true" : void 0,
				"data-slash-index": index,
				className: 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__ */ jsx("div", {
		"data-testid": "copilot-chat-input",
		className: 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__ */ jsxs("div", {
			ref: gridRef,
			className: 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__ */ jsx("div", {
					ref: addButtonContainerRef,
					className: twMerge("cpk:flex cpk:items-center", isExpanded ? "cpk:row-start-2" : "cpk:row-start-1", "cpk:col-start-1"),
					children: BoundAddMenuButton
				}),
				/* @__PURE__ */ jsx("div", {
					className: 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__ */ jsx("div", {
						className: "cpk:flex cpk:w-full cpk:items-center cpk:justify-center cpk:py-3 cpk:px-5",
						children: /* @__PURE__ */ jsx(Loader2, { className: "cpk:size-[26px] cpk:animate-spin cpk:text-muted-foreground" })
					}) : /* @__PURE__ */ jsxs(Fragment$1, { children: [BoundTextArea, slashMenu] })
				}),
				/* @__PURE__ */ jsx("div", {
					ref: actionsContainerRef,
					className: 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__ */ jsxs(Fragment$1, { children: [onCancelTranscribe && BoundCancelTranscribeButton, onFinishTranscribe && BoundFinishTranscribeButton] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [onStartTranscribe && BoundStartTranscribeButton, BoundSendButton] })
				})
			]
		})
	});
	return /* @__PURE__ */ jsxs("div", {
		"data-copilotkit": true,
		ref: containerRef,
		className: cn("cpk:pointer-events-none cpk:relative cpk:z-20", positioning === "absolute" && "cpk:absolute cpk:bottom-0 cpk:left-0 cpk:right-0", className),
		style: {
			transform: keyboardHeight > 0 ? `translateY(-${keyboardHeight}px)` : void 0,
			transition: "transform 0.2s ease-out",
			...positioning === "absolute" || bottomAnchored ? { paddingBottom: "var(--copilotkit-license-banner-offset, 0px)" } : {}
		},
		...props,
		children: [/* @__PURE__ */ jsx("div", {
			className: "cpk:max-w-3xl cpk:mx-auto cpk:py-0 cpk:px-4 cpk:@3xl: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__ */ jsx("div", {
		className: "cpk:mr-[10px]",
		children: /* @__PURE__ */ jsx(Button, {
			type: "button",
			"data-testid": "copilot-send-button",
			variant: "chatInputToolbarPrimary",
			size: "chatInputToolbarIcon",
			className,
			...props,
			children: children ?? /* @__PURE__ */ jsx(ArrowUp, { className: "cpk:size-[18px]" })
		})
	});
	const ToolbarButton = _CopilotChatInput.ToolbarButton = ({ icon, labelKey, defaultClassName, className, ...props }) => {
		const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
		return /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
			asChild: true,
			children: /* @__PURE__ */ jsx(Button, {
				type: "button",
				variant: "chatInputToolbarSecondary",
				size: "chatInputToolbarIcon",
				className: twMerge(defaultClassName, className),
				...props,
				children: icon
			})
		}), /* @__PURE__ */ jsx(TooltipContent, {
			side: "bottom",
			children: /* @__PURE__ */ jsx("p", { children: labels[labelKey] })
		})] });
	};
	_CopilotChatInput.StartTranscribeButton = (props) => /* @__PURE__ */ jsx(ToolbarButton, {
		"data-testid": "copilot-start-transcribe-button",
		icon: /* @__PURE__ */ jsx(Mic, { className: "cpk:size-[18px]" }),
		labelKey: "chatInputToolbarStartTranscribeButtonLabel",
		defaultClassName: "cpk:mr-2",
		...props
	});
	_CopilotChatInput.CancelTranscribeButton = (props) => /* @__PURE__ */ jsx(ToolbarButton, {
		"data-testid": "copilot-cancel-transcribe-button",
		icon: /* @__PURE__ */ jsx(X, { className: "cpk:size-[18px]" }),
		labelKey: "chatInputToolbarCancelTranscribeButtonLabel",
		defaultClassName: "cpk:mr-2",
		...props
	});
	_CopilotChatInput.FinishTranscribeButton = (props) => /* @__PURE__ */ jsx(ToolbarButton, {
		"data-testid": "copilot-finish-transcribe-button",
		icon: /* @__PURE__ */ jsx(Check, { className: "cpk:size-[18px]" }),
		labelKey: "chatInputToolbarFinishTranscribeButtonLabel",
		defaultClassName: "cpk:mr-[10px]",
		...props
	});
	_CopilotChatInput.AddMenuButton = ({ className, toolsMenu, onAddFile, disabled, ...props }) => {
		const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
		const [mounted, setMounted] = useState(false);
		useEffect(() => setMounted(true), []);
		const menuItems = 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 = useCallback((items) => items.map((item, index) => {
			if (item === "-") return /* @__PURE__ */ jsx(DropdownMenuSeparator, {}, `separator-${index}`);
			if (item.items && item.items.length > 0) return /* @__PURE__ */ jsxs(DropdownMenuSub, { children: [/* @__PURE__ */ jsx(DropdownMenuSubTrigger, { children: item.label }), /* @__PURE__ */ jsx(DropdownMenuSubContent, { children: renderMenuItems(item.items) })] }, `group-${index}`);
			return /* @__PURE__ */ jsx(DropdownMenuItem, {
				onClick: item.action,
				children: item.label
			}, `item-${index}`);
		}), []);
		const hasMenuItems = menuItems.length > 0;
		const isDisabled = disabled || !hasMenuItems;
		const button = /* @__PURE__ */ jsx(Button, {
			type: "button",
			"data-testid": "copilot-add-menu-button",
			variant: "chatInputToolbarSecondary",
			size: "chatInputToolbarIcon",
			className: twMerge("cpk:ml-1", className),
			disabled: isDisabled,
			...props,
			children: /* @__PURE__ */ jsx(Plus, { className: "cpk:size-[20px]" })
		});
		if (!mounted) return button;
		return /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
			asChild: true,
			children: /* @__PURE__ */ jsx(DropdownMenuTrigger, {
				asChild: true,
				children: button
			})
		}), /* @__PURE__ */ jsx(TooltipContent, {
			side: "bottom",
			children: /* @__PURE__ */ jsxs("p", {
				className: "cpk:flex cpk:items-center cpk:gap-1 cpk:text-xs cpk:font-medium",
				children: [/* @__PURE__ */ jsx("span", { children: "Add attachments" }), /* @__PURE__ */ 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__ */ jsx(DropdownMenuContent, {
			side: "top",
			align: "start",
			children: renderMenuItems(menuItems)
		})] });
	};
	_CopilotChatInput.TextArea = forwardRef(function TextArea({ style, className, autoFocus, placeholder, ...props }, ref) {
		const internalTextareaRef = useRef(null);
		const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
		useImperativeHandle(ref, () => internalTextareaRef.current);
		useEffect(() => {
			if (autoFocus) internalTextareaRef.current?.focus({ preventScroll: true });
		}, [autoFocus]);
		return /* @__PURE__ */ jsx("textarea", {
			ref: internalTextareaRef,
			"data-testid": "copilot-chat-textarea",
			placeholder: placeholder ?? labels.chatInputPlaceholder,
			className: 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 }) => {
		const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
		return /* @__PURE__ */ 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/v2/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() {
	useEffect(() => {
		if (injected || typeof document === "undefined") return;
		injected = true;
		import("katex/dist/katex.min.css").catch(() => {
			console.warn("[CopilotKit] Failed to load katex styles — math content may render without formatting");
		});
	}, []);
}

//#endregion
//#region src/v2/hooks/use-render-tool-call.tsx
/**
* Memoized component that renders a single tool call.
* This prevents unnecessary re-renders when parent components update
* but the tool call data hasn't changed.
*/
const ToolCallRenderer = React.memo(function ToolCallRenderer({ toolCall, toolMessage, RenderComponent, isExecuting }) {
	const args = useMemo(() => partialJSONParse(toolCall.function.arguments), [toolCall.function.arguments]);
	const toolName = toolCall.function.name;
	if (toolMessage) return /* @__PURE__ */ jsx(RenderComponent, {
		name: toolName,
		toolCallId: toolCall.id,
		args,
		status: ToolCallStatus.Complete,
		result: toolMessage.content
	});
	else if (isExecuting) return /* @__PURE__ */ jsx(RenderComponent, {
		name: toolName,
		toolCallId: toolCall.id,
		args,
		status: ToolCallStatus.Executing,
		result: void 0
	});
	else return /* @__PURE__ */ jsx(RenderComponent, {
		name: toolName,
		toolCallId: toolCall.id,
		args,
		status: ToolCallStatus.InProgress,
		result: void 0
	});
}, (prevProps, nextProps) => {
	if (prevProps.toolCall.id !== nextProps.toolCall.id) return false;
	if (prevProps.toolCall.function.name !== nextProps.toolCall.function.name) return false;
	if (prevProps.toolCall.function.arguments !== nextProps.toolCall.function.arguments) return false;
	if (prevProps.toolMessage?.content !== nextProps.toolMessage?.content) return false;
	if (prevProps.isExecuting !== nextProps.isExecuting) return false;
	if (prevProps.RenderComponent !== nextProps.RenderComponent) return false;
	return true;
});
/**
* Hook that returns a function to render tool calls based on the render functions
* defined in CopilotKitProvider.
*
* @returns A function that takes a tool call and optional tool message and returns the rendered component
*/
function useRenderToolCall() {
	const { copilotkit, executingToolCallIds } = useCopilotKit();
	const agentId = useCopilotChatConfiguration()?.agentId ?? DEFAULT_AGENT_ID;
	const renderToolCalls = useSyncExternalStore((callback) => {
		return copilotkit.subscribe({ onRenderToolCallsChanged: callback }).unsubscribe;
	}, () => copilotkit.renderToolCalls, () => copilotkit.renderToolCalls);
	return useCallback(({ toolCall, toolMessage }) => {
		const exactMatches = renderToolCalls.filter((rc) => rc.name === toolCall.function.name);
		const renderConfig = exactMatches.find((rc) => rc.agentId === agentId) || exactMatches.find((rc) => !rc.agentId) || exactMatches[0] || renderToolCalls.find((rc) => rc.name === "*");
		if (!renderConfig) return null;
		const RenderComponent = renderConfig.render;
		return /* @__PURE__ */ jsx(ToolCallRenderer, {
			toolCall,
			toolMessage,
			RenderComponent,
			isExecuting: executingToolCallIds.has(toolCall.id)
		}, toolCall.id);
	}, [
		renderToolCalls,
		executingToolCallIds,
		agentId
	]);
}

//#endregion
//#region src/v2/components/CopilotKitInspector.tsx
const CopilotKitInspector = ({ core, openRequest, ...rest }) => {
	const [InspectorComponent, setInspectorComponent] = React$1.useState(null);
	const inspectorRef = React$1.useRef(null);
	React$1.useEffect(() => {
		let mounted = true;
		import("@copilotkit/web-inspector").then((mod) => {
			mod.defineWebInspector?.();
			const Component = createComponent({
				tagName: mod.WEB_INSPECTOR_TAG,
				elementClass: mod.WebInspectorElement,
				react: React$1
			});
			if (mounted) setInspectorComponent(() => Component);
		});
		return () => {
			mounted = false;
		};
	}, []);
	React$1.useEffect(() => {
		if (openRequest) inspectorRef.current?.openInspector("message_toolbar", openRequest);
	}, [InspectorComponent, openRequest]);
	if (!InspectorComponent) return null;
	return /* @__PURE__ */ jsx(InspectorComponent, {
		ref: inspectorRef,
		...rest,
		core: core ?? null
	});
};
CopilotKitInspector.displayName = "CopilotKitInspector";

//#endregion
//#region src/v2/components/CopilotKitInspectorContext.tsx
const CopilotKitInspectorContext = React$1.createContext({
	isLocalInspectorEnabled: false,
	openInspector: () => void 0
});
const CopilotKitInspectorContextProvider = CopilotKitInspectorContext.Provider;
function useCopilotKitInspector() {
	return React$1.useContext(CopilotKitInspectorContext);
}

//#endregion
//#region src/v2/components/license-warning-banner.tsx
const LICENSE_BANNER_OFFSET_PX = 52;
const LICENSE_BANNER_OFFSET_VAR = "--copilotkit-license-banner-offset";
const BANNER_STYLES = {
	base: {
		position: "fixed",
		bottom: "8px",
		left: "50%",
		transform: "translateX(-50%)",
		zIndex: 99999,
		display: "inline-flex",
		alignItems: "center",
		gap: "12px",
		whiteSpace: "nowrap",
		padding: "8px 16px",
		fontSize: "13px",
		fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif",
		borderRadius: "6px",
		boxShadow: "0 2px 8px rgba(0, 0, 0, 0.15)"
	},
	info: {
		backgroundColor: "#eff6ff",
		border: "1px solid #93c5fd",
		color: "#1e40af"
	},
	warning: {
		backgroundColor: "#fffbeb",
		border: "1px solid #fbbf24",
		color: "#92400e"
	},
	critical: {
		backgroundColor: "#fef2f2",
		border: "1px solid #fca5a5",
		color: "#991b1b"
	}
};
function getSeverityStyle(severity) {
	switch (severity) {
		case "warning": return BANNER_STYLES.warning;
		case "critical": return BANNER_STYLES.critical;
		default: return BANNER_STYLES.info;
	}
}
function BannerShell({ severity, message, actionLabel, actionUrl, onDismiss }) {
	useEffect(() => {
		if (typeof document === "undefined") return;
		const root = document.documentElement;
		root.style.setProperty(LICENSE_BANNER_OFFSET_VAR, `${LICENSE_BANNER_OFFSET_PX}px`);
		return () => {
			root.style.removeProperty(LICENSE_BANNER_OFFSET_VAR);
		};
	}, []);
	return /* @__PURE__ */ jsxs("div", {
		style: {
			...BANNER_STYLES.base,
			...getSeverityStyle(severity)
		},
		children: [/* @__PURE__ */ jsx("span", { children: message }), /* @__PURE__ */ jsxs("div", {
			style: {
				display: "flex",
				gap: "8px",
				alignItems: "center"
			},
			children: [/* @__PURE__ */ jsx("a", {
				href: actionUrl,
				target: "_blank",
				rel: "noopener noreferrer",
				style: {
					fontWeight: 600,
					textDecoration: "underline",
					color: "inherit"
				},
				children: actionLabel
			}), onDismiss && /* @__PURE__ */ jsx("button", {
				onClick: onDismiss,
				style: {
					background: "none",
					border: "none",
					cursor: "pointer",
					color: "inherit",
					fontSize: "16px"
				},
				children: "×"
			})]
		})]
	});
}
function LicenseWarningBanner({ type, featureName, expiryDate, graceRemaining, onDismiss }) {
	switch (type) {
		case "no_license": return /* @__PURE__ */ jsx(BannerShell, {
			severity: "info",
			message: "Powered by CopilotKit",
			actionLabel: "Get a license",
			actionUrl: "https://copilotkit.ai/pricing",
			onDismiss
		});
		case "feature_unlicensed": return /* @__PURE__ */ jsx(BannerShell, {
			severity: "warning",
			message: `⚠ The "${featureName}" feature requires a CopilotKit license.`,
			actionLabel: "Get a license",
			actionUrl: "https://copilotkit.ai/pricing",
			onDismiss
		});
		case "expiring": return /* @__PURE__ */ jsx(BannerShell, {
			severity: "warning",
			message: `Your CopilotKit license expires in ${graceRemaining} day${graceRemaining !== 1 ? "s" : ""}. Please renew.`,
			actionLabel: "Renew",
			actionUrl: "https://dashboard.operations.copilotkit.ai",
			onDismiss
		});
		case "expired": return /* @__PURE__ */ jsx(BannerShell, {
			severity: "critical",
			message: `Your CopilotKit license expired${expiryDate ? ` on ${expiryDate}` : ""}. Please renew at copilotkit.ai/pricing`,
			actionLabel: "Renew now",
			actionUrl: "https://copilotkit.ai/pricing",
			onDismiss
		});
		case "invalid": return /* @__PURE__ */ jsx(BannerShell, {
			severity: "critical",
			message: "Invalid CopilotKit license token. Please check your configuration.",
			actionLabel: "Get a license",
			actionUrl: "https://copilotkit.ai/pricing",
			onDismiss
		});
		default: return null;
	}
}
function InlineFeatureWarning({ featureName }) {
	return /* @__PURE__ */ jsxs("div", {
		style: {
			padding: "8px 12px",
			backgroundColor: "#fffbeb",
			border: "1px solid #fbbf24",
			borderRadius: "6px",
			fontSize: "13px",
			color: "#92400e",
			fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif"
		},
		children: [
			"⚠ The \"",
			featureName,
			"\" feature requires a CopilotKit license.",
			" ",
			/* @__PURE__ */ jsx("a", {
				href: "https://copilotkit.ai/pricing",
				target: "_blank",
				rel: "noopener noreferrer",
				style: {
					color: "#b45309",
					textDecoration: "underline"
				},
				children: "Get one at copilotkit.ai/pricing"
			})
		]
	});
}

//#endregion
//#region src/v2/components/MCPAppsActivityRenderer.tsx
/**
* Run an MCP app `ui/message` follow-up, scoped to the thread it was enqueued
* for (issue #5819).
*
* The MCP request queue delays follow-up work until the agent is idle. There is
* a single shared registry agent per id, and switching threads overwrites its
* `threadId`/`messages` in place. So if the host switches threads while a
* follow-up is queued, running it now would execute against — and stream into —
* the now-foreground thread.
*
* - **Same thread** (the common case): run on the shared agent, unchanged.
* - **Thread changed**: the shared agent has moved on, so the follow-up can no
*   longer run in its originating thread's context. Drop it rather than leak it
*   into the current thread. (The MCP app already received its `ui/message` ack
*   at enqueue time; only the optional agent turn is skipped.)
*
* @internal exported for testing.
*/
async function ɵrunMcpFollowUp({ host, agent, capturedThreadId }) {
	const currentThreadId = agent.threadId || "default";
	const originThreadId = capturedThreadId || "default";
	if (currentThreadId === originThreadId) return host.runAgent({ agent });
	console.warn(`[MCPAppsRenderer] ui/message follow-up dropped: the thread changed (${originThreadId} → ${currentThreadId}) between enqueue and execution, so running it would leak into the now-foreground thread.`);
	return {
		result: void 0,
		newMessages: []
	};
}
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?.length ? " " + extraCspDomains.join(" ") : "";
	return `<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src * data: blob: 'unsafe-inline'; media-src * blob: data:; font-src * blob: data:; script-src ${baseScriptSrc + extra}; style-src * blob: data: 'unsafe-inline'; connect-src *; frame-src ${baseFrameSrc + extra}; base-uri 'self';" />
<style>html,body{margin:0;padding:0;height:100%;width:100%;overflow:hidden}*{box-sizing:border-box}iframe{background-color:transparent;border:none;padding:0;overflow:hidden;width:100%;height:100%}</style>
</head>
<body>
<script>
if(window.self===window.top){throw new Error("This file must be used in an iframe.")}
const inner=document.createElement("iframe");
inner.style="width:100%;height:100%;border:none;";
inner.setAttribute("sandbox","allow-scripts allow-same-origin allow-forms");
document.body.appendChild(inner);
window.addEventListener("message",async(event)=>{
if(event.source===window.parent){
if(event.data&&event.data.method==="ui/notifications/sandbox-resource-ready"){
const{html,sandbox}=event.data.params;
if(typeof sandbox==="string")inner.setAttribute("sandbox",sandbox);
if(typeof html==="string")inner.srcdoc=html;
}else if(inner&&inner.contentWindow){
inner.contentWindow.postMessage(event.data,"*");
}
}else if(event.source===inner.contentWindow){
window.parent.postMessage(event.data,"*");
}
});
window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-ready",params:{}},"*");
<\/script>
</body>
</html>`;
}
/**
* Queue for serializing MCP app requests to an agent.
* Ensures requests wait for the agent to stop running and are processed one at a time.
*/
var MCPAppsRequestQueue = class {
	constructor() {
		this.queues = /* @__PURE__ */ new Map();
		this.processing = /* @__PURE__ */ new Map();
	}
	/**
	* Add a request to the queue for a specific agent thread.
	* Returns a promise that resolves when the request completes.
	*/
	async enqueue(agent, request) {
		const threadId = agent.threadId || "default";
		return new Promise((resolve, reject) => {
			let queue = this.queues.get(threadId);
			if (!queue) {
				queue = [];
				this.queues.set(threadId, queue);
			}
			queue.push({
				execute: request,
				resolve,
				reject
			});
			this.processQueue(threadId, agent);
		});
	}
	async processQueue(threadId, agent) {
		if (this.processing.get(threadId)) return;
		this.processing.set(threadId, true);
		try {
			const queue = this.queues.get(threadId);
			if (!queue) return;
			while (queue.length > 0) {
				const item = queue[0];
				try {
					await this.waitForAgentIdle(agent);
					const result = await item.execute();
					item.resolve(result);
				} catch (error) {
					item.reject(error instanceof Error ? error : new Error(String(error)));
				}
				queue.shift();
			}
		} finally {
			this.processing.set(threadId, false);
		}
	}
	waitForAgentIdle(agent) {
		return new Promise((resolve) => {
			if (!agent.isRunning) {
				resolve();
				return;
			}
			let done = false;
			const finish = () => {
				if (done) return;
				done = true;
				clearInterval(checkInterval);
				sub.unsubscribe();
				resolve();
			};
			const sub = agent.subscribe({
				onRunFinalized: finish,
				onRunFailed: finish
			});
			const checkInterval = setInterval(() => {
				if (!agent.isRunning) finish();
			}, 500);
		});
	}
};
const mcpAppsRequestQueue = new MCPAppsRequestQueue();
/**
* Activity type for MCP Apps events - must match the middleware's MCPAppsActivityType
*/
const MCPAppsActivityType = "mcp-apps";
const MCPAppsActivityContentSchema = z.object({
	result: z.object({
		content: z.array(z.any()).optional(),
		structuredContent: z.any().optional(),
		isError: z.boolean().optional()
	}),
	resourceUri: z.string(),
	serverHash: z.string(),
	serverId: z.string().optional(),
	toolInput: z.record(z.string(), z.unknown()).optional()
});
function isRequest(msg) {
	return "id" in msg && "method" in msg;
}
function isNotification(msg) {
	return !("id" in msg) && "method" in msg;
}
/**
* MCP Apps Extension Activity Renderer
*
* Renders MCP Apps UI in a sandboxed iframe with full protocol support.
* Fetches resource content on-demand via proxied MCP requests.
*/
const MCPAppsActivityRenderer = function MCPAppsActivityRenderer({ content, agent }) {
	const { copilotkit } = useCopilotKit$1();
	const containerRef = useRef(null);
	const iframeRef = useRef(null);
	const [iframeReady, setIframeReady] = useState(false);
	const [error, setError] = useState(null);
	const [isLoading, setIsLoading] = useState(true);
	const [iframeSize, setIframeSize] = useState({});
	const [fetchedResource, setFetchedResource] = useState(null);
	const contentRef = useRef(content);
	contentRef.current = content;
	const agentRef = useRef(agent);
	agentRef.current = agent;
	const fetchStateRef = useRef({
		inProgress: false,
		promise: null,
		resourceUri: null
	});
	const sendToIframe = useCallback((msg) => {
		if (iframeRef.current?.contentWindow) {
			console.log("[MCPAppsRenderer] Sending to iframe:", msg);
			iframeRef.current.contentWindow.postMessage(msg, "*");
		}
	}, []);
	const sendResponse = useCallback((id, result) => {
		sendToIframe({
			jsonrpc: "2.0",
			id,
			result
		});
	}, [sendToIframe]);
	const sendErrorResponse = useCallback((id, code, message) => {
		sendToIframe({
			jsonrpc: "2.0",
			id,
			error: {
				code,
				message
			}
		});
	}, [sendToIframe]);
	const sendNotification = useCallback((method, params) => {
		sendToIframe({
			jsonrpc: "2.0",
			method,
			params: params || {}
		});
	}, [sendToIframe]);
	useEffect(() => {
		const { resourceUri, serverHash, serverId } = content;
		if (fetchStateRef.current.inProgress && fetchStateRef.current.resourceUri === resourceUri) {
			fetchStateRef.current.promise?.then((resource) => {
				if (resource) {
					setFetchedResource(resource);
					setIsLoading(false);
				}
			}).catch((err) => {
				setError(err instanceof Error ? err : new Error(String(err)));
				setIsLoading(false);
			});
			return;
		}
		if (!agent) {
			setError(/* @__PURE__ */ new Error("No agent available to fetch resource"));
			setIsLoading(false);
			return;
		}
		fetchStateRef.current.inProgress = true;
		fetchStateRef.current.resourceUri = resourceUri;
		const fetchPromise = (async () => {
			try {
				const resource = (await mcpAppsRequestQueue.enqueue(agent, () => agent.runAgent({ forwardedProps: { __proxiedMCPRequest: {
					serverHash,
					serverId,
					method: "resources/read",
					params: { uri: resourceUri }
				} } }))).result?.contents?.[0];
				if (!resource) throw new Error("No resource content in response");
				return resource;
			} catch (err) {
				console.error("[MCPAppsRenderer] Failed to fetch resource:", err);
				throw err;
			} finally {
				fetchStateRef.current.inProgress = false;
			}
		})();
		fetchStateRef.current.promise = fetchPromise;
		fetchPromise.then((resource) => {
			if (resource) {
				setFetchedResource(resource);
				setIsLoading(false);
			}
		}).catch((err) => {
			setError(err instanceof Error ? err : new Error(String(err)));
			setIsLoading(false);
		});
	}, [agent, content]);
	useEffect(() => {
		if (isLoading || !fetchedResource) return;
		const container = containerRef.current;
		if (!container) return;
		let mounted = true;
		let messageHandler = null;
		let initialListener = null;
		let createdIframe = null;
		const setup = async () => {
			try {
				const iframe = document.createElement("iframe");
				createdIframe = iframe;
				iframe.style.width = "100%";
				iframe.style.height = "100px";
				iframe.style.border = "none";
				iframe.style.backgroundColor = "transparent";
				iframe.style.display = "block";
				iframe.setAttribute("sandbox", "allow-scripts allow-same-origin allow-forms");
				iframe.setAttribute("data-testid", "mcp-app-iframe");
				iframe.setAttribute("title", "Interactive MCP application");
				const sandboxReady = new Promise((resolve) => {
					initialListener = (event) => {
						if (event.source === iframe.contentWindow) {
							if (event.data?.method === "ui/notifications/sandbox-proxy-ready") {
								if (initialListener) {
									window.removeEventListener("message", initialListener);
									initialListener = null;
								}
								resolve();
							}
						}
					};
					window.addEventListener("message", initialListener);
				});
				if (!mounted) {
					if (initialListener) {
						window.removeEventListener("message", initialListener);
						initialListener = null;
					}
					return;
				}
				const cspDomains = fetchedResource._meta?.ui?.csp?.resourceDomains;
				iframe.srcdoc = buildSandboxHTML(cspDomains);
				iframeRef.current = iframe;
				container.appendChild(iframe);
				await sandboxReady;
				if (!mounted) return;
				console.log("[MCPAppsRenderer] Sandbox proxy ready");
				messageHandler = async (event) => {
					if (event.source !== iframe.contentWindow) return;
					const msg = event.data;
					if (!msg || typeof msg !== "object" || msg.jsonrpc !== "2.0") return;
					console.log("[MCPAppsRenderer] Received from iframe:", msg);
					if (isRequest(msg)) switch (msg.method) {
						case "ui/initialize":
							sendResponse(msg.id, {
								protocolVersion: PROTOCOL_VERSION,
								hostInfo: {
									name: "CopilotKit MCP Apps Host",
									version: "1.0.0"
								},
								hostCapabilities: {
									openLinks: {},
									logging: {}
								},
								hostContext: {
									theme: "light",
									platform: "web"
								}
							});
							break;
						case "ui/message": {
							const currentAgent = agentRef.current;
							if (!currentAgent) {
								console.warn("[MCPAppsRenderer] ui/message: No agent available");
								sendResponse(msg.id, { isError: false });
								break;
							}
							try {
								const params = msg.params;
								const role = params.role || "user";
								const textContent = params.content?.filter((c) => c.type === "text" && c.text).map((c) => c.text).join("\n") || "";
								if (textContent) currentAgent.addMessage({
									id: crypto.randomUUID(),
									role,
									content: textContent
								});
								sendResponse(msg.id, { isError: false });
								if ((params.followUp ?? role === "user") && textContent) {
									const capturedThreadId = currentAgent.threadId || "default";
									mcpAppsRequestQueue.enqueue(currentAgent, () => ɵrunMcpFollowUp({
										host: copilotkit,
										agent: currentAgent,
										capturedThreadId
									})).catch((err) => console.error("[MCPAppsRenderer] ui/message agent run failed:", err));
								}
							} catch (err) {
								console.error("[MCPAppsRenderer] ui/message error:", err);
								sendResponse(msg.id, { isError: true });
							}
							break;
						}
						case "ui/open-link": {
							const url = msg.params?.url;
							if (url) {
								window.open(url, "_blank", "noopener,noreferrer");
								sendResponse(msg.id, { isError: false });
							} else sendErrorResponse(msg.id, -32602, "Missing url parameter");
							break;
						}
						case "tools/call": {
							const { serverHash, serverId } = contentRef.current;
							const currentAgent = agentRef.current;
							if (!serverHash) {
								sendErrorResponse(msg.id, -32603, "No server hash available for proxying");
								break;
							}
							if (!currentAgent) {
								sendErrorResponse(msg.id, -32603, "No agent available for proxying");
								break;
							}
							try {
								const runResult = await mcpAppsRequestQueue.enqueue(currentAgent, () => currentAgent.runAgent({ forwardedProps: { __proxiedMCPRequest: {
									serverHash,
									serverId,
									method: "tools/call",
									params: msg.params
								} } }));
								sendResponse(msg.id, runResult.result || {});
							} catch (err) {
								console.error("[MCPAppsRenderer] tools/call error:", err);
								sendErrorResponse(msg.id, -32603, String(err));
							}
							break;
						}
						default: sendErrorResponse(msg.id, -32601, `Method not found: ${msg.method}`);
					}
					if (isNotification(msg)) switch (msg.method) {
						case "ui/notifications/initialized":
							console.log("[MCPAppsRenderer] Inner iframe initialized");
							if (mounted) setIframeReady(true);
							break;
						case "ui/notifications/size-changed": {
							const { width, height } = msg.params || {};
							console.log("[MCPAppsRenderer] Size change:", {
								width,
								height
							});
							if (mounted) setIframeSize({
								width: typeof width === "number" ? width : void 0,
								height: typeof height === "number" ? height : void 0
							});
							break;
						}
						case "notifications/message":
							console.log("[MCPAppsRenderer] App log:", msg.params);
							break;
					}
				};
				window.addEventListener("message", messageHandler);
				let html;
				if (fetchedResource.text) html = fetchedResource.text;
				else if (fetchedResource.blob) html = atob(fetchedResource.blob);
				else throw new Error("Resource has no text or blob content");
				sendNotification("ui/notifications/sandbox-resource-ready", { html });
			} catch (err) {
				console.error("[MCPAppsRenderer] Setup error:", err);
				if (mounted) setError(err instanceof Error ? err : new Error(String(err)));
			}
		};
		setup();
		return () => {
			mounted = false;
			if (initialListener) {
				window.removeEventListener("message", initialListener);
				initialListener = null;
			}
			if (messageHandler) window.removeEventListener("message", messageHandler);
			if (createdIframe) {
				createdIframe.remove();
				createdIframe = null;
			}
			iframeRef.current = null;
		};
	}, [
		isLoading,
		fetchedResource,
		sendNotification,
		sendResponse,
		sendErrorResponse
	]);
	useEffect(() => {
		if (iframeRef.current) {
			if (iframeSize.width !== void 0) {
				iframeRef.current.style.minWidth = `min(${iframeSize.width}px, 100%)`;
				iframeRef.current.style.width = "100%";
			}
			if (iframeSize.height !== void 0) iframeRef.current.style.height = `${iframeSize.height}px`;
		}
	}, [iframeSize]);
	useEffect(() => {
		if (iframeReady && content.toolInput) {
			console.log("[MCPAppsRenderer] Sending tool input:", content.toolInput);
			sendNotification("ui/notifications/tool-input", { arguments: content.toolInput });
		}
	}, [
		iframeReady,
		content.toolInput,
		sendNotification
	]);
	useEffect(() => {
		if (iframeReady && content.result) {
			console.log("[MCPAppsRenderer] Sending tool result:", content.result);
			sendNotification("ui/notifications/tool-result", content.result);
		}
	}, [
		iframeReady,
		content.result,
		sendNotification
	]);
	const borderStyle = fetchedResource?._meta?.ui?.prefersBorder === true ? {
		borderRadius: "8px",
		backgroundColor: "#f9f9f9",
		border: "1px solid #e0e0e0"
	} : {};
	return /* @__PURE__ */ jsxs("div", {
		ref: containerRef,
		style: {
			width: "100%",
			height: iframeSize.height ? `${iframeSize.height}px` : "auto",
			minHeight: "100px",
			overflow: "hidden",
			position: "relative",
			...borderStyle
		},
		children: [isLoading && /* @__PURE__ */ jsx("div", {
			style: {
				padding: "1rem",
				color: "#666"
			},
			children: "Loading..."
		}), error && /* @__PURE__ */ jsxs("div", {
			style: {
				color: "red",
				padding: "1rem"
			},
			children: ["Error: ", error.message]
		})]
	});
};

//#endregion
//#region src/v2/providers/SandboxFunctionsContext.ts
const SandboxFunctionsContext = createContext([]);
function useSandboxFunctions() {
	return useContext(SandboxFunctionsContext);
}

//#endregion
//#region src/v2/lib/processPartialHtml.ts
/**
* Extracts all complete `<style>` blocks from the raw HTML.
* Returns the concatenated style tags, suitable for injection into `<head>`.
*/
function extractCompleteStyles(html) {
	const matches = html.match(/<style\b[^>]*>[\s\S]*?<\/style>/gi);
	return matches ? matches.join("") : "";
}
/**
* Processes raw accumulated HTML for safe preview via innerHTML injection.
* Pure function, no DOM dependencies.
*
* Pipeline (order matters):
* 1. Strip incomplete tag at end
* 2. Strip complete <style>, <script>, and <head> blocks
* 3. Strip incomplete <style>/<script>/<head> blocks
* 4. Strip incomplete HTML entities
* 5. Extract body content (or use full string if no <body>)
*/
function processPartialHtml(html) {
	let result = html;
	result = result.replace(/<[^>]*$/, "");
	result = result.replace(/<(style|script|head)\b[^>]*>[\s\S]*?<\/\1>/gi, "");
	result = result.replace(/<(style|script|head)\b[^>]*>[\s\S]*$/gi, "");
	result = result.replace(/&[a-zA-Z0-9#]*$/, "");
	const bodyMatch = result.match(/<body[^>]*>([\s\S]*)/i);
	if (bodyMatch) {
		result = bodyMatch[1];
		result = result.replace(/<\/body>[\s\S]*/i, "");
	}
	return result;
}

//#endregion
//#region src/v2/components/OpenGenerativeUIRenderer.tsx
const OpenGenerativeUIActivityType = "open-generative-ui";
const OpenGenerativeUIContentSchema = z.object({
	initialHeight: z.number().optional(),
	generating: z.boolean().optional(),
	css: z.string().optional(),
	cssComplete: z.boolean().optional(),
	html: z.array(z.string()).optional(),
	htmlComplete: z.boolean().optional(),
	jsFunctions: z.string().optional(),
	jsFunctionsComplete: z.boolean().optional(),
	jsExpressions: z.array(z.string()).optional(),
	jsExpressionsComplete: z.boolean().optional()
});
/**
* Schema for the generateSandboxedUi tool call arguments.
* Used by the frontend tool renderer to display placeholder messages.
*/
const GenerateSandboxedUiArgsSchema = z.object({
	initialHeight: z.number().optional(),
	placeholderMessages: z.array(z.string()).optional(),
	css: z.string().optional(),
	html: z.string().optional(),
	jsFunctions: z.string().optional(),
	jsExpressions: z.array(z.string()).optional()
});
const THROTTLE_MS = 1e3;
/**
* Returns true when the inner component should re-render immediately
* (no throttle delay).
*/
function shouldFlushImmediately(prev, next) {
	if (next.cssComplete && (!prev || !prev.cssComplete)) return true;
	if (next.htmlComplete) return true;
	if (next.generating === false) return true;
	if (next.jsFunctions && (!prev || !prev.jsFunctions)) return true;
	if ((next.jsExpressions?.length ?? 0) > (prev?.jsExpressions?.length ?? 0)) return true;
	if (next.html?.length && (!prev || !prev.html?.length)) return true;
	return false;
}
/**
* Outer wrapper — absorbs every parent re-render but only forwards
* throttled content snapshots to the memoized inner component.
*/
const OpenGenerativeUIActivityRenderer = function OpenGenerativeUIActivityRenderer({ content }) {
	const latestContentRef = useRef(content);
	latestContentRef.current = content;
	const [throttledContent, setThrottledContent] = useState(content);
	const throttledContentRef = useRef(throttledContent);
	const timerRef = useRef(null);
	if (throttledContentRef.current !== content) {
		if (shouldFlushImmediately(throttledContentRef.current, content)) {
			if (timerRef.current !== null) {
				clearTimeout(timerRef.current);
				timerRef.current = null;
			}
			throttledContentRef.current = content;
			setThrottledContent(content);
		}
	}
	const flush = useCallback(() => {
		timerRef.current = null;
		const latest = latestContentRef.current;
		throttledContentRef.current = latest;
		setThrottledContent(latest);
	}, []);
	useEffect(() => {
		if (throttledContentRef.current === content) return;
		if (timerRef.current === null) timerRef.current = setTimeout(flush, THROTTLE_MS);
	}, [content, flush]);
	useEffect(() => {
		return () => {
			if (timerRef.current !== null) clearTimeout(timerRef.current);
		};
	}, []);
	return /* @__PURE__ */ jsx(OpenGenerativeUIActivityRendererInner, { content: throttledContent });
};
function ensureHead(html) {
	if (/<head[\s>]/i.test(html)) return html;
	return `<head></head>${html}`;
}
function injectCssIntoHtml(html, css) {
	const headCloseIdx = html.indexOf("</head>");
	if (headCloseIdx !== -1) return html.slice(0, headCloseIdx) + `<style>${css}</style>` + html.slice(headCloseIdx);
	return `<head><style>${css}</style></head>${html}`;
}
const OpenGenerativeUIActivityRendererInner = React.memo(function OpenGenerativeUIActivityRendererInner({ content }) {
	const initialHeight = content.initialHeight ?? 200;
	const [autoHeight, setAutoHeight] = useState(null);
	const sandboxFunctions = useSandboxFunctions();
	const localApi = useMemo(() => {
		const api = {};
		for (const fn of sandboxFunctions) api[fn.name] = fn.handler;
		return api;
	}, [sandboxFunctions]);
	const fullHtml = content.htmlComplete && content.html?.length ? content.html.join("") : void 0;
	const css = content.cssComplete ? content.css : void 0;
	const cssReady = !!content.cssComplete;
	const partialHtml = !content.htmlComplete && content.html?.length ? content.html.join("") : void 0;
	const previewBody = partialHtml ? processPartialHtml(partialHtml) : void 0;
	const previewStyles = partialHtml ? extractCompleteStyles(partialHtml) : "";
	const hasPreview = cssReady && !!previewBody?.trim();
	const hasVisibleSandbox = !!fullHtml || hasPreview;
	const containerRef = useRef(null);
	const sandboxRef = useRef(null);
	const previewSandboxRef = useRef(null);
	const previewReadyRef = useRef(false);
	const sandboxReadyRef = useRef(false);
	const executedIndexRef = useRef(0);
	const pendingQueueRef = useRef([]);
	const jsFunctionsInjectedRef = useRef(false);
	useEffect(() => {
		const container = containerRef.current;
		if (!container || fullHtml || !hasPreview || previewSandboxRef.current) return;
		let cancelled = false;
		import("@jetbrains/websandbox").then((mod) => {
			if (cancelled) return;
			const sandbox = (mod.default?.default ?? mod.default).create({}, {
				frameContainer: container,
				frameContent: "<head></head><body></body>",
				allowAdditionalAttributes: ""
			});
			previewSandboxRef.current = sandbox;
			sandbox.iframe.style.width = "100%";
			sandbox.iframe.style.height = "100%";
			sandbox.iframe.style.border = "none";
			sandbox.iframe.style.backgroundColor = "transparent";
			sandbox.promise.then(() => {
				if (cancelled) return;
				previewReadyRef.current = true;
				sandbox.run(`
            var s = document.createElement('style');
            s.textContent = 'html, body { overflow: hidden !important; }';
            document.head.appendChild(s);
          `);
				const headParts = [];
				if (css) headParts.push(`<style>${css}</style>`);
				if (previewStyles) headParts.push(previewStyles);
				if (headParts.length) sandbox.run(`document.head.innerHTML = ${JSON.stringify(headParts.join(""))}`);
				if (previewBody) sandbox.run(`document.body.innerHTML = ${JSON.stringify(previewBody)}`);
			});
		}).catch((err) => {
			console.error("[OpenGenerativeUI] Failed to load sandbox module:", err);
		});
		return () => {
			cancelled = true;
		};
	}, [hasPreview, fullHtml]);
	useEffect(() => {
		if (!previewSandboxRef.current || !previewReadyRef.current) return;
		const headParts = [];
		if (css) headParts.push(`<style>${css}</style>`);
		if (previewStyles) headParts.push(previewStyles);
		if (headParts.length) previewSandboxRef.current.run(`document.head.innerHTML = ${JSON.stringify(headParts.join(""))}`);
		if (!previewBody) return;
		previewSandboxRef.current.run(`document.body.innerHTML = ${JSON.stringify(previewBody)}`);
	}, [
		previewBody,
		previewStyles,
		css
	]);
	useEffect(() => {
		const container = containerRef.current;
		if (!container || !fullHtml) return;
		if (previewSandboxRef.current) {
			previewSandboxRef.current.destroy();
			previewSandboxRef.current = null;
			previewReadyRef.current = false;
		}
		let cancelled = false;
		executedIndexRef.current = 0;
		jsFunctionsInjectedRef.current = false;
		sandboxReadyRef.current = false;
		pendingQueueRef.current = [];
		const htmlContent = css ? injectCssIntoHtml(fullHtml, css) : fullHtml;
		import("@jetbrains/websandbox").then((mod) => {
			if (cancelled) return;
			const sandbox = (mod.default?.default ?? mod.default).create(localApi, {
				frameContainer: container,
				frameContent: ensureHead(htmlContent),
				allowAdditionalAttributes: ""
			});
			sandboxRef.current = sandbox;
			sandbox.iframe.style.width = "100%";
			sandbox.iframe.style.height = "100%";
			sandbox.iframe.style.border = "none";
			sandbox.iframe.style.backgroundColor = "transparent";
			sandbox.promise.then(() => {
				if (cancelled) return;
				sandboxReadyRef.current = true;
				sandbox.run(`
            var s = document.createElement('style');
            s.textContent = 'html, body { overflow: hidden !important; }';
            document.head.appendChild(s);
          `);
				const queue = pendingQueueRef.current;
				pendingQueueRef.current = [];
				for (const code of queue) sandbox.run(code);
			});
		}).catch((err) => {
			console.error("[OpenGenerativeUI] Failed to load sandbox module:", err);
		});
		return () => {
			cancelled = true;
			if (previewSandboxRef.current) {
				previewSandboxRef.current.destroy();
				previewSandboxRef.current = null;
				previewReadyRef.current = false;
			}
			if (sandboxRef.current) {
				sandboxRef.current.destroy();
				sandboxRef.current = null;
			}
			sandboxReadyRef.current = false;
			setAutoHeight(null);
		};
	}, [
		fullHtml,
		css,
		localApi
	]);
	useEffect(() => {
		if (!content.jsFunctions || jsFunctionsInjectedRef.current) return;
		jsFunctionsInjectedRef.current = true;
		const sandbox = sandboxRef.current;
		if (sandboxReadyRef.current && sandbox) sandbox.run(content.jsFunctions);
		else pendingQueueRef.current.push(content.jsFunctions);
	}, [content.jsFunctions]);
	useEffect(() => {
		const expressions = content.jsExpressions;
		if (!expressions || expressions.length === 0) return;
		const startIndex = executedIndexRef.current;
		if (startIndex >= expressions.length) return;
		const newExprs = expressions.slice(startIndex);
		executedIndexRef.current = expressions.length;
		const sandbox = sandboxRef.current;
		if (sandboxReadyRef.current && sandbox) (async () => {
			for (const expr of newExprs) await sandbox.run(expr);
		})();
		else pendingQueueRef.current.push(...newExprs);
	}, [content.jsExpressions?.length]);
	const generationDone = content.generating === false;
	useEffect(() => {
		const sandbox = sandboxRef.current;
		if (!generationDone || !sandbox) return;
		let handled = false;
		const onMessage = (e) => {
			if (handled) return;
			if (e.source === sandbox.iframe.contentWindow && e.data?.type === "__ck_resize") {
				handled = true;
				setAutoHeight(e.data.height);
				window.removeEventListener("message", onMessage);
			}
		};
		window.addEventListener("message", onMessage);
		const measureOnce = `
        (function() {
          var s = document.createElement('style');
          s.textContent = 'body { height: auto !important; min-height: 0 !important; }';
          document.head.appendChild(s);
          var h = document.body.scrollHeight;
          var cs = getComputedStyle(document.body);
          h += parseFloat(cs.marginTop) || 0;
          h += parseFloat(cs.marginBottom) || 0;
          s.remove();
          parent.postMessage({ type: "__ck_resize", height: Math.ceil(h) }, "*");
        })();
      `;
		if (sandboxReadyRef.current) sandbox.run(measureOnce);
		else pendingQueueRef.current.push(measureOnce);
		return () => {
			window.removeEventListener("message", onMessage);
		};
	}, [generationDone]);
	const height = autoHeight ?? initialHeight;
	const isGenerating = content.generating !== false;
	return /* @__PURE__ */ jsx("div", {
		ref: containerRef,
		style: {
			position: "relative",
			width: "100%",
			height: `${height}px`,
			borderRadius: "8px",
			backgroundColor: hasVisibleSandbox ? "transparent" : "#f5f5f5",
			border: hasVisibleSandbox ? "none" : "1px solid #e0e0e0",
			display: hasVisibleSandbox ? "block" : "flex",
			alignItems: hasVisibleSandbox ? void 0 : "center",
			justifyContent: hasVisibleSandbox ? void 0 : "center",
			overflow: "hidden"
		},
		children: isGenerating && /* @__PURE__ */ jsxs("div", {
			style: {
				position: "absolute",
				inset: 0,
				zIndex: 10,
				pointerEvents: "all",
				backgroundColor: "rgba(255, 255, 255, 0.5)",
				display: "flex",
				alignItems: "center",
				justifyContent: "center"
			},
			children: [/* @__PURE__ */ jsxs("svg", {
				width: "48",
				height: "48",
				viewBox: "0 0 24 24",
				fill: "none",
				style: { animation: "ck-spin 1s linear infinite" },
				children: [/* @__PURE__ */ jsx("circle", {
					cx: "12",
					cy: "12",
					r: "10",
					stroke: "#e0e0e0",
					strokeWidth: "3"
				}), /* @__PURE__ */ jsx("path", {
					d: "M12 2a10 10 0 0 1 10 10",
					stroke: "#999",
					strokeWidth: "3",
					strokeLinecap: "round"
				})]
			}), /* @__PURE__ */ jsx("style", { children: `@keyframes ck-spin { to { transform: rotate(360deg) } }` })]
		})
	});
}, (prev, next) => prev.content === next.content);
/**
* Frontend tool renderer for generateSandboxedUi.
* Displays placeholder messages while the UI is being generated.
*/
const OpenGenerativeUIToolRenderer = function OpenGenerativeUIToolRenderer(props) {
	const [visibleMessageIndex, setVisibleMessageIndex] = useState(0);
	const prevMessageCountRef = useRef(0);
	const messages = props.args.placeholderMessages;
	useEffect(() => {
		if (!messages || messages.length === 0) return;
		if (messages.length !== prevMessageCountRef.current) {
			prevMessageCountRef.current = messages.length;
			setVisibleMessageIndex(messages.length - 1);
		}
		if (props.status === ToolCallStatus.Complete) return;
		const timer = setInterval(() => {
			setVisibleMessageIndex((i) => (i + 1) % messages.length);
		}, 5e3);
		return () => clearInterval(timer);
	}, [messages?.length, props.status]);
	if (props.status === ToolCallStatus.Complete) return null;
	if (!messages || messages.length === 0) return null;
	return /* @__PURE__ */ jsx("div", {
		style: {
			padding: "8px 12px",
			color: "#999",
			fontSize: "14px"
		},
		children: messages[visibleMessageIndex] ?? messages[0]
	});
};

//#endregion
//#region src/v2/a2ui/A2UIRecoveryStates.tsx
/**
* The pre-paint lifecycle fields the middleware stamps onto the `a2ui-surface`
* activity content (alongside `a2ui_operations` on paint). `.passthrough()` keeps
* `a2ui_operations` and any future fields intact.
*/
const A2UILifecycleFields = {
	status: z.enum([
		"building",
		"retrying",
		"failed"
	]).optional(),
	attempt: z.number().optional(),
	maxAttempts: z.number().optional(),
	progressTokens: z.number().optional(),
	error: z.string().optional(),
	errors: z.array(z.any()).optional(),
	attempts: z.array(z.any()).optional(),
	debugExposure: z.enum([
		"hidden",
		"collapsed",
		"verbose"
	]).optional()
};
/** Server-stamped debugExposure wins; else the client option; else "collapsed". */
function resolveDebugExposure(content, optionDebugExposure) {
	return content?.debugExposure ?? optionDebugExposure;
}
/** building: the generic skeleton + optional live token count. */
function A2UIBuildingState({ content }) {
	return /* @__PURE__ */ jsx(A2UIGeneratingSkeleton, {
		label: "Building interface",
		tokens: typeof content?.progressTokens === "number" ? content.progressTokens : void 0
	});
}
/**
* retrying: stays the generic skeleton through fast/transient retries; only once
* the retry is perceptible (after `showAfterMs`, or once `attempt` crosses
* `showAfterAttempts`) does the sub-label reveal "Retrying generation… (N/M)".
*/
function A2UIRetryingState({ content, showAfterMs, showAfterAttempts, debugExposure }) {
	const attempt = typeof content?.attempt === "number" ? content.attempt : void 0;
	const maxAttempts = typeof content?.maxAttempts === "number" ? content.maxAttempts : void 0;
	const immediate = attempt !== void 0 && attempt >= showAfterAttempts;
	const [revealed, setRevealed] = useState(immediate);
	useEffect(() => {
		if (immediate) {
			setRevealed(true);
			return;
		}
		const timer = setTimeout(() => setRevealed(true), showAfterMs);
		return () => clearTimeout(timer);
	}, [immediate, showAfterMs]);
	const tokens = typeof content?.progressTokens === "number" ? content.progressTokens : void 0;
	if (!revealed) return /* @__PURE__ */ jsx(A2UIGeneratingSkeleton, {
		label: "Building interface",
		tokens
	});
	const label = attempt !== void 0 && maxAttempts !== void 0 ? `Retrying generation… (${attempt}/${maxAttempts} attempts)` : "Retrying generation…";
	const errors = Array.isArray(content?.errors) ? content.errors : [];
	return /* @__PURE__ */ jsx(A2UIGeneratingSkeleton, {
		label,
		tokens,
		children: debugExposure !== "hidden" && errors.length > 0 && /* @__PURE__ */ jsx(A2UIDebugDetails, {
			label: "validation issues",
			open: debugExposure === "verbose",
			payload: {
				attempt: content?.attempt,
				errors
			}
		})
	});
}
/** failed: a clean hard-failure card that replaces the skeleton in place. */
function A2UIRecoveryFailure({ content, debugExposure }) {
	return /* @__PURE__ */ jsxs("div", {
		className: "cpk:rounded-lg cpk:border cpk:border-amber-200 cpk:bg-amber-50 cpk:p-3 cpk:text-sm cpk:text-amber-800",
		children: [
			/* @__PURE__ */ jsx("div", {
				className: "cpk:font-medium",
				children: "Couldn't generate the UI"
			}),
			/* @__PURE__ */ jsx("div", {
				className: "cpk:mt-1 cpk:text-xs cpk:text-amber-700",
				children: "Something went wrong rendering this. You can keep chatting and try again."
			}),
			debugExposure !== "hidden" && /* @__PURE__ */ jsx(A2UIDebugDetails, {
				label: "developer details",
				open: debugExposure === "verbose",
				payload: {
					error: content?.error,
					attempts: content?.attempts
				}
			})
		]
	});
}
/**
* Animated wireframe skeleton with a label, an optional live token count, and an
* optional debug-detail slot below it. Pure CSS animation (no data dependency).
* The `tokens` count drives a progressive reveal of skeleton rows.
*/
function A2UIGeneratingSkeleton({ label, tokens, children }) {
	const phase = tokens == null ? 3 : tokens < 50 ? 0 : tokens < 200 ? 1 : tokens < 400 ? 2 : 3;
	return /* @__PURE__ */ jsxs("div", {
		style: {
			margin: "12px 0",
			maxWidth: 320
		},
		children: [
			/* @__PURE__ */ jsxs("div", {
				style: {
					position: "relative",
					overflow: "hidden",
					borderRadius: 12,
					border: "1px solid rgba(228,228,231,0.8)",
					backgroundColor: "#fff",
					boxShadow: "0 1px 2px rgba(0,0,0,0.04)",
					padding: "16px 18px 14px"
				},
				children: [
					/* @__PURE__ */ jsxs("div", {
						style: {
							display: "flex",
							alignItems: "center",
							gap: 8,
							marginBottom: 12
						},
						children: [/* @__PURE__ */ jsxs("div", {
							style: {
								display: "flex",
								gap: 4
							},
							children: [
								/* @__PURE__ */ jsx(Dot, {}),
								/* @__PURE__ */ jsx(Dot, {}),
								/* @__PURE__ */ jsx(Dot, {})
							]
						}), /* @__PURE__ */ jsx(Bar, {
							w: 64,
							h: 6,
							bg: "#e4e4e7",
							opacity: phase >= 1 ? 1 : .4,
							transition: "opacity 0.5s"
						})]
					}),
					/* @__PURE__ */ jsxs("div", {
						style: {
							display: "grid",
							gap: 7
						},
						children: [
							/* @__PURE__ */ jsxs(Row, {
								show: phase >= 0,
								children: [/* @__PURE__ */ jsx(Bar, {
									w: 36,
									h: 7,
									bg: "rgba(147,197,253,0.7)",
									anim: 0
								}), /* @__PURE__ */ jsx(Bar, {
									w: 80,
									h: 7,
									bg: "rgba(219,234,254,0.8)",
									anim: .2
								})]
							}),
							/* @__PURE__ */ jsxs(Row, {
								show: phase >= 0,
								delay: .1,
								children: [
									/* @__PURE__ */ jsx(Spacer, {}),
									/* @__PURE__ */ jsx(Dot, {}),
									/* @__PURE__ */ jsx(Bar, {
										w: 100,
										h: 7,
										bg: "rgba(24,24,27,0.2)",
										anim: .3
									})
								]
							}),
							/* @__PURE__ */ jsxs(Row, {
								show: phase >= 1,
								delay: .15,
								children: [
									/* @__PURE__ */ jsx(Spacer, {}),
									/* @__PURE__ */ jsx(Bar, {
										w: 48,
										h: 7,
										bg: "rgba(24,24,27,0.15)",
										anim: .1
									}),
									/* @__PURE__ */ jsx(Bar, {
										w: 40,
										h: 7,
										bg: "rgba(153,246,228,0.6)",
										anim: .5
									}),
									/* @__PURE__ */ jsx(Bar, {
										w: 56,
										h: 7,
										bg: "rgba(147,197,253,0.6)",
										anim: .3
									})
								]
							}),
							/* @__PURE__ */ jsxs(Row, {
								show: phase >= 1,
								delay: .2,
								children: [
									/* @__PURE__ */ jsx(Spacer, {}),
									/* @__PURE__ */ jsx(Dot, {}),
									/* @__PURE__ */ jsx(Bar, {
										w: 60,
										h: 7,
										bg: "rgba(24,24,27,0.15)",
										anim: .4
									})
								]
							}),
							/* @__PURE__ */ jsxs(Row, {
								show: phase >= 2,
								delay: .25,
								children: [
									/* @__PURE__ */ jsx(Bar, {
										w: 40,
										h: 7,
										bg: "rgba(153,246,228,0.5)",
										anim: .2
									}),
									/* @__PURE__ */ jsx(Dot, {}),
									/* @__PURE__ */ jsx(Bar, {
										w: 48,
										h: 7,
										bg: "rgba(24,24,27,0.15)",
										anim: .6
									}),
									/* @__PURE__ */ jsx(Bar, {
										w: 64,
										h: 7,
										bg: "rgba(147,197,253,0.5)",
										anim: .1
									})
								]
							}),
							/* @__PURE__ */ jsxs(Row, {
								show: phase >= 2,
								delay: .3,
								children: [/* @__PURE__ */ jsx(Bar, {
									w: 36,
									h: 7,
									bg: "rgba(147,197,253,0.6)",
									anim: .5
								}), /* @__PURE__ */ jsx(Bar, {
									w: 36,
									h: 7,
									bg: "rgba(24,24,27,0.12)",
									anim: .7
								})]
							}),
							/* @__PURE__ */ jsxs(Row, {
								show: phase >= 3,
								delay: .35,
								children: [
									/* @__PURE__ */ jsx(Dot, {}),
									/* @__PURE__ */ jsx(Bar, {
										w: 44,
										h: 7,
										bg: "rgba(24,24,27,0.18)",
										anim: .3
									}),
									/* @__PURE__ */ jsx(Dot, {}),
									/* @__PURE__ */ jsx(Bar, {
										w: 56,
										h: 7,
										bg: "rgba(153,246,228,0.5)",
										anim: .8
									}),
									/* @__PURE__ */ jsx(Bar, {
										w: 48,
										h: 7,
										bg: "rgba(147,197,253,0.5)",
										anim: .4
									})
								]
							})
						]
					}),
					/* @__PURE__ */ jsx("div", { style: {
						pointerEvents: "none",
						position: "absolute",
						inset: 0,
						background: "linear-gradient(105deg, transparent 0%, transparent 40%, rgba(255,255,255,0.6) 50%, transparent 60%, transparent 100%)",
						backgroundSize: "250% 100%",
						animation: "cpk-a2ui-sweep 3s ease-in-out infinite"
					} })
				]
			}),
			/* @__PURE__ */ jsxs("div", {
				style: {
					display: "flex",
					alignItems: "center",
					justifyContent: "center",
					gap: 8,
					marginTop: 8
				},
				children: [/* @__PURE__ */ jsx("span", {
					style: {
						fontSize: 12,
						color: "#a1a1aa",
						letterSpacing: "0.025em"
					},
					children: label
				}), typeof tokens === "number" && tokens > 0 && /* @__PURE__ */ jsxs("span", {
					style: {
						fontSize: 11,
						color: "#d4d4d8",
						fontVariantNumeric: "tabular-nums"
					},
					children: [
						"~",
						tokens.toLocaleString(),
						" tokens"
					]
				})]
			}),
			children,
			/* @__PURE__ */ jsx("style", { children: `
        @keyframes cpk-a2ui-fade {
          0%, 100% { opacity: 1; }
          50% { opacity: 0.5; }
        }
        @keyframes cpk-a2ui-sweep {
          0% { background-position: 250% 0; }
          100% { background-position: -250% 0; }
        }
      ` })
		]
	});
}
function A2UIDebugDetails({ label, open, payload }) {
	return /* @__PURE__ */ jsxs("details", {
		open,
		className: "cpk:mt-2 cpk:text-xs",
		children: [/* @__PURE__ */ jsx("summary", {
			className: "cpk:cursor-pointer cpk:text-gray-500",
			children: label
		}), /* @__PURE__ */ jsx("pre", {
			className: "cpk:mt-1 cpk:overflow-auto cpk:rounded cpk:bg-gray-100 cpk:p-2 cpk:text-gray-700",
			style: { fontSize: 11 },
			children: JSON.stringify(payload, null, 2)
		})]
	});
}
function Dot() {
	return /* @__PURE__ */ jsx("div", { style: {
		width: 7,
		height: 7,
		borderRadius: "50%",
		backgroundColor: "#d4d4d8",
		flexShrink: 0
	} });
}
function Spacer() {
	return /* @__PURE__ */ jsx("div", { style: { width: 12 } });
}
function Bar({ w, h, bg, anim, opacity, transition }) {
	return /* @__PURE__ */ jsx("div", { style: {
		width: w,
		height: h,
		borderRadius: 9999,
		backgroundColor: bg,
		...anim !== void 0 ? { animation: `cpk-a2ui-fade 2.4s ease-in-out ${anim}s infinite` } : {},
		...opacity !== void 0 ? { opacity } : {},
		...transition ? { transition } : {}
	} });
}
function Row({ children, show, delay = 0 }) {
	return /* @__PURE__ */ jsx("div", {
		style: {
			display: "flex",
			alignItems: "center",
			gap: 6,
			opacity: show ? 1 : 0,
			transition: `opacity 0.4s ${delay}s`
		},
		children
	});
}

//#endregion
//#region src/v2/a2ui/A2UIMessageRenderer.tsx
/**
* The container key used to wrap A2UI operations for explicit detection.
* Must match A2UI_OPERATIONS_KEY in @ag-ui/a2ui-middleware and copilotkit.a2ui (Python).
*/
const A2UI_OPERATIONS_KEY = "a2ui_operations";
let initialized = false;
function ensureInitialized() {
	if (!initialized) {
		initializeDefaultCatalog();
		injectStyles();
		initialized = true;
	}
}
/**
* The `a2ui-surface` activity carries the WHOLE generative-UI lifecycle on one
* stable messageId (OSS-162): pre-paint `status` ("building" | "retrying" |
* "failed") with recovery detail, then `a2ui_operations` on paint. The states
* swap in place, so the painted surface replaces the skeleton with no extra
* coordination. `.passthrough()` preserves operations + any future fields.
*/
const A2UISurfaceContentSchema = z.object({
	a2ui_operations: z.array(z.any()).optional(),
	...A2UILifecycleFields
}).passthrough();
function createA2UIMessageRenderer(options) {
	const { theme, catalog, loadingComponent, recovery, onAction } = options;
	const showAfterMs = recovery?.showAfterMs ?? 2e3;
	const showAfterAttempts = recovery?.showAfterAttempts ?? 2;
	const optionDebugExposure = recovery?.debugExposure ?? "collapsed";
	return {
		activityType: "a2ui-surface",
		content: A2UISurfaceContentSchema,
		render: ({ content, agent }) => {
			ensureInitialized();
			const [operations, setOperations] = useState([]);
			const { copilotkit } = useCopilotKit$1();
			const lastContentRef = useRef(null);
			useEffect(() => {
				if (content === lastContentRef.current) return;
				lastContentRef.current = content;
				const incoming = content?.[A2UI_OPERATIONS_KEY];
				if (!content || !Array.isArray(incoming)) {
					setOperations([]);
					return;
				}
				setOperations(incoming);
			}, [content]);
			const groupedOperations = useMemo(() => {
				const groups = /* @__PURE__ */ new Map();
				for (const operation of operations) {
					const surfaceId = getOperationSurfaceId(operation) ?? DEFAULT_SURFACE_ID;
					if (!groups.has(surfaceId)) groups.set(surfaceId, []);
					groups.get(surfaceId).push(operation);
				}
				return groups;
			}, [operations]);
			const hasOps = groupedOperations.size > 0;
			const renderLifecycle = (c) => {
				const status = c?.status;
				const debugExposure = resolveDebugExposure(c, optionDebugExposure);
				if (status === "failed") return /* @__PURE__ */ jsx(A2UIRecoveryFailure, {
					content: c,
					debugExposure
				});
				if (status === "retrying") return /* @__PURE__ */ jsx(A2UIRetryingState, {
					content: c,
					showAfterMs,
					showAfterAttempts,
					debugExposure
				});
				if (loadingComponent) return /* @__PURE__ */ jsx(loadingComponent, {});
				return /* @__PURE__ */ jsx(A2UIBuildingState, { content: c });
			};
			const lastLoaderContentRef = useRef(null);
			if (!(Array.isArray(content?.[A2UI_OPERATIONS_KEY]) && content[A2UI_OPERATIONS_KEY].length > 0)) lastLoaderContentRef.current = content;
			const [surfaceReady, setSurfaceReady] = useState(false);
			const readyRef = useRef(false);
			const markSurfaceReady = useCallback(() => {
				if (readyRef.current) return;
				readyRef.current = true;
				requestAnimationFrame(() => setSurfaceReady(true));
			}, []);
			useEffect(() => {
				if (!hasOps) {
					setSurfaceReady(false);
					readyRef.current = false;
					return;
				}
				const t = setTimeout(() => setSurfaceReady(true), 8e3);
				return () => clearTimeout(t);
			}, [hasOps]);
			if (!hasOps) return renderLifecycle(content);
			const surfaces = /* @__PURE__ */ jsx("div", {
				className: "cpk:flex cpk:min-h-0 cpk:flex-1 cpk:flex-col cpk:gap-6 cpk:overflow-auto cpk:py-6",
				children: Array.from(groupedOperations.entries()).map(([surfaceId, ops]) => /* @__PURE__ */ jsx(ReactSurfaceHost, {
					surfaceId,
					operations: ops,
					theme,
					agent,
					copilotkit,
					catalog,
					onAction,
					onReady: markSurfaceReady
				}, surfaceId))
			});
			return /* @__PURE__ */ jsxs("div", {
				style: { position: "relative" },
				children: [/* @__PURE__ */ jsx("div", {
					"aria-hidden": !surfaceReady,
					style: surfaceReady ? void 0 : {
						position: "absolute",
						inset: 0,
						opacity: 0,
						pointerEvents: "none"
					},
					children: surfaces
				}), !surfaceReady && renderLifecycle(lastLoaderContentRef.current ?? content)]
			});
		}
	};
}
/**
* Orchestrates a single A2UI user action: runs the optional `onAction`
* interceptor first, then forwards to the agent unless the interceptor
* suppressed it (returned `null`). Exported for unit testing; the wiring lives
* in {@link ReactSurfaceHost}.
*/
async function runA2UIAction({ message, agent, copilotkit, onAction }) {
	if (!agent) return;
	const action = message.userAction;
	const forward = async (forwardAction) => {
		const a2uiAction = forwardAction !== void 0 ? {
			...message,
			userAction: forwardAction
		} : message;
		try {
			copilotkit.setProperties({
				...copilotkit.properties,
				a2uiAction
			});
			await copilotkit.runAgent({ agent });
		} finally {
			if (copilotkit.properties) {
				const { a2uiAction: _omit, ...rest } = copilotkit.properties;
				copilotkit.setProperties(rest);
			}
		}
	};
	if (onAction && action) {
		const result = await onAction(action, forward);
		if (result === null) return;
		if (result) {
			await forward(result);
			return;
		}
	}
	await forward();
}
/**
* Renders a single A2UI surface using the React renderer.
* Wraps A2UIProvider + A2UIRenderer and bridges actions back to CopilotKit.
*/
function ReactSurfaceHost({ surfaceId, operations, theme, agent, copilotkit, catalog, onAction, onReady }) {
	return /* @__PURE__ */ jsx("div", {
		className: "cpk:flex cpk:w-full cpk:flex-none cpk:flex-col cpk:gap-4",
		children: /* @__PURE__ */ jsxs(A2UIProvider, {
			onAction: useCallback((message) => runA2UIAction({
				message,
				agent,
				copilotkit,
				onAction
			}), [
				agent,
				copilotkit,
				onAction
			]),
			theme,
			catalog,
			children: [/* @__PURE__ */ jsx(SurfaceMessageProcessor, {
				surfaceId,
				operations,
				onReady
			}), /* @__PURE__ */ jsx(A2UISurfaceOrError, { surfaceId })]
		})
	});
}
/**
* Renders the A2UI surface, or an error message if processing failed.
* Must be a child of A2UIProvider to access the error state.
*/
function A2UISurfaceOrError({ surfaceId }) {
	const error = useA2UIError();
	if (error) return /* @__PURE__ */ jsxs("div", {
		className: "cpk:rounded-lg cpk:border cpk:border-red-200 cpk:bg-red-50 cpk:p-3 cpk:text-sm cpk:text-red-700",
		children: ["A2UI render error: ", error]
	});
	return /* @__PURE__ */ jsx(A2UIRenderer, {
		surfaceId,
		className: "cpk:flex cpk:flex-1"
	});
}
/**
* Processes A2UI operations into the provider's message processor.
* Must be a child of A2UIProvider to access the actions context.
*/
function SurfaceMessageProcessor({ surfaceId, operations, onReady }) {
	const { processMessages, getSurface } = useA2UIActions();
	const lastHashRef = useRef("");
	useEffect(() => {
		const hash = JSON.stringify(operations);
		if (hash === lastHashRef.current) return;
		lastHashRef.current = hash;
		processMessages(getSurface(surfaceId) ? operations.filter((op) => !op?.createSurface) : operations);
		if (onReady && surfaceHasRenderableContent(operations)) onReady();
	}, [
		processMessages,
		getSurface,
		surfaceId,
		operations,
		onReady
	]);
	return null;
}
/**
* Whether the surface's operations are enough to paint a visible card yet.
* A data-bound surface references its data via `path` and renders nothing until
* the data model has ≥1 value; a static surface (no path refs) paints from its
* components alone. Used to time the loader→surface cross-over to actual content
* arrival rather than a fixed delay. (OSS-162)
*/
function surfaceHasRenderableContent(operations) {
	const componentOps = operations.filter((o) => o?.updateComponents);
	if (!componentOps.length) return false;
	if (!JSON.stringify(componentOps).includes("\"path\"")) return true;
	return operations.some((o) => {
		const v = o?.updateDataModel?.value;
		if (!v || typeof v !== "object") return false;
		return Object.values(v).some((x) => Array.isArray(x) ? x.length > 0 : x !== null && x !== void 0 && x !== "");
	});
}
function getOperationSurfaceId(operation) {
	if (!operation || typeof operation !== "object") return null;
	if (typeof operation.surfaceId === "string") return operation.surfaceId;
	return operation?.createSurface?.surfaceId ?? operation?.updateComponents?.surfaceId ?? operation?.updateDataModel?.surfaceId ?? operation?.deleteSurface?.surfaceId ?? null;
}

//#endregion
//#region src/v2/types/defineToolCallRenderer.ts
function defineToolCallRenderer(def) {
	const argsSchema = def.name === "*" && !def.args ? z.any() : def.args;
	return {
		name: def.name,
		args: argsSchema,
		render: def.render,
		...def.agentId ? { agentId: def.agentId } : {}
	};
}

//#endregion
//#region src/v2/a2ui/A2UIToolCallRenderer.tsx
/**
* Tool name used by the dynamic A2UI generation secondary LLM.
*/
const RENDER_A2UI_TOOL_NAME = "render_a2ui";
/**
* Registers a no-op renderer for the `render_a2ui` tool call so its raw streamed
* args are never surfaced in the transcript.
*
* The generation skeleton / retry / failure UX is NO LONGER owned here (OSS-162):
* the A2UI middleware drives the whole lifecycle on the `a2ui-surface` activity
* (one stable messageId, building → retrying → failed → painted), rendered in
* place by `createA2UIMessageRenderer`. Owning a skeleton per tool call caused a
* duplicate skeleton on retries / multi-call generations and a skeleton that
* lingered after the surface painted — both fixed by retiring it here.
*
* Users can still override with their own `useRenderTool({ name: "render_a2ui" })`
* (hook-based entries take priority over this prop-based registration).
*/
function A2UIBuiltInToolCallRenderer() {
	const { copilotkit } = useCopilotKit$1();
	useEffect(() => {
		const renderer = defineToolCallRenderer({
			name: RENDER_A2UI_TOOL_NAME,
			args: z.any(),
			render: () => /* @__PURE__ */ jsx(Fragment$1, {})
		});
		const existing = copilotkit._renderToolCalls ?? [];
		copilotkit.setRenderToolCalls([...existing.filter((rc) => rc.name !== RENDER_A2UI_TOOL_NAME), renderer]);
	}, [copilotkit]);
	return null;
}

//#endregion
//#region src/v2/a2ui/A2UICatalogContext.tsx
/**
* Renders agent context describing the available A2UI catalog and custom components.
* Only mount this component when A2UI is enabled.
*
* The entries are scoped to the agents the runtime applies A2UI to
* (`copilotkit.a2uiAgents`, #5369), so agents outside that list don't receive
* the catalog/schema/guidelines payload on their runs.
*
* When `includeSchema` is true, the full component schemas (JSON Schema) are also
* sent as context using the same description key as the A2UI middleware, so the
* middleware can optionally overwrite it with a server-side schema.
*/
function A2UICatalogContext({ catalog, includeSchema }) {
	const { copilotkit } = useCopilotKit$1();
	const capabilitiesValue = useMemo(() => buildCatalogContextValue(catalog), [catalog]);
	const schemaValue = useMemo(() => includeSchema !== false ? JSON.stringify(extractCatalogComponentSchemas(catalog)) : null, [catalog, includeSchema]);
	const a2uiAgentsKey = copilotkit?.a2uiAgents?.join(",");
	useLayoutEffect(() => {
		if (!copilotkit) return;
		const agentIds = copilotkit.a2uiAgents;
		const scope = agentIds ? { agentIds } : {};
		const ids = [];
		ids.push(copilotkit.addContext({
			description: "A2UI catalog capabilities: available catalog IDs and custom component definitions the client can render.",
			value: capabilitiesValue,
			...scope
		}));
		if (schemaValue) {
			ids.push(copilotkit.addContext({
				description: A2UI_SCHEMA_CONTEXT_DESCRIPTION,
				value: schemaValue,
				...scope
			}));
			ids.push(copilotkit.addContext({
				description: "A2UI generation guidelines — protocol rules, tool arguments, path rules, data model format, and form/two-way-binding instructions.",
				value: A2UI_DEFAULT_GENERATION_GUIDELINES,
				...scope
			}));
			ids.push(copilotkit.addContext({
				description: "A2UI design guidelines — visual design rules, component hierarchy tips, and action handler patterns.",
				value: A2UI_DEFAULT_DESIGN_GUIDELINES,
				...scope
			}));
		}
		return () => {
			for (const id of ids) copilotkit.removeContext(id);
		};
	}, [
		copilotkit,
		capabilitiesValue,
		schemaValue,
		a2uiAgentsKey
	]);
	return null;
}

//#endregion
//#region src/v2/lib/react-core.ts
var CopilotKitCoreReact = class extends CopilotKitCore {
	constructor(config) {
		super(config);
		this._renderToolCalls = [];
		this._hookRenderToolCalls = /* @__PURE__ */ new Map();
		this._cachedMergedRenderToolCalls = null;
		this._renderCustomMessages = [];
		this._renderActivityMessages = [];
		this._interruptElement = null;
		this._renderToolCalls = config.renderToolCalls ?? [];
		this._renderCustomMessages = config.renderCustomMessages ?? [];
		this._renderActivityMessages = config.renderActivityMessages ?? [];
	}
	get renderCustomMessages() {
		return this._renderCustomMessages;
	}
	get renderActivityMessages() {
		return this._renderActivityMessages;
	}
	get renderToolCalls() {
		if (this._hookRenderToolCalls.size === 0) return this._renderToolCalls;
		if (this._cachedMergedRenderToolCalls) return this._cachedMergedRenderToolCalls;
		const merged = /* @__PURE__ */ new Map();
		for (const rc of this._renderToolCalls) merged.set(`${rc.agentId ?? ""}:${rc.name}`, rc);
		for (const [key, rc] of this._hookRenderToolCalls) merged.set(key, rc);
		this._cachedMergedRenderToolCalls = Array.from(merged.values());
		return this._cachedMergedRenderToolCalls;
	}
	setRenderActivityMessages(renderers) {
		this._renderActivityMessages = renderers;
	}
	setRenderCustomMessages(renderers) {
		this._renderCustomMessages = renderers;
	}
	setRenderToolCalls(renderToolCalls) {
		this._renderToolCalls = renderToolCalls;
		this._cachedMergedRenderToolCalls = null;
		this._notifyRenderToolCallsChanged();
	}
	addHookRenderToolCall(entry) {
		const key = `${entry.agentId ?? ""}:${entry.name}`;
		this._hookRenderToolCalls.set(key, entry);
		this._cachedMergedRenderToolCalls = null;
		this._notifyRenderToolCallsChanged();
	}
	removeHookRenderToolCall(name, agentId) {
		const key = `${agentId ?? ""}:${name}`;
		if (this._hookRenderToolCalls.delete(key)) {
			this._cachedMergedRenderToolCalls = null;
			this._notifyRenderToolCallsChanged();
		}
	}
	_notifyRenderToolCallsChanged() {
		this.notifySubscribers((subscriber) => {
			const reactSubscriber = subscriber;
			if (reactSubscriber.onRenderToolCallsChanged) reactSubscriber.onRenderToolCallsChanged({
				copilotkit: this,
				renderToolCalls: this.renderToolCalls
			});
		}, "Subscriber onRenderToolCallsChanged error:");
	}
	get interruptElement() {
		return this._interruptElement;
	}
	setInterruptElement(element) {
		this._interruptElement = element;
		this.notifySubscribers((subscriber) => {
			subscriber.onInterruptElementChanged?.({
				copilotkit: this,
				interruptElement: this._interruptElement
			});
		}, "Subscriber onInterruptElementChanged error:");
	}
	subscribe(subscriber) {
		return super.subscribe(subscriber);
	}
	/**
	* Wait for pending React state updates before the follow-up agent run.
	*
	* When a frontend tool handler calls setState(), React 18 batches the update
	* and schedules a commit via its internal scheduler (MessageChannel). The
	* useAgentContext hook registers context via useLayoutEffect, which runs
	* synchronously after React commits that batch.
	*
	* Awaiting a zero-delay timeout yields to the macrotask queue. React's
	* MessageChannel task runs first, committing the pending state and running
	* useLayoutEffect (which updates the context store). The follow-up runAgent
	* call then reads fresh context.
	*/
	async waitForPendingFrameworkUpdates() {
		await new Promise((resolve) => setTimeout(resolve, 0));
	}
};

//#endregion
//#region src/v2/providers/CopilotKitProvider.tsx
const zodToJsonSchemaAdapter = (schema, options) => {
	const refStrategy = options?.$refStrategy;
	return zodToJsonSchema(schema, refStrategy === "root" || refStrategy === "relative" || refStrategy === "none" || refStrategy === "seen" ? { $refStrategy: refStrategy } : {});
};
const HEADER_NAME = "X-CopilotCloud-Public-Api-Key";
const COPILOT_CLOUD_CHAT_URL$1 = "https://api.cloud.copilotkit.ai/copilotkit/v1";
const EMPTY_HEADERS = Object.freeze({});
const EMPTY_PROPERTIES = Object.freeze({});
const EMPTY_AGENTS = Object.freeze({});
const DEFAULT_DESIGN_SKILL = `When generating UI with generateSandboxedUi, follow these design principles inspired by shadcn/ui:

- Use a minimal, flat aesthetic. Avoid drop shadows and gradients — rely on subtle borders (1px solid, light gray like #e5e7eb) to define surfaces.
- Neutral base palette: white backgrounds, zinc/slate gray text (#09090b for headings, #71717a for secondary text). One accent color for interactive elements.
- Use system font stacks (system-ui, -apple-system, sans-serif) at readable sizes (14px body, 600 weight for headings). Tight line-heights.
- Small, consistent border-radius (6–8px). Cards and containers use border, not shadow, for separation.
- Buttons: solid fill for primary (dark bg, white text), outline for secondary (border + transparent bg). Subtle hover state (slight opacity or background shift).
- Use CSS Grid or Flexbox for layout. Ensure the UI looks good at any width.
- Minimal transitions (150ms) for hover/focus states only. No decorative animations.
- Keep the UI focused and dense — avoid excessive padding. Use compact spacing (8–12px gaps, 10–14px padding in controls).`;
const GENERATE_SANDBOXED_UI_DESCRIPTION = "Generate sandboxed UI. IMPORTANT: The generated code runs in a sandboxed iframe WITHOUT same-origin access. Do NOT use localStorage, sessionStorage, document.cookie, IndexedDB, or fetch/XMLHttpRequest to same-origin URLs. To communicate with the host application, use Websandbox.connection.remote.<functionName>(args) which returns a Promise.\n\nYou CAN use external libraries from CDNs by including <script> or <link> tags in the HTML <head> (e.g., Chart.js, D3, Three.js, x-data-spreadsheet, etc.). CDN resources load normally inside the sandbox.\n\nPARAMETER ORDER IS CRITICAL — generate parameters in exactly this order:\n1. initialHeight + placeholderMessages (shown to user while generating)\n2. css (all styles FIRST — the user sees a placeholder until CSS is complete)\n3. html (streams in live — the user watches the UI build as HTML is generated)\n4. jsFunctions (reusable helper functions)\n5. jsExpressions (applied one-by-one — the user sees each expression take effect)";
function useStableArrayProp(prop, warningMessage, isMeaningfulChange) {
	const empty = useMemo(() => [], []);
	const value = prop ?? empty;
	const initial = useRef(value);
	useEffect(() => {
		if (warningMessage && value !== initial.current && (isMeaningfulChange ? isMeaningfulChange(initial.current, value) : true)) console.error(warningMessage);
	}, [value, warningMessage]);
	return value;
}
const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY_HEADERS, credentials, publicApiKey, publicLicenseKey, licenseToken, properties = EMPTY_PROPERTIES, agents__unsafe_dev_only: agents = EMPTY_AGENTS, selfManagedAgents = EMPTY_AGENTS, renderToolCalls, renderActivityMessages, renderCustomMessages, frontendTools, humanInTheLoop, openGenerativeUI, showDevConsole = false, useSingleEndpoint, onError, a2ui, defaultThrottleMs, inspectorDefaultAnchor, debug }) => {
	const [shouldRenderInspector, setShouldRenderInspector] = useState(false);
	const [isLocalInspectorEnabled, setIsLocalInspectorEnabled] = useState(false);
	const [inspectorOpenRequest, setInspectorOpenRequest] = useState(null);
	const [runtimeA2UIEnabled, setRuntimeA2UIEnabled] = useState(false);
	const [runtimeOpenGenUIEnabled, setRuntimeOpenGenUIEnabled] = useState(false);
	const [catalogToggleVersion, setCatalogToggleVersion] = useState(0);
	const openGenUIActive = runtimeOpenGenUIEnabled || !!openGenerativeUI;
	const a2uiCatalogProvided = !!a2ui?.catalog;
	const a2uiActive = runtimeA2UIEnabled || a2uiCatalogProvided;
	const [runtimeLicenseStatus, setRuntimeLicenseStatus] = useState(void 0);
	useEffect(() => {
		if (typeof window === "undefined") return;
		const isLocalhost = new Set(["localhost", "127.0.0.1"]).has(window.location?.hostname ?? "");
		const canShowLocalInspectorAction = process.env.NODE_ENV === "development" && isLocalhost;
		if (showDevConsole === true) {
			setShouldRenderInspector(true);
			setIsLocalInspectorEnabled(canShowLocalInspectorAction);
		} else if (showDevConsole === "auto") if (isLocalhost) {
			setShouldRenderInspector(true);
			setIsLocalInspectorEnabled(canShowLocalInspectorAction);
		} else {
			setShouldRenderInspector(false);
			setIsLocalInspectorEnabled(false);
		}
		else {
			setShouldRenderInspector(false);
			setIsLocalInspectorEnabled(false);
		}
	}, [showDevConsole]);
	const requestInspectorOpen = useCallback((request) => {
		setInspectorOpenRequest({ ...request });
	}, []);
	const inspectorContextValue = useMemo(() => ({
		isLocalInspectorEnabled,
		openInspector: requestInspectorOpen
	}), [isLocalInspectorEnabled, requestInspectorOpen]);
	const renderToolCallsList = useStableArrayProp(renderToolCalls, "renderToolCalls must be a stable array. If you want to dynamically add or remove tools, use `useFrontendTool` instead.", (initial, next) => {
		const key = (rc) => `${rc?.agentId ?? ""}:${rc?.name ?? ""}`;
		const setFrom = (arr) => new Set(arr.map(key));
		const a = setFrom(initial);
		const b = setFrom(next);
		if (a.size !== b.size) return true;
		for (const k of a) if (!b.has(k)) return true;
		return false;
	});
	const renderCustomMessagesList = useStableArrayProp(renderCustomMessages, "renderCustomMessages must be a stable array.");
	const renderActivityMessagesList = useStableArrayProp(renderActivityMessages, "renderActivityMessages must be a stable array.");
	const copilotkitRef = useRef(null);
	const rawCatalog = a2ui?.catalog;
	const filteredCatalog = useMemo(() => {
		if (!rawCatalog) return rawCatalog;
		if (!(rawCatalog instanceof Catalog)) return rawCatalog;
		const core = copilotkitRef.current;
		return filterCatalog(rawCatalog, (name) => core ? core.isCatalogComponentEnabled(name) : true);
	}, [rawCatalog, catalogToggleVersion]);
	const builtInActivityRenderers = useMemo(() => {
		const renderers = [{
			activityType: MCPAppsActivityType,
			content: MCPAppsActivityContentSchema,
			render: MCPAppsActivityRenderer
		}];
		if (openGenUIActive) renderers.push({
			activityType: OpenGenerativeUIActivityType,
			content: OpenGenerativeUIContentSchema,
			render: OpenGenerativeUIActivityRenderer
		});
		if (a2uiActive) renderers.unshift(createA2UIMessageRenderer({
			theme: a2ui?.theme ?? viewerTheme,
			catalog: filteredCatalog,
			loadingComponent: a2ui?.loadingComponent,
			recovery: a2ui?.recovery
		}));
		return renderers;
	}, [
		a2uiActive,
		openGenUIActive,
		a2ui,
		filteredCatalog
	]);
	const allActivityRenderers = useMemo(() => {
		return [...renderActivityMessagesList, ...builtInActivityRenderers];
	}, [renderActivityMessagesList, builtInActivityRenderers]);
	const resolvedPublicKey = publicApiKey ?? publicLicenseKey;
	const mergedAgents = useMemo(() => ({
		...agents,
		...selfManagedAgents
	}), [agents, selfManagedAgents]);
	const hasLocalAgents = mergedAgents && Object.keys(mergedAgents).length > 0;
	const hasSelfManagedAgents = Object.keys(selfManagedAgents).length > 0;
	useEffect(() => {
		if (hasSelfManagedAgents && !resolvedPublicKey) console.warn("[CopilotKit] `selfManagedAgents` is part of CopilotKit's Enterprise Intelligence offering. Provide a `publicLicenseKey` for production use — contact the CopilotKit team about licensing.");
	}, [hasSelfManagedAgents, resolvedPublicKey]);
	const headers = typeof headersProp === "function" ? headersProp() : headersProp;
	const mergedHeaders = useMemo(() => {
		if (!resolvedPublicKey) return headers;
		if (headers[HEADER_NAME]) return headers;
		return {
			...headers,
			[HEADER_NAME]: resolvedPublicKey
		};
	}, [headers, resolvedPublicKey]);
	if (!runtimeUrl && !resolvedPublicKey && !hasLocalAgents) {
		const message = "Missing required prop: 'runtimeUrl' or 'publicApiKey' or 'publicLicenseKey'";
		if (process.env.NODE_ENV === "production") throw new Error(message);
		else console.warn(message);
	}
	const chatApiEndpoint = runtimeUrl ?? (resolvedPublicKey ? COPILOT_CLOUD_CHAT_URL$1 : void 0);
	const frontendToolsList = useStableArrayProp(frontendTools, "frontendTools must be a stable array. If you want to dynamically add or remove tools, use `useFrontendTool` instead.");
	const humanInTheLoopList = useStableArrayProp(humanInTheLoop, "humanInTheLoop must be a stable array. If you want to dynamically add or remove human-in-the-loop tools, use `useHumanInTheLoop` instead.");
	const sandboxFunctionsList = useStableArrayProp(openGenerativeUI?.sandboxFunctions, "openGenerativeUI.sandboxFunctions must be a stable array.");
	const processedHumanInTheLoopTools = useMemo(() => {
		const processedTools = [];
		const processedRenderToolCalls = [];
		humanInTheLoopList.forEach((tool) => {
			const frontendTool = {
				name: tool.name,
				description: tool.description,
				parameters: tool.parameters,
				followUp: tool.followUp,
				...tool.agentId && { agentId: tool.agentId },
				handler: async () => {
					return new Promise((resolve) => {
						console.warn(`Human-in-the-loop tool '${tool.name}' called but no interactive handler is set up.`);
						resolve(void 0);
					});
				}
			};
			processedTools.push(frontendTool);
			if (tool.render) processedRenderToolCalls.push({
				name: tool.name,
				args: tool.parameters,
				render: tool.render,
				...tool.agentId && { agentId: tool.agentId }
			});
		});
		return {
			tools: processedTools,
			renderToolCalls: processedRenderToolCalls
		};
	}, [humanInTheLoopList]);
	const builtInFrontendTools = useMemo(() => {
		if (!openGenUIActive) return [];
		return [{
			name: "generateSandboxedUi",
			description: GENERATE_SANDBOXED_UI_DESCRIPTION,
			parameters: GenerateSandboxedUiArgsSchema,
			handler: async () => "UI generated",
			followUp: true,
			render: OpenGenerativeUIToolRenderer
		}];
	}, [openGenUIActive]);
	const allTools = useMemo(() => {
		const tools = [];
		tools.push(...frontendToolsList);
		tools.push(...builtInFrontendTools);
		tools.push(...processedHumanInTheLoopTools.tools);
		return tools;
	}, [
		frontendToolsList,
		builtInFrontendTools,
		processedHumanInTheLoopTools
	]);
	const allRenderToolCalls = useMemo(() => {
		const combined = [...renderToolCallsList];
		[...frontendToolsList, ...builtInFrontendTools].forEach((tool) => {
			if (tool.render) {
				const args = tool.parameters || (tool.name === "*" ? z.any() : void 0);
				if (args) combined.push({
					name: tool.name,
					args,
					render: tool.render
				});
			}
		});
		combined.push(...processedHumanInTheLoopTools.renderToolCalls);
		return combined;
	}, [
		renderToolCallsList,
		frontendToolsList,
		builtInFrontendTools,
		processedHumanInTheLoopTools
	]);
	if (copilotkitRef.current === null) {
		copilotkitRef.current = new CopilotKitCoreReact({
			runtimeUrl: chatApiEndpoint,
			deferInitialConnection: true,
			runtimeTransport: useSingleEndpoint === true ? "single" : useSingleEndpoint === false ? "rest" : "auto",
			headers: mergedHeaders,
			credentials,
			properties,
			agents__unsafe_dev_only: mergedAgents,
			tools: allTools,
			renderToolCalls: allRenderToolCalls,
			renderActivityMessages: allActivityRenderers,
			renderCustomMessages: renderCustomMessagesList,
			debug
		});
		if (defaultThrottleMs !== void 0) copilotkitRef.current.setDefaultThrottleMs(defaultThrottleMs);
	}
	const copilotkit = copilotkitRef.current;
	useEffect(() => {
		if (!rawCatalog) return;
		if (!(rawCatalog instanceof Catalog)) return;
		const components = Array.from(rawCatalog.components.values()).map((comp) => ({
			name: comp.name,
			description: void 0,
			schema: comp.schema
		}));
		copilotkit.setCatalogComponents(components);
		const subscription = copilotkit.subscribe({ onCatalogComponentsChanged: () => {
			setCatalogToggleVersion((v) => v + 1);
		} });
		return () => subscription.unsubscribe();
	}, [copilotkit, rawCatalog]);
	useEffect(() => {
		const syncRuntimeInfo = () => {
			setRuntimeA2UIEnabled(copilotkit.a2uiEnabled);
			setRuntimeOpenGenUIEnabled(copilotkit.openGenerativeUIEnabled);
			setRuntimeLicenseStatus(copilotkit.licenseStatus);
		};
		const subscription = copilotkit.subscribe({ onRuntimeConnectionStatusChanged: syncRuntimeInfo });
		syncRuntimeInfo();
		return () => {
			subscription.unsubscribe();
		};
	}, [copilotkit]);
	const [, forceUpdate] = useReducer((x) => x + 1, 0);
	useEffect(() => {
		const subscription = copilotkit.subscribe({ onRenderToolCallsChanged: () => {
			forceUpdate();
		} });
		return () => {
			subscription.unsubscribe();
		};
	}, [copilotkit]);
	const [executingToolCallIds, setExecutingToolCallIds] = useState(() => /* @__PURE__ */ new Set());
	useEffect(() => {
		const subscription = copilotkit.subscribe({
			onToolExecutionStart: ({ toolCallId }) => {
				setExecutingToolCallIds((prev) => {
					if (prev.has(toolCallId)) return prev;
					const next = new Set(prev);
					next.add(toolCallId);
					return next;
				});
			},
			onToolExecutionEnd: ({ toolCallId }) => {
				setExecutingToolCallIds((prev) => {
					if (!prev.has(toolCallId)) return prev;
					const next = new Set(prev);
					next.delete(toolCallId);
					return next;
				});
			}
		});
		return () => {
			subscription.unsubscribe();
		};
	}, [copilotkit]);
	const onErrorRef = useRef(onError);
	useEffect(() => {
		onErrorRef.current = onError;
	}, [onError]);
	useEffect(() => {
		const subscription = copilotkit.subscribe({ onError: (event) => {
			if (onErrorRef.current) onErrorRef.current(event);
			else console.error(`[CopilotKit] Error (${event.code}):`, event.error, event.context ?? {});
		} });
		return () => {
			subscription.unsubscribe();
		};
	}, [copilotkit]);
	useEffect(() => {
		copilotkit.setRuntimeUrl(chatApiEndpoint);
		copilotkit.setRuntimeTransport(useSingleEndpoint === true ? "single" : useSingleEndpoint === false ? "rest" : "auto");
		copilotkit.setHeaders(mergedHeaders);
		copilotkit.setCredentials(credentials);
		copilotkit.setProperties(a2uiCatalogProvided ? {
			...properties,
			a2uiCatalogAvailable: true
		} : properties);
		copilotkit.setAgents__unsafe_dev_only(mergedAgents);
		copilotkit.setDebug(debug);
		copilotkit.connect();
	}, [
		copilotkit,
		chatApiEndpoint,
		mergedHeaders,
		credentials,
		properties,
		a2uiCatalogProvided,
		mergedAgents,
		useSingleEndpoint,
		debug
	]);
	const didMountRef = useRef(false);
	useEffect(() => {
		if (!didMountRef.current) return;
		copilotkit.setTools(allTools);
	}, [copilotkit, allTools]);
	useEffect(() => {
		if (!didMountRef.current) return;
		copilotkit.setRenderToolCalls(allRenderToolCalls);
	}, [copilotkit, allRenderToolCalls]);
	useEffect(() => {
		if (!didMountRef.current) return;
		copilotkit.setRenderActivityMessages(allActivityRenderers);
	}, [copilotkit, allActivityRenderers]);
	useEffect(() => {
		if (!didMountRef.current) return;
		copilotkit.setRenderCustomMessages(renderCustomMessagesList);
	}, [copilotkit, renderCustomMessagesList]);
	useEffect(() => {
		didMountRef.current = true;
	}, []);
	useEffect(() => {
		copilotkit.setDefaultThrottleMs(defaultThrottleMs);
	}, [copilotkit, defaultThrottleMs]);
	const designSkill = openGenerativeUI?.designSkill ?? DEFAULT_DESIGN_SKILL;
	useLayoutEffect(() => {
		if (!copilotkit || !openGenUIActive) return;
		const id = copilotkit.addContext({
			description: "Design guidelines for the generateSandboxedUi tool. Follow these when building UI.",
			value: designSkill
		});
		return () => {
			copilotkit.removeContext(id);
		};
	}, [
		copilotkit,
		designSkill,
		openGenUIActive
	]);
	const sandboxFunctionsDescriptors = useMemo(() => {
		if (sandboxFunctionsList.length === 0) return null;
		return JSON.stringify(sandboxFunctionsList.map((fn) => ({
			name: fn.name,
			description: fn.description,
			parameters: schemaToJsonSchema(fn.parameters, { zodToJsonSchema: zodToJsonSchemaAdapter })
		})));
	}, [sandboxFunctionsList]);
	useLayoutEffect(() => {
		if (!copilotkit || !sandboxFunctionsDescriptors || !openGenUIActive) return;
		const id = copilotkit.addContext({
			description: "Sandbox functions available in generated sandboxed UI code. Call via: await Websandbox.connection.remote.<functionName>(args)",
			value: sandboxFunctionsDescriptors
		});
		return () => {
			copilotkit.removeContext(id);
		};
	}, [
		copilotkit,
		sandboxFunctionsDescriptors,
		openGenUIActive
	]);
	const contextValue = useMemo(() => ({
		copilotkit,
		executingToolCallIds
	}), [copilotkit, executingToolCallIds]);
	const licenseContextValue = useMemo(() => createLicenseContextValue(runtimeLicenseStatus), [runtimeLicenseStatus]);
	return /* @__PURE__ */ jsx(SandboxFunctionsContext.Provider, {
		value: sandboxFunctionsList,
		children: /* @__PURE__ */ jsx(CopilotKitContext.Provider, {
			value: contextValue,
			children: /* @__PURE__ */ jsxs(LicenseContext.Provider, {
				value: licenseContextValue,
				children: [
					a2uiActive && /* @__PURE__ */ jsx(A2UIBuiltInToolCallRenderer, {}),
					a2uiActive && /* @__PURE__ */ jsx(A2UICatalogContext, {
						catalog: filteredCatalog,
						includeSchema: a2ui?.includeSchema
					}),
					/* @__PURE__ */ jsxs(CopilotKitInspectorContextProvider, {
						value: inspectorContextValue,
						children: [children, shouldRenderInspector ? /* @__PURE__ */ jsx(CopilotKitInspector, {
							core: copilotkit,
							defaultAnchor: inspectorDefaultAnchor,
							openRequest: inspectorOpenRequest
						}) : null]
					}),
					runtimeLicenseStatus === "none" && !resolvedPublicKey && /* @__PURE__ */ jsx(LicenseWarningBanner, { type: "no_license" }),
					runtimeLicenseStatus === "expired" && /* @__PURE__ */ jsx(LicenseWarningBanner, { type: "expired" }),
					runtimeLicenseStatus === "invalid" && /* @__PURE__ */ jsx(LicenseWarningBanner, { type: "invalid" }),
					runtimeLicenseStatus === "expiring" && /* @__PURE__ */ jsx(LicenseWarningBanner, { type: "expiring" })
				]
			})
		})
	});
};

//#endregion
//#region src/v2/hooks/use-render-custom-messages.tsx
function useRenderCustomMessages() {
	const { copilotkit } = useCopilotKit$1();
	const config = useCopilotChatConfiguration();
	if (!config) return null;
	const { agentId, threadId } = config;
	const customMessageRenderers = copilotkit.renderCustomMessages.filter((renderer) => renderer.agentId === void 0 || renderer.agentId === agentId).sort((a, b) => {
		const aHasAgent = a.agentId !== void 0;
		if (aHasAgent === (b.agentId !== void 0)) return 0;
		return aHasAgent ? -1 : 1;
	});
	return function(params) {
		if (!customMessageRenderers.length) return null;
		const { message, position } = params;
		const resolvedRunId = copilotkit.getRunIdForMessage(agentId, threadId, message.id) ?? copilotkit.getRunIdsForThread(agentId, threadId).slice(-1)[0];
		const runId = resolvedRunId ?? `missing-run-id:${message.id}`;
		const agent = copilotkit.getAgent(agentId);
		if (!agent) return null;
		const messagesIdsInRun = resolvedRunId ? agent.messages.filter((msg) => copilotkit.getRunIdForMessage(agentId, threadId, msg.id) === resolvedRunId).map((msg) => msg.id) : [message.id];
		const rawMessageIndex = agent.messages.findIndex((msg) => msg.id === message.id);
		const messageIndex = rawMessageIndex >= 0 ? rawMessageIndex : 0;
		const messageIndexInRun = resolvedRunId ? Math.max(messagesIdsInRun.indexOf(message.id), 0) : 0;
		const numberOfMessagesInRun = resolvedRunId ? messagesIdsInRun.length : 1;
		const stateSnapshot = resolvedRunId ? copilotkit.getStateByRun(agentId, threadId, resolvedRunId) : void 0;
		let result = null;
		for (const renderer of customMessageRenderers) {
			if (!renderer.render) continue;
			const Component = renderer.render;
			result = /* @__PURE__ */ jsx(Component, {
				message,
				position,
				runId,
				messageIndex,
				messageIndexInRun,
				numberOfMessagesInRun,
				agentId,
				stateSnapshot
			}, `${runId}-${message.id}-${position}`);
			if (result) break;
		}
		return result;
	};
}

//#endregion
//#region src/v2/hooks/use-render-activity-message.tsx
function useRenderActivityMessage() {
	const { copilotkit } = useCopilotKit$1();
	const agentId = useCopilotChatConfiguration()?.agentId ?? DEFAULT_AGENT_ID;
	const renderers = copilotkit.renderActivityMessages;
	const findRenderer = useCallback((activityType) => {
		if (!renderers.length) return null;
		const matches = renderers.filter((renderer) => renderer.activityType === activityType);
		return matches.find((candidate) => candidate.agentId === agentId) ?? matches.find((candidate) => candidate.agentId === void 0) ?? renderers.find((candidate) => candidate.activityType === "*") ?? null;
	}, [agentId, renderers]);
	const renderActivityMessage = useCallback((message) => {
		const renderer = findRenderer(message.activityType);
		if (!renderer) return null;
		const parseResult = renderer.content["~standard"].validate(message.content);
		if (parseResult instanceof Promise) {
			console.warn(`Async content validation is not supported for activity message '${message.activityType}'`);
			return null;
		}
		if (parseResult.issues) {
			console.warn(`Failed to parse content for activity message '${message.activityType}':`, parseResult.issues);
			return null;
		}
		const Component = renderer.render;
		const agent = copilotkit.getAgent(agentId);
		return /* @__PURE__ */ jsx(Component, {
			activityType: message.activityType,
			content: parseResult.value,
			message,
			agent
		}, message.id);
	}, [
		agentId,
		copilotkit,
		findRenderer
	]);
	return useMemo(() => ({
		renderActivityMessage,
		findRenderer
	}), [renderActivityMessage, findRenderer]);
}

//#endregion
//#region src/v2/hooks/use-frontend-tool.tsx
const EMPTY_DEPS$1 = [];
function useFrontendTool(tool, deps) {
	const { copilotkit } = useCopilotKit();
	const extraDeps = deps ?? EMPTY_DEPS$1;
	useEffect(() => {
		const name = tool.name;
		if (copilotkit.getTool({
			toolName: name,
			agentId: tool.agentId
		})) {
			console.warn(`Tool '${name}' already exists for agent '${tool.agentId || "global"}'. Overriding with latest registration.`);
			copilotkit.removeTool(name, tool.agentId);
		}
		copilotkit.addTool(tool);
		if (tool.render) copilotkit.addHookRenderToolCall({
			name,
			args: tool.parameters,
			agentId: tool.agentId,
			render: tool.render
		});
		return () => {
			copilotkit.removeTool(name, tool.agentId);
		};
	}, [
		tool.name,
		tool.available,
		copilotkit,
		JSON.stringify(extraDeps)
	]);
}

//#endregion
//#region src/v2/hooks/use-component.tsx
/**
* Registers a React component as a frontend tool renderer in chat.
*
* This hook is a convenience wrapper around `useFrontendTool` that:
* - builds a model-facing tool description,
* - forwards optional schema parameters (any Standard Schema V1 compatible library),
* - renders your component with tool call parameters.
*
* Use this when you want to display a typed visual component for a tool call
* without manually wiring a full frontend tool object.
*
* When `parameters` is provided, render props are inferred from the schema.
* When omitted, the render component may accept any props.
*
* @typeParam TSchema - Schema describing tool parameters, or `undefined` when no schema is given.
* @param config - Tool registration config.
* @param deps - Optional dependencies to refresh registration (same semantics as `useEffect`).
*
* @example
* ```tsx
* // Without parameters — render accepts any props
* useComponent({
*   name: "showGreeting",
*   render: ({ message }: { message: string }) => <div>{message}</div>,
* });
* ```
*
* @example
* ```tsx
* // With parameters — render props inferred from schema
* useComponent({
*   name: "showWeatherCard",
*   parameters: z.object({ city: z.string() }),
*   render: ({ city }) => <div>{city}</div>,
* });
* ```
*
* @example
* ```tsx
* useComponent(
*   {
*     name: "renderProfile",
*     parameters: z.object({ userId: z.string() }),
*     render: ProfileCard,
*     agentId: "support-agent",
*   },
*   [selectedAgentId],
* );
* ```
*/
function useComponent(config, deps) {
	const prefix = `Use this tool to display the "${config.name}" component in the chat. This tool renders a visual UI component for the user.`;
	const fullDescription = config.description ? `${prefix}\n\n${config.description}` : prefix;
	useFrontendTool({
		name: config.name,
		description: fullDescription,
		parameters: config.parameters,
		render: ({ args }) => {
			const Component = config.render;
			return /* @__PURE__ */ jsx(Component, { ...args });
		},
		agentId: config.agentId,
		followUp: config.followUp
	}, deps);
}

//#endregion
//#region src/v2/hooks/use-render-tool.tsx
const EMPTY_DEPS = [];
/**
* Registers a renderer entry in CopilotKit's `renderToolCalls` registry.
*
* Key behavior:
* - deduplicates by `agentId:name` (latest registration wins),
* - keeps renderer entries on cleanup so historical chat tool calls can still render,
* - refreshes registration when `deps` change.
*
* @typeParam S - Schema type describing tool call parameters.
* @param config - Renderer config for wildcard or named tools.
* @param deps - Optional dependencies to refresh registration.
*
* @example
* ```tsx
* useRenderTool(
*   {
*     name: "searchDocs",
*     parameters: z.object({ query: z.string() }),
*     render: ({ status, parameters, result }) => {
*       if (status === "executing") return <div>Searching {parameters.query}</div>;
*       if (status === "complete") return <div>{result}</div>;
*       return <div>Preparing...</div>;
*     },
*   },
*   [],
* );
* ```
*
* @example
* ```tsx
* useRenderTool(
*   {
*     name: "summarize",
*     parameters: z.object({ text: z.string() }),
*     agentId: "research-agent",
*     render: ({ name, status }) => <div>{name}: {status}</div>,
*   },
*   [selectedAgentId],
* );
* ```
*/
function useRenderTool(config, deps) {
	const { copilotkit } = useCopilotKit();
	const extraDeps = deps ?? EMPTY_DEPS;
	useEffect(() => {
		const renderer = config.name === "*" && !config.parameters ? defineToolCallRenderer({
			name: "*",
			render: (props) => config.render({
				...props,
				parameters: props.args
			}),
			...config.agentId ? { agentId: config.agentId } : {}
		}) : defineToolCallRenderer({
			name: config.name,
			args: config.parameters,
			render: (props) => {
				if (props.status === ToolCallStatus.InProgress) return config.render({
					...props,
					parameters: props.args
				});
				if (props.status === ToolCallStatus.Executing) return config.render({
					...props,
					parameters: props.args
				});
				return config.render({
					...props,
					parameters: props.args
				});
			},
			...config.agentId ? { agentId: config.agentId } : {}
		});
		copilotkit.addHookRenderToolCall(renderer);
	}, [
		config.name,
		copilotkit,
		JSON.stringify(extraDeps)
	]);
}

//#endregion
//#region src/v2/hooks/use-default-render-tool.tsx
/**
* Module-level dedup set so an unknown status value only emits a console
* warning the FIRST time we encounter it. Otherwise a stuck/unmapped status
* would log on every re-render (potentially many per second).
*/
const warnedUnknownStatuses = /* @__PURE__ */ new Set();
/**
* Map a {@link ToolCallStatus} enum value to the documented string-union
* status the {@link DefaultRenderProps} contract exposes. Unknown / future
* enum members log a warning (once per distinct value) and fall back to
* `"inProgress"`.
*/
function mapToolCallStatus(status) {
	switch (status) {
		case ToolCallStatus.Complete: return "complete";
		case ToolCallStatus.Executing: return "executing";
		case ToolCallStatus.InProgress: return "inProgress";
		default: {
			const key = String(status);
			if (!warnedUnknownStatuses.has(key)) {
				warnedUnknownStatuses.add(key);
				console.warn(`[CopilotKit] Unknown ToolCallStatus "${key}" in default tool-call renderer; falling back to "inProgress".`);
			}
			return "inProgress";
		}
	}
}
/**
* Convert the framework-internal renderer props (`args`, enum status) into
* the documented {@link DefaultRenderProps} shape (`parameters`, string-union
* status) so a user `config.render` always sees the documented contract.
*/
function adaptRendererProps(props) {
	return {
		name: props.name,
		toolCallId: props.toolCallId,
		parameters: props.args,
		status: mapToolCallStatus(props.status),
		result: props.result
	};
}
/**
* Registers a wildcard (`"*"`) tool-call renderer via `useRenderTool`.
*
* - Call with no config to use CopilotKit's built-in default tool-call card.
* - Pass `config.render` to replace the default UI with your own fallback renderer.
*
* This is useful when you want a generic renderer for tools that do not have a
* dedicated `useRenderTool({ name: "..." })` registration.
*
* @param config - Optional custom wildcard render function.
* @param deps - Optional dependencies to refresh registration.
*
* @example
* ```tsx
* useDefaultRenderTool();
* ```
*
* @example
* ```tsx
* useDefaultRenderTool({
*   render: ({ name, status }) => <div>{name}: {status}</div>,
* });
* ```
*
* @example
* ```tsx
* useDefaultRenderTool(
*   {
*     render: ({ name, result }) => (
*       <ToolEventRow title={name} payload={result} compact={compactMode} />
*     ),
*   },
*   [compactMode],
* );
* ```
*/
function useDefaultRenderTool(config, deps) {
	const userRender = config?.render;
	useRenderTool({
		name: "*",
		render: userRender ? (raw) => userRender(adaptRendererProps(raw)) : (raw) => /* @__PURE__ */ jsx(DefaultToolCallRenderer, { ...adaptRendererProps(raw) })
	}, deps);
}
/**
* Guarded JSON.stringify used inside the expanded `<pre>` blocks. A circular
* reference would otherwise crash the entire React tree on render.
*/
function safeStringifyForPre(value) {
	try {
		return JSON.stringify(value, null, 2);
	} catch (err) {
		console.warn("[CopilotKit] Failed to JSON.stringify tool-call payload for default renderer; falling back to String():", err);
		try {
			return String(value);
		} catch (innerErr) {
			console.warn("[CopilotKit] safeStringifyForPre: value could not be stringified:", innerErr);
			return "[unserializable]";
		}
	}
}
function DefaultToolCallRenderer({ name, toolCallId, parameters, status, result }) {
	const [isExpanded, setIsExpanded] = useState(false);
	const isActive = status === "inProgress" || status === "executing";
	const isComplete = status === "complete";
	const statusLabel = isActive ? "Running" : isComplete ? "Done" : status;
	const dotClassName = isActive ? "cpk:bg-amber-500" : isComplete ? "cpk:bg-emerald-500" : "cpk:bg-zinc-400";
	const badgeClassName = isActive ? "cpk:bg-amber-100 cpk:text-amber-800 cpk:dark:bg-amber-500/15 cpk:dark:text-amber-400" : isComplete ? "cpk:bg-emerald-100 cpk:text-emerald-800 cpk:dark:bg-emerald-500/15 cpk:dark:text-emerald-400" : "cpk:bg-zinc-100 cpk:text-zinc-800 cpk:dark:bg-zinc-700/40 cpk:dark:text-zinc-300";
	return /* @__PURE__ */ jsx("div", {
		"data-testid": "copilot-tool-render",
		"data-tool-name": name,
		"data-tool-call-id": toolCallId,
		"data-status": status,
		"data-args": safeStringifyForAttr(parameters),
		"data-result": safeStringifyForAttr(result),
		className: "cpk:mt-2 cpk:pb-2",
		children: /* @__PURE__ */ jsxs("div", {
			className: "cpk:rounded-xl cpk:border cpk:border-zinc-200/60 cpk:bg-white/70 cpk:p-4 cpk:shadow-sm cpk:backdrop-blur cpk:dark:border-zinc-800/60 cpk:dark:bg-zinc-900/50",
			children: [/* @__PURE__ */ jsxs("button", {
				type: "button",
				"aria-expanded": isExpanded,
				onClick: () => setIsExpanded(!isExpanded),
				className: "cpk:flex cpk:w-full cpk:cursor-pointer cpk:select-none cpk:items-center cpk:justify-between cpk:gap-2.5 cpk:border-none cpk:bg-transparent cpk:p-0 cpk:m-0 cpk:text-left cpk:text-inherit",
				style: { font: "inherit" },
				children: [/* @__PURE__ */ jsxs("div", {
					className: "cpk:flex cpk:min-w-0 cpk:items-center cpk:gap-2",
					children: [
						/* @__PURE__ */ jsx("svg", {
							className: `cpk:h-3.5 cpk:w-3.5 cpk:flex-shrink-0 cpk:text-zinc-500 cpk:transition-transform cpk:dark:text-zinc-400 ${isExpanded ? "cpk:rotate-90" : ""}`,
							fill: "none",
							viewBox: "0 0 24 24",
							strokeWidth: 2,
							stroke: "currentColor",
							children: /* @__PURE__ */ jsx("path", {
								strokeLinecap: "round",
								strokeLinejoin: "round",
								d: "M8.25 4.5l7.5 7.5-7.5 7.5"
							})
						}),
						/* @__PURE__ */ jsx("span", { className: `cpk:inline-block cpk:h-2 cpk:w-2 cpk:flex-shrink-0 cpk:rounded-full ${dotClassName}` }),
						/* @__PURE__ */ jsx("span", {
							"data-testid": "copilot-tool-render-name",
							className: "cpk:truncate cpk:text-[13px] cpk:font-semibold cpk:text-zinc-900 cpk:dark:text-zinc-100",
							children: name
						})
					]
				}), /* @__PURE__ */ jsx("span", {
					"data-testid": "copilot-tool-render-status",
					className: `cpk:inline-flex cpk:flex-shrink-0 cpk:items-center cpk:rounded-full cpk:px-2 cpk:py-0.5 cpk:text-[11px] cpk:font-medium ${badgeClassName}`,
					children: statusLabel
				})]
			}), isExpanded && /* @__PURE__ */ jsxs("div", {
				className: "cpk:mt-3 cpk:grid cpk:gap-3",
				children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
					className: "cpk:text-[10px] cpk:uppercase cpk:text-zinc-500 cpk:dark:text-zinc-400",
					children: "Arguments"
				}), /* @__PURE__ */ jsx("pre", {
					className: "cpk:mt-1.5 cpk:max-h-[200px] cpk:overflow-auto cpk:rounded-md cpk:bg-zinc-100 cpk:p-2.5 cpk:text-[11px] cpk:leading-relaxed cpk:text-zinc-800 cpk:whitespace-pre-wrap cpk:break-words cpk:dark:bg-zinc-800/60 cpk:dark:text-zinc-200",
					children: safeStringifyForPre(parameters ?? {})
				})] }), result !== void 0 && /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
					className: "cpk:text-[10px] cpk:uppercase cpk:text-zinc-500 cpk:dark:text-zinc-400",
					children: "Result"
				}), /* @__PURE__ */ jsx("pre", {
					className: "cpk:mt-1.5 cpk:max-h-[200px] cpk:overflow-auto cpk:rounded-md cpk:bg-zinc-100 cpk:p-2.5 cpk:text-[11px] cpk:leading-relaxed cpk:text-zinc-800 cpk:whitespace-pre-wrap cpk:break-words cpk:dark:bg-zinc-800/60 cpk:dark:text-zinc-200",
					children: typeof result === "string" ? result : safeStringifyForPre(result)
				})] })]
			})]
		})
	});
}
function safeStringifyForAttr(value) {
	if (value === void 0 || value === null) return "";
	if (typeof value === "string") return value;
	try {
		return JSON.stringify(value);
	} catch (err) {
		console.warn("[CopilotKit] Failed to JSON.stringify tool-call payload for data-* attribute; falling back to String():", err);
		try {
			return String(value);
		} catch (innerErr) {
			console.warn("[CopilotKit] safeStringifyForAttr: value could not be stringified:", innerErr);
			return "";
		}
	}
}

//#endregion
//#region src/v2/hooks/use-human-in-the-loop.tsx
function useHumanInTheLoop(tool, deps) {
	const { copilotkit } = useCopilotKit();
	const resolvePromiseRef = useRef(null);
	const cleanupAbortRef = useRef(null);
	const respond = useCallback(async (result) => {
		if (resolvePromiseRef.current) {
			cleanupAbortRef.current?.();
			cleanupAbortRef.current = null;
			resolvePromiseRef.current(result);
			resolvePromiseRef.current = null;
		}
	}, []);
	const handler = useCallback(async (_args, context) => {
		const signal = context?.signal;
		return new Promise((resolve, reject) => {
			if (signal?.aborted) {
				reject(/* @__PURE__ */ new Error("Human-in-the-loop interaction aborted"));
				return;
			}
			resolvePromiseRef.current = resolve;
			if (signal) {
				const onAbort = () => {
					cleanupAbortRef.current = null;
					resolvePromiseRef.current = null;
					reject(/* @__PURE__ */ new Error("Human-in-the-loop interaction aborted"));
				};
				signal.addEventListener("abort", onAbort, { once: true });
				cleanupAbortRef.current = () => {
					signal.removeEventListener("abort", onAbort);
				};
			}
		});
	}, []);
	const RenderComponent = useCallback((props) => {
		const ToolComponent = tool.render;
		if (props.status === ToolCallStatus.InProgress) {
			const enhancedProps = {
				...props,
				name: tool.name,
				description: tool.description || "",
				agentId: tool.agentId,
				respond: void 0
			};
			return React.createElement(ToolComponent, enhancedProps);
		} else if (props.status === ToolCallStatus.Executing) {
			const enhancedProps = {
				...props,
				name: tool.name,
				description: tool.description || "",
				agentId: tool.agentId,
				respond
			};
			return React.createElement(ToolComponent, enhancedProps);
		} else if (props.status === ToolCallStatus.Complete) {
			const enhancedProps = {
				...props,
				name: tool.name,
				description: tool.description || "",
				agentId: tool.agentId,
				respond: void 0
			};
			return React.createElement(ToolComponent, enhancedProps);
		}
		return props;
	}, [
		tool.render,
		tool.name,
		tool.description,
		tool.agentId,
		respond
	]);
	useFrontendTool({
		...tool,
		handler,
		render: RenderComponent
	}, deps);
	useEffect(() => {
		return () => {
			copilotkit.removeHookRenderToolCall(tool.name, tool.agentId);
		};
	}, [
		copilotkit,
		tool.name,
		tool.agentId
	]);
}

//#endregion
//#region src/v2/hooks/use-agent.tsx
let UseAgentUpdate = /* @__PURE__ */ function(UseAgentUpdate) {
	UseAgentUpdate["OnMessagesChanged"] = "OnMessagesChanged";
	UseAgentUpdate["OnStateChanged"] = "OnStateChanged";
	UseAgentUpdate["OnRunStatusChanged"] = "OnRunStatusChanged";
	return UseAgentUpdate;
}({});
const ALL_UPDATES = [
	UseAgentUpdate.OnMessagesChanged,
	UseAgentUpdate.OnStateChanged,
	UseAgentUpdate.OnRunStatusChanged
];
function useAgent({ agentId, threadId, runtimeAgentId, updates, throttleMs } = {}) {
	if (threadId != null && runtimeAgentId == null) throw new Error(`useAgent: \`threadId\` requires \`runtimeAgentId\`. A threadId is written onto a single agent, but an agent resolved by agentId alone is shared, so scoping a thread to it would clobber other useAgent callers. Pass a distinct local \`agentId\` and the runtime agent to route to, e.g. useAgent({ agentId: "chat-1", runtimeAgentId: "${agentId ?? "default"}", threadId }).`);
	if (runtimeAgentId != null && threadId == null) throw new Error(`useAgent: \`runtimeAgentId\` requires \`threadId\`. A proxied agent exists to scope a thread to a private instance; without a threadId it behaves like the shared agent while adding a registration and a local agentId to keep unique. Either pass the thread, e.g. useAgent({ agentId: "${agentId ?? "chat-1"}", runtimeAgentId: "${runtimeAgentId}", threadId }), or bind to the agent directly with useAgent({ agentId: "${runtimeAgentId}" }).`);
	if (runtimeAgentId != null && agentId == null) throw new Error(`useAgent: \`runtimeAgentId\` requires an explicit \`agentId\`. The proxied agent is registered under \`agentId\`, and the usual fallbacks (chat configuration, then "${DEFAULT_AGENT_ID}") name agents that already exist — registering over one throws or shadows it. Pick a local id for this hook, e.g. useAgent({ agentId: "chat-1", runtimeAgentId: "${runtimeAgentId}", threadId }).`);
	const chatConfig = useCopilotChatConfiguration();
	const resolvedAgentId = agentId ?? chatConfig?.agentId ?? DEFAULT_AGENT_ID;
	const { copilotkit } = useCopilotKit();
	const providerThrottleMs = copilotkit.defaultThrottleMs;
	const [, forceUpdate] = useReducer((x) => x + 1, 0);
	const updateFlags = useMemo(() => updates ?? ALL_UPDATES, [JSON.stringify(updates)]);
	const provisionalAgentCache = useRef(/* @__PURE__ */ new Map());
	const [registeredProxyAgent, setRegisteredProxyAgent] = useState(null);
	useEffect(() => {
		if (runtimeAgentId == null) {
			setRegisteredProxyAgent(null);
			return;
		}
		const { agent: proxy, unregister } = copilotkit.registerProxiedAgent({
			agentId: resolvedAgentId,
			runtimeAgentId
		});
		provisionalAgentCache.current.delete(resolvedAgentId);
		setRegisteredProxyAgent(proxy);
		return () => {
			unregister();
			setRegisteredProxyAgent(null);
		};
	}, [
		copilotkit,
		resolvedAgentId,
		runtimeAgentId
	]);
	const { agent, isReady } = useMemo(() => {
		if (runtimeAgentId != null) {
			if (registeredProxyAgent) {
				provisionalAgentCache.current.delete(resolvedAgentId);
				return {
					agent: registeredProxyAgent,
					isReady: true
				};
			}
			const cached = provisionalAgentCache.current.get(resolvedAgentId);
			if (cached) {
				copilotkit.applyHeadersToAgent(cached);
				return {
					agent: cached,
					isReady: false
				};
			}
			const provisional = new ProxiedCopilotRuntimeAgent({
				runtimeUrl: copilotkit.runtimeUrl,
				agentId: resolvedAgentId,
				runtimeAgentId,
				transport: copilotkit.runtimeTransport,
				runtimeMode: "pending"
			});
			copilotkit.applyHeadersToAgent(provisional);
			provisionalAgentCache.current.set(resolvedAgentId, provisional);
			return {
				agent: provisional,
				isReady: false
			};
		}
		const existing = copilotkit.getAgent(resolvedAgentId);
		if (existing) {
			provisionalAgentCache.current.delete(resolvedAgentId);
			return {
				agent: existing,
				isReady: true
			};
		}
		const isRuntimeConfigured = copilotkit.runtimeUrl !== void 0;
		const status = copilotkit.runtimeConnectionStatus;
		if (isRuntimeConfigured && (status === CopilotKitCoreRuntimeConnectionStatus.Disconnected || status === CopilotKitCoreRuntimeConnectionStatus.Connecting)) {
			const cached = provisionalAgentCache.current.get(resolvedAgentId);
			if (cached) return {
				agent: cached,
				isReady: false
			};
			const provisional = new ProxiedCopilotRuntimeAgent({
				runtimeUrl: copilotkit.runtimeUrl,
				agentId: resolvedAgentId,
				transport: copilotkit.runtimeTransport,
				credentials: copilotkit.credentials,
				runtimeMode: "pending"
			});
			copilotkit.applyHeadersToAgent(provisional);
			provisionalAgentCache.current.set(resolvedAgentId, provisional);
			return {
				agent: provisional,
				isReady: false
			};
		}
		if (isRuntimeConfigured && status === CopilotKitCoreRuntimeConnectionStatus.Error) {
			const cached = provisionalAgentCache.current.get(resolvedAgentId);
			if (cached) return {
				agent: cached,
				isReady: false
			};
			const provisional = new ProxiedCopilotRuntimeAgent({
				runtimeUrl: copilotkit.runtimeUrl,
				agentId: resolvedAgentId,
				transport: copilotkit.runtimeTransport,
				credentials: copilotkit.credentials,
				runtimeMode: "pending"
			});
			copilotkit.applyHeadersToAgent(provisional);
			provisionalAgentCache.current.set(resolvedAgentId, provisional);
			return {
				agent: provisional,
				isReady: false
			};
		}
		const knownAgents = Object.keys(copilotkit.agents ?? {});
		const runtimePart = isRuntimeConfigured ? `runtimeUrl=${copilotkit.runtimeUrl}` : "no runtimeUrl";
		throw new Error(`useAgent: Agent '${resolvedAgentId}' not found after runtime sync (${runtimePart}). ` + (knownAgents.length ? `Known agents: [${knownAgents.join(", ")}]` : "No agents registered.") + " Verify your runtime /info and/or agents__unsafe_dev_only.");
	}, [
		resolvedAgentId,
		runtimeAgentId,
		registeredProxyAgent,
		copilotkit.agents,
		copilotkit.runtimeConnectionStatus,
		copilotkit.runtimeUrl,
		copilotkit.runtimeTransport,
		copilotkit.credentials,
		JSON.stringify(copilotkit.headers)
	]);
	useEffect(() => {
		if (updateFlags.length === 0) return;
		let active = true;
		const handlers = {};
		let batchScheduled = false;
		const batchedForceUpdate = () => {
			if (!active) return;
			if (!batchScheduled) {
				batchScheduled = true;
				queueMicrotask(() => {
					batchScheduled = false;
					if (active) forceUpdate();
				});
			}
		};
		if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) handlers.onMessagesChanged = batchedForceUpdate;
		if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) handlers.onStateChanged = batchedForceUpdate;
		if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {
			handlers.onRunInitialized = batchedForceUpdate;
			handlers.onRunFinalized = batchedForceUpdate;
			handlers.onRunFailed = batchedForceUpdate;
			handlers.onRunErrorEvent = batchedForceUpdate;
		}
		const subscription = copilotkit.subscribeToAgentWithOptions(agent, handlers, { throttleMs });
		return () => {
			active = false;
			subscription.unsubscribe();
		};
	}, [
		agent,
		forceUpdate,
		throttleMs,
		providerThrottleMs,
		updateFlags
	]);
	useEffect(() => {
		if (agent instanceof HttpAgent) copilotkit.applyHeadersToAgent(agent);
		if (agent instanceof ProxiedCopilotRuntimeAgent) agent.credentials = copilotkit.credentials;
	}, [
		agent,
		JSON.stringify(copilotkit.headers),
		copilotkit.credentials
	]);
	const configThreadId = chatConfig?.threadId;
	const configHasExplicitThreadId = chatConfig?.hasExplicitThreadId;
	const resolvedThreadId = threadId ?? (configHasExplicitThreadId ? configThreadId : void 0);
	useEffect(() => {
		if (!resolvedThreadId) return;
		agent.threadId = resolvedThreadId;
	}, [agent, resolvedThreadId]);
	return {
		agent,
		isReady
	};
}

//#endregion
//#region src/v2/hooks/use-capabilities.tsx
/**
* Returns the capabilities declared by the given agent (or the agent resolved
* from the surrounding chat configuration, falling back to the default agent).
* Capabilities are populated from the runtime `/info` response at connection
* time. The hook reads them synchronously from the agent instance — there is
* no separate loading state, but the value will be `undefined` until the
* runtime handshake completes.
*
* @param agentId - Optional agent ID. If omitted, inherits the surrounding
*          chat configuration's agent, falling back to the default agent.
* @returns The agent's capabilities, or `undefined` if the agent doesn't
*          declare capabilities.
*/
function useCapabilities(agentId) {
	const { agent } = useAgent({ agentId });
	if (agent && "capabilities" in agent) return agent.capabilities;
}

//#endregion
//#region src/v2/hooks/use-agent-context.tsx
function useAgentContext(context) {
	const { description, value } = context;
	const { copilotkit } = useCopilotKit();
	const stringValue = useMemo(() => {
		if (typeof value === "string") return value;
		return JSON.stringify(value);
	}, [value]);
	useLayoutEffect(() => {
		if (!copilotkit) return;
		const id = copilotkit.addContext({
			description,
			value: stringValue
		});
		return () => {
			copilotkit.removeContext(id);
		};
	}, [
		description,
		stringValue,
		copilotkit
	]);
}

//#endregion
//#region src/v2/hooks/use-suggestions.tsx
function useSuggestions({ agentId } = {}) {
	const { copilotkit } = useCopilotKit();
	const config = useCopilotChatConfiguration();
	const resolvedAgentId = useMemo(() => agentId ?? config?.agentId ?? DEFAULT_AGENT_ID, [agentId, config?.agentId]);
	const [suggestions, setSuggestions] = useState(() => {
		return copilotkit.getSuggestions(resolvedAgentId).suggestions;
	});
	const [isLoading, setIsLoading] = useState(() => {
		return copilotkit.getSuggestions(resolvedAgentId).isLoading;
	});
	useEffect(() => {
		const result = copilotkit.getSuggestions(resolvedAgentId);
		setSuggestions(result.suggestions);
		setIsLoading(result.isLoading);
	}, [copilotkit, resolvedAgentId]);
	useEffect(() => {
		const subscription = copilotkit.subscribe({
			onSuggestionsChanged: ({ agentId: changedAgentId, suggestions }) => {
				if (changedAgentId !== resolvedAgentId) return;
				setSuggestions(suggestions);
			},
			onSuggestionsStartedLoading: ({ agentId: changedAgentId }) => {
				if (changedAgentId !== resolvedAgentId) return;
				setIsLoading(true);
			},
			onSuggestionsFinishedLoading: ({ agentId: changedAgentId }) => {
				if (changedAgentId !== resolvedAgentId) return;
				setIsLoading(false);
			},
			onSuggestionsConfigChanged: () => {
				const result = copilotkit.getSuggestions(resolvedAgentId);
				setSuggestions(result.suggestions);
				setIsLoading(result.isLoading);
			}
		});
		return () => {
			subscription.unsubscribe();
		};
	}, [copilotkit, resolvedAgentId]);
	return {
		suggestions,
		reloadSuggestions: useCallback(() => {
			copilotkit.reloadSuggestions(resolvedAgentId);
		}, [copilotkit, resolvedAgentId]),
		clearSuggestions: useCallback(() => {
			copilotkit.clearSuggestions(resolvedAgentId);
		}, [copilotkit, resolvedAgentId]),
		isLoading
	};
}

//#endregion
//#region src/v2/hooks/use-configure-suggestions.tsx
function useConfigureSuggestions(config, deps) {
	const { copilotkit } = useCopilotKit();
	const chatConfig = useCopilotChatConfiguration();
	const extraDeps = deps ?? [];
	const resolvedConsumerAgentId = useMemo(() => chatConfig?.agentId ?? DEFAULT_AGENT_ID, [chatConfig?.agentId]);
	const rawConsumerAgentId = useMemo(() => config ? config.consumerAgentId : void 0, [config]);
	const normalizationCacheRef = useRef({
		serialized: null,
		config: null
	});
	const { normalizedConfig, serializedConfig } = useMemo(() => {
		if (!config) {
			normalizationCacheRef.current = {
				serialized: null,
				config: null
			};
			return {
				normalizedConfig: null,
				serializedConfig: null
			};
		}
		if (config.available === "disabled") {
			normalizationCacheRef.current = {
				serialized: null,
				config: null
			};
			return {
				normalizedConfig: null,
				serializedConfig: null
			};
		}
		let built;
		if (isDynamicConfig(config)) built = { ...config };
		else {
			const normalizedSuggestions = normalizeStaticSuggestions(config.suggestions);
			built = {
				...config,
				suggestions: normalizedSuggestions
			};
		}
		const serialized = JSON.stringify(built);
		const cache = normalizationCacheRef.current;
		if (cache.serialized === serialized && cache.config) return {
			normalizedConfig: cache.config,
			serializedConfig: serialized
		};
		normalizationCacheRef.current = {
			serialized,
			config: built
		};
		return {
			normalizedConfig: built,
			serializedConfig: serialized
		};
	}, [
		config,
		resolvedConsumerAgentId,
		...extraDeps
	]);
	const latestConfigRef = useRef(null);
	latestConfigRef.current = normalizedConfig;
	const previousSerializedConfigRef = useRef(null);
	const targetAgentId = useMemo(() => {
		if (!normalizedConfig) return resolvedConsumerAgentId;
		const consumer = normalizedConfig.consumerAgentId;
		if (!consumer || consumer === "*") return resolvedConsumerAgentId;
		return consumer;
	}, [normalizedConfig, resolvedConsumerAgentId]);
	const isGlobalConfig = rawConsumerAgentId === void 0 || rawConsumerAgentId === "*";
	const isDynamicConfigType = useMemo(() => !!normalizedConfig && "instructions" in normalizedConfig, [normalizedConfig]);
	const requestReload = useCallback(() => {
		if (!normalizedConfig) return;
		if (isGlobalConfig) {
			const seen = /* @__PURE__ */ new Set();
			const agents = Object.values(copilotkit.agents ?? {});
			for (const entry of agents) {
				const agentId = entry.agentId;
				if (!agentId) continue;
				seen.add(agentId);
				if (!entry.isRunning) copilotkit.reloadSuggestions(agentId);
			}
			if (targetAgentId && !seen.has(targetAgentId)) copilotkit.reloadSuggestions(targetAgentId);
			return;
		}
		if (!targetAgentId) return;
		copilotkit.reloadSuggestions(targetAgentId);
	}, [
		copilotkit,
		isGlobalConfig,
		normalizedConfig,
		targetAgentId
	]);
	useEffect(() => {
		if (!serializedConfig || !latestConfigRef.current) return;
		const id = copilotkit.addSuggestionsConfig(latestConfigRef.current);
		requestReload();
		return () => {
			copilotkit.removeSuggestionsConfig(id);
		};
	}, [
		copilotkit,
		serializedConfig,
		requestReload
	]);
	useEffect(() => {
		if (!normalizedConfig) {
			previousSerializedConfigRef.current = null;
			return;
		}
		if (serializedConfig && previousSerializedConfigRef.current === serializedConfig) return;
		if (serializedConfig) previousSerializedConfigRef.current = serializedConfig;
		requestReload();
	}, [
		normalizedConfig,
		requestReload,
		serializedConfig
	]);
	useEffect(() => {
		if (!normalizedConfig || extraDeps.length === 0) return;
		requestReload();
	}, [
		extraDeps.length,
		normalizedConfig,
		requestReload,
		...extraDeps
	]);
	useEffect(() => {
		if (!normalizedConfig || !isDynamicConfigType) return;
		if (!targetAgentId) return;
		if (!!copilotkit.getAgent(targetAgentId)) return;
		const subscription = copilotkit.subscribe({ onAgentsChanged: () => {
			if (copilotkit.getAgent(targetAgentId)) {
				requestReload();
				subscription.unsubscribe();
			}
		} });
		return () => {
			subscription.unsubscribe();
		};
	}, [
		copilotkit,
		normalizedConfig,
		isDynamicConfigType,
		targetAgentId,
		requestReload
	]);
}
function isDynamicConfig(config) {
	return "instructions" in config;
}
function normalizeStaticSuggestions(suggestions) {
	return suggestions.map((suggestion) => ({
		...suggestion,
		isLoading: suggestion.isLoading ?? false
	}));
}

//#endregion
//#region src/v2/hooks/use-interrupt.tsx
const INTERRUPT_EVENT_NAME = "on_interrupt";
function isPromiseLike(value) {
	return (typeof value === "object" || typeof value === "function") && value !== null && typeof Reflect.get(value, "then") === "function";
}
/** Derive the legacy-compatible `event` for any pending interrupt. */
function toLegacyEvent(pending) {
	if (pending.kind === "legacy") return pending.event;
	return {
		name: INTERRUPT_EVENT_NAME,
		value: pending.interrupts[0]
	};
}
/**
* Handles agent interrupts with optional filtering, preprocessing, and resume behavior.
*
* Supports both the AG-UI standard interrupt flow (`RUN_FINISHED` with
* `outcome.type === "interrupt"`) and the legacy custom-event flow
* (`on_interrupt`). For standard interrupts, `render` receives `interrupt`
* (the primary one) and `interrupts` (the full open set); call `resolve(payload)`
* to resume or `cancel()` to cancel. Resuming addresses the targeted interrupt
* and, once every open interrupt is addressed, submits a single spec `resume`
* array via `copilotkit.runAgent`.
*
* - `renderInChat: true` (default): the element is published into `<CopilotChat>`; returns `void`.
* - `renderInChat: false`: the hook returns the interrupt element for manual placement.
*
* @example
* ```tsx
* useInterrupt({
*   render: ({ interrupt, resolve, cancel }) => (
*     <div>
*       <p>{interrupt?.message}</p>
*       <button onClick={() => resolve({ approved: true })}>Approve</button>
*       <button onClick={() => cancel()}>Cancel</button>
*     </div>
*   ),
* });
* ```
*/
function useInterrupt(config) {
	const { copilotkit } = useCopilotKit();
	const { agent } = useAgent({ agentId: config.agentId });
	const [pending, setPending] = useState(null);
	const pendingRef = useRef(pending);
	pendingRef.current = pending;
	const [handlerResult, setHandlerResult] = useState(null);
	const interruptStateRef = useRef(new ɵInterruptState());
	const interruptRunIdsRef = useRef(/* @__PURE__ */ new Map());
	const legacyRunIdRef = useRef(void 0);
	useEffect(() => {
		const interruptState = interruptStateRef.current;
		let localLegacy = null;
		let localStandard = null;
		const subscription = agent.subscribe({
			onCustomEvent: ({ event }) => {
				if (event.name === INTERRUPT_EVENT_NAME) localLegacy = {
					name: event.name,
					value: event.value
				};
			},
			onRunFinishedEvent: (params) => {
				if (params.outcome === "interrupt") {
					const runId = params.input.runId;
					for (const interrupt of params.interrupts) interruptRunIdsRef.current.set(interrupt.id, runId);
					localStandard = params.interrupts;
				}
			},
			onRunStartedEvent: () => {
				localLegacy = null;
				localStandard = null;
				interruptRunIdsRef.current.clear();
				legacyRunIdRef.current = void 0;
				interruptState.clear();
				setPending(null);
			},
			onRunFinalized: (params) => {
				if (localStandard && localStandard.length > 0) {
					interruptState.setStandard(localStandard);
					setPending(interruptState.pending);
				} else if (localLegacy) {
					legacyRunIdRef.current = params.input.runId;
					interruptState.setLegacy(localLegacy);
					setPending(interruptState.pending);
				}
				localLegacy = null;
				localStandard = null;
			},
			onRunFailed: () => {
				localLegacy = null;
				localStandard = null;
				interruptRunIdsRef.current.clear();
				legacyRunIdRef.current = void 0;
				interruptState.clear();
				setPending(null);
			}
		});
		return () => {
			subscription.unsubscribe();
			interruptState.clear();
		};
	}, [agent]);
	const resolve = useCallback(async (payload, interruptId) => {
		const current = pendingRef.current;
		if (!current) return;
		if (current.kind === "standard" && current.interrupts.length > 1 && interruptId === void 0) console.warn(`[CopilotKit] useInterrupt: resolve()/cancel() called without an interruptId while ${current.interrupts.length} interrupts are open; defaulting to the first. Pass an interruptId to address a specific interrupt.`);
		const decision = interruptStateRef.current.resolve(payload, interruptId);
		if (decision.kind === "legacy-resume") {
			const runId = legacyRunIdRef.current;
			try {
				return await copilotkit.runAgent({
					agent,
					...runId !== void 0 ? { runId } : {},
					forwardedProps: { command: {
						resume: decision.payload,
						interruptEvent: decision.interruptValue
					} }
				});
			} catch (err) {
				console.error("[CopilotKit] useInterrupt resolve: runAgent rejected; clearing pending + rethrowing", err);
				setPending(null);
				throw err;
			}
		}
		if (decision.kind === "expired") {
			console.error(`[CopilotKit] useInterrupt: interrupt ${decision.interrupt.id} expired at ${decision.interrupt.expiresAt}; not resuming.`);
			interruptStateRef.current.clear();
			setPending(null);
			return;
		}
		if (decision.kind !== "resume") return;
		const runId = decision.resume.map((entry) => interruptRunIdsRef.current.get(entry.interruptId)).find((candidate) => candidate !== void 0);
		for (const toolResult of decision.toolResults) agent.addMessage({
			id: randomUUID(),
			role: "tool",
			toolCallId: toolResult.toolCallId,
			content: toolResult.content
		});
		try {
			return await copilotkit.runAgent({
				agent,
				resume: decision.resume,
				...runId !== void 0 ? { runId } : {}
			});
		} catch (err) {
			console.error("[CopilotKit] useInterrupt resolve: runAgent rejected; clearing pending + rethrowing", err);
			interruptStateRef.current.clear();
			setPending(null);
			throw err;
		}
	}, [agent, copilotkit]);
	const cancel = useCallback(async (interruptId) => {
		const current = pendingRef.current;
		if (!current) return;
		if (current.kind === "standard" && current.interrupts.length > 1 && interruptId === void 0) console.warn(`[CopilotKit] useInterrupt: resolve()/cancel() called without an interruptId while ${current.interrupts.length} interrupts are open; defaulting to the first. Pass an interruptId to address a specific interrupt.`);
		const decision = interruptStateRef.current.cancel(interruptId);
		if (decision.kind === "dismiss") {
			console.warn("[CopilotKit] useInterrupt: cancel() is not supported for legacy on_interrupt interrupts; dismissing.");
			interruptStateRef.current.clear();
			setPending(null);
			return;
		}
		if (decision.kind === "expired") {
			console.error(`[CopilotKit] useInterrupt: interrupt ${decision.interrupt.id} expired at ${decision.interrupt.expiresAt}; not resuming.`);
			interruptStateRef.current.clear();
			setPending(null);
			return;
		}
		if (decision.kind !== "resume") return;
		const runId = decision.resume.map((entry) => interruptRunIdsRef.current.get(entry.interruptId)).find((candidate) => candidate !== void 0);
		for (const toolResult of decision.toolResults) agent.addMessage({
			id: randomUUID(),
			role: "tool",
			toolCallId: toolResult.toolCallId,
			content: toolResult.content
		});
		try {
			return await copilotkit.runAgent({
				agent,
				resume: decision.resume,
				...runId !== void 0 ? { runId } : {}
			});
		} catch (err) {
			console.error("[CopilotKit] useInterrupt resolve: runAgent rejected; clearing pending + rethrowing", err);
			interruptStateRef.current.clear();
			setPending(null);
			throw err;
		}
	}, [agent, copilotkit]);
	const renderRef = useRef(config.render);
	renderRef.current = config.render;
	const enabledRef = useRef(config.enabled);
	enabledRef.current = config.enabled;
	const handlerRef = useRef(config.handler);
	handlerRef.current = config.handler;
	const resolveRef = useRef(resolve);
	resolveRef.current = resolve;
	const cancelRef = useRef(cancel);
	cancelRef.current = cancel;
	const isEnabled = (event) => {
		const predicate = enabledRef.current;
		if (!predicate) return true;
		try {
			return predicate(event);
		} catch (err) {
			console.error("[CopilotKit] useInterrupt enabled predicate threw; treating interrupt as disabled:", err);
			return false;
		}
	};
	useEffect(() => {
		if (!pending) {
			setHandlerResult(null);
			return;
		}
		const legacyEvent = toLegacyEvent(pending);
		if (!isEnabled(legacyEvent)) {
			setHandlerResult(null);
			return;
		}
		const handler = handlerRef.current;
		if (!handler) {
			setHandlerResult(null);
			return;
		}
		let cancelled = false;
		let maybePromise;
		try {
			maybePromise = handler({
				event: legacyEvent,
				interrupt: pending.kind === "standard" ? pending.interrupts[0] : null,
				interrupts: pending.kind === "standard" ? [...pending.interrupts] : [],
				resolve: resolveRef.current,
				cancel: cancelRef.current
			});
		} catch (err) {
			console.error("[CopilotKit] useInterrupt handler threw; result will be null:", err);
			if (!cancelled) setHandlerResult(null);
			return () => {
				cancelled = true;
			};
		}
		if (isPromiseLike(maybePromise)) Promise.resolve(maybePromise).then((resolved) => {
			if (!cancelled) setHandlerResult(resolved);
		}).catch((err) => {
			console.error("[CopilotKit] useInterrupt handler rejected; result will be null:", err);
			if (!cancelled) setHandlerResult(null);
		});
		else setHandlerResult(maybePromise);
		return () => {
			cancelled = true;
		};
	}, [pending]);
	const element = useMemo(() => {
		if (!pending) return null;
		const legacyEvent = toLegacyEvent(pending);
		if (!isEnabled(legacyEvent)) return null;
		return renderRef.current({
			event: legacyEvent,
			interrupt: pending.kind === "standard" ? pending.interrupts[0] : null,
			interrupts: pending.kind === "standard" ? [...pending.interrupts] : [],
			result: handlerResult,
			resolve,
			cancel
		});
	}, [
		pending,
		handlerResult,
		resolve,
		cancel
	]);
	useEffect(() => {
		if (config.renderInChat === false) return;
		copilotkit.setInterruptElement(element);
	}, [
		element,
		config.renderInChat,
		copilotkit
	]);
	useEffect(() => {
		if (config.renderInChat === false) return;
		return () => {
			copilotkit.setInterruptElement(null);
		};
	}, []);
	if (config.renderInChat === false) return element;
}

//#endregion
//#region src/v2/hooks/use-threads.tsx
function useThreadStoreSelector(store, selector) {
	return useSyncExternalStore(useCallback((onStoreChange) => {
		const subscription = store.select(selector).subscribe(onStoreChange);
		return () => subscription.unsubscribe();
	}, [store, selector]), () => selector(store.getState()), () => selector(store.getServerState()));
}
/**
* React hook for listing and managing Intelligence platform threads.
*
* On mount the hook fetches the thread list for the runtime-authenticated user
* and the given `agentId`. When the Intelligence platform exposes a WebSocket
* URL, it also opens a realtime subscription so the `threads` array stays
* current without polling — thread creates, renames, archives, and deletes
* from any client are reflected immediately.
*
* Mutation methods (`renameThread`, `archiveThread`, `unarchiveThread`,
* `deleteThread`) return promises that resolve once the platform confirms the
* operation and reject with an `Error` on failure.
*
* @param input - Agent identifier and optional list controls.
* @returns Thread list state and stable mutation callbacks.
*
* @example
* ```tsx
* import { useThreads } from "@copilotkit/react-core";
*
* function ThreadList() {
*   const { threads, isLoading, renameThread, deleteThread } = useThreads({
*     agentId: "agent-1",
*   });
*
*   if (isLoading) return <p>Loading…</p>;
*
*   return (
*     <ul>
*       {threads.map((t) => (
*         <li key={t.id}>
*           {t.name ?? "Untitled"}
*           <button onClick={() => renameThread(t.id, "New name")}>Rename</button>
*           <button onClick={() => deleteThread(t.id)}>Delete</button>
*         </li>
*       ))}
*     </ul>
*   );
* }
* ```
*/
function useThreads$1({ agentId, includeArchived, limit, enabled = true }) {
	const { copilotkit } = useCopilotKit();
	const [store] = useState(() => ɵcreateThreadStore({ fetch: globalThis.fetch }));
	const coreThreads = useThreadStoreSelector(store, ɵselectThreads);
	const threads = useMemo(() => coreThreads.map(({ id, agentId, name, archived, createdAt, updatedAt, lastRunAt }) => ({
		id,
		agentId,
		name,
		archived,
		createdAt,
		updatedAt,
		...lastRunAt !== void 0 ? { lastRunAt } : {}
	})), [coreThreads]);
	const storeIsLoading = useThreadStoreSelector(store, ɵselectThreadsIsLoading);
	const storeError = useThreadStoreSelector(store, ɵselectThreadsError);
	const fetchMoreError = useThreadStoreSelector(store, ɵselectFetchMoreError);
	const hasMoreThreads = useThreadStoreSelector(store, ɵselectHasNextPage);
	const isFetchingMoreThreads = useThreadStoreSelector(store, ɵselectIsFetchingNextPage);
	const isMutating = useThreadStoreSelector(store, ɵselectIsMutating);
	const headersKey = useMemo(() => {
		return JSON.stringify(Object.entries(copilotkit.headers ?? {}).sort(([left], [right]) => left.localeCompare(right)));
	}, [copilotkit.headers]);
	const runtimeStatus = copilotkit.runtimeConnectionStatus;
	const threadListEndpointSupported = copilotkit.threadEndpoints?.list !== false;
	const threadMutationsSupported = copilotkit.threadEndpoints?.mutations !== false;
	const threadEndpointsUnavailable = !!copilotkit.runtimeUrl && runtimeStatus === CopilotKitCoreRuntimeConnectionStatus.Connected && !threadListEndpointSupported;
	const runtimeError = useMemo(() => {
		if (copilotkit.runtimeUrl) return null;
		return /* @__PURE__ */ new Error("Runtime URL is not configured");
	}, [copilotkit.runtimeUrl]);
	const threadEndpointsError = useMemo(() => {
		if (!threadEndpointsUnavailable) return null;
		return /* @__PURE__ */ new Error("Thread endpoints are not available on this CopilotKit runtime");
	}, [threadEndpointsUnavailable]);
	const threadMutationsError = useMemo(() => {
		if (threadMutationsSupported) return null;
		return /* @__PURE__ */ new Error("Thread mutations are not available on this CopilotKit runtime");
	}, [threadMutationsSupported]);
	const [hasDispatchedContext, setHasDispatchedContext] = useState(false);
	const preConnectLoading = enabled && !!copilotkit.runtimeUrl && !threadEndpointsUnavailable && !hasDispatchedContext;
	const [configErrorDismissed, setConfigErrorDismissed] = useState(false);
	useEffect(() => {
		setConfigErrorDismissed(false);
	}, [runtimeError, threadEndpointsError]);
	const activeRuntimeError = configErrorDismissed ? null : runtimeError;
	const activeThreadEndpointsError = configErrorDismissed ? null : threadEndpointsError;
	const isLoading = activeRuntimeError || activeThreadEndpointsError ? false : preConnectLoading || storeIsLoading;
	const error = activeRuntimeError ?? activeThreadEndpointsError ?? storeError;
	const listError = storeError;
	useEffect(() => {
		store.start();
		return () => {
			store.stop();
		};
	}, [store]);
	useEffect(() => {
		if (!enabled) return;
		copilotkit.registerThreadStore(agentId, store);
		return () => {
			copilotkit.unregisterThreadStore(agentId);
		};
	}, [
		copilotkit,
		agentId,
		store,
		enabled
	]);
	useEffect(() => {
		if (!enabled) {
			store.setContext(null);
			setHasDispatchedContext(false);
			return;
		}
		if (!copilotkit.runtimeUrl) {
			store.setContext(null);
			setHasDispatchedContext(false);
			return;
		}
		if (runtimeStatus !== CopilotKitCoreRuntimeConnectionStatus.Connected) return;
		if (!threadListEndpointSupported) {
			store.setContext(null);
			setHasDispatchedContext(false);
			return;
		}
		const context = {
			runtimeUrl: copilotkit.runtimeUrl,
			headers: { ...copilotkit.headers },
			wsUrl: copilotkit.intelligence?.wsUrl,
			agentId,
			includeArchived,
			limit
		};
		store.setContext(context);
		setHasDispatchedContext(true);
	}, [
		store,
		enabled,
		copilotkit.runtimeUrl,
		runtimeStatus,
		headersKey,
		copilotkit.intelligence?.wsUrl,
		threadListEndpointSupported,
		agentId,
		includeArchived,
		limit
	]);
	const guardMutation = useCallback((mutation) => {
		return (...args) => {
			if (threadMutationsError) return Promise.reject(threadMutationsError);
			return mutation(...args);
		};
	}, [threadMutationsError]);
	const renameThread = useMemo(() => guardMutation((threadId, name) => store.renameThread(threadId, name)), [store, guardMutation]);
	const archiveThread = useMemo(() => guardMutation((threadId) => store.archiveThread(threadId)), [store, guardMutation]);
	const unarchiveThread = useMemo(() => guardMutation((threadId) => store.unarchiveThread(threadId)), [store, guardMutation]);
	const deleteThread = useMemo(() => guardMutation((threadId) => store.deleteThread(threadId)), [store, guardMutation]);
	return {
		threads,
		isLoading,
		error,
		listError,
		fetchMoreError,
		hasMoreThreads,
		isFetchingMoreThreads,
		isMutating,
		fetchMoreThreads: useCallback(() => store.fetchNextPage(), [store]),
		refetchThreads: useCallback(() => store.refetchThreads(), [store]),
		startNewThread: useCallback(() => {
			setConfigErrorDismissed(true);
			store.startNewThread();
		}, [store]),
		renameThread,
		archiveThread,
		unarchiveThread,
		deleteThread
	};
}

//#endregion
//#region src/v2/hooks/use-memories.tsx
function useMemoryStoreSelector(store, selector) {
	return useSyncExternalStore(useCallback((onStoreChange) => {
		const subscription = store.select(selector).subscribe(onStoreChange);
		return () => subscription.unsubscribe();
	}, [store, selector]), () => selector(store.getState()), () => selector(store.getServerState()));
}
/**
* React hook for listing and managing platform memories.
*
* Reads the memory store owned and wired by `CopilotKitCore`. On mount the
* hook exposes the live list plus stable `addMemory` / `updateMemory` /
* `removeMemory` / `refresh` callbacks. Mutations are server-authoritative:
* each resolves once the platform confirms the operation and rejects with an
* `Error` on failure.
*
* Realtime updates are automatic: the core's memory store opens its own
* `user_meta:memories:<joinCode>` channel and applies `memory_metadata` deltas
* to the list. You can still call `refresh()` to re-pull the REST snapshot on
* demand.
*
* @returns Memory list state and stable mutation callbacks.
*
* @example
* ```tsx
* import { useMemories } from "@copilotkit/react-core";
*
* function MemoryList() {
*   const { memories, isLoading, isAvailable, addMemory, removeMemory } =
*     useMemories();
*
*   if (!isAvailable) return null;
*   if (isLoading) return <p>Loading…</p>;
*
*   return (
*     <ul>
*       {memories.map((m) => (
*         <li key={m.id}>
*           {m.content}
*           <button onClick={() => removeMemory(m.id)}>Delete</button>
*         </li>
*       ))}
*     </ul>
*   );
* }
* ```
*/
function useMemories() {
	const { copilotkit } = useCopilotKit();
	const store = copilotkit.getMemoryStore();
	return {
		memories: useMemoryStoreSelector(store, ɵselectMemories),
		isLoading: useMemoryStoreSelector(store, ɵselectMemoriesIsLoading),
		error: useMemoryStoreSelector(store, ɵselectMemoriesError),
		isAvailable: useMemoryStoreSelector(store, ɵselectMemoriesAvailable),
		realtimeStatus: useMemoryStoreSelector(store, ɵselectMemoriesRealtimeStatus),
		refresh: useCallback(() => store.refresh(), [store]),
		addMemory: useCallback((input) => store.addMemory(input), [store]),
		updateMemory: useCallback((id, changes) => store.updateMemory(id, changes), [store]),
		removeMemory: useCallback((id) => store.removeMemory(id), [store])
	};
}

//#endregion
//#region src/v2/lib/record-annotation.ts
/**
* Low-level function that posts an arbitrary annotation to the CopilotKit
* runtime's general annotation endpoint (`POST /annotate`).
*
* This is the single transport entry point for annotations. Higher-level
* hooks such as `useLearnFromUserAction` build the `type`/`payload` pair
* for their specific annotation shape and delegate the HTTP call here.
*
* The function uses the same transport as `useLearnFromUserAction`:
* - `runtimeUrl` from `copilotkit.runtimeUrl` (BFF proxies to the platform)
* - `headers` from `copilotkit.headers` (customer auth forwarded to BFF)
* - `clientEventId` auto-generated via `randomUUID()` when omitted
* - `userId` is resolved server-side by the runtime; the client never sends it
* - Errors propagate to the caller (fire-and-propagate, not fire-and-forget)
*
* @param args - Transport dependencies plus annotation fields.
* @returns The platform result containing the annotation row `id` and a
*          `duplicate` flag.
* @throws When the network request fails or the runtime returns a non-2xx
*         status. Callers that want fire-and-forget behavior should `.catch`
*         at the call site.
*/
async function recordAnnotation(args) {
	const { runtimeUrl, headers, type, payload, threadId, occurredAt } = args;
	const body = {
		type,
		threadId,
		clientEventId: args.clientEventId ?? randomUUID$1(),
		...payload !== void 0 ? { payload } : {},
		...occurredAt !== void 0 ? { occurredAt } : {}
	};
	const response = await fetch(`${runtimeUrl}/annotate`, {
		method: "POST",
		headers: {
			"Content-Type": "application/json",
			...headers
		},
		body: JSON.stringify(body)
	});
	if (!response.ok) {
		const text = await response.text().catch(() => "");
		throw new Error(`recordAnnotation: request failed (${response.status})${text ? `: ${text}` : ""}`);
	}
	const text = await response.text();
	if (!text) throw new Error(`recordAnnotation: runtime ${runtimeUrl}/annotate returned ${response.status} with an empty body`);
	try {
		return JSON.parse(text);
	} catch {
		throw new Error(`recordAnnotation: runtime ${runtimeUrl}/annotate returned a non-JSON body (status ${response.status})`);
	}
}

//#endregion
//#region src/v2/hooks/use-learn-from-user-action.tsx
/**
* Record a user UI interaction in the Intelligence platform's user-actions
* stream. The platform's auto-curated knowledge base agent reads these
* (alongside finished agent runs) and writes free-form Obsidian-flavored
* markdown to `/project`, where any agent in the same project can later
* read it via the `copilotkit_knowledge_base_shell` MCP tool.
*
* The hook returns a stable function. Calling it issues a request to the
* customer's CopilotKit runtime (`POST ${runtimeUrl}/annotate`), which
* resolves the Intel user from the BFF's auth and forwards to the
* platform — the Intel API key never reaches the browser.
*
* If `clientEventId` is omitted `recordAnnotation` generates a UUID per call,
* so a naive double-call (e.g. React 18 strict-mode double-mount, or a retry
* after a network blip on a fresh Promise) is naturally safe. Supply your
* own key when a single semantic event must remain idempotent across
* multiple `learnFromUserAction(...)` calls.
*
* @example
* ```tsx
* import { useLearnFromUserAction } from "@copilotkit/react-core";
*
* function SettingsPage({ threadId }) {
*   const learnFromUserAction = useLearnFromUserAction();
*
*   const onRename = (oldName: string, newName: string) => {
*     void learnFromUserAction({
*       threadId,
*       title: "Renamed project",
*       data: { previous: { name: oldName }, next: { name: newName } },
*     });
*   };
* }
* ```
*/
function useLearnFromUserAction() {
	const { copilotkit } = useCopilotKit();
	return useCallback(async (input) => {
		const runtimeUrl = copilotkit.runtimeUrl;
		if (!runtimeUrl) throw new Error("useLearnFromUserAction: runtimeUrl is not configured. Set it on <CopilotKitProvider runtimeUrl=...>.");
		const payload = {
			...input.title !== void 0 ? { title: input.title } : {},
			...input.description !== void 0 ? { description: input.description } : {},
			...input.data !== void 0 ? { data: input.data } : {}
		};
		return recordAnnotation({
			runtimeUrl,
			headers: copilotkit.headers ?? {},
			type: "user_action",
			payload: Object.keys(payload).length > 0 ? payload : void 0,
			threadId: input.threadId,
			clientEventId: input.clientEventId,
			occurredAt: input.occurredAt
		});
	}, [copilotkit]);
}

//#endregion
//#region src/v2/hooks/use-learn-from-user-action-in-current-thread.tsx
/**
* Record a user UI interaction against the **current chat's** thread. The
* `threadId` is sourced from the surrounding
* `<CopilotChatConfigurationProvider>` (the same provider `<CopilotChat>`,
* `<CopilotSidebar>`, and friends set up), so callers in a chat-aware
* subtree don't need to thread an id through manually.
*
* Throws on **call** (not on mount) when there is no chat-config provider
* in scope — matches the "throw on call when runtimeUrl is missing"
* behavior of {@link useLearnFromUserAction}. Mounting the hook in a branch
* that never fires is harmless.
*
* The recorder does NOT accept a `threadId` override. If you need to
* record against an explicit thread, use {@link useLearnFromUserAction}
* directly — two hooks, two crisp contracts, no mode confusion.
*
* This hook always uses `config.threadId`, regardless of whether the
* surrounding chat config minted it internally or received one from
* the caller. Auto-minted threads simply mean the action lands under
* a thread the platform never saw — the writer agent still distills
* user-action-only threads (it does not require the thread to exist
* in `cpki.threads`), so the loop keeps learning.
*
* @example
* ```tsx
* import { useLearnFromUserActionInCurrentThread } from "@copilotkit/react-core";
*
* function SettingsPanel() {
*   const learnFromUserAction = useLearnFromUserActionInCurrentThread();
*
*   const onRename = (oldName: string, newName: string) => {
*     void learnFromUserAction({
*       title: "Renamed project",
*       data: { previous: { name: oldName }, next: { name: newName } },
*     });
*   };
*
*   // ...
* }
* ```
*/
function useLearnFromUserActionInCurrentThread() {
	const config = useCopilotChatConfiguration();
	const learnFromUserAction = useLearnFromUserAction();
	return useCallback(async (input) => {
		const threadId = config?.threadId;
		if (!threadId) throw new Error("useLearnFromUserActionInCurrentThread: no CopilotChatConfigurationProvider in scope. Wrap the call site in <CopilotChat>, <CopilotSidebar>, or <CopilotChatConfigurationProvider>, or use `useLearnFromUserAction()` and pass `threadId` explicitly.");
		return learnFromUserAction({
			...input,
			threadId
		});
	}, [config?.threadId, learnFromUserAction]);
}

//#endregion
//#region src/v2/hooks/use-attachments.tsx
/**
* Hook that manages file attachment state — uploads, drag-and-drop, paste,
* and lifecycle. All returned callbacks are referentially stable across
* renders (via useCallback) to avoid destabilizing downstream memoization.
*/
function useAttachments({ config }) {
	const enabled = config?.enabled ?? false;
	const [attachments, setAttachments] = useState([]);
	const [dragOver, setDragOver] = useState(false);
	const fileInputRef = useRef(null);
	const containerRef = useRef(null);
	const configRef = useRef(config);
	configRef.current = config;
	const attachmentsRef = useRef([]);
	attachmentsRef.current = attachments;
	const processFiles = useCallback(async (files) => {
		const cfg = configRef.current;
		const accept = cfg?.accept ?? "*/*";
		const maxSize = cfg?.maxSize ?? 20 * 1024 * 1024;
		const rejectedFiles = files.filter((file) => !matchesAcceptFilter(file, accept));
		for (const file of rejectedFiles) cfg?.onUploadFailed?.({
			reason: "invalid-type",
			file,
			message: `File "${file.name}" is not accepted. Supported types: ${accept}`
		});
		const validFiles = files.filter((file) => matchesAcceptFilter(file, accept));
		for (const file of validFiles) {
			if (exceedsMaxSize(file, maxSize)) {
				cfg?.onUploadFailed?.({
					reason: "file-too-large",
					file,
					message: `File "${file.name}" exceeds the maximum size of ${formatFileSize(maxSize)}`
				});
				continue;
			}
			const modality = getModalityFromMimeType(file.type);
			const placeholderId = randomUUID$1();
			const placeholder = {
				id: placeholderId,
				type: modality,
				source: {
					type: "data",
					value: "",
					mimeType: file.type
				},
				filename: file.name,
				size: file.size,
				status: "uploading"
			};
			setAttachments((prev) => [...prev, placeholder]);
			try {
				let source;
				let uploadMetadata;
				if (cfg?.onUpload) {
					const { metadata: meta, ...uploadSource } = await cfg.onUpload(file);
					source = uploadSource;
					uploadMetadata = meta;
				} else source = {
					type: "data",
					value: await readFileAsBase64(file),
					mimeType: file.type
				};
				let thumbnail;
				if (modality === "video") thumbnail = await generateVideoThumbnail(file);
				setAttachments((prev) => prev.map((att) => att.id === placeholderId ? {
					...att,
					source,
					status: "ready",
					thumbnail,
					metadata: uploadMetadata
				} : att));
			} catch (error) {
				setAttachments((prev) => prev.filter((att) => att.id !== placeholderId));
				console.error(`[CopilotKit] Failed to upload "${file.name}":`, error);
				cfg?.onUploadFailed?.({
					reason: "upload-failed",
					file,
					message: error instanceof Error ? error.message : `Failed to upload "${file.name}"`
				});
			}
		}
	}, []);
	const handleFileUpload = useCallback(async (e) => {
		if (!e.target.files?.length) return;
		try {
			await processFiles(Array.from(e.target.files));
		} catch (error) {
			console.error("[CopilotKit] Upload error:", error);
		}
	}, [processFiles]);
	const handleDragOver = useCallback((e) => {
		if (!configRef.current?.enabled) return;
		e.preventDefault();
		e.stopPropagation();
		setDragOver(true);
	}, []);
	const handleDragLeave = useCallback((e) => {
		e.preventDefault();
		e.stopPropagation();
		setDragOver(false);
	}, []);
	const handleDrop = useCallback(async (e) => {
		e.preventDefault();
		e.stopPropagation();
		setDragOver(false);
		if (!configRef.current?.enabled) return;
		const files = Array.from(e.dataTransfer.files);
		if (files.length > 0) try {
			await processFiles(files);
		} catch (error) {
			console.error("[CopilotKit] Drop error:", error);
		}
	}, [processFiles]);
	useEffect(() => {
		if (!enabled) return;
		const handlePaste = async (e) => {
			const target = e.target;
			if (!target || !containerRef.current?.contains(target)) return;
			const accept = configRef.current?.accept ?? "*/*";
			const fileItems = Array.from(e.clipboardData?.items || []).filter((item) => item.kind === "file" && item.getAsFile() !== null && matchesAcceptFilter(item.getAsFile(), accept));
			if (fileItems.length === 0) return;
			e.preventDefault();
			const files = fileItems.map((item) => item.getAsFile()).filter((f) => f !== null);
			try {
				await processFiles(files);
			} catch (error) {
				console.error("[CopilotKit] Paste error:", error);
			}
		};
		document.addEventListener("paste", handlePaste);
		return () => document.removeEventListener("paste", handlePaste);
	}, [enabled, processFiles]);
	return {
		attachments,
		enabled,
		dragOver,
		fileInputRef,
		containerRef,
		processFiles,
		handleFileUpload,
		handleDragOver,
		handleDragLeave,
		handleDrop,
		removeAttachment: useCallback((id) => {
			setAttachments((prev) => prev.filter((a) => a.id !== id));
		}, []),
		consumeAttachments: useCallback(() => {
			const ready = attachmentsRef.current.filter((a) => a.status === "ready");
			if (ready.length === 0) return ready;
			setAttachments((prev) => prev.filter((a) => a.status !== "ready"));
			if (fileInputRef.current) fileInputRef.current.value = "";
			return ready;
		}, [])
	};
}

//#endregion
//#region src/v2/hooks/use-learning-containers.tsx
/** The default learning containers value. Matches the backend default. */
const DEFAULT_CONTAINERS = ["project"];
/**
* Legacy compatibility hook that keeps a thread's plural learning-container
* annotation in sync by emitting
* `set_learning_containers` annotations via the CopilotKit runtime annotate
* endpoint (`POST ${runtimeUrl}/annotate`).
*
* **Emit rules:**
* - On mount with `["project"]` (the backend default) → does NOT emit.
*   Absence of an annotation equals the default, so the round-trip is skipped.
* - On mount with any other value → emits immediately.
* - On any subsequent content change (including a switch back to
*   `["project"]`) → emits (a deliberate switch is always recorded).
* - On unmount or threadId change → emits a reset to `["project"]`
*   so the backend is left in a clean state for the next consumer.
*   Changing `learningContainers` within the same thread does NOT reset the
*   thread; only the new value is emitted.
*
* Content-equality is evaluated via `JSON.stringify` so a fresh array literal
* with the same items does NOT trigger a redundant emit.
*
* If `runtimeUrl` is absent, all emits are silently skipped.
*
* @example
* ```tsx
* function ThreadPane({ threadId, userScope }: Props) {
*   useLearningContainers({
*     threadId,
*     learningContainers: [userScope],
*   });
*   // ...
* }
* ```
*
* @deprecated Legacy plural-container annotation compatibility only. New
* Intelligence runtimes assign one container with `ɵlearning.containerId` on
* `CopilotRuntime`.
*/
function useLearningContainers({ threadId, learningContainers }) {
	const { copilotkit } = useCopilotKit();
	/**
	* Tracks the last-synced container list so content-identical rerenders
	* (fresh array, same values) do not fire a redundant emit.
	* `null` = nothing synced yet (initial state or after a threadId reset).
	*/
	const lastSyncedRef = useRef(null);
	/** Guards the missing-runtimeUrl warning so it fires at most once per hook instance. */
	const warnedMissingUrlRef = useRef(false);
	const runtimeUrlRef = useRef(copilotkit.runtimeUrl);
	const headersRef = useRef(copilotkit.headers ?? {});
	runtimeUrlRef.current = copilotkit.runtimeUrl;
	headersRef.current = copilotkit.headers ?? {};
	const key = JSON.stringify(learningContainers);
	const defaultKey = JSON.stringify(DEFAULT_CONTAINERS);
	useEffect(() => {
		const runtimeUrl = copilotkit.runtimeUrl;
		const headers = copilotkit.headers ?? {};
		/**
		* Fire-and-forget emit; errors must not surface in render.
		* Failures are logged as warnings so they are diagnosable without
		* propagating into the React render cycle.
		*/
		const emit = (containers) => {
			if (!runtimeUrl) {
				if (!warnedMissingUrlRef.current) {
					warnedMissingUrlRef.current = true;
					console.warn("useLearningContainers: runtimeUrl not configured; learning-container sync disabled");
				}
				return;
			}
			recordAnnotation({
				runtimeUrl,
				headers,
				type: "set_learning_containers",
				payload: { containers },
				threadId
			}).catch((err) => {
				console.warn("useLearningContainers: failed to record set_learning_containers", err);
			});
		};
		if (lastSyncedRef.current === null) {
			if (key === defaultKey) {
				lastSyncedRef.current = learningContainers;
				return;
			}
			emit(learningContainers);
			lastSyncedRef.current = learningContainers;
		} else if (key !== JSON.stringify(lastSyncedRef.current)) {
			emit(learningContainers);
			lastSyncedRef.current = learningContainers;
		}
	}, [threadId, key]);
	useEffect(() => {
		const capturedThreadId = threadId;
		return () => {
			const capturedRuntimeUrl = runtimeUrlRef.current;
			const capturedHeaders = headersRef.current;
			if (capturedRuntimeUrl) recordAnnotation({
				runtimeUrl: capturedRuntimeUrl,
				headers: capturedHeaders,
				type: "set_learning_containers",
				payload: { containers: DEFAULT_CONTAINERS },
				threadId: capturedThreadId
			}).catch((err) => {
				console.warn("useLearningContainers: failed to record set_learning_containers", err);
			});
			lastSyncedRef.current = null;
		};
	}, [threadId]);
}

//#endregion
//#region src/v2/hooks/use-learning-containers-in-current-thread.tsx
/**
* Legacy compatibility hook that keeps the **current chat thread's** plural
* learning-container annotation in sync. The `threadId` is sourced from the surrounding
* `<CopilotChatConfigurationProvider>` (the same provider `<CopilotChat>`,
* `<CopilotSidebar>`, and friends set up), so callers in a chat-aware
* subtree don't need to thread an id through manually.
*
* **Throws on render** when there is no chat-config provider in scope or
* when the provider does not yet have an active `threadId`. Mount the hook
* inside a subtree that is guaranteed to have a thread context.
*
* If you need to manage an explicit thread, use {@link useLearningContainers}
* directly — two hooks, two crisp contracts, no mode confusion.
*
* @throws When no `CopilotChatConfigurationProvider` is in scope or when the
*         active `threadId` is absent/empty.
*
* @example
* ```tsx
* function ThreadPanel({ scope }: Props) {
*   useLearningContainersInCurrentThread({
*     learningContainers: [scope],
*   });
*   // ...
* }
* ```
*
* @deprecated Legacy plural-container annotation compatibility only. New
* Intelligence runtimes assign one container with `ɵlearning.containerId` on
* `CopilotRuntime`.
*/
function useLearningContainersInCurrentThread({ learningContainers }) {
	const threadId = useCopilotChatConfiguration()?.threadId;
	if (!threadId) throw new Error("useLearningContainersInCurrentThread must be used within a thread context (no active threadId). Wrap the component in <CopilotChat>, <CopilotSidebar>, or <CopilotChatConfigurationProvider>, or use `useLearningContainers()` and pass `threadId` explicitly.");
	useLearningContainers({
		threadId,
		learningContainers
	});
}

//#endregion
//#region src/v2/components/chat/CopilotChatToolCallsView.tsx
function CopilotChatToolCallsView({ message, messages = [] }) {
	const renderToolCall = useRenderToolCall();
	if (!message.toolCalls || message.toolCalls.length === 0) return null;
	return /* @__PURE__ */ jsx(Fragment$1, { children: message.toolCalls.map((toolCall) => {
		const toolMessage = messages.find((m) => m.role === "tool" && m.toolCallId === toolCall.id);
		return /* @__PURE__ */ jsx(React.Fragment, { children: renderToolCall({
			toolCall,
			toolMessage
		}) }, toolCall.id);
	}) });
}

//#endregion
//#region src/v2/components/chat/CopilotChatAssistantMessage.tsx
function CopilotChatAssistantMessage({ message, messages, isRunning, onThumbsUp, onThumbsDown, onReadAloud, onRegenerate, additionalToolbarItems, toolbarVisible = true, markdownRenderer, toolbar, copyButton, inspectorButton, thumbsUpButton, thumbsDownButton, readAloudButton, regenerateButton, toolCallsView, children, className, ...props }) {
	useKatexStyles();
	const { isLocalInspectorEnabled, openInspector } = useCopilotKitInspector();
	const chatConfiguration = useCopilotChatConfiguration();
	const boundMarkdownRenderer = renderSlot(markdownRenderer, CopilotChatAssistantMessage.MarkdownRenderer, { content: message.content || "" });
	const boundCopyButton = renderSlot(copyButton, CopilotChatAssistantMessage.CopyButton, { onClick: async () => {
		if (message.content) return await copyToClipboard(message.content);
		return false;
	} });
	const boundThumbsUpButton = renderSlot(thumbsUpButton, CopilotChatAssistantMessage.ThumbsUpButton, { onClick: onThumbsUp ? () => onThumbsUp(message) : void 0 });
	const boundInspectorButton = renderSlot(inspectorButton, CopilotChatAssistantMessage.InspectorButton, { onClick: () => openInspector({
		messageId: message.id,
		threadId: chatConfiguration?.threadId,
		agentId: chatConfiguration?.agentId
	}) });
	const boundThumbsDownButton = renderSlot(thumbsDownButton, CopilotChatAssistantMessage.ThumbsDownButton, { onClick: onThumbsDown ? () => onThumbsDown(message) : void 0 });
	const boundReadAloudButton = renderSlot(readAloudButton, CopilotChatAssistantMessage.ReadAloudButton, { onClick: onReadAloud ? () => onReadAloud(message) : void 0 });
	const boundRegenerateButton = renderSlot(regenerateButton, CopilotChatAssistantMessage.RegenerateButton, { onClick: onRegenerate ? () => onRegenerate(message) : void 0 });
	const boundToolbar = renderSlot(toolbar, CopilotChatAssistantMessage.Toolbar, { children: /* @__PURE__ */ jsxs("div", {
		className: "cpk:flex cpk:items-center cpk:gap-1",
		children: [
			boundCopyButton,
			isLocalInspectorEnabled && boundInspectorButton,
			(onThumbsUp || thumbsUpButton) && boundThumbsUpButton,
			(onThumbsDown || thumbsDownButton) && boundThumbsDownButton,
			(onReadAloud || readAloudButton) && boundReadAloudButton,
			(onRegenerate || regenerateButton) && boundRegenerateButton,
			additionalToolbarItems
		]
	}) });
	const boundToolCallsView = renderSlot(toolCallsView, CopilotChatToolCallsView, {
		message,
		messages
	});
	const hasContent = !!(message.content && message.content.trim().length > 0);
	const isLatestAssistantMessage = message.role === "assistant" && messages?.[messages.length - 1]?.id === message.id;
	const shouldShowToolbar = toolbarVisible && hasContent && !(isRunning && isLatestAssistantMessage);
	if (children) return /* @__PURE__ */ jsx("div", {
		"data-copilotkit": true,
		style: { display: "contents" },
		children: children({
			markdownRenderer: boundMarkdownRenderer,
			toolbar: boundToolbar,
			toolCallsView: boundToolCallsView,
			copyButton: boundCopyButton,
			inspectorButton: boundInspectorButton,
			thumbsUpButton: boundThumbsUpButton,
			thumbsDownButton: boundThumbsDownButton,
			readAloudButton: boundReadAloudButton,
			regenerateButton: boundRegenerateButton,
			message,
			messages,
			isRunning,
			onThumbsUp,
			onThumbsDown,
			onReadAloud,
			onRegenerate,
			additionalToolbarItems,
			toolbarVisible: shouldShowToolbar
		})
	});
	return /* @__PURE__ */ jsxs("div", {
		"data-copilotkit": true,
		"data-testid": "copilot-assistant-message",
		className: twMerge("copilotKitMessage copilotKitAssistantMessage", className),
		...props,
		"data-message-id": message.id,
		children: [
			/* @__PURE__ */ jsx("div", {
				className: "cpk:prose cpk:max-w-full cpk:break-words cpk:dark:prose-invert",
				children: boundMarkdownRenderer
			}),
			boundToolCallsView,
			shouldShowToolbar && boundToolbar
		]
	});
}
function CopilotKitColoredIcon() {
	const gradientId = useId().replace(/:/g, "");
	return /* @__PURE__ */ jsxs("svg", {
		"aria-hidden": "true",
		className: "cpk:size-5",
		"data-testid": "copilot-inspector-icon",
		viewBox: "0 0 24 24",
		children: [
			/* @__PURE__ */ jsx("path", {
				d: "M8.162 7.758c2.093-2.738 3.831-5.445 4.498-7.63a.093.093 0 01.14-.051c2.324 1.539 6.558 2.552 10.301 2.576a.09.09 0 01.085.124c-1.243 3.158-2.765 8.817-2.823 15.28-.001.095-.135.13-.183.046-2.131-3.729-8.955-8.968-11.982-10.205a.09.09 0 01-.036-.14z",
				fill: `url(#${gradientId}-purple)`
			}),
			/* @__PURE__ */ jsx("path", {
				d: "M15.223 6.083A61.492 61.492 0 018.25 7.827c-.045.008-.055.071-.012.089 3.05 1.267 9.84 6.492 11.952 10.206a.017.017 0 00.022.007.018.018 0 00.01-.024l-4.999-12.02z",
				fill: `url(#${gradientId}-blue)`
			}),
			/* @__PURE__ */ jsx("path", {
				d: "M12.81.07c2.8 1.528 6.037 2.214 10.33 2.575.028.002.036.039.012.051-.55.282-3.695 1.883-6.03 2.74-.626.23-1.256.443-1.876.64a.028.028 0 01-.033-.016L12.746.128c-.017-.04.027-.078.065-.058z",
				fill: `url(#${gradientId}-light-blue)`
			}),
			/* @__PURE__ */ jsx("path", {
				className: "cpk:fill-[#513C9F] cpk:dark:fill-[#B99AE8]",
				d: "M12.725.075c.046-.019.1.003.119.05l7.514 17.923a.091.091 0 01-.148.1l-.02-.03L12.675.195a.091.091 0 01.049-.12z"
			}),
			/* @__PURE__ */ jsx("path", {
				className: "cpk:fill-[#513C9F] cpk:dark:fill-[#B99AE8]",
				d: "M23.06 2.66c.044-.025.1-.01.125.034.025.044.009.1-.035.124v.001l-.008.004-.025.015-.1.054a41.384 41.384 0 01-1.811.92A47.05 47.05 0 0116.33 5.82c-1.954.674-3.97 1.197-5.497 1.552a66.27 66.27 0 01-2.38.507l-.138.026-.036.007h-.01l-.002.002a.091.091 0 11-.033-.18l.016.09-.015-.09h.002l.01-.002.035-.007.137-.025a66.16 66.16 0 002.373-.506c1.524-.354 3.533-.876 5.479-1.547a46.857 46.857 0 006.276-2.709c.166-.087.295-.156.381-.204l.099-.054.024-.014.008-.004z"
			}),
			/* @__PURE__ */ jsx("path", {
				className: "cpk:fill-[#ABABAB] cpk:dark:fill-[#D4D4D4]",
				d: "M13.838 2.272a.16.16 0 01.107.2l-2.72 9.055h6.4l.061.013a.16.16 0 010 .295l-.061.013h-6.541L.679 24.099l-.05.04a.16.16 0 01-.194-.245l10.43-12.285 2.773-9.23a.16.16 0 01.2-.107z"
			}),
			/* @__PURE__ */ jsx("path", {
				d: "M7.809 21.461l-1.232.173c.638 1.69 1.949 2.427 3.514 2.427 3.831 0 2.661-4.334 4.883-4.334 1.61 0 .956 3.513 4.423 3.513 2.116 0 2.326-2.131 1.966-3.048l-.008-.016-.567-.868c-.037-.058-.127-.036-.133.032l-.106 1.053a1.01 1.01 0 00.003.219c.088.727.144 2.491-1.155 2.491-1.37 0-1.7-3.467-4.423-3.467-3.196 0-2.785 4.289-4.747 4.289-1.294 0-2.28-1.46-2.418-2.464z",
				fill: `url(#${gradientId}-tail)`
			}),
			/* @__PURE__ */ jsxs("defs", { children: [
				/* @__PURE__ */ jsxs("linearGradient", {
					gradientUnits: "userSpaceOnUse",
					id: `${gradientId}-purple`,
					x1: "17.852",
					x2: "14.202",
					y1: "1.467",
					y2: "11.504",
					children: [/* @__PURE__ */ jsx("stop", { className: "cpk:[stop-color:#6430AB] cpk:dark:[stop-color:#B792F0]" }), /* @__PURE__ */ jsx("stop", {
						className: "cpk:[stop-color:#AA89D8] cpk:dark:[stop-color:#D3BDF7]",
						offset: "1"
					})]
				}),
				/* @__PURE__ */ jsxs("linearGradient", {
					gradientUnits: "userSpaceOnUse",
					id: `${gradientId}-blue`,
					x1: "15.024",
					x2: "10.324",
					y1: "7.125",
					y2: "16.204",
					children: [/* @__PURE__ */ jsx("stop", { className: "cpk:[stop-color:#005DBB] cpk:dark:[stop-color:#4D9FEF]" }), /* @__PURE__ */ jsx("stop", {
						className: "cpk:[stop-color:#3D92E8] cpk:dark:[stop-color:#84C0FA]",
						offset: "1"
					})]
				}),
				/* @__PURE__ */ jsxs("linearGradient", {
					gradientUnits: "userSpaceOnUse",
					id: `${gradientId}-light-blue`,
					x1: "17.122",
					x2: "15.707",
					y1: "1.467",
					y2: "5.892",
					children: [/* @__PURE__ */ jsx("stop", { className: "cpk:[stop-color:#1B70C4] cpk:dark:[stop-color:#61ACF2]" }), /* @__PURE__ */ jsx("stop", {
						className: "cpk:[stop-color:#54A4F2] cpk:dark:[stop-color:#9ACDFF]",
						offset: "1"
					})]
				}),
				/* @__PURE__ */ jsxs("linearGradient", {
					gradientUnits: "userSpaceOnUse",
					id: `${gradientId}-tail`,
					x1: "6.577",
					x2: "21.506",
					y1: "21.758",
					y2: "21.758",
					children: [
						/* @__PURE__ */ jsx("stop", { className: "cpk:[stop-color:#4497EA] cpk:dark:[stop-color:#79BCF5]" }),
						/* @__PURE__ */ jsx("stop", {
							className: "cpk:[stop-color:#1463B2] cpk:dark:[stop-color:#4594D8]",
							offset: ".255"
						}),
						/* @__PURE__ */ jsx("stop", {
							className: "cpk:[stop-color:#0A437D] cpk:dark:[stop-color:#347CB7]",
							offset: ".499"
						}),
						/* @__PURE__ */ jsx("stop", {
							className: "cpk:[stop-color:#2476C8] cpk:dark:[stop-color:#58A4E5]",
							offset: ".667"
						}),
						/* @__PURE__ */ jsx("stop", {
							className: "cpk:[stop-color:#0C549A] cpk:dark:[stop-color:#3C87C7]",
							offset: ".973"
						})
					]
				})
			] })
		]
	});
}
(function(_CopilotChatAssistantMessage) {
	_CopilotChatAssistantMessage.MarkdownRenderer = ({ content, className, ...props }) => /* @__PURE__ */ jsx(Streamdown, {
		className,
		...props,
		children: content ?? ""
	});
	_CopilotChatAssistantMessage.Toolbar = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
		"data-testid": "copilot-assistant-toolbar",
		className: twMerge("cpk:w-full cpk:bg-transparent cpk:flex cpk:items-center cpk:-ml-[5px] cpk:-mt-[0px]", className),
		...props
	});
	const ToolbarButton = _CopilotChatAssistantMessage.ToolbarButton = ({ title, tooltip, children, ...props }) => {
		return /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
			asChild: true,
			children: /* @__PURE__ */ jsx(Button, {
				type: "button",
				variant: "assistantMessageToolbarButton",
				"aria-label": title,
				...props,
				children
			})
		}), /* @__PURE__ */ jsx(TooltipContent, {
			side: "bottom",
			children: tooltip ?? /* @__PURE__ */ jsx("p", { children: title })
		})] });
	};
	_CopilotChatAssistantMessage.CopyButton = ({ className, title, onClick, ...props }) => {
		const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
		const [copied, setCopied] = useState(false);
		const timerRef = useRef(null);
		useEffect(() => {
			return () => {
				if (timerRef.current !== null) clearTimeout(timerRef.current);
			};
		}, []);
		const handleClick = async (event) => {
			let success = false;
			if (onClick) success = await Promise.resolve(onClick(event)) === true;
			if (success) {
				setCopied(true);
				if (timerRef.current !== null) clearTimeout(timerRef.current);
				timerRef.current = setTimeout(() => {
					timerRef.current = null;
					setCopied(false);
				}, 2e3);
			}
		};
		return /* @__PURE__ */ jsx(ToolbarButton, {
			"data-testid": "copilot-copy-button",
			title: title || labels.assistantMessageToolbarCopyMessageLabel,
			onClick: handleClick,
			className,
			...props,
			children: copied ? /* @__PURE__ */ jsx(Check, { className: "cpk:size-[18px]" }) : /* @__PURE__ */ jsx(Copy, { className: "cpk:size-[18px]" })
		});
	};
	_CopilotChatAssistantMessage.InspectorButton = ({ title, ...props }) => {
		const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
		const primaryLabel = title || labels.assistantMessageToolbarInspectorLabel;
		const localOnlyLabel = labels.assistantMessageToolbarInspectorLocalOnlyLabel;
		const accessibleLabel = `${primaryLabel} (${localOnlyLabel})`;
		return /* @__PURE__ */ jsx(ToolbarButton, {
			"data-testid": "copilot-inspector-button",
			title: accessibleLabel,
			tooltip: /* @__PURE__ */ jsxs("div", {
				className: "cpk:flex cpk:flex-col cpk:gap-0.5",
				children: [/* @__PURE__ */ jsx("span", { children: primaryLabel }), /* @__PURE__ */ jsx("span", {
					className: "cpk:text-[10px] cpk:opacity-65",
					children: localOnlyLabel
				})]
			}),
			...props,
			children: /* @__PURE__ */ jsx(CopilotKitColoredIcon, {})
		});
	};
	_CopilotChatAssistantMessage.ThumbsUpButton = ({ title, ...props }) => {
		const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
		return /* @__PURE__ */ jsx(ToolbarButton, {
			"data-testid": "copilot-thumbs-up-button",
			title: title || labels.assistantMessageToolbarThumbsUpLabel,
			...props,
			children: /* @__PURE__ */ jsx(ThumbsUp, { className: "cpk:size-[18px]" })
		});
	};
	_CopilotChatAssistantMessage.ThumbsDownButton = ({ title, ...props }) => {
		const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
		return /* @__PURE__ */ jsx(ToolbarButton, {
			"data-testid": "copilot-thumbs-down-button",
			title: title || labels.assistantMessageToolbarThumbsDownLabel,
			...props,
			children: /* @__PURE__ */ jsx(ThumbsDown, { className: "cpk:size-[18px]" })
		});
	};
	_CopilotChatAssistantMessage.ReadAloudButton = ({ title, ...props }) => {
		const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
		return /* @__PURE__ */ jsx(ToolbarButton, {
			"data-testid": "copilot-read-aloud-button",
			title: title || labels.assistantMessageToolbarReadAloudLabel,
			...props,
			children: /* @__PURE__ */ jsx(Volume2, { className: "cpk:size-[20px]" })
		});
	};
	_CopilotChatAssistantMessage.RegenerateButton = ({ title, ...props }) => {
		const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
		return /* @__PURE__ */ jsx(ToolbarButton, {
			"data-testid": "copilot-regenerate-button",
			title: title || labels.assistantMessageToolbarRegenerateLabel,
			...props,
			children: /* @__PURE__ */ jsx(RefreshCw, { className: "cpk:size-[18px]" })
		});
	};
})(CopilotChatAssistantMessage || (CopilotChatAssistantMessage = {}));
CopilotChatAssistantMessage.MarkdownRenderer.displayName = "CopilotChatAssistantMessage.MarkdownRenderer";
CopilotChatAssistantMessage.Toolbar.displayName = "CopilotChatAssistantMessage.Toolbar";
CopilotChatAssistantMessage.CopyButton.displayName = "CopilotChatAssistantMessage.CopyButton";
CopilotChatAssistantMessage.InspectorButton.displayName = "CopilotChatAssistantMessage.InspectorButton";
CopilotChatAssistantMessage.ThumbsUpButton.displayName = "CopilotChatAssistantMessage.ThumbsUpButton";
CopilotChatAssistantMessage.ThumbsDownButton.displayName = "CopilotChatAssistantMessage.ThumbsDownButton";
CopilotChatAssistantMessage.ReadAloudButton.displayName = "CopilotChatAssistantMessage.ReadAloudButton";
CopilotChatAssistantMessage.RegenerateButton.displayName = "CopilotChatAssistantMessage.RegenerateButton";
var CopilotChatAssistantMessage_default = CopilotChatAssistantMessage;

//#endregion
//#region src/v2/components/chat/Lightbox.tsx
function Lightbox({ onClose, children }) {
	useEffect(() => {
		const handleKey = (e) => {
			if (e.key === "Escape") onClose();
		};
		document.addEventListener("keydown", handleKey);
		return () => document.removeEventListener("keydown", handleKey);
	}, [onClose]);
	if (typeof document === "undefined") return null;
	return createPortal(/* @__PURE__ */ jsxs("div", {
		className: "cpk:fixed cpk:inset-0 cpk:z-[9999] cpk:flex cpk:items-center cpk:justify-center cpk:bg-black/80 cpk:animate-fade-in",
		onClick: onClose,
		children: [/* @__PURE__ */ jsx("button", {
			onClick: onClose,
			className: "cpk:absolute cpk:top-4 cpk:right-4 cpk:text-white cpk:bg-white/10 cpk:hover:bg-white/20 cpk:rounded-full cpk:w-10 cpk:h-10 cpk:flex cpk:items-center cpk:justify-center cpk:cursor-pointer cpk:border-none cpk:z-10",
			"aria-label": "Close preview",
			children: /* @__PURE__ */ jsx(X, { className: "cpk:w-5 cpk:h-5" })
		}), /* @__PURE__ */ jsx("div", {
			onClick: (e) => e.stopPropagation(),
			children
		})]
	}), document.body);
}
/**
* Hook that manages lightbox open/close and uses the View Transition API to
* morph the thumbnail into fullscreen content.
*
* The trick: `view-transition-name` must live on exactly ONE element at a time.
* - Old state (thumbnail visible): name is on the thumbnail.
* - New state (lightbox visible): name moves to the lightbox content.
* `flushSync` ensures React commits the DOM change synchronously inside the
* `startViewTransition` callback so the API can snapshot old → new correctly.
*/
function useLightbox() {
	const thumbnailRef = useRef(null);
	const [open, setOpen] = useState(false);
	const vtName = useId();
	return {
		thumbnailRef,
		vtName,
		open,
		openLightbox: useCallback(() => {
			const thumb = thumbnailRef.current;
			const doc = document;
			if (doc.startViewTransition && thumb) {
				thumb.style.viewTransitionName = vtName;
				doc.startViewTransition(() => {
					thumb.style.viewTransitionName = "";
					flushSync(() => setOpen(true));
				});
			} else setOpen(true);
		}, [vtName]),
		closeLightbox: useCallback(() => {
			const thumb = thumbnailRef.current;
			const doc = document;
			if (doc.startViewTransition && thumb) doc.startViewTransition(() => {
				flushSync(() => setOpen(false));
				thumb.style.viewTransitionName = vtName;
			}).finished.then(() => {
				thumb.style.viewTransitionName = "";
			}).catch(() => {
				thumb.style.viewTransitionName = "";
			});
			else setOpen(false);
		}, [vtName])
	};
}

//#endregion
//#region src/v2/components/chat/CopilotChatAttachmentRenderer.tsx
const ImageAttachment = memo(function ImageAttachment({ src, className }) {
	const [error, setError] = useState(false);
	const { thumbnailRef, vtName, open, openLightbox, closeLightbox } = useLightbox();
	if (error) return /* @__PURE__ */ jsx("div", {
		className: cn("cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:rounded-lg cpk:bg-muted cpk:p-4 cpk:text-sm cpk:text-muted-foreground", className),
		children: /* @__PURE__ */ jsx("span", { children: "Failed to load image" })
	});
	return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("img", {
		ref: thumbnailRef,
		src,
		alt: "Image attachment",
		className: cn("cpk:max-w-[80px] cpk:max-h-[80px] cpk:w-auto cpk:h-auto cpk:rounded-xl cpk:object-cover cpk:cursor-pointer cpk:bg-muted", className),
		onClick: openLightbox,
		onError: () => setError(true)
	}), open && /* @__PURE__ */ jsx(Lightbox, {
		onClose: closeLightbox,
		children: /* @__PURE__ */ jsx("img", {
			style: { viewTransitionName: vtName },
			src,
			alt: "Image attachment",
			className: "cpk:max-w-[90vw] cpk:max-h-[90vh] cpk:object-contain cpk:rounded-lg"
		})
	})] });
});
const AudioAttachment = memo(function AudioAttachment({ src, filename, className }) {
	return /* @__PURE__ */ jsxs("div", {
		className: cn("cpk:flex cpk:flex-col cpk:gap-1", className),
		children: [/* @__PURE__ */ jsx("audio", {
			src,
			controls: true,
			preload: "metadata",
			className: "cpk:max-w-[300px] cpk:w-full cpk:h-10"
		}), filename && /* @__PURE__ */ jsx("span", {
			className: "cpk:text-xs cpk:text-muted-foreground cpk:truncate cpk:max-w-[300px]",
			children: filename
		})]
	});
});
const VideoAttachment = memo(function VideoAttachment({ src, className }) {
	return /* @__PURE__ */ jsx("video", {
		src,
		controls: true,
		preload: "metadata",
		className: cn("cpk:max-w-[400px] cpk:w-full cpk:rounded-lg", className)
	});
});
const DocumentAttachment = memo(function DocumentAttachment({ source, filename, className }) {
	return /* @__PURE__ */ jsxs("div", {
		className: cn("cpk:inline-flex cpk:items-center cpk:gap-2 cpk:px-3 cpk:py-2 cpk:border cpk:border-border cpk:rounded-lg cpk:bg-muted", className),
		children: [/* @__PURE__ */ jsx("span", {
			className: "cpk:text-xs cpk:font-bold cpk:uppercase",
			children: getDocumentIcon(source.mimeType ?? "")
		}), /* @__PURE__ */ jsx("span", {
			className: "cpk:text-sm cpk:text-muted-foreground cpk:truncate",
			children: filename || source.mimeType || "Unknown type"
		})]
	});
});
const CopilotChatAttachmentRenderer = ({ type, source, filename, className }) => {
	const src = getSourceUrl(source);
	switch (type) {
		case "image": return /* @__PURE__ */ jsx(ImageAttachment, {
			src,
			className
		});
		case "audio": return /* @__PURE__ */ jsx(AudioAttachment, {
			src,
			filename,
			className
		});
		case "video": return /* @__PURE__ */ jsx(VideoAttachment, {
			src,
			className
		});
		case "document": return /* @__PURE__ */ jsx(DocumentAttachment, {
			source,
			filename,
			className
		});
	}
};

//#endregion
//#region src/v2/components/chat/CopilotChatUserMessage.tsx
function flattenUserMessageContent(content) {
	if (!content) return "";
	if (typeof content === "string") return content;
	return content.map((part) => {
		if (part && typeof part === "object" && "type" in part && part.type === "text" && typeof part.text === "string") return part.text;
		return "";
	}).filter((text) => text.length > 0).join("\n");
}
function getMediaParts(content) {
	if (!content || typeof content === "string") return [];
	return content.filter((part) => part.type === "image" || part.type === "audio" || part.type === "video" || part.type === "document");
}
function getFilename(part) {
	const meta = part.metadata;
	if (meta != null && typeof meta === "object" && "filename" in meta && typeof meta.filename === "string") return meta.filename;
}
function CopilotChatUserMessage({ message, onEditMessage, branchIndex, numberOfBranches, onSwitchToBranch, additionalToolbarItems, messageRenderer, toolbar, copyButton, editButton, branchNavigation, children, className, ...props }) {
	const flattenedContent = useMemo(() => flattenUserMessageContent(message.content), [message.content]);
	const mediaParts = useMemo(() => getMediaParts(message.content), [message.content]);
	const BoundMessageRenderer = renderSlot(messageRenderer, CopilotChatUserMessage.MessageRenderer, { content: flattenedContent });
	const BoundCopyButton = renderSlot(copyButton, CopilotChatUserMessage.CopyButton, { onClick: async () => {
		if (flattenedContent) return await copyToClipboard(flattenedContent);
		return false;
	} });
	const BoundEditButton = renderSlot(editButton, CopilotChatUserMessage.EditButton, { onClick: () => onEditMessage?.({ message }) });
	const BoundBranchNavigation = renderSlot(branchNavigation, CopilotChatUserMessage.BranchNavigation, {
		currentBranch: branchIndex,
		numberOfBranches,
		onSwitchToBranch,
		message
	});
	const showBranchNavigation = numberOfBranches && numberOfBranches > 1 && onSwitchToBranch;
	const BoundToolbar = renderSlot(toolbar, CopilotChatUserMessage.Toolbar, { children: /* @__PURE__ */ jsxs("div", {
		className: "cpk:flex cpk:items-center cpk:gap-1 cpk:justify-end",
		children: [
			additionalToolbarItems,
			BoundCopyButton,
			onEditMessage && BoundEditButton,
			showBranchNavigation && BoundBranchNavigation
		]
	}) });
	if (children) return /* @__PURE__ */ jsx("div", {
		"data-copilotkit": true,
		style: { display: "contents" },
		children: children({
			messageRenderer: BoundMessageRenderer,
			toolbar: BoundToolbar,
			copyButton: BoundCopyButton,
			editButton: BoundEditButton,
			branchNavigation: BoundBranchNavigation,
			message,
			branchIndex,
			numberOfBranches,
			additionalToolbarItems
		})
	});
	return /* @__PURE__ */ jsxs("div", {
		"data-copilotkit": true,
		"data-testid": "copilot-user-message",
		className: twMerge("copilotKitMessage copilotKitUserMessage cpk:flex cpk:flex-col cpk:items-end cpk:group cpk:pt-10", className),
		"data-message-id": message.id,
		...props,
		children: [
			mediaParts.length > 0 && /* @__PURE__ */ jsx("div", {
				className: "cpk:flex cpk:flex-row cpk:flex-wrap cpk:justify-end cpk:gap-2 cpk:mb-2",
				children: mediaParts.map((part, index) => /* @__PURE__ */ jsx(CopilotChatAttachmentRenderer, {
					type: part.type,
					source: part.source,
					filename: getFilename(part)
				}, index))
			}),
			BoundMessageRenderer,
			BoundToolbar
		]
	});
}
(function(_CopilotChatUserMessage) {
	_CopilotChatUserMessage.Container = ({ children, className, ...props }) => /* @__PURE__ */ jsx("div", {
		className: twMerge("cpk:flex cpk:flex-col cpk:items-end cpk:group", className),
		...props,
		children
	});
	_CopilotChatUserMessage.MessageRenderer = ({ content, className }) => /* @__PURE__ */ jsx("div", {
		className: twMerge("cpk:prose cpk:dark:prose-invert cpk:bg-muted cpk:relative cpk:max-w-[80%] cpk:rounded-[18px] cpk:px-4 cpk:py-1.5 cpk:data-[multiline]:py-3 cpk:inline-block cpk:whitespace-pre-wrap", className),
		children: content
	});
	_CopilotChatUserMessage.Toolbar = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
		"data-testid": "copilot-user-toolbar",
		className: twMerge("cpk:w-full cpk:bg-transparent cpk:flex cpk:items-center cpk:justify-end cpk:-mr-[5px] cpk:mt-[4px] cpk:invisible cpk:group-hover:visible", className),
		...props
	});
	const ToolbarButton = _CopilotChatUserMessage.ToolbarButton = ({ title, children, className, ...props }) => {
		return /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
			asChild: true,
			children: /* @__PURE__ */ jsx(Button, {
				type: "button",
				variant: "assistantMessageToolbarButton",
				"aria-label": title,
				className: twMerge(className),
				...props,
				children
			})
		}), /* @__PURE__ */ jsx(TooltipContent, {
			side: "bottom",
			children: /* @__PURE__ */ jsx("p", { children: title })
		})] });
	};
	_CopilotChatUserMessage.CopyButton = ({ className, title, onClick, ...props }) => {
		const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
		const [copied, setCopied] = useState(false);
		const handleClick = async (event) => {
			let success = false;
			if (onClick) success = await Promise.resolve(onClick(event)) === true;
			if (success) {
				setCopied(true);
				setTimeout(() => setCopied(false), 2e3);
			}
		};
		return /* @__PURE__ */ jsx(ToolbarButton, {
			"data-testid": "copilot-user-copy-button",
			title: title || labels.userMessageToolbarCopyMessageLabel,
			onClick: handleClick,
			className,
			...props,
			children: copied ? /* @__PURE__ */ jsx(Check, { className: "cpk:size-[18px]" }) : /* @__PURE__ */ jsx(Copy, { className: "cpk:size-[18px]" })
		});
	};
	_CopilotChatUserMessage.EditButton = ({ className, title, ...props }) => {
		const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
		return /* @__PURE__ */ jsx(ToolbarButton, {
			"data-testid": "copilot-edit-button",
			title: title || labels.userMessageToolbarEditMessageLabel,
			className,
			...props,
			children: /* @__PURE__ */ jsx(Edit, { className: "cpk:size-[18px]" })
		});
	};
	_CopilotChatUserMessage.BranchNavigation = ({ className, currentBranch = 0, numberOfBranches = 1, onSwitchToBranch, message, ...props }) => {
		if (!numberOfBranches || numberOfBranches <= 1 || !onSwitchToBranch) return null;
		const canGoPrev = currentBranch > 0;
		const canGoNext = currentBranch < numberOfBranches - 1;
		return /* @__PURE__ */ jsxs("div", {
			"data-testid": "copilot-branch-navigation",
			className: twMerge("cpk:flex cpk:items-center cpk:gap-1", className),
			...props,
			children: [
				/* @__PURE__ */ jsx(Button, {
					type: "button",
					variant: "assistantMessageToolbarButton",
					onClick: () => onSwitchToBranch?.({
						branchIndex: currentBranch - 1,
						numberOfBranches,
						message
					}),
					disabled: !canGoPrev,
					className: "cpk:h-6 cpk:w-6 cpk:p-0",
					children: /* @__PURE__ */ jsx(ChevronLeft, { className: "cpk:size-[20px]" })
				}),
				/* @__PURE__ */ jsxs("span", {
					className: "cpk:text-sm cpk:text-muted-foreground cpk:px-0 cpk:font-medium",
					children: [
						currentBranch + 1,
						"/",
						numberOfBranches
					]
				}),
				/* @__PURE__ */ jsx(Button, {
					type: "button",
					variant: "assistantMessageToolbarButton",
					onClick: () => onSwitchToBranch?.({
						branchIndex: currentBranch + 1,
						numberOfBranches,
						message
					}),
					disabled: !canGoNext,
					className: "cpk:h-6 cpk:w-6 cpk:p-0",
					children: /* @__PURE__ */ jsx(ChevronRight, { className: "cpk:size-[20px]" })
				})
			]
		});
	};
})(CopilotChatUserMessage || (CopilotChatUserMessage = {}));
CopilotChatUserMessage.Container.displayName = "CopilotChatUserMessage.Container";
CopilotChatUserMessage.MessageRenderer.displayName = "CopilotChatUserMessage.MessageRenderer";
CopilotChatUserMessage.Toolbar.displayName = "CopilotChatUserMessage.Toolbar";
CopilotChatUserMessage.ToolbarButton.displayName = "CopilotChatUserMessage.ToolbarButton";
CopilotChatUserMessage.CopyButton.displayName = "CopilotChatUserMessage.CopyButton";
CopilotChatUserMessage.EditButton.displayName = "CopilotChatUserMessage.EditButton";
CopilotChatUserMessage.BranchNavigation.displayName = "CopilotChatUserMessage.BranchNavigation";
var CopilotChatUserMessage_default = CopilotChatUserMessage;

//#endregion
//#region src/v2/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 = useRef(null);
	const [elapsed, setElapsed] = useState(0);
	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] = useState(isStreaming);
	const userToggledRef = useRef(false);
	useEffect(() => {
		if (isStreaming) {
			userToggledRef.current = false;
			setIsOpen(true);
		} else if (!userToggledRef.current) setIsOpen(false);
	}, [isStreaming]);
	const handleToggle = hasContent ? () => {
		userToggledRef.current = true;
		setIsOpen((prev) => !prev);
	} : void 0;
	const label = isStreaming ? "Thinking…" : `Thought for ${formatDuration(elapsed)}`;
	const boundHeader = renderSlot(header, CopilotChatReasoningMessage.Header, {
		isOpen,
		label,
		hasContent,
		isStreaming,
		onClick: handleToggle
	});
	const boundContent = renderSlot(contentView, CopilotChatReasoningMessage.Content, {
		isStreaming,
		hasContent,
		children: message.content
	});
	const boundToggle = renderSlot(toggle, CopilotChatReasoningMessage.Toggle, {
		isOpen,
		children: boundContent
	});
	if (children) return /* @__PURE__ */ jsx("div", {
		"data-copilotkit": true,
		style: { display: "contents" },
		children: children({
			header: boundHeader,
			contentView: boundContent,
			toggle: boundToggle,
			message,
			messages,
			isRunning
		})
	});
	return /* @__PURE__ */ jsxs("div", {
		className: 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__ */ jsxs("button", {
			type: "button",
			className: 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__ */ jsx("span", {
					className: "cpk:font-medium",
					children: label
				}),
				isStreaming && !hasContent && /* @__PURE__ */ jsx("span", {
					className: "cpk:inline-flex cpk:items-center cpk:ml-1",
					children: /* @__PURE__ */ jsx("span", { className: "cpk:w-1.5 cpk:h-1.5 cpk:rounded-full cpk:bg-muted-foreground cpk:animate-pulse" })
				}),
				headerChildren,
				isExpandable && /* @__PURE__ */ jsx(ChevronRight, { className: 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__ */ jsx("div", {
			className: twMerge("cpk:pb-2 cpk:pt-1", className),
			...contentProps,
			children: /* @__PURE__ */ jsxs("div", {
				className: "cpk:text-sm cpk:text-muted-foreground",
				children: [/* @__PURE__ */ jsx(Streamdown, { children: typeof contentChildren === "string" ? contentChildren : "" }), isStreaming && hasContent && /* @__PURE__ */ jsx("span", {
					className: "cpk:inline-flex cpk:items-center cpk:ml-1 cpk:align-middle",
					children: /* @__PURE__ */ 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__ */ jsx("div", {
			className: twMerge("cpk:grid cpk:transition-[grid-template-rows] cpk:duration-200 cpk:ease-in-out", className),
			style: { gridTemplateRows: isOpen ? "1fr" : "0fr" },
			...toggleProps,
			children: /* @__PURE__ */ 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
//#region src/v2/components/chat/CopilotChatSuggestionPill.tsx
const baseClasses = "group cpk:inline-flex cpk:h-7 cpk:sm:h-8 cpk:items-center cpk:gap-1 cpk:sm:gap-1.5 cpk:rounded-full cpk:border cpk:border-border/60 cpk:bg-background cpk:px-2.5 cpk:sm:px-3 cpk:text-[11px] cpk:sm:text-xs cpk:leading-none cpk:text-foreground cpk:transition-colors cpk:cursor-pointer cpk:hover:bg-accent/60 cpk:hover:text-foreground cpk:focus-visible:outline-none cpk:focus-visible:ring-2 cpk:focus-visible:ring-ring cpk:focus-visible:ring-offset-2 cpk:focus-visible:ring-offset-background cpk:disabled:cursor-not-allowed cpk:disabled:text-muted-foreground cpk:disabled:hover:bg-background cpk:disabled:hover:text-muted-foreground cpk:pointer-events-auto";
const labelClasses = "cpk:whitespace-nowrap cpk:font-medium cpk:leading-none";
const CopilotChatSuggestionPill = React.forwardRef(function CopilotChatSuggestionPill({ className, children, icon, isLoading, type, ...props }, ref) {
	const showIcon = !isLoading && icon;
	return /* @__PURE__ */ jsxs("button", {
		ref,
		"data-copilotkit": true,
		"data-testid": "copilot-suggestion",
		"data-slot": "suggestion-pill",
		className: cn(baseClasses, className),
		type: type ?? "button",
		"aria-busy": isLoading || void 0,
		disabled: isLoading || props.disabled,
		...props,
		children: [isLoading ? /* @__PURE__ */ jsx("span", {
			className: "cpk:flex cpk:h-3.5 cpk:sm:h-4 cpk:w-3.5 cpk:sm:w-4 cpk:items-center cpk:justify-center cpk:text-muted-foreground",
			children: /* @__PURE__ */ jsx(Loader2, {
				className: "cpk:h-3.5 cpk:sm:h-4 cpk:w-3.5 cpk:sm:w-4 cpk:animate-spin",
				"aria-hidden": "true"
			})
		}) : showIcon && /* @__PURE__ */ jsx("span", {
			className: "cpk:flex cpk:h-3.5 cpk:sm:h-4 cpk:w-3.5 cpk:sm:w-4 cpk:items-center cpk:justify-center cpk:text-muted-foreground",
			children: icon
		}), /* @__PURE__ */ jsx("span", {
			className: labelClasses,
			children
		})]
	});
});
CopilotChatSuggestionPill.displayName = "CopilotChatSuggestionPill";

//#endregion
//#region src/v2/components/chat/CopilotChatSuggestionView.tsx
const DefaultContainer = React.forwardRef(function DefaultContainer({ className, ...props }, ref) {
	return /* @__PURE__ */ jsx("div", {
		ref,
		"data-copilotkit": true,
		"data-testid": "copilot-suggestions",
		className: cn("cpk:flex cpk:flex-wrap cpk:items-center cpk:gap-1.5 cpk:sm:gap-2 cpk:pl-0 cpk:pr-4 cpk:@3xl:px-0 cpk:pointer-events-none", className),
		...props
	});
});
const CopilotChatSuggestionView = React.forwardRef(function CopilotChatSuggestionView({ suggestions, onSelectSuggestion, loadingIndexes, container, suggestion: suggestionSlot, className, children, ...restProps }, ref) {
	const loadingSet = React.useMemo(() => {
		if (!loadingIndexes || loadingIndexes.length === 0) return /* @__PURE__ */ new Set();
		return new Set(loadingIndexes);
	}, [loadingIndexes]);
	const ContainerElement = renderSlot(container, DefaultContainer, {
		ref,
		className,
		...restProps
	});
	const suggestionElements = suggestions.map((suggestion, index) => {
		const isLoading = loadingSet.has(index) || suggestion.isLoading === true;
		const pill = renderSlot(suggestionSlot, CopilotChatSuggestionPill, {
			children: suggestion.title,
			className: suggestion.className,
			isLoading,
			type: "button",
			onClick: () => onSelectSuggestion?.(suggestion, index)
		});
		return React.cloneElement(pill, { key: `${suggestion.title}-${index}` });
	});
	const boundContainer = React.cloneElement(ContainerElement, void 0, suggestionElements);
	if (typeof children === "function") {
		const sampleSuggestion = renderSlot(suggestionSlot, CopilotChatSuggestionPill, {
			children: suggestions[0]?.title ?? "",
			isLoading: suggestions.length > 0 ? loadingSet.has(0) || suggestions[0]?.isLoading === true : false,
			type: "button"
		});
		return /* @__PURE__ */ jsx("div", {
			"data-copilotkit": true,
			style: { display: "contents" },
			children: children({
				container: boundContainer,
				suggestion: sampleSuggestion,
				suggestions,
				onSelectSuggestion,
				loadingIndexes,
				className,
				...restProps
			})
		});
	}
	if (children) return /* @__PURE__ */ jsxs("div", {
		"data-copilotkit": true,
		style: { display: "contents" },
		children: [boundContainer, children]
	});
	return boundContainer;
});
CopilotChatSuggestionView.displayName = "CopilotChatSuggestionView";

//#endregion
//#region src/v2/components/chat/scroll-element-context.ts
/**
* Provides the scroll container element to child components that need it for
* virtualization. Set by CopilotChatView.ScrollView; consumed by
* CopilotChatMessageView to feed useVirtualizer's getScrollElement.
*
* Carries the element itself (not a ref) so that context consumers re-render
* reactively when the scroll container is first mounted.
*/
const ScrollElementContext = React.createContext(null);

//#endregion
//#region src/v2/components/intelligence-indicator/IntelligenceIndicatorView.tsx
/**
* The presentational "CopilotKit Intelligence" face — the default
* rendered by the {@link IntelligenceIndicator} brain and the default
* value for the `intelligenceIndicator` slot.
*
* Layout: a glassmorphism pill (the `__chrome` layer) wrapping an icon
* and a label. The icon is two overlaid SVG paths — a spinner arc and a
* checkmark — whose geometry lives in each path's `d` ATTRIBUTE so it
* renders in every browser (the CSS `d:` property is Chrome-only).
*
* Two states, driven by the `data-status` attribute (see globals.css
* for the exact timing):
*  1. **In-progress.** The arc spins (CSS rotation) inside the pill and
*     the checkmark is hidden. Label + icon are a saturated purple.
*  2. **Finished.** The arc fades out mid-spin while the checkmark draws
*     itself in upright (animated `stroke-dashoffset`); the pill chrome
*     fades away; and the label + icon settle from purple to a neutral
*     gray, with the label slanting slightly (a `transform: skewX`
*     faux-italic, so it interpolates with the color instead of snapping
*     and never reflows). The result reads as quiet "history metadata"
*     rather than an active spinner. The label text itself never changes
*     — the static check plus the color/slant shift carry the "done"
*     meaning, so no wording change is needed.
*
* All motion is gated behind `prefers-reduced-motion` (globals.css):
* when reduced motion is requested the arc does not spin and the two
* states swap instantly, without transitions.
*
* Customize via the `intelligenceIndicator` slot on `CopilotChat`:
* a className string restyles the wrapper, a props object tweaks
* the default (`{ label }`), and a component replaces it entirely
* with full control over visuals and timing.
*/
function IntelligenceIndicatorView({ message, status, label, className, ...rest }) {
	return /* @__PURE__ */ jsxs("span", {
		className: twMerge("cpk-intelligence-indicator", className),
		role: "status",
		"aria-live": "polite",
		"data-testid": `cpk-intelligence-indicator-${message.id}`,
		"data-status": status,
		title: label,
		...rest,
		children: [/* @__PURE__ */ jsx("span", {
			className: "cpk-intelligence-indicator__chrome",
			"aria-hidden": "true"
		}), /* @__PURE__ */ jsxs("span", {
			className: "cpk-intelligence-indicator__content",
			children: [/* @__PURE__ */ jsxs("svg", {
				className: "cpk-intelligence-indicator__icon",
				viewBox: "0 0 24 24",
				width: "14",
				height: "14",
				"aria-hidden": "true",
				children: [/* @__PURE__ */ jsx("path", {
					className: "cpk-intelligence-indicator__icon-arc",
					pathLength: 1,
					d: "M 12 3 C 17 3 21 7 21 12 C 21 17 17 21 12 21 C 7 21 3 17 3 12 C 3 7 7 3 12 3"
				}), /* @__PURE__ */ jsx("path", {
					className: "cpk-intelligence-indicator__icon-check",
					pathLength: 1,
					d: "M 5 12.5 L 9 16.5 L 19 6.5"
				})]
			}), /* @__PURE__ */ jsx("span", {
				className: "cpk-intelligence-indicator__label",
				children: label
			})]
		})]
	});
}

//#endregion
//#region src/v2/components/intelligence-indicator/IntelligenceIndicator.tsx
/**
* Grace window before showing the spinner. A matching tool call must
* remain unresolved (no `tool`-role result message in `agent.messages`)
* for at least this long before the indicator transitions out of
* `hidden`. This filters out history-replay flashes — during
* `connectAgent` replay, tool calls and their results arrive
* back-to-back in sub-millisecond bursts, so the timer is cancelled
* before it fires. Live runs cross the threshold easily because the
* tool actually has to execute.
*/
const PENDING_THRESHOLD_MS = 100;
/**
* Tool-name regex patterns that trigger the indicator. Matches any tool
* name *containing* the Intelligence MCP server's canonical tool name, so
* both the bare `copilotkit_knowledge_base_shell` and the namespaced
* `mcp__<server>__copilotkit_knowledge_base_shell` form (emitted by
* `@ag-ui/mcp-middleware`) light up the pill. If we add per-instance
* customization later (e.g. a `CopilotKitProvider` prop or a runtime-info
* field), this constant becomes the fallback.
*/
const DEFAULT_TOOL_PATTERNS = [/copilotkit_knowledge_base_shell/];
/**
* Phase to start in when an indicator first mounts. A turn that is already
* complete at mount jumps straight to `finished` — no `hidden` flash, no
* spinner blip — which is what makes scrolled-back / replayed history render
* its indicators directly in the finished state.
*
* Pure and timing-free on purpose: the grace window ({@link
* PENDING_THRESHOLD_MS}) only controls *when* the live transition is applied;
* these functions decide *what* it resolves to, so the decision can be unit
* tested deterministically without any timers.
*/
function initialIndicatorPhase(turnComplete) {
	return turnComplete ? "finished" : "hidden";
}
/**
* Phase the grace window resolves to once it elapses:
*   - completed turn → `finished` (replay-flash suppression: a tool whose
*     result lands within the window skips the spinner entirely),
*   - a still-pending matching tool call → `spinner`,
*   - otherwise stay `hidden` (the matching tool call hasn't landed yet).
*/
function resolveGracePhase(turnComplete, hasPending) {
	if (turnComplete) return "finished";
	if (hasPending) return "spinner";
	return "hidden";
}
const isMatchingToolCallName = (name) => typeof name === "string" && DEFAULT_TOOL_PATTERNS.some((p) => p.test(name));
const messageHasMatchingToolCall = (m) => {
	if (m.role !== "assistant") return false;
	return (Array.isArray(m.toolCalls) ? m.toolCalls : []).some((tc) => isMatchingToolCallName(tc?.function?.name));
};
/**
* Stable turn id for the messages that precede the first user message (a turn
* with no opening user message of its own). Used as the React key so the
* indicator for that turn never collides with a real user-message id.
*/
const INTELLIGENCE_TURN_HEAD = "__cpk_turn_head__";
/**
* Map each Intelligence-using turn to its anchor message — the FIRST bash-using
* assistant message of the turn — and a stable turn id (the id of the user
* message that opened the turn, or {@link INTELLIGENCE_TURN_HEAD} for the
* pre-first-user turn). Returns `Map<anchorMessageId, turnId>`.
*
* Anchoring to the FIRST (not last) bash-using message keeps the indicator
* fixed in place for the whole turn: later bash steps don't reposition it, so
* the spinner never abruptly jumps mid-turn (bug 1). `CopilotChatMessageView`
* emits exactly one `IntelligenceIndicator` per entry, keyed by the turn id and
* positioned at the anchor; the per-turn key also lets every past turn keep its
* own indicator in scroll-back.
*/
function getIntelligenceTurnAnchors(messages) {
	const anchors = /* @__PURE__ */ new Map();
	let turnId = INTELLIGENCE_TURN_HEAD;
	let anchorId = null;
	const commit = () => {
		if (anchorId !== null) anchors.set(anchorId, turnId);
		anchorId = null;
	};
	for (const m of messages) {
		if (m.role === "user") {
			commit();
			turnId = m.id;
			continue;
		}
		if (anchorId === null && messageHasMatchingToolCall(m)) anchorId = m.id;
	}
	commit();
	return anchors;
}
/**
* "Tool-call-like" messages do NOT count as a real follow-up: tool
* result messages, assistant messages that carry tool calls, and
* empty-content assistant messages (which some providers emit as a
* standalone wrapper around a batch of tool calls). A real follow-up
* is anything else — most importantly an assistant message with prose
* content, or a fresh user message.
*/
const isToolCallLikeMessage = (m) => {
	if (m.role === "tool") return true;
	if (m.role === "assistant") {
		if ((Array.isArray(m.toolCalls) ? m.toolCalls : []).length > 0) return true;
		const content = m.content;
		return typeof content !== "string" || content.trim().length === 0;
	}
	return false;
};
/**
* The "Using CopilotKit Intelligence" indicator brain. Auto-mounted by
* `CopilotChatMessageView` — once per Intelligence-using turn, at that
* turn's anchor message and keyed by the turn id (see
* {@link getIntelligenceTurnAnchors}). Callers do not register this
* themselves. It owns the run subscription and the phase machine and
* renders its swappable face via the `intelligenceIndicator` slot.
*
* Placement (which message anchors the turn) is decided by the view, so
* this component does not self-gate its own placement; it only derives
* in-progress/finished for the turn it was mounted on.
*
* Render gates (all must hold):
*   1. `copilotkit.intelligence !== undefined`
*   2. The (anchor) message is an assistant message with at least one
*      tool call whose name matches {@link DEFAULT_TOOL_PATTERNS}.
*   3. The phase machine is past `hidden`.
*
* Because the view keys each indicator by its turn id, the instance moves
* with the anchor across a hand-off (no remount, no spinner restart), and
* every prior Intelligence-using turn keeps its own persistent indicator
* in chat history.
*
* Phase machine (per-instance, all timers local):
*   - Starts in `hidden`, unless the message mounts onto an
*     already-completed turn (no pending work, agent stopped or a
*     real follow-up already present), in which case the lazy
*     `useState` initializer starts directly in `finished`. This is
*     what avoids a "hidden flash" on history replay.
*   - `hidden → spinner` once a matching tool call has been pending
*     (no `tool`-role result with a matching `toolCallId`) for
*     {@link PENDING_THRESHOLD_MS}. Replay flashes (tool call + result
*     in the same tick) never cross this threshold.
*   - `hidden → finished` if after the grace window the turn is
*     already complete (no pending work AND
*     `sawRealFollowup || !agent.isRunning`). Handles very fast tools
*     whose result lands within the grace window.
*   - `spinner → finished` as soon as EITHER `agent.isRunning` flips
*     false OR a non-tool-call-like message appears later in
*     `agent.messages` (i.e. the agent produced a "real" follow-up —
*     prose answer or a new user turn).
*   - `finished` is terminal: the indicator settles into its
*     persistent tag form and stays mounted.
*/
function IntelligenceIndicator(props) {
	const { message, agentId, label = "CopilotKit Intelligence", intelligenceIndicator } = props;
	const { copilotkit } = useCopilotKit$1();
	const config = useCopilotChatConfiguration();
	const { agent } = useAgent({
		agentId,
		updates: [UseAgentUpdate.OnRunStatusChanged, UseAgentUpdate.OnMessagesChanged]
	});
	const matchingToolCallIds = useMemo(() => {
		if (message.role !== "assistant") return [];
		const tcs = Array.isArray(message.toolCalls) ? message.toolCalls : [];
		const ids = [];
		for (const tc of tcs) if (isMatchingToolCallName(tc?.function?.name) && tc?.id) ids.push(tc.id);
		return ids;
	}, [message]);
	const hasPending = useMemo(() => {
		if (matchingToolCallIds.length === 0) return false;
		const resolved = /* @__PURE__ */ new Set();
		for (const m of agent.messages) if (m.role === "tool" && m.toolCallId) resolved.add(m.toolCallId);
		return matchingToolCallIds.some((id) => !resolved.has(id));
	}, [matchingToolCallIds, agent.messages]);
	const turnComplete = useMemo(() => {
		const idx = agent.messages.findIndex((m) => m.id === message.id);
		if (idx < 0) return false;
		for (let i = idx + 1; i < agent.messages.length; i += 1) if (!isToolCallLikeMessage(agent.messages[i])) return true;
		return false;
	}, [agent.messages, message.id]) || !agent.isRunning;
	const [phase, setPhase] = useState(() => initialIndicatorPhase(turnComplete));
	useEffect(() => {
		if (phase !== "hidden") return void 0;
		const t = setTimeout(() => {
			setPhase(resolveGracePhase(turnComplete, hasPending));
		}, PENDING_THRESHOLD_MS);
		return () => clearTimeout(t);
	}, [
		phase,
		hasPending,
		turnComplete
	]);
	useEffect(() => {
		if (phase !== "spinner") return void 0;
		if (turnComplete) setPhase("finished");
	}, [phase, turnComplete]);
	if (copilotkit.intelligence === void 0) return null;
	if (!config) return null;
	if (phase === "hidden") return null;
	if (message.role !== "assistant") return null;
	if (!messageHasMatchingToolCall(message)) return null;
	return renderSlot(intelligenceIndicator, IntelligenceIndicatorView, {
		message,
		status: phase === "finished" ? "finished" : "in-progress",
		label
	});
}

//#endregion
//#region src/v2/components/chat/CopilotChatMessageView.tsx
/**
* Resolves a slot value into a { Component, slotProps } pair, handling the three
* slot forms: a component type, a className string, or a partial-props object.
*/
function resolveSlotComponent(slot, DefaultComponent) {
	if (isReactComponentType(slot)) return {
		Component: slot,
		slotProps: void 0
	};
	if (typeof slot === "string") return {
		Component: DefaultComponent,
		slotProps: { className: slot }
	};
	if (slot && typeof slot === "object") return {
		Component: DefaultComponent,
		slotProps: slot
	};
	return {
		Component: DefaultComponent,
		slotProps: void 0
	};
}
/**
* Memoized wrapper for assistant messages to prevent re-renders when other messages change.
*/
const MemoizedAssistantMessage = React.memo(function MemoizedAssistantMessage({ message, messages, isRunning, AssistantMessageComponent, slotProps }) {
	return /* @__PURE__ */ 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.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.memo(function MemoizedUserMessage({ message, UserMessageComponent, slotProps }) {
	return /* @__PURE__ */ 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.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.memo(function MemoizedReasoningMessage({ message, messages, isRunning, ReasoningMessageComponent, slotProps }) {
	return /* @__PURE__ */ 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.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;
});
/**
* Deduplicates messages by ID. For assistant messages, merges occurrences:
* recovers non-empty content from any earlier occurrence if the latest wiped it
* (empty string means the streaming update cleared the field, not blank text),
* and similarly recovers toolCalls from earlier occurrences if the latest is
* undefined (an empty array [] is treated as intentional and kept as-is).
* For all other roles, keeps the last entry.
*
* @internal Exported for unit testing only — not part of the public API.
*/
/**
* Collapse tool calls that share an id, keeping first-seen order.
*
* AG-UI's TOOL_CALL_START handler appends to the parent message's `toolCalls`
* without checking whether that id is already present. So whenever a start
* event is applied twice — which the human-in-the-loop flow triggers when the
* run syncs after `respond()` — the message ends up carrying the same call
* twice. The second copy has EMPTY `arguments`, because a start event carries
* none; the args arrive later as TOOL_CALL_ARGS deltas addressed to the first
* copy.
*
* Left alone that renders the same tool call twice: once populated and once
* blank (an approval card with no transaction id, offering live buttons for an
* action already taken), and React warns "Encountered two children with the
* same key" because the call id is the render key.
*
* The empty copy is the redundant one, so prefer whichever entry actually
* carries arguments rather than blindly taking the first.
*/
function dedupeToolCalls(toolCalls) {
	const byId = /* @__PURE__ */ new Map();
	for (const toolCall of toolCalls) {
		const existing = byId.get(toolCall.id);
		if (!existing) {
			byId.set(toolCall.id, toolCall);
			continue;
		}
		if (!existing.function?.arguments && toolCall.function?.arguments) byId.set(toolCall.id, toolCall);
	}
	return byId.size === toolCalls.length ? toolCalls : [...byId.values()];
}
function deduplicateMessages(messages) {
	const acc = /* @__PURE__ */ new Map();
	for (const message of messages) {
		const existing = acc.get(message.id);
		if (existing && message.role === "assistant" && existing.role === "assistant") {
			const content = message.content || existing.content;
			const toolCalls = message.toolCalls ?? existing.toolCalls;
			acc.set(message.id, {
				...existing,
				...message,
				content,
				toolCalls: toolCalls ? dedupeToolCalls(toolCalls) : toolCalls
			});
		} else if (message.role === "assistant" && message.toolCalls) acc.set(message.id, {
			...message,
			toolCalls: dedupeToolCalls(message.toolCalls)
		});
		else acc.set(message.id, message);
	}
	return [...acc.values()];
}
const VIRTUALIZE_THRESHOLD = 50;
function CopilotChatMessageView({ messages = [], assistantMessage, userMessage, reasoningMessage, cursor, intelligenceIndicator, isRunning = false, children, className, ...props }) {
	const renderCustomMessage = useRenderCustomMessages();
	const { renderActivityMessage } = useRenderActivityMessage();
	const { copilotkit } = useCopilotKit$1();
	const config = useCopilotChatConfiguration();
	const [, forceUpdate] = useReducer((x) => x + 1, 0);
	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] = useState(null);
	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 = useMemo(() => deduplicateMessages(messages), [messages]);
	if (process.env.NODE_ENV === "development" && deduplicatedMessages.length < messages.length) console.warn(`CopilotChatMessageView: Merged ${messages.length - deduplicatedMessages.length} message(s) with duplicate IDs.`);
	const { Component: AssistantComponent, slotProps: assistantSlotProps } = useMemo(() => resolveSlotComponent(assistantMessage, CopilotChatAssistantMessage_default), [assistantMessage]);
	const agentId = config?.agentId;
	const threadId = config?.threadId;
	const assistantSlotPropsWithFeedback = useMemo(() => {
		const onThumbsUp = assistantSlotProps?.onThumbsUp;
		const onThumbsDown = assistantSlotProps?.onThumbsDown;
		if (!onThumbsUp && !onThumbsDown) return assistantSlotProps;
		const withRawEvent = (message) => {
			const rawEvent = agentId === void 0 || threadId === void 0 ? void 0 : copilotkit.getRawEventForMessage(agentId, threadId, message.id);
			return rawEvent === void 0 ? message : {
				...message,
				rawEvent
			};
		};
		return {
			...assistantSlotProps,
			...onThumbsUp && { onThumbsUp: (message) => onThumbsUp(withRawEvent(message)) },
			...onThumbsDown && { onThumbsDown: (message) => onThumbsDown(withRawEvent(message)) }
		};
	}, [
		assistantSlotProps,
		agentId,
		threadId,
		copilotkit
	]);
	const { Component: UserComponent, slotProps: userSlotProps } = useMemo(() => resolveSlotComponent(userMessage, CopilotChatUserMessage_default), [userMessage]);
	const { Component: ReasoningComponent, slotProps: reasoningSlotProps } = useMemo(() => resolveSlotComponent(reasoningMessage, CopilotChatReasoningMessage_default), [reasoningMessage]);
	const scrollElementFromCtx = useContext(ScrollElementContext);
	const scrollElement = scrollElementFromCtx && scrollElementFromCtx.clientHeight > 0 ? scrollElementFromCtx : null;
	useEffect(() => {
		if (process.env.NODE_ENV !== "production" && scrollElementFromCtx && scrollElementFromCtx.clientHeight === 0) console.warn("[CopilotKit] Chat scroll container has clientHeight=0 — virtualization disabled. Ensure the chat is rendered in a visible container with a non-zero height.");
	}, [scrollElementFromCtx]);
	const shouldVirtualize = !!scrollElement && !children && deduplicatedMessages.length > VIRTUALIZE_THRESHOLD;
	const virtualizer = useVirtualizer({
		count: shouldVirtualize ? deduplicatedMessages.length : 0,
		getScrollElement: () => scrollElement,
		estimateSize: () => 100,
		overscan: 5,
		measureElement: (el) => el?.getBoundingClientRect().height ?? 0,
		initialRect: {
			width: 0,
			height: 600
		}
	});
	const firstMessageId = deduplicatedMessages[0]?.id;
	useLayoutEffect(() => {
		if (!shouldVirtualize || !deduplicatedMessages.length) return;
		virtualizer.scrollToIndex(deduplicatedMessages.length - 1, { align: "end" });
	}, [shouldVirtualize, firstMessageId]);
	const intelligenceTurnAnchors = useMemo(() => getIntelligenceTurnAnchors(deduplicatedMessages), [deduplicatedMessages]);
	const renderMessageBlock = (message) => {
		const elements = [];
		const stateSnapshot = getStateSnapshotForMessage(message.id);
		if (renderCustomMessage) elements.push(/* @__PURE__ */ jsx(MemoizedCustomMessage, {
			message,
			position: "before",
			renderCustomMessage,
			stateSnapshot
		}, `${message.id}-custom-before`));
		if (message.role === "assistant") elements.push(/* @__PURE__ */ jsx(MemoizedAssistantMessage, {
			message,
			messages,
			isRunning,
			AssistantMessageComponent: AssistantComponent,
			slotProps: assistantSlotPropsWithFeedback
		}, message.id));
		else if (message.role === "user") elements.push(/* @__PURE__ */ jsx(MemoizedUserMessage, {
			message,
			UserMessageComponent: UserComponent,
			slotProps: userSlotProps
		}, message.id));
		else if (message.role === "activity") elements.push(/* @__PURE__ */ jsx(MemoizedActivityMessage, {
			message,
			renderActivityMessage
		}, message.id));
		else if (message.role === "reasoning") elements.push(/* @__PURE__ */ jsx(MemoizedReasoningMessage, {
			message,
			messages,
			isRunning,
			ReasoningMessageComponent: ReasoningComponent,
			slotProps: reasoningSlotProps
		}, message.id));
		if (renderCustomMessage) elements.push(/* @__PURE__ */ jsx(MemoizedCustomMessage, {
			message,
			position: "after",
			renderCustomMessage,
			stateSnapshot
		}, `${message.id}-custom-after`));
		const intelligenceTurnId = intelligenceTurnAnchors.get(message.id);
		if (intelligenceTurnId !== void 0) elements.push(/* @__PURE__ */ jsx(IntelligenceIndicator, {
			message,
			agentId: config?.agentId ?? DEFAULT_AGENT_ID,
			intelligenceIndicator
		}, `intelligence-${intelligenceTurnId}`));
		return elements.filter(Boolean);
	};
	const messageElements = shouldVirtualize ? [] : deduplicatedMessages.flatMap(renderMessageBlock);
	if (children) return /* @__PURE__ */ 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__ */ jsxs("div", {
		"data-copilotkit": true,
		"data-testid": "copilot-message-list",
		className: twMerge("copilotKitMessages cpk:flex cpk:flex-col", className),
		...props,
		children: [
			shouldVirtualize ? /* @__PURE__ */ jsx("div", {
				style: {
					height: virtualizer.getTotalSize(),
					position: "relative"
				},
				children: virtualizer.getVirtualItems().map((virtualItem) => {
					const message = deduplicatedMessages[virtualItem.index];
					return /* @__PURE__ */ jsx("div", {
						"data-index": virtualItem.index,
						ref: virtualizer.measureElement,
						style: {
							position: "absolute",
							top: 0,
							left: 0,
							width: "100%",
							transform: `translateY(${virtualItem.start}px)`
						},
						children: renderMessageBlock(message)
					}, message.id);
				})
			}) : messageElements,
			interruptElement,
			showCursor && /* @__PURE__ */ jsx("div", {
				className: "cpk:mt-2",
				children: renderSlot(cursor, CopilotChatMessageView.Cursor, {})
			})
		]
	});
}
CopilotChatMessageView.Cursor = function Cursor({ className, ...props }) {
	return /* @__PURE__ */ jsx("div", {
		"data-testid": "copilot-loading-cursor",
		className: twMerge("cpk:w-[11px] cpk:h-[11px] cpk:rounded-full cpk:bg-foreground cpk:animate-pulse-cursor cpk:ml-1", className),
		...props
	});
};

//#endregion
//#region src/v2/components/chat/CopilotChatAttachmentQueue.tsx
const CopilotChatAttachmentQueue = ({ attachments, onRemoveAttachment, className }) => {
	if (attachments.length === 0) return null;
	return /* @__PURE__ */ jsx("div", {
		"data-testid": "copilot-attachment-queue",
		className: cn("cpk:flex cpk:flex-wrap cpk:gap-2 cpk:p-2", className),
		children: attachments.map((attachment) => {
			const isMedia = attachment.type === "image" || attachment.type === "video";
			return /* @__PURE__ */ jsxs("div", {
				className: cn("cpk:relative cpk:inline-flex cpk:rounded-lg cpk:overflow-hidden cpk:border cpk:border-border", isMedia ? "cpk:w-[72px] cpk:h-[72px]" : attachment.type === "audio" ? "cpk:min-w-[200px] cpk:max-w-[280px] cpk:flex-col cpk:p-1 cpk:pr-8" : "cpk:p-2 cpk:px-3 cpk:pr-8 cpk:max-w-[240px]"),
				children: [
					attachment.status === "uploading" && /* @__PURE__ */ jsx(UploadingOverlay, {}),
					/* @__PURE__ */ jsx(AttachmentPreview, { attachment }),
					/* @__PURE__ */ jsx("button", {
						onClick: () => onRemoveAttachment(attachment.id),
						className: cn("cpk:absolute cpk:bg-black/60 cpk:text-white cpk:border-none cpk:rounded-full cpk:w-5 cpk:h-5 cpk:flex cpk:items-center cpk:justify-center cpk:cursor-pointer cpk:text-[10px] cpk:z-20", isMedia ? "cpk:top-1 cpk:right-1" : "cpk:top-1.5 cpk:right-1.5"),
						"aria-label": "Remove attachment",
						children: "✕"
					})
				]
			}, attachment.id);
		})
	});
};
function UploadingOverlay() {
	return /* @__PURE__ */ jsx("div", {
		className: "cpk:absolute cpk:inset-0 cpk:flex cpk:items-center cpk:justify-center cpk:bg-black/40 cpk:z-10",
		children: /* @__PURE__ */ jsx("div", { className: "cpk:w-5 cpk:h-5 cpk:border-2 cpk:border-white cpk:border-t-transparent cpk:rounded-full cpk:animate-spin" })
	});
}
function AttachmentPreview({ attachment }) {
	if (attachment.status === "uploading") return /* @__PURE__ */ jsx("div", { className: "cpk:w-full cpk:h-full" });
	switch (attachment.type) {
		case "image": return /* @__PURE__ */ jsx(ImagePreview, { attachment });
		case "audio": return /* @__PURE__ */ jsx(AudioPreview, { attachment });
		case "video": return /* @__PURE__ */ jsx(VideoPreview, { attachment });
		case "document": return /* @__PURE__ */ jsx(DocumentPreview, { attachment });
	}
}
function ImagePreview({ attachment }) {
	const src = getSourceUrl(attachment.source);
	const { thumbnailRef, vtName, open, openLightbox, closeLightbox } = useLightbox();
	return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("img", {
		ref: thumbnailRef,
		src,
		alt: attachment.filename || "Image attachment",
		className: "cpk:w-full cpk:h-full cpk:object-cover cpk:cursor-pointer",
		onClick: openLightbox
	}), open && /* @__PURE__ */ jsx(Lightbox, {
		onClose: closeLightbox,
		children: /* @__PURE__ */ jsx("img", {
			style: { viewTransitionName: vtName },
			src,
			alt: attachment.filename || "Image attachment",
			className: "cpk:max-w-[90vw] cpk:max-h-[90vh] cpk:object-contain cpk:rounded-lg"
		})
	})] });
}
function AudioPreview({ attachment }) {
	return /* @__PURE__ */ jsxs("div", {
		className: "cpk:flex cpk:flex-col cpk:gap-1 cpk:w-full",
		children: [/* @__PURE__ */ jsx("audio", {
			src: getSourceUrl(attachment.source),
			controls: true,
			preload: "metadata",
			className: "cpk:w-full cpk:h-8"
		}), attachment.filename && /* @__PURE__ */ jsx("span", {
			className: "cpk:text-xs cpk:font-medium cpk:overflow-hidden cpk:text-ellipsis cpk:whitespace-nowrap",
			children: attachment.filename
		})]
	});
}
function VideoPreview({ attachment }) {
	const src = getSourceUrl(attachment.source);
	const { thumbnailRef, vtName, open, openLightbox, closeLightbox } = useLightbox();
	return /* @__PURE__ */ jsxs(Fragment$1, { children: [
		/* @__PURE__ */ jsx("div", {
			ref: thumbnailRef,
			className: "cpk:w-full cpk:h-full",
			children: attachment.thumbnail ? /* @__PURE__ */ jsx("img", {
				src: attachment.thumbnail,
				alt: attachment.filename || "Video thumbnail",
				className: "cpk:w-full cpk:h-full cpk:object-cover"
			}) : /* @__PURE__ */ jsx("video", {
				src,
				preload: "metadata",
				muted: true,
				className: "cpk:w-full cpk:h-full cpk:object-cover"
			})
		}),
		/* @__PURE__ */ jsx("button", {
			onClick: openLightbox,
			className: "cpk:absolute cpk:inset-0 cpk:flex cpk:items-center cpk:justify-center cpk:z-10 cpk:cursor-pointer cpk:bg-black/20 cpk:border-none cpk:p-0",
			"aria-label": "Play video",
			children: /* @__PURE__ */ jsx("div", {
				className: "cpk:w-8 cpk:h-8 cpk:rounded-full cpk:bg-black/60 cpk:flex cpk:items-center cpk:justify-center",
				children: /* @__PURE__ */ jsx(Play, { className: "cpk:w-4 cpk:h-4 cpk:text-white cpk:ml-0.5" })
			})
		}),
		open && /* @__PURE__ */ jsx(Lightbox, {
			onClose: closeLightbox,
			children: /* @__PURE__ */ jsx("video", {
				style: { viewTransitionName: vtName },
				src,
				controls: true,
				autoPlay: true,
				className: "cpk:max-w-[90vw] cpk:max-h-[90vh] cpk:rounded-lg"
			})
		})
	] });
}
function isPdf(mimeType) {
	return !!mimeType && mimeType.includes("pdf");
}
function isText(mimeType) {
	return !!mimeType && mimeType.startsWith("text/");
}
function canPreviewInBrowser(mimeType) {
	return isPdf(mimeType) || isText(mimeType);
}
/**
* Convert a base64-encoded data source to a blob: URL that browsers will
* render inside an iframe (data: URLs are blocked for PDFs in most browsers).
*/
function useBlobUrl(attachment) {
	const [url, setUrl] = useState(null);
	useEffect(() => {
		if (attachment.source.type !== "data") return;
		try {
			const binary = atob(attachment.source.value);
			const bytes = new Uint8Array(binary.length);
			for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
			const blob = new Blob([bytes], { type: attachment.source.mimeType || "application/octet-stream" });
			const blobUrl = URL.createObjectURL(blob);
			setUrl(blobUrl);
			return () => URL.revokeObjectURL(blobUrl);
		} catch (error) {
			console.error("[CopilotKit] Failed to decode attachment data:", error);
			setUrl(null);
		}
	}, [
		attachment.source.type,
		attachment.source.value,
		attachment.source.mimeType
	]);
	if (attachment.source.type === "url") return attachment.source.value;
	return url;
}
function DocumentLightboxContent({ attachment, vtName }) {
	const mimeType = attachment.source.mimeType;
	const blobUrl = useBlobUrl(attachment);
	if (isPdf(mimeType)) {
		if (!blobUrl) return null;
		return /* @__PURE__ */ jsx("iframe", {
			style: { viewTransitionName: vtName },
			src: blobUrl,
			title: attachment.filename || "PDF preview",
			className: "cpk:w-[90vw] cpk:h-[90vh] cpk:max-w-[1000px] cpk:rounded-lg cpk:bg-white"
		});
	}
	if (isText(mimeType)) {
		const textContent = attachment.source.type === "data" ? (() => {
			try {
				return atob(attachment.source.value);
			} catch {
				return attachment.source.value;
			}
		})() : null;
		return /* @__PURE__ */ jsxs("div", {
			style: { viewTransitionName: vtName },
			className: "cpk:w-[90vw] cpk:max-w-[800px] cpk:max-h-[90vh] cpk:overflow-auto cpk:rounded-lg cpk:bg-white cpk:dark:bg-gray-900 cpk:p-6",
			children: [attachment.filename && /* @__PURE__ */ jsx("div", {
				className: "cpk:text-sm cpk:font-medium cpk:text-gray-500 cpk:dark:text-gray-400 cpk:mb-4 cpk:pb-2 cpk:border-b cpk:border-gray-200 cpk:dark:border-gray-700",
				children: attachment.filename
			}), textContent ? /* @__PURE__ */ jsx("pre", {
				className: "cpk:text-sm cpk:whitespace-pre-wrap cpk:break-words cpk:text-gray-800 cpk:dark:text-gray-200 cpk:font-mono cpk:m-0",
				children: textContent
			}) : blobUrl ? /* @__PURE__ */ jsx("iframe", {
				src: blobUrl,
				title: attachment.filename || "Text preview",
				className: "cpk:w-full cpk:h-[80vh] cpk:border-none"
			}) : null]
		});
	}
	return /* @__PURE__ */ jsxs("div", {
		style: { viewTransitionName: vtName },
		className: "cpk:flex cpk:flex-col cpk:items-center cpk:gap-4 cpk:p-8 cpk:rounded-lg cpk:bg-white cpk:dark:bg-gray-900",
		children: [
			/* @__PURE__ */ jsx("div", {
				className: "cpk:w-16 cpk:h-16 cpk:rounded-xl cpk:bg-primary cpk:text-primary-foreground cpk:flex cpk:items-center cpk:justify-center cpk:text-xl cpk:font-bold",
				children: getDocumentIcon(mimeType ?? "")
			}),
			/* @__PURE__ */ jsxs("div", {
				className: "cpk:text-center",
				children: [/* @__PURE__ */ jsx("div", {
					className: "cpk:text-base cpk:font-medium cpk:text-gray-800 cpk:dark:text-gray-200",
					children: attachment.filename || "Document"
				}), /* @__PURE__ */ jsxs("div", {
					className: "cpk:text-sm cpk:text-gray-500 cpk:dark:text-gray-400 cpk:mt-1",
					children: [mimeType || "Unknown type", attachment.size != null && ` · ${formatFileSize(attachment.size)}`]
				})]
			}),
			/* @__PURE__ */ jsx("div", {
				className: "cpk:text-xs cpk:text-gray-400 cpk:dark:text-gray-500",
				children: "No preview available for this file type"
			})
		]
	});
}
function DocumentPreview({ attachment }) {
	const { thumbnailRef, vtName, open, openLightbox, closeLightbox } = useLightbox();
	const mimeType = attachment.source.mimeType;
	const previewable = canPreviewInBrowser(mimeType);
	return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("div", {
		ref: thumbnailRef,
		className: cn("cpk:flex cpk:items-center cpk:gap-2", previewable && "cpk:cursor-pointer"),
		onClick: previewable ? openLightbox : void 0,
		children: [/* @__PURE__ */ jsx("div", {
			className: "cpk:w-8 cpk:h-8 cpk:rounded-md cpk:bg-primary cpk:text-primary-foreground cpk:flex cpk:items-center cpk:justify-center cpk:text-[10px] cpk:font-semibold cpk:shrink-0",
			children: getDocumentIcon(mimeType ?? "")
		}), /* @__PURE__ */ jsxs("div", {
			className: "cpk:flex cpk:flex-col cpk:min-w-0",
			children: [/* @__PURE__ */ jsx("span", {
				className: "cpk:text-xs cpk:font-medium cpk:break-all cpk:leading-tight",
				children: attachment.filename || "Document"
			}), attachment.size != null && /* @__PURE__ */ jsx("span", {
				className: "cpk:text-[11px] cpk:text-muted-foreground",
				children: formatFileSize(attachment.size)
			})]
		})]
	}), open && /* @__PURE__ */ jsx(Lightbox, {
		onClose: closeLightbox,
		children: /* @__PURE__ */ jsx(DocumentLightboxContent, {
			attachment,
			vtName
		})
	})] });
}

//#endregion
//#region src/v2/hooks/use-keyboard-height.tsx
/**
* Hook to detect mobile keyboard appearance and calculate available viewport height.
* Uses the Visual Viewport API to track keyboard state on mobile devices.
*
* @returns KeyboardState object with keyboard information
*/
function useKeyboardHeight() {
	const [keyboardState, setKeyboardState] = useState({
		isKeyboardOpen: false,
		keyboardHeight: 0,
		availableHeight: typeof window !== "undefined" ? window.innerHeight : 0,
		viewportHeight: typeof window !== "undefined" ? window.innerHeight : 0
	});
	useEffect(() => {
		if (typeof window === "undefined") return;
		const visualViewport = window.visualViewport;
		if (!visualViewport) return;
		const updateKeyboardState = () => {
			const layoutHeight = window.innerHeight;
			const visualHeight = visualViewport.height;
			const keyboardHeight = Math.max(0, layoutHeight - visualHeight);
			setKeyboardState({
				isKeyboardOpen: keyboardHeight > 150,
				keyboardHeight,
				availableHeight: visualHeight,
				viewportHeight: layoutHeight
			});
		};
		updateKeyboardState();
		visualViewport.addEventListener("resize", updateKeyboardState);
		visualViewport.addEventListener("scroll", updateKeyboardState);
		return () => {
			visualViewport.removeEventListener("resize", updateKeyboardState);
			visualViewport.removeEventListener("scroll", updateKeyboardState);
		};
	}, []);
	return keyboardState;
}

//#endregion
//#region src/v2/components/chat/normalize-auto-scroll.ts
const VALID = [
	"pin-to-bottom",
	"pin-to-send",
	"none"
];
function normalizeAutoScroll(value) {
	if (value === void 0) return "pin-to-bottom";
	if (value === true) return "pin-to-bottom";
	if (value === false) return "none";
	if (VALID.includes(value)) return value;
	return "pin-to-bottom";
}

//#endregion
//#region src/v2/components/chat/last-user-message-context.ts
const LastUserMessageContext = React.createContext({
	id: null,
	sendNonce: 0
});

//#endregion
//#region src/v2/hooks/use-pin-to-send.ts
function usePinToSend({ scrollRef, contentRef, spacerRef, topOffset = 16 }) {
	const { id, sendNonce } = useContext(LastUserMessageContext);
	const lastNonceRef = useRef(-1);
	useEffect(() => {
		if (sendNonce === lastNonceRef.current) return;
		lastNonceRef.current = sendNonce;
		if (!id) return;
		const scrollEl = scrollRef.current;
		const contentEl = contentRef.current;
		const spacerEl = spacerRef.current;
		if (!scrollEl || !contentEl || !spacerEl) return;
		const escaped = typeof CSS !== "undefined" && CSS.escape ? CSS.escape(id) : id.replace(/[!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g, "\\$&");
		const targetEl = contentEl.querySelector(`[data-message-id="${escaped}"]`);
		if (!targetEl) return;
		const viewportHeight = scrollEl.clientHeight;
		const userMessageHeight = targetEl.getBoundingClientRect().height;
		const paddingTop = parseFloat(getComputedStyle(targetEl).paddingTop) || 0;
		const bubbleHeight = Math.max(0, userMessageHeight - paddingTop);
		const spacerHeight = Math.max(0, viewportHeight - bubbleHeight - topOffset);
		spacerEl.style.height = `${spacerHeight}px`;
		const raf = requestAnimationFrame(() => {
			const targetTop = computeOffsetTop(targetEl, scrollEl) + paddingTop - topOffset;
			scrollEl.scrollTo({
				top: Math.max(0, targetTop),
				behavior: "smooth"
			});
		});
		const ro = new ResizeObserver(() => {
			if (!contentEl || !spacerEl || !scrollEl) return;
			const consumedBelow = contentEl.getBoundingClientRect().height - computeOffsetTop(targetEl, contentEl) - userMessageHeight;
			const remaining = Math.max(0, spacerHeight - consumedBelow);
			spacerEl.style.height = `${remaining}px`;
		});
		ro.observe(contentEl);
		return () => {
			cancelAnimationFrame(raf);
			ro.disconnect();
		};
	}, [
		id,
		sendNonce,
		scrollRef,
		contentRef,
		spacerRef,
		topOffset
	]);
}
function computeOffsetTop(el, stopAt) {
	const elRect = el.getBoundingClientRect();
	const stopRect = stopAt.getBoundingClientRect();
	return elRect.top - stopRect.top + stopAt.scrollTop;
}

//#endregion
//#region src/v2/components/chat/CopilotChatView.tsx
const SCROLL_BUTTON_OFFSET = 16;
function DropOverlay() {
	return /* @__PURE__ */ jsx("div", {
		className: cn("cpk:absolute cpk:inset-0 cpk:z-50 cpk:pointer-events-none", "cpk:flex cpk:items-center cpk:justify-center", "cpk:bg-primary/5 cpk:backdrop-blur-[2px]", "cpk:border-2 cpk:border-dashed cpk:border-primary/40 cpk:rounded-lg cpk:m-2"),
		children: /* @__PURE__ */ jsxs("div", {
			className: "cpk:flex cpk:flex-col cpk:items-center cpk:gap-2 cpk:text-primary/70",
			children: [/* @__PURE__ */ jsx(Upload, { className: "cpk:w-8 cpk:h-8" }), /* @__PURE__ */ jsx("span", {
				className: "cpk:text-sm cpk:font-medium",
				children: "Drop files here"
			})]
		})
	});
}
function CopilotChatView({ messageView, input, scrollView, suggestionView, welcomeScreen, messages = [], autoScroll = true, isRunning = false, suggestions, suggestionLoadingIndexes, onSelectSuggestion, onSubmitMessage, onStop, inputMode, inputValue, onInputChange, onStartTranscribe, onCancelTranscribe, onFinishTranscribe, onFinishTranscribeWithAudio, attachments, onRemoveAttachment, onAddFile, dragOver, onDragOver, onDragLeave, onDrop, isConnecting = false, hasExplicitThreadId = false, disclaimer, intelligenceIndicator, children, className, ...props }) {
	const [inputContainerEl, setInputContainerEl] = useState(null);
	const [inputContainerHeight, setInputContainerHeight] = useState(0);
	const [isResizing, setIsResizing] = useState(false);
	const resizeTimeoutRef = useRef(null);
	const { isKeyboardOpen, keyboardHeight, availableHeight } = useKeyboardHeight();
	useEffect(() => {
		const element = inputContainerEl;
		if (!element) {
			setInputContainerHeight(0);
			return;
		}
		const resizeObserver = new ResizeObserver((entries) => {
			for (const entry of entries) {
				const newHeight = entry.contentRect.height;
				setInputContainerHeight((prevHeight) => {
					if (newHeight !== prevHeight) {
						setIsResizing(true);
						if (resizeTimeoutRef.current) clearTimeout(resizeTimeoutRef.current);
						resizeTimeoutRef.current = setTimeout(() => {
							setIsResizing(false);
						}, 250);
						return newHeight;
					}
					return prevHeight;
				});
			}
		});
		resizeObserver.observe(element);
		setInputContainerHeight(element.offsetHeight);
		return () => {
			resizeObserver.disconnect();
			if (resizeTimeoutRef.current) clearTimeout(resizeTimeoutRef.current);
		};
	}, [inputContainerEl]);
	const BoundMessageView = renderSlot(messageView, CopilotChatMessageView, {
		messages,
		isRunning,
		intelligenceIndicator
	});
	const BoundInput = renderSlot(input, CopilotChatInput_default, {
		onSubmitMessage,
		onStop,
		mode: inputMode,
		value: inputValue,
		onChange: onInputChange,
		isRunning,
		onStartTranscribe,
		onCancelTranscribe,
		onFinishTranscribe,
		onFinishTranscribeWithAudio,
		onAddFile,
		positioning: "static",
		keyboardHeight: isKeyboardOpen ? keyboardHeight : 0,
		showDisclaimer: true,
		bottomAnchored: true,
		...disclaimer !== void 0 ? { disclaimer } : {}
	});
	const hasSuggestions = !isConnecting && !isRunning && Array.isArray(suggestions) && suggestions.length > 0;
	const BoundSuggestionView = hasSuggestions ? renderSlot(suggestionView, CopilotChatSuggestionView, {
		suggestions,
		loadingIndexes: suggestionLoadingIndexes,
		onSelectSuggestion,
		className: "cpk:mb-3 cpk:lg:ml-4 cpk:lg:mr-4 cpk:ml-0 cpk:mr-0"
	}) : null;
	const BoundScrollView = renderSlot(scrollView, CopilotChatView.ScrollView, {
		autoScroll,
		inputContainerHeight,
		isResizing,
		children: /* @__PURE__ */ jsx("div", {
			"data-testid": "copilot-scroll-content",
			style: { paddingBottom: `${inputContainerHeight + (hasSuggestions ? 4 : 32)}px` },
			children: /* @__PURE__ */ jsxs("div", {
				className: "cpk:max-w-3xl cpk:mx-auto",
				children: [BoundMessageView, hasSuggestions ? /* @__PURE__ */ jsx("div", {
					className: "cpk:pl-0 cpk:pr-4 cpk:@3xl:px-0 cpk:mt-4",
					children: BoundSuggestionView
				}) : null]
			})
		})
	});
	if (messages.length === 0 && !(welcomeScreen === false) && !isConnecting && !hasExplicitThreadId) {
		const BoundInputForWelcome = renderSlot(input, CopilotChatInput_default, {
			onSubmitMessage,
			onStop,
			mode: inputMode,
			value: inputValue,
			onChange: onInputChange,
			isRunning,
			onStartTranscribe,
			onCancelTranscribe,
			onFinishTranscribe,
			onFinishTranscribeWithAudio,
			onAddFile,
			positioning: "static",
			showDisclaimer: true,
			...disclaimer !== void 0 ? { disclaimer } : {}
		});
		const welcomeScreenSlot = welcomeScreen === true ? void 0 : welcomeScreen;
		const inputWithAttachments = /* @__PURE__ */ jsxs("div", {
			className: "cpk:w-full",
			children: [attachments && attachments.length > 0 && /* @__PURE__ */ jsx(CopilotChatAttachmentQueue, {
				attachments,
				onRemoveAttachment: (id) => onRemoveAttachment?.(id),
				className: "cpk:mb-2"
			}), BoundInputForWelcome]
		});
		const BoundWelcomeScreen = renderSlot(welcomeScreenSlot, CopilotChatView.WelcomeScreen, {
			input: inputWithAttachments,
			suggestionView: BoundSuggestionView ?? /* @__PURE__ */ jsx(Fragment$1, {})
		});
		return /* @__PURE__ */ jsxs("div", {
			"data-copilotkit": true,
			"data-testid": "copilot-chat",
			"data-copilot-running": isRunning ? "true" : "false",
			onDragOver,
			onDragLeave,
			onDrop,
			className: cn("copilotKitChat cpk:@container cpk:relative cpk:h-full cpk:flex cpk:flex-col", className),
			...props,
			children: [dragOver && /* @__PURE__ */ jsx(DropOverlay, {}), BoundWelcomeScreen]
		});
	}
	if (children) return /* @__PURE__ */ jsx("div", {
		"data-copilotkit": true,
		style: { display: "contents" },
		children: children({
			messageView: BoundMessageView,
			input: BoundInput,
			scrollView: BoundScrollView,
			suggestionView: BoundSuggestionView ?? /* @__PURE__ */ jsx(Fragment$1, {})
		})
	});
	return /* @__PURE__ */ jsxs("div", {
		"data-copilotkit": true,
		"data-testid": "copilot-chat",
		"data-copilot-running": isRunning ? "true" : "false",
		onDragOver,
		onDragLeave,
		onDrop,
		className: cn("copilotKitChat cpk:@container cpk:relative cpk:h-full cpk:flex cpk:flex-col", className),
		...props,
		children: [
			dragOver && /* @__PURE__ */ jsx(DropOverlay, {}),
			BoundScrollView,
			/* @__PURE__ */ jsxs("div", {
				ref: setInputContainerEl,
				"data-testid": "copilot-input-overlay",
				className: "cpk:absolute cpk:bottom-0 cpk:left-0 cpk:right-0 cpk:z-20 cpk:pointer-events-none",
				children: [attachments && attachments.length > 0 && /* @__PURE__ */ jsx("div", {
					className: "cpk:max-w-3xl cpk:mx-auto cpk:w-full cpk:pointer-events-auto",
					children: /* @__PURE__ */ jsx(CopilotChatAttachmentQueue, {
						attachments,
						onRemoveAttachment: (id) => onRemoveAttachment?.(id),
						className: "cpk:px-4"
					})
				}), BoundInput]
			})
		]
	});
}
(function(_CopilotChatView) {
	const ScrollContent = ({ children, scrollToBottomButton, feather, inputContainerHeight, isResizing }) => {
		const { isAtBottom, scrollToBottom, scrollRef } = useStickToBottomContext();
		const [scrollEl, setScrollEl] = useState(null);
		useLayoutEffect(() => {
			setScrollEl(scrollRef.current ?? null);
		}, []);
		const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});
		return /* @__PURE__ */ jsx(ScrollElementContext.Provider, {
			value: scrollEl,
			children: /* @__PURE__ */ jsxs(Fragment$1, { children: [
				/* @__PURE__ */ jsx(StickToBottom.Content, {
					className: "cpk:overflow-y-auto cpk:overflow-x-hidden",
					style: {
						flex: "1 1 0%",
						minHeight: 0
					},
					children: /* @__PURE__ */ jsx("div", {
						className: "cpk:px-4 cpk:@3xl:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6",
						children
					})
				}),
				BoundFeather,
				!isAtBottom && !isResizing && /* @__PURE__ */ jsx("div", {
					className: "cpk:absolute cpk:inset-x-0 cpk:flex cpk:justify-center cpk:z-30 cpk:pointer-events-none",
					style: { bottom: `${inputContainerHeight + SCROLL_BUTTON_OFFSET}px` },
					children: renderSlot(scrollToBottomButton, CopilotChatView.ScrollToBottomButton, { onClick: () => scrollToBottom() })
				})
			] })
		});
	};
	const PinToSendScrollContainer = ({ children, scrollRef, contentRef, scrollToBottom, scrollToBottomButton, feather, inputContainerHeight, isResizing, nonAutoScrollEl, nonAutoScrollRefCallback, showScrollButton, className, ...props }) => {
		const spacerRef = useRef(null);
		usePinToSend({
			scrollRef,
			contentRef,
			spacerRef,
			topOffset: 16
		});
		const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});
		return /* @__PURE__ */ jsx(ScrollElementContext.Provider, {
			value: nonAutoScrollEl,
			children: /* @__PURE__ */ jsxs("div", {
				className: cn("cpk:h-full cpk:max-h-full cpk:flex cpk:flex-col cpk:min-h-0 cpk:relative", className),
				children: [
					/* @__PURE__ */ jsxs("div", {
						ref: nonAutoScrollRefCallback,
						className: "cpk:flex-1 cpk:min-h-0 cpk:overflow-y-auto cpk:overflow-x-hidden",
						...props,
						children: [/* @__PURE__ */ jsx("div", {
							ref: contentRef,
							className: "cpk:px-4 cpk:@3xl:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6",
							children
						}), /* @__PURE__ */ jsx("div", {
							ref: spacerRef,
							"data-pin-to-send-spacer": true,
							"aria-hidden": "true",
							style: {
								height: 0,
								flex: "0 0 auto"
							}
						})]
					}),
					BoundFeather,
					showScrollButton && !isResizing && /* @__PURE__ */ jsx("div", {
						className: "cpk:absolute cpk:inset-x-0 cpk:flex cpk:justify-center cpk:z-30 cpk:pointer-events-none",
						style: { bottom: `${inputContainerHeight + SCROLL_BUTTON_OFFSET}px` },
						children: renderSlot(scrollToBottomButton, CopilotChatView.ScrollToBottomButton, { onClick: () => scrollToBottom() })
					})
				]
			})
		});
	};
	_CopilotChatView.ScrollView = ({ children, autoScroll = "pin-to-bottom", scrollToBottomButton, feather, inputContainerHeight = 0, isResizing = false, className, ...props }) => {
		const mode = normalizeAutoScroll(autoScroll);
		const [hasMounted, setHasMounted] = useState(false);
		const scrollRef = useRef(null);
		const contentRef = useRef(null);
		const scrollToBottom = useCallback(() => {
			const el = scrollRef.current;
			if (el) el.scrollTo({
				top: el.scrollHeight,
				behavior: "smooth"
			});
		}, []);
		const [showScrollButton, setShowScrollButton] = useState(false);
		const [nonAutoScrollEl, setNonAutoScrollEl] = useState(null);
		const nonAutoScrollRefCallback = useCallback((el) => {
			scrollRef.current = el;
			setNonAutoScrollEl(el);
		}, []);
		useEffect(() => {
			setHasMounted(true);
		}, []);
		useEffect(() => {
			if (mode === "pin-to-bottom") return;
			const scrollElement = nonAutoScrollEl;
			if (!scrollElement) return;
			const checkScroll = () => {
				setShowScrollButton(!(scrollElement.scrollHeight - scrollElement.scrollTop - scrollElement.clientHeight < 10));
			};
			checkScroll();
			scrollElement.addEventListener("scroll", checkScroll);
			const resizeObserver = new ResizeObserver(checkScroll);
			resizeObserver.observe(scrollElement);
			return () => {
				scrollElement.removeEventListener("scroll", checkScroll);
				resizeObserver.disconnect();
			};
		}, [nonAutoScrollEl, mode]);
		if (!hasMounted) return /* @__PURE__ */ jsx("div", {
			className: "cpk:h-full cpk:max-h-full cpk:flex cpk:flex-col cpk:min-h-0 cpk:overflow-y-auto cpk:overflow-x-hidden",
			children: /* @__PURE__ */ jsx("div", {
				className: "cpk:px-4 cpk:@3xl:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6",
				children
			})
		});
		if (mode === "none") {
			const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});
			return /* @__PURE__ */ jsx(ScrollElementContext.Provider, {
				value: nonAutoScrollEl,
				children: /* @__PURE__ */ jsxs("div", {
					ref: nonAutoScrollRefCallback,
					className: cn("cpk:h-full cpk:max-h-full cpk:flex cpk:flex-col cpk:min-h-0 cpk:overflow-y-auto cpk:overflow-x-hidden cpk:relative", className),
					...props,
					children: [
						/* @__PURE__ */ jsx("div", {
							ref: contentRef,
							className: "cpk:px-4 cpk:@3xl:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6",
							children
						}),
						BoundFeather,
						showScrollButton && !isResizing && /* @__PURE__ */ jsx("div", {
							className: "cpk:absolute cpk:inset-x-0 cpk:flex cpk:justify-center cpk:z-30 cpk:pointer-events-none",
							style: { bottom: `${inputContainerHeight + SCROLL_BUTTON_OFFSET}px` },
							children: renderSlot(scrollToBottomButton, CopilotChatView.ScrollToBottomButton, { onClick: () => scrollToBottom() })
						})
					]
				})
			});
		}
		if (mode === "pin-to-send") return /* @__PURE__ */ jsx(PinToSendScrollContainer, {
			scrollRef,
			contentRef,
			scrollToBottom,
			scrollToBottomButton,
			feather,
			inputContainerHeight,
			isResizing,
			nonAutoScrollEl,
			nonAutoScrollRefCallback,
			showScrollButton,
			className,
			...props,
			children
		});
		return /* @__PURE__ */ jsx(StickToBottom, {
			className: cn("cpk:flex-1 cpk:max-h-full cpk:flex cpk:flex-col cpk:min-h-0", className),
			resize: "smooth",
			initial: "smooth",
			...props,
			children: /* @__PURE__ */ jsx(ScrollContent, {
				scrollToBottomButton,
				feather,
				inputContainerHeight,
				isResizing,
				children
			})
		});
	};
	_CopilotChatView.ScrollToBottomButton = ({ className, ...props }) => /* @__PURE__ */ jsx(Button, {
		"data-testid": "copilot-scroll-to-bottom",
		variant: "outline",
		size: "sm",
		className: twMerge("cpk:rounded-full cpk:w-10 cpk:h-10 cpk:p-0 cpk:pointer-events-auto", "cpk:bg-white cpk:dark:bg-gray-900", "cpk:shadow-lg cpk:border cpk:border-gray-200 cpk:dark:border-gray-700", "cpk:hover:bg-gray-50 cpk:dark:hover:bg-gray-800", "cpk:flex cpk:items-center cpk:justify-center cpk:cursor-pointer", className),
		...props,
		children: /* @__PURE__ */ jsx(ChevronDown, { className: "cpk:w-4 cpk:h-4 cpk:text-gray-600 cpk:dark:text-white" })
	});
	_CopilotChatView.Feather = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
		className,
		...props
	});
	_CopilotChatView.WelcomeMessage = ({ className, ...props }) => {
		const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
		return /* @__PURE__ */ jsx("h1", {
			className: cn("cpk:text-xl cpk:sm:text-2xl cpk:font-medium cpk:text-foreground cpk:text-center", className),
			...props,
			children: labels.welcomeMessageText
		});
	};
	_CopilotChatView.WelcomeScreen = ({ welcomeMessage, input, suggestionView, className, children, ...props }) => {
		const BoundWelcomeMessage = renderSlot(welcomeMessage, CopilotChatView.WelcomeMessage, {});
		if (children) return /* @__PURE__ */ jsx("div", {
			"data-copilotkit": true,
			style: { display: "contents" },
			children: children({
				welcomeMessage: BoundWelcomeMessage,
				input,
				suggestionView,
				className,
				...props
			})
		});
		return /* @__PURE__ */ jsx("div", {
			"data-testid": "copilot-welcome-screen",
			className: cn("cpk:flex-1 cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:px-4", className),
			...props,
			children: /* @__PURE__ */ jsxs("div", {
				className: "cpk:w-full cpk:max-w-3xl cpk:flex cpk:flex-col cpk:items-center",
				children: [
					/* @__PURE__ */ jsx("div", {
						className: "cpk:mb-6",
						children: BoundWelcomeMessage
					}),
					/* @__PURE__ */ jsx("div", {
						className: "cpk:w-full",
						children: input
					}),
					/* @__PURE__ */ jsx("div", {
						className: "cpk:mt-4 cpk:flex cpk:justify-center",
						children: suggestionView
					})
				]
			})
		});
	};
})(CopilotChatView || (CopilotChatView = {}));
var CopilotChatView_default = CopilotChatView;

//#endregion
//#region src/v2/lib/transcription-client.ts
/**
* Convert a Blob to a base64 string
*/
async function blobToBase64(blob) {
	return new Promise((resolve, reject) => {
		const reader = new FileReader();
		reader.onloadend = () => {
			const base64 = reader.result.split(",")[1];
			resolve(base64 ?? "");
		};
		reader.onerror = () => reject(/* @__PURE__ */ new Error("Failed to read audio data"));
		reader.readAsDataURL(blob);
	});
}
/**
* Check if an error response matches our expected format
*/
function isTranscriptionErrorResponse(data) {
	return typeof data === "object" && data !== null && "error" in data && "message" in data && typeof data.error === "string" && typeof data.message === "string";
}
/**
* Parse error info from a transcription error response
*/
function parseTranscriptionError(response) {
	return {
		code: response.error,
		message: response.message,
		retryable: response.retryable ?? false
	};
}
/**
* Custom error type for transcription failures.
* Extends Error with transcription-specific info for contextual error handling.
*/
var TranscriptionError = class extends Error {
	constructor(info) {
		super(info.message);
		this.name = "TranscriptionError";
		this.info = info;
	}
};
/**
* Transcribe an audio blob using the CopilotKit runtime
*
* Supports both REST mode (multipart/form-data) and single-endpoint mode (base64 JSON)
*
* @throws {TranscriptionError} When transcription fails with typed error information
*/
async function transcribeAudio(core, audioBlob, filename = "recording.webm") {
	const runtimeUrl = core.runtimeUrl;
	if (!runtimeUrl) throw new TranscriptionError({
		code: TranscriptionErrorCode$1.INVALID_REQUEST,
		message: "Runtime URL is not configured",
		retryable: false
	});
	const headers = { ...core.headers };
	let response;
	try {
		if (core.runtimeTransport === "single") {
			const base64Audio = await blobToBase64(audioBlob);
			headers["Content-Type"] = "application/json";
			response = await fetch(runtimeUrl, {
				method: "POST",
				headers,
				body: JSON.stringify({
					method: "transcribe",
					body: {
						audio: base64Audio,
						mimeType: audioBlob.type || "audio/webm",
						filename
					}
				})
			});
		} else {
			delete headers["Content-Type"];
			const formData = new FormData();
			formData.append("audio", audioBlob, filename);
			response = await fetch(`${runtimeUrl}/transcribe`, {
				method: "POST",
				headers,
				body: formData
			});
		}
	} catch (error) {
		throw new TranscriptionError({
			code: TranscriptionErrorCode$1.NETWORK_ERROR,
			message: error instanceof Error ? error.message : "Network request failed",
			retryable: true
		});
	}
	if (!response.ok) {
		let errorData;
		try {
			errorData = await response.json();
		} catch {
			throw new TranscriptionError({
				code: TranscriptionErrorCode$1.PROVIDER_ERROR,
				message: `HTTP ${response.status}: ${response.statusText}`,
				retryable: response.status >= 500
			});
		}
		if (isTranscriptionErrorResponse(errorData)) throw new TranscriptionError(parseTranscriptionError(errorData));
		throw new TranscriptionError({
			code: TranscriptionErrorCode$1.PROVIDER_ERROR,
			message: typeof errorData === "object" && errorData !== null && "message" in errorData ? String(errorData.message) : "Transcription failed",
			retryable: response.status >= 500
		});
	}
	return await response.json();
}

//#endregion
//#region src/v2/components/chat/CopilotChat.tsx
function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen, attachments: attachmentsConfig, onError, throttleMs, ...props }) {
	const existingConfig = useCopilotChatConfiguration();
	const resolvedAgentId = agentId ?? existingConfig?.agentId ?? DEFAULT_AGENT_ID;
	const providedThreadId = threadId ?? existingConfig?.threadId;
	const resolvedThreadId = useMemo(() => providedThreadId ?? randomUUID$1(), [providedThreadId]);
	const hasExplicitThreadId = !!threadId || !!existingConfig?.hasExplicitThreadId;
	const { agent, isReady } = useAgent({
		agentId: resolvedAgentId,
		throttleMs
	});
	const { copilotkit } = useCopilotKit();
	const { suggestions: autoSuggestions } = useSuggestions({ agentId: resolvedAgentId });
	const { checkFeature } = useLicenseContext();
	const isChatLicensed = checkFeature("chat");
	useEffect(() => {
		if (!isChatLicensed) console.warn("[CopilotKit] Warning: \"chat\" feature is not licensed. Visit copilotkit.ai/pricing");
	}, [isChatLicensed]);
	const onErrorRef = useRef(onError);
	useEffect(() => {
		onErrorRef.current = onError;
	}, [onError]);
	useEffect(() => {
		if (!onErrorRef.current) return;
		const subscription = copilotkit.subscribe({ onError: (event) => {
			if (event.context?.agentId === resolvedAgentId || !event.context?.agentId) onErrorRef.current?.({
				error: event.error,
				code: event.code,
				context: event.context
			});
		} });
		return () => {
			subscription.unsubscribe();
		};
	}, [copilotkit, resolvedAgentId]);
	const [transcribeMode, setTranscribeMode] = useState("input");
	const [inputValue, setInputValue] = useState("");
	const [transcriptionError, setTranscriptionError] = useState(null);
	const [isTranscribing, setIsTranscribing] = useState(false);
	const { attachments: selectedAttachments, enabled: attachmentsEnabled, dragOver, fileInputRef, containerRef: chatContainerRef, handleFileUpload, handleDragOver, handleDragLeave, handleDrop, removeAttachment, consumeAttachments } = useAttachments({ config: attachmentsConfig });
	const selectedAttachmentsRef = useRef(selectedAttachments);
	useEffect(() => {
		selectedAttachmentsRef.current = selectedAttachments;
	}, [selectedAttachments]);
	const isTranscriptionEnabled = copilotkit.audioFileTranscriptionEnabled;
	const isMediaRecorderSupported = typeof window !== "undefined" && typeof MediaRecorder !== "undefined";
	const { messageView: providedMessageView, suggestionView: providedSuggestionView, onStop: providedStopHandler, ...restProps } = props;
	const [lastConnectedThreadId, setLastConnectedThreadId] = useState(null);
	const isConnecting = hasExplicitThreadId && lastConnectedThreadId !== resolvedThreadId;
	const activeConnectCountRef = useRef(0);
	const pendingRunActivityReconnectRef = useRef(false);
	const runActivityReconnectGenerationRef = useRef(0);
	const activeLocalRunIdsRef = useRef(/* @__PURE__ */ new Set());
	const recentlyLocalRunIdsRef = useRef(/* @__PURE__ */ new Map());
	const activeWakeRunIdsRef = useRef(/* @__PURE__ */ new Set());
	const recentlyWakeRunIdsRef = useRef(/* @__PURE__ */ new Map());
	const pendingWakeRunIdRef = useRef(void 0);
	const startRunActivityReconnectRef = useRef(null);
	const runtimeStatus = copilotkit.runtimeConnectionStatus === CopilotKitCoreRuntimeConnectionStatus.Connected ? "Connected" : copilotkit.runtimeConnectionStatus;
	const hasNativeIntelligenceRunActivity = hasExplicitThreadId && runtimeStatus === "Connected" && !!copilotkit.intelligence?.wsUrl && copilotkit.threadEndpoints?.realtimeMetadata === true;
	const [standaloneRunActivityStore] = useState(() => ɵcreateThreadStore({ fetch: globalThis.fetch }));
	const previousThreadIdRef = useRef(null);
	const hasExplicitThreadIdRef = useRef(hasExplicitThreadId);
	hasExplicitThreadIdRef.current = hasExplicitThreadId;
	const rememberRecentlyLocalRunId = useCallback((runId) => {
		const existingTimeout = recentlyLocalRunIdsRef.current.get(runId);
		if (existingTimeout) clearTimeout(existingTimeout);
		const timeout = setTimeout(() => {
			recentlyLocalRunIdsRef.current.delete(runId);
		}, 3e4);
		recentlyLocalRunIdsRef.current.set(runId, timeout);
	}, []);
	const rememberRecentlyWakeRunId = useCallback((runId) => {
		const existingTimeout = recentlyWakeRunIdsRef.current.get(runId);
		if (existingTimeout) clearTimeout(existingTimeout);
		const timeout = setTimeout(() => {
			recentlyWakeRunIdsRef.current.delete(runId);
		}, 3e4);
		recentlyWakeRunIdsRef.current.set(runId, timeout);
	}, []);
	const isLocalActiveRunActivity = useCallback((notification) => {
		if (notification.agentId && notification.agentId !== resolvedAgentId) return false;
		if (!notification.runId || !activeLocalRunIdsRef.current.has(notification.runId) && !recentlyLocalRunIdsRef.current.has(notification.runId)) return false;
		const eventType = notification.eventType.toUpperCase();
		return eventType === "RUN_STARTED" || eventType === "RUN_FINISHED" || eventType === "RUN_ERROR";
	}, [resolvedAgentId]);
	useEffect(() => {
		const recentlyLocalRunIds = recentlyLocalRunIdsRef.current;
		const recentlyWakeRunIds = recentlyWakeRunIdsRef.current;
		return () => {
			recentlyLocalRunIds.forEach((timeout) => {
				clearTimeout(timeout);
			});
			recentlyLocalRunIds.clear();
			recentlyWakeRunIds.forEach((timeout) => {
				clearTimeout(timeout);
			});
			recentlyWakeRunIds.clear();
		};
	}, []);
	useEffect(() => {
		const threadChanged = previousThreadIdRef.current !== resolvedThreadId;
		previousThreadIdRef.current = resolvedThreadId;
		agent.threadId = resolvedThreadId;
		if (!hasExplicitThreadId) {
			if (threadChanged && agent.messages.length > 0) agent.setMessages([]);
			return;
		}
		let detached = false;
		const connectAbortController = new AbortController();
		if (agent instanceof HttpAgent) agent.abortController = connectAbortController;
		const connect = async (agentToConnect) => {
			activeConnectCountRef.current += 1;
			try {
				await copilotkit.connectAgent({ agent: agentToConnect });
			} catch (error) {
				if (detached) return;
				console.error("CopilotChat: connectAgent failed", error);
			} finally {
				if (!detached) (typeof requestAnimationFrame === "function" ? requestAnimationFrame : (cb) => setTimeout(cb, 16))(() => {
					if (!detached) setLastConnectedThreadId(resolvedThreadId);
				});
				else if (!hasExplicitThreadIdRef.current) agentToConnect.setMessages([]);
				activeConnectCountRef.current = Math.max(0, activeConnectCountRef.current - 1);
				if (!detached && activeConnectCountRef.current === 0) {
					const startReconnect = startRunActivityReconnectRef.current;
					if (pendingRunActivityReconnectRef.current && startReconnect) {
						pendingRunActivityReconnectRef.current = false;
						startReconnect(runActivityReconnectGenerationRef.current);
					}
				}
			}
		};
		connect(agent);
		return () => {
			detached = true;
			connectAbortController.abort();
			agent.detachActiveRun().catch(() => {});
		};
	}, [
		resolvedThreadId,
		agent,
		resolvedAgentId,
		hasExplicitThreadId
	]);
	useEffect(() => {
		if (!hasNativeIntelligenceRunActivity) return;
		const registeredThreadStore = copilotkit.getThreadStore(resolvedAgentId);
		const threadStore = registeredThreadStore ?? standaloneRunActivityStore;
		if (!threadStore?.subscribeToRunActivity) return;
		const ownsStandaloneStore = registeredThreadStore === void 0;
		if (ownsStandaloneStore) {
			threadStore.start();
			const context = copilotkit.runtimeUrl ? {
				runtimeUrl: copilotkit.runtimeUrl,
				headers: { ...copilotkit.headers },
				wsUrl: copilotkit.intelligence?.wsUrl,
				agentId: resolvedAgentId
			} : null;
			threadStore.setContext(context);
		}
		const generation = runActivityReconnectGenerationRef.current + 1;
		runActivityReconnectGenerationRef.current = generation;
		let detached = false;
		let wakeReconnectActive = false;
		let pendingAgentIdleDrain = null;
		const hasActiveAgentRun = () => activeLocalRunIdsRef.current.size > 0 || agent.isRunning;
		const scheduleAgentIdleDrain = () => {
			if (pendingAgentIdleDrain !== null) return;
			pendingAgentIdleDrain = setTimeout(() => {
				pendingAgentIdleDrain = null;
				if (detached || runActivityReconnectGenerationRef.current !== generation || !pendingRunActivityReconnectRef.current) return;
				if (hasActiveAgentRun()) {
					scheduleAgentIdleDrain();
					return;
				}
				startRunActivityReconnectRef.current?.(generation);
			}, 10);
		};
		const connect = async () => {
			activeConnectCountRef.current += 1;
			wakeReconnectActive = true;
			const wakeRunId = pendingWakeRunIdRef.current;
			pendingWakeRunIdRef.current = void 0;
			if (wakeRunId) activeWakeRunIdsRef.current.add(wakeRunId);
			let didConnect = false;
			try {
				await copilotkit.connectAgent({ agent });
				didConnect = true;
			} catch (error) {
				if (!detached) console.error("CopilotChat: run activity reconnect failed", error);
			} finally {
				if (wakeRunId) {
					activeWakeRunIdsRef.current.delete(wakeRunId);
					if (didConnect) rememberRecentlyWakeRunId(wakeRunId);
				}
				activeConnectCountRef.current = Math.max(0, activeConnectCountRef.current - 1);
				wakeReconnectActive = false;
				if (!detached && runActivityReconnectGenerationRef.current === generation && activeConnectCountRef.current === 0 && pendingRunActivityReconnectRef.current) {
					pendingRunActivityReconnectRef.current = false;
					connect();
				}
			}
		};
		startRunActivityReconnectRef.current = (requestedGeneration) => {
			if (detached || requestedGeneration !== generation || runActivityReconnectGenerationRef.current !== generation) return;
			if (hasActiveAgentRun()) {
				pendingRunActivityReconnectRef.current = true;
				scheduleAgentIdleDrain();
				return;
			}
			if (activeConnectCountRef.current > 0) {
				if (!wakeReconnectActive) pendingRunActivityReconnectRef.current = true;
				return;
			}
			pendingRunActivityReconnectRef.current = false;
			connect();
		};
		const subscription = threadStore.subscribeToRunActivity((notification) => {
			if (notification.threadId !== resolvedThreadId) return;
			if (notification.agentId && notification.agentId !== resolvedAgentId) return;
			if (isLocalActiveRunActivity(notification)) return;
			if (notification.runId && (activeWakeRunIdsRef.current.has(notification.runId) || recentlyWakeRunIdsRef.current.has(notification.runId))) return;
			pendingWakeRunIdRef.current = notification.runId;
			startRunActivityReconnectRef.current?.(generation);
		});
		return () => {
			detached = true;
			pendingRunActivityReconnectRef.current = false;
			pendingWakeRunIdRef.current = void 0;
			if (pendingAgentIdleDrain !== null) {
				clearTimeout(pendingAgentIdleDrain);
				pendingAgentIdleDrain = null;
			}
			if (startRunActivityReconnectRef.current) startRunActivityReconnectRef.current = null;
			if (wakeReconnectActive) agent.detachActiveRun().catch(() => {});
			activeWakeRunIdsRef.current.clear();
			subscription.unsubscribe();
			if (ownsStandaloneStore) {
				threadStore.setContext(null);
				threadStore.stop();
			}
		};
	}, [
		agent,
		resolvedAgentId,
		resolvedThreadId,
		hasExplicitThreadId,
		hasNativeIntelligenceRunActivity,
		copilotkit.runtimeConnectionStatus,
		copilotkit.runtimeUrl,
		copilotkit.headers,
		copilotkit.intelligence?.wsUrl,
		copilotkit.threadEndpoints?.realtimeMetadata,
		standaloneRunActivityStore,
		isLocalActiveRunActivity,
		rememberRecentlyWakeRunId
	]);
	const waitForActiveRunToSettle = useCallback(async () => {
		const maybeAware = agent;
		const activeRunCompletionPromise = isRunCompletionAware(maybeAware) ? maybeAware.activeRunCompletionPromise : void 0;
		if (agent.isRunning && activeRunCompletionPromise) try {
			await activeRunCompletionPromise;
		} catch (error) {
			console.error("CopilotChat: in-flight run rejected while queuing send", error);
		}
	}, [agent]);
	const onSubmitInput = useCallback(async (value) => {
		if (selectedAttachmentsRef.current.some((a) => a.status === "uploading")) {
			console.error("[CopilotKit] Cannot send while attachments are uploading (pre-await guard)");
			setTranscriptionError("Cannot send while attachments are uploading.");
			return;
		}
		setInputValue("");
		await waitForActiveRunToSettle();
		if (selectedAttachmentsRef.current.some((a) => a.status === "uploading")) {
			console.error("[CopilotKit] Cannot send while attachments are uploading (post-await re-check)");
			setTranscriptionError("Cannot send while attachments are uploading.");
			setInputValue(value);
			return;
		}
		const readyAttachments = consumeAttachments();
		if (readyAttachments.length > 0) {
			const contentParts = [];
			if (value.trim()) contentParts.push({
				type: "text",
				text: value
			});
			for (const att of readyAttachments) contentParts.push({
				type: att.type,
				source: att.source,
				metadata: {
					...att.filename ? { filename: att.filename } : {},
					...att.metadata
				}
			});
			agent.addMessage({
				id: randomUUID$1(),
				role: "user",
				content: contentParts
			});
		} else agent.addMessage({
			id: randomUUID$1(),
			role: "user",
			content: value
		});
		const localRunId = hasNativeIntelligenceRunActivity ? randomUUID$1() : void 0;
		if (localRunId) activeLocalRunIdsRef.current.add(localRunId);
		try {
			await copilotkit.runAgent({
				agent,
				...localRunId !== void 0 ? { runId: localRunId } : {}
			});
		} catch (error) {
			console.error("CopilotChat: runAgent failed", error);
		} finally {
			if (localRunId) {
				activeLocalRunIdsRef.current.delete(localRunId);
				rememberRecentlyLocalRunId(localRunId);
			}
			if (pendingRunActivityReconnectRef.current && activeLocalRunIdsRef.current.size === 0 && activeConnectCountRef.current === 0) {
				const startReconnect = startRunActivityReconnectRef.current;
				if (startReconnect) {
					pendingRunActivityReconnectRef.current = false;
					startReconnect(runActivityReconnectGenerationRef.current);
				}
			}
		}
	}, [
		agent,
		consumeAttachments,
		waitForActiveRunToSettle,
		hasNativeIntelligenceRunActivity,
		rememberRecentlyLocalRunId
	]);
	const handleSelectSuggestion = useCallback(async (suggestion) => {
		await waitForActiveRunToSettle();
		agent.addMessage({
			id: randomUUID$1(),
			role: "user",
			content: suggestion.message
		});
		const localRunId = hasNativeIntelligenceRunActivity ? randomUUID$1() : void 0;
		if (localRunId) activeLocalRunIdsRef.current.add(localRunId);
		try {
			await copilotkit.runAgent({
				agent,
				...localRunId !== void 0 ? { runId: localRunId } : {}
			});
		} catch (error) {
			console.error("CopilotChat: runAgent failed after selecting suggestion", error);
		} finally {
			if (localRunId) {
				activeLocalRunIdsRef.current.delete(localRunId);
				rememberRecentlyLocalRunId(localRunId);
			}
			if (pendingRunActivityReconnectRef.current && activeLocalRunIdsRef.current.size === 0 && activeConnectCountRef.current === 0) {
				const startReconnect = startRunActivityReconnectRef.current;
				if (startReconnect) {
					pendingRunActivityReconnectRef.current = false;
					startReconnect(runActivityReconnectGenerationRef.current);
				}
			}
		}
	}, [
		agent,
		waitForActiveRunToSettle,
		hasNativeIntelligenceRunActivity,
		rememberRecentlyLocalRunId
	]);
	const stopCurrentRun = useCallback(() => {
		try {
			copilotkit.stopAgent({ agent });
		} catch (error) {
			console.error("CopilotChat: stopAgent failed", error);
			try {
				agent.abortRun();
			} catch (abortError) {
				console.error("CopilotChat: abortRun fallback failed", abortError);
			}
		}
	}, [agent]);
	const handleStartTranscribe = useCallback(() => {
		setTranscriptionError(null);
		setTranscribeMode("transcribe");
	}, []);
	const handleCancelTranscribe = useCallback(() => {
		setTranscriptionError(null);
		setTranscribeMode("input");
	}, []);
	const handleFinishTranscribe = useCallback(() => {
		setTranscribeMode("input");
	}, []);
	const handleFinishTranscribeWithAudio = useCallback(async (audioBlob) => {
		setIsTranscribing(true);
		try {
			setTranscriptionError(null);
			const result = await transcribeAudio(copilotkit, audioBlob);
			setInputValue((prev) => {
				const trimmedPrev = prev.trim();
				if (trimmedPrev) return `${trimmedPrev} ${result.text}`;
				return result.text;
			});
		} catch (error) {
			console.error("CopilotChat: Transcription failed", error);
			if (error instanceof TranscriptionError) {
				const { code, retryable, message } = error.info;
				switch (code) {
					case TranscriptionErrorCode.RATE_LIMITED:
						setTranscriptionError("Too many requests. Please wait a moment.");
						break;
					case TranscriptionErrorCode.AUTH_FAILED:
						setTranscriptionError("Authentication error. Please check your configuration.");
						break;
					case TranscriptionErrorCode.AUDIO_TOO_LONG:
						setTranscriptionError("Recording is too long. Please try a shorter recording.");
						break;
					case TranscriptionErrorCode.AUDIO_TOO_SHORT:
						setTranscriptionError("Recording is too short. Please try again.");
						break;
					case TranscriptionErrorCode.INVALID_AUDIO_FORMAT:
						setTranscriptionError("Audio format not supported.");
						break;
					case TranscriptionErrorCode.SERVICE_NOT_CONFIGURED:
						setTranscriptionError("Transcription service is not available.");
						break;
					case TranscriptionErrorCode.NETWORK_ERROR:
						setTranscriptionError("Network error. Please check your connection.");
						break;
					default: setTranscriptionError(retryable ? "Transcription failed. Please try again." : message);
				}
			} else setTranscriptionError("Transcription failed. Please try again.");
		} finally {
			setIsTranscribing(false);
		}
	}, []);
	useEffect(() => {
		if (transcriptionError) {
			const timer = setTimeout(() => {
				setTranscriptionError(null);
			}, 5e3);
			return () => clearTimeout(timer);
		}
	}, [transcriptionError]);
	const stableMessageView = useShallowStableRef(typeof providedMessageView === "string" ? { className: providedMessageView } : providedMessageView);
	const stableSuggestionView = useShallowStableRef(providedSuggestionView);
	const handleAddFile = useCallback(() => {
		setTimeout(() => {
			fileInputRef.current?.click();
		}, 100);
	}, []);
	const mergedProps = {
		isRunning: agent.isRunning,
		suggestions: isReady ? autoSuggestions : [],
		onSelectSuggestion: isReady ? handleSelectSuggestion : void 0,
		suggestionView: stableSuggestionView,
		...restProps
	};
	if (stableMessageView !== void 0) mergedProps.messageView = stableMessageView;
	const hasMessages = agent.messages.length > 0;
	const effectiveStopHandler = agent.isRunning && hasMessages ? providedStopHandler ?? stopCurrentRun : providedStopHandler;
	const showTranscription = isTranscriptionEnabled && isMediaRecorderSupported;
	const effectiveMode = isTranscribing ? "processing" : transcribeMode;
	const messages = useMemo(() => [...agent.messages], [agent.messages.map((m) => {
		const contentKey = typeof m.content === "string" ? m.content.length : Array.isArray(m.content) ? m.content.length : m.content && typeof m.content === "object" ? JSON.stringify(m.content) : 0;
		const toolCallsKey = "toolCalls" in m && Array.isArray(m.toolCalls) ? m.toolCalls.map((tc) => `${tc.id}:${tc.function?.arguments?.length ?? 0}`).join(";") : "";
		return `${m.id}:${m.role}:${contentKey}:${toolCallsKey}`;
	}).join(",")]);
	const lastUserMessageId = useMemo(() => {
		for (let i = messages.length - 1; i >= 0; i--) if (messages[i].role === "user") return messages[i].id;
		return null;
	}, [messages]);
	const [sendNonce, setSendNonce] = useState(0);
	const prevLastUserMessageIdRef = useRef(lastUserMessageId);
	useEffect(() => {
		if (lastUserMessageId && lastUserMessageId !== prevLastUserMessageIdRef.current) {
			setSendNonce((n) => n + 1);
			prevLastUserMessageIdRef.current = lastUserMessageId;
		}
	}, [lastUserMessageId]);
	const lastUserMessageState = useMemo(() => ({
		id: lastUserMessageId,
		sendNonce
	}), [lastUserMessageId, sendNonce]);
	const RenderedChatView = renderSlot(chatView, CopilotChatView, {
		...mergedProps,
		messages,
		onSubmitMessage: isReady ? onSubmitInput : void 0,
		onStop: effectiveStopHandler,
		inputMode: effectiveMode,
		inputValue,
		onInputChange: setInputValue,
		onStartTranscribe: showTranscription ? handleStartTranscribe : void 0,
		onCancelTranscribe: showTranscription ? handleCancelTranscribe : void 0,
		onFinishTranscribe: showTranscription ? handleFinishTranscribe : void 0,
		onFinishTranscribeWithAudio: showTranscription ? handleFinishTranscribeWithAudio : void 0,
		attachments: selectedAttachments,
		onRemoveAttachment: removeAttachment,
		onAddFile: attachmentsEnabled ? handleAddFile : void 0,
		dragOver,
		onDragOver: handleDragOver,
		onDragLeave: handleDragLeave,
		onDrop: handleDrop,
		isConnecting,
		hasExplicitThreadId
	});
	return /* @__PURE__ */ jsx(CopilotChatConfigurationProvider, {
		agentId: resolvedAgentId,
		threadId: resolvedThreadId,
		hasExplicitThreadId,
		labels,
		isModalDefaultOpen,
		children: /* @__PURE__ */ jsxs("div", {
			ref: chatContainerRef,
			style: { display: "contents" },
			children: [
				attachmentsEnabled && /* @__PURE__ */ jsx("input", {
					type: "file",
					multiple: true,
					ref: fileInputRef,
					onChange: handleFileUpload,
					accept: attachmentsConfig?.accept ?? "*/*",
					style: { display: "none" }
				}),
				!isChatLicensed && /* @__PURE__ */ jsx(InlineFeatureWarning, { featureName: "Chat" }),
				transcriptionError && /* @__PURE__ */ jsx("div", {
					style: {
						position: "absolute",
						bottom: "100px",
						left: "50%",
						transform: "translateX(-50%)",
						backgroundColor: "#ef4444",
						color: "white",
						padding: "8px 16px",
						borderRadius: "8px",
						fontSize: "14px",
						zIndex: 50
					},
					children: transcriptionError
				}),
				/* @__PURE__ */ jsx(LastUserMessageContext.Provider, {
					value: lastUserMessageState,
					children: RenderedChatView
				})
			]
		})
	});
}
(function(_CopilotChat) {
	_CopilotChat.View = CopilotChatView;
})(CopilotChat || (CopilotChat = {}));

//#endregion
//#region src/v2/components/chat/CopilotChatToggleButton.tsx
const DefaultOpenIcon = ({ className, ...props }) => /* @__PURE__ */ jsx(MessageCircle, {
	className: cn("cpk:h-6 cpk:w-6", className),
	strokeWidth: 1.75,
	fill: "currentColor",
	...props
});
const DefaultCloseIcon = ({ className, ...props }) => /* @__PURE__ */ jsx(X, {
	className: cn("cpk:h-6 cpk:w-6", className),
	strokeWidth: 1.75,
	...props
});
DefaultOpenIcon.displayName = "CopilotChatToggleButton.OpenIcon";
DefaultCloseIcon.displayName = "CopilotChatToggleButton.CloseIcon";
const ICON_TRANSITION_STYLE = Object.freeze({ transition: "opacity 120ms ease-out, transform 260ms cubic-bezier(0.22, 1, 0.36, 1)" });
const ICON_WRAPPER_BASE = "cpk:pointer-events-none cpk:absolute cpk:inset-0 cpk:flex cpk:items-center cpk:justify-center cpk:will-change-transform";
const BUTTON_BASE_CLASSES = cn("copilotKitButton", "cpk:fixed cpk:bottom-6 cpk:right-6 cpk:z-[1100] cpk:flex cpk:h-14 cpk:w-14 cpk:items-center cpk:justify-center", "cpk:rounded-full cpk:border cpk:border-primary cpk:bg-primary cpk:text-primary-foreground", "cpk:shadow-sm cpk:transition-all cpk:duration-200 cpk:ease-out", "cpk:hover:scale-[1.04] cpk:hover:shadow-md", "cpk:cursor-pointer", "cpk:active:scale-[0.96]", "cpk:focus-visible:outline-none cpk:focus-visible:ring-2 cpk:focus-visible:ring-primary/50 cpk:focus-visible:ring-offset-2 cpk:focus-visible:ring-offset-background", "cpk:disabled:pointer-events-none cpk:disabled:opacity-60");
const CopilotChatToggleButton = React.forwardRef(function CopilotChatToggleButton({ openIcon, closeIcon, className, ...buttonProps }, ref) {
	const { onClick, type, disabled, ...restProps } = buttonProps;
	const configuration = useCopilotChatConfiguration();
	const labels = configuration?.labels ?? CopilotChatDefaultLabels;
	const [fallbackOpen, setFallbackOpen] = useState(false);
	const isOpen = configuration?.isModalOpen ?? fallbackOpen;
	const setModalOpen = configuration?.setModalOpen ?? setFallbackOpen;
	const handleClick = (event) => {
		if (disabled) return;
		if (onClick) onClick(event);
		if (event.defaultPrevented) return;
		setModalOpen(!isOpen);
	};
	const renderedOpenIcon = renderSlot(openIcon, DefaultOpenIcon, {
		className: "cpk:h-6 cpk:w-6",
		"aria-hidden": true,
		focusable: false
	});
	const renderedCloseIcon = renderSlot(closeIcon, DefaultCloseIcon, {
		className: "cpk:h-6 cpk:w-6",
		"aria-hidden": true,
		focusable: false
	});
	const openIconElement = /* @__PURE__ */ jsx("span", {
		"aria-hidden": "true",
		"data-slot": "chat-toggle-button-open-icon",
		className: ICON_WRAPPER_BASE,
		style: {
			...ICON_TRANSITION_STYLE,
			opacity: isOpen ? 0 : 1,
			transform: `scale(${isOpen ? .75 : 1}) rotate(${isOpen ? 90 : 0}deg)`
		},
		children: renderedOpenIcon
	});
	const closeIconElement = /* @__PURE__ */ jsx("span", {
		"aria-hidden": "true",
		"data-slot": "chat-toggle-button-close-icon",
		className: ICON_WRAPPER_BASE,
		style: {
			...ICON_TRANSITION_STYLE,
			opacity: isOpen ? 1 : 0,
			transform: `scale(${isOpen ? 1 : .75}) rotate(${isOpen ? 0 : -90}deg)`
		},
		children: renderedCloseIcon
	});
	return /* @__PURE__ */ jsxs("button", {
		ref,
		type: type ?? "button",
		"data-copilotkit": true,
		"data-testid": "copilot-chat-toggle",
		"data-slot": "chat-toggle-button",
		"data-state": isOpen ? "open" : "closed",
		className: cn(BUTTON_BASE_CLASSES, className),
		"aria-label": isOpen ? labels.chatToggleCloseLabel : labels.chatToggleOpenLabel,
		"aria-pressed": isOpen,
		disabled,
		onClick: handleClick,
		...restProps,
		children: [openIconElement, closeIconElement]
	});
});
CopilotChatToggleButton.displayName = "CopilotChatToggleButton";

//#endregion
//#region src/v2/components/chat/CopilotModalHeader.tsx
/**
* Reactively tracks whether the viewport is in the mobile range (≤767px) — the
* same breakpoint the drawer + chat coordination use. SSR-safe: starts `false`
* (desktop) so the server render and first client render agree, then syncs on
* mount and on resize.
*/
function useIsMobileViewport() {
	const [isMobile, setIsMobile] = useState(false);
	useEffect(() => {
		if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
		const mql = window.matchMedia("(max-width: 767px)");
		const update = () => setIsMobile(mql.matches);
		update();
		mql.addEventListener("change", update);
		return () => mql.removeEventListener("change", update);
	}, []);
	return isMobile;
}
function CopilotModalHeader({ title, titleContent, closeButton, drawerLauncher, children, className, ...rest }) {
	const configuration = useCopilotChatConfiguration();
	const fallbackTitle = configuration?.labels.modalHeaderTitle ?? CopilotChatDefaultLabels.modalHeaderTitle;
	const resolvedTitle = title ?? fallbackTitle;
	const isMobile = useIsMobileViewport();
	const drawerRegistered = (configuration?.drawerRegistered ?? false) && isMobile;
	const handleClose = useCallback(() => {
		configuration?.setModalOpen?.(false);
	}, [configuration]);
	const handleToggleDrawer = useCallback(() => {
		configuration?.setDrawerOpen?.(!configuration.drawerOpen);
	}, [configuration]);
	const BoundTitle = renderSlot(titleContent, CopilotModalHeader.Title, { children: resolvedTitle });
	const BoundCloseButton = renderSlot(closeButton, CopilotModalHeader.CloseButton, { onClick: handleClose });
	const BoundDrawerLauncher = drawerRegistered ? renderSlot(drawerLauncher, CopilotModalHeader.DrawerLauncher, {
		onClick: handleToggleDrawer,
		"aria-expanded": configuration?.drawerOpen ?? false
	}) : null;
	if (children) return children({
		titleContent: BoundTitle,
		closeButton: BoundCloseButton,
		drawerLauncher: BoundDrawerLauncher,
		title: resolvedTitle,
		...rest
	});
	return /* @__PURE__ */ jsx("header", {
		"data-testid": "copilot-modal-header",
		"data-slot": "copilot-modal-header",
		className: cn("copilotKitHeader", "cpk:flex cpk:items-center cpk:justify-between cpk:border-b cpk:border-border cpk:px-4 cpk:py-4", "cpk:bg-background/95 cpk:backdrop-blur cpk:supports-[backdrop-filter]:bg-background/80", className),
		...rest,
		children: /* @__PURE__ */ jsxs("div", {
			className: "cpk:flex cpk:w-full cpk:items-center cpk:gap-2",
			children: [
				/* @__PURE__ */ jsx("div", {
					className: "cpk:flex cpk:flex-1 cpk:justify-start",
					children: BoundDrawerLauncher ?? /* @__PURE__ */ jsx("span", { "aria-hidden": "true" })
				}),
				/* @__PURE__ */ jsx("div", {
					className: "cpk:flex cpk:flex-1 cpk:justify-center cpk:text-center",
					children: BoundTitle
				}),
				/* @__PURE__ */ jsx("div", {
					className: "cpk:flex cpk:flex-1 cpk:justify-end",
					children: BoundCloseButton
				})
			]
		})
	});
}
CopilotModalHeader.displayName = "CopilotModalHeader";
(function(_CopilotModalHeader) {
	_CopilotModalHeader.Title = ({ children, className, ...props }) => /* @__PURE__ */ jsx("div", {
		"data-testid": "copilot-header-title",
		className: cn("cpk:w-full cpk:text-base cpk:font-medium cpk:leading-none cpk:tracking-tight cpk:text-foreground", className),
		...props,
		children
	});
	_CopilotModalHeader.CloseButton = ({ className, ...props }) => /* @__PURE__ */ jsx("button", {
		type: "button",
		"data-testid": "copilot-close-button",
		className: cn("cpk:inline-flex cpk:size-8 cpk:items-center cpk:justify-center cpk:rounded-full cpk:text-muted-foreground cpk:transition cpk:cursor-pointer", "cpk:hover:bg-muted cpk:hover:text-foreground cpk:focus-visible:outline-none cpk:focus-visible:ring-2 cpk:focus-visible:ring-ring", className),
		"aria-label": "Close",
		...props,
		children: /* @__PURE__ */ jsx(X, {
			className: "cpk:h-4 cpk:w-4",
			"aria-hidden": "true"
		})
	});
	_CopilotModalHeader.DrawerLauncher = ({ className, ...props }) => /* @__PURE__ */ jsx("button", {
		type: "button",
		"data-testid": "copilot-threads-drawer-launcher",
		className: cn("cpk:inline-flex cpk:size-8 cpk:items-center cpk:justify-center cpk:rounded-full cpk:text-muted-foreground cpk:transition cpk:cursor-pointer", "cpk:hover:bg-muted cpk:hover:text-foreground cpk:focus-visible:outline-none cpk:focus-visible:ring-2 cpk:focus-visible:ring-ring", className),
		"aria-label": "Open threads",
		...props,
		children: /* @__PURE__ */ jsx(PanelLeftOpen, {
			className: "cpk:h-4 cpk:w-4",
			"aria-hidden": "true"
		})
	});
})(CopilotModalHeader || (CopilotModalHeader = {}));
CopilotModalHeader.Title.displayName = "CopilotModalHeader.Title";
CopilotModalHeader.CloseButton.displayName = "CopilotModalHeader.CloseButton";
CopilotModalHeader.DrawerLauncher.displayName = "CopilotModalHeader.DrawerLauncher";

//#endregion
//#region src/v2/components/chat/CopilotSidebarView.tsx
const DEFAULT_SIDEBAR_WIDTH = 480;
const SIDEBAR_TRANSITION_MS = 260;
function CopilotSidebarView({ header, toggleButton, width, defaultOpen = true, position = "right", ...props }) {
	return /* @__PURE__ */ jsx(CopilotChatConfigurationProvider, {
		isModalDefaultOpen: defaultOpen,
		children: /* @__PURE__ */ jsx(CopilotSidebarViewInternal, {
			header,
			toggleButton,
			width,
			position,
			...props
		})
	});
}
function CopilotSidebarViewInternal({ header, toggleButton, width, position = "right", ...props }) {
	const isSidebarOpen = useCopilotChatConfiguration()?.isModalOpen ?? false;
	const sidebarRef = useRef(null);
	const [sidebarWidth, setSidebarWidth] = useState(width ?? DEFAULT_SIDEBAR_WIDTH);
	const widthToCss = (w) => {
		return typeof w === "number" ? `${w}px` : w;
	};
	const widthToMargin = (w) => {
		if (typeof w === "number") return `${w}px`;
		return w;
	};
	useEffect(() => {
		if (width !== void 0) return;
		if (typeof window === "undefined") return;
		const element = sidebarRef.current;
		if (!element) return;
		const updateWidth = () => {
			const rect = element.getBoundingClientRect();
			if (rect.width > 0) setSidebarWidth(rect.width);
		};
		updateWidth();
		if (typeof ResizeObserver !== "undefined") {
			const observer = new ResizeObserver(() => updateWidth());
			observer.observe(element);
			return () => observer.disconnect();
		}
		window.addEventListener("resize", updateWidth);
		return () => window.removeEventListener("resize", updateWidth);
	}, [width]);
	const hasMounted = useRef(false);
	useLayoutEffect(() => {
		if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
		if (!window.matchMedia("(min-width: 768px)").matches) return;
		const marginStyleProp = position === "left" ? "marginInlineStart" : "marginInlineEnd";
		const transitionCssProp = position === "left" ? "margin-inline-start" : "margin-inline-end";
		if (isSidebarOpen) {
			if (hasMounted.current) document.body.style.transition = `${transitionCssProp} ${SIDEBAR_TRANSITION_MS}ms ease`;
			document.body.style[marginStyleProp] = widthToMargin(sidebarWidth);
		} else if (hasMounted.current) {
			document.body.style.transition = `${transitionCssProp} ${SIDEBAR_TRANSITION_MS}ms ease`;
			document.body.style[marginStyleProp] = "";
		}
		hasMounted.current = true;
		return () => {
			document.body.style[marginStyleProp] = "";
			document.body.style.transition = "";
		};
	}, [
		isSidebarOpen,
		sidebarWidth,
		position
	]);
	const headerElement = renderSlot(header, CopilotModalHeader, {});
	return /* @__PURE__ */ jsxs(Fragment$1, { children: [renderSlot(toggleButton, CopilotChatToggleButton, position === "left" ? { className: "cpk:left-6 cpk:right-auto" } : {}), /* @__PURE__ */ jsx("aside", {
		ref: sidebarRef,
		"data-copilotkit": true,
		"data-testid": "copilot-sidebar",
		"data-copilot-sidebar": true,
		"data-position": position,
		className: cn("copilotKitSidebar copilotKitWindow", "cpk:fixed cpk:top-0 cpk:z-[1200] cpk:flex", position === "left" ? "cpk:left-0" : "cpk:right-0", "cpk:h-[100vh] cpk:h-[100dvh] cpk:max-h-screen", "cpk:w-full", position === "left" ? "cpk:border-r" : "cpk:border-l", "cpk:border-border cpk:bg-background cpk:text-foreground cpk:shadow-xl", "cpk:transition-transform cpk:duration-300 cpk:ease-out", isSidebarOpen ? "cpk:translate-x-0" : position === "left" ? "cpk:-translate-x-full cpk:pointer-events-none" : "cpk:translate-x-full cpk:pointer-events-none"),
		style: {
			["--sidebar-width"]: widthToCss(sidebarWidth),
			paddingTop: "env(safe-area-inset-top)",
			paddingBottom: "env(safe-area-inset-bottom)"
		},
		"aria-hidden": !isSidebarOpen,
		"aria-label": "Copilot chat sidebar",
		role: "complementary",
		children: /* @__PURE__ */ jsxs("div", {
			className: "cpk:flex cpk:h-full cpk:w-full cpk:flex-col cpk:overflow-hidden",
			children: [headerElement, /* @__PURE__ */ jsx("div", {
				className: "cpk:flex-1 cpk:overflow-hidden",
				"data-sidebar-chat": true,
				children: /* @__PURE__ */ jsx(CopilotChatView_default, { ...props })
			})]
		})
	})] });
}
CopilotSidebarView.displayName = "CopilotSidebarView";
(function(_CopilotSidebarView) {
	_CopilotSidebarView.WelcomeScreen = ({ welcomeMessage, input, suggestionView, className, children, ...props }) => {
		const BoundWelcomeMessage = renderSlot(welcomeMessage, CopilotChatView_default.WelcomeMessage, {});
		if (children) return /* @__PURE__ */ jsx("div", {
			"data-copilotkit": true,
			style: { display: "contents" },
			children: children({
				welcomeMessage: BoundWelcomeMessage,
				input,
				suggestionView,
				className,
				...props
			})
		});
		return /* @__PURE__ */ jsxs("div", {
			className: cn("cpk:h-full cpk:flex cpk:flex-col", className),
			...props,
			children: [/* @__PURE__ */ jsx("div", {
				className: "cpk:flex-1 cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:px-4",
				children: BoundWelcomeMessage
			}), /* @__PURE__ */ jsx("div", {
				className: "cpk:px-8 cpk:pb-4",
				children: /* @__PURE__ */ jsxs("div", {
					className: "cpk:max-w-3xl cpk:mx-auto",
					children: [/* @__PURE__ */ jsx("div", {
						className: "cpk:mb-4 cpk:flex cpk:justify-center",
						children: suggestionView
					}), input]
				})
			})]
		});
	};
})(CopilotSidebarView || (CopilotSidebarView = {}));

//#endregion
//#region src/v2/components/chat/CopilotPopupView.tsx
const DEFAULT_POPUP_WIDTH = 420;
const DEFAULT_POPUP_HEIGHT = 560;
const dimensionToCss = (value, fallback) => {
	if (typeof value === "number" && Number.isFinite(value)) return `${value}px`;
	if (typeof value === "string" && value.trim().length > 0) return value;
	return `${fallback}px`;
};
function CopilotPopupView({ header, toggleButton, width, height, clickOutsideToClose, defaultOpen = true, className, ...restProps }) {
	return /* @__PURE__ */ jsx(CopilotChatConfigurationProvider, {
		isModalDefaultOpen: defaultOpen,
		children: /* @__PURE__ */ jsx(CopilotPopupViewInternal, {
			header,
			toggleButton,
			width,
			height,
			clickOutsideToClose,
			className,
			...restProps
		})
	});
}
function CopilotPopupViewInternal({ header, toggleButton, width, height, clickOutsideToClose, className, ...restProps }) {
	const configuration = useCopilotChatConfiguration();
	const isPopupOpen = configuration?.isModalOpen ?? false;
	const setModalOpen = configuration?.setModalOpen;
	const labels = configuration?.labels ?? CopilotChatDefaultLabels;
	const containerRef = useRef(null);
	const [isRendered, setIsRendered] = useState(isPopupOpen);
	const [isAnimatingOut, setIsAnimatingOut] = useState(false);
	useEffect(() => {
		if (isPopupOpen) {
			setIsRendered(true);
			setIsAnimatingOut(false);
			return;
		}
		if (!isRendered) return;
		setIsAnimatingOut(true);
		const timeout = setTimeout(() => {
			setIsRendered(false);
			setIsAnimatingOut(false);
		}, 200);
		return () => clearTimeout(timeout);
	}, [isPopupOpen, isRendered]);
	useEffect(() => {
		if (!isPopupOpen) return;
		if (typeof window === "undefined") return;
		const handleKeyDown = (event) => {
			if (event.key === "Escape") {
				event.preventDefault();
				setModalOpen?.(false);
			}
		};
		window.addEventListener("keydown", handleKeyDown);
		return () => window.removeEventListener("keydown", handleKeyDown);
	}, [isPopupOpen, setModalOpen]);
	useEffect(() => {
		if (!isPopupOpen) return;
		const focusTimer = setTimeout(() => {
			const container = containerRef.current;
			if (container && !container.contains(document.activeElement)) container.focus({ preventScroll: true });
		}, 200);
		return () => clearTimeout(focusTimer);
	}, [isPopupOpen]);
	useEffect(() => {
		if (!isPopupOpen || !clickOutsideToClose) return;
		if (typeof document === "undefined") return;
		const handlePointerDown = (event) => {
			const target = event.target;
			if (!target) return;
			if (containerRef.current?.contains(target)) return;
			const toggleButton = document.querySelector("[data-slot='chat-toggle-button']");
			if (toggleButton && toggleButton.contains(target)) return;
			setModalOpen?.(false);
		};
		document.addEventListener("pointerdown", handlePointerDown);
		return () => document.removeEventListener("pointerdown", handlePointerDown);
	}, [
		isPopupOpen,
		clickOutsideToClose,
		setModalOpen
	]);
	const headerElement = useMemo(() => renderSlot(header, CopilotModalHeader, {}), [header]);
	const toggleButtonElement = useMemo(() => renderSlot(toggleButton, CopilotChatToggleButton, {}), [toggleButton]);
	const resolvedWidth = dimensionToCss(width, DEFAULT_POPUP_WIDTH);
	const resolvedHeight = dimensionToCss(height, DEFAULT_POPUP_HEIGHT);
	const popupStyle = useMemo(() => ({
		"--copilot-popup-width": resolvedWidth,
		"--copilot-popup-height": resolvedHeight,
		"--copilot-popup-max-width": "calc(100vw - 3rem)",
		"--copilot-popup-max-height": "calc(100dvh - 7.5rem)",
		paddingTop: "env(safe-area-inset-top)",
		paddingBottom: "env(safe-area-inset-bottom)",
		paddingLeft: "env(safe-area-inset-left)",
		paddingRight: "env(safe-area-inset-right)"
	}), [resolvedHeight, resolvedWidth]);
	const popupAnimationClass = isPopupOpen && !isAnimatingOut ? "cpk:pointer-events-auto cpk:translate-y-0 cpk:opacity-100 cpk:md:scale-100" : "cpk:pointer-events-none cpk:translate-y-4 cpk:opacity-0 cpk:md:translate-y-5 cpk:md:scale-[0.95]";
	return /* @__PURE__ */ jsxs(Fragment$1, { children: [toggleButtonElement, isRendered ? /* @__PURE__ */ jsx("div", {
		"data-copilotkit": true,
		className: cn("cpk:fixed cpk:inset-0 cpk:z-[1200] cpk:flex cpk:max-w-full cpk:flex-col cpk:items-stretch", "cpk:md:inset-auto cpk:md:bottom-24 cpk:md:right-6 cpk:md:items-end cpk:md:gap-4"),
		children: /* @__PURE__ */ jsxs("div", {
			ref: containerRef,
			tabIndex: -1,
			role: "dialog",
			"aria-label": labels.modalHeaderTitle,
			"data-testid": "copilot-popup",
			"data-copilot-popup": true,
			className: cn("copilotKitPopup copilotKitWindow", "cpk:relative cpk:flex cpk:h-full cpk:w-full cpk:flex-col cpk:overflow-hidden cpk:bg-background cpk:text-foreground", "cpk:origin-bottom cpk:focus:outline-none cpk:transform-gpu cpk:transition-transform cpk:transition-opacity cpk:duration-200 cpk:ease-out", "cpk:md:transition-transform cpk:md:transition-opacity", "cpk:rounded-none cpk:border cpk:border-border/0 cpk:shadow-none cpk:ring-0", "cpk:md:h-[var(--copilot-popup-height)] cpk:md:w-[var(--copilot-popup-width)]", "cpk:md:max-h-[var(--copilot-popup-max-height)] cpk:md:max-w-[var(--copilot-popup-max-width)]", "cpk:md:origin-bottom-right cpk:md:rounded-2xl cpk:md:border-border cpk:md:shadow-xl cpk:md:ring-1 cpk:md:ring-border/40", popupAnimationClass),
			style: popupStyle,
			children: [headerElement, /* @__PURE__ */ jsx("div", {
				className: "cpk:flex-1 cpk:overflow-hidden",
				"data-popup-chat": true,
				children: /* @__PURE__ */ jsx(CopilotChatView_default, {
					...restProps,
					className: cn("cpk:h-full cpk:min-h-0", className)
				})
			})]
		})
	}) : null] });
}
CopilotPopupView.displayName = "CopilotPopupView";
(function(_CopilotPopupView) {
	_CopilotPopupView.WelcomeScreen = ({ welcomeMessage, input, suggestionView, className, children, ...props }) => {
		const BoundWelcomeMessage = renderSlot(welcomeMessage, CopilotChatView_default.WelcomeMessage, {});
		if (children) return /* @__PURE__ */ jsx("div", {
			"data-copilotkit": true,
			style: { display: "contents" },
			children: children({
				welcomeMessage: BoundWelcomeMessage,
				input,
				suggestionView,
				className,
				...props
			})
		});
		return /* @__PURE__ */ jsxs("div", {
			className: cn("cpk:h-full cpk:flex cpk:flex-col", className),
			...props,
			children: [/* @__PURE__ */ jsx("div", {
				className: "cpk:flex-1 cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:px-4",
				children: BoundWelcomeMessage
			}), /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
				className: "cpk:mb-4 cpk:flex cpk:justify-center cpk:px-4",
				children: suggestionView
			}), input] })]
		});
	};
})(CopilotPopupView || (CopilotPopupView = {}));
var CopilotPopupView_default = CopilotPopupView;

//#endregion
//#region src/v2/components/chat/CopilotSidebar.tsx
function CopilotSidebar({ header, toggleButton, defaultOpen, width, position, ...chatProps }) {
	const { checkFeature } = useLicenseContext$1();
	const isSidebarLicensed = checkFeature("sidebar");
	useEffect(() => {
		if (!isSidebarLicensed) console.warn("[CopilotKit] Warning: \"sidebar\" feature is not licensed. Visit copilotkit.ai/pricing");
	}, [isSidebarLicensed]);
	const SidebarViewOverride = useMemo(() => {
		const Component = (viewProps) => {
			const { header: viewHeader, toggleButton: viewToggleButton, width: viewWidth, defaultOpen: viewDefaultOpen, position: viewPosition, ...restProps } = viewProps;
			return /* @__PURE__ */ jsx(CopilotSidebarView, {
				...restProps,
				header: header ?? viewHeader,
				toggleButton: toggleButton ?? viewToggleButton,
				width: width ?? viewWidth,
				defaultOpen: defaultOpen ?? viewDefaultOpen,
				position: position ?? viewPosition
			});
		};
		return Object.assign(Component, CopilotChatView_default);
	}, [
		header,
		toggleButton,
		width,
		defaultOpen,
		position
	]);
	return /* @__PURE__ */ jsxs(Fragment$1, { children: [!isSidebarLicensed && /* @__PURE__ */ jsx(InlineFeatureWarning, { featureName: "Sidebar" }), /* @__PURE__ */ jsx(CopilotChat, {
		welcomeScreen: CopilotSidebarView.WelcomeScreen,
		...chatProps,
		isModalDefaultOpen: defaultOpen,
		chatView: SidebarViewOverride
	})] });
}
CopilotSidebar.displayName = "CopilotSidebar";

//#endregion
//#region src/v2/components/chat/CopilotPopup.tsx
const PopupShellPropsContext = React.createContext({});
const PopupViewOverride = (viewProps) => {
	const { header: viewHeader, toggleButton: viewToggleButton, width: viewWidth, height: viewHeight, clickOutsideToClose: viewClickOutsideToClose, defaultOpen: viewDefaultOpen, ...restProps } = viewProps;
	const shell = useContext(PopupShellPropsContext);
	return /* @__PURE__ */ jsx(CopilotPopupView_default, {
		...restProps,
		header: shell.header ?? viewHeader,
		toggleButton: shell.toggleButton ?? viewToggleButton,
		width: shell.width ?? viewWidth,
		height: shell.height ?? viewHeight,
		clickOutsideToClose: shell.clickOutsideToClose ?? viewClickOutsideToClose,
		defaultOpen: shell.defaultOpen ?? viewDefaultOpen
	});
};
const PopupViewOverrideWithStatics = Object.assign(PopupViewOverride, CopilotChatView_default);
function CopilotPopup({ header, toggleButton, defaultOpen, width, height, clickOutsideToClose, ...chatProps }) {
	const { checkFeature } = useLicenseContext$1();
	const isPopupLicensed = checkFeature("popup");
	useEffect(() => {
		if (!isPopupLicensed) console.warn("[CopilotKit] Warning: \"popup\" feature is not licensed. Visit copilotkit.ai/pricing");
	}, [isPopupLicensed]);
	const shellProps = useMemo(() => ({
		header,
		toggleButton,
		width,
		height,
		clickOutsideToClose,
		defaultOpen
	}), [
		clickOutsideToClose,
		header,
		toggleButton,
		height,
		width,
		defaultOpen
	]);
	return /* @__PURE__ */ jsxs(Fragment$1, { children: [!isPopupLicensed && /* @__PURE__ */ jsx(InlineFeatureWarning, { featureName: "Popup" }), /* @__PURE__ */ jsx(PopupShellPropsContext.Provider, {
		value: shellProps,
		children: /* @__PURE__ */ jsx(CopilotChat, {
			welcomeScreen: CopilotPopupView_default.WelcomeScreen,
			...chatProps,
			isModalDefaultOpen: defaultOpen,
			chatView: PopupViewOverrideWithStatics
		})
	})] });
}
CopilotPopup.displayName = "CopilotPopup";

//#endregion
//#region src/v2/components/chat/CopilotThreadsDrawer.tsx
/**
* Maps a {@link Thread} from {@link useThreads} to the element's
* {@link DrawerThread} view shape. The shapes are structurally compatible; this
* narrows to exactly the fields the element renders so the element never sees
* platform-internal fields.
*/
function toDrawerThread(thread) {
	return {
		id: thread.id,
		name: thread.name,
		archived: thread.archived,
		createdAt: thread.createdAt,
		updatedAt: thread.updatedAt,
		...thread.lastRunAt !== void 0 ? { lastRunAt: thread.lastRunAt } : {}
	};
}
/** The chat input textarea's documented `data-testid`. */
const CHAT_INPUT_TESTID = "copilot-chat-textarea";
/** The chat view container's documented `data-testid`. */
const CHAT_CONTAINER_TESTID = "copilot-chat";
/**
* Returns the chat input element for focus-return after a thread is selected.
*
* Best-effort and SCOPED: walks up from the drawer element looking for an
* ancestor that contains a chat-view container (`data-testid="copilot-chat"`),
* then returns the chat input within that subtree. This avoids focusing the
* wrong composer on a page hosting more than one chat (multi-chat dashboards),
* where a document-global lookup would grab whichever input appears first in
* DOM order rather than the one this drawer drives.
*
* Falls back to a document-global lookup when no scoping ancestor is found
* (e.g. the drawer and chat share no common container, or headless usage),
* and returns `null` when there is no chat input at all.
*
* @param origin - The drawer element to scope the search from.
*/
function findChatInput(origin) {
	if (typeof document === "undefined") return null;
	const container = origin?.closest?.(`[data-testid="${CHAT_CONTAINER_TESTID}"]`);
	if (container) {
		const scoped = container.querySelector(`[data-testid="${CHAT_INPUT_TESTID}"]`);
		if (scoped) return scoped;
	}
	return document.querySelector(`[data-testid="${CHAT_INPUT_TESTID}"]`);
}
/**
* React wrapper for the shadow-DOM `<copilotkit-threads-drawer>` threads drawer.
*
* Responsibilities:
* - Registers the custom element on the client (SSR-safe; nothing renders
*   during prerender to avoid hydration mismatch).
* - Feeds the element domain data: `threads`, `loading`, `error`,
*   `activeThreadId`, `licensed`, fetch-more state.
* - Routes the element's outbound events to core thread operations
*   ({@link useThreads}) and chat-configuration changes.
* - Registers with the surrounding chat configuration so the header
*   thread-list launcher appears, and binds the element `open` state to the
*   configuration's `drawerOpen`.
*
* License gating is two-pronged: the locked view shows when no license is configured
* (the runtime reported no license status) OR the `threads` feature is
* explicitly unlicensed. While unlicensed, the thread fetch is skipped entirely
* so an unlicensed drawer issues no network requests.
*
* Thread switching needs no host wiring: when `onThreadSelect`/`onNewThread`
* are omitted, the wrapper drives the surrounding chat configuration directly
* ({@link CopilotChatConfigurationValue.setActiveThreadId} /
* {@link CopilotChatConfigurationValue.startNewThread}), so a bare drawer
* connects to the picked thread and shows the welcome screen on "+ New". Pass
* the callbacks only to take control yourself.
*
* @example
* ```tsx
* // Callback-free: the drawer drives the chat configuration itself.
* <CopilotKitProvider runtimeUrl="/api/copilotkit" publicLicenseKey="ck_pub_...">
*   <CopilotChat />
*   <CopilotThreadsDrawer />
* </CopilotKitProvider>
* ```
*/
function CopilotThreadsDrawer({ agentId, onThreadSelect, onNewThread, onLicensed, licenseUrl, renderRow, label, recentLabel, collapsible, onCollapseChange, limit, "data-testid": dataTestId = "copilot-threads-drawer" }) {
	const configuration = useCopilotChatConfiguration();
	const { status, checkFeature } = useLicenseContext$1();
	const licensePresent = status === "valid" || status === "expiring";
	const featureLicensed = checkFeature("threads");
	const licensed = licensePresent && featureLicensed;
	const licensePending = status === null;
	const resolvedAgentId = agentId ?? configuration?.agentId ?? DEFAULT_AGENT_ID;
	const activeThreadId = configuration?.threadId ?? null;
	const { threads, isLoading, listError, fetchMoreError, hasMoreThreads, isFetchingMoreThreads, archiveThread, unarchiveThread, deleteThread, fetchMoreThreads, refetchThreads, startNewThread } = useThreads$1({
		agentId: resolvedAgentId,
		includeArchived: true,
		enabled: licensed,
		...limit !== void 0 ? { limit } : {}
	});
	const drawerThreads = useMemo(() => threads.map(toDrawerThread), [threads]);
	const elementRef = useRef(null);
	const [mounted, setMounted] = useState(false);
	useEffect(() => {
		defineCopilotKitThreadsDrawer();
		setMounted(true);
	}, []);
	const registerDrawer = configuration?.registerDrawer;
	useEffect(() => {
		if (!registerDrawer) return;
		return registerDrawer();
	}, [registerDrawer]);
	const [localDrawerOpen, setLocalDrawerOpen] = useState(false);
	const drawerOpen = configuration ? configuration.drawerOpen : localDrawerOpen;
	const setDrawerOpen = configuration ? configuration.setDrawerOpen : setLocalDrawerOpen;
	const setActiveThreadId = configuration?.setActiveThreadId;
	const startNewThreadConfig = configuration?.startNewThread;
	const handleThreadSelected = useCallback((threadId) => {
		if (onThreadSelect) onThreadSelect(threadId);
		else setActiveThreadId?.(threadId, { explicit: true });
		findChatInput(elementRef.current)?.focus();
	}, [onThreadSelect, setActiveThreadId]);
	const handleNewThread = useCallback(() => {
		startNewThread();
		if (onNewThread) onNewThread();
		else startNewThreadConfig?.();
	}, [
		startNewThread,
		onNewThread,
		startNewThreadConfig
	]);
	const handleArchive = useCallback((threadId) => {
		archiveThread(threadId).catch((err) => {
			console.error("CopilotThreadsDrawer: archiveThread failed", err);
		});
	}, [archiveThread]);
	const handleUnarchive = useCallback((threadId) => {
		unarchiveThread(threadId).catch((err) => {
			console.error("CopilotThreadsDrawer: unarchiveThread failed", err);
		});
	}, [unarchiveThread]);
	const handleDelete = useCallback((threadId) => {
		const isActive = threadId === activeThreadId;
		deleteThread(threadId).then(() => {
			if (isActive) {
				startNewThread();
				if (onNewThread) onNewThread();
				else startNewThreadConfig?.();
			}
		}).catch((err) => {
			console.error("CopilotThreadsDrawer: deleteThread failed", err);
		});
	}, [
		deleteThread,
		activeThreadId,
		startNewThread,
		onNewThread,
		startNewThreadConfig
	]);
	const handleFilterChange = useCallback(() => {
		refetchThreads();
	}, [refetchThreads]);
	const handleRetry = useCallback((scope) => {
		if (scope === "fetch-more") fetchMoreThreads();
		else refetchThreads();
	}, [fetchMoreThreads, refetchThreads]);
	const handleOpenChange = useCallback((open) => {
		setDrawerOpen(open);
	}, [setDrawerOpen]);
	const handleLicensed = useCallback(() => {
		onLicensed?.();
	}, [onLicensed]);
	const handleLoadMore = useCallback(() => {
		fetchMoreThreads();
	}, [fetchMoreThreads]);
	const handleCollapseChange = useCallback((collapsed) => {
		onCollapseChange?.(collapsed);
	}, [onCollapseChange]);
	const handlersRef = useRef({
		handleThreadSelected,
		handleNewThread,
		handleArchive,
		handleUnarchive,
		handleDelete,
		handleFilterChange,
		handleRetry,
		handleOpenChange,
		handleLicensed,
		handleLoadMore,
		handleCollapseChange
	});
	handlersRef.current = {
		handleThreadSelected,
		handleNewThread,
		handleArchive,
		handleUnarchive,
		handleDelete,
		handleFilterChange,
		handleRetry,
		handleOpenChange,
		handleLicensed,
		handleLoadMore,
		handleCollapseChange
	};
	useEffect(() => {
		const el = elementRef.current;
		if (!el) return;
		const onThreadSelected = (event) => {
			const detail = event.detail;
			handlersRef.current.handleThreadSelected(detail.threadId);
		};
		const onNewThreadEvent = () => handlersRef.current.handleNewThread();
		const onArchive = (event) => {
			const detail = event.detail;
			handlersRef.current.handleArchive(detail.threadId);
		};
		const onUnarchive = (event) => {
			const detail = event.detail;
			handlersRef.current.handleUnarchive(detail.threadId);
		};
		const onDelete = (event) => {
			const detail = event.detail;
			handlersRef.current.handleDelete(detail.threadId);
		};
		const onFilterChange = (_event) => {
			handlersRef.current.handleFilterChange();
		};
		const onOpenChangeEvent = (event) => {
			const detail = event.detail;
			handlersRef.current.handleOpenChange(detail.open);
		};
		const onRetry = (event) => {
			const detail = event.detail;
			handlersRef.current.handleRetry(detail.scope);
		};
		const onLicensedEvent = () => handlersRef.current.handleLicensed();
		const onLoadMore = () => handlersRef.current.handleLoadMore();
		const onCollapseChangeEvent = (event) => {
			const detail = event.detail;
			handlersRef.current.handleCollapseChange(detail.collapsed);
		};
		el.addEventListener("thread-selected", onThreadSelected);
		el.addEventListener("new-thread", onNewThreadEvent);
		el.addEventListener("archive", onArchive);
		el.addEventListener("unarchive", onUnarchive);
		el.addEventListener("delete", onDelete);
		el.addEventListener("filter-change", onFilterChange);
		el.addEventListener("open-change", onOpenChangeEvent);
		el.addEventListener("retry", onRetry);
		el.addEventListener("licensed", onLicensedEvent);
		el.addEventListener("load-more", onLoadMore);
		el.addEventListener("collapse-change", onCollapseChangeEvent);
		return () => {
			el.removeEventListener("thread-selected", onThreadSelected);
			el.removeEventListener("new-thread", onNewThreadEvent);
			el.removeEventListener("archive", onArchive);
			el.removeEventListener("unarchive", onUnarchive);
			el.removeEventListener("delete", onDelete);
			el.removeEventListener("filter-change", onFilterChange);
			el.removeEventListener("open-change", onOpenChangeEvent);
			el.removeEventListener("retry", onRetry);
			el.removeEventListener("licensed", onLicensedEvent);
			el.removeEventListener("load-more", onLoadMore);
			el.removeEventListener("collapse-change", onCollapseChangeEvent);
		};
	}, [mounted]);
	useEffect(() => {
		const el = elementRef.current;
		if (!el) return;
		el.threads = drawerThreads;
	}, [drawerThreads, mounted]);
	useEffect(() => {
		const el = elementRef.current;
		if (!el) return;
		el.loading = isLoading || licensePending;
		el.error = listError ? listError.message : null;
		el.activeThreadId = activeThreadId;
		el.licensed = licensed || licensePending;
		el.hasMore = hasMoreThreads;
		el.fetchingMore = isFetchingMoreThreads;
		el.fetchMoreError = fetchMoreError ? fetchMoreError.message : null;
	}, [
		isLoading,
		listError,
		fetchMoreError,
		activeThreadId,
		licensed,
		licensePending,
		hasMoreThreads,
		isFetchingMoreThreads,
		mounted
	]);
	useEffect(() => {
		const el = elementRef.current;
		if (!el) return;
		el.open = drawerOpen;
	}, [drawerOpen, mounted]);
	useEffect(() => {
		const el = elementRef.current;
		if (!el) return;
		if (label !== void 0) el.label = label;
	}, [label, mounted]);
	useEffect(() => {
		const el = elementRef.current;
		if (!el) return;
		if (licenseUrl !== void 0) el.licenseUrl = licenseUrl;
	}, [licenseUrl, mounted]);
	useEffect(() => {
		const el = elementRef.current;
		if (!el) return;
		if (collapsible !== void 0) el.collapsible = collapsible;
	}, [collapsible, mounted]);
	const rowChildren = useMemo(() => {
		if (!renderRow) return null;
		return drawerThreads.map((drawerThread) => {
			const fullThread = threads.find((t) => t.id === drawerThread.id);
			if (!fullThread) return null;
			const content = renderRow(fullThread);
			if (content === null || content === void 0) return null;
			return /* @__PURE__ */ jsx("div", {
				slot: `row:${drawerThread.id}`,
				children: content
			}, drawerThread.id);
		});
	}, [
		renderRow,
		drawerThreads,
		threads
	]);
	if (!mounted) return null;
	return React.createElement(COPILOTKIT_THREADS_DRAWER_TAG, {
		ref: elementRef,
		"data-testid": dataTestId,
		...recentLabel !== void 0 ? { "recent-label": recentLabel } : {}
	}, rowChildren);
}
CopilotThreadsDrawer.displayName = "CopilotThreadsDrawer";

//#endregion
//#region src/v2/components/WildcardToolCallRender.tsx
const WildcardToolCallRender = defineToolCallRenderer({
	name: "*",
	render: ({ args, result, name, status }) => {
		const [isExpanded, setIsExpanded] = useState(false);
		const statusString = String(status);
		return /* @__PURE__ */ jsx("div", {
			className: "cpk:mt-2 cpk:pb-2",
			children: /* @__PURE__ */ jsxs("div", {
				className: "cpk:rounded-xl cpk:border cpk:border-zinc-200/60 cpk:dark:border-zinc-800/60 cpk:bg-white/70 cpk:dark:bg-zinc-900/50 cpk:shadow-sm cpk:backdrop-blur cpk:p-4",
				children: [/* @__PURE__ */ jsxs("div", {
					className: "cpk:flex cpk:items-center cpk:justify-between cpk:gap-3 cpk:cursor-pointer",
					onClick: () => setIsExpanded(!isExpanded),
					children: [/* @__PURE__ */ jsxs("div", {
						className: "cpk:flex cpk:items-center cpk:gap-2 cpk:min-w-0",
						children: [
							/* @__PURE__ */ jsx("svg", {
								className: `cpk:h-4 cpk:w-4 cpk:text-zinc-500 cpk:dark:text-zinc-400 cpk:transition-transform ${isExpanded ? "cpk:rotate-90" : ""}`,
								fill: "none",
								viewBox: "0 0 24 24",
								strokeWidth: 2,
								stroke: "currentColor",
								children: /* @__PURE__ */ jsx("path", {
									strokeLinecap: "round",
									strokeLinejoin: "round",
									d: "M8.25 4.5l7.5 7.5-7.5 7.5"
								})
							}),
							/* @__PURE__ */ jsx("span", { className: "cpk:inline-block cpk:h-2 cpk:w-2 cpk:rounded-full cpk:bg-blue-500" }),
							/* @__PURE__ */ jsx("span", {
								className: "cpk:truncate cpk:text-sm cpk:font-medium cpk:text-zinc-900 cpk:dark:text-zinc-100",
								children: name
							})
						]
					}), /* @__PURE__ */ jsx("span", {
						className: `cpk:inline-flex cpk:items-center cpk:rounded-full cpk:px-2 cpk:py-1 cpk:text-xs cpk:font-medium ${statusString === "inProgress" || statusString === "executing" ? "cpk:bg-amber-100 cpk:text-amber-800 cpk:dark:bg-amber-500/15 cpk:dark:text-amber-400" : statusString === "complete" ? "cpk:bg-emerald-100 cpk:text-emerald-800 cpk:dark:bg-emerald-500/15 cpk:dark:text-emerald-400" : "cpk:bg-zinc-100 cpk:text-zinc-800 cpk:dark:bg-zinc-700/40 cpk:dark:text-zinc-300"}`,
						children: String(status)
					})]
				}), isExpanded && /* @__PURE__ */ jsxs("div", {
					className: "cpk:mt-3 cpk:grid cpk:gap-4",
					children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
						className: "cpk:text-xs cpk:uppercase cpk:tracking-wide cpk:text-zinc-500 cpk:dark:text-zinc-400",
						children: "Arguments"
					}), /* @__PURE__ */ jsx("pre", {
						className: "cpk:mt-2 cpk:max-h-64 cpk:overflow-auto cpk:rounded-md cpk:bg-zinc-50 cpk:dark:bg-zinc-800/60 cpk:p-3 cpk:text-xs cpk:leading-relaxed cpk:text-zinc-800 cpk:dark:text-zinc-200 cpk:whitespace-pre-wrap cpk:break-words",
						children: JSON.stringify(args ?? {}, null, 2)
					})] }), result !== void 0 && /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
						className: "cpk:text-xs cpk:uppercase cpk:tracking-wide cpk:text-zinc-500 cpk:dark:text-zinc-400",
						children: "Result"
					}), /* @__PURE__ */ jsx("pre", {
						className: "cpk:mt-2 cpk:max-h-64 cpk:overflow-auto cpk:rounded-md cpk:bg-zinc-50 cpk:dark:bg-zinc-800/60 cpk:p-3 cpk:text-xs cpk:leading-relaxed cpk:text-zinc-800 cpk:dark:text-zinc-200 cpk:whitespace-pre-wrap cpk:break-words",
						children: typeof result === "string" ? result : JSON.stringify(result, null, 2)
					})] })]
				})]
			})
		});
	}
});

//#endregion
//#region src/context/copilot-context.tsx
const emptyCopilotContext$1 = {
	actions: {},
	setAction: () => {},
	removeAction: () => {},
	setRegisteredActions: () => "",
	removeRegisteredAction: () => {},
	chatComponentsCache: { current: {
		actions: {},
		coAgentStateRenders: {}
	} },
	getContextString: (documents, categories) => returnAndThrowInDebug(""),
	addContext: () => "",
	removeContext: () => {},
	getAllContext: () => [],
	getFunctionCallHandler: () => returnAndThrowInDebug(async () => {}),
	isLoading: false,
	setIsLoading: () => returnAndThrowInDebug(false),
	chatInstructions: "",
	setChatInstructions: () => returnAndThrowInDebug(""),
	additionalInstructions: [],
	setAdditionalInstructions: () => returnAndThrowInDebug([]),
	getDocumentsContext: (categories) => returnAndThrowInDebug([]),
	addDocumentContext: () => returnAndThrowInDebug(""),
	removeDocumentContext: () => {},
	copilotApiConfig: new class {
		get chatApiEndpoint() {
			throw new Error("Remember to wrap your app in a `<CopilotKit> {...} </CopilotKit>` !!!");
		}
		get headers() {
			return {};
		}
		get body() {
			return {};
		}
	}(),
	chatSuggestionConfiguration: {},
	addChatSuggestionConfiguration: () => {},
	removeChatSuggestionConfiguration: () => {},
	showDevConsole: false,
	coagentStates: {},
	setCoagentStates: () => {},
	coagentStatesRef: { current: {} },
	setCoagentStatesWithRef: () => {},
	agentSession: null,
	setAgentSession: () => {},
	forwardedParameters: {},
	agentLock: null,
	threadId: "",
	setThreadId: () => {},
	runId: null,
	setRunId: () => {},
	chatAbortControllerRef: { current: null },
	availableAgents: [],
	extensions: {},
	setExtensions: () => {},
	interruptActions: {},
	setInterruptAction: () => {},
	removeInterruptAction: () => {},
	interruptEventQueue: {},
	addInterruptEvent: () => {},
	resolveInterruptEvent: () => {},
	onError: () => {},
	bannerError: null,
	setBannerError: () => {},
	internalErrorHandlers: {},
	setInternalErrorHandler: () => {},
	removeInternalErrorHandler: () => {}
};
const CopilotContext = React.createContext(emptyCopilotContext$1);
function useCopilotContext() {
	const context = React.useContext(CopilotContext);
	if (context === emptyCopilotContext$1) throw new Error("Remember to wrap your app in a `<CopilotKit> {...} </CopilotKit>` !!!");
	return context;
}
function returnAndThrowInDebug(_value) {
	throw new Error("Remember to wrap your app in a `<CopilotKit> {...} </CopilotKit>` !!!");
}

//#endregion
//#region src/hooks/use-tree.ts
const removeNode = (nodes, id) => {
	return nodes.reduce((result, node) => {
		if (node.id !== id) {
			const newNode = {
				...node,
				children: removeNode(node.children, id)
			};
			result.push(newNode);
		}
		return result;
	}, []);
};
const addNode = (nodes, newNode, parentId) => {
	if (!parentId) return [...nodes, newNode];
	return nodes.map((node) => {
		if (node.id === parentId) return {
			...node,
			children: [...node.children, newNode]
		};
		else if (node.children.length) return {
			...node,
			children: addNode(node.children, newNode, parentId)
		};
		return node;
	});
};
const treeIndentationRepresentation = (index, indentLevel) => {
	if (indentLevel === 0) return (index + 1).toString();
	else if (indentLevel === 1) return String.fromCharCode(65 + index);
	else if (indentLevel === 2) return String.fromCharCode(97 + index);
	else return "-";
};
const printNode = (node, prefix = "", indentLevel = 0) => {
	const indent = " ".repeat(3).repeat(indentLevel);
	const prefixPlusIndentLength = prefix.length + indent.length;
	const subsequentLinesPrefix = " ".repeat(prefixPlusIndentLength);
	const valueLines = node.value.split("\n");
	const outputFirstLine = `${indent}${prefix}${valueLines[0]}`;
	const outputSubsequentLines = valueLines.slice(1).map((line) => `${subsequentLinesPrefix}${line}`).join("\n");
	let output = `${outputFirstLine}\n`;
	if (outputSubsequentLines) output += `${outputSubsequentLines}\n`;
	const childPrePrefix = " ".repeat(prefix.length);
	node.children.forEach((child, index) => output += printNode(child, `${childPrePrefix}${treeIndentationRepresentation(index, indentLevel + 1)}. `, indentLevel + 1));
	return output;
};
function treeReducer(state, action) {
	switch (action.type) {
		case "ADD_NODE": {
			const { value, parentId, id: newNodeId } = action;
			const newNode = {
				id: newNodeId,
				value,
				children: [],
				categories: new Set(action.categories)
			};
			try {
				return addNode(state, newNode, parentId);
			} catch (error) {
				console.error(`Error while adding node with id ${newNodeId}: ${error}`);
				return state;
			}
		}
		case "REMOVE_NODE": return removeNode(state, action.id);
		default: return state;
	}
}
const useTree = () => {
	const [tree, dispatch] = useReducer(treeReducer, []);
	const addElement = useCallback((value, categories, parentId) => {
		const newNodeId = randomId();
		dispatch({
			type: "ADD_NODE",
			value,
			parentId,
			id: newNodeId,
			categories
		});
		return newNodeId;
	}, []);
	const removeElement = useCallback((id) => {
		dispatch({
			type: "REMOVE_NODE",
			id
		});
	}, []);
	const getAllElements = useCallback(() => {
		return tree;
	}, [tree]);
	return {
		tree,
		addElement,
		printTree: useCallback((categories) => {
			const categoriesSet = new Set(categories);
			let output = "";
			tree.forEach((node, index) => {
				if (!setsHaveIntersection$1(categoriesSet, node.categories)) return;
				if (index !== 0) output += "\n";
				output += printNode(node, `${treeIndentationRepresentation(index, 0)}. `);
			});
			return output;
		}, [tree]),
		removeElement,
		getAllElements
	};
};
function setsHaveIntersection$1(setA, setB) {
	const [smallerSet, largerSet] = setA.size <= setB.size ? [setA, setB] : [setB, setA];
	for (let item of smallerSet) if (largerSet.has(item)) return true;
	return false;
}

//#endregion
//#region src/hooks/use-flat-category-store.ts
const useFlatCategoryStore = () => {
	const [elements, dispatch] = useReducer(flatCategoryStoreReducer, /* @__PURE__ */ new Map());
	return {
		addElement: useCallback((value, categories) => {
			const newId = randomId();
			dispatch({
				type: "ADD_ELEMENT",
				value,
				id: newId,
				categories
			});
			return newId;
		}, []),
		removeElement: useCallback((id) => {
			dispatch({
				type: "REMOVE_ELEMENT",
				id
			});
		}, []),
		allElements: useCallback((categories) => {
			const categoriesSet = new Set(categories);
			const result = [];
			elements.forEach((element) => {
				if (setsHaveIntersection(categoriesSet, element.categories)) result.push(element.value);
			});
			return result;
		}, [elements])
	};
};
function flatCategoryStoreReducer(state, action) {
	switch (action.type) {
		case "ADD_ELEMENT": {
			const { value, id, categories } = action;
			const newElement = {
				id,
				value,
				categories: new Set(categories)
			};
			const newState = new Map(state);
			newState.set(id, newElement);
			return newState;
		}
		case "REMOVE_ELEMENT": {
			const newState = new Map(state);
			newState.delete(action.id);
			return newState;
		}
		default: return state;
	}
}
function setsHaveIntersection(setA, setB) {
	const [smallerSet, largerSet] = setA.size <= setB.size ? [setA, setB] : [setB, setA];
	for (let item of smallerSet) if (largerSet.has(item)) return true;
	return false;
}

//#endregion
//#region src/context/copilot-messages-context.tsx
const emptyCopilotContext = {
	messages: [],
	setMessages: () => [],
	suggestions: [],
	setSuggestions: () => []
};
const CopilotMessagesContext = React.createContext(emptyCopilotContext);
function useCopilotMessagesContext() {
	const context = React.useContext(CopilotMessagesContext);
	if (context === emptyCopilotContext) throw new Error("A messages consuming component was not wrapped with `<CopilotMessages> {...} </CopilotMessages>`");
	return context;
}

//#endregion
//#region src/components/toast/toast-provider.tsx
const ToastContext = createContext(void 0);
function getErrorSeverity(error) {
	if (error.severity) switch (error.severity) {
		case Severity.CRITICAL: return "critical";
		case Severity.WARNING: return "warning";
		case Severity.INFO: return "info";
		default: return "info";
	}
	const message = error.message.toLowerCase();
	if (message.includes("api key") || message.includes("401") || message.includes("unauthorized") || message.includes("authentication") || message.includes("incorrect api key")) return "critical";
	return "info";
}
function getErrorColors(severity) {
	switch (severity) {
		case "critical": return {
			background: "#fee2e2",
			border: "#dc2626",
			text: "#7f1d1d",
			icon: "#dc2626"
		};
		case "warning": return {
			background: "#fef3c7",
			border: "#d97706",
			text: "#78350f",
			icon: "#d97706"
		};
		case "info": return {
			background: "#dbeafe",
			border: "#2563eb",
			text: "#1e3a8a",
			icon: "#2563eb"
		};
	}
}
function useToast() {
	const context = useContext(ToastContext);
	if (!context) throw new Error("useToast must be used within a ToastProvider");
	return context;
}
function formatBannerMessage(message) {
	const jsonMatch = message.match(/'message':\s*'([^']+)'/);
	if (jsonMatch) return jsonMatch[1];
	let cleaned = message.split(" - ")[0];
	cleaned = cleaned.split(": Error code")[0];
	cleaned = cleaned.replace(/:\s*\d{3}$/, "");
	cleaned = cleaned.replace(/See more:.*$/g, "");
	cleaned = cleaned.trim();
	return cleaned || "An error occurred.";
}
function extractUrl(message) {
	const markdownMatch = /\[([^\]]+)\]\(([^)]+)\)/.exec(message);
	if (markdownMatch) return {
		url: markdownMatch[2],
		text: "See More"
	};
	const plainMatch = /(https?:\/\/[^\s)]+)/.exec(message);
	if (plainMatch) return {
		url: plainMatch[0].replace(/[.,;:'"]*$/, ""),
		text: "See More"
	};
	return null;
}
function BannerErrorDisplay({ bannerError, onDismiss }) {
	const [detailsExpanded, setDetailsExpanded] = useState(false);
	const colors = getErrorColors(getErrorSeverity(bannerError));
	const details = bannerError.details;
	const link = extractUrl(bannerError.message);
	return /* @__PURE__ */ jsxs("div", {
		"data-testid": "copilot-error-banner",
		style: {
			position: "fixed",
			bottom: "20px",
			left: "50%",
			transform: "translateX(-50%)",
			zIndex: 9999,
			backgroundColor: colors.background,
			border: `1px solid ${colors.border}`,
			borderLeft: `4px solid ${colors.border}`,
			borderRadius: "8px",
			padding: "12px 16px",
			fontSize: "13px",
			boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
			backdropFilter: "blur(8px)",
			maxWidth: "min(90vw, 700px)",
			width: "100%",
			boxSizing: "border-box",
			overflow: "hidden"
		},
		children: [/* @__PURE__ */ jsxs("div", {
			style: {
				display: "flex",
				justifyContent: "space-between",
				alignItems: "center",
				gap: "10px"
			},
			children: [/* @__PURE__ */ jsxs("div", {
				style: {
					display: "flex",
					alignItems: "center",
					gap: "8px",
					flex: 1,
					minWidth: 0
				},
				children: [/* @__PURE__ */ jsx("div", { style: {
					width: "12px",
					height: "12px",
					borderRadius: "50%",
					backgroundColor: colors.border,
					flexShrink: 0
				} }), /* @__PURE__ */ jsxs("div", {
					style: {
						display: "flex",
						alignItems: "center",
						gap: "10px",
						flex: 1,
						minWidth: 0
					},
					children: [
						/* @__PURE__ */ jsx("div", {
							style: {
								color: colors.text,
								lineHeight: "1.4",
								fontWeight: "400",
								fontSize: "13px",
								flex: 1,
								wordBreak: "break-all",
								overflowWrap: "break-word",
								maxWidth: "550px",
								overflow: "hidden",
								display: "-webkit-box",
								WebkitLineClamp: 10,
								WebkitBoxOrient: "vertical"
							},
							children: formatBannerMessage(bannerError.message)
						}),
						link && /* @__PURE__ */ jsx("button", {
							onClick: () => window.open(link.url, "_blank", "noopener,noreferrer"),
							style: {
								background: colors.border,
								color: "white",
								border: "none",
								borderRadius: "5px",
								padding: "4px 10px",
								fontSize: "11px",
								fontWeight: "500",
								cursor: "pointer",
								transition: "all 0.2s ease",
								flexShrink: 0
							},
							onMouseEnter: (e) => {
								e.currentTarget.style.opacity = "0.9";
								e.currentTarget.style.transform = "translateY(-1px)";
							},
							onMouseLeave: (e) => {
								e.currentTarget.style.opacity = "1";
								e.currentTarget.style.transform = "translateY(0)";
							},
							children: link.text
						}),
						details && /* @__PURE__ */ jsx("button", {
							onClick: () => setDetailsExpanded(!detailsExpanded),
							style: {
								background: "transparent",
								border: `1px solid ${colors.border}`,
								borderRadius: "5px",
								padding: "4px 10px",
								fontSize: "11px",
								fontWeight: "500",
								cursor: "pointer",
								color: colors.text,
								flexShrink: 0,
								transition: "all 0.2s ease"
							},
							onMouseEnter: (e) => {
								e.currentTarget.style.background = "rgba(0, 0, 0, 0.05)";
							},
							onMouseLeave: (e) => {
								e.currentTarget.style.background = "transparent";
							},
							children: detailsExpanded ? "Hide Details" : "Show Details"
						})
					]
				})]
			}), /* @__PURE__ */ jsx("button", {
				onClick: onDismiss,
				style: {
					background: "transparent",
					border: "none",
					color: colors.text,
					cursor: "pointer",
					padding: "2px",
					borderRadius: "3px",
					fontSize: "14px",
					lineHeight: "1",
					opacity: .6,
					transition: "all 0.2s ease",
					flexShrink: 0
				},
				title: "Dismiss",
				onMouseEnter: (e) => {
					e.currentTarget.style.opacity = "1";
					e.currentTarget.style.background = "rgba(0, 0, 0, 0.05)";
				},
				onMouseLeave: (e) => {
					e.currentTarget.style.opacity = "0.6";
					e.currentTarget.style.background = "transparent";
				},
				children: "x"
			})]
		}), detailsExpanded && details && /* @__PURE__ */ jsxs("div", {
			style: {
				marginTop: "10px",
				padding: "10px",
				background: "rgba(0, 0, 0, 0.04)",
				borderRadius: "6px",
				fontSize: "11px",
				fontFamily: "monospace",
				color: colors.text,
				lineHeight: "1.5",
				maxHeight: "200px",
				overflowY: "auto",
				whiteSpace: "pre-wrap",
				wordBreak: "break-all"
			},
			children: [
				details.code && /* @__PURE__ */ jsxs("div", { children: [
					/* @__PURE__ */ jsx("strong", { children: "Code:" }),
					" ",
					details.code
				] }),
				details.originalMessage && /* @__PURE__ */ jsxs("div", {
					style: { marginTop: "4px" },
					children: [
						/* @__PURE__ */ jsx("strong", { children: "Message:" }),
						" ",
						details.originalMessage
					]
				}),
				details.context && Object.keys(details.context).length > 0 && /* @__PURE__ */ jsxs("div", {
					style: { marginTop: "4px" },
					children: [
						/* @__PURE__ */ jsx("strong", { children: "Context:" }),
						" ",
						JSON.stringify(details.context, null, 2)
					]
				}),
				details.stack && /* @__PURE__ */ jsxs("div", {
					style: {
						marginTop: "4px",
						opacity: .7
					},
					children: [
						/* @__PURE__ */ jsx("strong", { children: "Stack:" }),
						"\n",
						details.stack
					]
				})
			]
		})]
	});
}
function ToastProvider({ enabled, children }) {
	const [toasts, setToasts] = useState([]);
	const [bannerError, setBannerErrorState] = useState(null);
	const removeToast = useCallback((id) => {
		setToasts((prev) => prev.filter((toast) => toast.id !== id));
	}, []);
	const addToast = useCallback((toast) => {
		if (!enabled) return;
		const id = toast.id ?? Math.random().toString(36).slice(2, 9);
		setToasts((currentToasts) => {
			if (currentToasts.find((toast) => toast.id === id)) return currentToasts;
			return [...currentToasts, {
				...toast,
				id
			}];
		});
		if (toast.duration) setTimeout(() => {
			removeToast(id);
		}, toast.duration);
	}, [enabled, removeToast]);
	const setBannerError = useCallback((error) => {
		if (!enabled && error !== null) return;
		setBannerErrorState(error);
	}, [enabled]);
	const value = {
		toasts,
		addToast,
		addGraphQLErrorsToast: useCallback((errors) => {
			console.warn("addGraphQLErrorsToast is deprecated. All errors now show as banners.");
		}, []),
		removeToast,
		enabled,
		bannerError,
		setBannerError
	};
	return /* @__PURE__ */ jsxs(ToastContext.Provider, {
		value,
		children: [bannerError && /* @__PURE__ */ jsx(BannerErrorDisplay, {
			bannerError,
			onDismiss: () => setBannerError(null)
		}), children]
	});
}

//#endregion
//#region src/utils/dev-console.ts
function isLocalhost() {
	if (typeof window === "undefined") return false;
	return window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1" || window.location.hostname === "0.0.0.0";
}
function shouldShowDevConsole(showDevConsole) {
	if (showDevConsole !== void 0) return showDevConsole;
	return isLocalhost();
}

//#endregion
//#region src/components/copilot-provider/copilot-messages.tsx
/**
* An internal context to separate the messages state (which is constantly changing) from the rest of CopilotKit context
*/
/**
* Determine whether a GraphQL error should be suppressed based on its visibility
* and whether the dev console is active.
*
* Returns `null` when the error should be surfaced to the UI, or a log prefix
* string when the error should be suppressed (logged to console only).
*
* Exported for unit testing.
*/
function getErrorSuppression(visibility, isDev) {
	if (visibility === ErrorVisibility.SILENT) return "CopilotKit Silent Error:";
	if (!isDev && visibility === ErrorVisibility.DEV_ONLY) return "CopilotKit Error (hidden in production):";
	return null;
}
const MessagesTapContext = createContext(null);
function useMessagesTap() {
	const tap = useContext(MessagesTapContext);
	if (!tap) throw new Error("useMessagesTap must be used inside <MessagesTapProvider>");
	return tap;
}
function MessagesTapProvider({ children }) {
	const messagesRef = useRef([]);
	const tapRef = useRef({
		getMessagesFromTap: () => messagesRef.current,
		updateTapMessages: (messages) => {
			messagesRef.current = messages;
		}
	});
	return /* @__PURE__ */ jsx(MessagesTapContext.Provider, {
		value: tapRef.current,
		children
	});
}
/**
* CopilotKit messages context.
*/
function CopilotMessages({ children }) {
	const [messages, setMessages] = useState([]);
	useRef(void 0);
	useRef(void 0);
	useRef(void 0);
	const { updateTapMessages } = useMessagesTap();
	const { threadId, agentSession, showDevConsole, onError, copilotApiConfig } = useCopilotContext();
	const { setBannerError } = useToast();
	const traceUIError = useCallback(async (error, originalError) => {
		if (!onError || !copilotApiConfig.publicApiKey) return;
		try {
			await onError({
				type: "error",
				timestamp: Date.now(),
				context: {
					source: "ui",
					request: {
						operation: "loadAgentState",
						url: copilotApiConfig.chatApiEndpoint,
						startTime: Date.now()
					},
					technical: {
						environment: "browser",
						userAgent: typeof navigator !== "undefined" ? navigator.userAgent : void 0,
						stackTrace: originalError instanceof Error ? originalError.stack : void 0
					}
				},
				error
			});
		} catch (traceError) {
			console.error("Error in CopilotMessages onError handler:", traceError);
		}
	}, [
		onError,
		copilotApiConfig.publicApiKey,
		copilotApiConfig.chatApiEndpoint
	]);
	const createStructuredError = (gqlError) => {
		const extensions = gqlError.extensions;
		const originalError = extensions?.originalError;
		if (originalError?.stack) {
			if (originalError.stack.includes("CopilotApiDiscoveryError")) return new CopilotKitApiDiscoveryError({ message: originalError.message });
			if (originalError.stack.includes("CopilotKitRemoteEndpointDiscoveryError")) return new CopilotKitRemoteEndpointDiscoveryError({ message: originalError.message });
			if (originalError.stack.includes("CopilotKitAgentDiscoveryError")) return new CopilotKitAgentDiscoveryError({
				agentName: "",
				availableAgents: []
			});
		}
		const message = originalError?.message || gqlError.message;
		const code = extensions?.code;
		if (code) return new CopilotKitError({
			message,
			code
		});
		return null;
	};
	useCallback((error) => {
		if (error.graphQLErrors?.length) {
			const graphQLErrors = error.graphQLErrors;
			const routeError = (gqlError) => {
				const visibility = gqlError.extensions?.visibility;
				const suppression = getErrorSuppression(visibility, shouldShowDevConsole(showDevConsole));
				if (suppression) {
					console.error(suppression, gqlError.message);
					return;
				}
				const ckError = createStructuredError(gqlError);
				if (ckError) {
					setBannerError(ckError);
					traceUIError(ckError, gqlError);
				} else {
					const fallbackError = new CopilotKitError({
						message: gqlError.message,
						code: CopilotKitErrorCode.UNKNOWN
					});
					setBannerError(fallbackError);
					traceUIError(fallbackError, gqlError);
				}
			};
			graphQLErrors.forEach(routeError);
		} else {
			const fallbackError = new CopilotKitError({
				message: error?.message || String(error),
				code: CopilotKitErrorCode.UNKNOWN
			});
			setBannerError(fallbackError);
			traceUIError(fallbackError, error);
		}
	}, [
		setBannerError,
		showDevConsole,
		traceUIError
	]);
	useEffect(() => {
		updateTapMessages(messages);
	}, [messages, updateTapMessages]);
	const memoizedChildren = useMemo(() => children, [children]);
	const [suggestions, setSuggestions] = useState([]);
	return /* @__PURE__ */ jsx(CopilotMessagesContext.Provider, {
		value: {
			messages,
			setMessages,
			suggestions,
			setSuggestions
		},
		children: memoizedChildren
	});
}

//#endregion
//#region src/components/usage-banner.tsx
function UsageBanner({ severity = Severity.CRITICAL, message = "", onClose, actions }) {
	if (!message || !severity) return null;
	const theme = {
		[Severity.INFO]: {
			bg: "#f8fafc",
			border: "#e2e8f0",
			text: "#475569",
			accent: "#3b82f6"
		},
		[Severity.WARNING]: {
			bg: "#fffbeb",
			border: "#fbbf24",
			text: "#92400e",
			accent: "#f59e0b"
		},
		[Severity.CRITICAL]: {
			bg: "#fef2f2",
			border: "#fecaca",
			text: "#dc2626",
			accent: "#ef4444"
		}
	}[severity];
	return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("style", { children: `
          @keyframes slideUp {
            from { opacity: 0; transform: translateX(-50%) translateY(8px); }
            to { opacity: 1; transform: translateX(-50%) translateY(0); }
          }
          
          .usage-banner {
            position: fixed;
            bottom: 24px;
            left: 50%;
            transform: translateX(-50%);
            width: min(600px, calc(100vw - 32px));
            z-index: 10000;
            animation: slideUp 0.2s cubic-bezier(0.16, 1, 0.3, 1);
          }
          
          .banner-content {
            background: linear-gradient(135deg, ${theme.bg} 0%, ${theme.bg}f5 100%);
            border: 1px solid ${theme.border};
            border-radius: 12px;
            padding: 18px 20px;
            box-shadow: 
              0 4px 24px rgba(0, 0, 0, 0.08),
              0 2px 8px rgba(0, 0, 0, 0.04),
              inset 0 1px 0 rgba(255, 255, 255, 0.7);
            display: flex;
            align-items: center;
            gap: 16px;
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
            backdrop-filter: blur(12px);
            position: relative;
            overflow: hidden;
          }
          
          .banner-content::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            height: 1px;
            background: linear-gradient(90deg, transparent, ${theme.accent}40, transparent);
          }
          
          .banner-message {
            color: ${theme.text};
            font-size: 14px;
            line-height: 1.5;
            font-weight: 500;
            flex: 1;
            letter-spacing: -0.01em;
          }
          
          .close-btn {
            background: rgba(0, 0, 0, 0.05);
            border: none;
            color: ${theme.text};
            cursor: pointer;
            padding: 0;
            border-radius: 6px;
            opacity: 0.6;
            transition: all 0.15s cubic-bezier(0.16, 1, 0.3, 1);
            font-size: 14px;
            line-height: 1;
            flex-shrink: 0;
            width: 24px;
            height: 24px;
            display: flex;
            align-items: center;
            justify-content: center;
          }
          
          .close-btn:hover {
            opacity: 1;
            background: rgba(0, 0, 0, 0.08);
            transform: scale(1.05);
          }
          
          .btn-primary {
            background: linear-gradient(135deg, ${theme.accent} 0%, ${theme.accent}e6 100%);
            color: white;
            border: none;
            border-radius: 8px;
            padding: 10px 18px;
            font-size: 13px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.15s cubic-bezier(0.16, 1, 0.3, 1);
            font-family: inherit;
            flex-shrink: 0;
            box-shadow: 
              0 2px 8px ${theme.accent}30,
              inset 0 1px 0 rgba(255, 255, 255, 0.2);
            letter-spacing: -0.01em;
          }
          
          .btn-primary:hover {
            transform: translateY(-1px) scale(1.02);
            box-shadow: 
              0 4px 12px ${theme.accent}40,
              inset 0 1px 0 rgba(255, 255, 255, 0.25);
          }
          
          .btn-primary:active {
            transform: translateY(0) scale(0.98);
            transition: all 0.08s cubic-bezier(0.16, 1, 0.3, 1);
          }
          
          @media (max-width: 640px) {
            .usage-banner {
              width: calc(100vw - 24px);
            }
            
            .banner-content {
              padding: 16px;
              gap: 12px;
            }
            
            .banner-message {
              font-size: 13px;
              line-height: 1.45;
            }
            
            .btn-primary {
              padding: 8px 14px;
              font-size: 12px;
            }
            
            .close-btn {
              width: 22px;
              height: 22px;
              font-size: 12px;
            }
          }
        ` }), /* @__PURE__ */ jsx("div", {
		className: "usage-banner",
		"data-testid": "copilot-error-banner",
		children: /* @__PURE__ */ jsxs("div", {
			className: "banner-content",
			children: [
				/* @__PURE__ */ jsx("div", {
					className: "banner-message",
					children: message
				}),
				actions?.primary && /* @__PURE__ */ jsx("button", {
					className: "btn-primary",
					onClick: actions.primary.onClick,
					children: actions.primary.label
				}),
				onClose && /* @__PURE__ */ jsx("button", {
					className: "close-btn",
					onClick: onClose,
					title: "Close",
					children: "×"
				})
			]
		})
	})] });
}
const getErrorActions = (error) => {
	switch (error.code) {
		case CopilotKitErrorCode.MISSING_PUBLIC_API_KEY_ERROR: return { primary: {
			label: "Show me how",
			onClick: () => window.open("https://docs.copilotkit.ai/premium/overview#getting-access", "_blank", "noopener,noreferrer")
		} };
		case CopilotKitErrorCode.UPGRADE_REQUIRED_ERROR: return { primary: {
			label: "Upgrade",
			onClick: () => window.open("https://dashboard.operations.copilotkit.ai", "_blank", "noopener,noreferrer")
		} };
		default: return;
	}
};

//#endregion
//#region src/lib/status-checker.ts
const STATUS_CHECK_INTERVAL = 1e3 * 60 * 5;
var StatusChecker = class {
	constructor() {
		this.activeKey = null;
		this.intervalId = null;
		this.instanceCount = 0;
		this.lastResponse = null;
	}
	async start(publicApiKey, onUpdate) {
		this.instanceCount++;
		if (this.activeKey === publicApiKey) return;
		if (this.intervalId) clearInterval(this.intervalId);
		const checkStatus = async () => {
			try {
				const response = await fetch(`${COPILOT_CLOUD_API_URL}/ciu`, {
					method: "GET",
					headers: { [COPILOT_CLOUD_PUBLIC_API_KEY_HEADER]: publicApiKey }
				}).then((response) => response.json());
				this.lastResponse = response;
				onUpdate?.(response);
				return response;
			} catch (error) {
				return null;
			}
		};
		const initialResponse = await checkStatus();
		this.intervalId = setInterval(checkStatus, STATUS_CHECK_INTERVAL);
		this.activeKey = publicApiKey;
		return initialResponse;
	}
	getLastResponse() {
		return this.lastResponse;
	}
	stop() {
		this.instanceCount--;
		if (this.instanceCount === 0) {
			if (this.intervalId) {
				clearInterval(this.intervalId);
				this.intervalId = null;
				this.activeKey = null;
				this.lastResponse = null;
			}
		}
	}
};

//#endregion
//#region src/components/toast/exclamation-mark-icon.tsx
const ExclamationMarkIcon = ({ className, style }) => /* @__PURE__ */ jsxs("svg", {
	xmlns: "http://www.w3.org/2000/svg",
	width: "24",
	height: "24",
	viewBox: "0 0 24 24",
	fill: "none",
	stroke: "currentColor",
	strokeWidth: "2",
	strokeLinecap: "round",
	strokeLinejoin: "round",
	className: `lucide lucide-circle-alert ${className ? className : ""}`,
	style,
	children: [
		/* @__PURE__ */ jsx("circle", {
			cx: "12",
			cy: "12",
			r: "10"
		}),
		/* @__PURE__ */ jsx("line", {
			x1: "12",
			x2: "12",
			y1: "8",
			y2: "12"
		}),
		/* @__PURE__ */ jsx("line", {
			x1: "12",
			x2: "12.01",
			y1: "16",
			y2: "16"
		})
	]
});

//#endregion
//#region src/components/error-boundary/error-utils.tsx
function ErrorToast({ errors }) {
	return /* @__PURE__ */ jsxs("div", {
		style: {
			fontSize: "13px",
			maxWidth: "600px"
		},
		children: [errors.map((error, idx) => {
			const message = ("extensions" in error ? error.extensions?.originalError : {})?.message ?? error.message;
			const code = "extensions" in error ? error.extensions?.code : null;
			return /* @__PURE__ */ jsxs("div", {
				style: {
					marginTop: idx === 0 ? 0 : 10,
					marginBottom: 14
				},
				children: [
					/* @__PURE__ */ jsx(ExclamationMarkIcon, { style: { marginBottom: 4 } }),
					code && /* @__PURE__ */ jsxs("div", {
						style: {
							fontWeight: "600",
							marginBottom: 4
						},
						children: [
							"Copilot Runtime Error:",
							" ",
							/* @__PURE__ */ jsx("span", {
								style: {
									fontFamily: "monospace",
									fontWeight: "normal"
								},
								children: code
							})
						]
					}),
					/* @__PURE__ */ jsx(ReactMarkdown, { children: message })
				]
			}, idx);
		}), /* @__PURE__ */ jsx("div", {
			style: {
				fontSize: "11px",
				opacity: .75
			},
			children: "NOTE: This error only displays during local development."
		})]
	});
}
function useErrorToast() {
	const { addToast } = useToast();
	return useCallback((errors) => {
		addToast({
			type: "error",
			id: errors.map((err) => {
				const message = "extensions" in err ? (err.extensions?.originalError)?.message || err.message : err.message;
				const stack = err.stack || "";
				return btoa(message + stack).slice(0, 32);
			}).join("|"),
			message: /* @__PURE__ */ jsx(ErrorToast, { errors })
		});
	}, [addToast]);
}
function useAsyncCallback(callback, deps) {
	const addErrorToast = useErrorToast();
	return useCallback(async (...args) => {
		try {
			return await callback(...args);
		} catch (error) {
			console.error("Error in async callback:", error);
			addErrorToast([error]);
			throw error;
		}
	}, deps);
}

//#endregion
//#region src/components/error-boundary/error-boundary.tsx
const statusChecker = new StatusChecker();
var CopilotErrorBoundary = class extends React.Component {
	constructor(props) {
		super(props);
		this.state = { hasError: false };
	}
	static getDerivedStateFromError(error) {
		return {
			hasError: true,
			error
		};
	}
	componentDidMount() {
		if (this.props.publicApiKey) statusChecker.start(this.props.publicApiKey, (newStatus) => {
			this.setState((prevState) => {
				if (newStatus?.severity !== prevState.status?.severity) return { status: newStatus ?? void 0 };
				return null;
			});
		});
	}
	componentWillUnmount() {
		statusChecker.stop();
	}
	componentDidCatch(error, errorInfo) {
		console.error("CopilotKit Error:", error, errorInfo);
	}
	render() {
		if (this.state.hasError) {
			if (this.state.error instanceof CopilotKitError) return /* @__PURE__ */ jsxs(Fragment$1, { children: [this.props.children, this.props.showUsageBanner && /* @__PURE__ */ jsx(UsageBanner, {
				severity: this.state.status?.severity ?? this.state.error.severity,
				message: this.state.status?.message ?? this.state.error.message,
				actions: getErrorActions(this.state.error)
			})] });
			throw this.state.error;
		}
		return this.props.children;
	}
};

//#endregion
//#region src/context/coagent-state-renders-context.tsx
const CoAgentStateRendersContext = createContext(void 0);
function CoAgentStateRendersProvider({ children }) {
	const [coAgentStateRenders, setCoAgentStateRenders] = useState({});
	const setCoAgentStateRender = useCallback((id, stateRender) => {
		setCoAgentStateRenders((prevPoints) => ({
			...prevPoints,
			[id]: stateRender
		}));
	}, []);
	const removeCoAgentStateRender = useCallback((id) => {
		setCoAgentStateRenders((prevPoints) => {
			const newPoints = { ...prevPoints };
			delete newPoints[id];
			return newPoints;
		});
	}, []);
	const claimsRef = useRef({});
	return /* @__PURE__ */ jsx(CoAgentStateRendersContext.Provider, {
		value: {
			coAgentStateRenders,
			setCoAgentStateRender,
			removeCoAgentStateRender,
			claimsRef
		},
		children
	});
}
function useCoAgentStateRenders() {
	const context = useContext(CoAgentStateRendersContext);
	if (!context) throw new Error("useCoAgentStateRenders must be used within CoAgentStateRendersProvider");
	return context;
}

//#endregion
//#region src/context/threads-context.tsx
const ThreadsContext = createContext(void 0);
function ThreadsProvider({ children, threadId: explicitThreadId }) {
	const [internalThreadId, setInternalThreadId] = useState(() => randomUUID$1());
	const [internalIsExplicit, setInternalIsExplicit] = useState(false);
	const threadId = explicitThreadId ?? internalThreadId;
	const isThreadIdExplicit = explicitThreadId != null || internalIsExplicit;
	const setThreadId = useCallback((value) => {
		setInternalThreadId(value);
		setInternalIsExplicit(true);
	}, []);
	return /* @__PURE__ */ jsx(ThreadsContext.Provider, {
		value: {
			threadId,
			setThreadId,
			isThreadIdExplicit
		},
		children
	});
}
function useThreads() {
	const context = useContext(ThreadsContext);
	if (!context) throw new Error("useThreads must be used within ThreadsProvider");
	return context;
}

//#endregion
//#region src/hooks/use-coagent-state-render-bridge.helpers.ts
let RenderStatus = /* @__PURE__ */ function(RenderStatus) {
	RenderStatus["InProgress"] = "inProgress";
	RenderStatus["Complete"] = "complete";
	return RenderStatus;
}({});
let ClaimAction = /* @__PURE__ */ function(ClaimAction) {
	ClaimAction["Create"] = "create";
	ClaimAction["Override"] = "override";
	ClaimAction["Existing"] = "existing";
	ClaimAction["Block"] = "block";
	return ClaimAction;
}({});
function getStateWithoutConstantKeys(state) {
	if (!state) return {};
	const { messages, tools, copilotkit, ...stateWithoutConstantKeys } = state;
	return stateWithoutConstantKeys;
}
function areStatesEquals(a, b) {
	if (a && !b || !a && b) return false;
	const { messages, tools, copilotkit, ...aWithoutConstantKeys } = a;
	const { messages: bMessages, tools: bTools, copilotkit: bCopilotkit, ...bWithoutConstantKeys } = b;
	return JSON.stringify(aWithoutConstantKeys) === JSON.stringify(bWithoutConstantKeys);
}
function isPlaceholderMessageId(messageId) {
	return !!messageId && messageId.startsWith("coagent-state-render-");
}
function isPlaceholderMessageName(messageName) {
	return messageName === "coagent-state-render";
}
function readCachedMessageEntry(entry) {
	if (!entry || typeof entry !== "object") return {
		snapshot: entry,
		runId: void 0
	};
	return {
		snapshot: "snapshot" in entry ? entry.snapshot : entry,
		runId: "runId" in entry ? entry.runId : void 0
	};
}
function getEffectiveRunId({ existingClaimRunId, cachedMessageRunId, runId }) {
	return existingClaimRunId || cachedMessageRunId || runId || "pending";
}
/**
* Resolve whether a message can claim a render slot.
* This is a pure decision function; the caller applies claim mutations.
*/
function resolveClaim({ claims, context, stateSnapshot }) {
	const { messageId, stateRenderId, runId, messageIndex } = context;
	const existing = claims[messageId];
	if (existing) {
		const canRender = existing.stateRenderId === stateRenderId;
		const shouldUpdateRunId = canRender && runId && (!existing.runId || existing.runId === "pending");
		return {
			canRender,
			action: canRender ? ClaimAction.Existing : ClaimAction.Block,
			updateRunId: shouldUpdateRunId ? runId : void 0
		};
	}
	const normalizedRunId = runId ?? "pending";
	const renderClaimedByOtherMessageEntry = Object.entries(claims).find(([, claim]) => claim.stateRenderId === stateRenderId && (claim.runId ?? "pending") === normalizedRunId && dataToUUID(getStateWithoutConstantKeys(claim.stateSnapshot)) === dataToUUID(getStateWithoutConstantKeys(stateSnapshot)));
	const renderClaimedByOtherMessage = renderClaimedByOtherMessageEntry?.[1];
	const claimedMessageId = renderClaimedByOtherMessageEntry?.[0];
	if (renderClaimedByOtherMessage) {
		if (messageIndex !== void 0 && renderClaimedByOtherMessage.messageIndex !== void 0 && messageIndex > renderClaimedByOtherMessage.messageIndex) return {
			canRender: true,
			action: ClaimAction.Override,
			nextClaim: {
				stateRenderId,
				runId,
				messageIndex
			},
			lockOthers: runId === renderClaimedByOtherMessage.runId || isPlaceholderMessageId(claimedMessageId)
		};
		if (runId && renderClaimedByOtherMessage.runId && runId !== renderClaimedByOtherMessage.runId) return {
			canRender: true,
			action: ClaimAction.Override,
			nextClaim: {
				stateRenderId,
				runId,
				messageIndex
			},
			lockOthers: isPlaceholderMessageId(claimedMessageId)
		};
		if (isPlaceholderMessageId(claimedMessageId)) return {
			canRender: true,
			action: ClaimAction.Override,
			nextClaim: {
				stateRenderId,
				runId,
				messageIndex
			},
			lockOthers: true
		};
		if (stateSnapshot && renderClaimedByOtherMessage.stateSnapshot && !areStatesEquals(renderClaimedByOtherMessage.stateSnapshot, stateSnapshot)) return {
			canRender: true,
			action: ClaimAction.Override,
			nextClaim: {
				stateRenderId,
				runId
			}
		};
		return {
			canRender: false,
			action: ClaimAction.Block
		};
	}
	if (!runId) return {
		canRender: false,
		action: ClaimAction.Block
	};
	return {
		canRender: true,
		action: ClaimAction.Create,
		nextClaim: {
			stateRenderId,
			runId,
			messageIndex
		}
	};
}
/**
* Select the best snapshot to render for this message.
* Priority order is:
* 1) explicit message snapshot
* 2) live agent state (latest assistant only)
* 3) cached snapshot for message
* 4) cached snapshot for stateRenderId+runId
* 5) last cached snapshot for stateRenderId
*/
function selectSnapshot({ messageId, messageName, allowLiveState, skipLatestCache, stateRenderId, effectiveRunId, stateSnapshotProp, agentState, agentMessages, existingClaim, caches }) {
	const lastAssistantId = agentMessages ? [...agentMessages].toReversed().find((msg) => msg.role === "assistant")?.id : void 0;
	const latestSnapshot = stateRenderId !== void 0 ? caches.byStateRenderAndRun[`${stateRenderId}::latest`] : void 0;
	const messageIndex = agentMessages ? agentMessages.findIndex((msg) => msg.id === messageId) : -1;
	const messageRole = messageIndex >= 0 && agentMessages ? agentMessages[messageIndex]?.role : void 0;
	let previousUserMessageId;
	if (messageIndex > 0 && agentMessages) {
		for (let i = messageIndex - 1; i >= 0; i -= 1) if (agentMessages[i]?.role === "user") {
			previousUserMessageId = agentMessages[i]?.id;
			break;
		}
	}
	const liveStateIsStale = stateSnapshotProp === void 0 && latestSnapshot !== void 0 && agentState !== void 0 && areStatesEquals(latestSnapshot, agentState);
	const shouldUseLiveState = (Boolean(allowLiveState) || !lastAssistantId || messageId === lastAssistantId) && !liveStateIsStale;
	const snapshot = stateSnapshotProp ? parseJson(stateSnapshotProp, stateSnapshotProp) : shouldUseLiveState ? agentState : void 0;
	const hasSnapshotKeys = !!(snapshot && Object.keys(snapshot).length > 0);
	const allowEmptySnapshot = snapshot !== void 0 && !hasSnapshotKeys && (stateSnapshotProp !== void 0 || shouldUseLiveState);
	const messageCacheEntry = caches.byMessageId[messageId];
	const cachedMessageSnapshot = readCachedMessageEntry(messageCacheEntry).snapshot;
	const cacheKey = stateRenderId !== void 0 ? `${stateRenderId}::${effectiveRunId}` : void 0;
	let cachedSnapshot = cachedMessageSnapshot ?? caches.byMessageId[messageId];
	if (cachedSnapshot === void 0 && cacheKey && caches.byStateRenderAndRun[cacheKey] !== void 0) cachedSnapshot = caches.byStateRenderAndRun[cacheKey];
	if (cachedSnapshot === void 0 && stateRenderId && previousUserMessageId && caches.byStateRenderAndRun[`${stateRenderId}::pending:${previousUserMessageId}`] !== void 0) cachedSnapshot = caches.byStateRenderAndRun[`${stateRenderId}::pending:${previousUserMessageId}`];
	if (cachedSnapshot === void 0 && !skipLatestCache && stateRenderId && messageRole !== "assistant" && (stateSnapshotProp !== void 0 || agentState && Object.keys(agentState).length > 0)) cachedSnapshot = caches.byStateRenderAndRun[`${stateRenderId}::latest`];
	const snapshotForClaim = existingClaim?.locked ? existingClaim.stateSnapshot ?? cachedSnapshot : hasSnapshotKeys ? snapshot : existingClaim?.stateSnapshot ?? cachedSnapshot;
	return {
		snapshot,
		hasSnapshotKeys,
		cachedSnapshot,
		allowEmptySnapshot,
		snapshotForClaim
	};
}

//#endregion
//#region src/hooks/use-coagent-state-render-registry.ts
const LAST_SNAPSHOTS_BY_RENDER_AND_RUN = "__lastSnapshotsByStateRenderIdAndRun";
const LAST_SNAPSHOTS_BY_MESSAGE = "__lastSnapshotsByMessageId";
function getClaimsStore(claimsRef) {
	return claimsRef.current;
}
function getSnapshotCaches(claimsRef) {
	const store = getClaimsStore(claimsRef);
	return {
		byStateRenderAndRun: store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] ?? {},
		byMessageId: store[LAST_SNAPSHOTS_BY_MESSAGE] ?? {}
	};
}
function useStateRenderRegistry({ agentId, stateRenderId, message, messageIndex, stateSnapshot, agentState, agentMessages, claimsRef }) {
	const store = getClaimsStore(claimsRef);
	const runId = message.runId;
	const cachedMessageEntry = store[LAST_SNAPSHOTS_BY_MESSAGE]?.[message.id];
	const { runId: cachedMessageRunId } = readCachedMessageEntry(cachedMessageEntry);
	const existingClaimRunId = claimsRef.current[message.id]?.runId;
	const effectiveRunId = getEffectiveRunId({
		existingClaimRunId,
		cachedMessageRunId,
		runId
	});
	useEffect(() => {
		return () => {
			const existingClaim = claimsRef.current[message.id];
			if (existingClaim?.stateSnapshot && Object.keys(existingClaim.stateSnapshot).length > 0) {
				const snapshotCache = { ...store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] };
				const cacheKey = `${existingClaim.stateRenderId}::${existingClaim.runId ?? "pending"}`;
				snapshotCache[cacheKey] = existingClaim.stateSnapshot;
				snapshotCache[`${existingClaim.stateRenderId}::latest`] = existingClaim.stateSnapshot;
				store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] = snapshotCache;
				const messageCache = { ...store[LAST_SNAPSHOTS_BY_MESSAGE] };
				messageCache[message.id] = {
					snapshot: existingClaim.stateSnapshot,
					runId: existingClaim.runId ?? effectiveRunId
				};
				store[LAST_SNAPSHOTS_BY_MESSAGE] = messageCache;
			}
			delete claimsRef.current[message.id];
		};
	}, [
		claimsRef,
		effectiveRunId,
		message.id
	]);
	if (!stateRenderId) return { canRender: false };
	const caches = getSnapshotCaches(claimsRef);
	const existingClaim = claimsRef.current[message.id];
	const { snapshot, hasSnapshotKeys, allowEmptySnapshot, snapshotForClaim } = selectSnapshot({
		messageId: message.id,
		messageName: message.name,
		allowLiveState: isPlaceholderMessageName(message.name) || isPlaceholderMessageId(message.id),
		skipLatestCache: isPlaceholderMessageName(message.name) || isPlaceholderMessageId(message.id),
		stateRenderId,
		effectiveRunId,
		stateSnapshotProp: stateSnapshot,
		agentState,
		agentMessages,
		existingClaim,
		caches
	});
	const resolution = resolveClaim({
		claims: claimsRef.current,
		context: {
			agentId,
			messageId: message.id,
			stateRenderId,
			runId: effectiveRunId,
			messageIndex
		},
		stateSnapshot: snapshotForClaim
	});
	if (resolution.action === ClaimAction.Block) return { canRender: false };
	if (resolution.updateRunId && claimsRef.current[message.id]) claimsRef.current[message.id].runId = resolution.updateRunId;
	if (resolution.nextClaim) claimsRef.current[message.id] = resolution.nextClaim;
	if (resolution.lockOthers) Object.entries(claimsRef.current).forEach(([id, claim]) => {
		if (id !== message.id && claim.stateRenderId === stateRenderId) claim.locked = true;
	});
	if (existingClaim && !existingClaim.locked && agentMessages?.length) {
		const indexInAgentMessages = agentMessages.findIndex((msg) => msg.id === message.id);
		if (indexInAgentMessages >= 0 && indexInAgentMessages < agentMessages.length - 1) existingClaim.locked = true;
	}
	const existingSnapshot = claimsRef.current[message.id].stateSnapshot;
	const snapshotChanged = stateSnapshot && existingSnapshot !== void 0 && !areStatesEquals(existingSnapshot, snapshot);
	if (snapshot && (stateSnapshot || hasSnapshotKeys || allowEmptySnapshot) && (!claimsRef.current[message.id].locked || snapshotChanged)) {
		if (!claimsRef.current[message.id].locked || snapshotChanged) {
			claimsRef.current[message.id].stateSnapshot = snapshot;
			const snapshotCache = { ...store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] };
			const cacheKey = `${stateRenderId}::${effectiveRunId}`;
			snapshotCache[cacheKey] = snapshot;
			snapshotCache[`${stateRenderId}::latest`] = snapshot;
			store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] = snapshotCache;
			const messageCache = { ...store[LAST_SNAPSHOTS_BY_MESSAGE] };
			messageCache[message.id] = {
				snapshot,
				runId: effectiveRunId
			};
			store[LAST_SNAPSHOTS_BY_MESSAGE] = messageCache;
			if (stateSnapshot) claimsRef.current[message.id].locked = true;
		}
	} else if (snapshotForClaim) {
		if (!claimsRef.current[message.id].stateSnapshot) {
			claimsRef.current[message.id].stateSnapshot = snapshotForClaim;
			const snapshotCache = { ...store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] };
			const cacheKey = `${stateRenderId}::${effectiveRunId}`;
			snapshotCache[cacheKey] = snapshotForClaim;
			snapshotCache[`${stateRenderId}::latest`] = snapshotForClaim;
			store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] = snapshotCache;
			const messageCache = { ...store[LAST_SNAPSHOTS_BY_MESSAGE] };
			messageCache[message.id] = {
				snapshot: snapshotForClaim,
				runId: effectiveRunId
			};
			store[LAST_SNAPSHOTS_BY_MESSAGE] = messageCache;
		}
	}
	return { canRender: true };
}

//#endregion
//#region src/hooks/use-coagent-state-render-bridge.tsx
function useCoagentStateRenderBridge(agentId, props) {
	const { stateSnapshot, message } = props;
	const { coAgentStateRenders, claimsRef } = useCoAgentStateRenders();
	const { agent } = useAgent({ agentId });
	const [nodeName, setNodeName] = useState(void 0);
	const [, forceUpdate] = useState(0);
	useEffect(() => {
		if (!agent) return;
		const { unsubscribe } = agent.subscribe({
			onStateChanged: () => {
				forceUpdate((value) => value + 1);
			},
			onStepStartedEvent: ({ event }) => {
				if (event.stepName !== nodeName) setNodeName(event.stepName);
			},
			onStepFinishedEvent: ({ event }) => {
				if (event.stepName === nodeName) setNodeName(void 0);
			}
		});
		return () => {
			unsubscribe();
		};
	}, [agentId, nodeName]);
	const getStateRender = useCallback((messageId) => {
		return Object.entries(coAgentStateRenders).find(([stateRenderId, stateRender]) => {
			if (claimsRef.current[messageId]) return stateRenderId === claimsRef.current[messageId].stateRenderId;
			const matchingAgentName = stateRender.name === agentId;
			const matchesNodeContext = stateRender.nodeName ? stateRender.nodeName === nodeName : true;
			return matchingAgentName && matchesNodeContext;
		});
	}, [
		coAgentStateRenders,
		nodeName,
		agentId
	]);
	const stateRenderEntry = useMemo(() => getStateRender(message.id), [getStateRender, message.id]);
	const stateRenderId = stateRenderEntry?.[0];
	const stateRender = stateRenderEntry?.[1];
	const { canRender } = useStateRenderRegistry({
		agentId,
		stateRenderId,
		message: {
			...message,
			runId: props.runId ?? message.runId
		},
		messageIndex: props.messageIndex,
		stateSnapshot,
		agentState: agent?.state,
		agentMessages: agent?.messages,
		claimsRef
	});
	return useMemo(() => {
		if (!stateRender || !stateRenderId) return null;
		if (!canRender) return null;
		if (stateRender.handler) stateRender.handler({
			state: stateSnapshot ? parseJson(stateSnapshot, stateSnapshot) : agent?.state ?? {},
			nodeName: nodeName ?? ""
		});
		if (stateRender.render) {
			const status = agent?.isRunning ? RenderStatus.InProgress : RenderStatus.Complete;
			if (typeof stateRender.render === "string") return stateRender.render;
			return stateRender.render({
				status,
				state: claimsRef.current[message.id].stateSnapshot ?? {},
				nodeName: nodeName ?? ""
			});
		}
	}, [
		stateRender,
		stateRenderId,
		agent?.state,
		agent?.isRunning,
		nodeName,
		message.id,
		stateSnapshot,
		canRender
	]);
}
function CoAgentStateRenderBridge(props) {
	return useCoagentStateRenderBridge(props.agentId, props);
}

//#endregion
//#region src/components/CopilotListeners.tsx
const usePredictStateSubscription = (agent) => {
	const predictStateToolsRef = useRef([]);
	const getSubscriber = useCallback((agent) => ({
		onCustomEvent: ({ event }) => {
			if (event.name === "PredictState") predictStateToolsRef.current = event.value;
		},
		onToolCallArgsEvent: ({ partialToolCallArgs, toolCallName }) => {
			predictStateToolsRef.current.forEach((t) => {
				if (t?.tool !== toolCallName) return;
				const emittedState = typeof partialToolCallArgs === "string" ? parseJson(partialToolCallArgs, partialToolCallArgs) : partialToolCallArgs;
				agent.setState({ [t.state_key]: emittedState[t.state_key] });
			});
		}
	}), []);
	useEffect(() => {
		if (!agent) return;
		const subscriber = getSubscriber(agent);
		const { unsubscribe } = agent.subscribe(subscriber);
		return () => {
			unsubscribe();
		};
	}, [agent, getSubscriber]);
};
function CopilotListenersAgentSubscription() {
	const { copilotkit } = useCopilotKit$1();
	const configAgentId = useCopilotChatConfiguration()?.agentId;
	const { agent } = useAgent({ agentId: useMemo(() => {
		const requested = configAgentId ?? DEFAULT_AGENT_ID;
		const registered = copilotkit.agents ?? {};
		if (registered[requested]) return requested;
		if (requested === DEFAULT_AGENT_ID) {
			const firstRegistered = Object.keys(registered)[0];
			if (firstRegistered) return firstRegistered;
		}
		return requested;
	}, [configAgentId, copilotkit.agents]) });
	usePredictStateSubscription(agent);
	return null;
}
function CopilotListeners() {
	const { copilotkit } = useCopilotKit$1();
	const { setBannerError } = useToast();
	const hasAgents = Object.keys(copilotkit.agents ?? {}).length > 0;
	const hasRuntime = copilotkit.runtimeUrl !== void 0;
	useEffect(() => {
		const subscription = copilotkit.subscribe({ onError: ({ error, code, context }) => {
			if (error.name === "AbortError" || error.message === "Fetch is aborted" || error.message === "signal is aborted without reason" || error.message === "component unmounted" || !error.message) return;
			if (process.env.NODE_ENV === "development") console.error("[CopilotKit] Agent error:", error.message, "\n  Code:", code, "\n  Context:", context, "\n  Stack:", error.stack);
			const ckError = new CopilotKitLowLevelError({
				error,
				message: error.message,
				url: typeof window !== "undefined" ? window.location.href : ""
			});
			ckError.details = {
				code,
				context,
				stack: error.stack,
				originalMessage: error.message
			};
			setBannerError(ckError);
		} });
		return () => {
			subscription.unsubscribe();
		};
	}, [copilotkit?.subscribe]);
	return hasAgents || hasRuntime ? /* @__PURE__ */ jsx(CopilotListenersAgentSubscription, {}) : null;
}

//#endregion
//#region src/components/copilot-provider/copilotkit.tsx
function CopilotKit({ children, ...props }) {
	const enabled = shouldShowDevConsole(props.showDevConsole);
	const showInspector = shouldShowDevConsole(props.enableInspector);
	const publicApiKey = props.publicApiKey || props.publicLicenseKey;
	const renderArr = useMemo(() => [{ render: CoAgentStateRenderBridge }], []);
	const { onError: _onError, ...v2Props } = props;
	return /* @__PURE__ */ jsx(ToastProvider, {
		enabled,
		children: /* @__PURE__ */ jsx(CopilotErrorBoundary, {
			publicApiKey,
			showUsageBanner: enabled,
			children: /* @__PURE__ */ jsx(ThreadsProvider, {
				threadId: props.threadId,
				children: /* @__PURE__ */ jsx(CopilotKitProvider, {
					...v2Props,
					showDevConsole: showInspector,
					renderCustomMessages: renderArr,
					children: /* @__PURE__ */ jsx(CopilotKitInternal, {
						...props,
						children
					})
				})
			})
		})
	});
}
/**
* Bridge component that subscribes to v2.x copilotkit core error events
* and forwards them to v1.x error handling system.
* This ensures only ONE subscription exists regardless of how many times
* Chat components are rendered.
*/
function CopilotKitErrorBridge() {
	const { copilotkit } = useCopilotKit$1();
	const { onError, copilotApiConfig } = useCopilotContext();
	useEffect(() => {
		if (!copilotkit) return;
		const subscription = copilotkit.subscribe({ onError: async (event) => {
			const errorEvent = {
				type: "error",
				timestamp: Date.now(),
				context: {
					source: "agent",
					request: {
						operation: event.code || "unknown",
						url: copilotApiConfig?.chatApiEndpoint,
						startTime: Date.now()
					},
					technical: {
						environment: "browser",
						userAgent: typeof navigator !== "undefined" ? navigator.userAgent : void 0,
						stackTrace: event.error.stack
					},
					...event.context
				},
				error: event.error
			};
			try {
				await onError(errorEvent);
			} catch (handlerError) {
				console.error("Error in onError handler:", handlerError);
			}
		} });
		return () => {
			subscription.unsubscribe();
		};
	}, [
		copilotkit,
		onError,
		copilotApiConfig
	]);
	return null;
}
function CopilotKitInternal(cpkProps) {
	const { children, ...props } = cpkProps;
	/**
	* This will throw an error if the props are invalid.
	*/
	validateProps(cpkProps);
	const publicApiKey = props.publicLicenseKey || props.publicApiKey;
	const chatApiEndpoint = props.runtimeUrl || COPILOT_CLOUD_CHAT_URL;
	const [actions, setActions] = useState({});
	const [registeredActionConfigs, setRegisteredActionConfigs] = useState(/* @__PURE__ */ new Map());
	const chatComponentsCache = useRef({
		actions: {},
		coAgentStateRenders: {}
	});
	const { addElement, removeElement, printTree, getAllElements } = useTree();
	const [isLoading, setIsLoading] = useState(false);
	const [chatInstructions, setChatInstructions] = useState("");
	const [authStates, setAuthStates] = useState({});
	const [extensions, setExtensions] = useState({});
	const [additionalInstructions, setAdditionalInstructions] = useState([]);
	const { addElement: addDocument, removeElement: removeDocument, allElements: allDocuments } = useFlatCategoryStore();
	const setAction = useCallback((id, action) => {
		setActions((prevPoints) => {
			return {
				...prevPoints,
				[id]: action
			};
		});
	}, []);
	const removeAction = useCallback((id) => {
		setActions((prevPoints) => {
			const newPoints = { ...prevPoints };
			delete newPoints[id];
			return newPoints;
		});
	}, []);
	const getContextString = useCallback((documents, categories) => {
		return `${documents.map((document) => {
			return `${document.name} (${document.sourceApplication}):\n${document.getContents()}`;
		}).join("\n\n")}\n\n${printTree(categories)}`;
	}, [printTree]);
	const addContext = useCallback((context, parentId, categories = defaultCopilotContextCategories) => {
		return addElement(context, categories, parentId);
	}, [addElement]);
	const removeContext = useCallback((id) => {
		removeElement(id);
	}, [removeElement]);
	const getAllContext = useCallback(() => {
		return getAllElements();
	}, [getAllElements]);
	const getFunctionCallHandler = useCallback((customEntryPoints) => {
		return entryPointsToFunctionCallHandler(Object.values(customEntryPoints || actions));
	}, [actions]);
	const getDocumentsContext = useCallback((categories) => {
		return allDocuments(categories);
	}, [allDocuments]);
	const addDocumentContext = useCallback((documentPointer, categories = defaultCopilotContextCategories) => {
		return addDocument(documentPointer, categories);
	}, [addDocument]);
	const removeDocumentContext = useCallback((documentId) => {
		removeDocument(documentId);
	}, [removeDocument]);
	const copilotApiConfig = useMemo(() => {
		let cloud = void 0;
		if (publicApiKey) cloud = { guardrails: { input: { restrictToTopic: {
			enabled: Boolean(props.guardrails_c),
			validTopics: props.guardrails_c?.validTopics || [],
			invalidTopics: props.guardrails_c?.invalidTopics || []
		} } } };
		return {
			publicApiKey,
			...cloud ? { cloud } : {},
			chatApiEndpoint,
			headers: typeof props.headers === "function" ? props.headers() : props.headers || {},
			properties: props.properties || {},
			transcribeAudioUrl: props.transcribeAudioUrl,
			textToSpeechUrl: props.textToSpeechUrl,
			credentials: props.credentials
		};
	}, [
		publicApiKey,
		props.headers,
		props.properties,
		props.transcribeAudioUrl,
		props.textToSpeechUrl,
		props.credentials,
		props.cloudRestrictToTopic,
		props.guardrails_c
	]);
	useMemo(() => {
		const authHeaders = Object.values(authStates || {}).reduce((acc, state) => {
			if (state.status === "authenticated" && state.authHeaders) return {
				...acc,
				...Object.entries(state.authHeaders).reduce((headers, [key, value]) => ({
					...headers,
					[key.startsWith("X-Custom-") ? key : `X-Custom-${key}`]: value
				}), {})
			};
			return acc;
		}, {});
		return {
			...copilotApiConfig.headers,
			...copilotApiConfig.publicApiKey ? { [COPILOT_CLOUD_PUBLIC_API_KEY_HEADER]: copilotApiConfig.publicApiKey } : {},
			...authHeaders
		};
	}, [
		copilotApiConfig.headers,
		copilotApiConfig.publicApiKey,
		authStates
	]);
	const [internalErrorHandlers, _setInternalErrorHandler] = useState({});
	const setInternalErrorHandler = useCallback((handler) => {
		_setInternalErrorHandler((prev) => ({
			...prev,
			...handler
		}));
	}, []);
	const removeInternalErrorHandler = useCallback((key) => {
		_setInternalErrorHandler((prev) => {
			const { [key]: _removed, ...rest } = prev;
			return rest;
		});
	}, []);
	const onErrorRef = useRef(props.onError);
	useEffect(() => {
		onErrorRef.current = props.onError;
	}, [props.onError]);
	const internalHandlersRef = useRef({});
	useEffect(() => {
		internalHandlersRef.current = internalErrorHandlers;
	}, [internalErrorHandlers]);
	const handleErrors = useCallback(async (error) => {
		if (copilotApiConfig.publicApiKey && onErrorRef.current) try {
			await onErrorRef.current(error);
		} catch (e) {
			console.error("Error in public onError handler:", e);
		}
		const handlers = Object.values(internalHandlersRef.current);
		await Promise.all(handlers.map((h) => Promise.resolve(h(error)).catch((e) => console.error("Error in internal error handler:", e))));
	}, [copilotApiConfig.publicApiKey]);
	const [chatSuggestionConfiguration, setChatSuggestionConfiguration] = useState({});
	const addChatSuggestionConfiguration = useCallback((id, suggestion) => {
		setChatSuggestionConfiguration((prev) => ({
			...prev,
			[id]: suggestion
		}));
	}, [setChatSuggestionConfiguration]);
	const removeChatSuggestionConfiguration = useCallback((id) => {
		setChatSuggestionConfiguration((prev) => {
			const { [id]: _, ...rest } = prev;
			return rest;
		});
	}, [setChatSuggestionConfiguration]);
	const [availableAgents, setAvailableAgents] = useState([]);
	const [coagentStates, setCoagentStates] = useState({});
	const coagentStatesRef = useRef({});
	const setCoagentStatesWithRef = useCallback((value) => {
		const newValue = typeof value === "function" ? value(coagentStatesRef.current) : value;
		coagentStatesRef.current = newValue;
		setCoagentStates((prev) => {
			return newValue;
		});
	}, []);
	let initialAgentSession = null;
	if (props.agent) initialAgentSession = { agentName: props.agent };
	const [agentSession, setAgentSession] = useState(initialAgentSession);
	useEffect(() => {
		if (props.agent) setAgentSession({ agentName: props.agent });
		else setAgentSession(null);
	}, [props.agent]);
	const { threadId, setThreadId: setInternalThreadId, isThreadIdExplicit } = useThreads();
	const setThreadId = useCallback((value) => {
		if (props.threadId) throw new Error("Cannot call setThreadId() when threadId is provided via props.");
		setInternalThreadId(value);
	}, [props.threadId]);
	const [runId, setRunId] = useState(null);
	const chatAbortControllerRef = useRef(null);
	const showDevConsole = shouldShowDevConsole(props.showDevConsole);
	const [interruptActions, _setInterruptActions] = useState({});
	const setInterruptAction = useCallback((action) => {
		_setInterruptActions((prev) => {
			if (action == null || !action.id) return prev;
			return {
				...prev,
				[action.id]: {
					...prev[action.id],
					...action
				}
			};
		});
	}, []);
	const removeInterruptAction = useCallback((actionId) => {
		_setInterruptActions((prev) => {
			const { [actionId]: _, ...rest } = prev;
			return rest;
		});
	}, []);
	const [interruptEventQueue, setInterruptEventQueue] = useState({});
	const addInterruptEvent = useCallback((queuedEvent) => {
		setInterruptEventQueue((prev) => {
			const threadQueue = prev[queuedEvent.threadId] || [];
			return {
				...prev,
				[queuedEvent.threadId]: [...threadQueue, queuedEvent]
			};
		});
	}, []);
	const resolveInterruptEvent = useCallback((threadId, eventId, response) => {
		setInterruptEventQueue((prev) => {
			const threadQueue = prev[threadId] || [];
			return {
				...prev,
				[threadId]: threadQueue.map((queuedEvent) => queuedEvent.eventId === eventId ? {
					...queuedEvent,
					event: {
						...queuedEvent.event,
						response
					}
				} : queuedEvent)
			};
		});
	}, []);
	const memoizedChildren = useMemo(() => children, [children]);
	const [bannerError, setBannerError] = useState(null);
	const agentLock = useMemo(() => props.agent ?? null, [props.agent]);
	const forwardedParameters = useMemo(() => props.forwardedParameters ?? {}, [props.forwardedParameters]);
	const updateExtensions = useCallback((newExtensions) => {
		setExtensions((prev) => {
			const resolved = typeof newExtensions === "function" ? newExtensions(prev) : newExtensions;
			return Object.keys(resolved).length === Object.keys(prev).length && Object.entries(resolved).every(([key, value]) => prev[key] === value) ? prev : resolved;
		});
	}, [setExtensions]);
	const updateAuthStates = useCallback((newAuthStates) => {
		setAuthStates((prev) => {
			const resolved = typeof newAuthStates === "function" ? newAuthStates(prev) : newAuthStates;
			return Object.keys(resolved).length === Object.keys(prev).length && Object.entries(resolved).every(([key, value]) => prev[key] === value) ? prev : resolved;
		});
	}, [setAuthStates]);
	const handleSetRegisteredActions = useCallback((actionConfig) => {
		const key = actionConfig.action.name || randomUUID$1();
		setRegisteredActionConfigs((prev) => {
			const newMap = new Map(prev);
			newMap.set(key, actionConfig);
			return newMap;
		});
		return key;
	}, []);
	const handleRemoveRegisteredAction = useCallback((actionKey) => {
		setRegisteredActionConfigs((prev) => {
			const newMap = new Map(prev);
			newMap.delete(actionKey);
			return newMap;
		});
	}, []);
	const RegisteredActionsRenderer = useMemo(() => {
		return () => /* @__PURE__ */ jsx(Fragment$1, { children: Array.from(registeredActionConfigs.entries()).map(([key, config]) => {
			const Component = config.component;
			return /* @__PURE__ */ jsx(Component, { action: config.action }, key);
		}) });
	}, [registeredActionConfigs]);
	const copilotContextValue = useMemo(() => ({
		actions,
		chatComponentsCache,
		getFunctionCallHandler,
		setAction,
		removeAction,
		setRegisteredActions: handleSetRegisteredActions,
		removeRegisteredAction: handleRemoveRegisteredAction,
		getContextString,
		addContext,
		removeContext,
		getAllContext,
		getDocumentsContext,
		addDocumentContext,
		removeDocumentContext,
		copilotApiConfig,
		isLoading,
		setIsLoading,
		chatSuggestionConfiguration,
		addChatSuggestionConfiguration,
		removeChatSuggestionConfiguration,
		chatInstructions,
		setChatInstructions,
		additionalInstructions,
		setAdditionalInstructions,
		showDevConsole,
		coagentStates,
		setCoagentStates,
		coagentStatesRef,
		setCoagentStatesWithRef,
		agentSession,
		setAgentSession,
		forwardedParameters,
		agentLock,
		threadId,
		setThreadId,
		runId,
		setRunId,
		chatAbortControllerRef,
		availableAgents,
		authConfig_c: props.authConfig_c,
		authStates_c: authStates,
		setAuthStates_c: updateAuthStates,
		extensions,
		setExtensions: updateExtensions,
		interruptActions,
		setInterruptAction,
		removeInterruptAction,
		interruptEventQueue,
		addInterruptEvent,
		resolveInterruptEvent,
		bannerError,
		setBannerError,
		onError: handleErrors,
		internalErrorHandlers,
		setInternalErrorHandler,
		removeInternalErrorHandler
	}), [
		actions,
		chatComponentsCache,
		getFunctionCallHandler,
		setAction,
		removeAction,
		handleSetRegisteredActions,
		handleRemoveRegisteredAction,
		getContextString,
		addContext,
		removeContext,
		getAllContext,
		getDocumentsContext,
		addDocumentContext,
		removeDocumentContext,
		copilotApiConfig,
		isLoading,
		chatSuggestionConfiguration,
		addChatSuggestionConfiguration,
		removeChatSuggestionConfiguration,
		chatInstructions,
		additionalInstructions,
		showDevConsole,
		coagentStates,
		setCoagentStatesWithRef,
		agentSession,
		setAgentSession,
		forwardedParameters,
		agentLock,
		threadId,
		setThreadId,
		runId,
		availableAgents,
		props.authConfig_c,
		authStates,
		updateAuthStates,
		extensions,
		updateExtensions,
		interruptActions,
		setInterruptAction,
		removeInterruptAction,
		interruptEventQueue,
		addInterruptEvent,
		resolveInterruptEvent,
		bannerError,
		handleErrors,
		internalErrorHandlers,
		setInternalErrorHandler,
		removeInternalErrorHandler
	]);
	return /* @__PURE__ */ jsx(CopilotChatConfigurationProvider, {
		agentId: props.agent ?? "default",
		threadId,
		hasExplicitThreadId: isThreadIdExplicit,
		children: /* @__PURE__ */ jsxs(CopilotContext.Provider, {
			value: copilotContextValue,
			children: [
				/* @__PURE__ */ jsx(CopilotListeners, {}),
				/* @__PURE__ */ jsx(CopilotKitErrorBridge, {}),
				/* @__PURE__ */ jsxs(CoAgentStateRendersProvider, { children: [/* @__PURE__ */ jsx(MessagesTapProvider, { children: /* @__PURE__ */ jsxs(CopilotMessages, { children: [/* @__PURE__ */ jsx(React.Fragment, { children: memoizedChildren }, "children"), /* @__PURE__ */ jsx(RegisteredActionsRenderer, {}, "actions")] }) }), bannerError && showDevConsole && /* @__PURE__ */ jsx(UsageBanner, {
					severity: bannerError.severity,
					message: bannerError.message,
					onClose: () => setBannerError(null),
					actions: getErrorActions(bannerError)
				})] })
			]
		})
	});
}
const defaultCopilotContextCategories = ["global"];
function entryPointsToFunctionCallHandler(actions) {
	return async ({ name, args }) => {
		let actionsByFunctionName = {};
		for (let action of actions) actionsByFunctionName[action.name] = action;
		const action = actionsByFunctionName[name];
		let result = void 0;
		if (action) {
			await new Promise((resolve, reject) => {
				flushSync(async () => {
					try {
						result = await action.handler?.(args);
						resolve();
					} catch (error) {
						reject(error);
					}
				});
			});
			await new Promise((resolve) => setTimeout(resolve, 20));
		}
		return result;
	};
}
function formatFeatureName(featureName) {
	return featureName.replace(/_c$/, "").split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
}
function validateProps(props) {
	const cloudFeatures = Object.keys(props).filter((key) => key.endsWith("_c"));
	const hasApiKey = props.publicApiKey || props.publicLicenseKey;
	const hasLocalAgents = Object.keys({
		...props.agents__unsafe_dev_only,
		...props.selfManagedAgents
	}).length > 0;
	if (!props.runtimeUrl && !hasApiKey && !hasLocalAgents) throw new ConfigurationError("Missing required prop: 'runtimeUrl' or 'publicApiKey' or 'publicLicenseKey'");
	if (cloudFeatures.length > 0 && !hasApiKey) throw new MissingPublicApiKeyError(`Missing required prop: 'publicApiKey' or 'publicLicenseKey' to use cloud features: ${cloudFeatures.map(formatFeatureName).join(", ")}`);
}

//#endregion
export { useCapabilities as $, CopilotChatMessageView as A, CopilotChatAudioRecorder as At, CopilotChatAssistantMessage_default as B, CopilotModalHeader as C, MCPAppsActivityRenderer as Ct, CopilotChat as D, useRenderToolCall as Dt, DefaultOpenIcon as E, CopilotKitInspector as Et, CopilotChatSuggestionView as F, useLearnFromUserActionInCurrentThread as G, useLearningContainersInCurrentThread as H, CopilotChatSuggestionPill as I, useThreads$1 as J, useLearnFromUserAction as K, CopilotChatReasoningMessage_default as L, IntelligenceIndicator as M, useCopilotChatConfiguration as Mt, getIntelligenceTurnAnchors as N, CopilotChatView_default as O, CopilotChatInput_default as Ot, IntelligenceIndicatorView as P, useAgentContext as Q, CopilotChatUserMessage_default as R, CopilotSidebarView as S, MCPAppsActivityContentSchema as St, DefaultCloseIcon as T, ɵrunMcpFollowUp as Tt, useLearningContainers as U, CopilotChatToolCallsView as V, useAttachments as W, useConfigureSuggestions as X, useInterrupt as Y, useSuggestions as Z, WildcardToolCallRender as _, OpenGenerativeUIActivityType as _t, ThreadsProvider as a, useComponent as at, CopilotSidebar as b, SandboxFunctionsContext as bt, CoAgentStateRendersProvider as c, useRenderCustomMessages as ct, shouldShowDevConsole as d, useLicenseContext$1 as dt, UseAgentUpdate as et, useToast as f, CopilotKitCoreReact as ft, useCopilotContext as g, OpenGenerativeUIActivityRenderer as gt, CopilotContext as h, GenerateSandboxedUiArgsSchema as ht, ThreadsContext as i, useRenderTool as it, INTELLIGENCE_TURN_HEAD as j, CopilotChatConfigurationProvider as jt, CopilotChatAttachmentQueue as k, AudioRecorderError as kt, useCoAgentStateRenders as l, CopilotKitProvider as lt, useCopilotMessagesContext as m, createA2UIMessageRenderer as mt, defaultCopilotContextCategories as n, useHumanInTheLoop as nt, useThreads as o, useFrontendTool as ot, CopilotMessagesContext as p, defineToolCallRenderer as pt, useMemories as q, CoAgentStateRenderBridge as r, useDefaultRenderTool as rt, CoAgentStateRendersContext as s, useRenderActivityMessage as st, CopilotKit as t, useAgent as tt, useAsyncCallback as u, useCopilotKit$1 as ut, CopilotThreadsDrawer as v, OpenGenerativeUIContentSchema as vt, CopilotChatToggleButton as w, MCPAppsActivityType as wt, CopilotPopupView as x, useSandboxFunctions as xt, CopilotPopup as y, OpenGenerativeUIToolRenderer as yt, CopilotChatAttachmentRenderer as z };
//# sourceMappingURL=copilotkit-ykQW_VJZ.mjs.map