@copilotkit/react-core 1.59.4 → 1.59.5
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/dist/{copilotkit-LdQ8w20l.cjs → copilotkit-CFfEVdV4.cjs} +340 -203
- package/dist/copilotkit-CFfEVdV4.cjs.map +1 -0
- package/dist/{copilotkit-CtqalfG8.d.cts → copilotkit-Ctvinul7.d.cts} +40 -3
- package/dist/copilotkit-Ctvinul7.d.cts.map +1 -0
- package/dist/{copilotkit-DoIlZQqa.mjs → copilotkit-DEGlMWM0.mjs} +340 -203
- package/dist/copilotkit-DEGlMWM0.mjs.map +1 -0
- package/dist/{copilotkit-D42EuTt0.d.mts → copilotkit-DqDT5RLa.d.mts} +40 -3
- package/dist/copilotkit-DqDT5RLa.d.mts.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.umd.js +339 -202
- package/dist/index.umd.js.map +1 -1
- package/dist/v2/index.cjs +1 -1
- package/dist/v2/index.css +1 -1
- package/dist/v2/index.d.cts +2 -2
- package/dist/v2/index.d.mts +2 -2
- package/dist/v2/index.mjs +1 -1
- package/dist/v2/index.umd.js +339 -202
- package/dist/v2/index.umd.js.map +1 -1
- package/package.json +6 -6
- package/dist/copilotkit-CtqalfG8.d.cts.map +0 -1
- package/dist/copilotkit-D42EuTt0.d.mts.map +0 -1
- package/dist/copilotkit-DoIlZQqa.mjs.map +0 -1
- package/dist/copilotkit-LdQ8w20l.cjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilotkit-CFfEVdV4.cjs","names":["React","DEFAULT_AGENT_ID","twMerge","React","Slot","TooltipPrimitive","DropdownMenuPrimitive","ChevronRightIcon","Square","Loader2","ArrowUp","Mic","X","Check","Plus","CopilotKitCore","z","EMPTY_DEPS","ToolCallStatus","React","ToolCallStatus","DEFAULT_AGENT_ID","React","z","z","React","ToolCallStatus","z","z","DEFAULT_SURFACE_ID","A2UIProvider","A2UIRenderer","z","A2UI_SCHEMA_CONTEXT_DESCRIPTION","A2UI_DEFAULT_GENERATION_GUIDELINES","A2UI_DEFAULT_DESIGN_GUIDELINES","COPILOT_CLOUD_CHAT_URL","viewerTheme","z","DEFAULT_AGENT_ID","React","DEFAULT_AGENT_ID","CopilotKitCoreRuntimeConnectionStatus","ProxiedCopilotRuntimeAgent","HttpAgent","DEFAULT_AGENT_ID","DEFAULT_AGENT_ID","useThreads","ɵselectThreads","ɵselectThreadsIsLoading","ɵselectThreadsError","ɵselectHasNextPage","ɵselectIsFetchingNextPage","CopilotKitCoreRuntimeConnectionStatus","React","Streamdown","Check","Copy","ThumbsUp","ThumbsDown","Volume2","RefreshCw","X","Check","Copy","Edit","ChevronLeft","ChevronRight","ChevronRight","Streamdown","React","Loader2","React","React","React","CopilotChatAssistantMessage","CopilotChatUserMessage","CopilotChatReasoningMessage","DEFAULT_AGENT_ID","Play","React","Upload","CopilotChatInput","StickToBottom","ChevronDown","TranscriptionErrorCode","DEFAULT_AGENT_ID","HttpAgent","TranscriptionErrorCode","MessageCircle","X","React","X","CopilotChatView","CopilotChatView","CopilotChatView","CopilotPopupView","CopilotChatView","emptyCopilotContext","React","setsHaveIntersection","React","Severity","ErrorVisibility","CopilotKitApiDiscoveryError","CopilotKitRemoteEndpointDiscoveryError","CopilotKitAgentDiscoveryError","CopilotKitError","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/lib/react-core.ts","../src/v2/context.ts","../src/v2/types/defineToolCallRenderer.ts","../src/v2/hooks/use-render-tool.tsx","../src/v2/hooks/use-default-render-tool.tsx","../src/v2/hooks/use-render-tool-call.tsx","../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/A2UIRecoveryStates.tsx","../src/v2/a2ui/A2UIMessageRenderer.tsx","../src/v2/a2ui/A2UIToolCallRenderer.tsx","../src/v2/hooks/use-agent-context.tsx","../src/v2/a2ui/A2UICatalogContext.tsx","../src/v2/providers/CopilotKitProvider.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-human-in-the-loop.tsx","../src/v2/hooks/use-agent.tsx","../src/v2/hooks/use-capabilities.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/lib/record-annotation.ts","../src/v2/hooks/use-learn-from-user-action.tsx","../src/v2/hooks/use-learn-from-user-action-in-current-thread.tsx","../src/v2/hooks/use-attachments.tsx","../src/v2/hooks/use-learning-containers.tsx","../src/v2/hooks/use-learning-containers-in-current-thread.tsx","../src/v2/components/chat/CopilotChatToolCallsView.tsx","../src/v2/components/chat/CopilotChatAssistantMessage.tsx","../src/v2/components/chat/Lightbox.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/intelligence-indicator/IntelligenceIndicatorView.tsx","../src/v2/components/intelligence-indicator/IntelligenceIndicator.tsx","../src/v2/components/chat/CopilotChatMessageView.tsx","../src/v2/components/chat/CopilotChatAttachmentQueue.tsx","../src/v2/hooks/use-keyboard-height.tsx","../src/v2/components/chat/normalize-auto-scroll.ts","../src/v2/components/chat/last-user-message-context.ts","../src/v2/hooks/use-pin-to-send.ts","../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 // True when the current threadId was chosen by the caller rather than\n // silently minted inside the provider chain. Consumers that only make\n // sense against a real backend thread (e.g. /connect, suppressing the\n // welcome screen on switch) gate on this instead of `!!threadId`.\n hasExplicitThreadId: boolean;\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 // Lets internal wrappers (e.g. the v1 CopilotKit bridge, which pipes a\n // ThreadsProvider-minted UUID through as `threadId`) declare that the\n // threadId they are supplying is NOT a caller choice. When omitted, the\n // provider infers explicitness from whether the `threadId` prop itself\n // was supplied.\n hasExplicitThreadId?: boolean;\n isModalDefaultOpen?: boolean;\n}\n\n// Provider component\nexport const CopilotChatConfigurationProvider: React.FC<\n CopilotChatConfigurationProviderProps\n> = ({\n children,\n labels,\n agentId,\n threadId,\n hasExplicitThreadId,\n isModalDefaultOpen,\n}) => {\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 // If a caller passed `hasExplicitThreadId`, trust it verbatim (lets the v1\n // bridge mark an auto-minted UUID as non-explicit). Otherwise infer: a\n // threadId supplied as a prop here is by definition a caller choice.\n const ownHasExplicitThreadId =\n hasExplicitThreadId !== undefined ? hasExplicitThreadId : !!threadId;\n const resolvedHasExplicitThreadId =\n ownHasExplicitThreadId || !!parentConfig?.hasExplicitThreadId;\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 hasExplicitThreadId: resolvedHasExplicitThreadId,\n isModalOpen: resolvedIsModalOpen,\n setModalOpen: resolvedSetModalOpen,\n }),\n [\n mergedLabels,\n resolvedAgentId,\n resolvedThreadId,\n resolvedHasExplicitThreadId,\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\nconst Button = React.forwardRef<\n HTMLButtonElement,\n React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n }\n>(function Button(\n { className, variant, size, asChild = false, ...props },\n ref,\n) {\n const Comp = asChild ? Slot : \"button\";\n\n return (\n <Comp\n ref={ref}\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 type { KeyboardEvent, ChangeEvent } from \"react\";\nimport React, {\n useState,\n useRef,\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 type { CopilotChatLabels } from \"../../providers/CopilotChatConfigurationProvider\";\nimport {\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 type { WithSlots } from \"../../lib/slots\";\nimport { renderSlot } 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 /**\n * Set to `true` when the input sits at the bottom of its container as a\n * flex-last-child (visible position is driven by layout, not CSS\n * positioning). Triggers reservation of bottom space for the fixed\n * CopilotKit license banner via the\n * `--copilotkit-license-banner-offset` CSS var so the two don't overlap.\n *\n * Not needed when `positioning === \"absolute\"`; that mode already pins the\n * input to the bottom and picks up the same reservation automatically.\n * Leave unset (default `false`) for inputs rendered mid-layout such as the\n * welcome screen, where the banner offset would push the input off-center.\n */\n bottomAnchored?: 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 bottomAnchored = false,\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 // Skip key handling during IME composition (e.g. CJK input).\n // The compositionend event will fire separately when composition ends.\n if (e.nativeEvent.isComposing || e.keyCode === 229) {\n return;\n }\n\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 // When the composer holds sendable text, Enter ALWAYS sends — even\n // while a run is in flight. A non-empty composer is unambiguous intent\n // to send a new message, not to stop the agent. This is what unblocks\n // consecutive interrupt pills: after picking turn-1's slot the resume\n // run is still streaming (`isProcessing` true) when the user types and\n // Enters turn-2's prompt; routing that Enter to `onStop` aborted the\n // run and the next interrupt never surfaced. Stop stays reachable via\n // Enter only when the composer is empty (the genuine stop affordance).\n if (isProcessing && !canSend) {\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 // Always clear the input after sending, including controlled mode.\n // In controlled mode, onChange(\"\") notifies the parent to reset its state.\n if (!isControlled) {\n setInternalValue(\"\");\n }\n onChange?.(\"\");\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 onCompositionStart: () => {\n isComposingRef.current = true;\n },\n onCompositionEnd: () => {\n isComposingRef.current = false;\n },\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 // The send/stop button is an explicit control: when a run is in flight it\n // renders as a Stop (Square) button, so a click maps to stop regardless of\n // composer contents. The Enter key behaves differently (see handleKeyDown):\n // a non-empty composer + Enter sends a new message rather than stopping.\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 // Track whether an IME composition is active so we can avoid\n // resetting textarea.value during measurement (which would break\n // the composition session).\n const isComposingRef = useRef(false);\n\n const ensureMeasurements = useCallback(() => {\n const textarea = inputRef.current;\n if (!textarea || isComposingRef.current) {\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 // Reserve room when the fixed license banner is visible so it doesn't\n // overlap the input. Applied only for bottom-anchored inputs (either\n // `positioning === \"absolute\"`, or an explicitly-flagged flex-last-child\n // input in run state). The welcome-screen input sits mid-layout and\n // must stay still when the banner is present.\n ...(positioning === \"absolute\" || bottomAnchored\n ? { paddingBottom: \"var(--copilotkit-license-banner-offset, 0px)\" }\n : {}),\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 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 { createContext, useContext, useEffect, useReducer } from \"react\";\nimport { CopilotKitCoreReact } from \"./lib/react-core\";\nimport type { CopilotKitCoreReactConfig } from \"./lib/react-core\";\nimport type { LicenseContextValue } from \"@copilotkit/shared\";\n\n// Re-export so headless.ts (and consumers) reference the same type declaration.\nexport { CopilotKitCoreReact };\nexport type { CopilotKitCoreReactConfig };\n\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\nexport const EMPTY_SET: ReadonlySet<string> = new Set();\n\nexport const CopilotKitContext = createContext<CopilotKitContextValue | null>(\n null,\n);\n\nexport const useCopilotKit = (): CopilotKitContextValue => {\n const context = useContext(CopilotKitContext);\n const [, forceUpdate] = useReducer((x: number) => 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\n// License context — shared between web and RN providers.\n// Default is permissive (all features allowed) — providers override via createLicenseContextValue.\n// Inlined here to avoid a runtime import from @copilotkit/shared, which pulls in\n// Node-only deps (jose) that break React Native's Metro bundler.\nexport const LicenseContext = createContext<LicenseContextValue>({\n status: null,\n license: null,\n checkFeature: () => true,\n getLimit: () => null,\n} as LicenseContextValue);\n\nexport const useLicenseContext = (): LicenseContextValue =>\n useContext(LicenseContext);\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 toolCallId: string;\n args: Partial<T>;\n status: ToolCallStatus.InProgress;\n result: undefined;\n }\n | {\n name: string;\n toolCallId: string;\n args: T;\n status: ToolCallStatus.Executing;\n result: undefined;\n }\n | {\n name: string;\n toolCallId: 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 { useEffect } from \"react\";\nimport type { StandardSchemaV1, InferSchemaOutput } from \"@copilotkit/shared\";\nimport { useCopilotKit } from \"../context\";\nimport { defineToolCallRenderer } from \"../types/defineToolCallRenderer\";\n\nconst EMPTY_DEPS: ReadonlyArray<unknown> = [];\n\nexport interface RenderToolInProgressProps<S extends StandardSchemaV1> {\n name: string;\n toolCallId: string;\n parameters: Partial<InferSchemaOutput<S>>;\n status: \"inProgress\";\n result: undefined;\n}\n\nexport interface RenderToolExecutingProps<S extends StandardSchemaV1> {\n name: string;\n toolCallId: string;\n parameters: InferSchemaOutput<S>;\n status: \"executing\";\n result: undefined;\n}\n\nexport interface RenderToolCompleteProps<S extends StandardSchemaV1> {\n name: string;\n toolCallId: 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, JSON.stringify(extraDeps)]);\n}\n","import React, { useState } from \"react\";\nimport { ToolCallStatus } from \"@copilotkit/core\";\nimport { useRenderTool } from \"./use-render-tool\";\n\nexport type DefaultRenderProps = {\n /** The name of the tool being called. */\n name: string;\n /** The id of the tool call being rendered. */\n toolCallId: 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 * Shape that `useRenderToolCall` actually invokes a registered `*` renderer\n * with: `{ name, toolCallId, args, status: ToolCallStatus, result }`.\n *\n * `useDefaultRenderTool` accepts user `config.render` typed against the\n * documented {@link DefaultRenderProps}, then wraps it via {@link adaptRendererProps}\n * so the user's function receives the documented shape — not the raw\n * framework-internal one.\n */\ntype RawRendererProps = {\n name: string;\n toolCallId: string;\n args: unknown;\n status: ToolCallStatus;\n result: string | undefined;\n};\n\n/**\n * Module-level dedup set so an unknown status value only emits a console\n * warning the FIRST time we encounter it. Otherwise a stuck/unmapped status\n * would log on every re-render (potentially many per second).\n */\nconst warnedUnknownStatuses = new Set<string>();\n\n/**\n * Map a {@link ToolCallStatus} enum value to the documented string-union\n * status the {@link DefaultRenderProps} contract exposes. Unknown / future\n * enum members log a warning (once per distinct value) and fall back to\n * `\"inProgress\"`.\n */\nexport function mapToolCallStatus(\n status: ToolCallStatus,\n): DefaultRenderProps[\"status\"] {\n switch (status) {\n case ToolCallStatus.Complete:\n return \"complete\";\n case ToolCallStatus.Executing:\n return \"executing\";\n case ToolCallStatus.InProgress:\n return \"inProgress\";\n default: {\n // Surface unknown / future enum values so callers know their custom\n // renderer is being invoked with an unmapped status. Fall back to\n // \"inProgress\" — the safest treat-as-pending default. Dedup by value\n // so a stuck unmapped status doesn't spam console on every render.\n const key = String(status);\n if (!warnedUnknownStatuses.has(key)) {\n warnedUnknownStatuses.add(key);\n console.warn(\n `[CopilotKit] Unknown ToolCallStatus \"${key}\" in default tool-call renderer; falling back to \"inProgress\".`,\n );\n }\n return \"inProgress\";\n }\n }\n}\n\n/**\n * Convert the framework-internal renderer props (`args`, enum status) into\n * the documented {@link DefaultRenderProps} shape (`parameters`, string-union\n * status) so a user `config.render` always sees the documented contract.\n */\nexport function adaptRendererProps(\n props: RawRendererProps,\n): DefaultRenderProps {\n return {\n name: props.name,\n toolCallId: props.toolCallId,\n parameters: props.args,\n status: mapToolCallStatus(props.status),\n result: props.result,\n };\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 const userRender = config?.render;\n\n // When the caller supplies their own render, wrap it so it receives the\n // documented {@link DefaultRenderProps} (parameters, string-union status)\n // even though `useRenderToolCall` invokes the registered render with the\n // framework-internal `{ args, status: ToolCallStatus, ... }` shape.\n const registered: (props: RawRendererProps) => React.ReactElement = userRender\n ? (raw) => userRender(adaptRendererProps(raw))\n : (raw) => <DefaultToolCallRenderer {...adaptRendererProps(raw)} />;\n\n useRenderTool(\n {\n name: \"*\",\n // `useRenderTool` types the render with the raw framework signature;\n // the wrapper above adapts to the documented shape. We cast through\n // `unknown` to bridge the public type without `as any`.\n render: registered as unknown as (props: unknown) => React.ReactElement,\n },\n deps,\n );\n}\n\n/**\n * Guarded JSON.stringify used inside the expanded `<pre>` blocks. A circular\n * reference would otherwise crash the entire React tree on render.\n */\nfunction safeStringifyForPre(value: unknown): string {\n try {\n return JSON.stringify(value, null, 2);\n } catch (err) {\n console.warn(\n \"[CopilotKit] Failed to JSON.stringify tool-call payload for default renderer; falling back to String():\",\n err,\n );\n try {\n return String(value);\n } catch (innerErr) {\n console.warn(\n \"[CopilotKit] safeStringifyForPre: value could not be stringified:\",\n innerErr,\n );\n return \"[unserializable]\";\n }\n }\n}\n\nexport function DefaultToolCallRenderer({\n name,\n toolCallId,\n parameters,\n status,\n result,\n}: DefaultRenderProps): React.ReactElement {\n const [isExpanded, setIsExpanded] = useState(false);\n\n const isActive = status === \"inProgress\" || status === \"executing\";\n const isComplete = status === \"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 data-testid=\"copilot-tool-render\"\n data-tool-name={name}\n data-tool-call-id={toolCallId}\n data-status={status}\n data-args={safeStringifyForAttr(parameters)}\n data-result={safeStringifyForAttr(result)}\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. A real <button> with aria-expanded\n and reset styles so it visually matches the previous <div> but\n is keyboard-accessible (Enter/Space toggle natively). */}\n <button\n type=\"button\"\n aria-expanded={isExpanded}\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 width: \"100%\",\n border: \"none\",\n padding: 0,\n margin: 0,\n background: \"transparent\",\n textAlign: \"left\",\n font: \"inherit\",\n color: \"inherit\",\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 data-testid=\"copilot-tool-render-name\"\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 data-testid=\"copilot-tool-render-status\"\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 </button>\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 {safeStringifyForPre(parameters ?? {})}\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 : safeStringifyForPre(result)}\n </pre>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction safeStringifyForAttr(value: unknown): string {\n if (value === undefined || value === null) return \"\";\n if (typeof value === \"string\") return value;\n try {\n return JSON.stringify(value);\n } catch (err) {\n console.warn(\n \"[CopilotKit] Failed to JSON.stringify tool-call payload for data-* attribute; falling back to String():\",\n err,\n );\n try {\n return String(value);\n } catch (innerErr) {\n console.warn(\n \"[CopilotKit] safeStringifyForAttr: value could not be stringified:\",\n innerErr,\n );\n return \"\";\n }\n }\n}\n","import React, { useCallback, useMemo, useSyncExternalStore } from \"react\";\nimport type { ToolCall, ToolMessage } from \"@ag-ui/core\";\nimport { ToolCallStatus } from \"@copilotkit/core\";\nimport { useCopilotKit } from \"../context\";\nimport { useCopilotChatConfiguration } from \"../providers/CopilotChatConfigurationProvider\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkit/shared\";\nimport { partialJSONParse } from \"@copilotkit/shared\";\nimport type { ReactToolCallRenderer } from \"../types/react-tool-call-renderer\";\nimport {\n DefaultToolCallRenderer,\n mapToolCallStatus,\n} from \"./use-default-render-tool\";\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 toolCallId={toolCall.id}\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 toolCallId={toolCall.id}\n args={args}\n status={ToolCallStatus.Executing}\n result={undefined}\n />\n );\n } else {\n return (\n <RenderComponent\n name={toolName}\n toolCallId={toolCall.id}\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 // Fall back to the framework's built-in default tool-call renderer\n // when neither a per-tool nor a wildcard renderer has been\n // registered. This makes \"zero custom renderers\" demos paint tool\n // calls out-of-the-box instead of going invisible.\n const RenderComponent = (renderConfig?.render ??\n defaultToolCallRenderAdapter) as ReactToolCallRenderer<unknown>[\"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\n// Adapter that bridges the ReactToolCallRenderer signature\n// (`{ name, args, status, result, toolCallId }`) to the\n// `DefaultToolCallRenderer` signature (`{ name, toolCallId, parameters,\n// status, result }`) so the latter can be used as a zero-config fallback\n// when no `*` renderer is registered.\n//\n// Status mapping is delegated to `mapToolCallStatus` (an explicit switch\n// over the `ToolCallStatus` enum with a logged fallback for unknown /\n// future values). Keeping the mapping in one place ensures\n// `useDefaultRenderTool`'s opt-in render path and this zero-config\n// fallback agree on the documented string-union surface.\nfunction defaultToolCallRenderAdapter(props: {\n name: string;\n args: unknown;\n status: ToolCallStatus;\n result: string | undefined;\n toolCallId: string;\n}): React.ReactElement {\n return (\n <DefaultToolCallRenderer\n name={props.name}\n toolCallId={props.toolCallId}\n parameters={props.args}\n status={mapToolCallStatus(props.status)}\n result={props.result}\n />\n );\n}\n\n/**\n * Test-only export so the adapter's status-mapping + logging behavior can\n * be exercised directly without rebuilding the full provider/render\n * pipeline. Not part of the package public API.\n *\n * @internal\n */\nexport const __testOnly_defaultToolCallRenderAdapter =\n defaultToolCallRenderAdapter;\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, { useEffect } from \"react\";\n\n// Total reserved vertical space for the fixed license banner: banner height\n// (~36px) + bottom offset (8px) + visual gap above the chat input (~8px).\nconst LICENSE_BANNER_OFFSET_PX = 52;\nconst LICENSE_BANNER_OFFSET_VAR = \"--copilotkit-license-banner-offset\";\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 // Publish the banner's reserved bottom offset so the chat input can lift\n // itself above it via padding-bottom: var(--copilotkit-license-banner-offset).\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n const root = document.documentElement;\n root.style.setProperty(\n LICENSE_BANNER_OFFSET_VAR,\n `${LICENSE_BANNER_OFFSET_PX}px`,\n );\n return () => {\n root.style.removeProperty(LICENSE_BANNER_OFFSET_VAR);\n };\n }, []);\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.string(), 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","\"use client\";\nimport React, { useEffect, useState } from \"react\";\nimport { z } from \"zod\";\n\n/**\n * Shared pre-paint lifecycle states for the A2UI surface renderer (OSS-162).\n *\n * The A2UI middleware drives the WHOLE generative-UI lifecycle on a single\n * `a2ui-surface` activity (one stable messageId, `replace: true`), so the states\n * below swap IN PLACE and the painted surface ultimately replaces them:\n *\n * building → animated skeleton + \"Building interface\" (+ optional ~N tokens)\n * retrying → same skeleton; once perceptible, the sub-label becomes\n * \"Retrying generation… (N/M attempts)\" (threshold-gated so a fast\n * transient retry never flashes), with debug detail per debugExposure\n * failed → a clean hard-failure card (replacing the skeleton), developer\n * detail tucked into an expander gated by debugExposure\n * painted → the surface renderer owns the UI (these states render nothing)\n *\n * Timing (`showAfterMs` / `showAfterAttempts`) and how much debug detail to surface\n * (`debugExposure`) are client concerns; the server can override `debugExposure`\n * by stamping it onto the activity content (it wins over the client option).\n */\nexport type A2UIRecoveryRendererOptions = {\n /** Delay (ms) before the \"Retrying…\" sub-label becomes visible. Default 2000. */\n showAfterMs?: number;\n /** Show the \"Retrying…\" sub-label immediately once `attempt` reaches this. Default 2. */\n showAfterAttempts?: number;\n /** How much retry/debug detail to surface. Default \"collapsed\". */\n debugExposure?: \"hidden\" | \"collapsed\" | \"verbose\";\n};\n\nexport type DebugExposure = \"hidden\" | \"collapsed\" | \"verbose\";\n\n/**\n * The pre-paint lifecycle fields the middleware stamps onto the `a2ui-surface`\n * activity content (alongside `a2ui_operations` on paint). `.passthrough()` keeps\n * `a2ui_operations` and any future fields intact.\n */\nexport const A2UILifecycleFields = {\n status: z.enum([\"building\", \"retrying\", \"failed\"]).optional(),\n attempt: z.number().optional(),\n maxAttempts: z.number().optional(),\n progressTokens: z.number().optional(),\n error: z.string().optional(),\n errors: z.array(z.any()).optional(),\n attempts: z.array(z.any()).optional(),\n // Server-side knob (stamped by the A2UI middleware): \"hidden\" | \"collapsed\" | \"verbose\".\n debugExposure: z.enum([\"hidden\", \"collapsed\", \"verbose\"]).optional(),\n};\n\n/** Server-stamped debugExposure wins; else the client option; else \"collapsed\". */\nexport function resolveDebugExposure(\n content: any,\n optionDebugExposure: DebugExposure,\n): DebugExposure {\n return content?.debugExposure ?? optionDebugExposure;\n}\n\n// --- Lifecycle states ---------------------------------------------------------\n\n/** building: the generic skeleton + optional live token count. */\nexport function A2UIBuildingState({ content }: { content: any }) {\n const tokens =\n typeof content?.progressTokens === \"number\"\n ? content.progressTokens\n : undefined;\n return <A2UIGeneratingSkeleton label=\"Building interface\" tokens={tokens} />;\n}\n\n/**\n * retrying: stays the generic skeleton through fast/transient retries; only once\n * the retry is perceptible (after `showAfterMs`, or once `attempt` crosses\n * `showAfterAttempts`) does the sub-label reveal \"Retrying generation… (N/M)\".\n */\nexport function A2UIRetryingState({\n content,\n showAfterMs,\n showAfterAttempts,\n debugExposure,\n}: {\n content: any;\n showAfterMs: number;\n showAfterAttempts: number;\n debugExposure: DebugExposure;\n}) {\n const attempt =\n typeof content?.attempt === \"number\" ? content.attempt : undefined;\n const maxAttempts =\n typeof content?.maxAttempts === \"number\" ? content.maxAttempts : undefined;\n const immediate = attempt !== undefined && attempt >= showAfterAttempts;\n const [revealed, setRevealed] = useState(immediate);\n\n useEffect(() => {\n if (immediate) {\n setRevealed(true);\n return;\n }\n const timer = setTimeout(() => setRevealed(true), showAfterMs);\n return () => clearTimeout(timer);\n }, [immediate, showAfterMs]);\n\n const tokens =\n typeof content?.progressTokens === \"number\"\n ? content.progressTokens\n : undefined;\n\n // Not yet perceptible → indistinguishable from normal building.\n if (!revealed) {\n return (\n <A2UIGeneratingSkeleton label=\"Building interface\" tokens={tokens} />\n );\n }\n\n const label =\n attempt !== undefined && maxAttempts !== undefined\n ? `Retrying generation… (${attempt}/${maxAttempts} attempts)`\n : \"Retrying generation…\";\n const errors = Array.isArray(content?.errors) ? content.errors : [];\n\n return (\n <A2UIGeneratingSkeleton label={label} tokens={tokens}>\n {debugExposure !== \"hidden\" && errors.length > 0 && (\n <A2UIDebugDetails\n label=\"validation issues\"\n open={debugExposure === \"verbose\"}\n payload={{ attempt: content?.attempt, errors }}\n />\n )}\n </A2UIGeneratingSkeleton>\n );\n}\n\n/** failed: a clean hard-failure card that replaces the skeleton in place. */\nexport function A2UIRecoveryFailure({\n content,\n debugExposure,\n}: {\n content: any;\n debugExposure: DebugExposure;\n}) {\n return (\n <div className=\"cpk:rounded-lg cpk:border cpk:border-amber-200 cpk:bg-amber-50 cpk:p-3 cpk:text-sm cpk:text-amber-800\">\n <div className=\"cpk:font-medium\">Couldn't generate the UI</div>\n <div className=\"cpk:mt-1 cpk:text-xs cpk:text-amber-700\">\n Something went wrong rendering this. You can keep chatting and try\n again.\n </div>\n {debugExposure !== \"hidden\" && (\n <A2UIDebugDetails\n label=\"developer details\"\n open={debugExposure === \"verbose\"}\n payload={{ error: content?.error, attempts: content?.attempts }}\n />\n )}\n </div>\n );\n}\n\n// --- Skeleton + primitives (ported from the retired render_a2ui renderer) -----\n\n/**\n * Animated wireframe skeleton with a label, an optional live token count, and an\n * optional debug-detail slot below it. Pure CSS animation (no data dependency).\n * The `tokens` count drives a progressive reveal of skeleton rows.\n */\nexport function A2UIGeneratingSkeleton({\n label,\n tokens,\n children,\n}: {\n label: string;\n tokens?: number;\n children?: React.ReactNode;\n}) {\n // No count yet → show the fuller skeleton rather than an empty box.\n const phase =\n tokens == null\n ? 3\n : tokens < 50\n ? 0\n : tokens < 200\n ? 1\n : tokens < 400\n ? 2\n : 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={{ fontSize: 12, color: \"#a1a1aa\", letterSpacing: \"0.025em\" }}\n >\n {label}\n </span>\n {typeof tokens === \"number\" && 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 {children}\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\nexport function A2UIDebugDetails({\n label,\n open,\n payload,\n}: {\n label: string;\n open: boolean;\n payload: unknown;\n}) {\n return (\n <details open={open} className=\"cpk:mt-2 cpk:text-xs\">\n <summary className=\"cpk:cursor-pointer cpk:text-gray-500\">\n {label}\n </summary>\n <pre\n className=\"cpk:mt-1 cpk:overflow-auto cpk:rounded cpk:bg-gray-100 cpk:p-2 cpk:text-gray-700\"\n style={{ fontSize: 11 }}\n >\n {JSON.stringify(payload, null, 2)}\n </pre>\n </details>\n );\n}\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","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\";\nimport {\n A2UILifecycleFields,\n A2UIBuildingState,\n A2UIRetryingState,\n A2UIRecoveryFailure,\n resolveDebugExposure,\n type A2UIRecoveryRendererOptions,\n} from \"./A2UIRecoveryStates\";\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 the A2UI surface is building. */\n loadingComponent?: React.ComponentType;\n /**\n * Pre-paint recovery/loading UX options (OSS-162): timing before the\n * \"Retrying…\" sub-label appears + how much retry/debug detail to surface.\n */\n recovery?: A2UIRecoveryRendererOptions;\n};\n\n/**\n * The `a2ui-surface` activity carries the WHOLE generative-UI lifecycle on one\n * stable messageId (OSS-162): pre-paint `status` (\"building\" | \"retrying\" |\n * \"failed\") with recovery detail, then `a2ui_operations` on paint. The states\n * swap in place, so the painted surface replaces the skeleton with no extra\n * coordination. `.passthrough()` preserves operations + any future fields.\n */\nconst A2UISurfaceContentSchema = z\n .object({\n a2ui_operations: z.array(z.any()).optional(),\n ...A2UILifecycleFields,\n })\n .passthrough();\n\nexport function createA2UIMessageRenderer(\n options: A2UIMessageRendererOptions,\n): ReactActivityMessageRenderer<any> {\n const { theme, catalog, loadingComponent, recovery } = options;\n const showAfterMs = recovery?.showAfterMs ?? 2000;\n const showAfterAttempts = recovery?.showAfterAttempts ?? 2;\n const optionDebugExposure = recovery?.debugExposure ?? \"collapsed\";\n\n return {\n activityType: \"a2ui-surface\",\n content: A2UISurfaceContentSchema,\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 const hasOps = groupedOperations.size > 0;\n\n // Renders the pre-paint lifecycle state for a given content snapshot.\n const renderLifecycle = (c: any) => {\n const status = c?.status;\n const debugExposure = resolveDebugExposure(c, optionDebugExposure);\n if (status === \"failed\") {\n return (\n <A2UIRecoveryFailure content={c} debugExposure={debugExposure} />\n );\n }\n if (status === \"retrying\") {\n return (\n <A2UIRetryingState\n content={c}\n showAfterMs={showAfterMs}\n showAfterAttempts={showAfterAttempts}\n debugExposure={debugExposure}\n />\n );\n }\n // \"building\" / default: a host-supplied loader wins; else the skeleton.\n if (loadingComponent) {\n const LoadingComponent = loadingComponent;\n return <LoadingComponent />;\n }\n return <A2UIBuildingState content={c} />;\n };\n\n // Remember the last pre-paint snapshot so the hand-off below keeps showing\n // exactly what was on screen (building skeleton w/ its count, or the retry\n // status) instead of flickering to a generic one.\n const lastLoaderContentRef = useRef<any>(null);\n // Track from the CONTENT (not the lagging operations state) so a paint\n // snapshot never clobbers the last genuine pre-paint snapshot.\n const contentHasOps =\n Array.isArray(content?.[A2UI_OPERATIONS_KEY]) &&\n content[A2UI_OPERATIONS_KEY].length > 0;\n if (!contentHasOps) lastLoaderContentRef.current = content;\n\n // Cross-over: hold the loader in-flow while the surface mounts + paints\n // OFFSCREEN, then swap the instant the surface reports its first painted\n // content (onReady). That makes the card REPLACE the skeleton with no gap,\n // independent of stream latency / payload size / machine speed — a fixed\n // delay can't, since the \"right\" delay varies with all of those. The timer\n // below is only a safety fallback if onReady never fires. (OSS-162)\n const [surfaceReady, setSurfaceReady] = useState(false);\n const readyRef = useRef(false);\n const markSurfaceReady = useCallback(() => {\n if (readyRef.current) return;\n readyRef.current = true;\n // One frame so the painted surface is on-screen before the loader drops.\n requestAnimationFrame(() => setSurfaceReady(true));\n }, []);\n useEffect(() => {\n if (!hasOps) {\n setSurfaceReady(false);\n readyRef.current = false;\n return;\n }\n const t = setTimeout(() => setSurfaceReady(true), 8000); // fallback only\n return () => clearTimeout(t);\n }, [hasOps]);\n\n if (!hasOps) {\n // No painted surface yet → render the pre-paint lifecycle state. These\n // share this activity's messageId, so the painted surface below replaces\n // them in place once operations arrive.\n return renderLifecycle(content);\n }\n\n const surfaces = (\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 onReady={markSurfaceReady}\n />\n ))}\n </div>\n );\n\n // Stable tree: ReactSurfaceHost stays MOUNTED in the same position across\n // the hold→ready swap (only its wrapper styling toggles), so the surface\n // painted OFFSCREEN during the hold is preserved — not remounted, which\n // would reintroduce the very gap we're closing. The loader sits on top\n // until ready, then is removed and the surface drops into normal flow.\n return (\n <div style={{ position: \"relative\" }}>\n <div\n aria-hidden={!surfaceReady}\n style={\n surfaceReady\n ? undefined\n : {\n position: \"absolute\",\n inset: 0,\n opacity: 0,\n pointerEvents: \"none\",\n }\n }\n >\n {surfaces}\n </div>\n {!surfaceReady &&\n renderLifecycle(lastLoaderContentRef.current ?? content)}\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 /** Fired once the surface has processed its first operations (painted). */\n onReady?: () => void;\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 onReady,\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 onReady={onReady}\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 onReady,\n}: {\n surfaceId: string;\n operations: any[];\n onReady?: () => void;\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 // Signal the cross-over to swap ONLY once the surface can actually paint a\n // card. A data-bound list renders nothing until its data model arrives, so\n // for those we wait for the first non-empty updateDataModel; static surfaces\n // are renderable from components alone. Latency-independent. (OSS-162)\n if (onReady && surfaceHasRenderableContent(operations)) onReady();\n }, [processMessages, getSurface, surfaceId, operations, onReady]);\n\n return null;\n}\n\n/**\n * Whether the surface's operations are enough to paint a visible card yet.\n * A data-bound surface references its data via `path` and renders nothing until\n * the data model has ≥1 value; a static surface (no path refs) paints from its\n * components alone. Used to time the loader→surface cross-over to actual content\n * arrival rather than a fixed delay. (OSS-162)\n */\nfunction surfaceHasRenderableContent(operations: any[]): boolean {\n const componentOps = operations.filter((o) => o?.updateComponents);\n if (!componentOps.length) return false;\n const needsData = JSON.stringify(componentOps).includes('\"path\"');\n if (!needsData) return true;\n return operations.some((o) => {\n const v = o?.updateDataModel?.value;\n if (!v || typeof v !== \"object\") return false;\n return Object.values(v).some((x) =>\n Array.isArray(x)\n ? x.length > 0\n : x !== null && x !== undefined && x !== \"\",\n );\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 { useEffect } 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 */\nexport const RENDER_A2UI_TOOL_NAME = \"render_a2ui\";\n\n/**\n * Registers a no-op renderer for the `render_a2ui` tool call so its raw streamed\n * args are never surfaced in the transcript.\n *\n * The generation skeleton / retry / failure UX is NO LONGER owned here (OSS-162):\n * the A2UI middleware drives the whole lifecycle on the `a2ui-surface` activity\n * (one stable messageId, building → retrying → failed → painted), rendered in\n * place by `createA2UIMessageRenderer`. Owning a skeleton per tool call caused a\n * duplicate skeleton on retries / multi-call generations and a skeleton that\n * lingered after the surface painted — both fixed by retiring it here.\n *\n * Users can still override with their own `useRenderTool({ name: \"render_a2ui\" })`\n * (hook-based entries take priority over this prop-based registration).\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 nothing: the a2ui-surface activity owns all generation UX.\n render: () => <></>,\n });\n\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 \"../context\";\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","\"use client\";\n\nimport type { AbstractAgent } from \"@ag-ui/client\";\nimport type { FrontendTool } from \"@copilotkit/core\";\nimport type React from \"react\";\nimport {\n useMemo,\n useEffect,\n useLayoutEffect,\n useReducer,\n useRef,\n useState,\n} from \"react\";\nimport type { ReactNode } from \"react\";\n// Context extracted to ../context.ts for cross-platform reuse (React Native)\nimport { CopilotKitContext, LicenseContext } from \"../context\";\nimport type { CopilotKitContextValue } from \"../context\";\nexport type { CopilotKitContextValue } from \"../context\";\nexport { CopilotKitContext, useLicenseContext } from \"../context\";\nimport { z } from \"zod\";\nimport { CopilotKitInspector } from \"../components/CopilotKitInspector\";\nimport type { Anchor } from \"@copilotkit/web-inspector\";\nimport { LicenseWarningBanner } from \"../components/license-warning-banner\";\nimport { createLicenseContextValue } from \"@copilotkit/shared\";\nimport type { LicenseContextValue, DebugConfig } 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 type { A2UIRecoveryRendererOptions } from \"../a2ui/A2UIRecoveryStates\";\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// Stable frozen defaults keep provider effects from re-running just because a\n// caller omitted an object prop on a rerender.\nconst EMPTY_HEADERS: Readonly<Record<string, string>> = Object.freeze({});\nconst EMPTY_PROPERTIES: Readonly<Record<string, unknown>> = Object.freeze({});\nconst EMPTY_AGENTS: Readonly<Record<string, AbstractAgent>> = Object.freeze({});\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// Provider props interface\nexport interface CopilotKitProviderProps {\n children: ReactNode;\n runtimeUrl?: string;\n headers?: Record<string, string> | (() => 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 * Options for the A2UI error-recovery status UI (OSS-162): how long before\n * the transient \"Retrying…\" hint appears, after how many attempts, and how\n * much retry/debug detail to surface. When omitted, sane defaults apply.\n */\n recovery?: A2UIRecoveryRendererOptions;\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 * Enable debug logging for the client-side event pipeline.\n */\n debug?: DebugConfig;\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: headersProp = EMPTY_HEADERS,\n credentials,\n publicApiKey,\n publicLicenseKey,\n licenseToken,\n properties = EMPTY_PROPERTIES,\n agents__unsafe_dev_only: agents = EMPTY_AGENTS,\n selfManagedAgents = EMPTY_AGENTS,\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 debug,\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 // The a2ui-surface renderer owns the WHOLE generative-UI lifecycle (OSS-162):\n // building skeleton → retrying → hard-failure → painted surface, all on one\n // activity, swapped in place. `recovery` tunes the pre-paint UX (timing +\n // debug exposure); the server can override debugExposure via the middleware.\n renderers.unshift(\n createA2UIMessageRenderer({\n theme: a2ui?.theme ?? viewerTheme,\n catalog: a2ui?.catalog,\n loadingComponent: a2ui?.loadingComponent,\n recovery: a2ui?.recovery,\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 // Resolve headers from function or static object\n const headers =\n typeof headersProp === \"function\" ? headersProp() : headersProp;\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 debug,\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 const subscription = copilotkit.subscribe({\n onError: (event) => {\n if (onErrorRef.current) {\n onErrorRef.current(event);\n } else {\n console.error(\n `[CopilotKit] Error (${event.code}):`,\n event.error,\n event.context ?? {},\n );\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 copilotkit.setDebug(debug);\n }, [\n copilotkit,\n chatApiEndpoint,\n mergedHeaders,\n credentials,\n properties,\n mergedAgents,\n useSingleEndpoint,\n debug,\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 (inside the\n // ref-init block above) so child hooks see the correct value on first render.\n // This effect handles subsequent updates when the prop changes.\n useEffect(() => {\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// Re-export useCopilotKit from context for backward compatibility\nexport { useCopilotKit } from \"../context\";\n","import { useCopilotChatConfiguration, useCopilotKit } from \"../providers\";\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 const agent = copilotkit.getAgent(agentId);\n if (!agent) {\n return null;\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\";\n\nexport function useRenderActivityMessage() {\n const { copilotkit } = useCopilotKit();\n const agentId = useCopilotChatConfiguration()?.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 const agent = copilotkit.getAgent(agentId);\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, copilotkit, findRenderer],\n );\n\n return useMemo(\n () => ({ renderActivityMessage, findRenderer }),\n [renderActivityMessage, findRenderer],\n );\n}\n","import { useEffect } from \"react\";\nimport { useCopilotKit } from \"../context\";\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, JSON.stringify(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 followUp?: boolean;\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 followUp: config.followUp,\n },\n deps,\n );\n}\n","import { useCopilotKit } from \"../context\";\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 { useCopilotKit } from \"../context\";\nimport { useMemo, useEffect, useReducer, useRef } from \"react\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkit/shared\";\nimport type { AbstractAgent } from \"@ag-ui/client\";\nimport { HttpAgent } from \"@ag-ui/client\";\nimport {\n ProxiedCopilotRuntimeAgent,\n CopilotKitCoreRuntimeConnectionStatus,\n} from \"@copilotkit/core\";\nimport type { SubscribeToAgentSubscriber } from \"@copilotkit/core\";\nimport { useCopilotChatConfiguration } from \"../providers/CopilotChatConfigurationProvider\";\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 updates?: UseAgentUpdate[];\n /**\n * Throttle interval (in milliseconds) for re-renders triggered by\n * `onMessagesChanged` and `onStateChanged` notifications. Useful to reduce\n * re-render frequency during high-frequency streaming updates.\n *\n * Uses a leading+trailing pattern with a shared window — first update\n * fires immediately, subsequent updates within the window are coalesced,\n * and a trailing timer ensures the most recent update fires after the\n * window expires. See `CopilotKitCore.subscribeToAgentWithOptions` in `@copilotkit/core`\n * for details.\n *\n * Resolved as: `throttleMs ?? provider defaultThrottleMs ?? 0`.\n * Passing `throttleMs={0}` explicitly disables throttling even when the\n * provider specifies a non-zero `defaultThrottleMs`.\n *\n * Run lifecycle callbacks (`onRunInitialized`, `onRunFinalized`,\n * `onRunFailed`, `onRunErrorEvent`) always fire immediately.\n *\n * @default undefined\n * When unset, inherits from the provider's `defaultThrottleMs`;\n * if that is also unset, the effective value is `0` (no throttle).\n */\n throttleMs?: number;\n}\n\nexport function useAgent({ agentId, updates, throttleMs }: UseAgentProps = {}) {\n agentId ??= DEFAULT_AGENT_ID;\n\n const { copilotkit } = useCopilotKit();\n // Read the provider-level default so it appears in the effect's dep array.\n // subscribeToAgentWithOptions reads it from the core instance, but React needs the dep\n // to know when to re-subscribe.\n const providerThrottleMs = copilotkit.defaultThrottleMs;\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 const existing = copilotkit.getAgent(agentId);\n if (existing) {\n // Real agent found — clear any cached provisional for this ID\n provisionalAgentCache.current.delete(agentId);\n return existing;\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(agentId);\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 provisionalAgentCache.current.set(agentId, 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 const cached = provisionalAgentCache.current.get(agentId);\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 provisionalAgentCache.current.set(agentId, 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 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 let active = true;\n const handlers: SubscribeToAgentSubscriber = {};\n\n // Microtask-batched forceUpdate: coalesces multiple synchronous\n // notifications (e.g. OnStateChanged + OnRunStatusChanged firing in the\n // same tick) into a single React re-render. This prevents the scroll\n // jumping described in #3499 where rapid unbatched forceUpdate calls\n // cause brief content height fluctuations during streaming.\n let batchScheduled = false;\n const batchedForceUpdate = () => {\n if (!active) return;\n if (!batchScheduled) {\n batchScheduled = true;\n queueMicrotask(() => {\n batchScheduled = false;\n if (active) {\n forceUpdate();\n }\n });\n }\n };\n\n if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) {\n handlers.onMessagesChanged = batchedForceUpdate;\n }\n\n if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) {\n handlers.onStateChanged = batchedForceUpdate;\n }\n\n if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {\n handlers.onRunInitialized = batchedForceUpdate;\n handlers.onRunFinalized = batchedForceUpdate;\n handlers.onRunFailed = batchedForceUpdate;\n // Protocol-level RUN_ERROR event (distinct from onRunFailed which\n // handles local exceptions like network errors).\n handlers.onRunErrorEvent = batchedForceUpdate;\n }\n\n const subscription = copilotkit.subscribeToAgentWithOptions(\n agent,\n handlers,\n {\n throttleMs,\n },\n );\n return () => {\n active = false;\n subscription.unsubscribe();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agent, forceUpdate, throttleMs, providerThrottleMs, 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 // Propagate the caller-supplied threadId from the chat configuration onto\n // the agent. AbstractAgent's constructor auto-mints a UUID when no threadId\n // is passed, so without this sync the agent ships its own random UUID in\n // /agent/run, /agent/connect, /agent/stop — diverging from the threadId the\n // app code reads via useThreads/useCopilotChatConfiguration. Gated on\n // hasExplicitThreadId so a ThreadsProvider-minted placeholder UUID doesn't\n // overwrite the auto-minted agent UUID (both are random and useless to the\n // backend; the explicit gate keeps the agent's UUID stable across renders).\n const chatConfig = useCopilotChatConfiguration();\n const configThreadId = chatConfig?.threadId;\n const configHasExplicitThreadId = chatConfig?.hasExplicitThreadId;\n useEffect(() => {\n if (!configHasExplicitThreadId || !configThreadId) return;\n agent.threadId = configThreadId;\n }, [agent, configThreadId, configHasExplicitThreadId]);\n\n return {\n agent,\n };\n}\n","import type { AgentCapabilities } from \"@ag-ui/core\";\nimport { useAgent } from \"./use-agent\";\n\n/**\n * Returns the capabilities declared by the given agent (or the default agent).\n * Capabilities are populated from the runtime `/info` response at connection\n * time. The hook reads them synchronously from the agent instance — there is\n * no separate loading state, but the value will be `undefined` until the\n * runtime handshake completes.\n *\n * @param agentId - Optional agent ID. If omitted, uses the default agent.\n * @returns The agent's capabilities, or `undefined` if the agent doesn't\n * declare capabilities.\n */\nexport function useCapabilities(\n agentId?: string,\n): AgentCapabilities | undefined {\n const { agent } = useAgent({ agentId });\n\n if (agent && \"capabilities\" in agent) {\n return (agent as { capabilities?: AgentCapabilities }).capabilities;\n }\n\n return undefined;\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { Suggestion } from \"@copilotkit/core\";\nimport { useCopilotKit } from \"../context\";\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 \"../context\";\nimport { useCopilotChatConfiguration } from \"../providers/CopilotChatConfigurationProvider\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkit/shared\";\nimport type {\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 isDynamicConfigType = useMemo(\n () => !!normalizedConfig && \"instructions\" in normalizedConfig,\n [normalizedConfig],\n );\n\n const requestReload = useCallback(() => {\n if (!normalizedConfig) {\n return;\n }\n\n if (isGlobalConfig) {\n const seen = new Set<string>();\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 seen.add(agentId);\n if (!entry.isRunning) {\n copilotkit.reloadSuggestions(agentId);\n }\n }\n // Also reload for the chat's resolved consumer agent. The registry can\n // be empty at this point (e.g. runtime info still loading), in which\n // case the loop above wouldn't have fired for the agent the user is\n // actually chatting with — and the welcome screen would render with\n // no suggestions until they navigate away and back.\n if (targetAgentId && !seen.has(targetAgentId)) {\n copilotkit.reloadSuggestions(targetAgentId);\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 // When agents arrive after the initial render (runtime info just landed),\n // re-request a reload so dynamic configs that need a real agent can finally\n // generate. Skip for static configs — they don't need an agent and the\n // initial mount reload already handled them. Skip when the target agent\n // is already in the registry — the initial reload already covered it, and\n // re-firing on every subsequent `onAgentsChanged` (e.g. dev-mode hot\n // reloads, sibling chat configs mounting) would stack overlapping\n // generations.\n useEffect(() => {\n if (!normalizedConfig || !isDynamicConfigType) return;\n if (!targetAgentId) return;\n\n const initiallyPresent = !!copilotkit.getAgent(targetAgentId);\n if (initiallyPresent) return;\n\n const subscription = copilotkit.subscribe({\n onAgentsChanged: () => {\n if (copilotkit.getAgent(targetAgentId)) {\n requestReload();\n subscription.unsubscribe();\n }\n },\n });\n return () => {\n subscription.unsubscribe();\n };\n }, [\n copilotkit,\n normalizedConfig,\n isDynamicConfigType,\n targetAgentId,\n requestReload,\n ]);\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 \"../context\";\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 // Do NOT synchronously clear pendingEvent here — onRunStartedEvent\n // already clears it when the resume run begins. Clearing synchronously\n // unmounts the card before commit, which previously forced consumers\n // to wrap their resolve() in a 500ms setTimeout to keep the UI alive.\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 // Stabilize consumer-supplied callbacks behind refs so inline lambdas\n // (a new identity every parent render) do NOT churn the element memo\n // identity or the handler effect. Without this, every dep-churn cycle\n // would re-run the publish effect's cleanup, racing a stale `null` past\n // the new element and unmounting the in-chat card on each render.\n const renderRef = useRef(config.render);\n renderRef.current = config.render;\n const enabledRef = useRef(config.enabled);\n enabledRef.current = config.enabled;\n const handlerRef = useRef(config.handler);\n handlerRef.current = config.handler;\n // F4: mirror `resolve` behind a ref so the handler effect does not depend\n // on resolve's identity. Without this, churn in [agent, copilotkit]\n // (resolve's deps) would re-run the effect for the same pendingEvent and\n // double-invoke the consumer handler.\n const resolveRef = useRef(resolve);\n resolveRef.current = resolve;\n\n // F5: predicate evaluator that treats a throw as \"disabled\" (false) and\n // logs the error. Called from both the handler effect and the element\n // memo, neither of which may crash the React tree on a consumer bug.\n const isEnabled = (event: InterruptEvent): boolean => {\n const predicate = enabledRef.current;\n if (!predicate) return true;\n try {\n return predicate(event);\n } catch (err) {\n console.error(\n \"[CopilotKit] useInterrupt enabled predicate threw; treating interrupt as disabled:\",\n err,\n );\n return false;\n }\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 // F5: a throw from the predicate is treated as \"disabled\".\n if (!isEnabled(pendingEvent)) {\n setHandlerResult(null);\n return;\n }\n const handler = handlerRef.current;\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 // F3: a synchronous throw from the consumer handler must not escape the\n // effect. Honor the documented contract (\"Rejecting/throwing falls back\n // to `result = null`\") at the sync branch too.\n let maybePromise: ReturnType<typeof handler>;\n try {\n maybePromise = handler({\n event: pendingEvent,\n resolve: resolveRef.current,\n });\n } catch (err) {\n console.error(\n \"[CopilotKit] useInterrupt handler threw; result will be null:\",\n err,\n );\n if (!cancelled) setHandlerResult(null);\n return () => {\n cancelled = true;\n };\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((err) => {\n // F3 (companion): log the async failure so it isn't silently\n // swallowed, while preserving the documented null-fallback.\n console.error(\n \"[CopilotKit] useInterrupt handler rejected; result will be null:\",\n err,\n );\n if (!cancelled) setHandlerResult(null);\n });\n } else {\n setHandlerResult(maybePromise);\n }\n\n return () => {\n cancelled = true;\n };\n // F4: depend ONLY on pendingEvent. resolve is read via resolveRef so\n // identity churn in [agent, copilotkit] cannot double-fire the handler.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [pendingEvent]);\n\n const element = useMemo(() => {\n if (!pendingEvent) return null;\n // F5: throwing predicate → disabled.\n if (!isEnabled(pendingEvent)) return null;\n\n return renderRef.current({\n event: pendingEvent,\n result: handlerResult,\n resolve,\n });\n }, [pendingEvent, handlerResult, resolve]);\n\n // Publish to core for in-chat rendering. Publish-only — do NOT nullify\n // on dep churn; the element memo already returns null when pendingEvent\n // is null (the legitimate clear path: onRunStartedEvent / onRunFailed).\n useEffect(() => {\n if (config.renderInChat === false) return;\n copilotkit.setInterruptElement(element);\n }, [element, config.renderInChat, copilotkit]);\n\n // Nullify on true unmount only. Separate effect with empty deps so the\n // cleanup runs exactly once when the component is removed from the tree.\n useEffect(() => {\n if (config.renderInChat === false) return;\n return () => {\n copilotkit.setInterruptElement(null);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\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 \"../context\";\nimport {\n CopilotKitCoreRuntimeConnectionStatus,\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 * ISO-8601 timestamp of the most recent agent run on this thread. Absent\n * when the thread has never been run. Prefer this over `updatedAt` for\n * user-facing \"last activity\" displays — it is not bumped by metadata-only\n * actions like rename or archive.\n */\n lastRunAt?: 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, lastRunAt }) => ({\n id,\n agentId,\n name,\n archived,\n createdAt,\n updatedAt,\n ...(lastRunAt !== undefined ? { lastRunAt } : {}),\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\n // Tracks whether we've dispatched the first real context to the store.\n // The store itself starts with `isLoading: false`, so before we dispatch\n // consumers would otherwise see an empty, non-loading state (empty-list\n // flash). While runtimeUrl is set and we haven't dispatched yet, we\n // synthesize `isLoading: true` so the UI keeps its loading indicator until\n // the first fetch is in flight (at which point the store's own\n // isLoading takes over).\n const [hasDispatchedContext, setHasDispatchedContext] = useState(false);\n const preConnectLoading = !!copilotkit.runtimeUrl && !hasDispatchedContext;\n\n const isLoading = runtimeError ? false : preConnectLoading || storeIsLoading;\n const error = runtimeError ?? storeError;\n\n useEffect(() => {\n store.start();\n return () => {\n store.stop();\n };\n }, [store]);\n\n // Defer setting the context until the runtime reports Connected. Before\n // `/info` resolves we don't know `intelligence.wsUrl`, so dispatching the\n // context early would issue a list fetch with `wsUrl: undefined`, then a\n // second list fetch (and a `/threads/subscribe`) once the flag lands.\n // Waiting lets the hook issue just one `/threads?…` + one `/threads/subscribe`.\n //\n // When `runtimeUrl` is absent we dispatch `null` to clear the store. For\n // transient states (Disconnected/Connecting/Error with a URL still set) we\n // leave the previously-dispatched context in place — any in-flight\n // realtime subscription or cached thread list stays usable while the\n // runtime recovers, and we don't re-trigger a fetch storm on transitions.\n const runtimeStatus = copilotkit.runtimeConnectionStatus;\n useEffect(() => {\n copilotkit.registerThreadStore(agentId, store);\n return () => {\n copilotkit.unregisterThreadStore(agentId);\n };\n }, [copilotkit, agentId, store]);\n\n useEffect(() => {\n if (!copilotkit.runtimeUrl) {\n store.setContext(null);\n return;\n }\n\n // Wait for /info to land so we can include `wsUrl` in the initial\n // context and avoid a redundant second list fetch.\n if (runtimeStatus !== CopilotKitCoreRuntimeConnectionStatus.Connected) {\n return;\n }\n\n const context: ɵThreadRuntimeContext = {\n runtimeUrl: copilotkit.runtimeUrl,\n headers: { ...copilotkit.headers },\n wsUrl: copilotkit.intelligence?.wsUrl,\n agentId,\n includeArchived,\n limit,\n };\n\n store.setContext(context);\n setHasDispatchedContext(true);\n }, [\n store,\n copilotkit.runtimeUrl,\n runtimeStatus,\n headersKey,\n copilotkit.intelligence?.wsUrl,\n agentId,\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 { randomUUID } from \"@copilotkit/shared\";\n\n/**\n * The result shape returned by the CopilotKit runtime `/annotate` endpoint.\n */\nexport interface RecordAnnotationResult {\n /** Platform-assigned id of the annotation row. */\n id: string;\n /** `true` when the platform recognized this `clientEventId` as a retry. */\n duplicate: boolean;\n}\n\n/**\n * Arguments for {@link recordAnnotation}.\n *\n * The transport dependencies (`runtimeUrl`, `headers`) mirror what the\n * `useLearnFromUserAction` hook reads from `copilotkit` context, so the hook\n * can pass them through without any structural change.\n *\n * `userId` is intentionally absent — the runtime resolves the user from BFF\n * auth server-side and the browser must never send it.\n */\nexport interface RecordAnnotationArgs {\n /**\n * Base URL of the customer's CopilotKit runtime\n * (e.g. `https://bff.example.com/api/copilotkit`).\n * The function appends `/annotate`.\n */\n runtimeUrl: string;\n /**\n * Extra HTTP headers forwarded from `copilotkit.headers` — typically used\n * for customer auth tokens that the BFF needs to identify the user.\n */\n headers: Record<string, string>;\n /**\n * The annotation discriminant understood by the Intelligence platform.\n * Known values: `\"user_action\"`, `\"set_learning_containers\"`.\n */\n type: string;\n /**\n * Free-form, JSON-serializable payload whose shape depends on `type`.\n * Omit (or pass `undefined`) for annotation types with no payload body.\n */\n payload?: unknown;\n /** Thread the annotation is associated with. */\n threadId: string;\n /**\n * Caller-supplied idempotency key. When omitted, a UUID is generated so\n * every call is naturally safe against platform-level duplicate processing.\n * Supply your own key when the same semantic event must stay idempotent\n * across multiple calls (e.g. a retry button or a React strict-mode\n * double-mount).\n */\n clientEventId?: string;\n /**\n * ISO-8601 client-asserted timestamp.\n * Defaults to server `NOW()` when absent.\n */\n occurredAt?: string;\n}\n\n/**\n * Low-level function that posts an arbitrary annotation to the CopilotKit\n * runtime's general annotation endpoint (`POST /annotate`).\n *\n * This is the single transport entry point for all annotation types. Higher-\n * level hooks (e.g. `useLearnFromUserAction`) build the `type`/`payload` pair\n * for their specific annotation shape and delegate the HTTP call here.\n *\n * The function uses the same transport as `useLearnFromUserAction`:\n * - `runtimeUrl` from `copilotkit.runtimeUrl` (BFF proxies to the platform)\n * - `headers` from `copilotkit.headers` (customer auth forwarded to BFF)\n * - `clientEventId` auto-generated via `randomUUID()` when omitted\n * - `userId` is resolved server-side by the runtime; the client never sends it\n * - Errors propagate to the caller (fire-and-propagate, not fire-and-forget)\n *\n * @param args - Transport dependencies plus annotation fields.\n * @returns The platform result containing the annotation row `id` and a\n * `duplicate` flag.\n * @throws When the network request fails or the runtime returns a non-2xx\n * status. Callers that want fire-and-forget behavior should `.catch`\n * at the call site.\n */\nexport async function recordAnnotation(\n args: RecordAnnotationArgs,\n): Promise<RecordAnnotationResult> {\n const { runtimeUrl, headers, type, payload, threadId, occurredAt } = args;\n\n const clientEventId = args.clientEventId ?? randomUUID();\n\n const body: Record<string, unknown> = {\n type,\n threadId,\n clientEventId,\n ...(payload !== undefined ? { payload } : {}),\n ...(occurredAt !== undefined ? { occurredAt } : {}),\n };\n\n const response = await fetch(`${runtimeUrl}/annotate`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...headers,\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => \"\");\n throw new Error(\n `recordAnnotation: request failed (${response.status})${text ? `: ${text}` : \"\"}`,\n );\n }\n\n const text = await response.text();\n if (!text) {\n throw new Error(\n `recordAnnotation: runtime ${runtimeUrl}/annotate returned ${response.status} with an empty body`,\n );\n }\n try {\n return JSON.parse(text) as RecordAnnotationResult;\n } catch {\n throw new Error(\n `recordAnnotation: runtime ${runtimeUrl}/annotate returned a non-JSON body (status ${response.status})`,\n );\n }\n}\n","import { useCallback } from \"react\";\nimport { useCopilotKit } from \"../context\";\nimport { recordAnnotation } from \"../lib/record-annotation\";\n\n/**\n * Input to {@link UseLearnFromUserActionRecorder}, the function returned\n * by {@link useLearnFromUserAction}. Captures a single UI interaction that\n * the Intelligence platform's auto-curated knowledge base loop will distill\n * into the team's `/project` notes.\n */\nexport interface LearnFromUserActionInput {\n /** Thread the action is associated with. May be unknown to the platform. */\n threadId: string;\n /** Short, agent-readable summary of what the user did. Optional. */\n title?: string | null;\n /** Optional longer explanation. */\n description?: string | null;\n /** Free-form, JSON-serializable snapshot describing the action. Optional. */\n data?: unknown;\n /** ISO-8601 client-asserted timestamp. Defaults to server NOW() when absent. */\n occurredAt?: string;\n /**\n * Caller-supplied idempotency key. When omitted, `recordAnnotation` generates a\n * fresh UUID per call so retries collapse to the original row at the\n * platform. Supply your own to keep a single semantic event idempotent\n * across calls (e.g. a React re-render or a manual retry button).\n */\n clientEventId?: string;\n}\n\n/** Outcome returned by the recorder function. */\nexport interface LearnFromUserActionResult {\n /** Platform-assigned id of the user-action row. */\n id: string;\n /** True when the platform recognized this `clientEventId` as a retry. */\n duplicate: boolean;\n}\n\n/** Recorder function returned by {@link useLearnFromUserAction}. */\nexport type UseLearnFromUserActionRecorder = (\n input: LearnFromUserActionInput,\n) => Promise<LearnFromUserActionResult>;\n\n/**\n * Record a user UI interaction in the Intelligence platform's user-actions\n * stream. The platform's auto-curated knowledge base agent reads these\n * (alongside finished agent runs) and writes free-form Obsidian-flavored\n * markdown to `/project`, where any agent in the same project can later\n * read it via the `copilotkit_knowledge_base_shell` MCP tool.\n *\n * The hook returns a stable function. Calling it issues a request to the\n * customer's CopilotKit runtime (`POST ${runtimeUrl}/annotate`), which\n * resolves the Intel user from the BFF's auth and forwards to the\n * platform — the Intel API key never reaches the browser.\n *\n * If `clientEventId` is omitted `recordAnnotation` generates a UUID per call,\n * so a naive double-call (e.g. React 18 strict-mode double-mount, or a retry\n * after a network blip on a fresh Promise) is naturally safe. Supply your\n * own key when a single semantic event must remain idempotent across\n * multiple `learnFromUserAction(...)` calls.\n *\n * @example\n * ```tsx\n * import { useLearnFromUserAction } from \"@copilotkit/react-core\";\n *\n * function SettingsPage({ threadId }) {\n * const learnFromUserAction = useLearnFromUserAction();\n *\n * const onRename = (oldName: string, newName: string) => {\n * void learnFromUserAction({\n * threadId,\n * title: \"Renamed project\",\n * data: { previous: { name: oldName }, next: { name: newName } },\n * });\n * };\n * }\n * ```\n */\nexport function useLearnFromUserAction(): UseLearnFromUserActionRecorder {\n const { copilotkit } = useCopilotKit();\n\n return useCallback(\n async (\n input: LearnFromUserActionInput,\n ): Promise<LearnFromUserActionResult> => {\n const runtimeUrl = copilotkit.runtimeUrl;\n if (!runtimeUrl) {\n throw new Error(\n \"useLearnFromUserAction: runtimeUrl is not configured. Set it on <CopilotKitProvider runtimeUrl=...>.\",\n );\n }\n\n const payload: Record<string, unknown> = {\n ...(input.title !== undefined ? { title: input.title } : {}),\n ...(input.description !== undefined\n ? { description: input.description }\n : {}),\n ...(input.data !== undefined ? { data: input.data } : {}),\n };\n\n return recordAnnotation({\n runtimeUrl,\n headers: copilotkit.headers ?? {},\n type: \"user_action\",\n payload: Object.keys(payload).length > 0 ? payload : undefined,\n threadId: input.threadId,\n clientEventId: input.clientEventId,\n occurredAt: input.occurredAt,\n });\n },\n [copilotkit],\n );\n}\n","import { useCallback } from \"react\";\nimport { useCopilotChatConfiguration } from \"../providers\";\nimport type {\n LearnFromUserActionInput,\n LearnFromUserActionResult,\n} from \"./use-learn-from-user-action\";\nimport { useLearnFromUserAction } from \"./use-learn-from-user-action\";\n\n/**\n * Input to {@link UseLearnFromUserActionInCurrentThreadRecorder} — same as\n * {@link LearnFromUserActionInput} minus `threadId`, which is sourced from\n * the surrounding `<CopilotChatConfigurationProvider>` at call time.\n */\nexport type LearnFromUserActionInCurrentThreadInput = Omit<\n LearnFromUserActionInput,\n \"threadId\"\n>;\n\n/** Recorder function returned by {@link useLearnFromUserActionInCurrentThread}. */\nexport type UseLearnFromUserActionInCurrentThreadRecorder = (\n input: LearnFromUserActionInCurrentThreadInput,\n) => Promise<LearnFromUserActionResult>;\n\n/**\n * Record a user UI interaction against the **current chat's** thread. The\n * `threadId` is sourced from the surrounding\n * `<CopilotChatConfigurationProvider>` (the same provider `<CopilotChat>`,\n * `<CopilotSidebar>`, and friends set up), so callers in a chat-aware\n * subtree don't need to thread an id through manually.\n *\n * Throws on **call** (not on mount) when there is no chat-config provider\n * in scope — matches the \"throw on call when runtimeUrl is missing\"\n * behavior of {@link useLearnFromUserAction}. Mounting the hook in a branch\n * that never fires is harmless.\n *\n * The recorder does NOT accept a `threadId` override. If you need to\n * record against an explicit thread, use {@link useLearnFromUserAction}\n * directly — two hooks, two crisp contracts, no mode confusion.\n *\n * This hook always uses `config.threadId`, regardless of whether the\n * surrounding chat config minted it internally or received one from\n * the caller. Auto-minted threads simply mean the action lands under\n * a thread the platform never saw — the writer agent still distills\n * user-action-only threads (it does not require the thread to exist\n * in `cpki.threads`), so the loop keeps learning.\n *\n * @example\n * ```tsx\n * import { useLearnFromUserActionInCurrentThread } from \"@copilotkit/react-core\";\n *\n * function SettingsPanel() {\n * const learnFromUserAction = useLearnFromUserActionInCurrentThread();\n *\n * const onRename = (oldName: string, newName: string) => {\n * void learnFromUserAction({\n * title: \"Renamed project\",\n * data: { previous: { name: oldName }, next: { name: newName } },\n * });\n * };\n *\n * // ...\n * }\n * ```\n */\nexport function useLearnFromUserActionInCurrentThread(): UseLearnFromUserActionInCurrentThreadRecorder {\n const config = useCopilotChatConfiguration();\n const learnFromUserAction = useLearnFromUserAction();\n\n return useCallback(\n async (\n input: LearnFromUserActionInCurrentThreadInput,\n ): Promise<LearnFromUserActionResult> => {\n const threadId = config?.threadId;\n if (!threadId) {\n throw new Error(\n \"useLearnFromUserActionInCurrentThread: no CopilotChatConfigurationProvider in scope. \" +\n \"Wrap the call site in <CopilotChat>, <CopilotSidebar>, or <CopilotChatConfigurationProvider>, \" +\n \"or use `useLearnFromUserAction()` and pass `threadId` explicitly.\",\n );\n }\n return learnFromUserAction({ ...input, threadId });\n },\n [config?.threadId, learnFromUserAction],\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 { useEffect, useRef } from \"react\";\nimport { useCopilotKit } from \"../context\";\nimport { recordAnnotation } from \"../lib/record-annotation\";\n\n/** The default learning containers value. Matches the backend default. */\nconst DEFAULT_CONTAINERS: string[] = [\"project\"];\n\n/**\n * Arguments for {@link useLearningContainers}.\n */\nexport interface UseLearningContainersArgs {\n /** Thread to apply the learning-container selection to. */\n threadId: string;\n /**\n * The ordered list of learning container identifiers to activate for this\n * thread. Defaults to `[\"project\"]` on the backend when absent.\n */\n learningContainers: readonly string[];\n}\n\n/**\n * Declaratively keeps a thread's learning containers in sync by emitting\n * `set_learning_containers` annotations via the CopilotKit runtime annotate\n * endpoint (`POST ${runtimeUrl}/annotate`).\n *\n * **Emit rules:**\n * - On mount with `[\"project\"]` (the backend default) → does NOT emit.\n * Absence of an annotation equals the default, so the round-trip is skipped.\n * - On mount with any other value → emits immediately.\n * - On any subsequent content change (including a switch back to\n * `[\"project\"]`) → emits (a deliberate switch is always recorded).\n * - On unmount or threadId change → emits a reset to `[\"project\"]`\n * so the backend is left in a clean state for the next consumer.\n * Changing `learningContainers` within the same thread does NOT reset the\n * thread; only the new value is emitted.\n *\n * Content-equality is evaluated via `JSON.stringify` so a fresh array literal\n * with the same items does NOT trigger a redundant emit.\n *\n * If `runtimeUrl` is absent, all emits are silently skipped.\n *\n * @example\n * ```tsx\n * function ThreadPane({ threadId, userScope }: Props) {\n * useLearningContainers({\n * threadId,\n * learningContainers: [userScope],\n * });\n * // ...\n * }\n * ```\n */\nexport function useLearningContainers({\n threadId,\n learningContainers,\n}: UseLearningContainersArgs): void {\n const { copilotkit } = useCopilotKit();\n\n /**\n * Tracks the last-synced container list so content-identical rerenders\n * (fresh array, same values) do not fire a redundant emit.\n * `null` = nothing synced yet (initial state or after a threadId reset).\n */\n const lastSyncedRef = useRef<readonly string[] | null>(null);\n\n /** Guards the missing-runtimeUrl warning so it fires at most once per hook instance. */\n const warnedMissingUrlRef = useRef(false);\n\n // Keep a ref to the latest transport values so the cleanup effect can read\n // them without being added to its dep array (which would cause it to re-run\n // and re-register on every render).\n const runtimeUrlRef = useRef<string | null | undefined>(\n copilotkit.runtimeUrl,\n );\n const headersRef = useRef<Record<string, string>>(copilotkit.headers ?? {});\n runtimeUrlRef.current = copilotkit.runtimeUrl;\n headersRef.current = copilotkit.headers ?? {};\n\n // Content-stable dependency: same items in same order → same key string.\n const key = JSON.stringify(learningContainers);\n const defaultKey = JSON.stringify(DEFAULT_CONTAINERS);\n\n // ── Effect 1: sync containers ──────────────────────────────────────────────\n // Fires on mount, on threadId change, and on container-content change.\n // Does NOT emit a reset on cleanup — container changes within the same thread\n // are direct transitions, not reset-then-set.\n // threadId changes are handled by Effect 2's cleanup.\n useEffect(() => {\n const runtimeUrl = copilotkit.runtimeUrl;\n const headers = copilotkit.headers ?? {};\n\n /**\n * Fire-and-forget emit; errors must not surface in render.\n * Failures are logged as warnings so they are diagnosable without\n * propagating into the React render cycle.\n */\n const emit = (containers: readonly string[]): void => {\n if (!runtimeUrl) {\n if (!warnedMissingUrlRef.current) {\n warnedMissingUrlRef.current = true;\n console.warn(\n \"useLearningContainers: runtimeUrl not configured; learning-container sync disabled\",\n );\n }\n return;\n }\n recordAnnotation({\n runtimeUrl,\n headers,\n type: \"set_learning_containers\",\n payload: { containers },\n threadId,\n }).catch((err) => {\n console.warn(\n \"useLearningContainers: failed to record set_learning_containers\",\n err,\n );\n });\n };\n\n if (lastSyncedRef.current === null) {\n // First run (or after a threadId reset): skip if already on the default.\n if (key === defaultKey) {\n lastSyncedRef.current = learningContainers;\n return;\n }\n emit(learningContainers);\n lastSyncedRef.current = learningContainers;\n } else {\n // Subsequent runs: only emit when the content actually changed.\n const lastKey = JSON.stringify(lastSyncedRef.current);\n if (key !== lastKey) {\n emit(learningContainers);\n lastSyncedRef.current = learningContainers;\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [threadId, key]);\n\n // ── Effect 2: unmount / threadId-change reset ──────────────────────────────\n // Runs whenever threadId changes and on unmount.\n // The cleanup emits the reset for the OLD threadId before the new one takes\n // over (or on final unmount). We intentionally do NOT re-run this effect when\n // runtimeUrl or headers change — we read the latest values via refs instead.\n useEffect(() => {\n // Capture the threadId that was active when this effect ran.\n const capturedThreadId = threadId;\n\n return () => {\n const capturedRuntimeUrl = runtimeUrlRef.current;\n const capturedHeaders = headersRef.current;\n\n if (capturedRuntimeUrl) {\n recordAnnotation({\n runtimeUrl: capturedRuntimeUrl,\n headers: capturedHeaders,\n type: \"set_learning_containers\",\n payload: { containers: DEFAULT_CONTAINERS },\n threadId: capturedThreadId,\n }).catch((err) => {\n console.warn(\n \"useLearningContainers: failed to record set_learning_containers\",\n err,\n );\n });\n }\n\n // Reset tracking so the next effect run (new threadId) starts fresh.\n lastSyncedRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [threadId]);\n}\n","import { useCopilotChatConfiguration } from \"../providers\";\nimport type { UseLearningContainersArgs } from \"./use-learning-containers\";\nimport { useLearningContainers } from \"./use-learning-containers\";\n\n/**\n * Arguments for {@link useLearningContainersInCurrentThread}.\n * Same as {@link UseLearningContainersArgs} minus `threadId`, which is\n * sourced from the surrounding `<CopilotChatConfigurationProvider>` at\n * render time.\n */\nexport type UseLearningContainersInCurrentThreadArgs = Omit<\n UseLearningContainersArgs,\n \"threadId\"\n>;\n\n/**\n * Declaratively keeps the **current chat thread's** learning containers in\n * sync. The `threadId` is sourced from the surrounding\n * `<CopilotChatConfigurationProvider>` (the same provider `<CopilotChat>`,\n * `<CopilotSidebar>`, and friends set up), so callers in a chat-aware\n * subtree don't need to thread an id through manually.\n *\n * **Throws on render** when there is no chat-config provider in scope or\n * when the provider does not yet have an active `threadId`. Mount the hook\n * inside a subtree that is guaranteed to have a thread context.\n *\n * If you need to manage an explicit thread, use {@link useLearningContainers}\n * directly — two hooks, two crisp contracts, no mode confusion.\n *\n * @throws When no `CopilotChatConfigurationProvider` is in scope or when the\n * active `threadId` is absent/empty.\n *\n * @example\n * ```tsx\n * function ThreadPanel({ scope }: Props) {\n * useLearningContainersInCurrentThread({\n * learningContainers: [scope],\n * });\n * // ...\n * }\n * ```\n */\nexport function useLearningContainersInCurrentThread({\n learningContainers,\n}: UseLearningContainersInCurrentThreadArgs): void {\n const config = useCopilotChatConfiguration();\n const threadId = config?.threadId;\n\n if (!threadId) {\n throw new Error(\n \"useLearningContainersInCurrentThread must be used within a thread context (no active threadId). \" +\n \"Wrap the component in <CopilotChat>, <CopilotSidebar>, or <CopilotChatConfigurationProvider>, \" +\n \"or use `useLearningContainers()` and pass `threadId` explicitly.\",\n );\n }\n\n // Delegate to the base hook. The threadId is stable from the config context.\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useLearningContainers({ threadId, learningContainers });\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 { copyToClipboard } from \"@copilotkit/shared\";\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 return await copyToClipboard(message.content);\n }\n return false;\n },\n },\n );\n\n const boundThumbsUpButton = renderSlot(\n thumbsUpButton,\n CopilotChatAssistantMessage.ThumbsUpButton,\n {\n onClick: onThumbsUp ? () => onThumbsUp(message) : undefined,\n },\n );\n\n const boundThumbsDownButton = renderSlot(\n thumbsDownButton,\n CopilotChatAssistantMessage.ThumbsDownButton,\n {\n onClick: onThumbsDown ? () => onThumbsDown(message) : undefined,\n },\n );\n\n const boundReadAloudButton = renderSlot(\n readAloudButton,\n CopilotChatAssistantMessage.ReadAloudButton,\n {\n onClick: onReadAloud ? () => onReadAloud(message) : undefined,\n },\n );\n\n const boundRegenerateButton = renderSlot(\n regenerateButton,\n CopilotChatAssistantMessage.RegenerateButton,\n {\n onClick: onRegenerate ? () => onRegenerate(message) : undefined,\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 = async (event: React.MouseEvent<HTMLButtonElement>) => {\n let success = false;\n if (onClick) {\n // onClick may return a boolean indicating copy success\n const result = await Promise.resolve(onClick(event));\n success = result === true;\n }\n\n if (success) {\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 };\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, { useCallback, useEffect, useId, useRef, useState } from \"react\";\nimport { createPortal, flushSync } from \"react-dom\";\nimport { X } from \"lucide-react\";\n\ninterface LightboxProps {\n onClose: () => void;\n children: React.ReactNode;\n}\n\nexport function 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 */\nexport function 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 thumb.style.viewTransitionName = vtName;\n\n doc.startViewTransition(() => {\n thumb.style.viewTransitionName = \"\";\n flushSync(() => setOpen(true));\n });\n } else {\n setOpen(true);\n }\n }, [vtName]);\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 flushSync(() => setOpen(false));\n thumb.style.viewTransitionName = vtName;\n });\n transition.finished\n .then(() => {\n thumb.style.viewTransitionName = \"\";\n })\n .catch(() => {\n thumb.style.viewTransitionName = \"\";\n });\n } else {\n setOpen(false);\n }\n }, [vtName]);\n\n return {\n thumbnailRef,\n vtName,\n open,\n openLightbox,\n closeLightbox,\n };\n}\n","import React, { memo, useState } from \"react\";\nimport type { InputContentSource } from \"@copilotkit/shared\";\nimport { getSourceUrl, getDocumentIcon } from \"@copilotkit/shared\";\nimport { cn } from \"../../lib/utils\";\nimport { Lightbox, useLightbox } from \"./Lightbox\";\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 const { thumbnailRef, vtName, open, openLightbox, closeLightbox } =\n useLightbox();\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 <>\n <img\n ref={thumbnailRef as React.Ref<HTMLImageElement>}\n src={src}\n alt=\"Image attachment\"\n className={cn(\n \"cpk:max-w-[80px] cpk:max-h-[80px] cpk:w-auto cpk:h-auto cpk:rounded-xl cpk:object-cover cpk:cursor-pointer cpk:bg-muted\",\n className,\n )}\n onClick={openLightbox}\n onError={() => setError(true)}\n />\n {open && (\n <Lightbox onClose={closeLightbox}>\n <img\n style={{ viewTransitionName: vtName }}\n src={src}\n alt=\"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\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 copyToClipboard,\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 return await copyToClipboard(flattenedContent);\n }\n return false;\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 {mediaParts.length > 0 && (\n <div className=\"cpk:flex cpk:flex-row cpk:flex-wrap cpk:justify-end cpk:gap-2 cpk:mb-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 {BoundMessageRenderer}\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 = async (event: React.MouseEvent<HTMLButtonElement>) => {\n let success = false;\n if (onClick) {\n // onClick may return a boolean indicating copy success\n const result = await Promise.resolve(onClick(event));\n success = result === true;\n }\n\n if (success) {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\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 // Track whether the user has manually toggled so auto-collapse doesn't\n // override their explicit intent (prevents flaky test failures on CI\n // where async forceUpdate timing can race with click handlers).\n const [isOpen, setIsOpen] = useState(isStreaming);\n const userToggledRef = useRef(false);\n\n useEffect(() => {\n if (isStreaming) {\n // Reset user-toggle tracking when a new streaming session starts\n userToggledRef.current = false;\n setIsOpen(true);\n } else if (!userToggledRef.current) {\n // Auto-collapse only if the user hasn't manually toggled\n setIsOpen(false);\n }\n }, [isStreaming]);\n\n const handleToggle = hasContent\n ? () => {\n userToggledRef.current = true;\n setIsOpen((prev) => !prev);\n }\n : undefined;\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: handleToggle,\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 from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport type { Message } from \"@ag-ui/core\";\n\n/** Lifecycle state the brain hands the face. */\nexport type IntelligenceIndicatorStatus = \"in-progress\" | \"finished\";\n\nexport interface IntelligenceIndicatorViewProps extends React.HTMLAttributes<HTMLSpanElement> {\n /** The assistant message this indicator is attached to. */\n message: Message;\n /**\n * Whether the intelligence work is still running (`in-progress`) or\n * has settled (`finished`). Drives the icon morph and chrome\n * fade-out via the `data-status` attribute on the wrapper.\n */\n status: IntelligenceIndicatorStatus;\n /** The visible label, e.g. \"Using CopilotKit Intelligence\". */\n label: string;\n}\n\n/**\n * The presentational \"CopilotKit Intelligence\" face — the default\n * rendered by the {@link IntelligenceIndicator} brain and the default\n * value for the `intelligenceIndicator` slot.\n *\n * Single-element three-stage design:\n * 1. **In-progress.** Glassmorphism pill chrome around a 270° arc icon\n * and the label. The arc has a single continuous visible stroke\n * (one `stroke-dasharray` dash + one gap, summing to the path\n * length) and the whole SVG rotates — so the viewer sees one\n * C-shaped arc spinning around the visual center.\n * 2. **Icon morph (~250 ms).** On status flip the single icon path\n * interpolates from the arc to a checkmark via CSS `d:` while the\n * dashed stroke transitions to solid (filling in the gap that was\n * the spinner's open portion). The SVG rotation animation is\n * removed; the snap back to identity is masked by the simultaneous\n * shape change. Chrome and text stay at full opacity throughout.\n * 3. **Settle (~400 ms, starts at +250 ms).** Chrome (background,\n * border, shadow, backdrop-blur) fades to zero opacity. The label\n * and icon stroke color transitions from saturated purple to a\n * true-neutral gray at 0.8 alpha — no hue cast, reads as \"settled\n * history metadata.\" The label simultaneously skews to ~10° (a\n * transform-based italic feel that interpolates smoothly with the\n * color, rather than the discrete `font-style: italic` snap that\n * would cause a layout pop). The label text stays put — only its\n * color and slant change — so there is no \"bump\" where the brand\n * text disappears and reappears.\n *\n * Hard sequence: stage 3 has a 250 ms transition-delay so it waits\n * for stage 2 to finish. Total settle time ~650 ms in production.\n *\n * Both shapes are 3-segment cubic Bézier paths with matched command\n * structure (one `M` plus three `C`s), which is what makes the d\n * morph interpolate as a continuous shape change rather than snapping.\n *\n * The label is identical in both states (default \"CopilotKit\n * Intelligence\"). The static check icon carries the \"done\" semantic;\n * the color + slant transition does the \"settle\" work without needing\n * any wording change.\n *\n * Customize via the `intelligenceIndicator` slot on `CopilotChat`:\n * a className string restyles the wrapper, a props object tweaks\n * the default (`{ label }`), and a component replaces it entirely\n * with full control over visuals and timing.\n */\nexport function IntelligenceIndicatorView({\n message,\n status,\n label,\n className,\n ...rest\n}: IntelligenceIndicatorViewProps): React.ReactElement {\n return (\n <span\n className={twMerge(\"cpk-intelligence-indicator\", className)}\n role=\"status\"\n aria-live=\"polite\"\n data-testid={`cpk-intelligence-indicator-${message.id}`}\n data-status={status}\n title={label}\n {...rest}\n >\n {/* Chrome layer — bg, border, shadow, backdrop-blur. Sits behind\n the content via `position: absolute; inset: 0`. Fades to zero\n opacity once the icon morph completes. */}\n <span className=\"cpk-intelligence-indicator__chrome\" aria-hidden=\"true\" />\n\n {/* Content layer — icon + label. Stays put across the whole\n transition; only its color alpha drops on settle. */}\n <span className=\"cpk-intelligence-indicator__content\">\n <svg\n className=\"cpk-intelligence-indicator__icon\"\n viewBox=\"0 0 24 24\"\n width=\"14\"\n height=\"14\"\n aria-hidden=\"true\"\n >\n {/* Single path element whose `d` attribute morphs from the\n arc to the checkmark via CSS `d:` interpolation. Both\n shapes are 3-segment cubic Béziers; the arc is a 270°\n quarter-by-quarter approximation of a circle, the\n checkmark is a 2-stroke polyline split into 3 cubics\n with collinear controls (so the segments render as\n straight lines). */}\n <path className=\"cpk-intelligence-indicator__icon-path\" />\n </svg>\n <span className=\"cpk-intelligence-indicator__label\">{label}</span>\n </span>\n </span>\n );\n}\n","import React, { useEffect, useMemo, useState } from \"react\";\nimport type { Message } from \"@ag-ui/core\";\nimport { useCopilotKit } from \"../../providers/CopilotKitProvider\";\nimport { useCopilotChatConfiguration } from \"../../providers/CopilotChatConfigurationProvider\";\nimport { useAgent, UseAgentUpdate } from \"../../hooks/use-agent\";\nimport { renderSlot } from \"../../lib/slots\";\nimport type { SlotValue } from \"../../lib/slots\";\nimport { IntelligenceIndicatorView } from \"./IntelligenceIndicatorView\";\n\n/**\n * Grace window before showing the spinner. A matching tool call must\n * remain unresolved (no `tool`-role result message in `agent.messages`)\n * for at least this long before the indicator transitions out of\n * `hidden`. This filters out history-replay flashes — during\n * `connectAgent` replay, tool calls and their results arrive\n * back-to-back in sub-millisecond bursts, so the timer is cancelled\n * before it fires. Live runs cross the threshold easily because the\n * tool actually has to execute.\n */\nconst PENDING_THRESHOLD_MS = 100;\n\n/**\n * Tool-name regex patterns that trigger the indicator. Matches any tool\n * name *containing* the Intelligence MCP server's canonical tool name, so\n * both the bare `copilotkit_knowledge_base_shell` and the namespaced\n * `mcp__<server>__copilotkit_knowledge_base_shell` form (emitted by\n * `@ag-ui/mcp-middleware`) light up the pill. If we add per-instance\n * customization later (e.g. a `CopilotKitProvider` prop or a runtime-info\n * field), this constant becomes the fallback.\n */\nconst DEFAULT_TOOL_PATTERNS: readonly RegExp[] = [\n /copilotkit_knowledge_base_shell/,\n];\n\n/**\n * Phase machine. Once `finished` is reached the indicator persists\n * indefinitely; placement (one indicator per turn, at the turn's first\n * bash-using message) is owned by `getIntelligenceTurnAnchors`, not by\n * this machine.\n */\nexport type Phase = \"hidden\" | \"spinner\" | \"finished\";\n\n/**\n * Phase to start in when an indicator first mounts. A turn that is already\n * complete at mount jumps straight to `finished` — no `hidden` flash, no\n * spinner blip — which is what makes scrolled-back / replayed history render\n * its indicators directly in the finished state.\n *\n * Pure and timing-free on purpose: the grace window ({@link\n * PENDING_THRESHOLD_MS}) only controls *when* the live transition is applied;\n * these functions decide *what* it resolves to, so the decision can be unit\n * tested deterministically without any timers.\n */\nexport function initialIndicatorPhase(turnComplete: boolean): Phase {\n return turnComplete ? \"finished\" : \"hidden\";\n}\n\n/**\n * Phase the grace window resolves to once it elapses:\n * - completed turn → `finished` (replay-flash suppression: a tool whose\n * result lands within the window skips the spinner entirely),\n * - a still-pending matching tool call → `spinner`,\n * - otherwise stay `hidden` (the matching tool call hasn't landed yet).\n */\nexport function resolveGracePhase(\n turnComplete: boolean,\n hasPending: boolean,\n): Phase {\n if (turnComplete) return \"finished\";\n if (hasPending) return \"spinner\";\n return \"hidden\";\n}\n\nexport interface IntelligenceIndicatorProps {\n /** The message this indicator is attached to. */\n message: Message;\n /**\n * Agent id whose run state the indicator tracks. Pass through from\n * the surrounding chat configuration; mounting from\n * `CopilotChatMessageView` resolves this automatically.\n */\n agentId: string;\n /**\n * Optional override for the visible label. Defaults to\n * \"CopilotKit Intelligence\".\n */\n label?: string;\n /**\n * Slot override for the presentational face. A className string, a\n * props object, or a full replacement component — see\n * {@link IntelligenceIndicatorView}. Forwarded from the\n * `intelligenceIndicator` slot on `CopilotChat`.\n */\n intelligenceIndicator?: SlotValue<typeof IntelligenceIndicatorView>;\n}\n\nconst isMatchingToolCallName = (name: unknown): boolean =>\n typeof name === \"string\" && DEFAULT_TOOL_PATTERNS.some((p) => p.test(name));\n\nconst messageHasMatchingToolCall = (m: Message): boolean => {\n if (m.role !== \"assistant\") return false;\n const tcs = Array.isArray(m.toolCalls) ? m.toolCalls : [];\n return tcs.some((tc) => isMatchingToolCallName(tc?.function?.name));\n};\n\n/**\n * Stable turn id for the messages that precede the first user message (a turn\n * with no opening user message of its own). Used as the React key so the\n * indicator for that turn never collides with a real user-message id.\n */\nexport const INTELLIGENCE_TURN_HEAD = \"__cpk_turn_head__\";\n\n/**\n * Map each Intelligence-using turn to its anchor message — the FIRST bash-using\n * assistant message of the turn — and a stable turn id (the id of the user\n * message that opened the turn, or {@link INTELLIGENCE_TURN_HEAD} for the\n * pre-first-user turn). Returns `Map<anchorMessageId, turnId>`.\n *\n * Anchoring to the FIRST (not last) bash-using message keeps the indicator\n * fixed in place for the whole turn: later bash steps don't reposition it, so\n * the spinner never abruptly jumps mid-turn (bug 1). `CopilotChatMessageView`\n * emits exactly one `IntelligenceIndicator` per entry, keyed by the turn id and\n * positioned at the anchor; the per-turn key also lets every past turn keep its\n * own indicator in scroll-back.\n */\nexport function getIntelligenceTurnAnchors(\n messages: readonly Message[],\n): Map<string, string> {\n const anchors = new Map<string, string>();\n let turnId = INTELLIGENCE_TURN_HEAD;\n let anchorId: string | null = null;\n const commit = (): void => {\n if (anchorId !== null) anchors.set(anchorId, turnId);\n anchorId = null;\n };\n for (const m of messages) {\n if (m.role === \"user\") {\n commit();\n turnId = m.id;\n continue;\n }\n // First bash-using message of the turn wins; later ones don't move it.\n if (anchorId === null && messageHasMatchingToolCall(m)) anchorId = m.id;\n }\n commit();\n return anchors;\n}\n\n/**\n * \"Tool-call-like\" messages do NOT count as a real follow-up: tool\n * result messages, assistant messages that carry tool calls, and\n * empty-content assistant messages (which some providers emit as a\n * standalone wrapper around a batch of tool calls). A real follow-up\n * is anything else — most importantly an assistant message with prose\n * content, or a fresh user message.\n */\nconst isToolCallLikeMessage = (m: Message): boolean => {\n if (m.role === \"tool\") return true;\n if (m.role === \"assistant\") {\n const tcs = Array.isArray(m.toolCalls) ? m.toolCalls : [];\n if (tcs.length > 0) return true;\n const content = m.content;\n return typeof content !== \"string\" || content.trim().length === 0;\n }\n return false;\n};\n\n/**\n * The \"Using CopilotKit Intelligence\" indicator brain. Auto-mounted by\n * `CopilotChatMessageView` — once per Intelligence-using turn, at that\n * turn's anchor message and keyed by the turn id (see\n * {@link getIntelligenceTurnAnchors}). Callers do not register this\n * themselves. It owns the run subscription and the phase machine and\n * renders its swappable face via the `intelligenceIndicator` slot.\n *\n * Placement (which message anchors the turn) is decided by the view, so\n * this component does not self-gate its own placement; it only derives\n * in-progress/finished for the turn it was mounted on.\n *\n * Render gates (all must hold):\n * 1. `copilotkit.intelligence !== undefined`\n * 2. The (anchor) message is an assistant message with at least one\n * tool call whose name matches {@link DEFAULT_TOOL_PATTERNS}.\n * 3. The phase machine is past `hidden`.\n *\n * Because the view keys each indicator by its turn id, the instance moves\n * with the anchor across a hand-off (no remount, no spinner restart), and\n * every prior Intelligence-using turn keeps its own persistent indicator\n * in chat history.\n *\n * Phase machine (per-instance, all timers local):\n * - Starts in `hidden`, unless the message mounts onto an\n * already-completed turn (no pending work, agent stopped or a\n * real follow-up already present), in which case the lazy\n * `useState` initializer starts directly in `finished`. This is\n * what avoids a \"hidden flash\" on history replay.\n * - `hidden → spinner` once a matching tool call has been pending\n * (no `tool`-role result with a matching `toolCallId`) for\n * {@link PENDING_THRESHOLD_MS}. Replay flashes (tool call + result\n * in the same tick) never cross this threshold.\n * - `hidden → finished` if after the grace window the turn is\n * already complete (no pending work AND\n * `sawRealFollowup || !agent.isRunning`). Handles very fast tools\n * whose result lands within the grace window.\n * - `spinner → finished` as soon as EITHER `agent.isRunning` flips\n * false OR a non-tool-call-like message appears later in\n * `agent.messages` (i.e. the agent produced a \"real\" follow-up —\n * prose answer or a new user turn).\n * - `finished` is terminal: the indicator settles into its\n * persistent tag form and stays mounted.\n */\nexport function IntelligenceIndicator(\n props: IntelligenceIndicatorProps,\n): React.ReactElement | null {\n const {\n message,\n agentId,\n label = \"CopilotKit Intelligence\",\n intelligenceIndicator,\n } = props;\n\n const { copilotkit } = useCopilotKit();\n const config = useCopilotChatConfiguration();\n const { agent } = useAgent({\n agentId,\n updates: [\n UseAgentUpdate.OnRunStatusChanged,\n UseAgentUpdate.OnMessagesChanged,\n ],\n });\n\n // IDs of matching tool calls on this message.\n const matchingToolCallIds = useMemo<readonly string[]>(() => {\n if (message.role !== \"assistant\") return [];\n const tcs = Array.isArray(message.toolCalls) ? message.toolCalls : [];\n const ids: string[] = [];\n for (const tc of tcs) {\n if (isMatchingToolCallName(tc?.function?.name) && tc?.id) {\n ids.push(tc.id);\n }\n }\n return ids;\n }, [message]);\n\n // Pending = at least one matching tool call has no corresponding\n // `tool`-role result message in `agent.messages`.\n const hasPending = useMemo(() => {\n if (matchingToolCallIds.length === 0) return false;\n const resolved = new Set<string>();\n for (const m of agent.messages) {\n if (m.role === \"tool\" && m.toolCallId) resolved.add(m.toolCallId);\n }\n return matchingToolCallIds.some((id) => !resolved.has(id));\n }, [matchingToolCallIds, agent.messages]);\n\n // True once the agent has produced a \"real\" message *after* this\n // assistant message — prose, a new user turn, etc. Tool-call-like\n // messages do not count (they're part of the same tool flow).\n const sawRealFollowup = useMemo(() => {\n const idx = agent.messages.findIndex((m) => m.id === message.id);\n if (idx < 0) return false;\n for (let i = idx + 1; i < agent.messages.length; i += 1) {\n if (!isToolCallLikeMessage(agent.messages[i]!)) return true;\n }\n return false;\n }, [agent.messages, message.id]);\n\n // Turn-completion signal — set the moment the agent stops running or\n // a \"real\" follow-up (prose / user turn) appears after this message.\n // Independent of whether the pending tool call resolved; if the run\n // finishes with a still-unresolved match (rare in production, common\n // in tests), the indicator should still settle.\n const turnComplete = sawRealFollowup || !agent.isRunning;\n\n // Lazy init: if this indicator mounts onto a message whose turn has\n // already completed (e.g. history replay finished before mount),\n // skip directly to `finished` — no `hidden` flash, no spinner blip.\n const [phase, setPhase] = useState<Phase>(() =>\n initialIndicatorPhase(turnComplete),\n );\n\n // hidden → spinner OR hidden → finished (after grace window). The grace\n // window only controls the *timing*; `resolveGracePhase` owns the decision.\n // Resolving back to `hidden` (matching tool call not landed yet) is a\n // no-op `setPhase`, preserving the \"only leave hidden once decided\" rule.\n useEffect(() => {\n if (phase !== \"hidden\") return undefined;\n const t = setTimeout(() => {\n setPhase(resolveGracePhase(turnComplete, hasPending));\n }, PENDING_THRESHOLD_MS);\n return () => clearTimeout(t);\n }, [phase, hasPending, turnComplete]);\n\n // spinner → finished\n useEffect(() => {\n if (phase !== \"spinner\") return undefined;\n if (turnComplete) {\n setPhase(\"finished\");\n }\n return undefined;\n }, [phase, turnComplete]);\n\n // ─── Render gates ────────────────────────────────────────────────────\n // Hooks above MUST run unconditionally; bail with `null` only after.\n\n if (copilotkit.intelligence === undefined) return null;\n if (!config) return null;\n if (phase === \"hidden\") return null;\n\n if (message.role !== \"assistant\") return null;\n if (!messageHasMatchingToolCall(message)) return null;\n\n // Placement (which message anchors this turn's indicator) is decided by\n // `CopilotChatMessageView` via `getIntelligenceTurnAnchors`, which mounts\n // exactly one instance per turn keyed by the turn id. The brain therefore\n // does not decide its own placement; it only owns the run-status →\n // in-progress/finished derivation for the turn it anchors.\n\n // ─── Render the (swappable) face ──────────────────────────────────────\n\n const status = phase === \"finished\" ? \"finished\" : \"in-progress\";\n\n return renderSlot(intelligenceIndicator, IntelligenceIndicatorView, {\n message,\n status,\n label,\n });\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 type { WithSlots } from \"../../lib/slots\";\nimport { renderSlot, isReactComponentType } from \"../../lib/slots\";\nimport CopilotChatAssistantMessage from \"./CopilotChatAssistantMessage\";\nimport CopilotChatUserMessage from \"./CopilotChatUserMessage\";\nimport CopilotChatReasoningMessage from \"./CopilotChatReasoningMessage\";\nimport type {\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 { useCopilotKit } from \"../../providers/CopilotKitProvider\";\nimport { useCopilotChatConfiguration } from \"../../providers/CopilotChatConfigurationProvider\";\nimport {\n IntelligenceIndicator,\n getIntelligenceTurnAnchors,\n} from \"../intelligence-indicator\";\nimport type { IntelligenceIndicatorView } from \"../intelligence-indicator\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkit/shared\";\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\n/**\n * Deduplicates messages by ID. For assistant messages, merges occurrences:\n * recovers non-empty content from any earlier occurrence if the latest wiped it\n * (empty string means the streaming update cleared the field, not blank text),\n * and similarly recovers toolCalls from earlier occurrences if the latest is\n * undefined (an empty array [] is treated as intentional and kept as-is).\n * For all other roles, keeps the last entry.\n *\n * @internal Exported for unit testing only — not part of the public API.\n */\nexport function deduplicateMessages(messages: Message[]): Message[] {\n const acc = new Map<string, Message>();\n for (const message of messages) {\n const existing = acc.get(message.id);\n if (\n existing &&\n message.role === \"assistant\" &&\n existing.role === \"assistant\"\n ) {\n // Empty string means the streaming update cleared the field — fall back to\n // any non-empty content seen earlier. Use { ...existing, ...message } so\n // fields present only in an earlier occurrence are not silently dropped.\n const content = message.content || existing.content;\n // undefined toolCalls means this chunk had no tool call activity — recover\n // from earlier occurrences. An explicit [] means all tool calls completed.\n const toolCalls = message.toolCalls ?? existing.toolCalls;\n acc.set(message.id, {\n ...existing,\n ...message,\n content,\n toolCalls,\n } as AssistantMessage);\n } else {\n acc.set(message.id, message);\n }\n }\n return [...acc.values()];\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 intelligenceIndicator: typeof IntelligenceIndicatorView;\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 intelligenceIndicator,\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 agent = copilotkit.getAgent(config.agentId);\n if (!agent) return;\n\n const subscription = agent.subscribe({\n onStateChanged: forceUpdate,\n });\n return () => subscription.unsubscribe();\n }, [config?.agentId, 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 const deduplicatedMessages = useMemo(\n () => deduplicateMessages(messages),\n [messages],\n );\n\n if (\n process.env.NODE_ENV === \"development\" &&\n deduplicatedMessages.length < messages.length\n ) {\n console.warn(\n `CopilotChatMessageView: Merged ${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 // Map each Intelligence-using turn's anchor message → stable turn id. One\n // indicator is emitted per turn (keyed by the turn id) at its anchor, so it\n // moves with the anchor without remounting. `getIntelligenceTurnAnchors`\n // only yields anchors for turns that invoked the knowledge-base tool, so\n // non-Intelligence turns naturally produce an empty map (and the indicator\n // itself also hard-gates on intelligence mode).\n const intelligenceTurnAnchors = useMemo(\n () => getIntelligenceTurnAnchors(deduplicatedMessages),\n [deduplicatedMessages],\n );\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 // Auto-mount the IntelligenceIndicator once per Intelligence-using turn,\n // at that turn's anchor message (its first bash-using assistant), keyed by\n // the stable turn id. Keying by turn (not message) means the indicator\n // moves with the anchor across a hand-off without remounting, and past\n // turns keep their own indicator.\n const intelligenceTurnId = intelligenceTurnAnchors.get(message.id);\n if (intelligenceTurnId !== undefined) {\n elements.push(\n <IntelligenceIndicator\n key={`intelligence-${intelligenceTurnId}`}\n message={message}\n agentId={config?.agentId ?? DEFAULT_AGENT_ID}\n intelligenceIndicator={intelligenceIndicator}\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, { useEffect, useState } from \"react\";\nimport type { Attachment } from \"@copilotkit/shared\";\nimport {\n formatFileSize,\n getSourceUrl,\n getDocumentIcon,\n} from \"@copilotkit/shared\";\nimport { Play } from \"lucide-react\";\nimport { cn } from \"../../lib/utils\";\nimport { Lightbox, useLightbox } from \"./Lightbox\";\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\n data-testid=\"copilot-attachment-queue\"\n className={cn(\"cpk:flex cpk:flex-wrap cpk:gap-2 cpk:p-2\", className)}\n >\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// 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","export type AutoScrollMode = \"pin-to-bottom\" | \"pin-to-send\" | \"none\";\n\nconst VALID: readonly AutoScrollMode[] = [\n \"pin-to-bottom\",\n \"pin-to-send\",\n \"none\",\n];\n\nexport function normalizeAutoScroll(\n value: AutoScrollMode | boolean | undefined,\n): AutoScrollMode {\n if (value === undefined) return \"pin-to-bottom\";\n if (value === true) return \"pin-to-bottom\";\n if (value === false) return \"none\";\n if ((VALID as readonly string[]).includes(value)) return value;\n return \"pin-to-bottom\";\n}\n","import React from \"react\";\n\n/**\n * Context used by `CopilotChatView` to announce the latest user message\n * to descendants (notably `usePinToSend`), so scroll logic can anchor\n * the viewport to the most recent user turn in \"pin-to-send\" mode.\n *\n * `sendNonce` increments on each new send so repeated IDs (e.g., message\n * edits that preserve the ID) still trigger dependent effects.\n */\nexport type LastUserMessageState = {\n id: string | null;\n sendNonce: number;\n};\n\nexport const LastUserMessageContext = React.createContext<LastUserMessageState>(\n {\n id: null,\n sendNonce: 0,\n },\n);\n","import { useContext, useEffect, useRef } from \"react\";\nimport { LastUserMessageContext } from \"../components/chat/last-user-message-context\";\n\nexport type UsePinToSendOptions = {\n scrollRef: React.RefObject<HTMLElement | null>;\n contentRef: React.RefObject<HTMLElement | null>;\n spacerRef: React.RefObject<HTMLElement | null>;\n topOffset?: number;\n};\n\nexport function usePinToSend({\n scrollRef,\n contentRef,\n spacerRef,\n topOffset = 16,\n}: UsePinToSendOptions): void {\n const { id, sendNonce } = useContext(LastUserMessageContext);\n const lastNonceRef = useRef<number>(-1);\n const currentSpacerHeightRef = useRef<number>(0);\n\n useEffect(() => {\n if (sendNonce === lastNonceRef.current) return;\n lastNonceRef.current = sendNonce;\n\n if (!id) return;\n const scrollEl = scrollRef.current;\n const contentEl = contentRef.current;\n const spacerEl = spacerRef.current;\n if (!scrollEl || !contentEl || !spacerEl) return;\n\n const escaped =\n typeof CSS !== \"undefined\" && CSS.escape\n ? CSS.escape(id)\n : id.replace(/[!\"#$%&'()*+,./:;<=>?@[\\\\\\]^`{|}~]/g, \"\\\\$&\");\n const targetEl = contentEl.querySelector<HTMLElement>(\n `[data-message-id=\"${escaped}\"]`,\n );\n if (!targetEl) return;\n\n // The target message's element has a top padding (e.g. `pt-10`) that\n // creates breathing room above the visible bubble. When we \"anchor at\n // the top\", we mean anchor the *bubble*, not the element's padded box.\n // So we scroll past the padding (it goes above the viewport, hiding\n // whatever was above the element too — including the previous message's\n // trailing copy button).\n const viewportHeight = scrollEl.clientHeight;\n const userMessageHeight = targetEl.getBoundingClientRect().height;\n const paddingTop = parseFloat(getComputedStyle(targetEl).paddingTop) || 0;\n const bubbleHeight = Math.max(0, userMessageHeight - paddingTop);\n const spacerHeight = Math.max(0, viewportHeight - bubbleHeight - topOffset);\n\n spacerEl.style.height = `${spacerHeight}px`;\n currentSpacerHeightRef.current = spacerHeight;\n\n const raf = requestAnimationFrame(() => {\n // Scroll so the BUBBLE is `topOffset` from the viewport top — the\n // padding above the bubble ends up scrolled off-screen.\n const targetTop =\n computeOffsetTop(targetEl, scrollEl) + paddingTop - topOffset;\n scrollEl.scrollTo({ top: Math.max(0, targetTop), behavior: \"smooth\" });\n });\n\n // Shrink-only ResizeObserver: as the assistant response grows below the\n // anchored user message, collapse the spacer by the same amount so total\n // scrollable space below the bubble stays constant (and the bubble stays\n // pinned). Never grow the spacer after initial sizing.\n const ro = new ResizeObserver(() => {\n if (!contentEl || !spacerEl || !scrollEl) return;\n const contentHeight = contentEl.getBoundingClientRect().height;\n const targetOffsetWithinContent = computeOffsetTop(targetEl, contentEl);\n const consumedBelow =\n contentHeight - targetOffsetWithinContent - userMessageHeight;\n const remaining = Math.max(0, spacerHeight - consumedBelow);\n if (remaining < currentSpacerHeightRef.current) {\n spacerEl.style.height = `${remaining}px`;\n currentSpacerHeightRef.current = remaining;\n }\n });\n ro.observe(contentEl);\n\n return () => {\n cancelAnimationFrame(raf);\n ro.disconnect();\n };\n }, [id, sendNonce, scrollRef, contentRef, spacerRef, topOffset]);\n}\n\n// Compute the offset of el relative to stopAt, accounting for stopAt's current scrollTop.\n// Uses getBoundingClientRect so it works regardless of CSS positioning (including position:static).\nfunction computeOffsetTop(el: HTMLElement, stopAt: HTMLElement): number {\n const elRect = el.getBoundingClientRect();\n const stopRect = stopAt.getBoundingClientRect();\n return elRect.top - stopRect.top + stopAt.scrollTop;\n}\n","import React, {\n useCallback,\n useRef,\n useState,\n useEffect,\n useLayoutEffect,\n} from \"react\";\nimport { ScrollElementContext } from \"./scroll-element-context\";\nimport type { WithSlots, SlotValue } from \"../../lib/slots\";\nimport { renderSlot } from \"../../lib/slots\";\nimport CopilotChatMessageView from \"./CopilotChatMessageView\";\nimport type { IntelligenceIndicatorView } from \"../intelligence-indicator\";\nimport type {\n CopilotChatInputProps,\n CopilotChatInputMode,\n} from \"./CopilotChatInput\";\nimport CopilotChatInput from \"./CopilotChatInput\";\nimport CopilotChatSuggestionView, {\n CopilotChatSuggestionViewProps,\n} from \"./CopilotChatSuggestionView\";\nimport type { Suggestion } from \"@copilotkit/core\";\nimport type { 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\";\nimport { normalizeAutoScroll } from \"./normalize-auto-scroll\";\nimport type { AutoScrollMode } from \"./normalize-auto-scroll\";\nimport { usePinToSend } from \"../../hooks/use-pin-to-send\";\n\n// Vertical gap between the scroll-to-bottom button and the input container.\nconst SCROLL_BUTTON_OFFSET = 16;\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?: AutoScrollMode | 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 * When `true`, suppresses the welcome screen while a thread's initial\n * connect is in flight. Prevents the \"How can I help you today?\" flash\n * that would otherwise appear between mounting an empty agent instance\n * and the bootstrap messages arriving from /connect.\n */\n isConnecting?: boolean;\n /**\n * When `true`, the caller has explicitly picked a thread (via `threadId`\n * prop or `CopilotChatConfigurationProvider`). Suppresses the welcome\n * screen unconditionally — a caller-managed thread targets a specific\n * conversation and should render its messages (or an empty panel during\n * connect) rather than a generic \"start a new chat\" greeting.\n */\n hasExplicitThreadId?: boolean;\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 /**\n * Slot for the \"Using CopilotKit Intelligence\" indicator. Pass-through\n * to `CopilotChatMessageView`'s `intelligenceIndicator` slot — accepts a\n * className string, a props object, or a replacement component.\n */\n intelligenceIndicator?: SlotValue<typeof IntelligenceIndicatorView>;\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 isConnecting = false,\n hasExplicitThreadId = false,\n // Deprecated — forwarded to input slot\n disclaimer,\n // Pass-through to CopilotChatMessageView's intelligenceIndicator slot\n intelligenceIndicator,\n children,\n className,\n ...props\n}: CopilotChatViewProps) {\n // Element-as-state via callback ref. The overlay wrapper only renders on the\n // chat-view branch (the welcome-screen branch omits it), so a plain\n // useRef + `[]` useEffect would observe `null` on mount whenever the chat\n // starts on the welcome screen and never re-attach after the user sends\n // their first message — leaving inputContainerHeight at 0 and the scroll\n // content's reserved bottom padding at 32px instead of ~input height. The\n // result is the last messages scrolling underneath the absolute-positioned\n // input pill. Subscribing to element state lets the observer attach (and\n // detach) reactively as the overlay mounts/unmounts.\n const [inputContainerEl, setInputContainerEl] =\n useState<HTMLDivElement | null>(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 = inputContainerEl;\n if (!element) {\n // Reset measured height so the scroll content's paddingBottom doesn't\n // hold a stale value if the overlay unmounts (e.g. messages cleared\n // and the welcome screen returns).\n setInputContainerHeight(0);\n return;\n }\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 }, [inputContainerEl]);\n\n const BoundMessageView = renderSlot(messageView, CopilotChatMessageView, {\n messages,\n isRunning,\n intelligenceIndicator,\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 showDisclaimer: true,\n // The parent overlay wrapper handles absolute bottom-0 positioning.\n // `bottomAnchored` still triggers the license-banner offset padding\n // inside CopilotChatInput. The welcome-screen input (below) intentionally\n // omits this flag.\n bottomAnchored: true,\n ...(disclaimer !== undefined ? { disclaimer } : {}),\n } as CopilotChatInputProps);\n\n // Hide suggestions while a thread is connecting or a run is in flight.\n // Otherwise, mid-replay (bootstrap stream from /connect) or mid-run, the\n // suggestions would render against a still-assembling message tree and\n // visibly jump as each final text chunk reflows the layout.\n const hasSuggestions =\n !isConnecting &&\n !isRunning &&\n Array.isArray(suggestions) &&\n 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 data-testid=\"copilot-scroll-content\"\n style={{\n paddingBottom: `${inputContainerHeight + (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 // Suppress the welcome screen (1) while the initial connect is in flight\n // and (2) whenever the caller has picked a specific thread. The caller-\n // managed case targets a conversation directly, so the generic welcome\n // greeting is never the right thing to show — even for a thread that\n // happens to have no messages yet.\n const shouldShowWelcomeScreen =\n isEmpty && !welcomeScreenDisabled && !isConnecting && !hasExplicitThreadId;\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\n ref={setInputContainerEl}\n data-testid=\"copilot-input-overlay\"\n className=\"cpk:absolute cpk:bottom-0 cpk:left-0 cpk:right-0 cpk:z-20 cpk:pointer-events-none\"\n >\n {attachments && attachments.length > 0 && (\n <div className=\"cpk:max-w-3xl cpk:mx-auto cpk:w-full cpk:pointer-events-auto\">\n <CopilotChatAttachmentQueue\n attachments={attachments}\n onRemoveAttachment={(id) => onRemoveAttachment?.(id)}\n className=\"cpk:px-4\"\n />\n </div>\n )}\n {BoundInput}\n </div>\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 {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 + SCROLL_BUTTON_OFFSET}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 // Internal component for pin-to-send scroll behavior — not exported on CopilotChatView.\n const PinToSendScrollContainer: React.FC<\n React.HTMLAttributes<HTMLDivElement> & {\n scrollRef: React.MutableRefObject<HTMLElement | null>;\n contentRef: React.MutableRefObject<HTMLElement | null>;\n scrollToBottom: () => void;\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 nonAutoScrollEl: HTMLElement | null;\n nonAutoScrollRefCallback: (el: HTMLElement | null) => void;\n showScrollButton: boolean;\n }\n > = ({\n children,\n scrollRef,\n contentRef,\n scrollToBottom,\n scrollToBottomButton,\n feather,\n inputContainerHeight,\n isResizing,\n nonAutoScrollEl,\n nonAutoScrollRefCallback,\n showScrollButton,\n className,\n ...props\n }) => {\n const spacerRef = useRef<HTMLDivElement>(null);\n\n usePinToSend({\n scrollRef,\n contentRef,\n spacerRef,\n topOffset: 16,\n });\n\n // The feather and scroll-to-bottom button live OUTSIDE the scroll\n // container. `position: absolute` children of an `overflow: auto` element\n // are positioned relative to the scroll *content*, which means they\n // scroll away with it. Placing them as siblings of the scroll container\n // (inside a `relative` wrapper) keeps them pinned to the viewport bottom.\n const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});\n\n return (\n <ScrollElementContext.Provider value={nonAutoScrollEl}>\n <div\n className={cn(\n \"cpk:h-full cpk:max-h-full cpk:flex cpk:flex-col cpk:min-h-0 cpk:relative\",\n className,\n )}\n >\n <div\n ref={nonAutoScrollRefCallback}\n className=\"cpk:flex-1 cpk:min-h-0 cpk:overflow-y-auto cpk:overflow-x-hidden\"\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 <div\n ref={spacerRef}\n data-pin-to-send-spacer\n aria-hidden=\"true\"\n style={{ height: 0, flex: \"0 0 auto\" }}\n />\n </div>\n {BoundFeather}\n {/* Scroll to bottom button */}\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 + SCROLL_BUTTON_OFFSET}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 export const ScrollView: React.FC<\n React.HTMLAttributes<HTMLDivElement> & {\n autoScroll?: AutoScrollMode | 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 = \"pin-to-bottom\",\n scrollToBottomButton,\n feather,\n inputContainerHeight = 0,\n isResizing = false,\n className,\n ...props\n }) => {\n const mode = normalizeAutoScroll(autoScroll);\n const [hasMounted, setHasMounted] = useState(false);\n // Plain refs for the \"none\" and \"pin-to-send\" paths. Do NOT use\n // useStickToBottom() here — its internal effects would attach scroll-following\n // behavior to these refs and fight pin-to-send. The \"pin-to-bottom\" path\n // gets its refs via <StickToBottom> below, scoped to that branch only.\n const scrollRef = useRef<HTMLElement | null>(null);\n const contentRef = useRef<HTMLElement | null>(null);\n const scrollToBottom = useCallback(() => {\n const el = scrollRef.current;\n if (el) el.scrollTo({ top: el.scrollHeight, behavior: \"smooth\" });\n }, []);\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 ref object; 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 (mode === \"pin-to-bottom\") 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, mode]);\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 if (mode === \"none\") {\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 {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 + SCROLL_BUTTON_OFFSET}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 if (mode === \"pin-to-send\") {\n return (\n <PinToSendScrollContainer\n scrollRef={scrollRef}\n contentRef={contentRef}\n scrollToBottom={scrollToBottom}\n scrollToBottomButton={scrollToBottomButton}\n feather={feather}\n inputContainerHeight={inputContainerHeight}\n isResizing={isResizing}\n nonAutoScrollEl={nonAutoScrollEl}\n nonAutoScrollRefCallback={nonAutoScrollRefCallback}\n showScrollButton={showScrollButton}\n className={className}\n {...props}\n >\n {children}\n </PinToSendScrollContainer>\n );\n }\n\n // mode === \"pin-to-bottom\" (default)\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 // Default renders an empty div — no visual, but the element is still in the\n // tree so a slot override of the form `scrollView={{ feather: \"my-class\" }}`\n // can apply classes (and any consumer with a full component override gets\n // the className/style forwarding they expect).\n export const Feather: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n className,\n ...props\n }) => <div className={className} {...props} />;\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 type { CopilotChatViewProps } from \"./CopilotChatView\";\nimport { CopilotChatView } from \"./CopilotChatView\";\nimport type { CopilotChatInputMode } from \"./CopilotChatInput\";\nimport type { CopilotChatLabels } from \"../../providers/CopilotChatConfigurationProvider\";\nimport {\n CopilotChatConfigurationProvider,\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 type { Suggestion, CopilotKitCoreErrorCode } from \"@copilotkit/core\";\nimport { isRunCompletionAware } 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 type { AbstractAgent } from \"@ag-ui/client\";\nimport { HttpAgent } from \"@ag-ui/client\";\nimport type { SlotValue } from \"../../lib/slots\";\nimport { renderSlot, useShallowStableRef } from \"../../lib/slots\";\nimport {\n transcribeAudio,\n TranscriptionError,\n} from \"../../lib/transcription-client\";\nimport { LastUserMessageContext } from \"./last-user-message-context\";\nimport type { LastUserMessageState } from \"./last-user-message-context\";\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 providedThreadId = threadId ?? existingConfig?.threadId;\n const resolvedThreadId = useMemo(\n () => providedThreadId ?? randomUUID(),\n [providedThreadId],\n );\n // \"Explicit\" means a caller actually picked this thread — via the\n // `threadId` prop on CopilotChat or a wrapping provider that marked its\n // threadId as caller-chosen. An auto-minted UUID leaking down through a\n // CopilotChatConfigurationProvider (e.g. from the v1 CopilotKit →\n // ThreadsProvider chain) does NOT count; treating it as explicit is\n // what made /connect fire against 404s and the welcome screen stay\n // hidden for fresh empty chats.\n const hasExplicitThreadId =\n !!threadId || !!existingConfig?.hasExplicitThreadId;\n\n const { agent } = useAgent({\n agentId: resolvedAgentId,\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 // onSubmitInput awaits an in-flight run before sending the new message, so\n // it must re-check the \"uploading\" guard against FRESH state AFTER the await\n // — the closure-captured `selectedAttachments` is stale across the await\n // (an upload can start during the wait).\n const selectedAttachmentsRef = useRef(selectedAttachments);\n useEffect(() => {\n selectedAttachmentsRef.current = selectedAttachments;\n }, [selectedAttachments]);\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 // Tracks the last threadId for which connectAgent has completed (success or\n // failure). When the user supplies a threadId, we're in \"resume existing\n // thread\" mode — the welcome screen should be suppressed until the connect\n // resolves, otherwise switching threads flashes the welcome screen while the\n // new thread's messages are still en route.\n const [lastConnectedThreadId, setLastConnectedThreadId] = useState<\n string | null\n >(null);\n const isConnecting =\n hasExplicitThreadId && lastConnectedThreadId !== resolvedThreadId;\n\n useEffect(() => {\n // Non-explicit threads skip /connect, but the first runAgent still has to\n // ship the same SDK-generated threadId that the chat UI is rendering.\n agent.threadId = resolvedThreadId;\n\n // When the caller hasn't picked a specific thread, resolvedThreadId is a\n // UUID minted locally (either in this CopilotChat or in a wrapping\n // ThreadsProvider). The backend has never seen it, so /connect would\n // always 404 — skip the call. A real thread is only created once the\n // user runs the agent for the first time.\n if (!hasExplicitThreadId) return;\n\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 (agentToConnect: AbstractAgent) => {\n try {\n await copilotkit.connectAgent({ agent: agentToConnect });\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 } finally {\n // Whether the connect succeeded or failed, we're no longer in the\n // transitional \"connecting\" state for this thread — unblock the\n // welcome-screen-suppression so the view can settle.\n //\n // Defer one animation frame so any trailing React commits from the\n // bootstrap replay (final assistant message content) paint before\n // isConnecting flips off. Without this, suggestions + copy button\n // can briefly appear against an incompletely-laid-out message tree\n // and visibly snap once the last text chunk lands.\n if (!detached) {\n const raf =\n typeof requestAnimationFrame === \"function\"\n ? requestAnimationFrame\n : (cb: () => void) => setTimeout(cb, 16);\n raf(() => {\n if (!detached) setLastConnectedThreadId(resolvedThreadId);\n });\n }\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, hasExplicitThreadId]);\n\n // Serializes consecutive sends: if a run is already in flight, let it finish\n // before dispatching the next message instead of pre-empting it.\n // `copilotkit.runAgent` would otherwise call `agent.detachActiveRun()` and\n // ABORT the in-flight run. That abort is harmful when the in-flight run is an\n // interrupt RESUME: the resume re-enters and completes the paused agent\n // graph, and aborting it mid-flight leaves the graph paused — so the new\n // message lands as another resume of the SAME paused graph (re-interrupting\n // with no fresh payload) instead of starting a clean new turn. This is the\n // consecutive-interrupt regression: pick turn-1's slot (kicks off the\n // resume), then immediately send turn-2's message — without waiting, turn-2\n // aborts the resume and the 2nd interrupt's card never mounts. Awaiting the\n // active run's completion serializes the two turns so the resume finishes\n // (graph completes) before the new message starts a fresh run.\n //\n // The completion promise lives only on `IntelligenceAgent` (via the\n // `RunCompletionAware` contract), not on the `AbstractAgent` type held here —\n // so it is reached through a type guard, not a cast. Agents that don't\n // implement the contract degrade safely (the await is skipped).\n const waitForActiveRunToSettle = useCallback(async () => {\n if (\n agent.isRunning &&\n isRunCompletionAware(agent) &&\n agent.activeRunCompletionPromise\n ) {\n try {\n await agent.activeRunCompletionPromise;\n } catch (error) {\n // The in-flight run rejected — proceed with the new send anyway,\n // but log so a chronically-failing in-flight run is observable.\n console.error(\n \"CopilotChat: in-flight run rejected while queuing send\",\n error,\n );\n }\n }\n }, [agent]);\n\n const onSubmitInput = useCallback(\n async (value: string) => {\n // Block if uploads in progress (fast fail against current state before\n // the value is committed — re-checked against live state after the\n // await below, since an upload can start during the wait).\n if (\n selectedAttachmentsRef.current.some((a) => a.status === \"uploading\")\n ) {\n console.error(\n \"[CopilotKit] Cannot send while attachments are uploading (pre-await guard)\",\n );\n setTranscriptionError(\"Cannot send while attachments are uploading.\");\n return;\n }\n\n // Clear the input immediately so the composer reflects the accepted send\n // even though the actual dispatch may be deferred behind the in-flight\n // run. If the post-await guard later BLOCKS the send (e.g. an upload\n // starts during the await), the typed text is RESTORED to the composer\n // below so it is never silently lost.\n setInputValue(\"\");\n\n // If a run is already in flight, let it finish before sending the new\n // message instead of pre-empting it (see waitForActiveRunToSettle).\n await waitForActiveRunToSettle();\n\n // Re-check the uploading guard against LIVE attachment state: an upload\n // can start (or stay in flight) during the await above, so a snapshot\n // taken before the await could consume an attachment with an incomplete\n // source. On block, RESTORE the typed text to the composer (it was\n // optimistically cleared on accept) so the user's input is not silently\n // lost, and surface a user-visible banner — console.error alone is\n // invisible to the user.\n if (\n selectedAttachmentsRef.current.some((a) => a.status === \"uploading\")\n ) {\n console.error(\n \"[CopilotKit] Cannot send while attachments are uploading (post-await re-check)\",\n );\n setTranscriptionError(\"Cannot send while attachments are uploading.\");\n setInputValue(value);\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 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, consumeAttachments, waitForActiveRunToSettle],\n );\n\n const handleSelectSuggestion = useCallback(\n async (suggestion: Suggestion) => {\n // Mirror onSubmitInput's send-serialization: if a run is in flight, wait\n // for it to settle before dispatching, so selecting a suggestion mid-run\n // does NOT pre-empt/abort the active run (the same #5195 fix the\n // typed-Enter path got — here for the suggestion path).\n await waitForActiveRunToSettle();\n\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, waitForActiveRunToSettle],\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 // Compute the ID of the last user message for scroll-pinning logic.\n const lastUserMessageId = useMemo(() => {\n for (let i = messages.length - 1; i >= 0; i--) {\n if (messages[i].role === \"user\") return messages[i].id;\n }\n return null;\n }, [messages]);\n\n // Track a nonce that increments each time a new user message ID appears.\n // Using useState ensures the context value propagates correctly on the\n // render that follows the state update (approach b from the design doc).\n const [sendNonce, setSendNonce] = useState(0);\n // Seed with the current value so restoring a thread with existing messages\n // does not count as a new send. Only later-render id transitions bump.\n const prevLastUserMessageIdRef = useRef<string | null>(lastUserMessageId);\n\n useEffect(() => {\n if (\n lastUserMessageId &&\n lastUserMessageId !== prevLastUserMessageIdRef.current\n ) {\n setSendNonce((n) => n + 1);\n prevLastUserMessageIdRef.current = lastUserMessageId;\n }\n }, [lastUserMessageId]);\n\n const lastUserMessageState = useMemo<LastUserMessageState>(\n () => ({ id: lastUserMessageId, sendNonce }),\n [lastUserMessageId, sendNonce],\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 isConnecting,\n hasExplicitThreadId,\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 hasExplicitThreadId={hasExplicitThreadId}\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 <LastUserMessageContext.Provider value={lastUserMessageState}>\n {RenderedChatView}\n </LastUserMessageContext.Provider>\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 position?: \"left\" | \"right\";\n};\n\nexport function CopilotSidebarView({\n header,\n toggleButton,\n width,\n defaultOpen = true,\n position = \"right\",\n ...props\n}: CopilotSidebarViewProps) {\n return (\n <CopilotChatConfigurationProvider isModalDefaultOpen={defaultOpen}>\n <CopilotSidebarViewInternal\n header={header}\n toggleButton={toggleButton}\n width={width}\n position={position}\n {...props}\n />\n </CopilotChatConfigurationProvider>\n );\n}\n\nfunction CopilotSidebarViewInternal({\n header,\n toggleButton,\n width,\n position = \"right\",\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 const marginStyleProp =\n position === \"left\" ? \"marginInlineStart\" : \"marginInlineEnd\";\n const transitionCssProp =\n position === \"left\" ? \"margin-inline-start\" : \"margin-inline-end\";\n\n if (isSidebarOpen) {\n if (hasMounted.current) {\n document.body.style.transition = `${transitionCssProp} ${SIDEBAR_TRANSITION_MS}ms ease`;\n }\n document.body.style[marginStyleProp] = widthToMargin(sidebarWidth);\n } else if (hasMounted.current) {\n document.body.style.transition = `${transitionCssProp} ${SIDEBAR_TRANSITION_MS}ms ease`;\n document.body.style[marginStyleProp] = \"\";\n }\n\n hasMounted.current = true;\n\n return () => {\n document.body.style[marginStyleProp] = \"\";\n document.body.style.transition = \"\";\n };\n }, [isSidebarOpen, sidebarWidth, position]);\n\n const headerElement = renderSlot(header, CopilotModalHeader, {});\n const toggleButtonElement = renderSlot(\n toggleButton,\n CopilotChatToggleButton,\n position === \"left\" ? { className: \"cpk:left-6 cpk:right-auto\" } : {},\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 data-position={position}\n className={cn(\n \"copilotKitSidebar copilotKitWindow\",\n \"cpk:fixed cpk:top-0 cpk:z-[1200] cpk:flex\",\n position === \"left\" ? \"cpk:left-0\" : \"cpk:right-0\",\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 position === \"left\" ? \"cpk:border-r\" : \"cpk:border-l\",\n \"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 : position === \"left\"\n ? \"cpk:-translate-x-full cpk:pointer-events-none\"\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 position?: CopilotSidebarViewProps[\"position\"];\n};\n\nexport function CopilotSidebar({\n header,\n toggleButton,\n defaultOpen,\n width,\n position,\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 position: viewPosition,\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 position={position ?? viewPosition}\n />\n );\n };\n\n return Object.assign(Component, CopilotChatView);\n }, [header, toggleButton, width, defaultOpen, position]);\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 type { GraphQLError } from \"@copilotkit/runtime-client-gql\";\nimport React, { createContext, useContext, useState, useCallback } from \"react\";\nimport type { PartialBy, CopilotKitError } from \"@copilotkit/shared\";\nimport { 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 data-testid=\"copilot-error-banner\"\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).slice(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/**\n * Determine whether a GraphQL error should be suppressed based on its visibility\n * and whether the dev console is active.\n *\n * Returns `null` when the error should be surfaced to the UI, or a log prefix\n * string when the error should be suppressed (logged to console only).\n *\n * Exported for unit testing.\n */\nexport function getErrorSuppression(\n visibility: ErrorVisibility | undefined,\n isDev: boolean,\n): string | null {\n // Silent errors are always suppressed\n if (visibility === ErrorVisibility.SILENT) {\n return \"CopilotKit Silent Error:\";\n }\n\n // DEV_ONLY errors are suppressed in production\n if (!isDev && visibility === ErrorVisibility.DEV_ONLY) {\n return \"CopilotKit Error (hidden in production):\";\n }\n\n // All other visibilities (TOAST, BANNER, undefined) are always surfaced\n return null;\n}\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 const suppression = getErrorSuppression(visibility, isDev);\n if (suppression) {\n console.error(suppression, gqlError.message);\n return;\n }\n\n // TOAST and BANNER errors are always surfaced, even in production\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 // Non-GraphQL errors are always surfaced to the user\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 [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 type { CopilotKitError } from \"@copilotkit/shared\";\nimport {\n Severity,\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\" data-testid=\"copilot-error-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/overview#getting-access\",\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 useCallback,\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 // True when the current threadId was chosen by the caller — either via\n // the `threadId` prop on <CopilotKit> / <ThreadsProvider>, or via a later\n // setThreadId() call. False when the provider minted a UUID on first\n // mount so downstream consumers don't have to treat that placeholder as\n // a real backend thread.\n isThreadIdExplicit: boolean;\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, setInternalThreadId] = useState<string>(() =>\n randomUUID(),\n );\n const [internalIsExplicit, setInternalIsExplicit] = useState<boolean>(false);\n\n const threadId = explicitThreadId ?? internalThreadId;\n const isThreadIdExplicit = explicitThreadId != null || internalIsExplicit;\n\n const setThreadId = useCallback((value: SetStateAction<string>) => {\n setInternalThreadId(value);\n setInternalIsExplicit(true);\n }, []);\n\n return (\n <ThreadsContext.Provider\n value={{\n threadId,\n setThreadId,\n isThreadIdExplicit,\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].toReversed().find((msg) => msg.role === \"assistant\")\n ?.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\nfunction CopilotListenersAgentSubscription() {\n const existingConfig = useCopilotChatConfiguration();\n const resolvedAgentId = existingConfig?.agentId;\n\n const { agent } = useAgent({ agentId: resolvedAgentId });\n\n usePredictStateSubscription(agent);\n\n return null;\n}\n\nexport function CopilotListeners() {\n const { copilotkit } = useCopilotKit();\n const { setBannerError } = useToast();\n\n // Only render the agent subscription when agents are registered or a runtime\n // is configured. Without this guard, useAgent() throws when the agents map is\n // empty and no runtimeUrl is set (#3249).\n const hasAgents = Object.keys(copilotkit.agents ?? {}).length > 0;\n const hasRuntime = copilotkit.runtimeUrl !== undefined;\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 hasAgents || hasRuntime ? <CopilotListenersAgentSubscription /> : 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:\n typeof props.headers === \"function\"\n ? props.headers()\n : 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 {\n threadId,\n setThreadId: setInternalThreadId,\n isThreadIdExplicit,\n } = 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 hasExplicitThreadId={isThreadIdExplicit}\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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CAAC,WAAW,OAAO,KAAK,KAAK,CAAC,UAInD,OAAO,QAAQ,SAAS,CAAC,OAAO,CAAC,KAAK,WAAW,KAAK,SAAS,MAAM,GAEtD,OAAO;IACxB;IAEJ,CAAC,cAAc,CAChB;CAED,MAAM,qDACH,iBAA8B;EAC7B,MAAM,MAAM,aAAa,OAAO,4CAAoB;AACpD,8BAA4B,SAAS;GACnC,MAAM,SAAS,IAAI,IAAI,KAAK;AAC5B,UAAO,IAAI,KAAK,aAAa;AAC7B,UAAO;IACP;AACF,SAAO;IAET,EAAE,CACH;CAED,MAAM,uDAA4C,cAAsB;AACtE,8BAA4B,SAAS;GACnC,MAAM,SAAS,IAAI,IAAI,KAAK;AAC5B,UAAO,OAAO,UAAU;AACxB,UAAO;IACP;IACD,EAAE,CAAC;CAGN,MAAM,qDAA0C;AAC9C,eACE,mFACG,MAAM,KAAK,wBAAwB,SAAS,CAAC,CAAC,KAAK,CAAC,KAAK,YAAY;GACpE,MAAM,YAAY,OAAO;AACzB,UAAO,2CAAC,aAAoB,QAAQ,OAAO,UAApB,IAA8B;IACrD,GACD;IAEJ,CAAC,wBAAwB,CAAC;CAE7B,MAAM,gDACG;EACL;EACA;EACA;EACA;EACA;EACA,sBAAsB;EACtB,wBAAwB;EACxB;EACA;EACA;EACA;EACA;EACA;EACA;EACkB;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,cAAc,MAAM;EACpB,cAAc;EACd,iBAAiB;EACjB;EACA,eAAe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS;EACT;EACA;EACA;EACD,GACD;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,MAAM;EACN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CACF;AAED,QACE,2CAAC;EAGC,SAAS,MAAM,SAAS;EACd;EACV,qBAAqB;YAErB,4CAAC,eAAe;GAAS,OAAO;;IAC9B,2CAAC,qBAAmB;IACpB,2CAAC,0BAAwB;IACzB,4CAAC,0CACC,2CAAC,iCACC,4CAAC,8BACC,2CAACC,cAAM,sBAAyB,oBAAZ,WAA8C,EAClE,2CAAC,+BAA8B,UAAY,IAC3B,GACE,EACrB,eAAe,kBACd,2CAAC;KACC,UAAU,YAAY;KACtB,SAAS,YAAY;KACrB,eAAe,eAAe,KAAK;KACnC,SAAS,gBAAgB,YAAY;MACrC,IAEwB;;IACN;GACO;;AAIvC,MAAa,kCAAkC,CAAC,SAAS;AAEzD,SAAS,iCACP,SACqB;AACrB,QAAO,OAAO,EACZ,MACA,WAII;EACJ,IAAI,wBAA6D,EAAE;AACnE,OAAK,IAAI,UAAU,QACjB,uBAAsB,OAAO,QAAQ;EAGvC,MAAM,SAAS,sBAAsB;EACrC,IAAI,SAAc;AAClB,MAAI,QAAQ;AACV,SAAM,IAAI,SAAe,SAAS,WAAW;AAC3C,6BAAU,YAAY;AACpB,SAAI;AACF,eAAS,MAAM,OAAO,UAAU,KAAK;AACrC,eAAS;cACF,OAAO;AACd,aAAO,MAAM;;MAEf;KACF;AACF,SAAM,IAAI,SAAS,YAAY,WAAW,SAAS,GAAG,CAAC;;AAEzD,SAAO;;;AAIX,SAAS,kBAAkB,aAA6B;AACtD,QAAO,YACJ,QAAQ,OAAO,GAAG,CAClB,MAAM,IAAI,CACV,KAAK,SAAS,KAAK,OAAO,EAAE,CAAC,aAAa,GAAG,KAAK,MAAM,EAAE,CAAC,aAAa,CAAC,CACzE,KAAK,IAAI;;AAGd,SAAS,cAAc,OAAsC;CAC3D,MAAM,gBAAgB,OAAO,KAAK,MAAM,CAAC,QAAQ,QAAQ,IAAI,SAAS,KAAK,CAAC;CAG5E,MAAM,YAAY,MAAM,gBAAgB,MAAM;AAE9C,KAAI,CAAC,MAAM,cAAc,CAAC,UACxB,OAAM,IAAIC,sCACR,8EACD;AAGH,KAAI,cAAc,SAAS,KAAK,CAAC,UAC/B,OAAM,IAAIC,4CACR,sFAAsF,cACnF,IAAI,kBAAkB,CACtB,KAAK,KAAK,GACd"}
|