@copilotkit/react-core 1.55.2-next.0 → 1.55.2-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/dist/copilotkit-BuhSUZHb.d.mts.map +1 -1
- package/dist/{copilotkit-OhEIYGcY.mjs → copilotkit-Cd-NrDyp.mjs} +42 -15
- package/dist/copilotkit-Cd-NrDyp.mjs.map +1 -0
- package/dist/{copilotkit-7z4C8joY.cjs → copilotkit-Dgdpbqjt.cjs} +42 -15
- package/dist/copilotkit-Dgdpbqjt.cjs.map +1 -0
- package/dist/copilotkit-dwDWYpya.d.cts.map +1 -1
- package/dist/index.cjs +6 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +6 -3
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +23 -27
- package/dist/index.umd.js.map +1 -1
- package/dist/v2/index.cjs +1 -1
- package/dist/v2/index.mjs +1 -1
- package/dist/v2/index.umd.js +47 -26
- package/dist/v2/index.umd.js.map +1 -1
- package/package.json +6 -6
- package/src/components/copilot-provider/copilotkit.tsx +2 -2
- package/src/hooks/use-agent-nodename.ts +3 -0
- package/src/hooks/use-coagent-state-render-bridge.helpers.ts +2 -1
- package/src/hooks/use-coagent-state-render-registry.ts +6 -6
- package/src/hooks/use-copilot-chat_internal.ts +1 -1
- package/src/lib/copilot-task.ts +1 -1
- package/src/utils/utils.ts +0 -2
- package/src/v2/a2ui/A2UIMessageRenderer.tsx +1 -1
- package/src/v2/components/chat/CopilotChatMessageView.tsx +41 -5
- package/src/v2/components/chat/__tests__/CopilotChatMessageView.test.tsx +192 -82
- package/src/v2/providers/CopilotChatConfigurationProvider.tsx +2 -2
- package/dist/copilotkit-7z4C8joY.cjs.map +0 -1
- package/dist/copilotkit-OhEIYGcY.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"copilotkit-7z4C8joY.cjs","names":["React","DEFAULT_AGENT_ID","twMerge","Slot","TooltipPrimitive","DropdownMenuPrimitive","ChevronRightIcon","Square","Loader2","ArrowUp","Mic","X","Check","Plus","React","z","z","React","ToolCallStatus","z","DEFAULT_SURFACE_ID","A2UIProvider","A2UIRenderer","z","z","A2UI_SCHEMA_CONTEXT_DESCRIPTION","A2UI_DEFAULT_GENERATION_GUIDELINES","A2UI_DEFAULT_DESIGN_GUIDELINES","CopilotKitCore","COPILOT_CLOUD_CHAT_URL","viewerTheme","z","React","ToolCallStatus","DEFAULT_AGENT_ID","HttpAgent","DEFAULT_AGENT_ID","CopilotKitCoreRuntimeConnectionStatus","ProxiedCopilotRuntimeAgent","DEFAULT_AGENT_ID","EMPTY_DEPS","React","DEFAULT_AGENT_ID","DEFAULT_AGENT_ID","useThreads","ɵselectThreads","ɵselectThreadsIsLoading","ɵselectThreadsError","ɵselectHasNextPage","ɵselectIsFetchingNextPage","React","Streamdown","Check","Copy","ThumbsUp","ThumbsDown","Volume2","RefreshCw","Check","Copy","Edit","ChevronLeft","ChevronRight","ChevronRight","Streamdown","React","Loader2","React","React","React","CopilotChatAssistantMessage","CopilotChatUserMessage","CopilotChatReasoningMessage","X","Play","Upload","CopilotChatInput","StickToBottom","ChevronDown","TranscriptionErrorCode","DEFAULT_AGENT_ID","HttpAgent","TranscriptionErrorCode","MessageCircle","X","React","X","CopilotChatView","CopilotChatView","CopilotChatView","CopilotPopupView","CopilotChatView","emptyCopilotContext","React","setsHaveIntersection","React","Severity","CopilotKitApiDiscoveryError","CopilotKitRemoteEndpointDiscoveryError","CopilotKitAgentDiscoveryError","CopilotKitError","ErrorVisibility","CopilotKitErrorCode","Severity","CopilotKitErrorCode","COPILOT_CLOUD_API_URL","COPILOT_CLOUD_PUBLIC_API_KEY_HEADER","ReactMarkdown","React","CopilotKitError","CopilotKitLowLevelError","CopilotKitV2Provider","COPILOT_CLOUD_CHAT_URL","COPILOT_CLOUD_PUBLIC_API_KEY_HEADER","React","ConfigurationError","MissingPublicApiKeyError"],"sources":["../src/v2/lib/slots.tsx","../src/v2/providers/CopilotChatConfigurationProvider.tsx","../src/v2/lib/utils.ts","../src/v2/components/ui/button.tsx","../src/v2/components/ui/tooltip.tsx","../src/v2/components/ui/dropdown-menu.tsx","../src/v2/components/chat/CopilotChatAudioRecorder.tsx","../src/v2/components/chat/CopilotChatInput.tsx","../src/v2/hooks/useKatexStyles.ts","../src/v2/components/CopilotKitInspector.tsx","../src/v2/components/license-warning-banner.tsx","../src/v2/components/MCPAppsActivityRenderer.tsx","../src/v2/providers/SandboxFunctionsContext.ts","../src/v2/lib/processPartialHtml.ts","../src/v2/components/OpenGenerativeUIRenderer.tsx","../src/v2/a2ui/A2UIMessageRenderer.tsx","../src/v2/types/defineToolCallRenderer.ts","../src/v2/a2ui/A2UIToolCallRenderer.tsx","../src/v2/hooks/use-agent-context.tsx","../src/v2/a2ui/A2UICatalogContext.tsx","../src/v2/lib/react-core.ts","../src/v2/providers/CopilotKitProvider.tsx","../src/v2/hooks/use-render-tool-call.tsx","../src/v2/hooks/use-agent.tsx","../src/v2/hooks/use-render-custom-messages.tsx","../src/v2/hooks/use-render-activity-message.tsx","../src/v2/hooks/use-frontend-tool.tsx","../src/v2/hooks/use-component.tsx","../src/v2/hooks/use-render-tool.tsx","../src/v2/hooks/use-default-render-tool.tsx","../src/v2/hooks/use-human-in-the-loop.tsx","../src/v2/hooks/use-suggestions.tsx","../src/v2/hooks/use-configure-suggestions.tsx","../src/v2/hooks/use-interrupt.tsx","../src/v2/hooks/use-threads.tsx","../src/v2/hooks/use-attachments.tsx","../src/v2/components/chat/CopilotChatToolCallsView.tsx","../src/v2/components/chat/CopilotChatAssistantMessage.tsx","../src/v2/components/chat/CopilotChatAttachmentRenderer.tsx","../src/v2/components/chat/CopilotChatUserMessage.tsx","../src/v2/components/chat/CopilotChatReasoningMessage.tsx","../src/v2/components/chat/CopilotChatSuggestionPill.tsx","../src/v2/components/chat/CopilotChatSuggestionView.tsx","../src/v2/components/chat/scroll-element-context.ts","../src/v2/components/chat/CopilotChatMessageView.tsx","../src/v2/components/chat/CopilotChatAttachmentQueue.tsx","../src/v2/hooks/use-keyboard-height.tsx","../src/v2/components/chat/CopilotChatView.tsx","../src/v2/lib/transcription-client.ts","../src/v2/components/chat/CopilotChat.tsx","../src/v2/components/chat/CopilotChatToggleButton.tsx","../src/v2/components/chat/CopilotModalHeader.tsx","../src/v2/components/chat/CopilotSidebarView.tsx","../src/v2/components/chat/CopilotPopupView.tsx","../src/v2/components/chat/CopilotSidebar.tsx","../src/v2/components/chat/CopilotPopup.tsx","../src/v2/components/WildcardToolCallRender.tsx","../src/context/copilot-context.tsx","../src/hooks/use-tree.ts","../src/hooks/use-flat-category-store.ts","../src/context/copilot-messages-context.tsx","../src/components/toast/toast-provider.tsx","../src/utils/dev-console.ts","../src/components/copilot-provider/copilot-messages.tsx","../src/components/usage-banner.tsx","../src/lib/status-checker.ts","../src/components/toast/exclamation-mark-icon.tsx","../src/components/error-boundary/error-utils.tsx","../src/components/error-boundary/error-boundary.tsx","../src/context/coagent-state-renders-context.tsx","../src/context/threads-context.tsx","../src/hooks/use-coagent-state-render-bridge.helpers.ts","../src/hooks/use-coagent-state-render-registry.ts","../src/hooks/use-coagent-state-render-bridge.tsx","../src/components/CopilotListeners.tsx","../src/components/copilot-provider/copilotkit.tsx"],"sourcesContent":["import React, { useRef } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\n/** Existing union (unchanged) */\nexport type SlotValue<C extends React.ComponentType<any>> =\n | C\n | string\n | Partial<React.ComponentProps<C>>;\n\n/**\n * Shallow equality comparison for objects.\n */\nexport function shallowEqual<T extends Record<string, unknown>>(\n obj1: T,\n obj2: T,\n): boolean {\n const keys1 = Object.keys(obj1);\n const keys2 = Object.keys(obj2);\n\n if (keys1.length !== keys2.length) return false;\n\n for (const key of keys1) {\n if (obj1[key] !== obj2[key]) return false;\n }\n\n return true;\n}\n\n/**\n * Returns true only for plain JS objects (`{}`), excluding arrays, Dates,\n * class instances, and other exotic objects that happen to have typeof \"object\".\n */\nfunction isPlainObject(obj: unknown): obj is Record<string, unknown> {\n return (\n obj !== null &&\n typeof obj === \"object\" &&\n Object.prototype.toString.call(obj) === \"[object Object]\"\n );\n}\n\n/**\n * Returns the same reference as long as the value is shallowly equal to the\n * previous render's value.\n *\n * - Identical references bail out immediately (O(1)).\n * - Plain objects ({}) are shallow-compared key-by-key.\n * - Arrays, Dates, class instances, functions, and primitives are compared by\n * reference only — shallowEqual is never called on non-plain objects, which\n * avoids incorrect equality for e.g. [1,2] vs [1,2] (different arrays).\n *\n * Typical use: stabilize inline slot props so MemoizedSlotWrapper's shallow\n * equality check isn't defeated by a new object reference on every render.\n */\nexport function useShallowStableRef<T>(value: T): T {\n const ref = useRef(value);\n\n // 1. Identical reference — bail early, no comparison needed.\n if (ref.current === value) return ref.current;\n\n // 2. Both are plain objects — shallow-compare to detect structural equality.\n if (isPlainObject(ref.current) && isPlainObject(value)) {\n if (shallowEqual(ref.current, value)) return ref.current;\n }\n\n // 3. Different values (or non-comparable types) — update the ref.\n ref.current = value;\n return ref.current;\n}\n\n/** Utility: concrete React elements for every slot */\ntype SlotElements<S> = { [K in keyof S]: React.ReactElement };\n\nexport type WithSlots<\n S extends Record<string, React.ComponentType<any>>,\n Rest = {},\n> = {\n /** Per‑slot overrides */\n [K in keyof S]?: SlotValue<S[K]>;\n} & {\n children?: (props: SlotElements<S> & Rest) => React.ReactNode;\n} & Omit<Rest, \"children\">;\n\n/**\n * Check if a value is a React component type (function, class, forwardRef, memo, etc.)\n */\nexport function isReactComponentType(\n value: unknown,\n): value is React.ComponentType<any> {\n if (typeof value === \"function\") {\n return true;\n }\n // forwardRef, memo, lazy have $$typeof but are not valid elements\n if (\n value &&\n typeof value === \"object\" &&\n \"$$typeof\" in value &&\n !React.isValidElement(value)\n ) {\n return true;\n }\n return false;\n}\n\n/**\n * Internal function to render a slot value as a React element (non-memoized).\n */\nfunction renderSlotElement(\n slot: SlotValue<React.ComponentType<any>> | undefined,\n DefaultComponent: React.ComponentType<any>,\n props: Record<string, unknown>,\n): React.ReactElement {\n if (typeof slot === \"string\") {\n // When slot is a string, treat it as a className and merge with existing className\n const existingClassName = props.className as string | undefined;\n return React.createElement(DefaultComponent, {\n ...props,\n className: twMerge(existingClassName, slot),\n });\n }\n\n // Check if slot is a React component type (function, forwardRef, memo, etc.)\n if (isReactComponentType(slot)) {\n return React.createElement(slot, props);\n }\n\n // If slot is a plain object (not a React element), treat it as props override\n if (slot && typeof slot === \"object\" && !React.isValidElement(slot)) {\n return React.createElement(DefaultComponent, {\n ...props,\n ...slot,\n });\n }\n\n return React.createElement(DefaultComponent, props);\n}\n\n/**\n * Internal memoized wrapper component for renderSlot.\n * Uses forwardRef to support ref forwarding.\n */\nconst MemoizedSlotWrapper = React.memo(\n React.forwardRef<unknown, any>(function MemoizedSlotWrapper(props, ref) {\n const { $slot, $component, ...rest } = props;\n const propsWithRef: Record<string, unknown> =\n ref !== null ? { ...rest, ref } : rest;\n return renderSlotElement($slot, $component, propsWithRef);\n }),\n (prev: any, next: any) => {\n // Compare slot and component references\n if (prev.$slot !== next.$slot) return false;\n if (prev.$component !== next.$component) return false;\n\n // Shallow compare remaining props (ref is handled separately by React)\n const { $slot: _ps, $component: _pc, ...prevRest } = prev;\n const { $slot: _ns, $component: _nc, ...nextRest } = next;\n return shallowEqual(\n prevRest as Record<string, unknown>,\n nextRest as Record<string, unknown>,\n );\n },\n);\n\n/**\n * Renders a slot value as a memoized React element.\n * Automatically prevents unnecessary re-renders using shallow prop comparison.\n * Supports ref forwarding.\n *\n * @example\n * renderSlot(customInput, CopilotChatInput, { onSubmit: handleSubmit })\n */\nexport function renderSlot<\n C extends React.ComponentType<any>,\n P = React.ComponentProps<C>,\n>(\n slot: SlotValue<C> | undefined,\n DefaultComponent: C,\n props: P,\n): React.ReactElement {\n return React.createElement(MemoizedSlotWrapper, {\n ...props,\n $slot: slot,\n $component: DefaultComponent,\n } as any);\n}\n","import React, {\n createContext,\n useCallback,\n useContext,\n ReactNode,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { DEFAULT_AGENT_ID, randomUUID } from \"@copilotkit/shared\";\nimport { useShallowStableRef } from \"../lib/slots\";\n\n// Default labels\nexport const CopilotChatDefaultLabels = {\n chatInputPlaceholder: \"Type a message...\",\n chatInputToolbarStartTranscribeButtonLabel: \"Transcribe\",\n chatInputToolbarCancelTranscribeButtonLabel: \"Cancel\",\n chatInputToolbarFinishTranscribeButtonLabel: \"Finish\",\n chatInputToolbarAddButtonLabel: \"Add attachments\",\n chatInputToolbarToolsButtonLabel: \"Tools\",\n assistantMessageToolbarCopyCodeLabel: \"Copy\",\n assistantMessageToolbarCopyCodeCopiedLabel: \"Copied\",\n assistantMessageToolbarCopyMessageLabel: \"Copy\",\n assistantMessageToolbarThumbsUpLabel: \"Good response\",\n assistantMessageToolbarThumbsDownLabel: \"Bad response\",\n assistantMessageToolbarReadAloudLabel: \"Read aloud\",\n assistantMessageToolbarRegenerateLabel: \"Regenerate\",\n userMessageToolbarCopyMessageLabel: \"Copy\",\n userMessageToolbarEditMessageLabel: \"Edit\",\n chatDisclaimerText:\n \"AI can make mistakes. Please verify important information.\",\n chatToggleOpenLabel: \"Open chat\",\n chatToggleCloseLabel: \"Close chat\",\n modalHeaderTitle: \"CopilotKit Chat\",\n welcomeMessageText: \"How can I help you today?\",\n};\n\nexport type CopilotChatLabels = typeof CopilotChatDefaultLabels;\n\n// Define the full configuration interface\nexport interface CopilotChatConfigurationValue {\n labels: CopilotChatLabels;\n agentId: string;\n threadId: string;\n isModalOpen: boolean;\n setModalOpen: (open: boolean) => void;\n}\n\n// Create the configuration context\nconst CopilotChatConfiguration =\n createContext<CopilotChatConfigurationValue | null>(null);\n\n// Provider props interface\nexport interface CopilotChatConfigurationProviderProps {\n children: ReactNode;\n labels?: Partial<CopilotChatLabels>;\n agentId?: string;\n threadId?: string;\n isModalDefaultOpen?: boolean;\n}\n\n// Provider component\nexport const CopilotChatConfigurationProvider: React.FC<\n CopilotChatConfigurationProviderProps\n> = ({ children, labels, agentId, threadId, isModalDefaultOpen }) => {\n const parentConfig = useContext(CopilotChatConfiguration);\n\n // Stabilize labels references so that inline objects (new reference on every\n // parent render) don't invalidate mergedLabels and churn the context value.\n // parentConfig?.labels is already stabilized by the parent provider's own\n // useShallowStableRef, so we only need to stabilize the local labels prop.\n const stableLabels = useShallowStableRef(labels);\n const mergedLabels: CopilotChatLabels = useMemo(\n () => ({\n ...CopilotChatDefaultLabels,\n ...(parentConfig?.labels ?? {}),\n ...(stableLabels ?? {}),\n }),\n [stableLabels, parentConfig?.labels],\n );\n\n const resolvedAgentId = agentId ?? parentConfig?.agentId ?? DEFAULT_AGENT_ID;\n\n const resolvedThreadId = useMemo(() => {\n if (threadId) {\n return threadId;\n }\n if (parentConfig?.threadId) {\n return parentConfig.threadId;\n }\n return randomUUID();\n }, [threadId, parentConfig?.threadId]);\n\n const resolvedDefaultOpen = isModalDefaultOpen ?? true;\n\n const [internalModalOpen, setInternalModalOpen] =\n useState<boolean>(resolvedDefaultOpen);\n\n const hasExplicitDefault = isModalDefaultOpen !== undefined;\n\n // When this provider owns its modal state, wrap the setter so that changes\n // propagate upward to any ancestor provider. This allows an outer\n // CopilotChatConfigurationProvider (e.g. a user's layout-level provider) to\n // observe open/close events that originate deep in the tree — fixing the\n // \"outer hook always returns true\" regression (CPK-7152 Behavior B).\n const setAndSync = useCallback(\n (open: boolean) => {\n setInternalModalOpen(open);\n parentConfig?.setModalOpen(open);\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [parentConfig?.setModalOpen],\n );\n\n // Sync parent → child: when an ancestor's modal state is changed externally\n // (e.g. the user calls setModalOpen from an outer hook), reflect that change\n // in our own state so the sidebar/popup responds accordingly.\n // Skip the initial mount so that our own isModalDefaultOpen is respected and\n // not immediately overwritten by the parent's current value.\n const isMounted = useRef(false);\n useEffect(() => {\n if (!hasExplicitDefault) return;\n if (!isMounted.current) {\n isMounted.current = true;\n return;\n }\n if (parentConfig?.isModalOpen === undefined) return;\n setInternalModalOpen(parentConfig.isModalOpen);\n }, [parentConfig?.isModalOpen, hasExplicitDefault]);\n\n const resolvedIsModalOpen = hasExplicitDefault\n ? internalModalOpen\n : (parentConfig?.isModalOpen ?? internalModalOpen);\n const resolvedSetModalOpen = hasExplicitDefault\n ? setAndSync\n : (parentConfig?.setModalOpen ?? setInternalModalOpen);\n\n const configurationValue: CopilotChatConfigurationValue = useMemo(\n () => ({\n labels: mergedLabels,\n agentId: resolvedAgentId,\n threadId: resolvedThreadId,\n isModalOpen: resolvedIsModalOpen,\n setModalOpen: resolvedSetModalOpen,\n }),\n [\n mergedLabels,\n resolvedAgentId,\n resolvedThreadId,\n resolvedIsModalOpen,\n resolvedSetModalOpen,\n ],\n );\n\n return (\n <CopilotChatConfiguration.Provider value={configurationValue}>\n {children}\n </CopilotChatConfiguration.Provider>\n );\n};\n\n// Hook to use the full configuration\nexport const useCopilotChatConfiguration =\n (): CopilotChatConfigurationValue | null => {\n const configuration = useContext(CopilotChatConfiguration);\n return configuration;\n };\n","import { clsx, type ClassValue } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge({ prefix: \"cpk\" });\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst buttonVariants = cva(\n \"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\",\n {\n variants: {\n variant: {\n default:\n \"cpk:bg-primary cpk:text-primary-foreground cpk:shadow-xs cpk:hover:bg-primary/90\",\n destructive:\n \"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\",\n outline:\n \"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\",\n secondary:\n \"cpk:bg-secondary cpk:text-secondary-foreground cpk:shadow-xs cpk:hover:bg-secondary/80\",\n ghost:\n \"cpk:hover:bg-accent cpk:hover:text-accent-foreground cpk:dark:hover:bg-accent/50 cpk:cursor-pointer\",\n link: \"cpk:text-primary cpk:underline-offset-4 cpk:hover:underline\",\n assistantMessageToolbarButton: [\n \"cpk:cursor-pointer\",\n // Background and text\n \"cpk:p-0 cpk:text-[rgb(93,93,93)] cpk:hover:bg-[#E8E8E8]\",\n // Dark mode - lighter gray for better contrast\n \"cpk:dark:text-[rgb(243,243,243)] cpk:dark:hover:bg-[#303030]\",\n // Shape and sizing\n \"cpk:h-8 cpk:w-8\",\n // Interactions\n \"cpk:transition-colors\",\n // Hover states\n \"cpk:hover:text-[rgb(93,93,93)]\",\n \"cpk:dark:hover:text-[rgb(243,243,243)]\",\n ],\n chatInputToolbarPrimary: [\n \"cpk:cursor-pointer\",\n // Background and text\n \"cpk:bg-black cpk:text-white\",\n // Dark mode\n \"cpk:dark:bg-white cpk:dark:text-black cpk:dark:focus-visible:outline-white\",\n // Shape and sizing\n \"cpk:rounded-full\",\n // Interactions\n \"cpk:transition-colors\",\n // Focus states\n \"cpk:focus:outline-none\",\n // Hover states\n \"cpk:hover:opacity-70 cpk:disabled:hover:opacity-100\",\n // Disabled states\n \"cpk:disabled:cursor-not-allowed cpk:disabled:bg-[#00000014] cpk:disabled:text-[rgb(13,13,13)]\",\n \"cpk:dark:disabled:bg-[#454545] cpk:dark:disabled:text-white \",\n ],\n chatInputToolbarSecondary: [\n \"cpk:cursor-pointer\",\n // Background and text\n \"cpk:bg-transparent cpk:text-[#444444]\",\n // Dark mode\n \"cpk:dark:text-white cpk:dark:border-[#404040]\",\n // Shape and sizing\n \"cpk:rounded-full\",\n // Interactions\n \"cpk:transition-colors\",\n // Focus states\n \"cpk:focus:outline-none\",\n // Hover states\n \"cpk:hover:bg-[#f8f8f8] cpk:hover:text-[#333333]\",\n \"cpk:dark:hover:bg-[#404040] cpk:dark:hover:text-[#FFFFFF]\",\n // Disabled states\n \"cpk:disabled:cursor-not-allowed cpk:disabled:opacity-50\",\n \"cpk:disabled:hover:bg-transparent cpk:disabled:hover:text-[#444444]\",\n \"cpk:dark:disabled:hover:bg-transparent cpk:dark:disabled:hover:text-[#CCCCCC]\",\n ],\n },\n size: {\n default: \"cpk:h-9 cpk:px-4 cpk:py-2 cpk:has-[>svg]:px-3\",\n sm: \"cpk:h-8 cpk:rounded-md cpk:gap-1.5 cpk:px-3 cpk:has-[>svg]:px-2.5\",\n lg: \"cpk:h-10 cpk:rounded-md cpk:px-6 cpk:has-[>svg]:px-4\",\n icon: \"cpk:size-9\",\n chatInputToolbarIcon: [\n // Shape and sizing\n \"cpk:h-9 cpk:w-9 cpk:rounded-full\",\n ],\n chatInputToolbarIconLabel: [\n // Shape and sizing\n \"cpk:h-9 cpk:px-3 cpk:rounded-full\",\n // Layout\n \"cpk:gap-2\",\n // Typography\n \"cpk:font-normal\",\n ],\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nfunction Button({\n className,\n variant,\n size,\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n }) {\n const Comp = asChild ? Slot : \"button\";\n\n return (\n <Comp\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n );\n}\n\nexport { Button, buttonVariants };\n","import * as React from \"react\";\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\n\nimport { cn } from \"../../lib/utils\";\n\nfunction TooltipProvider({\n delayDuration = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delayDuration={delayDuration}\n {...props}\n />\n );\n}\n\nfunction Tooltip({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n return (\n <TooltipProvider>\n <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n </TooltipProvider>\n );\n}\n\nfunction TooltipTrigger({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />;\n}\n\nfunction TooltipContent({\n className,\n sideOffset = 0,\n children,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-copilotkit\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n \"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\",\n className,\n )}\n {...props}\n >\n {children}\n <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]\" />\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n );\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\";\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\";\n\nimport { cn } from \"../../lib/utils\";\n\nfunction DropdownMenu({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />;\n}\n\nfunction DropdownMenuPortal({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n return (\n <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n );\n}\n\nfunction DropdownMenuTrigger({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n return (\n <DropdownMenuPrimitive.Trigger\n data-slot=\"dropdown-menu-trigger\"\n {...props}\n />\n );\n}\n\nfunction DropdownMenuContent({\n className,\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-copilotkit\n data-slot=\"dropdown-menu-content\"\n sideOffset={sideOffset}\n className={cn(\n \"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\",\n className,\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n );\n}\n\nfunction DropdownMenuGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n return (\n <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n );\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean;\n variant?: \"default\" | \"destructive\";\n}) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"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\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n className={cn(\n \"cpk:focus:bg-accent cpk:focus:text-accent-foreground cpk:relative cpk:flex cpk:cursor-default cpk:items-center cpk:gap-2 cpk:rounded-sm cpk:py-1.5 cpk:pr-2 cpk:pl-8 cpk:text-sm cpk:outline-hidden cpk:select-none cpk:data-[disabled]:pointer-events-none cpk:data-[disabled]:opacity-50 cpk:[&_svg]:pointer-events-none cpk:[&_svg]:shrink-0 cpk:[&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n checked={checked}\n {...props}\n >\n <span className=\"cpk:pointer-events-none cpk:absolute cpk:left-2 cpk:flex cpk:size-3.5 cpk:items-center cpk:justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CheckIcon className=\"cpk:size-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n );\n}\n\nfunction DropdownMenuRadioGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n return (\n <DropdownMenuPrimitive.RadioGroup\n data-slot=\"dropdown-menu-radio-group\"\n {...props}\n />\n );\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n return (\n <DropdownMenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n className={cn(\n \"cpk:focus:bg-accent cpk:focus:text-accent-foreground cpk:relative cpk:flex cpk:cursor-default cpk:items-center cpk:gap-2 cpk:rounded-sm cpk:py-1.5 cpk:pr-2 cpk:pl-8 cpk:text-sm cpk:outline-hidden cpk:select-none cpk:data-[disabled]:pointer-events-none cpk:data-[disabled]:opacity-50 cpk:[&_svg]:pointer-events-none cpk:[&_svg]:shrink-0 cpk:[&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n >\n <span className=\"cpk:pointer-events-none cpk:absolute cpk:left-2 cpk:flex cpk:size-3.5 cpk:items-center cpk:justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CircleIcon className=\"cpk:size-2 cpk:fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n );\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\n \"cpk:px-2 cpk:py-1.5 cpk:text-sm cpk:font-medium cpk:data-[inset]:pl-8\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn(\"cpk:bg-border cpk:-mx-1 cpk:my-1 cpk:h-px\", className)}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\n \"cpk:text-muted-foreground cpk:ml-auto cpk:text-xs cpk:tracking-widest\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSub({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />;\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"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\",\n className,\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"cpk:ml-auto cpk:size-4\" />\n </DropdownMenuPrimitive.SubTrigger>\n );\n}\n\nfunction DropdownMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\n \"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\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport {\n DropdownMenu,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n};\n","import {\n useRef,\n useEffect,\n useImperativeHandle,\n forwardRef,\n useCallback,\n useState,\n} from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\n/** Finite-state machine for every recorder implementation */\nexport type AudioRecorderState = \"idle\" | \"recording\" | \"processing\";\n\n/** Error subclass so callers can `instanceof`-guard recorder failures */\nexport class AudioRecorderError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"AudioRecorderError\";\n }\n}\n\nexport interface AudioRecorderRef {\n state: AudioRecorderState;\n start: () => Promise<void>;\n stop: () => Promise<Blob>;\n dispose: () => void;\n}\n\nexport const CopilotChatAudioRecorder = forwardRef<\n AudioRecorderRef,\n React.HTMLAttributes<HTMLDivElement>\n>((props, ref) => {\n const { className, ...divProps } = props;\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n // Recording state\n const [recorderState, setRecorderState] =\n useState<AudioRecorderState>(\"idle\");\n const mediaRecorderRef = useRef<MediaRecorder | null>(null);\n const audioChunksRef = useRef<Blob[]>([]);\n const streamRef = useRef<MediaStream | null>(null);\n const analyserRef = useRef<AnalyserNode | null>(null);\n const audioContextRef = useRef<AudioContext | null>(null);\n const animationIdRef = useRef<number | null>(null);\n\n // Amplitude history buffer for scrolling waveform\n const amplitudeHistoryRef = useRef<number[]>([]);\n const frameCountRef = useRef<number>(0);\n const scrollOffsetRef = useRef<number>(0);\n const smoothedAmplitudeRef = useRef<number>(0);\n const fadeOpacityRef = useRef<number>(0);\n\n // Clean up all resources\n const cleanup = useCallback(() => {\n if (animationIdRef.current) {\n cancelAnimationFrame(animationIdRef.current);\n animationIdRef.current = null;\n }\n if (\n mediaRecorderRef.current &&\n mediaRecorderRef.current.state !== \"inactive\"\n ) {\n try {\n mediaRecorderRef.current.stop();\n } catch {\n // Ignore errors during cleanup\n }\n }\n if (streamRef.current) {\n streamRef.current.getTracks().forEach((track) => track.stop());\n streamRef.current = null;\n }\n if (audioContextRef.current && audioContextRef.current.state !== \"closed\") {\n audioContextRef.current.close().catch(() => {\n // Ignore close errors\n });\n audioContextRef.current = null;\n }\n mediaRecorderRef.current = null;\n analyserRef.current = null;\n audioChunksRef.current = [];\n amplitudeHistoryRef.current = [];\n frameCountRef.current = 0;\n scrollOffsetRef.current = 0;\n smoothedAmplitudeRef.current = 0;\n fadeOpacityRef.current = 0;\n }, []);\n\n // Start recording\n const start = useCallback(async () => {\n if (recorderState !== \"idle\") {\n throw new AudioRecorderError(\"Recorder is already active\");\n }\n\n try {\n // Request microphone access\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n streamRef.current = stream;\n\n // Set up audio context for visualization\n const audioContext = new AudioContext();\n audioContextRef.current = audioContext;\n const source = audioContext.createMediaStreamSource(stream);\n const analyser = audioContext.createAnalyser();\n analyser.fftSize = 2048; // Higher resolution for time-domain waveform\n source.connect(analyser);\n analyserRef.current = analyser;\n\n // Determine best MIME type for recording\n const mimeType = MediaRecorder.isTypeSupported(\"audio/webm;codecs=opus\")\n ? \"audio/webm;codecs=opus\"\n : MediaRecorder.isTypeSupported(\"audio/webm\")\n ? \"audio/webm\"\n : MediaRecorder.isTypeSupported(\"audio/mp4\")\n ? \"audio/mp4\"\n : \"\";\n\n const options: MediaRecorderOptions = mimeType ? { mimeType } : {};\n const mediaRecorder = new MediaRecorder(stream, options);\n mediaRecorderRef.current = mediaRecorder;\n audioChunksRef.current = [];\n\n mediaRecorder.ondataavailable = (event) => {\n if (event.data.size > 0) {\n audioChunksRef.current.push(event.data);\n }\n };\n\n // Start recording with timeslice to collect data periodically\n mediaRecorder.start(100);\n setRecorderState(\"recording\");\n } catch (error) {\n cleanup();\n if (error instanceof Error && error.name === \"NotAllowedError\") {\n throw new AudioRecorderError(\"Microphone permission denied\");\n }\n if (error instanceof Error && error.name === \"NotFoundError\") {\n throw new AudioRecorderError(\"No microphone found\");\n }\n throw new AudioRecorderError(\n error instanceof Error ? error.message : \"Failed to start recording\",\n );\n }\n }, [recorderState, cleanup]);\n\n // Stop recording and return audio blob\n const stop = useCallback((): Promise<Blob> => {\n return new Promise((resolve, reject) => {\n const mediaRecorder = mediaRecorderRef.current;\n if (!mediaRecorder || recorderState !== \"recording\") {\n reject(new AudioRecorderError(\"No active recording\"));\n return;\n }\n\n setRecorderState(\"processing\");\n\n mediaRecorder.onstop = () => {\n const mimeType = mediaRecorder.mimeType || \"audio/webm\";\n const audioBlob = new Blob(audioChunksRef.current, { type: mimeType });\n\n // Clean up but keep the blob\n cleanup();\n setRecorderState(\"idle\");\n resolve(audioBlob);\n };\n\n mediaRecorder.onerror = () => {\n cleanup();\n setRecorderState(\"idle\");\n reject(new AudioRecorderError(\"Recording failed\"));\n };\n\n mediaRecorder.stop();\n });\n }, [recorderState, cleanup]);\n\n // Calculate RMS amplitude from time-domain data\n const calculateAmplitude = (dataArray: Uint8Array): number => {\n let sum = 0;\n for (let i = 0; i < dataArray.length; i++) {\n // Normalize to -1 to 1 range (128 is center/silence)\n const sample = (dataArray[i] ?? 128) / 128 - 1;\n sum += sample * sample;\n }\n return Math.sqrt(sum / dataArray.length);\n };\n\n // Canvas rendering with animation\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n\n // Configuration\n const barWidth = 2;\n const barGap = 1;\n const barSpacing = barWidth + barGap;\n const scrollSpeed = 1 / 3; // Pixels per frame\n\n const draw = () => {\n const rect = canvas.getBoundingClientRect();\n const dpr = window.devicePixelRatio || 1;\n\n // Update canvas dimensions if container resized\n if (\n canvas.width !== rect.width * dpr ||\n canvas.height !== rect.height * dpr\n ) {\n canvas.width = rect.width * dpr;\n canvas.height = rect.height * dpr;\n ctx.scale(dpr, dpr);\n }\n\n // Calculate how many bars fit in the canvas (plus extra for smooth scrolling)\n const maxBars = Math.floor(rect.width / barSpacing) + 2;\n\n // Get current amplitude if recording\n if (analyserRef.current && recorderState === \"recording\") {\n // Pre-fill history with zeros on first frame so line is visible immediately\n if (amplitudeHistoryRef.current.length === 0) {\n amplitudeHistoryRef.current = new Array(maxBars).fill(0);\n }\n\n // Fade in the waveform smoothly\n if (fadeOpacityRef.current < 1) {\n fadeOpacityRef.current = Math.min(1, fadeOpacityRef.current + 0.03);\n }\n\n // Smooth scrolling - increment offset every frame\n scrollOffsetRef.current += scrollSpeed;\n\n // Sample amplitude every frame for smoothing\n const bufferLength = analyserRef.current.fftSize;\n const dataArray = new Uint8Array(bufferLength);\n analyserRef.current.getByteTimeDomainData(dataArray);\n const rawAmplitude = calculateAmplitude(dataArray);\n\n // Smoothing: gradual attack and decay\n const attackSpeed = 0.12; // Smooth rise\n const decaySpeed = 0.08; // Smooth fade out\n const speed =\n rawAmplitude > smoothedAmplitudeRef.current\n ? attackSpeed\n : decaySpeed;\n smoothedAmplitudeRef.current +=\n (rawAmplitude - smoothedAmplitudeRef.current) * speed;\n\n // When offset reaches a full bar width, add a new sample and reset offset\n if (scrollOffsetRef.current >= barSpacing) {\n scrollOffsetRef.current -= barSpacing;\n amplitudeHistoryRef.current.push(smoothedAmplitudeRef.current);\n\n // Trim history to fit canvas\n if (amplitudeHistoryRef.current.length > maxBars) {\n amplitudeHistoryRef.current =\n amplitudeHistoryRef.current.slice(-maxBars);\n }\n }\n }\n\n // Clear canvas\n ctx.clearRect(0, 0, rect.width, rect.height);\n\n // Get current foreground color\n const computedStyle = getComputedStyle(canvas);\n ctx.fillStyle = computedStyle.color;\n ctx.globalAlpha = fadeOpacityRef.current;\n\n const centerY = rect.height / 2;\n const maxAmplitude = rect.height / 2 - 2; // Leave some padding\n\n const history = amplitudeHistoryRef.current;\n\n // Only draw when recording (history has data)\n if (history.length > 0) {\n const offset = scrollOffsetRef.current;\n const edgeFadeWidth = 12; // Pixels to fade at each edge\n\n for (let i = 0; i < history.length; i++) {\n const amplitude = history[i] ?? 0;\n // Scale amplitude (RMS is typically 0-0.5 for normal speech)\n const scaledAmplitude = Math.min(amplitude * 4, 1);\n const barHeight = Math.max(2, scaledAmplitude * maxAmplitude * 2);\n\n // Position: right-aligned with smooth scroll offset\n const x = rect.width - (history.length - i) * barSpacing - offset;\n const y = centerY - barHeight / 2;\n\n // Only draw if visible\n if (x + barWidth > 0 && x < rect.width) {\n // Calculate edge fade opacity\n let edgeOpacity = 1;\n if (x < edgeFadeWidth) {\n // Fade out on left edge\n edgeOpacity = Math.max(0, x / edgeFadeWidth);\n } else if (x > rect.width - edgeFadeWidth) {\n // Fade in on right edge\n edgeOpacity = Math.max(0, (rect.width - x) / edgeFadeWidth);\n }\n\n ctx.globalAlpha = fadeOpacityRef.current * edgeOpacity;\n ctx.fillRect(x, y, barWidth, barHeight);\n }\n }\n }\n\n animationIdRef.current = requestAnimationFrame(draw);\n };\n\n draw();\n\n return () => {\n if (animationIdRef.current) {\n cancelAnimationFrame(animationIdRef.current);\n }\n };\n }, [recorderState]);\n\n // Cleanup on unmount\n useEffect(() => {\n return cleanup;\n }, [cleanup]);\n\n // Expose AudioRecorder API via ref\n useImperativeHandle(\n ref,\n () => ({\n get state() {\n return recorderState;\n },\n start,\n stop,\n dispose: cleanup,\n }),\n [recorderState, start, stop, cleanup],\n );\n\n return (\n <div\n className={twMerge(\"cpk:w-full cpk:py-3 cpk:px-5\", className)}\n {...divProps}\n >\n <canvas ref={canvasRef} className=\"cpk:block cpk:w-full cpk:h-[26px]\" />\n </div>\n );\n});\n\nCopilotChatAudioRecorder.displayName = \"CopilotChatAudioRecorder\";\n","import React, {\n useState,\n useRef,\n KeyboardEvent,\n ChangeEvent,\n useEffect,\n useLayoutEffect,\n forwardRef,\n useImperativeHandle,\n useCallback,\n useMemo,\n} from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { Plus, Mic, ArrowUp, X, Check, Square, Loader2 } from \"lucide-react\";\n\nimport {\n CopilotChatLabels,\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"../../providers/CopilotChatConfigurationProvider\";\nimport { Button } from \"../../components/ui/button\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"../../components/ui/tooltip\";\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n DropdownMenuSeparator,\n} from \"../../components/ui/dropdown-menu\";\n\nimport { CopilotChatAudioRecorder } from \"./CopilotChatAudioRecorder\";\nimport { renderSlot, WithSlots } from \"../../lib/slots\";\nimport { cn } from \"../../lib/utils\";\n\nexport type CopilotChatInputMode = \"input\" | \"transcribe\" | \"processing\";\n\nexport type ToolsMenuItem = {\n label: string;\n} & (\n | {\n action: () => void;\n items?: never;\n }\n | {\n action?: never;\n items: (ToolsMenuItem | \"-\")[];\n }\n);\n\ntype CopilotChatInputSlots = {\n textArea: typeof CopilotChatInput.TextArea;\n sendButton: typeof CopilotChatInput.SendButton;\n startTranscribeButton: typeof CopilotChatInput.StartTranscribeButton;\n cancelTranscribeButton: typeof CopilotChatInput.CancelTranscribeButton;\n finishTranscribeButton: typeof CopilotChatInput.FinishTranscribeButton;\n addMenuButton: typeof CopilotChatInput.AddMenuButton;\n audioRecorder: typeof CopilotChatAudioRecorder;\n disclaimer: typeof CopilotChatInput.Disclaimer;\n};\n\ntype CopilotChatInputRestProps = {\n mode?: CopilotChatInputMode;\n toolsMenu?: (ToolsMenuItem | \"-\")[];\n autoFocus?: boolean;\n onSubmitMessage?: (value: string) => void;\n onStop?: () => void;\n isRunning?: boolean;\n onStartTranscribe?: () => void;\n onCancelTranscribe?: () => void;\n onFinishTranscribe?: () => void;\n onFinishTranscribeWithAudio?: (audioBlob: Blob) => Promise<void>;\n onAddFile?: () => void;\n value?: string;\n onChange?: (value: string) => void;\n /** Positioning mode for the input container. Default: 'static' */\n positioning?: \"static\" | \"absolute\";\n /** Keyboard height in pixels for mobile keyboard handling */\n keyboardHeight?: number;\n /** Ref for the outer positioning container */\n containerRef?: React.Ref<HTMLDivElement>;\n /** Whether to show the disclaimer. Default: true for absolute positioning, false for static */\n showDisclaimer?: boolean;\n} & Omit<React.HTMLAttributes<HTMLDivElement>, \"onChange\">;\n\ntype CopilotChatInputBaseProps = WithSlots<\n CopilotChatInputSlots,\n CopilotChatInputRestProps\n>;\n\ntype CopilotChatInputChildrenArgs = CopilotChatInputBaseProps extends {\n children?: infer C;\n}\n ? C extends (props: infer P) => React.ReactNode\n ? P\n : never\n : never;\n\nexport type CopilotChatInputProps = Omit<\n CopilotChatInputBaseProps,\n \"children\"\n> & {\n children?: (props: CopilotChatInputChildrenArgs) => React.ReactNode;\n};\n\nconst SLASH_MENU_MAX_VISIBLE_ITEMS = 5;\nconst SLASH_MENU_ITEM_HEIGHT_PX = 40;\n\nexport function CopilotChatInput({\n mode = \"input\",\n onSubmitMessage,\n onStop,\n isRunning = false,\n onStartTranscribe,\n onCancelTranscribe,\n onFinishTranscribe,\n onFinishTranscribeWithAudio,\n onAddFile,\n onChange,\n value,\n toolsMenu,\n autoFocus = false,\n positioning = \"static\",\n keyboardHeight = 0,\n containerRef,\n showDisclaimer,\n textArea,\n sendButton,\n startTranscribeButton,\n cancelTranscribeButton,\n finishTranscribeButton,\n addMenuButton,\n audioRecorder,\n disclaimer,\n children,\n className,\n ...props\n}: CopilotChatInputProps) {\n const isControlled = value !== undefined;\n const [internalValue, setInternalValue] = useState<string>(() => value ?? \"\");\n\n useEffect(() => {\n if (!isControlled && value !== undefined) {\n setInternalValue(value);\n }\n }, [isControlled, value]);\n\n const resolvedValue = isControlled ? (value ?? \"\") : internalValue;\n\n const [layout, setLayout] = useState<\"compact\" | \"expanded\">(\"compact\");\n const ignoreResizeRef = useRef(false);\n const resizeEvaluationRafRef = useRef<number | null>(null);\n const isExpanded = mode === \"input\" && layout === \"expanded\";\n const [commandQuery, setCommandQuery] = useState<string | null>(null);\n const [slashHighlightIndex, setSlashHighlightIndex] = useState(0);\n\n const inputRef = useRef<HTMLTextAreaElement>(null);\n const gridRef = useRef<HTMLDivElement>(null);\n const addButtonContainerRef = useRef<HTMLDivElement>(null);\n const actionsContainerRef = useRef<HTMLDivElement>(null);\n const audioRecorderRef =\n useRef<React.ElementRef<typeof CopilotChatAudioRecorder>>(null);\n const slashMenuRef = useRef<HTMLDivElement>(null);\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n\n const previousModalStateRef = useRef<boolean | undefined>(undefined);\n const measurementCanvasRef = useRef<HTMLCanvasElement | null>(null);\n const measurementsRef = useRef({\n singleLineHeight: 0,\n maxHeight: 0,\n paddingLeft: 0,\n paddingRight: 0,\n });\n\n // Cached container dimensions — invalidated on resize, lazily repopulated on next layout pass.\n // Eliminates getComputedStyle(grid) + 2x getBoundingClientRect per compact-layout evaluation.\n const containerCacheRef = useRef<{\n compactWidth: number;\n } | null>(null);\n\n const commandItems = useMemo(() => {\n const entries: ToolsMenuItem[] = [];\n const seen = new Set<string>();\n\n const pushItem = (item: ToolsMenuItem | \"-\") => {\n if (item === \"-\") {\n return;\n }\n\n if (item.items && item.items.length > 0) {\n for (const nested of item.items) {\n pushItem(nested);\n }\n return;\n }\n\n if (!seen.has(item.label)) {\n seen.add(item.label);\n entries.push(item);\n }\n };\n\n if (onAddFile) {\n pushItem({\n label: labels.chatInputToolbarAddButtonLabel,\n action: onAddFile,\n });\n }\n\n if (toolsMenu && toolsMenu.length > 0) {\n for (const item of toolsMenu) {\n pushItem(item);\n }\n }\n\n return entries;\n }, [labels.chatInputToolbarAddButtonLabel, onAddFile, toolsMenu]);\n\n const filteredCommands = useMemo(() => {\n if (commandQuery === null) {\n return [] as ToolsMenuItem[];\n }\n\n if (commandItems.length === 0) {\n return [] as ToolsMenuItem[];\n }\n\n const query = commandQuery.trim().toLowerCase();\n if (query.length === 0) {\n return commandItems;\n }\n\n const startsWith: ToolsMenuItem[] = [];\n const contains: ToolsMenuItem[] = [];\n for (const item of commandItems) {\n const label = item.label.toLowerCase();\n if (label.startsWith(query)) {\n startsWith.push(item);\n } else if (label.includes(query)) {\n contains.push(item);\n }\n }\n\n return [...startsWith, ...contains];\n }, [commandItems, commandQuery]);\n\n useEffect(() => {\n if (!autoFocus) {\n previousModalStateRef.current = config?.isModalOpen;\n return;\n }\n\n if (config?.isModalOpen && !previousModalStateRef.current) {\n inputRef.current?.focus({ preventScroll: true });\n }\n\n previousModalStateRef.current = config?.isModalOpen;\n }, [config?.isModalOpen, autoFocus]);\n\n useEffect(() => {\n if (commandItems.length === 0 && commandQuery !== null) {\n setCommandQuery(null);\n }\n }, [commandItems.length, commandQuery]);\n\n const previousCommandQueryRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (\n commandQuery !== null &&\n commandQuery !== previousCommandQueryRef.current &&\n filteredCommands.length > 0\n ) {\n setSlashHighlightIndex(0);\n }\n\n previousCommandQueryRef.current = commandQuery;\n }, [commandQuery, filteredCommands.length]);\n\n useEffect(() => {\n if (commandQuery === null) {\n setSlashHighlightIndex(0);\n return;\n }\n\n if (filteredCommands.length === 0) {\n setSlashHighlightIndex(-1);\n } else if (\n slashHighlightIndex < 0 ||\n slashHighlightIndex >= filteredCommands.length\n ) {\n setSlashHighlightIndex(0);\n }\n }, [commandQuery, filteredCommands, slashHighlightIndex]);\n\n // Handle recording based on mode changes\n useEffect(() => {\n const recorder = audioRecorderRef.current;\n if (!recorder) {\n return;\n }\n\n if (mode === \"transcribe\") {\n // Start recording when entering transcribe mode\n recorder.start().catch(console.error);\n } else {\n // Stop recording when leaving transcribe mode\n if (recorder.state === \"recording\") {\n recorder.stop().catch(console.error);\n }\n }\n }, [mode]);\n\n useEffect(() => {\n if (mode !== \"input\") {\n setLayout(\"compact\");\n setCommandQuery(null);\n }\n }, [mode]);\n\n const updateSlashState = useCallback(\n (value: string) => {\n if (commandItems.length === 0) {\n setCommandQuery((prev) => (prev === null ? prev : null));\n return;\n }\n\n if (value.startsWith(\"/\")) {\n const firstLine = value.split(/\\r?\\n/, 1)[0] ?? \"\";\n const query = firstLine.slice(1);\n setCommandQuery((prev) => (prev === query ? prev : query));\n } else {\n setCommandQuery((prev) => (prev === null ? prev : null));\n }\n },\n [commandItems.length],\n );\n\n useEffect(() => {\n updateSlashState(resolvedValue);\n }, [resolvedValue, updateSlashState]);\n\n // Handlers\n const handleChange = (e: ChangeEvent<HTMLTextAreaElement>) => {\n const nextValue = e.target.value;\n if (!isControlled) {\n setInternalValue(nextValue);\n }\n onChange?.(nextValue);\n updateSlashState(nextValue);\n };\n\n const clearInputValue = useCallback(() => {\n if (!isControlled) {\n setInternalValue(\"\");\n }\n\n if (onChange) {\n onChange(\"\");\n }\n }, [isControlled, onChange]);\n\n const runCommand = useCallback(\n (item: ToolsMenuItem) => {\n clearInputValue();\n\n item.action?.();\n\n setCommandQuery(null);\n setSlashHighlightIndex(0);\n\n requestAnimationFrame(() => {\n inputRef.current?.focus();\n });\n },\n [clearInputValue],\n );\n\n const handleKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => {\n if (commandQuery !== null && mode === \"input\") {\n if (e.key === \"ArrowDown\") {\n if (filteredCommands.length > 0) {\n e.preventDefault();\n setSlashHighlightIndex((prev) => {\n if (filteredCommands.length === 0) {\n return prev;\n }\n const next = prev === -1 ? 0 : (prev + 1) % filteredCommands.length;\n return next;\n });\n }\n return;\n }\n\n if (e.key === \"ArrowUp\") {\n if (filteredCommands.length > 0) {\n e.preventDefault();\n setSlashHighlightIndex((prev) => {\n if (filteredCommands.length === 0) {\n return prev;\n }\n if (prev === -1) {\n return filteredCommands.length - 1;\n }\n return prev <= 0 ? filteredCommands.length - 1 : prev - 1;\n });\n }\n return;\n }\n\n if (e.key === \"Enter\") {\n const selected =\n slashHighlightIndex >= 0\n ? filteredCommands[slashHighlightIndex]\n : undefined;\n if (selected) {\n e.preventDefault();\n runCommand(selected);\n return;\n }\n }\n\n if (e.key === \"Escape\") {\n e.preventDefault();\n setCommandQuery(null);\n return;\n }\n }\n\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n if (isProcessing) {\n onStop?.();\n } else {\n send();\n }\n }\n };\n\n const send = () => {\n if (!onSubmitMessage) {\n return;\n }\n const trimmed = resolvedValue.trim();\n if (!trimmed) {\n return;\n }\n\n onSubmitMessage(trimmed);\n\n if (!isControlled) {\n setInternalValue(\"\");\n onChange?.(\"\");\n }\n\n if (inputRef.current) {\n inputRef.current.focus();\n }\n };\n\n const BoundTextArea = renderSlot(textArea, CopilotChatInput.TextArea, {\n ref: inputRef,\n value: resolvedValue,\n onChange: handleChange,\n onKeyDown: handleKeyDown,\n autoFocus: autoFocus,\n className: twMerge(\n \"cpk:w-full cpk:py-3\",\n isExpanded ? \"cpk:px-5\" : \"cpk:pr-5\",\n ),\n });\n\n const isProcessing = mode !== \"transcribe\" && isRunning;\n const canSend = resolvedValue.trim().length > 0 && !!onSubmitMessage;\n const canStop = !!onStop;\n\n const handleSendButtonClick = () => {\n if (isProcessing) {\n onStop?.();\n return;\n }\n send();\n };\n\n const BoundAudioRecorder = renderSlot(\n audioRecorder,\n CopilotChatAudioRecorder,\n {\n ref: audioRecorderRef,\n },\n );\n\n const BoundSendButton = renderSlot(sendButton, CopilotChatInput.SendButton, {\n onClick: handleSendButtonClick,\n disabled: isProcessing ? !canStop : !canSend,\n children:\n isProcessing && canStop ? (\n <Square className=\"cpk:size-[18px] cpk:fill-current\" />\n ) : undefined,\n });\n\n const BoundStartTranscribeButton = renderSlot(\n startTranscribeButton,\n CopilotChatInput.StartTranscribeButton,\n {\n onClick: onStartTranscribe,\n },\n );\n\n const BoundCancelTranscribeButton = renderSlot(\n cancelTranscribeButton,\n CopilotChatInput.CancelTranscribeButton,\n {\n onClick: onCancelTranscribe,\n },\n );\n\n // Handler for finish button - stops recording and passes audio blob\n const handleFinishTranscribe = useCallback(async () => {\n const recorder = audioRecorderRef.current;\n if (recorder && recorder.state === \"recording\") {\n try {\n const audioBlob = await recorder.stop();\n if (onFinishTranscribeWithAudio) {\n await onFinishTranscribeWithAudio(audioBlob);\n }\n } catch (error) {\n console.error(\"Failed to stop recording:\", error);\n }\n }\n // Always call the original handler to reset mode\n onFinishTranscribe?.();\n }, [onFinishTranscribe, onFinishTranscribeWithAudio]);\n\n const BoundFinishTranscribeButton = renderSlot(\n finishTranscribeButton,\n CopilotChatInput.FinishTranscribeButton,\n {\n onClick: handleFinishTranscribe,\n },\n );\n\n const BoundAddMenuButton = renderSlot(\n addMenuButton,\n CopilotChatInput.AddMenuButton,\n {\n disabled: mode === \"transcribe\",\n onAddFile,\n toolsMenu,\n },\n );\n\n const BoundDisclaimer = renderSlot(\n disclaimer,\n CopilotChatInput.Disclaimer,\n {},\n );\n\n // Determine whether to show disclaimer based on prop or positioning default\n const shouldShowDisclaimer = showDisclaimer ?? positioning === \"absolute\";\n\n if (children) {\n const childProps = {\n textArea: BoundTextArea,\n audioRecorder: BoundAudioRecorder,\n sendButton: BoundSendButton,\n startTranscribeButton: BoundStartTranscribeButton,\n cancelTranscribeButton: BoundCancelTranscribeButton,\n finishTranscribeButton: BoundFinishTranscribeButton,\n addMenuButton: BoundAddMenuButton,\n disclaimer: BoundDisclaimer,\n onSubmitMessage,\n onStop,\n isRunning,\n onStartTranscribe,\n onCancelTranscribe,\n onFinishTranscribe,\n onAddFile,\n mode,\n toolsMenu,\n autoFocus,\n positioning,\n keyboardHeight,\n showDisclaimer: shouldShowDisclaimer,\n containerRef,\n } as CopilotChatInputChildrenArgs;\n\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children(childProps)}\n </div>\n );\n }\n\n const handleContainerClick = (e: React.MouseEvent<HTMLDivElement>) => {\n // Don't focus if clicking on buttons or other interactive elements\n const target = e.target as HTMLElement;\n if (\n target.tagName !== \"BUTTON\" &&\n !target.closest(\"button\") &&\n inputRef.current &&\n mode === \"input\"\n ) {\n inputRef.current.focus();\n }\n };\n\n const ensureMeasurements = useCallback(() => {\n const textarea = inputRef.current;\n if (!textarea) {\n return;\n }\n\n const previousValue = textarea.value;\n const previousHeight = textarea.style.height;\n\n textarea.style.height = \"auto\";\n\n const computedStyle = window.getComputedStyle(textarea);\n const paddingLeft = parseFloat(computedStyle.paddingLeft) || 0;\n const paddingRight = parseFloat(computedStyle.paddingRight) || 0;\n const paddingTop = parseFloat(computedStyle.paddingTop) || 0;\n const paddingBottom = parseFloat(computedStyle.paddingBottom) || 0;\n\n textarea.value = \"\";\n const singleLineHeight = textarea.scrollHeight;\n textarea.value = previousValue;\n\n const contentHeight = singleLineHeight - paddingTop - paddingBottom;\n const maxHeight = contentHeight * 5 + paddingTop + paddingBottom;\n\n measurementsRef.current = {\n singleLineHeight,\n maxHeight,\n paddingLeft,\n paddingRight,\n };\n\n textarea.style.height = previousHeight;\n textarea.style.maxHeight = `${maxHeight}px`;\n }, []);\n\n const adjustTextareaHeight = useCallback(() => {\n const textarea = inputRef.current;\n if (!textarea) {\n return 0;\n }\n\n if (measurementsRef.current.singleLineHeight === 0) {\n ensureMeasurements();\n }\n\n const { maxHeight } = measurementsRef.current;\n if (maxHeight) {\n textarea.style.maxHeight = `${maxHeight}px`;\n }\n\n textarea.style.height = \"auto\";\n const scrollHeight = textarea.scrollHeight;\n if (maxHeight) {\n textarea.style.height = `${Math.min(scrollHeight, maxHeight)}px`;\n } else {\n textarea.style.height = `${scrollHeight}px`;\n }\n\n return scrollHeight;\n }, [ensureMeasurements]);\n\n const updateLayout = useCallback((nextLayout: \"compact\" | \"expanded\") => {\n setLayout((prev) => {\n if (prev === nextLayout) {\n return prev;\n }\n ignoreResizeRef.current = true;\n return nextLayout;\n });\n }, []);\n\n const updateContainerCache = useCallback((): {\n compactWidth: number;\n } | null => {\n const grid = gridRef.current;\n const addContainer = addButtonContainerRef.current;\n const actionsContainer = actionsContainerRef.current;\n if (!grid || !addContainer || !actionsContainer) return null;\n\n const gridStyles = window.getComputedStyle(grid);\n const paddingLeft = parseFloat(gridStyles.paddingLeft) || 0;\n const paddingRight = parseFloat(gridStyles.paddingRight) || 0;\n const columnGap = parseFloat(gridStyles.columnGap) || 0;\n const gridAvailableWidth = grid.clientWidth - paddingLeft - paddingRight;\n\n if (gridAvailableWidth <= 0) return null;\n\n const addWidth = addContainer.getBoundingClientRect().width;\n const actionsWidth = actionsContainer.getBoundingClientRect().width;\n const compactWidth = Math.max(\n gridAvailableWidth - addWidth - actionsWidth - columnGap * 2,\n 0,\n );\n\n if (compactWidth <= 0) return null;\n\n const result = { compactWidth };\n containerCacheRef.current = result;\n return result;\n }, []);\n\n const evaluateLayout = useCallback(() => {\n if (mode !== \"input\") {\n updateLayout(\"compact\");\n return;\n }\n\n if (\n typeof window !== \"undefined\" &&\n typeof window.matchMedia === \"function\"\n ) {\n const isMobileViewport = window.matchMedia(\"(max-width: 767px)\").matches;\n if (isMobileViewport) {\n ensureMeasurements();\n adjustTextareaHeight();\n updateLayout(\"expanded\");\n return;\n }\n }\n\n const textarea = inputRef.current;\n const grid = gridRef.current;\n const addContainer = addButtonContainerRef.current;\n const actionsContainer = actionsContainerRef.current;\n\n if (!textarea || !grid || !addContainer || !actionsContainer) {\n return;\n }\n\n if (measurementsRef.current.singleLineHeight === 0) {\n ensureMeasurements();\n }\n\n const scrollHeight = adjustTextareaHeight();\n const baseline = measurementsRef.current.singleLineHeight;\n const hasExplicitBreak = resolvedValue.includes(\"\\n\");\n const renderedMultiline =\n baseline > 0 ? scrollHeight > baseline + 1 : false;\n let shouldExpand = hasExplicitBreak || renderedMultiline;\n\n if (!shouldExpand) {\n // Use cached container dimensions (lazily populated on first access, invalidated on resize).\n const cache = containerCacheRef.current ?? updateContainerCache();\n\n if (cache && cache.compactWidth > 0) {\n const compactInnerWidth = Math.max(\n cache.compactWidth -\n (measurementsRef.current.paddingLeft || 0) -\n (measurementsRef.current.paddingRight || 0),\n 0,\n );\n\n if (compactInnerWidth > 0) {\n // Read font fresh each evaluation — getComputedStyle for style-only\n // properties is cheap and avoids stale values after CSS/theme changes.\n const textareaStyles = window.getComputedStyle(textarea);\n let font = textareaStyles.font;\n if (!font) {\n const {\n fontStyle,\n fontVariant,\n fontWeight,\n fontSize,\n lineHeight,\n fontFamily,\n } = textareaStyles;\n if (fontSize && fontFamily) {\n font = `${fontStyle} ${fontVariant} ${fontWeight} ${fontSize}/${lineHeight} ${fontFamily}`;\n }\n }\n\n if (font?.trim()) {\n const canvas =\n measurementCanvasRef.current ?? document.createElement(\"canvas\");\n if (!measurementCanvasRef.current) {\n measurementCanvasRef.current = canvas;\n }\n\n const context = canvas.getContext(\"2d\");\n if (context) {\n context.font = font;\n\n const lines =\n resolvedValue.length > 0 ? resolvedValue.split(\"\\n\") : [\"\"];\n let longestWidth = 0;\n for (const line of lines) {\n const metrics = context.measureText(line || \" \");\n if (metrics.width > longestWidth) {\n longestWidth = metrics.width;\n }\n }\n\n if (longestWidth > compactInnerWidth) {\n shouldExpand = true;\n }\n } else if (process.env.NODE_ENV !== \"production\") {\n console.warn(\n \"[CopilotChatInput] canvas.getContext('2d') returned null. \" +\n \"Text-width-based expansion will be unavailable.\",\n );\n }\n } else if (process.env.NODE_ENV !== \"production\") {\n console.warn(\n \"[CopilotChatInput] Could not resolve textarea font for layout measurement. \" +\n \"Text-width-based expansion will be skipped until the next evaluation.\",\n );\n }\n }\n }\n }\n\n const nextLayout = shouldExpand ? \"expanded\" : \"compact\";\n updateLayout(nextLayout);\n }, [\n adjustTextareaHeight,\n ensureMeasurements,\n mode,\n resolvedValue,\n updateContainerCache,\n updateLayout,\n ]);\n\n useLayoutEffect(() => {\n evaluateLayout();\n }, [evaluateLayout]);\n\n useEffect(() => {\n if (typeof ResizeObserver === \"undefined\") {\n return;\n }\n\n const textarea = inputRef.current;\n const grid = gridRef.current;\n const addContainer = addButtonContainerRef.current;\n const actionsContainer = actionsContainerRef.current;\n\n if (!textarea || !grid || !addContainer || !actionsContainer) {\n return;\n }\n\n const containerTargets = new Set<Element>([\n grid,\n addContainer,\n actionsContainer,\n ]);\n\n const scheduleEvaluation = (invalidateCache: boolean) => {\n if (ignoreResizeRef.current) {\n ignoreResizeRef.current = false;\n // Self-inflicted resize from a layout toggle — container dimensions\n // are unchanged, so keep the cache warm.\n return;\n }\n\n if (invalidateCache) {\n containerCacheRef.current = null;\n }\n\n if (typeof window === \"undefined\") {\n evaluateLayout();\n return;\n }\n\n if (resizeEvaluationRafRef.current !== null) {\n cancelAnimationFrame(resizeEvaluationRafRef.current);\n }\n\n resizeEvaluationRafRef.current = window.requestAnimationFrame(() => {\n resizeEvaluationRafRef.current = null;\n evaluateLayout();\n });\n };\n\n // Single observer for all elements — inspect entry.target to decide\n // whether to invalidate the container dimension cache. Container\n // targets (grid, buttons) changing size means compactWidth may have\n // changed; textarea height changes (typing) do not affect it.\n const observer = new ResizeObserver((entries) => {\n let shouldInvalidate = false;\n for (const entry of entries) {\n if (containerTargets.has(entry.target)) {\n shouldInvalidate = true;\n break;\n }\n }\n scheduleEvaluation(shouldInvalidate);\n });\n\n observer.observe(grid);\n observer.observe(addContainer);\n observer.observe(actionsContainer);\n observer.observe(textarea);\n\n return () => {\n observer.disconnect();\n if (\n typeof window !== \"undefined\" &&\n resizeEvaluationRafRef.current !== null\n ) {\n cancelAnimationFrame(resizeEvaluationRafRef.current);\n resizeEvaluationRafRef.current = null;\n }\n };\n }, [evaluateLayout]);\n\n const slashMenuVisible = commandQuery !== null && commandItems.length > 0;\n\n useEffect(() => {\n if (!slashMenuVisible || slashHighlightIndex < 0) {\n return;\n }\n\n const active = slashMenuRef.current?.querySelector<HTMLElement>(\n `[data-slash-index=\"${slashHighlightIndex}\"]`,\n );\n active?.scrollIntoView({ block: \"nearest\" });\n }, [slashMenuVisible, slashHighlightIndex]);\n\n const slashMenu = slashMenuVisible ? (\n <div\n data-testid=\"copilot-slash-menu\"\n role=\"listbox\"\n aria-label=\"Slash commands\"\n ref={slashMenuRef}\n 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]\"\n style={{\n maxHeight: `${SLASH_MENU_MAX_VISIBLE_ITEMS * SLASH_MENU_ITEM_HEIGHT_PX}px`,\n }}\n >\n {filteredCommands.length === 0 ? (\n <div className=\"cpk:px-3 cpk:py-2 cpk:text-sm cpk:text-muted-foreground\">\n No commands found\n </div>\n ) : (\n filteredCommands.map((item, index) => {\n const isActive = index === slashHighlightIndex;\n return (\n <button\n key={`${item.label}-${index}`}\n type=\"button\"\n role=\"option\"\n aria-selected={isActive}\n data-active={isActive ? \"true\" : undefined}\n data-slash-index={index}\n className={twMerge(\n \"cpk:w-full cpk:px-3 cpk:py-2 cpk:text-left cpk:text-sm cpk:transition-colors\",\n \"cpk:hover:bg-muted cpk:dark:hover:bg-[#2f2f2f]\",\n isActive\n ? \"cpk:bg-muted cpk:dark:bg-[#2f2f2f]\"\n : \"cpk:bg-transparent\",\n )}\n onMouseEnter={() => setSlashHighlightIndex(index)}\n onMouseDown={(event) => {\n event.preventDefault();\n runCommand(item);\n }}\n >\n {item.label}\n </button>\n );\n })\n )}\n </div>\n ) : null;\n\n // The input pill (inner component)\n const inputPill = (\n <div\n data-testid=\"copilot-chat-input\"\n className={twMerge(\n // V1 compatibility class for custom styling\n \"copilotKitInput\",\n // Layout\n \"cpk:flex cpk:w-full cpk:flex-col cpk:items-center cpk:justify-center\",\n // Interaction\n \"cpk:cursor-text\",\n // Overflow and clipping\n \"cpk:overflow-visible cpk:bg-clip-padding cpk:contain-inline-size\",\n // Background\n \"cpk:bg-white cpk:dark:bg-[#303030]\",\n // Visual effects\n \"cpk:shadow-[0_4px_4px_0_#0000000a,0_0_1px_0_#0000009e] cpk:rounded-[28px]\",\n )}\n onClick={handleContainerClick}\n data-layout={isExpanded ? \"expanded\" : \"compact\"}\n >\n <div\n ref={gridRef}\n className={twMerge(\n \"cpk:grid cpk:w-full cpk:gap-x-3 cpk:gap-y-3 cpk:px-3 cpk:py-2\",\n isExpanded\n ? \"cpk:grid-cols-[auto_minmax(0,1fr)_auto] cpk:grid-rows-[auto_auto]\"\n : \"cpk:grid-cols-[auto_minmax(0,1fr)_auto] cpk:items-center\",\n )}\n data-layout={isExpanded ? \"expanded\" : \"compact\"}\n >\n <div\n ref={addButtonContainerRef}\n className={twMerge(\n \"cpk:flex cpk:items-center\",\n isExpanded ? \"cpk:row-start-2\" : \"cpk:row-start-1\",\n \"cpk:col-start-1\",\n )}\n >\n {BoundAddMenuButton}\n </div>\n <div\n className={twMerge(\n \"cpk:relative cpk:flex cpk:min-w-0 cpk:flex-col cpk:min-h-[50px] cpk:justify-center\",\n isExpanded\n ? \"cpk:col-span-3 cpk:row-start-1\"\n : \"cpk:col-start-2 cpk:row-start-1\",\n )}\n >\n {mode === \"transcribe\" ? (\n BoundAudioRecorder\n ) : mode === \"processing\" ? (\n <div className=\"cpk:flex cpk:w-full cpk:items-center cpk:justify-center cpk:py-3 cpk:px-5\">\n <Loader2 className=\"cpk:size-[26px] cpk:animate-spin cpk:text-muted-foreground\" />\n </div>\n ) : (\n <>\n {BoundTextArea}\n {slashMenu}\n </>\n )}\n </div>\n <div\n ref={actionsContainerRef}\n className={twMerge(\n \"cpk:flex cpk:items-center cpk:justify-end cpk:gap-2\",\n isExpanded\n ? \"cpk:col-start-3 cpk:row-start-2\"\n : \"cpk:col-start-3 cpk:row-start-1\",\n )}\n >\n {mode === \"transcribe\" ? (\n <>\n {onCancelTranscribe && BoundCancelTranscribeButton}\n {onFinishTranscribe && BoundFinishTranscribeButton}\n </>\n ) : (\n <>\n {onStartTranscribe && BoundStartTranscribeButton}\n {BoundSendButton}\n </>\n )}\n </div>\n </div>\n </div>\n );\n\n return (\n <div\n data-copilotkit\n ref={containerRef}\n className={cn(\n \"cpk:pointer-events-none cpk:relative cpk:z-20\",\n positioning === \"absolute\" &&\n \"cpk:absolute cpk:bottom-0 cpk:left-0 cpk:right-0\",\n className,\n )}\n style={{\n transform:\n keyboardHeight > 0 ? `translateY(-${keyboardHeight}px)` : undefined,\n transition: \"transform 0.2s ease-out\",\n }}\n {...props}\n >\n <div className=\"cpk:max-w-3xl cpk:mx-auto cpk:py-0 cpk:px-4 cpk:sm:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-4 cpk:pointer-events-auto\">\n {inputPill}\n </div>\n {shouldShowDisclaimer && BoundDisclaimer}\n </div>\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotChatInput {\n export const SendButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, children, ...props }) => (\n <div className=\"cpk:mr-[10px]\">\n <Button\n type=\"button\"\n data-testid=\"copilot-send-button\"\n variant=\"chatInputToolbarPrimary\"\n size=\"chatInputToolbarIcon\"\n className={className}\n {...props}\n >\n {children ?? <ArrowUp className=\"cpk:size-[18px]\" />}\n </Button>\n </div>\n );\n\n export const ToolbarButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & {\n icon: React.ReactNode;\n labelKey: keyof CopilotChatLabels;\n defaultClassName?: string;\n }\n > = ({ icon, labelKey, defaultClassName, className, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"chatInputToolbarSecondary\"\n size=\"chatInputToolbarIcon\"\n className={twMerge(defaultClassName, className)}\n {...props}\n >\n {icon}\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">\n <p>{labels[labelKey]}</p>\n </TooltipContent>\n </Tooltip>\n );\n };\n\n export const StartTranscribeButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = (props) => (\n <ToolbarButton\n data-testid=\"copilot-start-transcribe-button\"\n icon={<Mic className=\"cpk:size-[18px]\" />}\n labelKey=\"chatInputToolbarStartTranscribeButtonLabel\"\n defaultClassName=\"cpk:mr-2\"\n {...props}\n />\n );\n\n export const CancelTranscribeButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = (props) => (\n <ToolbarButton\n data-testid=\"copilot-cancel-transcribe-button\"\n icon={<X className=\"cpk:size-[18px]\" />}\n labelKey=\"chatInputToolbarCancelTranscribeButtonLabel\"\n defaultClassName=\"cpk:mr-2\"\n {...props}\n />\n );\n\n export const FinishTranscribeButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = (props) => (\n <ToolbarButton\n data-testid=\"copilot-finish-transcribe-button\"\n icon={<Check className=\"cpk:size-[18px]\" />}\n labelKey=\"chatInputToolbarFinishTranscribeButtonLabel\"\n defaultClassName=\"cpk:mr-[10px]\"\n {...props}\n />\n );\n\n export const AddMenuButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & {\n toolsMenu?: (ToolsMenuItem | \"-\")[];\n onAddFile?: () => void;\n }\n > = ({ className, toolsMenu, onAddFile, disabled, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n\n // Defer Radix UI rendering until after hydration to avoid ID mismatches\n const [mounted, setMounted] = useState(false);\n useEffect(() => setMounted(true), []);\n\n const menuItems = useMemo<(ToolsMenuItem | \"-\")[]>(() => {\n const items: (ToolsMenuItem | \"-\")[] = [];\n\n if (onAddFile) {\n items.push({\n label: labels.chatInputToolbarAddButtonLabel,\n action: onAddFile,\n });\n }\n\n if (toolsMenu && toolsMenu.length > 0) {\n if (items.length > 0) {\n items.push(\"-\");\n }\n\n for (const item of toolsMenu) {\n if (item === \"-\") {\n if (items.length === 0 || items[items.length - 1] === \"-\") {\n continue;\n }\n items.push(item);\n } else {\n items.push(item);\n }\n }\n\n while (items.length > 0 && items[items.length - 1] === \"-\") {\n items.pop();\n }\n }\n\n return items;\n }, [onAddFile, toolsMenu, labels.chatInputToolbarAddButtonLabel]);\n\n const renderMenuItems = useCallback(\n (items: (ToolsMenuItem | \"-\")[]): React.ReactNode =>\n items.map((item, index) => {\n if (item === \"-\") {\n return <DropdownMenuSeparator key={`separator-${index}`} />;\n }\n\n if (item.items && item.items.length > 0) {\n return (\n <DropdownMenuSub key={`group-${index}`}>\n <DropdownMenuSubTrigger>{item.label}</DropdownMenuSubTrigger>\n <DropdownMenuSubContent>\n {renderMenuItems(item.items)}\n </DropdownMenuSubContent>\n </DropdownMenuSub>\n );\n }\n\n return (\n <DropdownMenuItem key={`item-${index}`} onClick={item.action}>\n {item.label}\n </DropdownMenuItem>\n );\n }),\n [],\n );\n\n const hasMenuItems = menuItems.length > 0;\n const isDisabled = disabled || !hasMenuItems;\n\n const button = (\n <Button\n type=\"button\"\n data-testid=\"copilot-add-menu-button\"\n variant=\"chatInputToolbarSecondary\"\n size=\"chatInputToolbarIcon\"\n className={twMerge(\"cpk:ml-1\", className)}\n disabled={isDisabled}\n {...props}\n >\n <Plus className=\"cpk:size-[20px]\" />\n </Button>\n );\n\n // Render plain button during SSR; Radix wrappers only after hydration\n if (!mounted) return button;\n\n return (\n <DropdownMenu>\n <Tooltip>\n <TooltipTrigger asChild>\n <DropdownMenuTrigger asChild>{button}</DropdownMenuTrigger>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">\n <p className=\"cpk:flex cpk:items-center cpk:gap-1 cpk:text-xs cpk:font-medium\">\n <span>Add attachments</span>\n <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\">\n /\n </code>\n </p>\n </TooltipContent>\n </Tooltip>\n {hasMenuItems && (\n <DropdownMenuContent side=\"top\" align=\"start\">\n {renderMenuItems(menuItems)}\n </DropdownMenuContent>\n )}\n </DropdownMenu>\n );\n };\n\n export type TextAreaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>;\n\n export const TextArea = forwardRef<HTMLTextAreaElement, TextAreaProps>(\n function TextArea(\n { style, className, autoFocus, placeholder, ...props },\n ref,\n ) {\n const internalTextareaRef = useRef<HTMLTextAreaElement>(null);\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n\n useImperativeHandle(\n ref,\n () => internalTextareaRef.current as HTMLTextAreaElement,\n );\n\n useEffect(() => {\n if (autoFocus) {\n internalTextareaRef.current?.focus({ preventScroll: true });\n }\n }, [autoFocus]);\n\n return (\n <textarea\n ref={internalTextareaRef}\n data-testid=\"copilot-chat-textarea\"\n placeholder={placeholder ?? labels.chatInputPlaceholder}\n className={twMerge(\n \"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]\",\n className,\n )}\n style={{\n overflow: \"auto\",\n resize: \"none\",\n ...style,\n }}\n rows={1}\n {...props}\n />\n );\n },\n );\n\n export const AudioRecorder = CopilotChatAudioRecorder;\n\n export const Disclaimer: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n className,\n ...props\n }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <div\n className={cn(\n \"cpk:text-center cpk:text-xs cpk:text-muted-foreground cpk:py-3 cpk:px-4 cpk:max-w-3xl cpk:mx-auto\",\n className,\n )}\n {...props}\n >\n {labels.chatDisclaimerText}\n </div>\n );\n };\n}\n\nCopilotChatInput.TextArea.displayName = \"CopilotChatInput.TextArea\";\nCopilotChatInput.SendButton.displayName = \"CopilotChatInput.SendButton\";\nCopilotChatInput.ToolbarButton.displayName = \"CopilotChatInput.ToolbarButton\";\nCopilotChatInput.StartTranscribeButton.displayName =\n \"CopilotChatInput.StartTranscribeButton\";\nCopilotChatInput.CancelTranscribeButton.displayName =\n \"CopilotChatInput.CancelTranscribeButton\";\nCopilotChatInput.FinishTranscribeButton.displayName =\n \"CopilotChatInput.FinishTranscribeButton\";\nCopilotChatInput.AddMenuButton.displayName = \"CopilotChatInput.AddMenuButton\";\nCopilotChatInput.Disclaimer.displayName = \"CopilotChatInput.Disclaimer\";\n\nexport default CopilotChatInput;\n","\"use client\";\n\nimport { useEffect } from \"react\";\n\nlet injected = false;\n\n/**\n * Dynamically injects KaTeX CSS at runtime to avoid the Next.js\n * \"Global CSS cannot be imported from within node_modules\" build error.\n *\n * Uses a singleton flag so the stylesheet is only injected once.\n */\nexport function useKatexStyles(): void {\n useEffect(() => {\n if (injected || typeof document === \"undefined\") return;\n injected = true;\n\n // Dynamic import defers CSS loading to runtime, bypassing\n // Next.js static analysis that rejects global CSS from node_modules.\n\n void import(\"katex/dist/katex.min.css\").catch(() => {\n console.warn(\n \"[CopilotKit] Failed to load katex styles — math content may render without formatting\",\n );\n });\n }, []);\n}\n","import * as React from \"react\";\nimport { createComponent } from \"@lit-labs/react\";\nimport type { CopilotKitCore } from \"@copilotkit/core\";\nimport type { Anchor } from \"@copilotkit/web-inspector\";\n\ntype CopilotKitInspectorBaseProps = {\n core?: CopilotKitCore | null;\n defaultAnchor?: Anchor;\n [key: string]: unknown;\n};\n\ntype InspectorComponent = React.ComponentType<CopilotKitInspectorBaseProps>;\n\nexport interface CopilotKitInspectorProps extends CopilotKitInspectorBaseProps {}\n\nexport const CopilotKitInspector: React.FC<CopilotKitInspectorProps> = ({\n core,\n ...rest\n}) => {\n const [InspectorComponent, setInspectorComponent] =\n React.useState<InspectorComponent | null>(null);\n\n React.useEffect(() => {\n let mounted = true;\n\n // Load the web component only on the client to keep SSR output stable.\n import(\"@copilotkit/web-inspector\").then((mod) => {\n mod.defineWebInspector?.();\n\n const Component = createComponent({\n tagName: mod.WEB_INSPECTOR_TAG,\n elementClass: mod.WebInspectorElement,\n react: React,\n }) as InspectorComponent;\n\n if (mounted) {\n setInspectorComponent(() => Component);\n }\n });\n\n return () => {\n mounted = false;\n };\n }, []);\n\n // During SSR (and until the client finishes loading), render nothing to keep markup consistent.\n if (!InspectorComponent) return null;\n\n return <InspectorComponent {...rest} core={core ?? null} />;\n};\n\nCopilotKitInspector.displayName = \"CopilotKitInspector\";\n","import React from \"react\";\n\ninterface LicenseWarningBannerProps {\n type:\n | \"no_license\"\n | \"expired\"\n | \"expiring\"\n | \"invalid\"\n | \"feature_unlicensed\";\n featureName?: string;\n expiryDate?: string;\n graceRemaining?: number;\n onDismiss?: () => void;\n}\n\nconst BANNER_STYLES: Record<string, React.CSSProperties> = {\n base: {\n position: \"fixed\",\n bottom: \"8px\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n zIndex: 99999,\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"12px\",\n whiteSpace: \"nowrap\",\n padding: \"8px 16px\",\n fontSize: \"13px\",\n fontFamily:\n \"-apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif\",\n borderRadius: \"6px\",\n boxShadow: \"0 2px 8px rgba(0, 0, 0, 0.15)\",\n },\n info: {\n backgroundColor: \"#eff6ff\",\n border: \"1px solid #93c5fd\",\n color: \"#1e40af\",\n },\n warning: {\n backgroundColor: \"#fffbeb\",\n border: \"1px solid #fbbf24\",\n color: \"#92400e\",\n },\n critical: {\n backgroundColor: \"#fef2f2\",\n border: \"1px solid #fca5a5\",\n color: \"#991b1b\",\n },\n};\n\nfunction getSeverityStyle(severity: string): React.CSSProperties {\n switch (severity) {\n case \"warning\":\n return BANNER_STYLES.warning;\n case \"critical\":\n return BANNER_STYLES.critical;\n default:\n return BANNER_STYLES.info;\n }\n}\n\nfunction BannerShell({\n severity,\n message,\n actionLabel,\n actionUrl,\n onDismiss,\n}: {\n severity: string;\n message: string;\n actionLabel: string;\n actionUrl: string;\n onDismiss?: () => void;\n}) {\n return (\n <div style={{ ...BANNER_STYLES.base, ...getSeverityStyle(severity) }}>\n <span>{message}</span>\n <div style={{ display: \"flex\", gap: \"8px\", alignItems: \"center\" }}>\n <a\n href={actionUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{\n fontWeight: 600,\n textDecoration: \"underline\",\n color: \"inherit\",\n }}\n >\n {actionLabel}\n </a>\n {onDismiss && (\n <button\n onClick={onDismiss}\n style={{\n background: \"none\",\n border: \"none\",\n cursor: \"pointer\",\n color: \"inherit\",\n fontSize: \"16px\",\n }}\n >\n ×\n </button>\n )}\n </div>\n </div>\n );\n}\n\nexport function LicenseWarningBanner({\n type,\n featureName,\n expiryDate,\n graceRemaining,\n onDismiss,\n}: LicenseWarningBannerProps) {\n switch (type) {\n case \"no_license\":\n return (\n <BannerShell\n severity=\"info\"\n message=\"Powered by CopilotKit\"\n actionLabel=\"Get a license\"\n actionUrl=\"https://copilotkit.ai/pricing\"\n onDismiss={onDismiss}\n />\n );\n case \"feature_unlicensed\":\n return (\n <BannerShell\n severity=\"warning\"\n message={`⚠ The \"${featureName}\" feature requires a CopilotKit license.`}\n actionLabel=\"Get a license\"\n actionUrl=\"https://copilotkit.ai/pricing\"\n onDismiss={onDismiss}\n />\n );\n case \"expiring\":\n return (\n <BannerShell\n severity=\"warning\"\n message={`Your CopilotKit license expires in ${graceRemaining} day${graceRemaining !== 1 ? \"s\" : \"\"}. Please renew.`}\n actionLabel=\"Renew\"\n actionUrl=\"https://cloud.copilotkit.ai\"\n onDismiss={onDismiss}\n />\n );\n case \"expired\":\n return (\n <BannerShell\n severity=\"critical\"\n message={`Your CopilotKit license expired${expiryDate ? ` on ${expiryDate}` : \"\"}. Please renew at copilotkit.ai/pricing`}\n actionLabel=\"Renew now\"\n actionUrl=\"https://copilotkit.ai/pricing\"\n onDismiss={onDismiss}\n />\n );\n case \"invalid\":\n return (\n <BannerShell\n severity=\"critical\"\n message=\"Invalid CopilotKit license token. Please check your configuration.\"\n actionLabel=\"Get a license\"\n actionUrl=\"https://copilotkit.ai/pricing\"\n onDismiss={onDismiss}\n />\n );\n default:\n return null;\n }\n}\n\nexport function InlineFeatureWarning({ featureName }: { featureName: string }) {\n return (\n <div\n style={{\n padding: \"8px 12px\",\n backgroundColor: \"#fffbeb\",\n border: \"1px solid #fbbf24\",\n borderRadius: \"6px\",\n fontSize: \"13px\",\n color: \"#92400e\",\n fontFamily:\n \"-apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif\",\n }}\n >\n ⚠ The "{featureName}" feature requires a CopilotKit license.{\" \"}\n <a\n href=\"https://copilotkit.ai/pricing\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{ color: \"#b45309\", textDecoration: \"underline\" }}\n >\n Get one at copilotkit.ai/pricing\n </a>\n </div>\n );\n}\n","\"use client\";\n\nimport React, { useEffect, useRef, useState, useCallback } from \"react\";\nimport { z } from \"zod\";\nimport type { AbstractAgent, RunAgentResult } from \"@ag-ui/client\";\nimport { useCopilotKit } from \"../providers/CopilotKitProvider\";\n\n// Protocol version supported\nconst PROTOCOL_VERSION = \"2025-06-18\";\n\n// Build sandbox proxy HTML with optional extra CSP domains from resource metadata\nfunction buildSandboxHTML(extraCspDomains?: string[]): string {\n const baseScriptSrc =\n \"'self' 'wasm-unsafe-eval' 'unsafe-inline' 'unsafe-eval' blob: data: http://localhost:* https://localhost:*\";\n const baseFrameSrc = \"* blob: data: http://localhost:* https://localhost:*\";\n const extra = extraCspDomains?.length ? \" \" + extraCspDomains.join(\" \") : \"\";\n const scriptSrc = baseScriptSrc + extra;\n const frameSrc = baseFrameSrc + extra;\n\n return `<!doctype html>\n<html>\n<head>\n<meta charset=\"utf-8\" />\n<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 ${scriptSrc}; style-src * blob: data: 'unsafe-inline'; connect-src *; frame-src ${frameSrc}; base-uri 'self';\" />\n<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>\n</head>\n<body>\n<script>\nif(window.self===window.top){throw new Error(\"This file must be used in an iframe.\")}\nconst inner=document.createElement(\"iframe\");\ninner.style=\"width:100%;height:100%;border:none;\";\ninner.setAttribute(\"sandbox\",\"allow-scripts allow-same-origin allow-forms\");\ndocument.body.appendChild(inner);\nwindow.addEventListener(\"message\",async(event)=>{\nif(event.source===window.parent){\nif(event.data&&event.data.method===\"ui/notifications/sandbox-resource-ready\"){\nconst{html,sandbox}=event.data.params;\nif(typeof sandbox===\"string\")inner.setAttribute(\"sandbox\",sandbox);\nif(typeof html===\"string\")inner.srcdoc=html;\n}else if(inner&&inner.contentWindow){\ninner.contentWindow.postMessage(event.data,\"*\");\n}\n}else if(event.source===inner.contentWindow){\nwindow.parent.postMessage(event.data,\"*\");\n}\n});\nwindow.parent.postMessage({jsonrpc:\"2.0\",method:\"ui/notifications/sandbox-proxy-ready\",params:{}},\"*\");\n</script>\n</body>\n</html>`;\n}\n\n/**\n * Queue for serializing MCP app requests to an agent.\n * Ensures requests wait for the agent to stop running and are processed one at a time.\n */\nclass MCPAppsRequestQueue {\n private queues = new Map<\n string,\n Array<{\n execute: () => Promise<RunAgentResult>;\n resolve: (result: RunAgentResult) => void;\n reject: (error: Error) => void;\n }>\n >();\n private processing = new Map<string, boolean>();\n\n /**\n * Add a request to the queue for a specific agent thread.\n * Returns a promise that resolves when the request completes.\n */\n async enqueue(\n agent: AbstractAgent,\n request: () => Promise<RunAgentResult>,\n ): Promise<RunAgentResult> {\n const threadId = agent.threadId || \"default\";\n\n return new Promise((resolve, reject) => {\n // Get or create queue for this thread\n let queue = this.queues.get(threadId);\n if (!queue) {\n queue = [];\n this.queues.set(threadId, queue);\n }\n\n // Add request to queue\n queue.push({ execute: request, resolve, reject });\n\n // Start processing if not already running\n this.processQueue(threadId, agent);\n });\n }\n\n private async processQueue(\n threadId: string,\n agent: AbstractAgent,\n ): Promise<void> {\n // If already processing this queue, return\n if (this.processing.get(threadId)) {\n return;\n }\n\n this.processing.set(threadId, true);\n\n try {\n const queue = this.queues.get(threadId);\n if (!queue) return;\n\n while (queue.length > 0) {\n const item = queue[0]!;\n\n try {\n // Wait for any active run to complete before processing\n await this.waitForAgentIdle(agent);\n\n // Execute the request\n const result = await item.execute();\n item.resolve(result);\n } catch (error) {\n item.reject(\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n\n // Remove processed item\n queue.shift();\n }\n } finally {\n this.processing.set(threadId, false);\n }\n }\n\n private waitForAgentIdle(agent: AbstractAgent): Promise<void> {\n return new Promise((resolve) => {\n if (!agent.isRunning) {\n resolve();\n return;\n }\n\n let done = false;\n const finish = () => {\n if (done) return;\n done = true;\n clearInterval(checkInterval);\n sub.unsubscribe();\n resolve();\n };\n\n const sub = agent.subscribe({\n onRunFinalized: finish,\n onRunFailed: finish,\n });\n\n // Fallback for reconnect scenarios where events don't fire\n const checkInterval = setInterval(() => {\n if (!agent.isRunning) finish();\n }, 500);\n });\n }\n}\n\n// Global queue instance for all MCP app requests\nconst mcpAppsRequestQueue = new MCPAppsRequestQueue();\n\n/**\n * Activity type for MCP Apps events - must match the middleware's MCPAppsActivityType\n */\nexport const MCPAppsActivityType = \"mcp-apps\";\n\n// Zod schema for activity content validation (middleware 0.0.2 format)\nexport const MCPAppsActivityContentSchema = z.object({\n result: z.object({\n content: z.array(z.any()).optional(),\n structuredContent: z.any().optional(),\n isError: z.boolean().optional(),\n }),\n // Resource URI to fetch (e.g., \"ui://server/dashboard\")\n resourceUri: z.string(),\n // MD5 hash of server config (renamed from serverId in 0.0.1)\n serverHash: z.string(),\n // Optional stable server ID from config (takes precedence over serverHash)\n serverId: z.string().optional(),\n // Original tool input arguments\n toolInput: z.record(z.unknown()).optional(),\n});\n\nexport type MCPAppsActivityContent = z.infer<\n typeof MCPAppsActivityContentSchema\n>;\n\n// Type for the resource fetched from the server\ninterface FetchedResource {\n uri: string;\n mimeType?: string;\n text?: string;\n blob?: string;\n _meta?: {\n ui?: {\n prefersBorder?: boolean;\n csp?: {\n connectDomains?: string[];\n resourceDomains?: string[];\n };\n };\n };\n}\n\ninterface JSONRPCRequest {\n jsonrpc: \"2.0\";\n id: string | number;\n method: string;\n params?: Record<string, unknown>;\n}\n\ninterface JSONRPCResponse {\n jsonrpc: \"2.0\";\n id: string | number;\n result?: unknown;\n error?: { code: number; message: string };\n}\n\ninterface JSONRPCNotification {\n jsonrpc: \"2.0\";\n method: string;\n params?: Record<string, unknown>;\n}\n\ntype JSONRPCMessage = JSONRPCRequest | JSONRPCResponse | JSONRPCNotification;\n\nfunction isRequest(msg: JSONRPCMessage): msg is JSONRPCRequest {\n return \"id\" in msg && \"method\" in msg;\n}\n\nfunction isNotification(msg: JSONRPCMessage): msg is JSONRPCNotification {\n return !(\"id\" in msg) && \"method\" in msg;\n}\n\n/**\n * Props for the activity renderer component\n */\ninterface MCPAppsActivityRendererProps {\n activityType: string;\n content: MCPAppsActivityContent;\n message: unknown; // ActivityMessage from @ag-ui/core\n agent: AbstractAgent | undefined;\n}\n\n/**\n * MCP Apps Extension Activity Renderer\n *\n * Renders MCP Apps UI in a sandboxed iframe with full protocol support.\n * Fetches resource content on-demand via proxied MCP requests.\n */\nexport const MCPAppsActivityRenderer: React.FC<MCPAppsActivityRendererProps> =\n function MCPAppsActivityRenderer({ content, agent }) {\n const { copilotkit } = useCopilotKit();\n const containerRef = useRef<HTMLDivElement>(null);\n const iframeRef = useRef<HTMLIFrameElement | null>(null);\n const [iframeReady, setIframeReady] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [iframeSize, setIframeSize] = useState<{\n width?: number;\n height?: number;\n }>({});\n const [fetchedResource, setFetchedResource] =\n useState<FetchedResource | null>(null);\n\n // Use refs for values that shouldn't trigger re-renders but need latest values\n const contentRef = useRef(content);\n contentRef.current = content;\n\n // Store agent in a ref for use in async handlers\n const agentRef = useRef(agent);\n agentRef.current = agent;\n\n // Ref to track fetch state - survives StrictMode remounts\n const fetchStateRef = useRef<{\n inProgress: boolean;\n promise: Promise<FetchedResource | null> | null;\n resourceUri: string | null;\n }>({ inProgress: false, promise: null, resourceUri: null });\n\n // Callback to send a message to the iframe\n const sendToIframe = useCallback((msg: JSONRPCMessage) => {\n if (iframeRef.current?.contentWindow) {\n console.log(\"[MCPAppsRenderer] Sending to iframe:\", msg);\n iframeRef.current.contentWindow.postMessage(msg, \"*\");\n }\n }, []);\n\n // Callback to send a JSON-RPC response\n const sendResponse = useCallback(\n (id: string | number, result: unknown) => {\n sendToIframe({\n jsonrpc: \"2.0\",\n id,\n result,\n });\n },\n [sendToIframe],\n );\n\n // Callback to send a JSON-RPC error response\n const sendErrorResponse = useCallback(\n (id: string | number, code: number, message: string) => {\n sendToIframe({\n jsonrpc: \"2.0\",\n id,\n error: { code, message },\n });\n },\n [sendToIframe],\n );\n\n // Callback to send a notification\n const sendNotification = useCallback(\n (method: string, params?: Record<string, unknown>) => {\n sendToIframe({\n jsonrpc: \"2.0\",\n method,\n params: params || {},\n });\n },\n [sendToIframe],\n );\n\n // Effect 0: Fetch the resource content on mount\n // Uses ref-based deduplication to handle React StrictMode double-mounting\n useEffect(() => {\n const { resourceUri, serverHash, serverId } = content;\n\n // Check if we already have a fetch in progress for this resource\n // This handles StrictMode double-mounting - second mount reuses first mount's promise\n if (\n fetchStateRef.current.inProgress &&\n fetchStateRef.current.resourceUri === resourceUri\n ) {\n // Reuse the existing promise\n fetchStateRef.current.promise\n ?.then((resource) => {\n if (resource) {\n setFetchedResource(resource);\n setIsLoading(false);\n }\n })\n .catch((err) => {\n setError(err instanceof Error ? err : new Error(String(err)));\n setIsLoading(false);\n });\n return;\n }\n\n if (!agent) {\n setError(new Error(\"No agent available to fetch resource\"));\n setIsLoading(false);\n return;\n }\n\n // Mark fetch as in progress\n fetchStateRef.current.inProgress = true;\n fetchStateRef.current.resourceUri = resourceUri;\n\n // Create the fetch promise using the queue to serialize requests\n const fetchPromise = (async (): Promise<FetchedResource | null> => {\n try {\n // Use queue to wait for agent to be idle and serialize requests\n const runResult = await mcpAppsRequestQueue.enqueue(agent, () =>\n agent.runAgent({\n forwardedProps: {\n __proxiedMCPRequest: {\n serverHash,\n serverId, // optional, takes precedence if provided\n method: \"resources/read\",\n params: { uri: resourceUri },\n },\n },\n }),\n );\n\n // Extract resource from result\n // The response format is: { contents: [{ uri, mimeType, text?, blob?, _meta? }] }\n const resultData = runResult.result as\n | { contents?: FetchedResource[] }\n | undefined;\n const resource = resultData?.contents?.[0];\n\n if (!resource) {\n throw new Error(\"No resource content in response\");\n }\n\n return resource;\n } catch (err) {\n console.error(\"[MCPAppsRenderer] Failed to fetch resource:\", err);\n throw err;\n } finally {\n // Mark fetch as complete\n fetchStateRef.current.inProgress = false;\n }\n })();\n\n // Store the promise for potential reuse\n fetchStateRef.current.promise = fetchPromise;\n\n // Handle the result\n fetchPromise\n .then((resource) => {\n if (resource) {\n setFetchedResource(resource);\n setIsLoading(false);\n }\n })\n .catch((err) => {\n setError(err instanceof Error ? err : new Error(String(err)));\n setIsLoading(false);\n });\n\n // No cleanup needed - we want the fetch to complete even if StrictMode unmounts\n }, [agent, content]);\n\n // Effect 1: Setup sandbox proxy iframe and communication (after resource is fetched)\n useEffect(() => {\n // Wait for resource to be fetched\n if (isLoading || !fetchedResource) {\n return;\n }\n\n // Capture container reference at effect start (refs are cleared during unmount)\n const container = containerRef.current;\n if (!container) {\n return;\n }\n\n let mounted = true;\n let messageHandler: ((event: MessageEvent) => void) | null = null;\n let initialListener: ((event: MessageEvent) => void) | null = null;\n let createdIframe: HTMLIFrameElement | null = null;\n\n const setup = async () => {\n try {\n // Create sandbox proxy iframe\n const iframe = document.createElement(\"iframe\");\n createdIframe = iframe; // Track for cleanup\n iframe.style.width = \"100%\";\n iframe.style.height = \"100px\"; // Start small, will be resized by size-changed notification\n iframe.style.border = \"none\";\n iframe.style.backgroundColor = \"transparent\";\n iframe.style.display = \"block\";\n iframe.setAttribute(\n \"sandbox\",\n \"allow-scripts allow-same-origin allow-forms\",\n );\n\n // Wait for sandbox proxy to be ready\n const sandboxReady = new Promise<void>((resolve) => {\n initialListener = (event: MessageEvent) => {\n if (event.source === iframe.contentWindow) {\n if (\n event.data?.method === \"ui/notifications/sandbox-proxy-ready\"\n ) {\n if (initialListener) {\n window.removeEventListener(\"message\", initialListener);\n initialListener = null;\n }\n resolve();\n }\n }\n };\n window.addEventListener(\"message\", initialListener);\n });\n\n // Check mounted before adding to DOM (handles StrictMode double-mount)\n if (!mounted) {\n if (initialListener) {\n window.removeEventListener(\"message\", initialListener);\n initialListener = null;\n }\n return;\n }\n\n // Build sandbox HTML with CSP domains from resource metadata\n const cspDomains = fetchedResource._meta?.ui?.csp?.resourceDomains;\n iframe.srcdoc = buildSandboxHTML(cspDomains);\n iframeRef.current = iframe;\n container.appendChild(iframe);\n\n // Wait for sandbox proxy to signal ready\n await sandboxReady;\n if (!mounted) return;\n\n console.log(\"[MCPAppsRenderer] Sandbox proxy ready\");\n\n // Setup message handler for JSON-RPC messages from the inner iframe\n messageHandler = async (event: MessageEvent) => {\n if (event.source !== iframe.contentWindow) return;\n\n const msg = event.data as JSONRPCMessage;\n if (!msg || typeof msg !== \"object\" || msg.jsonrpc !== \"2.0\")\n return;\n\n console.log(\"[MCPAppsRenderer] Received from iframe:\", msg);\n\n // Handle requests (need response)\n if (isRequest(msg)) {\n switch (msg.method) {\n case \"ui/initialize\": {\n // Respond with host capabilities\n sendResponse(msg.id, {\n protocolVersion: PROTOCOL_VERSION,\n hostInfo: {\n name: \"CopilotKit MCP Apps Host\",\n version: \"1.0.0\",\n },\n hostCapabilities: {\n openLinks: {},\n logging: {},\n },\n hostContext: {\n theme: \"light\",\n platform: \"web\",\n },\n });\n break;\n }\n\n case \"ui/message\": {\n // Add message to CopilotKit chat and optionally invoke agent\n const currentAgent = agentRef.current;\n\n if (!currentAgent) {\n console.warn(\n \"[MCPAppsRenderer] ui/message: No agent available\",\n );\n sendResponse(msg.id, { isError: false });\n break;\n }\n\n try {\n const params = msg.params as {\n role?: string;\n content?: Array<{ type: string; text?: string }>;\n followUp?: boolean;\n };\n\n const role =\n (params.role as \"user\" | \"assistant\") || \"user\";\n\n // Extract text content from the message\n const textContent =\n params.content\n ?.filter((c) => c.type === \"text\" && c.text)\n .map((c) => c.text)\n .join(\"\\n\") || \"\";\n\n if (textContent) {\n currentAgent.addMessage({\n id: crypto.randomUUID(),\n role,\n content: textContent,\n });\n }\n\n // Acknowledge the message immediately — don't block on agent run\n sendResponse(msg.id, { isError: false });\n\n // Determine whether to invoke the agent after adding message.\n // followUp: true → always invoke agent\n // followUp: false → display-only, skip agent\n // not specified → invoke for user messages, skip for assistant\n const shouldFollowUp = params.followUp ?? role === \"user\";\n\n if (shouldFollowUp && textContent) {\n // Use copilotkit.runAgent to go through RunHandler — provides\n // frontend tools, context, tool execution, and abort support.\n // Fire-and-forget: errors are handled by RunHandler's error emission.\n mcpAppsRequestQueue\n .enqueue(currentAgent, () =>\n copilotkit.runAgent({ agent: currentAgent }),\n )\n .catch((err) =>\n console.error(\n \"[MCPAppsRenderer] ui/message agent run failed:\",\n err,\n ),\n );\n }\n } catch (err) {\n console.error(\"[MCPAppsRenderer] ui/message error:\", err);\n sendResponse(msg.id, { isError: true });\n }\n break;\n }\n\n case \"ui/open-link\": {\n // Open URL in new tab\n const url = msg.params?.url as string | undefined;\n if (url) {\n window.open(url, \"_blank\", \"noopener,noreferrer\");\n sendResponse(msg.id, { isError: false });\n } else {\n sendErrorResponse(msg.id, -32602, \"Missing url parameter\");\n }\n break;\n }\n\n case \"tools/call\": {\n // Proxy tool call to MCP server via agent.runAgent()\n const { serverHash, serverId } = contentRef.current;\n const currentAgent = agentRef.current;\n\n if (!serverHash) {\n sendErrorResponse(\n msg.id,\n -32603,\n \"No server hash available for proxying\",\n );\n break;\n }\n\n if (!currentAgent) {\n sendErrorResponse(\n msg.id,\n -32603,\n \"No agent available for proxying\",\n );\n break;\n }\n\n try {\n // Use queue to wait for agent to be idle and serialize requests\n const runResult = await mcpAppsRequestQueue.enqueue(\n currentAgent,\n () =>\n currentAgent.runAgent({\n forwardedProps: {\n __proxiedMCPRequest: {\n serverHash,\n serverId, // optional, takes precedence if provided\n method: \"tools/call\",\n params: msg.params,\n },\n },\n }),\n );\n\n // The result from runAgent contains the MCP response\n sendResponse(msg.id, runResult.result || {});\n } catch (err) {\n console.error(\"[MCPAppsRenderer] tools/call error:\", err);\n sendErrorResponse(msg.id, -32603, String(err));\n }\n break;\n }\n\n default:\n sendErrorResponse(\n msg.id,\n -32601,\n `Method not found: ${msg.method}`,\n );\n }\n }\n\n // Handle notifications (no response needed)\n if (isNotification(msg)) {\n switch (msg.method) {\n case \"ui/notifications/initialized\": {\n console.log(\"[MCPAppsRenderer] Inner iframe initialized\");\n if (mounted) {\n setIframeReady(true);\n }\n break;\n }\n\n case \"ui/notifications/size-changed\": {\n const { width, height } = msg.params || {};\n console.log(\"[MCPAppsRenderer] Size change:\", {\n width,\n height,\n });\n if (mounted) {\n setIframeSize({\n width: typeof width === \"number\" ? width : undefined,\n height: typeof height === \"number\" ? height : undefined,\n });\n }\n break;\n }\n\n case \"notifications/message\": {\n // Logging notification from the app\n console.log(\"[MCPAppsRenderer] App log:\", msg.params);\n break;\n }\n }\n }\n };\n\n window.addEventListener(\"message\", messageHandler);\n\n // Extract HTML content from fetched resource\n let html: string;\n if (fetchedResource.text) {\n html = fetchedResource.text;\n } else if (fetchedResource.blob) {\n html = atob(fetchedResource.blob);\n } else {\n throw new Error(\"Resource has no text or blob content\");\n }\n\n // Send the resource content to the sandbox proxy\n sendNotification(\"ui/notifications/sandbox-resource-ready\", { html });\n } catch (err) {\n console.error(\"[MCPAppsRenderer] Setup error:\", err);\n if (mounted) {\n setError(err instanceof Error ? err : new Error(String(err)));\n }\n }\n };\n\n setup();\n\n return () => {\n mounted = false;\n // Clean up initial listener if still active\n if (initialListener) {\n window.removeEventListener(\"message\", initialListener);\n initialListener = null;\n }\n if (messageHandler) {\n window.removeEventListener(\"message\", messageHandler);\n }\n // Remove the iframe we created (using tracked reference, not DOM query)\n // This works even if containerRef.current is null during unmount\n if (createdIframe) {\n createdIframe.remove();\n createdIframe = null;\n }\n iframeRef.current = null;\n };\n }, [\n isLoading,\n fetchedResource,\n sendNotification,\n sendResponse,\n sendErrorResponse,\n ]);\n\n // Effect 2: Update iframe size when it changes\n useEffect(() => {\n if (iframeRef.current) {\n if (iframeSize.width !== undefined) {\n // Use minWidth with min() to allow expansion but cap at 100%\n iframeRef.current.style.minWidth = `min(${iframeSize.width}px, 100%)`;\n iframeRef.current.style.width = \"100%\";\n }\n if (iframeSize.height !== undefined) {\n iframeRef.current.style.height = `${iframeSize.height}px`;\n }\n }\n }, [iframeSize]);\n\n // Effect 3: Send tool input when iframe ready\n useEffect(() => {\n if (iframeReady && content.toolInput) {\n console.log(\"[MCPAppsRenderer] Sending tool input:\", content.toolInput);\n sendNotification(\"ui/notifications/tool-input\", {\n arguments: content.toolInput,\n });\n }\n }, [iframeReady, content.toolInput, sendNotification]);\n\n // Effect 4: Send tool result when iframe ready\n useEffect(() => {\n if (iframeReady && content.result) {\n console.log(\"[MCPAppsRenderer] Sending tool result:\", content.result);\n sendNotification(\"ui/notifications/tool-result\", content.result);\n }\n }, [iframeReady, content.result, sendNotification]);\n\n // Determine border styling based on prefersBorder metadata from fetched resource\n // true = show border/background, false = none, undefined = host decides (we default to none)\n const prefersBorder = fetchedResource?._meta?.ui?.prefersBorder;\n const borderStyle =\n prefersBorder === true\n ? {\n borderRadius: \"8px\",\n backgroundColor: \"#f9f9f9\",\n border: \"1px solid #e0e0e0\",\n }\n : {};\n\n return (\n <div\n ref={containerRef}\n style={{\n width: \"100%\",\n height: iframeSize.height ? `${iframeSize.height}px` : \"auto\",\n minHeight: \"100px\",\n overflow: \"hidden\",\n position: \"relative\",\n ...borderStyle,\n }}\n >\n {isLoading && (\n <div style={{ padding: \"1rem\", color: \"#666\" }}>Loading...</div>\n )}\n {error && (\n <div style={{ color: \"red\", padding: \"1rem\" }}>\n Error: {error.message}\n </div>\n )}\n </div>\n );\n };\n","import { createContext, useContext } from \"react\";\nimport type { SandboxFunction } from \"../types/sandbox-function\";\n\nexport const SandboxFunctionsContext = createContext<\n readonly SandboxFunction[]\n>([]);\n\nexport function useSandboxFunctions(): readonly SandboxFunction[] {\n return useContext(SandboxFunctionsContext);\n}\n","/**\n * Extracts all complete `<style>` blocks from the raw HTML.\n * Returns the concatenated style tags, suitable for injection into `<head>`.\n */\nexport function extractCompleteStyles(html: string): string {\n const matches = html.match(/<style\\b[^>]*>[\\s\\S]*?<\\/style>/gi);\n return matches ? matches.join(\"\") : \"\";\n}\n\n/**\n * Processes raw accumulated HTML for safe preview via innerHTML injection.\n * Pure function, no DOM dependencies.\n *\n * Pipeline (order matters):\n * 1. Strip incomplete tag at end\n * 2. Strip complete <style>, <script>, and <head> blocks\n * 3. Strip incomplete <style>/<script>/<head> blocks\n * 4. Strip incomplete HTML entities\n * 5. Extract body content (or use full string if no <body>)\n */\nexport function processPartialHtml(html: string): string {\n let result = html;\n\n // 1. Strip incomplete tag at end — e.g. `<div class=\"fo`\n result = result.replace(/<[^>]*$/, \"\");\n\n // 2. Strip complete <style>, <script>, and <head> blocks\n result = result.replace(/<(style|script|head)\\b[^>]*>[\\s\\S]*?<\\/\\1>/gi, \"\");\n\n // 3. Strip incomplete <style>/<script>/<head> blocks (opening tag, no close)\n result = result.replace(/<(style|script|head)\\b[^>]*>[\\s\\S]*$/gi, \"\");\n\n // 4. Strip incomplete HTML entities — e.g. `&` without semicolon\n result = result.replace(/&[a-zA-Z0-9#]*$/, \"\");\n\n // 5. Extract body content\n const bodyMatch = result.match(/<body[^>]*>([\\s\\S]*)/i);\n if (bodyMatch) {\n result = bodyMatch[1]!;\n // Strip </body> and everything after\n result = result.replace(/<\\/body>[\\s\\S]*/i, \"\");\n }\n\n return result;\n}\n","\"use client\";\n\nimport React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { z } from \"zod\";\nimport { ToolCallStatus } from \"@copilotkit/core\";\nimport { useSandboxFunctions } from \"../providers/SandboxFunctionsContext\";\nimport {\n processPartialHtml,\n extractCompleteStyles,\n} from \"../lib/processPartialHtml\";\n\nexport const OpenGenerativeUIActivityType = \"open-generative-ui\";\n\nexport const OpenGenerativeUIContentSchema = z.object({\n initialHeight: z.number().optional(),\n generating: z.boolean().optional(),\n css: z.string().optional(),\n cssComplete: z.boolean().optional(),\n html: z.array(z.string()).optional(),\n htmlComplete: z.boolean().optional(),\n jsFunctions: z.string().optional(),\n jsFunctionsComplete: z.boolean().optional(),\n jsExpressions: z.array(z.string()).optional(),\n jsExpressionsComplete: z.boolean().optional(),\n});\n\nexport type OpenGenerativeUIContent = z.infer<\n typeof OpenGenerativeUIContentSchema\n>;\n\n/**\n * Schema for the generateSandboxedUi tool call arguments.\n * Used by the frontend tool renderer to display placeholder messages.\n */\nexport const GenerateSandboxedUiArgsSchema = z.object({\n initialHeight: z.number().optional(),\n placeholderMessages: z.array(z.string()).optional(),\n css: z.string().optional(),\n html: z.string().optional(),\n jsFunctions: z.string().optional(),\n jsExpressions: z.array(z.string()).optional(),\n});\n\nexport type GenerateSandboxedUiArgs = z.infer<\n typeof GenerateSandboxedUiArgsSchema\n>;\n\ninterface OpenGenerativeUIActivityRendererProps {\n activityType: string;\n content: OpenGenerativeUIContent;\n message: unknown;\n agent: unknown;\n}\n\nconst THROTTLE_MS = 1000;\n\n/**\n * Returns true when the inner component should re-render immediately\n * (no throttle delay).\n */\nfunction shouldFlushImmediately(\n prev: OpenGenerativeUIContent | null,\n next: OpenGenerativeUIContent,\n): boolean {\n // CSS finished — switch from placeholder to preview\n if (next.cssComplete && (!prev || !prev.cssComplete)) return true;\n // Streaming done\n if (next.htmlComplete) return true;\n // Generation finished\n if (next.generating === false) return true;\n // jsFunctions appeared\n if (next.jsFunctions && (!prev || !prev.jsFunctions)) return true;\n // jsExpressions grew\n if ((next.jsExpressions?.length ?? 0) > (prev?.jsExpressions?.length ?? 0))\n return true;\n // First html chunk arrived (first preview — no delay)\n if (next.html?.length && (!prev || !prev.html?.length)) return true;\n return false;\n}\n\n/**\n * Outer wrapper — absorbs every parent re-render but only forwards\n * throttled content snapshots to the memoized inner component.\n */\nexport const OpenGenerativeUIActivityRenderer: React.FC<OpenGenerativeUIActivityRendererProps> =\n function OpenGenerativeUIActivityRenderer({ content }) {\n const latestContentRef = useRef(content);\n latestContentRef.current = content;\n\n const [throttledContent, setThrottledContent] =\n useState<OpenGenerativeUIContent>(content);\n const throttledContentRef = useRef(throttledContent);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // Synchronous state adjustment during render (React-approved pattern).\n // When shouldFlushImmediately is true, update state before commit so the\n // inner component sees the new content in the same render pass — no extra\n // async cycle that would break test timing.\n if (throttledContentRef.current !== content) {\n if (shouldFlushImmediately(throttledContentRef.current, content)) {\n if (timerRef.current !== null) {\n clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n throttledContentRef.current = content;\n setThrottledContent(content);\n }\n }\n\n const flush = useCallback(() => {\n timerRef.current = null;\n const latest = latestContentRef.current;\n throttledContentRef.current = latest;\n setThrottledContent(latest);\n }, []);\n\n // Schedule throttled updates for non-immediate content changes\n useEffect(() => {\n // Already up to date (initial render or synchronous flush above)\n if (throttledContentRef.current === content) return;\n\n // Schedule a throttled flush if none pending\n if (timerRef.current === null) {\n timerRef.current = setTimeout(flush, THROTTLE_MS);\n }\n }, [content, flush]);\n\n // Cleanup timer on unmount\n useEffect(() => {\n return () => {\n if (timerRef.current !== null) {\n clearTimeout(timerRef.current);\n }\n };\n }, []);\n\n return <OpenGenerativeUIActivityRendererInner content={throttledContent} />;\n };\n\n// ---------------------------------------------------------------------------\n// Inner component — all the expensive work, protected by React.memo\n// ---------------------------------------------------------------------------\n\ninterface InnerProps {\n content: OpenGenerativeUIContent;\n}\n\nfunction ensureHead(html: string): string {\n if (/<head[\\s>]/i.test(html)) return html;\n return `<head></head>${html}`;\n}\n\nfunction injectCssIntoHtml(html: string, css: string): string {\n const headCloseIdx = html.indexOf(\"</head>\");\n if (headCloseIdx !== -1) {\n return (\n html.slice(0, headCloseIdx) +\n `<style>${css}</style>` +\n html.slice(headCloseIdx)\n );\n }\n return `<head><style>${css}</style></head>${html}`;\n}\n\nconst OpenGenerativeUIActivityRendererInner = React.memo(\n function OpenGenerativeUIActivityRendererInner({ content }: InnerProps) {\n const initialHeight = content.initialHeight ?? 200;\n const [autoHeight, setAutoHeight] = useState<number | null>(null);\n const sandboxFunctions = useSandboxFunctions();\n\n const localApi = useMemo(() => {\n const api: Record<string, Function> = {};\n for (const fn of sandboxFunctions) {\n api[fn.name] = fn.handler;\n }\n return api;\n }, [sandboxFunctions]);\n\n // Join html chunks only when streaming is complete\n const fullHtml =\n content.htmlComplete && content.html?.length\n ? content.html.join(\"\")\n : undefined;\n\n // CSS from the dedicated parameter (available once cssComplete)\n const css = content.cssComplete ? content.css : undefined;\n\n // Derived state for preview streaming — gate on cssComplete so we\n // show the placeholder until styles are ready.\n const cssReady = !!content.cssComplete;\n const partialHtml =\n !content.htmlComplete && content.html?.length\n ? content.html.join(\"\")\n : undefined;\n const previewBody = partialHtml\n ? processPartialHtml(partialHtml)\n : undefined;\n const previewStyles = partialHtml ? extractCompleteStyles(partialHtml) : \"\";\n const hasPreview = cssReady && !!previewBody?.trim();\n const hasVisibleSandbox = !!fullHtml || hasPreview;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const sandboxRef = useRef<{\n run: (code: string | Function) => Promise<unknown>;\n destroy: () => void;\n iframe: HTMLIFrameElement;\n } | null>(null);\n const previewSandboxRef = useRef<{\n run: (code: string | Function) => Promise<unknown>;\n destroy: () => void;\n iframe: HTMLIFrameElement;\n } | null>(null);\n const previewReadyRef = useRef(false);\n const sandboxReadyRef = useRef(false);\n const executedIndexRef = useRef(0);\n const pendingQueueRef = useRef<string[]>([]);\n const jsFunctionsInjectedRef = useRef(false);\n\n // Effect 0 — Preview sandbox creation\n useEffect(() => {\n const container = containerRef.current;\n if (!container || fullHtml || !hasPreview || previewSandboxRef.current)\n return;\n\n let cancelled = false;\n\n import(\"@jetbrains/websandbox\")\n .then((mod: any) => {\n if (cancelled) return;\n\n const Websandbox = mod.default?.default ?? mod.default;\n const sandbox = Websandbox.create(\n {},\n {\n frameContainer: container,\n frameContent: \"<head></head><body></body>\",\n allowAdditionalAttributes: \"\",\n },\n );\n previewSandboxRef.current = sandbox;\n\n sandbox.iframe.style.width = \"100%\";\n sandbox.iframe.style.height = \"100%\";\n sandbox.iframe.style.border = \"none\";\n sandbox.iframe.style.backgroundColor = \"transparent\";\n\n sandbox.promise.then(() => {\n if (cancelled) return;\n previewReadyRef.current = true;\n\n // Prevent scrollbars inside preview iframe\n sandbox.run(`\n var s = document.createElement('style');\n s.textContent = 'html, body { overflow: hidden !important; }';\n document.head.appendChild(s);\n `);\n\n // Inject CSS from the dedicated parameter + any inline styles from HTML\n const headParts: string[] = [];\n if (css) headParts.push(`<style>${css}</style>`);\n if (previewStyles) headParts.push(previewStyles);\n if (headParts.length) {\n sandbox.run(\n `document.head.innerHTML = ${JSON.stringify(headParts.join(\"\"))}`,\n );\n }\n if (previewBody) {\n sandbox.run(\n `document.body.innerHTML = ${JSON.stringify(previewBody)}`,\n );\n }\n });\n })\n .catch((err: unknown) => {\n console.error(\n \"[OpenGenerativeUI] Failed to load sandbox module:\",\n err,\n );\n });\n\n return () => {\n cancelled = true;\n };\n }, [hasPreview, fullHtml]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Effect 0b — Preview content updates (body + styles)\n useEffect(() => {\n if (!previewSandboxRef.current || !previewReadyRef.current) return;\n const headParts: string[] = [];\n if (css) headParts.push(`<style>${css}</style>`);\n if (previewStyles) headParts.push(previewStyles);\n if (headParts.length) {\n previewSandboxRef.current.run(\n `document.head.innerHTML = ${JSON.stringify(headParts.join(\"\"))}`,\n );\n }\n if (!previewBody) return;\n previewSandboxRef.current.run(\n `document.body.innerHTML = ${JSON.stringify(previewBody)}`,\n );\n }, [previewBody, previewStyles, css]);\n\n // Effect 1 — Final sandbox lifecycle (depends on fullHtml)\n useEffect(() => {\n const container = containerRef.current;\n if (!container || !fullHtml) return;\n\n // Destroy preview sandbox when transitioning to final\n if (previewSandboxRef.current) {\n previewSandboxRef.current.destroy();\n previewSandboxRef.current = null;\n previewReadyRef.current = false;\n }\n\n let cancelled = false;\n\n // Reset state for new html\n executedIndexRef.current = 0;\n jsFunctionsInjectedRef.current = false;\n sandboxReadyRef.current = false;\n pendingQueueRef.current = [];\n\n // Dynamic import to avoid SSR issues (websandbox references `self` at module level)\n const htmlContent = css ? injectCssIntoHtml(fullHtml, css) : fullHtml;\n import(\"@jetbrains/websandbox\")\n .then((mod: any) => {\n if (cancelled) return;\n\n // websandbox ships a UMD bundle with its own webpack `default` export.\n // Consumer bundlers (e.g. Next.js webpack) wrap CJS under another `.default`,\n // resulting in mod.default.default for the actual Websandbox class.\n const Websandbox = mod.default?.default ?? mod.default;\n const sandbox = Websandbox.create(localApi, {\n frameContainer: container,\n frameContent: ensureHead(htmlContent),\n allowAdditionalAttributes: \"\",\n });\n sandboxRef.current = sandbox;\n\n // Style the iframe to fill container\n sandbox.iframe.style.width = \"100%\";\n sandbox.iframe.style.height = \"100%\";\n sandbox.iframe.style.border = \"none\";\n sandbox.iframe.style.backgroundColor = \"transparent\";\n\n sandbox.promise.then(() => {\n if (cancelled) return;\n sandboxReadyRef.current = true;\n\n // Prevent scrollbars — the container auto-sizes to fit content\n sandbox.run(`\n var s = document.createElement('style');\n s.textContent = 'html, body { overflow: hidden !important; }';\n document.head.appendChild(s);\n `);\n\n // Flush pending queue\n const queue = pendingQueueRef.current;\n pendingQueueRef.current = [];\n for (const code of queue) {\n sandbox.run(code);\n }\n });\n })\n .catch((err: unknown) => {\n console.error(\n \"[OpenGenerativeUI] Failed to load sandbox module:\",\n err,\n );\n });\n\n return () => {\n cancelled = true;\n // Destroy preview sandbox if it still exists\n if (previewSandboxRef.current) {\n previewSandboxRef.current.destroy();\n previewSandboxRef.current = null;\n previewReadyRef.current = false;\n }\n if (sandboxRef.current) {\n sandboxRef.current.destroy();\n sandboxRef.current = null;\n }\n sandboxReadyRef.current = false;\n setAutoHeight(null);\n };\n }, [fullHtml, css, localApi]);\n\n // Effect 2 — jsFunctions injection (depends on content.jsFunctions)\n useEffect(() => {\n if (!content.jsFunctions || jsFunctionsInjectedRef.current) return;\n jsFunctionsInjectedRef.current = true;\n\n const sandbox = sandboxRef.current;\n if (sandboxReadyRef.current && sandbox) {\n sandbox.run(content.jsFunctions);\n } else {\n pendingQueueRef.current.push(content.jsFunctions);\n }\n }, [content.jsFunctions]);\n\n // Effect 3 — jsExpressions execution (depends on content.jsExpressions?.length)\n useEffect(() => {\n const expressions = content.jsExpressions;\n if (!expressions || expressions.length === 0) return;\n\n const startIndex = executedIndexRef.current;\n if (startIndex >= expressions.length) return;\n\n const newExprs = expressions.slice(startIndex);\n executedIndexRef.current = expressions.length;\n\n const sandbox = sandboxRef.current;\n if (sandboxReadyRef.current && sandbox) {\n (async () => {\n for (const expr of newExprs) {\n await sandbox.run(expr);\n }\n })();\n } else {\n pendingQueueRef.current.push(...newExprs);\n }\n }, [content.jsExpressions?.length]);\n\n // Effect 4 — One-shot height measurement (fires once when generation completes)\n // Uses body.scrollHeight (not documentElement.scrollHeight) because the latter\n // is clamped to the iframe viewport and can never shrink below the current size.\n const generationDone = content.generating === false;\n useEffect(() => {\n const sandbox = sandboxRef.current;\n if (!generationDone || !sandbox) return;\n\n let handled = false;\n const onMessage = (e: MessageEvent) => {\n if (handled) return;\n if (\n e.source === sandbox.iframe.contentWindow &&\n e.data?.type === \"__ck_resize\"\n ) {\n handled = true;\n setAutoHeight(e.data.height);\n window.removeEventListener(\"message\", onMessage);\n }\n };\n window.addEventListener(\"message\", onMessage);\n\n const measureOnce = `\n (function() {\n var s = document.createElement('style');\n s.textContent = 'body { height: auto !important; min-height: 0 !important; }';\n document.head.appendChild(s);\n var h = document.body.scrollHeight;\n var cs = getComputedStyle(document.body);\n h += parseFloat(cs.marginTop) || 0;\n h += parseFloat(cs.marginBottom) || 0;\n s.remove();\n parent.postMessage({ type: \"__ck_resize\", height: Math.ceil(h) }, \"*\");\n })();\n `;\n\n if (sandboxReadyRef.current) {\n sandbox.run(measureOnce);\n } else {\n pendingQueueRef.current.push(measureOnce);\n }\n\n return () => {\n window.removeEventListener(\"message\", onMessage);\n };\n }, [generationDone]);\n\n const height = autoHeight ?? initialHeight;\n\n const isGenerating = content.generating !== false;\n\n return (\n <div\n ref={containerRef}\n style={{\n position: \"relative\",\n width: \"100%\",\n height: `${height}px`,\n borderRadius: \"8px\",\n backgroundColor: hasVisibleSandbox ? \"transparent\" : \"#f5f5f5\",\n border: hasVisibleSandbox ? \"none\" : \"1px solid #e0e0e0\",\n display: hasVisibleSandbox ? \"block\" : \"flex\",\n alignItems: hasVisibleSandbox ? undefined : \"center\",\n justifyContent: hasVisibleSandbox ? undefined : \"center\",\n overflow: \"hidden\",\n }}\n >\n {isGenerating && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n zIndex: 10,\n pointerEvents: \"all\",\n backgroundColor: \"rgba(255, 255, 255, 0.5)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <svg\n width=\"48\"\n height=\"48\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n style={{ animation: \"ck-spin 1s linear infinite\" }}\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"#e0e0e0\" strokeWidth=\"3\" />\n <path\n d=\"M12 2a10 10 0 0 1 10 10\"\n stroke=\"#999\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n />\n </svg>\n <style>{`@keyframes ck-spin { to { transform: rotate(360deg) } }`}</style>\n </div>\n )}\n </div>\n );\n },\n (prev, next) => prev.content === next.content,\n);\n\n/**\n * Frontend tool renderer for generateSandboxedUi.\n * Displays placeholder messages while the UI is being generated.\n */\nexport const OpenGenerativeUIToolRenderer: React.FC<\n | {\n name: string;\n args: Partial<GenerateSandboxedUiArgs>;\n status: ToolCallStatus.InProgress;\n result: undefined;\n }\n | {\n name: string;\n args: GenerateSandboxedUiArgs;\n status: ToolCallStatus.Executing;\n result: undefined;\n }\n | {\n name: string;\n args: GenerateSandboxedUiArgs;\n status: ToolCallStatus.Complete;\n result: string;\n }\n> = function OpenGenerativeUIToolRenderer(props) {\n const [visibleMessageIndex, setVisibleMessageIndex] = useState(0);\n const prevMessageCountRef = useRef(0);\n\n const messages = props.args.placeholderMessages;\n\n // Cycle through placeholder messages\n useEffect(() => {\n if (!messages || messages.length === 0) return;\n\n // When a new message streams in, jump to it immediately\n if (messages.length !== prevMessageCountRef.current) {\n prevMessageCountRef.current = messages.length;\n setVisibleMessageIndex(messages.length - 1);\n }\n\n // Auto-cycle every 3s while still in progress\n if (props.status === ToolCallStatus.Complete) return;\n const timer = setInterval(() => {\n setVisibleMessageIndex((i) => (i + 1) % messages.length);\n }, 5000);\n return () => clearInterval(timer);\n }, [messages?.length, props.status]);\n\n // Don't render anything once complete — the activity renderer handles the UI\n if (props.status === ToolCallStatus.Complete) return null;\n\n if (!messages || messages.length === 0) return null;\n\n return (\n <div\n style={{\n padding: \"8px 12px\",\n color: \"#999\",\n fontSize: \"14px\",\n }}\n >\n {messages[visibleMessageIndex] ?? messages[0]}\n </div>\n );\n};\n","import { useCopilotKit } from \"../providers\";\nimport type { ReactActivityMessageRenderer } from \"../types/react-activity-message-renderer\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { z } from \"zod\";\nimport {\n A2UIProvider,\n useA2UIActions,\n useA2UIError,\n A2UIRenderer,\n initializeDefaultCatalog,\n injectStyles,\n DEFAULT_SURFACE_ID,\n} from \"@copilotkit/a2ui-renderer\";\nimport type { Theme, A2UIClientEventMessage } from \"@copilotkit/a2ui-renderer\";\n\n/**\n * The container key used to wrap A2UI operations for explicit detection.\n * Must match A2UI_OPERATIONS_KEY in @ag-ui/a2ui-middleware and copilotkit.a2ui (Python).\n */\nconst A2UI_OPERATIONS_KEY = \"a2ui_operations\";\n\n// Initialize the React renderer's component catalog and styles once\nlet initialized = false;\nfunction ensureInitialized() {\n if (!initialized) {\n initializeDefaultCatalog();\n injectStyles();\n initialized = true;\n }\n}\n\n/**\n * User action with dataContextPath, as dispatched by A2UI components.\n */\nexport type A2UIUserAction = {\n name: string;\n sourceComponentId: string;\n surfaceId: string;\n timestamp: string;\n context?: Record<string, unknown>;\n dataContextPath?: string;\n};\n\nexport type A2UIMessageRendererOptions = {\n theme: Theme;\n /** Optional component catalog to pass to A2UIProvider */\n catalog?: any;\n /** Optional custom loading component shown while A2UI surface is generating. */\n loadingComponent?: React.ComponentType;\n};\n\nexport function createA2UIMessageRenderer(\n options: A2UIMessageRendererOptions,\n): ReactActivityMessageRenderer<any> {\n const { theme, catalog, loadingComponent } = options;\n\n return {\n activityType: \"a2ui-surface\",\n content: z.any(),\n render: ({ content, agent }) => {\n ensureInitialized();\n\n const [operations, setOperations] = useState<any[]>([]);\n const { copilotkit } = useCopilotKit();\n\n const lastContentRef = useRef<unknown>(null);\n useEffect(() => {\n // Skip if same content reference\n if (content === lastContentRef.current) return;\n lastContentRef.current = content;\n\n const incoming = content?.[A2UI_OPERATIONS_KEY];\n if (!content || !Array.isArray(incoming)) {\n setOperations([]);\n return;\n }\n\n setOperations(incoming);\n }, [content]);\n\n // Group operations by surface ID\n const groupedOperations = useMemo(() => {\n const groups = new Map<string, any[]>();\n\n for (const operation of operations) {\n const surfaceId =\n getOperationSurfaceId(operation) ?? DEFAULT_SURFACE_ID;\n\n if (!groups.has(surfaceId)) {\n groups.set(surfaceId, []);\n }\n groups.get(surfaceId)!.push(operation);\n }\n\n return groups;\n }, [operations]);\n\n if (!groupedOperations.size) {\n // Show loading state while A2UI surface is being generated\n const LoadingComponent = loadingComponent ?? DefaultA2UILoading;\n return <LoadingComponent />;\n }\n\n return (\n <div className=\"cpk:flex cpk:min-h-0 cpk:flex-1 cpk:flex-col cpk:gap-6 cpk:overflow-auto cpk:py-6\">\n {Array.from(groupedOperations.entries()).map(([surfaceId, ops]) => (\n <ReactSurfaceHost\n key={surfaceId}\n surfaceId={surfaceId}\n operations={ops}\n theme={theme}\n agent={agent}\n copilotkit={copilotkit}\n catalog={catalog}\n />\n ))}\n </div>\n );\n },\n };\n}\n\ntype ReactSurfaceHostProps = {\n surfaceId: string;\n operations: any[];\n theme: Theme;\n agent: any;\n copilotkit: any;\n /** Optional component catalog to pass to A2UIProvider */\n catalog?: any;\n};\n\n/**\n * Renders a single A2UI surface using the React renderer.\n * Wraps A2UIProvider + A2UIRenderer and bridges actions back to CopilotKit.\n */\nfunction ReactSurfaceHost({\n surfaceId,\n operations,\n theme,\n agent,\n copilotkit,\n catalog,\n}: ReactSurfaceHostProps) {\n // Bridge: when the React renderer dispatches an action, forward to CopilotKit\n const handleAction = useCallback(\n async (message: A2UIClientEventMessage) => {\n if (!agent) return;\n\n const action = message.userAction as A2UIUserAction | undefined;\n\n try {\n copilotkit.setProperties({\n ...(copilotkit.properties ?? {}),\n a2uiAction: message,\n });\n\n await copilotkit.runAgent({ agent });\n } finally {\n if (copilotkit.properties) {\n const { a2uiAction, ...rest } = copilotkit.properties;\n copilotkit.setProperties(rest);\n }\n }\n },\n [agent, copilotkit],\n );\n\n return (\n <div className=\"cpk:flex cpk:w-full cpk:flex-none cpk:flex-col cpk:gap-4\">\n <A2UIProvider onAction={handleAction} theme={theme} catalog={catalog}>\n <SurfaceMessageProcessor\n surfaceId={surfaceId}\n operations={operations}\n />\n <A2UISurfaceOrError surfaceId={surfaceId} />\n </A2UIProvider>\n </div>\n );\n}\n\n/**\n * Renders the A2UI surface, or an error message if processing failed.\n * Must be a child of A2UIProvider to access the error state.\n */\nfunction A2UISurfaceOrError({ surfaceId }: { surfaceId: string }) {\n const error = useA2UIError();\n if (error) {\n return (\n <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\">\n A2UI render error: {error}\n </div>\n );\n }\n return <A2UIRenderer surfaceId={surfaceId} className=\"cpk:flex cpk:flex-1\" />;\n}\n\n/**\n * Processes A2UI operations into the provider's message processor.\n * Must be a child of A2UIProvider to access the actions context.\n */\nfunction SurfaceMessageProcessor({\n surfaceId,\n operations,\n}: {\n surfaceId: string;\n operations: any[];\n}) {\n const { processMessages, getSurface } = useA2UIActions();\n const lastHashRef = useRef<string>(\"\");\n useEffect(() => {\n // Skip if operations haven't actually changed (deep compare via hash).\n // ACTIVITY_DELTA + ACTIVITY_SNAPSHOT can trigger multiple renders with\n // the same logical content but different object references.\n const hash = JSON.stringify(operations);\n if (hash === lastHashRef.current) return;\n lastHashRef.current = hash;\n\n // Filter out createSurface if the surface already exists — the\n // MessageProcessor throws on duplicate createSurface, but content\n // snapshots always include the full operation list.\n const existing = getSurface(surfaceId);\n const ops = existing\n ? operations.filter((op) => !op?.createSurface)\n : operations;\n\n // Error handling is done inside A2UIProvider.processMessages\n processMessages(ops);\n }, [processMessages, getSurface, surfaceId, operations]);\n\n return null;\n}\n\n/**\n * Default loading component shown while an A2UI surface is generating.\n * Displays an animated shimmer skeleton.\n */\nfunction DefaultA2UILoading() {\n return (\n <div\n className=\"cpk:flex cpk:flex-col cpk:gap-3 cpk:rounded-xl cpk:border cpk:border-gray-100 cpk:bg-gray-50/50 cpk:p-5\"\n style={{ minHeight: 120 }}\n >\n <div className=\"cpk:flex cpk:items-center cpk:gap-2\">\n <div\n className=\"cpk:h-3 cpk:w-3 cpk:rounded-full cpk:bg-gray-200\"\n style={{\n animation: \"cpk-a2ui-pulse 1.5s ease-in-out infinite\",\n }}\n />\n <span className=\"cpk:text-xs cpk:font-medium cpk:text-gray-400\">\n Generating UI...\n </span>\n </div>\n <div className=\"cpk:flex cpk:flex-col cpk:gap-2\">\n {[0.8, 0.6, 0.4].map((width, i) => (\n <div\n key={i}\n className=\"cpk:h-3 cpk:rounded cpk:bg-gray-200/70\"\n style={{\n width: `${width * 100}%`,\n animation: `cpk-a2ui-pulse 1.5s ease-in-out ${i * 0.15}s infinite`,\n }}\n />\n ))}\n </div>\n <style>{`\n @keyframes cpk-a2ui-pulse {\n 0%, 100% { opacity: 0.4; }\n 50% { opacity: 1; }\n }\n `}</style>\n </div>\n );\n}\n\nfunction getOperationSurfaceId(operation: any): string | null {\n if (!operation || typeof operation !== \"object\") {\n return null;\n }\n\n if (typeof operation.surfaceId === \"string\") {\n return operation.surfaceId;\n }\n\n // v0.9 message keys\n return (\n operation?.createSurface?.surfaceId ??\n operation?.updateComponents?.surfaceId ??\n operation?.updateDataModel?.surfaceId ??\n operation?.deleteSurface?.surfaceId ??\n null\n );\n}\n","import React from \"react\";\nimport { z } from \"zod\";\nimport type { StandardSchemaV1, InferSchemaOutput } from \"@copilotkit/shared\";\nimport { ReactToolCallRenderer } from \"./react-tool-call-renderer\";\nimport { ToolCallStatus } from \"@copilotkit/core\";\n\n/**\n * Helper to define a type-safe tool call renderer entry.\n * - Accepts a single object whose keys match ReactToolCallRenderer's fields: { name, args, render, agentId? }.\n * - Derives `args` type from the provided schema (any Standard Schema V1 compatible library).\n * - Ensures the render function param type exactly matches ReactToolCallRenderer<T>[\"render\"]'s param.\n * - For wildcard tools (name: \"*\"), args is optional and defaults to z.any()\n */\ntype RenderProps<T> =\n | {\n name: string;\n args: Partial<T>;\n status: ToolCallStatus.InProgress;\n result: undefined;\n }\n | {\n name: string;\n args: T;\n status: ToolCallStatus.Executing;\n result: undefined;\n }\n | {\n name: string;\n args: T;\n status: ToolCallStatus.Complete;\n result: string;\n };\n\n// Overload for wildcard tools without args\nexport function defineToolCallRenderer(def: {\n name: \"*\";\n render: (props: RenderProps<any>) => React.ReactElement;\n agentId?: string;\n}): ReactToolCallRenderer<any>;\n\n// Overload for regular tools with args\nexport function defineToolCallRenderer<S extends StandardSchemaV1>(def: {\n name: string;\n args: S;\n render: (props: RenderProps<InferSchemaOutput<S>>) => React.ReactElement;\n agentId?: string;\n}): ReactToolCallRenderer<InferSchemaOutput<S>>;\n\n// Implementation\nexport function defineToolCallRenderer<S extends StandardSchemaV1>(def: {\n name: string;\n args?: S;\n render: (props: any) => React.ReactElement;\n agentId?: string;\n}): ReactToolCallRenderer<any> {\n // For wildcard tools, default to z.any() if no args provided\n const argsSchema = def.name === \"*\" && !def.args ? z.any() : def.args;\n\n return {\n name: def.name,\n args: argsSchema,\n render: def.render as React.ComponentType<any>,\n ...(def.agentId ? { agentId: def.agentId } : {}),\n };\n}\n","import React, { useEffect, useRef } from \"react\";\nimport { useCopilotKit } from \"../providers/CopilotKitProvider\";\nimport { defineToolCallRenderer } from \"../types/defineToolCallRenderer\";\nimport { z } from \"zod\";\n\n/**\n * Tool name used by the dynamic A2UI generation secondary LLM.\n * This renderer is auto-registered when A2UI is enabled.\n */\nexport const RENDER_A2UI_TOOL_NAME = \"render_a2ui\";\n\ninterface A2UIProgressProps {\n parameters: unknown;\n}\n\n/**\n * Built-in progress indicator for dynamic A2UI generation.\n * Shows a skeleton wireframe that progressively reveals as tokens stream in.\n *\n * Registered automatically when A2UI is enabled. Users can override by\n * providing their own `useRenderTool({ name: \"render_a2ui\", ... })`.\n */\nfunction A2UIProgressIndicator({ parameters }: A2UIProgressProps) {\n const lastRef = useRef({ time: 0, tokens: 0 });\n const now = Date.now();\n\n let { tokens } = lastRef.current;\n if (now - lastRef.current.time > 200) {\n const chars = JSON.stringify(parameters ?? {}).length;\n tokens = Math.round(chars / 4);\n lastRef.current = { time: now, tokens };\n }\n\n const phase = tokens < 50 ? 0 : tokens < 200 ? 1 : tokens < 400 ? 2 : 3;\n\n return (\n <div style={{ margin: \"12px 0\", maxWidth: 320 }}>\n <div\n style={{\n position: \"relative\",\n overflow: \"hidden\",\n borderRadius: 12,\n border: \"1px solid rgba(228,228,231,0.8)\",\n backgroundColor: \"#fff\",\n boxShadow: \"0 1px 2px rgba(0,0,0,0.04)\",\n padding: \"16px 18px 14px\",\n }}\n >\n {/* Top bar */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n marginBottom: 12,\n }}\n >\n <div style={{ display: \"flex\", gap: 4 }}>\n <Dot />\n <Dot />\n <Dot />\n </div>\n <Bar\n w={64}\n h={6}\n bg=\"#e4e4e7\"\n opacity={phase >= 1 ? 1 : 0.4}\n transition=\"opacity 0.5s\"\n />\n </div>\n\n {/* Skeleton lines */}\n <div style={{ display: \"grid\", gap: 7 }}>\n <Row show={phase >= 0}>\n <Bar w={36} h={7} bg=\"rgba(147,197,253,0.7)\" anim={0} />\n <Bar w={80} h={7} bg=\"rgba(219,234,254,0.8)\" anim={0.2} />\n </Row>\n <Row show={phase >= 0} delay={0.1}>\n <Spacer />\n <Dot />\n <Bar w={100} h={7} bg=\"rgba(24,24,27,0.2)\" anim={0.3} />\n </Row>\n <Row show={phase >= 1} delay={0.15}>\n <Spacer />\n <Bar w={48} h={7} bg=\"rgba(24,24,27,0.15)\" anim={0.1} />\n <Bar w={40} h={7} bg=\"rgba(153,246,228,0.6)\" anim={0.5} />\n <Bar w={56} h={7} bg=\"rgba(147,197,253,0.6)\" anim={0.3} />\n </Row>\n <Row show={phase >= 1} delay={0.2}>\n <Spacer />\n <Dot />\n <Bar w={60} h={7} bg=\"rgba(24,24,27,0.15)\" anim={0.4} />\n </Row>\n <Row show={phase >= 2} delay={0.25}>\n <Bar w={40} h={7} bg=\"rgba(153,246,228,0.5)\" anim={0.2} />\n <Dot />\n <Bar w={48} h={7} bg=\"rgba(24,24,27,0.15)\" anim={0.6} />\n <Bar w={64} h={7} bg=\"rgba(147,197,253,0.5)\" anim={0.1} />\n </Row>\n <Row show={phase >= 2} delay={0.3}>\n <Bar w={36} h={7} bg=\"rgba(147,197,253,0.6)\" anim={0.5} />\n <Bar w={36} h={7} bg=\"rgba(24,24,27,0.12)\" anim={0.7} />\n </Row>\n <Row show={phase >= 3} delay={0.35}>\n <Dot />\n <Bar w={44} h={7} bg=\"rgba(24,24,27,0.18)\" anim={0.3} />\n <Dot />\n <Bar w={56} h={7} bg=\"rgba(153,246,228,0.5)\" anim={0.8} />\n <Bar w={48} h={7} bg=\"rgba(147,197,253,0.5)\" anim={0.4} />\n </Row>\n </div>\n\n {/* Shimmer */}\n <div\n style={{\n pointerEvents: \"none\",\n position: \"absolute\",\n inset: 0,\n background:\n \"linear-gradient(105deg, transparent 0%, transparent 40%, rgba(255,255,255,0.6) 50%, transparent 60%, transparent 100%)\",\n backgroundSize: \"250% 100%\",\n animation: \"cpk-a2ui-sweep 3s ease-in-out infinite\",\n }}\n />\n </div>\n\n {/* Label */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 8,\n marginTop: 8,\n }}\n >\n <span\n style={{\n fontSize: 12,\n color: \"#a1a1aa\",\n letterSpacing: \"0.025em\",\n }}\n >\n Building interface\n </span>\n {tokens > 0 && (\n <span\n style={{\n fontSize: 11,\n color: \"#d4d4d8\",\n fontVariantNumeric: \"tabular-nums\",\n }}\n >\n ~{tokens.toLocaleString()} tokens\n </span>\n )}\n </div>\n\n <style>{`\n @keyframes cpk-a2ui-fade {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n }\n @keyframes cpk-a2ui-sweep {\n 0% { background-position: 250% 0; }\n 100% { background-position: -250% 0; }\n }\n `}</style>\n </div>\n );\n}\n\n// --- Primitives ---\n\nfunction Dot() {\n return (\n <div\n style={{\n width: 7,\n height: 7,\n borderRadius: \"50%\",\n backgroundColor: \"#d4d4d8\",\n flexShrink: 0,\n }}\n />\n );\n}\n\nfunction Spacer() {\n return <div style={{ width: 12 }} />;\n}\n\nfunction Bar({\n w,\n h,\n bg,\n anim,\n opacity,\n transition,\n}: {\n w: number;\n h: number;\n bg: string;\n anim?: number;\n opacity?: number;\n transition?: string;\n}) {\n return (\n <div\n style={{\n width: w,\n height: h,\n borderRadius: 9999,\n backgroundColor: bg,\n ...(anim !== undefined\n ? { animation: `cpk-a2ui-fade 2.4s ease-in-out ${anim}s infinite` }\n : {}),\n ...(opacity !== undefined ? { opacity } : {}),\n ...(transition ? { transition } : {}),\n }}\n />\n );\n}\n\nfunction Row({\n children,\n show,\n delay = 0,\n}: {\n children: React.ReactNode;\n show: boolean;\n delay?: number;\n}) {\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 6,\n opacity: show ? 1 : 0,\n transition: `opacity 0.4s ${delay}s`,\n }}\n >\n {children}\n </div>\n );\n}\n\n// --- Hook entry point ---\n\n/**\n * Registers the built-in `render_a2ui` tool call renderer via the props-based\n * `setRenderToolCalls` mechanism (not `useRenderTool`).\n *\n * This ensures user-registered `useRenderTool({ name: \"render_a2ui\", ... })`\n * hooks automatically override the built-in, since the merge logic in\n * react-core.ts gives hook-based entries priority over prop-based entries.\n */\nexport function A2UIBuiltInToolCallRenderer(): null {\n const { copilotkit } = useCopilotKit();\n\n useEffect(() => {\n const renderer = defineToolCallRenderer({\n name: RENDER_A2UI_TOOL_NAME,\n args: z.any(),\n render: ({ status, args: parameters }) => {\n if (status === \"complete\") return <></>;\n const params = parameters as any;\n // Hide skeleton once the A2UI surface has enough data to render.\n // For data-bound surfaces: items array is populated.\n // For dashboard-style surfaces: components array has multiple entries\n // (meaning the streaming path is emitting activity snapshots).\n const items = params?.items;\n if (Array.isArray(items) && items.length > 0) return <></>;\n const components = params?.components;\n if (Array.isArray(components) && components.length > 2) return <></>;\n return <A2UIProgressIndicator parameters={parameters} />;\n },\n });\n\n // Register via props-based mechanism so useRenderTool hooks take priority\n const existing = (copilotkit as any)._renderToolCalls ?? [];\n copilotkit.setRenderToolCalls([\n ...existing.filter((rc: any) => rc.name !== RENDER_A2UI_TOOL_NAME),\n renderer,\n ]);\n }, [copilotkit]);\n\n return null;\n}\n","import { useCopilotKit } from \"../providers/CopilotKitProvider\";\nimport { useLayoutEffect, useMemo } from \"react\";\n\n/**\n * Represents any value that can be serialized to JSON.\n */\nexport type JsonSerializable =\n | string\n | number\n | boolean\n | null\n | JsonSerializable[]\n | { [key: string]: JsonSerializable };\n\n/**\n * Context configuration for useAgentContext.\n * Accepts any JSON-serializable value which will be converted to a string.\n */\nexport interface AgentContextInput {\n /** A human-readable description of what this context represents */\n description: string;\n /** The context value - will be converted to a JSON string if not already a string */\n value: JsonSerializable;\n}\n\nexport function useAgentContext(context: AgentContextInput) {\n const { description, value } = context;\n const { copilotkit } = useCopilotKit();\n\n const stringValue = useMemo(() => {\n if (typeof value === \"string\") {\n return value;\n }\n return JSON.stringify(value);\n }, [value]);\n\n useLayoutEffect(() => {\n if (!copilotkit) return;\n\n const id = copilotkit.addContext({ description, value: stringValue });\n return () => {\n copilotkit.removeContext(id);\n };\n }, [description, stringValue, copilotkit]);\n}\n","\"use client\";\n\nimport {\n buildCatalogContextValue,\n A2UI_SCHEMA_CONTEXT_DESCRIPTION,\n extractCatalogComponentSchemas,\n} from \"@copilotkit/a2ui-renderer\";\nimport {\n A2UI_DEFAULT_GENERATION_GUIDELINES,\n A2UI_DEFAULT_DESIGN_GUIDELINES,\n} from \"@copilotkit/shared\";\nimport { useAgentContext } from \"../hooks/use-agent-context\";\nimport { useCopilotKit } from \"../providers/CopilotKitProvider\";\nimport { useLayoutEffect, useMemo } from \"react\";\n\n/**\n * Renders agent context describing the available A2UI catalog and custom components.\n * Only mount this component when A2UI is enabled.\n *\n * When `includeSchema` is true, the full component schemas (JSON Schema) are also\n * sent as context using the same description key as the A2UI middleware, so the\n * middleware can optionally overwrite it with a server-side schema.\n */\nexport function A2UICatalogContext({\n catalog,\n includeSchema,\n}: {\n catalog?: any;\n includeSchema?: boolean;\n}) {\n const contextValue = buildCatalogContextValue(catalog);\n\n useAgentContext({\n description:\n \"A2UI catalog capabilities: available catalog IDs and custom component definitions the client can render.\",\n value: contextValue,\n });\n\n // When includeSchema is true, send full component schemas in the same format\n // as the A2UI middleware so it can overwrite with a server-side schema if needed.\n const { copilotkit } = useCopilotKit();\n const schemaValue = useMemo(\n () =>\n includeSchema !== false\n ? JSON.stringify(extractCatalogComponentSchemas(catalog))\n : null,\n [catalog, includeSchema],\n );\n\n useLayoutEffect(() => {\n if (!copilotkit || !schemaValue) return;\n const ids: string[] = [];\n ids.push(\n copilotkit.addContext({\n description: A2UI_SCHEMA_CONTEXT_DESCRIPTION,\n value: schemaValue,\n }),\n );\n ids.push(\n copilotkit.addContext({\n description:\n \"A2UI generation guidelines — protocol rules, tool arguments, path rules, data model format, and form/two-way-binding instructions.\",\n value: A2UI_DEFAULT_GENERATION_GUIDELINES,\n }),\n );\n ids.push(\n copilotkit.addContext({\n description:\n \"A2UI design guidelines — visual design rules, component hierarchy tips, and action handler patterns.\",\n value: A2UI_DEFAULT_DESIGN_GUIDELINES,\n }),\n );\n return () => {\n for (const id of ids) copilotkit.removeContext(id);\n };\n }, [copilotkit, schemaValue]);\n\n return null;\n}\n","import React from \"react\";\nimport { ReactActivityMessageRenderer, ReactToolCallRenderer } from \"../types\";\nimport { ReactCustomMessageRenderer } from \"../types/react-custom-message-renderer\";\nimport {\n CopilotKitCore,\n type CopilotKitCoreConfig,\n type CopilotKitCoreSubscriber,\n type CopilotKitCoreSubscription,\n} from \"@copilotkit/core\";\n\nexport interface CopilotKitCoreReactConfig extends CopilotKitCoreConfig {\n // Add any additional configuration properties specific to the React implementation\n renderToolCalls?: ReactToolCallRenderer<any>[];\n renderActivityMessages?: ReactActivityMessageRenderer<any>[];\n\n // Add custom message renderers\n renderCustomMessages?: ReactCustomMessageRenderer[];\n}\n\nexport interface CopilotKitCoreReactSubscriber extends CopilotKitCoreSubscriber {\n onRenderToolCallsChanged?: (event: {\n copilotkit: CopilotKitCore;\n renderToolCalls: ReactToolCallRenderer<any>[];\n }) => void | Promise<void>;\n onInterruptElementChanged?: (event: {\n copilotkit: CopilotKitCore;\n interruptElement: React.ReactElement | null;\n }) => void | Promise<void>;\n}\n\nexport class CopilotKitCoreReact extends CopilotKitCore {\n private _renderToolCalls: ReactToolCallRenderer<any>[] = [];\n private _hookRenderToolCalls: Map<string, ReactToolCallRenderer<any>> =\n new Map();\n private _cachedMergedRenderToolCalls: ReactToolCallRenderer<any>[] | null =\n null;\n private _renderCustomMessages: ReactCustomMessageRenderer[] = [];\n private _renderActivityMessages: ReactActivityMessageRenderer<any>[] = [];\n private _interruptElement: React.ReactElement | null = null;\n\n constructor(config: CopilotKitCoreReactConfig) {\n super(config);\n this._renderToolCalls = config.renderToolCalls ?? [];\n this._renderCustomMessages = config.renderCustomMessages ?? [];\n this._renderActivityMessages = config.renderActivityMessages ?? [];\n }\n\n get renderCustomMessages(): Readonly<ReactCustomMessageRenderer[]> {\n return this._renderCustomMessages;\n }\n\n get renderActivityMessages(): Readonly<ReactActivityMessageRenderer<any>>[] {\n return this._renderActivityMessages;\n }\n\n get renderToolCalls(): Readonly<ReactToolCallRenderer<any>>[] {\n if (this._hookRenderToolCalls.size === 0) {\n return this._renderToolCalls;\n }\n if (this._cachedMergedRenderToolCalls) {\n return this._cachedMergedRenderToolCalls;\n }\n // Merge: hook entries override prop entries with the same key\n const merged = new Map<string, ReactToolCallRenderer<any>>();\n for (const rc of this._renderToolCalls) {\n merged.set(`${rc.agentId ?? \"\"}:${rc.name}`, rc);\n }\n for (const [key, rc] of this._hookRenderToolCalls) {\n merged.set(key, rc);\n }\n this._cachedMergedRenderToolCalls = Array.from(merged.values());\n return this._cachedMergedRenderToolCalls;\n }\n\n setRenderActivityMessages(\n renderers: ReactActivityMessageRenderer<any>[],\n ): void {\n this._renderActivityMessages = renderers;\n }\n\n setRenderCustomMessages(renderers: ReactCustomMessageRenderer[]): void {\n this._renderCustomMessages = renderers;\n }\n\n setRenderToolCalls(renderToolCalls: ReactToolCallRenderer<any>[]): void {\n this._renderToolCalls = renderToolCalls;\n this._cachedMergedRenderToolCalls = null;\n this._notifyRenderToolCallsChanged();\n }\n\n addHookRenderToolCall(entry: ReactToolCallRenderer<any>): void {\n const key = `${entry.agentId ?? \"\"}:${entry.name}`;\n this._hookRenderToolCalls.set(key, entry);\n this._cachedMergedRenderToolCalls = null;\n this._notifyRenderToolCallsChanged();\n }\n\n removeHookRenderToolCall(name: string, agentId?: string): void {\n const key = `${agentId ?? \"\"}:${name}`;\n if (this._hookRenderToolCalls.delete(key)) {\n this._cachedMergedRenderToolCalls = null;\n this._notifyRenderToolCallsChanged();\n }\n }\n\n private _notifyRenderToolCallsChanged(): void {\n void this.notifySubscribers((subscriber) => {\n const reactSubscriber = subscriber as CopilotKitCoreReactSubscriber;\n if (reactSubscriber.onRenderToolCallsChanged) {\n reactSubscriber.onRenderToolCallsChanged({\n copilotkit: this,\n renderToolCalls: this.renderToolCalls,\n });\n }\n }, \"Subscriber onRenderToolCallsChanged error:\");\n }\n\n get interruptElement(): React.ReactElement | null {\n return this._interruptElement;\n }\n\n setInterruptElement(element: React.ReactElement | null): void {\n this._interruptElement = element;\n void this.notifySubscribers((subscriber) => {\n const reactSubscriber = subscriber as CopilotKitCoreReactSubscriber;\n reactSubscriber.onInterruptElementChanged?.({\n copilotkit: this,\n interruptElement: this._interruptElement,\n });\n }, \"Subscriber onInterruptElementChanged error:\");\n }\n\n // Override to accept React-specific subscriber type\n subscribe(\n subscriber: CopilotKitCoreReactSubscriber,\n ): CopilotKitCoreSubscription {\n return super.subscribe(subscriber);\n }\n\n /**\n * Wait for pending React state updates before the follow-up agent run.\n *\n * When a frontend tool handler calls setState(), React 18 batches the update\n * and schedules a commit via its internal scheduler (MessageChannel). The\n * useAgentContext hook registers context via useLayoutEffect, which runs\n * synchronously after React commits that batch.\n *\n * Awaiting a zero-delay timeout yields to the macrotask queue. React's\n * MessageChannel task runs first, committing the pending state and running\n * useLayoutEffect (which updates the context store). The follow-up runAgent\n * call then reads fresh context.\n */\n async waitForPendingFrameworkUpdates(): Promise<void> {\n await new Promise<void>((resolve) => setTimeout(resolve, 0));\n }\n}\n","\"use client\";\n\nimport type { AbstractAgent } from \"@ag-ui/client\";\nimport type { FrontendTool } from \"@copilotkit/core\";\nimport type React from \"react\";\nimport {\n createContext,\n useContext,\n type ReactNode,\n useMemo,\n useEffect,\n useLayoutEffect,\n useReducer,\n useRef,\n useState,\n} from \"react\";\nimport { z } from \"zod\";\nimport { CopilotKitInspector } from \"../components/CopilotKitInspector\";\nimport type { Anchor } from \"@copilotkit/web-inspector\";\nimport { LicenseWarningBanner } from \"../components/license-warning-banner\";\nimport {\n createLicenseContextValue,\n type LicenseContextValue,\n} from \"@copilotkit/shared\";\nimport type { CopilotKitCoreErrorCode } from \"@copilotkit/core\";\nimport {\n MCPAppsActivityContentSchema,\n MCPAppsActivityRenderer,\n MCPAppsActivityType,\n} from \"../components/MCPAppsActivityRenderer\";\nimport {\n OpenGenerativeUIActivityType,\n OpenGenerativeUIContentSchema,\n OpenGenerativeUIActivityRenderer,\n OpenGenerativeUIToolRenderer,\n GenerateSandboxedUiArgsSchema,\n} from \"../components/OpenGenerativeUIRenderer\";\nimport { createA2UIMessageRenderer } from \"../a2ui/A2UIMessageRenderer\";\nimport { A2UIBuiltInToolCallRenderer } from \"../a2ui/A2UIToolCallRenderer\";\nimport { A2UICatalogContext } from \"../a2ui/A2UICatalogContext\";\nimport { viewerTheme } from \"@copilotkit/a2ui-renderer\";\nimport type { Theme as A2UITheme } from \"@copilotkit/a2ui-renderer\";\nimport { CopilotKitCoreReact } from \"../lib/react-core\";\nimport type {\n ReactActivityMessageRenderer,\n ReactToolCallRenderer,\n} from \"../types\";\nimport type { ReactFrontendTool } from \"../types/frontend-tool\";\nimport type { ReactHumanInTheLoop } from \"../types/human-in-the-loop\";\nimport type { ReactCustomMessageRenderer } from \"../types/react-custom-message-renderer\";\nimport type { SandboxFunction } from \"../types/sandbox-function\";\nimport { SandboxFunctionsContext } from \"./SandboxFunctionsContext\";\nimport { schemaToJsonSchema } from \"@copilotkit/shared\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\n\nconst HEADER_NAME = \"X-CopilotCloud-Public-Api-Key\";\nconst COPILOT_CLOUD_CHAT_URL = \"https://api.cloud.copilotkit.ai/copilotkit/v1\";\n\nconst DEFAULT_DESIGN_SKILL = `When generating UI with generateSandboxedUi, follow these design principles inspired by shadcn/ui:\n\n- Use a minimal, flat aesthetic. Avoid drop shadows and gradients — rely on subtle borders (1px solid, light gray like #e5e7eb) to define surfaces.\n- Neutral base palette: white backgrounds, zinc/slate gray text (#09090b for headings, #71717a for secondary text). One accent color for interactive elements.\n- Use system font stacks (system-ui, -apple-system, sans-serif) at readable sizes (14px body, 600 weight for headings). Tight line-heights.\n- Small, consistent border-radius (6–8px). Cards and containers use border, not shadow, for separation.\n- Buttons: solid fill for primary (dark bg, white text), outline for secondary (border + transparent bg). Subtle hover state (slight opacity or background shift).\n- Use CSS Grid or Flexbox for layout. Ensure the UI looks good at any width.\n- Minimal transitions (150ms) for hover/focus states only. No decorative animations.\n- Keep the UI focused and dense — avoid excessive padding. Use compact spacing (8–12px gaps, 10–14px padding in controls).`;\n\nconst GENERATE_SANDBOXED_UI_DESCRIPTION =\n \"Generate sandboxed UI. \" +\n \"IMPORTANT: The generated code runs in a sandboxed iframe WITHOUT same-origin access. \" +\n \"Do NOT use localStorage, sessionStorage, document.cookie, IndexedDB, or fetch/XMLHttpRequest to same-origin URLs. \" +\n \"To communicate with the host application, use Websandbox.connection.remote.<functionName>(args) which returns a Promise.\\n\\n\" +\n \"You 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.). \" +\n \"CDN resources load normally inside the sandbox.\\n\\n\" +\n \"PARAMETER ORDER IS CRITICAL — generate parameters in exactly this order:\\n\" +\n \"1. initialHeight + placeholderMessages (shown to user while generating)\\n\" +\n \"2. css (all styles FIRST — the user sees a placeholder until CSS is complete)\\n\" +\n \"3. html (streams in live — the user watches the UI build as HTML is generated)\\n\" +\n \"4. jsFunctions (reusable helper functions)\\n\" +\n \"5. jsExpressions (applied one-by-one — the user sees each expression take effect)\";\n\n// Define the context value interface - idiomatic React naming\nexport interface CopilotKitContextValue {\n copilotkit: CopilotKitCoreReact;\n /**\n * Set of tool call IDs currently being executed.\n * This is tracked at the provider level to ensure tool execution events\n * are captured even before child components mount.\n */\n executingToolCallIds: ReadonlySet<string>;\n}\n\n// Empty set for default context value\nconst EMPTY_SET: ReadonlySet<string> = new Set();\n\n// Create the CopilotKit context\nconst CopilotKitContext = createContext<CopilotKitContextValue>({\n copilotkit: null!,\n executingToolCallIds: EMPTY_SET,\n});\n\nconst LicenseContext = createContext<LicenseContextValue>(\n createLicenseContextValue(null),\n);\n\nexport const useLicenseContext = (): LicenseContextValue =>\n useContext(LicenseContext);\n\n// Provider props interface\nexport interface CopilotKitProviderProps {\n children: ReactNode;\n runtimeUrl?: string;\n headers?: Record<string, string>;\n /**\n * Credentials mode for fetch requests (e.g., \"include\" for HTTP-only cookies in cross-origin requests).\n */\n credentials?: RequestCredentials;\n /**\n * The Copilot Cloud public API key.\n */\n publicApiKey?: string;\n /**\n * Alias for `publicApiKey`\n **/\n publicLicenseKey?: string;\n /**\n * Signed license token for offline verification of premium features.\n * Obtain from https://cloud.copilotkit.ai.\n */\n licenseToken?: string;\n properties?: Record<string, unknown>;\n useSingleEndpoint?: boolean;\n agents__unsafe_dev_only?: Record<string, AbstractAgent>;\n selfManagedAgents?: Record<string, AbstractAgent>;\n renderToolCalls?: ReactToolCallRenderer<any>[];\n renderActivityMessages?: ReactActivityMessageRenderer<any>[];\n renderCustomMessages?: ReactCustomMessageRenderer[];\n frontendTools?: ReactFrontendTool[];\n humanInTheLoop?: ReactHumanInTheLoop[];\n /**\n * Configuration for OpenGenerativeUI — sandboxed UI generated by the LLM.\n *\n * @example\n * ```tsx\n * <CopilotKit\n * runtimeUrl=\"/api/copilotkit\"\n * openGenerativeUI={{\n * sandboxFunctions: [{ name: \"addToCart\", description: \"…\", parameters: schema, handler: fn }],\n * }}\n * >\n * ```\n */\n openGenerativeUI?: {\n /**\n * Functions made available inside sandboxed iframes.\n * Each function is described to the LLM via agent context and exposed\n * via websandbox's `localApi`.\n *\n * Inside the iframe, call them with:\n * ```js\n * await Websandbox.connection.remote.<functionName>(args)\n * ```\n */\n sandboxFunctions?: SandboxFunction[];\n /**\n * Design guidelines injected as agent context for the `generateSandboxedUi` tool.\n * Override this to control the visual style of generated UIs.\n *\n * A sensible default is provided if omitted.\n */\n designSkill?: string;\n };\n showDevConsole?: boolean | \"auto\";\n /**\n * Error handler called when CopilotKit encounters an error.\n * Fires for all error types (runtime connection failures, agent errors, tool errors).\n */\n onError?: (event: {\n error: Error;\n code: CopilotKitCoreErrorCode;\n context: Record<string, any>;\n }) => void | Promise<void>;\n /**\n * Configuration for the A2UI (Agent-to-UI) renderer.\n * The built-in A2UI renderer is activated automatically when the runtime reports\n * that `a2ui` is configured in `CopilotRuntime`. This prop is optional and only\n * needed if you want to override the default theme.\n *\n * @example\n * ```tsx\n * <CopilotKit runtimeUrl=\"/api/copilotkit\" a2ui={{ theme: myCustomTheme }}>\n * {children}\n * </CopilotKit>\n * ```\n */\n a2ui?: {\n /**\n * Override the default A2UI viewer theme.\n * When omitted, the built-in `viewerTheme` from `@copilotkit/a2ui-renderer` is used.\n */\n theme?: A2UITheme;\n /**\n * Optional component catalog to pass to the A2UI renderer.\n * When omitted, the default basicCatalog is used.\n */\n catalog?: any;\n /**\n * Optional custom loading component shown while an A2UI surface is generating.\n * When omitted, a default animated skeleton is shown.\n */\n loadingComponent?: React.ComponentType;\n /**\n * When true (the default), the full component schemas from the catalog are\n * sent as agent context so the agent knows what components and props are\n * available. The A2UI middleware can overwrite this with a server-side\n * schema if configured. Set to false to disable.\n */\n includeSchema?: boolean;\n };\n /**\n * Default throttle interval (in milliseconds) for `useAgent` re-renders\n * triggered by `OnMessagesChanged` notifications. This value is used as\n * a fallback when neither the `useAgent()` hook nor `<CopilotChat>` /\n * `<CopilotSidebar>` / `<CopilotPopup>` specify an explicit `throttleMs`.\n *\n * @default undefined (components/hooks without an explicit throttleMs will be unthrottled)\n */\n defaultThrottleMs?: number;\n /**\n * Default anchor corner for the inspector button and window.\n * Only used on first load before the user drags to a custom position.\n * Defaults to `{ horizontal: \"right\", vertical: \"top\" }`.\n */\n inspectorDefaultAnchor?: Anchor;\n}\n\n// Small helper to normalize array props to a stable reference and warn\nfunction useStableArrayProp<T>(\n prop: T[] | undefined,\n warningMessage?: string,\n isMeaningfulChange?: (initial: T[], next: T[]) => boolean,\n): T[] {\n const empty = useMemo<T[]>(() => [], []);\n const value = prop ?? empty;\n const initial = useRef(value);\n\n useEffect(() => {\n if (\n warningMessage &&\n value !== initial.current &&\n (isMeaningfulChange ? isMeaningfulChange(initial.current, value) : true)\n ) {\n console.error(warningMessage);\n }\n }, [value, warningMessage]);\n\n return value;\n}\n\n// Provider component\nexport const CopilotKitProvider: React.FC<CopilotKitProviderProps> = ({\n children,\n runtimeUrl,\n headers = {},\n credentials,\n publicApiKey,\n publicLicenseKey,\n licenseToken,\n properties = {},\n agents__unsafe_dev_only: agents = {},\n selfManagedAgents = {},\n renderToolCalls,\n renderActivityMessages,\n renderCustomMessages,\n frontendTools,\n humanInTheLoop,\n openGenerativeUI,\n showDevConsole = false,\n useSingleEndpoint,\n onError,\n a2ui,\n defaultThrottleMs,\n inspectorDefaultAnchor,\n}) => {\n const [shouldRenderInspector, setShouldRenderInspector] = useState(false);\n const [runtimeA2UIEnabled, setRuntimeA2UIEnabled] = useState(false);\n const [runtimeOpenGenUIEnabled, setRuntimeOpenGenUIEnabled] = useState(false);\n const openGenUIActive = runtimeOpenGenUIEnabled || !!openGenerativeUI;\n const [runtimeLicenseStatus, setRuntimeLicenseStatus] = useState<\n string | undefined\n >(undefined);\n\n useEffect(() => {\n if (typeof window === \"undefined\") {\n return;\n }\n\n if (showDevConsole === true) {\n // Explicitly show the inspector\n setShouldRenderInspector(true);\n } else if (showDevConsole === \"auto\") {\n // Show on localhost or 127.0.0.1 only\n const localhostHosts = new Set([\"localhost\", \"127.0.0.1\"]);\n if (localhostHosts.has(window.location.hostname)) {\n setShouldRenderInspector(true);\n } else {\n setShouldRenderInspector(false);\n }\n } else {\n // showDevConsole is false or undefined (default false)\n setShouldRenderInspector(false);\n }\n }, [showDevConsole]);\n\n // Normalize array props to stable references with clear dev warnings\n const renderToolCallsList = useStableArrayProp<ReactToolCallRenderer<any>>(\n renderToolCalls,\n \"renderToolCalls must be a stable array. If you want to dynamically add or remove tools, use `useFrontendTool` instead.\",\n (initial, next) => {\n // Only warn if the shape (names+agentId) changed. Allow identity changes\n // to support updated closures from parents (e.g., Storybook state).\n const key = (rc?: ReactToolCallRenderer<unknown>) =>\n `${rc?.agentId ?? \"\"}:${rc?.name ?? \"\"}`;\n const setFrom = (arr: ReactToolCallRenderer<unknown>[]) =>\n new Set(arr.map(key));\n const a = setFrom(initial);\n const b = setFrom(next);\n if (a.size !== b.size) return true;\n for (const k of a) if (!b.has(k)) return true;\n return false;\n },\n );\n\n const renderCustomMessagesList =\n useStableArrayProp<ReactCustomMessageRenderer>(\n renderCustomMessages,\n \"renderCustomMessages must be a stable array.\",\n );\n\n const renderActivityMessagesList = useStableArrayProp<\n ReactActivityMessageRenderer<any>\n >(renderActivityMessages, \"renderActivityMessages must be a stable array.\");\n\n // Built-in activity renderers that are always included\n const builtInActivityRenderers = useMemo<\n ReactActivityMessageRenderer<any>[]\n >(() => {\n const renderers: ReactActivityMessageRenderer<any>[] = [\n {\n activityType: MCPAppsActivityType,\n content: MCPAppsActivityContentSchema,\n render: MCPAppsActivityRenderer,\n },\n ];\n\n if (openGenUIActive) {\n renderers.push({\n activityType: OpenGenerativeUIActivityType,\n content: OpenGenerativeUIContentSchema,\n render: OpenGenerativeUIActivityRenderer,\n });\n }\n\n if (runtimeA2UIEnabled) {\n renderers.unshift(\n createA2UIMessageRenderer({\n theme: a2ui?.theme ?? viewerTheme,\n catalog: a2ui?.catalog,\n loadingComponent: a2ui?.loadingComponent,\n }),\n );\n }\n\n return renderers;\n }, [runtimeA2UIEnabled, openGenUIActive, a2ui]);\n\n // Combine user-provided activity renderers with built-in ones\n // User-provided renderers take precedence (come first) so they can override built-ins\n const allActivityRenderers = useMemo(() => {\n return [...renderActivityMessagesList, ...builtInActivityRenderers];\n }, [renderActivityMessagesList, builtInActivityRenderers]);\n\n const resolvedPublicKey = publicApiKey ?? publicLicenseKey;\n const mergedAgents = useMemo(\n () => ({ ...agents, ...selfManagedAgents }),\n [agents, selfManagedAgents],\n );\n const hasLocalAgents = mergedAgents && Object.keys(mergedAgents).length > 0;\n\n // Merge a provided publicApiKey into headers (without overwriting an explicit header).\n const mergedHeaders = useMemo(() => {\n if (!resolvedPublicKey) return headers;\n if (headers[HEADER_NAME]) return headers;\n return {\n ...headers,\n [HEADER_NAME]: resolvedPublicKey,\n };\n }, [headers, resolvedPublicKey]);\n\n if (!runtimeUrl && !resolvedPublicKey && !hasLocalAgents) {\n const message =\n \"Missing required prop: 'runtimeUrl' or 'publicApiKey' or 'publicLicenseKey'\";\n if (process.env.NODE_ENV === \"production\") {\n throw new Error(message);\n } else {\n // In dev/test we warn but allow to facilitate local agents and unit tests.\n console.warn(message);\n }\n }\n\n const chatApiEndpoint =\n runtimeUrl ?? (resolvedPublicKey ? COPILOT_CLOUD_CHAT_URL : undefined);\n\n const frontendToolsList = useStableArrayProp<ReactFrontendTool>(\n frontendTools,\n \"frontendTools must be a stable array. If you want to dynamically add or remove tools, use `useFrontendTool` instead.\",\n );\n const humanInTheLoopList = useStableArrayProp<ReactHumanInTheLoop>(\n humanInTheLoop,\n \"humanInTheLoop must be a stable array. If you want to dynamically add or remove human-in-the-loop tools, use `useHumanInTheLoop` instead.\",\n );\n const sandboxFunctionsList = useStableArrayProp<SandboxFunction>(\n openGenerativeUI?.sandboxFunctions,\n \"openGenerativeUI.sandboxFunctions must be a stable array.\",\n );\n\n // Note: warnings for array identity changes are handled by useStableArrayProp\n\n // Process humanInTheLoop tools to create handlers and add render components\n const processedHumanInTheLoopTools = useMemo(() => {\n const processedTools: FrontendTool[] = [];\n const processedRenderToolCalls: ReactToolCallRenderer<unknown>[] = [];\n\n humanInTheLoopList.forEach((tool) => {\n // Create a promise-based handler for each human-in-the-loop tool\n const frontendTool: FrontendTool = {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n followUp: tool.followUp,\n ...(tool.agentId && { agentId: tool.agentId }),\n handler: async () => {\n // This handler will be replaced by the hook when it runs\n // For provider-level tools, we create a basic handler that waits for user interaction\n return new Promise((resolve) => {\n // The actual implementation will be handled by the render component\n // This is a placeholder that the hook will override\n console.warn(\n `Human-in-the-loop tool '${tool.name}' called but no interactive handler is set up.`,\n );\n resolve(undefined);\n });\n },\n };\n processedTools.push(frontendTool);\n\n // Add the render component to renderToolCalls\n if (tool.render) {\n processedRenderToolCalls.push({\n name: tool.name,\n args: tool.parameters!,\n render: tool.render,\n ...(tool.agentId && { agentId: tool.agentId }),\n } as ReactToolCallRenderer<unknown>);\n }\n });\n\n return { tools: processedTools, renderToolCalls: processedRenderToolCalls };\n }, [humanInTheLoopList]);\n\n // Built-in frontend tool for generateSandboxedUi — registered only when the runtime has openGenerativeUI enabled\n const builtInFrontendTools = useMemo<ReactFrontendTool[]>(() => {\n if (!openGenUIActive) return [];\n return [\n {\n name: \"generateSandboxedUi\",\n description: GENERATE_SANDBOXED_UI_DESCRIPTION,\n parameters: GenerateSandboxedUiArgsSchema,\n handler: async () => \"UI generated\",\n followUp: true,\n render: OpenGenerativeUIToolRenderer,\n },\n ];\n }, [openGenUIActive]);\n\n // Combine all tools for CopilotKitCore\n const allTools = useMemo(() => {\n const tools: FrontendTool[] = [];\n\n // Add frontend tools (user-provided + built-in)\n tools.push(...frontendToolsList);\n tools.push(...builtInFrontendTools);\n\n // Add processed human-in-the-loop tools\n tools.push(...processedHumanInTheLoopTools.tools);\n\n return tools;\n }, [frontendToolsList, builtInFrontendTools, processedHumanInTheLoopTools]);\n\n // Combine all render tool calls\n const allRenderToolCalls = useMemo(() => {\n const combined: ReactToolCallRenderer<unknown>[] = [...renderToolCallsList];\n\n // Add render components from frontend tools (user-provided + built-in)\n [...frontendToolsList, ...builtInFrontendTools].forEach((tool) => {\n if (tool.render) {\n // For wildcard tools without parameters, default to z.any()\n const args =\n tool.parameters || (tool.name === \"*\" ? z.any() : undefined);\n if (args) {\n combined.push({\n name: tool.name,\n args: args,\n render: tool.render,\n } as ReactToolCallRenderer<unknown>);\n }\n }\n });\n\n // Add render components from human-in-the-loop tools\n combined.push(...processedHumanInTheLoopTools.renderToolCalls);\n\n return combined;\n }, [\n renderToolCallsList,\n frontendToolsList,\n builtInFrontendTools,\n processedHumanInTheLoopTools,\n ]);\n\n // Stable instance: created once for the provider lifetime.\n // Updates are applied via setter effects below rather than recreating the instance.\n const copilotkitRef = useRef<CopilotKitCoreReact | null>(null);\n if (copilotkitRef.current === null) {\n copilotkitRef.current = new CopilotKitCoreReact({\n runtimeUrl: chatApiEndpoint,\n runtimeTransport:\n useSingleEndpoint === true\n ? \"single\"\n : useSingleEndpoint === false\n ? \"rest\"\n : \"auto\",\n headers: mergedHeaders,\n credentials,\n properties,\n agents__unsafe_dev_only: mergedAgents,\n tools: allTools,\n renderToolCalls: allRenderToolCalls,\n renderActivityMessages: allActivityRenderers,\n renderCustomMessages: renderCustomMessagesList,\n });\n // Set initial defaultThrottleMs synchronously so child hooks see the\n // correct value on their first render (before useEffect fires).\n if (defaultThrottleMs !== undefined) {\n copilotkitRef.current.setDefaultThrottleMs(defaultThrottleMs);\n }\n }\n const copilotkit = copilotkitRef.current;\n\n // Sync runtime feature flags from the core once runtime info is fetched\n useEffect(() => {\n // Check current value immediately (may already be set before subscription)\n setRuntimeA2UIEnabled(copilotkit.a2uiEnabled);\n const subscription = copilotkit.subscribe({\n onRuntimeConnectionStatusChanged: () => {\n setRuntimeA2UIEnabled(copilotkit.a2uiEnabled);\n setRuntimeOpenGenUIEnabled(copilotkit.openGenerativeUIEnabled);\n setRuntimeLicenseStatus(copilotkit.licenseStatus);\n },\n });\n return () => {\n subscription.unsubscribe();\n };\n }, [copilotkit]);\n\n // Subscribe to render tool calls changes to force re-renders\n const [, forceUpdate] = useReducer((x) => x + 1, 0);\n\n useEffect(() => {\n const subscription = copilotkit.subscribe({\n onRenderToolCallsChanged: () => {\n forceUpdate();\n },\n });\n\n return () => {\n subscription.unsubscribe();\n };\n }, [copilotkit]);\n\n // Track executing tool call IDs at the provider level.\n // This is critical for HITL reconnection: when connecting to a thread with\n // pending tool calls, the onToolExecutionStart event fires before child components\n // (like CopilotChatToolCallsView) mount. By tracking at the provider level,\n // we ensure the executing state is captured and available when children mount.\n const [executingToolCallIds, setExecutingToolCallIds] = useState<\n ReadonlySet<string>\n >(() => new Set());\n\n useEffect(() => {\n const subscription = copilotkit.subscribe({\n onToolExecutionStart: ({ toolCallId }) => {\n setExecutingToolCallIds((prev) => {\n if (prev.has(toolCallId)) return prev;\n const next = new Set(prev);\n next.add(toolCallId);\n return next;\n });\n },\n onToolExecutionEnd: ({ toolCallId }) => {\n setExecutingToolCallIds((prev) => {\n if (!prev.has(toolCallId)) return prev;\n const next = new Set(prev);\n next.delete(toolCallId);\n return next;\n });\n },\n });\n\n return () => {\n subscription.unsubscribe();\n };\n }, [copilotkit]);\n\n // onError subscription — forward core errors to user callback\n const onErrorRef = useRef(onError);\n useEffect(() => {\n onErrorRef.current = onError;\n }, [onError]);\n\n useEffect(() => {\n if (!onErrorRef.current) return;\n\n const subscription = copilotkit.subscribe({\n onError: (event) => {\n onErrorRef.current?.({\n error: event.error,\n code: event.code,\n context: event.context,\n });\n },\n });\n\n return () => {\n subscription.unsubscribe();\n };\n }, [copilotkit]);\n\n useEffect(() => {\n copilotkit.setRuntimeUrl(chatApiEndpoint);\n copilotkit.setRuntimeTransport(\n useSingleEndpoint === true\n ? \"single\"\n : useSingleEndpoint === false\n ? \"rest\"\n : \"auto\",\n );\n copilotkit.setHeaders(mergedHeaders);\n copilotkit.setCredentials(credentials);\n copilotkit.setProperties(properties);\n copilotkit.setAgents__unsafe_dev_only(mergedAgents);\n }, [\n copilotkit,\n chatApiEndpoint,\n mergedHeaders,\n credentials,\n properties,\n mergedAgents,\n useSingleEndpoint,\n ]);\n\n // Sync render/tool arrays to the stable instance via setters.\n // On mount, the constructor already receives the correct initial values,\n // so we skip the first invocation. This is critical because child hooks\n // (e.g., useFrontendTool, useHumanInTheLoop) register tools dynamically\n // via addTool()/setRenderToolCalls() in their own effects, which fire\n // BEFORE parent effects (React fires effects bottom-up). If the parent\n // setter effects ran on mount, they would overwrite the children's tools.\n const didMountRef = useRef(false);\n\n useEffect(() => {\n if (!didMountRef.current) return;\n copilotkit.setTools(allTools);\n }, [copilotkit, allTools]);\n\n useEffect(() => {\n if (!didMountRef.current) return;\n copilotkit.setRenderToolCalls(allRenderToolCalls);\n }, [copilotkit, allRenderToolCalls]);\n\n useEffect(() => {\n if (!didMountRef.current) return;\n copilotkit.setRenderActivityMessages(allActivityRenderers);\n }, [copilotkit, allActivityRenderers]);\n\n useEffect(() => {\n if (!didMountRef.current) return;\n copilotkit.setRenderCustomMessages(renderCustomMessagesList);\n }, [copilotkit, renderCustomMessagesList]);\n\n // Mark mount complete — must be declared AFTER the setter effects\n // so it runs last in the effect queue on the initial mount cycle.\n useEffect(() => {\n didMountRef.current = true;\n }, []);\n\n // Sync defaultThrottleMs to the core instance on prop changes.\n // Initial value is set synchronously during instance creation (below the\n // ref init) so child hooks see the correct value on their first render.\n // This effect handles subsequent updates when the prop changes.\n useEffect(() => {\n if (\n defaultThrottleMs !== undefined &&\n (!Number.isFinite(defaultThrottleMs) || defaultThrottleMs < 0)\n ) {\n console.error(\n `CopilotKitProvider: defaultThrottleMs must be a non-negative finite number, got ${defaultThrottleMs}. ` +\n `useAgent hooks without an explicit throttleMs will fall back to unthrottled.`,\n );\n }\n copilotkit.setDefaultThrottleMs(defaultThrottleMs);\n }, [copilotkit, defaultThrottleMs]);\n\n // Register design skill as agent context for the generateSandboxedUi tool\n const designSkill = openGenerativeUI?.designSkill ?? DEFAULT_DESIGN_SKILL;\n\n useLayoutEffect(() => {\n if (!copilotkit || !openGenUIActive) return;\n\n const id = copilotkit.addContext({\n description:\n \"Design guidelines for the generateSandboxedUi tool. Follow these when building UI.\",\n value: designSkill,\n });\n return () => {\n copilotkit.removeContext(id);\n };\n }, [copilotkit, designSkill, openGenUIActive]);\n\n // Register sandbox functions as agent context so the LLM knows how to call them\n const sandboxFunctionsDescriptors = useMemo(() => {\n if (sandboxFunctionsList.length === 0) return null;\n return JSON.stringify(\n sandboxFunctionsList.map((fn) => ({\n name: fn.name,\n description: fn.description,\n parameters: schemaToJsonSchema(fn.parameters, { zodToJsonSchema }),\n })),\n );\n }, [sandboxFunctionsList]);\n\n useLayoutEffect(() => {\n if (!copilotkit || !sandboxFunctionsDescriptors || !openGenUIActive) return;\n\n const id = copilotkit.addContext({\n description:\n \"Sandbox functions available in generated sandboxed UI code. Call via: await Websandbox.connection.remote.<functionName>(args)\",\n value: sandboxFunctionsDescriptors,\n });\n return () => {\n copilotkit.removeContext(id);\n };\n }, [copilotkit, sandboxFunctionsDescriptors, openGenUIActive]);\n\n const contextValue = useMemo<CopilotKitContextValue>(\n () => ({ copilotkit, executingToolCallIds }),\n [copilotkit, executingToolCallIds],\n );\n\n // License context — driven by server-reported status via /info endpoint\n const licenseContextValue = useMemo(\n () => createLicenseContextValue(null),\n [],\n );\n\n return (\n <SandboxFunctionsContext.Provider value={sandboxFunctionsList}>\n <CopilotKitContext.Provider value={contextValue}>\n <LicenseContext.Provider value={licenseContextValue}>\n {runtimeA2UIEnabled && <A2UIBuiltInToolCallRenderer />}\n {runtimeA2UIEnabled && (\n <A2UICatalogContext\n catalog={a2ui?.catalog}\n includeSchema={a2ui?.includeSchema}\n />\n )}\n {children}\n {shouldRenderInspector ? (\n <CopilotKitInspector\n core={copilotkit}\n defaultAnchor={inspectorDefaultAnchor}\n />\n ) : null}\n {/* License warnings — driven by server-reported status */}\n {runtimeLicenseStatus === \"none\" && !resolvedPublicKey && (\n <LicenseWarningBanner type=\"no_license\" />\n )}\n {runtimeLicenseStatus === \"expired\" && (\n <LicenseWarningBanner type=\"expired\" />\n )}\n {runtimeLicenseStatus === \"invalid\" && (\n <LicenseWarningBanner type=\"invalid\" />\n )}\n {runtimeLicenseStatus === \"expiring\" && (\n <LicenseWarningBanner type=\"expiring\" />\n )}\n </LicenseContext.Provider>\n </CopilotKitContext.Provider>\n </SandboxFunctionsContext.Provider>\n );\n};\n\n// Hook to use the CopilotKit instance - returns the full context value\nexport const useCopilotKit = (): CopilotKitContextValue => {\n const context = useContext(CopilotKitContext);\n const [, forceUpdate] = useReducer((x) => x + 1, 0);\n\n if (!context) {\n throw new Error(\"useCopilotKit must be used within CopilotKitProvider\");\n }\n useEffect(() => {\n const subscription = context.copilotkit.subscribe({\n onRuntimeConnectionStatusChanged: () => {\n forceUpdate();\n },\n });\n return () => {\n subscription.unsubscribe();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return context;\n};\n","import React, { useCallback, useMemo, useSyncExternalStore } from \"react\";\nimport { ToolCall, ToolMessage } from \"@ag-ui/core\";\nimport { ToolCallStatus } from \"@copilotkit/core\";\nimport { useCopilotKit } from \"../providers/CopilotKitProvider\";\nimport { useCopilotChatConfiguration } from \"../providers/CopilotChatConfigurationProvider\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkit/shared\";\nimport { partialJSONParse } from \"@copilotkit/shared\";\nimport { ReactToolCallRenderer } from \"../types/react-tool-call-renderer\";\n\nexport interface UseRenderToolCallProps {\n toolCall: ToolCall;\n toolMessage?: ToolMessage;\n}\n\n/**\n * Props for the memoized ToolCallRenderer component\n */\ninterface ToolCallRendererProps {\n toolCall: ToolCall;\n toolMessage?: ToolMessage;\n RenderComponent: ReactToolCallRenderer<unknown>[\"render\"];\n isExecuting: boolean;\n}\n\n/**\n * Memoized component that renders a single tool call.\n * This prevents unnecessary re-renders when parent components update\n * but the tool call data hasn't changed.\n */\nconst ToolCallRenderer = React.memo(\n function ToolCallRenderer({\n toolCall,\n toolMessage,\n RenderComponent,\n isExecuting,\n }: ToolCallRendererProps) {\n // Memoize args based on the arguments string to maintain stable reference\n const args = useMemo(\n () => partialJSONParse(toolCall.function.arguments),\n [toolCall.function.arguments],\n );\n\n const toolName = toolCall.function.name;\n\n // Render based on status to preserve discriminated union type inference\n if (toolMessage) {\n return (\n <RenderComponent\n name={toolName}\n args={args}\n status={ToolCallStatus.Complete}\n result={toolMessage.content}\n />\n );\n } else if (isExecuting) {\n return (\n <RenderComponent\n name={toolName}\n args={args}\n status={ToolCallStatus.Executing}\n result={undefined}\n />\n );\n } else {\n return (\n <RenderComponent\n name={toolName}\n args={args}\n status={ToolCallStatus.InProgress}\n result={undefined}\n />\n );\n }\n },\n // Custom comparison function to prevent re-renders when tool call data hasn't changed\n (prevProps, nextProps) => {\n // Compare tool call identity and content\n if (prevProps.toolCall.id !== nextProps.toolCall.id) return false;\n if (prevProps.toolCall.function.name !== nextProps.toolCall.function.name)\n return false;\n if (\n prevProps.toolCall.function.arguments !==\n nextProps.toolCall.function.arguments\n )\n return false;\n\n // Compare tool message (result)\n const prevResult = prevProps.toolMessage?.content;\n const nextResult = nextProps.toolMessage?.content;\n if (prevResult !== nextResult) return false;\n\n // Compare executing state\n if (prevProps.isExecuting !== nextProps.isExecuting) return false;\n\n // Compare render component reference\n if (prevProps.RenderComponent !== nextProps.RenderComponent) return false;\n\n return true;\n },\n);\n\n/**\n * Hook that returns a function to render tool calls based on the render functions\n * defined in CopilotKitProvider.\n *\n * @returns A function that takes a tool call and optional tool message and returns the rendered component\n */\nexport function useRenderToolCall() {\n const { copilotkit, executingToolCallIds } = useCopilotKit();\n const config = useCopilotChatConfiguration();\n const agentId = config?.agentId ?? DEFAULT_AGENT_ID;\n\n // Subscribe to render tool calls changes using useSyncExternalStore\n // This ensures we always have the latest value, even if subscriptions run in any order\n const renderToolCalls = useSyncExternalStore(\n (callback) => {\n return copilotkit.subscribe({\n onRenderToolCallsChanged: callback,\n }).unsubscribe;\n },\n () => copilotkit.renderToolCalls,\n () => copilotkit.renderToolCalls,\n );\n\n // Note: executingToolCallIds is now provided by CopilotKitProvider context.\n // This is critical for HITL reconnection: when connecting to a thread with\n // pending tool calls, the onToolExecutionStart event fires before child components\n // mount. By tracking at the provider level, the executing state is already\n // available when this hook first runs.\n\n const renderToolCall = useCallback(\n ({\n toolCall,\n toolMessage,\n }: UseRenderToolCallProps): React.ReactElement | null => {\n // Find the render config for this tool call by name\n // For rendering, we show all tool calls regardless of agentId\n // The agentId scoping only affects handler execution (in core)\n // Priority order:\n // 1. Exact match by name (prefer agent-specific if multiple exist)\n // 2. Wildcard (*) renderer\n const exactMatches = renderToolCalls.filter(\n (rc) => rc.name === toolCall.function.name,\n );\n\n // If multiple renderers with same name exist, prefer the one matching our agentId\n const renderConfig =\n exactMatches.find((rc) => rc.agentId === agentId) ||\n exactMatches.find((rc) => !rc.agentId) ||\n exactMatches[0] ||\n renderToolCalls.find((rc) => rc.name === \"*\");\n\n if (!renderConfig) {\n return null;\n }\n\n const RenderComponent = renderConfig.render;\n const isExecuting = executingToolCallIds.has(toolCall.id);\n\n // Use the memoized ToolCallRenderer component to prevent unnecessary re-renders\n return (\n <ToolCallRenderer\n key={toolCall.id}\n toolCall={toolCall}\n toolMessage={toolMessage}\n RenderComponent={RenderComponent}\n isExecuting={isExecuting}\n />\n );\n },\n [renderToolCalls, executingToolCallIds, agentId],\n );\n\n return renderToolCall;\n}\n","import { useCopilotKit } from \"../providers/CopilotKitProvider\";\nimport { useCopilotChatConfiguration } from \"../providers/CopilotChatConfigurationProvider\";\nimport { useMemo, useEffect, useReducer, useRef } from \"react\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkit/shared\";\nimport { AbstractAgent, HttpAgent } from \"@ag-ui/client\";\nimport {\n ProxiedCopilotRuntimeAgent,\n CopilotKitCoreRuntimeConnectionStatus,\n} from \"@copilotkit/core\";\n\nexport enum UseAgentUpdate {\n OnMessagesChanged = \"OnMessagesChanged\",\n OnStateChanged = \"OnStateChanged\",\n OnRunStatusChanged = \"OnRunStatusChanged\",\n}\n\nconst ALL_UPDATES: UseAgentUpdate[] = [\n UseAgentUpdate.OnMessagesChanged,\n UseAgentUpdate.OnStateChanged,\n UseAgentUpdate.OnRunStatusChanged,\n];\n\nexport interface UseAgentProps {\n agentId?: string;\n threadId?: string;\n updates?: UseAgentUpdate[];\n /**\n * Throttle interval (in milliseconds) for React re-renders triggered by\n * `OnMessagesChanged` notifications. Useful to reduce re-render frequency\n * during high-frequency message updates such as streaming.\n *\n * Uses leading+trailing: first update fires immediately, subsequent updates\n * within the window are coalesced, and a trailing timer ensures the most\n * recent update fires after the window expires. The trailing edge restarts\n * the throttle window, so no two renders occur within `throttleMs` of each\n * other. Cleanup on unmount cancels any pending trailing timer.\n *\n * Must be a non-negative finite number. Negative or non-finite values fall\n * back to unthrottled behavior with a `console.error`. Only affects\n * `OnMessagesChanged` updates — `OnStateChanged` and `OnRunStatusChanged`\n * always fire immediately. If `updates` does not include\n * `OnMessagesChanged`, this property has no effect.\n *\n * Default: `0` (no throttle).\n */\n throttleMs?: number;\n}\n\n/**\n * Clone a registry agent for per-thread isolation.\n * Copies agent configuration (transport, headers, etc.) but resets conversation\n * state (messages, threadId, state) so each thread starts fresh.\n */\nfunction cloneForThread(\n source: AbstractAgent,\n threadId: string,\n headers: Record<string, string>,\n): AbstractAgent {\n const clone = source.clone();\n if (clone === source) {\n throw new Error(\n `useAgent: ${source.constructor.name}.clone() returned the same instance. ` +\n `clone() must return a new, independent object.`,\n );\n }\n clone.threadId = threadId;\n clone.setMessages([]);\n clone.setState({});\n if (clone instanceof HttpAgent) {\n clone.headers = { ...headers };\n }\n return clone;\n}\n\n/**\n * Module-level WeakMap: registryAgent → (threadId → clone).\n * Shared across all useAgent() calls so that every component using the same\n * (agentId, threadId) pair receives the same agent instance. Using WeakMap\n * ensures the clone map is garbage-collected when the registry agent is\n * replaced (e.g. after reconnect or hot-reload).\n */\nexport const globalThreadCloneMap = new WeakMap<\n AbstractAgent,\n Map<string, AbstractAgent>\n>();\n\n/**\n * Look up an existing per-thread clone without creating one.\n * Returns undefined when no clone has been created yet for this pair.\n */\nexport function getThreadClone(\n registryAgent: AbstractAgent | undefined | null,\n threadId: string | undefined | null,\n): AbstractAgent | undefined {\n if (!registryAgent || !threadId) return undefined;\n return globalThreadCloneMap.get(registryAgent)?.get(threadId);\n}\n\nfunction getOrCreateThreadClone(\n existing: AbstractAgent,\n threadId: string,\n headers: Record<string, string>,\n): AbstractAgent {\n let byThread = globalThreadCloneMap.get(existing);\n if (!byThread) {\n byThread = new Map();\n globalThreadCloneMap.set(existing, byThread);\n }\n const cached = byThread.get(threadId);\n if (cached) return cached;\n\n const clone = cloneForThread(existing, threadId, headers);\n byThread.set(threadId, clone);\n return clone;\n}\n\nexport function useAgent({\n agentId,\n threadId,\n updates,\n throttleMs,\n}: UseAgentProps = {}) {\n agentId ??= DEFAULT_AGENT_ID;\n\n const { copilotkit } = useCopilotKit();\n const providerThrottleMs = copilotkit.defaultThrottleMs;\n // Fall back to the enclosing CopilotChatConfigurationProvider's threadId so\n // that useAgent() called without explicit threadId (e.g. inside a custom\n // message renderer) automatically uses the same per-thread clone as the\n // CopilotChat component it lives within.\n const chatConfig = useCopilotChatConfiguration();\n threadId ??= chatConfig?.threadId;\n\n const effectiveThrottleMs = useMemo(() => {\n const resolved = throttleMs ?? providerThrottleMs ?? 0;\n if (!Number.isFinite(resolved) || resolved < 0) {\n // When both throttleMs and providerThrottleMs are undefined, resolved\n // is 0 which passes validation — so one of them must be defined here.\n const source =\n throttleMs !== undefined\n ? \"hook-level throttleMs\"\n : \"provider-level defaultThrottleMs\";\n console.error(\n `useAgent: ${source} must be a non-negative finite number, got ${resolved}. Falling back to unthrottled.`,\n );\n return 0;\n }\n return resolved;\n }, [throttleMs, providerThrottleMs]);\n\n const [, forceUpdate] = useReducer((x) => x + 1, 0);\n\n const updateFlags = useMemo(\n () => updates ?? ALL_UPDATES,\n [JSON.stringify(updates)],\n );\n\n // Cache provisional agents to avoid creating new references on every render\n // while the runtime is still connecting. A new reference would cascade into\n // CopilotChat's connectAgent effect, causing unnecessary HTTP calls.\n const provisionalAgentCache = useRef<Map<string, ProxiedCopilotRuntimeAgent>>(\n new Map(),\n );\n\n const agent: AbstractAgent = useMemo(() => {\n // Use a composite key when threadId is provided so that different threads\n // for the same agent get independent instances.\n const cacheKey = threadId ? `${agentId}:${threadId}` : agentId;\n\n const existing = copilotkit.getAgent(agentId);\n if (existing) {\n // Real agent found — clear any cached provisionals for this key and the\n // bare agentId key (handles the case where a provisional was created\n // before threadId was available, then the component re-renders with one).\n provisionalAgentCache.current.delete(cacheKey);\n provisionalAgentCache.current.delete(agentId);\n\n if (!threadId) {\n // No threadId — return the shared registry agent (original behavior)\n return existing;\n }\n\n // threadId provided — return the shared per-thread clone.\n // The global WeakMap ensures all components using the same\n // (registryAgent, threadId) pair receive the same instance, so state\n // mutations (addMessage, setState) are visible everywhere. The WeakMap\n // entry is GC-collected automatically when the registry agent is replaced.\n return getOrCreateThreadClone(existing, threadId, copilotkit.headers);\n }\n\n const isRuntimeConfigured = copilotkit.runtimeUrl !== undefined;\n const status = copilotkit.runtimeConnectionStatus;\n\n // While runtime is not yet synced, return a provisional runtime agent\n if (\n isRuntimeConfigured &&\n (status === CopilotKitCoreRuntimeConnectionStatus.Disconnected ||\n status === CopilotKitCoreRuntimeConnectionStatus.Connecting)\n ) {\n // Return cached provisional if available (keeps reference stable)\n const cached = provisionalAgentCache.current.get(cacheKey);\n if (cached) {\n // Update headers on the cached agent in case they changed\n cached.headers = { ...copilotkit.headers };\n return cached;\n }\n\n const provisional = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: copilotkit.runtimeUrl,\n agentId,\n transport: copilotkit.runtimeTransport,\n runtimeMode: \"pending\",\n });\n // Apply current headers so runs/connects inherit them\n provisional.headers = { ...copilotkit.headers };\n if (threadId) {\n provisional.threadId = threadId;\n }\n provisionalAgentCache.current.set(cacheKey, provisional);\n return provisional;\n }\n\n // Runtime is in Error state — return a provisional agent instead of throwing.\n // The error has already been emitted through the subscriber system\n // (RUNTIME_INFO_FETCH_FAILED). Throwing here would crash the React tree;\n // returning a provisional agent lets onError handlers fire while keeping\n // the app alive.\n if (\n isRuntimeConfigured &&\n status === CopilotKitCoreRuntimeConnectionStatus.Error\n ) {\n // Cache the provisional so that dep changes while in Error state (e.g.\n // headers update) return the same agent reference, matching the\n // Disconnected/Connecting path and preventing spurious re-subscriptions.\n const cached = provisionalAgentCache.current.get(cacheKey);\n if (cached) {\n cached.headers = { ...copilotkit.headers };\n return cached;\n }\n const provisional = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: copilotkit.runtimeUrl,\n agentId,\n transport: copilotkit.runtimeTransport,\n runtimeMode: \"pending\",\n });\n provisional.headers = { ...copilotkit.headers };\n if (threadId) {\n provisional.threadId = threadId;\n }\n provisionalAgentCache.current.set(cacheKey, provisional);\n return provisional;\n }\n\n // No runtime configured and agent doesn't exist — this is a configuration error.\n const knownAgents = Object.keys(copilotkit.agents ?? {});\n const runtimePart = isRuntimeConfigured\n ? `runtimeUrl=${copilotkit.runtimeUrl}`\n : \"no runtimeUrl\";\n throw new Error(\n `useAgent: Agent '${agentId}' not found after runtime sync (${runtimePart}). ` +\n (knownAgents.length\n ? `Known agents: [${knownAgents.join(\", \")}]`\n : \"No agents registered.\") +\n \" Verify your runtime /info and/or agents__unsafe_dev_only.\",\n );\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n agentId,\n threadId,\n copilotkit.agents,\n copilotkit.runtimeConnectionStatus,\n copilotkit.runtimeUrl,\n copilotkit.runtimeTransport,\n JSON.stringify(copilotkit.headers),\n ]);\n\n useEffect(() => {\n if (updateFlags.length === 0) return;\n\n const handlers: Parameters<AbstractAgent[\"subscribe\"]>[0] = {};\n let timerId: ReturnType<typeof setTimeout> | null = null;\n let active = true;\n\n if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) {\n const ms = effectiveThrottleMs;\n if (ms > 0) {\n // Throttled onMessagesChanged: leading+trailing pattern.\n // First notification fires immediately, subsequent ones within the\n // window are coalesced. Trailing timer fires after the window to\n // ensure the final state is rendered.\n let throttleActive = false;\n // Tracks whether a notification arrived during the throttle window,\n // so the trailing timer knows whether a re-render is needed.\n let pending = false;\n\n const throttledNotify = () => {\n if (!active) return;\n if (!throttleActive) {\n // Leading edge — fire immediately and start the throttle window\n throttleActive = true;\n pending = false;\n forceUpdate();\n timerId = setTimeout(function trailingEdge() {\n timerId = null;\n if (active && pending) {\n // Trailing edge — fire and restart the window\n pending = false;\n forceUpdate();\n timerId = setTimeout(trailingEdge, ms);\n } else {\n // No pending notifications — end the window\n throttleActive = false;\n }\n }, ms);\n } else {\n pending = true;\n }\n };\n\n handlers.onMessagesChanged = throttledNotify;\n } else {\n handlers.onMessagesChanged = forceUpdate;\n }\n }\n\n if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) {\n handlers.onStateChanged = forceUpdate;\n }\n\n if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {\n handlers.onRunInitialized = forceUpdate;\n handlers.onRunFinalized = forceUpdate;\n handlers.onRunFailed = forceUpdate;\n }\n\n const subscription = agent.subscribe(handlers);\n return () => {\n active = false;\n if (timerId !== null) {\n clearTimeout(timerId);\n }\n subscription.unsubscribe();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agent, forceUpdate, effectiveThrottleMs, updateFlags]);\n\n // Keep HttpAgent headers fresh without mutating inside useMemo, which is\n // unsafe in concurrent mode (React may invoke useMemo multiple times and\n // discard intermediate results, but mutations always land).\n useEffect(() => {\n if (agent instanceof HttpAgent) {\n agent.headers = { ...copilotkit.headers };\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agent, JSON.stringify(copilotkit.headers)]);\n\n return {\n agent,\n };\n}\n","import { useCopilotChatConfiguration, useCopilotKit } from \"../providers\";\nimport { getThreadClone } from \"./use-agent\";\nimport { ReactCustomMessageRendererPosition } from \"../types/react-custom-message-renderer\";\nimport { Message } from \"@ag-ui/core\";\n\ninterface UseRenderCustomMessagesParams {\n message: Message;\n position: ReactCustomMessageRendererPosition;\n}\n\nexport function useRenderCustomMessages() {\n const { copilotkit } = useCopilotKit();\n const config = useCopilotChatConfiguration();\n\n if (!config) {\n return null;\n }\n\n const { agentId, threadId } = config;\n\n const customMessageRenderers = copilotkit.renderCustomMessages\n .filter(\n (renderer) =>\n renderer.agentId === undefined || renderer.agentId === agentId,\n )\n .sort((a, b) => {\n const aHasAgent = a.agentId !== undefined;\n const bHasAgent = b.agentId !== undefined;\n if (aHasAgent === bHasAgent) return 0;\n return aHasAgent ? -1 : 1;\n });\n\n return function (params: UseRenderCustomMessagesParams) {\n if (!customMessageRenderers.length) {\n return null;\n }\n const { message, position } = params;\n const resolvedRunId =\n copilotkit.getRunIdForMessage(agentId, threadId, message.id) ??\n copilotkit.getRunIdsForThread(agentId, threadId).slice(-1)[0];\n const runId = resolvedRunId ?? `missing-run-id:${message.id}`;\n // Prefer the per-thread clone so that agent.messages reflects the actual\n // conversation state (messages live on the clone, not the registry agent).\n // Fall back to the registry agent when no clone exists (no threadId).\n const registryAgent = copilotkit.getAgent(agentId);\n const agent = getThreadClone(registryAgent, threadId) ?? registryAgent;\n if (!agent) {\n throw new Error(\"Agent not found\");\n }\n\n const messagesIdsInRun = resolvedRunId\n ? agent.messages\n .filter(\n (msg) =>\n copilotkit.getRunIdForMessage(agentId, threadId, msg.id) ===\n resolvedRunId,\n )\n .map((msg) => msg.id)\n : [message.id];\n\n const rawMessageIndex = agent.messages.findIndex(\n (msg) => msg.id === message.id,\n );\n const messageIndex = rawMessageIndex >= 0 ? rawMessageIndex : 0;\n const messageIndexInRun = resolvedRunId\n ? Math.max(messagesIdsInRun.indexOf(message.id), 0)\n : 0;\n const numberOfMessagesInRun = resolvedRunId ? messagesIdsInRun.length : 1;\n const stateSnapshot = resolvedRunId\n ? copilotkit.getStateByRun(agentId, threadId, resolvedRunId)\n : undefined;\n\n let result = null;\n for (const renderer of customMessageRenderers) {\n if (!renderer.render) {\n continue;\n }\n const Component = renderer.render;\n result = (\n <Component\n key={`${runId}-${message.id}-${position}`}\n message={message}\n position={position}\n runId={runId}\n messageIndex={messageIndex}\n messageIndexInRun={messageIndexInRun}\n numberOfMessagesInRun={numberOfMessagesInRun}\n agentId={agentId}\n stateSnapshot={stateSnapshot}\n />\n );\n if (result) {\n break;\n }\n }\n return result;\n };\n}\n","import { ActivityMessage } from \"@ag-ui/core\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkit/shared\";\nimport { useCopilotKit, useCopilotChatConfiguration } from \"../providers\";\nimport { useCallback, useMemo } from \"react\";\nimport { ReactActivityMessageRenderer } from \"../types\";\nimport { getThreadClone } from \"./use-agent\";\n\nexport function useRenderActivityMessage() {\n const { copilotkit } = useCopilotKit();\n const config = useCopilotChatConfiguration();\n const agentId = config?.agentId ?? DEFAULT_AGENT_ID;\n\n const renderers = copilotkit.renderActivityMessages;\n\n // Find the renderer for a given activity type\n const findRenderer = useCallback(\n (activityType: string): ReactActivityMessageRenderer<unknown> | null => {\n if (!renderers.length) {\n return null;\n }\n\n const matches = renderers.filter(\n (renderer) => renderer.activityType === activityType,\n );\n\n return (\n matches.find((candidate) => candidate.agentId === agentId) ??\n matches.find((candidate) => candidate.agentId === undefined) ??\n renderers.find((candidate) => candidate.activityType === \"*\") ??\n null\n );\n },\n [agentId, renderers],\n );\n\n const renderActivityMessage = useCallback(\n (message: ActivityMessage): React.ReactElement | null => {\n const renderer = findRenderer(message.activityType);\n\n if (!renderer) {\n return null;\n }\n\n const parseResult = renderer.content.safeParse(message.content);\n\n if (!parseResult.success) {\n console.warn(\n `Failed to parse content for activity message '${message.activityType}':`,\n parseResult.error,\n );\n return null;\n }\n\n const Component = renderer.render;\n // Prefer the per-thread clone so that handleAction in ReactSurfaceHost\n // calls runAgent on the same agent instance that CopilotChat renders from.\n // Without this, button clicks accumulate messages on the registry agent\n // while CopilotChat displays from the clone — responses appear to vanish.\n const registryAgent = copilotkit.getAgent(agentId);\n const agent =\n getThreadClone(registryAgent, config?.threadId) ?? registryAgent;\n\n return (\n <Component\n key={message.id}\n activityType={message.activityType}\n content={parseResult.data}\n message={message}\n agent={agent}\n />\n );\n },\n [agentId, config?.threadId, copilotkit, findRenderer],\n );\n\n return useMemo(\n () => ({ renderActivityMessage, findRenderer }),\n [renderActivityMessage, findRenderer],\n );\n}\n","import { useEffect } from \"react\";\nimport { useCopilotKit } from \"../providers/CopilotKitProvider\";\nimport type { ReactFrontendTool } from \"../types/frontend-tool\";\n\nconst EMPTY_DEPS: ReadonlyArray<unknown> = [];\n\nexport function useFrontendTool<\n T extends Record<string, unknown> = Record<string, unknown>,\n>(tool: ReactFrontendTool<T>, deps?: ReadonlyArray<unknown>) {\n const { copilotkit } = useCopilotKit();\n const extraDeps = deps ?? EMPTY_DEPS;\n\n useEffect(() => {\n const name = tool.name;\n\n // Always register/override the tool for this name on mount\n if (copilotkit.getTool({ toolName: name, agentId: tool.agentId })) {\n console.warn(\n `Tool '${name}' already exists for agent '${tool.agentId || \"global\"}'. Overriding with latest registration.`,\n );\n copilotkit.removeTool(name, tool.agentId);\n }\n copilotkit.addTool(tool);\n\n // Register/override renderer by name and agentId through core.\n // The render function is registered even when tool.parameters is\n // undefined — tools like HITL confirm dialogs have no parameters\n // but still need their UI rendered in the chat.\n if (tool.render) {\n copilotkit.addHookRenderToolCall({\n name,\n args: tool.parameters,\n agentId: tool.agentId,\n render: tool.render,\n });\n }\n\n return () => {\n copilotkit.removeTool(name, tool.agentId);\n // we are intentionally not removing the render here so that the tools can still render in the chat history\n };\n // Depend on stable keys by default and allow callers to opt into\n // additional dependencies for dynamic tool configuration.\n // tool.available is included so toggling availability re-registers the tool.\n }, [tool.name, tool.available, copilotkit, extraDeps.length, ...extraDeps]);\n}\n","import type { StandardSchemaV1, InferSchemaOutput } from \"@copilotkit/shared\";\nimport type { ComponentType } from \"react\";\nimport { useFrontendTool } from \"./use-frontend-tool\";\n\ntype InferRenderProps<T> = T extends StandardSchemaV1\n ? InferSchemaOutput<T>\n : any;\n\n/**\n * Registers a React component as a frontend tool renderer in chat.\n *\n * This hook is a convenience wrapper around `useFrontendTool` that:\n * - builds a model-facing tool description,\n * - forwards optional schema parameters (any Standard Schema V1 compatible library),\n * - renders your component with tool call parameters.\n *\n * Use this when you want to display a typed visual component for a tool call\n * without manually wiring a full frontend tool object.\n *\n * When `parameters` is provided, render props are inferred from the schema.\n * When omitted, the render component may accept any props.\n *\n * @typeParam TSchema - Schema describing tool parameters, or `undefined` when no schema is given.\n * @param config - Tool registration config.\n * @param deps - Optional dependencies to refresh registration (same semantics as `useEffect`).\n *\n * @example\n * ```tsx\n * // Without parameters — render accepts any props\n * useComponent({\n * name: \"showGreeting\",\n * render: ({ message }: { message: string }) => <div>{message}</div>,\n * });\n * ```\n *\n * @example\n * ```tsx\n * // With parameters — render props inferred from schema\n * useComponent({\n * name: \"showWeatherCard\",\n * parameters: z.object({ city: z.string() }),\n * render: ({ city }) => <div>{city}</div>,\n * });\n * ```\n *\n * @example\n * ```tsx\n * useComponent(\n * {\n * name: \"renderProfile\",\n * parameters: z.object({ userId: z.string() }),\n * render: ProfileCard,\n * agentId: \"support-agent\",\n * },\n * [selectedAgentId],\n * );\n * ```\n */\nexport function useComponent<\n TSchema extends StandardSchemaV1 | undefined = undefined,\n>(\n config: {\n name: string;\n description?: string;\n parameters?: TSchema;\n render: ComponentType<NoInfer<InferRenderProps<TSchema>>>;\n agentId?: string;\n },\n deps?: ReadonlyArray<unknown>,\n): void {\n const prefix = `Use this tool to display the \"${config.name}\" component in the chat. This tool renders a visual UI component for the user.`;\n const fullDescription = config.description\n ? `${prefix}\\n\\n${config.description}`\n : prefix;\n\n useFrontendTool(\n {\n name: config.name,\n description: fullDescription,\n parameters: config.parameters,\n render: ({ args }: { args: unknown }) => {\n const Component = config.render;\n return <Component {...(args as InferRenderProps<TSchema>)} />;\n },\n agentId: config.agentId,\n },\n deps,\n );\n}\n","import { useEffect } from \"react\";\nimport type { StandardSchemaV1, InferSchemaOutput } from \"@copilotkit/shared\";\nimport { useCopilotKit } from \"../providers/CopilotKitProvider\";\nimport { defineToolCallRenderer } from \"../types/defineToolCallRenderer\";\n\nconst EMPTY_DEPS: ReadonlyArray<unknown> = [];\n\nexport interface RenderToolInProgressProps<S extends StandardSchemaV1> {\n name: string;\n parameters: Partial<InferSchemaOutput<S>>;\n status: \"inProgress\";\n result: undefined;\n}\n\nexport interface RenderToolExecutingProps<S extends StandardSchemaV1> {\n name: string;\n parameters: InferSchemaOutput<S>;\n status: \"executing\";\n result: undefined;\n}\n\nexport interface RenderToolCompleteProps<S extends StandardSchemaV1> {\n name: string;\n parameters: InferSchemaOutput<S>;\n status: \"complete\";\n result: string;\n}\n\nexport type RenderToolProps<S extends StandardSchemaV1> =\n | RenderToolInProgressProps<S>\n | RenderToolExecutingProps<S>\n | RenderToolCompleteProps<S>;\n\ntype RenderToolConfig<S extends StandardSchemaV1> = {\n name: string;\n parameters?: S;\n render: (props: RenderToolProps<S>) => React.ReactElement;\n agentId?: string;\n};\n\n/**\n * Registers a wildcard (`\"*\"`) renderer for tool calls.\n *\n * The wildcard renderer is used as a fallback when no exact name-matched\n * renderer is registered for a tool call.\n *\n * @param config - Wildcard renderer configuration.\n * @param deps - Optional dependencies to refresh registration.\n *\n * @example\n * ```tsx\n * useRenderTool(\n * {\n * name: \"*\",\n * render: ({ name, status }) => (\n * <div>\n * {status === \"complete\" ? \"✓\" : \"⏳\"} {name}\n * </div>\n * ),\n * },\n * [],\n * );\n * ```\n */\nexport function useRenderTool(\n config: {\n name: \"*\";\n render: (props: any) => React.ReactElement;\n agentId?: string;\n },\n deps?: ReadonlyArray<unknown>,\n): void;\n\n/**\n * Registers a name-scoped renderer for tool calls.\n *\n * The provided `parameters` schema defines the typed shape of `props.parameters`\n * in `render` for `executing` and `complete` states. Accepts any Standard Schema V1\n * compatible library (Zod, Valibot, ArkType, etc.).\n *\n * @typeParam S - Schema type describing tool call parameters.\n * @param config - Named renderer configuration.\n * @param deps - Optional dependencies to refresh registration.\n *\n * @example\n * ```tsx\n * useRenderTool(\n * {\n * name: \"searchDocs\",\n * parameters: z.object({ query: z.string() }),\n * render: ({ status, parameters, result }) => {\n * if (status === \"inProgress\") return <div>Preparing...</div>;\n * if (status === \"executing\") return <div>Searching {parameters.query}</div>;\n * return <div>{result}</div>;\n * },\n * },\n * [],\n * );\n * ```\n */\nexport function useRenderTool<S extends StandardSchemaV1>(\n config: {\n name: string;\n parameters: S;\n render: (props: RenderToolProps<S>) => React.ReactElement;\n agentId?: string;\n },\n deps?: ReadonlyArray<unknown>,\n): void;\n\n/**\n * Registers a renderer entry in CopilotKit's `renderToolCalls` registry.\n *\n * Key behavior:\n * - deduplicates by `agentId:name` (latest registration wins),\n * - keeps renderer entries on cleanup so historical chat tool calls can still render,\n * - refreshes registration when `deps` change.\n *\n * @typeParam S - Schema type describing tool call parameters.\n * @param config - Renderer config for wildcard or named tools.\n * @param deps - Optional dependencies to refresh registration.\n *\n * @example\n * ```tsx\n * useRenderTool(\n * {\n * name: \"searchDocs\",\n * parameters: z.object({ query: z.string() }),\n * render: ({ status, parameters, result }) => {\n * if (status === \"executing\") return <div>Searching {parameters.query}</div>;\n * if (status === \"complete\") return <div>{result}</div>;\n * return <div>Preparing...</div>;\n * },\n * },\n * [],\n * );\n * ```\n *\n * @example\n * ```tsx\n * useRenderTool(\n * {\n * name: \"summarize\",\n * parameters: z.object({ text: z.string() }),\n * agentId: \"research-agent\",\n * render: ({ name, status }) => <div>{name}: {status}</div>,\n * },\n * [selectedAgentId],\n * );\n * ```\n */\nexport function useRenderTool<S extends StandardSchemaV1>(\n config: RenderToolConfig<S>,\n deps?: ReadonlyArray<unknown>,\n): void {\n const { copilotkit } = useCopilotKit();\n const extraDeps = deps ?? EMPTY_DEPS;\n\n useEffect(() => {\n // Build the ReactToolCallRenderer via defineToolCallRenderer\n const renderer =\n config.name === \"*\" && !config.parameters\n ? defineToolCallRenderer({\n name: \"*\",\n render: (props) =>\n config.render({ ...props, parameters: props.args }),\n ...(config.agentId ? { agentId: config.agentId } : {}),\n })\n : defineToolCallRenderer({\n name: config.name,\n args: config.parameters!,\n render: (props) =>\n config.render({ ...props, parameters: props.args }),\n ...(config.agentId ? { agentId: config.agentId } : {}),\n });\n\n copilotkit.addHookRenderToolCall(renderer);\n\n // No cleanup removal — keeps renderer for chat history, same as useFrontendTool\n }, [config.name, copilotkit, extraDeps.length, ...extraDeps]);\n}\n","import React, { useState } from \"react\";\nimport { useRenderTool } from \"./use-render-tool\";\n\ntype DefaultRenderProps = {\n /** The name of the tool being called. */\n name: string;\n /** The parsed parameters passed to the tool call. */\n parameters: unknown;\n /** Current execution status of the tool call. */\n status: \"inProgress\" | \"executing\" | \"complete\";\n /** The tool call result string, available only when `status` is `\"complete\"`. */\n result: string | undefined;\n};\n\n/**\n * Registers a wildcard (`\"*\"`) tool-call renderer via `useRenderTool`.\n *\n * - Call with no config to use CopilotKit's built-in default tool-call card.\n * - Pass `config.render` to replace the default UI with your own fallback renderer.\n *\n * This is useful when you want a generic renderer for tools that do not have a\n * dedicated `useRenderTool({ name: \"...\" })` registration.\n *\n * @param config - Optional custom wildcard render function.\n * @param deps - Optional dependencies to refresh registration.\n *\n * @example\n * ```tsx\n * useDefaultRenderTool();\n * ```\n *\n * @example\n * ```tsx\n * useDefaultRenderTool({\n * render: ({ name, status }) => <div>{name}: {status}</div>,\n * });\n * ```\n *\n * @example\n * ```tsx\n * useDefaultRenderTool(\n * {\n * render: ({ name, result }) => (\n * <ToolEventRow title={name} payload={result} compact={compactMode} />\n * ),\n * },\n * [compactMode],\n * );\n * ```\n */\nexport function useDefaultRenderTool(\n config?: {\n render?: (props: DefaultRenderProps) => React.ReactElement;\n },\n deps?: ReadonlyArray<unknown>,\n): void {\n useRenderTool(\n {\n name: \"*\",\n render: config?.render ?? DefaultToolCallRenderer,\n },\n deps,\n );\n}\n\nfunction DefaultToolCallRenderer({\n name,\n parameters,\n status,\n result,\n}: DefaultRenderProps): React.ReactElement {\n const [isExpanded, setIsExpanded] = useState(false);\n\n const statusString = String(status) as\n | \"inProgress\"\n | \"executing\"\n | \"complete\";\n const isActive =\n statusString === \"inProgress\" || statusString === \"executing\";\n const isComplete = statusString === \"complete\";\n\n const statusLabel = isActive ? \"Running\" : isComplete ? \"Done\" : status;\n const dotColor = isActive ? \"#f59e0b\" : isComplete ? \"#10b981\" : \"#a1a1aa\";\n const badgeBg = isActive ? \"#fef3c7\" : isComplete ? \"#d1fae5\" : \"#f4f4f5\";\n const badgeColor = isActive ? \"#92400e\" : isComplete ? \"#065f46\" : \"#3f3f46\";\n\n return (\n <div\n style={{\n marginTop: \"8px\",\n paddingBottom: \"8px\",\n }}\n >\n <div\n style={{\n borderRadius: \"12px\",\n border: \"1px solid #e4e4e7\",\n backgroundColor: \"#fafafa\",\n padding: \"14px 16px\",\n }}\n >\n {/* Header row — always visible */}\n <div\n onClick={() => setIsExpanded(!isExpanded)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: \"10px\",\n cursor: \"pointer\",\n userSelect: \"none\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n minWidth: 0,\n }}\n >\n <svg\n style={{\n height: \"14px\",\n width: \"14px\",\n color: \"#71717a\",\n transition: \"transform 0.15s\",\n transform: isExpanded ? \"rotate(90deg)\" : \"rotate(0deg)\",\n flexShrink: 0,\n }}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n strokeWidth={2}\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M8.25 4.5l7.5 7.5-7.5 7.5\"\n />\n </svg>\n <span\n style={{\n display: \"inline-block\",\n height: \"8px\",\n width: \"8px\",\n borderRadius: \"50%\",\n backgroundColor: dotColor,\n flexShrink: 0,\n }}\n />\n <span\n style={{\n fontSize: \"13px\",\n fontWeight: 600,\n color: \"#18181b\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {name}\n </span>\n </div>\n\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n borderRadius: \"9999px\",\n padding: \"2px 8px\",\n fontSize: \"11px\",\n fontWeight: 500,\n backgroundColor: badgeBg,\n color: badgeColor,\n flexShrink: 0,\n }}\n >\n {statusLabel}\n </span>\n </div>\n\n {/* Expandable details */}\n {isExpanded && (\n <div style={{ marginTop: \"12px\", display: \"grid\", gap: \"12px\" }}>\n <div>\n <div\n style={{\n fontSize: \"10px\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.05em\",\n color: \"#71717a\",\n }}\n >\n Arguments\n </div>\n <pre\n style={{\n marginTop: \"6px\",\n maxHeight: \"200px\",\n overflow: \"auto\",\n borderRadius: \"6px\",\n backgroundColor: \"#f4f4f5\",\n padding: \"10px\",\n fontSize: \"11px\",\n lineHeight: 1.6,\n color: \"#27272a\",\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n }}\n >\n {JSON.stringify(parameters ?? {}, null, 2)}\n </pre>\n </div>\n\n {result !== undefined && (\n <div>\n <div\n style={{\n fontSize: \"10px\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.05em\",\n color: \"#71717a\",\n }}\n >\n Result\n </div>\n <pre\n style={{\n marginTop: \"6px\",\n maxHeight: \"200px\",\n overflow: \"auto\",\n borderRadius: \"6px\",\n backgroundColor: \"#f4f4f5\",\n padding: \"10px\",\n fontSize: \"11px\",\n lineHeight: 1.6,\n color: \"#27272a\",\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n }}\n >\n {typeof result === \"string\"\n ? result\n : JSON.stringify(result, null, 2)}\n </pre>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n}\n","import { useCopilotKit } from \"../providers/CopilotKitProvider\";\nimport type { ReactFrontendTool } from \"../types/frontend-tool\";\nimport type { ReactHumanInTheLoop } from \"../types/human-in-the-loop\";\nimport type { ReactToolCallRenderer } from \"../types/react-tool-call-renderer\";\nimport { useCallback, useEffect, useRef } from \"react\";\nimport React from \"react\";\nimport { useFrontendTool } from \"./use-frontend-tool\";\n\nexport function useHumanInTheLoop<\n T extends Record<string, unknown> = Record<string, unknown>,\n>(tool: ReactHumanInTheLoop<T>, deps?: ReadonlyArray<unknown>) {\n const { copilotkit } = useCopilotKit();\n const resolvePromiseRef = useRef<((result: unknown) => void) | null>(null);\n\n const respond = useCallback(async (result: unknown) => {\n if (resolvePromiseRef.current) {\n resolvePromiseRef.current(result);\n resolvePromiseRef.current = null;\n }\n }, []);\n\n const handler = useCallback(async () => {\n return new Promise((resolve) => {\n resolvePromiseRef.current = resolve;\n });\n }, []);\n\n const RenderComponent: ReactToolCallRenderer<T>[\"render\"] = useCallback(\n (props) => {\n const ToolComponent = tool.render;\n\n // Enhance props based on current status\n if (props.status === \"inProgress\") {\n const enhancedProps = {\n ...props,\n name: tool.name,\n description: tool.description || \"\",\n respond: undefined,\n };\n return React.createElement(ToolComponent, enhancedProps);\n } else if (props.status === \"executing\") {\n const enhancedProps = {\n ...props,\n name: tool.name,\n description: tool.description || \"\",\n respond,\n };\n return React.createElement(ToolComponent, enhancedProps);\n } else if (props.status === \"complete\") {\n const enhancedProps = {\n ...props,\n name: tool.name,\n description: tool.description || \"\",\n respond: undefined,\n };\n return React.createElement(ToolComponent, enhancedProps);\n }\n\n // Fallback - just render with original props\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return React.createElement(ToolComponent, props as any);\n },\n [tool.render, tool.name, tool.description, respond],\n );\n\n const frontendTool: ReactFrontendTool<T> = {\n ...tool,\n handler,\n render: RenderComponent,\n };\n\n useFrontendTool(frontendTool, deps);\n\n // Human-in-the-loop tools should remove their renderer on unmount\n // since they can't respond to user interactions anymore\n useEffect(() => {\n return () => {\n copilotkit.removeHookRenderToolCall(tool.name, tool.agentId);\n };\n }, [copilotkit, tool.name, tool.agentId]);\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { Suggestion } from \"@copilotkit/core\";\nimport { useCopilotKit } from \"../providers/CopilotKitProvider\";\nimport { useCopilotChatConfiguration } from \"../providers/CopilotChatConfigurationProvider\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkit/shared\";\n\nexport interface UseSuggestionsOptions {\n agentId?: string;\n}\n\nexport interface UseSuggestionsResult {\n suggestions: Suggestion[];\n reloadSuggestions: () => void;\n clearSuggestions: () => void;\n isLoading: boolean;\n}\n\nexport function useSuggestions({\n agentId,\n}: UseSuggestionsOptions = {}): UseSuggestionsResult {\n const { copilotkit } = useCopilotKit();\n const config = useCopilotChatConfiguration();\n const resolvedAgentId = useMemo(\n () => agentId ?? config?.agentId ?? DEFAULT_AGENT_ID,\n [agentId, config?.agentId],\n );\n\n const [suggestions, setSuggestions] = useState<Suggestion[]>(() => {\n const result = copilotkit.getSuggestions(resolvedAgentId);\n return result.suggestions;\n });\n const [isLoading, setIsLoading] = useState(() => {\n const result = copilotkit.getSuggestions(resolvedAgentId);\n return result.isLoading;\n });\n\n useEffect(() => {\n const result = copilotkit.getSuggestions(resolvedAgentId);\n setSuggestions(result.suggestions);\n setIsLoading(result.isLoading);\n }, [copilotkit, resolvedAgentId]);\n\n useEffect(() => {\n const subscription = copilotkit.subscribe({\n onSuggestionsChanged: ({ agentId: changedAgentId, suggestions }) => {\n if (changedAgentId !== resolvedAgentId) {\n return;\n }\n setSuggestions(suggestions);\n },\n onSuggestionsStartedLoading: ({ agentId: changedAgentId }) => {\n if (changedAgentId !== resolvedAgentId) {\n return;\n }\n setIsLoading(true);\n },\n onSuggestionsFinishedLoading: ({ agentId: changedAgentId }) => {\n if (changedAgentId !== resolvedAgentId) {\n return;\n }\n setIsLoading(false);\n },\n onSuggestionsConfigChanged: () => {\n const result = copilotkit.getSuggestions(resolvedAgentId);\n setSuggestions(result.suggestions);\n setIsLoading(result.isLoading);\n },\n });\n\n return () => {\n subscription.unsubscribe();\n };\n }, [copilotkit, resolvedAgentId]);\n\n const reloadSuggestions = useCallback(() => {\n copilotkit.reloadSuggestions(resolvedAgentId);\n // Loading state is handled by onSuggestionsStartedLoading event\n }, [copilotkit, resolvedAgentId]);\n\n const clearSuggestions = useCallback(() => {\n copilotkit.clearSuggestions(resolvedAgentId);\n // State updates are handled by onSuggestionsChanged event\n }, [copilotkit, resolvedAgentId]);\n\n return {\n suggestions,\n reloadSuggestions,\n clearSuggestions,\n isLoading,\n };\n}\n","import { useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { useCopilotKit } from \"../providers/CopilotKitProvider\";\nimport { useCopilotChatConfiguration } from \"../providers/CopilotChatConfigurationProvider\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkit/shared\";\nimport {\n DynamicSuggestionsConfig,\n StaticSuggestionsConfig,\n SuggestionsConfig,\n Suggestion,\n} from \"@copilotkit/core\";\n\ntype StaticSuggestionInput = Omit<Suggestion, \"isLoading\"> &\n Partial<Pick<Suggestion, \"isLoading\">>;\n\ntype StaticSuggestionsConfigInput = Omit<\n StaticSuggestionsConfig,\n \"suggestions\"\n> & {\n suggestions: StaticSuggestionInput[];\n};\n\ntype SuggestionsConfigInput =\n | DynamicSuggestionsConfig\n | StaticSuggestionsConfigInput;\n\nexport function useConfigureSuggestions(\n config: SuggestionsConfigInput | null | undefined,\n deps?: ReadonlyArray<unknown>,\n): void {\n const { copilotkit } = useCopilotKit();\n const chatConfig = useCopilotChatConfiguration();\n const extraDeps = deps ?? [];\n\n const resolvedConsumerAgentId = useMemo(\n () => chatConfig?.agentId ?? DEFAULT_AGENT_ID,\n [chatConfig?.agentId],\n );\n\n const rawConsumerAgentId = useMemo(\n () =>\n config ? (config as SuggestionsConfigInput).consumerAgentId : undefined,\n [config],\n );\n\n const normalizationCacheRef = useRef<{\n serialized: string | null;\n config: SuggestionsConfig | null;\n }>({\n serialized: null,\n config: null,\n });\n\n const { normalizedConfig, serializedConfig } = useMemo(() => {\n if (!config) {\n normalizationCacheRef.current = { serialized: null, config: null };\n return { normalizedConfig: null, serializedConfig: null };\n }\n\n if (config.available === \"disabled\") {\n normalizationCacheRef.current = { serialized: null, config: null };\n return { normalizedConfig: null, serializedConfig: null };\n }\n\n let built: SuggestionsConfig;\n if (isDynamicConfig(config)) {\n built = {\n ...config,\n } satisfies DynamicSuggestionsConfig;\n } else {\n const normalizedSuggestions = normalizeStaticSuggestions(\n config.suggestions,\n );\n const baseConfig: StaticSuggestionsConfig = {\n ...config,\n suggestions: normalizedSuggestions,\n };\n built = baseConfig;\n }\n\n const serialized = JSON.stringify(built);\n const cache = normalizationCacheRef.current;\n if (cache.serialized === serialized && cache.config) {\n return { normalizedConfig: cache.config, serializedConfig: serialized };\n }\n\n normalizationCacheRef.current = { serialized, config: built };\n return { normalizedConfig: built, serializedConfig: serialized };\n }, [config, resolvedConsumerAgentId, ...extraDeps]);\n const latestConfigRef = useRef<SuggestionsConfig | null>(null);\n latestConfigRef.current = normalizedConfig;\n const previousSerializedConfigRef = useRef<string | null>(null);\n\n const targetAgentId = useMemo(() => {\n if (!normalizedConfig) {\n return resolvedConsumerAgentId;\n }\n const consumer = (\n normalizedConfig as StaticSuggestionsConfig | DynamicSuggestionsConfig\n ).consumerAgentId;\n if (!consumer || consumer === \"*\") {\n return resolvedConsumerAgentId;\n }\n return consumer;\n }, [normalizedConfig, resolvedConsumerAgentId]);\n\n const isGlobalConfig =\n rawConsumerAgentId === undefined || rawConsumerAgentId === \"*\";\n\n const requestReload = useCallback(() => {\n if (!normalizedConfig) {\n return;\n }\n\n if (isGlobalConfig) {\n const agents = Object.values(copilotkit.agents ?? {});\n for (const entry of agents) {\n const agentId = entry.agentId;\n if (!agentId) {\n continue;\n }\n if (!entry.isRunning) {\n copilotkit.reloadSuggestions(agentId);\n }\n }\n return;\n }\n\n if (!targetAgentId) {\n return;\n }\n\n copilotkit.reloadSuggestions(targetAgentId);\n }, [copilotkit, isGlobalConfig, normalizedConfig, targetAgentId]);\n\n useEffect(() => {\n if (!serializedConfig || !latestConfigRef.current) {\n return;\n }\n\n const id = copilotkit.addSuggestionsConfig(latestConfigRef.current);\n\n requestReload();\n\n return () => {\n copilotkit.removeSuggestionsConfig(id);\n };\n }, [copilotkit, serializedConfig, requestReload]);\n\n useEffect(() => {\n if (!normalizedConfig) {\n previousSerializedConfigRef.current = null;\n return;\n }\n if (\n serializedConfig &&\n previousSerializedConfigRef.current === serializedConfig\n ) {\n return;\n }\n if (serializedConfig) {\n previousSerializedConfigRef.current = serializedConfig;\n }\n requestReload();\n }, [normalizedConfig, requestReload, serializedConfig]);\n\n useEffect(() => {\n if (!normalizedConfig || extraDeps.length === 0) {\n return;\n }\n requestReload();\n }, [extraDeps.length, normalizedConfig, requestReload, ...extraDeps]);\n}\n\nfunction isDynamicConfig(\n config: SuggestionsConfigInput,\n): config is DynamicSuggestionsConfig {\n return \"instructions\" in config;\n}\n\nfunction normalizeStaticSuggestions(\n suggestions: StaticSuggestionInput[],\n): Suggestion[] {\n return suggestions.map((suggestion) => ({\n ...suggestion,\n isLoading: suggestion.isLoading ?? false,\n }));\n}\n","import React, {\n useState,\n useEffect,\n useCallback,\n useMemo,\n useRef,\n} from \"react\";\nimport { useCopilotKit } from \"../providers/CopilotKitProvider\";\nimport { useAgent } from \"./use-agent\";\nimport type {\n InterruptEvent,\n InterruptRenderProps,\n InterruptHandlerProps,\n} from \"../types/interrupt\";\n\nexport type { InterruptEvent, InterruptRenderProps, InterruptHandlerProps };\n\nconst INTERRUPT_EVENT_NAME = \"on_interrupt\";\n\ntype InterruptHandlerFn<TValue, TResult> = (\n props: InterruptHandlerProps<TValue>,\n) => TResult | PromiseLike<TResult>;\n\ntype InterruptResultFromHandler<THandler> = THandler extends (\n ...args: never[]\n) => infer TResult\n ? TResult extends PromiseLike<infer TResolved>\n ? TResolved | null\n : TResult | null\n : null;\n\ntype InterruptResult<TValue, TResult> = InterruptResultFromHandler<\n InterruptHandlerFn<TValue, TResult>\n>;\n\ntype InterruptRenderInChat = boolean | undefined;\n\ntype UseInterruptReturn<TRenderInChat extends InterruptRenderInChat> =\n TRenderInChat extends false\n ? React.ReactElement | null\n : TRenderInChat extends true | undefined\n ? void\n : React.ReactElement | null | void;\n\nexport function isPromiseLike<TValue>(\n value: TValue | PromiseLike<TValue>,\n): value is PromiseLike<TValue> {\n return (\n (typeof value === \"object\" || typeof value === \"function\") &&\n value !== null &&\n typeof Reflect.get(value, \"then\") === \"function\"\n );\n}\n\n/**\n * Configuration options for `useInterrupt`.\n */\ninterface UseInterruptConfigBase<TValue = unknown, TResult = never> {\n /**\n * Render function for the interrupt UI.\n *\n * This is called once an interrupt is finalized and accepted by `enabled` (if provided).\n * Use `resolve` from render props to resume the agent run with user input.\n */\n render: (\n props: InterruptRenderProps<TValue, InterruptResult<TValue, TResult>>,\n ) => React.ReactElement;\n /**\n * Optional pre-render handler invoked when an interrupt is received.\n *\n * Return either a sync value or an async value to pass into `render` as `result`.\n * Rejecting/throwing falls back to `result = null`.\n */\n handler?: InterruptHandlerFn<TValue, TResult>;\n /**\n * Optional predicate to filter which interrupts should be handled by this hook.\n * Return `false` to ignore an interrupt.\n */\n enabled?: (event: InterruptEvent<TValue>) => boolean;\n /** Optional agent id. Defaults to the current configured chat agent. */\n agentId?: string;\n}\n\nexport interface UseInterruptInChatConfig<\n TValue = unknown,\n TResult = never,\n> extends UseInterruptConfigBase<TValue, TResult> {\n /** When true (default), the interrupt UI renders inside `<CopilotChat>` automatically. Set to false to render it yourself. */\n renderInChat?: true;\n}\n\nexport interface UseInterruptExternalConfig<\n TValue = unknown,\n TResult = never,\n> extends UseInterruptConfigBase<TValue, TResult> {\n /** When true (default), the interrupt UI renders inside `<CopilotChat>` automatically. Set to false to render it yourself. */\n renderInChat: false;\n}\n\nexport interface UseInterruptDynamicConfig<\n TValue = unknown,\n TResult = never,\n> extends UseInterruptConfigBase<TValue, TResult> {\n /** Dynamic boolean mode. When non-literal, return type is a union. */\n renderInChat: boolean;\n}\n\nexport type UseInterruptConfig<\n TValue = unknown,\n TResult = never,\n TRenderInChat extends InterruptRenderInChat = undefined,\n> = UseInterruptConfigBase<TValue, TResult> & {\n /** When true (default), the interrupt UI renders inside `<CopilotChat>` automatically. Set to false to render it yourself. */\n renderInChat?: TRenderInChat;\n};\n\n/**\n * Handles agent interrupts (`on_interrupt`) with optional filtering, preprocessing, and resume behavior.\n *\n * The hook listens to custom events on the active agent, stores interrupt payloads per run,\n * and surfaces a render callback once the run finalizes. Call `resolve` from your UI to resume\n * execution with user-provided data.\n *\n * - `renderInChat: true` (default): the element is published into `<CopilotChat>` and this hook returns `void`.\n * - `renderInChat: false`: the hook returns the interrupt element so you can place it anywhere in your component tree.\n *\n * `event.value` is typed as `any` since the interrupt payload shape depends on your agent.\n * Type-narrow it in your callbacks (e.g. `handler`, `enabled`, `render`) as needed.\n *\n * @typeParam TResult - Inferred from `handler` return type. Exposed as `result` in `render`.\n * @param config - Interrupt configuration (renderer, optional handler/filter, and render mode).\n * @returns When `renderInChat` is `false`, returns the interrupt element (or `null` when idle).\n * Otherwise returns `void` and publishes the element into chat. In `render`, `result` is always\n * either the handler's resolved return value or `null` (including when no handler is provided,\n * when filtering skips the interrupt, or when handler execution fails).\n *\n * @example\n * ```tsx\n * import { useInterrupt } from \"@copilotkit/react-core/v2\";\n *\n * function InterruptUI() {\n * useInterrupt({\n * render: ({ event, resolve }) => (\n * <div>\n * <p>{event.value.question}</p>\n * <button onClick={() => resolve({ approved: true })}>Approve</button>\n * <button onClick={() => resolve({ approved: false })}>Reject</button>\n * </div>\n * ),\n * });\n *\n * return null;\n * }\n * ```\n *\n * @example\n * ```tsx\n * import { useInterrupt } from \"@copilotkit/react-core/v2\";\n *\n * function CustomPanel() {\n * const interruptElement = useInterrupt({\n * renderInChat: false,\n * enabled: (event) => event.value.startsWith(\"approval:\"),\n * handler: async ({ event }) => ({ label: event.value.toUpperCase() }),\n * render: ({ event, result, resolve }) => (\n * <aside>\n * <strong>{result?.label ?? \"\"}</strong>\n * <button onClick={() => resolve({ value: event.value })}>Continue</button>\n * </aside>\n * ),\n * });\n *\n * return <>{interruptElement}</>;\n * }\n * ```\n */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport function useInterrupt<\n TResult = never,\n TRenderInChat extends InterruptRenderInChat = undefined,\n>(\n config: UseInterruptConfig<any, TResult, TRenderInChat>,\n): UseInterruptReturn<TRenderInChat> {\n /* eslint-enable @typescript-eslint/no-explicit-any */\n const { copilotkit } = useCopilotKit();\n const { agent } = useAgent({ agentId: config.agentId });\n const [pendingEvent, setPendingEvent] = useState<InterruptEvent | null>(null);\n const pendingEventRef = useRef(pendingEvent);\n pendingEventRef.current = pendingEvent;\n const [handlerResult, setHandlerResult] =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n useState<InterruptResult<any, TResult>>(null);\n\n useEffect(() => {\n let localInterrupt: InterruptEvent | null = null;\n\n const subscription = agent.subscribe({\n onCustomEvent: ({ event }) => {\n if (event.name === INTERRUPT_EVENT_NAME) {\n localInterrupt = { name: event.name, value: event.value };\n }\n },\n onRunStartedEvent: () => {\n localInterrupt = null;\n setPendingEvent(null);\n },\n onRunFinalized: () => {\n if (localInterrupt) {\n setPendingEvent(localInterrupt);\n localInterrupt = null;\n }\n },\n onRunFailed: () => {\n localInterrupt = null;\n },\n });\n\n return () => subscription.unsubscribe();\n }, [agent]);\n\n const resolve = useCallback(\n (response: unknown) => {\n setPendingEvent(null);\n copilotkit.runAgent({\n agent,\n forwardedProps: {\n command: {\n resume: response,\n interruptEvent: pendingEventRef.current?.value,\n },\n },\n });\n },\n [agent, copilotkit],\n );\n\n useEffect(() => {\n // No interrupt to process — reset any stale handler result from a previous interrupt\n if (!pendingEvent) {\n setHandlerResult(null);\n return;\n }\n // Interrupt exists but the consumer's filter rejects it — treat as no-op\n if (config.enabled && !config.enabled(pendingEvent)) {\n setHandlerResult(null);\n return;\n }\n const handler = config.handler;\n // No handler provided — skip straight to rendering with a null result\n if (!handler) {\n setHandlerResult(null);\n return;\n }\n\n let cancelled = false;\n const maybePromise = handler({\n event: pendingEvent,\n resolve,\n });\n\n // If the handler returns a promise/thenable, wait for resolution before setting result.\n if (isPromiseLike(maybePromise)) {\n Promise.resolve(maybePromise)\n .then((resolved) => {\n if (!cancelled) setHandlerResult(resolved);\n })\n .catch(() => {\n if (!cancelled) setHandlerResult(null);\n });\n } else {\n setHandlerResult(maybePromise);\n }\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [pendingEvent, config.enabled, config.handler, resolve]);\n\n const element = useMemo(() => {\n if (!pendingEvent) return null;\n if (config.enabled && !config.enabled(pendingEvent)) return null;\n\n return config.render({\n event: pendingEvent,\n result: handlerResult,\n resolve,\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [pendingEvent, handlerResult, config.enabled, config.render, resolve]);\n\n // Publish to core for in-chat rendering\n useEffect(() => {\n if (config.renderInChat === false) return;\n copilotkit.setInterruptElement(element);\n return () => copilotkit.setInterruptElement(null);\n }, [element, config.renderInChat, copilotkit]);\n\n // Only return element when rendering outside chat\n if (config.renderInChat === false) {\n return element as UseInterruptReturn<TRenderInChat>;\n }\n\n return undefined as UseInterruptReturn<TRenderInChat>;\n}\n","import { useCopilotKit } from \"../providers/CopilotKitProvider\";\nimport {\n ɵcreateThreadStore,\n ɵselectThreads,\n ɵselectThreadsError,\n ɵselectThreadsIsLoading,\n ɵselectHasNextPage,\n ɵselectIsFetchingNextPage,\n type ɵThreadRuntimeContext,\n type ɵThreadStore,\n} from \"@copilotkit/core\";\nimport {\n useCallback,\n useEffect,\n useMemo,\n useState,\n useSyncExternalStore,\n} from \"react\";\n\n/**\n * A conversation thread managed by the Intelligence platform.\n *\n * Each thread has a unique `id`, an optional human-readable `name`, and\n * timestamp fields tracking creation and update times.\n */\nexport interface Thread {\n id: string;\n agentId: string;\n name: string | null;\n archived: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\n/**\n * Configuration for the {@link useThreads} hook.\n *\n * Thread operations are scoped to the runtime-authenticated user and the\n * provided agent on the Intelligence platform.\n */\nexport interface UseThreadsInput {\n /** The ID of the agent whose threads to list and manage. */\n agentId: string;\n /** When `true`, archived threads are included in the list. Defaults to `false`. */\n includeArchived?: boolean;\n /** Maximum number of threads to fetch per page. When set, enables cursor-based pagination. */\n limit?: number;\n}\n\n/**\n * Return value of the {@link useThreads} hook.\n *\n * The `threads` array is kept in sync with the platform via a realtime\n * WebSocket subscription (when available) and is sorted most-recently-updated\n * first. Mutations reject with an `Error` if the platform request fails.\n */\nexport interface UseThreadsResult {\n /**\n * Threads for the current user/agent pair, sorted by most recently\n * updated first. Updated in realtime when the platform pushes metadata\n * events. Includes archived threads only when `includeArchived` is set.\n */\n threads: Thread[];\n /**\n * `true` while the initial thread list is being fetched from the platform.\n * Subsequent realtime updates do not re-enter the loading state.\n */\n isLoading: boolean;\n /**\n * The most recent error from fetching threads or executing a mutation,\n * or `null` when there is no error. Reset to `null` on the next\n * successful fetch.\n */\n error: Error | null;\n /**\n * `true` when there are more threads available to fetch via\n * {@link fetchMoreThreads}. Only meaningful when `limit` is set.\n */\n hasMoreThreads: boolean;\n /**\n * `true` while a subsequent page of threads is being fetched.\n */\n isFetchingMoreThreads: boolean;\n /**\n * Fetch the next page of threads. No-op when {@link hasMoreThreads} is\n * `false` or a fetch is already in progress.\n */\n fetchMoreThreads: () => void;\n /**\n * Rename a thread on the platform.\n * Resolves when the server confirms the update; rejects on failure.\n */\n renameThread: (threadId: string, name: string) => Promise<void>;\n /**\n * Archive a thread on the platform.\n * Archived threads are excluded from subsequent list results.\n * Resolves when the server confirms the update; rejects on failure.\n */\n archiveThread: (threadId: string) => Promise<void>;\n /**\n * Permanently delete a thread from the platform.\n * This is irreversible. Resolves when the server confirms deletion;\n * rejects on failure.\n */\n deleteThread: (threadId: string) => Promise<void>;\n}\n\nfunction useThreadStoreSelector<T>(\n store: ɵThreadStore,\n selector: (state: ReturnType<ɵThreadStore[\"getState\"]>) => T,\n): T {\n return useSyncExternalStore(\n useCallback(\n (onStoreChange) => {\n const subscription = store.select(selector).subscribe(onStoreChange);\n return () => subscription.unsubscribe();\n },\n [store, selector],\n ),\n () => selector(store.getState()),\n );\n}\n\n/**\n * React hook for listing and managing Intelligence platform threads.\n *\n * On mount the hook fetches the thread list for the runtime-authenticated user\n * and the given `agentId`. When the Intelligence platform exposes a WebSocket\n * URL, it also opens a realtime subscription so the `threads` array stays\n * current without polling — thread creates, renames, archives, and deletes\n * from any client are reflected immediately.\n *\n * Mutation methods (`renameThread`, `archiveThread`, `deleteThread`) return\n * promises that resolve once the platform confirms the operation and reject\n * with an `Error` on failure.\n *\n * @param input - Agent identifier and optional list controls.\n * @returns Thread list state and stable mutation callbacks.\n *\n * @example\n * ```tsx\n * import { useThreads } from \"@copilotkit/react-core\";\n *\n * function ThreadList() {\n * const { threads, isLoading, renameThread, deleteThread } = useThreads({\n * agentId: \"agent-1\",\n * });\n *\n * if (isLoading) return <p>Loading…</p>;\n *\n * return (\n * <ul>\n * {threads.map((t) => (\n * <li key={t.id}>\n * {t.name ?? \"Untitled\"}\n * <button onClick={() => renameThread(t.id, \"New name\")}>Rename</button>\n * <button onClick={() => deleteThread(t.id)}>Delete</button>\n * </li>\n * ))}\n * </ul>\n * );\n * }\n * ```\n */\nexport function useThreads({\n agentId,\n includeArchived,\n limit,\n}: UseThreadsInput): UseThreadsResult {\n const { copilotkit } = useCopilotKit();\n\n const [store] = useState(() =>\n ɵcreateThreadStore({\n fetch: globalThis.fetch,\n }),\n );\n\n const coreThreads = useThreadStoreSelector(store, ɵselectThreads);\n const threads: Thread[] = useMemo(\n () =>\n coreThreads.map(\n ({ id, agentId, name, archived, createdAt, updatedAt }) => ({\n id,\n agentId,\n name,\n archived,\n createdAt,\n updatedAt,\n }),\n ),\n [coreThreads],\n );\n const storeIsLoading = useThreadStoreSelector(store, ɵselectThreadsIsLoading);\n const storeError = useThreadStoreSelector(store, ɵselectThreadsError);\n const hasMoreThreads = useThreadStoreSelector(store, ɵselectHasNextPage);\n const isFetchingMoreThreads = useThreadStoreSelector(\n store,\n ɵselectIsFetchingNextPage,\n );\n const headersKey = useMemo(() => {\n return JSON.stringify(\n Object.entries(copilotkit.headers ?? {}).sort(([left], [right]) =>\n left.localeCompare(right),\n ),\n );\n }, [copilotkit.headers]);\n const runtimeError = useMemo(() => {\n if (copilotkit.runtimeUrl) {\n return null;\n }\n\n return new Error(\"Runtime URL is not configured\");\n }, [copilotkit.runtimeUrl]);\n const isLoading = runtimeError ? false : storeIsLoading;\n const error = runtimeError ?? storeError;\n\n useEffect(() => {\n store.start();\n return () => {\n store.stop();\n };\n }, [store]);\n\n useEffect(() => {\n const context: ɵThreadRuntimeContext | null = copilotkit.runtimeUrl\n ? {\n runtimeUrl: copilotkit.runtimeUrl,\n headers: { ...copilotkit.headers },\n wsUrl: copilotkit.intelligence?.wsUrl,\n agentId,\n includeArchived,\n limit,\n }\n : null;\n\n store.setContext(context);\n }, [\n store,\n copilotkit.runtimeUrl,\n headersKey,\n copilotkit.intelligence?.wsUrl,\n agentId,\n copilotkit.headers,\n includeArchived,\n limit,\n ]);\n\n const renameThread = useCallback(\n (threadId: string, name: string) => store.renameThread(threadId, name),\n [store],\n );\n\n const archiveThread = useCallback(\n (threadId: string) => store.archiveThread(threadId),\n [store],\n );\n\n const deleteThread = useCallback(\n (threadId: string) => store.deleteThread(threadId),\n [store],\n );\n\n const fetchMoreThreads = useCallback(() => store.fetchNextPage(), [store]);\n\n return {\n threads,\n isLoading,\n error,\n hasMoreThreads,\n isFetchingMoreThreads,\n fetchMoreThreads,\n renameThread,\n archiveThread,\n deleteThread,\n };\n}\n","import React, { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n randomUUID,\n getModalityFromMimeType,\n exceedsMaxSize,\n readFileAsBase64,\n generateVideoThumbnail,\n matchesAcceptFilter,\n formatFileSize,\n} from \"@copilotkit/shared\";\nimport type { Attachment, AttachmentsConfig } from \"@copilotkit/shared\";\n\nexport interface UseAttachmentsProps {\n config?: AttachmentsConfig;\n}\n\nexport interface UseAttachmentsReturn {\n /** Currently selected attachments (uploading + ready). */\n attachments: Attachment[];\n /** Whether attachments are enabled. */\n enabled: boolean;\n /** Whether the user is dragging a file over the drop zone. */\n dragOver: boolean;\n /** Ref for the hidden file input element. */\n fileInputRef: React.RefObject<HTMLInputElement | null>;\n /** Ref for the container element (used for scoped paste handling). */\n containerRef: React.RefObject<HTMLDivElement | null>;\n /** Process an array of files (validate, upload, add to state). */\n processFiles: (files: File[]) => Promise<void>;\n /** Handler for `<input type=\"file\" onChange>`. */\n handleFileUpload: (e: React.ChangeEvent<HTMLInputElement>) => Promise<void>;\n /** Handler for `onDragOver` on the drop zone. */\n handleDragOver: (e: React.DragEvent) => void;\n /** Handler for `onDragLeave` on the drop zone. */\n handleDragLeave: (e: React.DragEvent) => void;\n /** Handler for `onDrop` on the drop zone. */\n handleDrop: (e: React.DragEvent) => Promise<void>;\n /** Remove an attachment by ID. */\n removeAttachment: (id: string) => void;\n /**\n * Consume ready attachments and clear the queue.\n * Returns the attachments that were ready; resets the file input.\n * No-ops if the queue is already empty (no state update triggered).\n */\n consumeAttachments: () => Attachment[];\n}\n\n/**\n * Hook that manages file attachment state — uploads, drag-and-drop, paste,\n * and lifecycle. All returned callbacks are referentially stable across\n * renders (via useCallback) to avoid destabilizing downstream memoization.\n */\nexport function useAttachments({\n config,\n}: UseAttachmentsProps): UseAttachmentsReturn {\n const enabled = config?.enabled ?? false;\n\n const [attachments, setAttachments] = useState<Attachment[]>([]);\n const [dragOver, setDragOver] = useState(false);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Keep refs to the latest values so stable callbacks can read current\n // state without appearing in dependency arrays.\n const configRef = useRef(config);\n configRef.current = config;\n const attachmentsRef = useRef<Attachment[]>([]);\n attachmentsRef.current = attachments;\n\n // Stable processFiles — reads config from ref, never changes identity\n const processFiles = useCallback(async (files: File[]) => {\n const cfg = configRef.current;\n const accept = cfg?.accept ?? \"*/*\";\n const maxSize = cfg?.maxSize ?? 20 * 1024 * 1024;\n\n const rejectedFiles = files.filter(\n (file) => !matchesAcceptFilter(file, accept),\n );\n for (const file of rejectedFiles) {\n cfg?.onUploadFailed?.({\n reason: \"invalid-type\",\n file,\n message: `File \"${file.name}\" is not accepted. Supported types: ${accept}`,\n });\n }\n\n const validFiles = files.filter((file) =>\n matchesAcceptFilter(file, accept),\n );\n\n for (const file of validFiles) {\n if (exceedsMaxSize(file, maxSize)) {\n cfg?.onUploadFailed?.({\n reason: \"file-too-large\",\n file,\n message: `File \"${file.name}\" exceeds the maximum size of ${formatFileSize(maxSize)}`,\n });\n continue;\n }\n\n const modality = getModalityFromMimeType(file.type);\n const placeholderId = randomUUID();\n const placeholder: Attachment = {\n id: placeholderId,\n type: modality,\n source: { type: \"data\", value: \"\", mimeType: file.type },\n filename: file.name,\n size: file.size,\n status: \"uploading\",\n };\n\n setAttachments((prev) => [...prev, placeholder]);\n\n try {\n let source: Attachment[\"source\"];\n let uploadMetadata: Record<string, unknown> | undefined;\n\n if (cfg?.onUpload) {\n const { metadata: meta, ...uploadSource } = await cfg.onUpload(file);\n source = uploadSource;\n uploadMetadata = meta;\n } else {\n const base64 = await readFileAsBase64(file);\n source = { type: \"data\", value: base64, mimeType: file.type };\n }\n\n let thumbnail: string | undefined;\n if (modality === \"video\") {\n thumbnail = await generateVideoThumbnail(file);\n }\n\n setAttachments((prev) =>\n prev.map((att) =>\n att.id === placeholderId\n ? {\n ...att,\n source,\n status: \"ready\" as const,\n thumbnail,\n metadata: uploadMetadata,\n }\n : att,\n ),\n );\n } catch (error) {\n setAttachments((prev) =>\n prev.filter((att) => att.id !== placeholderId),\n );\n console.error(`[CopilotKit] Failed to upload \"${file.name}\":`, error);\n cfg?.onUploadFailed?.({\n reason: \"upload-failed\",\n file,\n message:\n error instanceof Error\n ? error.message\n : `Failed to upload \"${file.name}\"`,\n });\n }\n }\n }, []);\n\n const handleFileUpload = useCallback(\n async (e: React.ChangeEvent<HTMLInputElement>) => {\n if (!e.target.files?.length) return;\n try {\n await processFiles(Array.from(e.target.files));\n } catch (error) {\n console.error(\"[CopilotKit] Upload error:\", error);\n }\n },\n [processFiles],\n );\n\n const handleDragOver = useCallback((e: React.DragEvent) => {\n if (!configRef.current?.enabled) return;\n e.preventDefault();\n e.stopPropagation();\n setDragOver(true);\n }, []);\n\n const handleDragLeave = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setDragOver(false);\n }, []);\n\n const handleDrop = useCallback(\n async (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setDragOver(false);\n if (!configRef.current?.enabled) return;\n\n const files = Array.from(e.dataTransfer.files);\n if (files.length > 0) {\n try {\n await processFiles(files);\n } catch (error) {\n console.error(\"[CopilotKit] Drop error:\", error);\n }\n }\n },\n [processFiles],\n );\n\n // Clipboard paste handler — scoped to the container\n useEffect(() => {\n if (!enabled) return;\n\n const handlePaste = async (e: ClipboardEvent) => {\n const target = e.target as HTMLElement | null;\n if (!target || !containerRef.current?.contains(target)) return;\n\n const accept = configRef.current?.accept ?? \"*/*\";\n const items = Array.from(e.clipboardData?.items || []);\n const fileItems = items.filter(\n (item) =>\n item.kind === \"file\" &&\n item.getAsFile() !== null &&\n matchesAcceptFilter(item.getAsFile()!, accept),\n );\n\n if (fileItems.length === 0) return;\n e.preventDefault();\n\n const files = fileItems\n .map((item) => item.getAsFile())\n .filter((f): f is File => f !== null);\n\n try {\n await processFiles(files);\n } catch (error) {\n console.error(\"[CopilotKit] Paste error:\", error);\n }\n };\n\n document.addEventListener(\"paste\", handlePaste);\n return () => document.removeEventListener(\"paste\", handlePaste);\n }, [enabled, processFiles]);\n\n const removeAttachment = useCallback((id: string) => {\n setAttachments((prev) => prev.filter((a) => a.id !== id));\n }, []);\n\n const consumeAttachments = useCallback(() => {\n const ready = attachmentsRef.current.filter((a) => a.status === \"ready\");\n if (ready.length === 0) return ready;\n setAttachments((prev) => prev.filter((a) => a.status !== \"ready\"));\n if (fileInputRef.current) {\n fileInputRef.current.value = \"\";\n }\n return ready;\n }, []);\n\n return {\n attachments,\n enabled,\n dragOver,\n fileInputRef,\n containerRef,\n processFiles,\n handleFileUpload,\n handleDragOver,\n handleDragLeave,\n handleDrop,\n removeAttachment,\n consumeAttachments,\n };\n}\n","import { useRenderToolCall } from \"../../hooks\";\nimport type { AssistantMessage, Message, ToolMessage } from \"@ag-ui/core\";\nimport React from \"react\";\n\nexport type CopilotChatToolCallsViewProps = {\n message: AssistantMessage;\n messages?: Message[];\n};\n\nexport function CopilotChatToolCallsView({\n message,\n messages = [],\n}: CopilotChatToolCallsViewProps) {\n const renderToolCall = useRenderToolCall();\n\n if (!message.toolCalls || message.toolCalls.length === 0) {\n return null;\n }\n\n return (\n <>\n {message.toolCalls.map((toolCall) => {\n const toolMessage = messages.find(\n (m) => m.role === \"tool\" && m.toolCallId === toolCall.id,\n ) as ToolMessage | undefined;\n\n return (\n <React.Fragment key={toolCall.id}>\n {renderToolCall({\n toolCall,\n toolMessage,\n })}\n </React.Fragment>\n );\n })}\n </>\n );\n}\n\nexport default CopilotChatToolCallsView;\n","import { AssistantMessage, Message } from \"@ag-ui/core\";\nimport { useEffect, useRef, useState } from \"react\";\nimport {\n Copy,\n Check,\n ThumbsUp,\n ThumbsDown,\n Volume2,\n RefreshCw,\n} from \"lucide-react\";\nimport {\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"../../providers/CopilotChatConfigurationProvider\";\nimport { twMerge } from \"tailwind-merge\";\nimport { Button } from \"../../components/ui/button\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"../../components/ui/tooltip\";\nimport { useKatexStyles } from \"../../hooks/useKatexStyles\";\nimport { WithSlots, renderSlot } from \"../../lib/slots\";\nimport { Streamdown } from \"streamdown\";\nimport CopilotChatToolCallsView from \"./CopilotChatToolCallsView\";\n\nexport type CopilotChatAssistantMessageProps = WithSlots<\n {\n markdownRenderer: typeof CopilotChatAssistantMessage.MarkdownRenderer;\n toolbar: typeof CopilotChatAssistantMessage.Toolbar;\n copyButton: typeof CopilotChatAssistantMessage.CopyButton;\n thumbsUpButton: typeof CopilotChatAssistantMessage.ThumbsUpButton;\n thumbsDownButton: typeof CopilotChatAssistantMessage.ThumbsDownButton;\n readAloudButton: typeof CopilotChatAssistantMessage.ReadAloudButton;\n regenerateButton: typeof CopilotChatAssistantMessage.RegenerateButton;\n toolCallsView: typeof CopilotChatToolCallsView;\n },\n {\n onThumbsUp?: (message: AssistantMessage) => void;\n onThumbsDown?: (message: AssistantMessage) => void;\n onReadAloud?: (message: AssistantMessage) => void;\n onRegenerate?: (message: AssistantMessage) => void;\n message: AssistantMessage;\n messages?: Message[];\n isRunning?: boolean;\n additionalToolbarItems?: React.ReactNode;\n toolbarVisible?: boolean;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\nexport function CopilotChatAssistantMessage({\n message,\n messages,\n isRunning,\n onThumbsUp,\n onThumbsDown,\n onReadAloud,\n onRegenerate,\n additionalToolbarItems,\n toolbarVisible = true,\n markdownRenderer,\n toolbar,\n copyButton,\n thumbsUpButton,\n thumbsDownButton,\n readAloudButton,\n regenerateButton,\n toolCallsView,\n children,\n className,\n ...props\n}: CopilotChatAssistantMessageProps) {\n useKatexStyles();\n\n const boundMarkdownRenderer = renderSlot(\n markdownRenderer,\n CopilotChatAssistantMessage.MarkdownRenderer,\n {\n content: message.content || \"\",\n },\n );\n\n const boundCopyButton = renderSlot(\n copyButton,\n CopilotChatAssistantMessage.CopyButton,\n {\n onClick: async () => {\n if (message.content) {\n try {\n await navigator.clipboard.writeText(message.content);\n } catch (err) {\n console.error(\"Failed to copy message:\", err);\n }\n }\n },\n },\n );\n\n const boundThumbsUpButton = renderSlot(\n thumbsUpButton,\n CopilotChatAssistantMessage.ThumbsUpButton,\n {\n onClick: onThumbsUp,\n },\n );\n\n const boundThumbsDownButton = renderSlot(\n thumbsDownButton,\n CopilotChatAssistantMessage.ThumbsDownButton,\n {\n onClick: onThumbsDown,\n },\n );\n\n const boundReadAloudButton = renderSlot(\n readAloudButton,\n CopilotChatAssistantMessage.ReadAloudButton,\n {\n onClick: onReadAloud,\n },\n );\n\n const boundRegenerateButton = renderSlot(\n regenerateButton,\n CopilotChatAssistantMessage.RegenerateButton,\n {\n onClick: onRegenerate,\n },\n );\n\n const boundToolbar = renderSlot(\n toolbar,\n CopilotChatAssistantMessage.Toolbar,\n {\n children: (\n <div className=\"cpk:flex cpk:items-center cpk:gap-1\">\n {boundCopyButton}\n {(onThumbsUp || thumbsUpButton) && boundThumbsUpButton}\n {(onThumbsDown || thumbsDownButton) && boundThumbsDownButton}\n {(onReadAloud || readAloudButton) && boundReadAloudButton}\n {(onRegenerate || regenerateButton) && boundRegenerateButton}\n {additionalToolbarItems}\n </div>\n ),\n },\n );\n\n const boundToolCallsView = renderSlot(\n toolCallsView,\n CopilotChatToolCallsView,\n {\n message,\n messages,\n },\n );\n\n // Don't show toolbar if message has no content (only tool calls)\n const hasContent = !!(message.content && message.content.trim().length > 0);\n const isLatestAssistantMessage =\n message.role === \"assistant\" &&\n messages?.[messages.length - 1]?.id === message.id;\n const shouldShowToolbar =\n toolbarVisible && hasContent && !(isRunning && isLatestAssistantMessage);\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n markdownRenderer: boundMarkdownRenderer,\n toolbar: boundToolbar,\n toolCallsView: boundToolCallsView,\n copyButton: boundCopyButton,\n thumbsUpButton: boundThumbsUpButton,\n thumbsDownButton: boundThumbsDownButton,\n readAloudButton: boundReadAloudButton,\n regenerateButton: boundRegenerateButton,\n message,\n messages,\n isRunning,\n onThumbsUp,\n onThumbsDown,\n onReadAloud,\n onRegenerate,\n additionalToolbarItems,\n toolbarVisible: shouldShowToolbar,\n })}\n </div>\n );\n }\n\n return (\n <div\n data-copilotkit\n data-testid=\"copilot-assistant-message\"\n className={twMerge(\n \"copilotKitMessage copilotKitAssistantMessage\",\n className,\n )}\n {...props}\n data-message-id={message.id}\n >\n <div className=\"cpk:prose cpk:max-w-full cpk:break-words cpk:dark:prose-invert\">\n {boundMarkdownRenderer}\n </div>\n {boundToolCallsView}\n {shouldShowToolbar && boundToolbar}\n </div>\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotChatAssistantMessage {\n export const MarkdownRenderer: React.FC<\n Omit<React.ComponentProps<typeof Streamdown>, \"children\"> & {\n content: string;\n }\n > = ({ content, className, ...props }) => (\n <Streamdown className={className} {...props}>\n {content ?? \"\"}\n </Streamdown>\n );\n\n export const Toolbar: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n className,\n ...props\n }) => (\n <div\n data-testid=\"copilot-assistant-toolbar\"\n className={twMerge(\n \"cpk:w-full cpk:bg-transparent cpk:flex cpk:items-center cpk:-ml-[5px] cpk:-mt-[0px]\",\n className,\n )}\n {...props}\n />\n );\n\n export const ToolbarButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & {\n title: string;\n children: React.ReactNode;\n }\n > = ({ title, children, ...props }) => {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"assistantMessageToolbarButton\"\n aria-label={title}\n {...props}\n >\n {children}\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">\n <p>{title}</p>\n </TooltipContent>\n </Tooltip>\n );\n };\n\n export const CopyButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, title, onClick, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n const [copied, setCopied] = useState(false);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n return () => {\n if (timerRef.current !== null) {\n clearTimeout(timerRef.current);\n }\n };\n }, []);\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n setCopied(true);\n if (timerRef.current !== null) {\n clearTimeout(timerRef.current);\n }\n timerRef.current = setTimeout(() => {\n timerRef.current = null;\n setCopied(false);\n }, 2000);\n\n if (onClick) {\n onClick(event);\n }\n };\n\n return (\n <ToolbarButton\n data-testid=\"copilot-copy-button\"\n title={title || labels.assistantMessageToolbarCopyMessageLabel}\n onClick={handleClick}\n className={className}\n {...props}\n >\n {copied ? (\n <Check className=\"cpk:size-[18px]\" />\n ) : (\n <Copy className=\"cpk:size-[18px]\" />\n )}\n </ToolbarButton>\n );\n };\n\n export const ThumbsUpButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-thumbs-up-button\"\n title={title || labels.assistantMessageToolbarThumbsUpLabel}\n {...props}\n >\n <ThumbsUp className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n\n export const ThumbsDownButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-thumbs-down-button\"\n title={title || labels.assistantMessageToolbarThumbsDownLabel}\n {...props}\n >\n <ThumbsDown className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n\n export const ReadAloudButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-read-aloud-button\"\n title={title || labels.assistantMessageToolbarReadAloudLabel}\n {...props}\n >\n <Volume2 className=\"cpk:size-[20px]\" />\n </ToolbarButton>\n );\n };\n\n export const RegenerateButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-regenerate-button\"\n title={title || labels.assistantMessageToolbarRegenerateLabel}\n {...props}\n >\n <RefreshCw className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n}\n\nCopilotChatAssistantMessage.MarkdownRenderer.displayName =\n \"CopilotChatAssistantMessage.MarkdownRenderer\";\nCopilotChatAssistantMessage.Toolbar.displayName =\n \"CopilotChatAssistantMessage.Toolbar\";\nCopilotChatAssistantMessage.CopyButton.displayName =\n \"CopilotChatAssistantMessage.CopyButton\";\nCopilotChatAssistantMessage.ThumbsUpButton.displayName =\n \"CopilotChatAssistantMessage.ThumbsUpButton\";\nCopilotChatAssistantMessage.ThumbsDownButton.displayName =\n \"CopilotChatAssistantMessage.ThumbsDownButton\";\nCopilotChatAssistantMessage.ReadAloudButton.displayName =\n \"CopilotChatAssistantMessage.ReadAloudButton\";\nCopilotChatAssistantMessage.RegenerateButton.displayName =\n \"CopilotChatAssistantMessage.RegenerateButton\";\n\nexport default CopilotChatAssistantMessage;\n","import React, { memo, useState } from \"react\";\nimport type { InputContentSource } from \"@copilotkit/shared\";\nimport { getSourceUrl, getDocumentIcon } from \"@copilotkit/shared\";\nimport { cn } from \"../../lib/utils\";\n\ninterface CopilotChatAttachmentRendererProps {\n type: \"image\" | \"audio\" | \"video\" | \"document\";\n source: InputContentSource;\n filename?: string;\n className?: string;\n}\n\nconst ImageAttachment = memo(function ImageAttachment({\n src,\n className,\n}: {\n src: string;\n className?: string;\n}) {\n const [error, setError] = useState(false);\n\n if (error) {\n return (\n <div\n className={cn(\n \"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\",\n className,\n )}\n >\n <span>Failed to load image</span>\n </div>\n );\n }\n\n return (\n <img\n src={src}\n alt=\"Image attachment\"\n className={cn(\"cpk:max-w-full cpk:h-auto cpk:rounded-lg\", className)}\n onError={() => setError(true)}\n />\n );\n});\n\nconst AudioAttachment = memo(function AudioAttachment({\n src,\n filename,\n className,\n}: {\n src: string;\n filename?: string;\n className?: string;\n}) {\n return (\n <div className={cn(\"cpk:flex cpk:flex-col cpk:gap-1\", className)}>\n <audio\n src={src}\n controls\n preload=\"metadata\"\n className=\"cpk:max-w-[300px] cpk:w-full cpk:h-10\"\n />\n {filename && (\n <span className=\"cpk:text-xs cpk:text-muted-foreground cpk:truncate cpk:max-w-[300px]\">\n {filename}\n </span>\n )}\n </div>\n );\n});\n\nconst VideoAttachment = memo(function VideoAttachment({\n src,\n className,\n}: {\n src: string;\n className?: string;\n}) {\n return (\n <video\n src={src}\n controls\n preload=\"metadata\"\n className={cn(\"cpk:max-w-[400px] cpk:w-full cpk:rounded-lg\", className)}\n />\n );\n});\n\nconst DocumentAttachment = memo(function DocumentAttachment({\n source,\n filename,\n className,\n}: {\n source: InputContentSource;\n filename?: string;\n className?: string;\n}) {\n return (\n <div\n className={cn(\n \"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\",\n className,\n )}\n >\n <span className=\"cpk:text-xs cpk:font-bold cpk:uppercase\">\n {getDocumentIcon(source.mimeType ?? \"\")}\n </span>\n <span className=\"cpk:text-sm cpk:text-muted-foreground cpk:truncate\">\n {filename || source.mimeType || \"Unknown type\"}\n </span>\n </div>\n );\n});\n\nexport const CopilotChatAttachmentRenderer: React.FC<\n CopilotChatAttachmentRendererProps\n> = ({ type, source, filename, className }) => {\n const src = getSourceUrl(source);\n\n switch (type) {\n case \"image\":\n return <ImageAttachment src={src} className={className} />;\n case \"audio\":\n return (\n <AudioAttachment src={src} filename={filename} className={className} />\n );\n case \"video\":\n return <VideoAttachment src={src} className={className} />;\n case \"document\":\n return (\n <DocumentAttachment\n source={source}\n filename={filename}\n className={className}\n />\n );\n }\n};\n\nexport default CopilotChatAttachmentRenderer;\n","import { useMemo, useState } from \"react\";\nimport { Copy, Check, Edit, ChevronLeft, ChevronRight } from \"lucide-react\";\nimport {\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"../../providers/CopilotChatConfigurationProvider\";\nimport { twMerge } from \"tailwind-merge\";\nimport { Button } from \"../../components/ui/button\";\nimport { UserMessage } from \"@ag-ui/core\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"../../components/ui/tooltip\";\nimport { renderSlot, WithSlots } from \"../../lib/slots\";\nimport {\n type ImageInputPart,\n type AudioInputPart,\n type VideoInputPart,\n type DocumentInputPart,\n} from \"@copilotkit/shared\";\nimport { CopilotChatAttachmentRenderer } from \"./CopilotChatAttachmentRenderer\";\n\nfunction flattenUserMessageContent(content?: UserMessage[\"content\"]): string {\n if (!content) {\n return \"\";\n }\n\n if (typeof content === \"string\") {\n return content;\n }\n\n return content\n .map((part) => {\n if (\n part &&\n typeof part === \"object\" &&\n \"type\" in part &&\n (part as { type?: unknown }).type === \"text\" &&\n typeof (part as { text?: unknown }).text === \"string\"\n ) {\n return (part as { text: string }).text;\n }\n return \"\";\n })\n .filter((text) => text.length > 0)\n .join(\"\\n\");\n}\n\ntype MediaPart =\n | ImageInputPart\n | AudioInputPart\n | VideoInputPart\n | DocumentInputPart;\n\nfunction getMediaParts(content: UserMessage[\"content\"]): MediaPart[] {\n if (!content || typeof content === \"string\") return [];\n return content.filter(\n (part): part is MediaPart =>\n part.type === \"image\" ||\n part.type === \"audio\" ||\n part.type === \"video\" ||\n part.type === \"document\",\n );\n}\n\nfunction getFilename(part: MediaPart): string | undefined {\n const meta = part.metadata;\n if (\n meta != null &&\n typeof meta === \"object\" &&\n \"filename\" in meta &&\n typeof meta.filename === \"string\"\n ) {\n return meta.filename;\n }\n return undefined;\n}\n\nexport interface CopilotChatUserMessageOnEditMessageProps {\n message: UserMessage;\n}\n\nexport interface CopilotChatUserMessageOnSwitchToBranchProps {\n message: UserMessage;\n branchIndex: number;\n numberOfBranches: number;\n}\n\nexport type CopilotChatUserMessageProps = WithSlots<\n {\n messageRenderer: typeof CopilotChatUserMessage.MessageRenderer;\n toolbar: typeof CopilotChatUserMessage.Toolbar;\n copyButton: typeof CopilotChatUserMessage.CopyButton;\n editButton: typeof CopilotChatUserMessage.EditButton;\n branchNavigation: typeof CopilotChatUserMessage.BranchNavigation;\n },\n {\n onEditMessage?: (props: CopilotChatUserMessageOnEditMessageProps) => void;\n onSwitchToBranch?: (\n props: CopilotChatUserMessageOnSwitchToBranchProps,\n ) => void;\n message: UserMessage;\n branchIndex?: number;\n numberOfBranches?: number;\n additionalToolbarItems?: React.ReactNode;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\nexport function CopilotChatUserMessage({\n message,\n onEditMessage,\n branchIndex,\n numberOfBranches,\n onSwitchToBranch,\n additionalToolbarItems,\n messageRenderer,\n toolbar,\n copyButton,\n editButton,\n branchNavigation,\n children,\n className,\n ...props\n}: CopilotChatUserMessageProps) {\n const flattenedContent = useMemo(\n () => flattenUserMessageContent(message.content),\n [message.content],\n );\n\n const mediaParts = useMemo(\n () => getMediaParts(message.content),\n [message.content],\n );\n\n const BoundMessageRenderer = renderSlot(\n messageRenderer,\n CopilotChatUserMessage.MessageRenderer,\n {\n content: flattenedContent,\n },\n );\n\n const BoundCopyButton = renderSlot(\n copyButton,\n CopilotChatUserMessage.CopyButton,\n {\n onClick: async () => {\n if (flattenedContent) {\n try {\n await navigator.clipboard.writeText(flattenedContent);\n } catch (err) {\n console.error(\"Failed to copy message:\", err);\n }\n }\n },\n },\n );\n\n const BoundEditButton = renderSlot(\n editButton,\n CopilotChatUserMessage.EditButton,\n {\n onClick: () => onEditMessage?.({ message }),\n },\n );\n\n const BoundBranchNavigation = renderSlot(\n branchNavigation,\n CopilotChatUserMessage.BranchNavigation,\n {\n currentBranch: branchIndex,\n numberOfBranches,\n onSwitchToBranch,\n message,\n },\n );\n\n const showBranchNavigation =\n numberOfBranches && numberOfBranches > 1 && onSwitchToBranch;\n\n const BoundToolbar = renderSlot(toolbar, CopilotChatUserMessage.Toolbar, {\n children: (\n <div className=\"cpk:flex cpk:items-center cpk:gap-1 cpk:justify-end\">\n {additionalToolbarItems}\n {BoundCopyButton}\n {onEditMessage && BoundEditButton}\n {showBranchNavigation && BoundBranchNavigation}\n </div>\n ),\n });\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n messageRenderer: BoundMessageRenderer,\n toolbar: BoundToolbar,\n copyButton: BoundCopyButton,\n editButton: BoundEditButton,\n branchNavigation: BoundBranchNavigation,\n message,\n branchIndex,\n numberOfBranches,\n additionalToolbarItems,\n })}\n </div>\n );\n }\n\n return (\n <div\n data-copilotkit\n data-testid=\"copilot-user-message\"\n className={twMerge(\n \"copilotKitMessage copilotKitUserMessage cpk:flex cpk:flex-col cpk:items-end cpk:group cpk:pt-10\",\n className,\n )}\n data-message-id={message.id}\n {...props}\n >\n {BoundMessageRenderer}\n {mediaParts.length > 0 && (\n <div className=\"cpk:flex cpk:flex-col cpk:items-end cpk:gap-2 cpk:mt-2\">\n {mediaParts.map((part, index) => (\n <CopilotChatAttachmentRenderer\n key={index}\n type={part.type}\n source={part.source}\n filename={getFilename(part)}\n />\n ))}\n </div>\n )}\n {BoundToolbar}\n </div>\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotChatUserMessage {\n export const Container: React.FC<\n React.PropsWithChildren<React.HTMLAttributes<HTMLDivElement>>\n > = ({ children, className, ...props }) => (\n <div\n className={twMerge(\n \"cpk:flex cpk:flex-col cpk:items-end cpk:group\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n );\n\n export const MessageRenderer: React.FC<{\n content: string;\n className?: string;\n }> = ({ content, className }) => (\n <div\n className={twMerge(\n \"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\",\n className,\n )}\n >\n {content}\n </div>\n );\n\n export const Toolbar: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n className,\n ...props\n }) => (\n <div\n data-testid=\"copilot-user-toolbar\"\n className={twMerge(\n \"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\",\n className,\n )}\n {...props}\n />\n );\n\n export const ToolbarButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & {\n title: string;\n children: React.ReactNode;\n }\n > = ({ title, children, className, ...props }) => {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"assistantMessageToolbarButton\"\n aria-label={title}\n className={twMerge(className)}\n {...props}\n >\n {children}\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">\n <p>{title}</p>\n </TooltipContent>\n </Tooltip>\n );\n };\n\n export const CopyButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & { copied?: boolean }\n > = ({ className, title, onClick, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n const [copied, setCopied] = useState(false);\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n\n if (onClick) {\n onClick(event);\n }\n };\n\n return (\n <ToolbarButton\n data-testid=\"copilot-user-copy-button\"\n title={title || labels.userMessageToolbarCopyMessageLabel}\n onClick={handleClick}\n className={className}\n {...props}\n >\n {copied ? (\n <Check className=\"cpk:size-[18px]\" />\n ) : (\n <Copy className=\"cpk:size-[18px]\" />\n )}\n </ToolbarButton>\n );\n };\n\n export const EditButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-edit-button\"\n title={title || labels.userMessageToolbarEditMessageLabel}\n className={className}\n {...props}\n >\n <Edit className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n\n export const BranchNavigation: React.FC<\n React.HTMLAttributes<HTMLDivElement> & {\n currentBranch?: number;\n numberOfBranches?: number;\n onSwitchToBranch?: (\n props: CopilotChatUserMessageOnSwitchToBranchProps,\n ) => void;\n message: UserMessage;\n }\n > = ({\n className,\n currentBranch = 0,\n numberOfBranches = 1,\n onSwitchToBranch,\n message,\n ...props\n }) => {\n if (!numberOfBranches || numberOfBranches <= 1 || !onSwitchToBranch) {\n return null;\n }\n\n const canGoPrev = currentBranch > 0;\n const canGoNext = currentBranch < numberOfBranches - 1;\n\n return (\n <div\n data-testid=\"copilot-branch-navigation\"\n className={twMerge(\"cpk:flex cpk:items-center cpk:gap-1\", className)}\n {...props}\n >\n <Button\n type=\"button\"\n variant=\"assistantMessageToolbarButton\"\n onClick={() =>\n onSwitchToBranch?.({\n branchIndex: currentBranch - 1,\n numberOfBranches,\n message,\n })\n }\n disabled={!canGoPrev}\n className=\"cpk:h-6 cpk:w-6 cpk:p-0\"\n >\n <ChevronLeft className=\"cpk:size-[20px]\" />\n </Button>\n <span className=\"cpk:text-sm cpk:text-muted-foreground cpk:px-0 cpk:font-medium\">\n {currentBranch + 1}/{numberOfBranches}\n </span>\n <Button\n type=\"button\"\n variant=\"assistantMessageToolbarButton\"\n onClick={() =>\n onSwitchToBranch?.({\n branchIndex: currentBranch + 1,\n numberOfBranches,\n message,\n })\n }\n disabled={!canGoNext}\n className=\"cpk:h-6 cpk:w-6 cpk:p-0\"\n >\n <ChevronRight className=\"cpk:size-[20px]\" />\n </Button>\n </div>\n );\n };\n}\n\nCopilotChatUserMessage.Container.displayName =\n \"CopilotChatUserMessage.Container\";\nCopilotChatUserMessage.MessageRenderer.displayName =\n \"CopilotChatUserMessage.MessageRenderer\";\nCopilotChatUserMessage.Toolbar.displayName = \"CopilotChatUserMessage.Toolbar\";\nCopilotChatUserMessage.ToolbarButton.displayName =\n \"CopilotChatUserMessage.ToolbarButton\";\nCopilotChatUserMessage.CopyButton.displayName =\n \"CopilotChatUserMessage.CopyButton\";\nCopilotChatUserMessage.EditButton.displayName =\n \"CopilotChatUserMessage.EditButton\";\nCopilotChatUserMessage.BranchNavigation.displayName =\n \"CopilotChatUserMessage.BranchNavigation\";\n\nexport default CopilotChatUserMessage;\n","import { ReasoningMessage, Message } from \"@ag-ui/core\";\nimport { useState, useEffect, useRef } from \"react\";\nimport { ChevronRight } from \"lucide-react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { Streamdown } from \"streamdown\";\nimport { WithSlots, renderSlot } from \"../../lib/slots\";\n\nexport type CopilotChatReasoningMessageProps = WithSlots<\n {\n header: typeof CopilotChatReasoningMessage.Header;\n contentView: typeof CopilotChatReasoningMessage.Content;\n toggle: typeof CopilotChatReasoningMessage.Toggle;\n },\n {\n message: ReasoningMessage;\n messages?: Message[];\n isRunning?: boolean;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\n/**\n * Formats an elapsed duration (in seconds) to a human-readable string.\n */\nfunction formatDuration(seconds: number): string {\n if (seconds < 1) return \"a few seconds\";\n if (seconds < 60) return `${Math.round(seconds)} seconds`;\n const mins = Math.floor(seconds / 60);\n const secs = Math.round(seconds % 60);\n if (secs === 0) return `${mins} minute${mins > 1 ? \"s\" : \"\"}`;\n return `${mins}m ${secs}s`;\n}\n\nexport function CopilotChatReasoningMessage({\n message,\n messages,\n isRunning,\n header,\n contentView,\n toggle,\n children,\n className,\n ...props\n}: CopilotChatReasoningMessageProps) {\n const isLatest = messages?.[messages.length - 1]?.id === message.id;\n const isStreaming = !!(isRunning && isLatest);\n const hasContent = !!(message.content && message.content.length > 0);\n\n // Track elapsed time while streaming\n const startTimeRef = useRef<number | null>(null);\n const [elapsed, setElapsed] = useState(0);\n\n useEffect(() => {\n if (isStreaming && startTimeRef.current === null) {\n startTimeRef.current = Date.now();\n }\n\n if (!isStreaming && startTimeRef.current !== null) {\n // Final snapshot of elapsed time\n setElapsed((Date.now() - startTimeRef.current) / 1000);\n return;\n }\n\n if (!isStreaming) return;\n\n // Tick every second while streaming\n const timer = setInterval(() => {\n if (startTimeRef.current !== null) {\n setElapsed((Date.now() - startTimeRef.current) / 1000);\n }\n }, 1000);\n return () => clearInterval(timer);\n }, [isStreaming]);\n\n // Default to open while streaming, auto-collapse when streaming ends\n const [isOpen, setIsOpen] = useState(isStreaming);\n\n useEffect(() => {\n if (isStreaming) {\n setIsOpen(true);\n } else {\n // Auto-collapse when reasoning finishes\n setIsOpen(false);\n }\n }, [isStreaming]);\n\n const label = isStreaming\n ? \"Thinking…\"\n : `Thought for ${formatDuration(elapsed)}`;\n\n const boundHeader = renderSlot(header, CopilotChatReasoningMessage.Header, {\n isOpen,\n label,\n hasContent,\n isStreaming,\n onClick: hasContent ? () => setIsOpen((prev) => !prev) : undefined,\n });\n\n const boundContent = renderSlot(\n contentView,\n CopilotChatReasoningMessage.Content,\n {\n isStreaming,\n hasContent,\n children: message.content,\n },\n );\n\n const boundToggle = renderSlot(toggle, CopilotChatReasoningMessage.Toggle, {\n isOpen,\n children: boundContent,\n });\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n header: boundHeader,\n contentView: boundContent,\n toggle: boundToggle,\n message,\n messages,\n isRunning,\n })}\n </div>\n );\n }\n\n return (\n <div\n className={twMerge(\"cpk:my-1\", className)}\n data-message-id={message.id}\n {...props}\n >\n {boundHeader}\n {boundToggle}\n </div>\n );\n}\n\nexport namespace CopilotChatReasoningMessage {\n export const Header: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & {\n isOpen?: boolean;\n label?: string;\n hasContent?: boolean;\n isStreaming?: boolean;\n }\n > = ({\n isOpen,\n label = \"Thoughts\",\n hasContent,\n isStreaming,\n className,\n children: headerChildren,\n ...headerProps\n }) => {\n const isExpandable = !!hasContent;\n\n return (\n <button\n type=\"button\"\n className={twMerge(\n \"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\",\n isExpandable\n ? \"cpk:hover:text-foreground cpk:cursor-pointer\"\n : \"cpk:cursor-default\",\n className,\n )}\n aria-expanded={isExpandable ? isOpen : undefined}\n {...headerProps}\n >\n <span className=\"cpk:font-medium\">{label}</span>\n {isStreaming && !hasContent && (\n <span className=\"cpk:inline-flex cpk:items-center cpk:ml-1\">\n <span className=\"cpk:w-1.5 cpk:h-1.5 cpk:rounded-full cpk:bg-muted-foreground cpk:animate-pulse\" />\n </span>\n )}\n {headerChildren}\n {isExpandable && (\n <ChevronRight\n className={twMerge(\n \"cpk:size-3.5 cpk:shrink-0 cpk:transition-transform cpk:duration-200\",\n isOpen && \"cpk:rotate-90\",\n )}\n />\n )}\n </button>\n );\n };\n\n export const Content: React.FC<\n React.HTMLAttributes<HTMLDivElement> & {\n isStreaming?: boolean;\n hasContent?: boolean;\n }\n > = ({\n isStreaming,\n hasContent,\n className,\n children: contentChildren,\n ...contentProps\n }) => {\n // Don't render the content area at all when there's nothing to show\n if (!hasContent && !isStreaming) return null;\n\n return (\n <div\n className={twMerge(\"cpk:pb-2 cpk:pt-1\", className)}\n {...contentProps}\n >\n <div className=\"cpk:text-sm cpk:text-muted-foreground\">\n <Streamdown>\n {typeof contentChildren === \"string\" ? contentChildren : \"\"}\n </Streamdown>\n {isStreaming && hasContent && (\n <span className=\"cpk:inline-flex cpk:items-center cpk:ml-1 cpk:align-middle\">\n <span className=\"cpk:w-2 cpk:h-2 cpk:rounded-full cpk:bg-muted-foreground cpk:animate-pulse-cursor\" />\n </span>\n )}\n </div>\n </div>\n );\n };\n\n export const Toggle: React.FC<\n React.HTMLAttributes<HTMLDivElement> & {\n isOpen?: boolean;\n }\n > = ({ isOpen, className, children: toggleChildren, ...toggleProps }) => {\n return (\n <div\n className={twMerge(\n \"cpk:grid cpk:transition-[grid-template-rows] cpk:duration-200 cpk:ease-in-out\",\n className,\n )}\n style={{ gridTemplateRows: isOpen ? \"1fr\" : \"0fr\" }}\n {...toggleProps}\n >\n <div className=\"cpk:overflow-hidden\">{toggleChildren}</div>\n </div>\n );\n };\n}\n\nCopilotChatReasoningMessage.Header.displayName =\n \"CopilotChatReasoningMessage.Header\";\nCopilotChatReasoningMessage.Content.displayName =\n \"CopilotChatReasoningMessage.Content\";\nCopilotChatReasoningMessage.Toggle.displayName =\n \"CopilotChatReasoningMessage.Toggle\";\n\nexport default CopilotChatReasoningMessage;\n","import React from \"react\";\nimport { Loader2 } from \"lucide-react\";\nimport { cn } from \"../../lib/utils\";\n\nexport interface CopilotChatSuggestionPillProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Optional icon to render on the left side when not loading. */\n icon?: React.ReactNode;\n /** Whether the pill should display a loading spinner. */\n isLoading?: boolean;\n}\n\nconst baseClasses =\n \"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\";\n\nconst labelClasses = \"cpk:whitespace-nowrap cpk:font-medium cpk:leading-none\";\n\nexport const CopilotChatSuggestionPill = React.forwardRef<\n HTMLButtonElement,\n CopilotChatSuggestionPillProps\n>(function CopilotChatSuggestionPill(\n { className, children, icon, isLoading, type, ...props },\n ref,\n) {\n const showIcon = !isLoading && icon;\n\n return (\n <button\n ref={ref}\n data-copilotkit\n data-testid=\"copilot-suggestion\"\n data-slot=\"suggestion-pill\"\n className={cn(baseClasses, className)}\n type={type ?? \"button\"}\n aria-busy={isLoading || undefined}\n disabled={isLoading || props.disabled}\n {...props}\n >\n {isLoading ? (\n <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\">\n <Loader2\n className=\"cpk:h-3.5 cpk:sm:h-4 cpk:w-3.5 cpk:sm:w-4 cpk:animate-spin\"\n aria-hidden=\"true\"\n />\n </span>\n ) : (\n showIcon && (\n <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\">\n {icon}\n </span>\n )\n )}\n <span className={labelClasses}>{children}</span>\n </button>\n );\n});\n\nCopilotChatSuggestionPill.displayName = \"CopilotChatSuggestionPill\";\n\nexport default CopilotChatSuggestionPill;\n","import React from \"react\";\nimport { Suggestion } from \"@copilotkit/core\";\nimport { renderSlot, WithSlots } from \"../../lib/slots\";\nimport { cn } from \"../../lib/utils\";\nimport CopilotChatSuggestionPill, {\n CopilotChatSuggestionPillProps,\n} from \"./CopilotChatSuggestionPill\";\n\nconst DefaultContainer = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(function DefaultContainer({ className, ...props }, ref) {\n return (\n <div\n ref={ref}\n data-copilotkit\n data-testid=\"copilot-suggestions\"\n className={cn(\n \"cpk:flex cpk:flex-wrap cpk:items-center cpk:gap-1.5 cpk:sm:gap-2 cpk:pl-0 cpk:pr-4 cpk:sm:px-0 cpk:pointer-events-none\",\n className,\n )}\n {...props}\n />\n );\n});\n\nexport type CopilotChatSuggestionViewProps = WithSlots<\n {\n container: typeof DefaultContainer;\n suggestion: typeof CopilotChatSuggestionPill;\n },\n {\n suggestions: Suggestion[];\n onSelectSuggestion?: (suggestion: Suggestion, index: number) => void;\n loadingIndexes?: ReadonlyArray<number>;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\nexport const CopilotChatSuggestionView = React.forwardRef<\n HTMLDivElement,\n CopilotChatSuggestionViewProps\n>(function CopilotChatSuggestionView(\n {\n suggestions,\n onSelectSuggestion,\n loadingIndexes,\n container,\n suggestion: suggestionSlot,\n className,\n children,\n ...restProps\n },\n ref,\n) {\n const loadingSet = React.useMemo(() => {\n if (!loadingIndexes || loadingIndexes.length === 0) {\n return new Set<number>();\n }\n return new Set(loadingIndexes);\n }, [loadingIndexes]);\n\n const ContainerElement = renderSlot(container, DefaultContainer, {\n ref,\n className,\n ...restProps,\n });\n\n const suggestionElements = suggestions.map((suggestion, index) => {\n const isLoading = loadingSet.has(index) || suggestion.isLoading === true;\n const pill = renderSlot<\n typeof CopilotChatSuggestionPill,\n CopilotChatSuggestionPillProps\n >(suggestionSlot, CopilotChatSuggestionPill, {\n children: suggestion.title,\n className: suggestion.className,\n isLoading,\n type: \"button\",\n onClick: () => onSelectSuggestion?.(suggestion, index),\n });\n\n return React.cloneElement(pill, {\n key: `${suggestion.title}-${index}`,\n });\n });\n\n const boundContainer = React.cloneElement(\n ContainerElement,\n undefined,\n suggestionElements,\n );\n\n if (typeof children === \"function\") {\n const sampleSuggestion = renderSlot<\n typeof CopilotChatSuggestionPill,\n CopilotChatSuggestionPillProps\n >(suggestionSlot, CopilotChatSuggestionPill, {\n children: suggestions[0]?.title ?? \"\",\n isLoading:\n suggestions.length > 0\n ? loadingSet.has(0) || suggestions[0]?.isLoading === true\n : false,\n type: \"button\",\n });\n\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n container: boundContainer,\n suggestion: sampleSuggestion,\n suggestions,\n onSelectSuggestion,\n loadingIndexes,\n className,\n ...restProps,\n })}\n </div>\n );\n }\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {boundContainer}\n {children}\n </div>\n );\n }\n\n return boundContainer;\n});\n\nCopilotChatSuggestionView.displayName = \"CopilotChatSuggestionView\";\n\nexport default CopilotChatSuggestionView;\n","import React from \"react\";\n\n/**\n * Provides the scroll container element to child components that need it for\n * virtualization. Set by CopilotChatView.ScrollView; consumed by\n * CopilotChatMessageView to feed useVirtualizer's getScrollElement.\n *\n * Carries the element itself (not a ref) so that context consumers re-render\n * reactively when the scroll container is first mounted.\n */\nexport const ScrollElementContext = React.createContext<HTMLElement | null>(\n null,\n);\n","import React, {\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useReducer,\n useState,\n} from \"react\";\nimport { useVirtualizer } from \"@tanstack/react-virtual\";\nimport { ScrollElementContext } from \"./scroll-element-context\";\nimport { WithSlots, renderSlot, isReactComponentType } from \"../../lib/slots\";\nimport CopilotChatAssistantMessage from \"./CopilotChatAssistantMessage\";\nimport CopilotChatUserMessage from \"./CopilotChatUserMessage\";\nimport CopilotChatReasoningMessage from \"./CopilotChatReasoningMessage\";\nimport {\n ActivityMessage,\n AssistantMessage,\n Message,\n ReasoningMessage,\n ToolMessage,\n UserMessage,\n} from \"@ag-ui/core\";\nimport { twMerge } from \"tailwind-merge\";\nimport { useRenderActivityMessage, useRenderCustomMessages } from \"../../hooks\";\nimport { getThreadClone } from \"../../hooks/use-agent\";\nimport { useCopilotKit } from \"../../providers/CopilotKitProvider\";\nimport { useCopilotChatConfiguration } from \"../../providers/CopilotChatConfigurationProvider\";\n\n/**\n * Resolves a slot value into a { Component, slotProps } pair, handling the three\n * slot forms: a component type, a className string, or a partial-props object.\n */\nfunction resolveSlotComponent<T extends React.ComponentType<any>>(\n slot: unknown,\n DefaultComponent: T,\n): { Component: T; slotProps: Partial<React.ComponentProps<T>> | undefined } {\n if (isReactComponentType(slot)) {\n return { Component: slot as T, slotProps: undefined };\n }\n if (typeof slot === \"string\") {\n return {\n Component: DefaultComponent,\n slotProps: { className: slot } as unknown as Partial<\n React.ComponentProps<T>\n >,\n };\n }\n if (slot && typeof slot === \"object\") {\n return {\n Component: DefaultComponent,\n slotProps: slot as Partial<React.ComponentProps<T>>,\n };\n }\n return { Component: DefaultComponent, slotProps: undefined };\n}\n\n/**\n * Memoized wrapper for assistant messages to prevent re-renders when other messages change.\n */\nconst MemoizedAssistantMessage = React.memo(\n function MemoizedAssistantMessage({\n message,\n messages,\n isRunning,\n AssistantMessageComponent,\n slotProps,\n }: {\n message: AssistantMessage;\n messages: Message[];\n isRunning: boolean;\n AssistantMessageComponent: typeof CopilotChatAssistantMessage;\n slotProps?: Partial<\n React.ComponentProps<typeof CopilotChatAssistantMessage>\n >;\n }) {\n return (\n <AssistantMessageComponent\n message={message}\n messages={messages}\n isRunning={isRunning}\n {...slotProps}\n />\n );\n },\n (prevProps, nextProps) => {\n // Only re-render if this specific message changed\n if (prevProps.message.id !== nextProps.message.id) return false;\n if (prevProps.message.content !== nextProps.message.content) return false;\n\n // Compare tool calls if present\n const prevToolCalls = prevProps.message.toolCalls;\n const nextToolCalls = nextProps.message.toolCalls;\n if (prevToolCalls?.length !== nextToolCalls?.length) return false;\n if (prevToolCalls && nextToolCalls) {\n for (let i = 0; i < prevToolCalls.length; i++) {\n const prevTc = prevToolCalls[i]!;\n const nextTc = nextToolCalls[i]!;\n if (prevTc.id !== nextTc.id) return false;\n if (prevTc.function.arguments !== nextTc.function.arguments)\n return false;\n }\n }\n\n // Check if tool results changed for this message's tool calls.\n // Tool results are separate messages with role=\"tool\" that reference tool call IDs.\n if (prevToolCalls && prevToolCalls.length > 0) {\n const toolCallIds = new Set(prevToolCalls.map((tc) => tc.id));\n\n const prevToolResults = prevProps.messages.filter(\n (m): m is ToolMessage =>\n m.role === \"tool\" && toolCallIds.has(m.toolCallId),\n );\n const nextToolResults = nextProps.messages.filter(\n (m): m is ToolMessage =>\n m.role === \"tool\" && toolCallIds.has(m.toolCallId),\n );\n\n if (prevToolResults.length !== nextToolResults.length) return false;\n\n for (let i = 0; i < prevToolResults.length; i++) {\n if (prevToolResults[i]!.content !== nextToolResults[i]!.content)\n return false;\n }\n }\n\n // Only care about isRunning if this message is CURRENTLY the latest\n // (we don't need to re-render just because a message stopped being the latest)\n const nextIsLatest =\n nextProps.messages[nextProps.messages.length - 1]?.id ===\n nextProps.message.id;\n if (nextIsLatest && prevProps.isRunning !== nextProps.isRunning)\n return false;\n\n // Check if component reference changed\n if (\n prevProps.AssistantMessageComponent !==\n nextProps.AssistantMessageComponent\n )\n return false;\n\n // Check if slot props changed\n if (prevProps.slotProps !== nextProps.slotProps) return false;\n\n return true;\n },\n);\n\n/**\n * Memoized wrapper for user messages to prevent re-renders when other messages change.\n */\nconst MemoizedUserMessage = React.memo(\n function MemoizedUserMessage({\n message,\n UserMessageComponent,\n slotProps,\n }: {\n message: UserMessage;\n UserMessageComponent: typeof CopilotChatUserMessage;\n slotProps?: Partial<React.ComponentProps<typeof CopilotChatUserMessage>>;\n }) {\n return <UserMessageComponent message={message} {...slotProps} />;\n },\n (prevProps, nextProps) => {\n // Only re-render if this specific message changed\n if (prevProps.message.id !== nextProps.message.id) return false;\n if (prevProps.message.content !== nextProps.message.content) return false;\n if (prevProps.UserMessageComponent !== nextProps.UserMessageComponent)\n return false;\n // Check if slot props changed\n if (prevProps.slotProps !== nextProps.slotProps) return false;\n return true;\n },\n);\n\n/**\n * Memoized wrapper for activity messages to prevent re-renders when other messages change.\n */\nconst MemoizedActivityMessage = React.memo(\n function MemoizedActivityMessage({\n message,\n renderActivityMessage,\n }: {\n message: ActivityMessage;\n renderActivityMessage: (\n message: ActivityMessage,\n ) => React.ReactElement | null;\n }) {\n return renderActivityMessage(message);\n },\n (prevProps, nextProps) => {\n // Message ID changed = different message, must re-render\n if (prevProps.message.id !== nextProps.message.id) return false;\n\n // Activity type changed = must re-render\n if (prevProps.message.activityType !== nextProps.message.activityType)\n return false;\n\n // Compare content using JSON.stringify (native code, handles deep comparison)\n if (\n JSON.stringify(prevProps.message.content) !==\n JSON.stringify(nextProps.message.content)\n )\n return false;\n\n return true;\n },\n);\n\n/**\n * Memoized wrapper for reasoning messages to prevent re-renders when other messages change.\n */\nconst MemoizedReasoningMessage = React.memo(\n function MemoizedReasoningMessage({\n message,\n messages,\n isRunning,\n ReasoningMessageComponent,\n slotProps,\n }: {\n message: ReasoningMessage;\n messages: Message[];\n isRunning: boolean;\n ReasoningMessageComponent: typeof CopilotChatReasoningMessage;\n slotProps?: Partial<\n React.ComponentProps<typeof CopilotChatReasoningMessage>\n >;\n }) {\n return (\n <ReasoningMessageComponent\n message={message}\n messages={messages}\n isRunning={isRunning}\n {...slotProps}\n />\n );\n },\n (prevProps, nextProps) => {\n // Only re-render if this specific message changed\n if (prevProps.message.id !== nextProps.message.id) return false;\n if (prevProps.message.content !== nextProps.message.content) return false;\n\n // Re-render when \"latest\" status changes (e.g. reasoning message is no longer the last message\n // because a text message was added after it — this transitions isStreaming from true to false)\n const prevIsLatest =\n prevProps.messages[prevProps.messages.length - 1]?.id ===\n prevProps.message.id;\n const nextIsLatest =\n nextProps.messages[nextProps.messages.length - 1]?.id ===\n nextProps.message.id;\n if (prevIsLatest !== nextIsLatest) return false;\n\n // Only care about isRunning if this message is CURRENTLY the latest\n if (nextIsLatest && prevProps.isRunning !== nextProps.isRunning)\n return false;\n\n // Check if component reference changed\n if (\n prevProps.ReasoningMessageComponent !==\n nextProps.ReasoningMessageComponent\n )\n return false;\n\n // Check if slot props changed\n if (prevProps.slotProps !== nextProps.slotProps) return false;\n\n return true;\n },\n);\n\n/**\n * Memoized wrapper for custom messages to prevent re-renders when other messages change.\n */\nconst MemoizedCustomMessage = React.memo(\n function MemoizedCustomMessage({\n message,\n position,\n renderCustomMessage,\n }: {\n message: Message;\n position: \"before\" | \"after\";\n renderCustomMessage: (params: {\n message: Message;\n position: \"before\" | \"after\";\n }) => React.ReactElement | null;\n stateSnapshot?: unknown;\n }) {\n return renderCustomMessage({ message, position });\n },\n (prevProps, nextProps) => {\n // Only re-render if the message or position changed\n if (prevProps.message.id !== nextProps.message.id) return false;\n if (prevProps.position !== nextProps.position) return false;\n // Compare message content - for assistant messages this is a string, for others may differ\n if (prevProps.message.content !== nextProps.message.content) return false;\n if (prevProps.message.role !== nextProps.message.role) return false;\n // Compare state snapshot - custom renderers may depend on state\n if (\n JSON.stringify(prevProps.stateSnapshot) !==\n JSON.stringify(nextProps.stateSnapshot)\n )\n return false;\n // Note: We don't compare renderCustomMessage function reference because it changes\n // frequently. The message and state comparison is sufficient to determine if a re-render is needed.\n return true;\n },\n);\n\nexport type CopilotChatMessageViewProps = Omit<\n WithSlots<\n {\n assistantMessage: typeof CopilotChatAssistantMessage;\n userMessage: typeof CopilotChatUserMessage;\n reasoningMessage: typeof CopilotChatReasoningMessage;\n cursor: typeof CopilotChatMessageView.Cursor;\n },\n {\n isRunning?: boolean;\n messages?: Message[];\n } & React.HTMLAttributes<HTMLDivElement>\n >,\n \"children\"\n> & {\n children?: (props: {\n isRunning: boolean;\n messages: Message[];\n messageElements: React.ReactElement[];\n interruptElement: React.ReactElement | null;\n }) => React.ReactElement;\n};\n\n// Above this many messages, activate TanStack Virtual to avoid mounting the\n// full DOM tree. Below the threshold the overhead of virtualization isn't\n// worth it and the simpler flat render is faster.\nconst VIRTUALIZE_THRESHOLD = 50;\n\nexport function CopilotChatMessageView({\n messages = [],\n assistantMessage,\n userMessage,\n reasoningMessage,\n cursor,\n isRunning = false,\n children,\n className,\n ...props\n}: CopilotChatMessageViewProps) {\n const renderCustomMessage = useRenderCustomMessages();\n const { renderActivityMessage } = useRenderActivityMessage();\n const { copilotkit } = useCopilotKit();\n const config = useCopilotChatConfiguration();\n const [, forceUpdate] = useReducer((x) => x + 1, 0);\n\n // Subscribe to state changes so custom message renderers re-render when state updates.\n useEffect(() => {\n if (!config?.agentId) return;\n const registryAgent = copilotkit.getAgent(config.agentId);\n // Prefer the per-thread clone so that state changes from the running agent\n // (which is the clone, not the registry) trigger re-renders.\n const agent =\n getThreadClone(registryAgent, config.threadId) ?? registryAgent;\n if (!agent) return;\n\n const subscription = agent.subscribe({\n onStateChanged: forceUpdate,\n });\n return () => subscription.unsubscribe();\n }, [config?.agentId, config?.threadId, copilotkit, forceUpdate]);\n\n // Subscribe to interrupt element changes for in-chat rendering.\n const [interruptElement, setInterruptElement] =\n useState<React.ReactElement | null>(null);\n useEffect(() => {\n setInterruptElement(copilotkit.interruptElement);\n const subscription = copilotkit.subscribe({\n onInterruptElementChanged: ({ interruptElement }) => {\n setInterruptElement(interruptElement);\n },\n });\n return () => subscription.unsubscribe();\n }, [copilotkit]);\n\n // Helper to get state snapshot for a message (used for memoization)\n const getStateSnapshotForMessage = (messageId: string): unknown => {\n if (!config) return undefined;\n const resolvedRunId =\n copilotkit.getRunIdForMessage(\n config.agentId,\n config.threadId,\n messageId,\n ) ??\n copilotkit\n .getRunIdsForThread(config.agentId, config.threadId)\n .slice(-1)[0];\n if (!resolvedRunId) return undefined;\n return copilotkit.getStateByRun(\n config.agentId,\n config.threadId,\n resolvedRunId,\n );\n };\n\n // Deduplicate messages by id, keeping the last occurrence of each.\n // During streaming, AbstractAgent.addMessage() can push duplicate messages\n // (same id) which causes React \"duplicate key\" warnings and rendering glitches.\n const deduplicatedMessages = useMemo(\n () => [...new Map(messages.map((m) => [m.id, m])).values()],\n [messages],\n );\n\n if (\n process.env.NODE_ENV === \"development\" &&\n deduplicatedMessages.length < messages.length\n ) {\n console.warn(\n `CopilotChatMessageView: Deduplicated ${messages.length - deduplicatedMessages.length} message(s) with duplicate IDs.`,\n );\n }\n\n // Resolve slot values once per prop change rather than inside renderMessageBlock.\n // resolveSlotComponent returns a new object every call when the slot is a CSS\n // class string, which would defeat MemoizedAssistantMessage's slotProps\n // reference-equality check and cause all completed messages to re-render.\n const { Component: AssistantComponent, slotProps: assistantSlotProps } =\n useMemo(\n () => resolveSlotComponent(assistantMessage, CopilotChatAssistantMessage),\n [assistantMessage],\n );\n const { Component: UserComponent, slotProps: userSlotProps } = useMemo(\n () => resolveSlotComponent(userMessage, CopilotChatUserMessage),\n [userMessage],\n );\n const { Component: ReasoningComponent, slotProps: reasoningSlotProps } =\n useMemo(\n () => resolveSlotComponent(reasoningMessage, CopilotChatReasoningMessage),\n [reasoningMessage],\n );\n\n // ---------------------------------------------------------------------------\n // Virtualization\n // ---------------------------------------------------------------------------\n // Receive the scroll container from context. ScrollView provides the element\n // as state (not a ref) so this component re-renders reactively when the\n // container first mounts. clientHeight === 0 means no real layout (jsdom) —\n // skip virtualization so tests run the flat path.\n const scrollElementFromCtx = useContext(ScrollElementContext);\n const scrollElement =\n scrollElementFromCtx && scrollElementFromCtx.clientHeight > 0\n ? scrollElementFromCtx\n : null;\n\n // Warn once in dev when a scroll element is provided but has no height —\n // this silently disables virtualization (e.g. chat inside display:none tab).\n useEffect(() => {\n if (\n process.env.NODE_ENV !== \"production\" &&\n scrollElementFromCtx &&\n scrollElementFromCtx.clientHeight === 0\n ) {\n console.warn(\n \"[CopilotKit] Chat scroll container has clientHeight=0 — virtualization disabled. \" +\n \"Ensure the chat is rendered in a visible container with a non-zero height.\",\n );\n }\n }, [scrollElementFromCtx]);\n\n // Virtualize only when we have a scroll element and enough messages. The\n // `children` render prop delegates layout to the caller, so we keep\n // messageElements flat for that case.\n const shouldVirtualize =\n !!scrollElement &&\n !children &&\n deduplicatedMessages.length > VIRTUALIZE_THRESHOLD;\n\n const virtualizer = useVirtualizer({\n // count=0 disables the virtualizer without changing hook call order.\n count: shouldVirtualize ? deduplicatedMessages.length : 0,\n getScrollElement: () => scrollElement,\n // Conservative height estimate. Items are measured by ResizeObserver after\n // first render so the estimate only affects the initial total height.\n estimateSize: () => 100,\n overscan: 5,\n measureElement: (el: Element) => el?.getBoundingClientRect().height ?? 0,\n // Assume a 600 px viewport before the real element is measured so that\n // the first virtual render shows ~6 items rather than 0.\n initialRect: { width: 0, height: 600 },\n });\n\n // Scroll to the bottom when virtual mode first activates or the thread changes\n // (detected by the first message ID changing). For streaming new messages,\n // use-stick-to-bottom handles auto-scroll via content height growth detection\n // on the virtualizer's total-size div — same as the flat path. Adding\n // deduplicatedMessages.length here would forcibly yank the user to the bottom\n // on every streaming chunk even if they've scrolled up to read history.\n const firstMessageId = deduplicatedMessages[0]?.id;\n useLayoutEffect(() => {\n if (!shouldVirtualize || !deduplicatedMessages.length) return;\n virtualizer.scrollToIndex(deduplicatedMessages.length - 1, {\n align: \"end\",\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [shouldVirtualize, firstMessageId]);\n\n // ---------------------------------------------------------------------------\n // Per-message rendering helper (shared by flat and virtual paths)\n // ---------------------------------------------------------------------------\n const renderMessageBlock = (message: Message): React.ReactElement[] => {\n const elements: (React.ReactElement | null | undefined)[] = [];\n const stateSnapshot = getStateSnapshotForMessage(message.id);\n\n if (renderCustomMessage) {\n elements.push(\n <MemoizedCustomMessage\n key={`${message.id}-custom-before`}\n message={message}\n position=\"before\"\n renderCustomMessage={renderCustomMessage}\n stateSnapshot={stateSnapshot}\n />,\n );\n }\n\n if (message.role === \"assistant\") {\n elements.push(\n <MemoizedAssistantMessage\n key={message.id}\n message={message as AssistantMessage}\n messages={messages}\n isRunning={isRunning}\n AssistantMessageComponent={AssistantComponent}\n slotProps={assistantSlotProps}\n />,\n );\n } else if (message.role === \"user\") {\n elements.push(\n <MemoizedUserMessage\n key={message.id}\n message={message as UserMessage}\n UserMessageComponent={UserComponent}\n slotProps={userSlotProps}\n />,\n );\n } else if (message.role === \"activity\") {\n elements.push(\n <MemoizedActivityMessage\n key={message.id}\n message={message as ActivityMessage}\n renderActivityMessage={renderActivityMessage}\n />,\n );\n } else if (message.role === \"reasoning\") {\n elements.push(\n <MemoizedReasoningMessage\n key={message.id}\n message={message as ReasoningMessage}\n messages={messages}\n isRunning={isRunning}\n ReasoningMessageComponent={ReasoningComponent}\n slotProps={reasoningSlotProps}\n />,\n );\n }\n\n if (renderCustomMessage) {\n elements.push(\n <MemoizedCustomMessage\n key={`${message.id}-custom-after`}\n message={message}\n position=\"after\"\n renderCustomMessage={renderCustomMessage}\n stateSnapshot={stateSnapshot}\n />,\n );\n }\n\n return elements.filter(Boolean) as React.ReactElement[];\n };\n\n // Build the flat element list only when we're not virtualizing (avoids\n // creating 500 React elements that we'd immediately discard).\n const messageElements: React.ReactElement[] = shouldVirtualize\n ? []\n : deduplicatedMessages.flatMap(renderMessageBlock);\n\n // ---------------------------------------------------------------------------\n // children render prop (custom layout, always non-virtual)\n // ---------------------------------------------------------------------------\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({ messageElements, messages, isRunning, interruptElement })}\n </div>\n );\n }\n\n // Hide the chat-level loading cursor when the last message is a reasoning\n // message — the reasoning card already shows its own loading indicator.\n const lastMessage = messages[messages.length - 1];\n const showCursor = isRunning && lastMessage?.role !== \"reasoning\";\n\n // ---------------------------------------------------------------------------\n // Render — shared wrapper, conditional inner content (virtual vs flat)\n // ---------------------------------------------------------------------------\n return (\n <div\n data-copilotkit\n data-testid=\"copilot-message-list\"\n className={twMerge(\"copilotKitMessages cpk:flex cpk:flex-col\", className)}\n {...props}\n >\n {shouldVirtualize ? (\n // Virtual path: only visible items are in the DOM; outer div maintains\n // total scroll height so the scrollbar reflects the full list size.\n <div\n style={{ height: virtualizer.getTotalSize(), position: \"relative\" }}\n >\n {virtualizer.getVirtualItems().map((virtualItem) => {\n const message = deduplicatedMessages[virtualItem.index]!;\n return (\n <div\n key={message.id}\n data-index={virtualItem.index}\n ref={virtualizer.measureElement}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n transform: `translateY(${virtualItem.start}px)`,\n }}\n >\n {renderMessageBlock(message)}\n </div>\n );\n })}\n </div>\n ) : (\n messageElements\n )}\n {interruptElement}\n {showCursor && (\n <div className=\"cpk:mt-2\">\n {renderSlot(cursor, CopilotChatMessageView.Cursor, {})}\n </div>\n )}\n </div>\n );\n}\n\nCopilotChatMessageView.Cursor = function Cursor({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n data-testid=\"copilot-loading-cursor\"\n className={twMerge(\n \"cpk:w-[11px] cpk:h-[11px] cpk:rounded-full cpk:bg-foreground cpk:animate-pulse-cursor cpk:ml-1\",\n className,\n )}\n {...props}\n />\n );\n};\n\nexport default CopilotChatMessageView;\n","import React, { useCallback, useEffect, useId, useRef, useState } from \"react\";\nimport { createPortal, flushSync } from \"react-dom\";\nimport type { Attachment } from \"@copilotkit/shared\";\nimport {\n formatFileSize,\n getSourceUrl,\n getDocumentIcon,\n} from \"@copilotkit/shared\";\nimport { Play, X } from \"lucide-react\";\nimport { cn } from \"../../lib/utils\";\n\ninterface CopilotChatAttachmentQueueProps {\n attachments: Attachment[];\n onRemoveAttachment: (id: string) => void;\n className?: string;\n}\n\nexport const CopilotChatAttachmentQueue: React.FC<\n CopilotChatAttachmentQueueProps\n> = ({ attachments, onRemoveAttachment, className }) => {\n if (attachments.length === 0) return null;\n\n return (\n <div className={cn(\"cpk:flex cpk:flex-wrap cpk:gap-2 cpk:p-2\", className)}>\n {attachments.map((attachment) => {\n const isMedia =\n attachment.type === \"image\" || attachment.type === \"video\";\n return (\n <div\n key={attachment.id}\n className={cn(\n \"cpk:relative cpk:inline-flex cpk:rounded-lg cpk:overflow-hidden cpk:border cpk:border-border\",\n isMedia\n ? \"cpk:w-[72px] cpk:h-[72px]\"\n : attachment.type === \"audio\"\n ? \"cpk:min-w-[200px] cpk:max-w-[280px] cpk:flex-col cpk:p-1 cpk:pr-8\"\n : \"cpk:p-2 cpk:px-3 cpk:pr-8 cpk:max-w-[240px]\",\n )}\n >\n {attachment.status === \"uploading\" && <UploadingOverlay />}\n <AttachmentPreview attachment={attachment} />\n <button\n onClick={() => onRemoveAttachment(attachment.id)}\n className={cn(\n \"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\",\n isMedia ? \"cpk:top-1 cpk:right-1\" : \"cpk:top-1.5 cpk:right-1.5\",\n )}\n aria-label=\"Remove attachment\"\n >\n ✕\n </button>\n </div>\n );\n })}\n </div>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Shared\n// ---------------------------------------------------------------------------\n\nfunction UploadingOverlay() {\n return (\n <div className=\"cpk:absolute cpk:inset-0 cpk:flex cpk:items-center cpk:justify-center cpk:bg-black/40 cpk:z-10\">\n <div className=\"cpk:w-5 cpk:h-5 cpk:border-2 cpk:border-white cpk:border-t-transparent cpk:rounded-full cpk:animate-spin\" />\n </div>\n );\n}\n\nfunction AttachmentPreview({ attachment }: { attachment: Attachment }) {\n if (attachment.status === \"uploading\") {\n return <div className=\"cpk:w-full cpk:h-full\" />;\n }\n\n switch (attachment.type) {\n case \"image\":\n return <ImagePreview attachment={attachment} />;\n case \"audio\":\n return <AudioPreview attachment={attachment} />;\n case \"video\":\n return <VideoPreview attachment={attachment} />;\n case \"document\":\n return <DocumentPreview attachment={attachment} />;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Lightbox – fullscreen overlay for images and videos (portal to body)\n// Uses the View Transition API when available for a smooth thumbnail-to-\n// fullscreen morph; falls back to a simple opacity fade.\n// ---------------------------------------------------------------------------\n\ninterface LightboxProps {\n onClose: () => void;\n children: React.ReactNode;\n}\n\nfunction Lightbox({ onClose, children }: LightboxProps) {\n useEffect(() => {\n const handleKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n document.addEventListener(\"keydown\", handleKey);\n return () => document.removeEventListener(\"keydown\", handleKey);\n }, [onClose]);\n\n if (typeof document === \"undefined\") return null;\n\n return createPortal(\n <div\n 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\"\n onClick={onClose}\n >\n <button\n onClick={onClose}\n 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\"\n aria-label=\"Close preview\"\n >\n <X className=\"cpk:w-5 cpk:h-5\" />\n </button>\n\n <div onClick={(e) => e.stopPropagation()}>{children}</div>\n </div>,\n document.body,\n );\n}\n\ntype DocWithVT = Document & {\n startViewTransition?: (cb: () => void) => { finished: Promise<void> };\n};\n\n/**\n * Hook that manages lightbox open/close and uses the View Transition API to\n * morph the thumbnail into fullscreen content.\n *\n * The trick: `view-transition-name` must live on exactly ONE element at a time.\n * - Old state (thumbnail visible): name is on the thumbnail.\n * - New state (lightbox visible): name moves to the lightbox content.\n * `flushSync` ensures React commits the DOM change synchronously inside the\n * `startViewTransition` callback so the API can snapshot old → new correctly.\n */\nfunction useLightbox() {\n const thumbnailRef = useRef<HTMLElement>(null);\n const [open, setOpen] = useState(false);\n const vtName = useId();\n\n const openLightbox = useCallback(() => {\n const thumb = thumbnailRef.current;\n const doc = document as DocWithVT;\n\n if (doc.startViewTransition && thumb) {\n // Old snapshot: name on the thumbnail\n thumb.style.viewTransitionName = vtName;\n\n doc.startViewTransition(() => {\n // New snapshot: remove from thumb (lightbox content will have it)\n thumb.style.viewTransitionName = \"\";\n flushSync(() => setOpen(true));\n });\n } else {\n setOpen(true);\n }\n }, []);\n\n const closeLightbox = useCallback(() => {\n const thumb = thumbnailRef.current;\n const doc = document as DocWithVT;\n\n if (doc.startViewTransition && thumb) {\n const transition = doc.startViewTransition(() => {\n // New snapshot: name back on thumbnail\n flushSync(() => setOpen(false));\n thumb.style.viewTransitionName = vtName;\n });\n // Clean up the name after animation finishes (or fails)\n transition.finished\n .then(() => {\n thumb.style.viewTransitionName = \"\";\n })\n .catch(() => {\n thumb.style.viewTransitionName = \"\";\n });\n } else {\n setOpen(false);\n }\n }, []);\n\n return {\n thumbnailRef,\n vtName,\n open,\n openLightbox,\n closeLightbox,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Image\n// ---------------------------------------------------------------------------\n\nfunction ImagePreview({ attachment }: { attachment: Attachment }) {\n const src = getSourceUrl(attachment.source);\n const { thumbnailRef, vtName, open, openLightbox, closeLightbox } =\n useLightbox();\n\n return (\n <>\n <img\n ref={thumbnailRef as React.Ref<HTMLImageElement>}\n src={src}\n alt={attachment.filename || \"Image attachment\"}\n className=\"cpk:w-full cpk:h-full cpk:object-cover cpk:cursor-pointer\"\n onClick={openLightbox}\n />\n {open && (\n <Lightbox onClose={closeLightbox}>\n <img\n style={{ viewTransitionName: vtName }}\n src={src}\n alt={attachment.filename || \"Image attachment\"}\n className=\"cpk:max-w-[90vw] cpk:max-h-[90vh] cpk:object-contain cpk:rounded-lg\"\n />\n </Lightbox>\n )}\n </>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Audio\n// ---------------------------------------------------------------------------\n\nfunction AudioPreview({ attachment }: { attachment: Attachment }) {\n const src = getSourceUrl(attachment.source);\n return (\n <div className=\"cpk:flex cpk:flex-col cpk:gap-1 cpk:w-full\">\n <audio\n src={src}\n controls\n preload=\"metadata\"\n className=\"cpk:w-full cpk:h-8\"\n />\n {attachment.filename && (\n <span className=\"cpk:text-xs cpk:font-medium cpk:overflow-hidden cpk:text-ellipsis cpk:whitespace-nowrap\">\n {attachment.filename}\n </span>\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Video – thumbnail with play button; click opens lightbox with full controls\n// ---------------------------------------------------------------------------\n\nfunction VideoPreview({ attachment }: { attachment: Attachment }) {\n const src = getSourceUrl(attachment.source);\n const { thumbnailRef, vtName, open, openLightbox, closeLightbox } =\n useLightbox();\n\n return (\n <>\n <div\n ref={thumbnailRef as React.Ref<HTMLDivElement>}\n className=\"cpk:w-full cpk:h-full\"\n >\n {attachment.thumbnail ? (\n <img\n src={attachment.thumbnail}\n alt={attachment.filename || \"Video thumbnail\"}\n className=\"cpk:w-full cpk:h-full cpk:object-cover\"\n />\n ) : (\n <video\n src={src}\n preload=\"metadata\"\n muted\n className=\"cpk:w-full cpk:h-full cpk:object-cover\"\n />\n )}\n </div>\n <button\n onClick={openLightbox}\n 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\"\n aria-label=\"Play video\"\n >\n <div className=\"cpk:w-8 cpk:h-8 cpk:rounded-full cpk:bg-black/60 cpk:flex cpk:items-center cpk:justify-center\">\n <Play className=\"cpk:w-4 cpk:h-4 cpk:text-white cpk:ml-0.5\" />\n </div>\n </button>\n {open && (\n <Lightbox onClose={closeLightbox}>\n <video\n style={{ viewTransitionName: vtName }}\n src={src}\n controls\n autoPlay\n className=\"cpk:max-w-[90vw] cpk:max-h-[90vh] cpk:rounded-lg\"\n />\n </Lightbox>\n )}\n </>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Document – click opens lightbox with PDF/text preview or info card\n// ---------------------------------------------------------------------------\n\nfunction isPdf(mimeType: string | undefined): boolean {\n return !!mimeType && mimeType.includes(\"pdf\");\n}\n\nfunction isText(mimeType: string | undefined): boolean {\n return !!mimeType && mimeType.startsWith(\"text/\");\n}\n\nfunction canPreviewInBrowser(mimeType: string | undefined): boolean {\n return isPdf(mimeType) || isText(mimeType);\n}\n\n/**\n * Convert a base64-encoded data source to a blob: URL that browsers will\n * render inside an iframe (data: URLs are blocked for PDFs in most browsers).\n */\nfunction useBlobUrl(attachment: Attachment): string | null {\n const [url, setUrl] = useState<string | null>(null);\n\n useEffect(() => {\n if (attachment.source.type !== \"data\") return;\n try {\n const binary = atob(attachment.source.value);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n const blob = new Blob([bytes], {\n type: attachment.source.mimeType || \"application/octet-stream\",\n });\n const blobUrl = URL.createObjectURL(blob);\n setUrl(blobUrl);\n return () => URL.revokeObjectURL(blobUrl);\n } catch (error) {\n console.error(\"[CopilotKit] Failed to decode attachment data:\", error);\n setUrl(null);\n }\n }, [\n attachment.source.type,\n attachment.source.value,\n attachment.source.mimeType,\n ]);\n\n if (attachment.source.type === \"url\") return attachment.source.value;\n return url;\n}\n\nfunction DocumentLightboxContent({\n attachment,\n vtName,\n}: {\n attachment: Attachment;\n vtName: string;\n}) {\n const mimeType = attachment.source.mimeType;\n const blobUrl = useBlobUrl(attachment);\n\n if (isPdf(mimeType)) {\n if (!blobUrl) return null;\n return (\n <iframe\n style={{ viewTransitionName: vtName }}\n src={blobUrl}\n title={attachment.filename || \"PDF preview\"}\n className=\"cpk:w-[90vw] cpk:h-[90vh] cpk:max-w-[1000px] cpk:rounded-lg cpk:bg-white\"\n />\n );\n }\n\n if (isText(mimeType)) {\n // Decode base64 text content for display\n const textContent =\n attachment.source.type === \"data\"\n ? (() => {\n try {\n return atob(attachment.source.value);\n } catch {\n return attachment.source.value;\n }\n })()\n : null;\n\n return (\n <div\n style={{ viewTransitionName: vtName }}\n 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\"\n >\n {attachment.filename && (\n <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\">\n {attachment.filename}\n </div>\n )}\n {textContent ? (\n <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\">\n {textContent}\n </pre>\n ) : blobUrl ? (\n <iframe\n src={blobUrl}\n title={attachment.filename || \"Text preview\"}\n className=\"cpk:w-full cpk:h-[80vh] cpk:border-none\"\n />\n ) : null}\n </div>\n );\n }\n\n // Fallback: info card for non-previewable documents\n return (\n <div\n style={{ viewTransitionName: vtName }}\n 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\"\n >\n <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\">\n {getDocumentIcon(mimeType ?? \"\")}\n </div>\n <div className=\"cpk:text-center\">\n <div className=\"cpk:text-base cpk:font-medium cpk:text-gray-800 cpk:dark:text-gray-200\">\n {attachment.filename || \"Document\"}\n </div>\n <div className=\"cpk:text-sm cpk:text-gray-500 cpk:dark:text-gray-400 cpk:mt-1\">\n {mimeType || \"Unknown type\"}\n {attachment.size != null && ` · ${formatFileSize(attachment.size)}`}\n </div>\n </div>\n <div className=\"cpk:text-xs cpk:text-gray-400 cpk:dark:text-gray-500\">\n No preview available for this file type\n </div>\n </div>\n );\n}\n\nfunction DocumentPreview({ attachment }: { attachment: Attachment }) {\n const { thumbnailRef, vtName, open, openLightbox, closeLightbox } =\n useLightbox();\n\n const mimeType = attachment.source.mimeType;\n const previewable = canPreviewInBrowser(mimeType);\n\n return (\n <>\n <div\n ref={thumbnailRef as React.Ref<HTMLDivElement>}\n className={cn(\n \"cpk:flex cpk:items-center cpk:gap-2\",\n previewable && \"cpk:cursor-pointer\",\n )}\n onClick={previewable ? openLightbox : undefined}\n >\n <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\">\n {getDocumentIcon(mimeType ?? \"\")}\n </div>\n <div className=\"cpk:flex cpk:flex-col cpk:min-w-0\">\n <span className=\"cpk:text-xs cpk:font-medium cpk:break-all cpk:leading-tight\">\n {attachment.filename || \"Document\"}\n </span>\n {attachment.size != null && (\n <span className=\"cpk:text-[11px] cpk:text-muted-foreground\">\n {formatFileSize(attachment.size)}\n </span>\n )}\n </div>\n </div>\n {open && (\n <Lightbox onClose={closeLightbox}>\n <DocumentLightboxContent attachment={attachment} vtName={vtName} />\n </Lightbox>\n )}\n </>\n );\n}\n","import { useState, useEffect } from \"react\";\n\nexport interface KeyboardState {\n isKeyboardOpen: boolean;\n keyboardHeight: number;\n availableHeight: number;\n viewportHeight: number;\n}\n\n/**\n * Hook to detect mobile keyboard appearance and calculate available viewport height.\n * Uses the Visual Viewport API to track keyboard state on mobile devices.\n *\n * @returns KeyboardState object with keyboard information\n */\nexport function useKeyboardHeight(): KeyboardState {\n const [keyboardState, setKeyboardState] = useState<KeyboardState>({\n isKeyboardOpen: false,\n keyboardHeight: 0,\n availableHeight: typeof window !== \"undefined\" ? window.innerHeight : 0,\n viewportHeight: typeof window !== \"undefined\" ? window.innerHeight : 0,\n });\n\n useEffect(() => {\n if (typeof window === \"undefined\") {\n return;\n }\n\n // Check if Visual Viewport API is available\n const visualViewport = window.visualViewport;\n if (!visualViewport) {\n return;\n }\n\n const updateKeyboardState = () => {\n const layoutHeight = window.innerHeight;\n const visualHeight = visualViewport.height;\n\n // Calculate keyboard height (difference between layout and visual viewport)\n const keyboardHeight = Math.max(0, layoutHeight - visualHeight);\n\n // Keyboard is considered open if the height difference is significant (> 150px)\n const isKeyboardOpen = keyboardHeight > 150;\n\n setKeyboardState({\n isKeyboardOpen,\n keyboardHeight,\n availableHeight: visualHeight,\n viewportHeight: layoutHeight,\n });\n };\n\n // Initial state\n updateKeyboardState();\n\n // Listen for viewport changes\n visualViewport.addEventListener(\"resize\", updateKeyboardState);\n visualViewport.addEventListener(\"scroll\", updateKeyboardState);\n\n return () => {\n visualViewport.removeEventListener(\"resize\", updateKeyboardState);\n visualViewport.removeEventListener(\"scroll\", updateKeyboardState);\n };\n }, []);\n\n return keyboardState;\n}\n","import React, {\n useCallback,\n useRef,\n useState,\n useEffect,\n useLayoutEffect,\n} from \"react\";\nimport { ScrollElementContext } from \"./scroll-element-context\";\nimport { WithSlots, SlotValue, renderSlot } from \"../../lib/slots\";\nimport CopilotChatMessageView from \"./CopilotChatMessageView\";\nimport CopilotChatInput, {\n CopilotChatInputProps,\n CopilotChatInputMode,\n} from \"./CopilotChatInput\";\nimport CopilotChatSuggestionView, {\n CopilotChatSuggestionViewProps,\n} from \"./CopilotChatSuggestionView\";\nimport { Suggestion } from \"@copilotkit/core\";\nimport { Message } from \"@ag-ui/core\";\nimport type { Attachment } from \"@copilotkit/shared\";\nimport { CopilotChatAttachmentQueue } from \"./CopilotChatAttachmentQueue\";\nimport { twMerge } from \"tailwind-merge\";\nimport {\n StickToBottom,\n useStickToBottom,\n useStickToBottomContext,\n} from \"use-stick-to-bottom\";\nimport { ChevronDown, Upload } from \"lucide-react\";\nimport { Button } from \"../../components/ui/button\";\nimport { cn } from \"../../lib/utils\";\nimport {\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"../../providers/CopilotChatConfigurationProvider\";\nimport { useKeyboardHeight } from \"../../hooks/use-keyboard-height\";\n\n// Height of the feather gradient overlay (h-24 = 6rem = 96px)\nconst FEATHER_HEIGHT = 96;\n\n// Forward declaration for WelcomeScreen component type\nexport type WelcomeScreenProps = WithSlots<\n {\n welcomeMessage: React.FC<React.HTMLAttributes<HTMLDivElement>>;\n },\n {\n input: React.ReactElement;\n suggestionView: React.ReactElement;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\nexport type CopilotChatViewProps = WithSlots<\n {\n messageView: typeof CopilotChatMessageView;\n scrollView: typeof CopilotChatView.ScrollView;\n input: typeof CopilotChatInput;\n suggestionView: typeof CopilotChatSuggestionView;\n },\n {\n messages?: Message[];\n autoScroll?: boolean;\n isRunning?: boolean;\n suggestions?: Suggestion[];\n suggestionLoadingIndexes?: ReadonlyArray<number>;\n onSelectSuggestion?: (suggestion: Suggestion, index: number) => void;\n welcomeScreen?: SlotValue<React.FC<WelcomeScreenProps>> | boolean;\n // Input behavior props\n onSubmitMessage?: (value: string) => void;\n onStop?: () => void;\n inputMode?: CopilotChatInputMode;\n inputValue?: string;\n onInputChange?: (value: string) => void;\n onStartTranscribe?: () => void;\n onCancelTranscribe?: () => void;\n onFinishTranscribe?: () => void;\n onFinishTranscribeWithAudio?: (audioBlob: Blob) => Promise<void>;\n // Attachment props\n attachments?: Attachment[];\n onRemoveAttachment?: (id: string) => void;\n onAddFile?: () => void;\n dragOver?: boolean;\n onDragOver?: (e: React.DragEvent) => void;\n onDragLeave?: (e: React.DragEvent) => void;\n onDrop?: (e: React.DragEvent) => void;\n /**\n * @deprecated Use the `input` slot's `disclaimer` prop instead:\n * ```tsx\n * <CopilotChat input={{ disclaimer: MyDisclaimer }} />\n * ```\n */\n disclaimer?: SlotValue<React.FC<React.HTMLAttributes<HTMLDivElement>>>;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\nfunction DropOverlay() {\n return (\n <div\n className={cn(\n \"cpk:absolute cpk:inset-0 cpk:z-50 cpk:pointer-events-none\",\n \"cpk:flex cpk:items-center cpk:justify-center\",\n \"cpk:bg-primary/5 cpk:backdrop-blur-[2px]\",\n \"cpk:border-2 cpk:border-dashed cpk:border-primary/40 cpk:rounded-lg cpk:m-2\",\n )}\n >\n <div className=\"cpk:flex cpk:flex-col cpk:items-center cpk:gap-2 cpk:text-primary/70\">\n <Upload className=\"cpk:w-8 cpk:h-8\" />\n <span className=\"cpk:text-sm cpk:font-medium\">Drop files here</span>\n </div>\n </div>\n );\n}\n\nexport function CopilotChatView({\n messageView,\n input,\n scrollView,\n suggestionView,\n welcomeScreen,\n messages = [],\n autoScroll = true,\n isRunning = false,\n suggestions,\n suggestionLoadingIndexes,\n onSelectSuggestion,\n // Input behavior props\n onSubmitMessage,\n onStop,\n inputMode,\n inputValue,\n onInputChange,\n onStartTranscribe,\n onCancelTranscribe,\n onFinishTranscribe,\n onFinishTranscribeWithAudio,\n // Attachment props\n attachments,\n onRemoveAttachment,\n onAddFile,\n dragOver,\n onDragOver,\n onDragLeave,\n onDrop,\n // Deprecated — forwarded to input slot\n disclaimer,\n children,\n className,\n ...props\n}: CopilotChatViewProps) {\n const inputContainerRef = useRef<HTMLDivElement>(null);\n const [inputContainerHeight, setInputContainerHeight] = useState(0);\n const [isResizing, setIsResizing] = useState(false);\n const resizeTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n\n // Track keyboard state for mobile\n const { isKeyboardOpen, keyboardHeight, availableHeight } =\n useKeyboardHeight();\n\n // Track input container height changes\n useEffect(() => {\n const element = inputContainerRef.current;\n if (!element) return;\n\n const resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const newHeight = entry.contentRect.height;\n\n // Update height and set resizing state\n setInputContainerHeight((prevHeight) => {\n if (newHeight !== prevHeight) {\n setIsResizing(true);\n\n // Clear existing timeout\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n\n // Set isResizing to false after a short delay\n resizeTimeoutRef.current = setTimeout(() => {\n setIsResizing(false);\n }, 250);\n\n return newHeight;\n }\n return prevHeight;\n });\n }\n });\n\n resizeObserver.observe(element);\n\n // Set initial height\n setInputContainerHeight(element.offsetHeight);\n\n return () => {\n resizeObserver.disconnect();\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n };\n }, []);\n\n const BoundMessageView = renderSlot(messageView, CopilotChatMessageView, {\n messages,\n isRunning,\n });\n\n const BoundInput = renderSlot(input, CopilotChatInput, {\n onSubmitMessage,\n onStop,\n mode: inputMode,\n value: inputValue,\n onChange: onInputChange,\n isRunning,\n onStartTranscribe,\n onCancelTranscribe,\n onFinishTranscribe,\n onFinishTranscribeWithAudio,\n onAddFile,\n positioning: \"static\",\n keyboardHeight: isKeyboardOpen ? keyboardHeight : 0,\n containerRef: inputContainerRef,\n showDisclaimer: true,\n ...(disclaimer !== undefined ? { disclaimer } : {}),\n } as CopilotChatInputProps);\n\n const hasSuggestions = Array.isArray(suggestions) && suggestions.length > 0;\n const BoundSuggestionView = hasSuggestions\n ? renderSlot(suggestionView, CopilotChatSuggestionView, {\n suggestions,\n loadingIndexes: suggestionLoadingIndexes,\n onSelectSuggestion,\n className: \"cpk:mb-3 cpk:lg:ml-4 cpk:lg:mr-4 cpk:ml-0 cpk:mr-0\",\n })\n : null;\n\n const BoundScrollView = renderSlot(scrollView, CopilotChatView.ScrollView, {\n autoScroll,\n inputContainerHeight,\n isResizing,\n children: (\n <div\n style={{\n paddingBottom: `${hasSuggestions ? 4 : 32}px`,\n }}\n >\n <div className=\"cpk:max-w-3xl cpk:mx-auto\">\n {BoundMessageView}\n {hasSuggestions ? (\n <div className=\"cpk:pl-0 cpk:pr-4 cpk:sm:px-0 cpk:mt-4\">\n {BoundSuggestionView}\n </div>\n ) : null}\n </div>\n </div>\n ),\n });\n\n // Welcome screen logic\n const isEmpty = messages.length === 0;\n // Type assertion needed because TypeScript doesn't fully propagate `| boolean` through WithSlots\n const welcomeScreenDisabled = (welcomeScreen as unknown) === false;\n const shouldShowWelcomeScreen = isEmpty && !welcomeScreenDisabled;\n\n if (shouldShowWelcomeScreen) {\n // Create a separate input for welcome screen with static positioning and disclaimer visible\n const BoundInputForWelcome = renderSlot(input, CopilotChatInput, {\n onSubmitMessage,\n onStop,\n mode: inputMode,\n value: inputValue,\n onChange: onInputChange,\n isRunning,\n onStartTranscribe,\n onCancelTranscribe,\n onFinishTranscribe,\n onFinishTranscribeWithAudio,\n onAddFile,\n positioning: \"static\",\n showDisclaimer: true,\n ...(disclaimer !== undefined ? { disclaimer } : {}),\n } as CopilotChatInputProps);\n\n // Convert boolean `true` to undefined (use default), and exclude `false` since we've checked for it\n const welcomeScreenSlot = (\n welcomeScreen === true ? undefined : welcomeScreen\n ) as SlotValue<React.FC<WelcomeScreenProps>> | undefined;\n // Wrap the input with attachment queue above it\n const inputWithAttachments = (\n <div className=\"cpk:w-full\">\n {attachments && attachments.length > 0 && (\n <CopilotChatAttachmentQueue\n attachments={attachments}\n onRemoveAttachment={(id) => onRemoveAttachment?.(id)}\n className=\"cpk:mb-2\"\n />\n )}\n {BoundInputForWelcome}\n </div>\n );\n\n const BoundWelcomeScreen = renderSlot(\n welcomeScreenSlot,\n CopilotChatView.WelcomeScreen,\n {\n input: inputWithAttachments,\n suggestionView: BoundSuggestionView ?? <></>,\n },\n );\n\n return (\n <div\n data-copilotkit\n data-testid=\"copilot-chat\"\n data-copilot-running={isRunning ? \"true\" : \"false\"}\n onDragOver={onDragOver}\n onDragLeave={onDragLeave}\n onDrop={onDrop}\n className={cn(\n \"copilotKitChat cpk:relative cpk:h-full cpk:flex cpk:flex-col\",\n className,\n )}\n {...props}\n >\n {dragOver && <DropOverlay />}\n {BoundWelcomeScreen}\n </div>\n );\n }\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n messageView: BoundMessageView,\n input: BoundInput,\n scrollView: BoundScrollView,\n suggestionView: BoundSuggestionView ?? <></>,\n })}\n </div>\n );\n }\n\n return (\n <div\n data-copilotkit\n data-testid=\"copilot-chat\"\n data-copilot-running={isRunning ? \"true\" : \"false\"}\n onDragOver={onDragOver}\n onDragLeave={onDragLeave}\n onDrop={onDrop}\n className={cn(\n \"copilotKitChat cpk:relative cpk:h-full cpk:flex cpk:flex-col\",\n className,\n )}\n {...props}\n >\n {dragOver && <DropOverlay />}\n {BoundScrollView}\n\n <div className=\"cpk:max-w-3xl cpk:mx-auto cpk:w-full\">\n {attachments && attachments.length > 0 && (\n <CopilotChatAttachmentQueue\n attachments={attachments}\n onRemoveAttachment={(id) => onRemoveAttachment?.(id)}\n className=\"cpk:px-4\"\n />\n )}\n </div>\n\n {BoundInput}\n </div>\n );\n}\n\nexport namespace CopilotChatView {\n // Inner component that has access to StickToBottom context\n const ScrollContent: React.FC<{\n children: React.ReactNode;\n scrollToBottomButton?: SlotValue<\n React.FC<React.ButtonHTMLAttributes<HTMLButtonElement>>\n >;\n feather?: SlotValue<React.FC<React.HTMLAttributes<HTMLDivElement>>>;\n inputContainerHeight: number;\n isResizing: boolean;\n }> = ({\n children,\n scrollToBottomButton,\n feather,\n inputContainerHeight,\n isResizing,\n }) => {\n const { isAtBottom, scrollToBottom, scrollRef } = useStickToBottomContext();\n\n // Capture the scroll element in state so the context value is reactive —\n // consumers re-render when the element is first set rather than reading a\n // ref that silently stays null until after their own layout effects fire.\n const [scrollEl, setScrollEl] = useState<HTMLElement | null>(null);\n useLayoutEffect(() => {\n setScrollEl(scrollRef.current ?? null);\n // scrollRef is a stable object; omitting from deps is intentional.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});\n\n return (\n // Provide the scroll element so CopilotChatMessageView can feed it to\n // useVirtualizer's getScrollElement. Using state (not the raw ref) means\n // the context value updates reactively when the element mounts.\n <ScrollElementContext.Provider value={scrollEl}>\n <>\n <StickToBottom.Content\n className=\"cpk:overflow-y-auto cpk:overflow-x-hidden\"\n style={{ flex: \"1 1 0%\", minHeight: 0 }}\n >\n <div className=\"cpk:px-4 cpk:sm:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6\">\n {children}\n </div>\n </StickToBottom.Content>\n\n {/* Feather gradient overlay */}\n {BoundFeather}\n\n {/* Scroll to bottom button - hidden during resize */}\n {!isAtBottom && !isResizing && (\n <div\n className=\"cpk:absolute cpk:inset-x-0 cpk:flex cpk:justify-center cpk:z-30 cpk:pointer-events-none\"\n style={{\n bottom: `${inputContainerHeight + FEATHER_HEIGHT + 16}px`,\n }}\n >\n {renderSlot(\n scrollToBottomButton,\n CopilotChatView.ScrollToBottomButton,\n {\n onClick: () => scrollToBottom(),\n },\n )}\n </div>\n )}\n </>\n </ScrollElementContext.Provider>\n );\n };\n\n export const ScrollView: React.FC<\n React.HTMLAttributes<HTMLDivElement> & {\n autoScroll?: boolean;\n scrollToBottomButton?: SlotValue<\n React.FC<React.ButtonHTMLAttributes<HTMLButtonElement>>\n >;\n feather?: SlotValue<React.FC<React.HTMLAttributes<HTMLDivElement>>>;\n inputContainerHeight?: number;\n isResizing?: boolean;\n }\n > = ({\n children,\n autoScroll = true,\n scrollToBottomButton,\n feather,\n inputContainerHeight = 0,\n isResizing = false,\n className,\n ...props\n }) => {\n const [hasMounted, setHasMounted] = useState(false);\n const { scrollRef, contentRef, scrollToBottom } = useStickToBottom();\n const [showScrollButton, setShowScrollButton] = useState(false);\n // Tracks the scroll container element for the non-autoScroll path so the\n // context value is reactive (element state, not a ref).\n const [nonAutoScrollEl, setNonAutoScrollEl] = useState<HTMLElement | null>(\n null,\n );\n\n // Callback ref that keeps scrollRef in sync with the DOM element while also\n // updating context state — eliminates the need for a useLayoutEffect.\n const nonAutoScrollRefCallback = useCallback(\n (el: HTMLElement | null) => {\n scrollRef.current = el;\n setNonAutoScrollEl(el);\n },\n // scrollRef is a stable object from useStickToBottom; safe to omit.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n );\n\n useEffect(() => {\n setHasMounted(true);\n }, []);\n\n // Monitor scroll position for non-autoscroll mode\n useEffect(() => {\n if (autoScroll) return; // Skip for autoscroll mode\n\n const scrollElement = scrollRef.current;\n if (!scrollElement) return;\n\n const checkScroll = () => {\n const atBottom =\n scrollElement.scrollHeight -\n scrollElement.scrollTop -\n scrollElement.clientHeight <\n 10;\n setShowScrollButton(!atBottom);\n };\n\n checkScroll();\n scrollElement.addEventListener(\"scroll\", checkScroll);\n\n // Also check on resize\n const resizeObserver = new ResizeObserver(checkScroll);\n resizeObserver.observe(scrollElement);\n\n return () => {\n scrollElement.removeEventListener(\"scroll\", checkScroll);\n resizeObserver.disconnect();\n };\n }, [scrollRef, autoScroll]);\n\n if (!hasMounted) {\n return (\n <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\">\n <div className=\"cpk:px-4 cpk:sm:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6\">\n {children}\n </div>\n </div>\n );\n }\n\n // When autoScroll is false, we don't use StickToBottom\n if (!autoScroll) {\n const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});\n\n return (\n // Provide the scroll element so CopilotChatMessageView can use it for\n // useVirtualizer. Element state (not a ref) keeps the context reactive.\n <ScrollElementContext.Provider value={nonAutoScrollEl}>\n <div\n ref={nonAutoScrollRefCallback}\n className={cn(\n \"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\",\n className,\n )}\n {...props}\n >\n <div\n ref={contentRef}\n className=\"cpk:px-4 cpk:sm:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6\"\n >\n {children}\n </div>\n\n {/* Feather gradient overlay */}\n {BoundFeather}\n\n {/* Scroll to bottom button for manual mode */}\n {showScrollButton && !isResizing && (\n <div\n className=\"cpk:absolute cpk:inset-x-0 cpk:flex cpk:justify-center cpk:z-30 cpk:pointer-events-none\"\n style={{\n bottom: `${inputContainerHeight + FEATHER_HEIGHT + 16}px`,\n }}\n >\n {renderSlot(\n scrollToBottomButton,\n CopilotChatView.ScrollToBottomButton,\n {\n onClick: () => scrollToBottom(),\n },\n )}\n </div>\n )}\n </div>\n </ScrollElementContext.Provider>\n );\n }\n\n return (\n <StickToBottom\n className={cn(\n \"cpk:flex-1 cpk:max-h-full cpk:flex cpk:flex-col cpk:min-h-0\",\n className,\n )}\n resize=\"smooth\"\n initial=\"smooth\"\n {...props}\n >\n <ScrollContent\n scrollToBottomButton={scrollToBottomButton}\n feather={feather}\n inputContainerHeight={inputContainerHeight}\n isResizing={isResizing}\n >\n {children}\n </ScrollContent>\n </StickToBottom>\n );\n };\n\n export const ScrollToBottomButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, ...props }) => (\n <Button\n data-testid=\"copilot-scroll-to-bottom\"\n variant=\"outline\"\n size=\"sm\"\n className={twMerge(\n \"cpk:rounded-full cpk:w-10 cpk:h-10 cpk:p-0 cpk:pointer-events-auto\",\n \"cpk:bg-white cpk:dark:bg-gray-900\",\n \"cpk:shadow-lg cpk:border cpk:border-gray-200 cpk:dark:border-gray-700\",\n \"cpk:hover:bg-gray-50 cpk:dark:hover:bg-gray-800\",\n \"cpk:flex cpk:items-center cpk:justify-center cpk:cursor-pointer\",\n className,\n )}\n {...props}\n >\n <ChevronDown className=\"cpk:w-4 cpk:h-4 cpk:text-gray-600 cpk:dark:text-white\" />\n </Button>\n );\n\n export const Feather: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n className,\n style,\n ...props\n }) => (\n <div\n className={cn(\n \"cpk:absolute cpk:bottom-0 cpk:left-0 cpk:right-4 cpk:h-24 cpk:pointer-events-none cpk:z-10 cpk:bg-gradient-to-t\",\n \"cpk:from-white cpk:via-white cpk:to-transparent\",\n \"cpk:dark:from-[rgb(33,33,33)] cpk:dark:via-[rgb(33,33,33)]\",\n className,\n )}\n style={style}\n {...props}\n />\n );\n\n export const WelcomeMessage: React.FC<\n React.HTMLAttributes<HTMLDivElement>\n > = ({ className, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n\n return (\n <h1\n className={cn(\n \"cpk:text-xl cpk:sm:text-2xl cpk:font-medium cpk:text-foreground cpk:text-center\",\n className,\n )}\n {...props}\n >\n {labels.welcomeMessageText}\n </h1>\n );\n };\n\n export const WelcomeScreen: React.FC<WelcomeScreenProps> = ({\n welcomeMessage,\n input,\n suggestionView,\n className,\n children,\n ...props\n }) => {\n // Render the welcomeMessage slot internally\n const BoundWelcomeMessage = renderSlot(\n welcomeMessage,\n CopilotChatView.WelcomeMessage,\n {},\n );\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n welcomeMessage: BoundWelcomeMessage,\n input,\n suggestionView,\n className,\n ...props,\n })}\n </div>\n );\n }\n\n return (\n <div\n data-testid=\"copilot-welcome-screen\"\n className={cn(\n \"cpk:flex-1 cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:px-4\",\n className,\n )}\n {...props}\n >\n <div className=\"cpk:w-full cpk:max-w-3xl cpk:flex cpk:flex-col cpk:items-center\">\n {/* Welcome message */}\n <div className=\"cpk:mb-6\">{BoundWelcomeMessage}</div>\n\n {/* Input */}\n <div className=\"cpk:w-full\">{input}</div>\n\n {/* Suggestions */}\n <div className=\"cpk:mt-4 cpk:flex cpk:justify-center\">\n {suggestionView}\n </div>\n </div>\n </div>\n );\n };\n}\n\nexport default CopilotChatView;\n","import type { CopilotKitCoreReact } from \"./react-core\";\nimport {\n TranscriptionErrorCode,\n type TranscriptionErrorResponse,\n} from \"@copilotkit/shared\";\n\nexport interface TranscriptionResult {\n text: string;\n size: number;\n type: string;\n}\n\n/**\n * Error info parsed from transcription endpoint error responses.\n */\nexport interface TranscriptionErrorInfo {\n code: TranscriptionErrorCode;\n message: string;\n retryable: boolean;\n}\n\n// Re-export error code enum for convenience\nexport { TranscriptionErrorCode };\n\n/**\n * Convert a Blob to a base64 string\n */\nasync function blobToBase64(blob: Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => {\n const result = reader.result as string;\n // Remove the data URL prefix to get pure base64\n const base64 = result.split(\",\")[1];\n resolve(base64 ?? \"\");\n };\n reader.onerror = () => reject(new Error(\"Failed to read audio data\"));\n reader.readAsDataURL(blob);\n });\n}\n\n/**\n * Check if an error response matches our expected format\n */\nfunction isTranscriptionErrorResponse(\n data: unknown,\n): data is TranscriptionErrorResponse {\n return (\n typeof data === \"object\" &&\n data !== null &&\n \"error\" in data &&\n \"message\" in data &&\n typeof (data as TranscriptionErrorResponse).error === \"string\" &&\n typeof (data as TranscriptionErrorResponse).message === \"string\"\n );\n}\n\n/**\n * Parse error info from a transcription error response\n */\nfunction parseTranscriptionError(\n response: TranscriptionErrorResponse,\n): TranscriptionErrorInfo {\n return {\n code: response.error,\n message: response.message,\n retryable: response.retryable ?? false,\n };\n}\n\n/**\n * Custom error type for transcription failures.\n * Extends Error with transcription-specific info for contextual error handling.\n */\nexport class TranscriptionError extends Error {\n public readonly info: TranscriptionErrorInfo;\n\n constructor(info: TranscriptionErrorInfo) {\n super(info.message);\n this.name = \"TranscriptionError\";\n this.info = info;\n }\n}\n\n/**\n * Transcribe an audio blob using the CopilotKit runtime\n *\n * Supports both REST mode (multipart/form-data) and single-endpoint mode (base64 JSON)\n *\n * @throws {TranscriptionError} When transcription fails with typed error information\n */\nexport async function transcribeAudio(\n core: CopilotKitCoreReact,\n audioBlob: Blob,\n filename: string = \"recording.webm\",\n): Promise<TranscriptionResult> {\n const runtimeUrl = core.runtimeUrl;\n if (!runtimeUrl) {\n throw new TranscriptionError({\n code: TranscriptionErrorCode.INVALID_REQUEST,\n message: \"Runtime URL is not configured\",\n retryable: false,\n });\n }\n\n const headers: Record<string, string> = { ...core.headers };\n let response: Response;\n\n try {\n if (core.runtimeTransport === \"single\") {\n // Single-endpoint mode: POST JSON with base64 audio\n const base64Audio = await blobToBase64(audioBlob);\n\n headers[\"Content-Type\"] = \"application/json\";\n\n response = await fetch(runtimeUrl, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n method: \"transcribe\",\n body: {\n audio: base64Audio,\n mimeType: audioBlob.type || \"audio/webm\",\n filename,\n },\n }),\n });\n } else {\n // REST mode: POST multipart/form-data to /transcribe\n // Don't set Content-Type - browser will set it with boundary for FormData\n delete headers[\"Content-Type\"];\n\n const formData = new FormData();\n formData.append(\"audio\", audioBlob, filename);\n\n response = await fetch(`${runtimeUrl}/transcribe`, {\n method: \"POST\",\n headers,\n body: formData,\n });\n }\n } catch (error) {\n // Network error - fetch failed\n throw new TranscriptionError({\n code: TranscriptionErrorCode.NETWORK_ERROR,\n message:\n error instanceof Error ? error.message : \"Network request failed\",\n retryable: true,\n });\n }\n\n if (!response.ok) {\n let errorData: unknown;\n try {\n errorData = await response.json();\n } catch {\n // Could not parse error response\n throw new TranscriptionError({\n code: TranscriptionErrorCode.PROVIDER_ERROR,\n message: `HTTP ${response.status}: ${response.statusText}`,\n retryable: response.status >= 500,\n });\n }\n\n // If we got a typed error response, use it\n if (isTranscriptionErrorResponse(errorData)) {\n throw new TranscriptionError(parseTranscriptionError(errorData));\n }\n\n // Unknown error format\n throw new TranscriptionError({\n code: TranscriptionErrorCode.PROVIDER_ERROR,\n message:\n typeof errorData === \"object\" &&\n errorData !== null &&\n \"message\" in errorData\n ? String((errorData as { message: unknown }).message)\n : \"Transcription failed\",\n retryable: response.status >= 500,\n });\n }\n\n return (await response.json()) as TranscriptionResult;\n}\n","import { useAgent } from \"../../hooks/use-agent\";\nimport { useAttachments } from \"../../hooks/use-attachments\";\nimport { useSuggestions } from \"../../hooks/use-suggestions\";\nimport { CopilotChatView, CopilotChatViewProps } from \"./CopilotChatView\";\nimport { CopilotChatInputMode } from \"./CopilotChatInput\";\nimport {\n CopilotChatConfigurationProvider,\n CopilotChatLabels,\n useCopilotChatConfiguration,\n} from \"../../providers/CopilotChatConfigurationProvider\";\nimport {\n DEFAULT_AGENT_ID,\n randomUUID,\n TranscriptionErrorCode,\n} from \"@copilotkit/shared\";\nimport type { AttachmentsConfig, InputContent } from \"@copilotkit/shared\";\nimport { Suggestion, CopilotKitCoreErrorCode } from \"@copilotkit/core\";\nimport React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n useCopilotKit,\n useLicenseContext,\n} from \"../../providers/CopilotKitProvider\";\nimport { InlineFeatureWarning } from \"../../components/license-warning-banner\";\nimport { AbstractAgent, HttpAgent } from \"@ag-ui/client\";\nimport { renderSlot, useShallowStableRef, SlotValue } from \"../../lib/slots\";\nimport {\n transcribeAudio,\n TranscriptionError,\n} from \"../../lib/transcription-client\";\n\nexport type CopilotChatProps = Omit<\n CopilotChatViewProps,\n | \"messages\"\n | \"isRunning\"\n | \"suggestions\"\n | \"suggestionLoadingIndexes\"\n | \"onSelectSuggestion\"\n // Attachment state props — managed internally based on `attachments` config\n | \"attachments\"\n | \"onRemoveAttachment\"\n | \"onAddFile\"\n | \"dragOver\"\n | \"onDragOver\"\n | \"onDragLeave\"\n | \"onDrop\"\n> & {\n agentId?: string;\n threadId?: string;\n labels?: Partial<CopilotChatLabels>;\n chatView?: SlotValue<typeof CopilotChatView>;\n isModalDefaultOpen?: boolean;\n /** Enable multimodal file attachments (images, audio, video, documents). */\n attachments?: AttachmentsConfig;\n /**\n * Error handler scoped to this chat's agent. Fires in addition to the\n * provider-level onError (does not suppress it). Receives only errors\n * whose context.agentId matches this chat's agent.\n */\n onError?: (event: {\n error: Error;\n code: CopilotKitCoreErrorCode;\n context: Record<string, any>;\n }) => void | Promise<void>;\n /**\n * Throttle interval (in milliseconds) for re-renders triggered by message\n * change notifications. Overrides the provider-level `defaultThrottleMs`\n * for this chat instance. Forwarded to the internal `useAgent()` hook,\n * which resolves the effective throttle value.\n *\n * @default undefined — inherits from provider `defaultThrottleMs`;\n * if that is also unset, re-renders are unthrottled. Note: passing\n * `throttleMs={0}` explicitly disables throttling for this instance\n * even when the provider specifies a non-zero `defaultThrottleMs`.\n */\n throttleMs?: number;\n};\nexport function CopilotChat({\n agentId,\n threadId,\n labels,\n chatView,\n isModalDefaultOpen,\n attachments: attachmentsConfig,\n onError,\n throttleMs,\n ...props\n}: CopilotChatProps) {\n // Check for existing configuration provider\n const existingConfig = useCopilotChatConfiguration();\n\n // Apply priority: props > existing config > defaults\n const resolvedAgentId =\n agentId ?? existingConfig?.agentId ?? DEFAULT_AGENT_ID;\n const resolvedThreadId = useMemo(\n () => threadId ?? existingConfig?.threadId ?? randomUUID(),\n [threadId, existingConfig?.threadId],\n );\n\n const { agent } = useAgent({\n agentId: resolvedAgentId,\n threadId: resolvedThreadId,\n throttleMs,\n });\n const { copilotkit } = useCopilotKit();\n const { suggestions: autoSuggestions } = useSuggestions({\n agentId: resolvedAgentId,\n });\n\n const { checkFeature } = useLicenseContext();\n const isChatLicensed = checkFeature(\"chat\");\n\n useEffect(() => {\n if (!isChatLicensed) {\n console.warn(\n '[CopilotKit] Warning: \"chat\" feature is not licensed. Visit copilotkit.ai/pricing',\n );\n }\n }, [isChatLicensed]);\n\n // onError subscription — forward core errors scoped to this chat's agent\n const onErrorRef = useRef(onError);\n useEffect(() => {\n onErrorRef.current = onError;\n }, [onError]);\n\n useEffect(() => {\n if (!onErrorRef.current) return;\n\n const subscription = copilotkit.subscribe({\n onError: (event) => {\n // Only forward errors that match this chat's agent\n if (\n event.context?.agentId === resolvedAgentId ||\n !event.context?.agentId\n ) {\n onErrorRef.current?.({\n error: event.error,\n code: event.code,\n context: event.context,\n });\n }\n },\n });\n\n return () => {\n subscription.unsubscribe();\n };\n }, [copilotkit, resolvedAgentId]);\n\n // Transcription state\n const [transcribeMode, setTranscribeMode] =\n useState<CopilotChatInputMode>(\"input\");\n const [inputValue, setInputValue] = useState(\"\");\n const [transcriptionError, setTranscriptionError] = useState<string | null>(\n null,\n );\n const [isTranscribing, setIsTranscribing] = useState(false);\n\n // Attachments\n const {\n attachments: selectedAttachments,\n enabled: attachmentsEnabled,\n dragOver,\n fileInputRef,\n containerRef: chatContainerRef,\n handleFileUpload,\n handleDragOver,\n handleDragLeave,\n handleDrop,\n removeAttachment,\n consumeAttachments,\n } = useAttachments({ config: attachmentsConfig });\n\n // Check if transcription is enabled\n const isTranscriptionEnabled = copilotkit.audioFileTranscriptionEnabled;\n\n // Check if browser supports MediaRecorder\n const isMediaRecorderSupported =\n typeof window !== \"undefined\" && typeof MediaRecorder !== \"undefined\";\n\n const {\n messageView: providedMessageView,\n suggestionView: providedSuggestionView,\n onStop: providedStopHandler,\n ...restProps\n } = props;\n\n useEffect(() => {\n let detached = false;\n\n // Create a fresh AbortController so we can cancel the HTTP request on cleanup.\n // HttpAgent (parent of ProxiedCopilotRuntimeAgent) uses this.abortController.signal\n // in its fetch config. Unlike runAgent(), connectAgent() does NOT create a new\n // AbortController automatically, so we must set one before connecting.\n const connectAbortController = new AbortController();\n if (agent instanceof HttpAgent) {\n agent.abortController = connectAbortController;\n }\n\n const connect = async (agent: AbstractAgent) => {\n try {\n await copilotkit.connectAgent({ agent });\n } catch (error) {\n // Ignore errors from aborted connections (e.g., React StrictMode cleanup)\n if (detached) return;\n // connectAgent already emits via the subscriber system, but catch\n // here to prevent unhandled rejections from unexpected errors.\n console.error(\"CopilotChat: connectAgent failed\", error);\n }\n };\n connect(agent);\n return () => {\n // Abort the HTTP request and detach the active run.\n // This is critical for React StrictMode which unmounts+remounts in dev,\n // preventing duplicate /connect requests from reaching the server.\n detached = true;\n connectAbortController.abort();\n // The .catch() is required to prevent a false-positive \"Uncaught (in promise)\n // AbortError\" in browser devtools. detachActiveRun() itself does not reject,\n // but without an attached handler V8 flags the promise chain as unhandled\n // when the abort signal propagates through connected promises internally.\n void agent.detachActiveRun().catch(() => {});\n };\n // copilotkit is intentionally excluded — it is a stable ref that never changes.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [resolvedThreadId, agent, resolvedAgentId]);\n\n const onSubmitInput = useCallback(\n async (value: string) => {\n // Block if uploads in progress\n const hasUploading = selectedAttachments.some(\n (a) => a.status === \"uploading\",\n );\n if (hasUploading) {\n console.error(\n \"[CopilotKit] Cannot send while attachments are uploading\",\n );\n return;\n }\n\n const readyAttachments = consumeAttachments();\n\n if (readyAttachments.length > 0) {\n const contentParts: InputContent[] = [];\n if (value.trim()) {\n contentParts.push({ type: \"text\", text: value });\n }\n for (const att of readyAttachments) {\n contentParts.push({\n type: att.type,\n source: att.source,\n metadata: {\n ...(att.filename ? { filename: att.filename } : {}),\n ...att.metadata,\n },\n } as InputContent);\n }\n agent.addMessage({\n id: randomUUID(),\n role: \"user\",\n content: contentParts,\n });\n } else {\n agent.addMessage({\n id: randomUUID(),\n role: \"user\",\n content: value,\n });\n }\n\n // Clear input after submitting\n setInputValue(\"\");\n try {\n await copilotkit.runAgent({ agent });\n } catch (error) {\n console.error(\"CopilotChat: runAgent failed\", error);\n }\n },\n // copilotkit is intentionally excluded — it is a stable ref that never changes.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [agent, selectedAttachments, consumeAttachments],\n );\n\n const handleSelectSuggestion = useCallback(\n async (suggestion: Suggestion) => {\n agent.addMessage({\n id: randomUUID(),\n role: \"user\",\n content: suggestion.message,\n });\n\n try {\n await copilotkit.runAgent({ agent });\n } catch (error) {\n console.error(\n \"CopilotChat: runAgent failed after selecting suggestion\",\n error,\n );\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [agent],\n );\n\n const stopCurrentRun = useCallback(() => {\n try {\n copilotkit.stopAgent({ agent });\n } catch (error) {\n console.error(\"CopilotChat: stopAgent failed\", error);\n try {\n agent.abortRun();\n } catch (abortError) {\n console.error(\"CopilotChat: abortRun fallback failed\", abortError);\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agent]);\n\n // Transcription handlers\n const handleStartTranscribe = useCallback(() => {\n setTranscriptionError(null);\n setTranscribeMode(\"transcribe\");\n }, []);\n\n const handleCancelTranscribe = useCallback(() => {\n setTranscriptionError(null);\n setTranscribeMode(\"input\");\n }, []);\n\n const handleFinishTranscribe = useCallback(() => {\n setTranscribeMode(\"input\");\n }, []);\n\n // Handle audio blob from CopilotChatInput and transcribe it\n const handleFinishTranscribeWithAudio = useCallback(\n async (audioBlob: Blob) => {\n setIsTranscribing(true);\n try {\n setTranscriptionError(null);\n\n // Send to transcription endpoint\n const result = await transcribeAudio(copilotkit, audioBlob);\n\n // Insert transcribed text into input\n setInputValue((prev) => {\n const trimmedPrev = prev.trim();\n if (trimmedPrev) {\n return `${trimmedPrev} ${result.text}`;\n }\n return result.text;\n });\n } catch (error) {\n console.error(\"CopilotChat: Transcription failed\", error);\n\n // Show contextual error message based on error type\n if (error instanceof TranscriptionError) {\n const { code, retryable, message } = error.info;\n switch (code) {\n case TranscriptionErrorCode.RATE_LIMITED:\n setTranscriptionError(\"Too many requests. Please wait a moment.\");\n break;\n case TranscriptionErrorCode.AUTH_FAILED:\n setTranscriptionError(\n \"Authentication error. Please check your configuration.\",\n );\n break;\n case TranscriptionErrorCode.AUDIO_TOO_LONG:\n setTranscriptionError(\n \"Recording is too long. Please try a shorter recording.\",\n );\n break;\n case TranscriptionErrorCode.AUDIO_TOO_SHORT:\n setTranscriptionError(\n \"Recording is too short. Please try again.\",\n );\n break;\n case TranscriptionErrorCode.INVALID_AUDIO_FORMAT:\n setTranscriptionError(\"Audio format not supported.\");\n break;\n case TranscriptionErrorCode.SERVICE_NOT_CONFIGURED:\n setTranscriptionError(\"Transcription service is not available.\");\n break;\n case TranscriptionErrorCode.NETWORK_ERROR:\n setTranscriptionError(\n \"Network error. Please check your connection.\",\n );\n break;\n default:\n // For retryable errors, show more helpful message\n setTranscriptionError(\n retryable ? \"Transcription failed. Please try again.\" : message,\n );\n }\n } else {\n // Fallback for unexpected errors\n setTranscriptionError(\"Transcription failed. Please try again.\");\n }\n } finally {\n setIsTranscribing(false);\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n );\n\n // Clear transcription error after a delay\n useEffect(() => {\n if (transcriptionError) {\n const timer = setTimeout(() => {\n setTranscriptionError(null);\n }, 5000);\n return () => clearTimeout(timer);\n }\n }, [transcriptionError]);\n\n // Stabilize slot object references so inline props (new object reference on\n // every parent render) don't defeat MemoizedSlotWrapper's shallow equality\n // check and cause unnecessary re-renders of the message list on each keystroke.\n const stableMessageView = useShallowStableRef(\n typeof providedMessageView === \"string\"\n ? { className: providedMessageView }\n : providedMessageView,\n );\n const stableSuggestionView = useShallowStableRef(providedSuggestionView);\n\n // Stabilize the `onAddFile` handler. Without useCallback, a new arrow\n // function is created inline on every render, causing CopilotChatView to\n // re-render on every keystroke even when nothing else changed.\n const handleAddFile = useCallback(() => {\n // Delay to let Radix dropdown menu close before triggering file input\n setTimeout(() => {\n fileInputRef.current?.click();\n }, 100);\n }, []);\n\n // Use shallow spread instead of ts-deepmerge. ts-deepmerge deep-clones plain\n // objects even from a single source, which would defeat the reference\n // stability we just established for stableMessageView and other slot values.\n const mergedProps: Partial<CopilotChatViewProps> = {\n isRunning: agent.isRunning,\n suggestions: autoSuggestions,\n onSelectSuggestion: handleSelectSuggestion,\n suggestionView: stableSuggestionView,\n ...restProps,\n };\n if (stableMessageView !== undefined)\n mergedProps.messageView = stableMessageView;\n\n const hasMessages = agent.messages.length > 0;\n const shouldAllowStop = agent.isRunning && hasMessages;\n const effectiveStopHandler = shouldAllowStop\n ? (providedStopHandler ?? stopCurrentRun)\n : providedStopHandler;\n\n // Determine if transcription feature should be available\n const showTranscription = isTranscriptionEnabled && isMediaRecorderSupported;\n\n // Determine mode: transcribing takes priority, then transcribe mode, then default to input\n const effectiveMode: CopilotChatInputMode = isTranscribing\n ? \"processing\"\n : transcribeMode;\n\n // Memoize messages array — only create a new reference when content changes.\n // We build a lightweight fingerprint instead of JSON.stringify to avoid\n // serializing large base64 attachment data on every render. The key captures:\n // - message id, role, content length (text streaming)\n // - content part count (multimodal additions)\n // - tool call ids + argument lengths (tool call streaming)\n const messagesMemoKey = agent.messages\n .map((m) => {\n const contentKey =\n typeof m.content === \"string\"\n ? m.content.length\n : Array.isArray(m.content)\n ? m.content.length\n : 0;\n const toolCallsKey =\n \"toolCalls\" in m && Array.isArray(m.toolCalls)\n ? m.toolCalls\n .map(\n (tc: any) => `${tc.id}:${tc.function?.arguments?.length ?? 0}`,\n )\n .join(\";\")\n : \"\";\n return `${m.id}:${m.role}:${contentKey}:${toolCallsKey}`;\n })\n .join(\",\");\n const messages = useMemo(\n () => [...agent.messages],\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [messagesMemoKey],\n );\n\n const finalProps: CopilotChatViewProps = {\n ...mergedProps,\n messages,\n // Input behavior props\n onSubmitMessage: onSubmitInput,\n onStop: effectiveStopHandler,\n inputMode: effectiveMode,\n inputValue,\n onInputChange: setInputValue,\n // Only provide transcription handlers if feature is available\n onStartTranscribe: showTranscription ? handleStartTranscribe : undefined,\n onCancelTranscribe: showTranscription ? handleCancelTranscribe : undefined,\n onFinishTranscribe: showTranscription ? handleFinishTranscribe : undefined,\n onFinishTranscribeWithAudio: showTranscription\n ? handleFinishTranscribeWithAudio\n : undefined,\n // Attachment props\n attachments: selectedAttachments,\n onRemoveAttachment: removeAttachment,\n onAddFile: attachmentsEnabled ? handleAddFile : undefined,\n dragOver,\n onDragOver: handleDragOver,\n onDragLeave: handleDragLeave,\n onDrop: handleDrop,\n };\n\n // Always create a provider with merged values\n // This ensures priority: props > existing config > defaults\n const RenderedChatView = renderSlot(chatView, CopilotChatView, finalProps);\n\n return (\n <CopilotChatConfigurationProvider\n agentId={resolvedAgentId}\n threadId={resolvedThreadId}\n labels={labels}\n isModalDefaultOpen={isModalDefaultOpen}\n >\n <div ref={chatContainerRef} style={{ display: \"contents\" }}>\n {attachmentsEnabled && (\n <input\n type=\"file\"\n multiple\n ref={fileInputRef}\n onChange={handleFileUpload}\n accept={attachmentsConfig?.accept ?? \"*/*\"}\n style={{ display: \"none\" }}\n />\n )}\n {!isChatLicensed && <InlineFeatureWarning featureName=\"Chat\" />}\n {transcriptionError && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100px\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n backgroundColor: \"#ef4444\",\n color: \"white\",\n padding: \"8px 16px\",\n borderRadius: \"8px\",\n fontSize: \"14px\",\n zIndex: 50,\n }}\n >\n {transcriptionError}\n </div>\n )}\n {RenderedChatView}\n </div>\n </CopilotChatConfigurationProvider>\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotChat {\n export const View = CopilotChatView;\n}\n","import React, { useState, MouseEvent } from \"react\";\nimport { MessageCircle, X } from \"lucide-react\";\n\nimport { renderSlot, SlotValue } from \"../../lib/slots\";\nimport { cn } from \"../../lib/utils\";\nimport {\n CopilotChatDefaultLabels,\n useCopilotChatConfiguration,\n} from \"../../providers/CopilotChatConfigurationProvider\";\n\nconst DefaultOpenIcon: React.FC<React.SVGProps<SVGSVGElement>> = ({\n className,\n ...props\n}) => (\n <MessageCircle\n className={cn(\"cpk:h-6 cpk:w-6\", className)}\n strokeWidth={1.75}\n fill=\"currentColor\"\n {...props}\n />\n);\n\nconst DefaultCloseIcon: React.FC<React.SVGProps<SVGSVGElement>> = ({\n className,\n ...props\n}) => (\n <X\n className={cn(\"cpk:h-6 cpk:w-6\", className)}\n strokeWidth={1.75}\n {...props}\n />\n);\n\nDefaultOpenIcon.displayName = \"CopilotChatToggleButton.OpenIcon\";\nDefaultCloseIcon.displayName = \"CopilotChatToggleButton.CloseIcon\";\n\nexport interface CopilotChatToggleButtonProps extends Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n \"children\"\n> {\n /** Optional slot override for the chat (closed) icon. */\n openIcon?: SlotValue<typeof DefaultOpenIcon>;\n /** Optional slot override for the close icon. */\n closeIcon?: SlotValue<typeof DefaultCloseIcon>;\n}\n\nconst ICON_TRANSITION_STYLE: React.CSSProperties = Object.freeze({\n transition:\n \"opacity 120ms ease-out, transform 260ms cubic-bezier(0.22, 1, 0.36, 1)\",\n});\n\nconst ICON_WRAPPER_BASE =\n \"cpk:pointer-events-none cpk:absolute cpk:inset-0 cpk:flex cpk:items-center cpk:justify-center cpk:will-change-transform\";\n\nconst BUTTON_BASE_CLASSES = cn(\n \"copilotKitButton\",\n \"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\",\n \"cpk:rounded-full cpk:border cpk:border-primary cpk:bg-primary cpk:text-primary-foreground\",\n \"cpk:shadow-sm cpk:transition-all cpk:duration-200 cpk:ease-out\",\n \"cpk:hover:scale-[1.04] cpk:hover:shadow-md\",\n \"cpk:cursor-pointer\",\n \"cpk:active:scale-[0.96]\",\n \"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\",\n \"cpk:disabled:pointer-events-none cpk:disabled:opacity-60\",\n);\n\nexport const CopilotChatToggleButton = React.forwardRef<\n HTMLButtonElement,\n CopilotChatToggleButtonProps\n>(function CopilotChatToggleButton(\n { openIcon, closeIcon, className, ...buttonProps },\n ref,\n) {\n const { onClick, type, disabled, ...restProps } = buttonProps;\n\n const configuration = useCopilotChatConfiguration();\n const labels = configuration?.labels ?? CopilotChatDefaultLabels;\n\n const [fallbackOpen, setFallbackOpen] = useState(false);\n\n const isOpen = configuration?.isModalOpen ?? fallbackOpen;\n const setModalOpen = configuration?.setModalOpen ?? setFallbackOpen;\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n if (disabled) {\n return;\n }\n\n if (onClick) {\n onClick(event);\n }\n\n if (event.defaultPrevented) {\n return;\n }\n\n const nextOpen = !isOpen;\n setModalOpen(nextOpen);\n };\n\n const renderedOpenIcon = renderSlot(openIcon, DefaultOpenIcon, {\n className: \"cpk:h-6 cpk:w-6\",\n \"aria-hidden\": true,\n focusable: false,\n });\n\n const renderedCloseIcon = renderSlot(closeIcon, DefaultCloseIcon, {\n className: \"cpk:h-6 cpk:w-6\",\n \"aria-hidden\": true,\n focusable: false,\n });\n\n const openIconElement = (\n <span\n aria-hidden=\"true\"\n data-slot=\"chat-toggle-button-open-icon\"\n className={ICON_WRAPPER_BASE}\n style={{\n ...ICON_TRANSITION_STYLE,\n opacity: isOpen ? 0 : 1,\n transform: `scale(${isOpen ? 0.75 : 1}) rotate(${isOpen ? 90 : 0}deg)`,\n }}\n >\n {renderedOpenIcon}\n </span>\n );\n\n const closeIconElement = (\n <span\n aria-hidden=\"true\"\n data-slot=\"chat-toggle-button-close-icon\"\n className={ICON_WRAPPER_BASE}\n style={{\n ...ICON_TRANSITION_STYLE,\n opacity: isOpen ? 1 : 0,\n transform: `scale(${isOpen ? 1 : 0.75}) rotate(${isOpen ? 0 : -90}deg)`,\n }}\n >\n {renderedCloseIcon}\n </span>\n );\n\n return (\n <button\n ref={ref}\n type={type ?? \"button\"}\n data-copilotkit\n data-testid=\"copilot-chat-toggle\"\n data-slot=\"chat-toggle-button\"\n data-state={isOpen ? \"open\" : \"closed\"}\n className={cn(BUTTON_BASE_CLASSES, className)}\n aria-label={\n isOpen ? labels.chatToggleCloseLabel : labels.chatToggleOpenLabel\n }\n aria-pressed={isOpen}\n disabled={disabled}\n onClick={handleClick}\n {...restProps}\n >\n {openIconElement}\n {closeIconElement}\n </button>\n );\n});\nCopilotChatToggleButton.displayName = \"CopilotChatToggleButton\";\nexport default CopilotChatToggleButton;\n\nexport {\n DefaultOpenIcon as CopilotChatToggleButtonOpenIcon,\n DefaultCloseIcon as CopilotChatToggleButtonCloseIcon,\n};\n","import React, { useCallback } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\nimport {\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"../../providers/CopilotChatConfigurationProvider\";\nimport { renderSlot, WithSlots } from \"../../lib/slots\";\nimport { X } from \"lucide-react\";\n\ntype HeaderSlots = {\n titleContent: typeof CopilotModalHeader.Title;\n closeButton: typeof CopilotModalHeader.CloseButton;\n};\n\ntype HeaderRestProps = {\n title?: string;\n} & Omit<React.HTMLAttributes<HTMLDivElement>, \"children\">;\n\nexport type CopilotModalHeaderProps = WithSlots<HeaderSlots, HeaderRestProps>;\n\nexport function CopilotModalHeader({\n title,\n titleContent,\n closeButton,\n children,\n className,\n ...rest\n}: CopilotModalHeaderProps) {\n const configuration = useCopilotChatConfiguration();\n\n const fallbackTitle =\n configuration?.labels.modalHeaderTitle ??\n CopilotChatDefaultLabels.modalHeaderTitle;\n const resolvedTitle = title ?? fallbackTitle;\n\n const handleClose = useCallback(() => {\n configuration?.setModalOpen?.(false);\n }, [configuration]);\n\n const BoundTitle = renderSlot(titleContent, CopilotModalHeader.Title, {\n children: resolvedTitle,\n });\n\n const BoundCloseButton = renderSlot(\n closeButton,\n CopilotModalHeader.CloseButton,\n {\n onClick: handleClose,\n },\n );\n\n if (children) {\n return children({\n titleContent: BoundTitle,\n closeButton: BoundCloseButton,\n title: resolvedTitle,\n ...rest,\n });\n }\n\n return (\n <header\n data-testid=\"copilot-modal-header\"\n data-slot=\"copilot-modal-header\"\n className={cn(\n \"copilotKitHeader\",\n \"cpk:flex cpk:items-center cpk:justify-between cpk:border-b cpk:border-border cpk:px-4 cpk:py-4\",\n \"cpk:bg-background/95 cpk:backdrop-blur cpk:supports-[backdrop-filter]:bg-background/80\",\n className,\n )}\n {...rest}\n >\n <div className=\"cpk:flex cpk:w-full cpk:items-center cpk:gap-2\">\n <div className=\"cpk:flex-1\" aria-hidden=\"true\" />\n <div className=\"cpk:flex cpk:flex-1 cpk:justify-center cpk:text-center\">\n {BoundTitle}\n </div>\n <div className=\"cpk:flex cpk:flex-1 cpk:justify-end\">\n {BoundCloseButton}\n </div>\n </div>\n </header>\n );\n}\n\nCopilotModalHeader.displayName = \"CopilotModalHeader\";\n\nexport namespace CopilotModalHeader {\n export const Title: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n children,\n className,\n ...props\n }) => (\n <div\n data-testid=\"copilot-header-title\"\n className={cn(\n \"cpk:w-full cpk:text-base cpk:font-medium cpk:leading-none cpk:tracking-tight cpk:text-foreground\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n );\n\n export const CloseButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, ...props }) => (\n <button\n type=\"button\"\n data-testid=\"copilot-close-button\"\n className={cn(\n \"cpk:inline-flex cpk:size-8 cpk:items-center cpk:justify-center cpk:rounded-full cpk:text-muted-foreground cpk:transition cpk:cursor-pointer\",\n \"cpk:hover:bg-muted cpk:hover:text-foreground cpk:focus-visible:outline-none cpk:focus-visible:ring-2 cpk:focus-visible:ring-ring\",\n className,\n )}\n aria-label=\"Close\"\n {...props}\n >\n <X className=\"cpk:h-4 cpk:w-4\" aria-hidden=\"true\" />\n </button>\n );\n}\n\nCopilotModalHeader.Title.displayName = \"CopilotModalHeader.Title\";\nCopilotModalHeader.CloseButton.displayName = \"CopilotModalHeader.CloseButton\";\n\nexport default CopilotModalHeader;\n","import React, { useEffect, useLayoutEffect, useRef, useState } from \"react\";\n\nimport CopilotChatView, {\n CopilotChatViewProps,\n WelcomeScreenProps,\n} from \"./CopilotChatView\";\nimport {\n CopilotChatConfigurationProvider,\n useCopilotChatConfiguration,\n} from \"../../providers/CopilotChatConfigurationProvider\";\nimport CopilotChatToggleButton from \"./CopilotChatToggleButton\";\nimport { cn } from \"../../lib/utils\";\nimport { CopilotModalHeader } from \"./CopilotModalHeader\";\nimport { renderSlot, SlotValue } from \"../../lib/slots\";\n\nconst DEFAULT_SIDEBAR_WIDTH = 480;\nconst SIDEBAR_TRANSITION_MS = 260;\n\nexport type CopilotSidebarViewProps = CopilotChatViewProps & {\n header?: SlotValue<typeof CopilotModalHeader>;\n toggleButton?: SlotValue<typeof CopilotChatToggleButton>;\n width?: number | string;\n defaultOpen?: boolean;\n};\n\nexport function CopilotSidebarView({\n header,\n toggleButton,\n width,\n defaultOpen = true,\n ...props\n}: CopilotSidebarViewProps) {\n return (\n <CopilotChatConfigurationProvider isModalDefaultOpen={defaultOpen}>\n <CopilotSidebarViewInternal\n header={header}\n toggleButton={toggleButton}\n width={width}\n {...props}\n />\n </CopilotChatConfigurationProvider>\n );\n}\n\nfunction CopilotSidebarViewInternal({\n header,\n toggleButton,\n width,\n ...props\n}: Omit<CopilotSidebarViewProps, \"defaultOpen\">) {\n const configuration = useCopilotChatConfiguration();\n\n const isSidebarOpen = configuration?.isModalOpen ?? false;\n\n const sidebarRef = useRef<HTMLDivElement | null>(null);\n const [sidebarWidth, setSidebarWidth] = useState<number | string>(\n width ?? DEFAULT_SIDEBAR_WIDTH,\n );\n\n // Helper to convert width to CSS value\n const widthToCss = (w: number | string): string => {\n return typeof w === \"number\" ? `${w}px` : w;\n };\n\n // Helper to extract numeric value for body margin (only works with px values)\n const widthToMargin = (w: number | string): string => {\n if (typeof w === \"number\") {\n return `${w}px`;\n }\n // For string values, use as-is (assumes valid CSS unit)\n return w;\n };\n\n useEffect(() => {\n // If width is explicitly provided, don't measure\n if (width !== undefined) {\n return;\n }\n\n if (typeof window === \"undefined\") {\n return;\n }\n\n const element = sidebarRef.current;\n if (!element) {\n return;\n }\n\n const updateWidth = () => {\n const rect = element.getBoundingClientRect();\n if (rect.width > 0) {\n setSidebarWidth(rect.width);\n }\n };\n\n updateWidth();\n\n if (typeof ResizeObserver !== \"undefined\") {\n const observer = new ResizeObserver(() => updateWidth());\n observer.observe(element);\n return () => observer.disconnect();\n }\n\n window.addEventListener(\"resize\", updateWidth);\n return () => window.removeEventListener(\"resize\", updateWidth);\n }, [width]);\n\n // Manage body margin for sidebar docking (desktop only).\n // useLayoutEffect runs before paint, so defaultOpen={true} never causes a\n // visible layout shift — the margin is already applied on the first frame.\n const hasMounted = useRef(false);\n\n useLayoutEffect(() => {\n if (\n typeof window === \"undefined\" ||\n typeof window.matchMedia !== \"function\"\n )\n return;\n if (!window.matchMedia(\"(min-width: 768px)\").matches) return;\n\n if (isSidebarOpen) {\n if (hasMounted.current) {\n document.body.style.transition = `margin-inline-end ${SIDEBAR_TRANSITION_MS}ms ease`;\n }\n document.body.style.marginInlineEnd = widthToMargin(sidebarWidth);\n } else if (hasMounted.current) {\n document.body.style.transition = `margin-inline-end ${SIDEBAR_TRANSITION_MS}ms ease`;\n document.body.style.marginInlineEnd = \"\";\n }\n\n hasMounted.current = true;\n\n return () => {\n document.body.style.marginInlineEnd = \"\";\n document.body.style.transition = \"\";\n };\n }, [isSidebarOpen, sidebarWidth]);\n\n const headerElement = renderSlot(header, CopilotModalHeader, {});\n const toggleButtonElement = renderSlot(\n toggleButton,\n CopilotChatToggleButton,\n {},\n );\n\n return (\n <>\n {toggleButtonElement}\n <aside\n ref={sidebarRef}\n data-copilotkit\n data-testid=\"copilot-sidebar\"\n data-copilot-sidebar\n className={cn(\n \"copilotKitSidebar copilotKitWindow\",\n \"cpk:fixed cpk:right-0 cpk:top-0 cpk:z-[1200] cpk:flex\",\n // Height with dvh fallback and safe area support\n \"cpk:h-[100vh] cpk:h-[100dvh] cpk:max-h-screen\",\n // Responsive width: full on mobile, custom on desktop\n \"cpk:w-full\",\n \"cpk:border-l cpk:border-border cpk:bg-background cpk:text-foreground cpk:shadow-xl\",\n \"cpk:transition-transform cpk:duration-300 cpk:ease-out\",\n isSidebarOpen\n ? \"cpk:translate-x-0\"\n : \"cpk:translate-x-full cpk:pointer-events-none\",\n )}\n style={\n {\n // Use CSS custom property for responsive width\n [\"--sidebar-width\" as string]: widthToCss(sidebarWidth),\n // Safe area insets for iOS\n paddingTop: \"env(safe-area-inset-top)\",\n paddingBottom: \"env(safe-area-inset-bottom)\",\n } as React.CSSProperties\n }\n aria-hidden={!isSidebarOpen}\n aria-label=\"Copilot chat sidebar\"\n role=\"complementary\"\n >\n <div className=\"cpk:flex cpk:h-full cpk:w-full cpk:flex-col cpk:overflow-hidden\">\n {headerElement}\n <div className=\"cpk:flex-1 cpk:overflow-hidden\" data-sidebar-chat>\n <CopilotChatView {...props} />\n </div>\n </div>\n </aside>\n </>\n );\n}\n\nCopilotSidebarView.displayName = \"CopilotSidebarView\";\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotSidebarView {\n /**\n * Sidebar-specific welcome screen layout:\n * - Suggestions at the top\n * - Welcome message in the middle\n * - Input fixed at the bottom (like normal chat)\n */\n export const WelcomeScreen: React.FC<WelcomeScreenProps> = ({\n welcomeMessage,\n input,\n suggestionView,\n className,\n children,\n ...props\n }) => {\n // Render the welcomeMessage slot internally\n const BoundWelcomeMessage = renderSlot(\n welcomeMessage,\n CopilotChatView.WelcomeMessage,\n {},\n );\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n welcomeMessage: BoundWelcomeMessage,\n input,\n suggestionView,\n className,\n ...props,\n })}\n </div>\n );\n }\n\n return (\n <div\n className={cn(\"cpk:h-full cpk:flex cpk:flex-col\", className)}\n {...props}\n >\n {/* Welcome message - centered vertically */}\n <div className=\"cpk:flex-1 cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:px-4\">\n {BoundWelcomeMessage}\n </div>\n\n {/* Suggestions and input at bottom */}\n <div className=\"cpk:px-8 cpk:pb-4\">\n <div className=\"cpk:max-w-3xl cpk:mx-auto\">\n {/* Suggestions above input */}\n <div className=\"cpk:mb-4 cpk:flex cpk:justify-center\">\n {suggestionView}\n </div>\n {input}\n </div>\n </div>\n </div>\n );\n };\n}\n\nexport default CopilotSidebarView;\n","import React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport CopilotChatView, {\n CopilotChatViewProps,\n WelcomeScreenProps,\n} from \"./CopilotChatView\";\nimport CopilotChatToggleButton from \"./CopilotChatToggleButton\";\nimport { CopilotModalHeader } from \"./CopilotModalHeader\";\nimport { cn } from \"../../lib/utils\";\nimport { renderSlot, SlotValue } from \"../../lib/slots\";\nimport {\n CopilotChatConfigurationProvider,\n CopilotChatDefaultLabels,\n useCopilotChatConfiguration,\n} from \"../../providers/CopilotChatConfigurationProvider\";\n\nconst DEFAULT_POPUP_WIDTH = 420;\nconst DEFAULT_POPUP_HEIGHT = 560;\n\nexport type CopilotPopupViewProps = CopilotChatViewProps & {\n header?: SlotValue<typeof CopilotModalHeader>;\n toggleButton?: SlotValue<typeof CopilotChatToggleButton>;\n width?: number | string;\n height?: number | string;\n clickOutsideToClose?: boolean;\n defaultOpen?: boolean;\n};\n\nconst dimensionToCss = (\n value: number | string | undefined,\n fallback: number,\n): string => {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return `${value}px`;\n }\n\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value;\n }\n\n return `${fallback}px`;\n};\n\nexport function CopilotPopupView({\n header,\n toggleButton,\n width,\n height,\n clickOutsideToClose,\n defaultOpen = true,\n className,\n ...restProps\n}: CopilotPopupViewProps) {\n return (\n <CopilotChatConfigurationProvider isModalDefaultOpen={defaultOpen}>\n <CopilotPopupViewInternal\n header={header}\n toggleButton={toggleButton}\n width={width}\n height={height}\n clickOutsideToClose={clickOutsideToClose}\n className={className}\n {...restProps}\n />\n </CopilotChatConfigurationProvider>\n );\n}\n\nfunction CopilotPopupViewInternal({\n header,\n toggleButton,\n width,\n height,\n clickOutsideToClose,\n className,\n ...restProps\n}: Omit<CopilotPopupViewProps, \"defaultOpen\">) {\n const configuration = useCopilotChatConfiguration();\n const isPopupOpen = configuration?.isModalOpen ?? false;\n const setModalOpen = configuration?.setModalOpen;\n const labels = configuration?.labels ?? CopilotChatDefaultLabels;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const [isRendered, setIsRendered] = useState(isPopupOpen);\n const [isAnimatingOut, setIsAnimatingOut] = useState(false);\n\n useEffect(() => {\n if (isPopupOpen) {\n setIsRendered(true);\n setIsAnimatingOut(false);\n return;\n }\n\n if (!isRendered) {\n return;\n }\n\n setIsAnimatingOut(true);\n const timeout = setTimeout(() => {\n setIsRendered(false);\n setIsAnimatingOut(false);\n }, 200);\n\n return () => clearTimeout(timeout);\n }, [isPopupOpen, isRendered]);\n\n useEffect(() => {\n if (!isPopupOpen) {\n return;\n }\n\n if (typeof window === \"undefined\") {\n return;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n setModalOpen?.(false);\n }\n };\n\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [isPopupOpen, setModalOpen]);\n\n useEffect(() => {\n if (!isPopupOpen) {\n return;\n }\n\n const focusTimer = setTimeout(() => {\n const container = containerRef.current;\n // Don't steal focus if something inside the popup (like the input) is already focused\n if (container && !container.contains(document.activeElement)) {\n container.focus({ preventScroll: true });\n }\n }, 200);\n\n return () => clearTimeout(focusTimer);\n }, [isPopupOpen]);\n\n useEffect(() => {\n if (!isPopupOpen || !clickOutsideToClose) {\n return;\n }\n\n if (typeof document === \"undefined\") {\n return;\n }\n\n const handlePointerDown = (event: PointerEvent) => {\n const target = event.target as Node | null;\n if (!target) {\n return;\n }\n\n const container = containerRef.current;\n if (container?.contains(target)) {\n return;\n }\n\n const toggleButton = document.querySelector(\n \"[data-slot='chat-toggle-button']\",\n );\n if (toggleButton && toggleButton.contains(target)) {\n return;\n }\n\n setModalOpen?.(false);\n };\n\n document.addEventListener(\"pointerdown\", handlePointerDown);\n return () => document.removeEventListener(\"pointerdown\", handlePointerDown);\n }, [isPopupOpen, clickOutsideToClose, setModalOpen]);\n\n const headerElement = useMemo(\n () => renderSlot(header, CopilotModalHeader, {}),\n [header],\n );\n const toggleButtonElement = useMemo(\n () => renderSlot(toggleButton, CopilotChatToggleButton, {}),\n [toggleButton],\n );\n\n const resolvedWidth = dimensionToCss(width, DEFAULT_POPUP_WIDTH);\n const resolvedHeight = dimensionToCss(height, DEFAULT_POPUP_HEIGHT);\n\n const popupStyle = useMemo(\n () =>\n ({\n \"--copilot-popup-width\": resolvedWidth,\n \"--copilot-popup-height\": resolvedHeight,\n \"--copilot-popup-max-width\": \"calc(100vw - 3rem)\",\n \"--copilot-popup-max-height\": \"calc(100dvh - 7.5rem)\",\n paddingTop: \"env(safe-area-inset-top)\",\n paddingBottom: \"env(safe-area-inset-bottom)\",\n paddingLeft: \"env(safe-area-inset-left)\",\n paddingRight: \"env(safe-area-inset-right)\",\n }) as React.CSSProperties,\n [resolvedHeight, resolvedWidth],\n );\n\n const popupAnimationClass =\n isPopupOpen && !isAnimatingOut\n ? \"cpk:pointer-events-auto cpk:translate-y-0 cpk:opacity-100 cpk:md:scale-100\"\n : \"cpk:pointer-events-none cpk:translate-y-4 cpk:opacity-0 cpk:md:translate-y-5 cpk:md:scale-[0.95]\";\n\n const popupContent = isRendered ? (\n <div\n data-copilotkit\n className={cn(\n \"cpk:fixed cpk:inset-0 cpk:z-[1200] cpk:flex cpk:max-w-full cpk:flex-col cpk:items-stretch\",\n \"cpk:md:inset-auto cpk:md:bottom-24 cpk:md:right-6 cpk:md:items-end cpk:md:gap-4\",\n )}\n >\n <div\n ref={containerRef}\n tabIndex={-1}\n role=\"dialog\"\n aria-label={labels.modalHeaderTitle}\n data-testid=\"copilot-popup\"\n data-copilot-popup\n className={cn(\n \"copilotKitPopup copilotKitWindow\",\n \"cpk:relative cpk:flex cpk:h-full cpk:w-full cpk:flex-col cpk:overflow-hidden cpk:bg-background cpk:text-foreground\",\n \"cpk:origin-bottom cpk:focus:outline-none cpk:transform-gpu cpk:transition-transform cpk:transition-opacity cpk:duration-200 cpk:ease-out\",\n \"cpk:md:transition-transform cpk:md:transition-opacity\",\n \"cpk:rounded-none cpk:border cpk:border-border/0 cpk:shadow-none cpk:ring-0\",\n \"cpk:md:h-[var(--copilot-popup-height)] cpk:md:w-[var(--copilot-popup-width)]\",\n \"cpk:md:max-h-[var(--copilot-popup-max-height)] cpk:md:max-w-[var(--copilot-popup-max-width)]\",\n \"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\",\n popupAnimationClass,\n )}\n style={popupStyle}\n >\n {headerElement}\n <div className=\"cpk:flex-1 cpk:overflow-hidden\" data-popup-chat>\n <CopilotChatView\n {...restProps}\n className={cn(\"cpk:h-full cpk:min-h-0\", className)}\n />\n </div>\n </div>\n </div>\n ) : null;\n\n return (\n <>\n {toggleButtonElement}\n {popupContent}\n </>\n );\n}\n\nCopilotPopupView.displayName = \"CopilotPopupView\";\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotPopupView {\n /**\n * Popup-specific welcome screen layout:\n * - Welcome message centered vertically\n * - Suggestions just above input\n * - Input fixed at the bottom\n */\n export const WelcomeScreen: React.FC<WelcomeScreenProps> = ({\n welcomeMessage,\n input,\n suggestionView,\n className,\n children,\n ...props\n }) => {\n // Render the welcomeMessage slot internally\n const BoundWelcomeMessage = renderSlot(\n welcomeMessage,\n CopilotChatView.WelcomeMessage,\n {},\n );\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n welcomeMessage: BoundWelcomeMessage,\n input,\n suggestionView,\n className,\n ...props,\n })}\n </div>\n );\n }\n\n return (\n <div\n className={cn(\"cpk:h-full cpk:flex cpk:flex-col\", className)}\n {...props}\n >\n {/* Welcome message - centered vertically */}\n <div className=\"cpk:flex-1 cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:px-4\">\n {BoundWelcomeMessage}\n </div>\n\n {/* Suggestions and input at bottom */}\n <div>\n {/* Suggestions above input */}\n <div className=\"cpk:mb-4 cpk:flex cpk:justify-center cpk:px-4\">\n {suggestionView}\n </div>\n {input}\n </div>\n </div>\n );\n };\n}\n\nexport default CopilotPopupView;\n","import React, { useEffect, useMemo } from \"react\";\nimport { useLicenseContext } from \"../../providers/CopilotKitProvider\";\nimport { InlineFeatureWarning } from \"../license-warning-banner\";\n\nimport { CopilotChat, CopilotChatProps } from \"./CopilotChat\";\nimport CopilotChatView, { CopilotChatViewProps } from \"./CopilotChatView\";\nimport {\n CopilotSidebarView,\n CopilotSidebarViewProps,\n} from \"./CopilotSidebarView\";\n\nexport type CopilotSidebarProps = Omit<CopilotChatProps, \"chatView\"> & {\n header?: CopilotSidebarViewProps[\"header\"];\n toggleButton?: CopilotSidebarViewProps[\"toggleButton\"];\n defaultOpen?: boolean;\n width?: number | string;\n};\n\nexport function CopilotSidebar({\n header,\n toggleButton,\n defaultOpen,\n width,\n ...chatProps\n}: CopilotSidebarProps) {\n const { checkFeature } = useLicenseContext();\n const isSidebarLicensed = checkFeature(\"sidebar\");\n\n useEffect(() => {\n if (!isSidebarLicensed) {\n console.warn(\n '[CopilotKit] Warning: \"sidebar\" feature is not licensed. Visit copilotkit.ai/pricing',\n );\n }\n }, [isSidebarLicensed]);\n\n const SidebarViewOverride = useMemo(() => {\n const Component: React.FC<CopilotChatViewProps> = (viewProps) => {\n const {\n header: viewHeader,\n toggleButton: viewToggleButton,\n width: viewWidth,\n defaultOpen: viewDefaultOpen,\n ...restProps\n } = viewProps as CopilotSidebarViewProps;\n\n return (\n <CopilotSidebarView\n {...(restProps as CopilotSidebarViewProps)}\n header={header ?? viewHeader}\n toggleButton={toggleButton ?? viewToggleButton}\n width={width ?? viewWidth}\n defaultOpen={defaultOpen ?? viewDefaultOpen}\n />\n );\n };\n\n return Object.assign(Component, CopilotChatView);\n }, [header, toggleButton, width, defaultOpen]);\n\n return (\n <>\n {!isSidebarLicensed && <InlineFeatureWarning featureName=\"Sidebar\" />}\n <CopilotChat\n welcomeScreen={CopilotSidebarView.WelcomeScreen}\n {...chatProps}\n isModalDefaultOpen={defaultOpen}\n chatView={SidebarViewOverride}\n />\n </>\n );\n}\n\nCopilotSidebar.displayName = \"CopilotSidebar\";\n\nexport default CopilotSidebar;\n","import React, { useEffect, useMemo } from \"react\";\nimport { useLicenseContext } from \"../../providers/CopilotKitProvider\";\nimport { InlineFeatureWarning } from \"../license-warning-banner\";\n\nimport { CopilotChat, CopilotChatProps } from \"./CopilotChat\";\nimport CopilotChatView, { CopilotChatViewProps } from \"./CopilotChatView\";\nimport CopilotPopupView, { CopilotPopupViewProps } from \"./CopilotPopupView\";\n\nexport type CopilotPopupProps = Omit<CopilotChatProps, \"chatView\"> & {\n header?: CopilotPopupViewProps[\"header\"];\n toggleButton?: CopilotPopupViewProps[\"toggleButton\"];\n defaultOpen?: boolean;\n width?: CopilotPopupViewProps[\"width\"];\n height?: CopilotPopupViewProps[\"height\"];\n clickOutsideToClose?: CopilotPopupViewProps[\"clickOutsideToClose\"];\n};\n\nexport function CopilotPopup({\n header,\n toggleButton,\n defaultOpen,\n width,\n height,\n clickOutsideToClose,\n ...chatProps\n}: CopilotPopupProps) {\n const { checkFeature } = useLicenseContext();\n const isPopupLicensed = checkFeature(\"popup\");\n\n useEffect(() => {\n if (!isPopupLicensed) {\n console.warn(\n '[CopilotKit] Warning: \"popup\" feature is not licensed. Visit copilotkit.ai/pricing',\n );\n }\n }, [isPopupLicensed]);\n\n const PopupViewOverride = useMemo(() => {\n const Component: React.FC<CopilotChatViewProps> = (viewProps) => {\n const {\n header: viewHeader,\n toggleButton: viewToggleButton,\n width: viewWidth,\n height: viewHeight,\n clickOutsideToClose: viewClickOutsideToClose,\n defaultOpen: viewDefaultOpen,\n ...restProps\n } = viewProps as CopilotPopupViewProps;\n\n return (\n <CopilotPopupView\n {...(restProps as CopilotPopupViewProps)}\n header={header ?? viewHeader}\n toggleButton={toggleButton ?? viewToggleButton}\n width={width ?? viewWidth}\n height={height ?? viewHeight}\n clickOutsideToClose={clickOutsideToClose ?? viewClickOutsideToClose}\n defaultOpen={defaultOpen ?? viewDefaultOpen}\n />\n );\n };\n\n return Object.assign(Component, CopilotChatView);\n }, [clickOutsideToClose, header, toggleButton, height, width, defaultOpen]);\n\n return (\n <>\n {!isPopupLicensed && <InlineFeatureWarning featureName=\"Popup\" />}\n <CopilotChat\n welcomeScreen={CopilotPopupView.WelcomeScreen}\n {...chatProps}\n isModalDefaultOpen={defaultOpen}\n chatView={PopupViewOverride}\n />\n </>\n );\n}\n\nCopilotPopup.displayName = \"CopilotPopup\";\n\nexport default CopilotPopup;\n","import { defineToolCallRenderer } from \"../types/defineToolCallRenderer\";\nimport { useState } from \"react\";\n\nexport const WildcardToolCallRender = defineToolCallRenderer({\n name: \"*\",\n render: ({ args, result, name, status }) => {\n const [isExpanded, setIsExpanded] = useState(false);\n\n const statusString = String(status) as\n | \"inProgress\"\n | \"executing\"\n | \"complete\";\n const isActive =\n statusString === \"inProgress\" || statusString === \"executing\";\n const isComplete = statusString === \"complete\";\n const statusStyles = isActive\n ? \"cpk:bg-amber-100 cpk:text-amber-800 cpk:dark:bg-amber-500/15 cpk:dark:text-amber-400\"\n : isComplete\n ? \"cpk:bg-emerald-100 cpk:text-emerald-800 cpk:dark:bg-emerald-500/15 cpk:dark:text-emerald-400\"\n : \"cpk:bg-zinc-100 cpk:text-zinc-800 cpk:dark:bg-zinc-700/40 cpk:dark:text-zinc-300\";\n\n return (\n <div className=\"cpk:mt-2 cpk:pb-2\">\n <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\">\n <div\n className=\"cpk:flex cpk:items-center cpk:justify-between cpk:gap-3 cpk:cursor-pointer\"\n onClick={() => setIsExpanded(!isExpanded)}\n >\n <div className=\"cpk:flex cpk:items-center cpk:gap-2 cpk:min-w-0\">\n <svg\n className={`cpk:h-4 cpk:w-4 cpk:text-zinc-500 cpk:dark:text-zinc-400 cpk:transition-transform ${\n isExpanded ? \"cpk:rotate-90\" : \"\"\n }`}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n strokeWidth={2}\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M8.25 4.5l7.5 7.5-7.5 7.5\"\n />\n </svg>\n <span className=\"cpk:inline-block cpk:h-2 cpk:w-2 cpk:rounded-full cpk:bg-blue-500\" />\n <span className=\"cpk:truncate cpk:text-sm cpk:font-medium cpk:text-zinc-900 cpk:dark:text-zinc-100\">\n {name}\n </span>\n </div>\n <span\n className={`cpk:inline-flex cpk:items-center cpk:rounded-full cpk:px-2 cpk:py-1 cpk:text-xs cpk:font-medium ${statusStyles}`}\n >\n {String(status)}\n </span>\n </div>\n\n {isExpanded && (\n <div className=\"cpk:mt-3 cpk:grid cpk:gap-4\">\n <div>\n <div className=\"cpk:text-xs cpk:uppercase cpk:tracking-wide cpk:text-zinc-500 cpk:dark:text-zinc-400\">\n Arguments\n </div>\n <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\">\n {JSON.stringify(args ?? {}, null, 2)}\n </pre>\n </div>\n\n {result !== undefined && (\n <div>\n <div className=\"cpk:text-xs cpk:uppercase cpk:tracking-wide cpk:text-zinc-500 cpk:dark:text-zinc-400\">\n Result\n </div>\n <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\">\n {typeof result === \"string\"\n ? result\n : JSON.stringify(result, null, 2)}\n </pre>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n },\n});\n","import {\n CopilotCloudConfig,\n FunctionCallHandler,\n CopilotErrorHandler,\n CopilotKitError,\n} from \"@copilotkit/shared\";\nimport {\n ActionRenderProps,\n CatchAllActionRenderProps,\n FrontendAction,\n} from \"../types/frontend-action\";\nimport React from \"react\";\nimport { TreeNodeId, Tree } from \"../hooks/use-tree\";\nimport { DocumentPointer } from \"../types\";\nimport { CopilotChatSuggestionConfiguration } from \"../types/chat-suggestion-configuration\";\nimport {\n CoAgentStateRender,\n CoAgentStateRenderProps,\n} from \"../types/coagent-action\";\nimport { CoagentState } from \"../types/coagent-state\";\nimport {\n CopilotRuntimeClient,\n ExtensionsInput,\n ForwardedParametersInput,\n} from \"@copilotkit/runtime-client-gql\";\nimport { Agent } from \"@copilotkit/runtime-client-gql\";\nimport {\n LangGraphInterruptRender,\n LangGraphInterruptActionSetter,\n QueuedInterruptEvent,\n} from \"../types/interrupt-action\";\n\n/**\n * Interface for the configuration of the Copilot API.\n */\nexport interface CopilotApiConfig {\n /**\n * The public API key for Copilot Cloud.\n */\n publicApiKey?: string;\n\n /**\n * The configuration for Copilot Cloud.\n */\n cloud?: CopilotCloudConfig;\n\n /**\n * The endpoint for the chat API.\n */\n chatApiEndpoint: string;\n\n /**\n * The endpoint for the Copilot transcribe audio service.\n */\n transcribeAudioUrl?: string;\n\n /**\n * The endpoint for the Copilot text to speech service.\n */\n textToSpeechUrl?: string;\n\n /**\n * additional headers to be sent with the request\n * @default {}\n * @example\n * ```\n * {\n * 'Authorization': 'Bearer your_token_here'\n * }\n * ```\n */\n headers: Record<string, string>;\n\n /**\n * Custom properties to be sent with the request\n * @default {}\n * @example\n * ```\n * {\n * 'user_id': 'user_id'\n * }\n * ```\n */\n properties?: Record<string, any>;\n\n /**\n * Indicates whether the user agent should send or receive cookies from the other domain\n * in the case of cross-origin requests.\n */\n credentials?: RequestCredentials;\n\n /**\n * Optional configuration for connecting to Model Context Protocol (MCP) servers.\n * This is typically derived from the CopilotKitProps and used internally.\n * @experimental\n */\n mcpServers?: Array<{ endpoint: string; apiKey?: string }>;\n}\n\nexport type InChatRenderFunction<\n TProps = ActionRenderProps<any> | CatchAllActionRenderProps<any>,\n> = (props: TProps) => string | React.JSX.Element;\nexport type CoagentInChatRenderFunction = (\n props: CoAgentStateRenderProps<any>,\n) => string | React.JSX.Element | undefined | null;\n\nexport interface ChatComponentsCache {\n actions: Record<string, InChatRenderFunction | string>;\n coAgentStateRenders: Record<string, CoagentInChatRenderFunction | string>;\n}\n\nexport interface AgentSession {\n agentName: string;\n threadId?: string;\n nodeName?: string;\n}\n\nexport interface AuthState {\n status: \"authenticated\" | \"unauthenticated\";\n authHeaders: Record<string, string>;\n userId?: string;\n metadata?: Record<string, any>;\n}\n\nexport type ActionName = string;\nexport type ContextTree = Tree;\n\nexport interface CopilotContextParams {\n // function-calling\n actions: Record<string, FrontendAction<any>>;\n setAction: (id: string, action: FrontendAction<any>) => void;\n removeAction: (id: string) => void;\n\n // registered actions for component-based rendering\n setRegisteredActions: (actionConfig: any) => string;\n removeRegisteredAction: (actionKey: string) => void;\n\n chatComponentsCache: React.RefObject<ChatComponentsCache>;\n\n getFunctionCallHandler: (\n customEntryPoints?: Record<string, FrontendAction<any>>,\n ) => FunctionCallHandler;\n\n // text context\n addContext: (\n context: string,\n parentId?: string,\n categories?: string[],\n ) => TreeNodeId;\n removeContext: (id: TreeNodeId) => void;\n getAllContext: () => Tree;\n getContextString: (\n documents: DocumentPointer[],\n categories: string[],\n ) => string;\n\n // document context\n addDocumentContext: (\n documentPointer: DocumentPointer,\n categories?: string[],\n ) => TreeNodeId;\n removeDocumentContext: (documentId: string) => void;\n getDocumentsContext: (categories: string[]) => DocumentPointer[];\n\n isLoading: boolean;\n setIsLoading: React.Dispatch<React.SetStateAction<boolean>>;\n\n chatSuggestionConfiguration: {\n [key: string]: CopilotChatSuggestionConfiguration;\n };\n addChatSuggestionConfiguration: (\n id: string,\n suggestion: CopilotChatSuggestionConfiguration,\n ) => void;\n removeChatSuggestionConfiguration: (id: string) => void;\n\n chatInstructions: string;\n setChatInstructions: React.Dispatch<React.SetStateAction<string>>;\n\n additionalInstructions?: string[];\n setAdditionalInstructions: React.Dispatch<React.SetStateAction<string[]>>;\n\n // api endpoints\n copilotApiConfig: CopilotApiConfig;\n\n showDevConsole: boolean;\n\n // agents\n coagentStates: Record<string, CoagentState>;\n setCoagentStates: React.Dispatch<\n React.SetStateAction<Record<string, CoagentState>>\n >;\n coagentStatesRef: React.RefObject<Record<string, CoagentState>>;\n setCoagentStatesWithRef: (\n value:\n | Record<string, CoagentState>\n | ((prev: Record<string, CoagentState>) => Record<string, CoagentState>),\n ) => void;\n\n agentSession: AgentSession | null;\n setAgentSession: React.Dispatch<React.SetStateAction<AgentSession | null>>;\n\n agentLock: string | null;\n\n threadId: string;\n setThreadId: React.Dispatch<React.SetStateAction<string>>;\n\n runId: string | null;\n setRunId: React.Dispatch<React.SetStateAction<string | null>>;\n\n // The chat abort controller can be used to stop generation globally,\n // i.e. when using `stop()` from `useChat`\n chatAbortControllerRef: React.MutableRefObject<AbortController | null>;\n\n /**\n * The forwarded parameters to use for the task.\n */\n forwardedParameters?: Partial<Pick<ForwardedParametersInput, \"temperature\">>;\n availableAgents: Agent[];\n\n /**\n * The auth states for the CopilotKit.\n */\n authStates_c?: Record<ActionName, AuthState>;\n setAuthStates_c?: React.Dispatch<\n React.SetStateAction<Record<ActionName, AuthState>>\n >;\n\n /**\n * The auth config for the CopilotKit.\n */\n authConfig_c?: {\n SignInComponent: React.ComponentType<{\n onSignInComplete: (authState: AuthState) => void;\n }>;\n };\n\n extensions: ExtensionsInput;\n setExtensions: React.Dispatch<React.SetStateAction<ExtensionsInput>>;\n interruptActions: Record<string, LangGraphInterruptRender>;\n setInterruptAction: LangGraphInterruptActionSetter;\n removeInterruptAction: (actionId: string) => void;\n interruptEventQueue: Record<string, QueuedInterruptEvent[]>;\n addInterruptEvent: (queuedEvent: QueuedInterruptEvent) => void;\n resolveInterruptEvent: (\n threadId: string,\n eventId: string,\n response: string,\n ) => void;\n\n /**\n * Optional trace handler for comprehensive debugging and observability.\n */\n onError: CopilotErrorHandler;\n\n // banner error state\n bannerError: CopilotKitError | null;\n setBannerError: React.Dispatch<React.SetStateAction<CopilotKitError | null>>;\n // Internal error handlers\n // These are used to handle errors that occur during the execution of the chat.\n // They are not intended for use by the developer. A component can register itself an error listener to be activated somewhere else as needed\n internalErrorHandlers: Record<string, CopilotErrorHandler>;\n setInternalErrorHandler: (\n handler: Record<string, CopilotErrorHandler>,\n ) => void;\n removeInternalErrorHandler: (id: string) => void;\n}\n\nconst emptyCopilotContext: CopilotContextParams = {\n actions: {},\n setAction: () => {},\n removeAction: () => {},\n\n setRegisteredActions: () => \"\",\n removeRegisteredAction: () => {},\n\n chatComponentsCache: { current: { actions: {}, coAgentStateRenders: {} } },\n getContextString: (documents: DocumentPointer[], categories: string[]) =>\n returnAndThrowInDebug(\"\"),\n addContext: () => \"\",\n removeContext: () => {},\n getAllContext: () => [],\n\n getFunctionCallHandler: () => returnAndThrowInDebug(async () => {}),\n\n isLoading: false,\n setIsLoading: () => returnAndThrowInDebug(false),\n\n chatInstructions: \"\",\n setChatInstructions: () => returnAndThrowInDebug(\"\"),\n\n additionalInstructions: [],\n setAdditionalInstructions: () => returnAndThrowInDebug([]),\n\n getDocumentsContext: (categories: string[]) => returnAndThrowInDebug([]),\n addDocumentContext: () => returnAndThrowInDebug(\"\"),\n removeDocumentContext: () => {},\n\n copilotApiConfig: new (class implements CopilotApiConfig {\n get chatApiEndpoint(): string {\n throw new Error(\n \"Remember to wrap your app in a `<CopilotKit> {...} </CopilotKit>` !!!\",\n );\n }\n\n get headers(): Record<string, string> {\n return {};\n }\n get body(): Record<string, any> {\n return {};\n }\n })(),\n\n chatSuggestionConfiguration: {},\n addChatSuggestionConfiguration: () => {},\n removeChatSuggestionConfiguration: () => {},\n showDevConsole: false,\n coagentStates: {},\n setCoagentStates: () => {},\n coagentStatesRef: { current: {} },\n setCoagentStatesWithRef: () => {},\n agentSession: null,\n setAgentSession: () => {},\n forwardedParameters: {},\n agentLock: null,\n threadId: \"\",\n setThreadId: () => {},\n runId: null,\n setRunId: () => {},\n chatAbortControllerRef: { current: null },\n availableAgents: [],\n extensions: {},\n setExtensions: () => {},\n interruptActions: {},\n setInterruptAction: () => {},\n removeInterruptAction: () => {},\n interruptEventQueue: {},\n addInterruptEvent: () => {},\n resolveInterruptEvent: () => {},\n onError: () => {},\n bannerError: null,\n setBannerError: () => {},\n internalErrorHandlers: {},\n setInternalErrorHandler: () => {},\n removeInternalErrorHandler: () => {},\n};\n\nexport const CopilotContext =\n React.createContext<CopilotContextParams>(emptyCopilotContext);\n\nexport function useCopilotContext(): CopilotContextParams {\n const context = React.useContext(CopilotContext);\n if (context === emptyCopilotContext) {\n throw new Error(\n \"Remember to wrap your app in a `<CopilotKit> {...} </CopilotKit>` !!!\",\n );\n }\n return context;\n}\n\nfunction returnAndThrowInDebug<T>(_value: T): T {\n throw new Error(\n \"Remember to wrap your app in a `<CopilotKit> {...} </CopilotKit>` !!!\",\n );\n}\n","import { randomId } from \"@copilotkit/shared\";\nimport { useCallback, useReducer } from \"react\";\n\nexport type TreeNodeId = string;\n\nexport interface TreeNode {\n id: TreeNodeId;\n value: string;\n children: TreeNode[];\n parentId?: TreeNodeId;\n categories: Set<string>;\n}\n\nexport type Tree = TreeNode[];\n\nexport interface UseTreeReturn {\n tree: Tree;\n addElement: (\n value: string,\n categories: string[],\n parentId?: TreeNodeId,\n ) => TreeNodeId;\n printTree: (categories: string[]) => string;\n removeElement: (id: TreeNodeId) => void;\n getAllElements: () => Tree;\n}\n\nconst findNode = (nodes: Tree, id: TreeNodeId): TreeNode | undefined => {\n for (const node of nodes) {\n if (node.id === id) {\n return node;\n }\n const result = findNode(node.children, id);\n if (result) {\n return result;\n }\n }\n return undefined;\n};\n\nconst removeNode = (nodes: Tree, id: TreeNodeId): Tree => {\n return nodes.reduce((result: Tree, node) => {\n if (node.id !== id) {\n const newNode = { ...node, children: removeNode(node.children, id) };\n result.push(newNode);\n }\n return result;\n }, []);\n};\n\nconst addNode = (\n nodes: Tree,\n newNode: TreeNode,\n parentId?: TreeNodeId,\n): Tree => {\n if (!parentId) {\n return [...nodes, newNode];\n }\n return nodes.map((node) => {\n if (node.id === parentId) {\n return { ...node, children: [...node.children, newNode] };\n } else if (node.children.length) {\n return { ...node, children: addNode(node.children, newNode, parentId) };\n }\n return node;\n });\n};\n\nconst treeIndentationRepresentation = (\n index: number,\n indentLevel: number,\n): string => {\n if (indentLevel === 0) {\n return (index + 1).toString();\n } else if (indentLevel === 1) {\n return String.fromCharCode(65 + index); // 65 is the ASCII value for 'A'\n } else if (indentLevel === 2) {\n return String.fromCharCode(97 + index); // 97 is the ASCII value for 'a'\n } else {\n return \"-\";\n }\n};\n\nconst printNode = (node: TreeNode, prefix = \"\", indentLevel = 0): string => {\n const indent = \" \".repeat(3).repeat(indentLevel);\n\n const prefixPlusIndentLength = prefix.length + indent.length;\n const subsequentLinesPrefix = \" \".repeat(prefixPlusIndentLength);\n\n const valueLines = node.value.split(\"\\n\");\n\n const outputFirstLine = `${indent}${prefix}${valueLines[0]}`;\n const outputSubsequentLines = valueLines\n .slice(1)\n .map((line) => `${subsequentLinesPrefix}${line}`)\n .join(\"\\n\");\n\n let output = `${outputFirstLine}\\n`;\n if (outputSubsequentLines) {\n output += `${outputSubsequentLines}\\n`;\n }\n\n const childPrePrefix = \" \".repeat(prefix.length);\n\n node.children.forEach(\n (child, index) =>\n (output += printNode(\n child,\n `${childPrePrefix}${treeIndentationRepresentation(index, indentLevel + 1)}. `,\n indentLevel + 1,\n )),\n );\n return output;\n};\n\n// Action types\ntype Action =\n | {\n type: \"ADD_NODE\";\n value: string;\n parentId?: string;\n id: string;\n categories: string[];\n }\n | { type: \"REMOVE_NODE\"; id: string };\n\n// Reducer function\nfunction treeReducer(state: Tree, action: Action): Tree {\n switch (action.type) {\n case \"ADD_NODE\": {\n const { value, parentId, id: newNodeId } = action;\n const newNode: TreeNode = {\n id: newNodeId,\n value,\n children: [],\n categories: new Set(action.categories),\n };\n\n try {\n return addNode(state, newNode, parentId);\n } catch (error) {\n console.error(`Error while adding node with id ${newNodeId}: ${error}`);\n return state;\n }\n }\n case \"REMOVE_NODE\":\n return removeNode(state, action.id);\n default:\n return state;\n }\n}\n\n// useTree hook\nconst useTree = (): UseTreeReturn => {\n const [tree, dispatch] = useReducer(treeReducer, []);\n\n const addElement = useCallback(\n (value: string, categories: string[], parentId?: string): TreeNodeId => {\n const newNodeId = randomId(); // Generate new ID outside of dispatch\n dispatch({\n type: \"ADD_NODE\",\n value,\n parentId,\n id: newNodeId,\n categories: categories,\n });\n return newNodeId; // Return the new ID\n },\n [],\n );\n\n const removeElement = useCallback((id: TreeNodeId): void => {\n dispatch({ type: \"REMOVE_NODE\", id });\n }, []);\n\n const getAllElements = useCallback(() => {\n return tree;\n }, [tree]);\n\n const printTree = useCallback(\n (categories: string[]): string => {\n const categoriesSet = new Set(categories);\n\n let output = \"\";\n tree.forEach((node, index) => {\n // if the node does not have any of the desired categories, continue to the next node\n if (!setsHaveIntersection(categoriesSet, node.categories)) {\n return;\n }\n\n // add a new line before each node except the first one\n if (index !== 0) {\n output += \"\\n\";\n }\n\n output += printNode(\n node,\n `${treeIndentationRepresentation(index, 0)}. `,\n );\n });\n return output;\n },\n [tree],\n );\n\n return { tree, addElement, printTree, removeElement, getAllElements };\n};\n\nexport default useTree;\n\nfunction setsHaveIntersection<T>(setA: Set<T>, setB: Set<T>): boolean {\n const [smallerSet, largerSet] =\n setA.size <= setB.size ? [setA, setB] : [setB, setA];\n\n for (let item of smallerSet) {\n if (largerSet.has(item)) {\n return true;\n }\n }\n\n return false;\n}\n","import { useCallback, useReducer } from \"react\";\nimport { randomId } from \"@copilotkit/shared\";\n\nexport type FlatCategoryStoreId = string;\n\nexport interface UseFlatCategoryStoreReturn<T> {\n addElement: (value: T, categories: string[]) => FlatCategoryStoreId;\n removeElement: (id: FlatCategoryStoreId) => void;\n allElements: (categories: string[]) => T[];\n}\n\ninterface FlatCategoryStoreElement<T> {\n id: FlatCategoryStoreId;\n value: T;\n categories: Set<string>;\n}\n\nconst useFlatCategoryStore = <T>(): UseFlatCategoryStoreReturn<T> => {\n const [elements, dispatch] = useReducer(\n flatCategoryStoreReducer<T>,\n new Map<FlatCategoryStoreId, FlatCategoryStoreElement<T>>(),\n );\n\n const addElement = useCallback(\n (value: T, categories: string[]): FlatCategoryStoreId => {\n const newId = randomId();\n dispatch({\n type: \"ADD_ELEMENT\",\n value,\n id: newId,\n categories,\n });\n return newId;\n },\n [],\n );\n\n const removeElement = useCallback((id: FlatCategoryStoreId): void => {\n dispatch({ type: \"REMOVE_ELEMENT\", id });\n }, []);\n\n const allElements = useCallback(\n (categories: string[]): T[] => {\n const categoriesSet = new Set(categories);\n const result: T[] = [];\n elements.forEach((element) => {\n if (setsHaveIntersection(categoriesSet, element.categories)) {\n result.push(element.value);\n }\n });\n return result;\n },\n [elements],\n );\n\n return { addElement, removeElement, allElements };\n};\n\nexport default useFlatCategoryStore;\n\n// Action types\ntype Action<T> =\n | {\n type: \"ADD_ELEMENT\";\n value: T;\n id: FlatCategoryStoreId;\n categories: string[];\n }\n | { type: \"REMOVE_ELEMENT\"; id: FlatCategoryStoreId };\n\n// Reducer\nfunction flatCategoryStoreReducer<T>(\n state: Map<FlatCategoryStoreId, FlatCategoryStoreElement<T>>,\n action: Action<T>,\n): Map<FlatCategoryStoreId, FlatCategoryStoreElement<T>> {\n switch (action.type) {\n case \"ADD_ELEMENT\": {\n const { value, id, categories } = action;\n const newElement: FlatCategoryStoreElement<T> = {\n id,\n value,\n categories: new Set(categories),\n };\n const newState = new Map(state);\n newState.set(id, newElement);\n return newState;\n }\n case \"REMOVE_ELEMENT\": {\n const newState = new Map(state);\n newState.delete(action.id);\n return newState;\n }\n default:\n return state;\n }\n}\n\nfunction setsHaveIntersection<T>(setA: Set<T>, setB: Set<T>): boolean {\n const [smallerSet, largerSet] =\n setA.size <= setB.size ? [setA, setB] : [setB, setA];\n\n for (let item of smallerSet) {\n if (largerSet.has(item)) {\n return true;\n }\n }\n\n return false;\n}\n","/**\n * An internal context to separate the messages state (which is constantly changing) from the rest of CopilotKit context\n */\n\nimport { Message } from \"@copilotkit/runtime-client-gql\";\nimport React from \"react\";\nimport { Suggestion } from \"@copilotkit/core\";\n\nexport interface CopilotMessagesContextParams {\n messages: Message[];\n setMessages: React.Dispatch<React.SetStateAction<Message[]>>; // suggestions state\n suggestions: Suggestion[];\n setSuggestions: React.Dispatch<React.SetStateAction<Suggestion[]>>;\n}\n\nconst emptyCopilotContext: CopilotMessagesContextParams = {\n messages: [],\n setMessages: () => [],\n // suggestions state\n suggestions: [],\n setSuggestions: () => [],\n};\n\nexport const CopilotMessagesContext =\n React.createContext<CopilotMessagesContextParams>(emptyCopilotContext);\n\nexport function useCopilotMessagesContext(): CopilotMessagesContextParams {\n const context = React.useContext(CopilotMessagesContext);\n if (context === emptyCopilotContext) {\n throw new Error(\n \"A messages consuming component was not wrapped with `<CopilotMessages> {...} </CopilotMessages>`\",\n );\n }\n return context;\n}\n","import { GraphQLError } from \"@copilotkit/runtime-client-gql\";\nimport React, { createContext, useContext, useState, useCallback } from \"react\";\nimport { PartialBy, CopilotKitError, Severity } from \"@copilotkit/shared\";\n\ninterface Toast {\n id: string;\n message: string | React.ReactNode;\n type: \"info\" | \"success\" | \"warning\" | \"error\";\n duration?: number;\n}\n\ninterface ToastContextValue {\n toasts: Toast[];\n addToast: (toast: PartialBy<Toast, \"id\">) => void;\n addGraphQLErrorsToast: (errors: GraphQLError[]) => void;\n removeToast: (id: string) => void;\n enabled: boolean;\n // Banner management\n bannerError: CopilotKitError | null;\n setBannerError: (error: CopilotKitError | null) => void;\n}\n\nconst ToastContext = createContext<ToastContextValue | undefined>(undefined);\n\n// Helper functions for error banner styling\ntype ErrorSeverity = \"critical\" | \"warning\" | \"info\";\n\ninterface ErrorColors {\n background: string;\n border: string;\n text: string;\n icon: string;\n}\n\nfunction getErrorSeverity(error: CopilotKitError): ErrorSeverity {\n // Use structured error severity if available\n if (error.severity) {\n switch (error.severity) {\n case Severity.CRITICAL:\n return \"critical\";\n case Severity.WARNING:\n return \"warning\";\n case Severity.INFO:\n return \"info\";\n default:\n return \"info\";\n }\n }\n\n // Fallback: Check for API key errors which should always be critical\n const message = error.message.toLowerCase();\n if (\n message.includes(\"api key\") ||\n message.includes(\"401\") ||\n message.includes(\"unauthorized\") ||\n message.includes(\"authentication\") ||\n message.includes(\"incorrect api key\")\n ) {\n return \"critical\";\n }\n\n // Default to info level\n return \"info\";\n}\n\nfunction getErrorColors(severity: ErrorSeverity): ErrorColors {\n switch (severity) {\n case \"critical\":\n return {\n background: \"#fee2e2\",\n border: \"#dc2626\",\n text: \"#7f1d1d\",\n icon: \"#dc2626\",\n };\n case \"warning\":\n return {\n background: \"#fef3c7\",\n border: \"#d97706\",\n text: \"#78350f\",\n icon: \"#d97706\",\n };\n case \"info\":\n return {\n background: \"#dbeafe\",\n border: \"#2563eb\",\n text: \"#1e3a8a\",\n icon: \"#2563eb\",\n };\n }\n}\n\nexport function useToast() {\n const context = useContext(ToastContext);\n if (!context) {\n throw new Error(\"useToast must be used within a ToastProvider\");\n }\n return context;\n}\n\nfunction formatBannerMessage(message: string): string {\n // Try to extract the useful message from JSON first\n const jsonMatch = message.match(/'message':\\s*'([^']+)'/);\n if (jsonMatch) {\n return jsonMatch[1];\n }\n\n // Strip technical garbage but keep the meaningful message\n let cleaned = message.split(\" - \")[0];\n cleaned = cleaned.split(\": Error code\")[0];\n cleaned = cleaned.replace(/:\\s*\\d{3}$/, \"\");\n cleaned = cleaned.replace(/See more:.*$/g, \"\");\n cleaned = cleaned.trim();\n\n return cleaned || \"An error occurred.\";\n}\n\nfunction extractUrl(message: string): { url: string; text: string } | null {\n const markdownMatch = /\\[([^\\]]+)\\]\\(([^)]+)\\)/.exec(message);\n if (markdownMatch) {\n return { url: markdownMatch[2], text: \"See More\" };\n }\n const plainMatch = /(https?:\\/\\/[^\\s)]+)/.exec(message);\n if (plainMatch) {\n return {\n url: plainMatch[0].replace(/[.,;:'\"]*$/, \"\"),\n text: \"See More\",\n };\n }\n return null;\n}\n\nfunction BannerErrorDisplay({\n bannerError,\n onDismiss,\n}: {\n bannerError: CopilotKitError;\n onDismiss: () => void;\n}) {\n const [detailsExpanded, setDetailsExpanded] = useState(false);\n const severity = getErrorSeverity(bannerError);\n const colors = getErrorColors(severity);\n\n // Extract optional error details attached by CopilotListeners\n const details = (bannerError as any).details as\n | {\n code?: string;\n context?: Record<string, any>;\n stack?: string;\n originalMessage?: string;\n }\n | undefined;\n\n const link = extractUrl(bannerError.message);\n\n return (\n <div\n style={{\n position: \"fixed\",\n bottom: \"20px\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n zIndex: 9999,\n backgroundColor: colors.background,\n border: `1px solid ${colors.border}`,\n borderLeft: `4px solid ${colors.border}`,\n borderRadius: \"8px\",\n padding: \"12px 16px\",\n fontSize: \"13px\",\n boxShadow: \"0 4px 12px rgba(0, 0, 0, 0.15)\",\n backdropFilter: \"blur(8px)\",\n maxWidth: \"min(90vw, 700px)\",\n width: \"100%\",\n boxSizing: \"border-box\",\n overflow: \"hidden\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n gap: \"10px\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n flex: 1,\n minWidth: 0,\n }}\n >\n <div\n style={{\n width: \"12px\",\n height: \"12px\",\n borderRadius: \"50%\",\n backgroundColor: colors.border,\n flexShrink: 0,\n }}\n />\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n flex: 1,\n minWidth: 0,\n }}\n >\n <div\n style={{\n color: colors.text,\n lineHeight: \"1.4\",\n fontWeight: \"400\",\n fontSize: \"13px\",\n flex: 1,\n wordBreak: \"break-all\",\n overflowWrap: \"break-word\",\n maxWidth: \"550px\",\n overflow: \"hidden\",\n display: \"-webkit-box\",\n WebkitLineClamp: 10,\n WebkitBoxOrient: \"vertical\",\n }}\n >\n {formatBannerMessage(bannerError.message)}\n </div>\n\n {link && (\n <button\n onClick={() =>\n window.open(link.url, \"_blank\", \"noopener,noreferrer\")\n }\n style={{\n background: colors.border,\n color: \"white\",\n border: \"none\",\n borderRadius: \"5px\",\n padding: \"4px 10px\",\n fontSize: \"11px\",\n fontWeight: \"500\",\n cursor: \"pointer\",\n transition: \"all 0.2s ease\",\n flexShrink: 0,\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = \"0.9\";\n e.currentTarget.style.transform = \"translateY(-1px)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = \"1\";\n e.currentTarget.style.transform = \"translateY(0)\";\n }}\n >\n {link.text}\n </button>\n )}\n\n {details && (\n <button\n onClick={() => setDetailsExpanded(!detailsExpanded)}\n style={{\n background: \"transparent\",\n border: `1px solid ${colors.border}`,\n borderRadius: \"5px\",\n padding: \"4px 10px\",\n fontSize: \"11px\",\n fontWeight: \"500\",\n cursor: \"pointer\",\n color: colors.text,\n flexShrink: 0,\n transition: \"all 0.2s ease\",\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.background = \"rgba(0, 0, 0, 0.05)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.background = \"transparent\";\n }}\n >\n {detailsExpanded ? \"Hide Details\" : \"Show Details\"}\n </button>\n )}\n </div>\n </div>\n <button\n onClick={onDismiss}\n style={{\n background: \"transparent\",\n border: \"none\",\n color: colors.text,\n cursor: \"pointer\",\n padding: \"2px\",\n borderRadius: \"3px\",\n fontSize: \"14px\",\n lineHeight: \"1\",\n opacity: 0.6,\n transition: \"all 0.2s ease\",\n flexShrink: 0,\n }}\n title=\"Dismiss\"\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = \"1\";\n e.currentTarget.style.background = \"rgba(0, 0, 0, 0.05)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = \"0.6\";\n e.currentTarget.style.background = \"transparent\";\n }}\n >\n x\n </button>\n </div>\n\n {detailsExpanded && details && (\n <div\n style={{\n marginTop: \"10px\",\n padding: \"10px\",\n background: \"rgba(0, 0, 0, 0.04)\",\n borderRadius: \"6px\",\n fontSize: \"11px\",\n fontFamily: \"monospace\",\n color: colors.text,\n lineHeight: \"1.5\",\n maxHeight: \"200px\",\n overflowY: \"auto\",\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-all\",\n }}\n >\n {details.code && (\n <div>\n <strong>Code:</strong> {details.code}\n </div>\n )}\n {details.originalMessage && (\n <div style={{ marginTop: \"4px\" }}>\n <strong>Message:</strong> {details.originalMessage}\n </div>\n )}\n {details.context && Object.keys(details.context).length > 0 && (\n <div style={{ marginTop: \"4px\" }}>\n <strong>Context:</strong>{\" \"}\n {JSON.stringify(details.context, null, 2)}\n </div>\n )}\n {details.stack && (\n <div style={{ marginTop: \"4px\", opacity: 0.7 }}>\n <strong>Stack:</strong>\n {\"\\n\"}\n {details.stack}\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n\nexport function ToastProvider({\n enabled,\n children,\n}: {\n enabled: boolean;\n children: React.ReactNode;\n}) {\n const [toasts, setToasts] = useState<Toast[]>([]);\n const [bannerError, setBannerErrorState] = useState<CopilotKitError | null>(\n null,\n );\n\n const removeToast = useCallback((id: string) => {\n setToasts((prev) => prev.filter((toast) => toast.id !== id));\n }, []);\n\n const addToast = useCallback(\n (toast: PartialBy<Toast, \"id\">) => {\n // Respect the enabled flag for ALL toasts\n if (!enabled) {\n return;\n }\n\n const id = toast.id ?? Math.random().toString(36).substring(2, 9);\n\n setToasts((currentToasts) => {\n if (currentToasts.find((toast) => toast.id === id))\n return currentToasts;\n return [...currentToasts, { ...toast, id }];\n });\n\n if (toast.duration) {\n setTimeout(() => {\n removeToast(id);\n }, toast.duration);\n }\n },\n [enabled, removeToast],\n );\n\n const setBannerError = useCallback(\n (error: CopilotKitError | null) => {\n // Respect the enabled flag for ALL errors\n if (!enabled && error !== null) {\n return;\n }\n setBannerErrorState(error);\n },\n [enabled],\n );\n\n const addGraphQLErrorsToast = useCallback((errors: GraphQLError[]) => {\n // DEPRECATED: All errors now route to banners for consistency\n console.warn(\n \"addGraphQLErrorsToast is deprecated. All errors now show as banners.\",\n );\n // Function kept for backward compatibility - does nothing\n }, []);\n\n const value = {\n toasts,\n addToast,\n addGraphQLErrorsToast,\n removeToast,\n enabled,\n bannerError,\n setBannerError,\n };\n\n return (\n <ToastContext.Provider value={value}>\n {/* Banner Error Display */}\n {bannerError && (\n <BannerErrorDisplay\n bannerError={bannerError}\n onDismiss={() => setBannerError(null)}\n />\n )}\n\n {/* Toast Display - Deprecated: All errors now show as banners */}\n {children}\n </ToastContext.Provider>\n );\n}\n\n// Toast component removed - all errors now show as banners for consistency\n","function isLocalhost(): boolean {\n if (typeof window === \"undefined\") return false;\n\n return (\n window.location.hostname === \"localhost\" ||\n window.location.hostname === \"127.0.0.1\" ||\n window.location.hostname === \"0.0.0.0\"\n );\n}\n\nexport function shouldShowDevConsole(showDevConsole?: boolean): boolean {\n // If explicitly set, use that value\n if (showDevConsole !== undefined) {\n return showDevConsole;\n }\n\n // If not set, default to true on localhost\n return isLocalhost();\n}\n","/**\n * An internal context to separate the messages state (which is constantly changing) from the rest of CopilotKit context\n */\n\nimport {\n ReactNode,\n useEffect,\n useState,\n useRef,\n useCallback,\n useMemo,\n createContext,\n useContext,\n} from \"react\";\nimport { CopilotMessagesContext } from \"../../context/copilot-messages-context\";\nimport {\n loadMessagesFromJsonRepresentation,\n Message,\n GraphQLError,\n} from \"@copilotkit/runtime-client-gql\";\nimport { useCopilotContext } from \"../../context/copilot-context\";\nimport { useToast } from \"../toast/toast-provider\";\nimport { shouldShowDevConsole } from \"../../utils/dev-console\";\nimport {\n ErrorVisibility,\n CopilotKitApiDiscoveryError,\n CopilotKitRemoteEndpointDiscoveryError,\n CopilotKitAgentDiscoveryError,\n CopilotKitError,\n CopilotKitErrorCode,\n} from \"@copilotkit/shared\";\nimport { Suggestion } from \"@copilotkit/core\";\n\n// Helper to determine if error should show as banner based on visibility and legacy patterns\nfunction shouldShowAsBanner(gqlError: GraphQLError): boolean {\n const extensions = gqlError.extensions;\n if (!extensions) return false;\n\n // Priority 1: Check error code for discovery errors (these should always be banners)\n const code = extensions.code as CopilotKitErrorCode;\n if (\n code === CopilotKitErrorCode.AGENT_NOT_FOUND ||\n code === CopilotKitErrorCode.API_NOT_FOUND ||\n code === CopilotKitErrorCode.REMOTE_ENDPOINT_NOT_FOUND ||\n code === CopilotKitErrorCode.CONFIGURATION_ERROR ||\n code === CopilotKitErrorCode.MISSING_PUBLIC_API_KEY_ERROR ||\n code === CopilotKitErrorCode.UPGRADE_REQUIRED_ERROR\n ) {\n return true;\n }\n\n // Priority 2: Check banner visibility\n if (extensions.visibility === ErrorVisibility.BANNER) {\n return true;\n }\n\n // Priority 3: Check for critical errors that should be banners regardless of formal classification\n const errorMessage = gqlError.message.toLowerCase();\n if (\n errorMessage.includes(\"api key\") ||\n errorMessage.includes(\"401\") ||\n errorMessage.includes(\"unauthorized\") ||\n errorMessage.includes(\"authentication\") ||\n errorMessage.includes(\"incorrect api key\")\n ) {\n return true;\n }\n\n // Priority 4: Legacy stack trace detection for discovery errors\n const originalError = extensions.originalError as any;\n if (originalError?.stack) {\n return (\n originalError.stack.includes(\"CopilotApiDiscoveryError\") ||\n originalError.stack.includes(\"CopilotKitRemoteEndpointDiscoveryError\") ||\n originalError.stack.includes(\"CopilotKitAgentDiscoveryError\")\n );\n }\n\n return false;\n}\n\n/**\n * MessagesTap is used to mitigate performance issues when we only need\n * a snapshot of the messages, not a continuously updating stream of messages.\n */\n\nexport type MessagesTap = {\n getMessagesFromTap: () => Message[];\n updateTapMessages: (messages: Message[]) => void;\n};\n\nconst MessagesTapContext = createContext<MessagesTap | null>(null);\n\nexport function useMessagesTap() {\n const tap = useContext(MessagesTapContext);\n if (!tap)\n throw new Error(\"useMessagesTap must be used inside <MessagesTapProvider>\");\n return tap;\n}\n\nexport function MessagesTapProvider({\n children,\n}: {\n children: React.ReactNode;\n}) {\n const messagesRef = useRef<Message[]>([]);\n\n const tapRef = useRef<MessagesTap>({\n getMessagesFromTap: () => messagesRef.current,\n updateTapMessages: (messages: Message[]) => {\n messagesRef.current = messages;\n },\n });\n\n return (\n <MessagesTapContext.Provider value={tapRef.current}>\n {children}\n </MessagesTapContext.Provider>\n );\n}\n\n/**\n * CopilotKit messages context.\n */\n\nexport function CopilotMessages({ children }: { children: ReactNode }) {\n const [messages, setMessages] = useState<Message[]>([]);\n const lastLoadedThreadId = useRef<string>(undefined!);\n const lastLoadedAgentName = useRef<string>(undefined!);\n const lastLoadedMessages = useRef<string>(undefined!);\n\n const { updateTapMessages } = useMessagesTap();\n\n const { threadId, agentSession, showDevConsole, onError, copilotApiConfig } =\n useCopilotContext();\n const { setBannerError } = useToast();\n\n // Helper function to trace UI errors (similar to useCopilotRuntimeClient)\n const traceUIError = useCallback(\n async (error: CopilotKitError, originalError?: any) => {\n // Just check if onError and publicApiKey are defined\n if (!onError || !copilotApiConfig.publicApiKey) return;\n\n try {\n const traceEvent = {\n type: \"error\" as const,\n timestamp: Date.now(),\n context: {\n source: \"ui\" as const,\n request: {\n operation: \"loadAgentState\",\n url: copilotApiConfig.chatApiEndpoint,\n startTime: Date.now(),\n },\n technical: {\n environment: \"browser\",\n userAgent:\n typeof navigator !== \"undefined\"\n ? navigator.userAgent\n : undefined,\n stackTrace:\n originalError instanceof Error\n ? originalError.stack\n : undefined,\n },\n },\n error,\n };\n await onError(traceEvent);\n } catch (traceError) {\n console.error(\"Error in CopilotMessages onError handler:\", traceError);\n }\n },\n [onError, copilotApiConfig.publicApiKey, copilotApiConfig.chatApiEndpoint],\n );\n\n const createStructuredError = (\n gqlError: GraphQLError,\n ): CopilotKitError | null => {\n const extensions = gqlError.extensions;\n const originalError = extensions?.originalError as any;\n\n // Priority: Check stack trace for discovery errors first\n if (originalError?.stack) {\n if (originalError.stack.includes(\"CopilotApiDiscoveryError\")) {\n return new CopilotKitApiDiscoveryError({\n message: originalError.message,\n });\n }\n if (\n originalError.stack.includes(\"CopilotKitRemoteEndpointDiscoveryError\")\n ) {\n return new CopilotKitRemoteEndpointDiscoveryError({\n message: originalError.message,\n });\n }\n if (originalError.stack.includes(\"CopilotKitAgentDiscoveryError\")) {\n return new CopilotKitAgentDiscoveryError({\n agentName: \"\",\n availableAgents: [],\n });\n }\n }\n\n // Fallback: Use the formal error code if available\n const message = originalError?.message || gqlError.message;\n const code = extensions?.code as CopilotKitErrorCode;\n\n if (code) {\n return new CopilotKitError({ message, code });\n }\n\n return null;\n };\n\n const handleGraphQLErrors = useCallback(\n (error: any) => {\n if (error.graphQLErrors?.length) {\n const graphQLErrors = error.graphQLErrors as GraphQLError[];\n\n // Route all errors to banners for consistent UI\n const routeError = (gqlError: GraphQLError) => {\n const extensions = gqlError.extensions;\n const visibility = extensions?.visibility as ErrorVisibility;\n const isDev = shouldShowDevConsole(showDevConsole);\n\n if (!isDev) {\n console.error(\n \"CopilotKit Error (hidden in production):\",\n gqlError.message,\n );\n return;\n }\n\n // Silent errors - just log\n if (visibility === ErrorVisibility.SILENT) {\n console.error(\"CopilotKit Silent Error:\", gqlError.message);\n return;\n }\n\n // All other errors (including DEV_ONLY) show as banners for consistency\n const ckError = createStructuredError(gqlError);\n if (ckError) {\n setBannerError(ckError);\n // Trace the structured error\n traceUIError(ckError, gqlError);\n } else {\n // Fallback: create a generic error for unstructured GraphQL errors\n const fallbackError = new CopilotKitError({\n message: gqlError.message,\n code: CopilotKitErrorCode.UNKNOWN,\n });\n setBannerError(fallbackError);\n // Trace the fallback error\n traceUIError(fallbackError, gqlError);\n }\n };\n\n // Process all errors as banners\n graphQLErrors.forEach(routeError);\n } else {\n const isDev = shouldShowDevConsole(showDevConsole);\n if (!isDev) {\n console.error(\"CopilotKit Error (hidden in production):\", error);\n } else {\n // Route non-GraphQL errors to banner as well\n const fallbackError = new CopilotKitError({\n message: error?.message || String(error),\n code: CopilotKitErrorCode.UNKNOWN,\n });\n setBannerError(fallbackError);\n // Trace the non-GraphQL error\n traceUIError(fallbackError, error);\n }\n }\n },\n [setBannerError, showDevConsole, traceUIError],\n );\n\n useEffect(() => {\n updateTapMessages(messages);\n }, [messages, updateTapMessages]);\n\n const memoizedChildren = useMemo(() => children, [children]);\n const [suggestions, setSuggestions] = useState<Suggestion[]>([]);\n\n return (\n <CopilotMessagesContext.Provider\n value={{\n messages,\n setMessages,\n suggestions,\n setSuggestions,\n }}\n >\n {memoizedChildren}\n </CopilotMessagesContext.Provider>\n );\n}\n","import {\n Severity,\n CopilotKitError,\n ErrorVisibility,\n CopilotKitErrorCode,\n} from \"@copilotkit/shared\";\nimport React from \"react\";\n\ninterface UsageBannerProps {\n severity?: Severity;\n message?: string | React.ReactNode;\n onClose?: () => void;\n actions?: {\n primary?: {\n label: string;\n onClick: () => void;\n };\n secondary?: {\n label: string;\n onClick: () => void;\n };\n };\n}\n\nexport function UsageBanner({\n severity = Severity.CRITICAL,\n message = \"\",\n onClose,\n actions,\n}: UsageBannerProps) {\n if (!message || !severity) {\n return null;\n }\n\n const themes = {\n [Severity.INFO]: {\n bg: \"#f8fafc\",\n border: \"#e2e8f0\",\n text: \"#475569\",\n accent: \"#3b82f6\",\n },\n [Severity.WARNING]: {\n bg: \"#fffbeb\",\n border: \"#fbbf24\",\n text: \"#92400e\",\n accent: \"#f59e0b\",\n },\n [Severity.CRITICAL]: {\n bg: \"#fef2f2\",\n border: \"#fecaca\",\n text: \"#dc2626\",\n accent: \"#ef4444\",\n },\n };\n\n const theme = themes[severity];\n\n return (\n <>\n <style>\n {`\n @keyframes slideUp {\n from { opacity: 0; transform: translateX(-50%) translateY(8px); }\n to { opacity: 1; transform: translateX(-50%) translateY(0); }\n }\n \n .usage-banner {\n position: fixed;\n bottom: 24px;\n left: 50%;\n transform: translateX(-50%);\n width: min(600px, calc(100vw - 32px));\n z-index: 10000;\n animation: slideUp 0.2s cubic-bezier(0.16, 1, 0.3, 1);\n }\n \n .banner-content {\n background: linear-gradient(135deg, ${theme.bg} 0%, ${theme.bg}f5 100%);\n border: 1px solid ${theme.border};\n border-radius: 12px;\n padding: 18px 20px;\n box-shadow: \n 0 4px 24px rgba(0, 0, 0, 0.08),\n 0 2px 8px rgba(0, 0, 0, 0.04),\n inset 0 1px 0 rgba(255, 255, 255, 0.7);\n display: flex;\n align-items: center;\n gap: 16px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;\n backdrop-filter: blur(12px);\n position: relative;\n overflow: hidden;\n }\n \n .banner-content::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 1px;\n background: linear-gradient(90deg, transparent, ${theme.accent}40, transparent);\n }\n \n .banner-message {\n color: ${theme.text};\n font-size: 14px;\n line-height: 1.5;\n font-weight: 500;\n flex: 1;\n letter-spacing: -0.01em;\n }\n \n .close-btn {\n background: rgba(0, 0, 0, 0.05);\n border: none;\n color: ${theme.text};\n cursor: pointer;\n padding: 0;\n border-radius: 6px;\n opacity: 0.6;\n transition: all 0.15s cubic-bezier(0.16, 1, 0.3, 1);\n font-size: 14px;\n line-height: 1;\n flex-shrink: 0;\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n \n .close-btn:hover {\n opacity: 1;\n background: rgba(0, 0, 0, 0.08);\n transform: scale(1.05);\n }\n \n .btn-primary {\n background: linear-gradient(135deg, ${theme.accent} 0%, ${theme.accent}e6 100%);\n color: white;\n border: none;\n border-radius: 8px;\n padding: 10px 18px;\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s cubic-bezier(0.16, 1, 0.3, 1);\n font-family: inherit;\n flex-shrink: 0;\n box-shadow: \n 0 2px 8px ${theme.accent}30,\n inset 0 1px 0 rgba(255, 255, 255, 0.2);\n letter-spacing: -0.01em;\n }\n \n .btn-primary:hover {\n transform: translateY(-1px) scale(1.02);\n box-shadow: \n 0 4px 12px ${theme.accent}40,\n inset 0 1px 0 rgba(255, 255, 255, 0.25);\n }\n \n .btn-primary:active {\n transform: translateY(0) scale(0.98);\n transition: all 0.08s cubic-bezier(0.16, 1, 0.3, 1);\n }\n \n @media (max-width: 640px) {\n .usage-banner {\n width: calc(100vw - 24px);\n }\n \n .banner-content {\n padding: 16px;\n gap: 12px;\n }\n \n .banner-message {\n font-size: 13px;\n line-height: 1.45;\n }\n \n .btn-primary {\n padding: 8px 14px;\n font-size: 12px;\n }\n \n .close-btn {\n width: 22px;\n height: 22px;\n font-size: 12px;\n }\n }\n `}\n </style>\n\n <div className=\"usage-banner\">\n <div className=\"banner-content\">\n <div className=\"banner-message\">{message}</div>\n {actions?.primary && (\n <button className=\"btn-primary\" onClick={actions.primary.onClick}>\n {actions.primary.label}\n </button>\n )}\n {onClose && (\n <button className=\"close-btn\" onClick={onClose} title=\"Close\">\n ×\n </button>\n )}\n </div>\n </div>\n </>\n );\n}\n\n// Get action button based on error type\nexport const getErrorActions = (error: CopilotKitError) => {\n switch (error.code) {\n case CopilotKitErrorCode.MISSING_PUBLIC_API_KEY_ERROR:\n return {\n primary: {\n label: \"Show me how\",\n onClick: () =>\n window.open(\n \"https://docs.copilotkit.ai/premium#how-do-i-get-access-to-premium-features\",\n \"_blank\",\n \"noopener,noreferrer\",\n ),\n },\n };\n case CopilotKitErrorCode.UPGRADE_REQUIRED_ERROR:\n return {\n primary: {\n label: \"Upgrade\",\n onClick: () =>\n window.open(\n \"https://cloud.copilotkit.ai\",\n \"_blank\",\n \"noopener,noreferrer\",\n ),\n },\n };\n default:\n return undefined;\n }\n};\n\nexport function renderCopilotKitUsage(\n error: CopilotKitError,\n onClose?: () => void,\n) {\n // Route based on error visibility level\n if (error.visibility !== ErrorVisibility.BANNER) {\n return null;\n }\n\n return (\n <UsageBanner\n severity={error.severity || Severity.CRITICAL}\n message={error.message}\n onClose={onClose}\n actions={getErrorActions(error)}\n />\n );\n}\n","import {\n COPILOT_CLOUD_API_URL,\n COPILOT_CLOUD_PUBLIC_API_KEY_HEADER,\n Severity,\n} from \"@copilotkit/shared\";\n\nconst STATUS_CHECK_INTERVAL = 1000 * 60 * 5; // 5 minutes\n\nexport type Status = {\n severity: Severity;\n message: string;\n};\n\nexport class StatusChecker {\n private activeKey: string | null = null;\n private intervalId: ReturnType<typeof setInterval> | null = null;\n private instanceCount = 0;\n private lastResponse: Status | null = null;\n\n async start(\n publicApiKey: string,\n onUpdate?: (status: Status | null) => void,\n ) {\n this.instanceCount++;\n if (this.activeKey === publicApiKey) return;\n\n if (this.intervalId) clearInterval(this.intervalId);\n\n const checkStatus = async () => {\n try {\n const response = await fetch(`${COPILOT_CLOUD_API_URL}/ciu`, {\n method: \"GET\",\n headers: {\n [COPILOT_CLOUD_PUBLIC_API_KEY_HEADER]: publicApiKey,\n },\n }).then((response) => response.json() as Promise<Status>);\n this.lastResponse = response;\n onUpdate?.(response);\n return response;\n } catch (error) {\n // Silently fail\n return null;\n }\n };\n\n const initialResponse = await checkStatus();\n this.intervalId = setInterval(checkStatus, STATUS_CHECK_INTERVAL);\n this.activeKey = publicApiKey;\n return initialResponse;\n }\n\n getLastResponse() {\n return this.lastResponse;\n }\n\n stop() {\n this.instanceCount--;\n if (this.instanceCount === 0) {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n this.activeKey = null;\n this.lastResponse = null;\n }\n }\n }\n}\n","import React from \"react\";\n\nexport const ExclamationMarkIcon = ({\n className,\n style,\n}: {\n className?: string;\n style?: React.CSSProperties;\n}) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={`lucide lucide-circle-alert ${className ? className : \"\"}`}\n style={style}\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" x2=\"12\" y1=\"8\" y2=\"12\" />\n <line x1=\"12\" x2=\"12.01\" y1=\"16\" y2=\"16\" />\n </svg>\n);\n","import React, { useCallback } from \"react\";\nimport { GraphQLError } from \"@copilotkit/runtime-client-gql\";\nimport { useToast } from \"../toast/toast-provider\";\nimport { ExclamationMarkIcon } from \"../toast/exclamation-mark-icon\";\nimport ReactMarkdown from \"react-markdown\";\n\ninterface OriginalError {\n message?: string;\n stack?: string;\n}\n\nexport function ErrorToast({ errors }: { errors: (Error | GraphQLError)[] }) {\n const errorsToRender = errors.map((error, idx) => {\n const originalError =\n \"extensions\" in error\n ? (error.extensions?.originalError as undefined | OriginalError)\n : {};\n const message = originalError?.message ?? error.message;\n const code =\n \"extensions\" in error ? (error.extensions?.code as string) : null;\n\n return (\n <div\n key={idx}\n style={{\n marginTop: idx === 0 ? 0 : 10,\n marginBottom: 14,\n }}\n >\n <ExclamationMarkIcon style={{ marginBottom: 4 }} />\n\n {code && (\n <div\n style={{\n fontWeight: \"600\",\n marginBottom: 4,\n }}\n >\n Copilot Runtime Error:{\" \"}\n <span style={{ fontFamily: \"monospace\", fontWeight: \"normal\" }}>\n {code}\n </span>\n </div>\n )}\n <ReactMarkdown>{message}</ReactMarkdown>\n </div>\n );\n });\n return (\n <div\n style={{\n fontSize: \"13px\",\n maxWidth: \"600px\",\n }}\n >\n {errorsToRender}\n <div style={{ fontSize: \"11px\", opacity: 0.75 }}>\n NOTE: This error only displays during local development.\n </div>\n </div>\n );\n}\n\nexport function useErrorToast() {\n const { addToast } = useToast();\n\n return useCallback(\n (errors: (Error | GraphQLError)[]) => {\n const errorId = errors\n .map((err) => {\n const message =\n \"extensions\" in err\n ? (err.extensions?.originalError as any)?.message || err.message\n : err.message;\n const stack = err.stack || \"\";\n return btoa(message + stack).slice(0, 32); // Create hash from message + stack\n })\n .join(\"|\");\n\n addToast({\n type: \"error\",\n id: errorId, // Toast libraries typically dedupe by id\n message: <ErrorToast errors={errors} />,\n });\n },\n [addToast],\n );\n}\n\nexport function useAsyncCallback<T extends (...args: any[]) => Promise<any>>(\n callback: T,\n deps: Parameters<typeof useCallback>[1],\n) {\n const addErrorToast = useErrorToast();\n return useCallback(async (...args: Parameters<T>) => {\n try {\n return await callback(...args);\n } catch (error) {\n console.error(\"Error in async callback:\", error);\n // @ts-ignore\n addErrorToast([error]);\n throw error;\n }\n }, deps);\n}\n","import React, { useEffect } from \"react\";\nimport { Severity, CopilotKitError } from \"@copilotkit/shared\";\nimport { StatusChecker } from \"../../lib/status-checker\";\nimport { getErrorActions, UsageBanner } from \"../usage-banner\";\nimport { useErrorToast } from \"./error-utils\";\n\nconst statusChecker = new StatusChecker();\n\ninterface Props {\n children: React.ReactNode;\n publicApiKey?: string;\n showUsageBanner?: boolean;\n}\n\ninterface State {\n hasError: boolean;\n error?: CopilotKitError;\n status?: {\n severity: Severity;\n message: string;\n };\n}\n\nexport class CopilotErrorBoundary extends React.Component<Props, State> {\n constructor(props: Props) {\n super(props);\n this.state = {\n hasError: false,\n };\n }\n\n static getDerivedStateFromError(error: CopilotKitError): State {\n return { hasError: true, error };\n }\n\n componentDidMount() {\n if (this.props.publicApiKey) {\n statusChecker.start(this.props.publicApiKey, (newStatus) => {\n this.setState((prevState) => {\n if (newStatus?.severity !== prevState.status?.severity) {\n return { status: newStatus ?? undefined };\n }\n return null;\n });\n });\n }\n }\n\n componentWillUnmount() {\n statusChecker.stop();\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {\n console.error(\"CopilotKit Error:\", error, errorInfo);\n }\n\n render() {\n if (this.state.hasError) {\n if (this.state.error instanceof CopilotKitError) {\n return (\n <>\n {this.props.children}\n {this.props.showUsageBanner && (\n <UsageBanner\n severity={\n this.state.status?.severity ?? this.state.error.severity\n }\n message={this.state.status?.message ?? this.state.error.message}\n actions={getErrorActions(this.state.error)}\n />\n )}\n </>\n );\n }\n throw this.state.error;\n }\n\n return this.props.children;\n }\n}\n\nexport function ErrorToast({\n error,\n children,\n}: {\n error?: Error;\n children: React.ReactNode;\n}) {\n const addErrorToast = useErrorToast();\n\n useEffect(() => {\n if (error) {\n addErrorToast([error]);\n }\n }, [error, addErrorToast]);\n\n if (!error) throw error;\n return children;\n}\n","import React, {\n createContext,\n useContext,\n useCallback,\n useState,\n useRef,\n ReactNode,\n RefObject,\n} from \"react\";\nimport { CoAgentStateRender } from \"../types/coagent-action\";\n\ninterface StateRenderClaim {\n stateRenderId: string;\n stateSnapshot?: any;\n runId?: string;\n messageIndex?: number;\n locked?: boolean;\n}\n\ntype ClaimsRef = Record<string, StateRenderClaim>;\n\nexport interface CoAgentStateRendersContextValue {\n coAgentStateRenders: Record<string, CoAgentStateRender<any>>;\n setCoAgentStateRender: (\n id: string,\n stateRender: CoAgentStateRender<any>,\n ) => void;\n removeCoAgentStateRender: (id: string) => void;\n claimsRef: RefObject<ClaimsRef>;\n}\n\nconst CoAgentStateRendersContext = createContext<\n CoAgentStateRendersContextValue | undefined\n>(undefined);\n\nexport function CoAgentStateRendersProvider({\n children,\n}: {\n children: ReactNode;\n}) {\n const [coAgentStateRenders, setCoAgentStateRenders] = useState<\n Record<string, CoAgentStateRender<any>>\n >({});\n\n const setCoAgentStateRender = useCallback(\n (id: string, stateRender: CoAgentStateRender<any>) => {\n setCoAgentStateRenders((prevPoints) => ({\n ...prevPoints,\n [id]: stateRender,\n }));\n },\n [],\n );\n\n const removeCoAgentStateRender = useCallback((id: string) => {\n setCoAgentStateRenders((prevPoints) => {\n const newPoints = { ...prevPoints };\n delete newPoints[id];\n return newPoints;\n });\n }, []);\n\n const claimsRef = useRef<ClaimsRef>({});\n\n return (\n <CoAgentStateRendersContext.Provider\n value={{\n coAgentStateRenders,\n setCoAgentStateRender,\n removeCoAgentStateRender,\n claimsRef,\n }}\n >\n {children}\n </CoAgentStateRendersContext.Provider>\n );\n}\n\nexport function useCoAgentStateRenders() {\n const context = useContext(CoAgentStateRendersContext);\n if (!context) {\n throw new Error(\n \"useCoAgentStateRenders must be used within CoAgentStateRendersProvider\",\n );\n }\n return context;\n}\n\nexport { CoAgentStateRendersContext };\n","import React, {\n createContext,\n useContext,\n useState,\n ReactNode,\n SetStateAction,\n} from \"react\";\nimport { randomUUID } from \"@copilotkit/shared\";\n\nexport interface ThreadsContextValue {\n threadId: string;\n setThreadId: (value: SetStateAction<string>) => void;\n}\n\nconst ThreadsContext = createContext<ThreadsContextValue | undefined>(\n undefined,\n);\n\nexport interface ThreadsProviderProps {\n children: ReactNode;\n threadId?: string;\n}\n\nexport function ThreadsProvider({\n children,\n threadId: explicitThreadId,\n}: ThreadsProviderProps) {\n const [internalThreadId, setThreadId] = useState<string>(() => randomUUID());\n\n const threadId = explicitThreadId ?? internalThreadId;\n\n return (\n <ThreadsContext.Provider\n value={{\n threadId,\n setThreadId,\n }}\n >\n {children}\n </ThreadsContext.Provider>\n );\n}\n\nexport function useThreads() {\n const context = useContext(ThreadsContext);\n if (!context) {\n throw new Error(\"useThreads must be used within ThreadsProvider\");\n }\n return context;\n}\n\nexport { ThreadsContext };\n","import { dataToUUID, parseJson } from \"@copilotkit/shared\";\n\nexport enum RenderStatus {\n InProgress = \"inProgress\",\n Complete = \"complete\",\n}\n\nexport enum ClaimAction {\n Create = \"create\",\n Override = \"override\",\n Existing = \"existing\",\n Block = \"block\",\n}\n\nexport interface StateRenderContext {\n agentId: string;\n stateRenderId: string;\n messageId: string;\n runId: string;\n messageIndex?: number;\n}\n\nexport interface Claim {\n stateRenderId: string;\n runId?: string;\n stateSnapshot?: any;\n locked?: boolean;\n messageIndex?: number;\n}\n\nexport type ClaimsByMessageId = Record<string, Claim>;\n\nexport interface ClaimResolution {\n canRender: boolean;\n action: ClaimAction;\n nextClaim?: Claim;\n lockOthers?: boolean;\n updateRunId?: string;\n}\n\nexport interface SnapshotCaches {\n byStateRenderAndRun: Record<string, any>;\n byMessageId: Record<string, any>;\n}\n\nexport interface SnapshotSelectionInput {\n messageId: string;\n messageName?: string;\n allowLiveState?: boolean;\n skipLatestCache?: boolean;\n stateRenderId?: string;\n effectiveRunId: string;\n stateSnapshotProp?: any;\n agentState?: any;\n agentMessages?: Array<{ id: string; role?: string }>;\n existingClaim?: Claim;\n caches: SnapshotCaches;\n}\n\nexport interface SnapshotSelectionResult {\n snapshot?: any;\n hasSnapshotKeys: boolean;\n cachedSnapshot?: any;\n allowEmptySnapshot?: boolean;\n snapshotForClaim?: any;\n}\n\nfunction getStateWithoutConstantKeys(state: any) {\n if (!state) return {};\n const { messages, tools, copilotkit, ...stateWithoutConstantKeys } = state;\n return stateWithoutConstantKeys;\n}\n\n// Function that compares states, without the constant keys\nexport function areStatesEquals(a: any, b: any) {\n if ((a && !b) || (!a && b)) return false;\n const { messages, tools, copilotkit, ...aWithoutConstantKeys } = a;\n const {\n messages: bMessages,\n tools: bTools,\n copilotkit: bCopilotkit,\n ...bWithoutConstantKeys\n } = b;\n\n return (\n JSON.stringify(aWithoutConstantKeys) ===\n JSON.stringify(bWithoutConstantKeys)\n );\n}\n\nexport function isPlaceholderMessageId(messageId: string | undefined) {\n return !!messageId && messageId.startsWith(\"coagent-state-render-\");\n}\n\nexport function isPlaceholderMessageName(messageName: string | undefined) {\n return messageName === \"coagent-state-render\";\n}\n\nexport function readCachedMessageEntry(entry: any): {\n snapshot?: any;\n runId?: string;\n} {\n if (!entry || typeof entry !== \"object\") {\n return { snapshot: entry, runId: undefined };\n }\n const snapshot = \"snapshot\" in entry ? entry.snapshot : entry;\n const runId = \"runId\" in entry ? entry.runId : undefined;\n return { snapshot, runId };\n}\n\nexport function getEffectiveRunId({\n existingClaimRunId,\n cachedMessageRunId,\n runId,\n}: {\n existingClaimRunId?: string;\n cachedMessageRunId?: string;\n runId?: string;\n}) {\n return existingClaimRunId || cachedMessageRunId || runId || \"pending\";\n}\n\n/**\n * Resolve whether a message can claim a render slot.\n * This is a pure decision function; the caller applies claim mutations.\n */\nexport function resolveClaim({\n claims,\n context,\n stateSnapshot,\n}: {\n claims: ClaimsByMessageId;\n context: StateRenderContext;\n stateSnapshot?: any;\n}): ClaimResolution {\n const { messageId, stateRenderId, runId, messageIndex } = context;\n const existing = claims[messageId];\n\n if (existing) {\n const canRender = existing.stateRenderId === stateRenderId;\n const shouldUpdateRunId =\n canRender && runId && (!existing.runId || existing.runId === \"pending\");\n return {\n canRender,\n action: canRender ? ClaimAction.Existing : ClaimAction.Block,\n updateRunId: shouldUpdateRunId ? runId : undefined,\n };\n }\n\n const normalizedRunId = runId ?? \"pending\";\n const renderClaimedByOtherMessageEntry = Object.entries(claims).find(\n ([, claim]) =>\n claim.stateRenderId === stateRenderId &&\n (claim.runId ?? \"pending\") === normalizedRunId &&\n dataToUUID(getStateWithoutConstantKeys(claim.stateSnapshot)) ===\n dataToUUID(getStateWithoutConstantKeys(stateSnapshot)),\n );\n\n const renderClaimedByOtherMessage = renderClaimedByOtherMessageEntry?.[1];\n const claimedMessageId = renderClaimedByOtherMessageEntry?.[0];\n\n if (renderClaimedByOtherMessage) {\n if (\n messageIndex !== undefined &&\n renderClaimedByOtherMessage.messageIndex !== undefined &&\n messageIndex > renderClaimedByOtherMessage.messageIndex\n ) {\n return {\n canRender: true,\n action: ClaimAction.Override,\n nextClaim: { stateRenderId, runId, messageIndex },\n lockOthers:\n runId === renderClaimedByOtherMessage.runId ||\n isPlaceholderMessageId(claimedMessageId),\n };\n }\n\n if (\n runId &&\n renderClaimedByOtherMessage.runId &&\n runId !== renderClaimedByOtherMessage.runId\n ) {\n return {\n canRender: true,\n action: ClaimAction.Override,\n nextClaim: { stateRenderId, runId, messageIndex },\n lockOthers: isPlaceholderMessageId(claimedMessageId),\n };\n }\n\n if (isPlaceholderMessageId(claimedMessageId)) {\n return {\n canRender: true,\n action: ClaimAction.Override,\n nextClaim: { stateRenderId, runId, messageIndex },\n lockOthers: true,\n };\n }\n\n if (\n stateSnapshot &&\n renderClaimedByOtherMessage.stateSnapshot &&\n !areStatesEquals(renderClaimedByOtherMessage.stateSnapshot, stateSnapshot)\n ) {\n return {\n canRender: true,\n action: ClaimAction.Override,\n nextClaim: { stateRenderId, runId },\n };\n }\n\n return { canRender: false, action: ClaimAction.Block };\n }\n\n if (!runId) {\n return { canRender: false, action: ClaimAction.Block };\n }\n\n return {\n canRender: true,\n action: ClaimAction.Create,\n nextClaim: { stateRenderId, runId, messageIndex },\n };\n}\n\n/**\n * Select the best snapshot to render for this message.\n * Priority order is:\n * 1) explicit message snapshot\n * 2) live agent state (latest assistant only)\n * 3) cached snapshot for message\n * 4) cached snapshot for stateRenderId+runId\n * 5) last cached snapshot for stateRenderId\n */\nexport function selectSnapshot({\n messageId,\n messageName,\n allowLiveState,\n skipLatestCache,\n stateRenderId,\n effectiveRunId,\n stateSnapshotProp,\n agentState,\n agentMessages,\n existingClaim,\n caches,\n}: SnapshotSelectionInput): SnapshotSelectionResult {\n const lastAssistantId = agentMessages\n ? [...agentMessages].reverse().find((msg) => msg.role === \"assistant\")?.id\n : undefined;\n const latestSnapshot =\n stateRenderId !== undefined\n ? caches.byStateRenderAndRun[`${stateRenderId}::latest`]\n : undefined;\n const messageIndex = agentMessages\n ? agentMessages.findIndex((msg) => msg.id === messageId)\n : -1;\n const messageRole =\n messageIndex >= 0 && agentMessages\n ? agentMessages[messageIndex]?.role\n : undefined;\n let previousUserMessageId: string | undefined;\n if (messageIndex > 0 && agentMessages) {\n for (let i = messageIndex - 1; i >= 0; i -= 1) {\n if (agentMessages[i]?.role === \"user\") {\n previousUserMessageId = agentMessages[i]?.id;\n break;\n }\n }\n }\n const liveStateIsStale =\n stateSnapshotProp === undefined &&\n latestSnapshot !== undefined &&\n agentState !== undefined &&\n areStatesEquals(latestSnapshot, agentState);\n const shouldUseLiveState =\n (Boolean(allowLiveState) ||\n !lastAssistantId ||\n messageId === lastAssistantId) &&\n !liveStateIsStale;\n const snapshot = stateSnapshotProp\n ? parseJson(stateSnapshotProp, stateSnapshotProp)\n : shouldUseLiveState\n ? agentState\n : undefined;\n const hasSnapshotKeys = !!(snapshot && Object.keys(snapshot).length > 0);\n const allowEmptySnapshot =\n snapshot !== undefined &&\n !hasSnapshotKeys &&\n (stateSnapshotProp !== undefined || shouldUseLiveState);\n\n const messageCacheEntry = caches.byMessageId[messageId];\n const cachedMessageSnapshot =\n readCachedMessageEntry(messageCacheEntry).snapshot;\n const cacheKey =\n stateRenderId !== undefined\n ? `${stateRenderId}::${effectiveRunId}`\n : undefined;\n let cachedSnapshot = cachedMessageSnapshot ?? caches.byMessageId[messageId];\n if (\n cachedSnapshot === undefined &&\n cacheKey &&\n caches.byStateRenderAndRun[cacheKey] !== undefined\n ) {\n cachedSnapshot = caches.byStateRenderAndRun[cacheKey];\n }\n if (\n cachedSnapshot === undefined &&\n stateRenderId &&\n previousUserMessageId &&\n caches.byStateRenderAndRun[\n `${stateRenderId}::pending:${previousUserMessageId}`\n ] !== undefined\n ) {\n cachedSnapshot =\n caches.byStateRenderAndRun[\n `${stateRenderId}::pending:${previousUserMessageId}`\n ];\n }\n if (\n cachedSnapshot === undefined &&\n !skipLatestCache &&\n stateRenderId &&\n messageRole !== \"assistant\" &&\n (stateSnapshotProp !== undefined ||\n (agentState && Object.keys(agentState).length > 0))\n ) {\n cachedSnapshot = caches.byStateRenderAndRun[`${stateRenderId}::latest`];\n }\n\n const snapshotForClaim = existingClaim?.locked\n ? (existingClaim.stateSnapshot ?? cachedSnapshot)\n : hasSnapshotKeys\n ? snapshot\n : (existingClaim?.stateSnapshot ?? cachedSnapshot);\n\n return {\n snapshot,\n hasSnapshotKeys,\n cachedSnapshot,\n allowEmptySnapshot,\n snapshotForClaim,\n };\n}\n","import { useEffect } from \"react\";\nimport {\n areStatesEquals,\n ClaimAction,\n getEffectiveRunId,\n isPlaceholderMessageId,\n isPlaceholderMessageName,\n readCachedMessageEntry,\n resolveClaim,\n selectSnapshot,\n type Claim,\n type ClaimsByMessageId,\n type SnapshotCaches,\n type StateRenderContext,\n} from \"./use-coagent-state-render-bridge.helpers\";\n\nexport interface StateRenderRegistryInput {\n agentId: string;\n stateRenderId?: string;\n message: { id: string; runId?: string; name?: string };\n messageIndex?: number;\n stateSnapshot?: any;\n agentState?: any;\n agentMessages?: Array<{ id: string; role?: string }>;\n claimsRef: React.MutableRefObject<Record<string, Claim>>;\n}\n\nexport interface StateRenderRegistryResult {\n canRender: boolean;\n}\n\nconst LAST_SNAPSHOTS_BY_RENDER_AND_RUN = \"__lastSnapshotsByStateRenderIdAndRun\";\nconst LAST_SNAPSHOTS_BY_MESSAGE = \"__lastSnapshotsByMessageId\";\n\ntype SnapshotByMessageEntry = { snapshot: any; runId?: string } | any;\ntype ClaimsStore = Record<string, Claim> & {\n [LAST_SNAPSHOTS_BY_RENDER_AND_RUN]?: Record<string, any>;\n [LAST_SNAPSHOTS_BY_MESSAGE]?: Record<string, SnapshotByMessageEntry>;\n};\n\nfunction getClaimsStore(\n claimsRef: React.MutableRefObject<Record<string, Claim>>,\n): ClaimsStore {\n return claimsRef.current as ClaimsStore;\n}\n\nfunction getSnapshotCaches(\n claimsRef: React.MutableRefObject<Record<string, Claim>>,\n): SnapshotCaches {\n const store = getClaimsStore(claimsRef);\n return {\n byStateRenderAndRun: store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] ?? {},\n byMessageId: store[LAST_SNAPSHOTS_BY_MESSAGE] ?? {},\n };\n}\n\nexport function useStateRenderRegistry({\n agentId,\n stateRenderId,\n message,\n messageIndex,\n stateSnapshot,\n agentState,\n agentMessages,\n claimsRef,\n}: StateRenderRegistryInput): StateRenderRegistryResult {\n const store = getClaimsStore(claimsRef);\n const runId = message.runId;\n const cachedMessageEntry = store[LAST_SNAPSHOTS_BY_MESSAGE]?.[message.id];\n const { runId: cachedMessageRunId } =\n readCachedMessageEntry(cachedMessageEntry);\n const existingClaimRunId = claimsRef.current[message.id]?.runId;\n const effectiveRunId = getEffectiveRunId({\n existingClaimRunId,\n cachedMessageRunId,\n runId,\n });\n\n useEffect(() => {\n return () => {\n const existingClaim = claimsRef.current[message.id];\n if (\n existingClaim?.stateSnapshot &&\n Object.keys(existingClaim.stateSnapshot).length > 0\n ) {\n const snapshotCache = {\n ...(store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] ?? {}),\n };\n const cacheKey = `${existingClaim.stateRenderId}::${existingClaim.runId ?? \"pending\"}`;\n snapshotCache[cacheKey] = existingClaim.stateSnapshot;\n snapshotCache[`${existingClaim.stateRenderId}::latest`] =\n existingClaim.stateSnapshot;\n store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] = snapshotCache;\n\n const messageCache = {\n ...(store[LAST_SNAPSHOTS_BY_MESSAGE] ?? {}),\n };\n messageCache[message.id] = {\n snapshot: existingClaim.stateSnapshot,\n runId: existingClaim.runId ?? effectiveRunId,\n };\n store[LAST_SNAPSHOTS_BY_MESSAGE] = messageCache;\n }\n delete claimsRef.current[message.id];\n };\n }, [claimsRef, effectiveRunId, message.id]);\n\n if (!stateRenderId) {\n return { canRender: false };\n }\n\n const caches = getSnapshotCaches(claimsRef);\n const existingClaim = claimsRef.current[message.id] as Claim | undefined;\n\n const { snapshot, hasSnapshotKeys, allowEmptySnapshot, snapshotForClaim } =\n selectSnapshot({\n messageId: message.id,\n messageName: message.name,\n allowLiveState:\n isPlaceholderMessageName(message.name) ||\n isPlaceholderMessageId(message.id),\n skipLatestCache:\n isPlaceholderMessageName(message.name) ||\n isPlaceholderMessageId(message.id),\n stateRenderId,\n effectiveRunId,\n stateSnapshotProp: stateSnapshot,\n agentState,\n agentMessages,\n existingClaim,\n caches,\n });\n\n const resolution = resolveClaim({\n claims: claimsRef.current as ClaimsByMessageId,\n context: {\n agentId,\n messageId: message.id,\n stateRenderId,\n runId: effectiveRunId,\n messageIndex,\n } satisfies StateRenderContext,\n stateSnapshot: snapshotForClaim,\n });\n\n if (resolution.action === ClaimAction.Block) {\n return { canRender: false };\n }\n\n if (resolution.updateRunId && claimsRef.current[message.id]) {\n claimsRef.current[message.id].runId = resolution.updateRunId;\n }\n\n if (resolution.nextClaim) {\n claimsRef.current[message.id] = resolution.nextClaim;\n }\n\n if (resolution.lockOthers) {\n Object.entries(claimsRef.current).forEach(([id, claim]) => {\n if (id !== message.id && claim.stateRenderId === stateRenderId) {\n claim.locked = true;\n }\n });\n }\n\n if (existingClaim && !existingClaim.locked && agentMessages?.length) {\n const indexInAgentMessages = agentMessages.findIndex(\n (msg: any) => msg.id === message.id,\n );\n if (\n indexInAgentMessages >= 0 &&\n indexInAgentMessages < agentMessages.length - 1\n ) {\n existingClaim.locked = true;\n }\n }\n\n const existingSnapshot = claimsRef.current[message.id].stateSnapshot;\n const snapshotChanged =\n stateSnapshot &&\n existingSnapshot !== undefined &&\n !areStatesEquals(existingSnapshot, snapshot);\n\n if (\n snapshot &&\n (stateSnapshot || hasSnapshotKeys || allowEmptySnapshot) &&\n (!claimsRef.current[message.id].locked || snapshotChanged)\n ) {\n if (!claimsRef.current[message.id].locked || snapshotChanged) {\n claimsRef.current[message.id].stateSnapshot = snapshot;\n const snapshotCache = {\n ...(store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] ?? {}),\n };\n const cacheKey = `${stateRenderId}::${effectiveRunId}`;\n snapshotCache[cacheKey] = snapshot;\n snapshotCache[`${stateRenderId}::latest`] = snapshot;\n store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] = snapshotCache;\n const messageCache = {\n ...(store[LAST_SNAPSHOTS_BY_MESSAGE] ?? {}),\n };\n messageCache[message.id] = { snapshot, runId: effectiveRunId };\n store[LAST_SNAPSHOTS_BY_MESSAGE] = messageCache;\n if (stateSnapshot) {\n claimsRef.current[message.id].locked = true;\n }\n }\n } else if (snapshotForClaim) {\n const existingSnapshot = claimsRef.current[message.id].stateSnapshot;\n if (!existingSnapshot) {\n claimsRef.current[message.id].stateSnapshot = snapshotForClaim;\n const snapshotCache = {\n ...(store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] ?? {}),\n };\n const cacheKey = `${stateRenderId}::${effectiveRunId}`;\n snapshotCache[cacheKey] = snapshotForClaim;\n snapshotCache[`${stateRenderId}::latest`] = snapshotForClaim;\n store[LAST_SNAPSHOTS_BY_RENDER_AND_RUN] = snapshotCache;\n const messageCache = {\n ...(store[LAST_SNAPSHOTS_BY_MESSAGE] ?? {}),\n };\n messageCache[message.id] = {\n snapshot: snapshotForClaim,\n runId: effectiveRunId,\n };\n store[LAST_SNAPSHOTS_BY_MESSAGE] = messageCache;\n }\n }\n\n return { canRender: true };\n}\n","import { ReactCustomMessageRendererPosition, useAgent } from \"../v2\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport type { AgentSubscriber } from \"@ag-ui/client\";\nimport { useCoAgentStateRenders } from \"../context\";\nimport { parseJson } from \"@copilotkit/shared\";\nimport { RenderStatus } from \"./use-coagent-state-render-bridge.helpers\";\nimport { useStateRenderRegistry } from \"./use-coagent-state-render-registry\";\n\n/**\n * Bridge hook that connects agent state renders to chat messages.\n *\n * ## Purpose\n * This hook finds matching state render configurations (registered via useCoAgentStateRender)\n * and returns UI to render in chat.\n * It ensures each state render appears bound to a specific message, preventing duplicates while\n * allowing re-binding when the underlying state changes significantly.\n *\n * ## Message-ID-Based Claiming System\n *\n * ### The Problem\n * Multiple bridge component instances render simultaneously (one per message). Without coordination,\n * they would all try to render the same state render, causing duplicates.\n *\n * ### The Solution: Message-ID Claims with State Comparison\n * Each state render is \"claimed\" by exactly one **message ID** (not runId):\n *\n * **Claim Structure**: `claimsRef.current[messageId] = { stateRenderId, runId, stateSnapshot, locked }`\n *\n * **Primary binding is by messageId because**:\n * - runId is not always available immediately (starts as \"pending\")\n * - messageId is the stable identifier throughout the message lifecycle\n * - Claims persist across component remounts via context ref\n *\n * ### Claiming Logic Flow\n *\n * 1. **Message already has a claim**:\n * - Check if the claim matches the current stateRenderId\n * - If yes → render (this message owns this render)\n * - Update runId if it was \"pending\" and now available\n *\n * 2. **State render claimed by another message**:\n * - Compare state snapshots (ignoring constant keys: messages, tools, copilotkit)\n * - If states are identical → block rendering (duplicate)\n * - **If states are different → allow claiming** (new data, new message)\n * - This handles cases where the same render type shows different states in different messages\n *\n * 3. **Unclaimed state render**:\n * - Only allow claiming if runId is \"pending\" (initial render)\n * - If runId is real but no claim exists → block (edge case protection)\n * - Create new claim: `claimsRef.current[messageId] = { stateRenderId, runId }`\n *\n * ### State Snapshot Locking\n *\n * Once a state snapshot is captured and locked for a message:\n * - The UI always renders with the locked snapshot (not live agent.state)\n * - Prevents UI from appearing \"wiped\" during state transitions\n * - Locked when: stateSnapshot prop is available (from message persistence)\n * - Unlocked state: can still update from live agent.state\n *\n * ### Synchronous Claiming (Ref-based)\n *\n * Claims are stored in a context-level ref (not React state):\n * - Multiple bridges render in the same tick\n * - State updates are async - would allow duplicates before update completes\n * - Ref provides immediate, synchronous claim checking\n * - Survives component remounts (stored in context, not component)\n *\n * ## Flow Example\n *\n * ```\n * Time 1: Message A renders, runId=undefined, state={progress: 50%}\n * → effectiveRunId = \"pending\"\n * → Claims: claimsRef[\"msgA\"] = { stateRenderId: \"tasks\", runId: \"pending\", stateSnapshot: {progress: 50%} }\n * → Renders UI with 50% progress\n *\n * Time 2: Message B renders, runId=undefined, same state\n * → Checks: \"tasks\" already claimed by msgA with same state\n * → Returns null (blocked - duplicate)\n *\n * Time 3: Real runId appears (e.g., \"run-123\")\n * → Updates claim: claimsRef[\"msgA\"].runId = \"run-123\"\n * → Message A continues rendering\n *\n * Time 4: Agent processes more, state={progress: 100%}\n * → Message A: locked to 50% (stateSnapshot locked)\n * → Message C renders with state={progress: 100%}\n * → Checks: \"tasks\" claimed by msgA but state is DIFFERENT (50% vs 100%)\n * → Allows new claim: claimsRef[\"msgC\"] = { stateRenderId: \"tasks\", runId: \"run-123\", stateSnapshot: {progress: 100%} }\n * → Both messages render independently with their own snapshots\n * ```\n */\nexport interface CoAgentStateRenderBridgeProps {\n message: any;\n position: ReactCustomMessageRendererPosition;\n runId: string;\n messageIndex: number;\n messageIndexInRun: number;\n numberOfMessagesInRun: number;\n agentId: string;\n stateSnapshot: any;\n}\n\nexport function useCoagentStateRenderBridge(\n agentId: string,\n props: CoAgentStateRenderBridgeProps,\n) {\n const { stateSnapshot, message } = props;\n const { coAgentStateRenders, claimsRef } = useCoAgentStateRenders();\n const { agent } = useAgent({ agentId });\n const [nodeName, setNodeName] = useState<string | undefined>(undefined);\n const [, forceUpdate] = useState(0);\n\n useEffect(() => {\n if (!agent) return;\n const subscriber: AgentSubscriber = {\n onStateChanged: () => {\n forceUpdate((value) => value + 1);\n },\n onStepStartedEvent: ({ event }) => {\n if (event.stepName !== nodeName) {\n setNodeName(event.stepName);\n }\n },\n onStepFinishedEvent: ({ event }) => {\n if (event.stepName === nodeName) {\n setNodeName(undefined);\n }\n },\n };\n\n const { unsubscribe } = agent.subscribe(subscriber);\n return () => {\n unsubscribe();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agentId, nodeName]);\n\n const getStateRender = useCallback(\n (messageId: string) => {\n return Object.entries(coAgentStateRenders).find(\n ([stateRenderId, stateRender]) => {\n if (claimsRef.current[messageId]) {\n return stateRenderId === claimsRef.current[messageId].stateRenderId;\n }\n const matchingAgentName = stateRender.name === agentId;\n const matchesNodeContext = stateRender.nodeName\n ? stateRender.nodeName === nodeName\n : true;\n return matchingAgentName && matchesNodeContext;\n },\n );\n },\n [coAgentStateRenders, nodeName, agentId],\n );\n const stateRenderEntry = useMemo(\n () => getStateRender(message.id),\n [getStateRender, message.id],\n );\n const stateRenderId = stateRenderEntry?.[0];\n const stateRender = stateRenderEntry?.[1];\n\n const registryMessage = {\n ...message,\n runId: props.runId ?? message.runId,\n };\n const { canRender } = useStateRenderRegistry({\n agentId,\n stateRenderId,\n message: registryMessage,\n messageIndex: props.messageIndex,\n stateSnapshot,\n agentState: agent?.state,\n agentMessages: agent?.messages,\n claimsRef,\n });\n\n return useMemo(() => {\n if (!stateRender || !stateRenderId) {\n return null;\n }\n if (!canRender) {\n return null;\n }\n\n if (stateRender.handler) {\n stateRender.handler({\n state: stateSnapshot\n ? parseJson(stateSnapshot, stateSnapshot)\n : (agent?.state ?? {}),\n nodeName: nodeName ?? \"\",\n });\n }\n\n if (stateRender.render) {\n const status = agent?.isRunning\n ? RenderStatus.InProgress\n : RenderStatus.Complete;\n\n if (typeof stateRender.render === \"string\") return stateRender.render;\n\n return stateRender.render({\n status,\n // Always use state from claim, to make sure the state does not seem \"wiped\" for a fraction of a second\n state: claimsRef.current[message.id].stateSnapshot ?? {},\n nodeName: nodeName ?? \"\",\n });\n }\n }, [\n stateRender,\n stateRenderId,\n agent?.state,\n agent?.isRunning,\n nodeName,\n message.id,\n stateSnapshot,\n canRender,\n ]);\n}\n\nexport function CoAgentStateRenderBridge(props: CoAgentStateRenderBridgeProps) {\n return useCoagentStateRenderBridge(props.agentId, props);\n}\n","import { useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { useAgent, useCopilotChatConfiguration, useCopilotKit } from \"../v2\";\nimport { CopilotKitError, parseJson } from \"@copilotkit/shared\";\nimport { useCopilotContext } from \"../context\";\nimport {\n AbstractAgent,\n AgentSubscriber,\n AGUIConnectNotImplementedError,\n} from \"@ag-ui/client\";\nimport { useErrorToast } from \"./error-boundary/error-utils\";\nimport { CopilotKitCoreSubscriber } from \"@copilotkit/core\";\nimport { useToast } from \"./toast/toast-provider\";\nimport { CopilotKitLowLevelError } from \"@copilotkit/shared\";\n\nconst usePredictStateSubscription = (agent?: AbstractAgent) => {\n const predictStateToolsRef = useRef<\n {\n tool: string;\n state_key: string;\n tool_argument: string;\n }[]\n >([]);\n\n const getSubscriber = useCallback(\n (agent: AbstractAgent): AgentSubscriber => ({\n onCustomEvent: ({ event }) => {\n if (event.name === \"PredictState\") {\n predictStateToolsRef.current = event.value;\n }\n },\n onToolCallArgsEvent: ({ partialToolCallArgs, toolCallName }) => {\n predictStateToolsRef.current.forEach((t) => {\n if (t?.tool !== toolCallName) return;\n\n const emittedState =\n typeof partialToolCallArgs === \"string\"\n ? parseJson(\n partialToolCallArgs as unknown as string,\n partialToolCallArgs,\n )\n : partialToolCallArgs;\n\n agent.setState({\n [t.state_key]: emittedState[t.state_key],\n });\n });\n },\n }),\n [],\n );\n\n useEffect(() => {\n if (!agent) return;\n\n const subscriber = getSubscriber(agent);\n const { unsubscribe } = agent.subscribe(subscriber);\n return () => {\n unsubscribe();\n };\n }, [agent, getSubscriber]);\n};\n\nexport function CopilotListeners() {\n const { copilotkit } = useCopilotKit();\n const existingConfig = useCopilotChatConfiguration();\n const resolvedAgentId = existingConfig?.agentId;\n const { setBannerError } = useToast();\n\n const { agent } = useAgent({ agentId: resolvedAgentId });\n\n usePredictStateSubscription(agent);\n\n useEffect(() => {\n const subscriber: CopilotKitCoreSubscriber = {\n onError: ({ error, code, context }) => {\n // Silently ignore abort errors (e.g. from navigation during active requests)\n if (\n error.name === \"AbortError\" ||\n error.message === \"Fetch is aborted\" ||\n error.message === \"signal is aborted without reason\" ||\n error.message === \"component unmounted\" ||\n !error.message\n ) {\n return;\n }\n\n // Always log full error details in development\n if (process.env.NODE_ENV === \"development\") {\n console.error(\n \"[CopilotKit] Agent error:\",\n error.message,\n \"\\n Code:\",\n code,\n \"\\n Context:\",\n context,\n \"\\n Stack:\",\n error.stack,\n );\n }\n\n const ckError = new CopilotKitLowLevelError({\n error,\n message: error.message,\n url: typeof window !== \"undefined\" ? window.location.href : \"\",\n });\n\n // Attach original error details for the banner to display\n (ckError as any).details = {\n code,\n context,\n stack: error.stack,\n originalMessage: error.message,\n };\n\n setBannerError(ckError);\n },\n };\n const subscription = copilotkit.subscribe(subscriber);\n\n return () => {\n subscription.unsubscribe();\n };\n }, [copilotkit?.subscribe]);\n\n return null;\n}\n","/**\n * This component will typically wrap your entire application (or a sub-tree of your application where you want to have a copilot). It provides the copilot context to all other components and hooks.\n *\n * ## Example\n *\n * You can find more information about self-hosting CopilotKit [here](/guides/self-hosting).\n *\n * ```tsx\n * import { CopilotKit } from \"@copilotkit/react-core\";\n *\n * <CopilotKit runtimeUrl=\"<your-runtime-url>\">\n * // ... your app ...\n * </CopilotKit>\n * ```\n */\n\nimport React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n SetStateAction,\n} from \"react\";\nimport {\n CopilotChatConfigurationProvider,\n CopilotKitInspector,\n CopilotKitProvider as CopilotKitV2Provider,\n useCopilotKit,\n} from \"../../v2\";\nimport {\n CopilotContext,\n CopilotApiConfig,\n ChatComponentsCache,\n AgentSession,\n AuthState,\n useCopilotContext,\n} from \"../../context/copilot-context\";\nimport useTree from \"../../hooks/use-tree\";\nimport {\n CopilotChatSuggestionConfiguration,\n DocumentPointer,\n} from \"../../types\";\nimport { flushSync } from \"react-dom\";\nimport {\n COPILOT_CLOUD_CHAT_URL,\n CopilotCloudConfig,\n FunctionCallHandler,\n COPILOT_CLOUD_PUBLIC_API_KEY_HEADER,\n randomUUID,\n ConfigurationError,\n MissingPublicApiKeyError,\n CopilotKitError,\n CopilotErrorEvent,\n CopilotErrorHandler,\n} from \"@copilotkit/shared\";\nimport { FrontendAction } from \"../../types/frontend-action\";\nimport useFlatCategoryStore from \"../../hooks/use-flat-category-store\";\nimport { CopilotKitProps } from \"./copilotkit-props\";\nimport { CoagentState } from \"../../types/coagent-state\";\nimport { CopilotMessages, MessagesTapProvider } from \"./copilot-messages\";\nimport { ToastProvider } from \"../toast/toast-provider\";\nimport { getErrorActions, UsageBanner } from \"../usage-banner\";\nimport { shouldShowDevConsole } from \"../../utils\";\nimport { CopilotErrorBoundary } from \"../error-boundary/error-boundary\";\nimport { Agent, ExtensionsInput } from \"@copilotkit/runtime-client-gql\";\nimport {\n LangGraphInterruptRender,\n LangGraphInterruptActionSetterArgs,\n QueuedInterruptEvent,\n} from \"../../types/interrupt-action\";\nimport { CoAgentStateRendersProvider } from \"../../context/coagent-state-renders-context\";\nimport { CoAgentStateRenderBridge } from \"../../hooks/use-coagent-state-render-bridge\";\nimport { ThreadsProvider, useThreads } from \"../../context/threads-context\";\nimport { CopilotListeners } from \"../CopilotListeners\";\n\nexport function CopilotKit({ children, ...props }: CopilotKitProps) {\n const enabled = shouldShowDevConsole(props.showDevConsole);\n const showInspector = shouldShowDevConsole(props.enableInspector);\n\n // Use API key if provided, otherwise use the license key\n const publicApiKey = props.publicApiKey || props.publicLicenseKey;\n\n const renderArr = useMemo(() => [{ render: CoAgentStateRenderBridge }], []);\n\n return (\n <ToastProvider enabled={enabled}>\n <CopilotErrorBoundary\n publicApiKey={publicApiKey}\n showUsageBanner={enabled}\n >\n <ThreadsProvider threadId={props.threadId}>\n <CopilotKitV2Provider\n {...props}\n showDevConsole={showInspector}\n renderCustomMessages={renderArr}\n useSingleEndpoint={props.useSingleEndpoint ?? true}\n >\n <CopilotKitInternal {...props}>{children}</CopilotKitInternal>\n </CopilotKitV2Provider>\n </ThreadsProvider>\n </CopilotErrorBoundary>\n </ToastProvider>\n );\n}\n\n/**\n * Bridge component that subscribes to v2.x copilotkit core error events\n * and forwards them to v1.x error handling system.\n * This ensures only ONE subscription exists regardless of how many times\n * Chat components are rendered.\n */\nfunction CopilotKitErrorBridge() {\n const { copilotkit } = useCopilotKit();\n const { onError, copilotApiConfig } = useCopilotContext();\n\n useEffect(() => {\n if (!copilotkit) return;\n\n const subscription = copilotkit.subscribe({\n onError: async (event) => {\n // Convert v2.x error event to v1.x CopilotErrorEvent format\n const errorEvent: CopilotErrorEvent = {\n type: \"error\",\n timestamp: Date.now(),\n context: {\n source: \"agent\",\n request: {\n operation: event.code || \"unknown\",\n url: copilotApiConfig?.chatApiEndpoint,\n startTime: Date.now(),\n },\n technical: {\n environment: \"browser\",\n userAgent:\n typeof navigator !== \"undefined\"\n ? navigator.userAgent\n : undefined,\n stackTrace: event.error.stack,\n },\n // Add additional context from v2.x event\n ...event.context,\n },\n error: event.error,\n };\n\n try {\n await onError(errorEvent);\n } catch (handlerError) {\n console.error(\"Error in onError handler:\", handlerError);\n }\n },\n });\n\n return () => {\n subscription.unsubscribe();\n };\n }, [copilotkit, onError, copilotApiConfig]);\n\n return null;\n}\n\nexport function CopilotKitInternal(cpkProps: CopilotKitProps) {\n const { children, ...props } = cpkProps;\n\n /**\n * This will throw an error if the props are invalid.\n */\n validateProps(cpkProps);\n\n // Use license key as API key if provided, otherwise use the API key\n const publicApiKey = props.publicLicenseKey || props.publicApiKey;\n\n const chatApiEndpoint = props.runtimeUrl || COPILOT_CLOUD_CHAT_URL;\n\n const [actions, setActions] = useState<Record<string, FrontendAction<any>>>(\n {},\n );\n\n // State for registered actions from useCopilotAction\n const [registeredActionConfigs, setRegisteredActionConfigs] = useState<\n Map<string, { type: string; action: any; component: any }>\n >(new Map());\n\n const chatComponentsCache = useRef<ChatComponentsCache>({\n actions: {},\n coAgentStateRenders: {},\n });\n\n const { addElement, removeElement, printTree, getAllElements } = useTree();\n const [isLoading, setIsLoading] = useState(false);\n const [chatInstructions, setChatInstructions] = useState(\"\");\n const [authStates, setAuthStates] = useState<Record<string, AuthState>>({});\n const [extensions, setExtensions] = useState<ExtensionsInput>({});\n const [additionalInstructions, setAdditionalInstructions] = useState<\n string[]\n >([]);\n\n const {\n addElement: addDocument,\n removeElement: removeDocument,\n allElements: allDocuments,\n } = useFlatCategoryStore<DocumentPointer>();\n\n // Compute all the functions and properties that we need to pass\n const setAction = useCallback((id: string, action: FrontendAction<any>) => {\n setActions((prevPoints) => {\n return {\n ...prevPoints,\n [id]: action,\n };\n });\n }, []);\n\n const removeAction = useCallback((id: string) => {\n setActions((prevPoints) => {\n const newPoints = { ...prevPoints };\n delete newPoints[id];\n return newPoints;\n });\n }, []);\n\n const getContextString = useCallback(\n (documents: DocumentPointer[], categories: string[]) => {\n const documentsString = documents\n .map((document) => {\n return `${document.name} (${document.sourceApplication}):\\n${document.getContents()}`;\n })\n .join(\"\\n\\n\");\n\n const nonDocumentStrings = printTree(categories);\n\n return `${documentsString}\\n\\n${nonDocumentStrings}`;\n },\n [printTree],\n );\n\n const addContext = useCallback(\n (\n context: string,\n parentId?: string,\n categories: string[] = defaultCopilotContextCategories,\n ) => {\n return addElement(context, categories, parentId);\n },\n [addElement],\n );\n\n const removeContext = useCallback(\n (id: string) => {\n removeElement(id);\n },\n [removeElement],\n );\n\n const getAllContext = useCallback(() => {\n return getAllElements();\n }, [getAllElements]);\n\n const getFunctionCallHandler = useCallback(\n (customEntryPoints?: Record<string, FrontendAction<any>>) => {\n return entryPointsToFunctionCallHandler(\n Object.values(customEntryPoints || actions),\n );\n },\n [actions],\n );\n\n const getDocumentsContext = useCallback(\n (categories: string[]) => {\n return allDocuments(categories);\n },\n [allDocuments],\n );\n\n const addDocumentContext = useCallback(\n (\n documentPointer: DocumentPointer,\n categories: string[] = defaultCopilotContextCategories,\n ) => {\n return addDocument(documentPointer, categories);\n },\n [addDocument],\n );\n\n const removeDocumentContext = useCallback(\n (documentId: string) => {\n removeDocument(documentId);\n },\n [removeDocument],\n );\n\n // get the appropriate CopilotApiConfig from the props\n const copilotApiConfig: CopilotApiConfig = useMemo(() => {\n let cloud: CopilotCloudConfig | undefined = undefined;\n if (publicApiKey) {\n cloud = {\n guardrails: {\n input: {\n restrictToTopic: {\n enabled: Boolean(props.guardrails_c),\n validTopics: props.guardrails_c?.validTopics || [],\n invalidTopics: props.guardrails_c?.invalidTopics || [],\n },\n },\n },\n };\n }\n\n return {\n publicApiKey: publicApiKey,\n ...(cloud ? { cloud } : {}),\n chatApiEndpoint: chatApiEndpoint,\n headers: props.headers || {},\n properties: props.properties || {},\n transcribeAudioUrl: props.transcribeAudioUrl,\n textToSpeechUrl: props.textToSpeechUrl,\n credentials: props.credentials,\n };\n }, [\n publicApiKey,\n props.headers,\n props.properties,\n props.transcribeAudioUrl,\n props.textToSpeechUrl,\n props.credentials,\n props.cloudRestrictToTopic,\n props.guardrails_c,\n ]);\n\n const headers = useMemo(() => {\n const authHeaders = Object.values(authStates || {}).reduce((acc, state) => {\n if (state.status === \"authenticated\" && state.authHeaders) {\n return {\n ...acc,\n ...Object.entries(state.authHeaders).reduce(\n (headers, [key, value]) => ({\n ...headers,\n [key.startsWith(\"X-Custom-\") ? key : `X-Custom-${key}`]: value,\n }),\n {},\n ),\n };\n }\n return acc;\n }, {});\n\n return {\n ...(copilotApiConfig.headers || {}),\n ...(copilotApiConfig.publicApiKey\n ? {\n [COPILOT_CLOUD_PUBLIC_API_KEY_HEADER]:\n copilotApiConfig.publicApiKey,\n }\n : {}),\n ...authHeaders,\n };\n }, [copilotApiConfig.headers, copilotApiConfig.publicApiKey, authStates]);\n\n const [internalErrorHandlers, _setInternalErrorHandler] = useState<\n Record<string, CopilotErrorHandler>\n >({});\n const setInternalErrorHandler = useCallback(\n (handler: Record<string, CopilotErrorHandler>) => {\n _setInternalErrorHandler((prev: Record<string, CopilotErrorHandler>) => ({\n ...prev,\n ...handler,\n }));\n },\n [],\n );\n const removeInternalErrorHandler = useCallback((key: string) => {\n _setInternalErrorHandler((prev) => {\n const { [key]: _removed, ...rest } = prev;\n return rest;\n });\n }, []);\n\n // Keep latest values in refs\n const onErrorRef = useRef<CopilotErrorHandler | undefined>(props.onError);\n useEffect(() => {\n onErrorRef.current = props.onError;\n }, [props.onError]);\n\n const internalHandlersRef = useRef<Record<string, CopilotErrorHandler>>({});\n useEffect(() => {\n internalHandlersRef.current = internalErrorHandlers;\n }, [internalErrorHandlers]);\n\n const handleErrors = useCallback(\n async (error: CopilotErrorEvent) => {\n if (copilotApiConfig.publicApiKey && onErrorRef.current) {\n try {\n await onErrorRef.current(error);\n } catch (e) {\n console.error(\"Error in public onError handler:\", e);\n }\n }\n const handlers = Object.values(internalHandlersRef.current);\n await Promise.all(\n handlers.map((h) =>\n Promise.resolve(h(error)).catch((e) =>\n console.error(\"Error in internal error handler:\", e),\n ),\n ),\n );\n },\n [copilotApiConfig.publicApiKey],\n );\n\n const [chatSuggestionConfiguration, setChatSuggestionConfiguration] =\n useState<{\n [key: string]: CopilotChatSuggestionConfiguration;\n }>({});\n\n const addChatSuggestionConfiguration = useCallback(\n (id: string, suggestion: CopilotChatSuggestionConfiguration) => {\n setChatSuggestionConfiguration((prev) => ({ ...prev, [id]: suggestion }));\n },\n [setChatSuggestionConfiguration],\n );\n\n const removeChatSuggestionConfiguration = useCallback(\n (id: string) => {\n setChatSuggestionConfiguration((prev) => {\n const { [id]: _, ...rest } = prev;\n return rest;\n });\n },\n [setChatSuggestionConfiguration],\n );\n\n const [availableAgents, setAvailableAgents] = useState<Agent[]>([]);\n const [coagentStates, setCoagentStates] = useState<\n Record<string, CoagentState>\n >({});\n const coagentStatesRef = useRef<Record<string, CoagentState>>({});\n const setCoagentStatesWithRef = useCallback(\n (\n value:\n | Record<string, CoagentState>\n | ((\n prev: Record<string, CoagentState>,\n ) => Record<string, CoagentState>),\n ) => {\n const newValue =\n typeof value === \"function\" ? value(coagentStatesRef.current) : value;\n coagentStatesRef.current = newValue;\n setCoagentStates((prev) => {\n return newValue;\n });\n },\n [],\n );\n\n let initialAgentSession: AgentSession | null = null;\n if (props.agent) {\n initialAgentSession = {\n agentName: props.agent,\n };\n }\n\n const [agentSession, setAgentSession] = useState<AgentSession | null>(\n initialAgentSession,\n );\n\n // Update agentSession when props.agent changes\n useEffect(() => {\n if (props.agent) {\n setAgentSession({\n agentName: props.agent,\n });\n } else {\n setAgentSession(null);\n }\n }, [props.agent]);\n\n const { threadId, setThreadId: setInternalThreadId } = useThreads();\n\n const setThreadId = useCallback(\n (value: SetStateAction<string>) => {\n if (props.threadId) {\n throw new Error(\n \"Cannot call setThreadId() when threadId is provided via props.\",\n );\n }\n setInternalThreadId(value);\n },\n [props.threadId],\n );\n\n const [runId, setRunId] = useState<string | null>(null);\n\n const chatAbortControllerRef = useRef<AbortController | null>(null);\n\n const showDevConsole = shouldShowDevConsole(props.showDevConsole);\n\n const [interruptActions, _setInterruptActions] = useState<\n Record<string, LangGraphInterruptRender>\n >({});\n const setInterruptAction = useCallback(\n (action: LangGraphInterruptActionSetterArgs) => {\n _setInterruptActions((prev) => {\n if (action == null || !action.id) {\n // Cannot set action without id\n return prev;\n }\n return {\n ...prev,\n [action.id]: {\n ...(prev[action.id] ?? {}),\n ...action,\n } as LangGraphInterruptRender,\n };\n });\n },\n [],\n );\n const removeInterruptAction = useCallback((actionId: string): void => {\n _setInterruptActions((prev) => {\n const { [actionId]: _, ...rest } = prev;\n return rest;\n });\n }, []);\n\n const [interruptEventQueue, setInterruptEventQueue] = useState<\n Record<string, QueuedInterruptEvent[]>\n >({});\n\n const addInterruptEvent = useCallback((queuedEvent: QueuedInterruptEvent) => {\n setInterruptEventQueue((prev) => {\n const threadQueue = prev[queuedEvent.threadId] || [];\n return {\n ...prev,\n [queuedEvent.threadId]: [...threadQueue, queuedEvent],\n };\n });\n }, []);\n\n const resolveInterruptEvent = useCallback(\n (threadId: string, eventId: string, response: string) => {\n setInterruptEventQueue((prev) => {\n const threadQueue = prev[threadId] || [];\n return {\n ...prev,\n [threadId]: threadQueue.map((queuedEvent) =>\n queuedEvent.eventId === eventId\n ? { ...queuedEvent, event: { ...queuedEvent.event, response } }\n : queuedEvent,\n ),\n };\n });\n },\n [],\n );\n\n const memoizedChildren = useMemo(() => children, [children]);\n const [bannerError, setBannerError] = useState<CopilotKitError | null>(null);\n\n const agentLock = useMemo(() => props.agent ?? null, [props.agent]);\n\n const forwardedParameters = useMemo(\n () => props.forwardedParameters ?? {},\n [props.forwardedParameters],\n );\n\n const updateExtensions = useCallback(\n (newExtensions: SetStateAction<ExtensionsInput>) => {\n setExtensions((prev: ExtensionsInput) => {\n const resolved =\n typeof newExtensions === \"function\"\n ? newExtensions(prev)\n : newExtensions;\n const isSameLength =\n Object.keys(resolved).length === Object.keys(prev).length;\n const isEqual =\n isSameLength &&\n // @ts-ignore\n Object.entries(resolved).every(([key, value]) => prev[key] === value);\n\n return isEqual ? prev : resolved;\n });\n },\n [setExtensions],\n );\n\n const updateAuthStates = useCallback(\n (newAuthStates: SetStateAction<Record<string, AuthState>>) => {\n setAuthStates((prev) => {\n const resolved =\n typeof newAuthStates === \"function\"\n ? newAuthStates(prev)\n : newAuthStates;\n const isSameLength =\n Object.keys(resolved).length === Object.keys(prev).length;\n const isEqual =\n isSameLength &&\n // @ts-ignore\n Object.entries(resolved).every(([key, value]) => prev[key] === value);\n\n return isEqual ? prev : resolved;\n });\n },\n [setAuthStates],\n );\n\n const handleSetRegisteredActions = useCallback(\n (actionConfig: any): string => {\n const key = actionConfig.action.name || randomUUID();\n setRegisteredActionConfigs((prev) => {\n const newMap = new Map(prev);\n newMap.set(key, actionConfig);\n return newMap;\n });\n return key;\n },\n [],\n );\n\n const handleRemoveRegisteredAction = useCallback((actionKey: string) => {\n setRegisteredActionConfigs((prev) => {\n const newMap = new Map(prev);\n newMap.delete(actionKey);\n return newMap;\n });\n }, []);\n\n // Component to render all registered actions\n const RegisteredActionsRenderer = useMemo(() => {\n return () => (\n <>\n {Array.from(registeredActionConfigs.entries()).map(([key, config]) => {\n const Component = config.component;\n return <Component key={key} action={config.action} />;\n })}\n </>\n );\n }, [registeredActionConfigs]);\n\n const copilotContextValue = useMemo(\n () => ({\n actions,\n chatComponentsCache,\n getFunctionCallHandler,\n setAction,\n removeAction,\n setRegisteredActions: handleSetRegisteredActions,\n removeRegisteredAction: handleRemoveRegisteredAction,\n getContextString,\n addContext,\n removeContext,\n getAllContext,\n getDocumentsContext,\n addDocumentContext,\n removeDocumentContext,\n copilotApiConfig: copilotApiConfig,\n isLoading,\n setIsLoading,\n chatSuggestionConfiguration,\n addChatSuggestionConfiguration,\n removeChatSuggestionConfiguration,\n chatInstructions,\n setChatInstructions,\n additionalInstructions,\n setAdditionalInstructions,\n showDevConsole,\n coagentStates,\n setCoagentStates,\n coagentStatesRef,\n setCoagentStatesWithRef,\n agentSession,\n setAgentSession,\n forwardedParameters,\n agentLock,\n threadId,\n setThreadId,\n runId,\n setRunId,\n chatAbortControllerRef,\n availableAgents,\n authConfig_c: props.authConfig_c,\n authStates_c: authStates,\n setAuthStates_c: updateAuthStates,\n extensions,\n setExtensions: updateExtensions,\n interruptActions,\n setInterruptAction,\n removeInterruptAction,\n interruptEventQueue,\n addInterruptEvent,\n resolveInterruptEvent,\n bannerError,\n setBannerError,\n onError: handleErrors,\n internalErrorHandlers,\n setInternalErrorHandler,\n removeInternalErrorHandler,\n }),\n [\n actions,\n chatComponentsCache,\n getFunctionCallHandler,\n setAction,\n removeAction,\n handleSetRegisteredActions,\n handleRemoveRegisteredAction,\n getContextString,\n addContext,\n removeContext,\n getAllContext,\n getDocumentsContext,\n addDocumentContext,\n removeDocumentContext,\n copilotApiConfig,\n isLoading,\n chatSuggestionConfiguration,\n addChatSuggestionConfiguration,\n removeChatSuggestionConfiguration,\n chatInstructions,\n additionalInstructions,\n showDevConsole,\n coagentStates,\n setCoagentStatesWithRef,\n agentSession,\n setAgentSession,\n forwardedParameters,\n agentLock,\n threadId,\n setThreadId,\n runId,\n availableAgents,\n props.authConfig_c,\n authStates,\n updateAuthStates,\n extensions,\n updateExtensions,\n interruptActions,\n setInterruptAction,\n removeInterruptAction,\n interruptEventQueue,\n addInterruptEvent,\n resolveInterruptEvent,\n bannerError,\n handleErrors,\n internalErrorHandlers,\n setInternalErrorHandler,\n removeInternalErrorHandler,\n ],\n );\n\n return (\n <CopilotChatConfigurationProvider\n // labels={labels}\n // isModalDefaultOpen={isModalDefaultOpen}\n agentId={props.agent ?? \"default\"}\n threadId={threadId}\n >\n <CopilotContext.Provider value={copilotContextValue}>\n <CopilotListeners />\n <CopilotKitErrorBridge />\n <CoAgentStateRendersProvider>\n <MessagesTapProvider>\n <CopilotMessages>\n <React.Fragment key=\"children\">{memoizedChildren}</React.Fragment>\n <RegisteredActionsRenderer key=\"actions\" />\n </CopilotMessages>\n </MessagesTapProvider>\n {bannerError && showDevConsole && (\n <UsageBanner\n severity={bannerError.severity}\n message={bannerError.message}\n onClose={() => setBannerError(null)}\n actions={getErrorActions(bannerError)}\n />\n )}\n </CoAgentStateRendersProvider>\n </CopilotContext.Provider>\n </CopilotChatConfigurationProvider>\n );\n}\n\nexport const defaultCopilotContextCategories = [\"global\"];\n\nfunction entryPointsToFunctionCallHandler(\n actions: FrontendAction<any>[],\n): FunctionCallHandler {\n return async ({\n name,\n args,\n }: {\n name: string;\n args: Record<string, any>;\n }) => {\n let actionsByFunctionName: Record<string, FrontendAction<any>> = {};\n for (let action of actions) {\n actionsByFunctionName[action.name] = action;\n }\n\n const action = actionsByFunctionName[name];\n let result: any = undefined;\n if (action) {\n await new Promise<void>((resolve, reject) => {\n flushSync(async () => {\n try {\n result = await action.handler?.(args);\n resolve();\n } catch (error) {\n reject(error);\n }\n });\n });\n await new Promise((resolve) => setTimeout(resolve, 20));\n }\n return result;\n };\n}\n\nfunction formatFeatureName(featureName: string): string {\n return featureName\n .replace(/_c$/, \"\")\n .split(\"_\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(\" \");\n}\n\nfunction validateProps(props: CopilotKitProps): never | void {\n const cloudFeatures = Object.keys(props).filter((key) => key.endsWith(\"_c\"));\n\n // Check if we have either a runtimeUrl or one of the API keys\n const hasApiKey = props.publicApiKey || props.publicLicenseKey;\n\n if (!props.runtimeUrl && !hasApiKey) {\n throw new ConfigurationError(\n \"Missing required prop: 'runtimeUrl' or 'publicApiKey' or 'publicLicenseKey'\",\n );\n }\n\n if (cloudFeatures.length > 0 && !hasApiKey) {\n throw new MissingPublicApiKeyError(\n `Missing required prop: 'publicApiKey' or 'publicLicenseKey' to use cloud features: ${cloudFeatures\n .map(formatFeatureName)\n .join(\", \")}`,\n );\n }\n}\n"],"mappings":"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"}
|