@copilotkit/react-core
Version:
<img src="https://github.com/user-attachments/assets/0a6b64d9-e193-4940-a3f6-60334ac34084" alt="banner" style="border-radius: 12px; border: 2px solid #d6d4fa;" />
1 lines • 993 kB
Source Map (JSON)
{"version":3,"file":"copilotkit-Bocmlr37.cjs","names":["DEFAULT_AGENT_ID","twMerge","React","Slot","TooltipPrimitive","React","DropdownMenuPrimitive","React","ChevronRightIcon","React","Square","Loader2","ArrowUp","Mic","X","Check","Plus","React","ToolCallStatus","DEFAULT_AGENT_ID","React","React","z","z","React","ToolCallStatus","z","z","DEFAULT_SURFACE_ID","A2UIProvider","A2UIRenderer","z","z","A2UI_SCHEMA_CONTEXT_DESCRIPTION","A2UI_DEFAULT_GENERATION_GUIDELINES","A2UI_DEFAULT_DESIGN_GUIDELINES","CopilotKitCore","COPILOT_CLOUD_CHAT_URL","Catalog","viewerTheme","z","CopilotKitContext","LicenseContext","DEFAULT_AGENT_ID","EMPTY_DEPS","ToolCallStatus","ToolCallStatus","ToolCallStatus","React","DEFAULT_AGENT_ID","ProxiedCopilotRuntimeAgent","CopilotKitCoreRuntimeConnectionStatus","HttpAgent","DEFAULT_AGENT_ID","DEFAULT_AGENT_ID","ɵInterruptState","useThreads","ɵselectThreads","ɵselectThreadsIsLoading","ɵselectThreadsError","ɵselectFetchMoreError","ɵselectHasNextPage","ɵselectIsFetchingNextPage","ɵselectIsMutating","CopilotKitCoreRuntimeConnectionStatus","ɵselectMemories","ɵselectMemoriesIsLoading","ɵselectMemoriesError","ɵselectMemoriesAvailable","ɵselectMemoriesRealtimeStatus","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","CopilotKitCoreRuntimeConnectionStatus","HttpAgent","TranscriptionErrorCode","MessageCircle","X","React","X","PanelLeftOpen","CopilotChatView","CopilotChatView","CopilotChatView","React","CopilotPopupView","CopilotChatView","DEFAULT_AGENT_ID","useThreads","React","COPILOTKIT_THREADS_DRAWER_TAG","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","DEFAULT_AGENT_ID","CopilotKitLowLevelError","CopilotKitV2Provider","COPILOT_CLOUD_CHAT_URL","COPILOT_CLOUD_PUBLIC_API_KEY_HEADER","React","ConfigurationError","MissingPublicApiKeyError"],"sources":["../src/v2/lib/shallow-stable-ref.ts","../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/lib/slots.tsx","../src/v2/components/chat/CopilotChatInput.tsx","../src/v2/hooks/useKatexStyles.ts","../src/v2/hooks/use-render-tool-call.tsx","../src/v2/components/CopilotKitInspector.tsx","../src/v2/components/CopilotKitInspectorContext.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/types/defineToolCallRenderer.ts","../src/v2/a2ui/A2UIToolCallRenderer.tsx","../src/v2/a2ui/A2UICatalogContext.tsx","../src/v2/lib/react-core.ts","../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-render-tool.tsx","../src/v2/hooks/use-default-render-tool.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-agent-context.tsx","../src/v2/hooks/use-suggestions.tsx","../src/v2/hooks/use-configure-suggestions.tsx","../src/v2/hooks/use-interrupt.tsx","../src/v2/hooks/use-threads.tsx","../src/v2/hooks/use-memories.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/chat/CopilotThreadsDrawer.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 { useRef } from \"react\";\n\n// Tailwind-free reference-stability helpers. Kept in their own leaf module (not\n// in ./slots, which imports `tailwind-merge`) so that DOM/CSS-free consumers —\n// e.g. CopilotChatConfigurationProvider, which is re-exported from the lean\n// `@copilotkit/react-core/v2/headless` entry — can reach them without pulling\n// `tailwind-merge` into the bundle (issue #4893).\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","import type { ReactNode } from \"react\";\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { DEFAULT_AGENT_ID, randomUUID } from \"@copilotkit/shared\";\n// Import from the tailwind-free leaf module (not ../lib/slots, which pulls\n// tailwind-merge) so this provider stays lean in the headless entry (issue #4893).\nimport { useShallowStableRef } from \"../lib/shallow-stable-ref\";\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 assistantMessageToolbarInspectorLabel: \"View in Inspector\",\n assistantMessageToolbarInspectorLocalOnlyLabel: \"Local Only\",\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/**\n * Mobile breakpoint below which the chat modal and the thread-list drawer are\n * mutually exclusive. At or above this width both surfaces may coexist. This\n * mirrors the `(max-width: 767px)` / `(min-width: 768px)` split already used by\n * CopilotChatInput and CopilotSidebarView.\n */\nconst MOBILE_MAX_WIDTH_PX = 767;\n\n/**\n * Reports whether the current viewport is in the mobile range (`<768px`), where\n * the chat modal and drawer must not be open simultaneously. SSR-safe and\n * defensive against environments without `matchMedia` (treated as desktop, so\n * no mutual-exclusion constraint is applied).\n *\n * @returns `true` when the viewport is mobile-width, `false` otherwise.\n */\nfunction isMobileViewport(): boolean {\n if (\n typeof window === \"undefined\" ||\n typeof window.matchMedia !== \"function\"\n ) {\n return false;\n }\n return window.matchMedia(`(max-width: ${MOBILE_MAX_WIDTH_PX}px)`).matches;\n}\n\n// Define the full configuration interface\nexport interface CopilotChatConfigurationValue {\n labels: CopilotChatLabels;\n agentId: string;\n threadId: string;\n isModalOpen: boolean;\n setModalOpen: (open: boolean) => void;\n /**\n * Whether the thread-list drawer is open. A sibling boolean to `isModalOpen`\n * (deliberately NOT folded into a tri-state enum): on desktop the chat modal\n * and the drawer coexist, so two independent booleans are required.\n */\n drawerOpen: boolean;\n /**\n * Toggles the drawer open state. On mobile viewports (`<768px`) opening the\n * drawer closes the chat modal (mutual exclusion); on desktop there is no\n * constraint.\n */\n setDrawerOpen: (open: boolean) => void;\n /**\n * True once a `<CopilotThreadsDrawer>` wrapper has registered itself with this chat\n * configuration. The header thread-list launcher renders ONLY when this is\n * set, so chats with no drawer stay byte-for-byte unchanged.\n */\n drawerRegistered: boolean;\n /**\n * Called by the drawer wrapper on mount to announce its presence (and flip\n * `drawerRegistered`). Returns a cleanup function that de-registers the\n * drawer on unmount.\n *\n * @returns A cleanup callback that reverses the registration.\n */\n registerDrawer: () => () => void;\n /**\n * Internal: registers the modal-close setter of the provider that actually\n * owns the rendered modal (a descendant that supplied `isModalDefaultOpen`),\n * so the drawer's mobile mutual-exclusion — owned by the top-most provider —\n * closes the modal that is genuinely on screen rather than the top-most\n * provider's own (possibly unrendered) modal state.\n *\n * @param closeModal - A setter the drawer may call to close the rendered modal.\n * @returns A cleanup callback that de-registers the closer.\n */\n ɵregisterModalCloser: (closeModal: (open: boolean) => void) => () => 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 * Imperatively sets the active thread for this chat configuration.\n *\n * Use this to drive the rendered thread without a host callback — e.g. a\n * `<CopilotThreadsDrawer>` selecting a thread row sets it explicitly so the chat\n * connects to that backend thread.\n *\n * Guarded like the top-level `<CopilotKit>` provider's `setThreadId`: when\n * the consumer controls the threadId via the `threadId` prop on this\n * provider, this is a no-op (a warning is logged) so a prop-controlled\n * threadId is never silently overridden.\n *\n * @param threadId - The thread id to make active.\n * @param options.explicit - Whether the thread is a caller choice. Defaults\n * to `true` (a picked thread). Pass `false` to set a non-explicit thread\n * so the welcome screen shows (see {@link startNewThread}).\n */\n setActiveThreadId: (\n threadId: string,\n options?: { explicit?: boolean },\n ) => void;\n /**\n * Resets the active thread to a fresh, non-explicit client-side thread: a\n * newly minted UUID with `hasExplicitThreadId=false`, so the welcome screen\n * shows. Pairs with the core `startNewThread()` to clear the conversation\n * with no host wiring.\n *\n * Guarded identically to {@link setActiveThreadId}: a no-op when the\n * threadId is prop-controlled.\n */\n startNewThread: () => void;\n}\n\n// Create the configuration context\nconst CopilotChatConfiguration =\n createContext<CopilotChatConfigurationValue | null>(null);\n\n// Provider props interface\nexport interface CopilotChatConfigurationProviderProps {\n children: ReactNode;\n labels?: Partial<CopilotChatLabels>;\n agentId?: string;\n threadId?: string;\n // 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 // A threadId prop is \"authoritative\" (caller-chosen) only when it is present\n // AND not explicitly flagged non-explicit. The v1 `<CopilotKit>` bridge pipes\n // an auto-minted UUID through as `threadId` with `hasExplicitThreadId={false}`\n // to SEED the thread without claiming the caller picked it; that seed must\n // stay overridable so imperative callers (e.g. `<CopilotThreadsDrawer>` selecting a\n // row, or `startNewThread`) can switch threads. A bare `threadId` prop (no\n // `hasExplicitThreadId`) is still treated as a caller choice.\n const threadIdPropIsAuthoritative =\n threadId !== undefined && hasExplicitThreadId !== false;\n\n // Whether this provider's threadId is controlled by the consumer. When\n // controlled, the imperative active-thread setters below must not override\n // the prop-driven value. A non-authoritative seed (v1 bridge auto-mint) is\n // NOT controlled, so imperative selection still works underneath it.\n const isThreadIdControlled = threadIdPropIsAuthoritative;\n\n // Imperative active-thread override owned by the TOP-MOST provider (the one\n // with no parent). A non-null override takes precedence over the auto-minted\n // UUID fallback below. Nested providers do not own this state — they proxy\n // the parent's setter (see resolved*ActiveThread below) and observe the\n // override through the inherited `parentConfig.threadId`.\n const [activeThreadOverride, setActiveThreadOverride] = useState<{\n threadId: string;\n explicit: boolean;\n } | null>(null);\n\n const resolvedThreadId = useMemo(() => {\n // An authoritative (caller-chosen) threadId prop always wins.\n if (threadIdPropIsAuthoritative) {\n return threadId as string;\n }\n // Otherwise an imperative override (a picked row or freshly-started thread)\n // beats both a non-authoritative seed (the v1 bridge's auto-minted UUID) and\n // the thread inherited from a parent provider.\n if (activeThreadOverride) {\n return activeThreadOverride.threadId;\n }\n if (parentConfig?.threadId) {\n return parentConfig.threadId;\n }\n if (threadId) {\n return threadId;\n }\n return randomUUID();\n }, [\n threadIdPropIsAuthoritative,\n threadId,\n parentConfig?.threadId,\n activeThreadOverride,\n ]);\n\n // Explicitness of this provider's own thread, mirroring the resolution order\n // above: an authoritative prop is a caller choice; otherwise an imperative\n // override carries its own explicitness (a picked row is explicit, a fresh\n // `startNewThread` is not); failing both, fall back to the (non-authoritative)\n // prop flag, which is `false` for the v1 bridge seed.\n const ownHasExplicitThreadId = threadIdPropIsAuthoritative\n ? true\n : (activeThreadOverride?.explicit ?? hasExplicitThreadId ?? false);\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 // Drawer presence + open state. When a parent provider exists, this provider\n // proxies the parent's drawer state and registration so that the whole chain\n // shares a single drawer (the drawer wrapper registers once, anywhere in the\n // subtree, and the header launcher anywhere can read/toggle it). Only the\n // top-most provider owns the underlying state.\n const [ownDrawerOpen, setOwnDrawerOpen] = useState<boolean>(false);\n const [ownDrawerCount, setOwnDrawerCount] = useState<number>(0);\n\n // The modal-close path used by the drawer's mobile mutual-exclusion. Held in\n // a ref so the drawer setter (owned by the top-most provider) can reach the\n // resolved modal setter without recreating its identity on every render.\n const modalCloseRef = useRef<(open: boolean) => void>(() => {});\n // Default to this provider's own resolved modal setter. When a DESCENDANT\n // provider owns the rendered modal (it supplied `isModalDefaultOpen`), it\n // registers its closer via `ɵregisterModalCloser` below, which overrides this\n // so the drawer closes the modal that is actually on screen.\n modalCloseRef.current = resolvedSetModalOpen;\n\n // Stack of descendant-registered modal closers. The most recently registered\n // closer (the deepest/last-rendered modal owner) is preferred, mirroring how\n // `resolvedThreadId`/modal ownership flows to the nearest explicit owner.\n const registeredModalClosersRef = useRef<Array<(open: boolean) => void>>([]);\n\n const ownRegisterModalCloser = useCallback(\n (closeModal: (open: boolean) => void) => {\n registeredModalClosersRef.current.push(closeModal);\n return () => {\n registeredModalClosersRef.current =\n registeredModalClosersRef.current.filter(\n (entry) => entry !== closeModal,\n );\n };\n },\n [],\n );\n\n const ownSetDrawerOpen = useCallback((open: boolean) => {\n setOwnDrawerOpen(open);\n // Mobile mutual-exclusion: opening the drawer closes the chat modal. Prefer\n // a descendant-registered closer (the actually-rendered modal) over this\n // provider's own resolved modal setter.\n if (open && isMobileViewport()) {\n const registered = registeredModalClosersRef.current;\n const closeModal =\n registered.length > 0\n ? registered[registered.length - 1]\n : modalCloseRef.current;\n closeModal(false);\n }\n }, []);\n\n const ownRegisterDrawer = useCallback(() => {\n setOwnDrawerCount((count) => count + 1);\n return () => {\n setOwnDrawerCount((count) => Math.max(0, count - 1));\n };\n }, []);\n\n const resolvedDrawerOpen = parentConfig\n ? parentConfig.drawerOpen\n : ownDrawerOpen;\n const resolvedSetDrawerOpen = parentConfig\n ? parentConfig.setDrawerOpen\n : ownSetDrawerOpen;\n const resolvedDrawerRegistered = parentConfig\n ? parentConfig.drawerRegistered\n : ownDrawerCount > 0;\n const resolvedRegisterDrawer = parentConfig\n ? parentConfig.registerDrawer\n : ownRegisterDrawer;\n const resolvedRegisterModalCloser = parentConfig\n ? parentConfig.ɵregisterModalCloser\n : ownRegisterModalCloser;\n\n // When THIS provider owns the rendered modal (it supplied\n // `isModalDefaultOpen`), register its closer up the chain so the top-most\n // provider's drawer mobile mutual-exclusion closes the modal that is actually\n // on screen. Re-registers if the resolved setter identity changes.\n useEffect(() => {\n if (!hasExplicitDefault) return;\n return resolvedRegisterModalCloser(resolvedSetModalOpen);\n }, [hasExplicitDefault, resolvedRegisterModalCloser, resolvedSetModalOpen]);\n\n // Active-thread override setters. The TOP-MOST provider owns the override\n // state; nested providers proxy the parent's setter so the whole chain drives\n // a single active thread (the override placed on the owner flows down via the\n // inherited threadId).\n //\n // The controlled-guard is applied at EACH level, not only on the owner: a\n // provider whose own `threadId` prop pins the rendered thread (per the\n // `resolvedThreadId` precedence above) intercepts the set with a no-op +\n // warning BEFORE proxying upward. This is required because in a nested chain\n // the controlled provider is often NOT the override owner — e.g. an\n // uncontrolled top-most provider with a controlled nested provider. Guarding\n // only the owner would let the set silently no-op (the nested `threadId` prop\n // wins at render) while the documented warning never fired.\n const isThreadIdControlledRef = useRef(isThreadIdControlled);\n isThreadIdControlledRef.current = isThreadIdControlled;\n\n const ownSetActiveThreadId = useCallback(\n (id: string, options?: { explicit?: boolean }) => {\n setActiveThreadOverride({\n threadId: id,\n explicit: options?.explicit ?? true,\n });\n },\n [],\n );\n\n const ownStartNewThread = useCallback(() => {\n setActiveThreadOverride({ threadId: randomUUID(), explicit: false });\n }, []);\n\n // Proxy to the parent's setter when nested, else to the owner's. Wrapped with\n // this provider's own controlled-guard so the nearest pinning (controlled)\n // provider — wherever it sits in the chain — is the one that no-ops + warns.\n const parentSetActiveThreadId = parentConfig?.setActiveThreadId;\n const parentStartNewThread = parentConfig?.startNewThread;\n\n const resolvedSetActiveThreadId = useCallback(\n (id: string, options?: { explicit?: boolean }) => {\n if (isThreadIdControlledRef.current) {\n console.warn(\n \"[CopilotKit] Ignoring setActiveThreadId(): threadId is controlled \" +\n \"via the `threadId` prop on CopilotChatConfigurationProvider.\",\n );\n return;\n }\n if (parentSetActiveThreadId) {\n parentSetActiveThreadId(id, options);\n return;\n }\n ownSetActiveThreadId(id, options);\n },\n [parentSetActiveThreadId, ownSetActiveThreadId],\n );\n\n const resolvedStartNewThread = useCallback(() => {\n if (isThreadIdControlledRef.current) {\n console.warn(\n \"[CopilotKit] Ignoring startNewThread(): threadId is controlled via \" +\n \"the `threadId` prop on CopilotChatConfigurationProvider.\",\n );\n return;\n }\n if (parentStartNewThread) {\n parentStartNewThread();\n return;\n }\n ownStartNewThread();\n }, [parentStartNewThread, ownStartNewThread]);\n\n // Mobile mutual-exclusion (other direction): opening the chat modal closes\n // the drawer. Layered over whichever modal setter we resolved above so the\n // existing parent/child modal-sync contract is preserved untouched.\n const setModalOpenWithDrawerExclusion = useCallback(\n (open: boolean) => {\n if (open && isMobileViewport()) {\n resolvedSetDrawerOpen(false);\n }\n resolvedSetModalOpen(open);\n },\n [resolvedSetModalOpen, resolvedSetDrawerOpen],\n );\n\n const configurationValue: CopilotChatConfigurationValue = useMemo(\n () => ({\n labels: mergedLabels,\n agentId: resolvedAgentId,\n threadId: resolvedThreadId,\n hasExplicitThreadId: resolvedHasExplicitThreadId,\n isModalOpen: resolvedIsModalOpen,\n setModalOpen: setModalOpenWithDrawerExclusion,\n drawerOpen: resolvedDrawerOpen,\n setDrawerOpen: resolvedSetDrawerOpen,\n drawerRegistered: resolvedDrawerRegistered,\n registerDrawer: resolvedRegisterDrawer,\n ɵregisterModalCloser: resolvedRegisterModalCloser,\n setActiveThreadId: resolvedSetActiveThreadId,\n startNewThread: resolvedStartNewThread,\n }),\n [\n mergedLabels,\n resolvedAgentId,\n resolvedThreadId,\n resolvedHasExplicitThreadId,\n resolvedIsModalOpen,\n setModalOpenWithDrawerExclusion,\n resolvedDrawerOpen,\n resolvedSetDrawerOpen,\n resolvedDrawerRegistered,\n resolvedRegisterDrawer,\n resolvedRegisterModalCloser,\n resolvedSetActiveThreadId,\n resolvedStartNewThread,\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\nconst TooltipTrigger = React.forwardRef<\n HTMLButtonElement,\n React.ComponentProps<typeof TooltipPrimitive.Trigger>\n>(function TooltipTrigger({ ...props }, ref) {\n return (\n <TooltipPrimitive.Trigger\n ref={ref}\n data-slot=\"tooltip-trigger\"\n {...props}\n />\n );\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\nconst DropdownMenuTrigger = React.forwardRef<\n HTMLButtonElement,\n React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>\n>(function DropdownMenuTrigger({ ...props }, ref) {\n return (\n <DropdownMenuPrimitive.Trigger\n ref={ref}\n data-slot=\"dropdown-menu-trigger\"\n {...props}\n />\n );\n});\n\nfunction DropdownMenuContent({\n className,\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-copilotkit\n data-slot=\"dropdown-menu-content\"\n sideOffset={sideOffset}\n className={cn(\n \"cpk:bg-popover cpk:text-popover-foreground cpk:data-[state=open]:animate-in cpk:data-[state=closed]:animate-out cpk:data-[state=closed]:fade-out-0 cpk:data-[state=open]:fade-in-0 cpk:data-[state=closed]:zoom-out-95 cpk:data-[state=open]:zoom-in-95 cpk:data-[side=bottom]:slide-in-from-top-2 cpk:data-[side=left]:slide-in-from-right-2 cpk:data-[side=right]:slide-in-from-left-2 cpk:data-[side=top]:slide-in-from-bottom-2 cpk:z-50 cpk:max-h-(--radix-dropdown-menu-content-available-height) cpk:min-w-[8rem] cpk:origin-(--radix-dropdown-menu-content-transform-origin) cpk:overflow-x-hidden cpk:overflow-y-auto cpk:rounded-md cpk:border cpk:p-1 cpk:shadow-md\",\n className,\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n );\n}\n\nfunction DropdownMenuGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n return (\n <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n );\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean;\n variant?: \"default\" | \"destructive\";\n}) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"cpk:focus:bg-accent cpk:focus:text-accent-foreground cpk:data-[variant=destructive]:text-destructive cpk:data-[variant=destructive]:focus:bg-destructive/10 cpk:dark:data-[variant=destructive]:focus:bg-destructive/20 cpk:data-[variant=destructive]:focus:text-destructive cpk:data-[variant=destructive]:*:[svg]:!text-destructive cpk:[&_svg:not([class*='text-'])]:text-muted-foreground cpk:relative cpk:flex cpk:cursor-default cpk:items-center cpk:gap-2 cpk:rounded-sm cpk:px-2 cpk:py-1.5 cpk:text-sm cpk:outline-hidden cpk:select-none cpk:data-[disabled]:pointer-events-none cpk:data-[disabled]:opacity-50 cpk:data-[inset]:pl-8 cpk:[&_svg]:pointer-events-none cpk:[&_svg]:shrink-0 cpk:[&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n className={cn(\n \"cpk:focus:bg-accent cpk:focus:text-accent-foreground cpk:relative cpk:flex cpk:cursor-default cpk:items-center cpk:gap-2 cpk:rounded-sm cpk:py-1.5 cpk:pr-2 cpk:pl-8 cpk:text-sm cpk:outline-hidden cpk:select-none cpk:data-[disabled]:pointer-events-none cpk:data-[disabled]:opacity-50 cpk:[&_svg]:pointer-events-none cpk:[&_svg]:shrink-0 cpk:[&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n checked={checked}\n {...props}\n >\n <span className=\"cpk:pointer-events-none cpk:absolute cpk:left-2 cpk:flex cpk:size-3.5 cpk:items-center cpk:justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CheckIcon className=\"cpk:size-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n );\n}\n\nfunction DropdownMenuRadioGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n return (\n <DropdownMenuPrimitive.RadioGroup\n data-slot=\"dropdown-menu-radio-group\"\n {...props}\n />\n );\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n return (\n <DropdownMenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n className={cn(\n \"cpk:focus:bg-accent cpk:focus:text-accent-foreground cpk:relative cpk:flex cpk:cursor-default cpk:items-center cpk:gap-2 cpk:rounded-sm cpk:py-1.5 cpk:pr-2 cpk:pl-8 cpk:text-sm cpk:outline-hidden cpk:select-none cpk:data-[disabled]:pointer-events-none cpk:data-[disabled]:opacity-50 cpk:[&_svg]:pointer-events-none cpk:[&_svg]:shrink-0 cpk:[&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n >\n <span className=\"cpk:pointer-events-none cpk:absolute cpk:left-2 cpk:flex cpk:size-3.5 cpk:items-center cpk:justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CircleIcon className=\"cpk:size-2 cpk:fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n );\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\n \"cpk:px-2 cpk:py-1.5 cpk:text-sm cpk:font-medium cpk:data-[inset]:pl-8\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn(\"cpk:bg-border cpk:-mx-1 cpk:my-1 cpk:h-px\", className)}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\n \"cpk:text-muted-foreground cpk:ml-auto cpk:text-xs cpk:tracking-widest\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSub({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />;\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"cpk:focus:bg-accent cpk:focus:text-accent-foreground cpk:data-[state=open]:bg-accent cpk:data-[state=open]:text-accent-foreground cpk:flex cpk:cursor-default cpk:items-center cpk:rounded-sm cpk:px-2 cpk:py-1.5 cpk:text-sm cpk:outline-hidden cpk:select-none cpk:data-[inset]:pl-8\",\n className,\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"cpk:ml-auto cpk:size-4\" />\n </DropdownMenuPrimitive.SubTrigger>\n );\n}\n\nfunction DropdownMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\n \"cpk:bg-popover cpk:text-popover-foreground cpk:data-[state=open]:animate-in cpk:data-[state=closed]:animate-out cpk:data-[state=closed]:fade-out-0 cpk:data-[state=open]:fade-in-0 cpk:data-[state=closed]:zoom-out-95 cpk:data-[state=open]:zoom-in-95 cpk:data-[side=bottom]:slide-in-from-top-2 cpk:data-[side=left]:slide-in-from-right-2 cpk:data-[side=right]:slide-in-from-left-2 cpk:data-[side=top]:slide-in-from-bottom-2 cpk:z-50 cpk:min-w-[8rem] cpk:origin-(--radix-dropdown-menu-content-transform-origin) cpk:overflow-hidden cpk:rounded-md cpk:border cpk:p-1 cpk:shadow-lg\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport {\n DropdownMenu,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n};\n","import {\n useRef,\n useEffect,\n useImperativeHandle,\n forwardRef,\n useCallback,\n useState,\n} from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\n/** Finite-state machine for every recorder implementation */\nexport type AudioRecorderState = \"idle\" | \"recording\" | \"processing\";\n\n/** Error subclass so callers can `instanceof`-guard recorder failures */\nexport class AudioRecorderError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"AudioRecorderError\";\n }\n}\n\nexport interface AudioRecorderRef {\n state: AudioRecorderState;\n start: () => Promise<void>;\n stop: () => Promise<Blob>;\n dispose: () => void;\n}\n\nexport const CopilotChatAudioRecorder = forwardRef<\n AudioRecorderRef,\n React.HTMLAttributes<HTMLDivElement>\n>((props, ref) => {\n const { className, ...divProps } = props;\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n // Recording state\n const [recorderState, setRecorderState] =\n useState<AudioRecorderState>(\"idle\");\n const mediaRecorderRef = useRef<MediaRecorder | null>(null);\n const audioChunksRef = useRef<Blob[]>([]);\n const streamRef = useRef<MediaStream | null>(null);\n const analyserRef = useRef<AnalyserNode | null>(null);\n const audioContextRef = useRef<AudioContext | null>(null);\n const animationIdRef = useRef<number | null>(null);\n\n // Amplitude history buffer for scrolling waveform\n const amplitudeHistoryRef = useRef<number[]>([]);\n const frameCountRef = useRef<number>(0);\n const scrollOffsetRef = useRef<number>(0);\n const smoothedAmplitudeRef = useRef<number>(0);\n const fadeOpacityRef = useRef<number>(0);\n\n // Clean up all resources\n const cleanup = useCallback(() => {\n if (animationIdRef.current) {\n cancelAnimationFrame(animationIdRef.current);\n animationIdRef.current = null;\n }\n if (\n mediaRecorderRef.current &&\n mediaRecorderRef.current.state !== \"inactive\"\n ) {\n try {\n mediaRecorderRef.current.stop();\n } catch {\n // Ignore errors during cleanup\n }\n }\n if (streamRef.current) {\n streamRef.current.getTracks().forEach((track) => track.stop());\n streamRef.current = null;\n }\n if (audioContextRef.current && audioContextRef.current.state !== \"closed\") {\n audioContextRef.current.close().catch(() => {\n // Ignore close errors\n });\n audioContextRef.current = null;\n }\n mediaRecorderRef.current = null;\n analyserRef.current = null;\n audioChunksRef.current = [];\n amplitudeHistoryRef.current = [];\n frameCountRef.current = 0;\n scrollOffsetRef.current = 0;\n smoothedAmplitudeRef.current = 0;\n fadeOpacityRef.current = 0;\n }, []);\n\n // Start recording\n const start = useCallback(async () => {\n if (recorderState !== \"idle\") {\n throw new AudioRecorderError(\"Recorder is already active\");\n }\n\n try {\n // Request microphone access\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n streamRef.current = stream;\n\n // Set up audio context for visualization\n const audioContext = new AudioContext();\n audioContextRef.current = audioContext;\n const source = audioContext.createMediaStreamSource(stream);\n const analyser = audioContext.createAnalyser();\n analyser.fftSize = 2048; // Higher resolution for time-domain waveform\n source.connect(analyser);\n analyserRef.current = analyser;\n\n // Determine best MIME type for recording\n const mimeType = MediaRecorder.isTypeSupported(\"audio/webm;codecs=opus\")\n ? \"audio/webm;codecs=opus\"\n : MediaRecorder.isTypeSupported(\"audio/webm\")\n ? \"audio/webm\"\n : MediaRecorder.isTypeSupported(\"audio/mp4\")\n ? \"audio/mp4\"\n : \"\";\n\n const options: MediaRecorderOptions = mimeType ? { mimeType } : {};\n const mediaRecorder = new MediaRecorder(stream, options);\n mediaRecorderRef.current = mediaRecorder;\n audioChunksRef.current = [];\n\n mediaRecorder.ondataavailable = (event) => {\n if (event.data.size > 0) {\n audioChunksRef.current.push(event.data);\n }\n };\n\n // Start recording with timeslice to collect data periodically\n mediaRecorder.start(100);\n setRecorderState(\"recording\");\n } catch (error) {\n cleanup();\n if (error instanceof Error && error.name === \"NotAllowedError\") {\n throw new AudioRecorderError(\"Microphone permission denied\");\n }\n if (error instanceof Error && error.name === \"NotFoundError\") {\n throw new AudioRecorderError(\"No microphone found\");\n }\n throw new AudioRecorderError(\n error instanceof Error ? error.message : \"Failed to start recording\",\n );\n }\n }, [recorderState, cleanup]);\n\n // Stop recording and return audio blob\n const stop = useCallback((): Promise<Blob> => {\n return new Promise((resolve, reject) => {\n const mediaRecorder = mediaRecorderRef.current;\n if (!mediaRecorder || recorderState !== \"recording\") {\n reject(new AudioRecorderError(\"No active recording\"));\n return;\n }\n\n setRecorderState(\"processing\");\n\n mediaRecorder.onstop = () => {\n const mimeType = mediaRecorder.mimeType || \"audio/webm\";\n const audioBlob = new Blob(audioChunksRef.current, { type: mimeType });\n\n // Clean up but keep the blob\n cleanup();\n setRecorderState(\"idle\");\n resolve(audioBlob);\n };\n\n mediaRecorder.onerror = () => {\n cleanup();\n setRecorderState(\"idle\");\n reject(new AudioRecorderError(\"Recording failed\"));\n };\n\n mediaRecorder.stop();\n });\n }, [recorderState, cleanup]);\n\n // Calculate RMS amplitude from time-domain data\n const calculateAmplitude = (dataArray: Uint8Array): number => {\n let sum = 0;\n for (let i = 0; i < dataArray.length; i++) {\n // Normalize to -1 to 1 range (128 is center/silence)\n const sample = (dataArray[i] ?? 128) / 128 - 1;\n sum += sample * sample;\n }\n return Math.sqrt(sum / dataArray.length);\n };\n\n // Canvas rendering with animation\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n\n // Configuration\n const barWidth = 2;\n const barGap = 1;\n const barSpacing = barWidth + barGap;\n const scrollSpeed = 1 / 3; // Pixels per frame\n\n const draw = () => {\n const rect = canvas.getBoundingClientRect();\n const dpr = window.devicePixelRatio || 1;\n\n // Update canvas dimensions if container resized\n if (\n canvas.width !== rect.width * dpr ||\n canvas.height !== rect.height * dpr\n ) {\n canvas.width = rect.width * dpr;\n canvas.height = rect.height * dpr;\n ctx.scale(dpr, dpr);\n }\n\n // Calculate how many bars fit in the canvas (plus extra for smooth scrolling)\n const maxBars = Math.floor(rect.width / barSpacing) + 2;\n\n // Get current amplitude if recording\n if (analyserRef.current && recorderState === \"recording\") {\n // Pre-fill history with zeros on first frame so line is visible immediately\n if (amplitudeHistoryRef.current.length === 0) {\n amplitudeHistoryRef.current = new Array(maxBars).fill(0);\n }\n\n // Fade in the waveform smoothly\n if (fadeOpacityRef.current < 1) {\n fadeOpacityRef.current = Math.min(1, fadeOpacityRef.current + 0.03);\n }\n\n // Smooth scrolling - increment offset every frame\n scrollOffsetRef.current += scrollSpeed;\n\n // Sample amplitude every frame for smoothing\n const bufferLength = analyserRef.current.fftSize;\n const dataArray = new Uint8Array(bufferLength);\n analyserRef.current.getByteTimeDomainData(dataArray);\n const rawAmplitude = calculateAmplitude(dataArray);\n\n // Smoothing: gradual attack and decay\n const attackSpeed = 0.12; // Smooth rise\n const decaySpeed = 0.08; // Smooth fade out\n const speed =\n rawAmplitude > smoothedAmplitudeRef.current\n ? attackSpeed\n : decaySpeed;\n smoothedAmplitudeRef.current +=\n (rawAmplitude - smoothedAmplitudeRef.current) * speed;\n\n // When offset reaches a full bar width, add a new sample and reset offset\n if (scrollOffsetRef.current >= barSpacing) {\n scrollOffsetRef.current -= barSpacing;\n amplitudeHistoryRef.current.push(smoothedAmplitudeRef.current);\n\n // Trim history to fit canvas\n if (amplitudeHistoryRef.current.length > maxBars) {\n amplitudeHistoryRef.current =\n amplitudeHistoryRef.current.slice(-maxBars);\n }\n }\n }\n\n // Clear canvas\n ctx.clearRect(0, 0, rect.width, rect.height);\n\n // Get current foreground color\n const computedStyle = getComputedStyle(canvas);\n ctx.fillStyle = computedStyle.color;\n ctx.globalAlpha = fadeOpacityRef.current;\n\n const centerY = rect.height / 2;\n const maxAmplitude = rect.height / 2 - 2; // Leave some padding\n\n const history = amplitudeHistoryRef.current;\n\n // Only draw when recording (history has data)\n if (history.length > 0) {\n const offset = scrollOffsetRef.current;\n const edgeFadeWidth = 12; // Pixels to fade at each edge\n\n for (let i = 0; i < history.length; i++) {\n const amplitude = history[i] ?? 0;\n // Scale amplitude (RMS is typically 0-0.5 for normal speech)\n const scaledAmplitude = Math.min(amplitude * 4, 1);\n const barHeight = Math.max(2, scaledAmplitude * maxAmplitude * 2);\n\n // Position: right-aligned with smooth scroll offset\n const x = rect.width - (history.length - i) * barSpacing - offset;\n const y = centerY - barHeight / 2;\n\n // Only draw if visible\n if (x + barWidth > 0 && x < rect.width) {\n // Calculate edge fade opacity\n let edgeOpacity = 1;\n if (x < edgeFadeWidth) {\n // Fade out on left edge\n edgeOpacity = Math.max(0, x / edgeFadeWidth);\n } else if (x > rect.width - edgeFadeWidth) {\n // Fade in on right edge\n edgeOpacity = Math.max(0, (rect.width - x) / edgeFadeWidth);\n }\n\n ctx.globalAlpha = fadeOpacityRef.current * edgeOpacity;\n ctx.fillRect(x, y, barWidth, barHeight);\n }\n }\n }\n\n animationIdRef.current = requestAnimationFrame(draw);\n };\n\n draw();\n\n return () => {\n if (animationIdRef.current) {\n cancelAnimationFrame(animationIdRef.current);\n }\n };\n }, [recorderState]);\n\n // Cleanup on unmount\n useEffect(() => {\n return cleanup;\n }, [cleanup]);\n\n // Expose AudioRecorder API via ref\n useImperativeHandle(\n ref,\n () => ({\n get state() {\n return recorderState;\n },\n start,\n stop,\n dispose: cleanup,\n }),\n [recorderState, start, stop, cleanup],\n );\n\n return (\n <div\n className={twMerge(\"cpk:w-full cpk:py-3 cpk:px-5\", className)}\n {...divProps}\n >\n <canvas ref={canvasRef} className=\"cpk:block cpk:w-full cpk:h-[26px]\" />\n </div>\n );\n});\n\nCopilotChatAudioRecorder.displayName = \"CopilotChatAudioRecorder\";\n","import React from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { shallowEqual, useShallowStableRef } from \"./shallow-stable-ref\";\n\n// Reference-stability helpers moved to ./shallow-stable-ref (a tailwind-free leaf\n// module) so the lean @copilotkit/react-core/v2/headless entry can reach them\n// without pulling tailwind-merge (issue #4893). Re-exported here to preserve this\n// module's public surface for existing importers (e.g. CopilotChat).\nexport { shallowEqual, useShallowStableRef };\n\n/** Existing union (unchanged) */\nexport type SlotValue<C extends React.ComponentType<any>> =\n | C\n | string\n | Partial<React.ComponentProps<C>>;\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 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 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:@3xl: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, { 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\";\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 // No per-tool or wildcard renderer registered → render nothing.\n // Showing an unhandled tool call is opt-in: register a named/wildcard\n // renderer via useRenderTool, or call useDefaultRenderTool() for the\n // built-in card. Auto-painting a default card here would leak internal\n // tool names plus raw args/result JSON into every app's chat in\n // production, so the card must be explicitly enabled.\n if (!renderConfig) {\n return null;\n }\n\n const RenderComponent =\n renderConfig.render 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","import * as React from \"react\";\nimport { createComponent } from \"@lit-labs/react\";\nimport type { CopilotKitCore } from \"@copilotkit/core\";\nimport type { Anchor, WebInspectorElement } from \"@copilotkit/web-inspector\";\nimport type { CopilotKitInspectorOpenRequest } from \"./CopilotKitInspectorContext\";\n\ntype CopilotKitInspectorBaseProps = {\n core?: CopilotKitCore | null;\n defaultAnchor?: Anchor;\n openRequest?: CopilotKitInspectorOpenRequest | null;\n [key: string]: unknown;\n};\n\ntype InspectorComponent = React.ComponentType<\n CopilotKitInspectorBaseProps & React.RefAttributes<WebInspectorElement>\n>;\n\nexport interface CopilotKitInspectorProps extends CopilotKitInspectorBaseProps {}\n\nexport const CopilotKitInspector: React.FC<CopilotKitInspectorProps> = ({\n core,\n openRequest,\n ...rest\n}) => {\n const [InspectorComponent, setInspectorComponent] =\n React.useState<InspectorComponent | null>(null);\n const inspectorRef = React.useRef<WebInspectorElement | 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 React.useEffect(() => {\n if (openRequest) {\n inspectorRef.current?.openInspector(\"message_toolbar\", openRequest);\n }\n }, [InspectorComponent, openRequest]);\n\n // During SSR (and until the client finishes loading), render nothing to keep markup consistent.\n if (!InspectorComponent) return null;\n\n return (\n <InspectorComponent ref={inspectorRef} {...rest} core={core ?? null} />\n );\n};\n\nCopilotKitInspector.displayName = \"CopilotKitInspector\";\n","\"use client\";\n\nimport * as React from \"react\";\n\nexport type CopilotKitInspectorOpenRequest = {\n messageId: string;\n threadId?: string;\n agentId?: string;\n};\n\ntype CopilotKitInspectorContextValue = {\n isLocalInspectorEnabled: boolean;\n openInspector: (request: CopilotKitInspectorOpenRequest) => void;\n};\n\nconst CopilotKitInspectorContext =\n React.createContext<CopilotKitInspectorContextValue>({\n isLocalInspectorEnabled: false,\n openInspector: () => undefined,\n });\n\nexport const CopilotKitInspectorContextProvider =\n CopilotKitInspectorContext.Provider;\n\nexport function useCopilotKitInspector(): CopilotKitInspectorContextValue {\n return React.useContext(CopilotKitInspectorContext);\n}\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://dashboard.operations.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/**\n * The subset of `CopilotKitCore` that {@link ɵrunMcpFollowUp} depends on.\n * Declared structurally so the runner can be unit-tested without a full core.\n */\nexport interface ɵMcpFollowUpHost {\n runAgent(params: { agent: AbstractAgent }): Promise<RunAgentResult>;\n}\n\n/**\n * Run an MCP app `ui/message` follow-up, scoped to the thread it was enqueued\n * for (issue #5819).\n *\n * The MCP request queue delays follow-up work until the agent is idle. There is\n * a single shared registry agent per id, and switching threads overwrites its\n * `threadId`/`messages` in place. So if the host switches threads while a\n * follow-up is queued, running it now would execute against — and stream into —\n * the now-foreground thread.\n *\n * - **Same thread** (the common case): run on the shared agent, unchanged.\n * - **Thread changed**: the shared agent has moved on, so the follow-up can no\n * longer run in its originating thread's context. Drop it rather than leak it\n * into the current thread. (The MCP app already received its `ui/message` ack\n * at enqueue time; only the optional agent turn is skipped.)\n *\n * @internal exported for testing.\n */\nexport async function ɵrunMcpFollowUp({\n host,\n agent,\n capturedThreadId,\n}: {\n host: ɵMcpFollowUpHost;\n agent: AbstractAgent;\n capturedThreadId: string;\n}): Promise<RunAgentResult> {\n const currentThreadId = agent.threadId || \"default\";\n const originThreadId = capturedThreadId || \"default\";\n\n if (currentThreadId === originThreadId) {\n return host.runAgent({ agent });\n }\n\n console.warn(\n \"[MCPAppsRenderer] ui/message follow-up dropped: the thread changed \" +\n `(${originThreadId} → ${currentThreadId}) between enqueue and execution, ` +\n \"so running it would leak into the now-foreground thread.\",\n );\n return { result: undefined, newMessages: [] };\n}\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 // Cross-frontend MCP-apps surface contract: the host-created sandbox\n // iframe is the addressable render surface for the MCP app, and every\n // frontend must expose it under the SAME testid so one shared probe\n // (harness `d5-mcp-apps`) and one shared e2e spec can assert the\n // surface mounted without per-frontend selectors. Angular declares\n // the same pair on its `copilot-mcp-apps-widget` template iframe;\n // Vue's renderer mirrors this block.\n iframe.setAttribute(\"data-testid\", \"mcp-app-iframe\");\n iframe.setAttribute(\"title\", \"Interactive MCP application\");\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 // Capture the thread this work is enqueued for NOW. The\n // queue delays it until the agent is idle; if the host\n // switches threads meanwhile, the shared agent's threadId\n // is overwritten. ɵrunMcpFollowUp compares against the\n // capture so a stale follow-up is dropped rather than run\n // against the now-foreground thread (issue #5819).\n const capturedThreadId =\n currentAgent.threadId || \"default\";\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 ɵrunMcpFollowUp({\n host: copilotkit,\n agent: currentAgent,\n capturedThreadId,\n }),\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} from \"./A2UIRecoveryStates\";\nimport type { A2UIRecoveryRendererOptions } 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\n/**\n * Intercept an A2UI user action before it reaches the agent.\n *\n * Called with the dispatched action and a `forward` helper that runs the agent\n * with the (optionally modified) action. The return value drives the default\n * forwarding:\n * - return `null` → the app handled it client-side (e.g. a `navigate` event);\n * the action is NOT forwarded to the agent.\n * - return an `A2UIUserAction` → that (possibly modified) action is forwarded.\n * - return `undefined` / `void` → the original action is forwarded unchanged.\n *\n * `forward` is provided for advanced cases where you want to do async work and\n * forward manually; if you call it yourself, return `null` to suppress the\n * default forward and avoid running the agent twice.\n */\nexport type A2UIActionInterceptor = (\n action: A2UIUserAction,\n forward: (action?: A2UIUserAction) => Promise<void>,\n) => void | A2UIUserAction | null | Promise<void | A2UIUserAction | null>;\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 * Intercept actions before they reach the agent. Lets an app handle an action\n * client-side (e.g. `navigate`) instead of forwarding every action. See\n * {@link A2UIActionInterceptor}.\n */\n onAction?: A2UIActionInterceptor;\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, onAction } = 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 onAction={onAction}\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 /** Optional interceptor run before an action is forwarded to the agent. */\n onAction?: A2UIActionInterceptor;\n /** Fired once the surface has processed its first operations (painted). */\n onReady?: () => void;\n};\n\n/**\n * Orchestrates a single A2UI user action: runs the optional `onAction`\n * interceptor first, then forwards to the agent unless the interceptor\n * suppressed it (returned `null`). Exported for unit testing; the wiring lives\n * in {@link ReactSurfaceHost}.\n */\nexport async function runA2UIAction({\n message,\n agent,\n copilotkit,\n onAction,\n}: {\n message: A2UIClientEventMessage;\n agent: any;\n copilotkit: any;\n onAction?: A2UIActionInterceptor;\n}): Promise<void> {\n if (!agent) return;\n\n const action = message.userAction as A2UIUserAction | undefined;\n\n // Forward to the agent, swapping in the (possibly modified) userAction while\n // preserving the rest of the original client-event envelope. Always restores\n // the prior properties afterwards so `a2uiAction` does not leak into later\n // runs. Called with no argument → the original message is forwarded as-is.\n const forward = async (forwardAction?: A2UIUserAction) => {\n const a2uiAction =\n forwardAction !== undefined\n ? { ...message, userAction: forwardAction }\n : message;\n try {\n copilotkit.setProperties({\n ...copilotkit.properties,\n a2uiAction,\n });\n\n await copilotkit.runAgent({ agent });\n } finally {\n if (copilotkit.properties) {\n const { a2uiAction: _omit, ...rest } = copilotkit.properties;\n copilotkit.setProperties(rest);\n }\n }\n };\n\n if (onAction && action) {\n const result = await onAction(action, forward);\n // null → the app handled it client-side; do NOT forward to the agent.\n if (result === null) return;\n // a returned action → forward the (possibly modified) action.\n if (result) {\n await forward(result);\n return;\n }\n // void/undefined falls through → forward unchanged (default preserved).\n }\n\n await forward();\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 onAction,\n onReady,\n}: ReactSurfaceHostProps) {\n // Bridge: when the React renderer dispatches an action, forward to CopilotKit\n const handleAction = useCallback(\n (message: A2UIClientEventMessage) =>\n runA2UIAction({ message, agent, copilotkit, onAction }),\n [agent, copilotkit, onAction],\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 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 { 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","\"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 { 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 * The entries are scoped to the agents the runtime applies A2UI to\n * (`copilotkit.a2uiAgents`, #5369), so agents outside that list don't receive\n * the catalog/schema/guidelines payload on their runs.\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 { copilotkit } = useCopilotKit();\n\n const capabilitiesValue = useMemo(\n () => buildCatalogContextValue(catalog),\n [catalog],\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 schemaValue = useMemo(\n () =>\n includeSchema !== false\n ? JSON.stringify(extractCatalogComponentSchemas(catalog))\n : null,\n [catalog, includeSchema],\n );\n\n // The agents list is read fresh inside the effect; this key only exists to\n // re-register the entries if the runtime's scoping changes on a reconnect.\n const a2uiAgentsKey = copilotkit?.a2uiAgents?.join(\",\");\n\n useLayoutEffect(() => {\n if (!copilotkit) return;\n const agentIds = copilotkit.a2uiAgents;\n const scope = agentIds ? { agentIds } : {};\n const ids: string[] = [];\n ids.push(\n copilotkit.addContext({\n description:\n \"A2UI catalog capabilities: available catalog IDs and custom component definitions the client can render.\",\n value: capabilitiesValue,\n ...scope,\n }),\n );\n if (schemaValue) {\n ids.push(\n copilotkit.addContext({\n description: A2UI_SCHEMA_CONTEXT_DESCRIPTION,\n value: schemaValue,\n ...scope,\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 ...scope,\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 ...scope,\n }),\n );\n }\n return () => {\n for (const id of ids) copilotkit.removeContext(id);\n };\n }, [copilotkit, capabilitiesValue, schemaValue, a2uiAgentsKey]);\n\n return null;\n}\n","import React from \"react\";\nimport { ReactActivityMessageRenderer, ReactToolCallRenderer } from \"../types\";\nimport { ReactCustomMessageRenderer } from \"../types/react-custom-message-renderer\";\nimport {\n CopilotKitCore,\n type CopilotKitCoreConfig,\n type CopilotKitCoreSubscriber,\n type CopilotKitCoreSubscription,\n} from \"@copilotkit/core\";\n\nexport interface CopilotKitCoreReactConfig extends CopilotKitCoreConfig {\n // Add any additional configuration properties specific to the React implementation\n renderToolCalls?: ReactToolCallRenderer<any>[];\n renderActivityMessages?: ReactActivityMessageRenderer<any>[];\n\n // Add custom message renderers\n renderCustomMessages?: ReactCustomMessageRenderer[];\n}\n\nexport interface CopilotKitCoreReactSubscriber extends CopilotKitCoreSubscriber {\n onRenderToolCallsChanged?: (event: {\n copilotkit: CopilotKitCore;\n renderToolCalls: ReactToolCallRenderer<any>[];\n }) => void | Promise<void>;\n onInterruptElementChanged?: (event: {\n copilotkit: CopilotKitCore;\n interruptElement: React.ReactElement | null;\n }) => void | Promise<void>;\n}\n\nexport class CopilotKitCoreReact extends CopilotKitCore {\n private _renderToolCalls: ReactToolCallRenderer<any>[] = [];\n private _hookRenderToolCalls: Map<string, ReactToolCallRenderer<any>> =\n new Map();\n private _cachedMergedRenderToolCalls: ReactToolCallRenderer<any>[] | null =\n null;\n private _renderCustomMessages: ReactCustomMessageRenderer[] = [];\n private _renderActivityMessages: ReactActivityMessageRenderer<any>[] = [];\n private _interruptElement: React.ReactElement | null = null;\n\n constructor(config: CopilotKitCoreReactConfig) {\n super(config);\n this._renderToolCalls = config.renderToolCalls ?? [];\n this._renderCustomMessages = config.renderCustomMessages ?? [];\n this._renderActivityMessages = config.renderActivityMessages ?? [];\n }\n\n get renderCustomMessages(): Readonly<ReactCustomMessageRenderer[]> {\n return this._renderCustomMessages;\n }\n\n get renderActivityMessages(): Readonly<ReactActivityMessageRenderer<any>>[] {\n return this._renderActivityMessages;\n }\n\n get renderToolCalls(): Readonly<ReactToolCallRenderer<any>>[] {\n if (this._hookRenderToolCalls.size === 0) {\n return this._renderToolCalls;\n }\n if (this._cachedMergedRenderToolCalls) {\n return this._cachedMergedRenderToolCalls;\n }\n // Merge: hook entries override prop entries with the same key\n const merged = new Map<string, ReactToolCallRenderer<any>>();\n for (const rc of this._renderToolCalls) {\n merged.set(`${rc.agentId ?? \"\"}:${rc.name}`, rc);\n }\n for (const [key, rc] of this._hookRenderToolCalls) {\n merged.set(key, rc);\n }\n this._cachedMergedRenderToolCalls = Array.from(merged.values());\n return this._cachedMergedRenderToolCalls;\n }\n\n setRenderActivityMessages(\n renderers: ReactActivityMessageRenderer<any>[],\n ): void {\n this._renderActivityMessages = renderers;\n }\n\n setRenderCustomMessages(renderers: ReactCustomMessageRenderer[]): void {\n this._renderCustomMessages = renderers;\n }\n\n setRenderToolCalls(renderToolCalls: ReactToolCallRenderer<any>[]): void {\n this._renderToolCalls = renderToolCalls;\n this._cachedMergedRenderToolCalls = null;\n this._notifyRenderToolCallsChanged();\n }\n\n addHookRenderToolCall(entry: ReactToolCallRenderer<any>): void {\n const key = `${entry.agentId ?? \"\"}:${entry.name}`;\n this._hookRenderToolCalls.set(key, entry);\n this._cachedMergedRenderToolCalls = null;\n this._notifyRenderToolCallsChanged();\n }\n\n removeHookRenderToolCall(name: string, agentId?: string): void {\n const key = `${agentId ?? \"\"}:${name}`;\n if (this._hookRenderToolCalls.delete(key)) {\n this._cachedMergedRenderToolCalls = null;\n this._notifyRenderToolCallsChanged();\n }\n }\n\n private _notifyRenderToolCallsChanged(): void {\n void this.notifySubscribers((subscriber) => {\n const reactSubscriber = subscriber as CopilotKitCoreReactSubscriber;\n if (reactSubscriber.onRenderToolCallsChanged) {\n reactSubscriber.onRenderToolCallsChanged({\n copilotkit: this,\n renderToolCalls: this.renderToolCalls,\n });\n }\n }, \"Subscriber onRenderToolCallsChanged error:\");\n }\n\n get interruptElement(): React.ReactElement | null {\n return this._interruptElement;\n }\n\n setInterruptElement(element: React.ReactElement | null): void {\n this._interruptElement = element;\n void this.notifySubscribers((subscriber) => {\n const reactSubscriber = subscriber as CopilotKitCoreReactSubscriber;\n reactSubscriber.onInterruptElementChanged?.({\n copilotkit: this,\n interruptElement: this._interruptElement,\n });\n }, \"Subscriber onInterruptElementChanged error:\");\n }\n\n // Override to accept React-specific subscriber type\n subscribe(\n subscriber: CopilotKitCoreReactSubscriber,\n ): CopilotKitCoreSubscription {\n return super.subscribe(subscriber);\n }\n\n /**\n * Wait for pending React state updates before the follow-up agent run.\n *\n * When a frontend tool handler calls setState(), React 18 batches the update\n * and schedules a commit via its internal scheduler (MessageChannel). The\n * useAgentContext hook registers context via useLayoutEffect, which runs\n * synchronously after React commits that batch.\n *\n * Awaiting a zero-delay timeout yields to the macrotask queue. React's\n * MessageChannel task runs first, committing the pending state and running\n * useLayoutEffect (which updates the context store). The follow-up runAgent\n * call then reads fresh context.\n */\n async waitForPendingFrameworkUpdates(): Promise<void> {\n await new Promise<void>((resolve) => setTimeout(resolve, 0));\n }\n}\n","\"use client\";\n\nimport type { AbstractAgent } from \"@ag-ui/client\";\nimport type { FrontendTool } from \"@copilotkit/core\";\nimport type React from \"react\";\nimport {\n useMemo,\n useCallback,\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 { CopilotKitInspectorContextProvider } from \"../components/CopilotKitInspectorContext\";\nimport type { CopilotKitInspectorOpenRequest } from \"../components/CopilotKitInspectorContext\";\nimport type { Anchor } from \"@copilotkit/web-inspector\";\nimport { LicenseWarningBanner } from \"../components/license-warning-banner\";\nimport { createLicenseContextValue } from \"@copilotkit/shared\";\nimport type {\n LicenseContextValue,\n DebugConfig,\n RuntimeLicenseStatus,\n} from \"@copilotkit/shared\";\nimport type { CopilotKitCoreErrorCode } from \"@copilotkit/core\";\nimport {\n MCPAppsActivityContentSchema,\n MCPAppsActivityRenderer,\n MCPAppsActivityType,\n} from \"../components/MCPAppsActivityRenderer\";\nimport {\n OpenGenerativeUIActivityType,\n OpenGenerativeUIContentSchema,\n OpenGenerativeUIActivityRenderer,\n OpenGenerativeUIToolRenderer,\n GenerateSandboxedUiArgsSchema,\n} from \"../components/OpenGenerativeUIRenderer\";\nimport { createA2UIMessageRenderer } from \"../a2ui/A2UIMessageRenderer\";\nimport type { A2UIRecoveryRendererOptions } from \"../a2ui/A2UIRecoveryStates\";\nimport { A2UIBuiltInToolCallRenderer } from \"../a2ui/A2UIToolCallRenderer\";\nimport { A2UICatalogContext } from \"../a2ui/A2UICatalogContext\";\nimport { viewerTheme, filterCatalog, Catalog } 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\n// Adapts zod-to-json-schema's zod-specific signature to the injectable\n// `zodToJsonSchema` contract of `schemaToJsonSchema`, which only invokes it\n// for schemas whose `~standard.vendor` is \"zod\".\nconst zodToJsonSchemaAdapter = (\n schema: unknown,\n options?: { $refStrategy?: string },\n): Record<string, unknown> => {\n const refStrategy = options?.$refStrategy;\n return zodToJsonSchema(\n schema as z.ZodType,\n refStrategy === \"root\" ||\n refStrategy === \"relative\" ||\n refStrategy === \"none\" ||\n refStrategy === \"seen\"\n ? { $refStrategy: refStrategy }\n : {},\n );\n};\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 /** Your CopilotKit public license key. */\n publicApiKey?: string;\n /** Your public license key for accessing Enterprise Intelligence Platform features. */\n publicLicenseKey?: string;\n /**\n * Signed license token for offline verification of Enterprise Intelligence Platform features.\n * Obtain from https://dashboard.operations.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 [isLocalInspectorEnabled, setIsLocalInspectorEnabled] = useState(false);\n const [inspectorOpenRequest, setInspectorOpenRequest] =\n useState<CopilotKitInspectorOpenRequest | null>(null);\n const [runtimeA2UIEnabled, setRuntimeA2UIEnabled] = useState(false);\n const [runtimeOpenGenUIEnabled, setRuntimeOpenGenUIEnabled] = useState(false);\n // Bumped by onCatalogComponentsChanged so the filtered catalog re-derives\n // when a component is enabled/disabled after mount.\n const [catalogToggleVersion, setCatalogToggleVersion] = useState(0);\n const openGenUIActive = runtimeOpenGenUIEnabled || !!openGenerativeUI;\n // A catalog passed to the provider is enough to turn A2UI on: render the\n // surfaces locally and forward the catalog signal so the runtime injects the\n // render tool — no runtime-side `a2ui` config required.\n const a2uiCatalogProvided = !!a2ui?.catalog;\n const a2uiActive = runtimeA2UIEnabled || a2uiCatalogProvided;\n const [runtimeLicenseStatus, setRuntimeLicenseStatus] = useState<\n RuntimeLicenseStatus | undefined\n >(undefined);\n\n useEffect(() => {\n if (typeof window === \"undefined\") {\n return;\n }\n\n const localhostHosts = new Set([\"localhost\", \"127.0.0.1\"]);\n const isLocalhost = localhostHosts.has(window.location?.hostname ?? \"\");\n const canShowLocalInspectorAction =\n process.env.NODE_ENV === \"development\" && isLocalhost;\n\n if (showDevConsole === true) {\n // Explicitly show the inspector\n setShouldRenderInspector(true);\n setIsLocalInspectorEnabled(canShowLocalInspectorAction);\n } else if (showDevConsole === \"auto\") {\n // Show on localhost or 127.0.0.1 only\n if (isLocalhost) {\n setShouldRenderInspector(true);\n setIsLocalInspectorEnabled(canShowLocalInspectorAction);\n } else {\n setShouldRenderInspector(false);\n setIsLocalInspectorEnabled(false);\n }\n } else {\n // showDevConsole is false or undefined (default false)\n setShouldRenderInspector(false);\n setIsLocalInspectorEnabled(false);\n }\n }, [showDevConsole]);\n\n const requestInspectorOpen = useCallback(\n (request: CopilotKitInspectorOpenRequest) => {\n setInspectorOpenRequest({ ...request });\n },\n [],\n );\n\n const inspectorContextValue = useMemo(\n () => ({\n isLocalInspectorEnabled,\n openInspector: requestInspectorOpen,\n }),\n [isLocalInspectorEnabled, requestInspectorOpen],\n );\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 // Stable core instance ref, declared here (before the activity-renderer memo)\n // so the filtered-catalog memo can read enablement off the current instance.\n // The instance itself is created in the ref-init block below; on the very\n // first render `current` is still null (nothing is disabled yet), so the\n // filtered catalog correctly equals the full catalog.\n const copilotkitRef = useRef<CopilotKitCoreReact | null>(null);\n\n // Raw catalog provided by the caller (typed loosely to match `a2ui.catalog?: any`).\n const rawCatalog = a2ui?.catalog as Catalog<any> | undefined;\n\n // Derive the FILTERED catalog: only components currently enabled on core.\n // Re-derives when enablement changes (catalogToggleVersion bump from the\n // onCatalogComponentsChanged subscription below). Passed to BOTH the render\n // path (createA2UIMessageRenderer) and the advertisement path (A2UICatalogContext)\n // so a disabled component vanishes from what the model sees AND what can paint.\n const filteredCatalog = useMemo(() => {\n if (!rawCatalog) return rawCatalog;\n // `filterCatalog` rebuilds a real `Catalog` (reads `.functions`). Callers may\n // also pass a minimal catalog-shaped object; only filter genuine instances.\n if (!(rawCatalog instanceof Catalog)) return rawCatalog;\n const core = copilotkitRef.current;\n return filterCatalog(rawCatalog, (name) =>\n core ? core.isCatalogComponentEnabled(name) : true,\n );\n // catalogToggleVersion forces re-derivation when enablement changes.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [rawCatalog, catalogToggleVersion]);\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 (a2uiActive) {\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: filteredCatalog,\n loadingComponent: a2ui?.loadingComponent,\n recovery: a2ui?.recovery,\n }),\n );\n }\n\n return renderers;\n }, [a2uiActive, openGenUIActive, a2ui, filteredCatalog]);\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 // `selfManagedAgents` is part of CopilotKit's Enterprise Intelligence offering.\n // The signal is advisory and client-side only (not enforced): warn — in both\n // development and production — when it is used without a license key so\n // production usage is surfaced. `agents__unsafe_dev_only` is the free local-dev\n // escape hatch and is intentionally NOT gated here.\n const hasSelfManagedAgents = Object.keys(selfManagedAgents).length > 0;\n useEffect(() => {\n if (hasSelfManagedAgents && !resolvedPublicKey) {\n console.warn(\n \"[CopilotKit] `selfManagedAgents` is part of CopilotKit's Enterprise \" +\n \"Intelligence offering. Provide a `publicLicenseKey` for production \" +\n \"use — contact the CopilotKit team about licensing.\",\n );\n }\n }, [hasSelfManagedAgents, resolvedPublicKey]);\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 as React.ComponentType<any>,\n ...(tool.agentId && { agentId: tool.agentId }),\n });\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 (ref declared above\n // so the filtered-catalog memo can read enablement off it).\n // Updates are applied via setter effects below rather than recreating the instance.\n if (copilotkitRef.current === null) {\n copilotkitRef.current = new CopilotKitCoreReact({\n runtimeUrl: chatApiEndpoint,\n // Defer the `/info` fetch out of construction. The core is constructed\n // during render, and React can start-and-discard renders (concurrent\n // rendering / Suspense / StrictMode) — a network request in the ctor\n // would fire once per discarded attempt (issue #5801). `connect()` below\n // starts the single request from a commit-phase effect.\n deferInitialConnection: true,\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 // Register the full A2UI catalog component list onto core so the inspector can\n // read `core.catalogComponents`, and re-derive the filtered catalog whenever\n // enablement changes. Descriptions are undefined here because the built\n // ComponentApi does not carry them (see plan A2 rationale).\n useEffect(() => {\n if (!rawCatalog) return;\n // Only register components for genuine `Catalog` instances, mirroring the\n // `filteredCatalog` guard above. A non-`Catalog` catalog-shaped object is\n // passed through UNFILTERED by `filteredCatalog`, so registering its\n // components here would make them toggleable in the inspector while\n // disabling never actually removes them from what the model sees — a silent\n // enforcement divergence. Guarding here keeps registration and filtering\n // consistent (nothing registered → nothing to toggle → nothing to filter)\n // and also avoids a mount-time throw when `.components` isn't a Map.\n if (!(rawCatalog instanceof Catalog)) return;\n const components = Array.from(rawCatalog.components.values()).map(\n (comp: { name: string; schema: unknown }) => ({\n name: comp.name,\n description: undefined as string | undefined,\n schema: comp.schema,\n }),\n );\n copilotkit.setCatalogComponents(components);\n const subscription = copilotkit.subscribe({\n onCatalogComponentsChanged: () => {\n setCatalogToggleVersion((v) => v + 1);\n },\n });\n return () => subscription.unsubscribe();\n }, [copilotkit, rawCatalog]);\n\n // Sync runtime feature flags from the core once runtime info is fetched.\n //\n // The core kicks off its `/info` fetch synchronously from its constructor\n // (during render), so `onRuntimeConnectionStatusChanged` can fire BEFORE this\n // passive effect runs and subscribes — especially on a cold first load\n // (incognito/hard refresh) where JS compile congestion delays the effect flush\n // past the `/info` resolution. If that happens, the settled values would be\n // lost forever. To close the race we read the CURRENT values immediately, so a\n // status that already resolved is captured whether or not we caught its event.\n // This MUST mirror the subscriber below (all three values), otherwise a missed\n // event leaves e.g. `licenseStatus` null indefinitely — which pins the threads\n // drawer to its \"Loading threads…\" state (licensePending never clears).\n useEffect(() => {\n const syncRuntimeInfo = () => {\n setRuntimeA2UIEnabled(copilotkit.a2uiEnabled);\n setRuntimeOpenGenUIEnabled(copilotkit.openGenerativeUIEnabled);\n setRuntimeLicenseStatus(copilotkit.licenseStatus);\n };\n const subscription = copilotkit.subscribe({\n onRuntimeConnectionStatusChanged: syncRuntimeInfo,\n });\n // Catch-up read after subscribing, so a status that settled between the\n // subscribe call and now is still reflected.\n syncRuntimeInfo();\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 // Forward a per-run signal when the provider has an A2UI catalog so the\n // runtime can turn A2UI on (and inject the render tool) without a separate\n // `a2ui.injectA2UITool` flag on the runtime.\n copilotkit.setProperties(\n a2uiCatalogProvided\n ? { ...properties, a2uiCatalogAvailable: true }\n : properties,\n );\n copilotkit.setAgents__unsafe_dev_only(mergedAgents);\n copilotkit.setDebug(debug);\n // Start the runtime `/info` connection now that we're in the commit phase.\n // The ctor deferred it (see `deferInitialConnection` above) so discarded\n // renders never fetch; `connect()` is idempotent, so StrictMode's\n // double-invoked effect and re-runs on unrelated prop changes collapse to a\n // single request (a real runtimeUrl/transport change reconnects via the\n // setters above). See #5801.\n copilotkit.connect();\n }, [\n copilotkit,\n chatApiEndpoint,\n mergedHeaders,\n credentials,\n properties,\n a2uiCatalogProvided,\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, {\n zodToJsonSchema: zodToJsonSchemaAdapter,\n }),\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(runtimeLicenseStatus),\n [runtimeLicenseStatus],\n );\n\n return (\n <SandboxFunctionsContext.Provider value={sandboxFunctionsList}>\n <CopilotKitContext.Provider value={contextValue}>\n <LicenseContext.Provider value={licenseContextValue}>\n {a2uiActive && <A2UIBuiltInToolCallRenderer />}\n {a2uiActive && (\n <A2UICatalogContext\n catalog={filteredCatalog}\n includeSchema={a2ui?.includeSchema}\n />\n )}\n <CopilotKitInspectorContextProvider value={inspectorContextValue}>\n {children}\n {shouldRenderInspector ? (\n <CopilotKitInspector\n core={copilotkit}\n defaultAnchor={inspectorDefaultAnchor}\n openRequest={inspectorOpenRequest}\n />\n ) : null}\n </CopilotKitInspectorContextProvider>\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 type { ActivityMessage } from \"@ag-ui/core\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkit/shared\";\nimport { useCopilotKit, useCopilotChatConfiguration } from \"../providers\";\nimport { useCallback, useMemo } from \"react\";\nimport type { 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[\"~standard\"].validate(\n message.content,\n );\n\n if (parseResult instanceof Promise) {\n console.warn(\n `Async content validation is not supported for activity message '${message.activityType}'`,\n );\n return null;\n }\n\n if (parseResult.issues) {\n console.warn(\n `Failed to parse content for activity message '${message.activityType}':`,\n parseResult.issues,\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.value}\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<any, Record<string, unknown>> | undefined =\n 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 { useEffect } from \"react\";\nimport type { StandardSchemaV1, InferSchemaOutput } from \"@copilotkit/shared\";\nimport { ToolCallStatus } from \"@copilotkit/core\";\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 // Branch per status so the discriminated union stays correlated\n // when `args` is re-exposed as `parameters`.\n render: (props) => {\n if (props.status === ToolCallStatus.InProgress) {\n return config.render({ ...props, parameters: props.args });\n }\n if (props.status === ToolCallStatus.Executing) {\n return config.render({ ...props, parameters: props.args });\n }\n return config.render({ ...props, parameters: props.args });\n },\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 dotClassName = isActive\n ? \"cpk:bg-amber-500\"\n : isComplete\n ? \"cpk:bg-emerald-500\"\n : \"cpk:bg-zinc-400\";\n const badgeClassName = 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\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 className=\"cpk:mt-2 cpk:pb-2\"\n >\n <div className=\"cpk:rounded-xl cpk:border cpk:border-zinc-200/60 cpk:bg-white/70 cpk:p-4 cpk:shadow-sm cpk:backdrop-blur cpk:dark:border-zinc-800/60 cpk:dark:bg-zinc-900/50\">\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 className=\"cpk:flex cpk:w-full cpk:cursor-pointer cpk:select-none cpk:items-center cpk:justify-between cpk:gap-2.5 cpk:border-none cpk:bg-transparent cpk:p-0 cpk:m-0 cpk:text-left cpk:text-inherit\"\n style={{\n font: \"inherit\",\n }}\n >\n <div className=\"cpk:flex cpk:min-w-0 cpk:items-center cpk:gap-2\">\n <svg\n className={`cpk:h-3.5 cpk:w-3.5 cpk:flex-shrink-0 cpk:text-zinc-500 cpk:transition-transform cpk:dark:text-zinc-400 ${\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\n className={`cpk:inline-block cpk:h-2 cpk:w-2 cpk:flex-shrink-0 cpk:rounded-full ${dotClassName}`}\n />\n <span\n data-testid=\"copilot-tool-render-name\"\n className=\"cpk:truncate cpk:text-[13px] cpk:font-semibold cpk:text-zinc-900 cpk:dark:text-zinc-100\"\n >\n {name}\n </span>\n </div>\n\n <span\n data-testid=\"copilot-tool-render-status\"\n className={`cpk:inline-flex cpk:flex-shrink-0 cpk:items-center cpk:rounded-full cpk:px-2 cpk:py-0.5 cpk:text-[11px] cpk:font-medium ${badgeClassName}`}\n >\n {statusLabel}\n </span>\n </button>\n\n {/* Expandable details */}\n {isExpanded && (\n <div className=\"cpk:mt-3 cpk:grid cpk:gap-3\">\n <div>\n <div className=\"cpk:text-[10px] cpk:uppercase cpk:text-zinc-500 cpk:dark:text-zinc-400\">\n Arguments\n </div>\n <pre className=\"cpk:mt-1.5 cpk:max-h-[200px] cpk:overflow-auto cpk:rounded-md cpk:bg-zinc-100 cpk:p-2.5 cpk:text-[11px] cpk:leading-relaxed cpk:text-zinc-800 cpk:whitespace-pre-wrap cpk:break-words cpk:dark:bg-zinc-800/60 cpk:dark:text-zinc-200\">\n {safeStringifyForPre(parameters ?? {})}\n </pre>\n </div>\n\n {result !== undefined && (\n <div>\n <div className=\"cpk:text-[10px] cpk:uppercase cpk:text-zinc-500 cpk:dark:text-zinc-400\">\n Result\n </div>\n <pre className=\"cpk:mt-1.5 cpk:max-h-[200px] cpk:overflow-auto cpk:rounded-md cpk:bg-zinc-100 cpk:p-2.5 cpk:text-[11px] cpk:leading-relaxed cpk:text-zinc-800 cpk:whitespace-pre-wrap cpk:break-words cpk:dark:bg-zinc-800/60 cpk:dark:text-zinc-200\">\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 { 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 { ToolCallStatus } from \"@copilotkit/core\";\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 // Cleanup that detaches the pending abort listener; cleared whenever the\n // promise settles (via respond() or abort) so the listener can't fire twice\n // or leak after the interaction is done.\n const cleanupAbortRef = useRef<(() => void) | null>(null);\n\n const respond = useCallback(async (result: unknown) => {\n if (resolvePromiseRef.current) {\n cleanupAbortRef.current?.();\n cleanupAbortRef.current = null;\n resolvePromiseRef.current(result);\n resolvePromiseRef.current = null;\n }\n }, []);\n\n const handler = useCallback(\n async (_args: T, context?: { signal?: AbortSignal }) => {\n const signal = context?.signal;\n return new Promise((resolve, reject) => {\n // If the run was already aborted before the handler ran, reject\n // immediately so core records an explicit error tool result instead of\n // silently resolving to an empty string.\n if (signal?.aborted) {\n reject(new Error(\"Human-in-the-loop interaction aborted\"));\n return;\n }\n\n resolvePromiseRef.current = resolve;\n\n if (signal) {\n const onAbort = () => {\n cleanupAbortRef.current = null;\n resolvePromiseRef.current = null;\n reject(new Error(\"Human-in-the-loop interaction aborted\"));\n };\n signal.addEventListener(\"abort\", onAbort, { once: true });\n cleanupAbortRef.current = () => {\n signal.removeEventListener(\"abort\", onAbort);\n };\n }\n });\n },\n [],\n );\n\n const RenderComponent: ReactToolCallRenderer<T>[\"render\"] = useCallback(\n (props) => {\n const ToolComponent = tool.render;\n\n // Build the HITL render props per status. `props` already carries\n // `toolCallId`; we overwrite `name`/`description` with the tool's\n // registration values and add the registration `agentId`, so the HITL\n // render always receives the full prop contract. `respond` is only live\n // while the tool is executing.\n if (props.status === ToolCallStatus.InProgress) {\n const enhancedProps = {\n ...props,\n name: tool.name,\n description: tool.description || \"\",\n agentId: tool.agentId,\n respond: undefined,\n };\n return React.createElement(ToolComponent, enhancedProps);\n } else if (props.status === ToolCallStatus.Executing) {\n const enhancedProps = {\n ...props,\n name: tool.name,\n description: tool.description || \"\",\n agentId: tool.agentId,\n respond,\n };\n return React.createElement(ToolComponent, enhancedProps);\n } else if (props.status === ToolCallStatus.Complete) {\n const enhancedProps = {\n ...props,\n name: tool.name,\n description: tool.description || \"\",\n agentId: tool.agentId,\n respond: undefined,\n };\n return React.createElement(ToolComponent, enhancedProps);\n }\n\n // ToolCallStatus has only the three states handled above, so this point\n // is unreachable and `props` narrows to `never`. The assignment turns a\n // newly-added status into a compile error here — forcing it to get its\n // own branch above — instead of silently rendering without `respond`.\n const exhaustiveCheck: never = props;\n return exhaustiveCheck;\n },\n [tool.render, tool.name, tool.description, tool.agentId, 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, useState } 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\ninterface UseAgentPropsBase {\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\n/**\n * Thread-scoped variant. `agentId`, `runtimeAgentId`, and `threadId` are a\n * matched set: together they give this hook a *private* agent — registered\n * under the local `agentId`, routing outbound to `runtimeAgentId` — that is\n * safe to pin a thread onto. None of the three is meaningful without the other\n * two, so all are required here.\n */\ninterface UseAgentThreadScopedProps {\n /**\n * The name to register this hook's proxied agent under.\n *\n * Required, and must not already be taken. The usual fallbacks (the chat\n * configuration's agentId, then `DEFAULT_AGENT_ID`) name agents that already\n * exist, and registering over one either throws `already registered` or\n * silently shadows it, depending on whether runtime discovery has landed — so\n * the caller has to name it.\n */\n agentId: string;\n /**\n * Thread to scope the agent's run to. Written onto the underlying agent, so\n * `/agent/run`, `/agent/connect`, and `/agent/stop` address this thread.\n *\n * REQUIRES `runtimeAgentId`. A runtime agent registered under a given id is a\n * singleton, so writing a per-hook threadId directly onto it would let two\n * `useAgent` calls that share an `agentId` clobber each other's thread.\n * Passing a distinct local `agentId` plus the `runtimeAgentId` it routes to\n * gives this hook a private proxied agent to pin the thread onto instead of a\n * shared one.\n */\n threadId: string;\n /**\n * The id of the runtime agent to route outbound requests to, while this hook\n * exposes a distinct local `agentId`. Registers a proxied agent via\n * `CopilotKitCore.registerProxiedAgent`, letting several frontend agents\n * (e.g. one per open thread) mount against a single runtime agent without a\n * shared-singleton collision.\n *\n * When set, `agentId` is the *local* registry id (must not collide with an\n * existing local or runtime-discovered agent) and `runtimeAgentId` is the\n * runtime agent the proxy addresses on `/agent/run` etc.\n *\n * REQUIRES `threadId`. Registering a private agent is only worth doing to\n * scope a thread to it; without a `threadId` the private agent would take its\n * thread from the chat configuration, which is what binding to the shared\n * agent via `agentId` alone already does — just with an extra registration\n * and a local id to keep unique.\n */\n runtimeAgentId: string;\n}\n\n/**\n * Default variant: neither `threadId` nor `runtimeAgentId`. The hook binds to\n * the shared agent registered under `agentId` and leaves its threadId to the\n * chat configuration (or to the agent's own auto-minted UUID).\n *\n * Both props are typed `undefined` here rather than omitted so that supplying\n * either one on its own fails to match *both* branches — that is the\n * type-level enforcement of the all-or-nothing rule.\n */\ninterface UseAgentUnscopedProps {\n /**\n * Agent to bind to. Resolution precedence: this property, then the surrounding\n * chat configuration's agentId, then the global default.\n */\n agentId?: string;\n /** Requires `runtimeAgentId`. See {@link UseAgentThreadScopedProps.threadId}. */\n threadId?: undefined;\n /** Requires `threadId`. See {@link UseAgentThreadScopedProps.runtimeAgentId}. */\n runtimeAgentId?: undefined;\n}\n\n/**\n * Props for {@link useAgent}.\n *\n * There are exactly two valid shapes, and the type admits nothing in between:\n *\n * - **Bind to an agent** — `useAgent()`, `useAgent({ agentId })`. The shared\n * instance from the registry; the thread comes from the chat configuration.\n * - **Bind a private agent to a thread** —\n * `useAgent({ agentId, runtimeAgentId, threadId })`. All three required.\n *\n * So `useAgent({ agentId, threadId })`, `useAgent({ agentId, runtimeAgentId })`,\n * and `useAgent({ runtimeAgentId, threadId })` are all compile errors. Each\n * partial combination is either unsafe (a thread scoped onto a shared singleton)\n * or pointless (a private agent with no thread, or one registered over an id\n * that already belongs to a real agent).\n */\nexport type UseAgentProps = UseAgentPropsBase &\n (UseAgentThreadScopedProps | UseAgentUnscopedProps);\n\nexport function useAgent({\n agentId,\n threadId,\n runtimeAgentId,\n updates,\n throttleMs,\n}: UseAgentProps = {}) {\n // `threadId` and `runtimeAgentId` are all-or-nothing. UseAgentProps already\n // rejects a lone one at compile time; these are the runtime backstop for\n // callers TypeScript doesn't cover — plain JS, `as any`, and props widened to\n // `string | undefined` at a call boundary. Fail loud rather than silently\n // mutating shared state or registering an agent that buys nothing.\n //\n // A threadId is written onto a single agent instance. An agent resolved by\n // `agentId` alone is a shared singleton, so a per-hook threadId there would\n // let two useAgent calls with the same agentId clobber each other's thread.\n // runtimeAgentId is what lets the hook register a *private* proxied agent\n // (below) and scope the threadId to that instead.\n if (threadId != null && runtimeAgentId == null) {\n throw new Error(\n `useAgent: \\`threadId\\` requires \\`runtimeAgentId\\`. A threadId is written onto a ` +\n `single agent, but an agent resolved by agentId alone is shared, so scoping a ` +\n `thread to it would clobber other useAgent callers. Pass a distinct local \\`agentId\\` ` +\n `and the runtime agent to route to, e.g. ` +\n `useAgent({ agentId: \"chat-1\", runtimeAgentId: \"${agentId ?? \"default\"}\", threadId }).`,\n );\n }\n\n // The converse: registering a private proxied agent is only worth doing in\n // order to scope a thread to it. Without a threadId the proxy would source its\n // thread from the chat configuration — exactly what binding to the shared\n // agent by `agentId` already does, minus a registration and a local id the\n // caller has to keep unique. Reject it rather than let it look meaningful.\n if (runtimeAgentId != null && threadId == null) {\n throw new Error(\n `useAgent: \\`runtimeAgentId\\` requires \\`threadId\\`. A proxied agent exists to scope a ` +\n `thread to a private instance; without a threadId it behaves like the shared agent ` +\n `while adding a registration and a local agentId to keep unique. Either pass the ` +\n `thread, e.g. useAgent({ agentId: \"${agentId ?? \"chat-1\"}\", runtimeAgentId: \"${runtimeAgentId}\", threadId }), ` +\n `or bind to the agent directly with useAgent({ agentId: \"${runtimeAgentId}\" }).`,\n );\n }\n\n // A proxied agent needs a local id of its own. Without an explicit `agentId`\n // the resolution below falls back to the chat configuration's agentId and then\n // DEFAULT_AGENT_ID — ids that already belong to real agents, so registering a\n // proxy over one either throws `already registered` or silently shadows it,\n // depending on whether runtime discovery has landed. Demand the caller name it.\n if (runtimeAgentId != null && agentId == null) {\n throw new Error(\n `useAgent: \\`runtimeAgentId\\` requires an explicit \\`agentId\\`. The proxied agent is ` +\n `registered under \\`agentId\\`, and the usual fallbacks (chat configuration, then ` +\n `\"${DEFAULT_AGENT_ID}\") name agents that already exist — registering over one throws or ` +\n `shadows it. Pick a local id for this hook, e.g. ` +\n `useAgent({ agentId: \"chat-1\", runtimeAgentId: \"${runtimeAgentId}\", threadId }).`,\n );\n }\n\n // Resolve agentId mirroring CopilotChat's precedence: an explicit prop wins,\n // then the surrounding chat configuration's agentId, then the global default.\n // Without the chat-config fallback, a useAgent() consumer rendered inside a\n // <CopilotChat agentId=\"...\"> subtree resolves to 'default' and throws once\n // the runtime has synced only a non-default agent (#5533).\n const chatConfig = useCopilotChatConfiguration();\n const resolvedAgentId = agentId ?? chatConfig?.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 // When runtimeAgentId is set, this hook owns a proxied agent registered under\n // `resolvedAgentId` that routes to `runtimeAgentId`. Register/unregister as a\n // single balanced effect (StrictMode-safe: the cleanup unregisters before the\n // remount re-registers). Exposing the registered agent via state re-renders\n // the hook so it swaps from the provisional stand-in to the real proxy\n // deterministically, without depending on the provider's agents-changed\n // subscription.\n const [registeredProxyAgent, setRegisteredProxyAgent] =\n useState<AbstractAgent | null>(null);\n useEffect(() => {\n if (runtimeAgentId == null) {\n setRegisteredProxyAgent(null);\n return;\n }\n const { agent: proxy, unregister } = copilotkit.registerProxiedAgent({\n agentId: resolvedAgentId,\n runtimeAgentId,\n });\n provisionalAgentCache.current.delete(resolvedAgentId);\n setRegisteredProxyAgent(proxy);\n return () => {\n unregister();\n setRegisteredProxyAgent(null);\n };\n }, [copilotkit, resolvedAgentId, runtimeAgentId]);\n\n const { agent, isReady } = useMemo<{\n agent: AbstractAgent;\n isReady: boolean;\n }>(() => {\n // Proxied-agent path: this hook registers its own agent (routing to\n // runtimeAgentId), so bypass the shared-singleton lookup entirely. Use the\n // registered instance once the effect has run; until then return a\n // provisional proxy so `agent` is never null and its reference stays stable\n // across the pre-registration renders.\n if (runtimeAgentId != null) {\n if (registeredProxyAgent) {\n provisionalAgentCache.current.delete(resolvedAgentId);\n return { agent: registeredProxyAgent, isReady: true };\n }\n const cached = provisionalAgentCache.current.get(resolvedAgentId);\n if (cached) {\n copilotkit.applyHeadersToAgent(cached);\n return { agent: cached, isReady: false };\n }\n const provisional = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: copilotkit.runtimeUrl,\n agentId: resolvedAgentId,\n runtimeAgentId,\n transport: copilotkit.runtimeTransport,\n runtimeMode: \"pending\",\n });\n copilotkit.applyHeadersToAgent(provisional);\n provisionalAgentCache.current.set(resolvedAgentId, provisional);\n return { agent: provisional, isReady: false };\n }\n\n const existing = copilotkit.getAgent(resolvedAgentId);\n if (existing) {\n // Real agent found — clear any cached provisional for this ID\n provisionalAgentCache.current.delete(resolvedAgentId);\n return { agent: existing, isReady: true };\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(resolvedAgentId);\n if (cached) {\n return { agent: cached, isReady: false };\n }\n\n const provisional = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: copilotkit.runtimeUrl,\n agentId: resolvedAgentId,\n transport: copilotkit.runtimeTransport,\n credentials: copilotkit.credentials,\n runtimeMode: \"pending\",\n });\n // Apply current headers so runs/connects inherit them\n copilotkit.applyHeadersToAgent(provisional);\n provisionalAgentCache.current.set(resolvedAgentId, provisional);\n return { agent: provisional, isReady: false };\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(resolvedAgentId);\n if (cached) {\n return { agent: cached, isReady: false };\n }\n const provisional = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: copilotkit.runtimeUrl,\n agentId: resolvedAgentId,\n transport: copilotkit.runtimeTransport,\n credentials: copilotkit.credentials,\n runtimeMode: \"pending\",\n });\n copilotkit.applyHeadersToAgent(provisional);\n provisionalAgentCache.current.set(resolvedAgentId, provisional);\n return { agent: provisional, isReady: false };\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 '${resolvedAgentId}' 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 resolvedAgentId,\n runtimeAgentId,\n registeredProxyAgent,\n copilotkit.agents,\n copilotkit.runtimeConnectionStatus,\n copilotkit.runtimeUrl,\n copilotkit.runtimeTransport,\n copilotkit.credentials,\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 request settings fresh without mutating inside useMemo,\n // which is unsafe in concurrent mode (React may invoke useMemo multiple\n // times and discard intermediate results, but mutations always land).\n useEffect(() => {\n if (agent instanceof HttpAgent) {\n // Merge core headers on top of the agent's own headers rather than\n // replacing them, so per-agent headers (e.g. an Authorization for a\n // self-hosted backend) are preserved (see #5635).\n copilotkit.applyHeadersToAgent(agent);\n }\n if (agent instanceof ProxiedCopilotRuntimeAgent) {\n agent.credentials = copilotkit.credentials;\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agent, JSON.stringify(copilotkit.headers), copilotkit.credentials]);\n\n // Propagate the caller-supplied threadId onto the agent. AbstractAgent's\n // constructor auto-mints a UUID when no threadId is passed, so without this\n // sync the agent ships its own random UUID in /agent/run, /agent/connect,\n // /agent/stop — diverging from the threadId the app code intends.\n //\n // Resolution precedence:\n // 1. An explicit `threadId` prop always wins. This lets headless callers\n // (e.g. React Native) scope the run to a thread without a\n // <CopilotChatConfigurationProvider> in the tree.\n // 2. Otherwise fall back to the chat configuration's threadId, gated on\n // hasExplicitThreadId so a ThreadsProvider-minted placeholder UUID\n // doesn't overwrite the auto-minted agent UUID (both are random and\n // useless to the backend; the explicit gate keeps the agent's UUID\n // stable across renders).\n const configThreadId = chatConfig?.threadId;\n const configHasExplicitThreadId = chatConfig?.hasExplicitThreadId;\n const resolvedThreadId =\n threadId ?? (configHasExplicitThreadId ? configThreadId : undefined);\n useEffect(() => {\n if (!resolvedThreadId) return;\n agent.threadId = resolvedThreadId;\n }, [agent, resolvedThreadId]);\n\n return {\n agent,\n /**\n * Whether `agent` is the real, runtime-synced (or locally-registered) agent\n * rather than a provisional stand-in returned while the runtime is still\n * connecting (or in an error state).\n *\n * `agent` is always a fully-constructed `AbstractAgent`, so calling\n * `agent.subscribe(...)`, `agent.setState(...)`, etc. is always safe. But\n * while `isReady` is `false` the instance is a placeholder that will be\n * swapped for the real agent once the runtime `/info` sync resolves, at\n * which point `agent` changes reference and dependent effects re-run.\n * Guard on `isReady` when you only want to act against the real agent —\n * e.g. subscribing to run-lifecycle events you don't want to miss during\n * the provisional window (#5000).\n */\n isReady,\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 agent resolved\n * from the surrounding chat configuration, falling back to 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, inherits the surrounding\n * chat configuration's agent, falling back to 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 { 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","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 { randomUUID } from \"@ag-ui/client\";\nimport type { Interrupt, Message } from \"@ag-ui/client\";\nimport { ɵInterruptState } from \"@copilotkit/core\";\nimport type { ɵPendingInterrupt } from \"@copilotkit/core\";\nimport { useCopilotKit } from \"../context\";\nimport { useAgent } from \"./use-agent\";\nimport type {\n InterruptEvent,\n InterruptRenderProps,\n InterruptHandlerProps,\n InterruptResolveFn,\n InterruptCancelFn,\n} from \"../types/interrupt\";\n\nexport type {\n InterruptEvent,\n InterruptRenderProps,\n InterruptHandlerProps,\n Interrupt,\n};\n\nconst INTERRUPT_EVENT_NAME = \"on_interrupt\";\n\n/**\n * Normalized pending interrupt. `legacy` carries the custom-event payload;\n * `standard` carries the AG-UI `outcome:\"interrupt\"` interrupts array.\n */\ntype PendingInterrupt = ɵPendingInterrupt;\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/** Derive the legacy-compatible `event` for any pending interrupt. */\nfunction toLegacyEvent(pending: PendingInterrupt): InterruptEvent {\n if (pending.kind === \"legacy\") return pending.event;\n return { name: INTERRUPT_EVENT_NAME, value: pending.interrupts[0] };\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 * Receives both the standard `interrupt`/`interrupts` and the legacy `event`.\n * Call `resolve(payload)` to resume with user input, or `cancel()` to cancel.\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 * Return a sync or async value to expose as `result` in `render`.\n * Rejecting/throwing falls back to `result = null`.\n */\n handler?: InterruptHandlerFn<TValue, TResult>;\n /**\n * Optional predicate to filter which interrupts this hook handles.\n * Receives the legacy-compatible event (for standard interrupts, `value` is\n * the primary `Interrupt`). Return `false` to ignore.\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. */\n renderInChat?: true;\n}\n\nexport interface UseInterruptExternalConfig<\n TValue = unknown,\n TResult = never,\n> extends UseInterruptConfigBase<TValue, TResult> {\n /** When false, the hook returns the interrupt element so you can place 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. */\n renderInChat?: TRenderInChat;\n};\n\n/**\n * Handles agent interrupts with optional filtering, preprocessing, and resume behavior.\n *\n * Supports both the AG-UI standard interrupt flow (`RUN_FINISHED` with\n * `outcome.type === \"interrupt\"`) and the legacy custom-event flow\n * (`on_interrupt`). For standard interrupts, `render` receives `interrupt`\n * (the primary one) and `interrupts` (the full open set); call `resolve(payload)`\n * to resume or `cancel()` to cancel. Resuming addresses the targeted interrupt\n * and, once every open interrupt is addressed, submits a single spec `resume`\n * array via `copilotkit.runAgent`.\n *\n * - `renderInChat: true` (default): the element is published into `<CopilotChat>`; returns `void`.\n * - `renderInChat: false`: the hook returns the interrupt element for manual placement.\n *\n * @example\n * ```tsx\n * useInterrupt({\n * render: ({ interrupt, resolve, cancel }) => (\n * <div>\n * <p>{interrupt?.message}</p>\n * <button onClick={() => resolve({ approved: true })}>Approve</button>\n * <button onClick={() => cancel()}>Cancel</button>\n * </div>\n * ),\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 [pending, setPending] = useState<PendingInterrupt | null>(null);\n const pendingRef = useRef(pending);\n pendingRef.current = pending;\n const [handlerResult, setHandlerResult] =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n useState<InterruptResult<any, TResult>>(null);\n\n const interruptStateRef = useRef(new ɵInterruptState());\n const interruptRunIdsRef = useRef(new Map<string, string>());\n const legacyRunIdRef = useRef<string | undefined>(undefined);\n\n useEffect(() => {\n const interruptState = interruptStateRef.current;\n let localLegacy: InterruptEvent | null = null;\n let localStandard: Interrupt[] | null = null;\n\n const subscription = agent.subscribe({\n onCustomEvent: ({ event }) => {\n if (event.name === INTERRUPT_EVENT_NAME) {\n localLegacy = { name: event.name, value: event.value };\n }\n },\n onRunFinishedEvent: (params) => {\n if (params.outcome === \"interrupt\") {\n const runId = params.input.runId;\n for (const interrupt of params.interrupts) {\n interruptRunIdsRef.current.set(interrupt.id, runId);\n }\n localStandard = params.interrupts;\n }\n },\n onRunStartedEvent: () => {\n localLegacy = null;\n localStandard = null;\n interruptRunIdsRef.current.clear();\n legacyRunIdRef.current = undefined;\n interruptState.clear();\n setPending(null);\n },\n onRunFinalized: (params) => {\n // Standard wins if both somehow appear for one run.\n if (localStandard && localStandard.length > 0) {\n interruptState.setStandard(localStandard);\n setPending(interruptState.pending);\n } else if (localLegacy) {\n legacyRunIdRef.current = params.input.runId;\n interruptState.setLegacy(localLegacy);\n setPending(interruptState.pending);\n }\n localLegacy = null;\n localStandard = null;\n },\n onRunFailed: () => {\n localLegacy = null;\n localStandard = null;\n interruptRunIdsRef.current.clear();\n legacyRunIdRef.current = undefined;\n interruptState.clear();\n setPending(null);\n },\n });\n\n return () => {\n subscription.unsubscribe();\n interruptState.clear();\n };\n }, [agent]);\n\n const resolve: InterruptResolveFn = useCallback(\n async (payload, interruptId) => {\n const current = pendingRef.current;\n if (!current) return;\n\n if (\n current.kind === \"standard\" &&\n current.interrupts.length > 1 &&\n interruptId === undefined\n ) {\n console.warn(\n `[CopilotKit] useInterrupt: resolve()/cancel() called without an interruptId while ${current.interrupts.length} interrupts are open; defaulting to the first. Pass an interruptId to address a specific interrupt.`,\n );\n }\n const decision = interruptStateRef.current.resolve(payload, interruptId);\n if (decision.kind === \"legacy-resume\") {\n const runId = legacyRunIdRef.current;\n try {\n return await copilotkit.runAgent({\n agent,\n ...(runId !== undefined ? { runId } : {}),\n forwardedProps: {\n command: {\n resume: decision.payload,\n interruptEvent: decision.interruptValue,\n },\n },\n });\n } catch (err) {\n console.error(\n \"[CopilotKit] useInterrupt resolve: runAgent rejected; clearing pending + rethrowing\",\n err,\n );\n setPending(null);\n throw err;\n }\n }\n if (decision.kind === \"expired\") {\n console.error(\n `[CopilotKit] useInterrupt: interrupt ${decision.interrupt.id} expired at ${decision.interrupt.expiresAt}; not resuming.`,\n );\n interruptStateRef.current.clear();\n setPending(null);\n return;\n }\n if (decision.kind !== \"resume\") return;\n const runId = decision.resume\n .map((entry) => interruptRunIdsRef.current.get(entry.interruptId))\n .find((candidate): candidate is string => candidate !== undefined);\n for (const toolResult of decision.toolResults) {\n agent.addMessage({\n id: randomUUID(),\n role: \"tool\",\n toolCallId: toolResult.toolCallId,\n content: toolResult.content,\n } as Message);\n }\n try {\n return await copilotkit.runAgent({\n agent,\n resume: decision.resume,\n ...(runId !== undefined ? { runId } : {}),\n });\n } catch (err) {\n console.error(\n \"[CopilotKit] useInterrupt resolve: runAgent rejected; clearing pending + rethrowing\",\n err,\n );\n interruptStateRef.current.clear();\n setPending(null);\n throw err;\n }\n },\n [agent, copilotkit],\n );\n\n const cancel: InterruptCancelFn = useCallback(\n async (interruptId) => {\n const current = pendingRef.current;\n if (!current) return;\n\n if (\n current.kind === \"standard\" &&\n current.interrupts.length > 1 &&\n interruptId === undefined\n ) {\n console.warn(\n `[CopilotKit] useInterrupt: resolve()/cancel() called without an interruptId while ${current.interrupts.length} interrupts are open; defaulting to the first. Pass an interruptId to address a specific interrupt.`,\n );\n }\n const decision = interruptStateRef.current.cancel(interruptId);\n if (decision.kind === \"dismiss\") {\n // Legacy interrupts have no cancel semantics; dismiss without resuming.\n console.warn(\n \"[CopilotKit] useInterrupt: cancel() is not supported for legacy on_interrupt interrupts; dismissing.\",\n );\n interruptStateRef.current.clear();\n setPending(null);\n return;\n }\n if (decision.kind === \"expired\") {\n console.error(\n `[CopilotKit] useInterrupt: interrupt ${decision.interrupt.id} expired at ${decision.interrupt.expiresAt}; not resuming.`,\n );\n interruptStateRef.current.clear();\n setPending(null);\n return;\n }\n if (decision.kind !== \"resume\") return;\n const runId = decision.resume\n .map((entry) => interruptRunIdsRef.current.get(entry.interruptId))\n .find((candidate): candidate is string => candidate !== undefined);\n for (const toolResult of decision.toolResults) {\n agent.addMessage({\n id: randomUUID(),\n role: \"tool\",\n toolCallId: toolResult.toolCallId,\n content: toolResult.content,\n } as Message);\n }\n try {\n return await copilotkit.runAgent({\n agent,\n resume: decision.resume,\n ...(runId !== undefined ? { runId } : {}),\n });\n } catch (err) {\n console.error(\n \"[CopilotKit] useInterrupt resolve: runAgent rejected; clearing pending + rethrowing\",\n err,\n );\n interruptStateRef.current.clear();\n setPending(null);\n throw err;\n }\n },\n [agent, copilotkit],\n );\n\n // Stabilize consumer-supplied callbacks behind refs so inline lambdas do not\n // churn the element memo identity or the handler effect.\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 const resolveRef = useRef(resolve);\n resolveRef.current = resolve;\n const cancelRef = useRef(cancel);\n cancelRef.current = cancel;\n\n // Predicate evaluator: a throw is treated as \"disabled\" (false) and logged.\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 if (!pending) {\n setHandlerResult(null);\n return;\n }\n const legacyEvent = toLegacyEvent(pending);\n if (!isEnabled(legacyEvent)) {\n setHandlerResult(null);\n return;\n }\n const handler = handlerRef.current;\n if (!handler) {\n setHandlerResult(null);\n return;\n }\n\n let cancelled = false;\n let maybePromise: ReturnType<typeof handler>;\n try {\n maybePromise = handler({\n event: legacyEvent,\n interrupt: pending.kind === \"standard\" ? pending.interrupts[0] : null,\n interrupts: pending.kind === \"standard\" ? [...pending.interrupts] : [],\n resolve: resolveRef.current,\n cancel: cancelRef.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 (isPromiseLike(maybePromise)) {\n Promise.resolve(maybePromise)\n .then((resolved) => {\n if (!cancelled) setHandlerResult(resolved);\n })\n .catch((err) => {\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 // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [pending]);\n\n const element = useMemo(() => {\n if (!pending) return null;\n const legacyEvent = toLegacyEvent(pending);\n if (!isEnabled(legacyEvent)) return null;\n\n return renderRef.current({\n event: legacyEvent,\n interrupt: pending.kind === \"standard\" ? pending.interrupts[0] : null,\n interrupts: pending.kind === \"standard\" ? [...pending.interrupts] : [],\n result: handlerResult,\n resolve,\n cancel,\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [pending, handlerResult, resolve, cancel]);\n\n // Publish to core for in-chat rendering. Publish-only.\n useEffect(() => {\n if (config.renderInChat === false) return;\n copilotkit.setInterruptElement(element);\n }, [element, config.renderInChat, copilotkit]);\n\n // Nullify on true unmount only.\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 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 ɵselectFetchMoreError,\n ɵselectThreadsIsLoading,\n ɵselectHasNextPage,\n ɵselectIsFetchingNextPage,\n ɵselectIsMutating,\n} from \"@copilotkit/core\";\nimport type { ɵThreadRuntimeContext, ɵThreadStore } 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 * When `false`, the hook stays inert: no runtime context is dispatched, so\n * NO thread-list fetch or realtime subscription is issued. Used by gated\n * surfaces (e.g. an unlicensed `<CopilotThreadsDrawer>`) that must not touch the\n * network until the gate opens. Defaults to `true`.\n *\n * Flipping `enabled` back to `true` resumes normal fetching on the next\n * effect run; mutations are likewise short-circuited while disabled.\n */\n enabled?: boolean;\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 * This channel folds together developer/config errors (missing runtime URL,\n * runtime without thread endpoints) and genuine list-load/mutation failures.\n * End-user surfaces that must not leak config errors should prefer\n * {@link listError}, which excludes the config/runtime-setup errors.\n */\n error: Error | null;\n /**\n * The most recent genuine list-load or mutation error from the platform, or\n * `null`. Unlike {@link error}, this EXCLUDES developer/config errors (a\n * missing runtime URL, or a runtime that does not advertise thread\n * endpoints), so an end-user surface can render it directly without leaking\n * a developer-facing configuration message into the UI.\n */\n listError: Error | null;\n /**\n * The error from the most recent FAILED next-page (fetch-more) load, or\n * `null`. Tracked separately from {@link listError} so a paginated-load\n * failure surfaces an inline \"couldn't load more\" affordance while the\n * already-loaded list stays visible. Cleared when a fetch-more is retried or\n * succeeds.\n */\n fetchMoreError: 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 * `true` while at least one thread mutation (rename, archive, unarchive,\n * delete) is awaiting a server response. Mutations apply optimistically, so\n * this is primarily useful for disabling controls or showing a subtle\n * in-flight indicator.\n */\n isMutating: 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 * Re-fetch the thread list from the platform without clearing the current\n * list. Backs the drawer's error-state Retry and the Active/All filter\n * refetch. No-op until the runtime is connected.\n */\n refetchThreads: () => void;\n /**\n * Reset to a fresh, non-explicit client-side thread so the welcome screen\n * shows. Lazy creation: no row appears in {@link threads} until the new\n * thread's first run persists server-side.\n */\n startNewThread: () => 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 * Restore a previously archived thread on the platform.\n * The thread re-appears in default (non-archived) list results.\n * Resolves when the server confirms the update; rejects on failure.\n */\n unarchiveThread: (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 // getServerSnapshot: without this third argument React throws\n // \"Missing getServerSnapshot\" during SSR/prerender (e.g. Next.js). The\n // store has no client data while prerendering, so we project from its\n // stable server state.\n () => selector(store.getServerState()),\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`, `unarchiveThread`,\n * `deleteThread`) return promises that resolve once the platform confirms the\n * operation and reject 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 enabled = true,\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 fetchMoreError = useThreadStoreSelector(store, ɵselectFetchMoreError);\n const hasMoreThreads = useThreadStoreSelector(store, ɵselectHasNextPage);\n const isFetchingMoreThreads = useThreadStoreSelector(\n store,\n ɵselectIsFetchingNextPage,\n );\n const isMutating = useThreadStoreSelector(store, ɵselectIsMutating);\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 runtimeStatus = copilotkit.runtimeConnectionStatus;\n const threadListEndpointSupported =\n copilotkit.threadEndpoints?.list !== false;\n const threadMutationsSupported =\n copilotkit.threadEndpoints?.mutations !== false;\n const threadEndpointsUnavailable =\n !!copilotkit.runtimeUrl &&\n runtimeStatus === CopilotKitCoreRuntimeConnectionStatus.Connected &&\n !threadListEndpointSupported;\n const runtimeError = useMemo(() => {\n if (copilotkit.runtimeUrl) {\n return null;\n }\n\n return new Error(\"Runtime URL is not configured\");\n }, [copilotkit.runtimeUrl]);\n const threadEndpointsError = useMemo(() => {\n if (!threadEndpointsUnavailable) {\n return null;\n }\n\n return new Error(\n \"Thread endpoints are not available on this CopilotKit runtime\",\n );\n }, [threadEndpointsUnavailable]);\n const threadMutationsError = useMemo(() => {\n if (threadMutationsSupported) {\n return null;\n }\n\n return new Error(\n \"Thread mutations are not available on this CopilotKit runtime\",\n );\n }, [threadMutationsSupported]);\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 =\n enabled &&\n !!copilotkit.runtimeUrl &&\n !threadEndpointsUnavailable &&\n !hasDispatchedContext;\n\n // `startNewThread` resets to a clean welcome surface, so it should clear any\n // lingering error banner — including the config/runtime-setup errors that\n // otherwise outrank the store's own (already-cleared) error. We cannot clear\n // a derived `runtimeError`/`threadEndpointsError` directly (they reflect\n // current config), so we suppress them with a dismissal flag that resets\n // whenever the underlying config-error identity changes (a genuine new config\n // problem re-surfaces).\n const [configErrorDismissed, setConfigErrorDismissed] = useState(false);\n useEffect(() => {\n setConfigErrorDismissed(false);\n }, [runtimeError, threadEndpointsError]);\n\n const activeRuntimeError = configErrorDismissed ? null : runtimeError;\n const activeThreadEndpointsError = configErrorDismissed\n ? null\n : threadEndpointsError;\n\n const isLoading =\n activeRuntimeError || activeThreadEndpointsError\n ? false\n : preConnectLoading || storeIsLoading;\n const error = activeRuntimeError ?? activeThreadEndpointsError ?? storeError;\n // End-user-facing list/mutation error only: developer/config errors are\n // excluded so a surface like <CopilotThreadsDrawer> does not show \"Runtime URL is\n // not configured\" to an end user.\n const listError = 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 useEffect(() => {\n // A disabled (e.g. unlicensed) drawer must not claim the agentId slot. The\n // registry is single-slot/last-writer-wins, so registering an inert store\n // would evict — and on unmount tear down — a co-mounted live store for the\n // same agent. Staying unregistered while disabled leaves the live store's\n // registration intact.\n if (!enabled) return;\n copilotkit.registerThreadStore(agentId, store);\n return () => {\n copilotkit.unregisterThreadStore(agentId);\n };\n }, [copilotkit, agentId, store, enabled]);\n\n useEffect(() => {\n // Disabled: stay inert. Clear any previously-dispatched context so an\n // in-flight subscription is torn down and no further fetch is issued.\n if (!enabled) {\n store.setContext(null);\n setHasDispatchedContext(false);\n return;\n }\n\n if (!copilotkit.runtimeUrl) {\n store.setContext(null);\n setHasDispatchedContext(false);\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 if (!threadListEndpointSupported) {\n store.setContext(null);\n setHasDispatchedContext(false);\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 enabled,\n copilotkit.runtimeUrl,\n runtimeStatus,\n headersKey,\n copilotkit.intelligence?.wsUrl,\n threadListEndpointSupported,\n agentId,\n includeArchived,\n limit,\n ]);\n\n const guardMutation = useCallback(\n <TArgs extends unknown[]>(\n mutation: (...args: TArgs) => Promise<void>,\n ): ((...args: TArgs) => Promise<void>) => {\n return (...args: TArgs) => {\n if (threadMutationsError) {\n return Promise.reject(threadMutationsError);\n }\n return mutation(...args);\n };\n },\n [threadMutationsError],\n );\n\n const renameThread = useMemo(\n () =>\n guardMutation((threadId: string, name: string) =>\n store.renameThread(threadId, name),\n ),\n [store, guardMutation],\n );\n\n const archiveThread = useMemo(\n () => guardMutation((threadId: string) => store.archiveThread(threadId)),\n [store, guardMutation],\n );\n\n const unarchiveThread = useMemo(\n () => guardMutation((threadId: string) => store.unarchiveThread(threadId)),\n [store, guardMutation],\n );\n\n const deleteThread = useMemo(\n () => guardMutation((threadId: string) => store.deleteThread(threadId)),\n [store, guardMutation],\n );\n\n const fetchMoreThreads = useCallback(() => store.fetchNextPage(), [store]);\n const refetchThreads = useCallback(() => store.refetchThreads(), [store]);\n const startNewThread = useCallback(() => {\n // The store's `newThreadStarted` reducer clears its own error; also dismiss\n // the derived config/runtime-setup errors so the welcome surface renders\n // with no stale error banner.\n setConfigErrorDismissed(true);\n store.startNewThread();\n }, [store]);\n\n return {\n threads,\n isLoading,\n error,\n listError,\n fetchMoreError,\n hasMoreThreads,\n isFetchingMoreThreads,\n isMutating,\n fetchMoreThreads,\n refetchThreads,\n startNewThread,\n renameThread,\n archiveThread,\n unarchiveThread,\n deleteThread,\n };\n}\n","import { useCopilotKit } from \"../context\";\nimport {\n ɵselectMemories,\n ɵselectMemoriesError,\n ɵselectMemoriesIsLoading,\n ɵselectMemoriesAvailable,\n ɵselectMemoriesRealtimeStatus,\n} from \"@copilotkit/core\";\nimport type {\n Memory,\n MemoryChanges,\n MemoryRealtimeStatus,\n ɵMemoryStore,\n NewMemory,\n} from \"@copilotkit/core\";\nimport { useCallback, useSyncExternalStore } from \"react\";\n\n/**\n * Return value of the {@link useMemories} hook.\n *\n * The `memories` array is the server-authoritative list for the current user.\n * It is hydrated from a REST snapshot and kept current by realtime\n * `memory_metadata` deltas from the store's own channel. Mutations resolve\n * once the platform confirms the operation and reject with an `Error` on\n * failure.\n */\nexport interface UseMemoriesResult {\n /**\n * Memories for the current user, newest first. Updated in realtime when\n * the platform pushes `memory_metadata` events.\n */\n memories: Memory[];\n /**\n * `true` while the initial memory snapshot is being fetched. Subsequent\n * realtime updates do not re-enter the loading state.\n */\n isLoading: boolean;\n /**\n * The most recent error from fetching memories or executing a mutation, or\n * `null` when there is no error. Cleared on the next fetch attempt, on a\n * successful fetch, when the runtime context changes, and on a successful\n * mutation (a failed mutation replaces it with that mutation's error).\n */\n error: Error | null;\n /**\n * `true` when the platform memory routes are available. Set to `false`\n * after a 404 or 501, indicating memory is not supported by the current\n * runtime configuration.\n */\n isAvailable: boolean;\n /**\n * Health of the realtime connection that streams live `memory_metadata`\n * deltas. Distinct from `isAvailable`/`error` (which describe the REST list\n * route): `\"connecting\"` while the socket opens/joins, `\"connected\"` once\n * live deltas are flowing, and `\"unavailable\"` once the socket permanently\n * gives up — at which point the list is a frozen snapshot. Lets the UI drop a\n * \"live\" indicator instead of showing it over stale data.\n */\n realtimeStatus: MemoryRealtimeStatus;\n /**\n * Re-fetch the memory snapshot from the platform. Resolves once the re-pull\n * settles; rejects if it fails or the store is torn down mid-flight.\n */\n refresh: () => Promise<void>;\n /**\n * Create a memory. Resolves to the stored memory (server-authoritative);\n * rejects on failure.\n */\n addMemory: (input: NewMemory) => Promise<Memory>;\n /**\n * Supersede a memory: the old memory is retired and a new one is created.\n * Resolves to the new memory (its `id` differs from `id`); rejects on\n * failure.\n *\n * Supersede is a FULL replacement, not a partial patch: `changes` is the\n * complete definition of the new memory. You must re-supply `content` and\n * `kind`, and an omitted `sourceThreadIds` resets the new memory's source\n * threads to empty — it does not preserve the prior memory's value.\n */\n updateMemory: (id: string, changes: MemoryChanges) => Promise<Memory>;\n /**\n * Retire a memory (non-lossy delete). Resolves when the server confirms;\n * rejects on failure.\n */\n removeMemory: (id: string) => Promise<void>;\n}\n\nfunction useMemoryStoreSelector<T>(\n store: ɵMemoryStore,\n selector: (state: ReturnType<ɵMemoryStore[\"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 // getServerSnapshot: without this third argument React throws\n // \"Missing getServerSnapshot\" during SSR/prerender (e.g. Next.js). The\n // store has no client data while prerendering, so we project from its\n // stable server state.\n () => selector(store.getServerState()),\n );\n}\n\n/**\n * React hook for listing and managing platform memories.\n *\n * Reads the memory store owned and wired by `CopilotKitCore`. On mount the\n * hook exposes the live list plus stable `addMemory` / `updateMemory` /\n * `removeMemory` / `refresh` callbacks. Mutations are server-authoritative:\n * each resolves once the platform confirms the operation and rejects with an\n * `Error` on failure.\n *\n * Realtime updates are automatic: the core's memory store opens its own\n * `user_meta:memories:<joinCode>` channel and applies `memory_metadata` deltas\n * to the list. You can still call `refresh()` to re-pull the REST snapshot on\n * demand.\n *\n * @returns Memory list state and stable mutation callbacks.\n *\n * @example\n * ```tsx\n * import { useMemories } from \"@copilotkit/react-core\";\n *\n * function MemoryList() {\n * const { memories, isLoading, isAvailable, addMemory, removeMemory } =\n * useMemories();\n *\n * if (!isAvailable) return null;\n * if (isLoading) return <p>Loading…</p>;\n *\n * return (\n * <ul>\n * {memories.map((m) => (\n * <li key={m.id}>\n * {m.content}\n * <button onClick={() => removeMemory(m.id)}>Delete</button>\n * </li>\n * ))}\n * </ul>\n * );\n * }\n * ```\n */\nexport function useMemories(): UseMemoriesResult {\n const { copilotkit } = useCopilotKit();\n\n const store = copilotkit.getMemoryStore();\n\n const memories = useMemoryStoreSelector(store, ɵselectMemories);\n const isLoading = useMemoryStoreSelector(store, ɵselectMemoriesIsLoading);\n const error = useMemoryStoreSelector(store, ɵselectMemoriesError);\n const isAvailable = useMemoryStoreSelector(store, ɵselectMemoriesAvailable);\n const realtimeStatus = useMemoryStoreSelector(\n store,\n ɵselectMemoriesRealtimeStatus,\n );\n\n const refresh = useCallback(() => store.refresh(), [store]);\n const addMemory = useCallback(\n (input: NewMemory) => store.addMemory(input),\n [store],\n );\n const updateMemory = useCallback(\n (id: string, changes: MemoryChanges) => store.updateMemory(id, changes),\n [store],\n );\n const removeMemory = useCallback(\n (id: string) => store.removeMemory(id),\n [store],\n );\n\n return {\n memories,\n isLoading,\n error,\n isAvailable,\n realtimeStatus,\n refresh,\n addMemory,\n updateMemory,\n removeMemory,\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 * `\"user_action\"` records a UI interaction for the self-learning loop.\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 annotations. Higher-level\n * hooks such as `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 *\n * @deprecated Legacy plural-container annotation compatibility only. New\n * Intelligence runtimes assign one container with `ɵlearning.containerId` on\n * `CopilotRuntime`.\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 * Legacy compatibility hook that keeps a thread's plural learning-container\n * annotation 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 *\n * @deprecated Legacy plural-container annotation compatibility only. New\n * Intelligence runtimes assign one container with `ɵlearning.containerId` on\n * `CopilotRuntime`.\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 *\n * @deprecated Legacy plural-container annotation compatibility only. New\n * Intelligence runtimes assign one container with `ɵlearning.containerId` on\n * `CopilotRuntime`.\n */\nexport type UseLearningContainersInCurrentThreadArgs = Omit<\n UseLearningContainersArgs,\n \"threadId\"\n>;\n\n/**\n * Legacy compatibility hook that keeps the **current chat thread's** plural\n * learning-container annotation in 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 *\n * @deprecated Legacy plural-container annotation compatibility only. New\n * Intelligence runtimes assign one container with `ɵlearning.containerId` on\n * `CopilotRuntime`.\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 type { AssistantMessage, Message } from \"@ag-ui/core\";\nimport { useEffect, useId, 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 type { WithSlots } from \"../../lib/slots\";\nimport { renderSlot } from \"../../lib/slots\";\nimport { Streamdown } from \"streamdown\";\nimport { copyToClipboard } from \"@copilotkit/shared\";\nimport CopilotChatToolCallsView from \"./CopilotChatToolCallsView\";\nimport { useCopilotKitInspector } from \"../CopilotKitInspectorContext\";\n\nexport type CopilotChatAssistantMessageProps = WithSlots<\n {\n markdownRenderer: typeof CopilotChatAssistantMessage.MarkdownRenderer;\n toolbar: typeof CopilotChatAssistantMessage.Toolbar;\n copyButton: typeof CopilotChatAssistantMessage.CopyButton;\n inspectorButton: typeof CopilotChatAssistantMessage.InspectorButton;\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 inspectorButton,\n thumbsUpButton,\n thumbsDownButton,\n readAloudButton,\n regenerateButton,\n toolCallsView,\n children,\n className,\n ...props\n}: CopilotChatAssistantMessageProps) {\n useKatexStyles();\n const { isLocalInspectorEnabled, openInspector } = useCopilotKitInspector();\n const chatConfiguration = useCopilotChatConfiguration();\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 boundInspectorButton = renderSlot(\n inspectorButton,\n CopilotChatAssistantMessage.InspectorButton,\n {\n onClick: () =>\n openInspector({\n messageId: message.id,\n threadId: chatConfiguration?.threadId,\n agentId: chatConfiguration?.agentId,\n }),\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 {isLocalInspectorEnabled && boundInspectorButton}\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 inspectorButton: boundInspectorButton,\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\nfunction CopilotKitColoredIcon() {\n const gradientId = useId().replace(/:/g, \"\");\n\n return (\n <svg\n aria-hidden=\"true\"\n className=\"cpk:size-5\"\n data-testid=\"copilot-inspector-icon\"\n viewBox=\"0 0 24 24\"\n >\n <path\n d=\"M8.162 7.758c2.093-2.738 3.831-5.445 4.498-7.63a.093.093 0 01.14-.051c2.324 1.539 6.558 2.552 10.301 2.576a.09.09 0 01.085.124c-1.243 3.158-2.765 8.817-2.823 15.28-.001.095-.135.13-.183.046-2.131-3.729-8.955-8.968-11.982-10.205a.09.09 0 01-.036-.14z\"\n fill={`url(#${gradientId}-purple)`}\n />\n <path\n d=\"M15.223 6.083A61.492 61.492 0 018.25 7.827c-.045.008-.055.071-.012.089 3.05 1.267 9.84 6.492 11.952 10.206a.017.017 0 00.022.007.018.018 0 00.01-.024l-4.999-12.02z\"\n fill={`url(#${gradientId}-blue)`}\n />\n <path\n d=\"M12.81.07c2.8 1.528 6.037 2.214 10.33 2.575.028.002.036.039.012.051-.55.282-3.695 1.883-6.03 2.74-.626.23-1.256.443-1.876.64a.028.028 0 01-.033-.016L12.746.128c-.017-.04.027-.078.065-.058z\"\n fill={`url(#${gradientId}-light-blue)`}\n />\n <path\n className=\"cpk:fill-[#513C9F] cpk:dark:fill-[#B99AE8]\"\n d=\"M12.725.075c.046-.019.1.003.119.05l7.514 17.923a.091.091 0 01-.148.1l-.02-.03L12.675.195a.091.091 0 01.049-.12z\"\n />\n <path\n className=\"cpk:fill-[#513C9F] cpk:dark:fill-[#B99AE8]\"\n d=\"M23.06 2.66c.044-.025.1-.01.125.034.025.044.009.1-.035.124v.001l-.008.004-.025.015-.1.054a41.384 41.384 0 01-1.811.92A47.05 47.05 0 0116.33 5.82c-1.954.674-3.97 1.197-5.497 1.552a66.27 66.27 0 01-2.38.507l-.138.026-.036.007h-.01l-.002.002a.091.091 0 11-.033-.18l.016.09-.015-.09h.002l.01-.002.035-.007.137-.025a66.16 66.16 0 002.373-.506c1.524-.354 3.533-.876 5.479-1.547a46.857 46.857 0 006.276-2.709c.166-.087.295-.156.381-.204l.099-.054.024-.014.008-.004z\"\n />\n <path\n className=\"cpk:fill-[#ABABAB] cpk:dark:fill-[#D4D4D4]\"\n d=\"M13.838 2.272a.16.16 0 01.107.2l-2.72 9.055h6.4l.061.013a.16.16 0 010 .295l-.061.013h-6.541L.679 24.099l-.05.04a.16.16 0 01-.194-.245l10.43-12.285 2.773-9.23a.16.16 0 01.2-.107z\"\n />\n <path\n d=\"M7.809 21.461l-1.232.173c.638 1.69 1.949 2.427 3.514 2.427 3.831 0 2.661-4.334 4.883-4.334 1.61 0 .956 3.513 4.423 3.513 2.116 0 2.326-2.131 1.966-3.048l-.008-.016-.567-.868c-.037-.058-.127-.036-.133.032l-.106 1.053a1.01 1.01 0 00.003.219c.088.727.144 2.491-1.155 2.491-1.37 0-1.7-3.467-4.423-3.467-3.196 0-2.785 4.289-4.747 4.289-1.294 0-2.28-1.46-2.418-2.464z\"\n fill={`url(#${gradientId}-tail)`}\n />\n <defs>\n <linearGradient\n gradientUnits=\"userSpaceOnUse\"\n id={`${gradientId}-purple`}\n x1=\"17.852\"\n x2=\"14.202\"\n y1=\"1.467\"\n y2=\"11.504\"\n >\n <stop className=\"cpk:[stop-color:#6430AB] cpk:dark:[stop-color:#B792F0]\" />\n <stop\n className=\"cpk:[stop-color:#AA89D8] cpk:dark:[stop-color:#D3BDF7]\"\n offset=\"1\"\n />\n </linearGradient>\n <linearGradient\n gradientUnits=\"userSpaceOnUse\"\n id={`${gradientId}-blue`}\n x1=\"15.024\"\n x2=\"10.324\"\n y1=\"7.125\"\n y2=\"16.204\"\n >\n <stop className=\"cpk:[stop-color:#005DBB] cpk:dark:[stop-color:#4D9FEF]\" />\n <stop\n className=\"cpk:[stop-color:#3D92E8] cpk:dark:[stop-color:#84C0FA]\"\n offset=\"1\"\n />\n </linearGradient>\n <linearGradient\n gradientUnits=\"userSpaceOnUse\"\n id={`${gradientId}-light-blue`}\n x1=\"17.122\"\n x2=\"15.707\"\n y1=\"1.467\"\n y2=\"5.892\"\n >\n <stop className=\"cpk:[stop-color:#1B70C4] cpk:dark:[stop-color:#61ACF2]\" />\n <stop\n className=\"cpk:[stop-color:#54A4F2] cpk:dark:[stop-color:#9ACDFF]\"\n offset=\"1\"\n />\n </linearGradient>\n <linearGradient\n gradientUnits=\"userSpaceOnUse\"\n id={`${gradientId}-tail`}\n x1=\"6.577\"\n x2=\"21.506\"\n y1=\"21.758\"\n y2=\"21.758\"\n >\n <stop className=\"cpk:[stop-color:#4497EA] cpk:dark:[stop-color:#79BCF5]\" />\n <stop\n className=\"cpk:[stop-color:#1463B2] cpk:dark:[stop-color:#4594D8]\"\n offset=\".255\"\n />\n <stop\n className=\"cpk:[stop-color:#0A437D] cpk:dark:[stop-color:#347CB7]\"\n offset=\".499\"\n />\n <stop\n className=\"cpk:[stop-color:#2476C8] cpk:dark:[stop-color:#58A4E5]\"\n offset=\".667\"\n />\n <stop\n className=\"cpk:[stop-color:#0C549A] cpk:dark:[stop-color:#3C87C7]\"\n offset=\".973\"\n />\n </linearGradient>\n </defs>\n </svg>\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 tooltip?: React.ReactNode;\n children: React.ReactNode;\n }\n > = ({ title, tooltip, 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 {tooltip ?? <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: unknown = 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 InspectorButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n const primaryLabel = title || labels.assistantMessageToolbarInspectorLabel;\n const localOnlyLabel =\n labels.assistantMessageToolbarInspectorLocalOnlyLabel;\n const accessibleLabel = `${primaryLabel} (${localOnlyLabel})`;\n return (\n <ToolbarButton\n data-testid=\"copilot-inspector-button\"\n title={accessibleLabel}\n tooltip={\n <div className=\"cpk:flex cpk:flex-col cpk:gap-0.5\">\n <span>{primaryLabel}</span>\n <span className=\"cpk:text-[10px] cpk:opacity-65\">\n {localOnlyLabel}\n </span>\n </div>\n }\n {...props}\n >\n <CopilotKitColoredIcon />\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.InspectorButton.displayName =\n \"CopilotChatAssistantMessage.InspectorButton\";\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 type { UserMessage } from \"@ag-ui/core\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"../../components/ui/tooltip\";\nimport type { WithSlots } from \"../../lib/slots\";\nimport { renderSlot } from \"../../lib/slots\";\nimport { copyToClipboard } from \"@copilotkit/shared\";\nimport type {\n ImageInputPart,\n AudioInputPart,\n VideoInputPart,\n DocumentInputPart,\n} from \"@copilotkit/shared\";\nimport { CopilotChatAttachmentRenderer } from \"./CopilotChatAttachmentRenderer\";\n\nfunction flattenUserMessageContent(content?: UserMessage[\"content\"]): string {\n if (!content) {\n return \"\";\n }\n\n if (typeof content === \"string\") {\n return content;\n }\n\n return content\n .map((part) => {\n if (\n part &&\n typeof part === \"object\" &&\n \"type\" in part &&\n (part as { type?: unknown }).type === \"text\" &&\n typeof (part as { text?: unknown }).text === \"string\"\n ) {\n return (part as { text: string }).text;\n }\n return \"\";\n })\n .filter((text) => text.length > 0)\n .join(\"\\n\");\n}\n\ntype MediaPart =\n | ImageInputPart\n | AudioInputPart\n | VideoInputPart\n | DocumentInputPart;\n\nfunction getMediaParts(content: UserMessage[\"content\"]): MediaPart[] {\n if (!content || typeof content === \"string\") return [];\n return content.filter(\n (part): part is MediaPart =>\n part.type === \"image\" ||\n part.type === \"audio\" ||\n part.type === \"video\" ||\n part.type === \"document\",\n );\n}\n\nfunction getFilename(part: MediaPart): string | undefined {\n const meta = part.metadata;\n if (\n meta != null &&\n typeof meta === \"object\" &&\n \"filename\" in meta &&\n typeof meta.filename === \"string\"\n ) {\n return meta.filename;\n }\n return undefined;\n}\n\nexport interface CopilotChatUserMessageOnEditMessageProps {\n message: UserMessage;\n}\n\nexport interface CopilotChatUserMessageOnSwitchToBranchProps {\n message: UserMessage;\n branchIndex: number;\n numberOfBranches: number;\n}\n\nexport type CopilotChatUserMessageProps = WithSlots<\n {\n messageRenderer: typeof CopilotChatUserMessage.MessageRenderer;\n toolbar: typeof CopilotChatUserMessage.Toolbar;\n copyButton: typeof CopilotChatUserMessage.CopyButton;\n editButton: typeof CopilotChatUserMessage.EditButton;\n branchNavigation: typeof CopilotChatUserMessage.BranchNavigation;\n },\n {\n onEditMessage?: (props: CopilotChatUserMessageOnEditMessageProps) => void;\n onSwitchToBranch?: (\n props: CopilotChatUserMessageOnSwitchToBranchProps,\n ) => void;\n message: UserMessage;\n branchIndex?: number;\n numberOfBranches?: number;\n additionalToolbarItems?: React.ReactNode;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\nexport function CopilotChatUserMessage({\n message,\n onEditMessage,\n branchIndex,\n numberOfBranches,\n onSwitchToBranch,\n additionalToolbarItems,\n messageRenderer,\n toolbar,\n copyButton,\n editButton,\n branchNavigation,\n children,\n className,\n ...props\n}: CopilotChatUserMessageProps) {\n const flattenedContent = useMemo(\n () => flattenUserMessageContent(message.content),\n [message.content],\n );\n\n const mediaParts = useMemo(\n () => getMediaParts(message.content),\n [message.content],\n );\n\n const BoundMessageRenderer = renderSlot(\n messageRenderer,\n CopilotChatUserMessage.MessageRenderer,\n {\n content: flattenedContent,\n },\n );\n\n const BoundCopyButton = renderSlot(\n copyButton,\n CopilotChatUserMessage.CopyButton,\n {\n onClick: async () => {\n if (flattenedContent) {\n 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: unknown = 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 type { Suggestion } from \"@copilotkit/core\";\nimport type { WithSlots } from \"../../lib/slots\";\nimport { renderSlot } from \"../../lib/slots\";\nimport { cn } from \"../../lib/utils\";\nimport type { CopilotChatSuggestionPillProps } from \"./CopilotChatSuggestionPill\";\nimport CopilotChatSuggestionPill 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:@3xl: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 * Layout: a glassmorphism pill (the `__chrome` layer) wrapping an icon\n * and a label. The icon is two overlaid SVG paths — a spinner arc and a\n * checkmark — whose geometry lives in each path's `d` ATTRIBUTE so it\n * renders in every browser (the CSS `d:` property is Chrome-only).\n *\n * Two states, driven by the `data-status` attribute (see globals.css\n * for the exact timing):\n * 1. **In-progress.** The arc spins (CSS rotation) inside the pill and\n * the checkmark is hidden. Label + icon are a saturated purple.\n * 2. **Finished.** The arc fades out mid-spin while the checkmark draws\n * itself in upright (animated `stroke-dashoffset`); the pill chrome\n * fades away; and the label + icon settle from purple to a neutral\n * gray, with the label slanting slightly (a `transform: skewX`\n * faux-italic, so it interpolates with the color instead of snapping\n * and never reflows). The result reads as quiet \"history metadata\"\n * rather than an active spinner. The label text itself never changes\n * — the static check plus the color/slant shift carry the \"done\"\n * meaning, so no wording change is needed.\n *\n * All motion is gated behind `prefers-reduced-motion` (globals.css):\n * when reduced motion is requested the arc does not spin and the two\n * states swap instantly, without transitions.\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 {/* Two overlaid paths whose geometry lives in the `d`\n ATTRIBUTE (works in every browser — the CSS `d:` property\n is Blink-only, so a stylesheet-driven `d` renders nothing\n in Safari/Firefox). Both paths set `pathLength={1}` so the\n stylesheet can express dashes as plain fractions of the\n shape. The arc is a full circle shown as a partial ring by\n its dash pattern; it spins while in-progress (CSS) and on\n the status flip fades out mid-spin while the checkmark\n draws itself in (see globals.css). */}\n <path\n className=\"cpk-intelligence-indicator__icon-arc\"\n pathLength={1}\n d=\"M 12 3 C 17 3 21 7 21 12 C 21 17 17 21 12 21 C 7 21 3 17 3 12 C 3 7 7 3 12 3\"\n />\n <path\n className=\"cpk-intelligence-indicator__icon-check\"\n pathLength={1}\n d=\"M 5 12.5 L 9 16.5 L 19 6.5\"\n />\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 */\n/**\n * Collapse tool calls that share an id, keeping first-seen order.\n *\n * AG-UI's TOOL_CALL_START handler appends to the parent message's `toolCalls`\n * without checking whether that id is already present. So whenever a start\n * event is applied twice — which the human-in-the-loop flow triggers when the\n * run syncs after `respond()` — the message ends up carrying the same call\n * twice. The second copy has EMPTY `arguments`, because a start event carries\n * none; the args arrive later as TOOL_CALL_ARGS deltas addressed to the first\n * copy.\n *\n * Left alone that renders the same tool call twice: once populated and once\n * blank (an approval card with no transaction id, offering live buttons for an\n * action already taken), and React warns \"Encountered two children with the\n * same key\" because the call id is the render key.\n *\n * The empty copy is the redundant one, so prefer whichever entry actually\n * carries arguments rather than blindly taking the first.\n */\nfunction dedupeToolCalls(\n toolCalls: NonNullable<AssistantMessage[\"toolCalls\"]>,\n): NonNullable<AssistantMessage[\"toolCalls\"]> {\n const byId = new Map<string, (typeof toolCalls)[number]>();\n for (const toolCall of toolCalls) {\n const existing = byId.get(toolCall.id);\n if (!existing) {\n byId.set(toolCall.id, toolCall);\n continue;\n }\n if (!existing.function?.arguments && toolCall.function?.arguments) {\n byId.set(toolCall.id, toolCall);\n }\n }\n return byId.size === toolCalls.length ? toolCalls : [...byId.values()];\n}\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: toolCalls ? dedupeToolCalls(toolCalls) : toolCalls,\n } as AssistantMessage);\n } else if (message.role === \"assistant\" && message.toolCalls) {\n // Duplicate call ids also arrive on a message that was never itself\n // duplicated, so this cannot live in the merge branch above.\n acc.set(message.id, {\n ...message,\n toolCalls: dedupeToolCalls(message.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\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\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 // As content below the anchored user message changes, adjust the spacer by\n // the same amount so total scrollable space below the bubble stays\n // constant and the bubble stays pinned.\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 spacerEl.style.height = `${remaining}px`;\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 } & Omit<React.HTMLAttributes<HTMLDivElement>, \"inputMode\">\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:@3xl: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:@container 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:@container 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:@3xl: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<HTMLDivElement | 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:@3xl: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<HTMLDivElement | 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 = nonAutoScrollEl;\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 }, [nonAutoScrollEl, 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:@3xl: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:@3xl: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 {\n CopilotKitCoreRuntimeConnectionStatus,\n isRunCompletionAware,\n ɵcreateThreadStore,\n} from \"@copilotkit/core\";\nimport type { ɵThreadRuntimeContext, ɵThreadStore } from \"@copilotkit/core\";\nimport React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { useCopilotKit, useLicenseContext } from \"../../context\";\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, isReady } = 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 const activeConnectCountRef = useRef(0);\n const pendingRunActivityReconnectRef = useRef(false);\n const runActivityReconnectGenerationRef = useRef(0);\n const activeLocalRunIdsRef = useRef<Set<string>>(new Set());\n const recentlyLocalRunIdsRef = useRef<\n Map<string, ReturnType<typeof setTimeout>>\n >(new Map());\n const activeWakeRunIdsRef = useRef<Set<string>>(new Set());\n const recentlyWakeRunIdsRef = useRef<\n Map<string, ReturnType<typeof setTimeout>>\n >(new Map());\n const pendingWakeRunIdRef = useRef<string | undefined>(undefined);\n const startRunActivityReconnectRef = useRef<\n ((generation: number) => void) | null\n >(null);\n const runtimeStatus =\n copilotkit.runtimeConnectionStatus ===\n CopilotKitCoreRuntimeConnectionStatus.Connected\n ? \"Connected\"\n : copilotkit.runtimeConnectionStatus;\n const hasNativeIntelligenceRunActivity =\n hasExplicitThreadId &&\n runtimeStatus === \"Connected\" &&\n !!copilotkit.intelligence?.wsUrl &&\n copilotkit.threadEndpoints?.realtimeMetadata === true;\n const [standaloneRunActivityStore] = useState<ɵThreadStore>(() =>\n ɵcreateThreadStore({\n fetch: globalThis.fetch,\n }),\n );\n\n // Tracks the threadId the connect effect last ran for, so it can tell a real\n // thread SWITCH from an incidental re-render (agent identity change, etc.).\n const previousThreadIdRef = useRef<string | null>(null);\n\n // Latest explicitness, readable from an async connect that may resolve after\n // the user has already switched threads (see the stale-connect guard below).\n const hasExplicitThreadIdRef = useRef(hasExplicitThreadId);\n hasExplicitThreadIdRef.current = hasExplicitThreadId;\n\n const rememberRecentlyLocalRunId = useCallback((runId: string) => {\n const existingTimeout = recentlyLocalRunIdsRef.current.get(runId);\n if (existingTimeout) {\n clearTimeout(existingTimeout);\n }\n\n const timeout = setTimeout(() => {\n recentlyLocalRunIdsRef.current.delete(runId);\n }, 30_000);\n recentlyLocalRunIdsRef.current.set(runId, timeout);\n }, []);\n\n const rememberRecentlyWakeRunId = useCallback((runId: string) => {\n const existingTimeout = recentlyWakeRunIdsRef.current.get(runId);\n if (existingTimeout) {\n clearTimeout(existingTimeout);\n }\n\n const timeout = setTimeout(() => {\n recentlyWakeRunIdsRef.current.delete(runId);\n }, 30_000);\n recentlyWakeRunIdsRef.current.set(runId, timeout);\n }, []);\n\n const isLocalActiveRunActivity = useCallback(\n (notification: { agentId?: string; runId?: string; eventType: string }) => {\n if (notification.agentId && notification.agentId !== resolvedAgentId) {\n return false;\n }\n if (\n !notification.runId ||\n (!activeLocalRunIdsRef.current.has(notification.runId) &&\n !recentlyLocalRunIdsRef.current.has(notification.runId))\n ) {\n return false;\n }\n\n const eventType = notification.eventType.toUpperCase();\n return (\n eventType === \"RUN_STARTED\" ||\n eventType === \"RUN_FINISHED\" ||\n eventType === \"RUN_ERROR\"\n );\n },\n [resolvedAgentId],\n );\n\n useEffect(() => {\n const recentlyLocalRunIds = recentlyLocalRunIdsRef.current;\n const recentlyWakeRunIds = recentlyWakeRunIdsRef.current;\n return () => {\n recentlyLocalRunIds.forEach((timeout) => {\n clearTimeout(timeout);\n });\n recentlyLocalRunIds.clear();\n recentlyWakeRunIds.forEach((timeout) => {\n clearTimeout(timeout);\n });\n recentlyWakeRunIds.clear();\n };\n }, []);\n\n useEffect(() => {\n const threadChanged = previousThreadIdRef.current !== resolvedThreadId;\n previousThreadIdRef.current = resolvedThreadId;\n\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) {\n // Switching to a fresh, non-backend thread (e.g. startNewThread / the\n // drawer's \"+ New\"): there are no messages to /connect for, so drop any\n // messages carried over from the previously-viewed thread and fall back\n // to the welcome screen. Guard on an actual threadId change so re-renders\n // of the current thread (including its first run) never wipe an\n // in-progress conversation.\n if (threadChanged && agent.messages.length > 0) {\n agent.setMessages([]);\n }\n return;\n }\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 activeConnectCountRef.current += 1;\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 } else if (!hasExplicitThreadIdRef.current) {\n // This connect was superseded (the user switched away while it was\n // still loading). If the now-current thread is a fresh non-explicit\n // one (e.g. the drawer's \"+ New\"), any snapshot this connect managed\n // to apply is stale — clear it so the welcome screen shows instead of\n // the abandoned thread's messages. A switch to ANOTHER explicit thread\n // is left alone: that thread's own connect owns the message reset.\n agentToConnect.setMessages([]);\n }\n activeConnectCountRef.current = Math.max(\n 0,\n activeConnectCountRef.current - 1,\n );\n if (!detached && activeConnectCountRef.current === 0) {\n const startReconnect = startRunActivityReconnectRef.current;\n if (pendingRunActivityReconnectRef.current && startReconnect) {\n pendingRunActivityReconnectRef.current = false;\n startReconnect(runActivityReconnectGenerationRef.current);\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 useEffect(() => {\n if (!hasNativeIntelligenceRunActivity) return;\n\n const registeredThreadStore = copilotkit.getThreadStore(resolvedAgentId);\n const threadStore = registeredThreadStore ?? standaloneRunActivityStore;\n if (!threadStore?.subscribeToRunActivity) return;\n const ownsStandaloneStore = registeredThreadStore === undefined;\n if (ownsStandaloneStore) {\n threadStore.start();\n const context: ɵThreadRuntimeContext | null = copilotkit.runtimeUrl\n ? {\n runtimeUrl: copilotkit.runtimeUrl,\n headers: { ...copilotkit.headers },\n wsUrl: copilotkit.intelligence?.wsUrl,\n agentId: resolvedAgentId,\n }\n : null;\n threadStore.setContext(context);\n }\n\n const generation = runActivityReconnectGenerationRef.current + 1;\n runActivityReconnectGenerationRef.current = generation;\n let detached = false;\n let wakeReconnectActive = false;\n let pendingAgentIdleDrain: ReturnType<typeof setTimeout> | null = null;\n const hasActiveAgentRun = () =>\n activeLocalRunIdsRef.current.size > 0 || agent.isRunning;\n const scheduleAgentIdleDrain = () => {\n if (pendingAgentIdleDrain !== null) return;\n pendingAgentIdleDrain = setTimeout(() => {\n pendingAgentIdleDrain = null;\n if (\n detached ||\n runActivityReconnectGenerationRef.current !== generation ||\n !pendingRunActivityReconnectRef.current\n ) {\n return;\n }\n if (hasActiveAgentRun()) {\n scheduleAgentIdleDrain();\n return;\n }\n startRunActivityReconnectRef.current?.(generation);\n }, 10);\n };\n\n const connect = async () => {\n activeConnectCountRef.current += 1;\n wakeReconnectActive = true;\n const wakeRunId = pendingWakeRunIdRef.current;\n pendingWakeRunIdRef.current = undefined;\n if (wakeRunId) {\n activeWakeRunIdsRef.current.add(wakeRunId);\n }\n let didConnect = false;\n try {\n await copilotkit.connectAgent({ agent });\n didConnect = true;\n } catch (error) {\n if (!detached) {\n console.error(\"CopilotChat: run activity reconnect failed\", error);\n }\n } finally {\n if (wakeRunId) {\n activeWakeRunIdsRef.current.delete(wakeRunId);\n if (didConnect) {\n rememberRecentlyWakeRunId(wakeRunId);\n }\n }\n activeConnectCountRef.current = Math.max(\n 0,\n activeConnectCountRef.current - 1,\n );\n wakeReconnectActive = false;\n const canDrainPendingReconnect =\n !detached &&\n runActivityReconnectGenerationRef.current === generation &&\n activeConnectCountRef.current === 0;\n\n if (\n canDrainPendingReconnect &&\n pendingRunActivityReconnectRef.current\n ) {\n pendingRunActivityReconnectRef.current = false;\n connect();\n }\n }\n };\n\n startRunActivityReconnectRef.current = (requestedGeneration) => {\n if (\n detached ||\n requestedGeneration !== generation ||\n runActivityReconnectGenerationRef.current !== generation\n ) {\n return;\n }\n if (hasActiveAgentRun()) {\n pendingRunActivityReconnectRef.current = true;\n scheduleAgentIdleDrain();\n return;\n }\n if (activeConnectCountRef.current > 0) {\n if (!wakeReconnectActive) {\n pendingRunActivityReconnectRef.current = true;\n }\n return;\n }\n pendingRunActivityReconnectRef.current = false;\n connect();\n };\n\n const subscription = threadStore.subscribeToRunActivity((notification) => {\n if (notification.threadId !== resolvedThreadId) return;\n if (notification.agentId && notification.agentId !== resolvedAgentId) {\n return;\n }\n if (isLocalActiveRunActivity(notification)) return;\n if (\n notification.runId &&\n (activeWakeRunIdsRef.current.has(notification.runId) ||\n recentlyWakeRunIdsRef.current.has(notification.runId))\n ) {\n return;\n }\n pendingWakeRunIdRef.current = notification.runId;\n startRunActivityReconnectRef.current?.(generation);\n });\n\n return () => {\n detached = true;\n pendingRunActivityReconnectRef.current = false;\n pendingWakeRunIdRef.current = undefined;\n if (pendingAgentIdleDrain !== null) {\n clearTimeout(pendingAgentIdleDrain);\n pendingAgentIdleDrain = null;\n }\n if (startRunActivityReconnectRef.current) {\n startRunActivityReconnectRef.current = null;\n }\n if (wakeReconnectActive) {\n agent.detachActiveRun().catch(() => {});\n }\n activeWakeRunIdsRef.current.clear();\n subscription.unsubscribe();\n if (ownsStandaloneStore) {\n threadStore.setContext(null);\n threadStore.stop();\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 }, [\n agent,\n resolvedAgentId,\n resolvedThreadId,\n hasExplicitThreadId,\n hasNativeIntelligenceRunActivity,\n copilotkit.runtimeConnectionStatus,\n copilotkit.runtimeUrl,\n copilotkit.headers,\n copilotkit.intelligence?.wsUrl,\n copilotkit.threadEndpoints?.realtimeMetadata,\n standaloneRunActivityStore,\n isLocalActiveRunActivity,\n rememberRecentlyWakeRunId,\n ]);\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 // Widen to `unknown` before the guard: narrowing `AbstractAgent` directly\n // would intersect with its PRIVATE `activeRunCompletionPromise` declaration\n // and collapse the narrowed type to `never`.\n const maybeAware: unknown = agent;\n const activeRunCompletionPromise = isRunCompletionAware(maybeAware)\n ? maybeAware.activeRunCompletionPromise\n : undefined;\n if (agent.isRunning && activeRunCompletionPromise) {\n try {\n await 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 const localRunId = hasNativeIntelligenceRunActivity\n ? randomUUID()\n : undefined;\n if (localRunId) {\n activeLocalRunIdsRef.current.add(localRunId);\n }\n\n try {\n await copilotkit.runAgent({\n agent,\n ...(localRunId !== undefined ? { runId: localRunId } : {}),\n });\n } catch (error) {\n console.error(\"CopilotChat: runAgent failed\", error);\n } finally {\n if (localRunId) {\n activeLocalRunIdsRef.current.delete(localRunId);\n rememberRecentlyLocalRunId(localRunId);\n }\n if (\n pendingRunActivityReconnectRef.current &&\n activeLocalRunIdsRef.current.size === 0 &&\n activeConnectCountRef.current === 0\n ) {\n const startReconnect = startRunActivityReconnectRef.current;\n if (startReconnect) {\n pendingRunActivityReconnectRef.current = false;\n startReconnect(runActivityReconnectGenerationRef.current);\n }\n }\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 [\n agent,\n consumeAttachments,\n waitForActiveRunToSettle,\n hasNativeIntelligenceRunActivity,\n rememberRecentlyLocalRunId,\n ],\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 const localRunId = hasNativeIntelligenceRunActivity\n ? randomUUID()\n : undefined;\n if (localRunId) {\n activeLocalRunIdsRef.current.add(localRunId);\n }\n\n try {\n await copilotkit.runAgent({\n agent,\n ...(localRunId !== undefined ? { runId: localRunId } : {}),\n });\n } catch (error) {\n console.error(\n \"CopilotChat: runAgent failed after selecting suggestion\",\n error,\n );\n } finally {\n if (localRunId) {\n activeLocalRunIdsRef.current.delete(localRunId);\n rememberRecentlyLocalRunId(localRunId);\n }\n if (\n pendingRunActivityReconnectRef.current &&\n activeLocalRunIdsRef.current.size === 0 &&\n activeConnectCountRef.current === 0\n ) {\n const startReconnect = startRunActivityReconnectRef.current;\n if (startReconnect) {\n pendingRunActivityReconnectRef.current = false;\n startReconnect(runActivityReconnectGenerationRef.current);\n }\n }\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [\n agent,\n waitForActiveRunToSettle,\n hasNativeIntelligenceRunActivity,\n rememberRecentlyLocalRunId,\n ],\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 // HIDE suggestion pills until the runtime is ready, mirroring the\n // `onSubmitMessage` gate below. Static `available:\"always\"` pills render\n // during the provisional window (before `/info` swaps the real agent in),\n // so a click before `isReady` would commit `suggestion.message` to the\n // doomed provisional agent and run against it — the same empty-assistant\n // loss the typed-message gate prevents. Withholding `onSelectSuggestion`\n // alone leaves the pill VISUALLY ENABLED but inert (a click silently drops\n // the user's intent), so instead we do not surface the pills at all until\n // the real agent is bound: passing an empty list keeps `hasSuggestions`\n // false in the view (the same mechanism that hides pills while connecting /\n // running). Once `isReady` flips true the real suggestions appear and the\n // handler goes live. The `onSelectSuggestion` gate is retained as\n // defense-in-depth for any custom chatView slot that renders its own pills.\n suggestions: isReady ? autoSuggestions : [],\n onSelectSuggestion: isReady ? handleSelectSuggestion : undefined,\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 // - object content for activity messages (ACTIVITY_SNAPSHOT replace keeps\n // the same message id; a length-based key is always 0 for objects and\n // freezes generative-UI / progress renderers on the first frame)\n // Multimodal attachments stay on the array branch (part count only), so this\n // does not reintroduce base64 serialization for user uploads.\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 : m.content && typeof m.content === \"object\"\n ? JSON.stringify(m.content)\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 // Gate submission on runtime readiness. While `isReady` is false the\n // `agent` returned by useAgent is a provisional stand-in that `/info` will\n // swap out; a message committed to it (and the composer cleared) is lost\n // on that swap, surfacing as an empty assistant response. Withholding\n // `onSubmitMessage` disables the send control (canSend keys off it) and\n // makes Enter a no-op that preserves the composer text until the real\n // agent is bound.\n onSubmitMessage: isReady ? onSubmitInput : undefined,\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, useEffect, useState } from \"react\";\n\nimport { cn } from \"../../lib/utils\";\nimport {\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"../../providers/CopilotChatConfigurationProvider\";\nimport type { WithSlots } from \"../../lib/slots\";\nimport { renderSlot } from \"../../lib/slots\";\nimport { PanelLeftOpen, X } from \"lucide-react\";\n\ntype HeaderSlots = {\n titleContent: typeof CopilotModalHeader.Title;\n closeButton: typeof CopilotModalHeader.CloseButton;\n drawerLauncher: typeof CopilotModalHeader.DrawerLauncher;\n};\n\ntype HeaderRestProps = {\n title?: string;\n} & Omit<React.HTMLAttributes<HTMLDivElement>, \"children\">;\n\n/**\n * Payload handed to the optional `children` render function. `drawerLauncher`\n * is nullable because the launcher is rendered only when a drawer has\n * registered — when none is present, custom layouts receive `null` and can omit\n * the launcher slot entirely.\n */\ntype HeaderChildrenPayload = {\n titleContent: React.ReactElement;\n closeButton: React.ReactElement;\n drawerLauncher: React.ReactElement | null;\n title?: string;\n} & Omit<HeaderRestProps, \"title\">;\n\nexport type CopilotModalHeaderProps = Omit<\n WithSlots<HeaderSlots, HeaderRestProps>,\n \"children\"\n> & {\n children?: (props: HeaderChildrenPayload) => React.ReactNode;\n};\n\n/**\n * Reactively tracks whether the viewport is in the mobile range (≤767px) — the\n * same breakpoint the drawer + chat coordination use. SSR-safe: starts `false`\n * (desktop) so the server render and first client render agree, then syncs on\n * mount and on resize.\n */\nfunction useIsMobileViewport(): boolean {\n const [isMobile, setIsMobile] = useState(false);\n useEffect(() => {\n if (\n typeof window === \"undefined\" ||\n typeof window.matchMedia !== \"function\"\n ) {\n return;\n }\n const mql = window.matchMedia(\"(max-width: 767px)\");\n const update = () => setIsMobile(mql.matches);\n update();\n mql.addEventListener(\"change\", update);\n return () => mql.removeEventListener(\"change\", update);\n }, []);\n return isMobile;\n}\n\nexport function CopilotModalHeader({\n title,\n titleContent,\n closeButton,\n drawerLauncher,\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 // The thread-list launcher renders ONLY when a <CopilotThreadsDrawer> wrapper has\n // registered with the chat configuration AND the viewport is mobile. On\n // desktop the drawer is an in-flow, persistent panel (it ignores `open`), so\n // an \"open the drawer\" launcher there is a dead no-op — it only does anything\n // for the mobile off-canvas drawer. Chats with no drawer get no launcher and\n // no behavior change.\n const isMobile = useIsMobileViewport();\n const drawerRegistered =\n (configuration?.drawerRegistered ?? false) && isMobile;\n\n const handleClose = useCallback(() => {\n configuration?.setModalOpen?.(false);\n }, [configuration]);\n\n const handleToggleDrawer = useCallback(() => {\n configuration?.setDrawerOpen?.(!configuration.drawerOpen);\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 // Only bind the launcher slot when a drawer is registered. When no drawer is\n // present, `BoundDrawerLauncher` is null and nothing is rendered.\n const BoundDrawerLauncher = drawerRegistered\n ? renderSlot(drawerLauncher, CopilotModalHeader.DrawerLauncher, {\n onClick: handleToggleDrawer,\n \"aria-expanded\": configuration?.drawerOpen ?? false,\n })\n : null;\n\n if (children) {\n return children({\n titleContent: BoundTitle,\n closeButton: BoundCloseButton,\n drawerLauncher: BoundDrawerLauncher,\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 cpk:flex-1 cpk:justify-start\">\n {BoundDrawerLauncher ?? <span aria-hidden=\"true\" />}\n </div>\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 /**\n * The thread-list launcher button. Rendered in the header ONLY when a\n * `<CopilotThreadsDrawer>` wrapper has registered with the chat configuration; it\n * toggles the drawer open state. The stable `data-testid` is the focus-return\n * target for the drawer wrapper on cancel/back/backdrop/Escape.\n */\n export const DrawerLauncher: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, ...props }) => (\n <button\n type=\"button\"\n data-testid=\"copilot-threads-drawer-launcher\"\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=\"Open threads\"\n {...props}\n >\n <PanelLeftOpen 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\";\nCopilotModalHeader.DrawerLauncher.displayName =\n \"CopilotModalHeader.DrawerLauncher\";\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, { useContext, useEffect, useMemo } from \"react\";\nimport { useLicenseContext } from \"../../providers/CopilotKitProvider\";\nimport { InlineFeatureWarning } from \"../license-warning-banner\";\n\nimport type { CopilotChatProps } from \"./CopilotChat\";\nimport { CopilotChat } from \"./CopilotChat\";\nimport type { CopilotChatViewProps } from \"./CopilotChatView\";\nimport CopilotChatView from \"./CopilotChatView\";\nimport type { CopilotPopupViewProps } from \"./CopilotPopupView\";\nimport CopilotPopupView from \"./CopilotPopupView\";\n\n/**\n * Carries the popup shell props (header, toggle, width, height, …) to the\n * chatView override without baking them into the override's component\n * identity. Width/height change on every resize; if they were `useMemo`\n * dependencies of the override component, each change would mint a new\n * component function, and rendering a new element *type* makes React unmount\n * and remount the entire chat subtree — resetting scrollTop to 0 and firing\n * `initial=\"smooth\"`, which visibly scrolls the message list from top to\n * bottom on every resize. Routing them through context keeps the override\n * identity stable (no remount) while still re-rendering CopilotPopupView with\n * the new dimensions on change.\n */\ntype PopupShellProps = {\n header?: CopilotPopupViewProps[\"header\"];\n toggleButton?: CopilotPopupViewProps[\"toggleButton\"];\n width?: CopilotPopupViewProps[\"width\"];\n height?: CopilotPopupViewProps[\"height\"];\n clickOutsideToClose?: CopilotPopupViewProps[\"clickOutsideToClose\"];\n defaultOpen?: boolean;\n};\n\nconst PopupShellPropsContext = React.createContext<PopupShellProps>({});\n\n// Stable override component. Its identity never changes, so the chat subtree\n// is never remounted on resize. Popup props flow in via context, so changing\n// width/height re-renders CopilotPopupView (a style update) instead.\nconst PopupViewOverride: 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 const shell = useContext(PopupShellPropsContext);\n\n return (\n <CopilotPopupView\n {...(restProps as CopilotPopupViewProps)}\n header={shell.header ?? viewHeader}\n toggleButton={shell.toggleButton ?? viewToggleButton}\n width={shell.width ?? viewWidth}\n height={shell.height ?? viewHeight}\n clickOutsideToClose={shell.clickOutsideToClose ?? viewClickOutsideToClose}\n defaultOpen={shell.defaultOpen ?? viewDefaultOpen}\n />\n );\n};\n\n// Preserve the static slot members (WelcomeScreen, etc.) that callers reach\n// through the CopilotChatView namespace. The cast restores those statics on\n// the type after Object.assign, matching the shape CopilotChat's `chatView`\n// slot expects (typeof CopilotChatView).\nconst PopupViewOverrideWithStatics = Object.assign(\n PopupViewOverride,\n CopilotChatView,\n) as typeof CopilotChatView;\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 shellProps = useMemo<PopupShellProps>(\n () => ({\n header,\n toggleButton,\n width,\n height,\n clickOutsideToClose,\n defaultOpen,\n }),\n [clickOutsideToClose, header, toggleButton, height, width, defaultOpen],\n );\n\n return (\n <>\n {!isPopupLicensed && <InlineFeatureWarning featureName=\"Popup\" />}\n <PopupShellPropsContext.Provider value={shellProps}>\n <CopilotChat\n welcomeScreen={CopilotPopupView.WelcomeScreen}\n {...chatProps}\n isModalDefaultOpen={defaultOpen}\n chatView={PopupViewOverrideWithStatics}\n />\n </PopupShellPropsContext.Provider>\n </>\n );\n}\n\nCopilotPopup.displayName = \"CopilotPopup\";\n\nexport default CopilotPopup;\n","\"use client\";\n\nimport React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n defineCopilotKitThreadsDrawer,\n COPILOTKIT_THREADS_DRAWER_TAG,\n} from \"@copilotkit/web-components/threads-drawer\";\nimport type {\n CopilotKitThreadsDrawer as CopilotKitThreadsDrawerElement,\n DrawerThread,\n ThreadSelectedDetail,\n ArchiveDetail,\n UnarchiveDetail,\n DeleteDetail,\n OpenChangeDetail,\n RetryDetail,\n} from \"@copilotkit/web-components/threads-drawer\";\n// TODO(ENT-1051): import `CollapseChangeDetail` from\n// \"@copilotkit/web-components/threads-drawer\" once the parallel element PR that\n// adds the collapse feature (property `collapsible` + event `collapse-change`)\n// lands and is published; declared locally here because the built element types\n// in this worktree predate it.\ntype CollapseChangeDetail = { collapsed: boolean };\nimport { DEFAULT_AGENT_ID } from \"@copilotkit/shared\";\nimport { useThreads } from \"../../hooks/use-threads\";\nimport type { Thread } from \"../../hooks/use-threads\";\nimport { useLicenseContext } from \"../../providers/CopilotKitProvider\";\nimport { useCopilotChatConfiguration } from \"../../providers/CopilotChatConfigurationProvider\";\n\n/**\n * Per-row content render function. Receives a thread and returns the React\n * node to project into the element's `slot=\"row:{id}\"`. Returning `null`\n * (or omitting the prop) falls back to the element's built-in row name.\n */\nexport type CopilotThreadsDrawerRowRenderer = (\n thread: Thread,\n) => React.ReactNode;\n\n/**\n * Props for {@link CopilotThreadsDrawer}.\n *\n * The drawer is a thin controller around the framework-agnostic\n * `<copilotkit-threads-drawer>` custom element. It feeds the element domain data\n * (threads/loading/error from {@link useThreads}, the active thread from the\n * chat configuration) and routes the element's outbound DOM events back into\n * core thread operations and chat-configuration changes.\n */\nexport interface CopilotThreadsDrawerProps {\n /**\n * The agent whose threads to list and manage. Defaults to the agent of the\n * surrounding chat configuration, or the platform default when none is set.\n */\n agentId?: string;\n /**\n * Optional escape-hatch called when the user picks a thread row. The wrapper\n * additionally focuses the chat input. When omitted, the wrapper drives the\n * surrounding chat configuration directly (`setActiveThreadId`), so a bare\n * `<CopilotThreadsDrawer>` switches the rendered thread with no host wiring. Provide\n * this only to take control of the active thread yourself (e.g. a v1\n * `setThreadId`); when provided it is preferred over the provider.\n */\n onThreadSelect?: (threadId: string) => void;\n /**\n * Optional escape-hatch called when the user starts a new thread (the\n * element's \"+ New\" button). The wrapper always resets the core thread store\n * to a fresh, non-explicit client-side thread (`startNewThread`). When this\n * is omitted, the wrapper also resets the surrounding chat configuration to a\n * fresh non-explicit thread (`startNewThread`) so the welcome screen shows\n * with no host wiring. Provide this only to clear your own active thread;\n * when provided it is preferred over the provider.\n */\n onNewThread?: () => void;\n /** Called when the Upgrade CTA is clicked. */\n onLicensed?: () => void;\n /**\n * Destination the locked view's Upgrade CTA opens in a new tab. Defaults to\n * the element's built-in CopilotKit Intelligence docs URL when omitted. Set\n * to an empty string to suppress the default navigation and handle the click\n * yourself via `onLicensed`.\n */\n licenseUrl?: string;\n /**\n * Optional per-row content. Rendered as light-DOM children with\n * `slot=\"row:{id}\"` so the element projects them in place of the default\n * row name. Return `null` for a given row to keep the element's default.\n */\n renderRow?: CopilotThreadsDrawerRowRenderer;\n /**\n * Accessible + default-header label for the drawer region. Sets the custom\n * element's `aria-label` and the default header text (shown when no\n * `slot=\"header\"` content is projected). Defaults to the element's built-in\n * `\"Threads\"` when omitted.\n */\n label?: string;\n /**\n * Heading for the \"Recent Conversations\" section above the thread list. Sets\n * the custom element's `recent-label` attribute. Defaults to the element's\n * built-in `\"Recent Conversations\"` when omitted.\n */\n recentLabel?: string;\n /**\n * Whether the drawer offers a collapse toggle. Sets the custom element's\n * `collapsible` PROPERTY. When `false`, the drawer has no collapse toggle and\n * is always expanded. Defaults to the element's built-in `true` when omitted.\n */\n collapsible?: boolean;\n /**\n * Called when the drawer's collapsed state changes (via the element's collapse\n * toggle), with the new collapsed state. Mirrors the element's\n * `collapse-change` event.\n */\n onCollapseChange?: (collapsed: boolean) => void;\n /**\n * Page size for thread pagination. When set, threads are fetched in pages of\n * this size and the drawer shows a \"Load more\" control while more remain.\n * When omitted, the full list loads at once and no pagination control shows.\n */\n limit?: number;\n /**\n * `data-testid` set on the underlying custom element (handy in tests and for\n * targeting from a host page). Defaults to `\"copilot-threads-drawer\"`.\n */\n \"data-testid\"?: string;\n}\n\n/**\n * Maps a {@link Thread} from {@link useThreads} to the element's\n * {@link DrawerThread} view shape. The shapes are structurally compatible; this\n * narrows to exactly the fields the element renders so the element never sees\n * platform-internal fields.\n */\nfunction toDrawerThread(thread: Thread): DrawerThread {\n return {\n id: thread.id,\n name: thread.name,\n archived: thread.archived,\n createdAt: thread.createdAt,\n updatedAt: thread.updatedAt,\n ...(thread.lastRunAt !== undefined ? { lastRunAt: thread.lastRunAt } : {}),\n };\n}\n\n/** The chat input textarea's documented `data-testid`. */\nconst CHAT_INPUT_TESTID = \"copilot-chat-textarea\";\n/** The chat view container's documented `data-testid`. */\nconst CHAT_CONTAINER_TESTID = \"copilot-chat\";\n\n/**\n * Returns the chat input element for focus-return after a thread is selected.\n *\n * Best-effort and SCOPED: walks up from the drawer element looking for an\n * ancestor that contains a chat-view container (`data-testid=\"copilot-chat\"`),\n * then returns the chat input within that subtree. This avoids focusing the\n * wrong composer on a page hosting more than one chat (multi-chat dashboards),\n * where a document-global lookup would grab whichever input appears first in\n * DOM order rather than the one this drawer drives.\n *\n * Falls back to a document-global lookup when no scoping ancestor is found\n * (e.g. the drawer and chat share no common container, or headless usage),\n * and returns `null` when there is no chat input at all.\n *\n * @param origin - The drawer element to scope the search from.\n */\nfunction findChatInput(origin: Element | null): HTMLElement | null {\n if (typeof document === \"undefined\") return null;\n\n // The drawer lives inside (or alongside) its own chat-view container. Find the\n // nearest such container with `closest` and scope the input lookup to it, so a\n // page hosting multiple chats focuses THIS drawer's composer rather than\n // whichever input appears first in DOM order. Walking up by \"ancestor that\n // *contains* a chat\" would instead climb past the drawer's own container (which\n // holds no nested chat) to the shared root and grab the first chat on the page.\n const container = origin?.closest?.(\n `[data-testid=\"${CHAT_CONTAINER_TESTID}\"]`,\n );\n if (container) {\n const scoped = container.querySelector<HTMLElement>(\n `[data-testid=\"${CHAT_INPUT_TESTID}\"]`,\n );\n if (scoped) return scoped;\n }\n\n // No scoping container found (drawer and chat share no common container, or\n // headless usage): fall back to a document-global lookup.\n return document.querySelector<HTMLElement>(\n `[data-testid=\"${CHAT_INPUT_TESTID}\"]`,\n );\n}\n\n/**\n * React wrapper for the shadow-DOM `<copilotkit-threads-drawer>` threads drawer.\n *\n * Responsibilities:\n * - Registers the custom element on the client (SSR-safe; nothing renders\n * during prerender to avoid hydration mismatch).\n * - Feeds the element domain data: `threads`, `loading`, `error`,\n * `activeThreadId`, `licensed`, fetch-more state.\n * - Routes the element's outbound events to core thread operations\n * ({@link useThreads}) and chat-configuration changes.\n * - Registers with the surrounding chat configuration so the header\n * thread-list launcher appears, and binds the element `open` state to the\n * configuration's `drawerOpen`.\n *\n * License gating is two-pronged: the locked view shows when no license is configured\n * (the runtime reported no license status) OR the `threads` feature is\n * explicitly unlicensed. While unlicensed, the thread fetch is skipped entirely\n * so an unlicensed drawer issues no network requests.\n *\n * Thread switching needs no host wiring: when `onThreadSelect`/`onNewThread`\n * are omitted, the wrapper drives the surrounding chat configuration directly\n * ({@link CopilotChatConfigurationValue.setActiveThreadId} /\n * {@link CopilotChatConfigurationValue.startNewThread}), so a bare drawer\n * connects to the picked thread and shows the welcome screen on \"+ New\". Pass\n * the callbacks only to take control yourself.\n *\n * @example\n * ```tsx\n * // Callback-free: the drawer drives the chat configuration itself.\n * <CopilotKitProvider runtimeUrl=\"/api/copilotkit\" publicLicenseKey=\"ck_pub_...\">\n * <CopilotChat />\n * <CopilotThreadsDrawer />\n * </CopilotKitProvider>\n * ```\n */\nexport function CopilotThreadsDrawer({\n agentId,\n onThreadSelect,\n onNewThread,\n onLicensed,\n licenseUrl,\n renderRow,\n label,\n recentLabel,\n collapsible,\n onCollapseChange,\n limit,\n \"data-testid\": dataTestId = \"copilot-threads-drawer\",\n}: CopilotThreadsDrawerProps): React.ReactElement | null {\n const configuration = useCopilotChatConfiguration();\n const { status, checkFeature } = useLicenseContext();\n\n // Two-pronged license gate. `checkFeature` fails OPEN (returns true) when no\n // license is configured, so it cannot by itself detect the no-license case.\n // We therefore also require a positive license-present signal from the\n // runtime-reported status. Only a \"valid\" or \"expiring\" license is treated\n // as present; a resolved \"none\"/\"expired\"/\"invalid\" status gates the drawer\n // to the locked view.\n const licensePresent = status === \"valid\" || status === \"expiring\";\n const featureLicensed = checkFeature(\"threads\");\n const licensed = licensePresent && featureLicensed;\n\n // The runtime reports license status asynchronously: `status` is null until\n // the first /info response lands. Treat that pending window as \"not yet\n // unlicensed\" — show the loading state, never the locked view — so a licensed\n // drawer doesn't flash the upgrade CTA before its license resolves (and never\n // strands the CTA on screen when the status is slow or fails to arrive). Only\n // a RESOLVED-negative status (`none`/`expired`/`invalid`, or a present license\n // missing the `threads` feature) surfaces the locked view.\n const licensePending = status === null;\n\n const resolvedAgentId = agentId ?? configuration?.agentId ?? DEFAULT_AGENT_ID;\n const activeThreadId = configuration?.threadId ?? null;\n\n // While unlicensed, skip the thread fetch entirely: the element shows only\n // its locked view and no `/threads` request is issued.\n const {\n threads,\n isLoading,\n listError,\n fetchMoreError,\n hasMoreThreads,\n isFetchingMoreThreads,\n archiveThread,\n unarchiveThread,\n deleteThread,\n fetchMoreThreads,\n refetchThreads,\n startNewThread,\n } = useThreads({\n agentId: resolvedAgentId,\n includeArchived: true,\n enabled: licensed,\n ...(limit !== undefined ? { limit } : {}),\n });\n\n const drawerThreads = useMemo(() => threads.map(toDrawerThread), [threads]);\n\n const elementRef = useRef<CopilotKitThreadsDrawerElement | null>(null);\n\n // Register the custom element on the client only. `customElements` is absent\n // during SSR/prerender; gating the render below on `mounted` keeps the server\n // output empty so there is no hydration mismatch or layout shift.\n const [mounted, setMounted] = useState(false);\n useEffect(() => {\n defineCopilotKitThreadsDrawer();\n setMounted(true);\n }, []);\n\n // Announce presence to the surrounding chat configuration so the header\n // launcher renders; de-register on unmount. Depend on the stable\n // `registerDrawer` callback, NOT the whole `configuration` object — the\n // object's identity changes on every drawer/modal/label update, which would\n // otherwise churn register/de-register each render and momentarily drop\n // `drawerRegistered` (flickering the header launcher).\n const registerDrawer = configuration?.registerDrawer;\n useEffect(() => {\n if (!registerDrawer) return;\n return registerDrawer();\n }, [registerDrawer]);\n\n // Drive the chat configuration's drawerOpen from the element's open-change\n // event, and reflect drawerOpen back onto the element below.\n //\n // Provider-less fallback: without a surrounding chat configuration there is no\n // shared open-state to bind to, so the wrapper keeps its own local open-state.\n // It starts CLOSED — matching the provider's own `ownDrawerOpen` default of\n // `false` — so a bare `<CopilotThreadsDrawer>` does not render stuck-open and the\n // element's open-change events still toggle it.\n const [localDrawerOpen, setLocalDrawerOpen] = useState(false);\n const drawerOpen = configuration ? configuration.drawerOpen : localDrawerOpen;\n const setDrawerOpen = configuration\n ? configuration.setDrawerOpen\n : setLocalDrawerOpen;\n\n // --- Event handlers (stable via refs to the latest closures) -------------\n // The element is imperatively wired with addEventListener once; we keep the\n // latest handler implementations in a ref so listeners need not be re-bound\n // every render (which would churn on each thread/loading change).\n\n // Prefer the host callbacks when provided; otherwise drive the surrounding\n // chat configuration directly so a bare `<CopilotThreadsDrawer>` works callback-free.\n const setActiveThreadId = configuration?.setActiveThreadId;\n const startNewThreadConfig = configuration?.startNewThread;\n\n const handleThreadSelected = useCallback(\n (threadId: string) => {\n if (onThreadSelect) {\n onThreadSelect(threadId);\n } else {\n // Selecting a row is an explicit, caller-driven thread choice: connect\n // the chat to that backend thread (suppresses the welcome screen).\n setActiveThreadId?.(threadId, { explicit: true });\n }\n // Return focus to the chat input so keyboard users land in the composer.\n // Scope the lookup to this drawer's own chat (not document-global).\n findChatInput(elementRef.current)?.focus();\n },\n [onThreadSelect, setActiveThreadId],\n );\n\n const handleNewThread = useCallback(() => {\n // Reset the core thread store to a fresh, non-explicit client-side thread\n // (clears any stale error so the welcome screen can render cleanly).\n startNewThread();\n if (onNewThread) {\n onNewThread();\n } else {\n // No host callback: reset the surrounding chat configuration to a fresh,\n // non-explicit thread so the welcome screen shows with no host wiring.\n startNewThreadConfig?.();\n }\n }, [startNewThread, onNewThread, startNewThreadConfig]);\n\n const handleArchive = useCallback(\n (threadId: string) => {\n void archiveThread(threadId).catch((err) => {\n console.error(\"CopilotThreadsDrawer: archiveThread failed\", err);\n });\n },\n [archiveThread],\n );\n\n const handleUnarchive = useCallback(\n (threadId: string) => {\n void unarchiveThread(threadId).catch((err) => {\n console.error(\"CopilotThreadsDrawer: unarchiveThread failed\", err);\n });\n },\n [unarchiveThread],\n );\n\n const handleDelete = useCallback(\n (threadId: string) => {\n // Deleting the active thread resets to a fresh, non-explicit thread so the\n // user is not stranded on a now-gone conversation. Archiving the active\n // thread keeps the user viewing it.\n const isActive = threadId === activeThreadId;\n // The core thread store performs the optimistic removal (and rollback on\n // failure) in its own reducer, so the wrapper holds no removal bookkeeping\n // of its own — it simply renders the threads the store hands it.\n void deleteThread(threadId)\n .then(() => {\n if (isActive) {\n startNewThread();\n if (onNewThread) {\n onNewThread();\n } else {\n startNewThreadConfig?.();\n }\n }\n })\n .catch((err) => {\n console.error(\"CopilotThreadsDrawer: deleteThread failed\", err);\n });\n },\n [\n deleteThread,\n activeThreadId,\n startNewThread,\n onNewThread,\n startNewThreadConfig,\n ],\n );\n\n const handleFilterChange = useCallback(() => {\n // The element owns the Active/All filter; on change we refetch so the list\n // reflects the server.\n refetchThreads();\n }, [refetchThreads]);\n\n const handleRetry = useCallback(\n (scope: RetryDetail[\"scope\"]) => {\n if (scope === \"fetch-more\") {\n fetchMoreThreads();\n } else {\n refetchThreads();\n }\n },\n [fetchMoreThreads, refetchThreads],\n );\n\n const handleOpenChange = useCallback(\n (open: boolean) => {\n setDrawerOpen(open);\n },\n [setDrawerOpen],\n );\n\n const handleLicensed = useCallback(() => {\n onLicensed?.();\n }, [onLicensed]);\n\n const handleLoadMore = useCallback(() => {\n // Advance pagination. No-op when there is no next page; the element only\n // surfaces the \"Load more\" control while `hasMore` is true.\n fetchMoreThreads();\n }, [fetchMoreThreads]);\n\n const handleCollapseChange = useCallback(\n (collapsed: boolean) => {\n onCollapseChange?.(collapsed);\n },\n [onCollapseChange],\n );\n\n // Keep a ref to the live handlers so the addEventListener effect can stay\n // stable (bind once) while still calling the freshest closures.\n const handlersRef = useRef({\n handleThreadSelected,\n handleNewThread,\n handleArchive,\n handleUnarchive,\n handleDelete,\n handleFilterChange,\n handleRetry,\n handleOpenChange,\n handleLicensed,\n handleLoadMore,\n handleCollapseChange,\n });\n handlersRef.current = {\n handleThreadSelected,\n handleNewThread,\n handleArchive,\n handleUnarchive,\n handleDelete,\n handleFilterChange,\n handleRetry,\n handleOpenChange,\n handleLicensed,\n handleLoadMore,\n handleCollapseChange,\n };\n\n // Bind the outbound DOM events once the element exists. Listeners are\n // bound a single time and cleaned up on unmount; they dispatch through the\n // handlers ref so they always invoke the latest closures.\n useEffect(() => {\n const el = elementRef.current;\n if (!el) return;\n\n const onThreadSelected = (event: Event) => {\n const detail = (event as CustomEvent<ThreadSelectedDetail>).detail;\n handlersRef.current.handleThreadSelected(detail.threadId);\n };\n const onNewThreadEvent = () => handlersRef.current.handleNewThread();\n const onArchive = (event: Event) => {\n const detail = (event as CustomEvent<ArchiveDetail>).detail;\n handlersRef.current.handleArchive(detail.threadId);\n };\n const onUnarchive = (event: Event) => {\n const detail = (event as CustomEvent<UnarchiveDetail>).detail;\n handlersRef.current.handleUnarchive(detail.threadId);\n };\n const onDelete = (event: Event) => {\n const detail = (event as CustomEvent<DeleteDetail>).detail;\n handlersRef.current.handleDelete(detail.threadId);\n };\n const onFilterChange = (_event: Event) => {\n handlersRef.current.handleFilterChange();\n };\n const onOpenChangeEvent = (event: Event) => {\n const detail = (event as CustomEvent<OpenChangeDetail>).detail;\n handlersRef.current.handleOpenChange(detail.open);\n };\n const onRetry = (event: Event) => {\n const detail = (event as CustomEvent<RetryDetail>).detail;\n handlersRef.current.handleRetry(detail.scope);\n };\n const onLicensedEvent = () => handlersRef.current.handleLicensed();\n const onLoadMore = () => handlersRef.current.handleLoadMore();\n const onCollapseChangeEvent = (event: Event) => {\n const detail = (event as CustomEvent<CollapseChangeDetail>).detail;\n handlersRef.current.handleCollapseChange(detail.collapsed);\n };\n\n el.addEventListener(\"thread-selected\", onThreadSelected);\n el.addEventListener(\"new-thread\", onNewThreadEvent);\n el.addEventListener(\"archive\", onArchive);\n el.addEventListener(\"unarchive\", onUnarchive);\n el.addEventListener(\"delete\", onDelete);\n el.addEventListener(\"filter-change\", onFilterChange);\n el.addEventListener(\"open-change\", onOpenChangeEvent);\n el.addEventListener(\"retry\", onRetry);\n el.addEventListener(\"licensed\", onLicensedEvent);\n el.addEventListener(\"load-more\", onLoadMore);\n el.addEventListener(\"collapse-change\", onCollapseChangeEvent);\n\n return () => {\n el.removeEventListener(\"thread-selected\", onThreadSelected);\n el.removeEventListener(\"new-thread\", onNewThreadEvent);\n el.removeEventListener(\"archive\", onArchive);\n el.removeEventListener(\"unarchive\", onUnarchive);\n el.removeEventListener(\"delete\", onDelete);\n el.removeEventListener(\"filter-change\", onFilterChange);\n el.removeEventListener(\"open-change\", onOpenChangeEvent);\n el.removeEventListener(\"retry\", onRetry);\n el.removeEventListener(\"licensed\", onLicensedEvent);\n el.removeEventListener(\"load-more\", onLoadMore);\n el.removeEventListener(\"collapse-change\", onCollapseChangeEvent);\n };\n // Re-bind only after the first client mount (deps: [mounted]); the element\n // ref is stable thereafter.\n }, [mounted]);\n\n // Assign object/array/boolean PROPERTIES imperatively. React would otherwise\n // set these as string attributes, which a custom element cannot accept for\n // arrays/objects. Setting them as instance properties is the correct interop.\n useEffect(() => {\n const el = elementRef.current;\n if (!el) return;\n el.threads = drawerThreads;\n }, [drawerThreads, mounted]);\n\n useEffect(() => {\n const el = elementRef.current;\n if (!el) return;\n // While the license is still resolving, force the loading state so the\n // element shows its spinner instead of an empty/unlicensed body.\n el.loading = isLoading || licensePending;\n // Only genuine list-load/mutation errors reach the end user. Developer/\n // config errors (missing runtime URL, runtime without thread endpoints) are\n // excluded via `listError` so they never leak into the drawer's error UI.\n el.error = listError ? listError.message : null;\n el.activeThreadId = activeThreadId;\n // Pending counts as licensed for rendering: `_renderBody` shows the locked view\n // only when `licensed` is false, so keeping it true until the status\n // resolves prevents the locked view from flashing (or sticking) mid-resolution.\n el.licensed = licensed || licensePending;\n el.hasMore = hasMoreThreads;\n el.fetchingMore = isFetchingMoreThreads;\n // Dedicated fetch-more error channel: drives the element's inline\n // \"couldn't load more — retry\" panel without disturbing the loaded list or\n // the initial-list `error`. The `retry{scope:\"fetch-more\"}` handler\n // becomes reachable once this panel renders.\n el.fetchMoreError = fetchMoreError ? fetchMoreError.message : null;\n }, [\n isLoading,\n listError,\n fetchMoreError,\n activeThreadId,\n licensed,\n licensePending,\n hasMoreThreads,\n isFetchingMoreThreads,\n mounted,\n ]);\n\n // Bind the element's controlled `open` to the chat configuration's\n // drawerOpen, so the header launcher and the element stay in sync.\n useEffect(() => {\n const el = elementRef.current;\n if (!el) return;\n el.open = drawerOpen;\n }, [drawerOpen, mounted]);\n\n // Mirror the optional `label` onto the element (its accessible + default\n // header text). Leave the element's built-in default (\"Threads\") in place\n // when the prop is omitted, rather than clobbering it with undefined.\n useEffect(() => {\n const el = elementRef.current;\n if (!el) return;\n if (label !== undefined) el.label = label;\n }, [label, mounted]);\n\n // Mirror the optional `licenseUrl` onto the element (the locked view's\n // Upgrade CTA destination). Leave the element's built-in default in place\n // when the prop is omitted, rather than clobbering it with undefined.\n useEffect(() => {\n const el = elementRef.current;\n if (!el) return;\n if (licenseUrl !== undefined) el.licenseUrl = licenseUrl;\n }, [licenseUrl, mounted]);\n\n // Mirror the optional `collapsible` onto the element as a PROPERTY (a\n // default-true boolean, exactly like `licensed` — a string attribute cannot\n // represent it since any non-empty value is truthy). Leave the element's\n // built-in default (`true`) in place when the prop is omitted, rather than\n // clobbering it with undefined.\n useEffect(() => {\n const el = elementRef.current;\n if (!el) return;\n if (collapsible !== undefined) {\n // TODO(ENT-1051): drop the intersection cast once the published element\n // type declares `collapsible` (see the local CollapseChangeDetail note).\n (\n el as CopilotKitThreadsDrawerElement & { collapsible: boolean }\n ).collapsible = collapsible;\n }\n }, [collapsible, mounted]);\n\n // Per-row light-DOM children projected via `slot=\"row:{id}\"`.\n const rowChildren = useMemo(() => {\n if (!renderRow) return null;\n return drawerThreads.map((drawerThread) => {\n const fullThread = threads.find((t) => t.id === drawerThread.id);\n if (!fullThread) return null;\n const content = renderRow(fullThread);\n if (content === null || content === undefined) return null;\n return (\n <div key={drawerThread.id} slot={`row:${drawerThread.id}`}>\n {content}\n </div>\n );\n });\n }, [renderRow, drawerThreads, threads]);\n\n // SSR / pre-mount: render nothing so the server output matches the initial\n // client render (the element is not yet registered), avoiding hydration\n // mismatch and layout shift.\n if (!mounted) return null;\n\n return React.createElement(\n COPILOTKIT_THREADS_DRAWER_TAG,\n {\n ref: elementRef,\n \"data-testid\": dataTestId,\n // Pass the section heading label as an attribute; omit it entirely when\n // unset so the element keeps its built-in default rather than receiving\n // an `undefined` that would clobber it.\n ...(recentLabel !== undefined ? { \"recent-label\": recentLabel } : {}),\n },\n rowChildren,\n );\n}\n\nCopilotThreadsDrawer.displayName = \"CopilotThreadsDrawer\";\n\nexport default CopilotThreadsDrawer;\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 type {\n CopilotCloudConfig,\n FunctionCallHandler,\n CopilotErrorHandler,\n CopilotKitError,\n} from \"@copilotkit/shared\";\nimport type {\n ActionRenderProps,\n CatchAllActionRenderProps,\n FrontendAction,\n} from \"../types/frontend-action\";\nimport React from \"react\";\nimport type { TreeNodeId, Tree } from \"../hooks/use-tree\";\nimport type { DocumentPointer } from \"../types\";\nimport type { CopilotChatSuggestionConfiguration } from \"../types/chat-suggestion-configuration\";\nimport type { CoAgentStateRenderProps } from \"../types/coagent-action\";\nimport { CoAgentStateRender } from \"../types/coagent-action\";\nimport type { CoagentState } from \"../types/coagent-state\";\nimport type {\n ExtensionsInput,\n ForwardedParametersInput,\n} from \"@copilotkit/runtime-client-gql\";\nimport { CopilotRuntimeClient } from \"@copilotkit/runtime-client-gql\";\nimport type { Agent } from \"@copilotkit/runtime-client-gql\";\nimport type {\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 * Your CopilotKit public license key (legacy `publicApiKey` alias of `publicLicenseKey`).\n */\n publicApiKey?: string;\n\n /**\n * The configuration for the CopilotKit hosted runtime.\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://dashboard.operations.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 {\n CopilotKitError,\n DEFAULT_AGENT_ID,\n parseJson,\n} from \"@copilotkit/shared\";\nimport { useCopilotContext } from \"../context\";\nimport type { AbstractAgent, AgentSubscriber } from \"@ag-ui/client\";\nimport { AGUIConnectNotImplementedError } from \"@ag-ui/client\";\nimport { useErrorToast } from \"./error-boundary/error-utils\";\nimport type { 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 { copilotkit } = useCopilotKit();\n const existingConfig = useCopilotChatConfiguration();\n const configAgentId = existingConfig?.agentId;\n\n // This subscription is provider-level (a sibling of {children}), so the\n // nearest chat configuration is the top-level one seeded with\n // `props.agent ?? \"default\"`. When the app passes no `agent` prop, that id is\n // \"default\" — but the runtime may register only a non-default agent. Binding\n // useAgent('default') would then throw \"Agent 'default' not found\" once the\n // runtime syncs, crashing the whole app even though the actual <CopilotChat>\n // subtree is correctly configured (#5533).\n //\n // The PredictState subscription here is best-effort and must never crash the\n // app. When the resolved id would be the default but no default agent is\n // registered, fall back to the sole/first registered agent so the hook still\n // binds something real. We compute a safe id (never call the hook\n // conditionally — that would violate the rules of hooks).\n const resolvedAgentId = useMemo(() => {\n const requested = configAgentId ?? DEFAULT_AGENT_ID;\n const registered = copilotkit.agents ?? {};\n // Check the registry record directly rather than `copilotkit.getAgent()`:\n // getAgent() logs `console.warn(\"Agent <id> not found\")` on a post-sync\n // miss, which is noisy for a valid setup where the default placeholder\n // simply isn't a registered agent (#5533).\n if (registered[requested]) {\n return requested;\n }\n // Requested agent isn't registered. If it's the default placeholder, bind\n // the first registered agent instead of throwing. (For an explicitly\n // configured non-default id, leave it as-is so useAgent's provisional /\n // error handling applies as before.)\n if (requested === DEFAULT_AGENT_ID) {\n const firstRegistered = Object.keys(registered)[0];\n if (firstRegistered) {\n return firstRegistered;\n }\n }\n return requested;\n }, [configAgentId, copilotkit.agents]);\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 type { SetStateAction } from \"react\";\nimport React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n CopilotChatConfigurationProvider,\n CopilotKitInspector,\n CopilotKitProvider as CopilotKitV2Provider,\n useCopilotKit,\n} from \"../../v2\";\nimport type {\n CopilotApiConfig,\n ChatComponentsCache,\n AgentSession,\n AuthState,\n} from \"../../context/copilot-context\";\nimport {\n CopilotContext,\n useCopilotContext,\n} from \"../../context/copilot-context\";\nimport useTree from \"../../hooks/use-tree\";\nimport type {\n CopilotChatSuggestionConfiguration,\n DocumentPointer,\n} from \"../../types\";\nimport { flushSync } from \"react-dom\";\nimport type {\n CopilotCloudConfig,\n FunctionCallHandler,\n CopilotKitError,\n CopilotErrorEvent,\n CopilotErrorHandler,\n} from \"@copilotkit/shared\";\nimport {\n COPILOT_CLOUD_CHAT_URL,\n COPILOT_CLOUD_PUBLIC_API_KEY_HEADER,\n randomUUID,\n ConfigurationError,\n MissingPublicApiKeyError,\n} from \"@copilotkit/shared\";\nimport type { FrontendAction } from \"../../types/frontend-action\";\nimport useFlatCategoryStore from \"../../hooks/use-flat-category-store\";\nimport type { CopilotKitProps } from \"./copilotkit-props\";\nimport type { 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 type { Agent, ExtensionsInput } from \"@copilotkit/runtime-client-gql\";\nimport type {\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 // v1's `onError` takes a v1 `CopilotErrorEvent` (with `type`/`timestamp`),\n // which the v2 provider's `onError` does not produce. The v1 handler is\n // invoked exclusively through `CopilotKitErrorBridge`, which adapts v2\n // error events to the v1 shape — so it must not be spread into the v2\n // provider directly.\n const { onError: _onError, ...v2Props } = props;\n\n return (\n <ToastProvider enabled={enabled}>\n <CopilotErrorBoundary\n publicApiKey={publicApiKey}\n showUsageBanner={enabled}\n >\n <ThreadsProvider threadId={props.threadId}>\n <CopilotKitV2Provider\n {...v2Props}\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 // Self-managed (and dev-only) agents are instantiated client-side and route\n // directly to their AG-UI endpoints, so they need neither a runtime nor a\n // cloud key. Mirror CopilotKitProvider's `hasLocalAgents` gate so the wrapper\n // doesn't reject a valid self-managed configuration (#5417).\n const hasLocalAgents =\n Object.keys({\n ...props.agents__unsafe_dev_only,\n ...props.selfManagedAgents,\n }).length > 0;\n\n if (!props.runtimeUrl && !hasApiKey && !hasLocalAgents) {\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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tB,MAAM,WACJ,OAAO,kBAAkB,aACrB,cAAc,KAAK,GACnB;AAQN,UANE,OAAO,KAAK,SAAS,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;CAM9C,MAAM,iBACJ,OAAO,KAAK;EACV,GAAG,MAAM;EACT,GAAG,MAAM;EACV,CAAC,CAAC,SAAS;AAEd,KAAI,CAAC,MAAM,cAAc,CAAC,aAAa,CAAC,eACtC,OAAM,IAAIC,sCACR,8EACD;AAGH,KAAI,cAAc,SAAS,KAAK,CAAC,UAC/B,OAAM,IAAIC,4CACR,sFAAsF,cACnF,IAAI,kBAAkB,CACtB,KAAK,KAAK,GACd"}