@copilotkit/react-core 1.61.2 → 1.62.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/{copilotkit-Be-o2UaU.mjs → copilotkit-BtRkFsNR.mjs} +941 -404
  2. package/dist/copilotkit-BtRkFsNR.mjs.map +1 -0
  3. package/dist/{copilotkit-CTCjVxkH.cjs → copilotkit-CdpDZi3i.cjs} +943 -400
  4. package/dist/copilotkit-CdpDZi3i.cjs.map +1 -0
  5. package/dist/{copilotkit-ClqbUuGX.d.cts → copilotkit-Cga6AHO0.d.cts} +429 -149
  6. package/dist/copilotkit-Cga6AHO0.d.cts.map +1 -0
  7. package/dist/{copilotkit-Bpt1c_-q.d.mts → copilotkit-DnLpJ2Cl.d.mts} +429 -149
  8. package/dist/copilotkit-DnLpJ2Cl.d.mts.map +1 -0
  9. package/dist/index.cjs +1 -1
  10. package/dist/index.d.cts +1 -1
  11. package/dist/index.d.mts +1 -1
  12. package/dist/index.mjs +1 -1
  13. package/dist/index.umd.js +193 -176
  14. package/dist/index.umd.js.map +1 -1
  15. package/dist/v2/headless.cjs +156 -11
  16. package/dist/v2/headless.cjs.map +1 -1
  17. package/dist/v2/headless.d.cts +111 -1
  18. package/dist/v2/headless.d.cts.map +1 -1
  19. package/dist/v2/headless.d.mts +111 -1
  20. package/dist/v2/headless.d.mts.map +1 -1
  21. package/dist/v2/headless.mjs +157 -12
  22. package/dist/v2/headless.mjs.map +1 -1
  23. package/dist/v2/index.cjs +2 -1
  24. package/dist/v2/index.css +1 -1
  25. package/dist/v2/index.d.cts +2 -2
  26. package/dist/v2/index.d.mts +2 -2
  27. package/dist/v2/index.mjs +2 -2
  28. package/dist/v2/index.umd.js +949 -412
  29. package/dist/v2/index.umd.js.map +1 -1
  30. package/package.json +8 -6
  31. package/dist/copilotkit-Be-o2UaU.mjs.map +0 -1
  32. package/dist/copilotkit-Bpt1c_-q.d.mts.map +0 -1
  33. package/dist/copilotkit-CTCjVxkH.cjs.map +0 -1
  34. package/dist/copilotkit-ClqbUuGX.d.cts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"headless.mjs","names":["EMPTY_DEPS","randomUUID"],"sources":["../../src/v2/lib/slots.tsx","../../src/v2/providers/CopilotChatConfigurationProvider.tsx","../../src/v2/hooks/use-agent.tsx","../../src/v2/hooks/use-frontend-tool.tsx","../../src/v2/hooks/use-component.tsx","../../src/v2/hooks/use-human-in-the-loop.tsx","../../src/v2/hooks/use-interrupt.tsx","../../src/v2/hooks/use-suggestions.tsx","../../src/v2/hooks/use-configure-suggestions.tsx","../../src/v2/hooks/use-agent-context.tsx","../../src/v2/hooks/use-threads.tsx","../../src/v2/types/defineToolCallRenderer.ts","../../src/v2/hooks/use-render-tool.tsx","../../src/v2/hooks/use-capabilities.tsx"],"sourcesContent":["import React, { useRef } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\n/** Existing union (unchanged) */\nexport type SlotValue<C extends React.ComponentType<any>> =\n | C\n | string\n | Partial<React.ComponentProps<C>>;\n\n/**\n * Shallow equality comparison for objects.\n */\nexport function shallowEqual<T extends Record<string, unknown>>(\n obj1: T,\n obj2: T,\n): boolean {\n const keys1 = Object.keys(obj1);\n const keys2 = Object.keys(obj2);\n\n if (keys1.length !== keys2.length) return false;\n\n for (const key of keys1) {\n if (obj1[key] !== obj2[key]) return false;\n }\n\n return true;\n}\n\n/**\n * Returns true only for plain JS objects (`{}`), excluding arrays, Dates,\n * class instances, and other exotic objects that happen to have typeof \"object\".\n */\nfunction isPlainObject(obj: unknown): obj is Record<string, unknown> {\n return (\n obj !== null &&\n typeof obj === \"object\" &&\n Object.prototype.toString.call(obj) === \"[object Object]\"\n );\n}\n\n/**\n * Returns the same reference as long as the value is shallowly equal to the\n * previous render's value.\n *\n * - Identical references bail out immediately (O(1)).\n * - Plain objects ({}) are shallow-compared key-by-key.\n * - Arrays, Dates, class instances, functions, and primitives are compared by\n * reference only — shallowEqual is never called on non-plain objects, which\n * avoids incorrect equality for e.g. [1,2] vs [1,2] (different arrays).\n *\n * Typical use: stabilize inline slot props so MemoizedSlotWrapper's shallow\n * equality check isn't defeated by a new object reference on every render.\n */\nexport function useShallowStableRef<T>(value: T): T {\n const ref = useRef(value);\n\n // 1. Identical reference — bail early, no comparison needed.\n if (ref.current === value) return ref.current;\n\n // 2. Both are plain objects — shallow-compare to detect structural equality.\n if (isPlainObject(ref.current) && isPlainObject(value)) {\n if (shallowEqual(ref.current, value)) return ref.current;\n }\n\n // 3. Different values (or non-comparable types) — update the ref.\n ref.current = value;\n return ref.current;\n}\n\n/** Utility: concrete React elements for every slot */\ntype SlotElements<S> = { [K in keyof S]: React.ReactElement };\n\nexport type WithSlots<\n S extends Record<string, React.ComponentType<any>>,\n Rest = {},\n> = {\n /** Per‑slot overrides */\n [K in keyof S]?: SlotValue<S[K]>;\n} & {\n children?: (props: SlotElements<S> & Rest) => React.ReactNode;\n} & Omit<Rest, \"children\">;\n\n/**\n * Check if a value is a React component type (function, class, forwardRef, memo, etc.)\n */\nexport function isReactComponentType(\n value: unknown,\n): value is React.ComponentType<any> {\n if (typeof value === \"function\") {\n return true;\n }\n // forwardRef, memo, lazy have $$typeof but are not valid elements\n if (\n value &&\n typeof value === \"object\" &&\n \"$$typeof\" in value &&\n !React.isValidElement(value)\n ) {\n return true;\n }\n return false;\n}\n\n/**\n * Internal function to render a slot value as a React element (non-memoized).\n */\nfunction renderSlotElement(\n slot: SlotValue<React.ComponentType<any>> | undefined,\n DefaultComponent: React.ComponentType<any>,\n props: Record<string, unknown>,\n): React.ReactElement {\n if (typeof slot === \"string\") {\n // When slot is a string, treat it as a className and merge with existing className\n const existingClassName = props.className as string | undefined;\n return React.createElement(DefaultComponent, {\n ...props,\n className: twMerge(existingClassName, slot),\n });\n }\n\n // Check if slot is a React component type (function, forwardRef, memo, etc.)\n if (isReactComponentType(slot)) {\n return React.createElement(slot, props);\n }\n\n // If slot is a plain object (not a React element), treat it as props override\n if (slot && typeof slot === \"object\" && !React.isValidElement(slot)) {\n return React.createElement(DefaultComponent, {\n ...props,\n ...slot,\n });\n }\n\n return React.createElement(DefaultComponent, props);\n}\n\n/**\n * Internal memoized wrapper component for renderSlot.\n * Uses forwardRef to support ref forwarding.\n */\nconst MemoizedSlotWrapper = React.memo(\n React.forwardRef<unknown, any>(function MemoizedSlotWrapper(props, ref) {\n const { $slot, $component, ...rest } = props;\n const propsWithRef: Record<string, unknown> =\n ref !== null ? { ...rest, ref } : rest;\n return renderSlotElement($slot, $component, propsWithRef);\n }),\n (prev: any, next: any) => {\n // Compare slot and component references\n if (prev.$slot !== next.$slot) return false;\n if (prev.$component !== next.$component) return false;\n\n // Shallow compare remaining props (ref is handled separately by React)\n const { $slot: _ps, $component: _pc, ...prevRest } = prev;\n const { $slot: _ns, $component: _nc, ...nextRest } = next;\n return shallowEqual(\n prevRest as Record<string, unknown>,\n nextRest as Record<string, unknown>,\n );\n },\n);\n\n/**\n * Renders a slot value as a memoized React element.\n * Automatically prevents unnecessary re-renders using shallow prop comparison.\n * Supports ref forwarding.\n *\n * @example\n * renderSlot(customInput, CopilotChatInput, { onSubmit: handleSubmit })\n */\nexport function renderSlot<\n C extends React.ComponentType<any>,\n P = React.ComponentProps<C>,\n>(\n slot: SlotValue<C> | undefined,\n DefaultComponent: C,\n props: P,\n): React.ReactElement {\n return React.createElement(MemoizedSlotWrapper, {\n ...props,\n $slot: slot,\n $component: DefaultComponent,\n } as any);\n}\n","import React, {\n createContext,\n useCallback,\n useContext,\n ReactNode,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { DEFAULT_AGENT_ID, randomUUID } from \"@copilotkit/shared\";\nimport { useShallowStableRef } from \"../lib/slots\";\n\n// Default labels\nexport const CopilotChatDefaultLabels = {\n chatInputPlaceholder: \"Type a message...\",\n chatInputToolbarStartTranscribeButtonLabel: \"Transcribe\",\n chatInputToolbarCancelTranscribeButtonLabel: \"Cancel\",\n chatInputToolbarFinishTranscribeButtonLabel: \"Finish\",\n chatInputToolbarAddButtonLabel: \"Add attachments\",\n chatInputToolbarToolsButtonLabel: \"Tools\",\n assistantMessageToolbarCopyCodeLabel: \"Copy\",\n assistantMessageToolbarCopyCodeCopiedLabel: \"Copied\",\n assistantMessageToolbarCopyMessageLabel: \"Copy\",\n assistantMessageToolbarThumbsUpLabel: \"Good response\",\n assistantMessageToolbarThumbsDownLabel: \"Bad response\",\n assistantMessageToolbarReadAloudLabel: \"Read aloud\",\n assistantMessageToolbarRegenerateLabel: \"Regenerate\",\n userMessageToolbarCopyMessageLabel: \"Copy\",\n userMessageToolbarEditMessageLabel: \"Edit\",\n chatDisclaimerText:\n \"AI can make mistakes. Please verify important information.\",\n chatToggleOpenLabel: \"Open chat\",\n chatToggleCloseLabel: \"Close chat\",\n modalHeaderTitle: \"CopilotKit Chat\",\n welcomeMessageText: \"How can I help you today?\",\n};\n\nexport type CopilotChatLabels = typeof CopilotChatDefaultLabels;\n\n// Define the full configuration interface\nexport interface CopilotChatConfigurationValue {\n labels: CopilotChatLabels;\n agentId: string;\n threadId: string;\n isModalOpen: boolean;\n setModalOpen: (open: boolean) => void;\n // True when the current threadId was chosen by the caller rather than\n // silently minted inside the provider chain. Consumers that only make\n // sense against a real backend thread (e.g. /connect, suppressing the\n // welcome screen on switch) gate on this instead of `!!threadId`.\n hasExplicitThreadId: boolean;\n}\n\n// Create the configuration context\nconst CopilotChatConfiguration =\n createContext<CopilotChatConfigurationValue | null>(null);\n\n// Provider props interface\nexport interface CopilotChatConfigurationProviderProps {\n children: ReactNode;\n labels?: Partial<CopilotChatLabels>;\n agentId?: string;\n threadId?: string;\n // Lets internal wrappers (e.g. the v1 CopilotKit bridge, which pipes a\n // ThreadsProvider-minted UUID through as `threadId`) declare that the\n // threadId they are supplying is NOT a caller choice. When omitted, the\n // provider infers explicitness from whether the `threadId` prop itself\n // was supplied.\n hasExplicitThreadId?: boolean;\n isModalDefaultOpen?: boolean;\n}\n\n// Provider component\nexport const CopilotChatConfigurationProvider: React.FC<\n CopilotChatConfigurationProviderProps\n> = ({\n children,\n labels,\n agentId,\n threadId,\n hasExplicitThreadId,\n isModalDefaultOpen,\n}) => {\n const parentConfig = useContext(CopilotChatConfiguration);\n\n // Stabilize labels references so that inline objects (new reference on every\n // parent render) don't invalidate mergedLabels and churn the context value.\n // parentConfig?.labels is already stabilized by the parent provider's own\n // useShallowStableRef, so we only need to stabilize the local labels prop.\n const stableLabels = useShallowStableRef(labels);\n const mergedLabels: CopilotChatLabels = useMemo(\n () => ({\n ...CopilotChatDefaultLabels,\n ...parentConfig?.labels,\n ...stableLabels,\n }),\n [stableLabels, parentConfig?.labels],\n );\n\n const resolvedAgentId = agentId ?? parentConfig?.agentId ?? DEFAULT_AGENT_ID;\n\n const resolvedThreadId = useMemo(() => {\n if (threadId) {\n return threadId;\n }\n if (parentConfig?.threadId) {\n return parentConfig.threadId;\n }\n return randomUUID();\n }, [threadId, parentConfig?.threadId]);\n\n // If a caller passed `hasExplicitThreadId`, trust it verbatim (lets the v1\n // bridge mark an auto-minted UUID as non-explicit). Otherwise infer: a\n // threadId supplied as a prop here is by definition a caller choice.\n const ownHasExplicitThreadId =\n hasExplicitThreadId !== undefined ? hasExplicitThreadId : !!threadId;\n const resolvedHasExplicitThreadId =\n ownHasExplicitThreadId || !!parentConfig?.hasExplicitThreadId;\n\n const resolvedDefaultOpen = isModalDefaultOpen ?? true;\n\n const [internalModalOpen, setInternalModalOpen] =\n useState<boolean>(resolvedDefaultOpen);\n\n const hasExplicitDefault = isModalDefaultOpen !== undefined;\n\n // When this provider owns its modal state, wrap the setter so that changes\n // propagate upward to any ancestor provider. This allows an outer\n // CopilotChatConfigurationProvider (e.g. a user's layout-level provider) to\n // observe open/close events that originate deep in the tree — fixing the\n // \"outer hook always returns true\" regression (CPK-7152 Behavior B).\n const setAndSync = useCallback(\n (open: boolean) => {\n setInternalModalOpen(open);\n parentConfig?.setModalOpen(open);\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [parentConfig?.setModalOpen],\n );\n\n // Sync parent → child: when an ancestor's modal state is changed externally\n // (e.g. the user calls setModalOpen from an outer hook), reflect that change\n // in our own state so the sidebar/popup responds accordingly.\n // Skip the initial mount so that our own isModalDefaultOpen is respected and\n // not immediately overwritten by the parent's current value.\n const isMounted = useRef(false);\n useEffect(() => {\n if (!hasExplicitDefault) return;\n if (!isMounted.current) {\n isMounted.current = true;\n return;\n }\n if (parentConfig?.isModalOpen === undefined) return;\n setInternalModalOpen(parentConfig.isModalOpen);\n }, [parentConfig?.isModalOpen, hasExplicitDefault]);\n\n const resolvedIsModalOpen = hasExplicitDefault\n ? internalModalOpen\n : (parentConfig?.isModalOpen ?? internalModalOpen);\n const resolvedSetModalOpen = hasExplicitDefault\n ? setAndSync\n : (parentConfig?.setModalOpen ?? setInternalModalOpen);\n\n const configurationValue: CopilotChatConfigurationValue = useMemo(\n () => ({\n labels: mergedLabels,\n agentId: resolvedAgentId,\n threadId: resolvedThreadId,\n hasExplicitThreadId: resolvedHasExplicitThreadId,\n isModalOpen: resolvedIsModalOpen,\n setModalOpen: resolvedSetModalOpen,\n }),\n [\n mergedLabels,\n resolvedAgentId,\n resolvedThreadId,\n resolvedHasExplicitThreadId,\n resolvedIsModalOpen,\n resolvedSetModalOpen,\n ],\n );\n\n return (\n <CopilotChatConfiguration.Provider value={configurationValue}>\n {children}\n </CopilotChatConfiguration.Provider>\n );\n};\n\n// Hook to use the full configuration\nexport const useCopilotChatConfiguration =\n (): CopilotChatConfigurationValue | null => {\n const configuration = useContext(CopilotChatConfiguration);\n return configuration;\n };\n","import { useCopilotKit } from \"../context\";\nimport { useMemo, useEffect, useReducer, useRef } from \"react\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkit/shared\";\nimport type { AbstractAgent } from \"@ag-ui/client\";\nimport { HttpAgent } from \"@ag-ui/client\";\nimport {\n ProxiedCopilotRuntimeAgent,\n CopilotKitCoreRuntimeConnectionStatus,\n} from \"@copilotkit/core\";\nimport type { SubscribeToAgentSubscriber } from \"@copilotkit/core\";\nimport { useCopilotChatConfiguration } from \"../providers/CopilotChatConfigurationProvider\";\n\nexport enum UseAgentUpdate {\n OnMessagesChanged = \"OnMessagesChanged\",\n OnStateChanged = \"OnStateChanged\",\n OnRunStatusChanged = \"OnRunStatusChanged\",\n}\n\nconst ALL_UPDATES: UseAgentUpdate[] = [\n UseAgentUpdate.OnMessagesChanged,\n UseAgentUpdate.OnStateChanged,\n UseAgentUpdate.OnRunStatusChanged,\n];\n\nexport interface UseAgentProps {\n agentId?: string;\n updates?: UseAgentUpdate[];\n /**\n * Throttle interval (in milliseconds) for re-renders triggered by\n * `onMessagesChanged` and `onStateChanged` notifications. Useful to reduce\n * re-render frequency during high-frequency streaming updates.\n *\n * Uses a leading+trailing pattern with a shared window — first update\n * fires immediately, subsequent updates within the window are coalesced,\n * and a trailing timer ensures the most recent update fires after the\n * window expires. See `CopilotKitCore.subscribeToAgentWithOptions` in `@copilotkit/core`\n * for details.\n *\n * Resolved as: `throttleMs ?? provider defaultThrottleMs ?? 0`.\n * Passing `throttleMs={0}` explicitly disables throttling even when the\n * provider specifies a non-zero `defaultThrottleMs`.\n *\n * Run lifecycle callbacks (`onRunInitialized`, `onRunFinalized`,\n * `onRunFailed`, `onRunErrorEvent`) always fire immediately.\n *\n * @default undefined\n * When unset, inherits from the provider's `defaultThrottleMs`;\n * if that is also unset, the effective value is `0` (no throttle).\n */\n throttleMs?: number;\n}\n\nexport function useAgent({ agentId, updates, throttleMs }: UseAgentProps = {}) {\n agentId ??= DEFAULT_AGENT_ID;\n\n const { copilotkit } = useCopilotKit();\n // Read the provider-level default so it appears in the effect's dep array.\n // subscribeToAgentWithOptions reads it from the core instance, but React needs the dep\n // to know when to re-subscribe.\n const providerThrottleMs = copilotkit.defaultThrottleMs;\n\n const [, forceUpdate] = useReducer((x) => x + 1, 0);\n\n const updateFlags = useMemo(\n () => updates ?? ALL_UPDATES,\n [JSON.stringify(updates)],\n );\n\n // Cache provisional agents to avoid creating new references on every render\n // while the runtime is still connecting. A new reference would cascade into\n // CopilotChat's connectAgent effect, causing unnecessary HTTP calls.\n const provisionalAgentCache = useRef<Map<string, ProxiedCopilotRuntimeAgent>>(\n new Map(),\n );\n\n const agent: AbstractAgent = useMemo(() => {\n const existing = copilotkit.getAgent(agentId);\n if (existing) {\n // Real agent found — clear any cached provisional for this ID\n provisionalAgentCache.current.delete(agentId);\n return existing;\n }\n\n const isRuntimeConfigured = copilotkit.runtimeUrl !== undefined;\n const status = copilotkit.runtimeConnectionStatus;\n\n // While runtime is not yet synced, return a provisional runtime agent\n if (\n isRuntimeConfigured &&\n (status === CopilotKitCoreRuntimeConnectionStatus.Disconnected ||\n status === CopilotKitCoreRuntimeConnectionStatus.Connecting)\n ) {\n // Return cached provisional if available (keeps reference stable)\n const cached = provisionalAgentCache.current.get(agentId);\n if (cached) {\n // Update headers on the cached agent in case they changed\n copilotkit.applyHeadersToAgent(cached);\n return cached;\n }\n\n const provisional = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: copilotkit.runtimeUrl,\n agentId,\n transport: copilotkit.runtimeTransport,\n runtimeMode: \"pending\",\n });\n // Apply current headers so runs/connects inherit them\n copilotkit.applyHeadersToAgent(provisional);\n provisionalAgentCache.current.set(agentId, provisional);\n return provisional;\n }\n\n // Runtime is in Error state — return a provisional agent instead of throwing.\n // The error has already been emitted through the subscriber system\n // (RUNTIME_INFO_FETCH_FAILED). Throwing here would crash the React tree;\n // returning a provisional agent lets onError handlers fire while keeping\n // the app alive.\n if (\n isRuntimeConfigured &&\n status === CopilotKitCoreRuntimeConnectionStatus.Error\n ) {\n const cached = provisionalAgentCache.current.get(agentId);\n if (cached) {\n copilotkit.applyHeadersToAgent(cached);\n return cached;\n }\n const provisional = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: copilotkit.runtimeUrl,\n agentId,\n transport: copilotkit.runtimeTransport,\n runtimeMode: \"pending\",\n });\n copilotkit.applyHeadersToAgent(provisional);\n provisionalAgentCache.current.set(agentId, provisional);\n return provisional;\n }\n\n // No runtime configured and agent doesn't exist — this is a configuration error.\n const knownAgents = Object.keys(copilotkit.agents ?? {});\n const runtimePart = isRuntimeConfigured\n ? `runtimeUrl=${copilotkit.runtimeUrl}`\n : \"no runtimeUrl\";\n throw new Error(\n `useAgent: Agent '${agentId}' not found after runtime sync (${runtimePart}). ` +\n (knownAgents.length\n ? `Known agents: [${knownAgents.join(\", \")}]`\n : \"No agents registered.\") +\n \" Verify your runtime /info and/or agents__unsafe_dev_only.\",\n );\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n agentId,\n copilotkit.agents,\n copilotkit.runtimeConnectionStatus,\n copilotkit.runtimeUrl,\n copilotkit.runtimeTransport,\n JSON.stringify(copilotkit.headers),\n ]);\n\n useEffect(() => {\n if (updateFlags.length === 0) return;\n\n let active = true;\n const handlers: SubscribeToAgentSubscriber = {};\n\n // Microtask-batched forceUpdate: coalesces multiple synchronous\n // notifications (e.g. OnStateChanged + OnRunStatusChanged firing in the\n // same tick) into a single React re-render. This prevents the scroll\n // jumping described in #3499 where rapid unbatched forceUpdate calls\n // cause brief content height fluctuations during streaming.\n let batchScheduled = false;\n const batchedForceUpdate = () => {\n if (!active) return;\n if (!batchScheduled) {\n batchScheduled = true;\n queueMicrotask(() => {\n batchScheduled = false;\n if (active) {\n forceUpdate();\n }\n });\n }\n };\n\n if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) {\n handlers.onMessagesChanged = batchedForceUpdate;\n }\n\n if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) {\n handlers.onStateChanged = batchedForceUpdate;\n }\n\n if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {\n handlers.onRunInitialized = batchedForceUpdate;\n handlers.onRunFinalized = batchedForceUpdate;\n handlers.onRunFailed = batchedForceUpdate;\n // Protocol-level RUN_ERROR event (distinct from onRunFailed which\n // handles local exceptions like network errors).\n handlers.onRunErrorEvent = batchedForceUpdate;\n }\n\n const subscription = copilotkit.subscribeToAgentWithOptions(\n agent,\n handlers,\n {\n throttleMs,\n },\n );\n return () => {\n active = false;\n subscription.unsubscribe();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agent, forceUpdate, throttleMs, providerThrottleMs, updateFlags]);\n\n // Keep HttpAgent headers fresh without mutating inside useMemo, which is\n // unsafe in concurrent mode (React may invoke useMemo multiple times and\n // discard intermediate results, but mutations always land).\n useEffect(() => {\n if (agent instanceof HttpAgent) {\n // Merge core headers on top of the agent's own headers rather than\n // replacing them, so per-agent headers (e.g. an Authorization for a\n // self-hosted backend) are preserved (see #5635).\n copilotkit.applyHeadersToAgent(agent);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agent, JSON.stringify(copilotkit.headers)]);\n\n // Propagate the caller-supplied threadId from the chat configuration onto\n // the agent. AbstractAgent's constructor auto-mints a UUID when no threadId\n // is passed, so without this sync the agent ships its own random UUID in\n // /agent/run, /agent/connect, /agent/stop — diverging from the threadId the\n // app code reads via useThreads/useCopilotChatConfiguration. Gated on\n // hasExplicitThreadId so a ThreadsProvider-minted placeholder UUID doesn't\n // overwrite the auto-minted agent UUID (both are random and useless to the\n // backend; the explicit gate keeps the agent's UUID stable across renders).\n const chatConfig = useCopilotChatConfiguration();\n const configThreadId = chatConfig?.threadId;\n const configHasExplicitThreadId = chatConfig?.hasExplicitThreadId;\n useEffect(() => {\n if (!configHasExplicitThreadId || !configThreadId) return;\n agent.threadId = configThreadId;\n }, [agent, configThreadId, configHasExplicitThreadId]);\n\n return {\n agent,\n };\n}\n","import { useEffect } from \"react\";\nimport { useCopilotKit } from \"../context\";\nimport type { ReactFrontendTool } from \"../types/frontend-tool\";\n\nconst EMPTY_DEPS: ReadonlyArray<unknown> = [];\n\nexport function useFrontendTool<\n T extends Record<string, unknown> = Record<string, unknown>,\n>(tool: ReactFrontendTool<T>, deps?: ReadonlyArray<unknown>) {\n const { copilotkit } = useCopilotKit();\n const extraDeps = deps ?? EMPTY_DEPS;\n\n useEffect(() => {\n const name = tool.name;\n\n // Always register/override the tool for this name on mount\n if (copilotkit.getTool({ toolName: name, agentId: tool.agentId })) {\n console.warn(\n `Tool '${name}' already exists for agent '${tool.agentId || \"global\"}'. Overriding with latest registration.`,\n );\n copilotkit.removeTool(name, tool.agentId);\n }\n copilotkit.addTool(tool);\n\n // Register/override renderer by name and agentId through core.\n // The render function is registered even when tool.parameters is\n // undefined — tools like HITL confirm dialogs have no parameters\n // but still need their UI rendered in the chat.\n if (tool.render) {\n copilotkit.addHookRenderToolCall({\n name,\n args: tool.parameters,\n agentId: tool.agentId,\n render: tool.render,\n });\n }\n\n return () => {\n copilotkit.removeTool(name, tool.agentId);\n // we are intentionally not removing the render here so that the tools can still render in the chat history\n };\n // Depend on stable keys by default and allow callers to opt into\n // additional dependencies for dynamic tool configuration.\n // tool.available is included so toggling availability re-registers the tool.\n }, [tool.name, tool.available, copilotkit, JSON.stringify(extraDeps)]);\n}\n","import type { StandardSchemaV1, InferSchemaOutput } from \"@copilotkit/shared\";\nimport type { ComponentType } from \"react\";\nimport { useFrontendTool } from \"./use-frontend-tool\";\n\ntype InferRenderProps<T> = T extends StandardSchemaV1\n ? InferSchemaOutput<T>\n : any;\n\n/**\n * Registers a React component as a frontend tool renderer in chat.\n *\n * This hook is a convenience wrapper around `useFrontendTool` that:\n * - builds a model-facing tool description,\n * - forwards optional schema parameters (any Standard Schema V1 compatible library),\n * - renders your component with tool call parameters.\n *\n * Use this when you want to display a typed visual component for a tool call\n * without manually wiring a full frontend tool object.\n *\n * When `parameters` is provided, render props are inferred from the schema.\n * When omitted, the render component may accept any props.\n *\n * @typeParam TSchema - Schema describing tool parameters, or `undefined` when no schema is given.\n * @param config - Tool registration config.\n * @param deps - Optional dependencies to refresh registration (same semantics as `useEffect`).\n *\n * @example\n * ```tsx\n * // Without parameters — render accepts any props\n * useComponent({\n * name: \"showGreeting\",\n * render: ({ message }: { message: string }) => <div>{message}</div>,\n * });\n * ```\n *\n * @example\n * ```tsx\n * // With parameters — render props inferred from schema\n * useComponent({\n * name: \"showWeatherCard\",\n * parameters: z.object({ city: z.string() }),\n * render: ({ city }) => <div>{city}</div>,\n * });\n * ```\n *\n * @example\n * ```tsx\n * useComponent(\n * {\n * name: \"renderProfile\",\n * parameters: z.object({ userId: z.string() }),\n * render: ProfileCard,\n * agentId: \"support-agent\",\n * },\n * [selectedAgentId],\n * );\n * ```\n */\nexport function useComponent<\n TSchema extends StandardSchemaV1<any, Record<string, unknown>> | undefined =\n undefined,\n>(\n config: {\n name: string;\n description?: string;\n parameters?: TSchema;\n render: ComponentType<NoInfer<InferRenderProps<TSchema>>>;\n agentId?: string;\n followUp?: boolean;\n },\n deps?: ReadonlyArray<unknown>,\n): void {\n const prefix = `Use this tool to display the \"${config.name}\" component in the chat. This tool renders a visual UI component for the user.`;\n const fullDescription = config.description\n ? `${prefix}\\n\\n${config.description}`\n : prefix;\n\n useFrontendTool(\n {\n name: config.name,\n description: fullDescription,\n parameters: config.parameters,\n render: ({ args }: { args: unknown }) => {\n const Component = config.render;\n return <Component {...(args as InferRenderProps<TSchema>)} />;\n },\n agentId: config.agentId,\n followUp: config.followUp,\n },\n deps,\n );\n}\n","import { useCopilotKit } from \"../context\";\nimport type { ReactFrontendTool } from \"../types/frontend-tool\";\nimport type { ReactHumanInTheLoop } from \"../types/human-in-the-loop\";\nimport type { ReactToolCallRenderer } from \"../types/react-tool-call-renderer\";\nimport { ToolCallStatus } from \"@copilotkit/core\";\nimport { useCallback, useEffect, useRef } from \"react\";\nimport React from \"react\";\nimport { useFrontendTool } from \"./use-frontend-tool\";\n\nexport function useHumanInTheLoop<\n T extends Record<string, unknown> = Record<string, unknown>,\n>(tool: ReactHumanInTheLoop<T>, deps?: ReadonlyArray<unknown>) {\n const { copilotkit } = useCopilotKit();\n const resolvePromiseRef = useRef<((result: unknown) => void) | null>(null);\n // Cleanup that detaches the pending abort listener; cleared whenever the\n // promise settles (via respond() or abort) so the listener can't fire twice\n // or leak after the interaction is done.\n const cleanupAbortRef = useRef<(() => void) | null>(null);\n\n const respond = useCallback(async (result: unknown) => {\n if (resolvePromiseRef.current) {\n cleanupAbortRef.current?.();\n cleanupAbortRef.current = null;\n resolvePromiseRef.current(result);\n resolvePromiseRef.current = null;\n }\n }, []);\n\n const handler = useCallback(\n async (_args: T, context?: { signal?: AbortSignal }) => {\n const signal = context?.signal;\n return new Promise((resolve, reject) => {\n // If the run was already aborted before the handler ran, reject\n // immediately so core records an explicit error tool result instead of\n // silently resolving to an empty string.\n if (signal?.aborted) {\n reject(new Error(\"Human-in-the-loop interaction aborted\"));\n return;\n }\n\n resolvePromiseRef.current = resolve;\n\n if (signal) {\n const onAbort = () => {\n cleanupAbortRef.current = null;\n resolvePromiseRef.current = null;\n reject(new Error(\"Human-in-the-loop interaction aborted\"));\n };\n signal.addEventListener(\"abort\", onAbort, { once: true });\n cleanupAbortRef.current = () => {\n signal.removeEventListener(\"abort\", onAbort);\n };\n }\n });\n },\n [],\n );\n\n const RenderComponent: ReactToolCallRenderer<T>[\"render\"] = useCallback(\n (props) => {\n const ToolComponent = tool.render;\n\n // Build the HITL render props per status. `props` already carries\n // `toolCallId`; we overwrite `name`/`description` with the tool's\n // registration values and add the registration `agentId`, so the HITL\n // render always receives the full prop contract. `respond` is only live\n // while the tool is executing.\n if (props.status === ToolCallStatus.InProgress) {\n const enhancedProps = {\n ...props,\n name: tool.name,\n description: tool.description || \"\",\n agentId: tool.agentId,\n respond: undefined,\n };\n return React.createElement(ToolComponent, enhancedProps);\n } else if (props.status === ToolCallStatus.Executing) {\n const enhancedProps = {\n ...props,\n name: tool.name,\n description: tool.description || \"\",\n agentId: tool.agentId,\n respond,\n };\n return React.createElement(ToolComponent, enhancedProps);\n } else if (props.status === ToolCallStatus.Complete) {\n const enhancedProps = {\n ...props,\n name: tool.name,\n description: tool.description || \"\",\n agentId: tool.agentId,\n respond: undefined,\n };\n return React.createElement(ToolComponent, enhancedProps);\n }\n\n // ToolCallStatus has only the three states handled above, so this point\n // is unreachable and `props` narrows to `never`. The assignment turns a\n // newly-added status into a compile error here — forcing it to get its\n // own branch above — instead of silently rendering without `respond`.\n const exhaustiveCheck: never = props;\n return exhaustiveCheck;\n },\n [tool.render, tool.name, tool.description, tool.agentId, respond],\n );\n\n const frontendTool: ReactFrontendTool<T> = {\n ...tool,\n handler,\n render: RenderComponent,\n };\n\n useFrontendTool(frontendTool, deps);\n\n // Human-in-the-loop tools should remove their renderer on unmount\n // since they can't respond to user interactions anymore\n useEffect(() => {\n return () => {\n copilotkit.removeHookRenderToolCall(tool.name, tool.agentId);\n };\n }, [copilotkit, tool.name, tool.agentId]);\n}\n","import React, {\n useState,\n useEffect,\n useCallback,\n useMemo,\n useRef,\n} from \"react\";\nimport {\n buildResumeArray,\n isInterruptExpired,\n randomUUID,\n} from \"@ag-ui/client\";\nimport type { Interrupt, Message, RunAgentResult } from \"@ag-ui/client\";\nimport { useCopilotKit } from \"../context\";\nimport { useAgent } from \"./use-agent\";\nimport type {\n InterruptEvent,\n InterruptRenderProps,\n InterruptHandlerProps,\n InterruptResolveFn,\n InterruptCancelFn,\n} from \"../types/interrupt\";\n\nexport type {\n InterruptEvent,\n InterruptRenderProps,\n InterruptHandlerProps,\n Interrupt,\n};\n\nconst INTERRUPT_EVENT_NAME = \"on_interrupt\";\n\n/** Internal accumulator response shape consumed by buildResumeArray. */\ntype ResumeResponse =\n | { status: \"resolved\"; payload?: unknown }\n | { status: \"cancelled\" };\n\n/**\n * Normalized pending interrupt. `legacy` carries the custom-event payload;\n * `standard` carries the AG-UI `outcome:\"interrupt\"` interrupts array.\n */\ntype PendingInterrupt =\n | { kind: \"legacy\"; event: InterruptEvent }\n | { kind: \"standard\"; interrupts: 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/** Derive the legacy-compatible `event` for any pending interrupt. */\nfunction toLegacyEvent(pending: PendingInterrupt): InterruptEvent {\n if (pending.kind === \"legacy\") return pending.event;\n return { name: INTERRUPT_EVENT_NAME, value: pending.interrupts[0] };\n}\n\n/**\n * Configuration options for `useInterrupt`.\n */\ninterface UseInterruptConfigBase<TValue = unknown, TResult = never> {\n /**\n * Render function for the interrupt UI.\n *\n * Receives both the standard `interrupt`/`interrupts` and the legacy `event`.\n * Call `resolve(payload)` to resume with user input, or `cancel()` to cancel.\n */\n render: (\n props: InterruptRenderProps<TValue, InterruptResult<TValue, TResult>>,\n ) => React.ReactElement;\n /**\n * Optional pre-render handler invoked when an interrupt is received.\n * Return a sync or async value to expose as `result` in `render`.\n * Rejecting/throwing falls back to `result = null`.\n */\n handler?: InterruptHandlerFn<TValue, TResult>;\n /**\n * Optional predicate to filter which interrupts this hook handles.\n * Receives the legacy-compatible event (for standard interrupts, `value` is\n * the primary `Interrupt`). Return `false` to ignore.\n */\n enabled?: (event: InterruptEvent<TValue>) => boolean;\n /** Optional agent id. Defaults to the current configured chat agent. */\n agentId?: string;\n}\n\nexport interface UseInterruptInChatConfig<\n TValue = unknown,\n TResult = never,\n> extends UseInterruptConfigBase<TValue, TResult> {\n /** When true (default), the interrupt UI renders inside `<CopilotChat>` automatically. */\n renderInChat?: true;\n}\n\nexport interface UseInterruptExternalConfig<\n TValue = unknown,\n TResult = never,\n> extends UseInterruptConfigBase<TValue, TResult> {\n /** When false, the hook returns the interrupt element so you can place it yourself. */\n renderInChat: false;\n}\n\nexport interface UseInterruptDynamicConfig<\n TValue = unknown,\n TResult = never,\n> extends UseInterruptConfigBase<TValue, TResult> {\n /** Dynamic boolean mode. When non-literal, return type is a union. */\n renderInChat: boolean;\n}\n\nexport type UseInterruptConfig<\n TValue = unknown,\n TResult = never,\n TRenderInChat extends InterruptRenderInChat = undefined,\n> = UseInterruptConfigBase<TValue, TResult> & {\n /** When true (default), the interrupt UI renders inside `<CopilotChat>` automatically. */\n renderInChat?: TRenderInChat;\n};\n\n/**\n * Handles agent interrupts with optional filtering, preprocessing, and resume behavior.\n *\n * Supports both the AG-UI standard interrupt flow (`RUN_FINISHED` with\n * `outcome.type === \"interrupt\"`) and the legacy custom-event flow\n * (`on_interrupt`). For standard interrupts, `render` receives `interrupt`\n * (the primary one) and `interrupts` (the full open set); call `resolve(payload)`\n * to resume or `cancel()` to cancel. Resuming addresses the targeted interrupt\n * and, once every open interrupt is addressed, submits a single spec `resume`\n * array via `copilotkit.runAgent`.\n *\n * - `renderInChat: true` (default): the element is published into `<CopilotChat>`; returns `void`.\n * - `renderInChat: false`: the hook returns the interrupt element for manual placement.\n *\n * @example\n * ```tsx\n * useInterrupt({\n * render: ({ interrupt, resolve, cancel }) => (\n * <div>\n * <p>{interrupt?.message}</p>\n * <button onClick={() => resolve({ approved: true })}>Approve</button>\n * <button onClick={() => cancel()}>Cancel</button>\n * </div>\n * ),\n * });\n * ```\n */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport function useInterrupt<\n TResult = never,\n TRenderInChat extends InterruptRenderInChat = undefined,\n>(\n config: UseInterruptConfig<any, TResult, TRenderInChat>,\n): UseInterruptReturn<TRenderInChat> {\n /* eslint-enable @typescript-eslint/no-explicit-any */\n const { copilotkit } = useCopilotKit();\n const { agent } = useAgent({ agentId: config.agentId });\n const [pending, setPending] = useState<PendingInterrupt | null>(null);\n const pendingRef = useRef(pending);\n pendingRef.current = pending;\n const [handlerResult, setHandlerResult] =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n useState<InterruptResult<any, TResult>>(null);\n\n // Accumulated per-interrupt responses for the current standard interrupt set.\n const responsesRef = useRef<Record<string, ResumeResponse>>({});\n\n useEffect(() => {\n let localLegacy: InterruptEvent | null = null;\n let localStandard: Interrupt[] | null = null;\n\n const subscription = agent.subscribe({\n onCustomEvent: ({ event }) => {\n if (event.name === INTERRUPT_EVENT_NAME) {\n localLegacy = { name: event.name, value: event.value };\n }\n },\n onRunFinishedEvent: (params) => {\n if (params.outcome === \"interrupt\") {\n localStandard = params.interrupts;\n }\n },\n onRunStartedEvent: () => {\n localLegacy = null;\n localStandard = null;\n responsesRef.current = {};\n setPending(null);\n },\n onRunFinalized: () => {\n // Standard wins if both somehow appear for one run.\n if (localStandard && localStandard.length > 0) {\n setPending({ kind: \"standard\", interrupts: localStandard });\n } else if (localLegacy) {\n setPending({ kind: \"legacy\", event: localLegacy });\n }\n localLegacy = null;\n localStandard = null;\n },\n onRunFailed: () => {\n localLegacy = null;\n localStandard = null;\n responsesRef.current = {};\n setPending(null);\n },\n });\n\n return () => subscription.unsubscribe();\n }, [agent]);\n\n // Submit the accumulated standard responses once all open interrupts are\n // addressed; otherwise return void and keep waiting.\n const submitStandardIfComplete = useCallback(\n async (interrupts: Interrupt[]): Promise<RunAgentResult | void> => {\n const allAddressed = interrupts.every((i) => responsesRef.current[i.id]);\n if (!allAddressed) return;\n\n const expired = interrupts.find((i) => isInterruptExpired(i));\n if (expired) {\n console.error(\n `[CopilotKit] useInterrupt: interrupt ${expired.id} expired at ${expired.expiresAt}; not resuming.`,\n );\n responsesRef.current = {};\n setPending(null);\n return;\n }\n\n const resume = buildResumeArray(interrupts, responsesRef.current);\n\n // Persist each resolution as a tool-result message so the conversation\n // stays well-formed on later turns. The interrupt run left the tool call\n // unanswered; without recording its result here, the NEXT turn ships a\n // dangling tool call (assistant tool-call with no tool result) and the\n // model errors / re-calls the tool in a loop. Only standard, tool-backed\n // interrupts carry a `toolCallId`; custom `ctx.interrupt()` ones don't and\n // are resumed purely via the `resume` array.\n for (const i of interrupts) {\n if (!i.toolCallId) continue;\n const response = responsesRef.current[i.id];\n const content =\n response.status === \"cancelled\"\n ? { status: \"cancelled\" }\n : (response.payload ?? { status: \"resolved\" });\n agent.addMessage({\n id: randomUUID(),\n role: \"tool\",\n toolCallId: i.toolCallId,\n content: JSON.stringify(content),\n } as Message);\n }\n\n responsesRef.current = {};\n try {\n return await copilotkit.runAgent({ agent, resume });\n } catch (err) {\n console.error(\n \"[CopilotKit] useInterrupt resolve: runAgent rejected; clearing pending + rethrowing\",\n err,\n );\n setPending(null);\n throw err;\n }\n },\n [agent, copilotkit],\n );\n\n const resolve: InterruptResolveFn = useCallback(\n async (payload, interruptId) => {\n const current = pendingRef.current;\n if (!current) return;\n\n if (current.kind === \"legacy\") {\n try {\n return await copilotkit.runAgent({\n agent,\n forwardedProps: {\n command: { resume: payload, interruptEvent: current.event.value },\n },\n });\n } catch (err) {\n console.error(\n \"[CopilotKit] useInterrupt resolve: runAgent rejected; clearing pending + rethrowing\",\n err,\n );\n setPending(null);\n throw err;\n }\n }\n\n if (current.interrupts.length > 1 && interruptId === undefined) {\n console.warn(\n `[CopilotKit] useInterrupt: resolve()/cancel() called without an interruptId while ${current.interrupts.length} interrupts are open; defaulting to the first. Pass an interruptId to address a specific interrupt.`,\n );\n }\n const id = interruptId ?? current.interrupts[0]?.id;\n if (!id) return;\n responsesRef.current[id] = { status: \"resolved\", payload };\n return submitStandardIfComplete(current.interrupts);\n },\n [agent, copilotkit, submitStandardIfComplete],\n );\n\n const cancel: InterruptCancelFn = useCallback(\n async (interruptId) => {\n const current = pendingRef.current;\n if (!current) return;\n\n if (current.kind === \"legacy\") {\n // Legacy interrupts have no cancel semantics; dismiss without resuming.\n console.warn(\n \"[CopilotKit] useInterrupt: cancel() is not supported for legacy on_interrupt interrupts; dismissing.\",\n );\n setPending(null);\n return;\n }\n\n if (current.interrupts.length > 1 && interruptId === undefined) {\n console.warn(\n `[CopilotKit] useInterrupt: resolve()/cancel() called without an interruptId while ${current.interrupts.length} interrupts are open; defaulting to the first. Pass an interruptId to address a specific interrupt.`,\n );\n }\n const id = interruptId ?? current.interrupts[0]?.id;\n if (!id) return;\n responsesRef.current[id] = { status: \"cancelled\" };\n return submitStandardIfComplete(current.interrupts);\n },\n [submitStandardIfComplete],\n );\n\n // Stabilize consumer-supplied callbacks behind refs so inline lambdas do not\n // churn the element memo identity or the handler effect.\n const renderRef = useRef(config.render);\n renderRef.current = config.render;\n const enabledRef = useRef(config.enabled);\n enabledRef.current = config.enabled;\n const handlerRef = useRef(config.handler);\n handlerRef.current = config.handler;\n const resolveRef = useRef(resolve);\n resolveRef.current = resolve;\n const cancelRef = useRef(cancel);\n cancelRef.current = cancel;\n\n // Predicate evaluator: a throw is treated as \"disabled\" (false) and logged.\n const isEnabled = (event: InterruptEvent): boolean => {\n const predicate = enabledRef.current;\n if (!predicate) return true;\n try {\n return predicate(event);\n } catch (err) {\n console.error(\n \"[CopilotKit] useInterrupt enabled predicate threw; treating interrupt as disabled:\",\n err,\n );\n return false;\n }\n };\n\n useEffect(() => {\n if (!pending) {\n setHandlerResult(null);\n return;\n }\n const legacyEvent = toLegacyEvent(pending);\n if (!isEnabled(legacyEvent)) {\n setHandlerResult(null);\n return;\n }\n const handler = handlerRef.current;\n if (!handler) {\n setHandlerResult(null);\n return;\n }\n\n let cancelled = false;\n let maybePromise: ReturnType<typeof handler>;\n try {\n maybePromise = handler({\n event: legacyEvent,\n interrupt: pending.kind === \"standard\" ? pending.interrupts[0] : null,\n interrupts: pending.kind === \"standard\" ? pending.interrupts : [],\n resolve: resolveRef.current,\n cancel: cancelRef.current,\n });\n } catch (err) {\n console.error(\n \"[CopilotKit] useInterrupt handler threw; result will be null:\",\n err,\n );\n if (!cancelled) setHandlerResult(null);\n return () => {\n cancelled = true;\n };\n }\n\n if (isPromiseLike(maybePromise)) {\n Promise.resolve(maybePromise)\n .then((resolved) => {\n if (!cancelled) setHandlerResult(resolved);\n })\n .catch((err) => {\n console.error(\n \"[CopilotKit] useInterrupt handler rejected; result will be null:\",\n err,\n );\n if (!cancelled) setHandlerResult(null);\n });\n } else {\n setHandlerResult(maybePromise);\n }\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [pending]);\n\n const element = useMemo(() => {\n if (!pending) return null;\n const legacyEvent = toLegacyEvent(pending);\n if (!isEnabled(legacyEvent)) return null;\n\n return renderRef.current({\n event: legacyEvent,\n interrupt: pending.kind === \"standard\" ? pending.interrupts[0] : null,\n interrupts: pending.kind === \"standard\" ? pending.interrupts : [],\n result: handlerResult,\n resolve,\n cancel,\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [pending, handlerResult, resolve, cancel]);\n\n // Publish to core for in-chat rendering. Publish-only.\n useEffect(() => {\n if (config.renderInChat === false) return;\n copilotkit.setInterruptElement(element);\n }, [element, config.renderInChat, copilotkit]);\n\n // Nullify on true unmount only.\n useEffect(() => {\n if (config.renderInChat === false) return;\n return () => {\n copilotkit.setInterruptElement(null);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n if (config.renderInChat === false) {\n return element as UseInterruptReturn<TRenderInChat>;\n }\n\n return undefined as UseInterruptReturn<TRenderInChat>;\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { Suggestion } from \"@copilotkit/core\";\nimport { useCopilotKit } from \"../context\";\nimport { useCopilotChatConfiguration } from \"../providers/CopilotChatConfigurationProvider\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkit/shared\";\n\nexport interface UseSuggestionsOptions {\n agentId?: string;\n}\n\nexport interface UseSuggestionsResult {\n suggestions: Suggestion[];\n reloadSuggestions: () => void;\n clearSuggestions: () => void;\n isLoading: boolean;\n}\n\nexport function useSuggestions({\n agentId,\n}: UseSuggestionsOptions = {}): UseSuggestionsResult {\n const { copilotkit } = useCopilotKit();\n const config = useCopilotChatConfiguration();\n const resolvedAgentId = useMemo(\n () => agentId ?? config?.agentId ?? DEFAULT_AGENT_ID,\n [agentId, config?.agentId],\n );\n\n const [suggestions, setSuggestions] = useState<Suggestion[]>(() => {\n const result = copilotkit.getSuggestions(resolvedAgentId);\n return result.suggestions;\n });\n const [isLoading, setIsLoading] = useState(() => {\n const result = copilotkit.getSuggestions(resolvedAgentId);\n return result.isLoading;\n });\n\n useEffect(() => {\n const result = copilotkit.getSuggestions(resolvedAgentId);\n setSuggestions(result.suggestions);\n setIsLoading(result.isLoading);\n }, [copilotkit, resolvedAgentId]);\n\n useEffect(() => {\n const subscription = copilotkit.subscribe({\n onSuggestionsChanged: ({ agentId: changedAgentId, suggestions }) => {\n if (changedAgentId !== resolvedAgentId) {\n return;\n }\n setSuggestions(suggestions);\n },\n onSuggestionsStartedLoading: ({ agentId: changedAgentId }) => {\n if (changedAgentId !== resolvedAgentId) {\n return;\n }\n setIsLoading(true);\n },\n onSuggestionsFinishedLoading: ({ agentId: changedAgentId }) => {\n if (changedAgentId !== resolvedAgentId) {\n return;\n }\n setIsLoading(false);\n },\n onSuggestionsConfigChanged: () => {\n const result = copilotkit.getSuggestions(resolvedAgentId);\n setSuggestions(result.suggestions);\n setIsLoading(result.isLoading);\n },\n });\n\n return () => {\n subscription.unsubscribe();\n };\n }, [copilotkit, resolvedAgentId]);\n\n const reloadSuggestions = useCallback(() => {\n copilotkit.reloadSuggestions(resolvedAgentId);\n // Loading state is handled by onSuggestionsStartedLoading event\n }, [copilotkit, resolvedAgentId]);\n\n const clearSuggestions = useCallback(() => {\n copilotkit.clearSuggestions(resolvedAgentId);\n // State updates are handled by onSuggestionsChanged event\n }, [copilotkit, resolvedAgentId]);\n\n return {\n suggestions,\n reloadSuggestions,\n clearSuggestions,\n isLoading,\n };\n}\n","import { useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { useCopilotKit } from \"../context\";\nimport { useCopilotChatConfiguration } from \"../providers/CopilotChatConfigurationProvider\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkit/shared\";\nimport type {\n DynamicSuggestionsConfig,\n StaticSuggestionsConfig,\n SuggestionsConfig,\n Suggestion,\n} from \"@copilotkit/core\";\n\ntype StaticSuggestionInput = Omit<Suggestion, \"isLoading\"> &\n Partial<Pick<Suggestion, \"isLoading\">>;\n\ntype StaticSuggestionsConfigInput = Omit<\n StaticSuggestionsConfig,\n \"suggestions\"\n> & {\n suggestions: StaticSuggestionInput[];\n};\n\ntype SuggestionsConfigInput =\n | DynamicSuggestionsConfig\n | StaticSuggestionsConfigInput;\n\nexport function useConfigureSuggestions(\n config: SuggestionsConfigInput | null | undefined,\n deps?: ReadonlyArray<unknown>,\n): void {\n const { copilotkit } = useCopilotKit();\n const chatConfig = useCopilotChatConfiguration();\n const extraDeps = deps ?? [];\n\n const resolvedConsumerAgentId = useMemo(\n () => chatConfig?.agentId ?? DEFAULT_AGENT_ID,\n [chatConfig?.agentId],\n );\n\n const rawConsumerAgentId = useMemo(\n () =>\n config ? (config as SuggestionsConfigInput).consumerAgentId : undefined,\n [config],\n );\n\n const normalizationCacheRef = useRef<{\n serialized: string | null;\n config: SuggestionsConfig | null;\n }>({\n serialized: null,\n config: null,\n });\n\n const { normalizedConfig, serializedConfig } = useMemo(() => {\n if (!config) {\n normalizationCacheRef.current = { serialized: null, config: null };\n return { normalizedConfig: null, serializedConfig: null };\n }\n\n if (config.available === \"disabled\") {\n normalizationCacheRef.current = { serialized: null, config: null };\n return { normalizedConfig: null, serializedConfig: null };\n }\n\n let built: SuggestionsConfig;\n if (isDynamicConfig(config)) {\n built = {\n ...config,\n } satisfies DynamicSuggestionsConfig;\n } else {\n const normalizedSuggestions = normalizeStaticSuggestions(\n config.suggestions,\n );\n const baseConfig: StaticSuggestionsConfig = {\n ...config,\n suggestions: normalizedSuggestions,\n };\n built = baseConfig;\n }\n\n const serialized = JSON.stringify(built);\n const cache = normalizationCacheRef.current;\n if (cache.serialized === serialized && cache.config) {\n return { normalizedConfig: cache.config, serializedConfig: serialized };\n }\n\n normalizationCacheRef.current = { serialized, config: built };\n return { normalizedConfig: built, serializedConfig: serialized };\n }, [config, resolvedConsumerAgentId, ...extraDeps]);\n const latestConfigRef = useRef<SuggestionsConfig | null>(null);\n latestConfigRef.current = normalizedConfig;\n const previousSerializedConfigRef = useRef<string | null>(null);\n\n const targetAgentId = useMemo(() => {\n if (!normalizedConfig) {\n return resolvedConsumerAgentId;\n }\n const consumer = (\n normalizedConfig as StaticSuggestionsConfig | DynamicSuggestionsConfig\n ).consumerAgentId;\n if (!consumer || consumer === \"*\") {\n return resolvedConsumerAgentId;\n }\n return consumer;\n }, [normalizedConfig, resolvedConsumerAgentId]);\n\n const isGlobalConfig =\n rawConsumerAgentId === undefined || rawConsumerAgentId === \"*\";\n\n const isDynamicConfigType = useMemo(\n () => !!normalizedConfig && \"instructions\" in normalizedConfig,\n [normalizedConfig],\n );\n\n const requestReload = useCallback(() => {\n if (!normalizedConfig) {\n return;\n }\n\n if (isGlobalConfig) {\n const seen = new Set<string>();\n const agents = Object.values(copilotkit.agents ?? {});\n for (const entry of agents) {\n const agentId = entry.agentId;\n if (!agentId) {\n continue;\n }\n seen.add(agentId);\n if (!entry.isRunning) {\n copilotkit.reloadSuggestions(agentId);\n }\n }\n // Also reload for the chat's resolved consumer agent. The registry can\n // be empty at this point (e.g. runtime info still loading), in which\n // case the loop above wouldn't have fired for the agent the user is\n // actually chatting with — and the welcome screen would render with\n // no suggestions until they navigate away and back.\n if (targetAgentId && !seen.has(targetAgentId)) {\n copilotkit.reloadSuggestions(targetAgentId);\n }\n return;\n }\n\n if (!targetAgentId) {\n return;\n }\n\n copilotkit.reloadSuggestions(targetAgentId);\n }, [copilotkit, isGlobalConfig, normalizedConfig, targetAgentId]);\n\n useEffect(() => {\n if (!serializedConfig || !latestConfigRef.current) {\n return;\n }\n\n const id = copilotkit.addSuggestionsConfig(latestConfigRef.current);\n\n requestReload();\n\n return () => {\n copilotkit.removeSuggestionsConfig(id);\n };\n }, [copilotkit, serializedConfig, requestReload]);\n\n useEffect(() => {\n if (!normalizedConfig) {\n previousSerializedConfigRef.current = null;\n return;\n }\n if (\n serializedConfig &&\n previousSerializedConfigRef.current === serializedConfig\n ) {\n return;\n }\n if (serializedConfig) {\n previousSerializedConfigRef.current = serializedConfig;\n }\n requestReload();\n }, [normalizedConfig, requestReload, serializedConfig]);\n\n useEffect(() => {\n if (!normalizedConfig || extraDeps.length === 0) {\n return;\n }\n requestReload();\n }, [extraDeps.length, normalizedConfig, requestReload, ...extraDeps]);\n\n // When agents arrive after the initial render (runtime info just landed),\n // re-request a reload so dynamic configs that need a real agent can finally\n // generate. Skip for static configs — they don't need an agent and the\n // initial mount reload already handled them. Skip when the target agent\n // is already in the registry — the initial reload already covered it, and\n // re-firing on every subsequent `onAgentsChanged` (e.g. dev-mode hot\n // reloads, sibling chat configs mounting) would stack overlapping\n // generations.\n useEffect(() => {\n if (!normalizedConfig || !isDynamicConfigType) return;\n if (!targetAgentId) return;\n\n const initiallyPresent = !!copilotkit.getAgent(targetAgentId);\n if (initiallyPresent) return;\n\n const subscription = copilotkit.subscribe({\n onAgentsChanged: () => {\n if (copilotkit.getAgent(targetAgentId)) {\n requestReload();\n subscription.unsubscribe();\n }\n },\n });\n return () => {\n subscription.unsubscribe();\n };\n }, [\n copilotkit,\n normalizedConfig,\n isDynamicConfigType,\n targetAgentId,\n requestReload,\n ]);\n}\n\nfunction isDynamicConfig(\n config: SuggestionsConfigInput,\n): config is DynamicSuggestionsConfig {\n return \"instructions\" in config;\n}\n\nfunction normalizeStaticSuggestions(\n suggestions: StaticSuggestionInput[],\n): Suggestion[] {\n return suggestions.map((suggestion) => ({\n ...suggestion,\n isLoading: suggestion.isLoading ?? false,\n }));\n}\n","import { useCopilotKit } from \"../context\";\nimport { useLayoutEffect, useMemo } from \"react\";\n\n/**\n * Represents any value that can be serialized to JSON.\n */\nexport type JsonSerializable =\n | string\n | number\n | boolean\n | null\n | JsonSerializable[]\n | { [key: string]: JsonSerializable };\n\n/**\n * Context configuration for useAgentContext.\n * Accepts any JSON-serializable value which will be converted to a string.\n */\nexport interface AgentContextInput {\n /** A human-readable description of what this context represents */\n description: string;\n /** The context value - will be converted to a JSON string if not already a string */\n value: JsonSerializable;\n}\n\nexport function useAgentContext(context: AgentContextInput) {\n const { description, value } = context;\n const { copilotkit } = useCopilotKit();\n\n const stringValue = useMemo(() => {\n if (typeof value === \"string\") {\n return value;\n }\n return JSON.stringify(value);\n }, [value]);\n\n useLayoutEffect(() => {\n if (!copilotkit) return;\n\n const id = copilotkit.addContext({ description, value: stringValue });\n return () => {\n copilotkit.removeContext(id);\n };\n }, [description, stringValue, copilotkit]);\n}\n","import { useCopilotKit } from \"../context\";\nimport {\n CopilotKitCoreRuntimeConnectionStatus,\n ɵcreateThreadStore,\n ɵselectThreads,\n ɵselectThreadsError,\n ɵselectThreadsIsLoading,\n ɵselectHasNextPage,\n ɵselectIsFetchingNextPage,\n} from \"@copilotkit/core\";\nimport type { ɵThreadRuntimeContext, ɵThreadStore } from \"@copilotkit/core\";\nimport {\n useCallback,\n useEffect,\n useMemo,\n useState,\n useSyncExternalStore,\n} from \"react\";\n\n/**\n * A conversation thread managed by the Intelligence platform.\n *\n * Each thread has a unique `id`, an optional human-readable `name`, and\n * timestamp fields tracking creation and update times.\n */\nexport interface Thread {\n id: string;\n agentId: string;\n name: string | null;\n archived: boolean;\n createdAt: string;\n updatedAt: string;\n /**\n * ISO-8601 timestamp of the most recent agent run on this thread. Absent\n * when the thread has never been run. Prefer this over `updatedAt` for\n * user-facing \"last activity\" displays — it is not bumped by metadata-only\n * actions like rename or archive.\n */\n lastRunAt?: string;\n}\n\n/**\n * Configuration for the {@link useThreads} hook.\n *\n * Thread operations are scoped to the runtime-authenticated user and the\n * provided agent on the Intelligence platform.\n */\nexport interface UseThreadsInput {\n /** The ID of the agent whose threads to list and manage. */\n agentId: string;\n /** When `true`, archived threads are included in the list. Defaults to `false`. */\n includeArchived?: boolean;\n /** Maximum number of threads to fetch per page. When set, enables cursor-based pagination. */\n limit?: number;\n}\n\n/**\n * Return value of the {@link useThreads} hook.\n *\n * The `threads` array is kept in sync with the platform via a realtime\n * WebSocket subscription (when available) and is sorted most-recently-updated\n * first. Mutations reject with an `Error` if the platform request fails.\n */\nexport interface UseThreadsResult {\n /**\n * Threads for the current user/agent pair, sorted by most recently\n * updated first. Updated in realtime when the platform pushes metadata\n * events. Includes archived threads only when `includeArchived` is set.\n */\n threads: Thread[];\n /**\n * `true` while the initial thread list is being fetched from the platform.\n * Subsequent realtime updates do not re-enter the loading state.\n */\n isLoading: boolean;\n /**\n * The most recent error from fetching threads or executing a mutation,\n * or `null` when there is no error. Reset to `null` on the next\n * successful fetch.\n */\n error: Error | null;\n /**\n * `true` when there are more threads available to fetch via\n * {@link fetchMoreThreads}. Only meaningful when `limit` is set.\n */\n hasMoreThreads: boolean;\n /**\n * `true` while a subsequent page of threads is being fetched.\n */\n isFetchingMoreThreads: boolean;\n /**\n * Fetch the next page of threads. No-op when {@link hasMoreThreads} is\n * `false` or a fetch is already in progress.\n */\n fetchMoreThreads: () => void;\n /**\n * Rename a thread on the platform.\n * Resolves when the server confirms the update; rejects on failure.\n */\n renameThread: (threadId: string, name: string) => Promise<void>;\n /**\n * Archive a thread on the platform.\n * Archived threads are excluded from subsequent list results.\n * Resolves when the server confirms the update; rejects on failure.\n */\n archiveThread: (threadId: string) => Promise<void>;\n /**\n * Restore a previously archived thread on the platform.\n * The thread re-appears in default (non-archived) list results.\n * Resolves when the server confirms the update; rejects on failure.\n */\n unarchiveThread: (threadId: string) => Promise<void>;\n /**\n * Permanently delete a thread from the platform.\n * This is irreversible. Resolves when the server confirms deletion;\n * rejects on failure.\n */\n deleteThread: (threadId: string) => Promise<void>;\n}\n\nfunction useThreadStoreSelector<T>(\n store: ɵThreadStore,\n selector: (state: ReturnType<ɵThreadStore[\"getState\"]>) => T,\n): T {\n return useSyncExternalStore(\n useCallback(\n (onStoreChange) => {\n const subscription = store.select(selector).subscribe(onStoreChange);\n return () => subscription.unsubscribe();\n },\n [store, selector],\n ),\n () => selector(store.getState()),\n );\n}\n\n/**\n * React hook for listing and managing Intelligence platform threads.\n *\n * On mount the hook fetches the thread list for the runtime-authenticated user\n * and the given `agentId`. When the Intelligence platform exposes a WebSocket\n * URL, it also opens a realtime subscription so the `threads` array stays\n * current without polling — thread creates, renames, archives, and deletes\n * from any client are reflected immediately.\n *\n * Mutation methods (`renameThread`, `archiveThread`, `unarchiveThread`,\n * `deleteThread`) return promises that resolve once the platform confirms the\n * operation and reject with an `Error` on failure.\n *\n * @param input - Agent identifier and optional list controls.\n * @returns Thread list state and stable mutation callbacks.\n *\n * @example\n * ```tsx\n * import { useThreads } from \"@copilotkit/react-core\";\n *\n * function ThreadList() {\n * const { threads, isLoading, renameThread, deleteThread } = useThreads({\n * agentId: \"agent-1\",\n * });\n *\n * if (isLoading) return <p>Loading…</p>;\n *\n * return (\n * <ul>\n * {threads.map((t) => (\n * <li key={t.id}>\n * {t.name ?? \"Untitled\"}\n * <button onClick={() => renameThread(t.id, \"New name\")}>Rename</button>\n * <button onClick={() => deleteThread(t.id)}>Delete</button>\n * </li>\n * ))}\n * </ul>\n * );\n * }\n * ```\n */\nexport function useThreads({\n agentId,\n includeArchived,\n limit,\n}: UseThreadsInput): UseThreadsResult {\n const { copilotkit } = useCopilotKit();\n\n const [store] = useState(() =>\n ɵcreateThreadStore({\n fetch: globalThis.fetch,\n }),\n );\n\n const coreThreads = useThreadStoreSelector(store, ɵselectThreads);\n const threads: Thread[] = useMemo(\n () =>\n coreThreads.map(\n ({ id, agentId, name, archived, createdAt, updatedAt, lastRunAt }) => ({\n id,\n agentId,\n name,\n archived,\n createdAt,\n updatedAt,\n ...(lastRunAt !== undefined ? { lastRunAt } : {}),\n }),\n ),\n [coreThreads],\n );\n const storeIsLoading = useThreadStoreSelector(store, ɵselectThreadsIsLoading);\n const storeError = useThreadStoreSelector(store, ɵselectThreadsError);\n const hasMoreThreads = useThreadStoreSelector(store, ɵselectHasNextPage);\n const isFetchingMoreThreads = useThreadStoreSelector(\n store,\n ɵselectIsFetchingNextPage,\n );\n const headersKey = useMemo(() => {\n return JSON.stringify(\n Object.entries(copilotkit.headers ?? {}).sort(([left], [right]) =>\n left.localeCompare(right),\n ),\n );\n }, [copilotkit.headers]);\n const runtimeStatus = copilotkit.runtimeConnectionStatus;\n const threadListEndpointSupported =\n copilotkit.threadEndpoints?.list !== false;\n const threadMutationsSupported =\n copilotkit.threadEndpoints?.mutations !== false;\n const threadEndpointsUnavailable =\n !!copilotkit.runtimeUrl &&\n runtimeStatus === CopilotKitCoreRuntimeConnectionStatus.Connected &&\n !threadListEndpointSupported;\n const runtimeError = useMemo(() => {\n if (copilotkit.runtimeUrl) {\n return null;\n }\n\n return new Error(\"Runtime URL is not configured\");\n }, [copilotkit.runtimeUrl]);\n const threadEndpointsError = useMemo(() => {\n if (!threadEndpointsUnavailable) {\n return null;\n }\n\n return new Error(\n \"Thread endpoints are not available on this CopilotKit runtime\",\n );\n }, [threadEndpointsUnavailable]);\n const threadMutationsError = useMemo(() => {\n if (threadMutationsSupported) {\n return null;\n }\n\n return new Error(\n \"Thread mutations are not available on this CopilotKit runtime\",\n );\n }, [threadMutationsSupported]);\n\n // Tracks whether we've dispatched the first real context to the store.\n // The store itself starts with `isLoading: false`, so before we dispatch\n // consumers would otherwise see an empty, non-loading state (empty-list\n // flash). While runtimeUrl is set and we haven't dispatched yet, we\n // synthesize `isLoading: true` so the UI keeps its loading indicator until\n // the first fetch is in flight (at which point the store's own\n // isLoading takes over).\n const [hasDispatchedContext, setHasDispatchedContext] = useState(false);\n const preConnectLoading =\n !!copilotkit.runtimeUrl &&\n !threadEndpointsUnavailable &&\n !hasDispatchedContext;\n\n const isLoading =\n runtimeError || threadEndpointsError\n ? false\n : preConnectLoading || storeIsLoading;\n const error = runtimeError ?? threadEndpointsError ?? storeError;\n\n useEffect(() => {\n store.start();\n return () => {\n store.stop();\n };\n }, [store]);\n\n // Defer setting the context until the runtime reports Connected. Before\n // `/info` resolves we don't know `intelligence.wsUrl`, so dispatching the\n // context early would issue a list fetch with `wsUrl: undefined`, then a\n // second list fetch (and a `/threads/subscribe`) once the flag lands.\n // Waiting lets the hook issue just one `/threads?…` + one `/threads/subscribe`.\n //\n // When `runtimeUrl` is absent we dispatch `null` to clear the store. For\n // transient states (Disconnected/Connecting/Error with a URL still set) we\n // leave the previously-dispatched context in place — any in-flight\n // realtime subscription or cached thread list stays usable while the\n // runtime recovers, and we don't re-trigger a fetch storm on transitions.\n useEffect(() => {\n copilotkit.registerThreadStore(agentId, store);\n return () => {\n copilotkit.unregisterThreadStore(agentId);\n };\n }, [copilotkit, agentId, store]);\n\n useEffect(() => {\n if (!copilotkit.runtimeUrl) {\n store.setContext(null);\n setHasDispatchedContext(false);\n return;\n }\n\n // Wait for /info to land so we can include `wsUrl` in the initial\n // context and avoid a redundant second list fetch.\n if (runtimeStatus !== CopilotKitCoreRuntimeConnectionStatus.Connected) {\n return;\n }\n\n if (!threadListEndpointSupported) {\n store.setContext(null);\n setHasDispatchedContext(false);\n return;\n }\n\n const context: ɵThreadRuntimeContext = {\n runtimeUrl: copilotkit.runtimeUrl,\n headers: { ...copilotkit.headers },\n wsUrl: copilotkit.intelligence?.wsUrl,\n agentId,\n includeArchived,\n limit,\n };\n\n store.setContext(context);\n setHasDispatchedContext(true);\n }, [\n store,\n copilotkit.runtimeUrl,\n runtimeStatus,\n headersKey,\n copilotkit.intelligence?.wsUrl,\n threadListEndpointSupported,\n agentId,\n includeArchived,\n limit,\n ]);\n\n const guardMutation = useCallback(\n <TArgs extends unknown[]>(\n mutation: (...args: TArgs) => Promise<void>,\n ): ((...args: TArgs) => Promise<void>) => {\n return (...args: TArgs) => {\n if (threadMutationsError) {\n return Promise.reject(threadMutationsError);\n }\n return mutation(...args);\n };\n },\n [threadMutationsError],\n );\n\n const renameThread = useMemo(\n () =>\n guardMutation((threadId: string, name: string) =>\n store.renameThread(threadId, name),\n ),\n [store, guardMutation],\n );\n\n const archiveThread = useMemo(\n () => guardMutation((threadId: string) => store.archiveThread(threadId)),\n [store, guardMutation],\n );\n\n const unarchiveThread = useMemo(\n () => guardMutation((threadId: string) => store.unarchiveThread(threadId)),\n [store, guardMutation],\n );\n\n const deleteThread = useMemo(\n () => guardMutation((threadId: string) => store.deleteThread(threadId)),\n [store, guardMutation],\n );\n\n const fetchMoreThreads = useCallback(() => store.fetchNextPage(), [store]);\n\n return {\n threads,\n isLoading,\n error,\n hasMoreThreads,\n isFetchingMoreThreads,\n fetchMoreThreads,\n renameThread,\n archiveThread,\n unarchiveThread,\n deleteThread,\n };\n}\n","import React from \"react\";\nimport { z } from \"zod\";\nimport type { StandardSchemaV1, InferSchemaOutput } from \"@copilotkit/shared\";\nimport { ReactToolCallRenderer } from \"./react-tool-call-renderer\";\nimport { ToolCallStatus } from \"@copilotkit/core\";\n\n/**\n * Helper to define a type-safe tool call renderer entry.\n * - Accepts a single object whose keys match ReactToolCallRenderer's fields: { name, args, render, agentId? }.\n * - Derives `args` type from the provided schema (any Standard Schema V1 compatible library).\n * - Ensures the render function param type exactly matches ReactToolCallRenderer<T>[\"render\"]'s param.\n * - For wildcard tools (name: \"*\"), args is optional and defaults to z.any()\n */\ntype RenderProps<T> =\n | {\n name: string;\n toolCallId: string;\n args: Partial<T>;\n status: ToolCallStatus.InProgress;\n result: undefined;\n }\n | {\n name: string;\n toolCallId: string;\n args: T;\n status: ToolCallStatus.Executing;\n result: undefined;\n }\n | {\n name: string;\n toolCallId: string;\n args: T;\n status: ToolCallStatus.Complete;\n result: string;\n };\n\n// Overload for wildcard tools without args\nexport function defineToolCallRenderer(def: {\n name: \"*\";\n render: (props: RenderProps<any>) => React.ReactElement;\n agentId?: string;\n}): ReactToolCallRenderer<any>;\n\n// Overload for regular tools with args\nexport function defineToolCallRenderer<S extends StandardSchemaV1>(def: {\n name: string;\n args: S;\n render: (props: RenderProps<InferSchemaOutput<S>>) => React.ReactElement;\n agentId?: string;\n}): ReactToolCallRenderer<InferSchemaOutput<S>>;\n\n// Implementation\nexport function defineToolCallRenderer<S extends StandardSchemaV1>(def: {\n name: string;\n args?: S;\n render: (props: any) => React.ReactElement;\n agentId?: string;\n}): ReactToolCallRenderer<any> {\n // For wildcard tools, default to z.any() if no args provided\n const argsSchema = def.name === \"*\" && !def.args ? z.any() : def.args;\n\n return {\n name: def.name,\n args: argsSchema,\n render: def.render as React.ComponentType<any>,\n ...(def.agentId ? { agentId: def.agentId } : {}),\n };\n}\n","import { useEffect } from \"react\";\nimport type { StandardSchemaV1, InferSchemaOutput } from \"@copilotkit/shared\";\nimport { ToolCallStatus } from \"@copilotkit/core\";\nimport { useCopilotKit } from \"../context\";\nimport { defineToolCallRenderer } from \"../types/defineToolCallRenderer\";\n\nconst EMPTY_DEPS: ReadonlyArray<unknown> = [];\n\nexport interface RenderToolInProgressProps<S extends StandardSchemaV1> {\n name: string;\n toolCallId: string;\n parameters: Partial<InferSchemaOutput<S>>;\n status: \"inProgress\";\n result: undefined;\n}\n\nexport interface RenderToolExecutingProps<S extends StandardSchemaV1> {\n name: string;\n toolCallId: string;\n parameters: InferSchemaOutput<S>;\n status: \"executing\";\n result: undefined;\n}\n\nexport interface RenderToolCompleteProps<S extends StandardSchemaV1> {\n name: string;\n toolCallId: string;\n parameters: InferSchemaOutput<S>;\n status: \"complete\";\n result: string;\n}\n\nexport type RenderToolProps<S extends StandardSchemaV1> =\n | RenderToolInProgressProps<S>\n | RenderToolExecutingProps<S>\n | RenderToolCompleteProps<S>;\n\ntype RenderToolConfig<S extends StandardSchemaV1> = {\n name: string;\n parameters?: S;\n render: (props: RenderToolProps<S>) => React.ReactElement;\n agentId?: string;\n};\n\n/**\n * Registers a wildcard (`\"*\"`) renderer for tool calls.\n *\n * The wildcard renderer is used as a fallback when no exact name-matched\n * renderer is registered for a tool call.\n *\n * @param config - Wildcard renderer configuration.\n * @param deps - Optional dependencies to refresh registration.\n *\n * @example\n * ```tsx\n * useRenderTool(\n * {\n * name: \"*\",\n * render: ({ name, status }) => (\n * <div>\n * {status === \"complete\" ? \"✓\" : \"⏳\"} {name}\n * </div>\n * ),\n * },\n * [],\n * );\n * ```\n */\nexport function useRenderTool(\n config: {\n name: \"*\";\n render: (props: any) => React.ReactElement;\n agentId?: string;\n },\n deps?: ReadonlyArray<unknown>,\n): void;\n\n/**\n * Registers a name-scoped renderer for tool calls.\n *\n * The provided `parameters` schema defines the typed shape of `props.parameters`\n * in `render` for `executing` and `complete` states. Accepts any Standard Schema V1\n * compatible library (Zod, Valibot, ArkType, etc.).\n *\n * @typeParam S - Schema type describing tool call parameters.\n * @param config - Named renderer configuration.\n * @param deps - Optional dependencies to refresh registration.\n *\n * @example\n * ```tsx\n * useRenderTool(\n * {\n * name: \"searchDocs\",\n * parameters: z.object({ query: z.string() }),\n * render: ({ status, parameters, result }) => {\n * if (status === \"inProgress\") return <div>Preparing...</div>;\n * if (status === \"executing\") return <div>Searching {parameters.query}</div>;\n * return <div>{result}</div>;\n * },\n * },\n * [],\n * );\n * ```\n */\nexport function useRenderTool<S extends StandardSchemaV1>(\n config: {\n name: string;\n parameters: S;\n render: (props: RenderToolProps<S>) => React.ReactElement;\n agentId?: string;\n },\n deps?: ReadonlyArray<unknown>,\n): void;\n\n/**\n * Registers a renderer entry in CopilotKit's `renderToolCalls` registry.\n *\n * Key behavior:\n * - deduplicates by `agentId:name` (latest registration wins),\n * - keeps renderer entries on cleanup so historical chat tool calls can still render,\n * - refreshes registration when `deps` change.\n *\n * @typeParam S - Schema type describing tool call parameters.\n * @param config - Renderer config for wildcard or named tools.\n * @param deps - Optional dependencies to refresh registration.\n *\n * @example\n * ```tsx\n * useRenderTool(\n * {\n * name: \"searchDocs\",\n * parameters: z.object({ query: z.string() }),\n * render: ({ status, parameters, result }) => {\n * if (status === \"executing\") return <div>Searching {parameters.query}</div>;\n * if (status === \"complete\") return <div>{result}</div>;\n * return <div>Preparing...</div>;\n * },\n * },\n * [],\n * );\n * ```\n *\n * @example\n * ```tsx\n * useRenderTool(\n * {\n * name: \"summarize\",\n * parameters: z.object({ text: z.string() }),\n * agentId: \"research-agent\",\n * render: ({ name, status }) => <div>{name}: {status}</div>,\n * },\n * [selectedAgentId],\n * );\n * ```\n */\nexport function useRenderTool<S extends StandardSchemaV1>(\n config: RenderToolConfig<S>,\n deps?: ReadonlyArray<unknown>,\n): void {\n const { copilotkit } = useCopilotKit();\n const extraDeps = deps ?? EMPTY_DEPS;\n\n useEffect(() => {\n // Build the ReactToolCallRenderer via defineToolCallRenderer\n const renderer =\n config.name === \"*\" && !config.parameters\n ? defineToolCallRenderer({\n name: \"*\",\n render: (props) =>\n config.render({ ...props, parameters: props.args }),\n ...(config.agentId ? { agentId: config.agentId } : {}),\n })\n : defineToolCallRenderer({\n name: config.name,\n args: config.parameters!,\n // Branch per status so the discriminated union stays correlated\n // when `args` is re-exposed as `parameters`.\n render: (props) => {\n if (props.status === ToolCallStatus.InProgress) {\n return config.render({ ...props, parameters: props.args });\n }\n if (props.status === ToolCallStatus.Executing) {\n return config.render({ ...props, parameters: props.args });\n }\n return config.render({ ...props, parameters: props.args });\n },\n ...(config.agentId ? { agentId: config.agentId } : {}),\n });\n\n copilotkit.addHookRenderToolCall(renderer);\n\n // No cleanup removal — keeps renderer for chat history, same as useFrontendTool\n }, [config.name, copilotkit, JSON.stringify(extraDeps)]);\n}\n","import type { AgentCapabilities } from \"@ag-ui/core\";\nimport { useAgent } from \"./use-agent\";\n\n/**\n * Returns the capabilities declared by the given agent (or the default agent).\n * Capabilities are populated from the runtime `/info` response at connection\n * time. The hook reads them synchronously from the agent instance — there is\n * no separate loading state, but the value will be `undefined` until the\n * runtime handshake completes.\n *\n * @param agentId - Optional agent ID. If omitted, uses the default agent.\n * @returns The agent's capabilities, or `undefined` if the agent doesn't\n * declare capabilities.\n */\nexport function useCapabilities(\n agentId?: string,\n): AgentCapabilities | undefined {\n const { agent } = useAgent({ agentId });\n\n if (agent && \"capabilities\" in agent) {\n return (agent as { capabilities?: AgentCapabilities }).capabilities;\n }\n\n return undefined;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"headless.mjs","names":["EMPTY_DEPS","randomUUID"],"sources":["../../src/v2/lib/slots.tsx","../../src/v2/providers/CopilotChatConfigurationProvider.tsx","../../src/v2/hooks/use-agent.tsx","../../src/v2/hooks/use-frontend-tool.tsx","../../src/v2/hooks/use-component.tsx","../../src/v2/hooks/use-human-in-the-loop.tsx","../../src/v2/hooks/use-interrupt.tsx","../../src/v2/hooks/use-suggestions.tsx","../../src/v2/hooks/use-configure-suggestions.tsx","../../src/v2/hooks/use-agent-context.tsx","../../src/v2/hooks/use-threads.tsx","../../src/v2/types/defineToolCallRenderer.ts","../../src/v2/hooks/use-render-tool.tsx","../../src/v2/hooks/use-capabilities.tsx"],"sourcesContent":["import React, { useRef } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\n/** Existing union (unchanged) */\nexport type SlotValue<C extends React.ComponentType<any>> =\n | C\n | string\n | Partial<React.ComponentProps<C>>;\n\n/**\n * Shallow equality comparison for objects.\n */\nexport function shallowEqual<T extends Record<string, unknown>>(\n obj1: T,\n obj2: T,\n): boolean {\n const keys1 = Object.keys(obj1);\n const keys2 = Object.keys(obj2);\n\n if (keys1.length !== keys2.length) return false;\n\n for (const key of keys1) {\n if (obj1[key] !== obj2[key]) return false;\n }\n\n return true;\n}\n\n/**\n * Returns true only for plain JS objects (`{}`), excluding arrays, Dates,\n * class instances, and other exotic objects that happen to have typeof \"object\".\n */\nfunction isPlainObject(obj: unknown): obj is Record<string, unknown> {\n return (\n obj !== null &&\n typeof obj === \"object\" &&\n Object.prototype.toString.call(obj) === \"[object Object]\"\n );\n}\n\n/**\n * Returns the same reference as long as the value is shallowly equal to the\n * previous render's value.\n *\n * - Identical references bail out immediately (O(1)).\n * - Plain objects ({}) are shallow-compared key-by-key.\n * - Arrays, Dates, class instances, functions, and primitives are compared by\n * reference only — shallowEqual is never called on non-plain objects, which\n * avoids incorrect equality for e.g. [1,2] vs [1,2] (different arrays).\n *\n * Typical use: stabilize inline slot props so MemoizedSlotWrapper's shallow\n * equality check isn't defeated by a new object reference on every render.\n */\nexport function useShallowStableRef<T>(value: T): T {\n const ref = useRef(value);\n\n // 1. Identical reference — bail early, no comparison needed.\n if (ref.current === value) return ref.current;\n\n // 2. Both are plain objects — shallow-compare to detect structural equality.\n if (isPlainObject(ref.current) && isPlainObject(value)) {\n if (shallowEqual(ref.current, value)) return ref.current;\n }\n\n // 3. Different values (or non-comparable types) — update the ref.\n ref.current = value;\n return ref.current;\n}\n\n/** Utility: concrete React elements for every slot */\ntype SlotElements<S> = { [K in keyof S]: React.ReactElement };\n\nexport type WithSlots<\n S extends Record<string, React.ComponentType<any>>,\n Rest = {},\n> = {\n /** Per‑slot overrides */\n [K in keyof S]?: SlotValue<S[K]>;\n} & {\n children?: (props: SlotElements<S> & Rest) => React.ReactNode;\n} & Omit<Rest, \"children\">;\n\n/**\n * Check if a value is a React component type (function, class, forwardRef, memo, etc.)\n */\nexport function isReactComponentType(\n value: unknown,\n): value is React.ComponentType<any> {\n if (typeof value === \"function\") {\n return true;\n }\n // forwardRef, memo, lazy have $$typeof but are not valid elements\n if (\n value &&\n typeof value === \"object\" &&\n \"$$typeof\" in value &&\n !React.isValidElement(value)\n ) {\n return true;\n }\n return false;\n}\n\n/**\n * Internal function to render a slot value as a React element (non-memoized).\n */\nfunction renderSlotElement(\n slot: SlotValue<React.ComponentType<any>> | undefined,\n DefaultComponent: React.ComponentType<any>,\n props: Record<string, unknown>,\n): React.ReactElement {\n if (typeof slot === \"string\") {\n // When slot is a string, treat it as a className and merge with existing className\n const existingClassName = props.className as string | undefined;\n return React.createElement(DefaultComponent, {\n ...props,\n className: twMerge(existingClassName, slot),\n });\n }\n\n // Check if slot is a React component type (function, forwardRef, memo, etc.)\n if (isReactComponentType(slot)) {\n return React.createElement(slot, props);\n }\n\n // If slot is a plain object (not a React element), treat it as props override\n if (slot && typeof slot === \"object\" && !React.isValidElement(slot)) {\n return React.createElement(DefaultComponent, {\n ...props,\n ...slot,\n });\n }\n\n return React.createElement(DefaultComponent, props);\n}\n\n/**\n * Internal memoized wrapper component for renderSlot.\n * Uses forwardRef to support ref forwarding.\n */\nconst MemoizedSlotWrapper = React.memo(\n React.forwardRef<unknown, any>(function MemoizedSlotWrapper(props, ref) {\n const { $slot, $component, ...rest } = props;\n const propsWithRef: Record<string, unknown> =\n ref !== null ? { ...rest, ref } : rest;\n return renderSlotElement($slot, $component, propsWithRef);\n }),\n (prev: any, next: any) => {\n // Compare slot and component references\n if (prev.$slot !== next.$slot) return false;\n if (prev.$component !== next.$component) return false;\n\n // Shallow compare remaining props (ref is handled separately by React)\n const { $slot: _ps, $component: _pc, ...prevRest } = prev;\n const { $slot: _ns, $component: _nc, ...nextRest } = next;\n return shallowEqual(\n prevRest as Record<string, unknown>,\n nextRest as Record<string, unknown>,\n );\n },\n);\n\n/**\n * Renders a slot value as a memoized React element.\n * Automatically prevents unnecessary re-renders using shallow prop comparison.\n * Supports ref forwarding.\n *\n * @example\n * renderSlot(customInput, CopilotChatInput, { onSubmit: handleSubmit })\n */\nexport function renderSlot<\n C extends React.ComponentType<any>,\n P = React.ComponentProps<C>,\n>(\n slot: SlotValue<C> | undefined,\n DefaultComponent: C,\n props: P,\n): React.ReactElement {\n return React.createElement(MemoizedSlotWrapper, {\n ...props,\n $slot: slot,\n $component: DefaultComponent,\n } as any);\n}\n","import type { ReactNode } from \"react\";\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { DEFAULT_AGENT_ID, randomUUID } from \"@copilotkit/shared\";\nimport { useShallowStableRef } from \"../lib/slots\";\n\n// Default labels\nexport const CopilotChatDefaultLabels = {\n chatInputPlaceholder: \"Type a message...\",\n chatInputToolbarStartTranscribeButtonLabel: \"Transcribe\",\n chatInputToolbarCancelTranscribeButtonLabel: \"Cancel\",\n chatInputToolbarFinishTranscribeButtonLabel: \"Finish\",\n chatInputToolbarAddButtonLabel: \"Add attachments\",\n chatInputToolbarToolsButtonLabel: \"Tools\",\n assistantMessageToolbarCopyCodeLabel: \"Copy\",\n assistantMessageToolbarCopyCodeCopiedLabel: \"Copied\",\n assistantMessageToolbarCopyMessageLabel: \"Copy\",\n assistantMessageToolbarThumbsUpLabel: \"Good response\",\n assistantMessageToolbarThumbsDownLabel: \"Bad response\",\n assistantMessageToolbarReadAloudLabel: \"Read aloud\",\n assistantMessageToolbarRegenerateLabel: \"Regenerate\",\n userMessageToolbarCopyMessageLabel: \"Copy\",\n userMessageToolbarEditMessageLabel: \"Edit\",\n chatDisclaimerText:\n \"AI can make mistakes. Please verify important information.\",\n chatToggleOpenLabel: \"Open chat\",\n chatToggleCloseLabel: \"Close chat\",\n modalHeaderTitle: \"CopilotKit Chat\",\n welcomeMessageText: \"How can I help you today?\",\n};\n\nexport type CopilotChatLabels = typeof CopilotChatDefaultLabels;\n\n/**\n * Mobile breakpoint below which the chat modal and the thread-list drawer are\n * mutually exclusive. At or above this width both surfaces may coexist. This\n * mirrors the `(max-width: 767px)` / `(min-width: 768px)` split already used by\n * CopilotChatInput and CopilotSidebarView.\n */\nconst MOBILE_MAX_WIDTH_PX = 767;\n\n/**\n * Reports whether the current viewport is in the mobile range (`<768px`), where\n * the chat modal and drawer must not be open simultaneously. SSR-safe and\n * defensive against environments without `matchMedia` (treated as desktop, so\n * no mutual-exclusion constraint is applied).\n *\n * @returns `true` when the viewport is mobile-width, `false` otherwise.\n */\nfunction isMobileViewport(): boolean {\n if (\n typeof window === \"undefined\" ||\n typeof window.matchMedia !== \"function\"\n ) {\n return false;\n }\n return window.matchMedia(`(max-width: ${MOBILE_MAX_WIDTH_PX}px)`).matches;\n}\n\n// Define the full configuration interface\nexport interface CopilotChatConfigurationValue {\n labels: CopilotChatLabels;\n agentId: string;\n threadId: string;\n isModalOpen: boolean;\n setModalOpen: (open: boolean) => void;\n /**\n * Whether the thread-list drawer is open. A sibling boolean to `isModalOpen`\n * (deliberately NOT folded into a tri-state enum): on desktop the chat modal\n * and the drawer coexist, so two independent booleans are required.\n */\n drawerOpen: boolean;\n /**\n * Toggles the drawer open state. On mobile viewports (`<768px`) opening the\n * drawer closes the chat modal (mutual exclusion); on desktop there is no\n * constraint.\n */\n setDrawerOpen: (open: boolean) => void;\n /**\n * True once a `<CopilotThreadsDrawer>` wrapper has registered itself with this chat\n * configuration. The header thread-list launcher renders ONLY when this is\n * set, so chats with no drawer stay byte-for-byte unchanged.\n */\n drawerRegistered: boolean;\n /**\n * Called by the drawer wrapper on mount to announce its presence (and flip\n * `drawerRegistered`). Returns a cleanup function that de-registers the\n * drawer on unmount.\n *\n * @returns A cleanup callback that reverses the registration.\n */\n registerDrawer: () => () => void;\n /**\n * Internal: registers the modal-close setter of the provider that actually\n * owns the rendered modal (a descendant that supplied `isModalDefaultOpen`),\n * so the drawer's mobile mutual-exclusion — owned by the top-most provider —\n * closes the modal that is genuinely on screen rather than the top-most\n * provider's own (possibly unrendered) modal state.\n *\n * @param closeModal - A setter the drawer may call to close the rendered modal.\n * @returns A cleanup callback that de-registers the closer.\n */\n ɵregisterModalCloser: (closeModal: (open: boolean) => void) => () => void;\n // True when the current threadId was chosen by the caller rather than\n // silently minted inside the provider chain. Consumers that only make\n // sense against a real backend thread (e.g. /connect, suppressing the\n // welcome screen on switch) gate on this instead of `!!threadId`.\n hasExplicitThreadId: boolean;\n /**\n * Imperatively sets the active thread for this chat configuration.\n *\n * Use this to drive the rendered thread without a host callback — e.g. a\n * `<CopilotThreadsDrawer>` selecting a thread row sets it explicitly so the chat\n * connects to that backend thread.\n *\n * Guarded like the top-level `<CopilotKit>` provider's `setThreadId`: when\n * the consumer controls the threadId via the `threadId` prop on this\n * provider, this is a no-op (a warning is logged) so a prop-controlled\n * threadId is never silently overridden.\n *\n * @param threadId - The thread id to make active.\n * @param options.explicit - Whether the thread is a caller choice. Defaults\n * to `true` (a picked thread). Pass `false` to set a non-explicit thread\n * so the welcome screen shows (see {@link startNewThread}).\n */\n setActiveThreadId: (\n threadId: string,\n options?: { explicit?: boolean },\n ) => void;\n /**\n * Resets the active thread to a fresh, non-explicit client-side thread: a\n * newly minted UUID with `hasExplicitThreadId=false`, so the welcome screen\n * shows. Pairs with the core `startNewThread()` to clear the conversation\n * with no host wiring.\n *\n * Guarded identically to {@link setActiveThreadId}: a no-op when the\n * threadId is prop-controlled.\n */\n startNewThread: () => void;\n}\n\n// Create the configuration context\nconst CopilotChatConfiguration =\n createContext<CopilotChatConfigurationValue | null>(null);\n\n// Provider props interface\nexport interface CopilotChatConfigurationProviderProps {\n children: ReactNode;\n labels?: Partial<CopilotChatLabels>;\n agentId?: string;\n threadId?: string;\n // Lets internal wrappers (e.g. the v1 CopilotKit bridge, which pipes a\n // ThreadsProvider-minted UUID through as `threadId`) declare that the\n // threadId they are supplying is NOT a caller choice. When omitted, the\n // provider infers explicitness from whether the `threadId` prop itself\n // was supplied.\n hasExplicitThreadId?: boolean;\n isModalDefaultOpen?: boolean;\n}\n\n// Provider component\nexport const CopilotChatConfigurationProvider: React.FC<\n CopilotChatConfigurationProviderProps\n> = ({\n children,\n labels,\n agentId,\n threadId,\n hasExplicitThreadId,\n isModalDefaultOpen,\n}) => {\n const parentConfig = useContext(CopilotChatConfiguration);\n\n // Stabilize labels references so that inline objects (new reference on every\n // parent render) don't invalidate mergedLabels and churn the context value.\n // parentConfig?.labels is already stabilized by the parent provider's own\n // useShallowStableRef, so we only need to stabilize the local labels prop.\n const stableLabels = useShallowStableRef(labels);\n const mergedLabels: CopilotChatLabels = useMemo(\n () => ({\n ...CopilotChatDefaultLabels,\n ...parentConfig?.labels,\n ...stableLabels,\n }),\n [stableLabels, parentConfig?.labels],\n );\n\n const resolvedAgentId = agentId ?? parentConfig?.agentId ?? DEFAULT_AGENT_ID;\n\n // A threadId prop is \"authoritative\" (caller-chosen) only when it is present\n // AND not explicitly flagged non-explicit. The v1 `<CopilotKit>` bridge pipes\n // an auto-minted UUID through as `threadId` with `hasExplicitThreadId={false}`\n // to SEED the thread without claiming the caller picked it; that seed must\n // stay overridable so imperative callers (e.g. `<CopilotThreadsDrawer>` selecting a\n // row, or `startNewThread`) can switch threads. A bare `threadId` prop (no\n // `hasExplicitThreadId`) is still treated as a caller choice.\n const threadIdPropIsAuthoritative =\n threadId !== undefined && hasExplicitThreadId !== false;\n\n // Whether this provider's threadId is controlled by the consumer. When\n // controlled, the imperative active-thread setters below must not override\n // the prop-driven value. A non-authoritative seed (v1 bridge auto-mint) is\n // NOT controlled, so imperative selection still works underneath it.\n const isThreadIdControlled = threadIdPropIsAuthoritative;\n\n // Imperative active-thread override owned by the TOP-MOST provider (the one\n // with no parent). A non-null override takes precedence over the auto-minted\n // UUID fallback below. Nested providers do not own this state — they proxy\n // the parent's setter (see resolved*ActiveThread below) and observe the\n // override through the inherited `parentConfig.threadId`.\n const [activeThreadOverride, setActiveThreadOverride] = useState<{\n threadId: string;\n explicit: boolean;\n } | null>(null);\n\n const resolvedThreadId = useMemo(() => {\n // An authoritative (caller-chosen) threadId prop always wins.\n if (threadIdPropIsAuthoritative) {\n return threadId as string;\n }\n // Otherwise an imperative override (a picked row or freshly-started thread)\n // beats both a non-authoritative seed (the v1 bridge's auto-minted UUID) and\n // the thread inherited from a parent provider.\n if (activeThreadOverride) {\n return activeThreadOverride.threadId;\n }\n if (parentConfig?.threadId) {\n return parentConfig.threadId;\n }\n if (threadId) {\n return threadId;\n }\n return randomUUID();\n }, [\n threadIdPropIsAuthoritative,\n threadId,\n parentConfig?.threadId,\n activeThreadOverride,\n ]);\n\n // Explicitness of this provider's own thread, mirroring the resolution order\n // above: an authoritative prop is a caller choice; otherwise an imperative\n // override carries its own explicitness (a picked row is explicit, a fresh\n // `startNewThread` is not); failing both, fall back to the (non-authoritative)\n // prop flag, which is `false` for the v1 bridge seed.\n const ownHasExplicitThreadId = threadIdPropIsAuthoritative\n ? true\n : (activeThreadOverride?.explicit ?? hasExplicitThreadId ?? false);\n const resolvedHasExplicitThreadId =\n ownHasExplicitThreadId || !!parentConfig?.hasExplicitThreadId;\n\n const resolvedDefaultOpen = isModalDefaultOpen ?? true;\n\n const [internalModalOpen, setInternalModalOpen] =\n useState<boolean>(resolvedDefaultOpen);\n\n const hasExplicitDefault = isModalDefaultOpen !== undefined;\n\n // When this provider owns its modal state, wrap the setter so that changes\n // propagate upward to any ancestor provider. This allows an outer\n // CopilotChatConfigurationProvider (e.g. a user's layout-level provider) to\n // observe open/close events that originate deep in the tree — fixing the\n // \"outer hook always returns true\" regression (CPK-7152 Behavior B).\n const setAndSync = useCallback(\n (open: boolean) => {\n setInternalModalOpen(open);\n parentConfig?.setModalOpen(open);\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [parentConfig?.setModalOpen],\n );\n\n // Sync parent → child: when an ancestor's modal state is changed externally\n // (e.g. the user calls setModalOpen from an outer hook), reflect that change\n // in our own state so the sidebar/popup responds accordingly.\n // Skip the initial mount so that our own isModalDefaultOpen is respected and\n // not immediately overwritten by the parent's current value.\n const isMounted = useRef(false);\n useEffect(() => {\n if (!hasExplicitDefault) return;\n if (!isMounted.current) {\n isMounted.current = true;\n return;\n }\n if (parentConfig?.isModalOpen === undefined) return;\n setInternalModalOpen(parentConfig.isModalOpen);\n }, [parentConfig?.isModalOpen, hasExplicitDefault]);\n\n const resolvedIsModalOpen = hasExplicitDefault\n ? internalModalOpen\n : (parentConfig?.isModalOpen ?? internalModalOpen);\n const resolvedSetModalOpen = hasExplicitDefault\n ? setAndSync\n : (parentConfig?.setModalOpen ?? setInternalModalOpen);\n\n // Drawer presence + open state. When a parent provider exists, this provider\n // proxies the parent's drawer state and registration so that the whole chain\n // shares a single drawer (the drawer wrapper registers once, anywhere in the\n // subtree, and the header launcher anywhere can read/toggle it). Only the\n // top-most provider owns the underlying state.\n const [ownDrawerOpen, setOwnDrawerOpen] = useState<boolean>(false);\n const [ownDrawerCount, setOwnDrawerCount] = useState<number>(0);\n\n // The modal-close path used by the drawer's mobile mutual-exclusion. Held in\n // a ref so the drawer setter (owned by the top-most provider) can reach the\n // resolved modal setter without recreating its identity on every render.\n const modalCloseRef = useRef<(open: boolean) => void>(() => {});\n // Default to this provider's own resolved modal setter. When a DESCENDANT\n // provider owns the rendered modal (it supplied `isModalDefaultOpen`), it\n // registers its closer via `ɵregisterModalCloser` below, which overrides this\n // so the drawer closes the modal that is actually on screen.\n modalCloseRef.current = resolvedSetModalOpen;\n\n // Stack of descendant-registered modal closers. The most recently registered\n // closer (the deepest/last-rendered modal owner) is preferred, mirroring how\n // `resolvedThreadId`/modal ownership flows to the nearest explicit owner.\n const registeredModalClosersRef = useRef<Array<(open: boolean) => void>>([]);\n\n const ownRegisterModalCloser = useCallback(\n (closeModal: (open: boolean) => void) => {\n registeredModalClosersRef.current.push(closeModal);\n return () => {\n registeredModalClosersRef.current =\n registeredModalClosersRef.current.filter(\n (entry) => entry !== closeModal,\n );\n };\n },\n [],\n );\n\n const ownSetDrawerOpen = useCallback((open: boolean) => {\n setOwnDrawerOpen(open);\n // Mobile mutual-exclusion: opening the drawer closes the chat modal. Prefer\n // a descendant-registered closer (the actually-rendered modal) over this\n // provider's own resolved modal setter.\n if (open && isMobileViewport()) {\n const registered = registeredModalClosersRef.current;\n const closeModal =\n registered.length > 0\n ? registered[registered.length - 1]\n : modalCloseRef.current;\n closeModal(false);\n }\n }, []);\n\n const ownRegisterDrawer = useCallback(() => {\n setOwnDrawerCount((count) => count + 1);\n return () => {\n setOwnDrawerCount((count) => Math.max(0, count - 1));\n };\n }, []);\n\n const resolvedDrawerOpen = parentConfig\n ? parentConfig.drawerOpen\n : ownDrawerOpen;\n const resolvedSetDrawerOpen = parentConfig\n ? parentConfig.setDrawerOpen\n : ownSetDrawerOpen;\n const resolvedDrawerRegistered = parentConfig\n ? parentConfig.drawerRegistered\n : ownDrawerCount > 0;\n const resolvedRegisterDrawer = parentConfig\n ? parentConfig.registerDrawer\n : ownRegisterDrawer;\n const resolvedRegisterModalCloser = parentConfig\n ? parentConfig.ɵregisterModalCloser\n : ownRegisterModalCloser;\n\n // When THIS provider owns the rendered modal (it supplied\n // `isModalDefaultOpen`), register its closer up the chain so the top-most\n // provider's drawer mobile mutual-exclusion closes the modal that is actually\n // on screen. Re-registers if the resolved setter identity changes.\n useEffect(() => {\n if (!hasExplicitDefault) return;\n return resolvedRegisterModalCloser(resolvedSetModalOpen);\n }, [hasExplicitDefault, resolvedRegisterModalCloser, resolvedSetModalOpen]);\n\n // Active-thread override setters. The TOP-MOST provider owns the override\n // state; nested providers proxy the parent's setter so the whole chain drives\n // a single active thread (the override placed on the owner flows down via the\n // inherited threadId).\n //\n // The controlled-guard is applied at EACH level, not only on the owner: a\n // provider whose own `threadId` prop pins the rendered thread (per the\n // `resolvedThreadId` precedence above) intercepts the set with a no-op +\n // warning BEFORE proxying upward. This is required because in a nested chain\n // the controlled provider is often NOT the override owner — e.g. an\n // uncontrolled top-most provider with a controlled nested provider. Guarding\n // only the owner would let the set silently no-op (the nested `threadId` prop\n // wins at render) while the documented warning never fired.\n const isThreadIdControlledRef = useRef(isThreadIdControlled);\n isThreadIdControlledRef.current = isThreadIdControlled;\n\n const ownSetActiveThreadId = useCallback(\n (id: string, options?: { explicit?: boolean }) => {\n setActiveThreadOverride({\n threadId: id,\n explicit: options?.explicit ?? true,\n });\n },\n [],\n );\n\n const ownStartNewThread = useCallback(() => {\n setActiveThreadOverride({ threadId: randomUUID(), explicit: false });\n }, []);\n\n // Proxy to the parent's setter when nested, else to the owner's. Wrapped with\n // this provider's own controlled-guard so the nearest pinning (controlled)\n // provider — wherever it sits in the chain — is the one that no-ops + warns.\n const parentSetActiveThreadId = parentConfig?.setActiveThreadId;\n const parentStartNewThread = parentConfig?.startNewThread;\n\n const resolvedSetActiveThreadId = useCallback(\n (id: string, options?: { explicit?: boolean }) => {\n if (isThreadIdControlledRef.current) {\n console.warn(\n \"[CopilotKit] Ignoring setActiveThreadId(): threadId is controlled \" +\n \"via the `threadId` prop on CopilotChatConfigurationProvider.\",\n );\n return;\n }\n if (parentSetActiveThreadId) {\n parentSetActiveThreadId(id, options);\n return;\n }\n ownSetActiveThreadId(id, options);\n },\n [parentSetActiveThreadId, ownSetActiveThreadId],\n );\n\n const resolvedStartNewThread = useCallback(() => {\n if (isThreadIdControlledRef.current) {\n console.warn(\n \"[CopilotKit] Ignoring startNewThread(): threadId is controlled via \" +\n \"the `threadId` prop on CopilotChatConfigurationProvider.\",\n );\n return;\n }\n if (parentStartNewThread) {\n parentStartNewThread();\n return;\n }\n ownStartNewThread();\n }, [parentStartNewThread, ownStartNewThread]);\n\n // Mobile mutual-exclusion (other direction): opening the chat modal closes\n // the drawer. Layered over whichever modal setter we resolved above so the\n // existing parent/child modal-sync contract is preserved untouched.\n const setModalOpenWithDrawerExclusion = useCallback(\n (open: boolean) => {\n if (open && isMobileViewport()) {\n resolvedSetDrawerOpen(false);\n }\n resolvedSetModalOpen(open);\n },\n [resolvedSetModalOpen, resolvedSetDrawerOpen],\n );\n\n const configurationValue: CopilotChatConfigurationValue = useMemo(\n () => ({\n labels: mergedLabels,\n agentId: resolvedAgentId,\n threadId: resolvedThreadId,\n hasExplicitThreadId: resolvedHasExplicitThreadId,\n isModalOpen: resolvedIsModalOpen,\n setModalOpen: setModalOpenWithDrawerExclusion,\n drawerOpen: resolvedDrawerOpen,\n setDrawerOpen: resolvedSetDrawerOpen,\n drawerRegistered: resolvedDrawerRegistered,\n registerDrawer: resolvedRegisterDrawer,\n ɵregisterModalCloser: resolvedRegisterModalCloser,\n setActiveThreadId: resolvedSetActiveThreadId,\n startNewThread: resolvedStartNewThread,\n }),\n [\n mergedLabels,\n resolvedAgentId,\n resolvedThreadId,\n resolvedHasExplicitThreadId,\n resolvedIsModalOpen,\n setModalOpenWithDrawerExclusion,\n resolvedDrawerOpen,\n resolvedSetDrawerOpen,\n resolvedDrawerRegistered,\n resolvedRegisterDrawer,\n resolvedRegisterModalCloser,\n resolvedSetActiveThreadId,\n resolvedStartNewThread,\n ],\n );\n\n return (\n <CopilotChatConfiguration.Provider value={configurationValue}>\n {children}\n </CopilotChatConfiguration.Provider>\n );\n};\n\n// Hook to use the full configuration\nexport const useCopilotChatConfiguration =\n (): CopilotChatConfigurationValue | null => {\n const configuration = useContext(CopilotChatConfiguration);\n return configuration;\n };\n","import { useCopilotKit } from \"../context\";\nimport { useMemo, useEffect, useReducer, useRef } from \"react\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkit/shared\";\nimport type { AbstractAgent } from \"@ag-ui/client\";\nimport { HttpAgent } from \"@ag-ui/client\";\nimport {\n ProxiedCopilotRuntimeAgent,\n CopilotKitCoreRuntimeConnectionStatus,\n} from \"@copilotkit/core\";\nimport type { SubscribeToAgentSubscriber } from \"@copilotkit/core\";\nimport { useCopilotChatConfiguration } from \"../providers/CopilotChatConfigurationProvider\";\n\nexport enum UseAgentUpdate {\n OnMessagesChanged = \"OnMessagesChanged\",\n OnStateChanged = \"OnStateChanged\",\n OnRunStatusChanged = \"OnRunStatusChanged\",\n}\n\nconst ALL_UPDATES: UseAgentUpdate[] = [\n UseAgentUpdate.OnMessagesChanged,\n UseAgentUpdate.OnStateChanged,\n UseAgentUpdate.OnRunStatusChanged,\n];\n\nexport interface UseAgentProps {\n agentId?: string;\n updates?: UseAgentUpdate[];\n /**\n * Throttle interval (in milliseconds) for re-renders triggered by\n * `onMessagesChanged` and `onStateChanged` notifications. Useful to reduce\n * re-render frequency during high-frequency streaming updates.\n *\n * Uses a leading+trailing pattern with a shared window — first update\n * fires immediately, subsequent updates within the window are coalesced,\n * and a trailing timer ensures the most recent update fires after the\n * window expires. See `CopilotKitCore.subscribeToAgentWithOptions` in `@copilotkit/core`\n * for details.\n *\n * Resolved as: `throttleMs ?? provider defaultThrottleMs ?? 0`.\n * Passing `throttleMs={0}` explicitly disables throttling even when the\n * provider specifies a non-zero `defaultThrottleMs`.\n *\n * Run lifecycle callbacks (`onRunInitialized`, `onRunFinalized`,\n * `onRunFailed`, `onRunErrorEvent`) always fire immediately.\n *\n * @default undefined\n * When unset, inherits from the provider's `defaultThrottleMs`;\n * if that is also unset, the effective value is `0` (no throttle).\n */\n throttleMs?: number;\n}\n\nexport function useAgent({ agentId, updates, throttleMs }: UseAgentProps = {}) {\n agentId ??= DEFAULT_AGENT_ID;\n\n const { copilotkit } = useCopilotKit();\n // Read the provider-level default so it appears in the effect's dep array.\n // subscribeToAgentWithOptions reads it from the core instance, but React needs the dep\n // to know when to re-subscribe.\n const providerThrottleMs = copilotkit.defaultThrottleMs;\n\n const [, forceUpdate] = useReducer((x) => x + 1, 0);\n\n const updateFlags = useMemo(\n () => updates ?? ALL_UPDATES,\n [JSON.stringify(updates)],\n );\n\n // Cache provisional agents to avoid creating new references on every render\n // while the runtime is still connecting. A new reference would cascade into\n // CopilotChat's connectAgent effect, causing unnecessary HTTP calls.\n const provisionalAgentCache = useRef<Map<string, ProxiedCopilotRuntimeAgent>>(\n new Map(),\n );\n\n const agent: AbstractAgent = useMemo(() => {\n const existing = copilotkit.getAgent(agentId);\n if (existing) {\n // Real agent found — clear any cached provisional for this ID\n provisionalAgentCache.current.delete(agentId);\n return existing;\n }\n\n const isRuntimeConfigured = copilotkit.runtimeUrl !== undefined;\n const status = copilotkit.runtimeConnectionStatus;\n\n // While runtime is not yet synced, return a provisional runtime agent\n if (\n isRuntimeConfigured &&\n (status === CopilotKitCoreRuntimeConnectionStatus.Disconnected ||\n status === CopilotKitCoreRuntimeConnectionStatus.Connecting)\n ) {\n // Return cached provisional if available (keeps reference stable)\n const cached = provisionalAgentCache.current.get(agentId);\n if (cached) {\n // Update headers on the cached agent in case they changed\n copilotkit.applyHeadersToAgent(cached);\n return cached;\n }\n\n const provisional = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: copilotkit.runtimeUrl,\n agentId,\n transport: copilotkit.runtimeTransport,\n runtimeMode: \"pending\",\n });\n // Apply current headers so runs/connects inherit them\n copilotkit.applyHeadersToAgent(provisional);\n provisionalAgentCache.current.set(agentId, provisional);\n return provisional;\n }\n\n // Runtime is in Error state — return a provisional agent instead of throwing.\n // The error has already been emitted through the subscriber system\n // (RUNTIME_INFO_FETCH_FAILED). Throwing here would crash the React tree;\n // returning a provisional agent lets onError handlers fire while keeping\n // the app alive.\n if (\n isRuntimeConfigured &&\n status === CopilotKitCoreRuntimeConnectionStatus.Error\n ) {\n const cached = provisionalAgentCache.current.get(agentId);\n if (cached) {\n copilotkit.applyHeadersToAgent(cached);\n return cached;\n }\n const provisional = new ProxiedCopilotRuntimeAgent({\n runtimeUrl: copilotkit.runtimeUrl,\n agentId,\n transport: copilotkit.runtimeTransport,\n runtimeMode: \"pending\",\n });\n copilotkit.applyHeadersToAgent(provisional);\n provisionalAgentCache.current.set(agentId, provisional);\n return provisional;\n }\n\n // No runtime configured and agent doesn't exist — this is a configuration error.\n const knownAgents = Object.keys(copilotkit.agents ?? {});\n const runtimePart = isRuntimeConfigured\n ? `runtimeUrl=${copilotkit.runtimeUrl}`\n : \"no runtimeUrl\";\n throw new Error(\n `useAgent: Agent '${agentId}' not found after runtime sync (${runtimePart}). ` +\n (knownAgents.length\n ? `Known agents: [${knownAgents.join(\", \")}]`\n : \"No agents registered.\") +\n \" Verify your runtime /info and/or agents__unsafe_dev_only.\",\n );\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n agentId,\n copilotkit.agents,\n copilotkit.runtimeConnectionStatus,\n copilotkit.runtimeUrl,\n copilotkit.runtimeTransport,\n JSON.stringify(copilotkit.headers),\n ]);\n\n useEffect(() => {\n if (updateFlags.length === 0) return;\n\n let active = true;\n const handlers: SubscribeToAgentSubscriber = {};\n\n // Microtask-batched forceUpdate: coalesces multiple synchronous\n // notifications (e.g. OnStateChanged + OnRunStatusChanged firing in the\n // same tick) into a single React re-render. This prevents the scroll\n // jumping described in #3499 where rapid unbatched forceUpdate calls\n // cause brief content height fluctuations during streaming.\n let batchScheduled = false;\n const batchedForceUpdate = () => {\n if (!active) return;\n if (!batchScheduled) {\n batchScheduled = true;\n queueMicrotask(() => {\n batchScheduled = false;\n if (active) {\n forceUpdate();\n }\n });\n }\n };\n\n if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) {\n handlers.onMessagesChanged = batchedForceUpdate;\n }\n\n if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) {\n handlers.onStateChanged = batchedForceUpdate;\n }\n\n if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {\n handlers.onRunInitialized = batchedForceUpdate;\n handlers.onRunFinalized = batchedForceUpdate;\n handlers.onRunFailed = batchedForceUpdate;\n // Protocol-level RUN_ERROR event (distinct from onRunFailed which\n // handles local exceptions like network errors).\n handlers.onRunErrorEvent = batchedForceUpdate;\n }\n\n const subscription = copilotkit.subscribeToAgentWithOptions(\n agent,\n handlers,\n {\n throttleMs,\n },\n );\n return () => {\n active = false;\n subscription.unsubscribe();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agent, forceUpdate, throttleMs, providerThrottleMs, updateFlags]);\n\n // Keep HttpAgent headers fresh without mutating inside useMemo, which is\n // unsafe in concurrent mode (React may invoke useMemo multiple times and\n // discard intermediate results, but mutations always land).\n useEffect(() => {\n if (agent instanceof HttpAgent) {\n // Merge core headers on top of the agent's own headers rather than\n // replacing them, so per-agent headers (e.g. an Authorization for a\n // self-hosted backend) are preserved (see #5635).\n copilotkit.applyHeadersToAgent(agent);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agent, JSON.stringify(copilotkit.headers)]);\n\n // Propagate the caller-supplied threadId from the chat configuration onto\n // the agent. AbstractAgent's constructor auto-mints a UUID when no threadId\n // is passed, so without this sync the agent ships its own random UUID in\n // /agent/run, /agent/connect, /agent/stop — diverging from the threadId the\n // app code reads via useThreads/useCopilotChatConfiguration. Gated on\n // hasExplicitThreadId so a ThreadsProvider-minted placeholder UUID doesn't\n // overwrite the auto-minted agent UUID (both are random and useless to the\n // backend; the explicit gate keeps the agent's UUID stable across renders).\n const chatConfig = useCopilotChatConfiguration();\n const configThreadId = chatConfig?.threadId;\n const configHasExplicitThreadId = chatConfig?.hasExplicitThreadId;\n useEffect(() => {\n if (!configHasExplicitThreadId || !configThreadId) return;\n agent.threadId = configThreadId;\n }, [agent, configThreadId, configHasExplicitThreadId]);\n\n return {\n agent,\n };\n}\n","import { useEffect } from \"react\";\nimport { useCopilotKit } from \"../context\";\nimport type { ReactFrontendTool } from \"../types/frontend-tool\";\n\nconst EMPTY_DEPS: ReadonlyArray<unknown> = [];\n\nexport function useFrontendTool<\n T extends Record<string, unknown> = Record<string, unknown>,\n>(tool: ReactFrontendTool<T>, deps?: ReadonlyArray<unknown>) {\n const { copilotkit } = useCopilotKit();\n const extraDeps = deps ?? EMPTY_DEPS;\n\n useEffect(() => {\n const name = tool.name;\n\n // Always register/override the tool for this name on mount\n if (copilotkit.getTool({ toolName: name, agentId: tool.agentId })) {\n console.warn(\n `Tool '${name}' already exists for agent '${tool.agentId || \"global\"}'. Overriding with latest registration.`,\n );\n copilotkit.removeTool(name, tool.agentId);\n }\n copilotkit.addTool(tool);\n\n // Register/override renderer by name and agentId through core.\n // The render function is registered even when tool.parameters is\n // undefined — tools like HITL confirm dialogs have no parameters\n // but still need their UI rendered in the chat.\n if (tool.render) {\n copilotkit.addHookRenderToolCall({\n name,\n args: tool.parameters,\n agentId: tool.agentId,\n render: tool.render,\n });\n }\n\n return () => {\n copilotkit.removeTool(name, tool.agentId);\n // we are intentionally not removing the render here so that the tools can still render in the chat history\n };\n // Depend on stable keys by default and allow callers to opt into\n // additional dependencies for dynamic tool configuration.\n // tool.available is included so toggling availability re-registers the tool.\n }, [tool.name, tool.available, copilotkit, JSON.stringify(extraDeps)]);\n}\n","import type { StandardSchemaV1, InferSchemaOutput } from \"@copilotkit/shared\";\nimport type { ComponentType } from \"react\";\nimport { useFrontendTool } from \"./use-frontend-tool\";\n\ntype InferRenderProps<T> = T extends StandardSchemaV1\n ? InferSchemaOutput<T>\n : any;\n\n/**\n * Registers a React component as a frontend tool renderer in chat.\n *\n * This hook is a convenience wrapper around `useFrontendTool` that:\n * - builds a model-facing tool description,\n * - forwards optional schema parameters (any Standard Schema V1 compatible library),\n * - renders your component with tool call parameters.\n *\n * Use this when you want to display a typed visual component for a tool call\n * without manually wiring a full frontend tool object.\n *\n * When `parameters` is provided, render props are inferred from the schema.\n * When omitted, the render component may accept any props.\n *\n * @typeParam TSchema - Schema describing tool parameters, or `undefined` when no schema is given.\n * @param config - Tool registration config.\n * @param deps - Optional dependencies to refresh registration (same semantics as `useEffect`).\n *\n * @example\n * ```tsx\n * // Without parameters — render accepts any props\n * useComponent({\n * name: \"showGreeting\",\n * render: ({ message }: { message: string }) => <div>{message}</div>,\n * });\n * ```\n *\n * @example\n * ```tsx\n * // With parameters — render props inferred from schema\n * useComponent({\n * name: \"showWeatherCard\",\n * parameters: z.object({ city: z.string() }),\n * render: ({ city }) => <div>{city}</div>,\n * });\n * ```\n *\n * @example\n * ```tsx\n * useComponent(\n * {\n * name: \"renderProfile\",\n * parameters: z.object({ userId: z.string() }),\n * render: ProfileCard,\n * agentId: \"support-agent\",\n * },\n * [selectedAgentId],\n * );\n * ```\n */\nexport function useComponent<\n TSchema extends StandardSchemaV1<any, Record<string, unknown>> | undefined =\n undefined,\n>(\n config: {\n name: string;\n description?: string;\n parameters?: TSchema;\n render: ComponentType<NoInfer<InferRenderProps<TSchema>>>;\n agentId?: string;\n followUp?: boolean;\n },\n deps?: ReadonlyArray<unknown>,\n): void {\n const prefix = `Use this tool to display the \"${config.name}\" component in the chat. This tool renders a visual UI component for the user.`;\n const fullDescription = config.description\n ? `${prefix}\\n\\n${config.description}`\n : prefix;\n\n useFrontendTool(\n {\n name: config.name,\n description: fullDescription,\n parameters: config.parameters,\n render: ({ args }: { args: unknown }) => {\n const Component = config.render;\n return <Component {...(args as InferRenderProps<TSchema>)} />;\n },\n agentId: config.agentId,\n followUp: config.followUp,\n },\n deps,\n );\n}\n","import { useCopilotKit } from \"../context\";\nimport type { ReactFrontendTool } from \"../types/frontend-tool\";\nimport type { ReactHumanInTheLoop } from \"../types/human-in-the-loop\";\nimport type { ReactToolCallRenderer } from \"../types/react-tool-call-renderer\";\nimport { ToolCallStatus } from \"@copilotkit/core\";\nimport { useCallback, useEffect, useRef } from \"react\";\nimport React from \"react\";\nimport { useFrontendTool } from \"./use-frontend-tool\";\n\nexport function useHumanInTheLoop<\n T extends Record<string, unknown> = Record<string, unknown>,\n>(tool: ReactHumanInTheLoop<T>, deps?: ReadonlyArray<unknown>) {\n const { copilotkit } = useCopilotKit();\n const resolvePromiseRef = useRef<((result: unknown) => void) | null>(null);\n // Cleanup that detaches the pending abort listener; cleared whenever the\n // promise settles (via respond() or abort) so the listener can't fire twice\n // or leak after the interaction is done.\n const cleanupAbortRef = useRef<(() => void) | null>(null);\n\n const respond = useCallback(async (result: unknown) => {\n if (resolvePromiseRef.current) {\n cleanupAbortRef.current?.();\n cleanupAbortRef.current = null;\n resolvePromiseRef.current(result);\n resolvePromiseRef.current = null;\n }\n }, []);\n\n const handler = useCallback(\n async (_args: T, context?: { signal?: AbortSignal }) => {\n const signal = context?.signal;\n return new Promise((resolve, reject) => {\n // If the run was already aborted before the handler ran, reject\n // immediately so core records an explicit error tool result instead of\n // silently resolving to an empty string.\n if (signal?.aborted) {\n reject(new Error(\"Human-in-the-loop interaction aborted\"));\n return;\n }\n\n resolvePromiseRef.current = resolve;\n\n if (signal) {\n const onAbort = () => {\n cleanupAbortRef.current = null;\n resolvePromiseRef.current = null;\n reject(new Error(\"Human-in-the-loop interaction aborted\"));\n };\n signal.addEventListener(\"abort\", onAbort, { once: true });\n cleanupAbortRef.current = () => {\n signal.removeEventListener(\"abort\", onAbort);\n };\n }\n });\n },\n [],\n );\n\n const RenderComponent: ReactToolCallRenderer<T>[\"render\"] = useCallback(\n (props) => {\n const ToolComponent = tool.render;\n\n // Build the HITL render props per status. `props` already carries\n // `toolCallId`; we overwrite `name`/`description` with the tool's\n // registration values and add the registration `agentId`, so the HITL\n // render always receives the full prop contract. `respond` is only live\n // while the tool is executing.\n if (props.status === ToolCallStatus.InProgress) {\n const enhancedProps = {\n ...props,\n name: tool.name,\n description: tool.description || \"\",\n agentId: tool.agentId,\n respond: undefined,\n };\n return React.createElement(ToolComponent, enhancedProps);\n } else if (props.status === ToolCallStatus.Executing) {\n const enhancedProps = {\n ...props,\n name: tool.name,\n description: tool.description || \"\",\n agentId: tool.agentId,\n respond,\n };\n return React.createElement(ToolComponent, enhancedProps);\n } else if (props.status === ToolCallStatus.Complete) {\n const enhancedProps = {\n ...props,\n name: tool.name,\n description: tool.description || \"\",\n agentId: tool.agentId,\n respond: undefined,\n };\n return React.createElement(ToolComponent, enhancedProps);\n }\n\n // ToolCallStatus has only the three states handled above, so this point\n // is unreachable and `props` narrows to `never`. The assignment turns a\n // newly-added status into a compile error here — forcing it to get its\n // own branch above — instead of silently rendering without `respond`.\n const exhaustiveCheck: never = props;\n return exhaustiveCheck;\n },\n [tool.render, tool.name, tool.description, tool.agentId, respond],\n );\n\n const frontendTool: ReactFrontendTool<T> = {\n ...tool,\n handler,\n render: RenderComponent,\n };\n\n useFrontendTool(frontendTool, deps);\n\n // Human-in-the-loop tools should remove their renderer on unmount\n // since they can't respond to user interactions anymore\n useEffect(() => {\n return () => {\n copilotkit.removeHookRenderToolCall(tool.name, tool.agentId);\n };\n }, [copilotkit, tool.name, tool.agentId]);\n}\n","import React, {\n useState,\n useEffect,\n useCallback,\n useMemo,\n useRef,\n} from \"react\";\nimport {\n buildResumeArray,\n isInterruptExpired,\n randomUUID,\n} from \"@ag-ui/client\";\nimport type { Interrupt, Message, RunAgentResult } from \"@ag-ui/client\";\nimport { useCopilotKit } from \"../context\";\nimport { useAgent } from \"./use-agent\";\nimport type {\n InterruptEvent,\n InterruptRenderProps,\n InterruptHandlerProps,\n InterruptResolveFn,\n InterruptCancelFn,\n} from \"../types/interrupt\";\n\nexport type {\n InterruptEvent,\n InterruptRenderProps,\n InterruptHandlerProps,\n Interrupt,\n};\n\nconst INTERRUPT_EVENT_NAME = \"on_interrupt\";\n\n/** Internal accumulator response shape consumed by buildResumeArray. */\ntype ResumeResponse =\n | { status: \"resolved\"; payload?: unknown }\n | { status: \"cancelled\" };\n\n/**\n * Normalized pending interrupt. `legacy` carries the custom-event payload;\n * `standard` carries the AG-UI `outcome:\"interrupt\"` interrupts array.\n */\ntype PendingInterrupt =\n | { kind: \"legacy\"; event: InterruptEvent }\n | { kind: \"standard\"; interrupts: 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/** Derive the legacy-compatible `event` for any pending interrupt. */\nfunction toLegacyEvent(pending: PendingInterrupt): InterruptEvent {\n if (pending.kind === \"legacy\") return pending.event;\n return { name: INTERRUPT_EVENT_NAME, value: pending.interrupts[0] };\n}\n\n/**\n * Configuration options for `useInterrupt`.\n */\ninterface UseInterruptConfigBase<TValue = unknown, TResult = never> {\n /**\n * Render function for the interrupt UI.\n *\n * Receives both the standard `interrupt`/`interrupts` and the legacy `event`.\n * Call `resolve(payload)` to resume with user input, or `cancel()` to cancel.\n */\n render: (\n props: InterruptRenderProps<TValue, InterruptResult<TValue, TResult>>,\n ) => React.ReactElement;\n /**\n * Optional pre-render handler invoked when an interrupt is received.\n * Return a sync or async value to expose as `result` in `render`.\n * Rejecting/throwing falls back to `result = null`.\n */\n handler?: InterruptHandlerFn<TValue, TResult>;\n /**\n * Optional predicate to filter which interrupts this hook handles.\n * Receives the legacy-compatible event (for standard interrupts, `value` is\n * the primary `Interrupt`). Return `false` to ignore.\n */\n enabled?: (event: InterruptEvent<TValue>) => boolean;\n /** Optional agent id. Defaults to the current configured chat agent. */\n agentId?: string;\n}\n\nexport interface UseInterruptInChatConfig<\n TValue = unknown,\n TResult = never,\n> extends UseInterruptConfigBase<TValue, TResult> {\n /** When true (default), the interrupt UI renders inside `<CopilotChat>` automatically. */\n renderInChat?: true;\n}\n\nexport interface UseInterruptExternalConfig<\n TValue = unknown,\n TResult = never,\n> extends UseInterruptConfigBase<TValue, TResult> {\n /** When false, the hook returns the interrupt element so you can place it yourself. */\n renderInChat: false;\n}\n\nexport interface UseInterruptDynamicConfig<\n TValue = unknown,\n TResult = never,\n> extends UseInterruptConfigBase<TValue, TResult> {\n /** Dynamic boolean mode. When non-literal, return type is a union. */\n renderInChat: boolean;\n}\n\nexport type UseInterruptConfig<\n TValue = unknown,\n TResult = never,\n TRenderInChat extends InterruptRenderInChat = undefined,\n> = UseInterruptConfigBase<TValue, TResult> & {\n /** When true (default), the interrupt UI renders inside `<CopilotChat>` automatically. */\n renderInChat?: TRenderInChat;\n};\n\n/**\n * Handles agent interrupts with optional filtering, preprocessing, and resume behavior.\n *\n * Supports both the AG-UI standard interrupt flow (`RUN_FINISHED` with\n * `outcome.type === \"interrupt\"`) and the legacy custom-event flow\n * (`on_interrupt`). For standard interrupts, `render` receives `interrupt`\n * (the primary one) and `interrupts` (the full open set); call `resolve(payload)`\n * to resume or `cancel()` to cancel. Resuming addresses the targeted interrupt\n * and, once every open interrupt is addressed, submits a single spec `resume`\n * array via `copilotkit.runAgent`.\n *\n * - `renderInChat: true` (default): the element is published into `<CopilotChat>`; returns `void`.\n * - `renderInChat: false`: the hook returns the interrupt element for manual placement.\n *\n * @example\n * ```tsx\n * useInterrupt({\n * render: ({ interrupt, resolve, cancel }) => (\n * <div>\n * <p>{interrupt?.message}</p>\n * <button onClick={() => resolve({ approved: true })}>Approve</button>\n * <button onClick={() => cancel()}>Cancel</button>\n * </div>\n * ),\n * });\n * ```\n */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport function useInterrupt<\n TResult = never,\n TRenderInChat extends InterruptRenderInChat = undefined,\n>(\n config: UseInterruptConfig<any, TResult, TRenderInChat>,\n): UseInterruptReturn<TRenderInChat> {\n /* eslint-enable @typescript-eslint/no-explicit-any */\n const { copilotkit } = useCopilotKit();\n const { agent } = useAgent({ agentId: config.agentId });\n const [pending, setPending] = useState<PendingInterrupt | null>(null);\n const pendingRef = useRef(pending);\n pendingRef.current = pending;\n const [handlerResult, setHandlerResult] =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n useState<InterruptResult<any, TResult>>(null);\n\n // Accumulated per-interrupt responses for the current standard interrupt set.\n const responsesRef = useRef<Record<string, ResumeResponse>>({});\n\n useEffect(() => {\n let localLegacy: InterruptEvent | null = null;\n let localStandard: Interrupt[] | null = null;\n\n const subscription = agent.subscribe({\n onCustomEvent: ({ event }) => {\n if (event.name === INTERRUPT_EVENT_NAME) {\n localLegacy = { name: event.name, value: event.value };\n }\n },\n onRunFinishedEvent: (params) => {\n if (params.outcome === \"interrupt\") {\n localStandard = params.interrupts;\n }\n },\n onRunStartedEvent: () => {\n localLegacy = null;\n localStandard = null;\n responsesRef.current = {};\n setPending(null);\n },\n onRunFinalized: () => {\n // Standard wins if both somehow appear for one run.\n if (localStandard && localStandard.length > 0) {\n setPending({ kind: \"standard\", interrupts: localStandard });\n } else if (localLegacy) {\n setPending({ kind: \"legacy\", event: localLegacy });\n }\n localLegacy = null;\n localStandard = null;\n },\n onRunFailed: () => {\n localLegacy = null;\n localStandard = null;\n responsesRef.current = {};\n setPending(null);\n },\n });\n\n return () => subscription.unsubscribe();\n }, [agent]);\n\n // Submit the accumulated standard responses once all open interrupts are\n // addressed; otherwise return void and keep waiting.\n const submitStandardIfComplete = useCallback(\n async (interrupts: Interrupt[]): Promise<RunAgentResult | void> => {\n const allAddressed = interrupts.every((i) => responsesRef.current[i.id]);\n if (!allAddressed) return;\n\n const expired = interrupts.find((i) => isInterruptExpired(i));\n if (expired) {\n console.error(\n `[CopilotKit] useInterrupt: interrupt ${expired.id} expired at ${expired.expiresAt}; not resuming.`,\n );\n responsesRef.current = {};\n setPending(null);\n return;\n }\n\n const resume = buildResumeArray(interrupts, responsesRef.current);\n\n // Persist each resolution as a tool-result message so the conversation\n // stays well-formed on later turns. The interrupt run left the tool call\n // unanswered; without recording its result here, the NEXT turn ships a\n // dangling tool call (assistant tool-call with no tool result) and the\n // model errors / re-calls the tool in a loop. Only standard, tool-backed\n // interrupts carry a `toolCallId`; custom `ctx.interrupt()` ones don't and\n // are resumed purely via the `resume` array.\n for (const i of interrupts) {\n if (!i.toolCallId) continue;\n const response = responsesRef.current[i.id];\n const content =\n response.status === \"cancelled\"\n ? { status: \"cancelled\" }\n : (response.payload ?? { status: \"resolved\" });\n agent.addMessage({\n id: randomUUID(),\n role: \"tool\",\n toolCallId: i.toolCallId,\n content: JSON.stringify(content),\n } as Message);\n }\n\n responsesRef.current = {};\n try {\n return await copilotkit.runAgent({ agent, resume });\n } catch (err) {\n console.error(\n \"[CopilotKit] useInterrupt resolve: runAgent rejected; clearing pending + rethrowing\",\n err,\n );\n setPending(null);\n throw err;\n }\n },\n [agent, copilotkit],\n );\n\n const resolve: InterruptResolveFn = useCallback(\n async (payload, interruptId) => {\n const current = pendingRef.current;\n if (!current) return;\n\n if (current.kind === \"legacy\") {\n try {\n return await copilotkit.runAgent({\n agent,\n forwardedProps: {\n command: { resume: payload, interruptEvent: current.event.value },\n },\n });\n } catch (err) {\n console.error(\n \"[CopilotKit] useInterrupt resolve: runAgent rejected; clearing pending + rethrowing\",\n err,\n );\n setPending(null);\n throw err;\n }\n }\n\n if (current.interrupts.length > 1 && interruptId === undefined) {\n console.warn(\n `[CopilotKit] useInterrupt: resolve()/cancel() called without an interruptId while ${current.interrupts.length} interrupts are open; defaulting to the first. Pass an interruptId to address a specific interrupt.`,\n );\n }\n const id = interruptId ?? current.interrupts[0]?.id;\n if (!id) return;\n responsesRef.current[id] = { status: \"resolved\", payload };\n return submitStandardIfComplete(current.interrupts);\n },\n [agent, copilotkit, submitStandardIfComplete],\n );\n\n const cancel: InterruptCancelFn = useCallback(\n async (interruptId) => {\n const current = pendingRef.current;\n if (!current) return;\n\n if (current.kind === \"legacy\") {\n // Legacy interrupts have no cancel semantics; dismiss without resuming.\n console.warn(\n \"[CopilotKit] useInterrupt: cancel() is not supported for legacy on_interrupt interrupts; dismissing.\",\n );\n setPending(null);\n return;\n }\n\n if (current.interrupts.length > 1 && interruptId === undefined) {\n console.warn(\n `[CopilotKit] useInterrupt: resolve()/cancel() called without an interruptId while ${current.interrupts.length} interrupts are open; defaulting to the first. Pass an interruptId to address a specific interrupt.`,\n );\n }\n const id = interruptId ?? current.interrupts[0]?.id;\n if (!id) return;\n responsesRef.current[id] = { status: \"cancelled\" };\n return submitStandardIfComplete(current.interrupts);\n },\n [submitStandardIfComplete],\n );\n\n // Stabilize consumer-supplied callbacks behind refs so inline lambdas do not\n // churn the element memo identity or the handler effect.\n const renderRef = useRef(config.render);\n renderRef.current = config.render;\n const enabledRef = useRef(config.enabled);\n enabledRef.current = config.enabled;\n const handlerRef = useRef(config.handler);\n handlerRef.current = config.handler;\n const resolveRef = useRef(resolve);\n resolveRef.current = resolve;\n const cancelRef = useRef(cancel);\n cancelRef.current = cancel;\n\n // Predicate evaluator: a throw is treated as \"disabled\" (false) and logged.\n const isEnabled = (event: InterruptEvent): boolean => {\n const predicate = enabledRef.current;\n if (!predicate) return true;\n try {\n return predicate(event);\n } catch (err) {\n console.error(\n \"[CopilotKit] useInterrupt enabled predicate threw; treating interrupt as disabled:\",\n err,\n );\n return false;\n }\n };\n\n useEffect(() => {\n if (!pending) {\n setHandlerResult(null);\n return;\n }\n const legacyEvent = toLegacyEvent(pending);\n if (!isEnabled(legacyEvent)) {\n setHandlerResult(null);\n return;\n }\n const handler = handlerRef.current;\n if (!handler) {\n setHandlerResult(null);\n return;\n }\n\n let cancelled = false;\n let maybePromise: ReturnType<typeof handler>;\n try {\n maybePromise = handler({\n event: legacyEvent,\n interrupt: pending.kind === \"standard\" ? pending.interrupts[0] : null,\n interrupts: pending.kind === \"standard\" ? pending.interrupts : [],\n resolve: resolveRef.current,\n cancel: cancelRef.current,\n });\n } catch (err) {\n console.error(\n \"[CopilotKit] useInterrupt handler threw; result will be null:\",\n err,\n );\n if (!cancelled) setHandlerResult(null);\n return () => {\n cancelled = true;\n };\n }\n\n if (isPromiseLike(maybePromise)) {\n Promise.resolve(maybePromise)\n .then((resolved) => {\n if (!cancelled) setHandlerResult(resolved);\n })\n .catch((err) => {\n console.error(\n \"[CopilotKit] useInterrupt handler rejected; result will be null:\",\n err,\n );\n if (!cancelled) setHandlerResult(null);\n });\n } else {\n setHandlerResult(maybePromise);\n }\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [pending]);\n\n const element = useMemo(() => {\n if (!pending) return null;\n const legacyEvent = toLegacyEvent(pending);\n if (!isEnabled(legacyEvent)) return null;\n\n return renderRef.current({\n event: legacyEvent,\n interrupt: pending.kind === \"standard\" ? pending.interrupts[0] : null,\n interrupts: pending.kind === \"standard\" ? pending.interrupts : [],\n result: handlerResult,\n resolve,\n cancel,\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [pending, handlerResult, resolve, cancel]);\n\n // Publish to core for in-chat rendering. Publish-only.\n useEffect(() => {\n if (config.renderInChat === false) return;\n copilotkit.setInterruptElement(element);\n }, [element, config.renderInChat, copilotkit]);\n\n // Nullify on true unmount only.\n useEffect(() => {\n if (config.renderInChat === false) return;\n return () => {\n copilotkit.setInterruptElement(null);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n if (config.renderInChat === false) {\n return element as UseInterruptReturn<TRenderInChat>;\n }\n\n return undefined as UseInterruptReturn<TRenderInChat>;\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { Suggestion } from \"@copilotkit/core\";\nimport { useCopilotKit } from \"../context\";\nimport { useCopilotChatConfiguration } from \"../providers/CopilotChatConfigurationProvider\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkit/shared\";\n\nexport interface UseSuggestionsOptions {\n agentId?: string;\n}\n\nexport interface UseSuggestionsResult {\n suggestions: Suggestion[];\n reloadSuggestions: () => void;\n clearSuggestions: () => void;\n isLoading: boolean;\n}\n\nexport function useSuggestions({\n agentId,\n}: UseSuggestionsOptions = {}): UseSuggestionsResult {\n const { copilotkit } = useCopilotKit();\n const config = useCopilotChatConfiguration();\n const resolvedAgentId = useMemo(\n () => agentId ?? config?.agentId ?? DEFAULT_AGENT_ID,\n [agentId, config?.agentId],\n );\n\n const [suggestions, setSuggestions] = useState<Suggestion[]>(() => {\n const result = copilotkit.getSuggestions(resolvedAgentId);\n return result.suggestions;\n });\n const [isLoading, setIsLoading] = useState(() => {\n const result = copilotkit.getSuggestions(resolvedAgentId);\n return result.isLoading;\n });\n\n useEffect(() => {\n const result = copilotkit.getSuggestions(resolvedAgentId);\n setSuggestions(result.suggestions);\n setIsLoading(result.isLoading);\n }, [copilotkit, resolvedAgentId]);\n\n useEffect(() => {\n const subscription = copilotkit.subscribe({\n onSuggestionsChanged: ({ agentId: changedAgentId, suggestions }) => {\n if (changedAgentId !== resolvedAgentId) {\n return;\n }\n setSuggestions(suggestions);\n },\n onSuggestionsStartedLoading: ({ agentId: changedAgentId }) => {\n if (changedAgentId !== resolvedAgentId) {\n return;\n }\n setIsLoading(true);\n },\n onSuggestionsFinishedLoading: ({ agentId: changedAgentId }) => {\n if (changedAgentId !== resolvedAgentId) {\n return;\n }\n setIsLoading(false);\n },\n onSuggestionsConfigChanged: () => {\n const result = copilotkit.getSuggestions(resolvedAgentId);\n setSuggestions(result.suggestions);\n setIsLoading(result.isLoading);\n },\n });\n\n return () => {\n subscription.unsubscribe();\n };\n }, [copilotkit, resolvedAgentId]);\n\n const reloadSuggestions = useCallback(() => {\n copilotkit.reloadSuggestions(resolvedAgentId);\n // Loading state is handled by onSuggestionsStartedLoading event\n }, [copilotkit, resolvedAgentId]);\n\n const clearSuggestions = useCallback(() => {\n copilotkit.clearSuggestions(resolvedAgentId);\n // State updates are handled by onSuggestionsChanged event\n }, [copilotkit, resolvedAgentId]);\n\n return {\n suggestions,\n reloadSuggestions,\n clearSuggestions,\n isLoading,\n };\n}\n","import { useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { useCopilotKit } from \"../context\";\nimport { useCopilotChatConfiguration } from \"../providers/CopilotChatConfigurationProvider\";\nimport { DEFAULT_AGENT_ID } from \"@copilotkit/shared\";\nimport type {\n DynamicSuggestionsConfig,\n StaticSuggestionsConfig,\n SuggestionsConfig,\n Suggestion,\n} from \"@copilotkit/core\";\n\ntype StaticSuggestionInput = Omit<Suggestion, \"isLoading\"> &\n Partial<Pick<Suggestion, \"isLoading\">>;\n\ntype StaticSuggestionsConfigInput = Omit<\n StaticSuggestionsConfig,\n \"suggestions\"\n> & {\n suggestions: StaticSuggestionInput[];\n};\n\ntype SuggestionsConfigInput =\n | DynamicSuggestionsConfig\n | StaticSuggestionsConfigInput;\n\nexport function useConfigureSuggestions(\n config: SuggestionsConfigInput | null | undefined,\n deps?: ReadonlyArray<unknown>,\n): void {\n const { copilotkit } = useCopilotKit();\n const chatConfig = useCopilotChatConfiguration();\n const extraDeps = deps ?? [];\n\n const resolvedConsumerAgentId = useMemo(\n () => chatConfig?.agentId ?? DEFAULT_AGENT_ID,\n [chatConfig?.agentId],\n );\n\n const rawConsumerAgentId = useMemo(\n () =>\n config ? (config as SuggestionsConfigInput).consumerAgentId : undefined,\n [config],\n );\n\n const normalizationCacheRef = useRef<{\n serialized: string | null;\n config: SuggestionsConfig | null;\n }>({\n serialized: null,\n config: null,\n });\n\n const { normalizedConfig, serializedConfig } = useMemo(() => {\n if (!config) {\n normalizationCacheRef.current = { serialized: null, config: null };\n return { normalizedConfig: null, serializedConfig: null };\n }\n\n if (config.available === \"disabled\") {\n normalizationCacheRef.current = { serialized: null, config: null };\n return { normalizedConfig: null, serializedConfig: null };\n }\n\n let built: SuggestionsConfig;\n if (isDynamicConfig(config)) {\n built = {\n ...config,\n } satisfies DynamicSuggestionsConfig;\n } else {\n const normalizedSuggestions = normalizeStaticSuggestions(\n config.suggestions,\n );\n const baseConfig: StaticSuggestionsConfig = {\n ...config,\n suggestions: normalizedSuggestions,\n };\n built = baseConfig;\n }\n\n const serialized = JSON.stringify(built);\n const cache = normalizationCacheRef.current;\n if (cache.serialized === serialized && cache.config) {\n return { normalizedConfig: cache.config, serializedConfig: serialized };\n }\n\n normalizationCacheRef.current = { serialized, config: built };\n return { normalizedConfig: built, serializedConfig: serialized };\n }, [config, resolvedConsumerAgentId, ...extraDeps]);\n const latestConfigRef = useRef<SuggestionsConfig | null>(null);\n latestConfigRef.current = normalizedConfig;\n const previousSerializedConfigRef = useRef<string | null>(null);\n\n const targetAgentId = useMemo(() => {\n if (!normalizedConfig) {\n return resolvedConsumerAgentId;\n }\n const consumer = (\n normalizedConfig as StaticSuggestionsConfig | DynamicSuggestionsConfig\n ).consumerAgentId;\n if (!consumer || consumer === \"*\") {\n return resolvedConsumerAgentId;\n }\n return consumer;\n }, [normalizedConfig, resolvedConsumerAgentId]);\n\n const isGlobalConfig =\n rawConsumerAgentId === undefined || rawConsumerAgentId === \"*\";\n\n const isDynamicConfigType = useMemo(\n () => !!normalizedConfig && \"instructions\" in normalizedConfig,\n [normalizedConfig],\n );\n\n const requestReload = useCallback(() => {\n if (!normalizedConfig) {\n return;\n }\n\n if (isGlobalConfig) {\n const seen = new Set<string>();\n const agents = Object.values(copilotkit.agents ?? {});\n for (const entry of agents) {\n const agentId = entry.agentId;\n if (!agentId) {\n continue;\n }\n seen.add(agentId);\n if (!entry.isRunning) {\n copilotkit.reloadSuggestions(agentId);\n }\n }\n // Also reload for the chat's resolved consumer agent. The registry can\n // be empty at this point (e.g. runtime info still loading), in which\n // case the loop above wouldn't have fired for the agent the user is\n // actually chatting with — and the welcome screen would render with\n // no suggestions until they navigate away and back.\n if (targetAgentId && !seen.has(targetAgentId)) {\n copilotkit.reloadSuggestions(targetAgentId);\n }\n return;\n }\n\n if (!targetAgentId) {\n return;\n }\n\n copilotkit.reloadSuggestions(targetAgentId);\n }, [copilotkit, isGlobalConfig, normalizedConfig, targetAgentId]);\n\n useEffect(() => {\n if (!serializedConfig || !latestConfigRef.current) {\n return;\n }\n\n const id = copilotkit.addSuggestionsConfig(latestConfigRef.current);\n\n requestReload();\n\n return () => {\n copilotkit.removeSuggestionsConfig(id);\n };\n }, [copilotkit, serializedConfig, requestReload]);\n\n useEffect(() => {\n if (!normalizedConfig) {\n previousSerializedConfigRef.current = null;\n return;\n }\n if (\n serializedConfig &&\n previousSerializedConfigRef.current === serializedConfig\n ) {\n return;\n }\n if (serializedConfig) {\n previousSerializedConfigRef.current = serializedConfig;\n }\n requestReload();\n }, [normalizedConfig, requestReload, serializedConfig]);\n\n useEffect(() => {\n if (!normalizedConfig || extraDeps.length === 0) {\n return;\n }\n requestReload();\n }, [extraDeps.length, normalizedConfig, requestReload, ...extraDeps]);\n\n // When agents arrive after the initial render (runtime info just landed),\n // re-request a reload so dynamic configs that need a real agent can finally\n // generate. Skip for static configs — they don't need an agent and the\n // initial mount reload already handled them. Skip when the target agent\n // is already in the registry — the initial reload already covered it, and\n // re-firing on every subsequent `onAgentsChanged` (e.g. dev-mode hot\n // reloads, sibling chat configs mounting) would stack overlapping\n // generations.\n useEffect(() => {\n if (!normalizedConfig || !isDynamicConfigType) return;\n if (!targetAgentId) return;\n\n const initiallyPresent = !!copilotkit.getAgent(targetAgentId);\n if (initiallyPresent) return;\n\n const subscription = copilotkit.subscribe({\n onAgentsChanged: () => {\n if (copilotkit.getAgent(targetAgentId)) {\n requestReload();\n subscription.unsubscribe();\n }\n },\n });\n return () => {\n subscription.unsubscribe();\n };\n }, [\n copilotkit,\n normalizedConfig,\n isDynamicConfigType,\n targetAgentId,\n requestReload,\n ]);\n}\n\nfunction isDynamicConfig(\n config: SuggestionsConfigInput,\n): config is DynamicSuggestionsConfig {\n return \"instructions\" in config;\n}\n\nfunction normalizeStaticSuggestions(\n suggestions: StaticSuggestionInput[],\n): Suggestion[] {\n return suggestions.map((suggestion) => ({\n ...suggestion,\n isLoading: suggestion.isLoading ?? false,\n }));\n}\n","import { useCopilotKit } from \"../context\";\nimport { useLayoutEffect, useMemo } from \"react\";\n\n/**\n * Represents any value that can be serialized to JSON.\n */\nexport type JsonSerializable =\n | string\n | number\n | boolean\n | null\n | JsonSerializable[]\n | { [key: string]: JsonSerializable };\n\n/**\n * Context configuration for useAgentContext.\n * Accepts any JSON-serializable value which will be converted to a string.\n */\nexport interface AgentContextInput {\n /** A human-readable description of what this context represents */\n description: string;\n /** The context value - will be converted to a JSON string if not already a string */\n value: JsonSerializable;\n}\n\nexport function useAgentContext(context: AgentContextInput) {\n const { description, value } = context;\n const { copilotkit } = useCopilotKit();\n\n const stringValue = useMemo(() => {\n if (typeof value === \"string\") {\n return value;\n }\n return JSON.stringify(value);\n }, [value]);\n\n useLayoutEffect(() => {\n if (!copilotkit) return;\n\n const id = copilotkit.addContext({ description, value: stringValue });\n return () => {\n copilotkit.removeContext(id);\n };\n }, [description, stringValue, copilotkit]);\n}\n","import { useCopilotKit } from \"../context\";\nimport {\n CopilotKitCoreRuntimeConnectionStatus,\n ɵcreateThreadStore,\n ɵselectThreads,\n ɵselectThreadsError,\n ɵselectThreadsIsLoading,\n ɵselectHasNextPage,\n ɵselectIsFetchingNextPage,\n ɵselectIsMutating,\n} from \"@copilotkit/core\";\nimport type { ɵThreadRuntimeContext, ɵThreadStore } from \"@copilotkit/core\";\nimport {\n useCallback,\n useEffect,\n useMemo,\n useState,\n useSyncExternalStore,\n} from \"react\";\n\n/**\n * A conversation thread managed by the Intelligence platform.\n *\n * Each thread has a unique `id`, an optional human-readable `name`, and\n * timestamp fields tracking creation and update times.\n */\nexport interface Thread {\n id: string;\n agentId: string;\n name: string | null;\n archived: boolean;\n createdAt: string;\n updatedAt: string;\n /**\n * ISO-8601 timestamp of the most recent agent run on this thread. Absent\n * when the thread has never been run. Prefer this over `updatedAt` for\n * user-facing \"last activity\" displays — it is not bumped by metadata-only\n * actions like rename or archive.\n */\n lastRunAt?: string;\n}\n\n/**\n * Configuration for the {@link useThreads} hook.\n *\n * Thread operations are scoped to the runtime-authenticated user and the\n * provided agent on the Intelligence platform.\n */\nexport interface UseThreadsInput {\n /** The ID of the agent whose threads to list and manage. */\n agentId: string;\n /** When `true`, archived threads are included in the list. Defaults to `false`. */\n includeArchived?: boolean;\n /** Maximum number of threads to fetch per page. When set, enables cursor-based pagination. */\n limit?: number;\n /**\n * When `false`, the hook stays inert: no runtime context is dispatched, so\n * NO thread-list fetch or realtime subscription is issued. Used by gated\n * surfaces (e.g. an unlicensed `<CopilotThreadsDrawer>`) that must not touch the\n * network until the gate opens. Defaults to `true`.\n *\n * Flipping `enabled` back to `true` resumes normal fetching on the next\n * effect run; mutations are likewise short-circuited while disabled.\n */\n enabled?: boolean;\n}\n\n/**\n * Return value of the {@link useThreads} hook.\n *\n * The `threads` array is kept in sync with the platform via a realtime\n * WebSocket subscription (when available) and is sorted most-recently-updated\n * first. Mutations reject with an `Error` if the platform request fails.\n */\nexport interface UseThreadsResult {\n /**\n * Threads for the current user/agent pair, sorted by most recently\n * updated first. Updated in realtime when the platform pushes metadata\n * events. Includes archived threads only when `includeArchived` is set.\n */\n threads: Thread[];\n /**\n * `true` while the initial thread list is being fetched from the platform.\n * Subsequent realtime updates do not re-enter the loading state.\n */\n isLoading: boolean;\n /**\n * The most recent error from fetching threads or executing a mutation,\n * or `null` when there is no error. Reset to `null` on the next\n * successful fetch.\n *\n * This channel folds together developer/config errors (missing runtime URL,\n * runtime without thread endpoints) and genuine list-load/mutation failures.\n * End-user surfaces that must not leak config errors should prefer\n * {@link listError}, which excludes the config/runtime-setup errors.\n */\n error: Error | null;\n /**\n * The most recent genuine list-load or mutation error from the platform, or\n * `null`. Unlike {@link error}, this EXCLUDES developer/config errors (a\n * missing runtime URL, or a runtime that does not advertise thread\n * endpoints), so an end-user surface can render it directly without leaking\n * a developer-facing configuration message into the UI.\n */\n listError: Error | null;\n /**\n * `true` when there are more threads available to fetch via\n * {@link fetchMoreThreads}. Only meaningful when `limit` is set.\n */\n hasMoreThreads: boolean;\n /**\n * `true` while a subsequent page of threads is being fetched.\n */\n isFetchingMoreThreads: boolean;\n /**\n * `true` while at least one thread mutation (rename, archive, unarchive,\n * delete) is awaiting a server response. Mutations apply optimistically, so\n * this is primarily useful for disabling controls or showing a subtle\n * in-flight indicator.\n */\n isMutating: boolean;\n /**\n * Fetch the next page of threads. No-op when {@link hasMoreThreads} is\n * `false` or a fetch is already in progress.\n */\n fetchMoreThreads: () => void;\n /**\n * Re-fetch the thread list from the platform without clearing the current\n * list. Backs the drawer's error-state Retry and the Active/All filter\n * refetch. No-op until the runtime is connected.\n */\n refetchThreads: () => void;\n /**\n * Reset to a fresh, non-explicit client-side thread so the welcome screen\n * shows. Lazy creation: no row appears in {@link threads} until the new\n * thread's first run persists server-side.\n */\n startNewThread: () => void;\n /**\n * Rename a thread on the platform.\n * Resolves when the server confirms the update; rejects on failure.\n */\n renameThread: (threadId: string, name: string) => Promise<void>;\n /**\n * Archive a thread on the platform.\n * Archived threads are excluded from subsequent list results.\n * Resolves when the server confirms the update; rejects on failure.\n */\n archiveThread: (threadId: string) => Promise<void>;\n /**\n * Restore a previously archived thread on the platform.\n * The thread re-appears in default (non-archived) list results.\n * Resolves when the server confirms the update; rejects on failure.\n */\n unarchiveThread: (threadId: string) => Promise<void>;\n /**\n * Permanently delete a thread from the platform.\n * This is irreversible. Resolves when the server confirms deletion;\n * rejects on failure.\n */\n deleteThread: (threadId: string) => Promise<void>;\n}\n\nfunction useThreadStoreSelector<T>(\n store: ɵThreadStore,\n selector: (state: ReturnType<ɵThreadStore[\"getState\"]>) => T,\n): T {\n return useSyncExternalStore(\n useCallback(\n (onStoreChange) => {\n const subscription = store.select(selector).subscribe(onStoreChange);\n return () => subscription.unsubscribe();\n },\n [store, selector],\n ),\n () => selector(store.getState()),\n // getServerSnapshot: without this third argument React throws\n // \"Missing getServerSnapshot\" during SSR/prerender (e.g. Next.js). The\n // store has no client data while prerendering, so we project from its\n // stable server state.\n () => selector(store.getServerState()),\n );\n}\n\n/**\n * React hook for listing and managing Intelligence platform threads.\n *\n * On mount the hook fetches the thread list for the runtime-authenticated user\n * and the given `agentId`. When the Intelligence platform exposes a WebSocket\n * URL, it also opens a realtime subscription so the `threads` array stays\n * current without polling — thread creates, renames, archives, and deletes\n * from any client are reflected immediately.\n *\n * Mutation methods (`renameThread`, `archiveThread`, `unarchiveThread`,\n * `deleteThread`) return promises that resolve once the platform confirms the\n * operation and reject with an `Error` on failure.\n *\n * @param input - Agent identifier and optional list controls.\n * @returns Thread list state and stable mutation callbacks.\n *\n * @example\n * ```tsx\n * import { useThreads } from \"@copilotkit/react-core\";\n *\n * function ThreadList() {\n * const { threads, isLoading, renameThread, deleteThread } = useThreads({\n * agentId: \"agent-1\",\n * });\n *\n * if (isLoading) return <p>Loading…</p>;\n *\n * return (\n * <ul>\n * {threads.map((t) => (\n * <li key={t.id}>\n * {t.name ?? \"Untitled\"}\n * <button onClick={() => renameThread(t.id, \"New name\")}>Rename</button>\n * <button onClick={() => deleteThread(t.id)}>Delete</button>\n * </li>\n * ))}\n * </ul>\n * );\n * }\n * ```\n */\nexport function useThreads({\n agentId,\n includeArchived,\n limit,\n enabled = true,\n}: UseThreadsInput): UseThreadsResult {\n const { copilotkit } = useCopilotKit();\n\n const [store] = useState(() =>\n ɵcreateThreadStore({\n fetch: globalThis.fetch,\n }),\n );\n\n const coreThreads = useThreadStoreSelector(store, ɵselectThreads);\n const threads: Thread[] = useMemo(\n () =>\n coreThreads.map(\n ({ id, agentId, name, archived, createdAt, updatedAt, lastRunAt }) => ({\n id,\n agentId,\n name,\n archived,\n createdAt,\n updatedAt,\n ...(lastRunAt !== undefined ? { lastRunAt } : {}),\n }),\n ),\n [coreThreads],\n );\n const storeIsLoading = useThreadStoreSelector(store, ɵselectThreadsIsLoading);\n const storeError = useThreadStoreSelector(store, ɵselectThreadsError);\n const hasMoreThreads = useThreadStoreSelector(store, ɵselectHasNextPage);\n const isFetchingMoreThreads = useThreadStoreSelector(\n store,\n ɵselectIsFetchingNextPage,\n );\n const isMutating = useThreadStoreSelector(store, ɵselectIsMutating);\n const headersKey = useMemo(() => {\n return JSON.stringify(\n Object.entries(copilotkit.headers ?? {}).sort(([left], [right]) =>\n left.localeCompare(right),\n ),\n );\n }, [copilotkit.headers]);\n const runtimeStatus = copilotkit.runtimeConnectionStatus;\n const threadListEndpointSupported =\n copilotkit.threadEndpoints?.list !== false;\n const threadMutationsSupported =\n copilotkit.threadEndpoints?.mutations !== false;\n const threadEndpointsUnavailable =\n !!copilotkit.runtimeUrl &&\n runtimeStatus === CopilotKitCoreRuntimeConnectionStatus.Connected &&\n !threadListEndpointSupported;\n const runtimeError = useMemo(() => {\n if (copilotkit.runtimeUrl) {\n return null;\n }\n\n return new Error(\"Runtime URL is not configured\");\n }, [copilotkit.runtimeUrl]);\n const threadEndpointsError = useMemo(() => {\n if (!threadEndpointsUnavailable) {\n return null;\n }\n\n return new Error(\n \"Thread endpoints are not available on this CopilotKit runtime\",\n );\n }, [threadEndpointsUnavailable]);\n const threadMutationsError = useMemo(() => {\n if (threadMutationsSupported) {\n return null;\n }\n\n return new Error(\n \"Thread mutations are not available on this CopilotKit runtime\",\n );\n }, [threadMutationsSupported]);\n\n // Tracks whether we've dispatched the first real context to the store.\n // The store itself starts with `isLoading: false`, so before we dispatch\n // consumers would otherwise see an empty, non-loading state (empty-list\n // flash). While runtimeUrl is set and we haven't dispatched yet, we\n // synthesize `isLoading: true` so the UI keeps its loading indicator until\n // the first fetch is in flight (at which point the store's own\n // isLoading takes over).\n const [hasDispatchedContext, setHasDispatchedContext] = useState(false);\n const preConnectLoading =\n enabled &&\n !!copilotkit.runtimeUrl &&\n !threadEndpointsUnavailable &&\n !hasDispatchedContext;\n\n // `startNewThread` resets to a clean welcome surface, so it should clear any\n // lingering error banner — including the config/runtime-setup errors that\n // otherwise outrank the store's own (already-cleared) error. We cannot clear\n // a derived `runtimeError`/`threadEndpointsError` directly (they reflect\n // current config), so we suppress them with a dismissal flag that resets\n // whenever the underlying config-error identity changes (a genuine new config\n // problem re-surfaces).\n const [configErrorDismissed, setConfigErrorDismissed] = useState(false);\n useEffect(() => {\n setConfigErrorDismissed(false);\n }, [runtimeError, threadEndpointsError]);\n\n const activeRuntimeError = configErrorDismissed ? null : runtimeError;\n const activeThreadEndpointsError = configErrorDismissed\n ? null\n : threadEndpointsError;\n\n const isLoading =\n activeRuntimeError || activeThreadEndpointsError\n ? false\n : preConnectLoading || storeIsLoading;\n const error = activeRuntimeError ?? activeThreadEndpointsError ?? storeError;\n // End-user-facing list/mutation error only: developer/config errors are\n // excluded so a surface like <CopilotThreadsDrawer> does not show \"Runtime URL is\n // not configured\" to an end user.\n const listError = storeError;\n\n useEffect(() => {\n store.start();\n return () => {\n store.stop();\n };\n }, [store]);\n\n // Defer setting the context until the runtime reports Connected. Before\n // `/info` resolves we don't know `intelligence.wsUrl`, so dispatching the\n // context early would issue a list fetch with `wsUrl: undefined`, then a\n // second list fetch (and a `/threads/subscribe`) once the flag lands.\n // Waiting lets the hook issue just one `/threads?…` + one `/threads/subscribe`.\n //\n // When `runtimeUrl` is absent we dispatch `null` to clear the store. For\n // transient states (Disconnected/Connecting/Error with a URL still set) we\n // leave the previously-dispatched context in place — any in-flight\n // realtime subscription or cached thread list stays usable while the\n // runtime recovers, and we don't re-trigger a fetch storm on transitions.\n useEffect(() => {\n // A disabled (e.g. unlicensed) drawer must not claim the agentId slot. The\n // registry is single-slot/last-writer-wins, so registering an inert store\n // would evict — and on unmount tear down — a co-mounted live store for the\n // same agent. Staying unregistered while disabled leaves the live store's\n // registration intact.\n if (!enabled) return;\n copilotkit.registerThreadStore(agentId, store);\n return () => {\n copilotkit.unregisterThreadStore(agentId);\n };\n }, [copilotkit, agentId, store, enabled]);\n\n useEffect(() => {\n // Disabled: stay inert. Clear any previously-dispatched context so an\n // in-flight subscription is torn down and no further fetch is issued.\n if (!enabled) {\n store.setContext(null);\n setHasDispatchedContext(false);\n return;\n }\n\n if (!copilotkit.runtimeUrl) {\n store.setContext(null);\n setHasDispatchedContext(false);\n return;\n }\n\n // Wait for /info to land so we can include `wsUrl` in the initial\n // context and avoid a redundant second list fetch.\n if (runtimeStatus !== CopilotKitCoreRuntimeConnectionStatus.Connected) {\n return;\n }\n\n if (!threadListEndpointSupported) {\n store.setContext(null);\n setHasDispatchedContext(false);\n return;\n }\n\n const context: ɵThreadRuntimeContext = {\n runtimeUrl: copilotkit.runtimeUrl,\n headers: { ...copilotkit.headers },\n wsUrl: copilotkit.intelligence?.wsUrl,\n agentId,\n includeArchived,\n limit,\n };\n\n store.setContext(context);\n setHasDispatchedContext(true);\n }, [\n store,\n enabled,\n copilotkit.runtimeUrl,\n runtimeStatus,\n headersKey,\n copilotkit.intelligence?.wsUrl,\n threadListEndpointSupported,\n agentId,\n includeArchived,\n limit,\n ]);\n\n const guardMutation = useCallback(\n <TArgs extends unknown[]>(\n mutation: (...args: TArgs) => Promise<void>,\n ): ((...args: TArgs) => Promise<void>) => {\n return (...args: TArgs) => {\n if (threadMutationsError) {\n return Promise.reject(threadMutationsError);\n }\n return mutation(...args);\n };\n },\n [threadMutationsError],\n );\n\n const renameThread = useMemo(\n () =>\n guardMutation((threadId: string, name: string) =>\n store.renameThread(threadId, name),\n ),\n [store, guardMutation],\n );\n\n const archiveThread = useMemo(\n () => guardMutation((threadId: string) => store.archiveThread(threadId)),\n [store, guardMutation],\n );\n\n const unarchiveThread = useMemo(\n () => guardMutation((threadId: string) => store.unarchiveThread(threadId)),\n [store, guardMutation],\n );\n\n const deleteThread = useMemo(\n () => guardMutation((threadId: string) => store.deleteThread(threadId)),\n [store, guardMutation],\n );\n\n const fetchMoreThreads = useCallback(() => store.fetchNextPage(), [store]);\n const refetchThreads = useCallback(() => store.refetchThreads(), [store]);\n const startNewThread = useCallback(() => {\n // The store's `newThreadStarted` reducer clears its own error; also dismiss\n // the derived config/runtime-setup errors so the welcome surface renders\n // with no stale error banner.\n setConfigErrorDismissed(true);\n store.startNewThread();\n }, [store]);\n\n return {\n threads,\n isLoading,\n error,\n listError,\n hasMoreThreads,\n isFetchingMoreThreads,\n isMutating,\n fetchMoreThreads,\n refetchThreads,\n startNewThread,\n renameThread,\n archiveThread,\n unarchiveThread,\n deleteThread,\n };\n}\n","import React from \"react\";\nimport { z } from \"zod\";\nimport type { StandardSchemaV1, InferSchemaOutput } from \"@copilotkit/shared\";\nimport { ReactToolCallRenderer } from \"./react-tool-call-renderer\";\nimport { ToolCallStatus } from \"@copilotkit/core\";\n\n/**\n * Helper to define a type-safe tool call renderer entry.\n * - Accepts a single object whose keys match ReactToolCallRenderer's fields: { name, args, render, agentId? }.\n * - Derives `args` type from the provided schema (any Standard Schema V1 compatible library).\n * - Ensures the render function param type exactly matches ReactToolCallRenderer<T>[\"render\"]'s param.\n * - For wildcard tools (name: \"*\"), args is optional and defaults to z.any()\n */\ntype RenderProps<T> =\n | {\n name: string;\n toolCallId: string;\n args: Partial<T>;\n status: ToolCallStatus.InProgress;\n result: undefined;\n }\n | {\n name: string;\n toolCallId: string;\n args: T;\n status: ToolCallStatus.Executing;\n result: undefined;\n }\n | {\n name: string;\n toolCallId: string;\n args: T;\n status: ToolCallStatus.Complete;\n result: string;\n };\n\n// Overload for wildcard tools without args\nexport function defineToolCallRenderer(def: {\n name: \"*\";\n render: (props: RenderProps<any>) => React.ReactElement;\n agentId?: string;\n}): ReactToolCallRenderer<any>;\n\n// Overload for regular tools with args\nexport function defineToolCallRenderer<S extends StandardSchemaV1>(def: {\n name: string;\n args: S;\n render: (props: RenderProps<InferSchemaOutput<S>>) => React.ReactElement;\n agentId?: string;\n}): ReactToolCallRenderer<InferSchemaOutput<S>>;\n\n// Implementation\nexport function defineToolCallRenderer<S extends StandardSchemaV1>(def: {\n name: string;\n args?: S;\n render: (props: any) => React.ReactElement;\n agentId?: string;\n}): ReactToolCallRenderer<any> {\n // For wildcard tools, default to z.any() if no args provided\n const argsSchema = def.name === \"*\" && !def.args ? z.any() : def.args;\n\n return {\n name: def.name,\n args: argsSchema,\n render: def.render as React.ComponentType<any>,\n ...(def.agentId ? { agentId: def.agentId } : {}),\n };\n}\n","import { useEffect } from \"react\";\nimport type { StandardSchemaV1, InferSchemaOutput } from \"@copilotkit/shared\";\nimport { ToolCallStatus } from \"@copilotkit/core\";\nimport { useCopilotKit } from \"../context\";\nimport { defineToolCallRenderer } from \"../types/defineToolCallRenderer\";\n\nconst EMPTY_DEPS: ReadonlyArray<unknown> = [];\n\nexport interface RenderToolInProgressProps<S extends StandardSchemaV1> {\n name: string;\n toolCallId: string;\n parameters: Partial<InferSchemaOutput<S>>;\n status: \"inProgress\";\n result: undefined;\n}\n\nexport interface RenderToolExecutingProps<S extends StandardSchemaV1> {\n name: string;\n toolCallId: string;\n parameters: InferSchemaOutput<S>;\n status: \"executing\";\n result: undefined;\n}\n\nexport interface RenderToolCompleteProps<S extends StandardSchemaV1> {\n name: string;\n toolCallId: string;\n parameters: InferSchemaOutput<S>;\n status: \"complete\";\n result: string;\n}\n\nexport type RenderToolProps<S extends StandardSchemaV1> =\n | RenderToolInProgressProps<S>\n | RenderToolExecutingProps<S>\n | RenderToolCompleteProps<S>;\n\ntype RenderToolConfig<S extends StandardSchemaV1> = {\n name: string;\n parameters?: S;\n render: (props: RenderToolProps<S>) => React.ReactElement;\n agentId?: string;\n};\n\n/**\n * Registers a wildcard (`\"*\"`) renderer for tool calls.\n *\n * The wildcard renderer is used as a fallback when no exact name-matched\n * renderer is registered for a tool call.\n *\n * @param config - Wildcard renderer configuration.\n * @param deps - Optional dependencies to refresh registration.\n *\n * @example\n * ```tsx\n * useRenderTool(\n * {\n * name: \"*\",\n * render: ({ name, status }) => (\n * <div>\n * {status === \"complete\" ? \"✓\" : \"⏳\"} {name}\n * </div>\n * ),\n * },\n * [],\n * );\n * ```\n */\nexport function useRenderTool(\n config: {\n name: \"*\";\n render: (props: any) => React.ReactElement;\n agentId?: string;\n },\n deps?: ReadonlyArray<unknown>,\n): void;\n\n/**\n * Registers a name-scoped renderer for tool calls.\n *\n * The provided `parameters` schema defines the typed shape of `props.parameters`\n * in `render` for `executing` and `complete` states. Accepts any Standard Schema V1\n * compatible library (Zod, Valibot, ArkType, etc.).\n *\n * @typeParam S - Schema type describing tool call parameters.\n * @param config - Named renderer configuration.\n * @param deps - Optional dependencies to refresh registration.\n *\n * @example\n * ```tsx\n * useRenderTool(\n * {\n * name: \"searchDocs\",\n * parameters: z.object({ query: z.string() }),\n * render: ({ status, parameters, result }) => {\n * if (status === \"inProgress\") return <div>Preparing...</div>;\n * if (status === \"executing\") return <div>Searching {parameters.query}</div>;\n * return <div>{result}</div>;\n * },\n * },\n * [],\n * );\n * ```\n */\nexport function useRenderTool<S extends StandardSchemaV1>(\n config: {\n name: string;\n parameters: S;\n render: (props: RenderToolProps<S>) => React.ReactElement;\n agentId?: string;\n },\n deps?: ReadonlyArray<unknown>,\n): void;\n\n/**\n * Registers a renderer entry in CopilotKit's `renderToolCalls` registry.\n *\n * Key behavior:\n * - deduplicates by `agentId:name` (latest registration wins),\n * - keeps renderer entries on cleanup so historical chat tool calls can still render,\n * - refreshes registration when `deps` change.\n *\n * @typeParam S - Schema type describing tool call parameters.\n * @param config - Renderer config for wildcard or named tools.\n * @param deps - Optional dependencies to refresh registration.\n *\n * @example\n * ```tsx\n * useRenderTool(\n * {\n * name: \"searchDocs\",\n * parameters: z.object({ query: z.string() }),\n * render: ({ status, parameters, result }) => {\n * if (status === \"executing\") return <div>Searching {parameters.query}</div>;\n * if (status === \"complete\") return <div>{result}</div>;\n * return <div>Preparing...</div>;\n * },\n * },\n * [],\n * );\n * ```\n *\n * @example\n * ```tsx\n * useRenderTool(\n * {\n * name: \"summarize\",\n * parameters: z.object({ text: z.string() }),\n * agentId: \"research-agent\",\n * render: ({ name, status }) => <div>{name}: {status}</div>,\n * },\n * [selectedAgentId],\n * );\n * ```\n */\nexport function useRenderTool<S extends StandardSchemaV1>(\n config: RenderToolConfig<S>,\n deps?: ReadonlyArray<unknown>,\n): void {\n const { copilotkit } = useCopilotKit();\n const extraDeps = deps ?? EMPTY_DEPS;\n\n useEffect(() => {\n // Build the ReactToolCallRenderer via defineToolCallRenderer\n const renderer =\n config.name === \"*\" && !config.parameters\n ? defineToolCallRenderer({\n name: \"*\",\n render: (props) =>\n config.render({ ...props, parameters: props.args }),\n ...(config.agentId ? { agentId: config.agentId } : {}),\n })\n : defineToolCallRenderer({\n name: config.name,\n args: config.parameters!,\n // Branch per status so the discriminated union stays correlated\n // when `args` is re-exposed as `parameters`.\n render: (props) => {\n if (props.status === ToolCallStatus.InProgress) {\n return config.render({ ...props, parameters: props.args });\n }\n if (props.status === ToolCallStatus.Executing) {\n return config.render({ ...props, parameters: props.args });\n }\n return config.render({ ...props, parameters: props.args });\n },\n ...(config.agentId ? { agentId: config.agentId } : {}),\n });\n\n copilotkit.addHookRenderToolCall(renderer);\n\n // No cleanup removal — keeps renderer for chat history, same as useFrontendTool\n }, [config.name, copilotkit, JSON.stringify(extraDeps)]);\n}\n","import type { AgentCapabilities } from \"@ag-ui/core\";\nimport { useAgent } from \"./use-agent\";\n\n/**\n * Returns the capabilities declared by the given agent (or the default agent).\n * Capabilities are populated from the runtime `/info` response at connection\n * time. The hook reads them synchronously from the agent instance — there is\n * no separate loading state, but the value will be `undefined` until the\n * runtime handshake completes.\n *\n * @param agentId - Optional agent ID. If omitted, uses the default agent.\n * @returns The agent's capabilities, or `undefined` if the agent doesn't\n * declare capabilities.\n */\nexport function useCapabilities(\n agentId?: string,\n): AgentCapabilities | undefined {\n const { agent } = useAgent({ agentId });\n\n if (agent && \"capabilities\" in agent) {\n return (agent as { capabilities?: AgentCapabilities }).capabilities;\n }\n\n return undefined;\n}\n"],"mappings":"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"}
package/dist/v2/index.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
- const require_copilotkit = require('../copilotkit-CTCjVxkH.cjs');
4
+ const require_copilotkit = require('../copilotkit-CdpDZi3i.cjs');
5
5
  require("./index.css");
6
6
  let _copilotkit_a2ui_renderer = require("@copilotkit/a2ui-renderer");
7
7
 
@@ -52,6 +52,7 @@ Object.defineProperty(exports, 'CopilotSidebarView', {
52
52
  return require_copilotkit.CopilotSidebarView;
53
53
  }
54
54
  });
55
+ exports.CopilotThreadsDrawer = require_copilotkit.CopilotThreadsDrawer;
55
56
  exports.INTELLIGENCE_TURN_HEAD = require_copilotkit.INTELLIGENCE_TURN_HEAD;
56
57
  exports.IntelligenceIndicator = require_copilotkit.IntelligenceIndicator;
57
58
  exports.IntelligenceIndicatorView = require_copilotkit.IntelligenceIndicatorView;