@copilotkitnext/react 1.52.2-next.0 → 1.52.2-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","names":["DEFAULT_AGENT_ID","twMerge","Slot","TooltipPrimitive","DropdownMenuPrimitive","ChevronRightIcon","React","Square","Loader2","ArrowUp","Mic","X","Check","Plus","React","z","CopilotKitCore","z","React","ToolCallStatus","DEFAULT_AGENT_ID","DEFAULT_AGENT_ID","EMPTY_DEPS","z","React","DEFAULT_AGENT_ID","CopilotKitCoreRuntimeConnectionStatus","ProxiedCopilotRuntimeAgent","DEFAULT_AGENT_ID","DEFAULT_AGENT_ID","React","Streamdown","Check","Copy","ThumbsUp","ThumbsDown","Volume2","RefreshCw","Check","Copy","Edit","ChevronLeft","ChevronRight","ChevronRight","Streamdown","React","Loader2","React","React","CopilotChatAssistantMessage","CopilotChatUserMessage","CopilotChatReasoningMessage","CopilotChatInput","StickToBottom","ChevronDown","TranscriptionErrorCode","DEFAULT_AGENT_ID","AGUIConnectNotImplementedError","TranscriptionErrorCode","MessageCircle","X","React","X","CopilotChatView","CopilotChatView","CopilotChatView","CopilotPopupView","CopilotChatView"],"sources":["../src/providers/CopilotChatConfigurationProvider.tsx","../src/lib/utils.ts","../src/components/ui/button.tsx","../src/components/ui/tooltip.tsx","../src/components/ui/dropdown-menu.tsx","../src/components/chat/CopilotChatAudioRecorder.tsx","../src/lib/slots.tsx","../src/components/chat/CopilotChatInput.tsx","../src/components/CopilotKitInspector.tsx","../src/components/MCPAppsActivityRenderer.tsx","../src/lib/react-core.ts","../src/providers/CopilotKitProvider.tsx","../src/hooks/use-render-tool-call.tsx","../src/hooks/use-render-custom-messages.tsx","../src/hooks/use-render-activity-message.tsx","../src/hooks/use-frontend-tool.tsx","../src/hooks/use-component.tsx","../src/types/defineToolCallRenderer.ts","../src/hooks/use-render-tool.tsx","../src/hooks/use-default-render-tool.tsx","../src/hooks/use-human-in-the-loop.tsx","../src/hooks/use-agent.tsx","../src/hooks/use-agent-context.tsx","../src/hooks/use-suggestions.tsx","../src/hooks/use-configure-suggestions.tsx","../src/hooks/use-interrupt.tsx","../src/components/chat/CopilotChatToolCallsView.tsx","../src/components/chat/CopilotChatAssistantMessage.tsx","../src/components/chat/CopilotChatUserMessage.tsx","../src/components/chat/CopilotChatReasoningMessage.tsx","../src/components/chat/CopilotChatSuggestionPill.tsx","../src/components/chat/CopilotChatSuggestionView.tsx","../src/components/chat/CopilotChatMessageView.tsx","../src/hooks/use-keyboard-height.tsx","../src/components/chat/CopilotChatView.tsx","../src/lib/transcription-client.ts","../src/components/chat/CopilotChat.tsx","../src/components/chat/CopilotChatToggleButton.tsx","../src/components/chat/CopilotModalHeader.tsx","../src/components/chat/CopilotSidebarView.tsx","../src/components/chat/CopilotPopupView.tsx","../src/components/chat/CopilotSidebar.tsx","../src/components/chat/CopilotPopup.tsx","../src/components/WildcardToolCallRender.tsx"],"sourcesContent":["import React, {\n createContext,\n useContext,\n ReactNode,\n useMemo,\n useState,\n} from \"react\";\nimport { DEFAULT_AGENT_ID, randomUUID } from \"@copilotkitnext/shared\";\n\n// Default labels\nexport const CopilotChatDefaultLabels = {\n chatInputPlaceholder: \"Type a message...\",\n chatInputToolbarStartTranscribeButtonLabel: \"Transcribe\",\n chatInputToolbarCancelTranscribeButtonLabel: \"Cancel\",\n chatInputToolbarFinishTranscribeButtonLabel: \"Finish\",\n chatInputToolbarAddButtonLabel: \"Add photos or files\",\n chatInputToolbarToolsButtonLabel: \"Tools\",\n assistantMessageToolbarCopyCodeLabel: \"Copy\",\n assistantMessageToolbarCopyCodeCopiedLabel: \"Copied\",\n assistantMessageToolbarCopyMessageLabel: \"Copy\",\n assistantMessageToolbarThumbsUpLabel: \"Good response\",\n assistantMessageToolbarThumbsDownLabel: \"Bad response\",\n assistantMessageToolbarReadAloudLabel: \"Read aloud\",\n assistantMessageToolbarRegenerateLabel: \"Regenerate\",\n userMessageToolbarCopyMessageLabel: \"Copy\",\n userMessageToolbarEditMessageLabel: \"Edit\",\n chatDisclaimerText:\n \"AI can make mistakes. Please verify important information.\",\n chatToggleOpenLabel: \"Open chat\",\n chatToggleCloseLabel: \"Close chat\",\n modalHeaderTitle: \"CopilotKit Chat\",\n welcomeMessageText: \"How can I help you today?\",\n};\n\nexport type CopilotChatLabels = typeof CopilotChatDefaultLabels;\n\n// Define the full configuration interface\nexport interface CopilotChatConfigurationValue {\n labels: CopilotChatLabels;\n agentId: string;\n threadId: string;\n isModalOpen: boolean;\n setModalOpen: (open: boolean) => void;\n}\n\n// Create the configuration context\nconst CopilotChatConfiguration =\n createContext<CopilotChatConfigurationValue | null>(null);\n\n// Provider props interface\nexport interface CopilotChatConfigurationProviderProps {\n children: ReactNode;\n labels?: Partial<CopilotChatLabels>;\n agentId?: string;\n threadId?: string;\n isModalDefaultOpen?: boolean;\n}\n\n// Provider component\nexport const CopilotChatConfigurationProvider: React.FC<\n CopilotChatConfigurationProviderProps\n> = ({ children, labels, agentId, threadId, isModalDefaultOpen }) => {\n const parentConfig = useContext(CopilotChatConfiguration);\n\n const mergedLabels: CopilotChatLabels = useMemo(\n () => ({\n ...CopilotChatDefaultLabels,\n ...(parentConfig?.labels ?? {}),\n ...(labels ?? {}),\n }),\n [labels, parentConfig?.labels],\n );\n\n const resolvedAgentId = agentId ?? parentConfig?.agentId ?? DEFAULT_AGENT_ID;\n\n const resolvedThreadId = useMemo(() => {\n if (threadId) {\n return threadId;\n }\n if (parentConfig?.threadId) {\n return parentConfig.threadId;\n }\n return randomUUID();\n }, [threadId, parentConfig?.threadId]);\n\n const resolvedDefaultOpen = isModalDefaultOpen ?? true;\n\n const [internalModalOpen, setInternalModalOpen] =\n useState<boolean>(resolvedDefaultOpen);\n\n const resolvedIsModalOpen = parentConfig?.isModalOpen ?? internalModalOpen;\n const resolvedSetModalOpen =\n parentConfig?.setModalOpen ?? setInternalModalOpen;\n\n const configurationValue: CopilotChatConfigurationValue = useMemo(\n () => ({\n labels: mergedLabels,\n agentId: resolvedAgentId,\n threadId: resolvedThreadId,\n isModalOpen: resolvedIsModalOpen,\n setModalOpen: resolvedSetModalOpen,\n }),\n [\n mergedLabels,\n resolvedAgentId,\n resolvedThreadId,\n resolvedIsModalOpen,\n resolvedSetModalOpen,\n ],\n );\n\n return (\n <CopilotChatConfiguration.Provider value={configurationValue}>\n {children}\n </CopilotChatConfiguration.Provider>\n );\n};\n\n// Hook to use the full configuration\nexport const useCopilotChatConfiguration =\n (): CopilotChatConfigurationValue | null => {\n const configuration = useContext(CopilotChatConfiguration);\n return configuration;\n };\n","import { clsx, type ClassValue } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge({ prefix: \"cpk\" });\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst buttonVariants = cva(\n \"cpk:inline-flex cpk:items-center cpk:justify-center cpk:gap-2 cpk:whitespace-nowrap cpk:rounded-md cpk:text-sm cpk:font-medium cpk:transition-all cpk:disabled:pointer-events-none cpk:disabled:opacity-50 cpk:[&_svg]:pointer-events-none cpk:[&_svg:not([class*='size-'])]:size-4 cpk:shrink-0 cpk:[&_svg]:shrink-0 cpk:outline-none cpk:focus-visible:border-ring cpk:focus-visible:ring-ring/50 cpk:focus-visible:ring-[3px] cpk:aria-invalid:ring-destructive/20 cpk:dark:aria-invalid:ring-destructive/40 cpk:aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default:\n \"cpk:bg-primary cpk:text-primary-foreground cpk:shadow-xs cpk:hover:bg-primary/90\",\n destructive:\n \"cpk:bg-destructive cpk:text-white cpk:shadow-xs cpk:hover:bg-destructive/90 cpk:focus-visible:ring-destructive/20 cpk:dark:focus-visible:ring-destructive/40 cpk:dark:bg-destructive/60\",\n outline:\n \"cpk:border cpk:bg-background cpk:shadow-xs cpk:hover:bg-accent cpk:hover:text-accent-foreground cpk:dark:bg-input/30 cpk:dark:border-input cpk:dark:hover:bg-input/50\",\n secondary:\n \"cpk:bg-secondary cpk:text-secondary-foreground cpk:shadow-xs cpk:hover:bg-secondary/80\",\n ghost:\n \"cpk:hover:bg-accent cpk:hover:text-accent-foreground cpk:dark:hover:bg-accent/50 cpk:cursor-pointer\",\n link: \"cpk:text-primary cpk:underline-offset-4 cpk:hover:underline\",\n assistantMessageToolbarButton: [\n \"cpk:cursor-pointer\",\n // Background and text\n \"cpk:p-0 cpk:text-[rgb(93,93,93)] cpk:hover:bg-[#E8E8E8]\",\n // Dark mode - lighter gray for better contrast\n \"cpk:dark:text-[rgb(243,243,243)] cpk:dark:hover:bg-[#303030]\",\n // Shape and sizing\n \"cpk:h-8 cpk:w-8\",\n // Interactions\n \"cpk:transition-colors\",\n // Hover states\n \"cpk:hover:text-[rgb(93,93,93)]\",\n \"cpk:dark:hover:text-[rgb(243,243,243)]\",\n ],\n chatInputToolbarPrimary: [\n \"cpk:cursor-pointer\",\n // Background and text\n \"cpk:bg-black cpk:text-white\",\n // Dark mode\n \"cpk:dark:bg-white cpk:dark:text-black cpk:dark:focus-visible:outline-white\",\n // Shape and sizing\n \"cpk:rounded-full\",\n // Interactions\n \"cpk:transition-colors\",\n // Focus states\n \"cpk:focus:outline-none\",\n // Hover states\n \"cpk:hover:opacity-70 cpk:disabled:hover:opacity-100\",\n // Disabled states\n \"cpk:disabled:cursor-not-allowed cpk:disabled:bg-[#00000014] cpk:disabled:text-[rgb(13,13,13)]\",\n \"cpk:dark:disabled:bg-[#454545] cpk:dark:disabled:text-white \",\n ],\n chatInputToolbarSecondary: [\n \"cpk:cursor-pointer\",\n // Background and text\n \"cpk:bg-transparent cpk:text-[#444444]\",\n // Dark mode\n \"cpk:dark:text-white cpk:dark:border-[#404040]\",\n // Shape and sizing\n \"cpk:rounded-full\",\n // Interactions\n \"cpk:transition-colors\",\n // Focus states\n \"cpk:focus:outline-none\",\n // Hover states\n \"cpk:hover:bg-[#f8f8f8] cpk:hover:text-[#333333]\",\n \"cpk:dark:hover:bg-[#404040] cpk:dark:hover:text-[#FFFFFF]\",\n // Disabled states\n \"cpk:disabled:cursor-not-allowed cpk:disabled:opacity-50\",\n \"cpk:disabled:hover:bg-transparent cpk:disabled:hover:text-[#444444]\",\n \"cpk:dark:disabled:hover:bg-transparent cpk:dark:disabled:hover:text-[#CCCCCC]\",\n ],\n },\n size: {\n default: \"cpk:h-9 cpk:px-4 cpk:py-2 cpk:has-[>svg]:px-3\",\n sm: \"cpk:h-8 cpk:rounded-md cpk:gap-1.5 cpk:px-3 cpk:has-[>svg]:px-2.5\",\n lg: \"cpk:h-10 cpk:rounded-md cpk:px-6 cpk:has-[>svg]:px-4\",\n icon: \"cpk:size-9\",\n chatInputToolbarIcon: [\n // Shape and sizing\n \"cpk:h-9 cpk:w-9 cpk:rounded-full\",\n ],\n chatInputToolbarIconLabel: [\n // Shape and sizing\n \"cpk:h-9 cpk:px-3 cpk:rounded-full\",\n // Layout\n \"cpk:gap-2\",\n // Typography\n \"cpk:font-normal\",\n ],\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nfunction Button({\n className,\n variant,\n size,\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n }) {\n const Comp = asChild ? Slot : \"button\";\n\n return (\n <Comp\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n );\n}\n\nexport { Button, buttonVariants };\n","import * as React from \"react\";\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction TooltipProvider({\n delayDuration = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delayDuration={delayDuration}\n {...props}\n />\n );\n}\n\nfunction Tooltip({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n return (\n <TooltipProvider>\n <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n </TooltipProvider>\n );\n}\n\nfunction TooltipTrigger({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />;\n}\n\nfunction TooltipContent({\n className,\n sideOffset = 0,\n children,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-copilotkit\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n \"cpk:bg-primary cpk:text-primary-foreground cpk:animate-in cpk:fade-in-0 cpk:zoom-in-95 cpk:data-[state=closed]:animate-out cpk:data-[state=closed]:fade-out-0 cpk:data-[state=closed]:zoom-out-95 cpk:data-[side=bottom]:slide-in-from-top-2 cpk:data-[side=left]:slide-in-from-right-2 cpk:data-[side=right]:slide-in-from-left-2 cpk:data-[side=top]:slide-in-from-bottom-2 cpk:z-50 cpk:w-fit cpk:origin-(--radix-tooltip-content-transform-origin) cpk:rounded-md cpk:px-3 cpk:py-1.5 cpk:text-xs cpk:text-balance\",\n className,\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"cpk:bg-primary cpk:fill-primary cpk:z-50 cpk:size-2.5 cpk:translate-y-[calc(-50%_-_2px)] cpk:rotate-45 cpk:rounded-[2px]\" />\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n );\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\";\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction DropdownMenu({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />;\n}\n\nfunction DropdownMenuPortal({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n return (\n <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n );\n}\n\nfunction DropdownMenuTrigger({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n return (\n <DropdownMenuPrimitive.Trigger\n data-slot=\"dropdown-menu-trigger\"\n {...props}\n />\n );\n}\n\nfunction DropdownMenuContent({\n className,\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-copilotkit\n data-slot=\"dropdown-menu-content\"\n sideOffset={sideOffset}\n className={cn(\n \"cpk:bg-popover cpk:text-popover-foreground cpk:data-[state=open]:animate-in cpk:data-[state=closed]:animate-out cpk:data-[state=closed]:fade-out-0 cpk:data-[state=open]:fade-in-0 cpk:data-[state=closed]:zoom-out-95 cpk:data-[state=open]:zoom-in-95 cpk:data-[side=bottom]:slide-in-from-top-2 cpk:data-[side=left]:slide-in-from-right-2 cpk:data-[side=right]:slide-in-from-left-2 cpk:data-[side=top]:slide-in-from-bottom-2 cpk:z-50 cpk:max-h-(--radix-dropdown-menu-content-available-height) cpk:min-w-[8rem] cpk:origin-(--radix-dropdown-menu-content-transform-origin) cpk:overflow-x-hidden cpk:overflow-y-auto cpk:rounded-md cpk:border cpk:p-1 cpk:shadow-md\",\n className,\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n );\n}\n\nfunction DropdownMenuGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n return (\n <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n );\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean;\n variant?: \"default\" | \"destructive\";\n}) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"cpk:focus:bg-accent cpk:focus:text-accent-foreground cpk:data-[variant=destructive]:text-destructive cpk:data-[variant=destructive]:focus:bg-destructive/10 cpk:dark:data-[variant=destructive]:focus:bg-destructive/20 cpk:data-[variant=destructive]:focus:text-destructive cpk:data-[variant=destructive]:*:[svg]:!text-destructive cpk:[&_svg:not([class*='text-'])]:text-muted-foreground cpk:relative cpk:flex cpk:cursor-default cpk:items-center cpk:gap-2 cpk:rounded-sm cpk:px-2 cpk:py-1.5 cpk:text-sm cpk:outline-hidden cpk:select-none cpk:data-[disabled]:pointer-events-none cpk:data-[disabled]:opacity-50 cpk:data-[inset]:pl-8 cpk:[&_svg]:pointer-events-none cpk:[&_svg]:shrink-0 cpk:[&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n className={cn(\n \"cpk:focus:bg-accent cpk:focus:text-accent-foreground cpk:relative cpk:flex cpk:cursor-default cpk:items-center cpk:gap-2 cpk:rounded-sm cpk:py-1.5 cpk:pr-2 cpk:pl-8 cpk:text-sm cpk:outline-hidden cpk:select-none cpk:data-[disabled]:pointer-events-none cpk:data-[disabled]:opacity-50 cpk:[&_svg]:pointer-events-none cpk:[&_svg]:shrink-0 cpk:[&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n checked={checked}\n {...props}\n >\n <span className=\"cpk:pointer-events-none cpk:absolute cpk:left-2 cpk:flex cpk:size-3.5 cpk:items-center cpk:justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CheckIcon className=\"cpk:size-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n );\n}\n\nfunction DropdownMenuRadioGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n return (\n <DropdownMenuPrimitive.RadioGroup\n data-slot=\"dropdown-menu-radio-group\"\n {...props}\n />\n );\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n return (\n <DropdownMenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n className={cn(\n \"cpk:focus:bg-accent cpk:focus:text-accent-foreground cpk:relative cpk:flex cpk:cursor-default cpk:items-center cpk:gap-2 cpk:rounded-sm cpk:py-1.5 cpk:pr-2 cpk:pl-8 cpk:text-sm cpk:outline-hidden cpk:select-none cpk:data-[disabled]:pointer-events-none cpk:data-[disabled]:opacity-50 cpk:[&_svg]:pointer-events-none cpk:[&_svg]:shrink-0 cpk:[&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n >\n <span className=\"cpk:pointer-events-none cpk:absolute cpk:left-2 cpk:flex cpk:size-3.5 cpk:items-center cpk:justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CircleIcon className=\"cpk:size-2 cpk:fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n );\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\n \"cpk:px-2 cpk:py-1.5 cpk:text-sm cpk:font-medium cpk:data-[inset]:pl-8\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn(\"cpk:bg-border cpk:-mx-1 cpk:my-1 cpk:h-px\", className)}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\n \"cpk:text-muted-foreground cpk:ml-auto cpk:text-xs cpk:tracking-widest\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSub({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />;\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"cpk:focus:bg-accent cpk:focus:text-accent-foreground cpk:data-[state=open]:bg-accent cpk:data-[state=open]:text-accent-foreground cpk:flex cpk:cursor-default cpk:items-center cpk:rounded-sm cpk:px-2 cpk:py-1.5 cpk:text-sm cpk:outline-hidden cpk:select-none cpk:data-[inset]:pl-8\",\n className,\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"cpk:ml-auto cpk:size-4\" />\n </DropdownMenuPrimitive.SubTrigger>\n );\n}\n\nfunction DropdownMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\n \"cpk:bg-popover cpk:text-popover-foreground cpk:data-[state=open]:animate-in cpk:data-[state=closed]:animate-out cpk:data-[state=closed]:fade-out-0 cpk:data-[state=open]:fade-in-0 cpk:data-[state=closed]:zoom-out-95 cpk:data-[state=open]:zoom-in-95 cpk:data-[side=bottom]:slide-in-from-top-2 cpk:data-[side=left]:slide-in-from-right-2 cpk:data-[side=right]:slide-in-from-left-2 cpk:data-[side=top]:slide-in-from-bottom-2 cpk:z-50 cpk:min-w-[8rem] cpk:origin-(--radix-dropdown-menu-content-transform-origin) cpk:overflow-hidden cpk:rounded-md cpk:border cpk:p-1 cpk:shadow-lg\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport {\n DropdownMenu,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n};\n","import {\n useRef,\n useEffect,\n useImperativeHandle,\n forwardRef,\n useCallback,\n useState,\n} from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\n/** Finite-state machine for every recorder implementation */\nexport type AudioRecorderState = \"idle\" | \"recording\" | \"processing\";\n\n/** Error subclass so callers can `instanceof`-guard recorder failures */\nexport class AudioRecorderError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"AudioRecorderError\";\n }\n}\n\nexport interface AudioRecorderRef {\n state: AudioRecorderState;\n start: () => Promise<void>;\n stop: () => Promise<Blob>;\n dispose: () => void;\n}\n\nexport const CopilotChatAudioRecorder = forwardRef<\n AudioRecorderRef,\n React.HTMLAttributes<HTMLDivElement>\n>((props, ref) => {\n const { className, ...divProps } = props;\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n // Recording state\n const [recorderState, setRecorderState] =\n useState<AudioRecorderState>(\"idle\");\n const mediaRecorderRef = useRef<MediaRecorder | null>(null);\n const audioChunksRef = useRef<Blob[]>([]);\n const streamRef = useRef<MediaStream | null>(null);\n const analyserRef = useRef<AnalyserNode | null>(null);\n const audioContextRef = useRef<AudioContext | null>(null);\n const animationIdRef = useRef<number | null>(null);\n\n // Amplitude history buffer for scrolling waveform\n const amplitudeHistoryRef = useRef<number[]>([]);\n const frameCountRef = useRef<number>(0);\n const scrollOffsetRef = useRef<number>(0);\n const smoothedAmplitudeRef = useRef<number>(0);\n const fadeOpacityRef = useRef<number>(0);\n\n // Clean up all resources\n const cleanup = useCallback(() => {\n if (animationIdRef.current) {\n cancelAnimationFrame(animationIdRef.current);\n animationIdRef.current = null;\n }\n if (\n mediaRecorderRef.current &&\n mediaRecorderRef.current.state !== \"inactive\"\n ) {\n try {\n mediaRecorderRef.current.stop();\n } catch {\n // Ignore errors during cleanup\n }\n }\n if (streamRef.current) {\n streamRef.current.getTracks().forEach((track) => track.stop());\n streamRef.current = null;\n }\n if (audioContextRef.current && audioContextRef.current.state !== \"closed\") {\n audioContextRef.current.close().catch(() => {\n // Ignore close errors\n });\n audioContextRef.current = null;\n }\n mediaRecorderRef.current = null;\n analyserRef.current = null;\n audioChunksRef.current = [];\n amplitudeHistoryRef.current = [];\n frameCountRef.current = 0;\n scrollOffsetRef.current = 0;\n smoothedAmplitudeRef.current = 0;\n fadeOpacityRef.current = 0;\n }, []);\n\n // Start recording\n const start = useCallback(async () => {\n if (recorderState !== \"idle\") {\n throw new AudioRecorderError(\"Recorder is already active\");\n }\n\n try {\n // Request microphone access\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n streamRef.current = stream;\n\n // Set up audio context for visualization\n const audioContext = new AudioContext();\n audioContextRef.current = audioContext;\n const source = audioContext.createMediaStreamSource(stream);\n const analyser = audioContext.createAnalyser();\n analyser.fftSize = 2048; // Higher resolution for time-domain waveform\n source.connect(analyser);\n analyserRef.current = analyser;\n\n // Determine best MIME type for recording\n const mimeType = MediaRecorder.isTypeSupported(\"audio/webm;codecs=opus\")\n ? \"audio/webm;codecs=opus\"\n : MediaRecorder.isTypeSupported(\"audio/webm\")\n ? \"audio/webm\"\n : MediaRecorder.isTypeSupported(\"audio/mp4\")\n ? \"audio/mp4\"\n : \"\";\n\n const options: MediaRecorderOptions = mimeType ? { mimeType } : {};\n const mediaRecorder = new MediaRecorder(stream, options);\n mediaRecorderRef.current = mediaRecorder;\n audioChunksRef.current = [];\n\n mediaRecorder.ondataavailable = (event) => {\n if (event.data.size > 0) {\n audioChunksRef.current.push(event.data);\n }\n };\n\n // Start recording with timeslice to collect data periodically\n mediaRecorder.start(100);\n setRecorderState(\"recording\");\n } catch (error) {\n cleanup();\n if (error instanceof Error && error.name === \"NotAllowedError\") {\n throw new AudioRecorderError(\"Microphone permission denied\");\n }\n if (error instanceof Error && error.name === \"NotFoundError\") {\n throw new AudioRecorderError(\"No microphone found\");\n }\n throw new AudioRecorderError(\n error instanceof Error ? error.message : \"Failed to start recording\",\n );\n }\n }, [recorderState, cleanup]);\n\n // Stop recording and return audio blob\n const stop = useCallback((): Promise<Blob> => {\n return new Promise((resolve, reject) => {\n const mediaRecorder = mediaRecorderRef.current;\n if (!mediaRecorder || recorderState !== \"recording\") {\n reject(new AudioRecorderError(\"No active recording\"));\n return;\n }\n\n setRecorderState(\"processing\");\n\n mediaRecorder.onstop = () => {\n const mimeType = mediaRecorder.mimeType || \"audio/webm\";\n const audioBlob = new Blob(audioChunksRef.current, { type: mimeType });\n\n // Clean up but keep the blob\n cleanup();\n setRecorderState(\"idle\");\n resolve(audioBlob);\n };\n\n mediaRecorder.onerror = () => {\n cleanup();\n setRecorderState(\"idle\");\n reject(new AudioRecorderError(\"Recording failed\"));\n };\n\n mediaRecorder.stop();\n });\n }, [recorderState, cleanup]);\n\n // Calculate RMS amplitude from time-domain data\n const calculateAmplitude = (dataArray: Uint8Array): number => {\n let sum = 0;\n for (let i = 0; i < dataArray.length; i++) {\n // Normalize to -1 to 1 range (128 is center/silence)\n const sample = (dataArray[i] ?? 128) / 128 - 1;\n sum += sample * sample;\n }\n return Math.sqrt(sum / dataArray.length);\n };\n\n // Canvas rendering with animation\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n\n // Configuration\n const barWidth = 2;\n const barGap = 1;\n const barSpacing = barWidth + barGap;\n const scrollSpeed = 1 / 3; // Pixels per frame\n\n const draw = () => {\n const rect = canvas.getBoundingClientRect();\n const dpr = window.devicePixelRatio || 1;\n\n // Update canvas dimensions if container resized\n if (\n canvas.width !== rect.width * dpr ||\n canvas.height !== rect.height * dpr\n ) {\n canvas.width = rect.width * dpr;\n canvas.height = rect.height * dpr;\n ctx.scale(dpr, dpr);\n }\n\n // Calculate how many bars fit in the canvas (plus extra for smooth scrolling)\n const maxBars = Math.floor(rect.width / barSpacing) + 2;\n\n // Get current amplitude if recording\n if (analyserRef.current && recorderState === \"recording\") {\n // Pre-fill history with zeros on first frame so line is visible immediately\n if (amplitudeHistoryRef.current.length === 0) {\n amplitudeHistoryRef.current = new Array(maxBars).fill(0);\n }\n\n // Fade in the waveform smoothly\n if (fadeOpacityRef.current < 1) {\n fadeOpacityRef.current = Math.min(1, fadeOpacityRef.current + 0.03);\n }\n\n // Smooth scrolling - increment offset every frame\n scrollOffsetRef.current += scrollSpeed;\n\n // Sample amplitude every frame for smoothing\n const bufferLength = analyserRef.current.fftSize;\n const dataArray = new Uint8Array(bufferLength);\n analyserRef.current.getByteTimeDomainData(dataArray);\n const rawAmplitude = calculateAmplitude(dataArray);\n\n // Smoothing: gradual attack and decay\n const attackSpeed = 0.12; // Smooth rise\n const decaySpeed = 0.08; // Smooth fade out\n const speed =\n rawAmplitude > smoothedAmplitudeRef.current\n ? attackSpeed\n : decaySpeed;\n smoothedAmplitudeRef.current +=\n (rawAmplitude - smoothedAmplitudeRef.current) * speed;\n\n // When offset reaches a full bar width, add a new sample and reset offset\n if (scrollOffsetRef.current >= barSpacing) {\n scrollOffsetRef.current -= barSpacing;\n amplitudeHistoryRef.current.push(smoothedAmplitudeRef.current);\n\n // Trim history to fit canvas\n if (amplitudeHistoryRef.current.length > maxBars) {\n amplitudeHistoryRef.current =\n amplitudeHistoryRef.current.slice(-maxBars);\n }\n }\n }\n\n // Clear canvas\n ctx.clearRect(0, 0, rect.width, rect.height);\n\n // Get current foreground color\n const computedStyle = getComputedStyle(canvas);\n ctx.fillStyle = computedStyle.color;\n ctx.globalAlpha = fadeOpacityRef.current;\n\n const centerY = rect.height / 2;\n const maxAmplitude = rect.height / 2 - 2; // Leave some padding\n\n const history = amplitudeHistoryRef.current;\n\n // Only draw when recording (history has data)\n if (history.length > 0) {\n const offset = scrollOffsetRef.current;\n const edgeFadeWidth = 12; // Pixels to fade at each edge\n\n for (let i = 0; i < history.length; i++) {\n const amplitude = history[i] ?? 0;\n // Scale amplitude (RMS is typically 0-0.5 for normal speech)\n const scaledAmplitude = Math.min(amplitude * 4, 1);\n const barHeight = Math.max(2, scaledAmplitude * maxAmplitude * 2);\n\n // Position: right-aligned with smooth scroll offset\n const x = rect.width - (history.length - i) * barSpacing - offset;\n const y = centerY - barHeight / 2;\n\n // Only draw if visible\n if (x + barWidth > 0 && x < rect.width) {\n // Calculate edge fade opacity\n let edgeOpacity = 1;\n if (x < edgeFadeWidth) {\n // Fade out on left edge\n edgeOpacity = Math.max(0, x / edgeFadeWidth);\n } else if (x > rect.width - edgeFadeWidth) {\n // Fade in on right edge\n edgeOpacity = Math.max(0, (rect.width - x) / edgeFadeWidth);\n }\n\n ctx.globalAlpha = fadeOpacityRef.current * edgeOpacity;\n ctx.fillRect(x, y, barWidth, barHeight);\n }\n }\n }\n\n animationIdRef.current = requestAnimationFrame(draw);\n };\n\n draw();\n\n return () => {\n if (animationIdRef.current) {\n cancelAnimationFrame(animationIdRef.current);\n }\n };\n }, [recorderState]);\n\n // Cleanup on unmount\n useEffect(() => {\n return cleanup;\n }, [cleanup]);\n\n // Expose AudioRecorder API via ref\n useImperativeHandle(\n ref,\n () => ({\n get state() {\n return recorderState;\n },\n start,\n stop,\n dispose: cleanup,\n }),\n [recorderState, start, stop, cleanup],\n );\n\n return (\n <div\n className={twMerge(\"cpk:w-full cpk:py-3 cpk:px-5\", className)}\n {...divProps}\n >\n <canvas ref={canvasRef} className=\"cpk:block cpk:w-full cpk:h-[26px]\" />\n </div>\n );\n});\n\nCopilotChatAudioRecorder.displayName = \"CopilotChatAudioRecorder\";\n","import React from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\n/** Existing union (unchanged) */\nexport type SlotValue<C extends React.ComponentType<any>> =\n | C\n | string\n | Partial<React.ComponentProps<C>>;\n\n/**\n * Shallow equality comparison for objects.\n */\nexport function shallowEqual<T extends Record<string, unknown>>(\n obj1: T,\n obj2: T,\n): boolean {\n const keys1 = Object.keys(obj1);\n const keys2 = Object.keys(obj2);\n\n if (keys1.length !== keys2.length) return false;\n\n for (const key of keys1) {\n if (obj1[key] !== obj2[key]) return false;\n }\n\n return true;\n}\n\n/** Utility: concrete React elements for every slot */\ntype SlotElements<S> = { [K in keyof S]: React.ReactElement };\n\nexport type WithSlots<\n S extends Record<string, React.ComponentType<any>>,\n Rest = {},\n> = {\n /** Per‑slot overrides */\n [K in keyof S]?: SlotValue<S[K]>;\n} & {\n children?: (props: SlotElements<S> & Rest) => React.ReactNode;\n} & Omit<Rest, \"children\">;\n\n/**\n * Check if a value is a React component type (function, class, forwardRef, memo, etc.)\n */\nexport function isReactComponentType(\n value: unknown,\n): value is React.ComponentType<any> {\n if (typeof value === \"function\") {\n return true;\n }\n // forwardRef, memo, lazy have $$typeof but are not valid elements\n if (\n value &&\n typeof value === \"object\" &&\n \"$$typeof\" in value &&\n !React.isValidElement(value)\n ) {\n return true;\n }\n return false;\n}\n\n/**\n * Internal function to render a slot value as a React element (non-memoized).\n */\nfunction renderSlotElement(\n slot: SlotValue<React.ComponentType<any>> | undefined,\n DefaultComponent: React.ComponentType<any>,\n props: Record<string, unknown>,\n): React.ReactElement {\n if (typeof slot === \"string\") {\n // When slot is a string, treat it as a className and merge with existing className\n const existingClassName = props.className as string | undefined;\n return React.createElement(DefaultComponent, {\n ...props,\n className: twMerge(existingClassName, slot),\n });\n }\n\n // Check if slot is a React component type (function, forwardRef, memo, etc.)\n if (isReactComponentType(slot)) {\n return React.createElement(slot, props);\n }\n\n // If slot is a plain object (not a React element), treat it as props override\n if (slot && typeof slot === \"object\" && !React.isValidElement(slot)) {\n return React.createElement(DefaultComponent, {\n ...props,\n ...slot,\n });\n }\n\n return React.createElement(DefaultComponent, props);\n}\n\n/**\n * Internal memoized wrapper component for renderSlot.\n * Uses forwardRef to support ref forwarding.\n */\nconst MemoizedSlotWrapper = React.memo(\n React.forwardRef<unknown, any>(function MemoizedSlotWrapper(props, ref) {\n const { $slot, $component, ...rest } = props;\n const propsWithRef: Record<string, unknown> =\n ref !== null ? { ...rest, ref } : rest;\n return renderSlotElement($slot, $component, propsWithRef);\n }),\n (prev: any, next: any) => {\n // Compare slot and component references\n if (prev.$slot !== next.$slot) return false;\n if (prev.$component !== next.$component) return false;\n\n // Shallow compare remaining props (ref is handled separately by React)\n const { $slot: _ps, $component: _pc, ...prevRest } = prev;\n const { $slot: _ns, $component: _nc, ...nextRest } = next;\n return shallowEqual(\n prevRest as Record<string, unknown>,\n nextRest as Record<string, unknown>,\n );\n },\n);\n\n/**\n * Renders a slot value as a memoized React element.\n * Automatically prevents unnecessary re-renders using shallow prop comparison.\n * Supports ref forwarding.\n *\n * @example\n * renderSlot(customInput, CopilotChatInput, { onSubmit: handleSubmit })\n */\nexport function renderSlot<\n C extends React.ComponentType<any>,\n P = React.ComponentProps<C>,\n>(\n slot: SlotValue<C> | undefined,\n DefaultComponent: C,\n props: P,\n): React.ReactElement {\n return React.createElement(MemoizedSlotWrapper, {\n ...props,\n $slot: slot,\n $component: DefaultComponent,\n } as any);\n}\n","import React, {\n useState,\n useRef,\n KeyboardEvent,\n ChangeEvent,\n useEffect,\n useLayoutEffect,\n forwardRef,\n useImperativeHandle,\n useCallback,\n useMemo,\n} from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { Plus, Mic, ArrowUp, X, Check, Square, Loader2 } from \"lucide-react\";\n\nimport {\n CopilotChatLabels,\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n DropdownMenuSeparator,\n} from \"@/components/ui/dropdown-menu\";\n\nimport { CopilotChatAudioRecorder } from \"./CopilotChatAudioRecorder\";\nimport { renderSlot, WithSlots } from \"@/lib/slots\";\nimport { cn } from \"@/lib/utils\";\n\nexport type CopilotChatInputMode = \"input\" | \"transcribe\" | \"processing\";\n\nexport type ToolsMenuItem = {\n label: string;\n} & (\n | {\n action: () => void;\n items?: never;\n }\n | {\n action?: never;\n items: (ToolsMenuItem | \"-\")[];\n }\n);\n\ntype CopilotChatInputSlots = {\n textArea: typeof CopilotChatInput.TextArea;\n sendButton: typeof CopilotChatInput.SendButton;\n startTranscribeButton: typeof CopilotChatInput.StartTranscribeButton;\n cancelTranscribeButton: typeof CopilotChatInput.CancelTranscribeButton;\n finishTranscribeButton: typeof CopilotChatInput.FinishTranscribeButton;\n addMenuButton: typeof CopilotChatInput.AddMenuButton;\n audioRecorder: typeof CopilotChatAudioRecorder;\n disclaimer: typeof CopilotChatInput.Disclaimer;\n};\n\ntype CopilotChatInputRestProps = {\n mode?: CopilotChatInputMode;\n toolsMenu?: (ToolsMenuItem | \"-\")[];\n autoFocus?: boolean;\n onSubmitMessage?: (value: string) => void;\n onStop?: () => void;\n isRunning?: boolean;\n onStartTranscribe?: () => void;\n onCancelTranscribe?: () => void;\n onFinishTranscribe?: () => void;\n onFinishTranscribeWithAudio?: (audioBlob: Blob) => Promise<void>;\n onAddFile?: () => void;\n value?: string;\n onChange?: (value: string) => void;\n /** Positioning mode for the input container. Default: 'static' */\n positioning?: \"static\" | \"absolute\";\n /** Keyboard height in pixels for mobile keyboard handling */\n keyboardHeight?: number;\n /** Ref for the outer positioning container */\n containerRef?: React.Ref<HTMLDivElement>;\n /** Whether to show the disclaimer. Default: true for absolute positioning, false for static */\n showDisclaimer?: boolean;\n} & Omit<React.HTMLAttributes<HTMLDivElement>, \"onChange\">;\n\ntype CopilotChatInputBaseProps = WithSlots<\n CopilotChatInputSlots,\n CopilotChatInputRestProps\n>;\n\ntype CopilotChatInputChildrenArgs = CopilotChatInputBaseProps extends {\n children?: infer C;\n}\n ? C extends (props: infer P) => React.ReactNode\n ? P\n : never\n : never;\n\nexport type CopilotChatInputProps = Omit<\n CopilotChatInputBaseProps,\n \"children\"\n> & {\n children?: (props: CopilotChatInputChildrenArgs) => React.ReactNode;\n};\n\nconst SLASH_MENU_MAX_VISIBLE_ITEMS = 5;\nconst SLASH_MENU_ITEM_HEIGHT_PX = 40;\n\nexport function CopilotChatInput({\n mode = \"input\",\n onSubmitMessage,\n onStop,\n isRunning = false,\n onStartTranscribe,\n onCancelTranscribe,\n onFinishTranscribe,\n onFinishTranscribeWithAudio,\n onAddFile,\n onChange,\n value,\n toolsMenu,\n autoFocus = true,\n positioning = \"static\",\n keyboardHeight = 0,\n containerRef,\n showDisclaimer,\n textArea,\n sendButton,\n startTranscribeButton,\n cancelTranscribeButton,\n finishTranscribeButton,\n addMenuButton,\n audioRecorder,\n disclaimer,\n children,\n className,\n ...props\n}: CopilotChatInputProps) {\n const isControlled = value !== undefined;\n const [internalValue, setInternalValue] = useState<string>(() => value ?? \"\");\n\n useEffect(() => {\n if (!isControlled && value !== undefined) {\n setInternalValue(value);\n }\n }, [isControlled, value]);\n\n const resolvedValue = isControlled ? (value ?? \"\") : internalValue;\n\n const [layout, setLayout] = useState<\"compact\" | \"expanded\">(\"compact\");\n const ignoreResizeRef = useRef(false);\n const resizeEvaluationRafRef = useRef<number | null>(null);\n const isExpanded = mode === \"input\" && layout === \"expanded\";\n const [commandQuery, setCommandQuery] = useState<string | null>(null);\n const [slashHighlightIndex, setSlashHighlightIndex] = useState(0);\n\n const inputRef = useRef<HTMLTextAreaElement>(null);\n const gridRef = useRef<HTMLDivElement>(null);\n const addButtonContainerRef = useRef<HTMLDivElement>(null);\n const actionsContainerRef = useRef<HTMLDivElement>(null);\n const audioRecorderRef =\n useRef<React.ElementRef<typeof CopilotChatAudioRecorder>>(null);\n const slashMenuRef = useRef<HTMLDivElement>(null);\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n\n const previousModalStateRef = useRef<boolean | undefined>(undefined);\n const measurementCanvasRef = useRef<HTMLCanvasElement | null>(null);\n const measurementsRef = useRef({\n singleLineHeight: 0,\n maxHeight: 0,\n paddingLeft: 0,\n paddingRight: 0,\n });\n\n 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();\n }\n\n previousModalStateRef.current = config?.isModalOpen;\n }, [config?.isModalOpen, autoFocus]);\n\n useEffect(() => {\n if (commandItems.length === 0 && commandQuery !== null) {\n setCommandQuery(null);\n }\n }, [commandItems.length, commandQuery]);\n\n const previousCommandQueryRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (\n commandQuery !== null &&\n commandQuery !== previousCommandQueryRef.current &&\n filteredCommands.length > 0\n ) {\n setSlashHighlightIndex(0);\n }\n\n previousCommandQueryRef.current = commandQuery;\n }, [commandQuery, filteredCommands.length]);\n\n useEffect(() => {\n if (commandQuery === null) {\n setSlashHighlightIndex(0);\n return;\n }\n\n if (filteredCommands.length === 0) {\n setSlashHighlightIndex(-1);\n } else if (\n slashHighlightIndex < 0 ||\n slashHighlightIndex >= filteredCommands.length\n ) {\n setSlashHighlightIndex(0);\n }\n }, [commandQuery, filteredCommands, slashHighlightIndex]);\n\n // Handle recording based on mode changes\n useEffect(() => {\n const recorder = audioRecorderRef.current;\n if (!recorder) {\n return;\n }\n\n if (mode === \"transcribe\") {\n // Start recording when entering transcribe mode\n recorder.start().catch(console.error);\n } else {\n // Stop recording when leaving transcribe mode\n if (recorder.state === \"recording\") {\n recorder.stop().catch(console.error);\n }\n }\n }, [mode]);\n\n useEffect(() => {\n if (mode !== \"input\") {\n setLayout(\"compact\");\n setCommandQuery(null);\n }\n }, [mode]);\n\n const updateSlashState = useCallback(\n (value: string) => {\n if (commandItems.length === 0) {\n setCommandQuery((prev) => (prev === null ? prev : null));\n return;\n }\n\n if (value.startsWith(\"/\")) {\n const firstLine = value.split(/\\r?\\n/, 1)[0] ?? \"\";\n const query = firstLine.slice(1);\n setCommandQuery((prev) => (prev === query ? prev : query));\n } else {\n setCommandQuery((prev) => (prev === null ? prev : null));\n }\n },\n [commandItems.length],\n );\n\n useEffect(() => {\n updateSlashState(resolvedValue);\n }, [resolvedValue, updateSlashState]);\n\n // Handlers\n const handleChange = (e: ChangeEvent<HTMLTextAreaElement>) => {\n const nextValue = e.target.value;\n if (!isControlled) {\n setInternalValue(nextValue);\n }\n onChange?.(nextValue);\n updateSlashState(nextValue);\n };\n\n const clearInputValue = useCallback(() => {\n if (!isControlled) {\n setInternalValue(\"\");\n }\n\n if (onChange) {\n onChange(\"\");\n }\n }, [isControlled, onChange]);\n\n const runCommand = useCallback(\n (item: ToolsMenuItem) => {\n clearInputValue();\n\n item.action?.();\n\n setCommandQuery(null);\n setSlashHighlightIndex(0);\n\n requestAnimationFrame(() => {\n inputRef.current?.focus();\n });\n },\n [clearInputValue],\n );\n\n const handleKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => {\n if (commandQuery !== null && mode === \"input\") {\n if (e.key === \"ArrowDown\") {\n if (filteredCommands.length > 0) {\n e.preventDefault();\n setSlashHighlightIndex((prev) => {\n if (filteredCommands.length === 0) {\n return prev;\n }\n const next = prev === -1 ? 0 : (prev + 1) % filteredCommands.length;\n return next;\n });\n }\n return;\n }\n\n if (e.key === \"ArrowUp\") {\n if (filteredCommands.length > 0) {\n e.preventDefault();\n setSlashHighlightIndex((prev) => {\n if (filteredCommands.length === 0) {\n return prev;\n }\n if (prev === -1) {\n return filteredCommands.length - 1;\n }\n return prev <= 0 ? filteredCommands.length - 1 : prev - 1;\n });\n }\n return;\n }\n\n if (e.key === \"Enter\") {\n const selected =\n slashHighlightIndex >= 0\n ? filteredCommands[slashHighlightIndex]\n : undefined;\n if (selected) {\n e.preventDefault();\n runCommand(selected);\n return;\n }\n }\n\n if (e.key === \"Escape\") {\n e.preventDefault();\n setCommandQuery(null);\n return;\n }\n }\n\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n if (isProcessing) {\n onStop?.();\n } else {\n send();\n }\n }\n };\n\n const send = () => {\n if (!onSubmitMessage) {\n return;\n }\n const trimmed = resolvedValue.trim();\n if (!trimmed) {\n return;\n }\n\n onSubmitMessage(trimmed);\n\n if (!isControlled) {\n setInternalValue(\"\");\n onChange?.(\"\");\n }\n\n if (inputRef.current) {\n inputRef.current.focus();\n }\n };\n\n const BoundTextArea = renderSlot(textArea, CopilotChatInput.TextArea, {\n ref: inputRef,\n value: resolvedValue,\n onChange: handleChange,\n onKeyDown: handleKeyDown,\n autoFocus: autoFocus,\n className: twMerge(\n \"cpk:w-full cpk:py-3\",\n isExpanded ? \"cpk:px-5\" : \"cpk:pr-5\",\n ),\n });\n\n const isProcessing = mode !== \"transcribe\" && isRunning;\n const canSend = resolvedValue.trim().length > 0 && !!onSubmitMessage;\n const canStop = !!onStop;\n\n const handleSendButtonClick = () => {\n if (isProcessing) {\n onStop?.();\n return;\n }\n send();\n };\n\n const BoundAudioRecorder = renderSlot(\n audioRecorder,\n CopilotChatAudioRecorder,\n {\n ref: audioRecorderRef,\n },\n );\n\n const BoundSendButton = renderSlot(sendButton, CopilotChatInput.SendButton, {\n onClick: handleSendButtonClick,\n disabled: isProcessing ? !canStop : !canSend,\n children:\n isProcessing && canStop ? (\n <Square className=\"cpk:size-[18px] cpk:fill-current\" />\n ) : undefined,\n });\n\n const BoundStartTranscribeButton = renderSlot(\n startTranscribeButton,\n CopilotChatInput.StartTranscribeButton,\n {\n onClick: onStartTranscribe,\n },\n );\n\n const BoundCancelTranscribeButton = renderSlot(\n cancelTranscribeButton,\n CopilotChatInput.CancelTranscribeButton,\n {\n onClick: onCancelTranscribe,\n },\n );\n\n // Handler for finish button - stops recording and passes audio blob\n const handleFinishTranscribe = useCallback(async () => {\n const recorder = audioRecorderRef.current;\n if (recorder && recorder.state === \"recording\") {\n try {\n const audioBlob = await recorder.stop();\n if (onFinishTranscribeWithAudio) {\n await onFinishTranscribeWithAudio(audioBlob);\n }\n } catch (error) {\n console.error(\"Failed to stop recording:\", error);\n }\n }\n // Always call the original handler to reset mode\n onFinishTranscribe?.();\n }, [onFinishTranscribe, onFinishTranscribeWithAudio]);\n\n const BoundFinishTranscribeButton = renderSlot(\n finishTranscribeButton,\n CopilotChatInput.FinishTranscribeButton,\n {\n onClick: handleFinishTranscribe,\n },\n );\n\n const BoundAddMenuButton = renderSlot(\n addMenuButton,\n CopilotChatInput.AddMenuButton,\n {\n disabled: mode === \"transcribe\",\n onAddFile,\n toolsMenu,\n },\n );\n\n const BoundDisclaimer = renderSlot(\n disclaimer,\n CopilotChatInput.Disclaimer,\n {},\n );\n\n // Determine whether to show disclaimer based on prop or positioning default\n const shouldShowDisclaimer = showDisclaimer ?? positioning === \"absolute\";\n\n if (children) {\n const childProps = {\n textArea: BoundTextArea,\n audioRecorder: BoundAudioRecorder,\n sendButton: BoundSendButton,\n startTranscribeButton: BoundStartTranscribeButton,\n cancelTranscribeButton: BoundCancelTranscribeButton,\n finishTranscribeButton: BoundFinishTranscribeButton,\n addMenuButton: BoundAddMenuButton,\n disclaimer: BoundDisclaimer,\n onSubmitMessage,\n onStop,\n isRunning,\n onStartTranscribe,\n onCancelTranscribe,\n onFinishTranscribe,\n onAddFile,\n mode,\n toolsMenu,\n autoFocus,\n positioning,\n keyboardHeight,\n showDisclaimer: shouldShowDisclaimer,\n } as CopilotChatInputChildrenArgs;\n\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children(childProps)}\n </div>\n );\n }\n\n const handleContainerClick = (e: React.MouseEvent<HTMLDivElement>) => {\n // Don't focus if clicking on buttons or other interactive elements\n const target = e.target as HTMLElement;\n if (\n target.tagName !== \"BUTTON\" &&\n !target.closest(\"button\") &&\n inputRef.current &&\n mode === \"input\"\n ) {\n inputRef.current.focus();\n }\n };\n\n const ensureMeasurements = useCallback(() => {\n const textarea = inputRef.current;\n if (!textarea) {\n return;\n }\n\n const previousValue = textarea.value;\n const previousHeight = textarea.style.height;\n\n textarea.style.height = \"auto\";\n\n const computedStyle = window.getComputedStyle(textarea);\n const paddingLeft = parseFloat(computedStyle.paddingLeft) || 0;\n const paddingRight = parseFloat(computedStyle.paddingRight) || 0;\n const paddingTop = parseFloat(computedStyle.paddingTop) || 0;\n const paddingBottom = parseFloat(computedStyle.paddingBottom) || 0;\n\n textarea.value = \"\";\n const singleLineHeight = textarea.scrollHeight;\n textarea.value = previousValue;\n\n const contentHeight = singleLineHeight - paddingTop - paddingBottom;\n const maxHeight = contentHeight * 5 + paddingTop + paddingBottom;\n\n measurementsRef.current = {\n singleLineHeight,\n maxHeight,\n paddingLeft,\n paddingRight,\n };\n\n textarea.style.height = previousHeight;\n textarea.style.maxHeight = `${maxHeight}px`;\n }, []);\n\n const adjustTextareaHeight = useCallback(() => {\n const textarea = inputRef.current;\n if (!textarea) {\n return 0;\n }\n\n if (measurementsRef.current.singleLineHeight === 0) {\n ensureMeasurements();\n }\n\n const { maxHeight } = measurementsRef.current;\n if (maxHeight) {\n textarea.style.maxHeight = `${maxHeight}px`;\n }\n\n textarea.style.height = \"auto\";\n const scrollHeight = textarea.scrollHeight;\n if (maxHeight) {\n textarea.style.height = `${Math.min(scrollHeight, maxHeight)}px`;\n } else {\n textarea.style.height = `${scrollHeight}px`;\n }\n\n return scrollHeight;\n }, [ensureMeasurements]);\n\n const updateLayout = useCallback((nextLayout: \"compact\" | \"expanded\") => {\n setLayout((prev) => {\n if (prev === nextLayout) {\n return prev;\n }\n ignoreResizeRef.current = true;\n return nextLayout;\n });\n }, []);\n\n const evaluateLayout = useCallback(() => {\n if (mode !== \"input\") {\n updateLayout(\"compact\");\n return;\n }\n\n if (\n typeof window !== \"undefined\" &&\n typeof window.matchMedia === \"function\"\n ) {\n const isMobileViewport = window.matchMedia(\"(max-width: 767px)\").matches;\n if (isMobileViewport) {\n ensureMeasurements();\n adjustTextareaHeight();\n updateLayout(\"expanded\");\n return;\n }\n }\n\n const textarea = inputRef.current;\n const grid = gridRef.current;\n const addContainer = addButtonContainerRef.current;\n const actionsContainer = actionsContainerRef.current;\n\n if (!textarea || !grid || !addContainer || !actionsContainer) {\n return;\n }\n\n if (measurementsRef.current.singleLineHeight === 0) {\n ensureMeasurements();\n }\n\n const scrollHeight = adjustTextareaHeight();\n const baseline = measurementsRef.current.singleLineHeight;\n const hasExplicitBreak = resolvedValue.includes(\"\\n\");\n const renderedMultiline =\n baseline > 0 ? scrollHeight > baseline + 1 : false;\n let shouldExpand = hasExplicitBreak || renderedMultiline;\n\n if (!shouldExpand) {\n 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) {\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 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 const textareaStyles = window.getComputedStyle(textarea);\n const font =\n textareaStyles.font ||\n `${textareaStyles.fontStyle} ${textareaStyles.fontVariant} ${textareaStyles.fontWeight} ${textareaStyles.fontSize}/${textareaStyles.lineHeight} ${textareaStyles.fontFamily}`;\n context.font = font;\n\n const compactInnerWidth = Math.max(\n compactWidth -\n (measurementsRef.current.paddingLeft || 0) -\n (measurementsRef.current.paddingRight || 0),\n 0,\n );\n\n if (compactInnerWidth > 0) {\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 }\n }\n }\n }\n\n const nextLayout = shouldExpand ? \"expanded\" : \"compact\";\n updateLayout(nextLayout);\n }, [\n adjustTextareaHeight,\n ensureMeasurements,\n mode,\n resolvedValue,\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 scheduleEvaluation = () => {\n if (ignoreResizeRef.current) {\n ignoreResizeRef.current = false;\n return;\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 const observer = new ResizeObserver(() => {\n scheduleEvaluation();\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 // 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 positioning === \"absolute\" &&\n \"cpk:absolute cpk:bottom-0 cpk:left-0 cpk:right-0 cpk:z-20 cpk:pointer-events-none\",\n className,\n )}\n style={{\n transform:\n keyboardHeight > 0 ? `translateY(-${keyboardHeight}px)` : undefined,\n transition: \"transform 0.2s ease-out\",\n }}\n {...props}\n >\n <div className=\"cpk:max-w-3xl cpk:mx-auto cpk:py-0 cpk:px-4 cpk:sm:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-4 cpk:pointer-events-auto\">\n {inputPill}\n </div>\n {shouldShowDisclaimer && BoundDisclaimer}\n </div>\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotChatInput {\n export const SendButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, children, ...props }) => (\n <div className=\"cpk:mr-[10px]\">\n <Button\n type=\"button\"\n data-testid=\"copilot-send-button\"\n variant=\"chatInputToolbarPrimary\"\n size=\"chatInputToolbarIcon\"\n className={className}\n {...props}\n >\n {children ?? <ArrowUp className=\"cpk:size-[18px]\" />}\n </Button>\n </div>\n );\n\n export const ToolbarButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & {\n icon: React.ReactNode;\n labelKey: keyof CopilotChatLabels;\n defaultClassName?: string;\n }\n > = ({ icon, labelKey, defaultClassName, className, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"chatInputToolbarSecondary\"\n size=\"chatInputToolbarIcon\"\n className={twMerge(defaultClassName, className)}\n {...props}\n >\n {icon}\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">\n <p>{labels[labelKey]}</p>\n </TooltipContent>\n </Tooltip>\n );\n };\n\n export const StartTranscribeButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = (props) => (\n <ToolbarButton\n data-testid=\"copilot-start-transcribe-button\"\n icon={<Mic className=\"cpk:size-[18px]\" />}\n labelKey=\"chatInputToolbarStartTranscribeButtonLabel\"\n defaultClassName=\"cpk:mr-2\"\n {...props}\n />\n );\n\n export const CancelTranscribeButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = (props) => (\n <ToolbarButton\n data-testid=\"copilot-cancel-transcribe-button\"\n icon={<X className=\"cpk:size-[18px]\" />}\n labelKey=\"chatInputToolbarCancelTranscribeButtonLabel\"\n defaultClassName=\"cpk:mr-2\"\n {...props}\n />\n );\n\n export const FinishTranscribeButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = (props) => (\n <ToolbarButton\n data-testid=\"copilot-finish-transcribe-button\"\n icon={<Check className=\"cpk:size-[18px]\" />}\n labelKey=\"chatInputToolbarFinishTranscribeButtonLabel\"\n defaultClassName=\"cpk:mr-[10px]\"\n {...props}\n />\n );\n\n export const AddMenuButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & {\n toolsMenu?: (ToolsMenuItem | \"-\")[];\n onAddFile?: () => void;\n }\n > = ({ className, toolsMenu, onAddFile, disabled, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n\n 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 return (\n <DropdownMenu>\n <Tooltip>\n <TooltipTrigger asChild>\n <DropdownMenuTrigger asChild>\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 </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 files and more</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 // Auto-scroll input into view on mobile when focused\n useEffect(() => {\n const textarea = internalTextareaRef.current;\n if (!textarea) return;\n\n const handleFocus = () => {\n // Small delay to let the keyboard start appearing\n setTimeout(() => {\n textarea.scrollIntoView({ behavior: \"smooth\", block: \"nearest\" });\n }, 300);\n };\n\n textarea.addEventListener(\"focus\", handleFocus);\n return () => textarea.removeEventListener(\"focus\", handleFocus);\n }, []);\n\n useEffect(() => {\n if (autoFocus) {\n internalTextareaRef.current?.focus();\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","import * as React from \"react\";\nimport { createComponent } from \"@lit-labs/react\";\nimport type { CopilotKitCore } from \"@copilotkitnext/core\";\n\ntype CopilotKitInspectorBaseProps = {\n core?: CopilotKitCore | null;\n [key: string]: unknown;\n};\n\ntype InspectorComponent = React.ComponentType<CopilotKitInspectorBaseProps>;\n\nexport interface CopilotKitInspectorProps extends CopilotKitInspectorBaseProps {}\n\nexport const CopilotKitInspector: React.FC<CopilotKitInspectorProps> = ({\n core,\n ...rest\n}) => {\n const [InspectorComponent, setInspectorComponent] =\n React.useState<InspectorComponent | null>(null);\n\n React.useEffect(() => {\n let mounted = true;\n\n // Load the web component only on the client to keep SSR output stable.\n import(\"@copilotkitnext/web-inspector\").then((mod) => {\n mod.defineWebInspector?.();\n\n const Component = createComponent({\n tagName: mod.WEB_INSPECTOR_TAG,\n elementClass: mod.WebInspectorElement,\n react: React,\n }) as InspectorComponent;\n\n if (mounted) {\n setInspectorComponent(() => Component);\n }\n });\n\n return () => {\n mounted = false;\n };\n }, []);\n\n // During SSR (and until the client finishes loading), render nothing to keep markup consistent.\n if (!InspectorComponent) return null;\n\n return <InspectorComponent {...rest} core={core ?? null} />;\n};\n\nCopilotKitInspector.displayName = \"CopilotKitInspector\";\n","\"use client\";\n\nimport React, { useEffect, useRef, useState, useCallback } from \"react\";\nimport { z } from \"zod\";\nimport type { AbstractAgent, RunAgentResult } from \"@ag-ui/client\";\n\n// Protocol version supported\nconst PROTOCOL_VERSION = \"2025-06-18\";\n\n// Build sandbox proxy HTML with optional extra CSP domains from resource metadata\nfunction buildSandboxHTML(extraCspDomains?: string[]): string {\n const baseScriptSrc =\n \"'self' 'wasm-unsafe-eval' 'unsafe-inline' 'unsafe-eval' blob: data: http://localhost:* https://localhost:*\";\n const baseFrameSrc = \"* blob: data: http://localhost:* https://localhost:*\";\n const extra = extraCspDomains?.length ? \" \" + extraCspDomains.join(\" \") : \"\";\n const scriptSrc = baseScriptSrc + extra;\n const frameSrc = baseFrameSrc + extra;\n\n return `<!doctype html>\n<html>\n<head>\n<meta charset=\"utf-8\" />\n<meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self'; img-src * data: blob: 'unsafe-inline'; media-src * blob: data:; font-src * blob: data:; script-src ${scriptSrc}; style-src * blob: data: 'unsafe-inline'; connect-src *; frame-src ${frameSrc}; base-uri 'self';\" />\n<style>html,body{margin:0;padding:0;height:100%;width:100%;overflow:hidden}*{box-sizing:border-box}iframe{background-color:transparent;border:none;padding:0;overflow:hidden;width:100%;height:100%}</style>\n</head>\n<body>\n<script>\nif(window.self===window.top){throw new Error(\"This file must be used in an iframe.\")}\nconst inner=document.createElement(\"iframe\");\ninner.style=\"width:100%;height:100%;border:none;\";\ninner.setAttribute(\"sandbox\",\"allow-scripts allow-same-origin allow-forms\");\ndocument.body.appendChild(inner);\nwindow.addEventListener(\"message\",async(event)=>{\nif(event.source===window.parent){\nif(event.data&&event.data.method===\"ui/notifications/sandbox-resource-ready\"){\nconst{html,sandbox}=event.data.params;\nif(typeof sandbox===\"string\")inner.setAttribute(\"sandbox\",sandbox);\nif(typeof html===\"string\")inner.srcdoc=html;\n}else if(inner&&inner.contentWindow){\ninner.contentWindow.postMessage(event.data,\"*\");\n}\n}else if(event.source===inner.contentWindow){\nwindow.parent.postMessage(event.data,\"*\");\n}\n});\nwindow.parent.postMessage({jsonrpc:\"2.0\",method:\"ui/notifications/sandbox-proxy-ready\",params:{}},\"*\");\n</script>\n</body>\n</html>`;\n}\n\n/**\n * Queue for serializing MCP app requests to an agent.\n * Ensures requests wait for the agent to stop running and are processed one at a time.\n */\nclass MCPAppsRequestQueue {\n private queues = new Map<\n string,\n Array<{\n execute: () => Promise<RunAgentResult>;\n resolve: (result: RunAgentResult) => void;\n reject: (error: Error) => void;\n }>\n >();\n private processing = new Map<string, boolean>();\n\n /**\n * Add a request to the queue for a specific agent thread.\n * Returns a promise that resolves when the request completes.\n */\n async enqueue(\n agent: AbstractAgent,\n request: () => Promise<RunAgentResult>,\n ): Promise<RunAgentResult> {\n const threadId = agent.threadId || \"default\";\n\n return new Promise((resolve, reject) => {\n // Get or create queue for this thread\n let queue = this.queues.get(threadId);\n if (!queue) {\n queue = [];\n this.queues.set(threadId, queue);\n }\n\n // Add request to queue\n queue.push({ execute: request, resolve, reject });\n\n // Start processing if not already running\n this.processQueue(threadId, agent);\n });\n }\n\n private async processQueue(\n threadId: string,\n agent: AbstractAgent,\n ): Promise<void> {\n // If already processing this queue, return\n if (this.processing.get(threadId)) {\n return;\n }\n\n this.processing.set(threadId, true);\n\n try {\n const queue = this.queues.get(threadId);\n if (!queue) return;\n\n while (queue.length > 0) {\n const item = queue[0]!;\n\n try {\n // Wait for any active run to complete before processing\n await this.waitForAgentIdle(agent);\n\n // Execute the request\n const result = await item.execute();\n item.resolve(result);\n } catch (error) {\n item.reject(\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n\n // Remove processed item\n queue.shift();\n }\n } finally {\n this.processing.set(threadId, false);\n }\n }\n\n private waitForAgentIdle(agent: AbstractAgent): Promise<void> {\n return new Promise((resolve) => {\n if (!agent.isRunning) {\n resolve();\n return;\n }\n\n let done = false;\n const finish = () => {\n if (done) return;\n done = true;\n clearInterval(checkInterval);\n sub.unsubscribe();\n resolve();\n };\n\n const sub = agent.subscribe({\n onRunFinalized: finish,\n onRunFailed: finish,\n });\n\n // Fallback for reconnect scenarios where events don't fire\n const checkInterval = setInterval(() => {\n if (!agent.isRunning) finish();\n }, 500);\n });\n }\n}\n\n// Global queue instance for all MCP app requests\nconst mcpAppsRequestQueue = new MCPAppsRequestQueue();\n\n/**\n * Activity type for MCP Apps events - must match the middleware's MCPAppsActivityType\n */\nexport const MCPAppsActivityType = \"mcp-apps\";\n\n// Zod schema for activity content validation (middleware 0.0.2 format)\nexport const MCPAppsActivityContentSchema = z.object({\n result: z.object({\n content: z.array(z.any()).optional(),\n structuredContent: z.any().optional(),\n isError: z.boolean().optional(),\n }),\n // Resource URI to fetch (e.g., \"ui://server/dashboard\")\n resourceUri: z.string(),\n // MD5 hash of server config (renamed from serverId in 0.0.1)\n serverHash: z.string(),\n // Optional stable server ID from config (takes precedence over serverHash)\n serverId: z.string().optional(),\n // Original tool input arguments\n toolInput: z.record(z.unknown()).optional(),\n});\n\nexport type MCPAppsActivityContent = z.infer<\n typeof MCPAppsActivityContentSchema\n>;\n\n// Type for the resource fetched from the server\ninterface FetchedResource {\n uri: string;\n mimeType?: string;\n text?: string;\n blob?: string;\n _meta?: {\n ui?: {\n prefersBorder?: boolean;\n csp?: {\n connectDomains?: string[];\n resourceDomains?: string[];\n };\n };\n };\n}\n\ninterface JSONRPCRequest {\n jsonrpc: \"2.0\";\n id: string | number;\n method: string;\n params?: Record<string, unknown>;\n}\n\ninterface JSONRPCResponse {\n jsonrpc: \"2.0\";\n id: string | number;\n result?: unknown;\n error?: { code: number; message: string };\n}\n\ninterface JSONRPCNotification {\n jsonrpc: \"2.0\";\n method: string;\n params?: Record<string, unknown>;\n}\n\ntype JSONRPCMessage = JSONRPCRequest | JSONRPCResponse | JSONRPCNotification;\n\nfunction isRequest(msg: JSONRPCMessage): msg is JSONRPCRequest {\n return \"id\" in msg && \"method\" in msg;\n}\n\nfunction isNotification(msg: JSONRPCMessage): msg is JSONRPCNotification {\n return !(\"id\" in msg) && \"method\" in msg;\n}\n\n/**\n * Props for the activity renderer component\n */\ninterface MCPAppsActivityRendererProps {\n activityType: string;\n content: MCPAppsActivityContent;\n message: unknown; // ActivityMessage from @ag-ui/core\n agent: AbstractAgent | undefined;\n}\n\n/**\n * MCP Apps Extension Activity Renderer\n *\n * Renders MCP Apps UI in a sandboxed iframe with full protocol support.\n * Fetches resource content on-demand via proxied MCP requests.\n */\nexport const MCPAppsActivityRenderer: React.FC<MCPAppsActivityRendererProps> =\n function MCPAppsActivityRenderer({ content, agent }) {\n const containerRef = useRef<HTMLDivElement>(null);\n const iframeRef = useRef<HTMLIFrameElement | null>(null);\n const [iframeReady, setIframeReady] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [iframeSize, setIframeSize] = useState<{\n width?: number;\n height?: number;\n }>({});\n const [fetchedResource, setFetchedResource] =\n useState<FetchedResource | null>(null);\n\n // Use refs for values that shouldn't trigger re-renders but need latest values\n const contentRef = useRef(content);\n contentRef.current = content;\n\n // Store agent in a ref for use in async handlers\n const agentRef = useRef(agent);\n agentRef.current = agent;\n\n // Ref to track fetch state - survives StrictMode remounts\n const fetchStateRef = useRef<{\n inProgress: boolean;\n promise: Promise<FetchedResource | null> | null;\n resourceUri: string | null;\n }>({ inProgress: false, promise: null, resourceUri: null });\n\n // Callback to send a message to the iframe\n const sendToIframe = useCallback((msg: JSONRPCMessage) => {\n if (iframeRef.current?.contentWindow) {\n console.log(\"[MCPAppsRenderer] Sending to iframe:\", msg);\n iframeRef.current.contentWindow.postMessage(msg, \"*\");\n }\n }, []);\n\n // Callback to send a JSON-RPC response\n const sendResponse = useCallback(\n (id: string | number, result: unknown) => {\n sendToIframe({\n jsonrpc: \"2.0\",\n id,\n result,\n });\n },\n [sendToIframe],\n );\n\n // Callback to send a JSON-RPC error response\n const sendErrorResponse = useCallback(\n (id: string | number, code: number, message: string) => {\n sendToIframe({\n jsonrpc: \"2.0\",\n id,\n error: { code, message },\n });\n },\n [sendToIframe],\n );\n\n // Callback to send a notification\n const sendNotification = useCallback(\n (method: string, params?: Record<string, unknown>) => {\n sendToIframe({\n jsonrpc: \"2.0\",\n method,\n params: params || {},\n });\n },\n [sendToIframe],\n );\n\n // Effect 0: Fetch the resource content on mount\n // Uses ref-based deduplication to handle React StrictMode double-mounting\n useEffect(() => {\n const { resourceUri, serverHash, serverId } = content;\n\n // Check if we already have a fetch in progress for this resource\n // This handles StrictMode double-mounting - second mount reuses first mount's promise\n if (\n fetchStateRef.current.inProgress &&\n fetchStateRef.current.resourceUri === resourceUri\n ) {\n // Reuse the existing promise\n fetchStateRef.current.promise\n ?.then((resource) => {\n if (resource) {\n setFetchedResource(resource);\n setIsLoading(false);\n }\n })\n .catch((err) => {\n setError(err instanceof Error ? err : new Error(String(err)));\n setIsLoading(false);\n });\n return;\n }\n\n if (!agent) {\n setError(new Error(\"No agent available to fetch resource\"));\n setIsLoading(false);\n return;\n }\n\n // Mark fetch as in progress\n fetchStateRef.current.inProgress = true;\n fetchStateRef.current.resourceUri = resourceUri;\n\n // Create the fetch promise using the queue to serialize requests\n const fetchPromise = (async (): Promise<FetchedResource | null> => {\n try {\n // Use queue to wait for agent to be idle and serialize requests\n const runResult = await mcpAppsRequestQueue.enqueue(agent, () =>\n agent.runAgent({\n forwardedProps: {\n __proxiedMCPRequest: {\n serverHash,\n serverId, // optional, takes precedence if provided\n method: \"resources/read\",\n params: { uri: resourceUri },\n },\n },\n }),\n );\n\n // Extract resource from result\n // The response format is: { contents: [{ uri, mimeType, text?, blob?, _meta? }] }\n const resultData = runResult.result as\n | { contents?: FetchedResource[] }\n | undefined;\n const resource = resultData?.contents?.[0];\n\n if (!resource) {\n throw new Error(\"No resource content in response\");\n }\n\n return resource;\n } catch (err) {\n console.error(\"[MCPAppsRenderer] Failed to fetch resource:\", err);\n throw err;\n } finally {\n // Mark fetch as complete\n fetchStateRef.current.inProgress = false;\n }\n })();\n\n // Store the promise for potential reuse\n fetchStateRef.current.promise = fetchPromise;\n\n // Handle the result\n fetchPromise\n .then((resource) => {\n if (resource) {\n setFetchedResource(resource);\n setIsLoading(false);\n }\n })\n .catch((err) => {\n setError(err instanceof Error ? err : new Error(String(err)));\n setIsLoading(false);\n });\n\n // No cleanup needed - we want the fetch to complete even if StrictMode unmounts\n }, [agent, content]);\n\n // Effect 1: Setup sandbox proxy iframe and communication (after resource is fetched)\n useEffect(() => {\n // Wait for resource to be fetched\n if (isLoading || !fetchedResource) {\n return;\n }\n\n // Capture container reference at effect start (refs are cleared during unmount)\n const container = containerRef.current;\n if (!container) {\n return;\n }\n\n let mounted = true;\n let messageHandler: ((event: MessageEvent) => void) | null = null;\n let initialListener: ((event: MessageEvent) => void) | null = null;\n let createdIframe: HTMLIFrameElement | null = null;\n\n const setup = async () => {\n try {\n // Create sandbox proxy iframe\n const iframe = document.createElement(\"iframe\");\n createdIframe = iframe; // Track for cleanup\n iframe.style.width = \"100%\";\n iframe.style.height = \"100px\"; // Start small, will be resized by size-changed notification\n iframe.style.border = \"none\";\n iframe.style.backgroundColor = \"transparent\";\n iframe.style.display = \"block\";\n iframe.setAttribute(\n \"sandbox\",\n \"allow-scripts allow-same-origin allow-forms\",\n );\n\n // Wait for sandbox proxy to be ready\n const sandboxReady = new Promise<void>((resolve) => {\n initialListener = (event: MessageEvent) => {\n if (event.source === iframe.contentWindow) {\n if (\n event.data?.method === \"ui/notifications/sandbox-proxy-ready\"\n ) {\n if (initialListener) {\n window.removeEventListener(\"message\", initialListener);\n initialListener = null;\n }\n resolve();\n }\n }\n };\n window.addEventListener(\"message\", initialListener);\n });\n\n // Check mounted before adding to DOM (handles StrictMode double-mount)\n if (!mounted) {\n if (initialListener) {\n window.removeEventListener(\"message\", initialListener);\n initialListener = null;\n }\n return;\n }\n\n // Build sandbox HTML with CSP domains from resource metadata\n const cspDomains = fetchedResource._meta?.ui?.csp?.resourceDomains;\n iframe.srcdoc = buildSandboxHTML(cspDomains);\n iframeRef.current = iframe;\n container.appendChild(iframe);\n\n // Wait for sandbox proxy to signal ready\n await sandboxReady;\n if (!mounted) return;\n\n console.log(\"[MCPAppsRenderer] Sandbox proxy ready\");\n\n // Setup message handler for JSON-RPC messages from the inner iframe\n messageHandler = async (event: MessageEvent) => {\n if (event.source !== iframe.contentWindow) return;\n\n const msg = event.data as JSONRPCMessage;\n if (!msg || typeof msg !== \"object\" || msg.jsonrpc !== \"2.0\")\n return;\n\n console.log(\"[MCPAppsRenderer] Received from iframe:\", msg);\n\n // Handle requests (need response)\n if (isRequest(msg)) {\n switch (msg.method) {\n case \"ui/initialize\": {\n // Respond with host capabilities\n sendResponse(msg.id, {\n protocolVersion: PROTOCOL_VERSION,\n hostInfo: {\n name: \"CopilotKit MCP Apps Host\",\n version: \"1.0.0\",\n },\n hostCapabilities: {\n openLinks: {},\n logging: {},\n },\n hostContext: {\n theme: \"light\",\n platform: \"web\",\n },\n });\n break;\n }\n\n case \"ui/message\": {\n // Add message to CopilotKit chat\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 };\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: (params.role as \"user\" | \"assistant\") || \"user\",\n content: textContent,\n });\n }\n sendResponse(msg.id, { isError: false });\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 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 \"@copilotkitnext/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 _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 return this._renderToolCalls;\n }\n\n setRenderToolCalls(renderToolCalls: ReactToolCallRenderer<any>[]): void {\n this._renderToolCalls = renderToolCalls;\n\n // Notify React-specific subscribers\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","\"use client\";\n\nimport type { AbstractAgent } from \"@ag-ui/client\";\nimport type { FrontendTool } from \"@copilotkitnext/core\";\nimport type React from \"react\";\nimport {\n createContext,\n useContext,\n type ReactNode,\n useMemo,\n useEffect,\n useReducer,\n useRef,\n useState,\n} from \"react\";\nimport { z } from \"zod\";\nimport { CopilotKitInspector } from \"../components/CopilotKitInspector\";\nimport {\n MCPAppsActivityContentSchema,\n MCPAppsActivityRenderer,\n MCPAppsActivityType,\n} from \"../components/MCPAppsActivityRenderer\";\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\";\n\nconst HEADER_NAME = \"X-CopilotCloud-Public-Api-Key\";\nconst COPILOT_CLOUD_CHAT_URL = \"https://api.cloud.copilotkit.ai/copilotkit/v1\";\n\n// Define the context value interface - idiomatic React naming\nexport interface CopilotKitContextValue {\n copilotkit: CopilotKitCoreReact;\n /**\n * Set of tool call IDs currently being executed.\n * This is tracked at the provider level to ensure tool execution events\n * are captured even before child components mount.\n */\n executingToolCallIds: ReadonlySet<string>;\n}\n\n// Empty set for default context value\nconst EMPTY_SET: ReadonlySet<string> = new Set();\n\n// Create the CopilotKit context\nconst CopilotKitContext = createContext<CopilotKitContextValue>({\n copilotkit: null!,\n executingToolCallIds: EMPTY_SET,\n});\n\n// Provider props interface\nexport interface CopilotKitProviderProps {\n children: ReactNode;\n runtimeUrl?: string;\n headers?: Record<string, string>;\n /**\n * Credentials mode for fetch requests (e.g., \"include\" for HTTP-only cookies in cross-origin requests).\n */\n credentials?: RequestCredentials;\n /**\n * The Copilot Cloud public API key.\n */\n publicApiKey?: string;\n /**\n * Alias for `publicApiKey`\n **/\n publicLicenseKey?: string;\n 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 showDevConsole?: boolean | \"auto\";\n}\n\n// Small helper to normalize array props to a stable reference and warn\nfunction useStableArrayProp<T>(\n prop: T[] | undefined,\n warningMessage?: string,\n isMeaningfulChange?: (initial: T[], next: T[]) => boolean,\n): T[] {\n const empty = useMemo<T[]>(() => [], []);\n const value = prop ?? empty;\n const initial = useRef(value);\n\n useEffect(() => {\n if (\n warningMessage &&\n value !== initial.current &&\n (isMeaningfulChange ? isMeaningfulChange(initial.current, value) : true)\n ) {\n console.error(warningMessage);\n }\n }, [value, warningMessage]);\n\n return value;\n}\n\n// Provider component\nexport const CopilotKitProvider: React.FC<CopilotKitProviderProps> = ({\n children,\n runtimeUrl,\n headers = {},\n credentials,\n publicApiKey,\n publicLicenseKey,\n properties = {},\n agents__unsafe_dev_only: agents = {},\n selfManagedAgents = {},\n renderToolCalls,\n renderActivityMessages,\n renderCustomMessages,\n frontendTools,\n humanInTheLoop,\n showDevConsole = false,\n useSingleEndpoint = false,\n}) => {\n const [shouldRenderInspector, setShouldRenderInspector] = useState(false);\n\n useEffect(() => {\n if (typeof window === \"undefined\") {\n return;\n }\n\n if (showDevConsole === true) {\n // Explicitly show the inspector\n setShouldRenderInspector(true);\n } else if (showDevConsole === \"auto\") {\n // Show on localhost or 127.0.0.1 only\n const localhostHosts = new Set([\"localhost\", \"127.0.0.1\"]);\n if (localhostHosts.has(window.location.hostname)) {\n setShouldRenderInspector(true);\n } else {\n setShouldRenderInspector(false);\n }\n } else {\n // showDevConsole is false or undefined (default false)\n setShouldRenderInspector(false);\n }\n }, [showDevConsole]);\n\n // Normalize array props to stable references with clear dev warnings\n const renderToolCallsList = useStableArrayProp<ReactToolCallRenderer<any>>(\n renderToolCalls,\n \"renderToolCalls must be a stable array. If you want to dynamically add or remove tools, use `useFrontendTool` instead.\",\n (initial, next) => {\n // Only warn if the shape (names+agentId) changed. Allow identity changes\n // to support updated closures from parents (e.g., Storybook state).\n const key = (rc?: ReactToolCallRenderer<unknown>) =>\n `${rc?.agentId ?? \"\"}:${rc?.name ?? \"\"}`;\n const setFrom = (arr: ReactToolCallRenderer<unknown>[]) =>\n new Set(arr.map(key));\n const a = setFrom(initial);\n const b = setFrom(next);\n if (a.size !== b.size) return true;\n for (const k of a) if (!b.has(k)) return true;\n return false;\n },\n );\n\n const renderCustomMessagesList =\n useStableArrayProp<ReactCustomMessageRenderer>(\n renderCustomMessages,\n \"renderCustomMessages must be a stable array.\",\n );\n\n const renderActivityMessagesList = useStableArrayProp<\n ReactActivityMessageRenderer<any>\n >(renderActivityMessages, \"renderActivityMessages must be a stable array.\");\n\n // Built-in activity renderers that are always included\n const builtInActivityRenderers = useMemo<ReactActivityMessageRenderer<any>[]>(\n () => [\n {\n activityType: MCPAppsActivityType,\n content: MCPAppsActivityContentSchema,\n render: MCPAppsActivityRenderer,\n },\n ],\n [],\n );\n\n // Combine user-provided activity renderers with built-in ones\n // User-provided renderers take precedence (come first) so they can override built-ins\n const allActivityRenderers = useMemo(() => {\n return [...renderActivityMessagesList, ...builtInActivityRenderers];\n }, [renderActivityMessagesList, builtInActivityRenderers]);\n\n const resolvedPublicKey = publicApiKey ?? publicLicenseKey;\n const mergedAgents = useMemo(\n () => ({ ...agents, ...selfManagedAgents }),\n [agents, selfManagedAgents],\n );\n const hasLocalAgents = mergedAgents && Object.keys(mergedAgents).length > 0;\n\n // Merge a provided publicApiKey into headers (without overwriting an explicit header).\n const mergedHeaders = useMemo(() => {\n if (!resolvedPublicKey) return headers;\n if (headers[HEADER_NAME]) return headers;\n return {\n ...headers,\n [HEADER_NAME]: resolvedPublicKey,\n };\n }, [headers, resolvedPublicKey]);\n\n if (!runtimeUrl && !resolvedPublicKey && !hasLocalAgents) {\n const message =\n \"Missing required prop: 'runtimeUrl' or 'publicApiKey' or 'publicLicenseKey'\";\n if (process.env.NODE_ENV === \"production\") {\n throw new Error(message);\n } else {\n // In dev/test we warn but allow to facilitate local agents and unit tests.\n console.warn(message);\n }\n }\n\n const chatApiEndpoint =\n runtimeUrl ?? (resolvedPublicKey ? COPILOT_CLOUD_CHAT_URL : undefined);\n\n const frontendToolsList = useStableArrayProp<ReactFrontendTool>(\n frontendTools,\n \"frontendTools must be a stable array. If you want to dynamically add or remove tools, use `useFrontendTool` instead.\",\n );\n const humanInTheLoopList = useStableArrayProp<ReactHumanInTheLoop>(\n humanInTheLoop,\n \"humanInTheLoop must be a stable array. If you want to dynamically add or remove human-in-the-loop tools, use `useHumanInTheLoop` instead.\",\n );\n\n // Note: warnings for array identity changes are handled by useStableArrayProp\n\n // Process humanInTheLoop tools to create handlers and add render components\n const processedHumanInTheLoopTools = useMemo(() => {\n const processedTools: FrontendTool[] = [];\n const processedRenderToolCalls: ReactToolCallRenderer<unknown>[] = [];\n\n humanInTheLoopList.forEach((tool) => {\n // Create a promise-based handler for each human-in-the-loop tool\n const frontendTool: FrontendTool = {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n followUp: tool.followUp,\n ...(tool.agentId && { agentId: tool.agentId }),\n handler: async () => {\n // This handler will be replaced by the hook when it runs\n // For provider-level tools, we create a basic handler that waits for user interaction\n return new Promise((resolve) => {\n // The actual implementation will be handled by the render component\n // This is a placeholder that the hook will override\n console.warn(\n `Human-in-the-loop tool '${tool.name}' called but no interactive handler is set up.`,\n );\n resolve(undefined);\n });\n },\n };\n processedTools.push(frontendTool);\n\n // Add the render component to renderToolCalls\n if (tool.render) {\n processedRenderToolCalls.push({\n name: tool.name,\n args: tool.parameters!,\n render: tool.render,\n ...(tool.agentId && { agentId: tool.agentId }),\n } as ReactToolCallRenderer<unknown>);\n }\n });\n\n return { tools: processedTools, renderToolCalls: processedRenderToolCalls };\n }, [humanInTheLoopList]);\n\n // Combine all tools for CopilotKitCore\n const allTools = useMemo(() => {\n const tools: FrontendTool[] = [];\n\n // Add frontend tools\n tools.push(...frontendToolsList);\n\n // Add processed human-in-the-loop tools\n tools.push(...processedHumanInTheLoopTools.tools);\n\n return tools;\n }, [frontendToolsList, 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\n frontendToolsList.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 }, [renderToolCallsList, frontendToolsList, processedHumanInTheLoopTools]);\n\n const copilotkit = useMemo(() => {\n const copilotkit = new CopilotKitCoreReact({\n runtimeUrl: chatApiEndpoint,\n runtimeTransport: useSingleEndpoint ? \"single\" : \"rest\",\n headers: mergedHeaders,\n credentials,\n properties,\n agents__unsafe_dev_only: mergedAgents,\n tools: allTools,\n renderToolCalls: allRenderToolCalls,\n renderActivityMessages: allActivityRenderers,\n renderCustomMessages: renderCustomMessagesList,\n });\n\n return copilotkit;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n allTools,\n allRenderToolCalls,\n allActivityRenderers,\n renderCustomMessagesList,\n useSingleEndpoint,\n ]);\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 useEffect(() => {\n copilotkit.setRuntimeUrl(chatApiEndpoint);\n copilotkit.setRuntimeTransport(useSingleEndpoint ? \"single\" : \"rest\");\n copilotkit.setHeaders(mergedHeaders);\n copilotkit.setCredentials(credentials);\n copilotkit.setProperties(properties);\n copilotkit.setAgents__unsafe_dev_only(mergedAgents);\n }, [\n chatApiEndpoint,\n mergedHeaders,\n credentials,\n properties,\n mergedAgents,\n useSingleEndpoint,\n ]);\n\n return (\n <CopilotKitContext.Provider\n value={{\n copilotkit,\n executingToolCallIds,\n }}\n >\n {children}\n {shouldRenderInspector ? <CopilotKitInspector core={copilotkit} /> : null}\n </CopilotKitContext.Provider>\n );\n};\n\n// Hook to use the CopilotKit instance - returns the full context value\nexport const useCopilotKit = (): CopilotKitContextValue => {\n const context = useContext(CopilotKitContext);\n const [, forceUpdate] = useReducer((x) => x + 1, 0);\n\n if (!context) {\n throw new Error(\"useCopilotKit must be used within CopilotKitProvider\");\n }\n useEffect(() => {\n const subscription = context.copilotkit.subscribe({\n onRuntimeConnectionStatusChanged: () => {\n forceUpdate();\n },\n });\n return () => {\n subscription.unsubscribe();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return context;\n};\n","import React, { useCallback, useMemo, useSyncExternalStore } from \"react\";\nimport { ToolCall, ToolMessage } from \"@ag-ui/core\";\nimport { ToolCallStatus } from \"@copilotkitnext/core\";\nimport { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport { useCopilotChatConfiguration } from \"@/providers/CopilotChatConfigurationProvider\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkitnext/shared\";\nimport { partialJSONParse } from \"@copilotkitnext/shared\";\nimport { ReactToolCallRenderer } from \"@/types/react-tool-call-renderer\";\n\nexport interface UseRenderToolCallProps {\n toolCall: ToolCall;\n toolMessage?: ToolMessage;\n}\n\n/**\n * Props for the memoized ToolCallRenderer component\n */\ninterface ToolCallRendererProps {\n toolCall: ToolCall;\n toolMessage?: ToolMessage;\n RenderComponent: ReactToolCallRenderer<unknown>[\"render\"];\n isExecuting: boolean;\n}\n\n/**\n * Memoized component that renders a single tool call.\n * This prevents unnecessary re-renders when parent components update\n * but the tool call data hasn't changed.\n */\nconst ToolCallRenderer = React.memo(\n function ToolCallRenderer({\n toolCall,\n toolMessage,\n RenderComponent,\n isExecuting,\n }: ToolCallRendererProps) {\n // Memoize args based on the arguments string to maintain stable reference\n const args = useMemo(\n () => partialJSONParse(toolCall.function.arguments),\n [toolCall.function.arguments],\n );\n\n const toolName = toolCall.function.name;\n\n // Render based on status to preserve discriminated union type inference\n if (toolMessage) {\n return (\n <RenderComponent\n name={toolName}\n args={args}\n status={ToolCallStatus.Complete}\n result={toolMessage.content}\n />\n );\n } else if (isExecuting) {\n return (\n <RenderComponent\n name={toolName}\n args={args}\n status={ToolCallStatus.Executing}\n result={undefined}\n />\n );\n } else {\n return (\n <RenderComponent\n name={toolName}\n args={args}\n status={ToolCallStatus.InProgress}\n result={undefined}\n />\n );\n }\n },\n // Custom comparison function to prevent re-renders when tool call data hasn't changed\n (prevProps, nextProps) => {\n // Compare tool call identity and content\n if (prevProps.toolCall.id !== nextProps.toolCall.id) return false;\n if (prevProps.toolCall.function.name !== nextProps.toolCall.function.name)\n return false;\n if (\n prevProps.toolCall.function.arguments !==\n nextProps.toolCall.function.arguments\n )\n return false;\n\n // Compare tool message (result)\n const prevResult = prevProps.toolMessage?.content;\n const nextResult = nextProps.toolMessage?.content;\n if (prevResult !== nextResult) return false;\n\n // Compare executing state\n if (prevProps.isExecuting !== nextProps.isExecuting) return false;\n\n // Compare render component reference\n if (prevProps.RenderComponent !== nextProps.RenderComponent) return false;\n\n return true;\n },\n);\n\n/**\n * Hook that returns a function to render tool calls based on the render functions\n * defined in CopilotKitProvider.\n *\n * @returns A function that takes a tool call and optional tool message and returns the rendered component\n */\nexport function useRenderToolCall() {\n const { copilotkit, executingToolCallIds } = useCopilotKit();\n const config = useCopilotChatConfiguration();\n const agentId = config?.agentId ?? DEFAULT_AGENT_ID;\n\n // Subscribe to render tool calls changes using useSyncExternalStore\n // This ensures we always have the latest value, even if subscriptions run in any order\n const renderToolCalls = useSyncExternalStore(\n (callback) => {\n return copilotkit.subscribe({\n onRenderToolCallsChanged: callback,\n }).unsubscribe;\n },\n () => copilotkit.renderToolCalls,\n () => copilotkit.renderToolCalls,\n );\n\n // Note: executingToolCallIds is now provided by CopilotKitProvider context.\n // This is critical for HITL reconnection: when connecting to a thread with\n // pending tool calls, the onToolExecutionStart event fires before child components\n // mount. By tracking at the provider level, the executing state is already\n // available when this hook first runs.\n\n const renderToolCall = useCallback(\n ({\n toolCall,\n toolMessage,\n }: UseRenderToolCallProps): React.ReactElement | null => {\n // Find the render config for this tool call by name\n // For rendering, we show all tool calls regardless of agentId\n // The agentId scoping only affects handler execution (in core)\n // Priority order:\n // 1. Exact match by name (prefer agent-specific if multiple exist)\n // 2. Wildcard (*) renderer\n const exactMatches = renderToolCalls.filter(\n (rc) => rc.name === toolCall.function.name,\n );\n\n // If multiple renderers with same name exist, prefer the one matching our agentId\n const renderConfig =\n exactMatches.find((rc) => rc.agentId === agentId) ||\n exactMatches.find((rc) => !rc.agentId) ||\n exactMatches[0] ||\n renderToolCalls.find((rc) => rc.name === \"*\");\n\n if (!renderConfig) {\n return null;\n }\n\n const RenderComponent = renderConfig.render;\n const isExecuting = executingToolCallIds.has(toolCall.id);\n\n // Use the memoized ToolCallRenderer component to prevent unnecessary re-renders\n return (\n <ToolCallRenderer\n key={toolCall.id}\n toolCall={toolCall}\n toolMessage={toolMessage}\n RenderComponent={RenderComponent}\n isExecuting={isExecuting}\n />\n );\n },\n [renderToolCalls, executingToolCallIds, agentId],\n );\n\n return renderToolCall;\n}\n","import { 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 throw new Error(\"Agent not found\");\n }\n\n const messagesIdsInRun = resolvedRunId\n ? agent.messages\n .filter(\n (msg) =>\n copilotkit.getRunIdForMessage(agentId, threadId, msg.id) ===\n resolvedRunId,\n )\n .map((msg) => msg.id)\n : [message.id];\n\n const rawMessageIndex = agent.messages.findIndex(\n (msg) => msg.id === message.id,\n );\n const messageIndex = rawMessageIndex >= 0 ? rawMessageIndex : 0;\n const messageIndexInRun = resolvedRunId\n ? Math.max(messagesIdsInRun.indexOf(message.id), 0)\n : 0;\n const numberOfMessagesInRun = resolvedRunId ? messagesIdsInRun.length : 1;\n const stateSnapshot = resolvedRunId\n ? copilotkit.getStateByRun(agentId, threadId, resolvedRunId)\n : undefined;\n\n let result = null;\n for (const renderer of customMessageRenderers) {\n if (!renderer.render) {\n continue;\n }\n const Component = renderer.render;\n result = (\n <Component\n key={`${runId}-${message.id}-${position}`}\n message={message}\n position={position}\n runId={runId}\n messageIndex={messageIndex}\n messageIndexInRun={messageIndexInRun}\n numberOfMessagesInRun={numberOfMessagesInRun}\n agentId={agentId}\n stateSnapshot={stateSnapshot}\n />\n );\n if (result) {\n break;\n }\n }\n return result;\n };\n}\n","import { ActivityMessage } from \"@ag-ui/core\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkitnext/shared\";\nimport { useCopilotKit, useCopilotChatConfiguration } from \"@/providers\";\nimport { useCallback, useMemo } from \"react\";\nimport { ReactActivityMessageRenderer } from \"@/types\";\n\nexport function useRenderActivityMessage() {\n const { copilotkit } = useCopilotKit();\n const config = useCopilotChatConfiguration();\n const agentId = config?.agentId ?? DEFAULT_AGENT_ID;\n\n const renderers = copilotkit.renderActivityMessages;\n\n // Find the renderer for a given activity type\n const findRenderer = useCallback(\n (activityType: string): ReactActivityMessageRenderer<unknown> | null => {\n if (!renderers.length) {\n return null;\n }\n\n const matches = renderers.filter(\n (renderer) => renderer.activityType === activityType,\n );\n\n return (\n matches.find((candidate) => candidate.agentId === agentId) ??\n matches.find((candidate) => candidate.agentId === undefined) ??\n renderers.find((candidate) => candidate.activityType === \"*\") ??\n null\n );\n },\n [agentId, renderers],\n );\n\n const renderActivityMessage = useCallback(\n (message: ActivityMessage): React.ReactElement | null => {\n const renderer = findRenderer(message.activityType);\n\n if (!renderer) {\n return null;\n }\n\n const parseResult = renderer.content.safeParse(message.content);\n\n if (!parseResult.success) {\n console.warn(\n `Failed to parse content for activity message '${message.activityType}':`,\n parseResult.error,\n );\n return null;\n }\n\n const Component = renderer.render;\n const agent = copilotkit.getAgent(agentId);\n\n return (\n <Component\n key={message.id}\n activityType={message.activityType}\n content={parseResult.data}\n message={message}\n agent={agent}\n />\n );\n },\n [agentId, copilotkit, findRenderer],\n );\n\n return useMemo(\n () => ({ renderActivityMessage, findRenderer }),\n [renderActivityMessage, findRenderer],\n );\n}\n","import { useEffect } from \"react\";\nimport { useCopilotKit } from \"../providers/CopilotKitProvider\";\nimport type { ReactFrontendTool } from \"../types/frontend-tool\";\nimport type { ReactToolCallRenderer } from \"../types/react-tool-call-renderer\";\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 if (tool.render) {\n // Get current render tool calls and merge with new entry\n const keyOf = (rc: ReactToolCallRenderer) =>\n `${rc.agentId ?? \"\"}:${rc.name}`;\n const currentRenderToolCalls =\n copilotkit.renderToolCalls as ReactToolCallRenderer[];\n\n // Build map from existing entries\n const mergedMap = new Map<string, ReactToolCallRenderer>();\n for (const rc of currentRenderToolCalls) {\n mergedMap.set(keyOf(rc), rc);\n }\n\n // Add/overwrite with new entry\n const newEntry: ReactToolCallRenderer = {\n name,\n args: tool.parameters,\n agentId: tool.agentId,\n render: tool.render,\n } as ReactToolCallRenderer;\n mergedMap.set(keyOf(newEntry), newEntry);\n\n // Set the merged list back\n copilotkit.setRenderToolCalls(Array.from(mergedMap.values()));\n }\n\n return () => {\n copilotkit.removeTool(name, tool.agentId);\n // we are intentionally not removing the render here so that the tools can still render in the chat history\n };\n // Depend on stable keys by default and allow callers to opt into\n // additional dependencies for dynamic tool configuration.\n // tool.available is included so toggling availability re-registers the tool.\n }, [tool.name, tool.available, copilotkit, extraDeps.length, ...extraDeps]);\n}\n","import { z } from \"zod\";\nimport type { ComponentType } from \"react\";\nimport { useFrontendTool } from \"./use-frontend-tool\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferRenderProps<T> = T extends z.ZodTypeAny ? z.infer<T> : 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 Zod parameters,\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 * via `z.infer`. When omitted, the render component may accept any props.\n *\n * @typeParam TSchema - Zod 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 z.ZodTypeAny | undefined = undefined,\n>(\n config: {\n name: string;\n description?: string;\n parameters?: TSchema;\n render: ComponentType<NoInfer<InferRenderProps<TSchema>>>;\n agentId?: string;\n },\n deps?: ReadonlyArray<unknown>,\n): void {\n const prefix = `Use this tool to display the \"${config.name}\" component in the chat. This tool renders a visual UI component for the user.`;\n const fullDescription = config.description\n ? `${prefix}\\n\\n${config.description}`\n : prefix;\n\n useFrontendTool(\n {\n name: config.name,\n description: fullDescription,\n parameters: config.parameters,\n render: ({ args }: { args: unknown }) => {\n const Component = config.render;\n return <Component {...(args as InferRenderProps<TSchema>)} />;\n },\n agentId: config.agentId,\n },\n deps,\n );\n}\n","import React from \"react\";\nimport { z } from \"zod\";\nimport { ReactToolCallRenderer } from \"./react-tool-call-renderer\";\nimport { ToolCallStatus } from \"@copilotkitnext/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 Zod schema.\n * - Ensures the render function param type exactly matches ReactToolCallRenderer<T>[\"render\"]'s param.\n * - For wildcard tools (name: \"*\"), args is optional and defaults to z.any()\n */\ntype RenderProps<T> =\n | {\n name: string;\n args: Partial<T>;\n status: ToolCallStatus.InProgress;\n result: undefined;\n }\n | {\n name: string;\n args: T;\n status: ToolCallStatus.Executing;\n result: undefined;\n }\n | {\n name: string;\n args: T;\n status: ToolCallStatus.Complete;\n result: string;\n };\n\n// Overload for wildcard tools without args\nexport function defineToolCallRenderer(def: {\n name: \"*\";\n render: (props: RenderProps<any>) => React.ReactElement;\n agentId?: string;\n}): ReactToolCallRenderer<any>;\n\n// Overload for regular tools with args\nexport function defineToolCallRenderer<S extends z.ZodTypeAny>(def: {\n name: string;\n args: S;\n render: (props: RenderProps<z.infer<S>>) => React.ReactElement;\n agentId?: string;\n}): ReactToolCallRenderer<z.infer<S>>;\n\n// Implementation\nexport function defineToolCallRenderer<S extends z.ZodTypeAny>(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 as any,\n render: def.render as React.ComponentType<any>,\n ...(def.agentId ? { agentId: def.agentId } : {}),\n };\n}\n","import { useEffect } from \"react\";\nimport type { z } from \"zod\";\nimport { useCopilotKit } from \"../providers/CopilotKitProvider\";\nimport { defineToolCallRenderer } from \"../types/defineToolCallRenderer\";\nimport type { ReactToolCallRenderer } from \"../types/react-tool-call-renderer\";\n\nconst EMPTY_DEPS: ReadonlyArray<unknown> = [];\n\nexport interface RenderToolInProgressProps<S extends z.ZodTypeAny> {\n name: string;\n parameters: Partial<z.infer<S>>;\n status: \"inProgress\";\n result: undefined;\n}\n\nexport interface RenderToolExecutingProps<S extends z.ZodTypeAny> {\n name: string;\n parameters: z.infer<S>;\n status: \"executing\";\n result: undefined;\n}\n\nexport interface RenderToolCompleteProps<S extends z.ZodTypeAny> {\n name: string;\n parameters: z.infer<S>;\n status: \"complete\";\n result: string;\n}\n\nexport type RenderToolProps<S extends z.ZodTypeAny> =\n | RenderToolInProgressProps<S>\n | RenderToolExecutingProps<S>\n | RenderToolCompleteProps<S>;\n\ntype RenderToolConfig<S extends z.ZodTypeAny> = {\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` Zod schema defines the typed shape of `props.parameters`\n * in `render` for `executing` and `complete` states.\n *\n * @typeParam S - Zod 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 z.ZodTypeAny>(\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 - Zod 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 z.ZodTypeAny>(\n config: RenderToolConfig<S>,\n deps?: ReadonlyArray<unknown>,\n): void {\n const { copilotkit } = useCopilotKit();\n const extraDeps = deps ?? EMPTY_DEPS;\n\n useEffect(() => {\n // Build the ReactToolCallRenderer via defineToolCallRenderer\n const renderer =\n config.name === \"*\" && !config.parameters\n ? defineToolCallRenderer({\n name: \"*\",\n render: (props) =>\n config.render({ ...props, parameters: props.args }),\n ...(config.agentId ? { agentId: config.agentId } : {}),\n })\n : defineToolCallRenderer({\n name: config.name,\n args: config.parameters!,\n render: (props) =>\n config.render({ ...props, parameters: props.args }),\n ...(config.agentId ? { agentId: config.agentId } : {}),\n });\n\n // Dedupe by \"agentId:name\" key, same pattern as useFrontendTool\n const keyOf = (rc: ReactToolCallRenderer) =>\n `${rc.agentId ?? \"\"}:${rc.name}`;\n const currentRenderToolCalls =\n copilotkit.renderToolCalls as ReactToolCallRenderer[];\n\n const mergedMap = new Map<string, ReactToolCallRenderer>();\n for (const rc of currentRenderToolCalls) {\n mergedMap.set(keyOf(rc), rc);\n }\n\n mergedMap.set(keyOf(renderer), renderer);\n\n copilotkit.setRenderToolCalls(Array.from(mergedMap.values()));\n\n // No cleanup removal — keeps renderer for chat history, same as useFrontendTool\n }, [config.name, copilotkit, extraDeps.length, ...extraDeps]);\n}\n","import React, { useState } from \"react\";\nimport { useRenderTool } from \"./use-render-tool\";\n\ntype DefaultRenderProps = {\n /** The name of the tool being called. */\n name: string;\n /** The parsed parameters passed to the tool call. */\n parameters: unknown;\n /** Current execution status of the tool call. */\n status: \"inProgress\" | \"executing\" | \"complete\";\n /** The tool call result string, available only when `status` is `\"complete\"`. */\n result: string | undefined;\n};\n\n/**\n * Registers a wildcard (`\"*\"`) tool-call renderer via `useRenderTool`.\n *\n * - Call with no config to use CopilotKit's built-in default tool-call card.\n * - Pass `config.render` to replace the default UI with your own fallback renderer.\n *\n * This is useful when you want a generic renderer for tools that do not have a\n * dedicated `useRenderTool({ name: \"...\" })` registration.\n *\n * @param config - Optional custom wildcard render function.\n * @param deps - Optional dependencies to refresh registration.\n *\n * @example\n * ```tsx\n * useDefaultRenderTool();\n * ```\n *\n * @example\n * ```tsx\n * useDefaultRenderTool({\n * render: ({ name, status }) => <div>{name}: {status}</div>,\n * });\n * ```\n *\n * @example\n * ```tsx\n * useDefaultRenderTool(\n * {\n * render: ({ name, result }) => (\n * <ToolEventRow title={name} payload={result} compact={compactMode} />\n * ),\n * },\n * [compactMode],\n * );\n * ```\n */\nexport function useDefaultRenderTool(\n config?: {\n render?: (props: DefaultRenderProps) => React.ReactElement;\n },\n deps?: ReadonlyArray<unknown>,\n): void {\n useRenderTool(\n {\n name: \"*\",\n render: config?.render ?? DefaultToolCallRenderer,\n },\n deps,\n );\n}\n\nfunction DefaultToolCallRenderer({\n name,\n parameters,\n status,\n result,\n}: DefaultRenderProps): React.ReactElement {\n const [isExpanded, setIsExpanded] = useState(false);\n\n const statusString = String(status) as\n | \"inProgress\"\n | \"executing\"\n | \"complete\";\n const isActive =\n statusString === \"inProgress\" || statusString === \"executing\";\n const isComplete = statusString === \"complete\";\n\n const statusLabel = isActive ? \"Running\" : isComplete ? \"Done\" : status;\n const dotColor = isActive ? \"#f59e0b\" : isComplete ? \"#10b981\" : \"#a1a1aa\";\n const badgeBg = isActive ? \"#fef3c7\" : isComplete ? \"#d1fae5\" : \"#f4f4f5\";\n const badgeColor = isActive ? \"#92400e\" : isComplete ? \"#065f46\" : \"#3f3f46\";\n\n return (\n <div\n style={{\n marginTop: \"8px\",\n paddingBottom: \"8px\",\n }}\n >\n <div\n style={{\n borderRadius: \"12px\",\n border: \"1px solid #e4e4e7\",\n backgroundColor: \"#fafafa\",\n padding: \"14px 16px\",\n }}\n >\n {/* Header row — always visible */}\n <div\n onClick={() => setIsExpanded(!isExpanded)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: \"10px\",\n cursor: \"pointer\",\n userSelect: \"none\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n minWidth: 0,\n }}\n >\n <svg\n style={{\n height: \"14px\",\n width: \"14px\",\n color: \"#71717a\",\n transition: \"transform 0.15s\",\n transform: isExpanded ? \"rotate(90deg)\" : \"rotate(0deg)\",\n flexShrink: 0,\n }}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n strokeWidth={2}\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M8.25 4.5l7.5 7.5-7.5 7.5\"\n />\n </svg>\n <span\n style={{\n display: \"inline-block\",\n height: \"8px\",\n width: \"8px\",\n borderRadius: \"50%\",\n backgroundColor: dotColor,\n flexShrink: 0,\n }}\n />\n <span\n style={{\n fontSize: \"13px\",\n fontWeight: 600,\n color: \"#18181b\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {name}\n </span>\n </div>\n\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n borderRadius: \"9999px\",\n padding: \"2px 8px\",\n fontSize: \"11px\",\n fontWeight: 500,\n backgroundColor: badgeBg,\n color: badgeColor,\n flexShrink: 0,\n }}\n >\n {statusLabel}\n </span>\n </div>\n\n {/* Expandable details */}\n {isExpanded && (\n <div style={{ marginTop: \"12px\", display: \"grid\", gap: \"12px\" }}>\n <div>\n <div\n style={{\n fontSize: \"10px\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.05em\",\n color: \"#71717a\",\n }}\n >\n Arguments\n </div>\n <pre\n style={{\n marginTop: \"6px\",\n maxHeight: \"200px\",\n overflow: \"auto\",\n borderRadius: \"6px\",\n backgroundColor: \"#f4f4f5\",\n padding: \"10px\",\n fontSize: \"11px\",\n lineHeight: 1.6,\n color: \"#27272a\",\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n }}\n >\n {JSON.stringify(parameters ?? {}, null, 2)}\n </pre>\n </div>\n\n {result !== undefined && (\n <div>\n <div\n style={{\n fontSize: \"10px\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.05em\",\n color: \"#71717a\",\n }}\n >\n Result\n </div>\n <pre\n style={{\n marginTop: \"6px\",\n maxHeight: \"200px\",\n overflow: \"auto\",\n borderRadius: \"6px\",\n backgroundColor: \"#f4f4f5\",\n padding: \"10px\",\n fontSize: \"11px\",\n lineHeight: 1.6,\n color: \"#27272a\",\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n }}\n >\n {typeof result === \"string\"\n ? result\n : JSON.stringify(result, null, 2)}\n </pre>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n}\n","import { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport type { ReactFrontendTool } from \"@/types/frontend-tool\";\nimport type { ReactHumanInTheLoop } from \"@/types/human-in-the-loop\";\nimport type { ReactToolCallRenderer } from \"@/types/react-tool-call-renderer\";\nimport { useCallback, useEffect, useRef } from \"react\";\nimport React from \"react\";\nimport { useFrontendTool } from \"./use-frontend-tool\";\n\nexport function useHumanInTheLoop<\n T extends Record<string, unknown> = Record<string, unknown>,\n>(tool: ReactHumanInTheLoop<T>, deps?: ReadonlyArray<unknown>) {\n const { copilotkit } = useCopilotKit();\n const resolvePromiseRef = useRef<((result: unknown) => void) | null>(null);\n\n const respond = useCallback(async (result: unknown) => {\n if (resolvePromiseRef.current) {\n resolvePromiseRef.current(result);\n resolvePromiseRef.current = null;\n }\n }, []);\n\n const handler = useCallback(async () => {\n return new Promise((resolve) => {\n resolvePromiseRef.current = resolve;\n });\n }, []);\n\n const RenderComponent: ReactToolCallRenderer<T>[\"render\"] = useCallback(\n (props) => {\n const ToolComponent = tool.render;\n\n // Enhance props based on current status\n if (props.status === \"inProgress\") {\n const enhancedProps = {\n ...props,\n name: tool.name,\n description: tool.description || \"\",\n respond: undefined,\n };\n return React.createElement(ToolComponent, enhancedProps);\n } else if (props.status === \"executing\") {\n const enhancedProps = {\n ...props,\n name: tool.name,\n description: tool.description || \"\",\n respond,\n };\n return React.createElement(ToolComponent, enhancedProps);\n } else if (props.status === \"complete\") {\n const enhancedProps = {\n ...props,\n name: tool.name,\n description: tool.description || \"\",\n respond: undefined,\n };\n return React.createElement(ToolComponent, enhancedProps);\n }\n\n // Fallback - just render with original props\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return React.createElement(ToolComponent, props as any);\n },\n [tool.render, tool.name, tool.description, respond],\n );\n\n const frontendTool: ReactFrontendTool<T> = {\n ...tool,\n handler,\n render: RenderComponent,\n };\n\n useFrontendTool(frontendTool, deps);\n\n // Human-in-the-loop tools should remove their renderer on unmount\n // since they can't respond to user interactions anymore\n useEffect(() => {\n return () => {\n const keyOf = (rc: ReactToolCallRenderer<any>) =>\n `${rc.agentId ?? \"\"}:${rc.name}`;\n const currentRenderToolCalls =\n copilotkit.renderToolCalls as ReactToolCallRenderer<any>[];\n const filtered = currentRenderToolCalls.filter(\n (rc) =>\n keyOf(rc) !==\n keyOf({ name: tool.name, agentId: tool.agentId } as any),\n );\n copilotkit.setRenderToolCalls(filtered);\n };\n }, [copilotkit, tool.name, tool.agentId]);\n}\n","import { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport { useMemo, useEffect, useReducer } from \"react\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkitnext/shared\";\nimport { AbstractAgent } from \"@ag-ui/client\";\nimport {\n ProxiedCopilotRuntimeAgent,\n CopilotKitCoreRuntimeConnectionStatus,\n} from \"@copilotkitnext/core\";\n\nexport enum UseAgentUpdate {\n OnMessagesChanged = \"OnMessagesChanged\",\n OnStateChanged = \"OnStateChanged\",\n OnRunStatusChanged = \"OnRunStatusChanged\",\n}\n\nconst ALL_UPDATES: UseAgentUpdate[] = [\n UseAgentUpdate.OnMessagesChanged,\n UseAgentUpdate.OnStateChanged,\n UseAgentUpdate.OnRunStatusChanged,\n];\n\nexport interface UseAgentProps {\n agentId?: string;\n updates?: UseAgentUpdate[];\n}\n\nexport function useAgent({ agentId, updates }: UseAgentProps = {}) {\n agentId ??= DEFAULT_AGENT_ID;\n\n const { copilotkit } = useCopilotKit();\n const [, forceUpdate] = useReducer((x) => x + 1, 0);\n\n const updateFlags = useMemo(\n () => updates ?? ALL_UPDATES,\n [JSON.stringify(updates)],\n );\n\n const agent: AbstractAgent = useMemo(() => {\n const existing = copilotkit.getAgent(agentId);\n if (existing) {\n return existing;\n }\n\n const isRuntimeConfigured = copilotkit.runtimeUrl !== undefined;\n const status = copilotkit.runtimeConnectionStatus;\n\n // While runtime is not yet synced, return a provisional runtime agent\n if (\n isRuntimeConfigured &&\n (status === CopilotKitCoreRuntimeConnectionStatus.Disconnected ||\n status === CopilotKitCoreRuntimeConnectionStatus.Connecting)\n ) {\n const provisional = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: copilotkit.runtimeUrl,\n agentId,\n transport: copilotkit.runtimeTransport,\n });\n // Apply current headers so runs/connects inherit them\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (provisional as any).headers = { ...copilotkit.headers };\n return provisional;\n }\n\n // If no runtime is configured (dev/local), return a no-op agent to satisfy the\n // non-undefined contract without forcing network behavior.\n // After runtime has synced (Connected or Error) or no runtime configured and the agent doesn't exist, throw a descriptive error\n const knownAgents = Object.keys(copilotkit.agents ?? {});\n const runtimePart = isRuntimeConfigured\n ? `runtimeUrl=${copilotkit.runtimeUrl}`\n : \"no runtimeUrl\";\n throw new Error(\n `useAgent: Agent '${agentId}' not found after runtime sync (${runtimePart}). ` +\n (knownAgents.length\n ? `Known agents: [${knownAgents.join(\", \")}]`\n : \"No agents registered.\") +\n \" Verify your runtime /info and/or agents__unsafe_dev_only.\",\n );\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n agentId,\n copilotkit.agents,\n copilotkit.runtimeConnectionStatus,\n copilotkit.runtimeUrl,\n copilotkit.runtimeTransport,\n JSON.stringify(copilotkit.headers),\n copilotkit,\n ]);\n\n useEffect(() => {\n if (updateFlags.length === 0) {\n return;\n }\n\n const handlers: Parameters<AbstractAgent[\"subscribe\"]>[0] = {};\n\n if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) {\n // Content stripping for immutableContent renderers is handled by CopilotKitCoreReact\n handlers.onMessagesChanged = () => {\n forceUpdate();\n };\n }\n\n if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) {\n handlers.onStateChanged = forceUpdate;\n }\n\n if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {\n handlers.onRunInitialized = forceUpdate;\n handlers.onRunFinalized = forceUpdate;\n handlers.onRunFailed = forceUpdate;\n }\n\n const subscription = agent.subscribe(handlers);\n return () => subscription.unsubscribe();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agent, forceUpdate, JSON.stringify(updateFlags)]);\n\n return {\n agent,\n };\n}\n","import { useCopilotKit } from \"../providers/CopilotKitProvider\";\nimport { useEffect, 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 useEffect(() => {\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 \"@copilotkitnext/core\";\nimport { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport { useCopilotChatConfiguration } from \"@/providers/CopilotChatConfigurationProvider\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkitnext/shared\";\n\nexport interface UseSuggestionsOptions {\n agentId?: string;\n}\n\nexport interface UseSuggestionsResult {\n suggestions: Suggestion[];\n reloadSuggestions: () => void;\n clearSuggestions: () => void;\n isLoading: boolean;\n}\n\nexport function useSuggestions({\n agentId,\n}: UseSuggestionsOptions = {}): UseSuggestionsResult {\n const { copilotkit } = useCopilotKit();\n const config = useCopilotChatConfiguration();\n const resolvedAgentId = useMemo(\n () => agentId ?? config?.agentId ?? DEFAULT_AGENT_ID,\n [agentId, config?.agentId],\n );\n\n const [suggestions, setSuggestions] = useState<Suggestion[]>(() => {\n const result = copilotkit.getSuggestions(resolvedAgentId);\n return result.suggestions;\n });\n const [isLoading, setIsLoading] = useState(() => {\n const result = copilotkit.getSuggestions(resolvedAgentId);\n return result.isLoading;\n });\n\n useEffect(() => {\n const result = copilotkit.getSuggestions(resolvedAgentId);\n setSuggestions(result.suggestions);\n setIsLoading(result.isLoading);\n }, [copilotkit, resolvedAgentId]);\n\n useEffect(() => {\n const subscription = copilotkit.subscribe({\n onSuggestionsChanged: ({ agentId: changedAgentId, suggestions }) => {\n if (changedAgentId !== resolvedAgentId) {\n return;\n }\n setSuggestions(suggestions);\n },\n onSuggestionsStartedLoading: ({ agentId: changedAgentId }) => {\n if (changedAgentId !== resolvedAgentId) {\n return;\n }\n setIsLoading(true);\n },\n onSuggestionsFinishedLoading: ({ agentId: changedAgentId }) => {\n if (changedAgentId !== resolvedAgentId) {\n return;\n }\n setIsLoading(false);\n },\n onSuggestionsConfigChanged: () => {\n const result = copilotkit.getSuggestions(resolvedAgentId);\n setSuggestions(result.suggestions);\n setIsLoading(result.isLoading);\n },\n });\n\n return () => {\n subscription.unsubscribe();\n };\n }, [copilotkit, resolvedAgentId]);\n\n const reloadSuggestions = useCallback(() => {\n copilotkit.reloadSuggestions(resolvedAgentId);\n // Loading state is handled by onSuggestionsStartedLoading event\n }, [copilotkit, resolvedAgentId]);\n\n const clearSuggestions = useCallback(() => {\n copilotkit.clearSuggestions(resolvedAgentId);\n // State updates are handled by onSuggestionsChanged event\n }, [copilotkit, resolvedAgentId]);\n\n return {\n suggestions,\n reloadSuggestions,\n clearSuggestions,\n isLoading,\n };\n}\n","import { useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport { useCopilotChatConfiguration } from \"@/providers/CopilotChatConfigurationProvider\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkitnext/shared\";\nimport {\n DynamicSuggestionsConfig,\n StaticSuggestionsConfig,\n SuggestionsConfig,\n Suggestion,\n} from \"@copilotkitnext/core\";\n\ntype StaticSuggestionInput = Omit<Suggestion, \"isLoading\"> &\n Partial<Pick<Suggestion, \"isLoading\">>;\n\ntype StaticSuggestionsConfigInput = Omit<\n StaticSuggestionsConfig,\n \"suggestions\"\n> & {\n suggestions: StaticSuggestionInput[];\n};\n\ntype SuggestionsConfigInput =\n | DynamicSuggestionsConfig\n | StaticSuggestionsConfigInput;\n\nexport function useConfigureSuggestions(\n config: SuggestionsConfigInput | null | undefined,\n deps?: ReadonlyArray<unknown>,\n): void {\n const { copilotkit } = useCopilotKit();\n const chatConfig = useCopilotChatConfiguration();\n const extraDeps = deps ?? [];\n\n const resolvedConsumerAgentId = useMemo(\n () => chatConfig?.agentId ?? DEFAULT_AGENT_ID,\n [chatConfig?.agentId],\n );\n\n const rawConsumerAgentId = useMemo(\n () =>\n config ? (config as SuggestionsConfigInput).consumerAgentId : undefined,\n [config],\n );\n\n const normalizationCacheRef = useRef<{\n serialized: string | null;\n config: SuggestionsConfig | null;\n }>({\n serialized: null,\n config: null,\n });\n\n const { normalizedConfig, serializedConfig } = useMemo(() => {\n if (!config) {\n normalizationCacheRef.current = { serialized: null, config: null };\n return { normalizedConfig: null, serializedConfig: null };\n }\n\n if (config.available === \"disabled\") {\n normalizationCacheRef.current = { serialized: null, config: null };\n return { normalizedConfig: null, serializedConfig: null };\n }\n\n let built: SuggestionsConfig;\n if (isDynamicConfig(config)) {\n built = {\n ...config,\n } satisfies DynamicSuggestionsConfig;\n } else {\n const normalizedSuggestions = normalizeStaticSuggestions(\n config.suggestions,\n );\n const baseConfig: StaticSuggestionsConfig = {\n ...config,\n suggestions: normalizedSuggestions,\n };\n built = baseConfig;\n }\n\n const serialized = JSON.stringify(built);\n const cache = normalizationCacheRef.current;\n if (cache.serialized === serialized && cache.config) {\n return { normalizedConfig: cache.config, serializedConfig: serialized };\n }\n\n normalizationCacheRef.current = { serialized, config: built };\n return { normalizedConfig: built, serializedConfig: serialized };\n }, [config, resolvedConsumerAgentId, ...extraDeps]);\n const latestConfigRef = useRef<SuggestionsConfig | null>(null);\n latestConfigRef.current = normalizedConfig;\n const previousSerializedConfigRef = useRef<string | null>(null);\n\n const targetAgentId = useMemo(() => {\n if (!normalizedConfig) {\n return resolvedConsumerAgentId;\n }\n const consumer = (\n normalizedConfig as StaticSuggestionsConfig | DynamicSuggestionsConfig\n ).consumerAgentId;\n if (!consumer || consumer === \"*\") {\n return resolvedConsumerAgentId;\n }\n return consumer;\n }, [normalizedConfig, resolvedConsumerAgentId]);\n\n const isGlobalConfig =\n rawConsumerAgentId === undefined || rawConsumerAgentId === \"*\";\n\n const requestReload = useCallback(() => {\n if (!normalizedConfig) {\n return;\n }\n\n if (isGlobalConfig) {\n const agents = Object.values(copilotkit.agents ?? {});\n for (const entry of agents) {\n const agentId = entry.agentId;\n if (!agentId) {\n continue;\n }\n if (!entry.isRunning) {\n copilotkit.reloadSuggestions(agentId);\n }\n }\n return;\n }\n\n if (!targetAgentId) {\n return;\n }\n\n copilotkit.reloadSuggestions(targetAgentId);\n }, [copilotkit, isGlobalConfig, normalizedConfig, targetAgentId]);\n\n useEffect(() => {\n if (!serializedConfig || !latestConfigRef.current) {\n return;\n }\n\n const id = copilotkit.addSuggestionsConfig(latestConfigRef.current);\n\n requestReload();\n\n return () => {\n copilotkit.removeSuggestionsConfig(id);\n };\n }, [copilotkit, serializedConfig, requestReload]);\n\n useEffect(() => {\n if (!normalizedConfig) {\n previousSerializedConfigRef.current = null;\n return;\n }\n if (\n serializedConfig &&\n previousSerializedConfigRef.current === serializedConfig\n ) {\n return;\n }\n if (serializedConfig) {\n previousSerializedConfigRef.current = serializedConfig;\n }\n requestReload();\n }, [normalizedConfig, requestReload, serializedConfig]);\n\n useEffect(() => {\n if (!normalizedConfig || extraDeps.length === 0) {\n return;\n }\n requestReload();\n }, [extraDeps.length, normalizedConfig, requestReload, ...extraDeps]);\n}\n\nfunction isDynamicConfig(\n config: SuggestionsConfigInput,\n): config is DynamicSuggestionsConfig {\n return \"instructions\" in config;\n}\n\nfunction normalizeStaticSuggestions(\n suggestions: StaticSuggestionInput[],\n): Suggestion[] {\n return suggestions.map((suggestion) => ({\n ...suggestion,\n isLoading: suggestion.isLoading ?? false,\n }));\n}\n","import React, { useState, useEffect, useCallback, useMemo } from \"react\";\nimport { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport { useAgent } from \"./use-agent\";\nimport type {\n InterruptEvent,\n InterruptRenderProps,\n InterruptHandlerProps,\n} from \"../types/interrupt\";\n\nexport type { InterruptEvent, InterruptRenderProps, InterruptHandlerProps };\n\nconst INTERRUPT_EVENT_NAME = \"on_interrupt\";\n\ntype InterruptHandlerFn<TValue, TResult> = (\n props: InterruptHandlerProps<TValue>,\n) => TResult | PromiseLike<TResult>;\n\ntype InterruptResultFromHandler<THandler> = THandler extends (\n ...args: never[]\n) => infer TResult\n ? TResult extends PromiseLike<infer TResolved>\n ? TResolved | null\n : TResult | null\n : null;\n\ntype InterruptResult<TValue, TResult> = InterruptResultFromHandler<\n InterruptHandlerFn<TValue, TResult>\n>;\n\ntype InterruptRenderInChat = boolean | undefined;\n\ntype UseInterruptReturn<TRenderInChat extends InterruptRenderInChat> =\n TRenderInChat extends false\n ? React.ReactElement | null\n : TRenderInChat extends true | undefined\n ? void\n : React.ReactElement | null | void;\n\nexport function isPromiseLike<TValue>(\n value: TValue | PromiseLike<TValue>,\n): value is PromiseLike<TValue> {\n return (\n (typeof value === \"object\" || typeof value === \"function\") &&\n value !== null &&\n typeof Reflect.get(value, \"then\") === \"function\"\n );\n}\n\n/**\n * Configuration options for `useInterrupt`.\n */\ninterface UseInterruptConfigBase<TValue = unknown, TResult = never> {\n /**\n * Render function for the interrupt UI.\n *\n * This is called once an interrupt is finalized and accepted by `enabled` (if provided).\n * Use `resolve` from render props to resume the agent run with user input.\n */\n render: (\n props: InterruptRenderProps<TValue, InterruptResult<TValue, TResult>>,\n ) => React.ReactElement;\n /**\n * Optional pre-render handler invoked when an interrupt is received.\n *\n * Return either a sync value or an async value to pass into `render` as `result`.\n * Rejecting/throwing falls back to `result = null`.\n */\n handler?: InterruptHandlerFn<TValue, TResult>;\n /**\n * Optional predicate to filter which interrupts should be handled by this hook.\n * Return `false` to ignore an interrupt.\n */\n enabled?: (event: InterruptEvent<TValue>) => boolean;\n /** Optional agent id. Defaults to the current configured chat agent. */\n agentId?: string;\n}\n\nexport interface UseInterruptInChatConfig<\n TValue = unknown,\n TResult = never,\n> extends UseInterruptConfigBase<TValue, TResult> {\n /** When true (default), the interrupt UI renders inside `<CopilotChat>` automatically. Set to false to render it yourself. */\n renderInChat?: true;\n}\n\nexport interface UseInterruptExternalConfig<\n TValue = unknown,\n TResult = never,\n> extends UseInterruptConfigBase<TValue, TResult> {\n /** When true (default), the interrupt UI renders inside `<CopilotChat>` automatically. Set to false to render it yourself. */\n renderInChat: false;\n}\n\nexport interface UseInterruptDynamicConfig<\n TValue = unknown,\n TResult = never,\n> extends UseInterruptConfigBase<TValue, TResult> {\n /** Dynamic boolean mode. When non-literal, return type is a union. */\n renderInChat: boolean;\n}\n\nexport type UseInterruptConfig<\n TValue = unknown,\n TResult = never,\n TRenderInChat extends InterruptRenderInChat = undefined,\n> = UseInterruptConfigBase<TValue, TResult> & {\n /** When true (default), the interrupt UI renders inside `<CopilotChat>` automatically. Set to false to render it yourself. */\n renderInChat?: TRenderInChat;\n};\n\n/**\n * Handles agent interrupts (`on_interrupt`) with optional filtering, preprocessing, and resume behavior.\n *\n * The hook listens to custom events on the active agent, stores interrupt payloads per run,\n * and surfaces a render callback once the run finalizes. Call `resolve` from your UI to resume\n * execution with user-provided data.\n *\n * - `renderInChat: true` (default): the element is published into `<CopilotChat>` and this hook returns `void`.\n * - `renderInChat: false`: the hook returns the interrupt element so you can place it anywhere in your component tree.\n *\n * `event.value` is typed as `any` since the interrupt payload shape depends on your agent.\n * Type-narrow it in your callbacks (e.g. `handler`, `enabled`, `render`) as needed.\n *\n * @typeParam TResult - Inferred from `handler` return type. Exposed as `result` in `render`.\n * @param config - Interrupt configuration (renderer, optional handler/filter, and render mode).\n * @returns When `renderInChat` is `false`, returns the interrupt element (or `null` when idle).\n * Otherwise returns `void` and publishes the element into chat. In `render`, `result` is always\n * either the handler's resolved return value or `null` (including when no handler is provided,\n * when filtering skips the interrupt, or when handler execution fails).\n *\n * @example\n * ```tsx\n * import { useInterrupt } from \"@copilotkitnext/react\";\n *\n * function InterruptUI() {\n * useInterrupt({\n * render: ({ event, resolve }) => (\n * <div>\n * <p>{event.value.question}</p>\n * <button onClick={() => resolve({ approved: true })}>Approve</button>\n * <button onClick={() => resolve({ approved: false })}>Reject</button>\n * </div>\n * ),\n * });\n *\n * return null;\n * }\n * ```\n *\n * @example\n * ```tsx\n * import { useInterrupt } from \"@copilotkitnext/react\";\n *\n * function CustomPanel() {\n * const interruptElement = useInterrupt({\n * renderInChat: false,\n * enabled: (event) => event.value.startsWith(\"approval:\"),\n * handler: async ({ event }) => ({ label: event.value.toUpperCase() }),\n * render: ({ event, result, resolve }) => (\n * <aside>\n * <strong>{result?.label ?? \"\"}</strong>\n * <button onClick={() => resolve({ value: event.value })}>Continue</button>\n * </aside>\n * ),\n * });\n *\n * return <>{interruptElement}</>;\n * }\n * ```\n */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport function useInterrupt<\n TResult = never,\n TRenderInChat extends InterruptRenderInChat = undefined,\n>(\n config: UseInterruptConfig<any, TResult, TRenderInChat>,\n): UseInterruptReturn<TRenderInChat> {\n /* eslint-enable @typescript-eslint/no-explicit-any */\n const { copilotkit } = useCopilotKit();\n const { agent } = useAgent({ agentId: config.agentId });\n const [pendingEvent, setPendingEvent] = useState<InterruptEvent | null>(null);\n const [handlerResult, setHandlerResult] =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n useState<InterruptResult<any, TResult>>(null);\n\n useEffect(() => {\n let localInterrupt: InterruptEvent | null = null;\n\n const subscription = agent.subscribe({\n onCustomEvent: ({ event }) => {\n if (event.name === INTERRUPT_EVENT_NAME) {\n localInterrupt = { name: event.name, value: event.value };\n }\n },\n onRunStartedEvent: () => {\n localInterrupt = null;\n setPendingEvent(null);\n },\n onRunFinalized: () => {\n if (localInterrupt) {\n setPendingEvent(localInterrupt);\n localInterrupt = null;\n }\n },\n onRunFailed: () => {\n localInterrupt = null;\n },\n });\n\n return () => subscription.unsubscribe();\n }, [agent]);\n\n const resolve = useCallback(\n (response: unknown) => {\n setPendingEvent(null);\n copilotkit.runAgent({\n agent,\n forwardedProps: { command: { resume: response } },\n });\n },\n [agent, copilotkit],\n );\n\n useEffect(() => {\n // No interrupt to process — reset any stale handler result from a previous interrupt\n if (!pendingEvent) {\n setHandlerResult(null);\n return;\n }\n // Interrupt exists but the consumer's filter rejects it — treat as no-op\n if (config.enabled && !config.enabled(pendingEvent)) {\n setHandlerResult(null);\n return;\n }\n const handler = config.handler;\n // No handler provided — skip straight to rendering with a null result\n if (!handler) {\n setHandlerResult(null);\n return;\n }\n\n let cancelled = false;\n const maybePromise = handler({\n event: pendingEvent,\n resolve,\n });\n\n // If the handler returns a promise/thenable, wait for resolution before setting result.\n if (isPromiseLike(maybePromise)) {\n Promise.resolve(maybePromise)\n .then((resolved) => {\n if (!cancelled) setHandlerResult(resolved);\n })\n .catch(() => {\n if (!cancelled) setHandlerResult(null);\n });\n } else {\n setHandlerResult(maybePromise);\n }\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [pendingEvent, config.enabled, config.handler, resolve]);\n\n const element = useMemo(() => {\n if (!pendingEvent) return null;\n if (config.enabled && !config.enabled(pendingEvent)) return null;\n\n return config.render({\n event: pendingEvent,\n result: handlerResult,\n resolve,\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [pendingEvent, handlerResult, config.enabled, config.render, resolve]);\n\n // Publish to core for in-chat rendering\n useEffect(() => {\n if (config.renderInChat === false) return;\n copilotkit.setInterruptElement(element);\n return () => copilotkit.setInterruptElement(null);\n }, [element, config.renderInChat, copilotkit]);\n\n // Only return element when rendering outside chat\n if (config.renderInChat === false) {\n return element as UseInterruptReturn<TRenderInChat>;\n }\n\n return undefined as UseInterruptReturn<TRenderInChat>;\n}\n","import { useRenderToolCall } from \"@/hooks\";\nimport type { AssistantMessage, Message, ToolMessage } from \"@ag-ui/core\";\nimport React from \"react\";\n\nexport type CopilotChatToolCallsViewProps = {\n message: AssistantMessage;\n messages?: Message[];\n};\n\nexport function CopilotChatToolCallsView({\n message,\n messages = [],\n}: CopilotChatToolCallsViewProps) {\n const renderToolCall = useRenderToolCall();\n\n if (!message.toolCalls || message.toolCalls.length === 0) {\n return null;\n }\n\n return (\n <>\n {message.toolCalls.map((toolCall) => {\n const toolMessage = messages.find(\n (m) => m.role === \"tool\" && m.toolCallId === toolCall.id,\n ) as ToolMessage | undefined;\n\n return (\n <React.Fragment key={toolCall.id}>\n {renderToolCall({\n toolCall,\n toolMessage,\n })}\n </React.Fragment>\n );\n })}\n </>\n );\n}\n\nexport default CopilotChatToolCallsView;\n","import { AssistantMessage, Message } from \"@ag-ui/core\";\nimport { 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 \"katex/dist/katex.min.css\";\nimport { WithSlots, renderSlot } from \"@/lib/slots\";\nimport { Streamdown } from \"streamdown\";\nimport CopilotChatToolCallsView from \"./CopilotChatToolCallsView\";\n\nexport type CopilotChatAssistantMessageProps = WithSlots<\n {\n markdownRenderer: typeof CopilotChatAssistantMessage.MarkdownRenderer;\n toolbar: typeof CopilotChatAssistantMessage.Toolbar;\n copyButton: typeof CopilotChatAssistantMessage.CopyButton;\n thumbsUpButton: typeof CopilotChatAssistantMessage.ThumbsUpButton;\n thumbsDownButton: typeof CopilotChatAssistantMessage.ThumbsDownButton;\n readAloudButton: typeof CopilotChatAssistantMessage.ReadAloudButton;\n regenerateButton: typeof CopilotChatAssistantMessage.RegenerateButton;\n toolCallsView: typeof CopilotChatToolCallsView;\n },\n {\n onThumbsUp?: (message: AssistantMessage) => void;\n onThumbsDown?: (message: AssistantMessage) => void;\n onReadAloud?: (message: AssistantMessage) => void;\n onRegenerate?: (message: AssistantMessage) => void;\n message: AssistantMessage;\n messages?: Message[];\n isRunning?: boolean;\n additionalToolbarItems?: React.ReactNode;\n toolbarVisible?: boolean;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\nexport function CopilotChatAssistantMessage({\n message,\n messages,\n isRunning,\n onThumbsUp,\n onThumbsDown,\n onReadAloud,\n onRegenerate,\n additionalToolbarItems,\n toolbarVisible = true,\n markdownRenderer,\n toolbar,\n copyButton,\n thumbsUpButton,\n thumbsDownButton,\n readAloudButton,\n regenerateButton,\n toolCallsView,\n children,\n className,\n ...props\n}: CopilotChatAssistantMessageProps) {\n const boundMarkdownRenderer = renderSlot(\n markdownRenderer,\n CopilotChatAssistantMessage.MarkdownRenderer,\n {\n content: message.content || \"\",\n },\n );\n\n const boundCopyButton = renderSlot(\n copyButton,\n CopilotChatAssistantMessage.CopyButton,\n {\n onClick: async () => {\n if (message.content) {\n try {\n await navigator.clipboard.writeText(message.content);\n } catch (err) {\n console.error(\"Failed to copy message:\", err);\n }\n }\n },\n },\n );\n\n const boundThumbsUpButton = renderSlot(\n thumbsUpButton,\n CopilotChatAssistantMessage.ThumbsUpButton,\n {\n onClick: onThumbsUp,\n },\n );\n\n const boundThumbsDownButton = renderSlot(\n thumbsDownButton,\n CopilotChatAssistantMessage.ThumbsDownButton,\n {\n onClick: onThumbsDown,\n },\n );\n\n const boundReadAloudButton = renderSlot(\n readAloudButton,\n CopilotChatAssistantMessage.ReadAloudButton,\n {\n onClick: onReadAloud,\n },\n );\n\n const boundRegenerateButton = renderSlot(\n regenerateButton,\n CopilotChatAssistantMessage.RegenerateButton,\n {\n onClick: onRegenerate,\n },\n );\n\n const boundToolbar = renderSlot(\n toolbar,\n CopilotChatAssistantMessage.Toolbar,\n {\n children: (\n <div className=\"cpk:flex cpk:items-center cpk:gap-1\">\n {boundCopyButton}\n {(onThumbsUp || thumbsUpButton) && boundThumbsUpButton}\n {(onThumbsDown || thumbsDownButton) && boundThumbsDownButton}\n {(onReadAloud || readAloudButton) && boundReadAloudButton}\n {(onRegenerate || regenerateButton) && boundRegenerateButton}\n {additionalToolbarItems}\n </div>\n ),\n },\n );\n\n const boundToolCallsView = renderSlot(\n toolCallsView,\n CopilotChatToolCallsView,\n {\n message,\n messages,\n },\n );\n\n // Don't show toolbar if message has no content (only tool calls)\n const hasContent = !!(message.content && message.content.trim().length > 0);\n const isLatestAssistantMessage =\n message.role === \"assistant\" &&\n messages?.[messages.length - 1]?.id === message.id;\n const shouldShowToolbar =\n toolbarVisible && hasContent && !(isRunning && isLatestAssistantMessage);\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n markdownRenderer: boundMarkdownRenderer,\n toolbar: boundToolbar,\n toolCallsView: boundToolCallsView,\n copyButton: boundCopyButton,\n thumbsUpButton: boundThumbsUpButton,\n thumbsDownButton: boundThumbsDownButton,\n readAloudButton: boundReadAloudButton,\n regenerateButton: boundRegenerateButton,\n message,\n messages,\n isRunning,\n onThumbsUp,\n onThumbsDown,\n onReadAloud,\n onRegenerate,\n additionalToolbarItems,\n toolbarVisible: shouldShowToolbar,\n })}\n </div>\n );\n }\n\n return (\n <div\n data-copilotkit\n data-testid=\"copilot-assistant-message\"\n className={twMerge(className)}\n {...props}\n data-message-id={message.id}\n >\n <div className=\"cpk:prose cpk:max-w-full cpk:break-words cpk:dark:prose-invert\">\n {boundMarkdownRenderer}\n </div>\n {boundToolCallsView}\n {shouldShowToolbar && boundToolbar}\n </div>\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotChatAssistantMessage {\n export const MarkdownRenderer: React.FC<\n Omit<React.ComponentProps<typeof Streamdown>, \"children\"> & {\n content: string;\n }\n > = ({ content, className, ...props }) => (\n <Streamdown className={className} {...props}>\n {content ?? \"\"}\n </Streamdown>\n );\n\n export const Toolbar: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n className,\n ...props\n }) => (\n <div\n data-testid=\"copilot-assistant-toolbar\"\n className={twMerge(\n \"cpk:w-full cpk:bg-transparent cpk:flex cpk:items-center cpk:-ml-[5px] cpk:-mt-[0px]\",\n className,\n )}\n {...props}\n />\n );\n\n export const ToolbarButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & {\n title: string;\n children: React.ReactNode;\n }\n > = ({ title, children, ...props }) => {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"assistantMessageToolbarButton\"\n aria-label={title}\n {...props}\n >\n {children}\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">\n <p>{title}</p>\n </TooltipContent>\n </Tooltip>\n );\n };\n\n export const CopyButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, title, onClick, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n const [copied, setCopied] = useState(false);\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n\n if (onClick) {\n onClick(event);\n }\n };\n\n return (\n <ToolbarButton\n data-testid=\"copilot-copy-button\"\n title={title || labels.assistantMessageToolbarCopyMessageLabel}\n onClick={handleClick}\n className={className}\n {...props}\n >\n {copied ? (\n <Check className=\"cpk:size-[18px]\" />\n ) : (\n <Copy className=\"cpk:size-[18px]\" />\n )}\n </ToolbarButton>\n );\n };\n\n export const ThumbsUpButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-thumbs-up-button\"\n title={title || labels.assistantMessageToolbarThumbsUpLabel}\n {...props}\n >\n <ThumbsUp className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n\n export const ThumbsDownButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-thumbs-down-button\"\n title={title || labels.assistantMessageToolbarThumbsDownLabel}\n {...props}\n >\n <ThumbsDown className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n\n export const ReadAloudButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-read-aloud-button\"\n title={title || labels.assistantMessageToolbarReadAloudLabel}\n {...props}\n >\n <Volume2 className=\"cpk:size-[20px]\" />\n </ToolbarButton>\n );\n };\n\n export const RegenerateButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-regenerate-button\"\n title={title || labels.assistantMessageToolbarRegenerateLabel}\n {...props}\n >\n <RefreshCw className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n}\n\nCopilotChatAssistantMessage.MarkdownRenderer.displayName =\n \"CopilotChatAssistantMessage.MarkdownRenderer\";\nCopilotChatAssistantMessage.Toolbar.displayName =\n \"CopilotChatAssistantMessage.Toolbar\";\nCopilotChatAssistantMessage.CopyButton.displayName =\n \"CopilotChatAssistantMessage.CopyButton\";\nCopilotChatAssistantMessage.ThumbsUpButton.displayName =\n \"CopilotChatAssistantMessage.ThumbsUpButton\";\nCopilotChatAssistantMessage.ThumbsDownButton.displayName =\n \"CopilotChatAssistantMessage.ThumbsDownButton\";\nCopilotChatAssistantMessage.ReadAloudButton.displayName =\n \"CopilotChatAssistantMessage.ReadAloudButton\";\nCopilotChatAssistantMessage.RegenerateButton.displayName =\n \"CopilotChatAssistantMessage.RegenerateButton\";\n\nexport default CopilotChatAssistantMessage;\n","import { useMemo, useState } from \"react\";\nimport { Copy, Check, Edit, ChevronLeft, ChevronRight } from \"lucide-react\";\nimport {\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport { twMerge } from \"tailwind-merge\";\nimport { Button } from \"@/components/ui/button\";\nimport { UserMessage } from \"@ag-ui/core\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { renderSlot, WithSlots } from \"@/lib/slots\";\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\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 BoundMessageRenderer = renderSlot(\n messageRenderer,\n CopilotChatUserMessage.MessageRenderer,\n {\n content: flattenedContent,\n },\n );\n\n const BoundCopyButton = renderSlot(\n copyButton,\n CopilotChatUserMessage.CopyButton,\n {\n onClick: async () => {\n if (flattenedContent) {\n try {\n await navigator.clipboard.writeText(flattenedContent);\n } catch (err) {\n console.error(\"Failed to copy message:\", err);\n }\n }\n },\n },\n );\n\n const BoundEditButton = renderSlot(\n editButton,\n CopilotChatUserMessage.EditButton,\n {\n onClick: () => onEditMessage?.({ message }),\n },\n );\n\n const BoundBranchNavigation = renderSlot(\n branchNavigation,\n CopilotChatUserMessage.BranchNavigation,\n {\n currentBranch: branchIndex,\n numberOfBranches,\n onSwitchToBranch,\n message,\n },\n );\n\n const showBranchNavigation =\n numberOfBranches && numberOfBranches > 1 && onSwitchToBranch;\n\n const BoundToolbar = renderSlot(toolbar, CopilotChatUserMessage.Toolbar, {\n children: (\n <div className=\"cpk:flex cpk:items-center cpk:gap-1 cpk:justify-end\">\n {additionalToolbarItems}\n {BoundCopyButton}\n {onEditMessage && BoundEditButton}\n {showBranchNavigation && BoundBranchNavigation}\n </div>\n ),\n });\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n messageRenderer: BoundMessageRenderer,\n toolbar: BoundToolbar,\n copyButton: BoundCopyButton,\n editButton: BoundEditButton,\n branchNavigation: BoundBranchNavigation,\n message,\n branchIndex,\n numberOfBranches,\n additionalToolbarItems,\n })}\n </div>\n );\n }\n\n return (\n <div\n data-copilotkit\n data-testid=\"copilot-user-message\"\n className={twMerge(\n \"cpk:flex cpk:flex-col cpk:items-end cpk:group cpk:pt-10\",\n className,\n )}\n data-message-id={message.id}\n {...props}\n >\n {BoundMessageRenderer}\n {BoundToolbar}\n </div>\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotChatUserMessage {\n export const Container: React.FC<\n React.PropsWithChildren<React.HTMLAttributes<HTMLDivElement>>\n > = ({ children, className, ...props }) => (\n <div\n className={twMerge(\n \"cpk:flex cpk:flex-col cpk:items-end cpk:group\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n );\n\n export const MessageRenderer: React.FC<{\n content: string;\n className?: string;\n }> = ({ content, className }) => (\n <div\n className={twMerge(\n \"cpk:prose cpk:dark:prose-invert cpk:bg-muted cpk:relative cpk:max-w-[80%] cpk:rounded-[18px] cpk:px-4 cpk:py-1.5 cpk:data-[multiline]:py-3 cpk:inline-block cpk:whitespace-pre-wrap\",\n className,\n )}\n >\n {content}\n </div>\n );\n\n export const Toolbar: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n className,\n ...props\n }) => (\n <div\n data-testid=\"copilot-user-toolbar\"\n className={twMerge(\n \"cpk:w-full cpk:bg-transparent cpk:flex cpk:items-center cpk:justify-end cpk:-mr-[5px] cpk:mt-[4px] cpk:invisible cpk:group-hover:visible\",\n className,\n )}\n {...props}\n />\n );\n\n export const ToolbarButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & {\n title: string;\n children: React.ReactNode;\n }\n > = ({ title, children, className, ...props }) => {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"assistantMessageToolbarButton\"\n aria-label={title}\n className={twMerge(className)}\n {...props}\n >\n {children}\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">\n <p>{title}</p>\n </TooltipContent>\n </Tooltip>\n );\n };\n\n export const CopyButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & { copied?: boolean }\n > = ({ className, title, onClick, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n const [copied, setCopied] = useState(false);\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n\n if (onClick) {\n onClick(event);\n }\n };\n\n return (\n <ToolbarButton\n data-testid=\"copilot-user-copy-button\"\n title={title || labels.userMessageToolbarCopyMessageLabel}\n onClick={handleClick}\n className={className}\n {...props}\n >\n {copied ? (\n <Check className=\"cpk:size-[18px]\" />\n ) : (\n <Copy className=\"cpk:size-[18px]\" />\n )}\n </ToolbarButton>\n );\n };\n\n export const EditButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-edit-button\"\n title={title || labels.userMessageToolbarEditMessageLabel}\n className={className}\n {...props}\n >\n <Edit className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n\n export const BranchNavigation: React.FC<\n React.HTMLAttributes<HTMLDivElement> & {\n currentBranch?: number;\n numberOfBranches?: number;\n onSwitchToBranch?: (\n props: CopilotChatUserMessageOnSwitchToBranchProps,\n ) => void;\n message: UserMessage;\n }\n > = ({\n className,\n currentBranch = 0,\n numberOfBranches = 1,\n onSwitchToBranch,\n message,\n ...props\n }) => {\n if (!numberOfBranches || numberOfBranches <= 1 || !onSwitchToBranch) {\n return null;\n }\n\n const canGoPrev = currentBranch > 0;\n const canGoNext = currentBranch < numberOfBranches - 1;\n\n return (\n <div\n data-testid=\"copilot-branch-navigation\"\n className={twMerge(\"cpk:flex cpk:items-center cpk:gap-1\", className)}\n {...props}\n >\n <Button\n type=\"button\"\n variant=\"assistantMessageToolbarButton\"\n onClick={() =>\n onSwitchToBranch?.({\n branchIndex: currentBranch - 1,\n numberOfBranches,\n message,\n })\n }\n disabled={!canGoPrev}\n className=\"cpk:h-6 cpk:w-6 cpk:p-0\"\n >\n <ChevronLeft className=\"cpk:size-[20px]\" />\n </Button>\n <span className=\"cpk:text-sm cpk:text-muted-foreground cpk:px-0 cpk:font-medium\">\n {currentBranch + 1}/{numberOfBranches}\n </span>\n <Button\n type=\"button\"\n variant=\"assistantMessageToolbarButton\"\n onClick={() =>\n onSwitchToBranch?.({\n branchIndex: currentBranch + 1,\n numberOfBranches,\n message,\n })\n }\n disabled={!canGoNext}\n className=\"cpk:h-6 cpk:w-6 cpk:p-0\"\n >\n <ChevronRight className=\"cpk:size-[20px]\" />\n </Button>\n </div>\n );\n };\n}\n\nCopilotChatUserMessage.Container.displayName =\n \"CopilotChatUserMessage.Container\";\nCopilotChatUserMessage.MessageRenderer.displayName =\n \"CopilotChatUserMessage.MessageRenderer\";\nCopilotChatUserMessage.Toolbar.displayName = \"CopilotChatUserMessage.Toolbar\";\nCopilotChatUserMessage.ToolbarButton.displayName =\n \"CopilotChatUserMessage.ToolbarButton\";\nCopilotChatUserMessage.CopyButton.displayName =\n \"CopilotChatUserMessage.CopyButton\";\nCopilotChatUserMessage.EditButton.displayName =\n \"CopilotChatUserMessage.EditButton\";\nCopilotChatUserMessage.BranchNavigation.displayName =\n \"CopilotChatUserMessage.BranchNavigation\";\n\nexport default CopilotChatUserMessage;\n","import { ReasoningMessage, Message } from \"@ag-ui/core\";\nimport { useState, useEffect, useRef } from \"react\";\nimport { ChevronRight } from \"lucide-react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { Streamdown } from \"streamdown\";\nimport { WithSlots, renderSlot } from \"@/lib/slots\";\n\nexport type CopilotChatReasoningMessageProps = WithSlots<\n {\n header: typeof CopilotChatReasoningMessage.Header;\n contentView: typeof CopilotChatReasoningMessage.Content;\n toggle: typeof CopilotChatReasoningMessage.Toggle;\n },\n {\n message: ReasoningMessage;\n messages?: Message[];\n isRunning?: boolean;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\n/**\n * Formats an elapsed duration (in seconds) to a human-readable string.\n */\nfunction formatDuration(seconds: number): string {\n if (seconds < 1) return \"a few seconds\";\n if (seconds < 60) return `${Math.round(seconds)} seconds`;\n const mins = Math.floor(seconds / 60);\n const secs = Math.round(seconds % 60);\n if (secs === 0) return `${mins} minute${mins > 1 ? \"s\" : \"\"}`;\n return `${mins}m ${secs}s`;\n}\n\nexport function CopilotChatReasoningMessage({\n message,\n messages,\n isRunning,\n header,\n contentView,\n toggle,\n children,\n className,\n ...props\n}: CopilotChatReasoningMessageProps) {\n const isLatest = messages?.[messages.length - 1]?.id === message.id;\n const isStreaming = !!(isRunning && isLatest);\n const hasContent = !!(message.content && message.content.length > 0);\n\n // Track elapsed time while streaming\n const startTimeRef = useRef<number | null>(null);\n const [elapsed, setElapsed] = useState(0);\n\n useEffect(() => {\n if (isStreaming && startTimeRef.current === null) {\n startTimeRef.current = Date.now();\n }\n\n if (!isStreaming && startTimeRef.current !== null) {\n // Final snapshot of elapsed time\n setElapsed((Date.now() - startTimeRef.current) / 1000);\n return;\n }\n\n if (!isStreaming) return;\n\n // Tick every second while streaming\n const timer = setInterval(() => {\n if (startTimeRef.current !== null) {\n setElapsed((Date.now() - startTimeRef.current) / 1000);\n }\n }, 1000);\n return () => clearInterval(timer);\n }, [isStreaming]);\n\n // Default to open while streaming, auto-collapse when streaming ends\n const [isOpen, setIsOpen] = useState(isStreaming);\n\n useEffect(() => {\n if (isStreaming) {\n setIsOpen(true);\n } else {\n // Auto-collapse when reasoning finishes\n setIsOpen(false);\n }\n }, [isStreaming]);\n\n const label = isStreaming\n ? \"Thinking…\"\n : `Thought for ${formatDuration(elapsed)}`;\n\n const boundHeader = renderSlot(header, CopilotChatReasoningMessage.Header, {\n isOpen,\n label,\n hasContent,\n isStreaming,\n onClick: hasContent ? () => setIsOpen((prev) => !prev) : undefined,\n });\n\n const boundContent = renderSlot(\n contentView,\n CopilotChatReasoningMessage.Content,\n {\n isStreaming,\n hasContent,\n children: message.content,\n },\n );\n\n const boundToggle = renderSlot(toggle, CopilotChatReasoningMessage.Toggle, {\n isOpen,\n children: boundContent,\n });\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n header: boundHeader,\n contentView: boundContent,\n toggle: boundToggle,\n message,\n messages,\n isRunning,\n })}\n </div>\n );\n }\n\n return (\n <div\n className={twMerge(\"cpk:my-1\", className)}\n data-message-id={message.id}\n {...props}\n >\n {boundHeader}\n {boundToggle}\n </div>\n );\n}\n\nexport namespace CopilotChatReasoningMessage {\n export const Header: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & {\n isOpen?: boolean;\n label?: string;\n hasContent?: boolean;\n isStreaming?: boolean;\n }\n > = ({\n isOpen,\n label = \"Thoughts\",\n hasContent,\n isStreaming,\n className,\n children: headerChildren,\n ...headerProps\n }) => {\n const isExpandable = !!hasContent;\n\n return (\n <button\n type=\"button\"\n className={twMerge(\n \"cpk:inline-flex cpk:items-center cpk:gap-1 cpk:py-1 cpk:text-sm cpk:text-muted-foreground cpk:transition-colors cpk:select-none\",\n isExpandable\n ? \"cpk:hover:text-foreground cpk:cursor-pointer\"\n : \"cpk:cursor-default\",\n className,\n )}\n aria-expanded={isExpandable ? isOpen : undefined}\n {...headerProps}\n >\n <span className=\"cpk:font-medium\">{label}</span>\n {isStreaming && !hasContent && (\n <span className=\"cpk:inline-flex cpk:items-center cpk:ml-1\">\n <span className=\"cpk:w-1.5 cpk:h-1.5 cpk:rounded-full cpk:bg-muted-foreground cpk:animate-pulse\" />\n </span>\n )}\n {headerChildren}\n {isExpandable && (\n <ChevronRight\n className={twMerge(\n \"cpk:size-3.5 cpk:shrink-0 cpk:transition-transform cpk:duration-200\",\n isOpen && \"cpk:rotate-90\",\n )}\n />\n )}\n </button>\n );\n };\n\n export const Content: React.FC<\n React.HTMLAttributes<HTMLDivElement> & {\n isStreaming?: boolean;\n hasContent?: boolean;\n }\n > = ({\n isStreaming,\n hasContent,\n className,\n children: contentChildren,\n ...contentProps\n }) => {\n // Don't render the content area at all when there's nothing to show\n if (!hasContent && !isStreaming) return null;\n\n return (\n <div\n className={twMerge(\"cpk:pb-2 cpk:pt-1\", className)}\n {...contentProps}\n >\n <div className=\"cpk:text-sm cpk:text-muted-foreground\">\n <Streamdown>\n {typeof contentChildren === \"string\" ? contentChildren : \"\"}\n </Streamdown>\n {isStreaming && hasContent && (\n <span className=\"cpk:inline-flex cpk:items-center cpk:ml-1 cpk:align-middle\">\n <span className=\"cpk:w-2 cpk:h-2 cpk:rounded-full cpk:bg-muted-foreground cpk:animate-pulse-cursor\" />\n </span>\n )}\n </div>\n </div>\n );\n };\n\n export const Toggle: React.FC<\n React.HTMLAttributes<HTMLDivElement> & {\n isOpen?: boolean;\n }\n > = ({ isOpen, className, children: toggleChildren, ...toggleProps }) => {\n return (\n <div\n className={twMerge(\n \"cpk:grid cpk:transition-[grid-template-rows] cpk:duration-200 cpk:ease-in-out\",\n className,\n )}\n style={{ gridTemplateRows: isOpen ? \"1fr\" : \"0fr\" }}\n {...toggleProps}\n >\n <div className=\"cpk:overflow-hidden\">{toggleChildren}</div>\n </div>\n );\n };\n}\n\nCopilotChatReasoningMessage.Header.displayName =\n \"CopilotChatReasoningMessage.Header\";\nCopilotChatReasoningMessage.Content.displayName =\n \"CopilotChatReasoningMessage.Content\";\nCopilotChatReasoningMessage.Toggle.displayName =\n \"CopilotChatReasoningMessage.Toggle\";\n\nexport default CopilotChatReasoningMessage;\n","import React from \"react\";\nimport { Loader2 } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\n\nexport interface CopilotChatSuggestionPillProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Optional icon to render on the left side when not loading. */\n icon?: React.ReactNode;\n /** Whether the pill should display a loading spinner. */\n isLoading?: boolean;\n}\n\nconst baseClasses =\n \"group cpk:inline-flex cpk:h-7 cpk:sm:h-8 cpk:items-center cpk:gap-1 cpk:sm:gap-1.5 cpk:rounded-full cpk:border cpk:border-border/60 cpk:bg-background cpk:px-2.5 cpk:sm:px-3 cpk:text-[11px] cpk:sm:text-xs cpk:leading-none cpk:text-foreground cpk:transition-colors cpk:cursor-pointer cpk:hover:bg-accent/60 cpk:hover:text-foreground cpk:focus-visible:outline-none cpk:focus-visible:ring-2 cpk:focus-visible:ring-ring cpk:focus-visible:ring-offset-2 cpk:focus-visible:ring-offset-background cpk:disabled:cursor-not-allowed cpk:disabled:text-muted-foreground cpk:disabled:hover:bg-background cpk:disabled:hover:text-muted-foreground cpk:pointer-events-auto\";\n\nconst labelClasses = \"cpk:whitespace-nowrap cpk:font-medium cpk:leading-none\";\n\nexport const CopilotChatSuggestionPill = React.forwardRef<\n HTMLButtonElement,\n CopilotChatSuggestionPillProps\n>(function CopilotChatSuggestionPill(\n { className, children, icon, isLoading, type, ...props },\n ref,\n) {\n const showIcon = !isLoading && icon;\n\n return (\n <button\n ref={ref}\n data-copilotkit\n data-testid=\"copilot-suggestion\"\n data-slot=\"suggestion-pill\"\n className={cn(baseClasses, className)}\n type={type ?? \"button\"}\n aria-busy={isLoading || undefined}\n disabled={isLoading || props.disabled}\n {...props}\n >\n {isLoading ? (\n <span className=\"cpk:flex cpk:h-3.5 cpk:sm:h-4 cpk:w-3.5 cpk:sm:w-4 cpk:items-center cpk:justify-center cpk:text-muted-foreground\">\n <Loader2\n className=\"cpk:h-3.5 cpk:sm:h-4 cpk:w-3.5 cpk:sm:w-4 cpk:animate-spin\"\n aria-hidden=\"true\"\n />\n </span>\n ) : (\n showIcon && (\n <span className=\"cpk:flex cpk:h-3.5 cpk:sm:h-4 cpk:w-3.5 cpk:sm:w-4 cpk:items-center cpk:justify-center cpk:text-muted-foreground\">\n {icon}\n </span>\n )\n )}\n <span className={labelClasses}>{children}</span>\n </button>\n );\n});\n\nCopilotChatSuggestionPill.displayName = \"CopilotChatSuggestionPill\";\n\nexport default CopilotChatSuggestionPill;\n","import React from \"react\";\nimport { Suggestion } from \"@copilotkitnext/core\";\nimport { renderSlot, WithSlots } from \"@/lib/slots\";\nimport { cn } from \"@/lib/utils\";\nimport CopilotChatSuggestionPill, {\n CopilotChatSuggestionPillProps,\n} from \"./CopilotChatSuggestionPill\";\n\nconst DefaultContainer = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(function DefaultContainer({ className, ...props }, ref) {\n return (\n <div\n ref={ref}\n data-copilotkit\n data-testid=\"copilot-suggestions\"\n className={cn(\n \"cpk:flex cpk:flex-wrap cpk:items-center cpk:gap-1.5 cpk:sm:gap-2 cpk:pl-0 cpk:pr-4 cpk:sm:px-0 cpk:pointer-events-none\",\n className,\n )}\n {...props}\n />\n );\n});\n\nexport type CopilotChatSuggestionViewProps = WithSlots<\n {\n container: typeof DefaultContainer;\n suggestion: typeof CopilotChatSuggestionPill;\n },\n {\n suggestions: Suggestion[];\n onSelectSuggestion?: (suggestion: Suggestion, index: number) => void;\n loadingIndexes?: ReadonlyArray<number>;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\nexport const CopilotChatSuggestionView = React.forwardRef<\n HTMLDivElement,\n CopilotChatSuggestionViewProps\n>(function CopilotChatSuggestionView(\n {\n suggestions,\n onSelectSuggestion,\n loadingIndexes,\n container,\n suggestion: suggestionSlot,\n className,\n children,\n ...restProps\n },\n ref,\n) {\n const loadingSet = React.useMemo(() => {\n if (!loadingIndexes || loadingIndexes.length === 0) {\n return new Set<number>();\n }\n return new Set(loadingIndexes);\n }, [loadingIndexes]);\n\n const ContainerElement = renderSlot(container, DefaultContainer, {\n ref,\n className,\n ...restProps,\n });\n\n const suggestionElements = suggestions.map((suggestion, index) => {\n const isLoading = loadingSet.has(index) || suggestion.isLoading === true;\n const pill = renderSlot<\n typeof CopilotChatSuggestionPill,\n CopilotChatSuggestionPillProps\n >(suggestionSlot, CopilotChatSuggestionPill, {\n children: suggestion.title,\n 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, { useEffect, useReducer, useState } from \"react\";\nimport { WithSlots, renderSlot, isReactComponentType } from \"@/lib/slots\";\nimport CopilotChatAssistantMessage from \"./CopilotChatAssistantMessage\";\nimport CopilotChatUserMessage from \"./CopilotChatUserMessage\";\nimport CopilotChatReasoningMessage from \"./CopilotChatReasoningMessage\";\nimport {\n ActivityMessage,\n AssistantMessage,\n Message,\n ReasoningMessage,\n 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\";\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 || !nextTc) return false;\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.role === \"tool\" && toolCallIds.has((m as any).toolCallId),\n );\n const nextToolResults = nextProps.messages.filter(\n (m) => m.role === \"tool\" && toolCallIds.has((m as any).toolCallId),\n );\n\n // If number of tool results changed, re-render\n if (prevToolResults.length !== nextToolResults.length) return false;\n\n // If any tool result content changed, re-render\n for (let i = 0; i < prevToolResults.length; i++) {\n if (\n (prevToolResults[i] as any).content !==\n (nextToolResults[i] as any).content\n )\n return false;\n }\n }\n\n // Only care about isRunning if this message is CURRENTLY the latest\n // (we don't need to re-render just because a message stopped being the latest)\n const nextIsLatest =\n nextProps.messages[nextProps.messages.length - 1]?.id ===\n nextProps.message.id;\n if (nextIsLatest && prevProps.isRunning !== nextProps.isRunning)\n return false;\n\n // Check if component reference changed\n if (\n prevProps.AssistantMessageComponent !==\n nextProps.AssistantMessageComponent\n )\n return false;\n\n // Check if slot props changed\n if (prevProps.slotProps !== nextProps.slotProps) return false;\n\n return true;\n },\n);\n\n/**\n * Memoized wrapper for user messages to prevent re-renders when other messages change.\n */\nconst MemoizedUserMessage = React.memo(\n function MemoizedUserMessage({\n message,\n UserMessageComponent,\n slotProps,\n }: {\n message: UserMessage;\n UserMessageComponent: typeof CopilotChatUserMessage;\n slotProps?: Partial<React.ComponentProps<typeof CopilotChatUserMessage>>;\n }) {\n return <UserMessageComponent message={message} {...slotProps} />;\n },\n (prevProps, nextProps) => {\n // Only re-render if this specific message changed\n if (prevProps.message.id !== nextProps.message.id) return false;\n if (prevProps.message.content !== nextProps.message.content) return false;\n if (prevProps.UserMessageComponent !== nextProps.UserMessageComponent)\n return false;\n // Check if slot props changed\n if (prevProps.slotProps !== nextProps.slotProps) return false;\n return true;\n },\n);\n\n/**\n * Memoized wrapper for activity messages to prevent re-renders when other messages change.\n */\nconst MemoizedActivityMessage = React.memo(\n function MemoizedActivityMessage({\n message,\n renderActivityMessage,\n }: {\n message: ActivityMessage;\n renderActivityMessage: (\n message: ActivityMessage,\n ) => React.ReactElement | null;\n }) {\n return renderActivityMessage(message);\n },\n (prevProps, nextProps) => {\n // Message ID changed = different message, must re-render\n if (prevProps.message.id !== nextProps.message.id) return false;\n\n // Activity type changed = must re-render\n if (prevProps.message.activityType !== nextProps.message.activityType)\n return false;\n\n // Compare content using JSON.stringify (native code, handles deep comparison)\n if (\n JSON.stringify(prevProps.message.content) !==\n JSON.stringify(nextProps.message.content)\n )\n return false;\n\n return true;\n },\n);\n\n/**\n * Memoized wrapper for reasoning messages to prevent re-renders when other messages change.\n */\nconst MemoizedReasoningMessage = React.memo(\n function MemoizedReasoningMessage({\n message,\n messages,\n isRunning,\n ReasoningMessageComponent,\n slotProps,\n }: {\n message: ReasoningMessage;\n messages: Message[];\n isRunning: boolean;\n ReasoningMessageComponent: typeof CopilotChatReasoningMessage;\n slotProps?: Partial<\n React.ComponentProps<typeof CopilotChatReasoningMessage>\n >;\n }) {\n return (\n <ReasoningMessageComponent\n message={message}\n messages={messages}\n isRunning={isRunning}\n {...slotProps}\n />\n );\n },\n (prevProps, nextProps) => {\n // Only re-render if this specific message changed\n if (prevProps.message.id !== nextProps.message.id) return false;\n if (prevProps.message.content !== nextProps.message.content) return false;\n\n // Re-render when \"latest\" status changes (e.g. reasoning message is no longer the last message\n // because a text message was added after it — this transitions isStreaming from true to false)\n const prevIsLatest =\n prevProps.messages[prevProps.messages.length - 1]?.id ===\n prevProps.message.id;\n const nextIsLatest =\n nextProps.messages[nextProps.messages.length - 1]?.id ===\n nextProps.message.id;\n if (prevIsLatest !== nextIsLatest) return false;\n\n // Only care about isRunning if this message is CURRENTLY the latest\n if (nextIsLatest && prevProps.isRunning !== nextProps.isRunning)\n return false;\n\n // Check if component reference changed\n if (\n prevProps.ReasoningMessageComponent !==\n nextProps.ReasoningMessageComponent\n )\n return false;\n\n // Check if slot props changed\n if (prevProps.slotProps !== nextProps.slotProps) return false;\n\n return true;\n },\n);\n\n/**\n * Memoized wrapper for custom messages to prevent re-renders when other messages change.\n */\nconst MemoizedCustomMessage = React.memo(\n function MemoizedCustomMessage({\n message,\n position,\n renderCustomMessage,\n }: {\n message: Message;\n position: \"before\" | \"after\";\n renderCustomMessage: (params: {\n message: Message;\n position: \"before\" | \"after\";\n }) => React.ReactElement | null;\n stateSnapshot?: unknown;\n }) {\n return renderCustomMessage({ message, position });\n },\n (prevProps, nextProps) => {\n // Only re-render if the message or position changed\n if (prevProps.message.id !== nextProps.message.id) return false;\n if (prevProps.position !== nextProps.position) return false;\n // Compare message content - for assistant messages this is a string, for others may differ\n if (prevProps.message.content !== nextProps.message.content) return false;\n if (prevProps.message.role !== nextProps.message.role) return false;\n // Compare state snapshot - custom renderers may depend on state\n if (\n JSON.stringify(prevProps.stateSnapshot) !==\n JSON.stringify(nextProps.stateSnapshot)\n )\n return false;\n // Note: We don't compare renderCustomMessage function reference because it changes\n // frequently. The message and state comparison is sufficient to determine if a re-render is needed.\n return true;\n },\n);\n\nexport type CopilotChatMessageViewProps = Omit<\n WithSlots<\n {\n assistantMessage: typeof CopilotChatAssistantMessage;\n userMessage: typeof CopilotChatUserMessage;\n reasoningMessage: typeof CopilotChatReasoningMessage;\n cursor: typeof CopilotChatMessageView.Cursor;\n },\n {\n isRunning?: boolean;\n messages?: Message[];\n } & React.HTMLAttributes<HTMLDivElement>\n >,\n \"children\"\n> & {\n children?: (props: {\n isRunning: boolean;\n messages: Message[];\n messageElements: React.ReactElement[];\n interruptElement: React.ReactElement | null;\n }) => React.ReactElement;\n};\n\nexport function CopilotChatMessageView({\n messages = [],\n assistantMessage,\n userMessage,\n reasoningMessage,\n cursor,\n isRunning = false,\n children,\n className,\n ...props\n}: CopilotChatMessageViewProps) {\n const renderCustomMessage = useRenderCustomMessages();\n const { renderActivityMessage } = useRenderActivityMessage();\n const { copilotkit } = useCopilotKit();\n const config = useCopilotChatConfiguration();\n const [, forceUpdate] = useReducer((x) => x + 1, 0);\n\n // Subscribe to state changes so custom message renderers re-render when state updates.\n useEffect(() => {\n if (!config?.agentId) return;\n const 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 messageElements: React.ReactElement[] = messages\n .flatMap((message) => {\n const elements: (React.ReactElement | null | undefined)[] = [];\n const stateSnapshot = getStateSnapshotForMessage(message.id);\n\n // Render custom message before (using memoized wrapper)\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 // Render the main message using memoized wrappers to prevent unnecessary re-renders\n if (message.role === \"assistant\") {\n // Determine the component and props from slot value\n let AssistantComponent = CopilotChatAssistantMessage;\n let assistantSlotProps:\n | Partial<React.ComponentProps<typeof CopilotChatAssistantMessage>>\n | undefined;\n\n if (isReactComponentType(assistantMessage)) {\n // Custom component (function, forwardRef, memo, etc.)\n AssistantComponent =\n assistantMessage as typeof CopilotChatAssistantMessage;\n } else if (typeof assistantMessage === \"string\") {\n // className string\n assistantSlotProps = { className: assistantMessage };\n } else if (assistantMessage && typeof assistantMessage === \"object\") {\n // Props object\n assistantSlotProps = assistantMessage as Partial<\n React.ComponentProps<typeof CopilotChatAssistantMessage>\n >;\n }\n\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 // Determine the component and props from slot value\n let UserComponent = CopilotChatUserMessage;\n let userSlotProps:\n | Partial<React.ComponentProps<typeof CopilotChatUserMessage>>\n | undefined;\n\n if (isReactComponentType(userMessage)) {\n // Custom component (function, forwardRef, memo, etc.)\n UserComponent = userMessage as typeof CopilotChatUserMessage;\n } else if (typeof userMessage === \"string\") {\n // className string\n userSlotProps = { className: userMessage };\n } else if (userMessage && typeof userMessage === \"object\") {\n // Props object\n userSlotProps = userMessage as Partial<\n React.ComponentProps<typeof CopilotChatUserMessage>\n >;\n }\n\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 // Use memoized wrapper to prevent re-renders when other messages change\n const activityMsg = message as ActivityMessage;\n elements.push(\n <MemoizedActivityMessage\n key={message.id}\n message={activityMsg}\n renderActivityMessage={renderActivityMessage}\n />,\n );\n } else if (message.role === \"reasoning\") {\n // Determine the component and props from slot value\n let ReasoningComponent = CopilotChatReasoningMessage;\n let reasoningSlotProps:\n | Partial<React.ComponentProps<typeof CopilotChatReasoningMessage>>\n | undefined;\n\n if (isReactComponentType(reasoningMessage)) {\n ReasoningComponent =\n reasoningMessage as typeof CopilotChatReasoningMessage;\n } else if (typeof reasoningMessage === \"string\") {\n reasoningSlotProps = { className: reasoningMessage };\n } else if (reasoningMessage && typeof reasoningMessage === \"object\") {\n reasoningSlotProps = reasoningMessage as Partial<\n React.ComponentProps<typeof CopilotChatReasoningMessage>\n >;\n }\n\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 // Render custom message after (using memoized wrapper)\n if (renderCustomMessage) {\n elements.push(\n <MemoizedCustomMessage\n key={`${message.id}-custom-after`}\n message={message}\n position=\"after\"\n renderCustomMessage={renderCustomMessage}\n stateSnapshot={stateSnapshot}\n />,\n );\n }\n\n return elements;\n })\n .filter(Boolean) as React.ReactElement[];\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 return (\n <div\n data-copilotkit\n data-testid=\"copilot-message-list\"\n className={twMerge(\"cpk:flex cpk:flex-col\", className)}\n {...props}\n >\n {messageElements}\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 { useState, useEffect } from \"react\";\n\nexport interface KeyboardState {\n isKeyboardOpen: boolean;\n keyboardHeight: number;\n availableHeight: number;\n viewportHeight: number;\n}\n\n/**\n * Hook to detect mobile keyboard appearance and calculate available viewport height.\n * Uses the Visual Viewport API to track keyboard state on mobile devices.\n *\n * @returns KeyboardState object with keyboard information\n */\nexport function useKeyboardHeight(): KeyboardState {\n const [keyboardState, setKeyboardState] = useState<KeyboardState>({\n isKeyboardOpen: false,\n keyboardHeight: 0,\n availableHeight: typeof window !== \"undefined\" ? window.innerHeight : 0,\n viewportHeight: typeof window !== \"undefined\" ? window.innerHeight : 0,\n });\n\n useEffect(() => {\n if (typeof window === \"undefined\") {\n return;\n }\n\n // Check if Visual Viewport API is available\n const visualViewport = window.visualViewport;\n if (!visualViewport) {\n return;\n }\n\n const updateKeyboardState = () => {\n const layoutHeight = window.innerHeight;\n const visualHeight = visualViewport.height;\n\n // Calculate keyboard height (difference between layout and visual viewport)\n const keyboardHeight = Math.max(0, layoutHeight - visualHeight);\n\n // Keyboard is considered open if the height difference is significant (> 150px)\n const isKeyboardOpen = keyboardHeight > 150;\n\n setKeyboardState({\n isKeyboardOpen,\n keyboardHeight,\n availableHeight: visualHeight,\n viewportHeight: layoutHeight,\n });\n };\n\n // Initial state\n updateKeyboardState();\n\n // Listen for viewport changes\n visualViewport.addEventListener(\"resize\", updateKeyboardState);\n visualViewport.addEventListener(\"scroll\", updateKeyboardState);\n\n return () => {\n visualViewport.removeEventListener(\"resize\", updateKeyboardState);\n visualViewport.removeEventListener(\"scroll\", updateKeyboardState);\n };\n }, []);\n\n return keyboardState;\n}\n","import React, { useRef, useState, useEffect } from \"react\";\nimport { WithSlots, SlotValue, renderSlot } from \"@/lib/slots\";\nimport CopilotChatMessageView from \"./CopilotChatMessageView\";\nimport CopilotChatInput, {\n CopilotChatInputProps,\n CopilotChatInputMode,\n} from \"./CopilotChatInput\";\nimport CopilotChatSuggestionView, {\n CopilotChatSuggestionViewProps,\n} from \"./CopilotChatSuggestionView\";\nimport { Suggestion } from \"@copilotkitnext/core\";\nimport { Message } from \"@ag-ui/core\";\nimport { twMerge } from \"tailwind-merge\";\nimport {\n StickToBottom,\n useStickToBottom,\n useStickToBottomContext,\n} from \"use-stick-to-bottom\";\nimport { ChevronDown } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\nimport {\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport { useKeyboardHeight } from \"@/hooks/use-keyboard-height\";\n\n// Height of the feather gradient overlay (h-24 = 6rem = 96px)\nconst FEATHER_HEIGHT = 96;\n\n// Forward declaration for WelcomeScreen component type\nexport type WelcomeScreenProps = WithSlots<\n {\n welcomeMessage: React.FC<React.HTMLAttributes<HTMLDivElement>>;\n },\n {\n input: React.ReactElement;\n suggestionView: React.ReactElement;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\nexport type CopilotChatViewProps = WithSlots<\n {\n messageView: typeof CopilotChatMessageView;\n scrollView: typeof CopilotChatView.ScrollView;\n input: typeof CopilotChatInput;\n suggestionView: typeof CopilotChatSuggestionView;\n },\n {\n messages?: Message[];\n autoScroll?: boolean;\n isRunning?: boolean;\n suggestions?: Suggestion[];\n suggestionLoadingIndexes?: ReadonlyArray<number>;\n onSelectSuggestion?: (suggestion: Suggestion, index: number) => void;\n welcomeScreen?: SlotValue<React.FC<WelcomeScreenProps>> | boolean;\n // Input behavior props\n onSubmitMessage?: (value: string) => void;\n onStop?: () => void;\n inputMode?: CopilotChatInputMode;\n inputValue?: string;\n onInputChange?: (value: string) => void;\n onStartTranscribe?: () => void;\n onCancelTranscribe?: () => void;\n onFinishTranscribe?: () => void;\n onFinishTranscribeWithAudio?: (audioBlob: Blob) => Promise<void>;\n /**\n * @deprecated Use the `input` slot's `disclaimer` prop instead:\n * ```tsx\n * <CopilotChat input={{ disclaimer: MyDisclaimer }} />\n * ```\n */\n disclaimer?: SlotValue<React.FC<React.HTMLAttributes<HTMLDivElement>>>;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\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 // Deprecated — forwarded to input slot\n disclaimer,\n children,\n className,\n ...props\n}: CopilotChatViewProps) {\n const inputContainerRef = useRef<HTMLDivElement>(null);\n const [inputContainerHeight, setInputContainerHeight] = useState(0);\n const [isResizing, setIsResizing] = useState(false);\n const resizeTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n\n // Track keyboard state for mobile\n const { isKeyboardOpen, keyboardHeight, availableHeight } =\n useKeyboardHeight();\n\n // Track input container height changes\n useEffect(() => {\n const element = inputContainerRef.current;\n if (!element) return;\n\n const resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const newHeight = entry.contentRect.height;\n\n // Update height and set resizing state\n setInputContainerHeight((prevHeight) => {\n if (newHeight !== prevHeight) {\n setIsResizing(true);\n\n // Clear existing timeout\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n\n // Set isResizing to false after a short delay\n resizeTimeoutRef.current = setTimeout(() => {\n setIsResizing(false);\n }, 250);\n\n return newHeight;\n }\n return prevHeight;\n });\n }\n });\n\n resizeObserver.observe(element);\n\n // Set initial height\n setInputContainerHeight(element.offsetHeight);\n\n return () => {\n resizeObserver.disconnect();\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n };\n }, []);\n\n const BoundMessageView = renderSlot(messageView, CopilotChatMessageView, {\n messages,\n isRunning,\n });\n\n const BoundInput = renderSlot(input, CopilotChatInput, {\n onSubmitMessage,\n onStop,\n mode: inputMode,\n value: inputValue,\n onChange: onInputChange,\n isRunning,\n onStartTranscribe,\n onCancelTranscribe,\n onFinishTranscribe,\n onFinishTranscribeWithAudio,\n positioning: \"absolute\",\n keyboardHeight: isKeyboardOpen ? keyboardHeight : 0,\n containerRef: inputContainerRef,\n showDisclaimer: true,\n ...(disclaimer !== undefined ? { disclaimer } : {}),\n } as CopilotChatInputProps);\n\n const hasSuggestions = Array.isArray(suggestions) && suggestions.length > 0;\n const BoundSuggestionView = hasSuggestions\n ? renderSlot(suggestionView, CopilotChatSuggestionView, {\n suggestions,\n loadingIndexes: suggestionLoadingIndexes,\n onSelectSuggestion,\n className: \"cpk:mb-3 cpk:lg:ml-4 cpk:lg:mr-4 cpk:ml-0 cpk:mr-0\",\n })\n : null;\n\n const BoundScrollView = renderSlot(scrollView, CopilotChatView.ScrollView, {\n autoScroll,\n inputContainerHeight,\n isResizing,\n children: (\n <div\n style={{\n paddingBottom: `${inputContainerHeight + FEATHER_HEIGHT + (hasSuggestions ? 4 : 32)}px`,\n }}\n >\n <div className=\"cpk:max-w-3xl cpk:mx-auto\">\n {BoundMessageView}\n {hasSuggestions ? (\n <div className=\"cpk:pl-0 cpk:pr-4 cpk:sm:px-0 cpk:mt-4\">\n {BoundSuggestionView}\n </div>\n ) : null}\n </div>\n </div>\n ),\n });\n\n // Welcome screen logic\n const isEmpty = messages.length === 0;\n // Type assertion needed because TypeScript doesn't fully propagate `| boolean` through WithSlots\n const welcomeScreenDisabled = (welcomeScreen as unknown) === false;\n const shouldShowWelcomeScreen = isEmpty && !welcomeScreenDisabled;\n\n if (shouldShowWelcomeScreen) {\n // Create a separate input for welcome screen with static positioning and disclaimer visible\n const BoundInputForWelcome = renderSlot(input, CopilotChatInput, {\n onSubmitMessage,\n onStop,\n mode: inputMode,\n value: inputValue,\n onChange: onInputChange,\n isRunning,\n onStartTranscribe,\n onCancelTranscribe,\n onFinishTranscribe,\n onFinishTranscribeWithAudio,\n 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 const BoundWelcomeScreen = renderSlot(\n welcomeScreenSlot,\n CopilotChatView.WelcomeScreen,\n {\n input: BoundInputForWelcome,\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 className={twMerge(\n \"cpk:relative cpk:h-full cpk:flex cpk:flex-col\",\n className,\n )}\n {...props}\n >\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 className={twMerge(\"cpk:relative cpk:h-full\", className)}\n {...props}\n >\n {BoundScrollView}\n\n {BoundInput}\n </div>\n );\n}\n\nexport namespace CopilotChatView {\n // Inner component that has access to StickToBottom context\n const ScrollContent: React.FC<{\n children: React.ReactNode;\n scrollToBottomButton?: SlotValue<\n React.FC<React.ButtonHTMLAttributes<HTMLButtonElement>>\n >;\n feather?: SlotValue<React.FC<React.HTMLAttributes<HTMLDivElement>>>;\n inputContainerHeight: number;\n isResizing: boolean;\n }> = ({\n children,\n scrollToBottomButton,\n feather,\n inputContainerHeight,\n isResizing,\n }) => {\n const { isAtBottom, scrollToBottom } = useStickToBottomContext();\n\n const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});\n\n return (\n <>\n <StickToBottom.Content\n className=\"cpk:overflow-y-scroll cpk:overflow-x-hidden\"\n style={{ flex: \"1 1 0%\", minHeight: 0 }}\n >\n <div className=\"cpk:px-4 cpk:sm:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6\">\n {children}\n </div>\n </StickToBottom.Content>\n\n {/* Feather gradient overlay */}\n {BoundFeather}\n\n {/* Scroll to bottom button - hidden during resize */}\n {!isAtBottom && !isResizing && (\n <div\n className=\"cpk:absolute cpk:inset-x-0 cpk:flex cpk:justify-center cpk:z-30 cpk:pointer-events-none\"\n style={{\n bottom: `${inputContainerHeight + FEATHER_HEIGHT + 16}px`,\n }}\n >\n {renderSlot(\n scrollToBottomButton,\n CopilotChatView.ScrollToBottomButton,\n {\n onClick: () => scrollToBottom(),\n },\n )}\n </div>\n )}\n </>\n );\n };\n\n export const ScrollView: React.FC<\n React.HTMLAttributes<HTMLDivElement> & {\n autoScroll?: boolean;\n scrollToBottomButton?: SlotValue<\n React.FC<React.ButtonHTMLAttributes<HTMLButtonElement>>\n >;\n feather?: SlotValue<React.FC<React.HTMLAttributes<HTMLDivElement>>>;\n inputContainerHeight?: number;\n isResizing?: boolean;\n }\n > = ({\n children,\n autoScroll = true,\n scrollToBottomButton,\n feather,\n inputContainerHeight = 0,\n isResizing = false,\n className,\n ...props\n }) => {\n const [hasMounted, setHasMounted] = useState(false);\n const { scrollRef, contentRef, scrollToBottom } = useStickToBottom();\n const [showScrollButton, setShowScrollButton] = useState(false);\n\n useEffect(() => {\n setHasMounted(true);\n }, []);\n\n // Monitor scroll position for non-autoscroll mode\n useEffect(() => {\n if (autoScroll) return; // Skip for autoscroll mode\n\n const scrollElement = scrollRef.current;\n if (!scrollElement) return;\n\n const checkScroll = () => {\n const atBottom =\n scrollElement.scrollHeight -\n scrollElement.scrollTop -\n scrollElement.clientHeight <\n 10;\n setShowScrollButton(!atBottom);\n };\n\n checkScroll();\n scrollElement.addEventListener(\"scroll\", checkScroll);\n\n // Also check on resize\n const resizeObserver = new ResizeObserver(checkScroll);\n resizeObserver.observe(scrollElement);\n\n return () => {\n scrollElement.removeEventListener(\"scroll\", checkScroll);\n resizeObserver.disconnect();\n };\n }, [scrollRef, autoScroll]);\n\n if (!hasMounted) {\n return (\n <div className=\"cpk:h-full cpk:max-h-full cpk:flex cpk:flex-col cpk:min-h-0 cpk:overflow-y-scroll cpk:overflow-x-hidden\">\n <div className=\"cpk:px-4 cpk:sm:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6\">\n {children}\n </div>\n </div>\n );\n }\n\n // When autoScroll is false, we don't use StickToBottom\n if (!autoScroll) {\n const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});\n\n return (\n <div\n ref={scrollRef}\n className={cn(\n \"cpk:h-full cpk:max-h-full cpk:flex cpk:flex-col cpk:min-h-0 cpk:overflow-y-scroll cpk:overflow-x-hidden cpk:relative\",\n className,\n )}\n {...props}\n >\n <div\n ref={contentRef}\n className=\"cpk:px-4 cpk:sm:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6\"\n >\n {children}\n </div>\n\n {/* Feather gradient overlay */}\n {BoundFeather}\n\n {/* Scroll to bottom button for manual mode */}\n {showScrollButton && !isResizing && (\n <div\n className=\"cpk:absolute cpk:inset-x-0 cpk:flex cpk:justify-center cpk:z-30 cpk:pointer-events-none\"\n style={{\n bottom: `${inputContainerHeight + FEATHER_HEIGHT + 16}px`,\n }}\n >\n {renderSlot(\n scrollToBottomButton,\n CopilotChatView.ScrollToBottomButton,\n {\n onClick: () => scrollToBottom(),\n },\n )}\n </div>\n )}\n </div>\n );\n }\n\n return (\n <StickToBottom\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 resize=\"smooth\"\n initial=\"smooth\"\n {...props}\n >\n <ScrollContent\n scrollToBottomButton={scrollToBottomButton}\n feather={feather}\n inputContainerHeight={inputContainerHeight}\n isResizing={isResizing}\n >\n {children}\n </ScrollContent>\n </StickToBottom>\n );\n };\n\n export const ScrollToBottomButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, ...props }) => (\n <Button\n data-testid=\"copilot-scroll-to-bottom\"\n variant=\"outline\"\n size=\"sm\"\n className={twMerge(\n \"cpk:rounded-full cpk:w-10 cpk:h-10 cpk:p-0 cpk:pointer-events-auto\",\n \"cpk:bg-white cpk:dark:bg-gray-900\",\n \"cpk:shadow-lg cpk:border cpk:border-gray-200 cpk:dark:border-gray-700\",\n \"cpk:hover:bg-gray-50 cpk:dark:hover:bg-gray-800\",\n \"cpk:flex cpk:items-center cpk:justify-center cpk:cursor-pointer\",\n className,\n )}\n {...props}\n >\n <ChevronDown className=\"cpk:w-4 cpk:h-4 cpk:text-gray-600 cpk:dark:text-white\" />\n </Button>\n );\n\n export const Feather: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n className,\n style,\n ...props\n }) => (\n <div\n className={cn(\n \"cpk:absolute cpk:bottom-0 cpk:left-0 cpk:right-4 cpk:h-24 cpk:pointer-events-none cpk:z-10 cpk:bg-gradient-to-t\",\n \"cpk:from-white cpk:via-white cpk:to-transparent\",\n \"cpk:dark:from-[rgb(33,33,33)] cpk:dark:via-[rgb(33,33,33)]\",\n className,\n )}\n style={style}\n {...props}\n />\n );\n\n export const WelcomeMessage: React.FC<\n React.HTMLAttributes<HTMLDivElement>\n > = ({ className, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n\n return (\n <h1\n className={cn(\n \"cpk:text-xl cpk:sm:text-2xl cpk:font-medium cpk:text-foreground cpk:text-center\",\n className,\n )}\n {...props}\n >\n {labels.welcomeMessageText}\n </h1>\n );\n };\n\n export const WelcomeScreen: React.FC<WelcomeScreenProps> = ({\n welcomeMessage,\n input,\n suggestionView,\n className,\n children,\n ...props\n }) => {\n // Render the welcomeMessage slot internally\n const BoundWelcomeMessage = renderSlot(\n welcomeMessage,\n CopilotChatView.WelcomeMessage,\n {},\n );\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n welcomeMessage: BoundWelcomeMessage,\n input,\n suggestionView,\n className,\n ...props,\n })}\n </div>\n );\n }\n\n return (\n <div\n data-testid=\"copilot-welcome-screen\"\n className={cn(\n \"cpk:flex-1 cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:px-4\",\n className,\n )}\n {...props}\n >\n <div className=\"cpk:w-full cpk:max-w-3xl cpk:flex cpk:flex-col cpk:items-center\">\n {/* Welcome message */}\n <div className=\"cpk:mb-6\">{BoundWelcomeMessage}</div>\n\n {/* Input */}\n <div className=\"cpk:w-full\">{input}</div>\n\n {/* Suggestions */}\n <div className=\"cpk:mt-4 cpk:flex cpk:justify-center\">\n {suggestionView}\n </div>\n </div>\n </div>\n );\n };\n}\n\nexport default CopilotChatView;\n","import type { CopilotKitCoreReact } from \"./react-core\";\nimport {\n TranscriptionErrorCode,\n type TranscriptionErrorResponse,\n} from \"@copilotkitnext/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 { useSuggestions } from \"@/hooks/use-suggestions\";\nimport { CopilotChatView, CopilotChatViewProps } from \"./CopilotChatView\";\nimport { CopilotChatInputMode } from \"./CopilotChatInput\";\nimport {\n CopilotChatConfigurationProvider,\n CopilotChatLabels,\n useCopilotChatConfiguration,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport {\n DEFAULT_AGENT_ID,\n randomUUID,\n TranscriptionErrorCode,\n} from \"@copilotkitnext/shared\";\nimport { Suggestion, CopilotKitCoreErrorCode } from \"@copilotkitnext/core\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { merge } from \"ts-deepmerge\";\nimport { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport { AbstractAgent, AGUIConnectNotImplementedError } from \"@ag-ui/client\";\nimport { renderSlot, SlotValue } from \"@/lib/slots\";\nimport {\n transcribeAudio,\n TranscriptionError,\n} from \"@/lib/transcription-client\";\n\nexport type CopilotChatProps = Omit<\n CopilotChatViewProps,\n | \"messages\"\n | \"isRunning\"\n | \"suggestions\"\n | \"suggestionLoadingIndexes\"\n | \"onSelectSuggestion\"\n> & {\n agentId?: string;\n threadId?: string;\n labels?: Partial<CopilotChatLabels>;\n chatView?: SlotValue<typeof CopilotChatView>;\n};\nexport function CopilotChat({\n agentId,\n threadId,\n labels,\n chatView,\n ...props\n}: CopilotChatProps) {\n // Check for existing configuration provider\n const existingConfig = useCopilotChatConfiguration();\n\n // Apply priority: props > existing config > defaults\n const resolvedAgentId =\n agentId ?? existingConfig?.agentId ?? DEFAULT_AGENT_ID;\n const resolvedThreadId = useMemo(\n () => threadId ?? existingConfig?.threadId ?? randomUUID(),\n [threadId, existingConfig?.threadId],\n );\n\n const { agent } = useAgent({ agentId: resolvedAgentId });\n const { copilotkit } = useCopilotKit();\n const { suggestions: autoSuggestions } = useSuggestions({\n agentId: resolvedAgentId,\n });\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 // Check if transcription is enabled\n const isTranscriptionEnabled = copilotkit.audioFileTranscriptionEnabled;\n\n // Check if browser supports MediaRecorder\n const isMediaRecorderSupported =\n typeof window !== \"undefined\" && typeof MediaRecorder !== \"undefined\";\n\n const {\n messageView: providedMessageView,\n suggestionView: providedSuggestionView,\n onStop: providedStopHandler,\n ...restProps\n } = props;\n\n useEffect(() => {\n const connect = async (agent: AbstractAgent) => {\n try {\n await copilotkit.connectAgent({ agent });\n } catch (error) {\n if (error instanceof AGUIConnectNotImplementedError) {\n // connect not implemented, ignore\n } else {\n throw error;\n }\n }\n };\n agent.threadId = resolvedThreadId;\n connect(agent);\n return () => {};\n }, [resolvedThreadId, agent, copilotkit, resolvedAgentId]);\n\n const onSubmitInput = useCallback(\n async (value: string) => {\n agent.addMessage({\n id: randomUUID(),\n role: \"user\",\n content: value,\n });\n // Clear input after submitting\n setInputValue(\"\");\n try {\n await copilotkit.runAgent({ agent });\n } catch (error) {\n console.error(\"CopilotChat: runAgent failed\", error);\n }\n },\n [agent, copilotkit],\n );\n\n const handleSelectSuggestion = useCallback(\n async (suggestion: Suggestion) => {\n agent.addMessage({\n id: randomUUID(),\n role: \"user\",\n content: suggestion.message,\n });\n\n try {\n await copilotkit.runAgent({ agent });\n } catch (error) {\n console.error(\n \"CopilotChat: runAgent failed after selecting suggestion\",\n error,\n );\n }\n },\n [agent, copilotkit],\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 }, [agent, copilotkit]);\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 [copilotkit],\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 const mergedProps = merge(\n {\n isRunning: agent.isRunning,\n suggestions: autoSuggestions,\n onSelectSuggestion: handleSelectSuggestion,\n suggestionView: providedSuggestionView,\n },\n {\n ...restProps,\n ...(typeof providedMessageView === \"string\"\n ? { messageView: { className: providedMessageView } }\n : providedMessageView !== undefined\n ? { messageView: providedMessageView }\n : {}),\n },\n );\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 new reference when content actually changes\n // (agent.messages is mutated in place, so we need a new reference for React to detect changes)\n\n const messages = useMemo(\n () => [...agent.messages],\n [JSON.stringify(agent.messages)],\n );\n\n const finalProps = merge(mergedProps, {\n messages,\n // Input behavior props\n onSubmitMessage: onSubmitInput,\n onStop: effectiveStopHandler,\n inputMode: effectiveMode,\n inputValue,\n onInputChange: setInputValue,\n // Only provide transcription handlers if feature is available\n onStartTranscribe: showTranscription ? handleStartTranscribe : undefined,\n onCancelTranscribe: showTranscription ? handleCancelTranscribe : undefined,\n onFinishTranscribe: showTranscription ? handleFinishTranscribe : undefined,\n onFinishTranscribeWithAudio: showTranscription\n ? handleFinishTranscribeWithAudio\n : undefined,\n }) as CopilotChatViewProps;\n\n // Always create a provider with merged values\n // This ensures priority: props > existing config > defaults\n const RenderedChatView = renderSlot(chatView, CopilotChatView, finalProps);\n\n return (\n <CopilotChatConfigurationProvider\n agentId={resolvedAgentId}\n threadId={resolvedThreadId}\n labels={labels}\n >\n {transcriptionError && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100px\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n backgroundColor: \"#ef4444\",\n color: \"white\",\n padding: \"8px 16px\",\n borderRadius: \"8px\",\n fontSize: \"14px\",\n zIndex: 50,\n }}\n >\n {transcriptionError}\n </div>\n )}\n {RenderedChatView}\n </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 \"cpk:fixed cpk:bottom-6 cpk:right-6 cpk:z-[1100] cpk:flex cpk:h-14 cpk:w-14 cpk:items-center cpk:justify-center\",\n \"cpk:rounded-full cpk:border cpk:border-primary cpk:bg-primary cpk:text-primary-foreground\",\n \"cpk:shadow-sm cpk:transition-all cpk:duration-200 cpk:ease-out\",\n \"cpk:hover:scale-[1.04] cpk:hover:shadow-md\",\n \"cpk:cursor-pointer\",\n \"cpk:active:scale-[0.96]\",\n \"cpk:focus-visible:outline-none cpk:focus-visible:ring-2 cpk:focus-visible:ring-primary/50 cpk:focus-visible:ring-offset-2 cpk:focus-visible:ring-offset-background\",\n \"cpk:disabled:pointer-events-none cpk:disabled:opacity-60\",\n);\n\nexport const CopilotChatToggleButton = React.forwardRef<\n HTMLButtonElement,\n CopilotChatToggleButtonProps\n>(function CopilotChatToggleButton(\n { openIcon, closeIcon, className, ...buttonProps },\n ref,\n) {\n const { onClick, type, disabled, ...restProps } = buttonProps;\n\n const configuration = useCopilotChatConfiguration();\n const labels = configuration?.labels ?? CopilotChatDefaultLabels;\n\n const [fallbackOpen, setFallbackOpen] = useState(false);\n\n const isOpen = configuration?.isModalOpen ?? fallbackOpen;\n const setModalOpen = configuration?.setModalOpen ?? setFallbackOpen;\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n if (disabled) {\n return;\n }\n\n if (onClick) {\n onClick(event);\n }\n\n if (event.defaultPrevented) {\n return;\n }\n\n const nextOpen = !isOpen;\n setModalOpen(nextOpen);\n };\n\n const renderedOpenIcon = renderSlot(openIcon, DefaultOpenIcon, {\n className: \"cpk:h-6 cpk:w-6\",\n \"aria-hidden\": true,\n focusable: false,\n });\n\n const renderedCloseIcon = renderSlot(closeIcon, DefaultCloseIcon, {\n className: \"cpk:h-6 cpk:w-6\",\n \"aria-hidden\": true,\n focusable: false,\n });\n\n const openIconElement = (\n <span\n aria-hidden=\"true\"\n data-slot=\"chat-toggle-button-open-icon\"\n className={ICON_WRAPPER_BASE}\n style={{\n ...ICON_TRANSITION_STYLE,\n opacity: isOpen ? 0 : 1,\n transform: `scale(${isOpen ? 0.75 : 1}) rotate(${isOpen ? 90 : 0}deg)`,\n }}\n >\n {renderedOpenIcon}\n </span>\n );\n\n const closeIconElement = (\n <span\n aria-hidden=\"true\"\n data-slot=\"chat-toggle-button-close-icon\"\n className={ICON_WRAPPER_BASE}\n style={{\n ...ICON_TRANSITION_STYLE,\n opacity: isOpen ? 1 : 0,\n transform: `scale(${isOpen ? 1 : 0.75}) rotate(${isOpen ? 0 : -90}deg)`,\n }}\n >\n {renderedCloseIcon}\n </span>\n );\n\n return (\n <button\n ref={ref}\n type={type ?? \"button\"}\n data-copilotkit\n data-testid=\"copilot-chat-toggle\"\n data-slot=\"chat-toggle-button\"\n data-state={isOpen ? \"open\" : \"closed\"}\n className={cn(BUTTON_BASE_CLASSES, className)}\n aria-label={\n isOpen ? labels.chatToggleCloseLabel : labels.chatToggleOpenLabel\n }\n aria-pressed={isOpen}\n disabled={disabled}\n onClick={handleClick}\n {...restProps}\n >\n {openIconElement}\n {closeIconElement}\n </button>\n );\n});\nCopilotChatToggleButton.displayName = \"CopilotChatToggleButton\";\nexport default CopilotChatToggleButton;\n\nexport {\n DefaultOpenIcon as CopilotChatToggleButtonOpenIcon,\n DefaultCloseIcon as CopilotChatToggleButtonCloseIcon,\n};\n","import React, { useCallback } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\nimport {\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport { renderSlot, WithSlots } from \"@/lib/slots\";\nimport { X } from \"lucide-react\";\n\ntype HeaderSlots = {\n titleContent: typeof CopilotModalHeader.Title;\n closeButton: typeof CopilotModalHeader.CloseButton;\n};\n\ntype HeaderRestProps = {\n title?: string;\n} & Omit<React.HTMLAttributes<HTMLDivElement>, \"children\">;\n\nexport type CopilotModalHeaderProps = WithSlots<HeaderSlots, HeaderRestProps>;\n\nexport function CopilotModalHeader({\n title,\n titleContent,\n closeButton,\n children,\n className,\n ...rest\n}: CopilotModalHeaderProps) {\n const configuration = useCopilotChatConfiguration();\n\n const fallbackTitle =\n configuration?.labels.modalHeaderTitle ??\n CopilotChatDefaultLabels.modalHeaderTitle;\n const resolvedTitle = title ?? fallbackTitle;\n\n const handleClose = useCallback(() => {\n configuration?.setModalOpen?.(false);\n }, [configuration]);\n\n const BoundTitle = renderSlot(titleContent, CopilotModalHeader.Title, {\n children: resolvedTitle,\n });\n\n const BoundCloseButton = renderSlot(\n closeButton,\n CopilotModalHeader.CloseButton,\n {\n onClick: handleClose,\n },\n );\n\n if (children) {\n return children({\n titleContent: BoundTitle,\n closeButton: BoundCloseButton,\n title: resolvedTitle,\n ...rest,\n });\n }\n\n return (\n <header\n data-testid=\"copilot-modal-header\"\n data-slot=\"copilot-modal-header\"\n className={cn(\n \"cpk:flex cpk:items-center cpk:justify-between cpk:border-b cpk:border-border cpk:px-4 cpk:py-4\",\n \"cpk:bg-background/95 cpk:backdrop-blur cpk:supports-[backdrop-filter]:bg-background/80\",\n className,\n )}\n {...rest}\n >\n <div className=\"cpk:flex cpk:w-full cpk:items-center cpk:gap-2\">\n <div className=\"cpk:flex-1\" aria-hidden=\"true\" />\n <div className=\"cpk:flex cpk:flex-1 cpk:justify-center cpk:text-center\">\n {BoundTitle}\n </div>\n <div className=\"cpk:flex cpk:flex-1 cpk:justify-end\">\n {BoundCloseButton}\n </div>\n </div>\n </header>\n );\n}\n\nCopilotModalHeader.displayName = \"CopilotModalHeader\";\n\nexport namespace CopilotModalHeader {\n export const Title: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n children,\n className,\n ...props\n }) => (\n <div\n data-testid=\"copilot-header-title\"\n className={cn(\n \"cpk:w-full cpk:text-base cpk:font-medium cpk:leading-none cpk:tracking-tight cpk:text-foreground\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n );\n\n export const CloseButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, ...props }) => (\n <button\n type=\"button\"\n data-testid=\"copilot-close-button\"\n className={cn(\n \"cpk:inline-flex cpk:size-8 cpk:items-center cpk:justify-center cpk:rounded-full cpk:text-muted-foreground cpk:transition cpk:cursor-pointer\",\n \"cpk:hover:bg-muted cpk:hover:text-foreground cpk:focus-visible:outline-none cpk:focus-visible:ring-2 cpk:focus-visible:ring-ring\",\n className,\n )}\n aria-label=\"Close\"\n {...props}\n >\n <X className=\"cpk:h-4 cpk:w-4\" aria-hidden=\"true\" />\n </button>\n );\n}\n\nCopilotModalHeader.Title.displayName = \"CopilotModalHeader.Title\";\nCopilotModalHeader.CloseButton.displayName = \"CopilotModalHeader.CloseButton\";\n\nexport default CopilotModalHeader;\n","import React, { useEffect, useLayoutEffect, useRef, useState } from \"react\";\n\nimport CopilotChatView, {\n CopilotChatViewProps,\n WelcomeScreenProps,\n} from \"./CopilotChatView\";\nimport {\n CopilotChatConfigurationProvider,\n useCopilotChatConfiguration,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport CopilotChatToggleButton from \"./CopilotChatToggleButton\";\nimport { cn } from \"@/lib/utils\";\nimport { CopilotModalHeader } from \"./CopilotModalHeader\";\nimport { renderSlot, SlotValue } from \"@/lib/slots\";\n\nconst DEFAULT_SIDEBAR_WIDTH = 480;\nconst SIDEBAR_TRANSITION_MS = 260;\n\nexport type CopilotSidebarViewProps = CopilotChatViewProps & {\n header?: SlotValue<typeof CopilotModalHeader>;\n toggleButton?: SlotValue<typeof CopilotChatToggleButton>;\n width?: number | string;\n defaultOpen?: boolean;\n};\n\nexport function CopilotSidebarView({\n header,\n toggleButton,\n width,\n defaultOpen = true,\n ...props\n}: CopilotSidebarViewProps) {\n return (\n <CopilotChatConfigurationProvider isModalDefaultOpen={defaultOpen}>\n <CopilotSidebarViewInternal\n header={header}\n toggleButton={toggleButton}\n width={width}\n {...props}\n />\n </CopilotChatConfigurationProvider>\n );\n}\n\nfunction CopilotSidebarViewInternal({\n header,\n toggleButton,\n width,\n ...props\n}: Omit<CopilotSidebarViewProps, \"defaultOpen\">) {\n const configuration = useCopilotChatConfiguration();\n\n const isSidebarOpen = configuration?.isModalOpen ?? false;\n\n const sidebarRef = useRef<HTMLDivElement | null>(null);\n const [sidebarWidth, setSidebarWidth] = useState<number | string>(\n width ?? DEFAULT_SIDEBAR_WIDTH,\n );\n\n // Helper to convert width to CSS value\n const widthToCss = (w: number | string): string => {\n return typeof w === \"number\" ? `${w}px` : w;\n };\n\n // Helper to extract numeric value for body margin (only works with px values)\n const widthToMargin = (w: number | string): string => {\n if (typeof w === \"number\") {\n return `${w}px`;\n }\n // For string values, use as-is (assumes valid CSS unit)\n return w;\n };\n\n useEffect(() => {\n // If width is explicitly provided, don't measure\n if (width !== undefined) {\n return;\n }\n\n if (typeof window === \"undefined\") {\n return;\n }\n\n const element = sidebarRef.current;\n if (!element) {\n return;\n }\n\n const updateWidth = () => {\n const rect = element.getBoundingClientRect();\n if (rect.width > 0) {\n setSidebarWidth(rect.width);\n }\n };\n\n updateWidth();\n\n if (typeof ResizeObserver !== \"undefined\") {\n const observer = new ResizeObserver(() => updateWidth());\n observer.observe(element);\n return () => observer.disconnect();\n }\n\n window.addEventListener(\"resize\", updateWidth);\n return () => window.removeEventListener(\"resize\", updateWidth);\n }, [width]);\n\n // Manage body margin for sidebar docking (desktop only).\n // useLayoutEffect runs before paint, so defaultOpen={true} never causes a\n // visible layout shift — the margin is already applied on the first frame.\n const hasMounted = useRef(false);\n\n useLayoutEffect(() => {\n if (\n typeof window === \"undefined\" ||\n typeof window.matchMedia !== \"function\"\n )\n return;\n if (!window.matchMedia(\"(min-width: 768px)\").matches) return;\n\n if (isSidebarOpen) {\n if (hasMounted.current) {\n document.body.style.transition = `margin-inline-end ${SIDEBAR_TRANSITION_MS}ms ease`;\n }\n document.body.style.marginInlineEnd = widthToMargin(sidebarWidth);\n } else if (hasMounted.current) {\n document.body.style.transition = `margin-inline-end ${SIDEBAR_TRANSITION_MS}ms ease`;\n document.body.style.marginInlineEnd = \"\";\n }\n\n hasMounted.current = true;\n\n return () => {\n document.body.style.marginInlineEnd = \"\";\n document.body.style.transition = \"\";\n };\n }, [isSidebarOpen, sidebarWidth]);\n\n const headerElement = renderSlot(header, CopilotModalHeader, {});\n const toggleButtonElement = renderSlot(\n toggleButton,\n CopilotChatToggleButton,\n {},\n );\n\n return (\n <>\n {toggleButtonElement}\n <aside\n ref={sidebarRef}\n data-copilotkit\n data-testid=\"copilot-sidebar\"\n data-copilot-sidebar\n className={cn(\n \"cpk:fixed cpk:right-0 cpk:top-0 cpk:z-[1200] cpk:flex\",\n // Height with dvh fallback and safe area support\n \"cpk:h-[100vh] cpk:h-[100dvh] cpk:max-h-screen\",\n // Responsive width: full on mobile, custom on desktop\n \"cpk:w-full\",\n \"cpk:border-l cpk:border-border cpk:bg-background cpk:text-foreground cpk:shadow-xl\",\n \"cpk:transition-transform cpk:duration-300 cpk:ease-out\",\n isSidebarOpen\n ? \"cpk:translate-x-0\"\n : \"cpk:translate-x-full cpk:pointer-events-none\",\n )}\n style={\n {\n // Use CSS custom property for responsive width\n [\"--sidebar-width\" as string]: widthToCss(sidebarWidth),\n // Safe area insets for iOS\n paddingTop: \"env(safe-area-inset-top)\",\n paddingBottom: \"env(safe-area-inset-bottom)\",\n } as React.CSSProperties\n }\n aria-hidden={!isSidebarOpen}\n aria-label=\"Copilot chat sidebar\"\n role=\"complementary\"\n >\n <div className=\"cpk:flex cpk:h-full cpk:w-full cpk:flex-col cpk:overflow-hidden\">\n {headerElement}\n <div className=\"cpk:flex-1 cpk:overflow-hidden\" data-sidebar-chat>\n <CopilotChatView {...props} />\n </div>\n </div>\n </aside>\n </>\n );\n}\n\nCopilotSidebarView.displayName = \"CopilotSidebarView\";\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotSidebarView {\n /**\n * Sidebar-specific welcome screen layout:\n * - Suggestions at the top\n * - Welcome message in the middle\n * - Input fixed at the bottom (like normal chat)\n */\n export const WelcomeScreen: React.FC<WelcomeScreenProps> = ({\n welcomeMessage,\n input,\n suggestionView,\n className,\n children,\n ...props\n }) => {\n // Render the welcomeMessage slot internally\n const BoundWelcomeMessage = renderSlot(\n welcomeMessage,\n CopilotChatView.WelcomeMessage,\n {},\n );\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n welcomeMessage: BoundWelcomeMessage,\n input,\n suggestionView,\n className,\n ...props,\n })}\n </div>\n );\n }\n\n return (\n <div\n className={cn(\"cpk:h-full cpk:flex cpk:flex-col\", className)}\n {...props}\n >\n {/* Welcome message - centered vertically */}\n <div className=\"cpk:flex-1 cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:px-4\">\n {BoundWelcomeMessage}\n </div>\n\n {/* Suggestions and input at bottom */}\n <div className=\"cpk:px-8 cpk:pb-4\">\n <div className=\"cpk:max-w-3xl cpk:mx-auto\">\n {/* Suggestions above input */}\n <div className=\"cpk:mb-4 cpk:flex cpk:justify-center\">\n {suggestionView}\n </div>\n {input}\n </div>\n </div>\n </div>\n );\n };\n}\n\nexport default CopilotSidebarView;\n","import React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport CopilotChatView, {\n CopilotChatViewProps,\n WelcomeScreenProps,\n} from \"./CopilotChatView\";\nimport CopilotChatToggleButton from \"./CopilotChatToggleButton\";\nimport { CopilotModalHeader } from \"./CopilotModalHeader\";\nimport { cn } from \"@/lib/utils\";\nimport { renderSlot, SlotValue } from \"@/lib/slots\";\nimport {\n CopilotChatConfigurationProvider,\n CopilotChatDefaultLabels,\n useCopilotChatConfiguration,\n} from \"@/providers/CopilotChatConfigurationProvider\";\n\nconst DEFAULT_POPUP_WIDTH = 420;\nconst DEFAULT_POPUP_HEIGHT = 560;\n\nexport type CopilotPopupViewProps = CopilotChatViewProps & {\n header?: SlotValue<typeof CopilotModalHeader>;\n toggleButton?: SlotValue<typeof CopilotChatToggleButton>;\n width?: number | string;\n height?: number | string;\n clickOutsideToClose?: boolean;\n defaultOpen?: boolean;\n};\n\nconst dimensionToCss = (\n value: number | string | undefined,\n fallback: number,\n): string => {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return `${value}px`;\n }\n\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value;\n }\n\n return `${fallback}px`;\n};\n\nexport function CopilotPopupView({\n header,\n toggleButton,\n width,\n height,\n clickOutsideToClose,\n defaultOpen = true,\n className,\n ...restProps\n}: CopilotPopupViewProps) {\n return (\n <CopilotChatConfigurationProvider isModalDefaultOpen={defaultOpen}>\n <CopilotPopupViewInternal\n header={header}\n toggleButton={toggleButton}\n width={width}\n height={height}\n clickOutsideToClose={clickOutsideToClose}\n className={className}\n {...restProps}\n />\n </CopilotChatConfigurationProvider>\n );\n}\n\nfunction CopilotPopupViewInternal({\n header,\n toggleButton,\n width,\n height,\n clickOutsideToClose,\n className,\n ...restProps\n}: Omit<CopilotPopupViewProps, \"defaultOpen\">) {\n const configuration = useCopilotChatConfiguration();\n const isPopupOpen = configuration?.isModalOpen ?? false;\n const setModalOpen = configuration?.setModalOpen;\n const labels = configuration?.labels ?? CopilotChatDefaultLabels;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const [isRendered, setIsRendered] = useState(isPopupOpen);\n const [isAnimatingOut, setIsAnimatingOut] = useState(false);\n\n useEffect(() => {\n if (isPopupOpen) {\n setIsRendered(true);\n setIsAnimatingOut(false);\n return;\n }\n\n if (!isRendered) {\n return;\n }\n\n setIsAnimatingOut(true);\n const timeout = setTimeout(() => {\n setIsRendered(false);\n setIsAnimatingOut(false);\n }, 200);\n\n return () => clearTimeout(timeout);\n }, [isPopupOpen, isRendered]);\n\n useEffect(() => {\n if (!isPopupOpen) {\n return;\n }\n\n if (typeof window === \"undefined\") {\n return;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n setModalOpen?.(false);\n }\n };\n\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [isPopupOpen, setModalOpen]);\n\n useEffect(() => {\n if (!isPopupOpen) {\n return;\n }\n\n const focusTimer = setTimeout(() => {\n const container = containerRef.current;\n // Don't steal focus if something inside the popup (like the input) is already focused\n if (container && !container.contains(document.activeElement)) {\n container.focus({ preventScroll: true });\n }\n }, 200);\n\n return () => clearTimeout(focusTimer);\n }, [isPopupOpen]);\n\n useEffect(() => {\n if (!isPopupOpen || !clickOutsideToClose) {\n return;\n }\n\n if (typeof document === \"undefined\") {\n return;\n }\n\n const handlePointerDown = (event: PointerEvent) => {\n const target = event.target as Node | null;\n if (!target) {\n return;\n }\n\n const container = containerRef.current;\n if (container?.contains(target)) {\n return;\n }\n\n const toggleButton = document.querySelector(\n \"[data-slot='chat-toggle-button']\",\n );\n if (toggleButton && toggleButton.contains(target)) {\n return;\n }\n\n setModalOpen?.(false);\n };\n\n document.addEventListener(\"pointerdown\", handlePointerDown);\n return () => document.removeEventListener(\"pointerdown\", handlePointerDown);\n }, [isPopupOpen, clickOutsideToClose, setModalOpen]);\n\n const headerElement = useMemo(\n () => renderSlot(header, CopilotModalHeader, {}),\n [header],\n );\n const toggleButtonElement = useMemo(\n () => renderSlot(toggleButton, CopilotChatToggleButton, {}),\n [toggleButton],\n );\n\n const resolvedWidth = dimensionToCss(width, DEFAULT_POPUP_WIDTH);\n const resolvedHeight = dimensionToCss(height, DEFAULT_POPUP_HEIGHT);\n\n const popupStyle = useMemo(\n () =>\n ({\n \"--copilot-popup-width\": resolvedWidth,\n \"--copilot-popup-height\": resolvedHeight,\n \"--copilot-popup-max-width\": \"calc(100vw - 3rem)\",\n \"--copilot-popup-max-height\": \"calc(100dvh - 7.5rem)\",\n paddingTop: \"env(safe-area-inset-top)\",\n paddingBottom: \"env(safe-area-inset-bottom)\",\n paddingLeft: \"env(safe-area-inset-left)\",\n paddingRight: \"env(safe-area-inset-right)\",\n }) as React.CSSProperties,\n [resolvedHeight, resolvedWidth],\n );\n\n const popupAnimationClass =\n isPopupOpen && !isAnimatingOut\n ? \"cpk:pointer-events-auto cpk:translate-y-0 cpk:opacity-100 cpk:md:scale-100\"\n : \"cpk:pointer-events-none cpk:translate-y-4 cpk:opacity-0 cpk:md:translate-y-5 cpk:md:scale-[0.95]\";\n\n const popupContent = isRendered ? (\n <div\n data-copilotkit\n className={cn(\n \"cpk:fixed cpk:inset-0 cpk:z-[1200] cpk:flex cpk:max-w-full cpk:flex-col cpk:items-stretch\",\n \"cpk:md:inset-auto cpk:md:bottom-24 cpk:md:right-6 cpk:md:items-end cpk:md:gap-4\",\n )}\n >\n <div\n ref={containerRef}\n tabIndex={-1}\n role=\"dialog\"\n aria-label={labels.modalHeaderTitle}\n data-testid=\"copilot-popup\"\n data-copilot-popup\n className={cn(\n \"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, { useMemo } from \"react\";\n\nimport { CopilotChat, CopilotChatProps } from \"./CopilotChat\";\nimport CopilotChatView, { CopilotChatViewProps } from \"./CopilotChatView\";\nimport {\n CopilotSidebarView,\n CopilotSidebarViewProps,\n} from \"./CopilotSidebarView\";\n\nexport type CopilotSidebarProps = Omit<CopilotChatProps, \"chatView\"> & {\n header?: CopilotSidebarViewProps[\"header\"];\n toggleButton?: CopilotSidebarViewProps[\"toggleButton\"];\n defaultOpen?: boolean;\n width?: number | string;\n};\n\nexport function CopilotSidebar({\n header,\n toggleButton,\n defaultOpen,\n width,\n ...chatProps\n}: CopilotSidebarProps) {\n const SidebarViewOverride = useMemo(() => {\n const Component: React.FC<CopilotChatViewProps> = (viewProps) => {\n const {\n header: viewHeader,\n toggleButton: viewToggleButton,\n width: viewWidth,\n defaultOpen: viewDefaultOpen,\n ...restProps\n } = viewProps as CopilotSidebarViewProps;\n\n return (\n <CopilotSidebarView\n {...(restProps as CopilotSidebarViewProps)}\n header={header ?? viewHeader}\n toggleButton={toggleButton ?? viewToggleButton}\n width={width ?? viewWidth}\n defaultOpen={defaultOpen ?? viewDefaultOpen}\n />\n );\n };\n\n return Object.assign(Component, CopilotChatView);\n }, [header, toggleButton, width, defaultOpen]);\n\n return (\n <CopilotChat\n welcomeScreen={CopilotSidebarView.WelcomeScreen}\n {...chatProps}\n chatView={SidebarViewOverride}\n />\n );\n}\n\nCopilotSidebar.displayName = \"CopilotSidebar\";\n\nexport default CopilotSidebar;\n","import React, { useMemo } from \"react\";\n\nimport { CopilotChat, CopilotChatProps } from \"./CopilotChat\";\nimport CopilotChatView, { CopilotChatViewProps } from \"./CopilotChatView\";\nimport CopilotPopupView, { CopilotPopupViewProps } from \"./CopilotPopupView\";\n\nexport type CopilotPopupProps = Omit<CopilotChatProps, \"chatView\"> & {\n header?: CopilotPopupViewProps[\"header\"];\n toggleButton?: CopilotPopupViewProps[\"toggleButton\"];\n defaultOpen?: boolean;\n width?: CopilotPopupViewProps[\"width\"];\n height?: CopilotPopupViewProps[\"height\"];\n clickOutsideToClose?: CopilotPopupViewProps[\"clickOutsideToClose\"];\n};\n\nexport function CopilotPopup({\n header,\n toggleButton,\n defaultOpen,\n width,\n height,\n clickOutsideToClose,\n ...chatProps\n}: CopilotPopupProps) {\n const PopupViewOverride = useMemo(() => {\n const Component: React.FC<CopilotChatViewProps> = (viewProps) => {\n const {\n header: viewHeader,\n toggleButton: viewToggleButton,\n width: viewWidth,\n height: viewHeight,\n clickOutsideToClose: viewClickOutsideToClose,\n defaultOpen: viewDefaultOpen,\n ...restProps\n } = viewProps as CopilotPopupViewProps;\n\n return (\n <CopilotPopupView\n {...(restProps as CopilotPopupViewProps)}\n header={header ?? viewHeader}\n toggleButton={toggleButton ?? viewToggleButton}\n width={width ?? viewWidth}\n height={height ?? viewHeight}\n clickOutsideToClose={clickOutsideToClose ?? viewClickOutsideToClose}\n defaultOpen={defaultOpen ?? viewDefaultOpen}\n />\n );\n };\n\n return Object.assign(Component, CopilotChatView);\n }, [clickOutsideToClose, header, toggleButton, height, width, defaultOpen]);\n\n return (\n <CopilotChat\n welcomeScreen={CopilotPopupView.WelcomeScreen}\n {...chatProps}\n chatView={PopupViewOverride}\n />\n );\n}\n\nCopilotPopup.displayName = \"CopilotPopup\";\n\nexport default CopilotPopup;\n","import { defineToolCallRenderer } from \"../types/defineToolCallRenderer\";\nimport { useState } from \"react\";\n\nexport const WildcardToolCallRender = defineToolCallRenderer({\n name: \"*\",\n render: ({ args, result, name, status }) => {\n const [isExpanded, setIsExpanded] = useState(false);\n\n const statusString = String(status) as\n | \"inProgress\"\n | \"executing\"\n | \"complete\";\n const isActive =\n statusString === \"inProgress\" || statusString === \"executing\";\n const isComplete = statusString === \"complete\";\n const statusStyles = isActive\n ? \"cpk:bg-amber-100 cpk:text-amber-800 cpk:dark:bg-amber-500/15 cpk:dark:text-amber-400\"\n : isComplete\n ? \"cpk:bg-emerald-100 cpk:text-emerald-800 cpk:dark:bg-emerald-500/15 cpk:dark:text-emerald-400\"\n : \"cpk:bg-zinc-100 cpk:text-zinc-800 cpk:dark:bg-zinc-700/40 cpk:dark:text-zinc-300\";\n\n return (\n <div className=\"cpk:mt-2 cpk:pb-2\">\n <div className=\"cpk:rounded-xl cpk:border cpk:border-zinc-200/60 cpk:dark:border-zinc-800/60 cpk:bg-white/70 cpk:dark:bg-zinc-900/50 cpk:shadow-sm cpk:backdrop-blur cpk:p-4\">\n <div\n className=\"cpk:flex cpk:items-center cpk:justify-between cpk:gap-3 cpk:cursor-pointer\"\n onClick={() => setIsExpanded(!isExpanded)}\n >\n <div className=\"cpk:flex cpk:items-center cpk:gap-2 cpk:min-w-0\">\n <svg\n className={`cpk:h-4 cpk:w-4 cpk:text-zinc-500 cpk:dark:text-zinc-400 cpk:transition-transform ${\n isExpanded ? \"cpk:rotate-90\" : \"\"\n }`}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n strokeWidth={2}\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M8.25 4.5l7.5 7.5-7.5 7.5\"\n />\n </svg>\n <span className=\"cpk:inline-block cpk:h-2 cpk:w-2 cpk:rounded-full cpk:bg-blue-500\" />\n <span className=\"cpk:truncate cpk:text-sm cpk:font-medium cpk:text-zinc-900 cpk:dark:text-zinc-100\">\n {name}\n </span>\n </div>\n <span\n className={`cpk:inline-flex cpk:items-center cpk:rounded-full cpk:px-2 cpk:py-1 cpk:text-xs cpk:font-medium ${statusStyles}`}\n >\n {String(status)}\n </span>\n </div>\n\n {isExpanded && (\n <div className=\"cpk:mt-3 cpk:grid cpk:gap-4\">\n <div>\n <div className=\"cpk:text-xs cpk:uppercase cpk:tracking-wide cpk:text-zinc-500 cpk:dark:text-zinc-400\">\n Arguments\n </div>\n <pre className=\"cpk:mt-2 cpk:max-h-64 cpk:overflow-auto cpk:rounded-md cpk:bg-zinc-50 cpk:dark:bg-zinc-800/60 cpk:p-3 cpk:text-xs cpk:leading-relaxed cpk:text-zinc-800 cpk:dark:text-zinc-200 cpk:whitespace-pre-wrap cpk:break-words\">\n {JSON.stringify(args ?? {}, null, 2)}\n </pre>\n </div>\n\n {result !== undefined && (\n <div>\n <div className=\"cpk:text-xs cpk:uppercase cpk:tracking-wide cpk:text-zinc-500 cpk:dark:text-zinc-400\">\n Result\n </div>\n <pre className=\"cpk:mt-2 cpk:max-h-64 cpk:overflow-auto cpk:rounded-md cpk:bg-zinc-50 cpk:dark:bg-zinc-800/60 cpk:p-3 cpk:text-xs cpk:leading-relaxed cpk:text-zinc-800 cpk:dark:text-zinc-200 cpk:whitespace-pre-wrap cpk:break-words\">\n {typeof result === \"string\"\n ? result\n : JSON.stringify(result, null, 2)}\n </pre>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n },\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.umd.js","names":["DEFAULT_AGENT_ID","twMerge","Slot","TooltipPrimitive","DropdownMenuPrimitive","ChevronRightIcon","React","Square","Loader2","ArrowUp","Mic","X","Check","Plus","React","z","CopilotKitCore","z","React","ToolCallStatus","DEFAULT_AGENT_ID","DEFAULT_AGENT_ID","EMPTY_DEPS","z","React","DEFAULT_AGENT_ID","CopilotKitCoreRuntimeConnectionStatus","ProxiedCopilotRuntimeAgent","DEFAULT_AGENT_ID","DEFAULT_AGENT_ID","React","Streamdown","Check","Copy","ThumbsUp","ThumbsDown","Volume2","RefreshCw","Check","Copy","Edit","ChevronLeft","ChevronRight","ChevronRight","Streamdown","React","Loader2","React","React","CopilotChatAssistantMessage","CopilotChatUserMessage","CopilotChatReasoningMessage","CopilotChatInput","StickToBottom","ChevronDown","TranscriptionErrorCode","DEFAULT_AGENT_ID","AGUIConnectNotImplementedError","TranscriptionErrorCode","MessageCircle","X","React","X","CopilotChatView","CopilotChatView","CopilotChatView","CopilotPopupView","CopilotChatView"],"sources":["../src/providers/CopilotChatConfigurationProvider.tsx","../src/lib/utils.ts","../src/components/ui/button.tsx","../src/components/ui/tooltip.tsx","../src/components/ui/dropdown-menu.tsx","../src/components/chat/CopilotChatAudioRecorder.tsx","../src/lib/slots.tsx","../src/components/chat/CopilotChatInput.tsx","../src/components/CopilotKitInspector.tsx","../src/components/MCPAppsActivityRenderer.tsx","../src/lib/react-core.ts","../src/providers/CopilotKitProvider.tsx","../src/hooks/use-render-tool-call.tsx","../src/hooks/use-render-custom-messages.tsx","../src/hooks/use-render-activity-message.tsx","../src/hooks/use-frontend-tool.tsx","../src/hooks/use-component.tsx","../src/types/defineToolCallRenderer.ts","../src/hooks/use-render-tool.tsx","../src/hooks/use-default-render-tool.tsx","../src/hooks/use-human-in-the-loop.tsx","../src/hooks/use-agent.tsx","../src/hooks/use-agent-context.tsx","../src/hooks/use-suggestions.tsx","../src/hooks/use-configure-suggestions.tsx","../src/hooks/use-interrupt.tsx","../src/components/chat/CopilotChatToolCallsView.tsx","../src/components/chat/CopilotChatAssistantMessage.tsx","../src/components/chat/CopilotChatUserMessage.tsx","../src/components/chat/CopilotChatReasoningMessage.tsx","../src/components/chat/CopilotChatSuggestionPill.tsx","../src/components/chat/CopilotChatSuggestionView.tsx","../src/components/chat/CopilotChatMessageView.tsx","../src/hooks/use-keyboard-height.tsx","../src/components/chat/CopilotChatView.tsx","../src/lib/transcription-client.ts","../src/components/chat/CopilotChat.tsx","../src/components/chat/CopilotChatToggleButton.tsx","../src/components/chat/CopilotModalHeader.tsx","../src/components/chat/CopilotSidebarView.tsx","../src/components/chat/CopilotPopupView.tsx","../src/components/chat/CopilotSidebar.tsx","../src/components/chat/CopilotPopup.tsx","../src/components/WildcardToolCallRender.tsx"],"sourcesContent":["import React, {\n createContext,\n useContext,\n ReactNode,\n useMemo,\n useState,\n} from \"react\";\nimport { DEFAULT_AGENT_ID, randomUUID } from \"@copilotkitnext/shared\";\n\n// Default labels\nexport const CopilotChatDefaultLabels = {\n chatInputPlaceholder: \"Type a message...\",\n chatInputToolbarStartTranscribeButtonLabel: \"Transcribe\",\n chatInputToolbarCancelTranscribeButtonLabel: \"Cancel\",\n chatInputToolbarFinishTranscribeButtonLabel: \"Finish\",\n chatInputToolbarAddButtonLabel: \"Add photos or files\",\n chatInputToolbarToolsButtonLabel: \"Tools\",\n assistantMessageToolbarCopyCodeLabel: \"Copy\",\n assistantMessageToolbarCopyCodeCopiedLabel: \"Copied\",\n assistantMessageToolbarCopyMessageLabel: \"Copy\",\n assistantMessageToolbarThumbsUpLabel: \"Good response\",\n assistantMessageToolbarThumbsDownLabel: \"Bad response\",\n assistantMessageToolbarReadAloudLabel: \"Read aloud\",\n assistantMessageToolbarRegenerateLabel: \"Regenerate\",\n userMessageToolbarCopyMessageLabel: \"Copy\",\n userMessageToolbarEditMessageLabel: \"Edit\",\n chatDisclaimerText:\n \"AI can make mistakes. Please verify important information.\",\n chatToggleOpenLabel: \"Open chat\",\n chatToggleCloseLabel: \"Close chat\",\n modalHeaderTitle: \"CopilotKit Chat\",\n welcomeMessageText: \"How can I help you today?\",\n};\n\nexport type CopilotChatLabels = typeof CopilotChatDefaultLabels;\n\n// Define the full configuration interface\nexport interface CopilotChatConfigurationValue {\n labels: CopilotChatLabels;\n agentId: string;\n threadId: string;\n isModalOpen: boolean;\n setModalOpen: (open: boolean) => void;\n}\n\n// Create the configuration context\nconst CopilotChatConfiguration =\n createContext<CopilotChatConfigurationValue | null>(null);\n\n// Provider props interface\nexport interface CopilotChatConfigurationProviderProps {\n children: ReactNode;\n labels?: Partial<CopilotChatLabels>;\n agentId?: string;\n threadId?: string;\n isModalDefaultOpen?: boolean;\n}\n\n// Provider component\nexport const CopilotChatConfigurationProvider: React.FC<\n CopilotChatConfigurationProviderProps\n> = ({ children, labels, agentId, threadId, isModalDefaultOpen }) => {\n const parentConfig = useContext(CopilotChatConfiguration);\n\n const mergedLabels: CopilotChatLabels = useMemo(\n () => ({\n ...CopilotChatDefaultLabels,\n ...(parentConfig?.labels ?? {}),\n ...(labels ?? {}),\n }),\n [labels, parentConfig?.labels],\n );\n\n const resolvedAgentId = agentId ?? parentConfig?.agentId ?? DEFAULT_AGENT_ID;\n\n const resolvedThreadId = useMemo(() => {\n if (threadId) {\n return threadId;\n }\n if (parentConfig?.threadId) {\n return parentConfig.threadId;\n }\n return randomUUID();\n }, [threadId, parentConfig?.threadId]);\n\n const resolvedDefaultOpen = isModalDefaultOpen ?? true;\n\n const [internalModalOpen, setInternalModalOpen] =\n useState<boolean>(resolvedDefaultOpen);\n\n const resolvedIsModalOpen = parentConfig?.isModalOpen ?? internalModalOpen;\n const resolvedSetModalOpen =\n parentConfig?.setModalOpen ?? setInternalModalOpen;\n\n const configurationValue: CopilotChatConfigurationValue = useMemo(\n () => ({\n labels: mergedLabels,\n agentId: resolvedAgentId,\n threadId: resolvedThreadId,\n isModalOpen: resolvedIsModalOpen,\n setModalOpen: resolvedSetModalOpen,\n }),\n [\n mergedLabels,\n resolvedAgentId,\n resolvedThreadId,\n resolvedIsModalOpen,\n resolvedSetModalOpen,\n ],\n );\n\n return (\n <CopilotChatConfiguration.Provider value={configurationValue}>\n {children}\n </CopilotChatConfiguration.Provider>\n );\n};\n\n// Hook to use the full configuration\nexport const useCopilotChatConfiguration =\n (): CopilotChatConfigurationValue | null => {\n const configuration = useContext(CopilotChatConfiguration);\n return configuration;\n };\n","import { clsx, type ClassValue } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge({ prefix: \"cpk\" });\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst buttonVariants = cva(\n \"cpk:inline-flex cpk:items-center cpk:justify-center cpk:gap-2 cpk:whitespace-nowrap cpk:rounded-md cpk:text-sm cpk:font-medium cpk:transition-all cpk:disabled:pointer-events-none cpk:disabled:opacity-50 cpk:[&_svg]:pointer-events-none cpk:[&_svg:not([class*='size-'])]:size-4 cpk:shrink-0 cpk:[&_svg]:shrink-0 cpk:outline-none cpk:focus-visible:border-ring cpk:focus-visible:ring-ring/50 cpk:focus-visible:ring-[3px] cpk:aria-invalid:ring-destructive/20 cpk:dark:aria-invalid:ring-destructive/40 cpk:aria-invalid:border-destructive\",\n {\n variants: {\n variant: {\n default:\n \"cpk:bg-primary cpk:text-primary-foreground cpk:shadow-xs cpk:hover:bg-primary/90\",\n destructive:\n \"cpk:bg-destructive cpk:text-white cpk:shadow-xs cpk:hover:bg-destructive/90 cpk:focus-visible:ring-destructive/20 cpk:dark:focus-visible:ring-destructive/40 cpk:dark:bg-destructive/60\",\n outline:\n \"cpk:border cpk:bg-background cpk:shadow-xs cpk:hover:bg-accent cpk:hover:text-accent-foreground cpk:dark:bg-input/30 cpk:dark:border-input cpk:dark:hover:bg-input/50\",\n secondary:\n \"cpk:bg-secondary cpk:text-secondary-foreground cpk:shadow-xs cpk:hover:bg-secondary/80\",\n ghost:\n \"cpk:hover:bg-accent cpk:hover:text-accent-foreground cpk:dark:hover:bg-accent/50 cpk:cursor-pointer\",\n link: \"cpk:text-primary cpk:underline-offset-4 cpk:hover:underline\",\n assistantMessageToolbarButton: [\n \"cpk:cursor-pointer\",\n // Background and text\n \"cpk:p-0 cpk:text-[rgb(93,93,93)] cpk:hover:bg-[#E8E8E8]\",\n // Dark mode - lighter gray for better contrast\n \"cpk:dark:text-[rgb(243,243,243)] cpk:dark:hover:bg-[#303030]\",\n // Shape and sizing\n \"cpk:h-8 cpk:w-8\",\n // Interactions\n \"cpk:transition-colors\",\n // Hover states\n \"cpk:hover:text-[rgb(93,93,93)]\",\n \"cpk:dark:hover:text-[rgb(243,243,243)]\",\n ],\n chatInputToolbarPrimary: [\n \"cpk:cursor-pointer\",\n // Background and text\n \"cpk:bg-black cpk:text-white\",\n // Dark mode\n \"cpk:dark:bg-white cpk:dark:text-black cpk:dark:focus-visible:outline-white\",\n // Shape and sizing\n \"cpk:rounded-full\",\n // Interactions\n \"cpk:transition-colors\",\n // Focus states\n \"cpk:focus:outline-none\",\n // Hover states\n \"cpk:hover:opacity-70 cpk:disabled:hover:opacity-100\",\n // Disabled states\n \"cpk:disabled:cursor-not-allowed cpk:disabled:bg-[#00000014] cpk:disabled:text-[rgb(13,13,13)]\",\n \"cpk:dark:disabled:bg-[#454545] cpk:dark:disabled:text-white \",\n ],\n chatInputToolbarSecondary: [\n \"cpk:cursor-pointer\",\n // Background and text\n \"cpk:bg-transparent cpk:text-[#444444]\",\n // Dark mode\n \"cpk:dark:text-white cpk:dark:border-[#404040]\",\n // Shape and sizing\n \"cpk:rounded-full\",\n // Interactions\n \"cpk:transition-colors\",\n // Focus states\n \"cpk:focus:outline-none\",\n // Hover states\n \"cpk:hover:bg-[#f8f8f8] cpk:hover:text-[#333333]\",\n \"cpk:dark:hover:bg-[#404040] cpk:dark:hover:text-[#FFFFFF]\",\n // Disabled states\n \"cpk:disabled:cursor-not-allowed cpk:disabled:opacity-50\",\n \"cpk:disabled:hover:bg-transparent cpk:disabled:hover:text-[#444444]\",\n \"cpk:dark:disabled:hover:bg-transparent cpk:dark:disabled:hover:text-[#CCCCCC]\",\n ],\n },\n size: {\n default: \"cpk:h-9 cpk:px-4 cpk:py-2 cpk:has-[>svg]:px-3\",\n sm: \"cpk:h-8 cpk:rounded-md cpk:gap-1.5 cpk:px-3 cpk:has-[>svg]:px-2.5\",\n lg: \"cpk:h-10 cpk:rounded-md cpk:px-6 cpk:has-[>svg]:px-4\",\n icon: \"cpk:size-9\",\n chatInputToolbarIcon: [\n // Shape and sizing\n \"cpk:h-9 cpk:w-9 cpk:rounded-full\",\n ],\n chatInputToolbarIconLabel: [\n // Shape and sizing\n \"cpk:h-9 cpk:px-3 cpk:rounded-full\",\n // Layout\n \"cpk:gap-2\",\n // Typography\n \"cpk:font-normal\",\n ],\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nfunction Button({\n className,\n variant,\n size,\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n }) {\n const Comp = asChild ? Slot : \"button\";\n\n return (\n <Comp\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n );\n}\n\nexport { Button, buttonVariants };\n","import * as React from \"react\";\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction TooltipProvider({\n delayDuration = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delayDuration={delayDuration}\n {...props}\n />\n );\n}\n\nfunction Tooltip({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n return (\n <TooltipProvider>\n <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n </TooltipProvider>\n );\n}\n\nfunction TooltipTrigger({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />;\n}\n\nfunction TooltipContent({\n className,\n sideOffset = 0,\n children,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-copilotkit\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n \"cpk:bg-primary cpk:text-primary-foreground cpk:animate-in cpk:fade-in-0 cpk:zoom-in-95 cpk:data-[state=closed]:animate-out cpk:data-[state=closed]:fade-out-0 cpk:data-[state=closed]:zoom-out-95 cpk:data-[side=bottom]:slide-in-from-top-2 cpk:data-[side=left]:slide-in-from-right-2 cpk:data-[side=right]:slide-in-from-left-2 cpk:data-[side=top]:slide-in-from-bottom-2 cpk:z-50 cpk:w-fit cpk:origin-(--radix-tooltip-content-transform-origin) cpk:rounded-md cpk:px-3 cpk:py-1.5 cpk:text-xs cpk:text-balance\",\n className,\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"cpk:bg-primary cpk:fill-primary cpk:z-50 cpk:size-2.5 cpk:translate-y-[calc(-50%_-_2px)] cpk:rotate-45 cpk:rounded-[2px]\" />\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n );\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\";\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction DropdownMenu({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />;\n}\n\nfunction DropdownMenuPortal({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n return (\n <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n );\n}\n\nfunction DropdownMenuTrigger({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n return (\n <DropdownMenuPrimitive.Trigger\n data-slot=\"dropdown-menu-trigger\"\n {...props}\n />\n );\n}\n\nfunction DropdownMenuContent({\n className,\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-copilotkit\n data-slot=\"dropdown-menu-content\"\n sideOffset={sideOffset}\n className={cn(\n \"cpk:bg-popover cpk:text-popover-foreground cpk:data-[state=open]:animate-in cpk:data-[state=closed]:animate-out cpk:data-[state=closed]:fade-out-0 cpk:data-[state=open]:fade-in-0 cpk:data-[state=closed]:zoom-out-95 cpk:data-[state=open]:zoom-in-95 cpk:data-[side=bottom]:slide-in-from-top-2 cpk:data-[side=left]:slide-in-from-right-2 cpk:data-[side=right]:slide-in-from-left-2 cpk:data-[side=top]:slide-in-from-bottom-2 cpk:z-50 cpk:max-h-(--radix-dropdown-menu-content-available-height) cpk:min-w-[8rem] cpk:origin-(--radix-dropdown-menu-content-transform-origin) cpk:overflow-x-hidden cpk:overflow-y-auto cpk:rounded-md cpk:border cpk:p-1 cpk:shadow-md\",\n className,\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n );\n}\n\nfunction DropdownMenuGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n return (\n <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n );\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean;\n variant?: \"default\" | \"destructive\";\n}) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"cpk:focus:bg-accent cpk:focus:text-accent-foreground cpk:data-[variant=destructive]:text-destructive cpk:data-[variant=destructive]:focus:bg-destructive/10 cpk:dark:data-[variant=destructive]:focus:bg-destructive/20 cpk:data-[variant=destructive]:focus:text-destructive cpk:data-[variant=destructive]:*:[svg]:!text-destructive cpk:[&_svg:not([class*='text-'])]:text-muted-foreground cpk:relative cpk:flex cpk:cursor-default cpk:items-center cpk:gap-2 cpk:rounded-sm cpk:px-2 cpk:py-1.5 cpk:text-sm cpk:outline-hidden cpk:select-none cpk:data-[disabled]:pointer-events-none cpk:data-[disabled]:opacity-50 cpk:data-[inset]:pl-8 cpk:[&_svg]:pointer-events-none cpk:[&_svg]:shrink-0 cpk:[&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n className={cn(\n \"cpk:focus:bg-accent cpk:focus:text-accent-foreground cpk:relative cpk:flex cpk:cursor-default cpk:items-center cpk:gap-2 cpk:rounded-sm cpk:py-1.5 cpk:pr-2 cpk:pl-8 cpk:text-sm cpk:outline-hidden cpk:select-none cpk:data-[disabled]:pointer-events-none cpk:data-[disabled]:opacity-50 cpk:[&_svg]:pointer-events-none cpk:[&_svg]:shrink-0 cpk:[&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n checked={checked}\n {...props}\n >\n <span className=\"cpk:pointer-events-none cpk:absolute cpk:left-2 cpk:flex cpk:size-3.5 cpk:items-center cpk:justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CheckIcon className=\"cpk:size-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n );\n}\n\nfunction DropdownMenuRadioGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n return (\n <DropdownMenuPrimitive.RadioGroup\n data-slot=\"dropdown-menu-radio-group\"\n {...props}\n />\n );\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n return (\n <DropdownMenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n className={cn(\n \"cpk:focus:bg-accent cpk:focus:text-accent-foreground cpk:relative cpk:flex cpk:cursor-default cpk:items-center cpk:gap-2 cpk:rounded-sm cpk:py-1.5 cpk:pr-2 cpk:pl-8 cpk:text-sm cpk:outline-hidden cpk:select-none cpk:data-[disabled]:pointer-events-none cpk:data-[disabled]:opacity-50 cpk:[&_svg]:pointer-events-none cpk:[&_svg]:shrink-0 cpk:[&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n {...props}\n >\n <span className=\"cpk:pointer-events-none cpk:absolute cpk:left-2 cpk:flex cpk:size-3.5 cpk:items-center cpk:justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CircleIcon className=\"cpk:size-2 cpk:fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n );\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\n \"cpk:px-2 cpk:py-1.5 cpk:text-sm cpk:font-medium cpk:data-[inset]:pl-8\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn(\"cpk:bg-border cpk:-mx-1 cpk:my-1 cpk:h-px\", className)}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\n \"cpk:text-muted-foreground cpk:ml-auto cpk:text-xs cpk:tracking-widest\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSub({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />;\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"cpk:focus:bg-accent cpk:focus:text-accent-foreground cpk:data-[state=open]:bg-accent cpk:data-[state=open]:text-accent-foreground cpk:flex cpk:cursor-default cpk:items-center cpk:rounded-sm cpk:px-2 cpk:py-1.5 cpk:text-sm cpk:outline-hidden cpk:select-none cpk:data-[inset]:pl-8\",\n className,\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"cpk:ml-auto cpk:size-4\" />\n </DropdownMenuPrimitive.SubTrigger>\n );\n}\n\nfunction DropdownMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\n \"cpk:bg-popover cpk:text-popover-foreground cpk:data-[state=open]:animate-in cpk:data-[state=closed]:animate-out cpk:data-[state=closed]:fade-out-0 cpk:data-[state=open]:fade-in-0 cpk:data-[state=closed]:zoom-out-95 cpk:data-[state=open]:zoom-in-95 cpk:data-[side=bottom]:slide-in-from-top-2 cpk:data-[side=left]:slide-in-from-right-2 cpk:data-[side=right]:slide-in-from-left-2 cpk:data-[side=top]:slide-in-from-bottom-2 cpk:z-50 cpk:min-w-[8rem] cpk:origin-(--radix-dropdown-menu-content-transform-origin) cpk:overflow-hidden cpk:rounded-md cpk:border cpk:p-1 cpk:shadow-lg\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport {\n DropdownMenu,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n};\n","import {\n useRef,\n useEffect,\n useImperativeHandle,\n forwardRef,\n useCallback,\n useState,\n} from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\n/** Finite-state machine for every recorder implementation */\nexport type AudioRecorderState = \"idle\" | \"recording\" | \"processing\";\n\n/** Error subclass so callers can `instanceof`-guard recorder failures */\nexport class AudioRecorderError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"AudioRecorderError\";\n }\n}\n\nexport interface AudioRecorderRef {\n state: AudioRecorderState;\n start: () => Promise<void>;\n stop: () => Promise<Blob>;\n dispose: () => void;\n}\n\nexport const CopilotChatAudioRecorder = forwardRef<\n AudioRecorderRef,\n React.HTMLAttributes<HTMLDivElement>\n>((props, ref) => {\n const { className, ...divProps } = props;\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n // Recording state\n const [recorderState, setRecorderState] =\n useState<AudioRecorderState>(\"idle\");\n const mediaRecorderRef = useRef<MediaRecorder | null>(null);\n const audioChunksRef = useRef<Blob[]>([]);\n const streamRef = useRef<MediaStream | null>(null);\n const analyserRef = useRef<AnalyserNode | null>(null);\n const audioContextRef = useRef<AudioContext | null>(null);\n const animationIdRef = useRef<number | null>(null);\n\n // Amplitude history buffer for scrolling waveform\n const amplitudeHistoryRef = useRef<number[]>([]);\n const frameCountRef = useRef<number>(0);\n const scrollOffsetRef = useRef<number>(0);\n const smoothedAmplitudeRef = useRef<number>(0);\n const fadeOpacityRef = useRef<number>(0);\n\n // Clean up all resources\n const cleanup = useCallback(() => {\n if (animationIdRef.current) {\n cancelAnimationFrame(animationIdRef.current);\n animationIdRef.current = null;\n }\n if (\n mediaRecorderRef.current &&\n mediaRecorderRef.current.state !== \"inactive\"\n ) {\n try {\n mediaRecorderRef.current.stop();\n } catch {\n // Ignore errors during cleanup\n }\n }\n if (streamRef.current) {\n streamRef.current.getTracks().forEach((track) => track.stop());\n streamRef.current = null;\n }\n if (audioContextRef.current && audioContextRef.current.state !== \"closed\") {\n audioContextRef.current.close().catch(() => {\n // Ignore close errors\n });\n audioContextRef.current = null;\n }\n mediaRecorderRef.current = null;\n analyserRef.current = null;\n audioChunksRef.current = [];\n amplitudeHistoryRef.current = [];\n frameCountRef.current = 0;\n scrollOffsetRef.current = 0;\n smoothedAmplitudeRef.current = 0;\n fadeOpacityRef.current = 0;\n }, []);\n\n // Start recording\n const start = useCallback(async () => {\n if (recorderState !== \"idle\") {\n throw new AudioRecorderError(\"Recorder is already active\");\n }\n\n try {\n // Request microphone access\n const stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n streamRef.current = stream;\n\n // Set up audio context for visualization\n const audioContext = new AudioContext();\n audioContextRef.current = audioContext;\n const source = audioContext.createMediaStreamSource(stream);\n const analyser = audioContext.createAnalyser();\n analyser.fftSize = 2048; // Higher resolution for time-domain waveform\n source.connect(analyser);\n analyserRef.current = analyser;\n\n // Determine best MIME type for recording\n const mimeType = MediaRecorder.isTypeSupported(\"audio/webm;codecs=opus\")\n ? \"audio/webm;codecs=opus\"\n : MediaRecorder.isTypeSupported(\"audio/webm\")\n ? \"audio/webm\"\n : MediaRecorder.isTypeSupported(\"audio/mp4\")\n ? \"audio/mp4\"\n : \"\";\n\n const options: MediaRecorderOptions = mimeType ? { mimeType } : {};\n const mediaRecorder = new MediaRecorder(stream, options);\n mediaRecorderRef.current = mediaRecorder;\n audioChunksRef.current = [];\n\n mediaRecorder.ondataavailable = (event) => {\n if (event.data.size > 0) {\n audioChunksRef.current.push(event.data);\n }\n };\n\n // Start recording with timeslice to collect data periodically\n mediaRecorder.start(100);\n setRecorderState(\"recording\");\n } catch (error) {\n cleanup();\n if (error instanceof Error && error.name === \"NotAllowedError\") {\n throw new AudioRecorderError(\"Microphone permission denied\");\n }\n if (error instanceof Error && error.name === \"NotFoundError\") {\n throw new AudioRecorderError(\"No microphone found\");\n }\n throw new AudioRecorderError(\n error instanceof Error ? error.message : \"Failed to start recording\",\n );\n }\n }, [recorderState, cleanup]);\n\n // Stop recording and return audio blob\n const stop = useCallback((): Promise<Blob> => {\n return new Promise((resolve, reject) => {\n const mediaRecorder = mediaRecorderRef.current;\n if (!mediaRecorder || recorderState !== \"recording\") {\n reject(new AudioRecorderError(\"No active recording\"));\n return;\n }\n\n setRecorderState(\"processing\");\n\n mediaRecorder.onstop = () => {\n const mimeType = mediaRecorder.mimeType || \"audio/webm\";\n const audioBlob = new Blob(audioChunksRef.current, { type: mimeType });\n\n // Clean up but keep the blob\n cleanup();\n setRecorderState(\"idle\");\n resolve(audioBlob);\n };\n\n mediaRecorder.onerror = () => {\n cleanup();\n setRecorderState(\"idle\");\n reject(new AudioRecorderError(\"Recording failed\"));\n };\n\n mediaRecorder.stop();\n });\n }, [recorderState, cleanup]);\n\n // Calculate RMS amplitude from time-domain data\n const calculateAmplitude = (dataArray: Uint8Array): number => {\n let sum = 0;\n for (let i = 0; i < dataArray.length; i++) {\n // Normalize to -1 to 1 range (128 is center/silence)\n const sample = (dataArray[i] ?? 128) / 128 - 1;\n sum += sample * sample;\n }\n return Math.sqrt(sum / dataArray.length);\n };\n\n // Canvas rendering with animation\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n\n // Configuration\n const barWidth = 2;\n const barGap = 1;\n const barSpacing = barWidth + barGap;\n const scrollSpeed = 1 / 3; // Pixels per frame\n\n const draw = () => {\n const rect = canvas.getBoundingClientRect();\n const dpr = window.devicePixelRatio || 1;\n\n // Update canvas dimensions if container resized\n if (\n canvas.width !== rect.width * dpr ||\n canvas.height !== rect.height * dpr\n ) {\n canvas.width = rect.width * dpr;\n canvas.height = rect.height * dpr;\n ctx.scale(dpr, dpr);\n }\n\n // Calculate how many bars fit in the canvas (plus extra for smooth scrolling)\n const maxBars = Math.floor(rect.width / barSpacing) + 2;\n\n // Get current amplitude if recording\n if (analyserRef.current && recorderState === \"recording\") {\n // Pre-fill history with zeros on first frame so line is visible immediately\n if (amplitudeHistoryRef.current.length === 0) {\n amplitudeHistoryRef.current = new Array(maxBars).fill(0);\n }\n\n // Fade in the waveform smoothly\n if (fadeOpacityRef.current < 1) {\n fadeOpacityRef.current = Math.min(1, fadeOpacityRef.current + 0.03);\n }\n\n // Smooth scrolling - increment offset every frame\n scrollOffsetRef.current += scrollSpeed;\n\n // Sample amplitude every frame for smoothing\n const bufferLength = analyserRef.current.fftSize;\n const dataArray = new Uint8Array(bufferLength);\n analyserRef.current.getByteTimeDomainData(dataArray);\n const rawAmplitude = calculateAmplitude(dataArray);\n\n // Smoothing: gradual attack and decay\n const attackSpeed = 0.12; // Smooth rise\n const decaySpeed = 0.08; // Smooth fade out\n const speed =\n rawAmplitude > smoothedAmplitudeRef.current\n ? attackSpeed\n : decaySpeed;\n smoothedAmplitudeRef.current +=\n (rawAmplitude - smoothedAmplitudeRef.current) * speed;\n\n // When offset reaches a full bar width, add a new sample and reset offset\n if (scrollOffsetRef.current >= barSpacing) {\n scrollOffsetRef.current -= barSpacing;\n amplitudeHistoryRef.current.push(smoothedAmplitudeRef.current);\n\n // Trim history to fit canvas\n if (amplitudeHistoryRef.current.length > maxBars) {\n amplitudeHistoryRef.current =\n amplitudeHistoryRef.current.slice(-maxBars);\n }\n }\n }\n\n // Clear canvas\n ctx.clearRect(0, 0, rect.width, rect.height);\n\n // Get current foreground color\n const computedStyle = getComputedStyle(canvas);\n ctx.fillStyle = computedStyle.color;\n ctx.globalAlpha = fadeOpacityRef.current;\n\n const centerY = rect.height / 2;\n const maxAmplitude = rect.height / 2 - 2; // Leave some padding\n\n const history = amplitudeHistoryRef.current;\n\n // Only draw when recording (history has data)\n if (history.length > 0) {\n const offset = scrollOffsetRef.current;\n const edgeFadeWidth = 12; // Pixels to fade at each edge\n\n for (let i = 0; i < history.length; i++) {\n const amplitude = history[i] ?? 0;\n // Scale amplitude (RMS is typically 0-0.5 for normal speech)\n const scaledAmplitude = Math.min(amplitude * 4, 1);\n const barHeight = Math.max(2, scaledAmplitude * maxAmplitude * 2);\n\n // Position: right-aligned with smooth scroll offset\n const x = rect.width - (history.length - i) * barSpacing - offset;\n const y = centerY - barHeight / 2;\n\n // Only draw if visible\n if (x + barWidth > 0 && x < rect.width) {\n // Calculate edge fade opacity\n let edgeOpacity = 1;\n if (x < edgeFadeWidth) {\n // Fade out on left edge\n edgeOpacity = Math.max(0, x / edgeFadeWidth);\n } else if (x > rect.width - edgeFadeWidth) {\n // Fade in on right edge\n edgeOpacity = Math.max(0, (rect.width - x) / edgeFadeWidth);\n }\n\n ctx.globalAlpha = fadeOpacityRef.current * edgeOpacity;\n ctx.fillRect(x, y, barWidth, barHeight);\n }\n }\n }\n\n animationIdRef.current = requestAnimationFrame(draw);\n };\n\n draw();\n\n return () => {\n if (animationIdRef.current) {\n cancelAnimationFrame(animationIdRef.current);\n }\n };\n }, [recorderState]);\n\n // Cleanup on unmount\n useEffect(() => {\n return cleanup;\n }, [cleanup]);\n\n // Expose AudioRecorder API via ref\n useImperativeHandle(\n ref,\n () => ({\n get state() {\n return recorderState;\n },\n start,\n stop,\n dispose: cleanup,\n }),\n [recorderState, start, stop, cleanup],\n );\n\n return (\n <div\n className={twMerge(\"cpk:w-full cpk:py-3 cpk:px-5\", className)}\n {...divProps}\n >\n <canvas ref={canvasRef} className=\"cpk:block cpk:w-full cpk:h-[26px]\" />\n </div>\n );\n});\n\nCopilotChatAudioRecorder.displayName = \"CopilotChatAudioRecorder\";\n","import React from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\n/** Existing union (unchanged) */\nexport type SlotValue<C extends React.ComponentType<any>> =\n | C\n | string\n | Partial<React.ComponentProps<C>>;\n\n/**\n * Shallow equality comparison for objects.\n */\nexport function shallowEqual<T extends Record<string, unknown>>(\n obj1: T,\n obj2: T,\n): boolean {\n const keys1 = Object.keys(obj1);\n const keys2 = Object.keys(obj2);\n\n if (keys1.length !== keys2.length) return false;\n\n for (const key of keys1) {\n if (obj1[key] !== obj2[key]) return false;\n }\n\n return true;\n}\n\n/** Utility: concrete React elements for every slot */\ntype SlotElements<S> = { [K in keyof S]: React.ReactElement };\n\nexport type WithSlots<\n S extends Record<string, React.ComponentType<any>>,\n Rest = {},\n> = {\n /** Per‑slot overrides */\n [K in keyof S]?: SlotValue<S[K]>;\n} & {\n children?: (props: SlotElements<S> & Rest) => React.ReactNode;\n} & Omit<Rest, \"children\">;\n\n/**\n * Check if a value is a React component type (function, class, forwardRef, memo, etc.)\n */\nexport function isReactComponentType(\n value: unknown,\n): value is React.ComponentType<any> {\n if (typeof value === \"function\") {\n return true;\n }\n // forwardRef, memo, lazy have $$typeof but are not valid elements\n if (\n value &&\n typeof value === \"object\" &&\n \"$$typeof\" in value &&\n !React.isValidElement(value)\n ) {\n return true;\n }\n return false;\n}\n\n/**\n * Internal function to render a slot value as a React element (non-memoized).\n */\nfunction renderSlotElement(\n slot: SlotValue<React.ComponentType<any>> | undefined,\n DefaultComponent: React.ComponentType<any>,\n props: Record<string, unknown>,\n): React.ReactElement {\n if (typeof slot === \"string\") {\n // When slot is a string, treat it as a className and merge with existing className\n const existingClassName = props.className as string | undefined;\n return React.createElement(DefaultComponent, {\n ...props,\n className: twMerge(existingClassName, slot),\n });\n }\n\n // Check if slot is a React component type (function, forwardRef, memo, etc.)\n if (isReactComponentType(slot)) {\n return React.createElement(slot, props);\n }\n\n // If slot is a plain object (not a React element), treat it as props override\n if (slot && typeof slot === \"object\" && !React.isValidElement(slot)) {\n return React.createElement(DefaultComponent, {\n ...props,\n ...slot,\n });\n }\n\n return React.createElement(DefaultComponent, props);\n}\n\n/**\n * Internal memoized wrapper component for renderSlot.\n * Uses forwardRef to support ref forwarding.\n */\nconst MemoizedSlotWrapper = React.memo(\n React.forwardRef<unknown, any>(function MemoizedSlotWrapper(props, ref) {\n const { $slot, $component, ...rest } = props;\n const propsWithRef: Record<string, unknown> =\n ref !== null ? { ...rest, ref } : rest;\n return renderSlotElement($slot, $component, propsWithRef);\n }),\n (prev: any, next: any) => {\n // Compare slot and component references\n if (prev.$slot !== next.$slot) return false;\n if (prev.$component !== next.$component) return false;\n\n // Shallow compare remaining props (ref is handled separately by React)\n const { $slot: _ps, $component: _pc, ...prevRest } = prev;\n const { $slot: _ns, $component: _nc, ...nextRest } = next;\n return shallowEqual(\n prevRest as Record<string, unknown>,\n nextRest as Record<string, unknown>,\n );\n },\n);\n\n/**\n * Renders a slot value as a memoized React element.\n * Automatically prevents unnecessary re-renders using shallow prop comparison.\n * Supports ref forwarding.\n *\n * @example\n * renderSlot(customInput, CopilotChatInput, { onSubmit: handleSubmit })\n */\nexport function renderSlot<\n C extends React.ComponentType<any>,\n P = React.ComponentProps<C>,\n>(\n slot: SlotValue<C> | undefined,\n DefaultComponent: C,\n props: P,\n): React.ReactElement {\n return React.createElement(MemoizedSlotWrapper, {\n ...props,\n $slot: slot,\n $component: DefaultComponent,\n } as any);\n}\n","import React, {\n useState,\n useRef,\n KeyboardEvent,\n ChangeEvent,\n useEffect,\n useLayoutEffect,\n forwardRef,\n useImperativeHandle,\n useCallback,\n useMemo,\n} from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { Plus, Mic, ArrowUp, X, Check, Square, Loader2 } from \"lucide-react\";\n\nimport {\n CopilotChatLabels,\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n DropdownMenuSeparator,\n} from \"@/components/ui/dropdown-menu\";\n\nimport { CopilotChatAudioRecorder } from \"./CopilotChatAudioRecorder\";\nimport { renderSlot, WithSlots } from \"@/lib/slots\";\nimport { cn } from \"@/lib/utils\";\n\nexport type CopilotChatInputMode = \"input\" | \"transcribe\" | \"processing\";\n\nexport type ToolsMenuItem = {\n label: string;\n} & (\n | {\n action: () => void;\n items?: never;\n }\n | {\n action?: never;\n items: (ToolsMenuItem | \"-\")[];\n }\n);\n\ntype CopilotChatInputSlots = {\n textArea: typeof CopilotChatInput.TextArea;\n sendButton: typeof CopilotChatInput.SendButton;\n startTranscribeButton: typeof CopilotChatInput.StartTranscribeButton;\n cancelTranscribeButton: typeof CopilotChatInput.CancelTranscribeButton;\n finishTranscribeButton: typeof CopilotChatInput.FinishTranscribeButton;\n addMenuButton: typeof CopilotChatInput.AddMenuButton;\n audioRecorder: typeof CopilotChatAudioRecorder;\n disclaimer: typeof CopilotChatInput.Disclaimer;\n};\n\ntype CopilotChatInputRestProps = {\n mode?: CopilotChatInputMode;\n toolsMenu?: (ToolsMenuItem | \"-\")[];\n autoFocus?: boolean;\n onSubmitMessage?: (value: string) => void;\n onStop?: () => void;\n isRunning?: boolean;\n onStartTranscribe?: () => void;\n onCancelTranscribe?: () => void;\n onFinishTranscribe?: () => void;\n onFinishTranscribeWithAudio?: (audioBlob: Blob) => Promise<void>;\n onAddFile?: () => void;\n value?: string;\n onChange?: (value: string) => void;\n /** Positioning mode for the input container. Default: 'static' */\n positioning?: \"static\" | \"absolute\";\n /** Keyboard height in pixels for mobile keyboard handling */\n keyboardHeight?: number;\n /** Ref for the outer positioning container */\n containerRef?: React.Ref<HTMLDivElement>;\n /** Whether to show the disclaimer. Default: true for absolute positioning, false for static */\n showDisclaimer?: boolean;\n} & Omit<React.HTMLAttributes<HTMLDivElement>, \"onChange\">;\n\ntype CopilotChatInputBaseProps = WithSlots<\n CopilotChatInputSlots,\n CopilotChatInputRestProps\n>;\n\ntype CopilotChatInputChildrenArgs = CopilotChatInputBaseProps extends {\n children?: infer C;\n}\n ? C extends (props: infer P) => React.ReactNode\n ? P\n : never\n : never;\n\nexport type CopilotChatInputProps = Omit<\n CopilotChatInputBaseProps,\n \"children\"\n> & {\n children?: (props: CopilotChatInputChildrenArgs) => React.ReactNode;\n};\n\nconst SLASH_MENU_MAX_VISIBLE_ITEMS = 5;\nconst SLASH_MENU_ITEM_HEIGHT_PX = 40;\n\nexport function CopilotChatInput({\n mode = \"input\",\n onSubmitMessage,\n onStop,\n isRunning = false,\n onStartTranscribe,\n onCancelTranscribe,\n onFinishTranscribe,\n onFinishTranscribeWithAudio,\n onAddFile,\n onChange,\n value,\n toolsMenu,\n autoFocus = true,\n positioning = \"static\",\n keyboardHeight = 0,\n containerRef,\n showDisclaimer,\n textArea,\n sendButton,\n startTranscribeButton,\n cancelTranscribeButton,\n finishTranscribeButton,\n addMenuButton,\n audioRecorder,\n disclaimer,\n children,\n className,\n ...props\n}: CopilotChatInputProps) {\n const isControlled = value !== undefined;\n const [internalValue, setInternalValue] = useState<string>(() => value ?? \"\");\n\n useEffect(() => {\n if (!isControlled && value !== undefined) {\n setInternalValue(value);\n }\n }, [isControlled, value]);\n\n const resolvedValue = isControlled ? (value ?? \"\") : internalValue;\n\n const [layout, setLayout] = useState<\"compact\" | \"expanded\">(\"compact\");\n const ignoreResizeRef = useRef(false);\n const resizeEvaluationRafRef = useRef<number | null>(null);\n const isExpanded = mode === \"input\" && layout === \"expanded\";\n const [commandQuery, setCommandQuery] = useState<string | null>(null);\n const [slashHighlightIndex, setSlashHighlightIndex] = useState(0);\n\n const inputRef = useRef<HTMLTextAreaElement>(null);\n const gridRef = useRef<HTMLDivElement>(null);\n const addButtonContainerRef = useRef<HTMLDivElement>(null);\n const actionsContainerRef = useRef<HTMLDivElement>(null);\n const audioRecorderRef =\n useRef<React.ElementRef<typeof CopilotChatAudioRecorder>>(null);\n const slashMenuRef = useRef<HTMLDivElement>(null);\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n\n const previousModalStateRef = useRef<boolean | undefined>(undefined);\n const measurementCanvasRef = useRef<HTMLCanvasElement | null>(null);\n const measurementsRef = useRef({\n singleLineHeight: 0,\n maxHeight: 0,\n paddingLeft: 0,\n paddingRight: 0,\n });\n\n 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();\n }\n\n previousModalStateRef.current = config?.isModalOpen;\n }, [config?.isModalOpen, autoFocus]);\n\n useEffect(() => {\n if (commandItems.length === 0 && commandQuery !== null) {\n setCommandQuery(null);\n }\n }, [commandItems.length, commandQuery]);\n\n const previousCommandQueryRef = useRef<string | null>(null);\n\n useEffect(() => {\n if (\n commandQuery !== null &&\n commandQuery !== previousCommandQueryRef.current &&\n filteredCommands.length > 0\n ) {\n setSlashHighlightIndex(0);\n }\n\n previousCommandQueryRef.current = commandQuery;\n }, [commandQuery, filteredCommands.length]);\n\n useEffect(() => {\n if (commandQuery === null) {\n setSlashHighlightIndex(0);\n return;\n }\n\n if (filteredCommands.length === 0) {\n setSlashHighlightIndex(-1);\n } else if (\n slashHighlightIndex < 0 ||\n slashHighlightIndex >= filteredCommands.length\n ) {\n setSlashHighlightIndex(0);\n }\n }, [commandQuery, filteredCommands, slashHighlightIndex]);\n\n // Handle recording based on mode changes\n useEffect(() => {\n const recorder = audioRecorderRef.current;\n if (!recorder) {\n return;\n }\n\n if (mode === \"transcribe\") {\n // Start recording when entering transcribe mode\n recorder.start().catch(console.error);\n } else {\n // Stop recording when leaving transcribe mode\n if (recorder.state === \"recording\") {\n recorder.stop().catch(console.error);\n }\n }\n }, [mode]);\n\n useEffect(() => {\n if (mode !== \"input\") {\n setLayout(\"compact\");\n setCommandQuery(null);\n }\n }, [mode]);\n\n const updateSlashState = useCallback(\n (value: string) => {\n if (commandItems.length === 0) {\n setCommandQuery((prev) => (prev === null ? prev : null));\n return;\n }\n\n if (value.startsWith(\"/\")) {\n const firstLine = value.split(/\\r?\\n/, 1)[0] ?? \"\";\n const query = firstLine.slice(1);\n setCommandQuery((prev) => (prev === query ? prev : query));\n } else {\n setCommandQuery((prev) => (prev === null ? prev : null));\n }\n },\n [commandItems.length],\n );\n\n useEffect(() => {\n updateSlashState(resolvedValue);\n }, [resolvedValue, updateSlashState]);\n\n // Handlers\n const handleChange = (e: ChangeEvent<HTMLTextAreaElement>) => {\n const nextValue = e.target.value;\n if (!isControlled) {\n setInternalValue(nextValue);\n }\n onChange?.(nextValue);\n updateSlashState(nextValue);\n };\n\n const clearInputValue = useCallback(() => {\n if (!isControlled) {\n setInternalValue(\"\");\n }\n\n if (onChange) {\n onChange(\"\");\n }\n }, [isControlled, onChange]);\n\n const runCommand = useCallback(\n (item: ToolsMenuItem) => {\n clearInputValue();\n\n item.action?.();\n\n setCommandQuery(null);\n setSlashHighlightIndex(0);\n\n requestAnimationFrame(() => {\n inputRef.current?.focus();\n });\n },\n [clearInputValue],\n );\n\n const handleKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => {\n if (commandQuery !== null && mode === \"input\") {\n if (e.key === \"ArrowDown\") {\n if (filteredCommands.length > 0) {\n e.preventDefault();\n setSlashHighlightIndex((prev) => {\n if (filteredCommands.length === 0) {\n return prev;\n }\n const next = prev === -1 ? 0 : (prev + 1) % filteredCommands.length;\n return next;\n });\n }\n return;\n }\n\n if (e.key === \"ArrowUp\") {\n if (filteredCommands.length > 0) {\n e.preventDefault();\n setSlashHighlightIndex((prev) => {\n if (filteredCommands.length === 0) {\n return prev;\n }\n if (prev === -1) {\n return filteredCommands.length - 1;\n }\n return prev <= 0 ? filteredCommands.length - 1 : prev - 1;\n });\n }\n return;\n }\n\n if (e.key === \"Enter\") {\n const selected =\n slashHighlightIndex >= 0\n ? filteredCommands[slashHighlightIndex]\n : undefined;\n if (selected) {\n e.preventDefault();\n runCommand(selected);\n return;\n }\n }\n\n if (e.key === \"Escape\") {\n e.preventDefault();\n setCommandQuery(null);\n return;\n }\n }\n\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n if (isProcessing) {\n onStop?.();\n } else {\n send();\n }\n }\n };\n\n const send = () => {\n if (!onSubmitMessage) {\n return;\n }\n const trimmed = resolvedValue.trim();\n if (!trimmed) {\n return;\n }\n\n onSubmitMessage(trimmed);\n\n if (!isControlled) {\n setInternalValue(\"\");\n onChange?.(\"\");\n }\n\n if (inputRef.current) {\n inputRef.current.focus();\n }\n };\n\n const BoundTextArea = renderSlot(textArea, CopilotChatInput.TextArea, {\n ref: inputRef,\n value: resolvedValue,\n onChange: handleChange,\n onKeyDown: handleKeyDown,\n autoFocus: autoFocus,\n className: twMerge(\n \"cpk:w-full cpk:py-3\",\n isExpanded ? \"cpk:px-5\" : \"cpk:pr-5\",\n ),\n });\n\n const isProcessing = mode !== \"transcribe\" && isRunning;\n const canSend = resolvedValue.trim().length > 0 && !!onSubmitMessage;\n const canStop = !!onStop;\n\n const handleSendButtonClick = () => {\n if (isProcessing) {\n onStop?.();\n return;\n }\n send();\n };\n\n const BoundAudioRecorder = renderSlot(\n audioRecorder,\n CopilotChatAudioRecorder,\n {\n ref: audioRecorderRef,\n },\n );\n\n const BoundSendButton = renderSlot(sendButton, CopilotChatInput.SendButton, {\n onClick: handleSendButtonClick,\n disabled: isProcessing ? !canStop : !canSend,\n children:\n isProcessing && canStop ? (\n <Square className=\"cpk:size-[18px] cpk:fill-current\" />\n ) : undefined,\n });\n\n const BoundStartTranscribeButton = renderSlot(\n startTranscribeButton,\n CopilotChatInput.StartTranscribeButton,\n {\n onClick: onStartTranscribe,\n },\n );\n\n const BoundCancelTranscribeButton = renderSlot(\n cancelTranscribeButton,\n CopilotChatInput.CancelTranscribeButton,\n {\n onClick: onCancelTranscribe,\n },\n );\n\n // Handler for finish button - stops recording and passes audio blob\n const handleFinishTranscribe = useCallback(async () => {\n const recorder = audioRecorderRef.current;\n if (recorder && recorder.state === \"recording\") {\n try {\n const audioBlob = await recorder.stop();\n if (onFinishTranscribeWithAudio) {\n await onFinishTranscribeWithAudio(audioBlob);\n }\n } catch (error) {\n console.error(\"Failed to stop recording:\", error);\n }\n }\n // Always call the original handler to reset mode\n onFinishTranscribe?.();\n }, [onFinishTranscribe, onFinishTranscribeWithAudio]);\n\n const BoundFinishTranscribeButton = renderSlot(\n finishTranscribeButton,\n CopilotChatInput.FinishTranscribeButton,\n {\n onClick: handleFinishTranscribe,\n },\n );\n\n const BoundAddMenuButton = renderSlot(\n addMenuButton,\n CopilotChatInput.AddMenuButton,\n {\n disabled: mode === \"transcribe\",\n onAddFile,\n toolsMenu,\n },\n );\n\n const BoundDisclaimer = renderSlot(\n disclaimer,\n CopilotChatInput.Disclaimer,\n {},\n );\n\n // Determine whether to show disclaimer based on prop or positioning default\n const shouldShowDisclaimer = showDisclaimer ?? positioning === \"absolute\";\n\n if (children) {\n const childProps = {\n textArea: BoundTextArea,\n audioRecorder: BoundAudioRecorder,\n sendButton: BoundSendButton,\n startTranscribeButton: BoundStartTranscribeButton,\n cancelTranscribeButton: BoundCancelTranscribeButton,\n finishTranscribeButton: BoundFinishTranscribeButton,\n addMenuButton: BoundAddMenuButton,\n disclaimer: BoundDisclaimer,\n onSubmitMessage,\n onStop,\n isRunning,\n onStartTranscribe,\n onCancelTranscribe,\n onFinishTranscribe,\n onAddFile,\n mode,\n toolsMenu,\n autoFocus,\n positioning,\n keyboardHeight,\n showDisclaimer: shouldShowDisclaimer,\n } as CopilotChatInputChildrenArgs;\n\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children(childProps)}\n </div>\n );\n }\n\n const handleContainerClick = (e: React.MouseEvent<HTMLDivElement>) => {\n // Don't focus if clicking on buttons or other interactive elements\n const target = e.target as HTMLElement;\n if (\n target.tagName !== \"BUTTON\" &&\n !target.closest(\"button\") &&\n inputRef.current &&\n mode === \"input\"\n ) {\n inputRef.current.focus();\n }\n };\n\n const ensureMeasurements = useCallback(() => {\n const textarea = inputRef.current;\n if (!textarea) {\n return;\n }\n\n const previousValue = textarea.value;\n const previousHeight = textarea.style.height;\n\n textarea.style.height = \"auto\";\n\n const computedStyle = window.getComputedStyle(textarea);\n const paddingLeft = parseFloat(computedStyle.paddingLeft) || 0;\n const paddingRight = parseFloat(computedStyle.paddingRight) || 0;\n const paddingTop = parseFloat(computedStyle.paddingTop) || 0;\n const paddingBottom = parseFloat(computedStyle.paddingBottom) || 0;\n\n textarea.value = \"\";\n const singleLineHeight = textarea.scrollHeight;\n textarea.value = previousValue;\n\n const contentHeight = singleLineHeight - paddingTop - paddingBottom;\n const maxHeight = contentHeight * 5 + paddingTop + paddingBottom;\n\n measurementsRef.current = {\n singleLineHeight,\n maxHeight,\n paddingLeft,\n paddingRight,\n };\n\n textarea.style.height = previousHeight;\n textarea.style.maxHeight = `${maxHeight}px`;\n }, []);\n\n const adjustTextareaHeight = useCallback(() => {\n const textarea = inputRef.current;\n if (!textarea) {\n return 0;\n }\n\n if (measurementsRef.current.singleLineHeight === 0) {\n ensureMeasurements();\n }\n\n const { maxHeight } = measurementsRef.current;\n if (maxHeight) {\n textarea.style.maxHeight = `${maxHeight}px`;\n }\n\n textarea.style.height = \"auto\";\n const scrollHeight = textarea.scrollHeight;\n if (maxHeight) {\n textarea.style.height = `${Math.min(scrollHeight, maxHeight)}px`;\n } else {\n textarea.style.height = `${scrollHeight}px`;\n }\n\n return scrollHeight;\n }, [ensureMeasurements]);\n\n const updateLayout = useCallback((nextLayout: \"compact\" | \"expanded\") => {\n setLayout((prev) => {\n if (prev === nextLayout) {\n return prev;\n }\n ignoreResizeRef.current = true;\n return nextLayout;\n });\n }, []);\n\n const evaluateLayout = useCallback(() => {\n if (mode !== \"input\") {\n updateLayout(\"compact\");\n return;\n }\n\n if (\n typeof window !== \"undefined\" &&\n typeof window.matchMedia === \"function\"\n ) {\n const isMobileViewport = window.matchMedia(\"(max-width: 767px)\").matches;\n if (isMobileViewport) {\n ensureMeasurements();\n adjustTextareaHeight();\n updateLayout(\"expanded\");\n return;\n }\n }\n\n const textarea = inputRef.current;\n const grid = gridRef.current;\n const addContainer = addButtonContainerRef.current;\n const actionsContainer = actionsContainerRef.current;\n\n if (!textarea || !grid || !addContainer || !actionsContainer) {\n return;\n }\n\n if (measurementsRef.current.singleLineHeight === 0) {\n ensureMeasurements();\n }\n\n const scrollHeight = adjustTextareaHeight();\n const baseline = measurementsRef.current.singleLineHeight;\n const hasExplicitBreak = resolvedValue.includes(\"\\n\");\n const renderedMultiline =\n baseline > 0 ? scrollHeight > baseline + 1 : false;\n let shouldExpand = hasExplicitBreak || renderedMultiline;\n\n if (!shouldExpand) {\n 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) {\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 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 const textareaStyles = window.getComputedStyle(textarea);\n const font =\n textareaStyles.font ||\n `${textareaStyles.fontStyle} ${textareaStyles.fontVariant} ${textareaStyles.fontWeight} ${textareaStyles.fontSize}/${textareaStyles.lineHeight} ${textareaStyles.fontFamily}`;\n context.font = font;\n\n const compactInnerWidth = Math.max(\n compactWidth -\n (measurementsRef.current.paddingLeft || 0) -\n (measurementsRef.current.paddingRight || 0),\n 0,\n );\n\n if (compactInnerWidth > 0) {\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 }\n }\n }\n }\n\n const nextLayout = shouldExpand ? \"expanded\" : \"compact\";\n updateLayout(nextLayout);\n }, [\n adjustTextareaHeight,\n ensureMeasurements,\n mode,\n resolvedValue,\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 scheduleEvaluation = () => {\n if (ignoreResizeRef.current) {\n ignoreResizeRef.current = false;\n return;\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 const observer = new ResizeObserver(() => {\n scheduleEvaluation();\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 // 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 positioning === \"absolute\" &&\n \"cpk:absolute cpk:bottom-0 cpk:left-0 cpk:right-0 cpk:z-20 cpk:pointer-events-none\",\n className,\n )}\n style={{\n transform:\n keyboardHeight > 0 ? `translateY(-${keyboardHeight}px)` : undefined,\n transition: \"transform 0.2s ease-out\",\n }}\n {...props}\n >\n <div className=\"cpk:max-w-3xl cpk:mx-auto cpk:py-0 cpk:px-4 cpk:sm:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-4 cpk:pointer-events-auto\">\n {inputPill}\n </div>\n {shouldShowDisclaimer && BoundDisclaimer}\n </div>\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotChatInput {\n export const SendButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, children, ...props }) => (\n <div className=\"cpk:mr-[10px]\">\n <Button\n type=\"button\"\n data-testid=\"copilot-send-button\"\n variant=\"chatInputToolbarPrimary\"\n size=\"chatInputToolbarIcon\"\n className={className}\n {...props}\n >\n {children ?? <ArrowUp className=\"cpk:size-[18px]\" />}\n </Button>\n </div>\n );\n\n export const ToolbarButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & {\n icon: React.ReactNode;\n labelKey: keyof CopilotChatLabels;\n defaultClassName?: string;\n }\n > = ({ icon, labelKey, defaultClassName, className, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"chatInputToolbarSecondary\"\n size=\"chatInputToolbarIcon\"\n className={twMerge(defaultClassName, className)}\n {...props}\n >\n {icon}\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">\n <p>{labels[labelKey]}</p>\n </TooltipContent>\n </Tooltip>\n );\n };\n\n export const StartTranscribeButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = (props) => (\n <ToolbarButton\n data-testid=\"copilot-start-transcribe-button\"\n icon={<Mic className=\"cpk:size-[18px]\" />}\n labelKey=\"chatInputToolbarStartTranscribeButtonLabel\"\n defaultClassName=\"cpk:mr-2\"\n {...props}\n />\n );\n\n export const CancelTranscribeButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = (props) => (\n <ToolbarButton\n data-testid=\"copilot-cancel-transcribe-button\"\n icon={<X className=\"cpk:size-[18px]\" />}\n labelKey=\"chatInputToolbarCancelTranscribeButtonLabel\"\n defaultClassName=\"cpk:mr-2\"\n {...props}\n />\n );\n\n export const FinishTranscribeButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = (props) => (\n <ToolbarButton\n data-testid=\"copilot-finish-transcribe-button\"\n icon={<Check className=\"cpk:size-[18px]\" />}\n labelKey=\"chatInputToolbarFinishTranscribeButtonLabel\"\n defaultClassName=\"cpk:mr-[10px]\"\n {...props}\n />\n );\n\n export const AddMenuButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & {\n toolsMenu?: (ToolsMenuItem | \"-\")[];\n onAddFile?: () => void;\n }\n > = ({ className, toolsMenu, onAddFile, disabled, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n\n 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 return (\n <DropdownMenu>\n <Tooltip>\n <TooltipTrigger asChild>\n <DropdownMenuTrigger asChild>\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 </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 files and more</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 // Auto-scroll input into view on mobile when focused\n useEffect(() => {\n const textarea = internalTextareaRef.current;\n if (!textarea) return;\n\n const handleFocus = () => {\n // Small delay to let the keyboard start appearing\n setTimeout(() => {\n textarea.scrollIntoView({ behavior: \"smooth\", block: \"nearest\" });\n }, 300);\n };\n\n textarea.addEventListener(\"focus\", handleFocus);\n return () => textarea.removeEventListener(\"focus\", handleFocus);\n }, []);\n\n useEffect(() => {\n if (autoFocus) {\n internalTextareaRef.current?.focus();\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","import * as React from \"react\";\nimport { createComponent } from \"@lit-labs/react\";\nimport type { CopilotKitCore } from \"@copilotkitnext/core\";\n\ntype CopilotKitInspectorBaseProps = {\n core?: CopilotKitCore | null;\n [key: string]: unknown;\n};\n\ntype InspectorComponent = React.ComponentType<CopilotKitInspectorBaseProps>;\n\nexport interface CopilotKitInspectorProps extends CopilotKitInspectorBaseProps {}\n\nexport const CopilotKitInspector: React.FC<CopilotKitInspectorProps> = ({\n core,\n ...rest\n}) => {\n const [InspectorComponent, setInspectorComponent] =\n React.useState<InspectorComponent | null>(null);\n\n React.useEffect(() => {\n let mounted = true;\n\n // Load the web component only on the client to keep SSR output stable.\n import(\"@copilotkitnext/web-inspector\").then((mod) => {\n mod.defineWebInspector?.();\n\n const Component = createComponent({\n tagName: mod.WEB_INSPECTOR_TAG,\n elementClass: mod.WebInspectorElement,\n react: React,\n }) as InspectorComponent;\n\n if (mounted) {\n setInspectorComponent(() => Component);\n }\n });\n\n return () => {\n mounted = false;\n };\n }, []);\n\n // During SSR (and until the client finishes loading), render nothing to keep markup consistent.\n if (!InspectorComponent) return null;\n\n return <InspectorComponent {...rest} core={core ?? null} />;\n};\n\nCopilotKitInspector.displayName = \"CopilotKitInspector\";\n","\"use client\";\n\nimport React, { useEffect, useRef, useState, useCallback } from \"react\";\nimport { z } from \"zod\";\nimport type { AbstractAgent, RunAgentResult } from \"@ag-ui/client\";\n\n// Protocol version supported\nconst PROTOCOL_VERSION = \"2025-06-18\";\n\n// Build sandbox proxy HTML with optional extra CSP domains from resource metadata\nfunction buildSandboxHTML(extraCspDomains?: string[]): string {\n const baseScriptSrc =\n \"'self' 'wasm-unsafe-eval' 'unsafe-inline' 'unsafe-eval' blob: data: http://localhost:* https://localhost:*\";\n const baseFrameSrc = \"* blob: data: http://localhost:* https://localhost:*\";\n const extra = extraCspDomains?.length ? \" \" + extraCspDomains.join(\" \") : \"\";\n const scriptSrc = baseScriptSrc + extra;\n const frameSrc = baseFrameSrc + extra;\n\n return `<!doctype html>\n<html>\n<head>\n<meta charset=\"utf-8\" />\n<meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'self'; img-src * data: blob: 'unsafe-inline'; media-src * blob: data:; font-src * blob: data:; script-src ${scriptSrc}; style-src * blob: data: 'unsafe-inline'; connect-src *; frame-src ${frameSrc}; base-uri 'self';\" />\n<style>html,body{margin:0;padding:0;height:100%;width:100%;overflow:hidden}*{box-sizing:border-box}iframe{background-color:transparent;border:none;padding:0;overflow:hidden;width:100%;height:100%}</style>\n</head>\n<body>\n<script>\nif(window.self===window.top){throw new Error(\"This file must be used in an iframe.\")}\nconst inner=document.createElement(\"iframe\");\ninner.style=\"width:100%;height:100%;border:none;\";\ninner.setAttribute(\"sandbox\",\"allow-scripts allow-same-origin allow-forms\");\ndocument.body.appendChild(inner);\nwindow.addEventListener(\"message\",async(event)=>{\nif(event.source===window.parent){\nif(event.data&&event.data.method===\"ui/notifications/sandbox-resource-ready\"){\nconst{html,sandbox}=event.data.params;\nif(typeof sandbox===\"string\")inner.setAttribute(\"sandbox\",sandbox);\nif(typeof html===\"string\")inner.srcdoc=html;\n}else if(inner&&inner.contentWindow){\ninner.contentWindow.postMessage(event.data,\"*\");\n}\n}else if(event.source===inner.contentWindow){\nwindow.parent.postMessage(event.data,\"*\");\n}\n});\nwindow.parent.postMessage({jsonrpc:\"2.0\",method:\"ui/notifications/sandbox-proxy-ready\",params:{}},\"*\");\n</script>\n</body>\n</html>`;\n}\n\n/**\n * Queue for serializing MCP app requests to an agent.\n * Ensures requests wait for the agent to stop running and are processed one at a time.\n */\nclass MCPAppsRequestQueue {\n private queues = new Map<\n string,\n Array<{\n execute: () => Promise<RunAgentResult>;\n resolve: (result: RunAgentResult) => void;\n reject: (error: Error) => void;\n }>\n >();\n private processing = new Map<string, boolean>();\n\n /**\n * Add a request to the queue for a specific agent thread.\n * Returns a promise that resolves when the request completes.\n */\n async enqueue(\n agent: AbstractAgent,\n request: () => Promise<RunAgentResult>,\n ): Promise<RunAgentResult> {\n const threadId = agent.threadId || \"default\";\n\n return new Promise((resolve, reject) => {\n // Get or create queue for this thread\n let queue = this.queues.get(threadId);\n if (!queue) {\n queue = [];\n this.queues.set(threadId, queue);\n }\n\n // Add request to queue\n queue.push({ execute: request, resolve, reject });\n\n // Start processing if not already running\n this.processQueue(threadId, agent);\n });\n }\n\n private async processQueue(\n threadId: string,\n agent: AbstractAgent,\n ): Promise<void> {\n // If already processing this queue, return\n if (this.processing.get(threadId)) {\n return;\n }\n\n this.processing.set(threadId, true);\n\n try {\n const queue = this.queues.get(threadId);\n if (!queue) return;\n\n while (queue.length > 0) {\n const item = queue[0]!;\n\n try {\n // Wait for any active run to complete before processing\n await this.waitForAgentIdle(agent);\n\n // Execute the request\n const result = await item.execute();\n item.resolve(result);\n } catch (error) {\n item.reject(\n error instanceof Error ? error : new Error(String(error)),\n );\n }\n\n // Remove processed item\n queue.shift();\n }\n } finally {\n this.processing.set(threadId, false);\n }\n }\n\n private waitForAgentIdle(agent: AbstractAgent): Promise<void> {\n return new Promise((resolve) => {\n if (!agent.isRunning) {\n resolve();\n return;\n }\n\n let done = false;\n const finish = () => {\n if (done) return;\n done = true;\n clearInterval(checkInterval);\n sub.unsubscribe();\n resolve();\n };\n\n const sub = agent.subscribe({\n onRunFinalized: finish,\n onRunFailed: finish,\n });\n\n // Fallback for reconnect scenarios where events don't fire\n const checkInterval = setInterval(() => {\n if (!agent.isRunning) finish();\n }, 500);\n });\n }\n}\n\n// Global queue instance for all MCP app requests\nconst mcpAppsRequestQueue = new MCPAppsRequestQueue();\n\n/**\n * Activity type for MCP Apps events - must match the middleware's MCPAppsActivityType\n */\nexport const MCPAppsActivityType = \"mcp-apps\";\n\n// Zod schema for activity content validation (middleware 0.0.2 format)\nexport const MCPAppsActivityContentSchema = z.object({\n result: z.object({\n content: z.array(z.any()).optional(),\n structuredContent: z.any().optional(),\n isError: z.boolean().optional(),\n }),\n // Resource URI to fetch (e.g., \"ui://server/dashboard\")\n resourceUri: z.string(),\n // MD5 hash of server config (renamed from serverId in 0.0.1)\n serverHash: z.string(),\n // Optional stable server ID from config (takes precedence over serverHash)\n serverId: z.string().optional(),\n // Original tool input arguments\n toolInput: z.record(z.unknown()).optional(),\n});\n\nexport type MCPAppsActivityContent = z.infer<\n typeof MCPAppsActivityContentSchema\n>;\n\n// Type for the resource fetched from the server\ninterface FetchedResource {\n uri: string;\n mimeType?: string;\n text?: string;\n blob?: string;\n _meta?: {\n ui?: {\n prefersBorder?: boolean;\n csp?: {\n connectDomains?: string[];\n resourceDomains?: string[];\n };\n };\n };\n}\n\ninterface JSONRPCRequest {\n jsonrpc: \"2.0\";\n id: string | number;\n method: string;\n params?: Record<string, unknown>;\n}\n\ninterface JSONRPCResponse {\n jsonrpc: \"2.0\";\n id: string | number;\n result?: unknown;\n error?: { code: number; message: string };\n}\n\ninterface JSONRPCNotification {\n jsonrpc: \"2.0\";\n method: string;\n params?: Record<string, unknown>;\n}\n\ntype JSONRPCMessage = JSONRPCRequest | JSONRPCResponse | JSONRPCNotification;\n\nfunction isRequest(msg: JSONRPCMessage): msg is JSONRPCRequest {\n return \"id\" in msg && \"method\" in msg;\n}\n\nfunction isNotification(msg: JSONRPCMessage): msg is JSONRPCNotification {\n return !(\"id\" in msg) && \"method\" in msg;\n}\n\n/**\n * Props for the activity renderer component\n */\ninterface MCPAppsActivityRendererProps {\n activityType: string;\n content: MCPAppsActivityContent;\n message: unknown; // ActivityMessage from @ag-ui/core\n agent: AbstractAgent | undefined;\n}\n\n/**\n * MCP Apps Extension Activity Renderer\n *\n * Renders MCP Apps UI in a sandboxed iframe with full protocol support.\n * Fetches resource content on-demand via proxied MCP requests.\n */\nexport const MCPAppsActivityRenderer: React.FC<MCPAppsActivityRendererProps> =\n function MCPAppsActivityRenderer({ content, agent }) {\n const containerRef = useRef<HTMLDivElement>(null);\n const iframeRef = useRef<HTMLIFrameElement | null>(null);\n const [iframeReady, setIframeReady] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [iframeSize, setIframeSize] = useState<{\n width?: number;\n height?: number;\n }>({});\n const [fetchedResource, setFetchedResource] =\n useState<FetchedResource | null>(null);\n\n // Use refs for values that shouldn't trigger re-renders but need latest values\n const contentRef = useRef(content);\n contentRef.current = content;\n\n // Store agent in a ref for use in async handlers\n const agentRef = useRef(agent);\n agentRef.current = agent;\n\n // Ref to track fetch state - survives StrictMode remounts\n const fetchStateRef = useRef<{\n inProgress: boolean;\n promise: Promise<FetchedResource | null> | null;\n resourceUri: string | null;\n }>({ inProgress: false, promise: null, resourceUri: null });\n\n // Callback to send a message to the iframe\n const sendToIframe = useCallback((msg: JSONRPCMessage) => {\n if (iframeRef.current?.contentWindow) {\n console.log(\"[MCPAppsRenderer] Sending to iframe:\", msg);\n iframeRef.current.contentWindow.postMessage(msg, \"*\");\n }\n }, []);\n\n // Callback to send a JSON-RPC response\n const sendResponse = useCallback(\n (id: string | number, result: unknown) => {\n sendToIframe({\n jsonrpc: \"2.0\",\n id,\n result,\n });\n },\n [sendToIframe],\n );\n\n // Callback to send a JSON-RPC error response\n const sendErrorResponse = useCallback(\n (id: string | number, code: number, message: string) => {\n sendToIframe({\n jsonrpc: \"2.0\",\n id,\n error: { code, message },\n });\n },\n [sendToIframe],\n );\n\n // Callback to send a notification\n const sendNotification = useCallback(\n (method: string, params?: Record<string, unknown>) => {\n sendToIframe({\n jsonrpc: \"2.0\",\n method,\n params: params || {},\n });\n },\n [sendToIframe],\n );\n\n // Effect 0: Fetch the resource content on mount\n // Uses ref-based deduplication to handle React StrictMode double-mounting\n useEffect(() => {\n const { resourceUri, serverHash, serverId } = content;\n\n // Check if we already have a fetch in progress for this resource\n // This handles StrictMode double-mounting - second mount reuses first mount's promise\n if (\n fetchStateRef.current.inProgress &&\n fetchStateRef.current.resourceUri === resourceUri\n ) {\n // Reuse the existing promise\n fetchStateRef.current.promise\n ?.then((resource) => {\n if (resource) {\n setFetchedResource(resource);\n setIsLoading(false);\n }\n })\n .catch((err) => {\n setError(err instanceof Error ? err : new Error(String(err)));\n setIsLoading(false);\n });\n return;\n }\n\n if (!agent) {\n setError(new Error(\"No agent available to fetch resource\"));\n setIsLoading(false);\n return;\n }\n\n // Mark fetch as in progress\n fetchStateRef.current.inProgress = true;\n fetchStateRef.current.resourceUri = resourceUri;\n\n // Create the fetch promise using the queue to serialize requests\n const fetchPromise = (async (): Promise<FetchedResource | null> => {\n try {\n // Use queue to wait for agent to be idle and serialize requests\n const runResult = await mcpAppsRequestQueue.enqueue(agent, () =>\n agent.runAgent({\n forwardedProps: {\n __proxiedMCPRequest: {\n serverHash,\n serverId, // optional, takes precedence if provided\n method: \"resources/read\",\n params: { uri: resourceUri },\n },\n },\n }),\n );\n\n // Extract resource from result\n // The response format is: { contents: [{ uri, mimeType, text?, blob?, _meta? }] }\n const resultData = runResult.result as\n | { contents?: FetchedResource[] }\n | undefined;\n const resource = resultData?.contents?.[0];\n\n if (!resource) {\n throw new Error(\"No resource content in response\");\n }\n\n return resource;\n } catch (err) {\n console.error(\"[MCPAppsRenderer] Failed to fetch resource:\", err);\n throw err;\n } finally {\n // Mark fetch as complete\n fetchStateRef.current.inProgress = false;\n }\n })();\n\n // Store the promise for potential reuse\n fetchStateRef.current.promise = fetchPromise;\n\n // Handle the result\n fetchPromise\n .then((resource) => {\n if (resource) {\n setFetchedResource(resource);\n setIsLoading(false);\n }\n })\n .catch((err) => {\n setError(err instanceof Error ? err : new Error(String(err)));\n setIsLoading(false);\n });\n\n // No cleanup needed - we want the fetch to complete even if StrictMode unmounts\n }, [agent, content]);\n\n // Effect 1: Setup sandbox proxy iframe and communication (after resource is fetched)\n useEffect(() => {\n // Wait for resource to be fetched\n if (isLoading || !fetchedResource) {\n return;\n }\n\n // Capture container reference at effect start (refs are cleared during unmount)\n const container = containerRef.current;\n if (!container) {\n return;\n }\n\n let mounted = true;\n let messageHandler: ((event: MessageEvent) => void) | null = null;\n let initialListener: ((event: MessageEvent) => void) | null = null;\n let createdIframe: HTMLIFrameElement | null = null;\n\n const setup = async () => {\n try {\n // Create sandbox proxy iframe\n const iframe = document.createElement(\"iframe\");\n createdIframe = iframe; // Track for cleanup\n iframe.style.width = \"100%\";\n iframe.style.height = \"100px\"; // Start small, will be resized by size-changed notification\n iframe.style.border = \"none\";\n iframe.style.backgroundColor = \"transparent\";\n iframe.style.display = \"block\";\n iframe.setAttribute(\n \"sandbox\",\n \"allow-scripts allow-same-origin allow-forms\",\n );\n\n // Wait for sandbox proxy to be ready\n const sandboxReady = new Promise<void>((resolve) => {\n initialListener = (event: MessageEvent) => {\n if (event.source === iframe.contentWindow) {\n if (\n event.data?.method === \"ui/notifications/sandbox-proxy-ready\"\n ) {\n if (initialListener) {\n window.removeEventListener(\"message\", initialListener);\n initialListener = null;\n }\n resolve();\n }\n }\n };\n window.addEventListener(\"message\", initialListener);\n });\n\n // Check mounted before adding to DOM (handles StrictMode double-mount)\n if (!mounted) {\n if (initialListener) {\n window.removeEventListener(\"message\", initialListener);\n initialListener = null;\n }\n return;\n }\n\n // Build sandbox HTML with CSP domains from resource metadata\n const cspDomains = fetchedResource._meta?.ui?.csp?.resourceDomains;\n iframe.srcdoc = buildSandboxHTML(cspDomains);\n iframeRef.current = iframe;\n container.appendChild(iframe);\n\n // Wait for sandbox proxy to signal ready\n await sandboxReady;\n if (!mounted) return;\n\n console.log(\"[MCPAppsRenderer] Sandbox proxy ready\");\n\n // Setup message handler for JSON-RPC messages from the inner iframe\n messageHandler = async (event: MessageEvent) => {\n if (event.source !== iframe.contentWindow) return;\n\n const msg = event.data as JSONRPCMessage;\n if (!msg || typeof msg !== \"object\" || msg.jsonrpc !== \"2.0\")\n return;\n\n console.log(\"[MCPAppsRenderer] Received from iframe:\", msg);\n\n // Handle requests (need response)\n if (isRequest(msg)) {\n switch (msg.method) {\n case \"ui/initialize\": {\n // Respond with host capabilities\n sendResponse(msg.id, {\n protocolVersion: PROTOCOL_VERSION,\n hostInfo: {\n name: \"CopilotKit MCP Apps Host\",\n version: \"1.0.0\",\n },\n hostCapabilities: {\n openLinks: {},\n logging: {},\n },\n hostContext: {\n theme: \"light\",\n platform: \"web\",\n },\n });\n break;\n }\n\n case \"ui/message\": {\n // Add message to CopilotKit chat\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 };\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: (params.role as \"user\" | \"assistant\") || \"user\",\n content: textContent,\n });\n }\n sendResponse(msg.id, { isError: false });\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 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 \"@copilotkitnext/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 _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 return this._renderToolCalls;\n }\n\n setRenderToolCalls(renderToolCalls: ReactToolCallRenderer<any>[]): void {\n this._renderToolCalls = renderToolCalls;\n\n // Notify React-specific subscribers\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","\"use client\";\n\nimport type { AbstractAgent } from \"@ag-ui/client\";\nimport type { FrontendTool } from \"@copilotkitnext/core\";\nimport type React from \"react\";\nimport {\n createContext,\n useContext,\n type ReactNode,\n useMemo,\n useEffect,\n useReducer,\n useRef,\n useState,\n} from \"react\";\nimport { z } from \"zod\";\nimport { CopilotKitInspector } from \"../components/CopilotKitInspector\";\nimport {\n MCPAppsActivityContentSchema,\n MCPAppsActivityRenderer,\n MCPAppsActivityType,\n} from \"../components/MCPAppsActivityRenderer\";\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\";\n\nconst HEADER_NAME = \"X-CopilotCloud-Public-Api-Key\";\nconst COPILOT_CLOUD_CHAT_URL = \"https://api.cloud.copilotkit.ai/copilotkit/v1\";\n\n// Define the context value interface - idiomatic React naming\nexport interface CopilotKitContextValue {\n copilotkit: CopilotKitCoreReact;\n /**\n * Set of tool call IDs currently being executed.\n * This is tracked at the provider level to ensure tool execution events\n * are captured even before child components mount.\n */\n executingToolCallIds: ReadonlySet<string>;\n}\n\n// Empty set for default context value\nconst EMPTY_SET: ReadonlySet<string> = new Set();\n\n// Create the CopilotKit context\nconst CopilotKitContext = createContext<CopilotKitContextValue>({\n copilotkit: null!,\n executingToolCallIds: EMPTY_SET,\n});\n\n// Provider props interface\nexport interface CopilotKitProviderProps {\n children: ReactNode;\n runtimeUrl?: string;\n headers?: Record<string, string>;\n /**\n * Credentials mode for fetch requests (e.g., \"include\" for HTTP-only cookies in cross-origin requests).\n */\n credentials?: RequestCredentials;\n /**\n * The Copilot Cloud public API key.\n */\n publicApiKey?: string;\n /**\n * Alias for `publicApiKey`\n **/\n publicLicenseKey?: string;\n 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 showDevConsole?: boolean | \"auto\";\n}\n\n// Small helper to normalize array props to a stable reference and warn\nfunction useStableArrayProp<T>(\n prop: T[] | undefined,\n warningMessage?: string,\n isMeaningfulChange?: (initial: T[], next: T[]) => boolean,\n): T[] {\n const empty = useMemo<T[]>(() => [], []);\n const value = prop ?? empty;\n const initial = useRef(value);\n\n useEffect(() => {\n if (\n warningMessage &&\n value !== initial.current &&\n (isMeaningfulChange ? isMeaningfulChange(initial.current, value) : true)\n ) {\n console.error(warningMessage);\n }\n }, [value, warningMessage]);\n\n return value;\n}\n\n// Provider component\nexport const CopilotKitProvider: React.FC<CopilotKitProviderProps> = ({\n children,\n runtimeUrl,\n headers = {},\n credentials,\n publicApiKey,\n publicLicenseKey,\n properties = {},\n agents__unsafe_dev_only: agents = {},\n selfManagedAgents = {},\n renderToolCalls,\n renderActivityMessages,\n renderCustomMessages,\n frontendTools,\n humanInTheLoop,\n showDevConsole = false,\n useSingleEndpoint = false,\n}) => {\n const [shouldRenderInspector, setShouldRenderInspector] = useState(false);\n\n useEffect(() => {\n if (typeof window === \"undefined\") {\n return;\n }\n\n if (showDevConsole === true) {\n // Explicitly show the inspector\n setShouldRenderInspector(true);\n } else if (showDevConsole === \"auto\") {\n // Show on localhost or 127.0.0.1 only\n const localhostHosts = new Set([\"localhost\", \"127.0.0.1\"]);\n if (localhostHosts.has(window.location.hostname)) {\n setShouldRenderInspector(true);\n } else {\n setShouldRenderInspector(false);\n }\n } else {\n // showDevConsole is false or undefined (default false)\n setShouldRenderInspector(false);\n }\n }, [showDevConsole]);\n\n // Normalize array props to stable references with clear dev warnings\n const renderToolCallsList = useStableArrayProp<ReactToolCallRenderer<any>>(\n renderToolCalls,\n \"renderToolCalls must be a stable array. If you want to dynamically add or remove tools, use `useFrontendTool` instead.\",\n (initial, next) => {\n // Only warn if the shape (names+agentId) changed. Allow identity changes\n // to support updated closures from parents (e.g., Storybook state).\n const key = (rc?: ReactToolCallRenderer<unknown>) =>\n `${rc?.agentId ?? \"\"}:${rc?.name ?? \"\"}`;\n const setFrom = (arr: ReactToolCallRenderer<unknown>[]) =>\n new Set(arr.map(key));\n const a = setFrom(initial);\n const b = setFrom(next);\n if (a.size !== b.size) return true;\n for (const k of a) if (!b.has(k)) return true;\n return false;\n },\n );\n\n const renderCustomMessagesList =\n useStableArrayProp<ReactCustomMessageRenderer>(\n renderCustomMessages,\n \"renderCustomMessages must be a stable array.\",\n );\n\n const renderActivityMessagesList = useStableArrayProp<\n ReactActivityMessageRenderer<any>\n >(renderActivityMessages, \"renderActivityMessages must be a stable array.\");\n\n // Built-in activity renderers that are always included\n const builtInActivityRenderers = useMemo<ReactActivityMessageRenderer<any>[]>(\n () => [\n {\n activityType: MCPAppsActivityType,\n content: MCPAppsActivityContentSchema,\n render: MCPAppsActivityRenderer,\n },\n ],\n [],\n );\n\n // Combine user-provided activity renderers with built-in ones\n // User-provided renderers take precedence (come first) so they can override built-ins\n const allActivityRenderers = useMemo(() => {\n return [...renderActivityMessagesList, ...builtInActivityRenderers];\n }, [renderActivityMessagesList, builtInActivityRenderers]);\n\n const resolvedPublicKey = publicApiKey ?? publicLicenseKey;\n const mergedAgents = useMemo(\n () => ({ ...agents, ...selfManagedAgents }),\n [agents, selfManagedAgents],\n );\n const hasLocalAgents = mergedAgents && Object.keys(mergedAgents).length > 0;\n\n // Merge a provided publicApiKey into headers (without overwriting an explicit header).\n const mergedHeaders = useMemo(() => {\n if (!resolvedPublicKey) return headers;\n if (headers[HEADER_NAME]) return headers;\n return {\n ...headers,\n [HEADER_NAME]: resolvedPublicKey,\n };\n }, [headers, resolvedPublicKey]);\n\n if (!runtimeUrl && !resolvedPublicKey && !hasLocalAgents) {\n const message =\n \"Missing required prop: 'runtimeUrl' or 'publicApiKey' or 'publicLicenseKey'\";\n if (process.env.NODE_ENV === \"production\") {\n throw new Error(message);\n } else {\n // In dev/test we warn but allow to facilitate local agents and unit tests.\n console.warn(message);\n }\n }\n\n const chatApiEndpoint =\n runtimeUrl ?? (resolvedPublicKey ? COPILOT_CLOUD_CHAT_URL : undefined);\n\n const frontendToolsList = useStableArrayProp<ReactFrontendTool>(\n frontendTools,\n \"frontendTools must be a stable array. If you want to dynamically add or remove tools, use `useFrontendTool` instead.\",\n );\n const humanInTheLoopList = useStableArrayProp<ReactHumanInTheLoop>(\n humanInTheLoop,\n \"humanInTheLoop must be a stable array. If you want to dynamically add or remove human-in-the-loop tools, use `useHumanInTheLoop` instead.\",\n );\n\n // Note: warnings for array identity changes are handled by useStableArrayProp\n\n // Process humanInTheLoop tools to create handlers and add render components\n const processedHumanInTheLoopTools = useMemo(() => {\n const processedTools: FrontendTool[] = [];\n const processedRenderToolCalls: ReactToolCallRenderer<unknown>[] = [];\n\n humanInTheLoopList.forEach((tool) => {\n // Create a promise-based handler for each human-in-the-loop tool\n const frontendTool: FrontendTool = {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n followUp: tool.followUp,\n ...(tool.agentId && { agentId: tool.agentId }),\n handler: async () => {\n // This handler will be replaced by the hook when it runs\n // For provider-level tools, we create a basic handler that waits for user interaction\n return new Promise((resolve) => {\n // The actual implementation will be handled by the render component\n // This is a placeholder that the hook will override\n console.warn(\n `Human-in-the-loop tool '${tool.name}' called but no interactive handler is set up.`,\n );\n resolve(undefined);\n });\n },\n };\n processedTools.push(frontendTool);\n\n // Add the render component to renderToolCalls\n if (tool.render) {\n processedRenderToolCalls.push({\n name: tool.name,\n args: tool.parameters!,\n render: tool.render,\n ...(tool.agentId && { agentId: tool.agentId }),\n } as ReactToolCallRenderer<unknown>);\n }\n });\n\n return { tools: processedTools, renderToolCalls: processedRenderToolCalls };\n }, [humanInTheLoopList]);\n\n // Combine all tools for CopilotKitCore\n const allTools = useMemo(() => {\n const tools: FrontendTool[] = [];\n\n // Add frontend tools\n tools.push(...frontendToolsList);\n\n // Add processed human-in-the-loop tools\n tools.push(...processedHumanInTheLoopTools.tools);\n\n return tools;\n }, [frontendToolsList, 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\n frontendToolsList.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 }, [renderToolCallsList, frontendToolsList, processedHumanInTheLoopTools]);\n\n const copilotkit = useMemo(() => {\n const copilotkit = new CopilotKitCoreReact({\n runtimeUrl: chatApiEndpoint,\n runtimeTransport: useSingleEndpoint ? \"single\" : \"rest\",\n headers: mergedHeaders,\n credentials,\n properties,\n agents__unsafe_dev_only: mergedAgents,\n tools: allTools,\n renderToolCalls: allRenderToolCalls,\n renderActivityMessages: allActivityRenderers,\n renderCustomMessages: renderCustomMessagesList,\n });\n\n return copilotkit;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n allTools,\n allRenderToolCalls,\n allActivityRenderers,\n renderCustomMessagesList,\n useSingleEndpoint,\n ]);\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 useEffect(() => {\n copilotkit.setRuntimeUrl(chatApiEndpoint);\n copilotkit.setRuntimeTransport(useSingleEndpoint ? \"single\" : \"rest\");\n copilotkit.setHeaders(mergedHeaders);\n copilotkit.setCredentials(credentials);\n copilotkit.setProperties(properties);\n copilotkit.setAgents__unsafe_dev_only(mergedAgents);\n }, [\n chatApiEndpoint,\n mergedHeaders,\n credentials,\n properties,\n mergedAgents,\n useSingleEndpoint,\n ]);\n\n return (\n <CopilotKitContext.Provider\n value={{\n copilotkit,\n executingToolCallIds,\n }}\n >\n {children}\n {shouldRenderInspector ? <CopilotKitInspector core={copilotkit} /> : null}\n </CopilotKitContext.Provider>\n );\n};\n\n// Hook to use the CopilotKit instance - returns the full context value\nexport const useCopilotKit = (): CopilotKitContextValue => {\n const context = useContext(CopilotKitContext);\n const [, forceUpdate] = useReducer((x) => x + 1, 0);\n\n if (!context) {\n throw new Error(\"useCopilotKit must be used within CopilotKitProvider\");\n }\n useEffect(() => {\n const subscription = context.copilotkit.subscribe({\n onRuntimeConnectionStatusChanged: () => {\n forceUpdate();\n },\n });\n return () => {\n subscription.unsubscribe();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return context;\n};\n","import React, { useCallback, useMemo, useSyncExternalStore } from \"react\";\nimport { ToolCall, ToolMessage } from \"@ag-ui/core\";\nimport { ToolCallStatus } from \"@copilotkitnext/core\";\nimport { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport { useCopilotChatConfiguration } from \"@/providers/CopilotChatConfigurationProvider\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkitnext/shared\";\nimport { partialJSONParse } from \"@copilotkitnext/shared\";\nimport { ReactToolCallRenderer } from \"@/types/react-tool-call-renderer\";\n\nexport interface UseRenderToolCallProps {\n toolCall: ToolCall;\n toolMessage?: ToolMessage;\n}\n\n/**\n * Props for the memoized ToolCallRenderer component\n */\ninterface ToolCallRendererProps {\n toolCall: ToolCall;\n toolMessage?: ToolMessage;\n RenderComponent: ReactToolCallRenderer<unknown>[\"render\"];\n isExecuting: boolean;\n}\n\n/**\n * Memoized component that renders a single tool call.\n * This prevents unnecessary re-renders when parent components update\n * but the tool call data hasn't changed.\n */\nconst ToolCallRenderer = React.memo(\n function ToolCallRenderer({\n toolCall,\n toolMessage,\n RenderComponent,\n isExecuting,\n }: ToolCallRendererProps) {\n // Memoize args based on the arguments string to maintain stable reference\n const args = useMemo(\n () => partialJSONParse(toolCall.function.arguments),\n [toolCall.function.arguments],\n );\n\n const toolName = toolCall.function.name;\n\n // Render based on status to preserve discriminated union type inference\n if (toolMessage) {\n return (\n <RenderComponent\n name={toolName}\n args={args}\n status={ToolCallStatus.Complete}\n result={toolMessage.content}\n />\n );\n } else if (isExecuting) {\n return (\n <RenderComponent\n name={toolName}\n args={args}\n status={ToolCallStatus.Executing}\n result={undefined}\n />\n );\n } else {\n return (\n <RenderComponent\n name={toolName}\n args={args}\n status={ToolCallStatus.InProgress}\n result={undefined}\n />\n );\n }\n },\n // Custom comparison function to prevent re-renders when tool call data hasn't changed\n (prevProps, nextProps) => {\n // Compare tool call identity and content\n if (prevProps.toolCall.id !== nextProps.toolCall.id) return false;\n if (prevProps.toolCall.function.name !== nextProps.toolCall.function.name)\n return false;\n if (\n prevProps.toolCall.function.arguments !==\n nextProps.toolCall.function.arguments\n )\n return false;\n\n // Compare tool message (result)\n const prevResult = prevProps.toolMessage?.content;\n const nextResult = nextProps.toolMessage?.content;\n if (prevResult !== nextResult) return false;\n\n // Compare executing state\n if (prevProps.isExecuting !== nextProps.isExecuting) return false;\n\n // Compare render component reference\n if (prevProps.RenderComponent !== nextProps.RenderComponent) return false;\n\n return true;\n },\n);\n\n/**\n * Hook that returns a function to render tool calls based on the render functions\n * defined in CopilotKitProvider.\n *\n * @returns A function that takes a tool call and optional tool message and returns the rendered component\n */\nexport function useRenderToolCall() {\n const { copilotkit, executingToolCallIds } = useCopilotKit();\n const config = useCopilotChatConfiguration();\n const agentId = config?.agentId ?? DEFAULT_AGENT_ID;\n\n // Subscribe to render tool calls changes using useSyncExternalStore\n // This ensures we always have the latest value, even if subscriptions run in any order\n const renderToolCalls = useSyncExternalStore(\n (callback) => {\n return copilotkit.subscribe({\n onRenderToolCallsChanged: callback,\n }).unsubscribe;\n },\n () => copilotkit.renderToolCalls,\n () => copilotkit.renderToolCalls,\n );\n\n // Note: executingToolCallIds is now provided by CopilotKitProvider context.\n // This is critical for HITL reconnection: when connecting to a thread with\n // pending tool calls, the onToolExecutionStart event fires before child components\n // mount. By tracking at the provider level, the executing state is already\n // available when this hook first runs.\n\n const renderToolCall = useCallback(\n ({\n toolCall,\n toolMessage,\n }: UseRenderToolCallProps): React.ReactElement | null => {\n // Find the render config for this tool call by name\n // For rendering, we show all tool calls regardless of agentId\n // The agentId scoping only affects handler execution (in core)\n // Priority order:\n // 1. Exact match by name (prefer agent-specific if multiple exist)\n // 2. Wildcard (*) renderer\n const exactMatches = renderToolCalls.filter(\n (rc) => rc.name === toolCall.function.name,\n );\n\n // If multiple renderers with same name exist, prefer the one matching our agentId\n const renderConfig =\n exactMatches.find((rc) => rc.agentId === agentId) ||\n exactMatches.find((rc) => !rc.agentId) ||\n exactMatches[0] ||\n renderToolCalls.find((rc) => rc.name === \"*\");\n\n if (!renderConfig) {\n return null;\n }\n\n const RenderComponent = renderConfig.render;\n const isExecuting = executingToolCallIds.has(toolCall.id);\n\n // Use the memoized ToolCallRenderer component to prevent unnecessary re-renders\n return (\n <ToolCallRenderer\n key={toolCall.id}\n toolCall={toolCall}\n toolMessage={toolMessage}\n RenderComponent={RenderComponent}\n isExecuting={isExecuting}\n />\n );\n },\n [renderToolCalls, executingToolCallIds, agentId],\n );\n\n return renderToolCall;\n}\n","import { 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 throw new Error(\"Agent not found\");\n }\n\n const messagesIdsInRun = resolvedRunId\n ? agent.messages\n .filter(\n (msg) =>\n copilotkit.getRunIdForMessage(agentId, threadId, msg.id) ===\n resolvedRunId,\n )\n .map((msg) => msg.id)\n : [message.id];\n\n const rawMessageIndex = agent.messages.findIndex(\n (msg) => msg.id === message.id,\n );\n const messageIndex = rawMessageIndex >= 0 ? rawMessageIndex : 0;\n const messageIndexInRun = resolvedRunId\n ? Math.max(messagesIdsInRun.indexOf(message.id), 0)\n : 0;\n const numberOfMessagesInRun = resolvedRunId ? messagesIdsInRun.length : 1;\n const stateSnapshot = resolvedRunId\n ? copilotkit.getStateByRun(agentId, threadId, resolvedRunId)\n : undefined;\n\n let result = null;\n for (const renderer of customMessageRenderers) {\n if (!renderer.render) {\n continue;\n }\n const Component = renderer.render;\n result = (\n <Component\n key={`${runId}-${message.id}-${position}`}\n message={message}\n position={position}\n runId={runId}\n messageIndex={messageIndex}\n messageIndexInRun={messageIndexInRun}\n numberOfMessagesInRun={numberOfMessagesInRun}\n agentId={agentId}\n stateSnapshot={stateSnapshot}\n />\n );\n if (result) {\n break;\n }\n }\n return result;\n };\n}\n","import { ActivityMessage } from \"@ag-ui/core\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkitnext/shared\";\nimport { useCopilotKit, useCopilotChatConfiguration } from \"@/providers\";\nimport { useCallback, useMemo } from \"react\";\nimport { ReactActivityMessageRenderer } from \"@/types\";\n\nexport function useRenderActivityMessage() {\n const { copilotkit } = useCopilotKit();\n const config = useCopilotChatConfiguration();\n const agentId = config?.agentId ?? DEFAULT_AGENT_ID;\n\n const renderers = copilotkit.renderActivityMessages;\n\n // Find the renderer for a given activity type\n const findRenderer = useCallback(\n (activityType: string): ReactActivityMessageRenderer<unknown> | null => {\n if (!renderers.length) {\n return null;\n }\n\n const matches = renderers.filter(\n (renderer) => renderer.activityType === activityType,\n );\n\n return (\n matches.find((candidate) => candidate.agentId === agentId) ??\n matches.find((candidate) => candidate.agentId === undefined) ??\n renderers.find((candidate) => candidate.activityType === \"*\") ??\n null\n );\n },\n [agentId, renderers],\n );\n\n const renderActivityMessage = useCallback(\n (message: ActivityMessage): React.ReactElement | null => {\n const renderer = findRenderer(message.activityType);\n\n if (!renderer) {\n return null;\n }\n\n const parseResult = renderer.content.safeParse(message.content);\n\n if (!parseResult.success) {\n console.warn(\n `Failed to parse content for activity message '${message.activityType}':`,\n parseResult.error,\n );\n return null;\n }\n\n const Component = renderer.render;\n const agent = copilotkit.getAgent(agentId);\n\n return (\n <Component\n key={message.id}\n activityType={message.activityType}\n content={parseResult.data}\n message={message}\n agent={agent}\n />\n );\n },\n [agentId, copilotkit, findRenderer],\n );\n\n return useMemo(\n () => ({ renderActivityMessage, findRenderer }),\n [renderActivityMessage, findRenderer],\n );\n}\n","import { useEffect } from \"react\";\nimport { useCopilotKit } from \"../providers/CopilotKitProvider\";\nimport type { ReactFrontendTool } from \"../types/frontend-tool\";\nimport type { ReactToolCallRenderer } from \"../types/react-tool-call-renderer\";\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 if (tool.render) {\n // Get current render tool calls and merge with new entry\n const keyOf = (rc: ReactToolCallRenderer) =>\n `${rc.agentId ?? \"\"}:${rc.name}`;\n const currentRenderToolCalls =\n copilotkit.renderToolCalls as ReactToolCallRenderer[];\n\n // Build map from existing entries\n const mergedMap = new Map<string, ReactToolCallRenderer>();\n for (const rc of currentRenderToolCalls) {\n mergedMap.set(keyOf(rc), rc);\n }\n\n // Add/overwrite with new entry\n const newEntry: ReactToolCallRenderer = {\n name,\n args: tool.parameters,\n agentId: tool.agentId,\n render: tool.render,\n } as ReactToolCallRenderer;\n mergedMap.set(keyOf(newEntry), newEntry);\n\n // Set the merged list back\n copilotkit.setRenderToolCalls(Array.from(mergedMap.values()));\n }\n\n return () => {\n copilotkit.removeTool(name, tool.agentId);\n // we are intentionally not removing the render here so that the tools can still render in the chat history\n };\n // Depend on stable keys by default and allow callers to opt into\n // additional dependencies for dynamic tool configuration.\n // tool.available is included so toggling availability re-registers the tool.\n }, [tool.name, tool.available, copilotkit, extraDeps.length, ...extraDeps]);\n}\n","import { z } from \"zod\";\nimport type { ComponentType } from \"react\";\nimport { useFrontendTool } from \"./use-frontend-tool\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferRenderProps<T> = T extends z.ZodTypeAny ? z.infer<T> : 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 Zod parameters,\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 * via `z.infer`. When omitted, the render component may accept any props.\n *\n * @typeParam TSchema - Zod 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 z.ZodTypeAny | undefined = undefined,\n>(\n config: {\n name: string;\n description?: string;\n parameters?: TSchema;\n render: ComponentType<NoInfer<InferRenderProps<TSchema>>>;\n agentId?: string;\n },\n deps?: ReadonlyArray<unknown>,\n): void {\n const prefix = `Use this tool to display the \"${config.name}\" component in the chat. This tool renders a visual UI component for the user.`;\n const fullDescription = config.description\n ? `${prefix}\\n\\n${config.description}`\n : prefix;\n\n useFrontendTool(\n {\n name: config.name,\n description: fullDescription,\n parameters: config.parameters,\n render: ({ args }: { args: unknown }) => {\n const Component = config.render;\n return <Component {...(args as InferRenderProps<TSchema>)} />;\n },\n agentId: config.agentId,\n },\n deps,\n );\n}\n","import React from \"react\";\nimport { z } from \"zod\";\nimport { ReactToolCallRenderer } from \"./react-tool-call-renderer\";\nimport { ToolCallStatus } from \"@copilotkitnext/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 Zod schema.\n * - Ensures the render function param type exactly matches ReactToolCallRenderer<T>[\"render\"]'s param.\n * - For wildcard tools (name: \"*\"), args is optional and defaults to z.any()\n */\ntype RenderProps<T> =\n | {\n name: string;\n args: Partial<T>;\n status: ToolCallStatus.InProgress;\n result: undefined;\n }\n | {\n name: string;\n args: T;\n status: ToolCallStatus.Executing;\n result: undefined;\n }\n | {\n name: string;\n args: T;\n status: ToolCallStatus.Complete;\n result: string;\n };\n\n// Overload for wildcard tools without args\nexport function defineToolCallRenderer(def: {\n name: \"*\";\n render: (props: RenderProps<any>) => React.ReactElement;\n agentId?: string;\n}): ReactToolCallRenderer<any>;\n\n// Overload for regular tools with args\nexport function defineToolCallRenderer<S extends z.ZodTypeAny>(def: {\n name: string;\n args: S;\n render: (props: RenderProps<z.infer<S>>) => React.ReactElement;\n agentId?: string;\n}): ReactToolCallRenderer<z.infer<S>>;\n\n// Implementation\nexport function defineToolCallRenderer<S extends z.ZodTypeAny>(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 as any,\n render: def.render as React.ComponentType<any>,\n ...(def.agentId ? { agentId: def.agentId } : {}),\n };\n}\n","import { useEffect } from \"react\";\nimport type { z } from \"zod\";\nimport { useCopilotKit } from \"../providers/CopilotKitProvider\";\nimport { defineToolCallRenderer } from \"../types/defineToolCallRenderer\";\nimport type { ReactToolCallRenderer } from \"../types/react-tool-call-renderer\";\n\nconst EMPTY_DEPS: ReadonlyArray<unknown> = [];\n\nexport interface RenderToolInProgressProps<S extends z.ZodTypeAny> {\n name: string;\n parameters: Partial<z.infer<S>>;\n status: \"inProgress\";\n result: undefined;\n}\n\nexport interface RenderToolExecutingProps<S extends z.ZodTypeAny> {\n name: string;\n parameters: z.infer<S>;\n status: \"executing\";\n result: undefined;\n}\n\nexport interface RenderToolCompleteProps<S extends z.ZodTypeAny> {\n name: string;\n parameters: z.infer<S>;\n status: \"complete\";\n result: string;\n}\n\nexport type RenderToolProps<S extends z.ZodTypeAny> =\n | RenderToolInProgressProps<S>\n | RenderToolExecutingProps<S>\n | RenderToolCompleteProps<S>;\n\ntype RenderToolConfig<S extends z.ZodTypeAny> = {\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` Zod schema defines the typed shape of `props.parameters`\n * in `render` for `executing` and `complete` states.\n *\n * @typeParam S - Zod 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 z.ZodTypeAny>(\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 - Zod 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 z.ZodTypeAny>(\n config: RenderToolConfig<S>,\n deps?: ReadonlyArray<unknown>,\n): void {\n const { copilotkit } = useCopilotKit();\n const extraDeps = deps ?? EMPTY_DEPS;\n\n useEffect(() => {\n // Build the ReactToolCallRenderer via defineToolCallRenderer\n const renderer =\n config.name === \"*\" && !config.parameters\n ? defineToolCallRenderer({\n name: \"*\",\n render: (props) =>\n config.render({ ...props, parameters: props.args }),\n ...(config.agentId ? { agentId: config.agentId } : {}),\n })\n : defineToolCallRenderer({\n name: config.name,\n args: config.parameters!,\n render: (props) =>\n config.render({ ...props, parameters: props.args }),\n ...(config.agentId ? { agentId: config.agentId } : {}),\n });\n\n // Dedupe by \"agentId:name\" key, same pattern as useFrontendTool\n const keyOf = (rc: ReactToolCallRenderer) =>\n `${rc.agentId ?? \"\"}:${rc.name}`;\n const currentRenderToolCalls =\n copilotkit.renderToolCalls as ReactToolCallRenderer[];\n\n const mergedMap = new Map<string, ReactToolCallRenderer>();\n for (const rc of currentRenderToolCalls) {\n mergedMap.set(keyOf(rc), rc);\n }\n\n mergedMap.set(keyOf(renderer), renderer);\n\n copilotkit.setRenderToolCalls(Array.from(mergedMap.values()));\n\n // No cleanup removal — keeps renderer for chat history, same as useFrontendTool\n }, [config.name, copilotkit, extraDeps.length, ...extraDeps]);\n}\n","import React, { useState } from \"react\";\nimport { useRenderTool } from \"./use-render-tool\";\n\ntype DefaultRenderProps = {\n /** The name of the tool being called. */\n name: string;\n /** The parsed parameters passed to the tool call. */\n parameters: unknown;\n /** Current execution status of the tool call. */\n status: \"inProgress\" | \"executing\" | \"complete\";\n /** The tool call result string, available only when `status` is `\"complete\"`. */\n result: string | undefined;\n};\n\n/**\n * Registers a wildcard (`\"*\"`) tool-call renderer via `useRenderTool`.\n *\n * - Call with no config to use CopilotKit's built-in default tool-call card.\n * - Pass `config.render` to replace the default UI with your own fallback renderer.\n *\n * This is useful when you want a generic renderer for tools that do not have a\n * dedicated `useRenderTool({ name: \"...\" })` registration.\n *\n * @param config - Optional custom wildcard render function.\n * @param deps - Optional dependencies to refresh registration.\n *\n * @example\n * ```tsx\n * useDefaultRenderTool();\n * ```\n *\n * @example\n * ```tsx\n * useDefaultRenderTool({\n * render: ({ name, status }) => <div>{name}: {status}</div>,\n * });\n * ```\n *\n * @example\n * ```tsx\n * useDefaultRenderTool(\n * {\n * render: ({ name, result }) => (\n * <ToolEventRow title={name} payload={result} compact={compactMode} />\n * ),\n * },\n * [compactMode],\n * );\n * ```\n */\nexport function useDefaultRenderTool(\n config?: {\n render?: (props: DefaultRenderProps) => React.ReactElement;\n },\n deps?: ReadonlyArray<unknown>,\n): void {\n useRenderTool(\n {\n name: \"*\",\n render: config?.render ?? DefaultToolCallRenderer,\n },\n deps,\n );\n}\n\nfunction DefaultToolCallRenderer({\n name,\n parameters,\n status,\n result,\n}: DefaultRenderProps): React.ReactElement {\n const [isExpanded, setIsExpanded] = useState(false);\n\n const statusString = String(status) as\n | \"inProgress\"\n | \"executing\"\n | \"complete\";\n const isActive =\n statusString === \"inProgress\" || statusString === \"executing\";\n const isComplete = statusString === \"complete\";\n\n const statusLabel = isActive ? \"Running\" : isComplete ? \"Done\" : status;\n const dotColor = isActive ? \"#f59e0b\" : isComplete ? \"#10b981\" : \"#a1a1aa\";\n const badgeBg = isActive ? \"#fef3c7\" : isComplete ? \"#d1fae5\" : \"#f4f4f5\";\n const badgeColor = isActive ? \"#92400e\" : isComplete ? \"#065f46\" : \"#3f3f46\";\n\n return (\n <div\n style={{\n marginTop: \"8px\",\n paddingBottom: \"8px\",\n }}\n >\n <div\n style={{\n borderRadius: \"12px\",\n border: \"1px solid #e4e4e7\",\n backgroundColor: \"#fafafa\",\n padding: \"14px 16px\",\n }}\n >\n {/* Header row — always visible */}\n <div\n onClick={() => setIsExpanded(!isExpanded)}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: \"10px\",\n cursor: \"pointer\",\n userSelect: \"none\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n minWidth: 0,\n }}\n >\n <svg\n style={{\n height: \"14px\",\n width: \"14px\",\n color: \"#71717a\",\n transition: \"transform 0.15s\",\n transform: isExpanded ? \"rotate(90deg)\" : \"rotate(0deg)\",\n flexShrink: 0,\n }}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n strokeWidth={2}\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M8.25 4.5l7.5 7.5-7.5 7.5\"\n />\n </svg>\n <span\n style={{\n display: \"inline-block\",\n height: \"8px\",\n width: \"8px\",\n borderRadius: \"50%\",\n backgroundColor: dotColor,\n flexShrink: 0,\n }}\n />\n <span\n style={{\n fontSize: \"13px\",\n fontWeight: 600,\n color: \"#18181b\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {name}\n </span>\n </div>\n\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n borderRadius: \"9999px\",\n padding: \"2px 8px\",\n fontSize: \"11px\",\n fontWeight: 500,\n backgroundColor: badgeBg,\n color: badgeColor,\n flexShrink: 0,\n }}\n >\n {statusLabel}\n </span>\n </div>\n\n {/* Expandable details */}\n {isExpanded && (\n <div style={{ marginTop: \"12px\", display: \"grid\", gap: \"12px\" }}>\n <div>\n <div\n style={{\n fontSize: \"10px\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.05em\",\n color: \"#71717a\",\n }}\n >\n Arguments\n </div>\n <pre\n style={{\n marginTop: \"6px\",\n maxHeight: \"200px\",\n overflow: \"auto\",\n borderRadius: \"6px\",\n backgroundColor: \"#f4f4f5\",\n padding: \"10px\",\n fontSize: \"11px\",\n lineHeight: 1.6,\n color: \"#27272a\",\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n }}\n >\n {JSON.stringify(parameters ?? {}, null, 2)}\n </pre>\n </div>\n\n {result !== undefined && (\n <div>\n <div\n style={{\n fontSize: \"10px\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.05em\",\n color: \"#71717a\",\n }}\n >\n Result\n </div>\n <pre\n style={{\n marginTop: \"6px\",\n maxHeight: \"200px\",\n overflow: \"auto\",\n borderRadius: \"6px\",\n backgroundColor: \"#f4f4f5\",\n padding: \"10px\",\n fontSize: \"11px\",\n lineHeight: 1.6,\n color: \"#27272a\",\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n }}\n >\n {typeof result === \"string\"\n ? result\n : JSON.stringify(result, null, 2)}\n </pre>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n}\n","import { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport type { ReactFrontendTool } from \"@/types/frontend-tool\";\nimport type { ReactHumanInTheLoop } from \"@/types/human-in-the-loop\";\nimport type { ReactToolCallRenderer } from \"@/types/react-tool-call-renderer\";\nimport { useCallback, useEffect, useRef } from \"react\";\nimport React from \"react\";\nimport { useFrontendTool } from \"./use-frontend-tool\";\n\nexport function useHumanInTheLoop<\n T extends Record<string, unknown> = Record<string, unknown>,\n>(tool: ReactHumanInTheLoop<T>, deps?: ReadonlyArray<unknown>) {\n const { copilotkit } = useCopilotKit();\n const resolvePromiseRef = useRef<((result: unknown) => void) | null>(null);\n\n const respond = useCallback(async (result: unknown) => {\n if (resolvePromiseRef.current) {\n resolvePromiseRef.current(result);\n resolvePromiseRef.current = null;\n }\n }, []);\n\n const handler = useCallback(async () => {\n return new Promise((resolve) => {\n resolvePromiseRef.current = resolve;\n });\n }, []);\n\n const RenderComponent: ReactToolCallRenderer<T>[\"render\"] = useCallback(\n (props) => {\n const ToolComponent = tool.render;\n\n // Enhance props based on current status\n if (props.status === \"inProgress\") {\n const enhancedProps = {\n ...props,\n name: tool.name,\n description: tool.description || \"\",\n respond: undefined,\n };\n return React.createElement(ToolComponent, enhancedProps);\n } else if (props.status === \"executing\") {\n const enhancedProps = {\n ...props,\n name: tool.name,\n description: tool.description || \"\",\n respond,\n };\n return React.createElement(ToolComponent, enhancedProps);\n } else if (props.status === \"complete\") {\n const enhancedProps = {\n ...props,\n name: tool.name,\n description: tool.description || \"\",\n respond: undefined,\n };\n return React.createElement(ToolComponent, enhancedProps);\n }\n\n // Fallback - just render with original props\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return React.createElement(ToolComponent, props as any);\n },\n [tool.render, tool.name, tool.description, respond],\n );\n\n const frontendTool: ReactFrontendTool<T> = {\n ...tool,\n handler,\n render: RenderComponent,\n };\n\n useFrontendTool(frontendTool, deps);\n\n // Human-in-the-loop tools should remove their renderer on unmount\n // since they can't respond to user interactions anymore\n useEffect(() => {\n return () => {\n const keyOf = (rc: ReactToolCallRenderer<any>) =>\n `${rc.agentId ?? \"\"}:${rc.name}`;\n const currentRenderToolCalls =\n copilotkit.renderToolCalls as ReactToolCallRenderer<any>[];\n const filtered = currentRenderToolCalls.filter(\n (rc) =>\n keyOf(rc) !==\n keyOf({ name: tool.name, agentId: tool.agentId } as any),\n );\n copilotkit.setRenderToolCalls(filtered);\n };\n }, [copilotkit, tool.name, tool.agentId]);\n}\n","import { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport { useMemo, useEffect, useReducer } from \"react\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkitnext/shared\";\nimport { AbstractAgent } from \"@ag-ui/client\";\nimport {\n ProxiedCopilotRuntimeAgent,\n CopilotKitCoreRuntimeConnectionStatus,\n} from \"@copilotkitnext/core\";\n\nexport enum UseAgentUpdate {\n OnMessagesChanged = \"OnMessagesChanged\",\n OnStateChanged = \"OnStateChanged\",\n OnRunStatusChanged = \"OnRunStatusChanged\",\n}\n\nconst ALL_UPDATES: UseAgentUpdate[] = [\n UseAgentUpdate.OnMessagesChanged,\n UseAgentUpdate.OnStateChanged,\n UseAgentUpdate.OnRunStatusChanged,\n];\n\nexport interface UseAgentProps {\n agentId?: string;\n updates?: UseAgentUpdate[];\n}\n\nexport function useAgent({ agentId, updates }: UseAgentProps = {}) {\n agentId ??= DEFAULT_AGENT_ID;\n\n const { copilotkit } = useCopilotKit();\n const [, forceUpdate] = useReducer((x) => x + 1, 0);\n\n const updateFlags = useMemo(\n () => updates ?? ALL_UPDATES,\n [JSON.stringify(updates)],\n );\n\n const agent: AbstractAgent = useMemo(() => {\n const existing = copilotkit.getAgent(agentId);\n if (existing) {\n return existing;\n }\n\n const isRuntimeConfigured = copilotkit.runtimeUrl !== undefined;\n const status = copilotkit.runtimeConnectionStatus;\n\n // While runtime is not yet synced, return a provisional runtime agent\n if (\n isRuntimeConfigured &&\n (status === CopilotKitCoreRuntimeConnectionStatus.Disconnected ||\n status === CopilotKitCoreRuntimeConnectionStatus.Connecting)\n ) {\n const provisional = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: copilotkit.runtimeUrl,\n agentId,\n transport: copilotkit.runtimeTransport,\n });\n // Apply current headers so runs/connects inherit them\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (provisional as any).headers = { ...copilotkit.headers };\n return provisional;\n }\n\n // If no runtime is configured (dev/local), return a no-op agent to satisfy the\n // non-undefined contract without forcing network behavior.\n // After runtime has synced (Connected or Error) or no runtime configured and the agent doesn't exist, throw a descriptive error\n const knownAgents = Object.keys(copilotkit.agents ?? {});\n const runtimePart = isRuntimeConfigured\n ? `runtimeUrl=${copilotkit.runtimeUrl}`\n : \"no runtimeUrl\";\n throw new Error(\n `useAgent: Agent '${agentId}' not found after runtime sync (${runtimePart}). ` +\n (knownAgents.length\n ? `Known agents: [${knownAgents.join(\", \")}]`\n : \"No agents registered.\") +\n \" Verify your runtime /info and/or agents__unsafe_dev_only.\",\n );\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n agentId,\n copilotkit.agents,\n copilotkit.runtimeConnectionStatus,\n copilotkit.runtimeUrl,\n copilotkit.runtimeTransport,\n JSON.stringify(copilotkit.headers),\n copilotkit,\n ]);\n\n useEffect(() => {\n if (updateFlags.length === 0) {\n return;\n }\n\n const handlers: Parameters<AbstractAgent[\"subscribe\"]>[0] = {};\n\n if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) {\n // Content stripping for immutableContent renderers is handled by CopilotKitCoreReact\n handlers.onMessagesChanged = () => {\n forceUpdate();\n };\n }\n\n if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) {\n handlers.onStateChanged = forceUpdate;\n }\n\n if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {\n handlers.onRunInitialized = forceUpdate;\n handlers.onRunFinalized = forceUpdate;\n handlers.onRunFailed = forceUpdate;\n }\n\n const subscription = agent.subscribe(handlers);\n return () => subscription.unsubscribe();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agent, forceUpdate, JSON.stringify(updateFlags)]);\n\n return {\n agent,\n };\n}\n","import { useCopilotKit } from \"../providers/CopilotKitProvider\";\nimport { useEffect, 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 useEffect(() => {\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 \"@copilotkitnext/core\";\nimport { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport { useCopilotChatConfiguration } from \"@/providers/CopilotChatConfigurationProvider\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkitnext/shared\";\n\nexport interface UseSuggestionsOptions {\n agentId?: string;\n}\n\nexport interface UseSuggestionsResult {\n suggestions: Suggestion[];\n reloadSuggestions: () => void;\n clearSuggestions: () => void;\n isLoading: boolean;\n}\n\nexport function useSuggestions({\n agentId,\n}: UseSuggestionsOptions = {}): UseSuggestionsResult {\n const { copilotkit } = useCopilotKit();\n const config = useCopilotChatConfiguration();\n const resolvedAgentId = useMemo(\n () => agentId ?? config?.agentId ?? DEFAULT_AGENT_ID,\n [agentId, config?.agentId],\n );\n\n const [suggestions, setSuggestions] = useState<Suggestion[]>(() => {\n const result = copilotkit.getSuggestions(resolvedAgentId);\n return result.suggestions;\n });\n const [isLoading, setIsLoading] = useState(() => {\n const result = copilotkit.getSuggestions(resolvedAgentId);\n return result.isLoading;\n });\n\n useEffect(() => {\n const result = copilotkit.getSuggestions(resolvedAgentId);\n setSuggestions(result.suggestions);\n setIsLoading(result.isLoading);\n }, [copilotkit, resolvedAgentId]);\n\n useEffect(() => {\n const subscription = copilotkit.subscribe({\n onSuggestionsChanged: ({ agentId: changedAgentId, suggestions }) => {\n if (changedAgentId !== resolvedAgentId) {\n return;\n }\n setSuggestions(suggestions);\n },\n onSuggestionsStartedLoading: ({ agentId: changedAgentId }) => {\n if (changedAgentId !== resolvedAgentId) {\n return;\n }\n setIsLoading(true);\n },\n onSuggestionsFinishedLoading: ({ agentId: changedAgentId }) => {\n if (changedAgentId !== resolvedAgentId) {\n return;\n }\n setIsLoading(false);\n },\n onSuggestionsConfigChanged: () => {\n const result = copilotkit.getSuggestions(resolvedAgentId);\n setSuggestions(result.suggestions);\n setIsLoading(result.isLoading);\n },\n });\n\n return () => {\n subscription.unsubscribe();\n };\n }, [copilotkit, resolvedAgentId]);\n\n const reloadSuggestions = useCallback(() => {\n copilotkit.reloadSuggestions(resolvedAgentId);\n // Loading state is handled by onSuggestionsStartedLoading event\n }, [copilotkit, resolvedAgentId]);\n\n const clearSuggestions = useCallback(() => {\n copilotkit.clearSuggestions(resolvedAgentId);\n // State updates are handled by onSuggestionsChanged event\n }, [copilotkit, resolvedAgentId]);\n\n return {\n suggestions,\n reloadSuggestions,\n clearSuggestions,\n isLoading,\n };\n}\n","import { useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport { useCopilotChatConfiguration } from \"@/providers/CopilotChatConfigurationProvider\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkitnext/shared\";\nimport {\n DynamicSuggestionsConfig,\n StaticSuggestionsConfig,\n SuggestionsConfig,\n Suggestion,\n} from \"@copilotkitnext/core\";\n\ntype StaticSuggestionInput = Omit<Suggestion, \"isLoading\"> &\n Partial<Pick<Suggestion, \"isLoading\">>;\n\ntype StaticSuggestionsConfigInput = Omit<\n StaticSuggestionsConfig,\n \"suggestions\"\n> & {\n suggestions: StaticSuggestionInput[];\n};\n\ntype SuggestionsConfigInput =\n | DynamicSuggestionsConfig\n | StaticSuggestionsConfigInput;\n\nexport function useConfigureSuggestions(\n config: SuggestionsConfigInput | null | undefined,\n deps?: ReadonlyArray<unknown>,\n): void {\n const { copilotkit } = useCopilotKit();\n const chatConfig = useCopilotChatConfiguration();\n const extraDeps = deps ?? [];\n\n const resolvedConsumerAgentId = useMemo(\n () => chatConfig?.agentId ?? DEFAULT_AGENT_ID,\n [chatConfig?.agentId],\n );\n\n const rawConsumerAgentId = useMemo(\n () =>\n config ? (config as SuggestionsConfigInput).consumerAgentId : undefined,\n [config],\n );\n\n const normalizationCacheRef = useRef<{\n serialized: string | null;\n config: SuggestionsConfig | null;\n }>({\n serialized: null,\n config: null,\n });\n\n const { normalizedConfig, serializedConfig } = useMemo(() => {\n if (!config) {\n normalizationCacheRef.current = { serialized: null, config: null };\n return { normalizedConfig: null, serializedConfig: null };\n }\n\n if (config.available === \"disabled\") {\n normalizationCacheRef.current = { serialized: null, config: null };\n return { normalizedConfig: null, serializedConfig: null };\n }\n\n let built: SuggestionsConfig;\n if (isDynamicConfig(config)) {\n built = {\n ...config,\n } satisfies DynamicSuggestionsConfig;\n } else {\n const normalizedSuggestions = normalizeStaticSuggestions(\n config.suggestions,\n );\n const baseConfig: StaticSuggestionsConfig = {\n ...config,\n suggestions: normalizedSuggestions,\n };\n built = baseConfig;\n }\n\n const serialized = JSON.stringify(built);\n const cache = normalizationCacheRef.current;\n if (cache.serialized === serialized && cache.config) {\n return { normalizedConfig: cache.config, serializedConfig: serialized };\n }\n\n normalizationCacheRef.current = { serialized, config: built };\n return { normalizedConfig: built, serializedConfig: serialized };\n }, [config, resolvedConsumerAgentId, ...extraDeps]);\n const latestConfigRef = useRef<SuggestionsConfig | null>(null);\n latestConfigRef.current = normalizedConfig;\n const previousSerializedConfigRef = useRef<string | null>(null);\n\n const targetAgentId = useMemo(() => {\n if (!normalizedConfig) {\n return resolvedConsumerAgentId;\n }\n const consumer = (\n normalizedConfig as StaticSuggestionsConfig | DynamicSuggestionsConfig\n ).consumerAgentId;\n if (!consumer || consumer === \"*\") {\n return resolvedConsumerAgentId;\n }\n return consumer;\n }, [normalizedConfig, resolvedConsumerAgentId]);\n\n const isGlobalConfig =\n rawConsumerAgentId === undefined || rawConsumerAgentId === \"*\";\n\n const requestReload = useCallback(() => {\n if (!normalizedConfig) {\n return;\n }\n\n if (isGlobalConfig) {\n const agents = Object.values(copilotkit.agents ?? {});\n for (const entry of agents) {\n const agentId = entry.agentId;\n if (!agentId) {\n continue;\n }\n if (!entry.isRunning) {\n copilotkit.reloadSuggestions(agentId);\n }\n }\n return;\n }\n\n if (!targetAgentId) {\n return;\n }\n\n copilotkit.reloadSuggestions(targetAgentId);\n }, [copilotkit, isGlobalConfig, normalizedConfig, targetAgentId]);\n\n useEffect(() => {\n if (!serializedConfig || !latestConfigRef.current) {\n return;\n }\n\n const id = copilotkit.addSuggestionsConfig(latestConfigRef.current);\n\n requestReload();\n\n return () => {\n copilotkit.removeSuggestionsConfig(id);\n };\n }, [copilotkit, serializedConfig, requestReload]);\n\n useEffect(() => {\n if (!normalizedConfig) {\n previousSerializedConfigRef.current = null;\n return;\n }\n if (\n serializedConfig &&\n previousSerializedConfigRef.current === serializedConfig\n ) {\n return;\n }\n if (serializedConfig) {\n previousSerializedConfigRef.current = serializedConfig;\n }\n requestReload();\n }, [normalizedConfig, requestReload, serializedConfig]);\n\n useEffect(() => {\n if (!normalizedConfig || extraDeps.length === 0) {\n return;\n }\n requestReload();\n }, [extraDeps.length, normalizedConfig, requestReload, ...extraDeps]);\n}\n\nfunction isDynamicConfig(\n config: SuggestionsConfigInput,\n): config is DynamicSuggestionsConfig {\n return \"instructions\" in config;\n}\n\nfunction normalizeStaticSuggestions(\n suggestions: StaticSuggestionInput[],\n): Suggestion[] {\n return suggestions.map((suggestion) => ({\n ...suggestion,\n isLoading: suggestion.isLoading ?? false,\n }));\n}\n","import React, { useState, useEffect, useCallback, useMemo } from \"react\";\nimport { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport { useAgent } from \"./use-agent\";\nimport type {\n InterruptEvent,\n InterruptRenderProps,\n InterruptHandlerProps,\n} from \"../types/interrupt\";\n\nexport type { InterruptEvent, InterruptRenderProps, InterruptHandlerProps };\n\nconst INTERRUPT_EVENT_NAME = \"on_interrupt\";\n\ntype InterruptHandlerFn<TValue, TResult> = (\n props: InterruptHandlerProps<TValue>,\n) => TResult | PromiseLike<TResult>;\n\ntype InterruptResultFromHandler<THandler> = THandler extends (\n ...args: never[]\n) => infer TResult\n ? TResult extends PromiseLike<infer TResolved>\n ? TResolved | null\n : TResult | null\n : null;\n\ntype InterruptResult<TValue, TResult> = InterruptResultFromHandler<\n InterruptHandlerFn<TValue, TResult>\n>;\n\ntype InterruptRenderInChat = boolean | undefined;\n\ntype UseInterruptReturn<TRenderInChat extends InterruptRenderInChat> =\n TRenderInChat extends false\n ? React.ReactElement | null\n : TRenderInChat extends true | undefined\n ? void\n : React.ReactElement | null | void;\n\nexport function isPromiseLike<TValue>(\n value: TValue | PromiseLike<TValue>,\n): value is PromiseLike<TValue> {\n return (\n (typeof value === \"object\" || typeof value === \"function\") &&\n value !== null &&\n typeof Reflect.get(value, \"then\") === \"function\"\n );\n}\n\n/**\n * Configuration options for `useInterrupt`.\n */\ninterface UseInterruptConfigBase<TValue = unknown, TResult = never> {\n /**\n * Render function for the interrupt UI.\n *\n * This is called once an interrupt is finalized and accepted by `enabled` (if provided).\n * Use `resolve` from render props to resume the agent run with user input.\n */\n render: (\n props: InterruptRenderProps<TValue, InterruptResult<TValue, TResult>>,\n ) => React.ReactElement;\n /**\n * Optional pre-render handler invoked when an interrupt is received.\n *\n * Return either a sync value or an async value to pass into `render` as `result`.\n * Rejecting/throwing falls back to `result = null`.\n */\n handler?: InterruptHandlerFn<TValue, TResult>;\n /**\n * Optional predicate to filter which interrupts should be handled by this hook.\n * Return `false` to ignore an interrupt.\n */\n enabled?: (event: InterruptEvent<TValue>) => boolean;\n /** Optional agent id. Defaults to the current configured chat agent. */\n agentId?: string;\n}\n\nexport interface UseInterruptInChatConfig<\n TValue = unknown,\n TResult = never,\n> extends UseInterruptConfigBase<TValue, TResult> {\n /** When true (default), the interrupt UI renders inside `<CopilotChat>` automatically. Set to false to render it yourself. */\n renderInChat?: true;\n}\n\nexport interface UseInterruptExternalConfig<\n TValue = unknown,\n TResult = never,\n> extends UseInterruptConfigBase<TValue, TResult> {\n /** When true (default), the interrupt UI renders inside `<CopilotChat>` automatically. Set to false to render it yourself. */\n renderInChat: false;\n}\n\nexport interface UseInterruptDynamicConfig<\n TValue = unknown,\n TResult = never,\n> extends UseInterruptConfigBase<TValue, TResult> {\n /** Dynamic boolean mode. When non-literal, return type is a union. */\n renderInChat: boolean;\n}\n\nexport type UseInterruptConfig<\n TValue = unknown,\n TResult = never,\n TRenderInChat extends InterruptRenderInChat = undefined,\n> = UseInterruptConfigBase<TValue, TResult> & {\n /** When true (default), the interrupt UI renders inside `<CopilotChat>` automatically. Set to false to render it yourself. */\n renderInChat?: TRenderInChat;\n};\n\n/**\n * Handles agent interrupts (`on_interrupt`) with optional filtering, preprocessing, and resume behavior.\n *\n * The hook listens to custom events on the active agent, stores interrupt payloads per run,\n * and surfaces a render callback once the run finalizes. Call `resolve` from your UI to resume\n * execution with user-provided data.\n *\n * - `renderInChat: true` (default): the element is published into `<CopilotChat>` and this hook returns `void`.\n * - `renderInChat: false`: the hook returns the interrupt element so you can place it anywhere in your component tree.\n *\n * `event.value` is typed as `any` since the interrupt payload shape depends on your agent.\n * Type-narrow it in your callbacks (e.g. `handler`, `enabled`, `render`) as needed.\n *\n * @typeParam TResult - Inferred from `handler` return type. Exposed as `result` in `render`.\n * @param config - Interrupt configuration (renderer, optional handler/filter, and render mode).\n * @returns When `renderInChat` is `false`, returns the interrupt element (or `null` when idle).\n * Otherwise returns `void` and publishes the element into chat. In `render`, `result` is always\n * either the handler's resolved return value or `null` (including when no handler is provided,\n * when filtering skips the interrupt, or when handler execution fails).\n *\n * @example\n * ```tsx\n * import { useInterrupt } from \"@copilotkitnext/react\";\n *\n * function InterruptUI() {\n * useInterrupt({\n * render: ({ event, resolve }) => (\n * <div>\n * <p>{event.value.question}</p>\n * <button onClick={() => resolve({ approved: true })}>Approve</button>\n * <button onClick={() => resolve({ approved: false })}>Reject</button>\n * </div>\n * ),\n * });\n *\n * return null;\n * }\n * ```\n *\n * @example\n * ```tsx\n * import { useInterrupt } from \"@copilotkitnext/react\";\n *\n * function CustomPanel() {\n * const interruptElement = useInterrupt({\n * renderInChat: false,\n * enabled: (event) => event.value.startsWith(\"approval:\"),\n * handler: async ({ event }) => ({ label: event.value.toUpperCase() }),\n * render: ({ event, result, resolve }) => (\n * <aside>\n * <strong>{result?.label ?? \"\"}</strong>\n * <button onClick={() => resolve({ value: event.value })}>Continue</button>\n * </aside>\n * ),\n * });\n *\n * return <>{interruptElement}</>;\n * }\n * ```\n */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport function useInterrupt<\n TResult = never,\n TRenderInChat extends InterruptRenderInChat = undefined,\n>(\n config: UseInterruptConfig<any, TResult, TRenderInChat>,\n): UseInterruptReturn<TRenderInChat> {\n /* eslint-enable @typescript-eslint/no-explicit-any */\n const { copilotkit } = useCopilotKit();\n const { agent } = useAgent({ agentId: config.agentId });\n const [pendingEvent, setPendingEvent] = useState<InterruptEvent | null>(null);\n const [handlerResult, setHandlerResult] =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n useState<InterruptResult<any, TResult>>(null);\n\n useEffect(() => {\n let localInterrupt: InterruptEvent | null = null;\n\n const subscription = agent.subscribe({\n onCustomEvent: ({ event }) => {\n if (event.name === INTERRUPT_EVENT_NAME) {\n localInterrupt = { name: event.name, value: event.value };\n }\n },\n onRunStartedEvent: () => {\n localInterrupt = null;\n setPendingEvent(null);\n },\n onRunFinalized: () => {\n if (localInterrupt) {\n setPendingEvent(localInterrupt);\n localInterrupt = null;\n }\n },\n onRunFailed: () => {\n localInterrupt = null;\n },\n });\n\n return () => subscription.unsubscribe();\n }, [agent]);\n\n const resolve = useCallback(\n (response: unknown) => {\n setPendingEvent(null);\n copilotkit.runAgent({\n agent,\n forwardedProps: { command: { resume: response } },\n });\n },\n [agent, copilotkit],\n );\n\n useEffect(() => {\n // No interrupt to process — reset any stale handler result from a previous interrupt\n if (!pendingEvent) {\n setHandlerResult(null);\n return;\n }\n // Interrupt exists but the consumer's filter rejects it — treat as no-op\n if (config.enabled && !config.enabled(pendingEvent)) {\n setHandlerResult(null);\n return;\n }\n const handler = config.handler;\n // No handler provided — skip straight to rendering with a null result\n if (!handler) {\n setHandlerResult(null);\n return;\n }\n\n let cancelled = false;\n const maybePromise = handler({\n event: pendingEvent,\n resolve,\n });\n\n // If the handler returns a promise/thenable, wait for resolution before setting result.\n if (isPromiseLike(maybePromise)) {\n Promise.resolve(maybePromise)\n .then((resolved) => {\n if (!cancelled) setHandlerResult(resolved);\n })\n .catch(() => {\n if (!cancelled) setHandlerResult(null);\n });\n } else {\n setHandlerResult(maybePromise);\n }\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [pendingEvent, config.enabled, config.handler, resolve]);\n\n const element = useMemo(() => {\n if (!pendingEvent) return null;\n if (config.enabled && !config.enabled(pendingEvent)) return null;\n\n return config.render({\n event: pendingEvent,\n result: handlerResult,\n resolve,\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [pendingEvent, handlerResult, config.enabled, config.render, resolve]);\n\n // Publish to core for in-chat rendering\n useEffect(() => {\n if (config.renderInChat === false) return;\n copilotkit.setInterruptElement(element);\n return () => copilotkit.setInterruptElement(null);\n }, [element, config.renderInChat, copilotkit]);\n\n // Only return element when rendering outside chat\n if (config.renderInChat === false) {\n return element as UseInterruptReturn<TRenderInChat>;\n }\n\n return undefined as UseInterruptReturn<TRenderInChat>;\n}\n","import { useRenderToolCall } from \"@/hooks\";\nimport type { AssistantMessage, Message, ToolMessage } from \"@ag-ui/core\";\nimport React from \"react\";\n\nexport type CopilotChatToolCallsViewProps = {\n message: AssistantMessage;\n messages?: Message[];\n};\n\nexport function CopilotChatToolCallsView({\n message,\n messages = [],\n}: CopilotChatToolCallsViewProps) {\n const renderToolCall = useRenderToolCall();\n\n if (!message.toolCalls || message.toolCalls.length === 0) {\n return null;\n }\n\n return (\n <>\n {message.toolCalls.map((toolCall) => {\n const toolMessage = messages.find(\n (m) => m.role === \"tool\" && m.toolCallId === toolCall.id,\n ) as ToolMessage | undefined;\n\n return (\n <React.Fragment key={toolCall.id}>\n {renderToolCall({\n toolCall,\n toolMessage,\n })}\n </React.Fragment>\n );\n })}\n </>\n );\n}\n\nexport default CopilotChatToolCallsView;\n","import { AssistantMessage, Message } from \"@ag-ui/core\";\nimport { 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 \"katex/dist/katex.min.css\";\nimport { WithSlots, renderSlot } from \"@/lib/slots\";\nimport { Streamdown } from \"streamdown\";\nimport CopilotChatToolCallsView from \"./CopilotChatToolCallsView\";\n\nexport type CopilotChatAssistantMessageProps = WithSlots<\n {\n markdownRenderer: typeof CopilotChatAssistantMessage.MarkdownRenderer;\n toolbar: typeof CopilotChatAssistantMessage.Toolbar;\n copyButton: typeof CopilotChatAssistantMessage.CopyButton;\n thumbsUpButton: typeof CopilotChatAssistantMessage.ThumbsUpButton;\n thumbsDownButton: typeof CopilotChatAssistantMessage.ThumbsDownButton;\n readAloudButton: typeof CopilotChatAssistantMessage.ReadAloudButton;\n regenerateButton: typeof CopilotChatAssistantMessage.RegenerateButton;\n toolCallsView: typeof CopilotChatToolCallsView;\n },\n {\n onThumbsUp?: (message: AssistantMessage) => void;\n onThumbsDown?: (message: AssistantMessage) => void;\n onReadAloud?: (message: AssistantMessage) => void;\n onRegenerate?: (message: AssistantMessage) => void;\n message: AssistantMessage;\n messages?: Message[];\n isRunning?: boolean;\n additionalToolbarItems?: React.ReactNode;\n toolbarVisible?: boolean;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\nexport function CopilotChatAssistantMessage({\n message,\n messages,\n isRunning,\n onThumbsUp,\n onThumbsDown,\n onReadAloud,\n onRegenerate,\n additionalToolbarItems,\n toolbarVisible = true,\n markdownRenderer,\n toolbar,\n copyButton,\n thumbsUpButton,\n thumbsDownButton,\n readAloudButton,\n regenerateButton,\n toolCallsView,\n children,\n className,\n ...props\n}: CopilotChatAssistantMessageProps) {\n const boundMarkdownRenderer = renderSlot(\n markdownRenderer,\n CopilotChatAssistantMessage.MarkdownRenderer,\n {\n content: message.content || \"\",\n },\n );\n\n const boundCopyButton = renderSlot(\n copyButton,\n CopilotChatAssistantMessage.CopyButton,\n {\n onClick: async () => {\n if (message.content) {\n try {\n await navigator.clipboard.writeText(message.content);\n } catch (err) {\n console.error(\"Failed to copy message:\", err);\n }\n }\n },\n },\n );\n\n const boundThumbsUpButton = renderSlot(\n thumbsUpButton,\n CopilotChatAssistantMessage.ThumbsUpButton,\n {\n onClick: onThumbsUp,\n },\n );\n\n const boundThumbsDownButton = renderSlot(\n thumbsDownButton,\n CopilotChatAssistantMessage.ThumbsDownButton,\n {\n onClick: onThumbsDown,\n },\n );\n\n const boundReadAloudButton = renderSlot(\n readAloudButton,\n CopilotChatAssistantMessage.ReadAloudButton,\n {\n onClick: onReadAloud,\n },\n );\n\n const boundRegenerateButton = renderSlot(\n regenerateButton,\n CopilotChatAssistantMessage.RegenerateButton,\n {\n onClick: onRegenerate,\n },\n );\n\n const boundToolbar = renderSlot(\n toolbar,\n CopilotChatAssistantMessage.Toolbar,\n {\n children: (\n <div className=\"cpk:flex cpk:items-center cpk:gap-1\">\n {boundCopyButton}\n {(onThumbsUp || thumbsUpButton) && boundThumbsUpButton}\n {(onThumbsDown || thumbsDownButton) && boundThumbsDownButton}\n {(onReadAloud || readAloudButton) && boundReadAloudButton}\n {(onRegenerate || regenerateButton) && boundRegenerateButton}\n {additionalToolbarItems}\n </div>\n ),\n },\n );\n\n const boundToolCallsView = renderSlot(\n toolCallsView,\n CopilotChatToolCallsView,\n {\n message,\n messages,\n },\n );\n\n // Don't show toolbar if message has no content (only tool calls)\n const hasContent = !!(message.content && message.content.trim().length > 0);\n const isLatestAssistantMessage =\n message.role === \"assistant\" &&\n messages?.[messages.length - 1]?.id === message.id;\n const shouldShowToolbar =\n toolbarVisible && hasContent && !(isRunning && isLatestAssistantMessage);\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n markdownRenderer: boundMarkdownRenderer,\n toolbar: boundToolbar,\n toolCallsView: boundToolCallsView,\n copyButton: boundCopyButton,\n thumbsUpButton: boundThumbsUpButton,\n thumbsDownButton: boundThumbsDownButton,\n readAloudButton: boundReadAloudButton,\n regenerateButton: boundRegenerateButton,\n message,\n messages,\n isRunning,\n onThumbsUp,\n onThumbsDown,\n onReadAloud,\n onRegenerate,\n additionalToolbarItems,\n toolbarVisible: shouldShowToolbar,\n })}\n </div>\n );\n }\n\n return (\n <div\n data-copilotkit\n data-testid=\"copilot-assistant-message\"\n className={twMerge(className)}\n {...props}\n data-message-id={message.id}\n >\n <div className=\"cpk:prose cpk:max-w-full cpk:break-words cpk:dark:prose-invert\">\n {boundMarkdownRenderer}\n </div>\n {boundToolCallsView}\n {shouldShowToolbar && boundToolbar}\n </div>\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotChatAssistantMessage {\n export const MarkdownRenderer: React.FC<\n Omit<React.ComponentProps<typeof Streamdown>, \"children\"> & {\n content: string;\n }\n > = ({ content, className, ...props }) => (\n <Streamdown className={className} {...props}>\n {content ?? \"\"}\n </Streamdown>\n );\n\n export const Toolbar: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n className,\n ...props\n }) => (\n <div\n data-testid=\"copilot-assistant-toolbar\"\n className={twMerge(\n \"cpk:w-full cpk:bg-transparent cpk:flex cpk:items-center cpk:-ml-[5px] cpk:-mt-[0px]\",\n className,\n )}\n {...props}\n />\n );\n\n export const ToolbarButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & {\n title: string;\n children: React.ReactNode;\n }\n > = ({ title, children, ...props }) => {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"assistantMessageToolbarButton\"\n aria-label={title}\n {...props}\n >\n {children}\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">\n <p>{title}</p>\n </TooltipContent>\n </Tooltip>\n );\n };\n\n export const CopyButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, title, onClick, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n const [copied, setCopied] = useState(false);\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n\n if (onClick) {\n onClick(event);\n }\n };\n\n return (\n <ToolbarButton\n data-testid=\"copilot-copy-button\"\n title={title || labels.assistantMessageToolbarCopyMessageLabel}\n onClick={handleClick}\n className={className}\n {...props}\n >\n {copied ? (\n <Check className=\"cpk:size-[18px]\" />\n ) : (\n <Copy className=\"cpk:size-[18px]\" />\n )}\n </ToolbarButton>\n );\n };\n\n export const ThumbsUpButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-thumbs-up-button\"\n title={title || labels.assistantMessageToolbarThumbsUpLabel}\n {...props}\n >\n <ThumbsUp className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n\n export const ThumbsDownButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-thumbs-down-button\"\n title={title || labels.assistantMessageToolbarThumbsDownLabel}\n {...props}\n >\n <ThumbsDown className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n\n export const ReadAloudButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-read-aloud-button\"\n title={title || labels.assistantMessageToolbarReadAloudLabel}\n {...props}\n >\n <Volume2 className=\"cpk:size-[20px]\" />\n </ToolbarButton>\n );\n };\n\n export const RegenerateButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-regenerate-button\"\n title={title || labels.assistantMessageToolbarRegenerateLabel}\n {...props}\n >\n <RefreshCw className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n}\n\nCopilotChatAssistantMessage.MarkdownRenderer.displayName =\n \"CopilotChatAssistantMessage.MarkdownRenderer\";\nCopilotChatAssistantMessage.Toolbar.displayName =\n \"CopilotChatAssistantMessage.Toolbar\";\nCopilotChatAssistantMessage.CopyButton.displayName =\n \"CopilotChatAssistantMessage.CopyButton\";\nCopilotChatAssistantMessage.ThumbsUpButton.displayName =\n \"CopilotChatAssistantMessage.ThumbsUpButton\";\nCopilotChatAssistantMessage.ThumbsDownButton.displayName =\n \"CopilotChatAssistantMessage.ThumbsDownButton\";\nCopilotChatAssistantMessage.ReadAloudButton.displayName =\n \"CopilotChatAssistantMessage.ReadAloudButton\";\nCopilotChatAssistantMessage.RegenerateButton.displayName =\n \"CopilotChatAssistantMessage.RegenerateButton\";\n\nexport default CopilotChatAssistantMessage;\n","import { useMemo, useState } from \"react\";\nimport { Copy, Check, Edit, ChevronLeft, ChevronRight } from \"lucide-react\";\nimport {\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport { twMerge } from \"tailwind-merge\";\nimport { Button } from \"@/components/ui/button\";\nimport { UserMessage } from \"@ag-ui/core\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { renderSlot, WithSlots } from \"@/lib/slots\";\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\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 BoundMessageRenderer = renderSlot(\n messageRenderer,\n CopilotChatUserMessage.MessageRenderer,\n {\n content: flattenedContent,\n },\n );\n\n const BoundCopyButton = renderSlot(\n copyButton,\n CopilotChatUserMessage.CopyButton,\n {\n onClick: async () => {\n if (flattenedContent) {\n try {\n await navigator.clipboard.writeText(flattenedContent);\n } catch (err) {\n console.error(\"Failed to copy message:\", err);\n }\n }\n },\n },\n );\n\n const BoundEditButton = renderSlot(\n editButton,\n CopilotChatUserMessage.EditButton,\n {\n onClick: () => onEditMessage?.({ message }),\n },\n );\n\n const BoundBranchNavigation = renderSlot(\n branchNavigation,\n CopilotChatUserMessage.BranchNavigation,\n {\n currentBranch: branchIndex,\n numberOfBranches,\n onSwitchToBranch,\n message,\n },\n );\n\n const showBranchNavigation =\n numberOfBranches && numberOfBranches > 1 && onSwitchToBranch;\n\n const BoundToolbar = renderSlot(toolbar, CopilotChatUserMessage.Toolbar, {\n children: (\n <div className=\"cpk:flex cpk:items-center cpk:gap-1 cpk:justify-end\">\n {additionalToolbarItems}\n {BoundCopyButton}\n {onEditMessage && BoundEditButton}\n {showBranchNavigation && BoundBranchNavigation}\n </div>\n ),\n });\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n messageRenderer: BoundMessageRenderer,\n toolbar: BoundToolbar,\n copyButton: BoundCopyButton,\n editButton: BoundEditButton,\n branchNavigation: BoundBranchNavigation,\n message,\n branchIndex,\n numberOfBranches,\n additionalToolbarItems,\n })}\n </div>\n );\n }\n\n return (\n <div\n data-copilotkit\n data-testid=\"copilot-user-message\"\n className={twMerge(\n \"cpk:flex cpk:flex-col cpk:items-end cpk:group cpk:pt-10\",\n className,\n )}\n data-message-id={message.id}\n {...props}\n >\n {BoundMessageRenderer}\n {BoundToolbar}\n </div>\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotChatUserMessage {\n export const Container: React.FC<\n React.PropsWithChildren<React.HTMLAttributes<HTMLDivElement>>\n > = ({ children, className, ...props }) => (\n <div\n className={twMerge(\n \"cpk:flex cpk:flex-col cpk:items-end cpk:group\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n );\n\n export const MessageRenderer: React.FC<{\n content: string;\n className?: string;\n }> = ({ content, className }) => (\n <div\n className={twMerge(\n \"cpk:prose cpk:dark:prose-invert cpk:bg-muted cpk:relative cpk:max-w-[80%] cpk:rounded-[18px] cpk:px-4 cpk:py-1.5 cpk:data-[multiline]:py-3 cpk:inline-block cpk:whitespace-pre-wrap\",\n className,\n )}\n >\n {content}\n </div>\n );\n\n export const Toolbar: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n className,\n ...props\n }) => (\n <div\n data-testid=\"copilot-user-toolbar\"\n className={twMerge(\n \"cpk:w-full cpk:bg-transparent cpk:flex cpk:items-center cpk:justify-end cpk:-mr-[5px] cpk:mt-[4px] cpk:invisible cpk:group-hover:visible\",\n className,\n )}\n {...props}\n />\n );\n\n export const ToolbarButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & {\n title: string;\n children: React.ReactNode;\n }\n > = ({ title, children, className, ...props }) => {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"assistantMessageToolbarButton\"\n aria-label={title}\n className={twMerge(className)}\n {...props}\n >\n {children}\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">\n <p>{title}</p>\n </TooltipContent>\n </Tooltip>\n );\n };\n\n export const CopyButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & { copied?: boolean }\n > = ({ className, title, onClick, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n const [copied, setCopied] = useState(false);\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n\n if (onClick) {\n onClick(event);\n }\n };\n\n return (\n <ToolbarButton\n data-testid=\"copilot-user-copy-button\"\n title={title || labels.userMessageToolbarCopyMessageLabel}\n onClick={handleClick}\n className={className}\n {...props}\n >\n {copied ? (\n <Check className=\"cpk:size-[18px]\" />\n ) : (\n <Copy className=\"cpk:size-[18px]\" />\n )}\n </ToolbarButton>\n );\n };\n\n export const EditButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-edit-button\"\n title={title || labels.userMessageToolbarEditMessageLabel}\n className={className}\n {...props}\n >\n <Edit className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n\n export const BranchNavigation: React.FC<\n React.HTMLAttributes<HTMLDivElement> & {\n currentBranch?: number;\n numberOfBranches?: number;\n onSwitchToBranch?: (\n props: CopilotChatUserMessageOnSwitchToBranchProps,\n ) => void;\n message: UserMessage;\n }\n > = ({\n className,\n currentBranch = 0,\n numberOfBranches = 1,\n onSwitchToBranch,\n message,\n ...props\n }) => {\n if (!numberOfBranches || numberOfBranches <= 1 || !onSwitchToBranch) {\n return null;\n }\n\n const canGoPrev = currentBranch > 0;\n const canGoNext = currentBranch < numberOfBranches - 1;\n\n return (\n <div\n data-testid=\"copilot-branch-navigation\"\n className={twMerge(\"cpk:flex cpk:items-center cpk:gap-1\", className)}\n {...props}\n >\n <Button\n type=\"button\"\n variant=\"assistantMessageToolbarButton\"\n onClick={() =>\n onSwitchToBranch?.({\n branchIndex: currentBranch - 1,\n numberOfBranches,\n message,\n })\n }\n disabled={!canGoPrev}\n className=\"cpk:h-6 cpk:w-6 cpk:p-0\"\n >\n <ChevronLeft className=\"cpk:size-[20px]\" />\n </Button>\n <span className=\"cpk:text-sm cpk:text-muted-foreground cpk:px-0 cpk:font-medium\">\n {currentBranch + 1}/{numberOfBranches}\n </span>\n <Button\n type=\"button\"\n variant=\"assistantMessageToolbarButton\"\n onClick={() =>\n onSwitchToBranch?.({\n branchIndex: currentBranch + 1,\n numberOfBranches,\n message,\n })\n }\n disabled={!canGoNext}\n className=\"cpk:h-6 cpk:w-6 cpk:p-0\"\n >\n <ChevronRight className=\"cpk:size-[20px]\" />\n </Button>\n </div>\n );\n };\n}\n\nCopilotChatUserMessage.Container.displayName =\n \"CopilotChatUserMessage.Container\";\nCopilotChatUserMessage.MessageRenderer.displayName =\n \"CopilotChatUserMessage.MessageRenderer\";\nCopilotChatUserMessage.Toolbar.displayName = \"CopilotChatUserMessage.Toolbar\";\nCopilotChatUserMessage.ToolbarButton.displayName =\n \"CopilotChatUserMessage.ToolbarButton\";\nCopilotChatUserMessage.CopyButton.displayName =\n \"CopilotChatUserMessage.CopyButton\";\nCopilotChatUserMessage.EditButton.displayName =\n \"CopilotChatUserMessage.EditButton\";\nCopilotChatUserMessage.BranchNavigation.displayName =\n \"CopilotChatUserMessage.BranchNavigation\";\n\nexport default CopilotChatUserMessage;\n","import { ReasoningMessage, Message } from \"@ag-ui/core\";\nimport { useState, useEffect, useRef } from \"react\";\nimport { ChevronRight } from \"lucide-react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { Streamdown } from \"streamdown\";\nimport { WithSlots, renderSlot } from \"@/lib/slots\";\n\nexport type CopilotChatReasoningMessageProps = WithSlots<\n {\n header: typeof CopilotChatReasoningMessage.Header;\n contentView: typeof CopilotChatReasoningMessage.Content;\n toggle: typeof CopilotChatReasoningMessage.Toggle;\n },\n {\n message: ReasoningMessage;\n messages?: Message[];\n isRunning?: boolean;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\n/**\n * Formats an elapsed duration (in seconds) to a human-readable string.\n */\nfunction formatDuration(seconds: number): string {\n if (seconds < 1) return \"a few seconds\";\n if (seconds < 60) return `${Math.round(seconds)} seconds`;\n const mins = Math.floor(seconds / 60);\n const secs = Math.round(seconds % 60);\n if (secs === 0) return `${mins} minute${mins > 1 ? \"s\" : \"\"}`;\n return `${mins}m ${secs}s`;\n}\n\nexport function CopilotChatReasoningMessage({\n message,\n messages,\n isRunning,\n header,\n contentView,\n toggle,\n children,\n className,\n ...props\n}: CopilotChatReasoningMessageProps) {\n const isLatest = messages?.[messages.length - 1]?.id === message.id;\n const isStreaming = !!(isRunning && isLatest);\n const hasContent = !!(message.content && message.content.length > 0);\n\n // Track elapsed time while streaming\n const startTimeRef = useRef<number | null>(null);\n const [elapsed, setElapsed] = useState(0);\n\n useEffect(() => {\n if (isStreaming && startTimeRef.current === null) {\n startTimeRef.current = Date.now();\n }\n\n if (!isStreaming && startTimeRef.current !== null) {\n // Final snapshot of elapsed time\n setElapsed((Date.now() - startTimeRef.current) / 1000);\n return;\n }\n\n if (!isStreaming) return;\n\n // Tick every second while streaming\n const timer = setInterval(() => {\n if (startTimeRef.current !== null) {\n setElapsed((Date.now() - startTimeRef.current) / 1000);\n }\n }, 1000);\n return () => clearInterval(timer);\n }, [isStreaming]);\n\n // Default to open while streaming, auto-collapse when streaming ends\n const [isOpen, setIsOpen] = useState(isStreaming);\n\n useEffect(() => {\n if (isStreaming) {\n setIsOpen(true);\n } else {\n // Auto-collapse when reasoning finishes\n setIsOpen(false);\n }\n }, [isStreaming]);\n\n const label = isStreaming\n ? \"Thinking…\"\n : `Thought for ${formatDuration(elapsed)}`;\n\n const boundHeader = renderSlot(header, CopilotChatReasoningMessage.Header, {\n isOpen,\n label,\n hasContent,\n isStreaming,\n onClick: hasContent ? () => setIsOpen((prev) => !prev) : undefined,\n });\n\n const boundContent = renderSlot(\n contentView,\n CopilotChatReasoningMessage.Content,\n {\n isStreaming,\n hasContent,\n children: message.content,\n },\n );\n\n const boundToggle = renderSlot(toggle, CopilotChatReasoningMessage.Toggle, {\n isOpen,\n children: boundContent,\n });\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n header: boundHeader,\n contentView: boundContent,\n toggle: boundToggle,\n message,\n messages,\n isRunning,\n })}\n </div>\n );\n }\n\n return (\n <div\n className={twMerge(\"cpk:my-1\", className)}\n data-message-id={message.id}\n {...props}\n >\n {boundHeader}\n {boundToggle}\n </div>\n );\n}\n\nexport namespace CopilotChatReasoningMessage {\n export const Header: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & {\n isOpen?: boolean;\n label?: string;\n hasContent?: boolean;\n isStreaming?: boolean;\n }\n > = ({\n isOpen,\n label = \"Thoughts\",\n hasContent,\n isStreaming,\n className,\n children: headerChildren,\n ...headerProps\n }) => {\n const isExpandable = !!hasContent;\n\n return (\n <button\n type=\"button\"\n className={twMerge(\n \"cpk:inline-flex cpk:items-center cpk:gap-1 cpk:py-1 cpk:text-sm cpk:text-muted-foreground cpk:transition-colors cpk:select-none\",\n isExpandable\n ? \"cpk:hover:text-foreground cpk:cursor-pointer\"\n : \"cpk:cursor-default\",\n className,\n )}\n aria-expanded={isExpandable ? isOpen : undefined}\n {...headerProps}\n >\n <span className=\"cpk:font-medium\">{label}</span>\n {isStreaming && !hasContent && (\n <span className=\"cpk:inline-flex cpk:items-center cpk:ml-1\">\n <span className=\"cpk:w-1.5 cpk:h-1.5 cpk:rounded-full cpk:bg-muted-foreground cpk:animate-pulse\" />\n </span>\n )}\n {headerChildren}\n {isExpandable && (\n <ChevronRight\n className={twMerge(\n \"cpk:size-3.5 cpk:shrink-0 cpk:transition-transform cpk:duration-200\",\n isOpen && \"cpk:rotate-90\",\n )}\n />\n )}\n </button>\n );\n };\n\n export const Content: React.FC<\n React.HTMLAttributes<HTMLDivElement> & {\n isStreaming?: boolean;\n hasContent?: boolean;\n }\n > = ({\n isStreaming,\n hasContent,\n className,\n children: contentChildren,\n ...contentProps\n }) => {\n // Don't render the content area at all when there's nothing to show\n if (!hasContent && !isStreaming) return null;\n\n return (\n <div\n className={twMerge(\"cpk:pb-2 cpk:pt-1\", className)}\n {...contentProps}\n >\n <div className=\"cpk:text-sm cpk:text-muted-foreground\">\n <Streamdown>\n {typeof contentChildren === \"string\" ? contentChildren : \"\"}\n </Streamdown>\n {isStreaming && hasContent && (\n <span className=\"cpk:inline-flex cpk:items-center cpk:ml-1 cpk:align-middle\">\n <span className=\"cpk:w-2 cpk:h-2 cpk:rounded-full cpk:bg-muted-foreground cpk:animate-pulse-cursor\" />\n </span>\n )}\n </div>\n </div>\n );\n };\n\n export const Toggle: React.FC<\n React.HTMLAttributes<HTMLDivElement> & {\n isOpen?: boolean;\n }\n > = ({ isOpen, className, children: toggleChildren, ...toggleProps }) => {\n return (\n <div\n className={twMerge(\n \"cpk:grid cpk:transition-[grid-template-rows] cpk:duration-200 cpk:ease-in-out\",\n className,\n )}\n style={{ gridTemplateRows: isOpen ? \"1fr\" : \"0fr\" }}\n {...toggleProps}\n >\n <div className=\"cpk:overflow-hidden\">{toggleChildren}</div>\n </div>\n );\n };\n}\n\nCopilotChatReasoningMessage.Header.displayName =\n \"CopilotChatReasoningMessage.Header\";\nCopilotChatReasoningMessage.Content.displayName =\n \"CopilotChatReasoningMessage.Content\";\nCopilotChatReasoningMessage.Toggle.displayName =\n \"CopilotChatReasoningMessage.Toggle\";\n\nexport default CopilotChatReasoningMessage;\n","import React from \"react\";\nimport { Loader2 } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\n\nexport interface CopilotChatSuggestionPillProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Optional icon to render on the left side when not loading. */\n icon?: React.ReactNode;\n /** Whether the pill should display a loading spinner. */\n isLoading?: boolean;\n}\n\nconst baseClasses =\n \"group cpk:inline-flex cpk:h-7 cpk:sm:h-8 cpk:items-center cpk:gap-1 cpk:sm:gap-1.5 cpk:rounded-full cpk:border cpk:border-border/60 cpk:bg-background cpk:px-2.5 cpk:sm:px-3 cpk:text-[11px] cpk:sm:text-xs cpk:leading-none cpk:text-foreground cpk:transition-colors cpk:cursor-pointer cpk:hover:bg-accent/60 cpk:hover:text-foreground cpk:focus-visible:outline-none cpk:focus-visible:ring-2 cpk:focus-visible:ring-ring cpk:focus-visible:ring-offset-2 cpk:focus-visible:ring-offset-background cpk:disabled:cursor-not-allowed cpk:disabled:text-muted-foreground cpk:disabled:hover:bg-background cpk:disabled:hover:text-muted-foreground cpk:pointer-events-auto\";\n\nconst labelClasses = \"cpk:whitespace-nowrap cpk:font-medium cpk:leading-none\";\n\nexport const CopilotChatSuggestionPill = React.forwardRef<\n HTMLButtonElement,\n CopilotChatSuggestionPillProps\n>(function CopilotChatSuggestionPill(\n { className, children, icon, isLoading, type, ...props },\n ref,\n) {\n const showIcon = !isLoading && icon;\n\n return (\n <button\n ref={ref}\n data-copilotkit\n data-testid=\"copilot-suggestion\"\n data-slot=\"suggestion-pill\"\n className={cn(baseClasses, className)}\n type={type ?? \"button\"}\n aria-busy={isLoading || undefined}\n disabled={isLoading || props.disabled}\n {...props}\n >\n {isLoading ? (\n <span className=\"cpk:flex cpk:h-3.5 cpk:sm:h-4 cpk:w-3.5 cpk:sm:w-4 cpk:items-center cpk:justify-center cpk:text-muted-foreground\">\n <Loader2\n className=\"cpk:h-3.5 cpk:sm:h-4 cpk:w-3.5 cpk:sm:w-4 cpk:animate-spin\"\n aria-hidden=\"true\"\n />\n </span>\n ) : (\n showIcon && (\n <span className=\"cpk:flex cpk:h-3.5 cpk:sm:h-4 cpk:w-3.5 cpk:sm:w-4 cpk:items-center cpk:justify-center cpk:text-muted-foreground\">\n {icon}\n </span>\n )\n )}\n <span className={labelClasses}>{children}</span>\n </button>\n );\n});\n\nCopilotChatSuggestionPill.displayName = \"CopilotChatSuggestionPill\";\n\nexport default CopilotChatSuggestionPill;\n","import React from \"react\";\nimport { Suggestion } from \"@copilotkitnext/core\";\nimport { renderSlot, WithSlots } from \"@/lib/slots\";\nimport { cn } from \"@/lib/utils\";\nimport CopilotChatSuggestionPill, {\n CopilotChatSuggestionPillProps,\n} from \"./CopilotChatSuggestionPill\";\n\nconst DefaultContainer = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(function DefaultContainer({ className, ...props }, ref) {\n return (\n <div\n ref={ref}\n data-copilotkit\n data-testid=\"copilot-suggestions\"\n className={cn(\n \"cpk:flex cpk:flex-wrap cpk:items-center cpk:gap-1.5 cpk:sm:gap-2 cpk:pl-0 cpk:pr-4 cpk:sm:px-0 cpk:pointer-events-none\",\n className,\n )}\n {...props}\n />\n );\n});\n\nexport type CopilotChatSuggestionViewProps = WithSlots<\n {\n container: typeof DefaultContainer;\n suggestion: typeof CopilotChatSuggestionPill;\n },\n {\n suggestions: Suggestion[];\n onSelectSuggestion?: (suggestion: Suggestion, index: number) => void;\n loadingIndexes?: ReadonlyArray<number>;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\nexport const CopilotChatSuggestionView = React.forwardRef<\n HTMLDivElement,\n CopilotChatSuggestionViewProps\n>(function CopilotChatSuggestionView(\n {\n suggestions,\n onSelectSuggestion,\n loadingIndexes,\n container,\n suggestion: suggestionSlot,\n className,\n children,\n ...restProps\n },\n ref,\n) {\n const loadingSet = React.useMemo(() => {\n if (!loadingIndexes || loadingIndexes.length === 0) {\n return new Set<number>();\n }\n return new Set(loadingIndexes);\n }, [loadingIndexes]);\n\n const ContainerElement = renderSlot(container, DefaultContainer, {\n ref,\n className,\n ...restProps,\n });\n\n const suggestionElements = suggestions.map((suggestion, index) => {\n const isLoading = loadingSet.has(index) || suggestion.isLoading === true;\n const pill = renderSlot<\n typeof CopilotChatSuggestionPill,\n CopilotChatSuggestionPillProps\n >(suggestionSlot, CopilotChatSuggestionPill, {\n children: suggestion.title,\n 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, { useEffect, useReducer, useState } from \"react\";\nimport { WithSlots, renderSlot, isReactComponentType } from \"@/lib/slots\";\nimport CopilotChatAssistantMessage from \"./CopilotChatAssistantMessage\";\nimport CopilotChatUserMessage from \"./CopilotChatUserMessage\";\nimport CopilotChatReasoningMessage from \"./CopilotChatReasoningMessage\";\nimport {\n ActivityMessage,\n AssistantMessage,\n Message,\n ReasoningMessage,\n 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\";\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 || !nextTc) return false;\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.role === \"tool\" && toolCallIds.has((m as any).toolCallId),\n );\n const nextToolResults = nextProps.messages.filter(\n (m) => m.role === \"tool\" && toolCallIds.has((m as any).toolCallId),\n );\n\n // If number of tool results changed, re-render\n if (prevToolResults.length !== nextToolResults.length) return false;\n\n // If any tool result content changed, re-render\n for (let i = 0; i < prevToolResults.length; i++) {\n if (\n (prevToolResults[i] as any).content !==\n (nextToolResults[i] as any).content\n )\n return false;\n }\n }\n\n // Only care about isRunning if this message is CURRENTLY the latest\n // (we don't need to re-render just because a message stopped being the latest)\n const nextIsLatest =\n nextProps.messages[nextProps.messages.length - 1]?.id ===\n nextProps.message.id;\n if (nextIsLatest && prevProps.isRunning !== nextProps.isRunning)\n return false;\n\n // Check if component reference changed\n if (\n prevProps.AssistantMessageComponent !==\n nextProps.AssistantMessageComponent\n )\n return false;\n\n // Check if slot props changed\n if (prevProps.slotProps !== nextProps.slotProps) return false;\n\n return true;\n },\n);\n\n/**\n * Memoized wrapper for user messages to prevent re-renders when other messages change.\n */\nconst MemoizedUserMessage = React.memo(\n function MemoizedUserMessage({\n message,\n UserMessageComponent,\n slotProps,\n }: {\n message: UserMessage;\n UserMessageComponent: typeof CopilotChatUserMessage;\n slotProps?: Partial<React.ComponentProps<typeof CopilotChatUserMessage>>;\n }) {\n return <UserMessageComponent message={message} {...slotProps} />;\n },\n (prevProps, nextProps) => {\n // Only re-render if this specific message changed\n if (prevProps.message.id !== nextProps.message.id) return false;\n if (prevProps.message.content !== nextProps.message.content) return false;\n if (prevProps.UserMessageComponent !== nextProps.UserMessageComponent)\n return false;\n // Check if slot props changed\n if (prevProps.slotProps !== nextProps.slotProps) return false;\n return true;\n },\n);\n\n/**\n * Memoized wrapper for activity messages to prevent re-renders when other messages change.\n */\nconst MemoizedActivityMessage = React.memo(\n function MemoizedActivityMessage({\n message,\n renderActivityMessage,\n }: {\n message: ActivityMessage;\n renderActivityMessage: (\n message: ActivityMessage,\n ) => React.ReactElement | null;\n }) {\n return renderActivityMessage(message);\n },\n (prevProps, nextProps) => {\n // Message ID changed = different message, must re-render\n if (prevProps.message.id !== nextProps.message.id) return false;\n\n // Activity type changed = must re-render\n if (prevProps.message.activityType !== nextProps.message.activityType)\n return false;\n\n // Compare content using JSON.stringify (native code, handles deep comparison)\n if (\n JSON.stringify(prevProps.message.content) !==\n JSON.stringify(nextProps.message.content)\n )\n return false;\n\n return true;\n },\n);\n\n/**\n * Memoized wrapper for reasoning messages to prevent re-renders when other messages change.\n */\nconst MemoizedReasoningMessage = React.memo(\n function MemoizedReasoningMessage({\n message,\n messages,\n isRunning,\n ReasoningMessageComponent,\n slotProps,\n }: {\n message: ReasoningMessage;\n messages: Message[];\n isRunning: boolean;\n ReasoningMessageComponent: typeof CopilotChatReasoningMessage;\n slotProps?: Partial<\n React.ComponentProps<typeof CopilotChatReasoningMessage>\n >;\n }) {\n return (\n <ReasoningMessageComponent\n message={message}\n messages={messages}\n isRunning={isRunning}\n {...slotProps}\n />\n );\n },\n (prevProps, nextProps) => {\n // Only re-render if this specific message changed\n if (prevProps.message.id !== nextProps.message.id) return false;\n if (prevProps.message.content !== nextProps.message.content) return false;\n\n // Re-render when \"latest\" status changes (e.g. reasoning message is no longer the last message\n // because a text message was added after it — this transitions isStreaming from true to false)\n const prevIsLatest =\n prevProps.messages[prevProps.messages.length - 1]?.id ===\n prevProps.message.id;\n const nextIsLatest =\n nextProps.messages[nextProps.messages.length - 1]?.id ===\n nextProps.message.id;\n if (prevIsLatest !== nextIsLatest) return false;\n\n // Only care about isRunning if this message is CURRENTLY the latest\n if (nextIsLatest && prevProps.isRunning !== nextProps.isRunning)\n return false;\n\n // Check if component reference changed\n if (\n prevProps.ReasoningMessageComponent !==\n nextProps.ReasoningMessageComponent\n )\n return false;\n\n // Check if slot props changed\n if (prevProps.slotProps !== nextProps.slotProps) return false;\n\n return true;\n },\n);\n\n/**\n * Memoized wrapper for custom messages to prevent re-renders when other messages change.\n */\nconst MemoizedCustomMessage = React.memo(\n function MemoizedCustomMessage({\n message,\n position,\n renderCustomMessage,\n }: {\n message: Message;\n position: \"before\" | \"after\";\n renderCustomMessage: (params: {\n message: Message;\n position: \"before\" | \"after\";\n }) => React.ReactElement | null;\n stateSnapshot?: unknown;\n }) {\n return renderCustomMessage({ message, position });\n },\n (prevProps, nextProps) => {\n // Only re-render if the message or position changed\n if (prevProps.message.id !== nextProps.message.id) return false;\n if (prevProps.position !== nextProps.position) return false;\n // Compare message content - for assistant messages this is a string, for others may differ\n if (prevProps.message.content !== nextProps.message.content) return false;\n if (prevProps.message.role !== nextProps.message.role) return false;\n // Compare state snapshot - custom renderers may depend on state\n if (\n JSON.stringify(prevProps.stateSnapshot) !==\n JSON.stringify(nextProps.stateSnapshot)\n )\n return false;\n // Note: We don't compare renderCustomMessage function reference because it changes\n // frequently. The message and state comparison is sufficient to determine if a re-render is needed.\n return true;\n },\n);\n\nexport type CopilotChatMessageViewProps = Omit<\n WithSlots<\n {\n assistantMessage: typeof CopilotChatAssistantMessage;\n userMessage: typeof CopilotChatUserMessage;\n reasoningMessage: typeof CopilotChatReasoningMessage;\n cursor: typeof CopilotChatMessageView.Cursor;\n },\n {\n isRunning?: boolean;\n messages?: Message[];\n } & React.HTMLAttributes<HTMLDivElement>\n >,\n \"children\"\n> & {\n children?: (props: {\n isRunning: boolean;\n messages: Message[];\n messageElements: React.ReactElement[];\n interruptElement: React.ReactElement | null;\n }) => React.ReactElement;\n};\n\nexport function CopilotChatMessageView({\n messages = [],\n assistantMessage,\n userMessage,\n reasoningMessage,\n cursor,\n isRunning = false,\n children,\n className,\n ...props\n}: CopilotChatMessageViewProps) {\n const renderCustomMessage = useRenderCustomMessages();\n const { renderActivityMessage } = useRenderActivityMessage();\n const { copilotkit } = useCopilotKit();\n const config = useCopilotChatConfiguration();\n const [, forceUpdate] = useReducer((x) => x + 1, 0);\n\n // Subscribe to state changes so custom message renderers re-render when state updates.\n useEffect(() => {\n if (!config?.agentId) return;\n const 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 // Deduplicate messages by id, keeping the last occurrence of each.\n // During streaming, AbstractAgent.addMessage() can push duplicate messages\n // (same id) which causes React \"duplicate key\" warnings and rendering glitches.\n const deduplicatedMessages = [\n ...new Map(messages.map((m) => [m.id, m])).values(),\n ];\n\n if (\n process.env.NODE_ENV === \"development\" &&\n deduplicatedMessages.length < messages.length\n ) {\n console.warn(\n `CopilotChatMessageView: Deduplicated ${messages.length - deduplicatedMessages.length} message(s) with duplicate IDs.`,\n );\n }\n\n const messageElements: React.ReactElement[] = deduplicatedMessages\n .flatMap((message) => {\n const elements: (React.ReactElement | null | undefined)[] = [];\n const stateSnapshot = getStateSnapshotForMessage(message.id);\n\n // Render custom message before (using memoized wrapper)\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 // Render the main message using memoized wrappers to prevent unnecessary re-renders\n if (message.role === \"assistant\") {\n // Determine the component and props from slot value\n let AssistantComponent = CopilotChatAssistantMessage;\n let assistantSlotProps:\n | Partial<React.ComponentProps<typeof CopilotChatAssistantMessage>>\n | undefined;\n\n if (isReactComponentType(assistantMessage)) {\n // Custom component (function, forwardRef, memo, etc.)\n AssistantComponent =\n assistantMessage as typeof CopilotChatAssistantMessage;\n } else if (typeof assistantMessage === \"string\") {\n // className string\n assistantSlotProps = { className: assistantMessage };\n } else if (assistantMessage && typeof assistantMessage === \"object\") {\n // Props object\n assistantSlotProps = assistantMessage as Partial<\n React.ComponentProps<typeof CopilotChatAssistantMessage>\n >;\n }\n\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 // Determine the component and props from slot value\n let UserComponent = CopilotChatUserMessage;\n let userSlotProps:\n | Partial<React.ComponentProps<typeof CopilotChatUserMessage>>\n | undefined;\n\n if (isReactComponentType(userMessage)) {\n // Custom component (function, forwardRef, memo, etc.)\n UserComponent = userMessage as typeof CopilotChatUserMessage;\n } else if (typeof userMessage === \"string\") {\n // className string\n userSlotProps = { className: userMessage };\n } else if (userMessage && typeof userMessage === \"object\") {\n // Props object\n userSlotProps = userMessage as Partial<\n React.ComponentProps<typeof CopilotChatUserMessage>\n >;\n }\n\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 // Use memoized wrapper to prevent re-renders when other messages change\n const activityMsg = message as ActivityMessage;\n elements.push(\n <MemoizedActivityMessage\n key={message.id}\n message={activityMsg}\n renderActivityMessage={renderActivityMessage}\n />,\n );\n } else if (message.role === \"reasoning\") {\n // Determine the component and props from slot value\n let ReasoningComponent = CopilotChatReasoningMessage;\n let reasoningSlotProps:\n | Partial<React.ComponentProps<typeof CopilotChatReasoningMessage>>\n | undefined;\n\n if (isReactComponentType(reasoningMessage)) {\n ReasoningComponent =\n reasoningMessage as typeof CopilotChatReasoningMessage;\n } else if (typeof reasoningMessage === \"string\") {\n reasoningSlotProps = { className: reasoningMessage };\n } else if (reasoningMessage && typeof reasoningMessage === \"object\") {\n reasoningSlotProps = reasoningMessage as Partial<\n React.ComponentProps<typeof CopilotChatReasoningMessage>\n >;\n }\n\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 // Render custom message after (using memoized wrapper)\n if (renderCustomMessage) {\n elements.push(\n <MemoizedCustomMessage\n key={`${message.id}-custom-after`}\n message={message}\n position=\"after\"\n renderCustomMessage={renderCustomMessage}\n stateSnapshot={stateSnapshot}\n />,\n );\n }\n\n return elements;\n })\n .filter(Boolean) as React.ReactElement[];\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 return (\n <div\n data-copilotkit\n data-testid=\"copilot-message-list\"\n className={twMerge(\"cpk:flex cpk:flex-col\", className)}\n {...props}\n >\n {messageElements}\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 { useState, useEffect } from \"react\";\n\nexport interface KeyboardState {\n isKeyboardOpen: boolean;\n keyboardHeight: number;\n availableHeight: number;\n viewportHeight: number;\n}\n\n/**\n * Hook to detect mobile keyboard appearance and calculate available viewport height.\n * Uses the Visual Viewport API to track keyboard state on mobile devices.\n *\n * @returns KeyboardState object with keyboard information\n */\nexport function useKeyboardHeight(): KeyboardState {\n const [keyboardState, setKeyboardState] = useState<KeyboardState>({\n isKeyboardOpen: false,\n keyboardHeight: 0,\n availableHeight: typeof window !== \"undefined\" ? window.innerHeight : 0,\n viewportHeight: typeof window !== \"undefined\" ? window.innerHeight : 0,\n });\n\n useEffect(() => {\n if (typeof window === \"undefined\") {\n return;\n }\n\n // Check if Visual Viewport API is available\n const visualViewport = window.visualViewport;\n if (!visualViewport) {\n return;\n }\n\n const updateKeyboardState = () => {\n const layoutHeight = window.innerHeight;\n const visualHeight = visualViewport.height;\n\n // Calculate keyboard height (difference between layout and visual viewport)\n const keyboardHeight = Math.max(0, layoutHeight - visualHeight);\n\n // Keyboard is considered open if the height difference is significant (> 150px)\n const isKeyboardOpen = keyboardHeight > 150;\n\n setKeyboardState({\n isKeyboardOpen,\n keyboardHeight,\n availableHeight: visualHeight,\n viewportHeight: layoutHeight,\n });\n };\n\n // Initial state\n updateKeyboardState();\n\n // Listen for viewport changes\n visualViewport.addEventListener(\"resize\", updateKeyboardState);\n visualViewport.addEventListener(\"scroll\", updateKeyboardState);\n\n return () => {\n visualViewport.removeEventListener(\"resize\", updateKeyboardState);\n visualViewport.removeEventListener(\"scroll\", updateKeyboardState);\n };\n }, []);\n\n return keyboardState;\n}\n","import React, { useRef, useState, useEffect } from \"react\";\nimport { WithSlots, SlotValue, renderSlot } from \"@/lib/slots\";\nimport CopilotChatMessageView from \"./CopilotChatMessageView\";\nimport CopilotChatInput, {\n CopilotChatInputProps,\n CopilotChatInputMode,\n} from \"./CopilotChatInput\";\nimport CopilotChatSuggestionView, {\n CopilotChatSuggestionViewProps,\n} from \"./CopilotChatSuggestionView\";\nimport { Suggestion } from \"@copilotkitnext/core\";\nimport { Message } from \"@ag-ui/core\";\nimport { twMerge } from \"tailwind-merge\";\nimport {\n StickToBottom,\n useStickToBottom,\n useStickToBottomContext,\n} from \"use-stick-to-bottom\";\nimport { ChevronDown } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\nimport {\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport { useKeyboardHeight } from \"@/hooks/use-keyboard-height\";\n\n// Height of the feather gradient overlay (h-24 = 6rem = 96px)\nconst FEATHER_HEIGHT = 96;\n\n// Forward declaration for WelcomeScreen component type\nexport type WelcomeScreenProps = WithSlots<\n {\n welcomeMessage: React.FC<React.HTMLAttributes<HTMLDivElement>>;\n },\n {\n input: React.ReactElement;\n suggestionView: React.ReactElement;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\nexport type CopilotChatViewProps = WithSlots<\n {\n messageView: typeof CopilotChatMessageView;\n scrollView: typeof CopilotChatView.ScrollView;\n input: typeof CopilotChatInput;\n suggestionView: typeof CopilotChatSuggestionView;\n },\n {\n messages?: Message[];\n autoScroll?: boolean;\n isRunning?: boolean;\n suggestions?: Suggestion[];\n suggestionLoadingIndexes?: ReadonlyArray<number>;\n onSelectSuggestion?: (suggestion: Suggestion, index: number) => void;\n welcomeScreen?: SlotValue<React.FC<WelcomeScreenProps>> | boolean;\n // Input behavior props\n onSubmitMessage?: (value: string) => void;\n onStop?: () => void;\n inputMode?: CopilotChatInputMode;\n inputValue?: string;\n onInputChange?: (value: string) => void;\n onStartTranscribe?: () => void;\n onCancelTranscribe?: () => void;\n onFinishTranscribe?: () => void;\n onFinishTranscribeWithAudio?: (audioBlob: Blob) => Promise<void>;\n /**\n * @deprecated Use the `input` slot's `disclaimer` prop instead:\n * ```tsx\n * <CopilotChat input={{ disclaimer: MyDisclaimer }} />\n * ```\n */\n disclaimer?: SlotValue<React.FC<React.HTMLAttributes<HTMLDivElement>>>;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\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 // Deprecated — forwarded to input slot\n disclaimer,\n children,\n className,\n ...props\n}: CopilotChatViewProps) {\n const inputContainerRef = useRef<HTMLDivElement>(null);\n const [inputContainerHeight, setInputContainerHeight] = useState(0);\n const [isResizing, setIsResizing] = useState(false);\n const resizeTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n\n // Track keyboard state for mobile\n const { isKeyboardOpen, keyboardHeight, availableHeight } =\n useKeyboardHeight();\n\n // Track input container height changes\n useEffect(() => {\n const element = inputContainerRef.current;\n if (!element) return;\n\n const resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const newHeight = entry.contentRect.height;\n\n // Update height and set resizing state\n setInputContainerHeight((prevHeight) => {\n if (newHeight !== prevHeight) {\n setIsResizing(true);\n\n // Clear existing timeout\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n\n // Set isResizing to false after a short delay\n resizeTimeoutRef.current = setTimeout(() => {\n setIsResizing(false);\n }, 250);\n\n return newHeight;\n }\n return prevHeight;\n });\n }\n });\n\n resizeObserver.observe(element);\n\n // Set initial height\n setInputContainerHeight(element.offsetHeight);\n\n return () => {\n resizeObserver.disconnect();\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n };\n }, []);\n\n const BoundMessageView = renderSlot(messageView, CopilotChatMessageView, {\n messages,\n isRunning,\n });\n\n const BoundInput = renderSlot(input, CopilotChatInput, {\n onSubmitMessage,\n onStop,\n mode: inputMode,\n value: inputValue,\n onChange: onInputChange,\n isRunning,\n onStartTranscribe,\n onCancelTranscribe,\n onFinishTranscribe,\n onFinishTranscribeWithAudio,\n positioning: \"absolute\",\n keyboardHeight: isKeyboardOpen ? keyboardHeight : 0,\n containerRef: inputContainerRef,\n showDisclaimer: true,\n ...(disclaimer !== undefined ? { disclaimer } : {}),\n } as CopilotChatInputProps);\n\n const hasSuggestions = Array.isArray(suggestions) && suggestions.length > 0;\n const BoundSuggestionView = hasSuggestions\n ? renderSlot(suggestionView, CopilotChatSuggestionView, {\n suggestions,\n loadingIndexes: suggestionLoadingIndexes,\n onSelectSuggestion,\n className: \"cpk:mb-3 cpk:lg:ml-4 cpk:lg:mr-4 cpk:ml-0 cpk:mr-0\",\n })\n : null;\n\n const BoundScrollView = renderSlot(scrollView, CopilotChatView.ScrollView, {\n autoScroll,\n inputContainerHeight,\n isResizing,\n children: (\n <div\n style={{\n paddingBottom: `${inputContainerHeight + FEATHER_HEIGHT + (hasSuggestions ? 4 : 32)}px`,\n }}\n >\n <div className=\"cpk:max-w-3xl cpk:mx-auto\">\n {BoundMessageView}\n {hasSuggestions ? (\n <div className=\"cpk:pl-0 cpk:pr-4 cpk:sm:px-0 cpk:mt-4\">\n {BoundSuggestionView}\n </div>\n ) : null}\n </div>\n </div>\n ),\n });\n\n // Welcome screen logic\n const isEmpty = messages.length === 0;\n // Type assertion needed because TypeScript doesn't fully propagate `| boolean` through WithSlots\n const welcomeScreenDisabled = (welcomeScreen as unknown) === false;\n const shouldShowWelcomeScreen = isEmpty && !welcomeScreenDisabled;\n\n if (shouldShowWelcomeScreen) {\n // Create a separate input for welcome screen with static positioning and disclaimer visible\n const BoundInputForWelcome = renderSlot(input, CopilotChatInput, {\n onSubmitMessage,\n onStop,\n mode: inputMode,\n value: inputValue,\n onChange: onInputChange,\n isRunning,\n onStartTranscribe,\n onCancelTranscribe,\n onFinishTranscribe,\n onFinishTranscribeWithAudio,\n 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 const BoundWelcomeScreen = renderSlot(\n welcomeScreenSlot,\n CopilotChatView.WelcomeScreen,\n {\n input: BoundInputForWelcome,\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 className={twMerge(\n \"cpk:relative cpk:h-full cpk:flex cpk:flex-col\",\n className,\n )}\n {...props}\n >\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 className={twMerge(\"cpk:relative cpk:h-full\", className)}\n {...props}\n >\n {BoundScrollView}\n\n {BoundInput}\n </div>\n );\n}\n\nexport namespace CopilotChatView {\n // Inner component that has access to StickToBottom context\n const ScrollContent: React.FC<{\n children: React.ReactNode;\n scrollToBottomButton?: SlotValue<\n React.FC<React.ButtonHTMLAttributes<HTMLButtonElement>>\n >;\n feather?: SlotValue<React.FC<React.HTMLAttributes<HTMLDivElement>>>;\n inputContainerHeight: number;\n isResizing: boolean;\n }> = ({\n children,\n scrollToBottomButton,\n feather,\n inputContainerHeight,\n isResizing,\n }) => {\n const { isAtBottom, scrollToBottom } = useStickToBottomContext();\n\n const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});\n\n return (\n <>\n <StickToBottom.Content\n className=\"cpk:overflow-y-scroll cpk:overflow-x-hidden\"\n style={{ flex: \"1 1 0%\", minHeight: 0 }}\n >\n <div className=\"cpk:px-4 cpk:sm:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6\">\n {children}\n </div>\n </StickToBottom.Content>\n\n {/* Feather gradient overlay */}\n {BoundFeather}\n\n {/* Scroll to bottom button - hidden during resize */}\n {!isAtBottom && !isResizing && (\n <div\n className=\"cpk:absolute cpk:inset-x-0 cpk:flex cpk:justify-center cpk:z-30 cpk:pointer-events-none\"\n style={{\n bottom: `${inputContainerHeight + FEATHER_HEIGHT + 16}px`,\n }}\n >\n {renderSlot(\n scrollToBottomButton,\n CopilotChatView.ScrollToBottomButton,\n {\n onClick: () => scrollToBottom(),\n },\n )}\n </div>\n )}\n </>\n );\n };\n\n export const ScrollView: React.FC<\n React.HTMLAttributes<HTMLDivElement> & {\n autoScroll?: boolean;\n scrollToBottomButton?: SlotValue<\n React.FC<React.ButtonHTMLAttributes<HTMLButtonElement>>\n >;\n feather?: SlotValue<React.FC<React.HTMLAttributes<HTMLDivElement>>>;\n inputContainerHeight?: number;\n isResizing?: boolean;\n }\n > = ({\n children,\n autoScroll = true,\n scrollToBottomButton,\n feather,\n inputContainerHeight = 0,\n isResizing = false,\n className,\n ...props\n }) => {\n const [hasMounted, setHasMounted] = useState(false);\n const { scrollRef, contentRef, scrollToBottom } = useStickToBottom();\n const [showScrollButton, setShowScrollButton] = useState(false);\n\n useEffect(() => {\n setHasMounted(true);\n }, []);\n\n // Monitor scroll position for non-autoscroll mode\n useEffect(() => {\n if (autoScroll) return; // Skip for autoscroll mode\n\n const scrollElement = scrollRef.current;\n if (!scrollElement) return;\n\n const checkScroll = () => {\n const atBottom =\n scrollElement.scrollHeight -\n scrollElement.scrollTop -\n scrollElement.clientHeight <\n 10;\n setShowScrollButton(!atBottom);\n };\n\n checkScroll();\n scrollElement.addEventListener(\"scroll\", checkScroll);\n\n // Also check on resize\n const resizeObserver = new ResizeObserver(checkScroll);\n resizeObserver.observe(scrollElement);\n\n return () => {\n scrollElement.removeEventListener(\"scroll\", checkScroll);\n resizeObserver.disconnect();\n };\n }, [scrollRef, autoScroll]);\n\n if (!hasMounted) {\n return (\n <div className=\"cpk:h-full cpk:max-h-full cpk:flex cpk:flex-col cpk:min-h-0 cpk:overflow-y-scroll cpk:overflow-x-hidden\">\n <div className=\"cpk:px-4 cpk:sm:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6\">\n {children}\n </div>\n </div>\n );\n }\n\n // When autoScroll is false, we don't use StickToBottom\n if (!autoScroll) {\n const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});\n\n return (\n <div\n ref={scrollRef}\n className={cn(\n \"cpk:h-full cpk:max-h-full cpk:flex cpk:flex-col cpk:min-h-0 cpk:overflow-y-scroll cpk:overflow-x-hidden cpk:relative\",\n className,\n )}\n {...props}\n >\n <div\n ref={contentRef}\n className=\"cpk:px-4 cpk:sm:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6\"\n >\n {children}\n </div>\n\n {/* Feather gradient overlay */}\n {BoundFeather}\n\n {/* Scroll to bottom button for manual mode */}\n {showScrollButton && !isResizing && (\n <div\n className=\"cpk:absolute cpk:inset-x-0 cpk:flex cpk:justify-center cpk:z-30 cpk:pointer-events-none\"\n style={{\n bottom: `${inputContainerHeight + FEATHER_HEIGHT + 16}px`,\n }}\n >\n {renderSlot(\n scrollToBottomButton,\n CopilotChatView.ScrollToBottomButton,\n {\n onClick: () => scrollToBottom(),\n },\n )}\n </div>\n )}\n </div>\n );\n }\n\n return (\n <StickToBottom\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 resize=\"smooth\"\n initial=\"smooth\"\n {...props}\n >\n <ScrollContent\n scrollToBottomButton={scrollToBottomButton}\n feather={feather}\n inputContainerHeight={inputContainerHeight}\n isResizing={isResizing}\n >\n {children}\n </ScrollContent>\n </StickToBottom>\n );\n };\n\n export const ScrollToBottomButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, ...props }) => (\n <Button\n data-testid=\"copilot-scroll-to-bottom\"\n variant=\"outline\"\n size=\"sm\"\n className={twMerge(\n \"cpk:rounded-full cpk:w-10 cpk:h-10 cpk:p-0 cpk:pointer-events-auto\",\n \"cpk:bg-white cpk:dark:bg-gray-900\",\n \"cpk:shadow-lg cpk:border cpk:border-gray-200 cpk:dark:border-gray-700\",\n \"cpk:hover:bg-gray-50 cpk:dark:hover:bg-gray-800\",\n \"cpk:flex cpk:items-center cpk:justify-center cpk:cursor-pointer\",\n className,\n )}\n {...props}\n >\n <ChevronDown className=\"cpk:w-4 cpk:h-4 cpk:text-gray-600 cpk:dark:text-white\" />\n </Button>\n );\n\n export const Feather: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n className,\n style,\n ...props\n }) => (\n <div\n className={cn(\n \"cpk:absolute cpk:bottom-0 cpk:left-0 cpk:right-4 cpk:h-24 cpk:pointer-events-none cpk:z-10 cpk:bg-gradient-to-t\",\n \"cpk:from-white cpk:via-white cpk:to-transparent\",\n \"cpk:dark:from-[rgb(33,33,33)] cpk:dark:via-[rgb(33,33,33)]\",\n className,\n )}\n style={style}\n {...props}\n />\n );\n\n export const WelcomeMessage: React.FC<\n React.HTMLAttributes<HTMLDivElement>\n > = ({ className, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n\n return (\n <h1\n className={cn(\n \"cpk:text-xl cpk:sm:text-2xl cpk:font-medium cpk:text-foreground cpk:text-center\",\n className,\n )}\n {...props}\n >\n {labels.welcomeMessageText}\n </h1>\n );\n };\n\n export const WelcomeScreen: React.FC<WelcomeScreenProps> = ({\n welcomeMessage,\n input,\n suggestionView,\n className,\n children,\n ...props\n }) => {\n // Render the welcomeMessage slot internally\n const BoundWelcomeMessage = renderSlot(\n welcomeMessage,\n CopilotChatView.WelcomeMessage,\n {},\n );\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n welcomeMessage: BoundWelcomeMessage,\n input,\n suggestionView,\n className,\n ...props,\n })}\n </div>\n );\n }\n\n return (\n <div\n data-testid=\"copilot-welcome-screen\"\n className={cn(\n \"cpk:flex-1 cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:px-4\",\n className,\n )}\n {...props}\n >\n <div className=\"cpk:w-full cpk:max-w-3xl cpk:flex cpk:flex-col cpk:items-center\">\n {/* Welcome message */}\n <div className=\"cpk:mb-6\">{BoundWelcomeMessage}</div>\n\n {/* Input */}\n <div className=\"cpk:w-full\">{input}</div>\n\n {/* Suggestions */}\n <div className=\"cpk:mt-4 cpk:flex cpk:justify-center\">\n {suggestionView}\n </div>\n </div>\n </div>\n );\n };\n}\n\nexport default CopilotChatView;\n","import type { CopilotKitCoreReact } from \"./react-core\";\nimport {\n TranscriptionErrorCode,\n type TranscriptionErrorResponse,\n} from \"@copilotkitnext/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 { useSuggestions } from \"@/hooks/use-suggestions\";\nimport { CopilotChatView, CopilotChatViewProps } from \"./CopilotChatView\";\nimport { CopilotChatInputMode } from \"./CopilotChatInput\";\nimport {\n CopilotChatConfigurationProvider,\n CopilotChatLabels,\n useCopilotChatConfiguration,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport {\n DEFAULT_AGENT_ID,\n randomUUID,\n TranscriptionErrorCode,\n} from \"@copilotkitnext/shared\";\nimport { Suggestion, CopilotKitCoreErrorCode } from \"@copilotkitnext/core\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { merge } from \"ts-deepmerge\";\nimport { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport { AbstractAgent, AGUIConnectNotImplementedError } from \"@ag-ui/client\";\nimport { renderSlot, SlotValue } from \"@/lib/slots\";\nimport {\n transcribeAudio,\n TranscriptionError,\n} from \"@/lib/transcription-client\";\n\nexport type CopilotChatProps = Omit<\n CopilotChatViewProps,\n | \"messages\"\n | \"isRunning\"\n | \"suggestions\"\n | \"suggestionLoadingIndexes\"\n | \"onSelectSuggestion\"\n> & {\n agentId?: string;\n threadId?: string;\n labels?: Partial<CopilotChatLabels>;\n chatView?: SlotValue<typeof CopilotChatView>;\n};\nexport function CopilotChat({\n agentId,\n threadId,\n labels,\n chatView,\n ...props\n}: CopilotChatProps) {\n // Check for existing configuration provider\n const existingConfig = useCopilotChatConfiguration();\n\n // Apply priority: props > existing config > defaults\n const resolvedAgentId =\n agentId ?? existingConfig?.agentId ?? DEFAULT_AGENT_ID;\n const resolvedThreadId = useMemo(\n () => threadId ?? existingConfig?.threadId ?? randomUUID(),\n [threadId, existingConfig?.threadId],\n );\n\n const { agent } = useAgent({ agentId: resolvedAgentId });\n const { copilotkit } = useCopilotKit();\n const { suggestions: autoSuggestions } = useSuggestions({\n agentId: resolvedAgentId,\n });\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 // Check if transcription is enabled\n const isTranscriptionEnabled = copilotkit.audioFileTranscriptionEnabled;\n\n // Check if browser supports MediaRecorder\n const isMediaRecorderSupported =\n typeof window !== \"undefined\" && typeof MediaRecorder !== \"undefined\";\n\n const {\n messageView: providedMessageView,\n suggestionView: providedSuggestionView,\n onStop: providedStopHandler,\n ...restProps\n } = props;\n\n useEffect(() => {\n const connect = async (agent: AbstractAgent) => {\n try {\n await copilotkit.connectAgent({ agent });\n } catch (error) {\n if (error instanceof AGUIConnectNotImplementedError) {\n // connect not implemented, ignore\n } else {\n throw error;\n }\n }\n };\n agent.threadId = resolvedThreadId;\n connect(agent);\n return () => {};\n }, [resolvedThreadId, agent, copilotkit, resolvedAgentId]);\n\n const onSubmitInput = useCallback(\n async (value: string) => {\n agent.addMessage({\n id: randomUUID(),\n role: \"user\",\n content: value,\n });\n // Clear input after submitting\n setInputValue(\"\");\n try {\n await copilotkit.runAgent({ agent });\n } catch (error) {\n console.error(\"CopilotChat: runAgent failed\", error);\n }\n },\n [agent, copilotkit],\n );\n\n const handleSelectSuggestion = useCallback(\n async (suggestion: Suggestion) => {\n agent.addMessage({\n id: randomUUID(),\n role: \"user\",\n content: suggestion.message,\n });\n\n try {\n await copilotkit.runAgent({ agent });\n } catch (error) {\n console.error(\n \"CopilotChat: runAgent failed after selecting suggestion\",\n error,\n );\n }\n },\n [agent, copilotkit],\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 }, [agent, copilotkit]);\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 [copilotkit],\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 const mergedProps = merge(\n {\n isRunning: agent.isRunning,\n suggestions: autoSuggestions,\n onSelectSuggestion: handleSelectSuggestion,\n suggestionView: providedSuggestionView,\n },\n {\n ...restProps,\n ...(typeof providedMessageView === \"string\"\n ? { messageView: { className: providedMessageView } }\n : providedMessageView !== undefined\n ? { messageView: providedMessageView }\n : {}),\n },\n );\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 new reference when content actually changes\n // (agent.messages is mutated in place, so we need a new reference for React to detect changes)\n\n const messages = useMemo(\n () => [...agent.messages],\n [JSON.stringify(agent.messages)],\n );\n\n const finalProps = merge(mergedProps, {\n messages,\n // Input behavior props\n onSubmitMessage: onSubmitInput,\n onStop: effectiveStopHandler,\n inputMode: effectiveMode,\n inputValue,\n onInputChange: setInputValue,\n // Only provide transcription handlers if feature is available\n onStartTranscribe: showTranscription ? handleStartTranscribe : undefined,\n onCancelTranscribe: showTranscription ? handleCancelTranscribe : undefined,\n onFinishTranscribe: showTranscription ? handleFinishTranscribe : undefined,\n onFinishTranscribeWithAudio: showTranscription\n ? handleFinishTranscribeWithAudio\n : undefined,\n }) as CopilotChatViewProps;\n\n // Always create a provider with merged values\n // This ensures priority: props > existing config > defaults\n const RenderedChatView = renderSlot(chatView, CopilotChatView, finalProps);\n\n return (\n <CopilotChatConfigurationProvider\n agentId={resolvedAgentId}\n threadId={resolvedThreadId}\n labels={labels}\n >\n {transcriptionError && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100px\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n backgroundColor: \"#ef4444\",\n color: \"white\",\n padding: \"8px 16px\",\n borderRadius: \"8px\",\n fontSize: \"14px\",\n zIndex: 50,\n }}\n >\n {transcriptionError}\n </div>\n )}\n {RenderedChatView}\n </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 \"cpk:fixed cpk:bottom-6 cpk:right-6 cpk:z-[1100] cpk:flex cpk:h-14 cpk:w-14 cpk:items-center cpk:justify-center\",\n \"cpk:rounded-full cpk:border cpk:border-primary cpk:bg-primary cpk:text-primary-foreground\",\n \"cpk:shadow-sm cpk:transition-all cpk:duration-200 cpk:ease-out\",\n \"cpk:hover:scale-[1.04] cpk:hover:shadow-md\",\n \"cpk:cursor-pointer\",\n \"cpk:active:scale-[0.96]\",\n \"cpk:focus-visible:outline-none cpk:focus-visible:ring-2 cpk:focus-visible:ring-primary/50 cpk:focus-visible:ring-offset-2 cpk:focus-visible:ring-offset-background\",\n \"cpk:disabled:pointer-events-none cpk:disabled:opacity-60\",\n);\n\nexport const CopilotChatToggleButton = React.forwardRef<\n HTMLButtonElement,\n CopilotChatToggleButtonProps\n>(function CopilotChatToggleButton(\n { openIcon, closeIcon, className, ...buttonProps },\n ref,\n) {\n const { onClick, type, disabled, ...restProps } = buttonProps;\n\n const configuration = useCopilotChatConfiguration();\n const labels = configuration?.labels ?? CopilotChatDefaultLabels;\n\n const [fallbackOpen, setFallbackOpen] = useState(false);\n\n const isOpen = configuration?.isModalOpen ?? fallbackOpen;\n const setModalOpen = configuration?.setModalOpen ?? setFallbackOpen;\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n if (disabled) {\n return;\n }\n\n if (onClick) {\n onClick(event);\n }\n\n if (event.defaultPrevented) {\n return;\n }\n\n const nextOpen = !isOpen;\n setModalOpen(nextOpen);\n };\n\n const renderedOpenIcon = renderSlot(openIcon, DefaultOpenIcon, {\n className: \"cpk:h-6 cpk:w-6\",\n \"aria-hidden\": true,\n focusable: false,\n });\n\n const renderedCloseIcon = renderSlot(closeIcon, DefaultCloseIcon, {\n className: \"cpk:h-6 cpk:w-6\",\n \"aria-hidden\": true,\n focusable: false,\n });\n\n const openIconElement = (\n <span\n aria-hidden=\"true\"\n data-slot=\"chat-toggle-button-open-icon\"\n className={ICON_WRAPPER_BASE}\n style={{\n ...ICON_TRANSITION_STYLE,\n opacity: isOpen ? 0 : 1,\n transform: `scale(${isOpen ? 0.75 : 1}) rotate(${isOpen ? 90 : 0}deg)`,\n }}\n >\n {renderedOpenIcon}\n </span>\n );\n\n const closeIconElement = (\n <span\n aria-hidden=\"true\"\n data-slot=\"chat-toggle-button-close-icon\"\n className={ICON_WRAPPER_BASE}\n style={{\n ...ICON_TRANSITION_STYLE,\n opacity: isOpen ? 1 : 0,\n transform: `scale(${isOpen ? 1 : 0.75}) rotate(${isOpen ? 0 : -90}deg)`,\n }}\n >\n {renderedCloseIcon}\n </span>\n );\n\n return (\n <button\n ref={ref}\n type={type ?? \"button\"}\n data-copilotkit\n data-testid=\"copilot-chat-toggle\"\n data-slot=\"chat-toggle-button\"\n data-state={isOpen ? \"open\" : \"closed\"}\n className={cn(BUTTON_BASE_CLASSES, className)}\n aria-label={\n isOpen ? labels.chatToggleCloseLabel : labels.chatToggleOpenLabel\n }\n aria-pressed={isOpen}\n disabled={disabled}\n onClick={handleClick}\n {...restProps}\n >\n {openIconElement}\n {closeIconElement}\n </button>\n );\n});\nCopilotChatToggleButton.displayName = \"CopilotChatToggleButton\";\nexport default CopilotChatToggleButton;\n\nexport {\n DefaultOpenIcon as CopilotChatToggleButtonOpenIcon,\n DefaultCloseIcon as CopilotChatToggleButtonCloseIcon,\n};\n","import React, { useCallback } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\nimport {\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport { renderSlot, WithSlots } from \"@/lib/slots\";\nimport { X } from \"lucide-react\";\n\ntype HeaderSlots = {\n titleContent: typeof CopilotModalHeader.Title;\n closeButton: typeof CopilotModalHeader.CloseButton;\n};\n\ntype HeaderRestProps = {\n title?: string;\n} & Omit<React.HTMLAttributes<HTMLDivElement>, \"children\">;\n\nexport type CopilotModalHeaderProps = WithSlots<HeaderSlots, HeaderRestProps>;\n\nexport function CopilotModalHeader({\n title,\n titleContent,\n closeButton,\n children,\n className,\n ...rest\n}: CopilotModalHeaderProps) {\n const configuration = useCopilotChatConfiguration();\n\n const fallbackTitle =\n configuration?.labels.modalHeaderTitle ??\n CopilotChatDefaultLabels.modalHeaderTitle;\n const resolvedTitle = title ?? fallbackTitle;\n\n const handleClose = useCallback(() => {\n configuration?.setModalOpen?.(false);\n }, [configuration]);\n\n const BoundTitle = renderSlot(titleContent, CopilotModalHeader.Title, {\n children: resolvedTitle,\n });\n\n const BoundCloseButton = renderSlot(\n closeButton,\n CopilotModalHeader.CloseButton,\n {\n onClick: handleClose,\n },\n );\n\n if (children) {\n return children({\n titleContent: BoundTitle,\n closeButton: BoundCloseButton,\n title: resolvedTitle,\n ...rest,\n });\n }\n\n return (\n <header\n data-testid=\"copilot-modal-header\"\n data-slot=\"copilot-modal-header\"\n className={cn(\n \"cpk:flex cpk:items-center cpk:justify-between cpk:border-b cpk:border-border cpk:px-4 cpk:py-4\",\n \"cpk:bg-background/95 cpk:backdrop-blur cpk:supports-[backdrop-filter]:bg-background/80\",\n className,\n )}\n {...rest}\n >\n <div className=\"cpk:flex cpk:w-full cpk:items-center cpk:gap-2\">\n <div className=\"cpk:flex-1\" aria-hidden=\"true\" />\n <div className=\"cpk:flex cpk:flex-1 cpk:justify-center cpk:text-center\">\n {BoundTitle}\n </div>\n <div className=\"cpk:flex cpk:flex-1 cpk:justify-end\">\n {BoundCloseButton}\n </div>\n </div>\n </header>\n );\n}\n\nCopilotModalHeader.displayName = \"CopilotModalHeader\";\n\nexport namespace CopilotModalHeader {\n export const Title: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n children,\n className,\n ...props\n }) => (\n <div\n data-testid=\"copilot-header-title\"\n className={cn(\n \"cpk:w-full cpk:text-base cpk:font-medium cpk:leading-none cpk:tracking-tight cpk:text-foreground\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n );\n\n export const CloseButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, ...props }) => (\n <button\n type=\"button\"\n data-testid=\"copilot-close-button\"\n className={cn(\n \"cpk:inline-flex cpk:size-8 cpk:items-center cpk:justify-center cpk:rounded-full cpk:text-muted-foreground cpk:transition cpk:cursor-pointer\",\n \"cpk:hover:bg-muted cpk:hover:text-foreground cpk:focus-visible:outline-none cpk:focus-visible:ring-2 cpk:focus-visible:ring-ring\",\n className,\n )}\n aria-label=\"Close\"\n {...props}\n >\n <X className=\"cpk:h-4 cpk:w-4\" aria-hidden=\"true\" />\n </button>\n );\n}\n\nCopilotModalHeader.Title.displayName = \"CopilotModalHeader.Title\";\nCopilotModalHeader.CloseButton.displayName = \"CopilotModalHeader.CloseButton\";\n\nexport default CopilotModalHeader;\n","import React, { useEffect, useLayoutEffect, useRef, useState } from \"react\";\n\nimport CopilotChatView, {\n CopilotChatViewProps,\n WelcomeScreenProps,\n} from \"./CopilotChatView\";\nimport {\n CopilotChatConfigurationProvider,\n useCopilotChatConfiguration,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport CopilotChatToggleButton from \"./CopilotChatToggleButton\";\nimport { cn } from \"@/lib/utils\";\nimport { CopilotModalHeader } from \"./CopilotModalHeader\";\nimport { renderSlot, SlotValue } from \"@/lib/slots\";\n\nconst DEFAULT_SIDEBAR_WIDTH = 480;\nconst SIDEBAR_TRANSITION_MS = 260;\n\nexport type CopilotSidebarViewProps = CopilotChatViewProps & {\n header?: SlotValue<typeof CopilotModalHeader>;\n toggleButton?: SlotValue<typeof CopilotChatToggleButton>;\n width?: number | string;\n defaultOpen?: boolean;\n};\n\nexport function CopilotSidebarView({\n header,\n toggleButton,\n width,\n defaultOpen = true,\n ...props\n}: CopilotSidebarViewProps) {\n return (\n <CopilotChatConfigurationProvider isModalDefaultOpen={defaultOpen}>\n <CopilotSidebarViewInternal\n header={header}\n toggleButton={toggleButton}\n width={width}\n {...props}\n />\n </CopilotChatConfigurationProvider>\n );\n}\n\nfunction CopilotSidebarViewInternal({\n header,\n toggleButton,\n width,\n ...props\n}: Omit<CopilotSidebarViewProps, \"defaultOpen\">) {\n const configuration = useCopilotChatConfiguration();\n\n const isSidebarOpen = configuration?.isModalOpen ?? false;\n\n const sidebarRef = useRef<HTMLDivElement | null>(null);\n const [sidebarWidth, setSidebarWidth] = useState<number | string>(\n width ?? DEFAULT_SIDEBAR_WIDTH,\n );\n\n // Helper to convert width to CSS value\n const widthToCss = (w: number | string): string => {\n return typeof w === \"number\" ? `${w}px` : w;\n };\n\n // Helper to extract numeric value for body margin (only works with px values)\n const widthToMargin = (w: number | string): string => {\n if (typeof w === \"number\") {\n return `${w}px`;\n }\n // For string values, use as-is (assumes valid CSS unit)\n return w;\n };\n\n useEffect(() => {\n // If width is explicitly provided, don't measure\n if (width !== undefined) {\n return;\n }\n\n if (typeof window === \"undefined\") {\n return;\n }\n\n const element = sidebarRef.current;\n if (!element) {\n return;\n }\n\n const updateWidth = () => {\n const rect = element.getBoundingClientRect();\n if (rect.width > 0) {\n setSidebarWidth(rect.width);\n }\n };\n\n updateWidth();\n\n if (typeof ResizeObserver !== \"undefined\") {\n const observer = new ResizeObserver(() => updateWidth());\n observer.observe(element);\n return () => observer.disconnect();\n }\n\n window.addEventListener(\"resize\", updateWidth);\n return () => window.removeEventListener(\"resize\", updateWidth);\n }, [width]);\n\n // Manage body margin for sidebar docking (desktop only).\n // useLayoutEffect runs before paint, so defaultOpen={true} never causes a\n // visible layout shift — the margin is already applied on the first frame.\n const hasMounted = useRef(false);\n\n useLayoutEffect(() => {\n if (\n typeof window === \"undefined\" ||\n typeof window.matchMedia !== \"function\"\n )\n return;\n if (!window.matchMedia(\"(min-width: 768px)\").matches) return;\n\n if (isSidebarOpen) {\n if (hasMounted.current) {\n document.body.style.transition = `margin-inline-end ${SIDEBAR_TRANSITION_MS}ms ease`;\n }\n document.body.style.marginInlineEnd = widthToMargin(sidebarWidth);\n } else if (hasMounted.current) {\n document.body.style.transition = `margin-inline-end ${SIDEBAR_TRANSITION_MS}ms ease`;\n document.body.style.marginInlineEnd = \"\";\n }\n\n hasMounted.current = true;\n\n return () => {\n document.body.style.marginInlineEnd = \"\";\n document.body.style.transition = \"\";\n };\n }, [isSidebarOpen, sidebarWidth]);\n\n const headerElement = renderSlot(header, CopilotModalHeader, {});\n const toggleButtonElement = renderSlot(\n toggleButton,\n CopilotChatToggleButton,\n {},\n );\n\n return (\n <>\n {toggleButtonElement}\n <aside\n ref={sidebarRef}\n data-copilotkit\n data-testid=\"copilot-sidebar\"\n data-copilot-sidebar\n className={cn(\n \"cpk:fixed cpk:right-0 cpk:top-0 cpk:z-[1200] cpk:flex\",\n // Height with dvh fallback and safe area support\n \"cpk:h-[100vh] cpk:h-[100dvh] cpk:max-h-screen\",\n // Responsive width: full on mobile, custom on desktop\n \"cpk:w-full\",\n \"cpk:border-l cpk:border-border cpk:bg-background cpk:text-foreground cpk:shadow-xl\",\n \"cpk:transition-transform cpk:duration-300 cpk:ease-out\",\n isSidebarOpen\n ? \"cpk:translate-x-0\"\n : \"cpk:translate-x-full cpk:pointer-events-none\",\n )}\n style={\n {\n // Use CSS custom property for responsive width\n [\"--sidebar-width\" as string]: widthToCss(sidebarWidth),\n // Safe area insets for iOS\n paddingTop: \"env(safe-area-inset-top)\",\n paddingBottom: \"env(safe-area-inset-bottom)\",\n } as React.CSSProperties\n }\n aria-hidden={!isSidebarOpen}\n aria-label=\"Copilot chat sidebar\"\n role=\"complementary\"\n >\n <div className=\"cpk:flex cpk:h-full cpk:w-full cpk:flex-col cpk:overflow-hidden\">\n {headerElement}\n <div className=\"cpk:flex-1 cpk:overflow-hidden\" data-sidebar-chat>\n <CopilotChatView {...props} />\n </div>\n </div>\n </aside>\n </>\n );\n}\n\nCopilotSidebarView.displayName = \"CopilotSidebarView\";\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotSidebarView {\n /**\n * Sidebar-specific welcome screen layout:\n * - Suggestions at the top\n * - Welcome message in the middle\n * - Input fixed at the bottom (like normal chat)\n */\n export const WelcomeScreen: React.FC<WelcomeScreenProps> = ({\n welcomeMessage,\n input,\n suggestionView,\n className,\n children,\n ...props\n }) => {\n // Render the welcomeMessage slot internally\n const BoundWelcomeMessage = renderSlot(\n welcomeMessage,\n CopilotChatView.WelcomeMessage,\n {},\n );\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n welcomeMessage: BoundWelcomeMessage,\n input,\n suggestionView,\n className,\n ...props,\n })}\n </div>\n );\n }\n\n return (\n <div\n className={cn(\"cpk:h-full cpk:flex cpk:flex-col\", className)}\n {...props}\n >\n {/* Welcome message - centered vertically */}\n <div className=\"cpk:flex-1 cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:px-4\">\n {BoundWelcomeMessage}\n </div>\n\n {/* Suggestions and input at bottom */}\n <div className=\"cpk:px-8 cpk:pb-4\">\n <div className=\"cpk:max-w-3xl cpk:mx-auto\">\n {/* Suggestions above input */}\n <div className=\"cpk:mb-4 cpk:flex cpk:justify-center\">\n {suggestionView}\n </div>\n {input}\n </div>\n </div>\n </div>\n );\n };\n}\n\nexport default CopilotSidebarView;\n","import React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport CopilotChatView, {\n CopilotChatViewProps,\n WelcomeScreenProps,\n} from \"./CopilotChatView\";\nimport CopilotChatToggleButton from \"./CopilotChatToggleButton\";\nimport { CopilotModalHeader } from \"./CopilotModalHeader\";\nimport { cn } from \"@/lib/utils\";\nimport { renderSlot, SlotValue } from \"@/lib/slots\";\nimport {\n CopilotChatConfigurationProvider,\n CopilotChatDefaultLabels,\n useCopilotChatConfiguration,\n} from \"@/providers/CopilotChatConfigurationProvider\";\n\nconst DEFAULT_POPUP_WIDTH = 420;\nconst DEFAULT_POPUP_HEIGHT = 560;\n\nexport type CopilotPopupViewProps = CopilotChatViewProps & {\n header?: SlotValue<typeof CopilotModalHeader>;\n toggleButton?: SlotValue<typeof CopilotChatToggleButton>;\n width?: number | string;\n height?: number | string;\n clickOutsideToClose?: boolean;\n defaultOpen?: boolean;\n};\n\nconst dimensionToCss = (\n value: number | string | undefined,\n fallback: number,\n): string => {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return `${value}px`;\n }\n\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value;\n }\n\n return `${fallback}px`;\n};\n\nexport function CopilotPopupView({\n header,\n toggleButton,\n width,\n height,\n clickOutsideToClose,\n defaultOpen = true,\n className,\n ...restProps\n}: CopilotPopupViewProps) {\n return (\n <CopilotChatConfigurationProvider isModalDefaultOpen={defaultOpen}>\n <CopilotPopupViewInternal\n header={header}\n toggleButton={toggleButton}\n width={width}\n height={height}\n clickOutsideToClose={clickOutsideToClose}\n className={className}\n {...restProps}\n />\n </CopilotChatConfigurationProvider>\n );\n}\n\nfunction CopilotPopupViewInternal({\n header,\n toggleButton,\n width,\n height,\n clickOutsideToClose,\n className,\n ...restProps\n}: Omit<CopilotPopupViewProps, \"defaultOpen\">) {\n const configuration = useCopilotChatConfiguration();\n const isPopupOpen = configuration?.isModalOpen ?? false;\n const setModalOpen = configuration?.setModalOpen;\n const labels = configuration?.labels ?? CopilotChatDefaultLabels;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const [isRendered, setIsRendered] = useState(isPopupOpen);\n const [isAnimatingOut, setIsAnimatingOut] = useState(false);\n\n useEffect(() => {\n if (isPopupOpen) {\n setIsRendered(true);\n setIsAnimatingOut(false);\n return;\n }\n\n if (!isRendered) {\n return;\n }\n\n setIsAnimatingOut(true);\n const timeout = setTimeout(() => {\n setIsRendered(false);\n setIsAnimatingOut(false);\n }, 200);\n\n return () => clearTimeout(timeout);\n }, [isPopupOpen, isRendered]);\n\n useEffect(() => {\n if (!isPopupOpen) {\n return;\n }\n\n if (typeof window === \"undefined\") {\n return;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n setModalOpen?.(false);\n }\n };\n\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [isPopupOpen, setModalOpen]);\n\n useEffect(() => {\n if (!isPopupOpen) {\n return;\n }\n\n const focusTimer = setTimeout(() => {\n const container = containerRef.current;\n // Don't steal focus if something inside the popup (like the input) is already focused\n if (container && !container.contains(document.activeElement)) {\n container.focus({ preventScroll: true });\n }\n }, 200);\n\n return () => clearTimeout(focusTimer);\n }, [isPopupOpen]);\n\n useEffect(() => {\n if (!isPopupOpen || !clickOutsideToClose) {\n return;\n }\n\n if (typeof document === \"undefined\") {\n return;\n }\n\n const handlePointerDown = (event: PointerEvent) => {\n const target = event.target as Node | null;\n if (!target) {\n return;\n }\n\n const container = containerRef.current;\n if (container?.contains(target)) {\n return;\n }\n\n const toggleButton = document.querySelector(\n \"[data-slot='chat-toggle-button']\",\n );\n if (toggleButton && toggleButton.contains(target)) {\n return;\n }\n\n setModalOpen?.(false);\n };\n\n document.addEventListener(\"pointerdown\", handlePointerDown);\n return () => document.removeEventListener(\"pointerdown\", handlePointerDown);\n }, [isPopupOpen, clickOutsideToClose, setModalOpen]);\n\n const headerElement = useMemo(\n () => renderSlot(header, CopilotModalHeader, {}),\n [header],\n );\n const toggleButtonElement = useMemo(\n () => renderSlot(toggleButton, CopilotChatToggleButton, {}),\n [toggleButton],\n );\n\n const resolvedWidth = dimensionToCss(width, DEFAULT_POPUP_WIDTH);\n const resolvedHeight = dimensionToCss(height, DEFAULT_POPUP_HEIGHT);\n\n const popupStyle = useMemo(\n () =>\n ({\n \"--copilot-popup-width\": resolvedWidth,\n \"--copilot-popup-height\": resolvedHeight,\n \"--copilot-popup-max-width\": \"calc(100vw - 3rem)\",\n \"--copilot-popup-max-height\": \"calc(100dvh - 7.5rem)\",\n paddingTop: \"env(safe-area-inset-top)\",\n paddingBottom: \"env(safe-area-inset-bottom)\",\n paddingLeft: \"env(safe-area-inset-left)\",\n paddingRight: \"env(safe-area-inset-right)\",\n }) as React.CSSProperties,\n [resolvedHeight, resolvedWidth],\n );\n\n const popupAnimationClass =\n isPopupOpen && !isAnimatingOut\n ? \"cpk:pointer-events-auto cpk:translate-y-0 cpk:opacity-100 cpk:md:scale-100\"\n : \"cpk:pointer-events-none cpk:translate-y-4 cpk:opacity-0 cpk:md:translate-y-5 cpk:md:scale-[0.95]\";\n\n const popupContent = isRendered ? (\n <div\n data-copilotkit\n className={cn(\n \"cpk:fixed cpk:inset-0 cpk:z-[1200] cpk:flex cpk:max-w-full cpk:flex-col cpk:items-stretch\",\n \"cpk:md:inset-auto cpk:md:bottom-24 cpk:md:right-6 cpk:md:items-end cpk:md:gap-4\",\n )}\n >\n <div\n ref={containerRef}\n tabIndex={-1}\n role=\"dialog\"\n aria-label={labels.modalHeaderTitle}\n data-testid=\"copilot-popup\"\n data-copilot-popup\n className={cn(\n \"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, { useMemo } from \"react\";\n\nimport { CopilotChat, CopilotChatProps } from \"./CopilotChat\";\nimport CopilotChatView, { CopilotChatViewProps } from \"./CopilotChatView\";\nimport {\n CopilotSidebarView,\n CopilotSidebarViewProps,\n} from \"./CopilotSidebarView\";\n\nexport type CopilotSidebarProps = Omit<CopilotChatProps, \"chatView\"> & {\n header?: CopilotSidebarViewProps[\"header\"];\n toggleButton?: CopilotSidebarViewProps[\"toggleButton\"];\n defaultOpen?: boolean;\n width?: number | string;\n};\n\nexport function CopilotSidebar({\n header,\n toggleButton,\n defaultOpen,\n width,\n ...chatProps\n}: CopilotSidebarProps) {\n const SidebarViewOverride = useMemo(() => {\n const Component: React.FC<CopilotChatViewProps> = (viewProps) => {\n const {\n header: viewHeader,\n toggleButton: viewToggleButton,\n width: viewWidth,\n defaultOpen: viewDefaultOpen,\n ...restProps\n } = viewProps as CopilotSidebarViewProps;\n\n return (\n <CopilotSidebarView\n {...(restProps as CopilotSidebarViewProps)}\n header={header ?? viewHeader}\n toggleButton={toggleButton ?? viewToggleButton}\n width={width ?? viewWidth}\n defaultOpen={defaultOpen ?? viewDefaultOpen}\n />\n );\n };\n\n return Object.assign(Component, CopilotChatView);\n }, [header, toggleButton, width, defaultOpen]);\n\n return (\n <CopilotChat\n welcomeScreen={CopilotSidebarView.WelcomeScreen}\n {...chatProps}\n chatView={SidebarViewOverride}\n />\n );\n}\n\nCopilotSidebar.displayName = \"CopilotSidebar\";\n\nexport default CopilotSidebar;\n","import React, { useMemo } from \"react\";\n\nimport { CopilotChat, CopilotChatProps } from \"./CopilotChat\";\nimport CopilotChatView, { CopilotChatViewProps } from \"./CopilotChatView\";\nimport CopilotPopupView, { CopilotPopupViewProps } from \"./CopilotPopupView\";\n\nexport type CopilotPopupProps = Omit<CopilotChatProps, \"chatView\"> & {\n header?: CopilotPopupViewProps[\"header\"];\n toggleButton?: CopilotPopupViewProps[\"toggleButton\"];\n defaultOpen?: boolean;\n width?: CopilotPopupViewProps[\"width\"];\n height?: CopilotPopupViewProps[\"height\"];\n clickOutsideToClose?: CopilotPopupViewProps[\"clickOutsideToClose\"];\n};\n\nexport function CopilotPopup({\n header,\n toggleButton,\n defaultOpen,\n width,\n height,\n clickOutsideToClose,\n ...chatProps\n}: CopilotPopupProps) {\n const PopupViewOverride = useMemo(() => {\n const Component: React.FC<CopilotChatViewProps> = (viewProps) => {\n const {\n header: viewHeader,\n toggleButton: viewToggleButton,\n width: viewWidth,\n height: viewHeight,\n clickOutsideToClose: viewClickOutsideToClose,\n defaultOpen: viewDefaultOpen,\n ...restProps\n } = viewProps as CopilotPopupViewProps;\n\n return (\n <CopilotPopupView\n {...(restProps as CopilotPopupViewProps)}\n header={header ?? viewHeader}\n toggleButton={toggleButton ?? viewToggleButton}\n width={width ?? viewWidth}\n height={height ?? viewHeight}\n clickOutsideToClose={clickOutsideToClose ?? viewClickOutsideToClose}\n defaultOpen={defaultOpen ?? viewDefaultOpen}\n />\n );\n };\n\n return Object.assign(Component, CopilotChatView);\n }, [clickOutsideToClose, header, toggleButton, height, width, defaultOpen]);\n\n return (\n <CopilotChat\n welcomeScreen={CopilotPopupView.WelcomeScreen}\n {...chatProps}\n chatView={PopupViewOverride}\n />\n );\n}\n\nCopilotPopup.displayName = \"CopilotPopup\";\n\nexport default CopilotPopup;\n","import { defineToolCallRenderer } from \"../types/defineToolCallRenderer\";\nimport { useState } from \"react\";\n\nexport const WildcardToolCallRender = defineToolCallRenderer({\n name: \"*\",\n render: ({ args, result, name, status }) => {\n const [isExpanded, setIsExpanded] = useState(false);\n\n const statusString = String(status) as\n | \"inProgress\"\n | \"executing\"\n | \"complete\";\n const isActive =\n statusString === \"inProgress\" || statusString === \"executing\";\n const isComplete = statusString === \"complete\";\n const statusStyles = isActive\n ? \"cpk:bg-amber-100 cpk:text-amber-800 cpk:dark:bg-amber-500/15 cpk:dark:text-amber-400\"\n : isComplete\n ? \"cpk:bg-emerald-100 cpk:text-emerald-800 cpk:dark:bg-emerald-500/15 cpk:dark:text-emerald-400\"\n : \"cpk:bg-zinc-100 cpk:text-zinc-800 cpk:dark:bg-zinc-700/40 cpk:dark:text-zinc-300\";\n\n return (\n <div className=\"cpk:mt-2 cpk:pb-2\">\n <div className=\"cpk:rounded-xl cpk:border cpk:border-zinc-200/60 cpk:dark:border-zinc-800/60 cpk:bg-white/70 cpk:dark:bg-zinc-900/50 cpk:shadow-sm cpk:backdrop-blur cpk:p-4\">\n <div\n className=\"cpk:flex cpk:items-center cpk:justify-between cpk:gap-3 cpk:cursor-pointer\"\n onClick={() => setIsExpanded(!isExpanded)}\n >\n <div className=\"cpk:flex cpk:items-center cpk:gap-2 cpk:min-w-0\">\n <svg\n className={`cpk:h-4 cpk:w-4 cpk:text-zinc-500 cpk:dark:text-zinc-400 cpk:transition-transform ${\n isExpanded ? \"cpk:rotate-90\" : \"\"\n }`}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n strokeWidth={2}\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M8.25 4.5l7.5 7.5-7.5 7.5\"\n />\n </svg>\n <span className=\"cpk:inline-block cpk:h-2 cpk:w-2 cpk:rounded-full cpk:bg-blue-500\" />\n <span className=\"cpk:truncate cpk:text-sm cpk:font-medium cpk:text-zinc-900 cpk:dark:text-zinc-100\">\n {name}\n </span>\n </div>\n <span\n className={`cpk:inline-flex cpk:items-center cpk:rounded-full cpk:px-2 cpk:py-1 cpk:text-xs cpk:font-medium ${statusStyles}`}\n >\n {String(status)}\n </span>\n </div>\n\n {isExpanded && (\n <div className=\"cpk:mt-3 cpk:grid cpk:gap-4\">\n <div>\n <div className=\"cpk:text-xs cpk:uppercase cpk:tracking-wide cpk:text-zinc-500 cpk:dark:text-zinc-400\">\n Arguments\n </div>\n <pre className=\"cpk:mt-2 cpk:max-h-64 cpk:overflow-auto cpk:rounded-md cpk:bg-zinc-50 cpk:dark:bg-zinc-800/60 cpk:p-3 cpk:text-xs cpk:leading-relaxed cpk:text-zinc-800 cpk:dark:text-zinc-200 cpk:whitespace-pre-wrap cpk:break-words\">\n {JSON.stringify(args ?? {}, null, 2)}\n </pre>\n </div>\n\n {result !== undefined && (\n <div>\n <div className=\"cpk:text-xs cpk:uppercase cpk:tracking-wide cpk:text-zinc-500 cpk:dark:text-zinc-400\">\n Result\n </div>\n <pre className=\"cpk:mt-2 cpk:max-h-64 cpk:overflow-auto cpk:rounded-md cpk:bg-zinc-50 cpk:dark:bg-zinc-800/60 cpk:p-3 cpk:text-xs cpk:leading-relaxed cpk:text-zinc-800 cpk:dark:text-zinc-200 cpk:whitespace-pre-wrap cpk:break-words\">\n {typeof result === \"string\"\n ? result\n : JSON.stringify(result, null, 2)}\n </pre>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n },\n});\n"],"mappings":"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"}