{"version":3,"file":"headless.mjs","names":["EMPTY_DEPS"],"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        cached.headers = { ...copilotkit.headers };\n        return cached;\n      }\n\n      const provisional = new ProxiedCopilotRuntimeAgent({\n        runtimeUrl: copilotkit.runtimeUrl,\n        agentId,\n        transport: copilotkit.runtimeTransport,\n        runtimeMode: \"pending\",\n      });\n      // Apply current headers so runs/connects inherit them\n      provisional.headers = { ...copilotkit.headers };\n      provisionalAgentCache.current.set(agentId, provisional);\n      return provisional;\n    }\n\n    // Runtime is in Error state — return a provisional agent instead of throwing.\n    // The error has already been emitted through the subscriber system\n    // (RUNTIME_INFO_FETCH_FAILED). Throwing here would crash the React tree;\n    // returning a provisional agent lets onError handlers fire while keeping\n    // the app alive.\n    if (\n      isRuntimeConfigured &&\n      status === CopilotKitCoreRuntimeConnectionStatus.Error\n    ) {\n      const cached = provisionalAgentCache.current.get(agentId);\n      if (cached) {\n        cached.headers = { ...copilotkit.headers };\n        return cached;\n      }\n      const provisional = new ProxiedCopilotRuntimeAgent({\n        runtimeUrl: copilotkit.runtimeUrl,\n        agentId,\n        transport: copilotkit.runtimeTransport,\n        runtimeMode: \"pending\",\n      });\n      provisional.headers = { ...copilotkit.headers };\n      provisionalAgentCache.current.set(agentId, provisional);\n      return provisional;\n    }\n\n    // No runtime configured and agent doesn't exist — this is a configuration error.\n    const knownAgents = Object.keys(copilotkit.agents ?? {});\n    const runtimePart = isRuntimeConfigured\n      ? `runtimeUrl=${copilotkit.runtimeUrl}`\n      : \"no runtimeUrl\";\n    throw new Error(\n      `useAgent: Agent '${agentId}' not found after runtime sync (${runtimePart}). ` +\n        (knownAgents.length\n          ? `Known agents: [${knownAgents.join(\", \")}]`\n          : \"No agents registered.\") +\n        \" Verify your runtime /info and/or agents__unsafe_dev_only.\",\n    );\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [\n    agentId,\n    copilotkit.agents,\n    copilotkit.runtimeConnectionStatus,\n    copilotkit.runtimeUrl,\n    copilotkit.runtimeTransport,\n    JSON.stringify(copilotkit.headers),\n  ]);\n\n  useEffect(() => {\n    if (updateFlags.length === 0) return;\n\n    let active = true;\n    const handlers: SubscribeToAgentSubscriber = {};\n\n    // Microtask-batched forceUpdate: coalesces multiple synchronous\n    // notifications (e.g. OnStateChanged + OnRunStatusChanged firing in the\n    // same tick) into a single React re-render. This prevents the scroll\n    // jumping described in #3499 where rapid unbatched forceUpdate calls\n    // cause brief content height fluctuations during streaming.\n    let batchScheduled = false;\n    const batchedForceUpdate = () => {\n      if (!active) return;\n      if (!batchScheduled) {\n        batchScheduled = true;\n        queueMicrotask(() => {\n          batchScheduled = false;\n          if (active) {\n            forceUpdate();\n          }\n        });\n      }\n    };\n\n    if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) {\n      handlers.onMessagesChanged = batchedForceUpdate;\n    }\n\n    if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) {\n      handlers.onStateChanged = batchedForceUpdate;\n    }\n\n    if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {\n      handlers.onRunInitialized = batchedForceUpdate;\n      handlers.onRunFinalized = batchedForceUpdate;\n      handlers.onRunFailed = batchedForceUpdate;\n      // Protocol-level RUN_ERROR event (distinct from onRunFailed which\n      // handles local exceptions like network errors).\n      handlers.onRunErrorEvent = batchedForceUpdate;\n    }\n\n    const subscription = copilotkit.subscribeToAgentWithOptions(\n      agent,\n      handlers,\n      {\n        throttleMs,\n      },\n    );\n    return () => {\n      active = false;\n      subscription.unsubscribe();\n    };\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [agent, forceUpdate, throttleMs, providerThrottleMs, updateFlags]);\n\n  // Keep HttpAgent headers fresh without mutating inside useMemo, which is\n  // unsafe in concurrent mode (React may invoke useMemo multiple times and\n  // discard intermediate results, but mutations always land).\n  useEffect(() => {\n    if (agent instanceof HttpAgent) {\n      agent.headers = { ...copilotkit.headers };\n    }\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [agent, JSON.stringify(copilotkit.headers)]);\n\n  // Propagate the caller-supplied threadId from the chat configuration onto\n  // the agent. AbstractAgent's constructor auto-mints a UUID when no threadId\n  // is passed, so without this sync the agent ships its own random UUID in\n  // /agent/run, /agent/connect, /agent/stop — diverging from the threadId the\n  // app code reads via useThreads/useCopilotChatConfiguration. Gated on\n  // hasExplicitThreadId so a ThreadsProvider-minted placeholder UUID doesn't\n  // overwrite the auto-minted agent UUID (both are random and useless to the\n  // backend; the explicit gate keeps the agent's UUID stable across renders).\n  const chatConfig = useCopilotChatConfiguration();\n  const configThreadId = chatConfig?.threadId;\n  const configHasExplicitThreadId = chatConfig?.hasExplicitThreadId;\n  useEffect(() => {\n    if (!configHasExplicitThreadId || !configThreadId) return;\n    agent.threadId = configThreadId;\n  }, [agent, configThreadId, configHasExplicitThreadId]);\n\n  return {\n    agent,\n  };\n}\n","import { useEffect } from \"react\";\nimport { useCopilotKit } from \"../context\";\nimport type { ReactFrontendTool } from \"../types/frontend-tool\";\n\nconst EMPTY_DEPS: ReadonlyArray<unknown> = [];\n\nexport function useFrontendTool<\n  T extends Record<string, unknown> = Record<string, unknown>,\n>(tool: ReactFrontendTool<T>, deps?: ReadonlyArray<unknown>) {\n  const { copilotkit } = useCopilotKit();\n  const extraDeps = deps ?? EMPTY_DEPS;\n\n  useEffect(() => {\n    const name = tool.name;\n\n    // Always register/override the tool for this name on mount\n    if (copilotkit.getTool({ toolName: name, agentId: tool.agentId })) {\n      console.warn(\n        `Tool '${name}' already exists for agent '${tool.agentId || \"global\"}'. Overriding with latest registration.`,\n      );\n      copilotkit.removeTool(name, tool.agentId);\n    }\n    copilotkit.addTool(tool);\n\n    // Register/override renderer by name and agentId through core.\n    // The render function is registered even when tool.parameters is\n    // undefined — tools like HITL confirm dialogs have no parameters\n    // but still need their UI rendered in the chat.\n    if (tool.render) {\n      copilotkit.addHookRenderToolCall({\n        name,\n        args: tool.parameters,\n        agentId: tool.agentId,\n        render: tool.render,\n      });\n    }\n\n    return () => {\n      copilotkit.removeTool(name, tool.agentId);\n      // we are intentionally not removing the render here so that the tools can still render in the chat history\n    };\n    // Depend on stable keys by default and allow callers to opt into\n    // additional dependencies for dynamic tool configuration.\n    // tool.available is included so toggling availability re-registers the tool.\n  }, [tool.name, tool.available, copilotkit, JSON.stringify(extraDeps)]);\n}\n","import type { StandardSchemaV1, InferSchemaOutput } from \"@copilotkit/shared\";\nimport type { ComponentType } from \"react\";\nimport { useFrontendTool } from \"./use-frontend-tool\";\n\ntype InferRenderProps<T> = T extends StandardSchemaV1\n  ? InferSchemaOutput<T>\n  : any;\n\n/**\n * Registers a React component as a frontend tool renderer in chat.\n *\n * This hook is a convenience wrapper around `useFrontendTool` that:\n * - builds a model-facing tool description,\n * - forwards optional schema parameters (any Standard Schema V1 compatible library),\n * - renders your component with tool call parameters.\n *\n * Use this when you want to display a typed visual component for a tool call\n * without manually wiring a full frontend tool object.\n *\n * When `parameters` is provided, render props are inferred from the schema.\n * When omitted, the render component may accept any props.\n *\n * @typeParam TSchema - Schema describing tool parameters, or `undefined` when no schema is given.\n * @param config - Tool registration config.\n * @param deps - Optional dependencies to refresh registration (same semantics as `useEffect`).\n *\n * @example\n * ```tsx\n * // Without parameters — render accepts any props\n * useComponent({\n *   name: \"showGreeting\",\n *   render: ({ message }: { message: string }) => <div>{message}</div>,\n * });\n * ```\n *\n * @example\n * ```tsx\n * // With parameters — render props inferred from schema\n * useComponent({\n *   name: \"showWeatherCard\",\n *   parameters: z.object({ city: z.string() }),\n *   render: ({ city }) => <div>{city}</div>,\n * });\n * ```\n *\n * @example\n * ```tsx\n * useComponent(\n *   {\n *     name: \"renderProfile\",\n *     parameters: z.object({ userId: z.string() }),\n *     render: ProfileCard,\n *     agentId: \"support-agent\",\n *   },\n *   [selectedAgentId],\n * );\n * ```\n */\nexport function useComponent<\n  TSchema extends StandardSchemaV1 | undefined = undefined,\n>(\n  config: {\n    name: string;\n    description?: string;\n    parameters?: TSchema;\n    render: ComponentType<NoInfer<InferRenderProps<TSchema>>>;\n    agentId?: string;\n    followUp?: boolean;\n  },\n  deps?: ReadonlyArray<unknown>,\n): void {\n  const prefix = `Use this tool to display the \"${config.name}\" component in the chat. This tool renders a visual UI component for the user.`;\n  const fullDescription = config.description\n    ? `${prefix}\\n\\n${config.description}`\n    : prefix;\n\n  useFrontendTool(\n    {\n      name: config.name,\n      description: fullDescription,\n      parameters: config.parameters,\n      render: ({ args }: { args: unknown }) => {\n        const Component = config.render;\n        return <Component {...(args as InferRenderProps<TSchema>)} />;\n      },\n      agentId: config.agentId,\n      followUp: config.followUp,\n    },\n    deps,\n  );\n}\n","import { useCopilotKit } from \"../context\";\nimport type { ReactFrontendTool } from \"../types/frontend-tool\";\nimport type { ReactHumanInTheLoop } from \"../types/human-in-the-loop\";\nimport type { ReactToolCallRenderer } from \"../types/react-tool-call-renderer\";\nimport { useCallback, useEffect, useRef } from \"react\";\nimport React from \"react\";\nimport { useFrontendTool } from \"./use-frontend-tool\";\n\nexport function useHumanInTheLoop<\n  T extends Record<string, unknown> = Record<string, unknown>,\n>(tool: ReactHumanInTheLoop<T>, deps?: ReadonlyArray<unknown>) {\n  const { copilotkit } = useCopilotKit();\n  const resolvePromiseRef = useRef<((result: unknown) => void) | null>(null);\n\n  const respond = useCallback(async (result: unknown) => {\n    if (resolvePromiseRef.current) {\n      resolvePromiseRef.current(result);\n      resolvePromiseRef.current = null;\n    }\n  }, []);\n\n  const handler = useCallback(async () => {\n    return new Promise((resolve) => {\n      resolvePromiseRef.current = resolve;\n    });\n  }, []);\n\n  const RenderComponent: ReactToolCallRenderer<T>[\"render\"] = useCallback(\n    (props) => {\n      const ToolComponent = tool.render;\n\n      // Enhance props based on current status\n      if (props.status === \"inProgress\") {\n        const enhancedProps = {\n          ...props,\n          name: tool.name,\n          description: tool.description || \"\",\n          respond: undefined,\n        };\n        return React.createElement(ToolComponent, enhancedProps);\n      } else if (props.status === \"executing\") {\n        const enhancedProps = {\n          ...props,\n          name: tool.name,\n          description: tool.description || \"\",\n          respond,\n        };\n        return React.createElement(ToolComponent, enhancedProps);\n      } else if (props.status === \"complete\") {\n        const enhancedProps = {\n          ...props,\n          name: tool.name,\n          description: tool.description || \"\",\n          respond: undefined,\n        };\n        return React.createElement(ToolComponent, enhancedProps);\n      }\n\n      // Fallback - just render with original props\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      return React.createElement(ToolComponent, props as any);\n    },\n    [tool.render, tool.name, tool.description, respond],\n  );\n\n  const frontendTool: ReactFrontendTool<T> = {\n    ...tool,\n    handler,\n    render: RenderComponent,\n  };\n\n  useFrontendTool(frontendTool, deps);\n\n  // Human-in-the-loop tools should remove their renderer on unmount\n  // since they can't respond to user interactions anymore\n  useEffect(() => {\n    return () => {\n      copilotkit.removeHookRenderToolCall(tool.name, tool.agentId);\n    };\n  }, [copilotkit, tool.name, tool.agentId]);\n}\n","import React, {\n  useState,\n  useEffect,\n  useCallback,\n  useMemo,\n  useRef,\n} from \"react\";\nimport { useCopilotKit } from \"../context\";\nimport { useAgent } from \"./use-agent\";\nimport type {\n  InterruptEvent,\n  InterruptRenderProps,\n  InterruptHandlerProps,\n} from \"../types/interrupt\";\n\nexport type { InterruptEvent, InterruptRenderProps, InterruptHandlerProps };\n\nconst INTERRUPT_EVENT_NAME = \"on_interrupt\";\n\ntype InterruptHandlerFn<TValue, TResult> = (\n  props: InterruptHandlerProps<TValue>,\n) => TResult | PromiseLike<TResult>;\n\ntype InterruptResultFromHandler<THandler> = THandler extends (\n  ...args: never[]\n) => infer TResult\n  ? TResult extends PromiseLike<infer TResolved>\n    ? TResolved | null\n    : TResult | null\n  : null;\n\ntype InterruptResult<TValue, TResult> = InterruptResultFromHandler<\n  InterruptHandlerFn<TValue, TResult>\n>;\n\ntype InterruptRenderInChat = boolean | undefined;\n\ntype UseInterruptReturn<TRenderInChat extends InterruptRenderInChat> =\n  TRenderInChat extends false\n    ? React.ReactElement | null\n    : TRenderInChat extends true | undefined\n      ? void\n      : React.ReactElement | null | void;\n\nexport function isPromiseLike<TValue>(\n  value: TValue | PromiseLike<TValue>,\n): value is PromiseLike<TValue> {\n  return (\n    (typeof value === \"object\" || typeof value === \"function\") &&\n    value !== null &&\n    typeof Reflect.get(value, \"then\") === \"function\"\n  );\n}\n\n/**\n * Configuration options for `useInterrupt`.\n */\ninterface UseInterruptConfigBase<TValue = unknown, TResult = never> {\n  /**\n   * Render function for the interrupt UI.\n   *\n   * This is called once an interrupt is finalized and accepted by `enabled` (if provided).\n   * Use `resolve` from render props to resume the agent run with user input.\n   */\n  render: (\n    props: InterruptRenderProps<TValue, InterruptResult<TValue, TResult>>,\n  ) => React.ReactElement;\n  /**\n   * Optional pre-render handler invoked when an interrupt is received.\n   *\n   * Return either a sync value or an async value to pass into `render` as `result`.\n   * Rejecting/throwing falls back to `result = null`.\n   */\n  handler?: InterruptHandlerFn<TValue, TResult>;\n  /**\n   * Optional predicate to filter which interrupts should be handled by this hook.\n   * Return `false` to ignore an interrupt.\n   */\n  enabled?: (event: InterruptEvent<TValue>) => boolean;\n  /** Optional agent id. Defaults to the current configured chat agent. */\n  agentId?: string;\n}\n\nexport interface UseInterruptInChatConfig<\n  TValue = unknown,\n  TResult = never,\n> extends UseInterruptConfigBase<TValue, TResult> {\n  /** When true (default), the interrupt UI renders inside `<CopilotChat>` automatically. Set to false to render it yourself. */\n  renderInChat?: true;\n}\n\nexport interface UseInterruptExternalConfig<\n  TValue = unknown,\n  TResult = never,\n> extends UseInterruptConfigBase<TValue, TResult> {\n  /** When true (default), the interrupt UI renders inside `<CopilotChat>` automatically. Set to false to render it yourself. */\n  renderInChat: false;\n}\n\nexport interface UseInterruptDynamicConfig<\n  TValue = unknown,\n  TResult = never,\n> extends UseInterruptConfigBase<TValue, TResult> {\n  /** Dynamic boolean mode. When non-literal, return type is a union. */\n  renderInChat: boolean;\n}\n\nexport type UseInterruptConfig<\n  TValue = unknown,\n  TResult = never,\n  TRenderInChat extends InterruptRenderInChat = undefined,\n> = UseInterruptConfigBase<TValue, TResult> & {\n  /** When true (default), the interrupt UI renders inside `<CopilotChat>` automatically. Set to false to render it yourself. */\n  renderInChat?: TRenderInChat;\n};\n\n/**\n * Handles agent interrupts (`on_interrupt`) with optional filtering, preprocessing, and resume behavior.\n *\n * The hook listens to custom events on the active agent, stores interrupt payloads per run,\n * and surfaces a render callback once the run finalizes. Call `resolve` from your UI to resume\n * execution with user-provided data.\n *\n * - `renderInChat: true` (default): the element is published into `<CopilotChat>` and this hook returns `void`.\n * - `renderInChat: false`: the hook returns the interrupt element so you can place it anywhere in your component tree.\n *\n * `event.value` is typed as `any` since the interrupt payload shape depends on your agent.\n * Type-narrow it in your callbacks (e.g. `handler`, `enabled`, `render`) as needed.\n *\n * @typeParam TResult - Inferred from `handler` return type. Exposed as `result` in `render`.\n * @param config - Interrupt configuration (renderer, optional handler/filter, and render mode).\n * @returns When `renderInChat` is `false`, returns the interrupt element (or `null` when idle).\n * Otherwise returns `void` and publishes the element into chat. In `render`, `result` is always\n * either the handler's resolved return value or `null` (including when no handler is provided,\n * when filtering skips the interrupt, or when handler execution fails).\n *\n * @example\n * ```tsx\n * import { useInterrupt } from \"@copilotkit/react-core/v2\";\n *\n * function InterruptUI() {\n *   useInterrupt({\n *     render: ({ event, resolve }) => (\n *       <div>\n *         <p>{event.value.question}</p>\n *         <button onClick={() => resolve({ approved: true })}>Approve</button>\n *         <button onClick={() => resolve({ approved: false })}>Reject</button>\n *       </div>\n *     ),\n *   });\n *\n *   return null;\n * }\n * ```\n *\n * @example\n * ```tsx\n * import { useInterrupt } from \"@copilotkit/react-core/v2\";\n *\n * function CustomPanel() {\n *   const interruptElement = useInterrupt({\n *     renderInChat: false,\n *     enabled: (event) => event.value.startsWith(\"approval:\"),\n *     handler: async ({ event }) => ({ label: event.value.toUpperCase() }),\n *     render: ({ event, result, resolve }) => (\n *       <aside>\n *         <strong>{result?.label ?? \"\"}</strong>\n *         <button onClick={() => resolve({ value: event.value })}>Continue</button>\n *       </aside>\n *     ),\n *   });\n *\n *   return <>{interruptElement}</>;\n * }\n * ```\n */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport function useInterrupt<\n  TResult = never,\n  TRenderInChat extends InterruptRenderInChat = undefined,\n>(\n  config: UseInterruptConfig<any, TResult, TRenderInChat>,\n): UseInterruptReturn<TRenderInChat> {\n  /* eslint-enable @typescript-eslint/no-explicit-any */\n  const { copilotkit } = useCopilotKit();\n  const { agent } = useAgent({ agentId: config.agentId });\n  const [pendingEvent, setPendingEvent] = useState<InterruptEvent | null>(null);\n  const pendingEventRef = useRef(pendingEvent);\n  pendingEventRef.current = pendingEvent;\n  const [handlerResult, setHandlerResult] =\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    useState<InterruptResult<any, TResult>>(null);\n\n  useEffect(() => {\n    let localInterrupt: InterruptEvent | null = null;\n\n    const subscription = agent.subscribe({\n      onCustomEvent: ({ event }) => {\n        if (event.name === INTERRUPT_EVENT_NAME) {\n          localInterrupt = { name: event.name, value: event.value };\n        }\n      },\n      onRunStartedEvent: () => {\n        localInterrupt = null;\n        setPendingEvent(null);\n      },\n      onRunFinalized: () => {\n        if (localInterrupt) {\n          setPendingEvent(localInterrupt);\n          localInterrupt = null;\n        }\n      },\n      onRunFailed: () => {\n        localInterrupt = null;\n      },\n    });\n\n    return () => subscription.unsubscribe();\n  }, [agent]);\n\n  const resolve = useCallback(\n    (response: unknown) => {\n      // Do NOT synchronously clear pendingEvent here — onRunStartedEvent\n      // already clears it when the resume run begins. Clearing synchronously\n      // unmounts the card before commit, which previously forced consumers\n      // to wrap their resolve() in a 500ms setTimeout to keep the UI alive.\n      copilotkit.runAgent({\n        agent,\n        forwardedProps: {\n          command: {\n            resume: response,\n            interruptEvent: pendingEventRef.current?.value,\n          },\n        },\n      });\n    },\n    [agent, copilotkit],\n  );\n\n  // Stabilize consumer-supplied callbacks behind refs so inline lambdas\n  // (a new identity every parent render) do NOT churn the element memo\n  // identity or the handler effect. Without this, every dep-churn cycle\n  // would re-run the publish effect's cleanup, racing a stale `null` past\n  // the new element and unmounting the in-chat card on each render.\n  const renderRef = useRef(config.render);\n  renderRef.current = config.render;\n  const enabledRef = useRef(config.enabled);\n  enabledRef.current = config.enabled;\n  const handlerRef = useRef(config.handler);\n  handlerRef.current = config.handler;\n  // F4: mirror `resolve` behind a ref so the handler effect does not depend\n  // on resolve's identity. Without this, churn in [agent, copilotkit]\n  // (resolve's deps) would re-run the effect for the same pendingEvent and\n  // double-invoke the consumer handler.\n  const resolveRef = useRef(resolve);\n  resolveRef.current = resolve;\n\n  // F5: predicate evaluator that treats a throw as \"disabled\" (false) and\n  // logs the error. Called from both the handler effect and the element\n  // memo, neither of which may crash the React tree on a consumer bug.\n  const isEnabled = (event: InterruptEvent): boolean => {\n    const predicate = enabledRef.current;\n    if (!predicate) return true;\n    try {\n      return predicate(event);\n    } catch (err) {\n      console.error(\n        \"[CopilotKit] useInterrupt enabled predicate threw; treating interrupt as disabled:\",\n        err,\n      );\n      return false;\n    }\n  };\n\n  useEffect(() => {\n    // No interrupt to process — reset any stale handler result from a previous interrupt\n    if (!pendingEvent) {\n      setHandlerResult(null);\n      return;\n    }\n    // Interrupt exists but the consumer's filter rejects it — treat as no-op.\n    // F5: a throw from the predicate is treated as \"disabled\".\n    if (!isEnabled(pendingEvent)) {\n      setHandlerResult(null);\n      return;\n    }\n    const handler = handlerRef.current;\n    // No handler provided — skip straight to rendering with a null result\n    if (!handler) {\n      setHandlerResult(null);\n      return;\n    }\n\n    let cancelled = false;\n    // F3: a synchronous throw from the consumer handler must not escape the\n    // effect. Honor the documented contract (\"Rejecting/throwing falls back\n    // to `result = null`\") at the sync branch too.\n    let maybePromise: ReturnType<typeof handler>;\n    try {\n      maybePromise = handler({\n        event: pendingEvent,\n        resolve: resolveRef.current,\n      });\n    } catch (err) {\n      console.error(\n        \"[CopilotKit] useInterrupt handler threw; result will be null:\",\n        err,\n      );\n      if (!cancelled) setHandlerResult(null);\n      return () => {\n        cancelled = true;\n      };\n    }\n\n    // If the handler returns a promise/thenable, wait for resolution before setting result.\n    if (isPromiseLike(maybePromise)) {\n      Promise.resolve(maybePromise)\n        .then((resolved) => {\n          if (!cancelled) setHandlerResult(resolved);\n        })\n        .catch((err) => {\n          // F3 (companion): log the async failure so it isn't silently\n          // swallowed, while preserving the documented null-fallback.\n          console.error(\n            \"[CopilotKit] useInterrupt handler rejected; result will be null:\",\n            err,\n          );\n          if (!cancelled) setHandlerResult(null);\n        });\n    } else {\n      setHandlerResult(maybePromise);\n    }\n\n    return () => {\n      cancelled = true;\n    };\n    // F4: depend ONLY on pendingEvent. resolve is read via resolveRef so\n    // identity churn in [agent, copilotkit] cannot double-fire the handler.\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [pendingEvent]);\n\n  const element = useMemo(() => {\n    if (!pendingEvent) return null;\n    // F5: throwing predicate → disabled.\n    if (!isEnabled(pendingEvent)) return null;\n\n    return renderRef.current({\n      event: pendingEvent,\n      result: handlerResult,\n      resolve,\n    });\n  }, [pendingEvent, handlerResult, resolve]);\n\n  // Publish to core for in-chat rendering. Publish-only — do NOT nullify\n  // on dep churn; the element memo already returns null when pendingEvent\n  // is null (the legitimate clear path: onRunStartedEvent / onRunFailed).\n  useEffect(() => {\n    if (config.renderInChat === false) return;\n    copilotkit.setInterruptElement(element);\n  }, [element, config.renderInChat, copilotkit]);\n\n  // Nullify on true unmount only. Separate effect with empty deps so the\n  // cleanup runs exactly once when the component is removed from the tree.\n  useEffect(() => {\n    if (config.renderInChat === false) return;\n    return () => {\n      copilotkit.setInterruptElement(null);\n    };\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, []);\n\n  // Only return element when rendering outside chat\n  if (config.renderInChat === false) {\n    return element as UseInterruptReturn<TRenderInChat>;\n  }\n\n  return undefined as UseInterruptReturn<TRenderInChat>;\n}\n","import { 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  type ɵThreadRuntimeContext,\n  type ɵThreadStore,\n} from \"@copilotkit/core\";\nimport {\n  useCallback,\n  useEffect,\n  useMemo,\n  useState,\n  useSyncExternalStore,\n} from \"react\";\n\n/**\n * A conversation thread managed by the Intelligence platform.\n *\n * Each thread has a unique `id`, an optional human-readable `name`, and\n * timestamp fields tracking creation and update times.\n */\nexport interface Thread {\n  id: string;\n  agentId: string;\n  name: string | null;\n  archived: boolean;\n  createdAt: string;\n  updatedAt: string;\n  /**\n   * ISO-8601 timestamp of the most recent agent run on this thread. Absent\n   * when the thread has never been run. Prefer this over `updatedAt` for\n   * user-facing \"last activity\" displays — it is not bumped by metadata-only\n   * actions like rename or archive.\n   */\n  lastRunAt?: string;\n}\n\n/**\n * Configuration for the {@link useThreads} hook.\n *\n * Thread operations are scoped to the runtime-authenticated user and the\n * provided agent on the Intelligence platform.\n */\nexport interface UseThreadsInput {\n  /** The ID of the agent whose threads to list and manage. */\n  agentId: string;\n  /** When `true`, archived threads are included in the list. Defaults to `false`. */\n  includeArchived?: boolean;\n  /** Maximum number of threads to fetch per page. When set, enables cursor-based pagination. */\n  limit?: number;\n}\n\n/**\n * Return value of the {@link useThreads} hook.\n *\n * The `threads` array is kept in sync with the platform via a realtime\n * WebSocket subscription (when available) and is sorted most-recently-updated\n * first. Mutations reject with an `Error` if the platform request fails.\n */\nexport interface UseThreadsResult {\n  /**\n   * Threads for the current user/agent pair, sorted by most recently\n   * updated first. Updated in realtime when the platform pushes metadata\n   * events. Includes archived threads only when `includeArchived` is set.\n   */\n  threads: Thread[];\n  /**\n   * `true` while the initial thread list is being fetched from the platform.\n   * Subsequent realtime updates do not re-enter the loading state.\n   */\n  isLoading: boolean;\n  /**\n   * The most recent error from fetching threads or executing a mutation,\n   * or `null` when there is no error. Reset to `null` on the next\n   * successful fetch.\n   */\n  error: Error | null;\n  /**\n   * `true` when there are more threads available to fetch via\n   * {@link fetchMoreThreads}. Only meaningful when `limit` is set.\n   */\n  hasMoreThreads: boolean;\n  /**\n   * `true` while a subsequent page of threads is being fetched.\n   */\n  isFetchingMoreThreads: boolean;\n  /**\n   * Fetch the next page of threads. No-op when {@link hasMoreThreads} is\n   * `false` or a fetch is already in progress.\n   */\n  fetchMoreThreads: () => void;\n  /**\n   * Rename a thread on the platform.\n   * Resolves when the server confirms the update; rejects on failure.\n   */\n  renameThread: (threadId: string, name: string) => Promise<void>;\n  /**\n   * Archive a thread on the platform.\n   * Archived threads are excluded from subsequent list results.\n   * Resolves when the server confirms the update; rejects on failure.\n   */\n  archiveThread: (threadId: string) => Promise<void>;\n  /**\n   * Permanently delete a thread from the platform.\n   * This is irreversible. Resolves when the server confirms deletion;\n   * rejects on failure.\n   */\n  deleteThread: (threadId: string) => Promise<void>;\n}\n\nfunction useThreadStoreSelector<T>(\n  store: ɵThreadStore,\n  selector: (state: ReturnType<ɵThreadStore[\"getState\"]>) => T,\n): T {\n  return useSyncExternalStore(\n    useCallback(\n      (onStoreChange) => {\n        const subscription = store.select(selector).subscribe(onStoreChange);\n        return () => subscription.unsubscribe();\n      },\n      [store, selector],\n    ),\n    () => selector(store.getState()),\n  );\n}\n\n/**\n * React hook for listing and managing Intelligence platform threads.\n *\n * On mount the hook fetches the thread list for the runtime-authenticated user\n * and the given `agentId`. When the Intelligence platform exposes a WebSocket\n * URL, it also opens a realtime subscription so the `threads` array stays\n * current without polling — thread creates, renames, archives, and deletes\n * from any client are reflected immediately.\n *\n * Mutation methods (`renameThread`, `archiveThread`, `deleteThread`) return\n * promises that resolve once the platform confirms the operation and reject\n * with an `Error` on failure.\n *\n * @param input - Agent identifier and optional list controls.\n * @returns Thread list state and stable mutation callbacks.\n *\n * @example\n * ```tsx\n * import { useThreads } from \"@copilotkit/react-core\";\n *\n * function ThreadList() {\n *   const { threads, isLoading, renameThread, deleteThread } = useThreads({\n *     agentId: \"agent-1\",\n *   });\n *\n *   if (isLoading) return <p>Loading…</p>;\n *\n *   return (\n *     <ul>\n *       {threads.map((t) => (\n *         <li key={t.id}>\n *           {t.name ?? \"Untitled\"}\n *           <button onClick={() => renameThread(t.id, \"New name\")}>Rename</button>\n *           <button onClick={() => deleteThread(t.id)}>Delete</button>\n *         </li>\n *       ))}\n *     </ul>\n *   );\n * }\n * ```\n */\nexport function useThreads({\n  agentId,\n  includeArchived,\n  limit,\n}: UseThreadsInput): UseThreadsResult {\n  const { copilotkit } = useCopilotKit();\n\n  const [store] = useState(() =>\n    ɵcreateThreadStore({\n      fetch: globalThis.fetch,\n    }),\n  );\n\n  const coreThreads = useThreadStoreSelector(store, ɵselectThreads);\n  const threads: Thread[] = useMemo(\n    () =>\n      coreThreads.map(\n        ({ id, agentId, name, archived, createdAt, updatedAt, lastRunAt }) => ({\n          id,\n          agentId,\n          name,\n          archived,\n          createdAt,\n          updatedAt,\n          ...(lastRunAt !== undefined ? { lastRunAt } : {}),\n        }),\n      ),\n    [coreThreads],\n  );\n  const storeIsLoading = useThreadStoreSelector(store, ɵselectThreadsIsLoading);\n  const storeError = useThreadStoreSelector(store, ɵselectThreadsError);\n  const hasMoreThreads = useThreadStoreSelector(store, ɵselectHasNextPage);\n  const isFetchingMoreThreads = useThreadStoreSelector(\n    store,\n    ɵselectIsFetchingNextPage,\n  );\n  const headersKey = useMemo(() => {\n    return JSON.stringify(\n      Object.entries(copilotkit.headers ?? {}).sort(([left], [right]) =>\n        left.localeCompare(right),\n      ),\n    );\n  }, [copilotkit.headers]);\n  const runtimeError = useMemo(() => {\n    if (copilotkit.runtimeUrl) {\n      return null;\n    }\n\n    return new Error(\"Runtime URL is not configured\");\n  }, [copilotkit.runtimeUrl]);\n\n  // Tracks whether we've dispatched the first real context to the store.\n  // The store itself starts with `isLoading: false`, so before we dispatch\n  // consumers would otherwise see an empty, non-loading state (empty-list\n  // flash). While runtimeUrl is set and we haven't dispatched yet, we\n  // synthesize `isLoading: true` so the UI keeps its loading indicator until\n  // the first fetch is in flight (at which point the store's own\n  // isLoading takes over).\n  const [hasDispatchedContext, setHasDispatchedContext] = useState(false);\n  const preConnectLoading = !!copilotkit.runtimeUrl && !hasDispatchedContext;\n\n  const isLoading = runtimeError ? false : preConnectLoading || storeIsLoading;\n  const error = runtimeError ?? storeError;\n\n  useEffect(() => {\n    store.start();\n    return () => {\n      store.stop();\n    };\n  }, [store]);\n\n  // Defer setting the context until the runtime reports Connected. Before\n  // `/info` resolves we don't know `intelligence.wsUrl`, so dispatching the\n  // context early would issue a list fetch with `wsUrl: undefined`, then a\n  // second list fetch (and a `/threads/subscribe`) once the flag lands.\n  // Waiting lets the hook issue just one `/threads?…` + one `/threads/subscribe`.\n  //\n  // When `runtimeUrl` is absent we dispatch `null` to clear the store. For\n  // transient states (Disconnected/Connecting/Error with a URL still set) we\n  // leave the previously-dispatched context in place — any in-flight\n  // realtime subscription or cached thread list stays usable while the\n  // runtime recovers, and we don't re-trigger a fetch storm on transitions.\n  const runtimeStatus = copilotkit.runtimeConnectionStatus;\n  useEffect(() => {\n    copilotkit.registerThreadStore(agentId, store);\n    return () => {\n      copilotkit.unregisterThreadStore(agentId);\n    };\n  }, [copilotkit, agentId, store]);\n\n  useEffect(() => {\n    if (!copilotkit.runtimeUrl) {\n      store.setContext(null);\n      return;\n    }\n\n    // Wait for /info to land so we can include `wsUrl` in the initial\n    // context and avoid a redundant second list fetch.\n    if (runtimeStatus !== CopilotKitCoreRuntimeConnectionStatus.Connected) {\n      return;\n    }\n\n    const context: ɵThreadRuntimeContext = {\n      runtimeUrl: copilotkit.runtimeUrl,\n      headers: { ...copilotkit.headers },\n      wsUrl: copilotkit.intelligence?.wsUrl,\n      agentId,\n      includeArchived,\n      limit,\n    };\n\n    store.setContext(context);\n    setHasDispatchedContext(true);\n  }, [\n    store,\n    copilotkit.runtimeUrl,\n    runtimeStatus,\n    headersKey,\n    copilotkit.intelligence?.wsUrl,\n    agentId,\n    includeArchived,\n    limit,\n  ]);\n\n  const renameThread = useCallback(\n    (threadId: string, name: string) => store.renameThread(threadId, name),\n    [store],\n  );\n\n  const archiveThread = useCallback(\n    (threadId: string) => store.archiveThread(threadId),\n    [store],\n  );\n\n  const deleteThread = useCallback(\n    (threadId: string) => store.deleteThread(threadId),\n    [store],\n  );\n\n  const fetchMoreThreads = useCallback(() => store.fetchNextPage(), [store]);\n\n  return {\n    threads,\n    isLoading,\n    error,\n    hasMoreThreads,\n    isFetchingMoreThreads,\n    fetchMoreThreads,\n    renameThread,\n    archiveThread,\n    deleteThread,\n  };\n}\n","import React from \"react\";\nimport { z } from \"zod\";\nimport type { StandardSchemaV1, InferSchemaOutput } from \"@copilotkit/shared\";\nimport { ReactToolCallRenderer } from \"./react-tool-call-renderer\";\nimport { ToolCallStatus } from \"@copilotkit/core\";\n\n/**\n * Helper to define a type-safe tool call renderer entry.\n * - Accepts a single object whose keys match ReactToolCallRenderer's fields: { name, args, render, agentId? }.\n * - Derives `args` type from the provided schema (any Standard Schema V1 compatible library).\n * - Ensures the render function param type exactly matches ReactToolCallRenderer<T>[\"render\"]'s param.\n * - For wildcard tools (name: \"*\"), args is optional and defaults to z.any()\n */\ntype RenderProps<T> =\n  | {\n      name: string;\n      toolCallId: string;\n      args: Partial<T>;\n      status: ToolCallStatus.InProgress;\n      result: undefined;\n    }\n  | {\n      name: string;\n      toolCallId: string;\n      args: T;\n      status: ToolCallStatus.Executing;\n      result: undefined;\n    }\n  | {\n      name: string;\n      toolCallId: string;\n      args: T;\n      status: ToolCallStatus.Complete;\n      result: string;\n    };\n\n// Overload for wildcard tools without args\nexport function defineToolCallRenderer(def: {\n  name: \"*\";\n  render: (props: RenderProps<any>) => React.ReactElement;\n  agentId?: string;\n}): ReactToolCallRenderer<any>;\n\n// Overload for regular tools with args\nexport function defineToolCallRenderer<S extends StandardSchemaV1>(def: {\n  name: string;\n  args: S;\n  render: (props: RenderProps<InferSchemaOutput<S>>) => React.ReactElement;\n  agentId?: string;\n}): ReactToolCallRenderer<InferSchemaOutput<S>>;\n\n// Implementation\nexport function defineToolCallRenderer<S extends StandardSchemaV1>(def: {\n  name: string;\n  args?: S;\n  render: (props: any) => React.ReactElement;\n  agentId?: string;\n}): ReactToolCallRenderer<any> {\n  // For wildcard tools, default to z.any() if no args provided\n  const argsSchema = def.name === \"*\" && !def.args ? z.any() : def.args;\n\n  return {\n    name: def.name,\n    args: argsSchema,\n    render: def.render as React.ComponentType<any>,\n    ...(def.agentId ? { agentId: def.agentId } : {}),\n  };\n}\n","import { useEffect } from \"react\";\nimport type { StandardSchemaV1, InferSchemaOutput } from \"@copilotkit/shared\";\nimport { useCopilotKit } from \"../context\";\nimport { defineToolCallRenderer } from \"../types/defineToolCallRenderer\";\n\nconst EMPTY_DEPS: ReadonlyArray<unknown> = [];\n\nexport interface RenderToolInProgressProps<S extends StandardSchemaV1> {\n  name: string;\n  toolCallId: string;\n  parameters: Partial<InferSchemaOutput<S>>;\n  status: \"inProgress\";\n  result: undefined;\n}\n\nexport interface RenderToolExecutingProps<S extends StandardSchemaV1> {\n  name: string;\n  toolCallId: string;\n  parameters: InferSchemaOutput<S>;\n  status: \"executing\";\n  result: undefined;\n}\n\nexport interface RenderToolCompleteProps<S extends StandardSchemaV1> {\n  name: string;\n  toolCallId: string;\n  parameters: InferSchemaOutput<S>;\n  status: \"complete\";\n  result: string;\n}\n\nexport type RenderToolProps<S extends StandardSchemaV1> =\n  | RenderToolInProgressProps<S>\n  | RenderToolExecutingProps<S>\n  | RenderToolCompleteProps<S>;\n\ntype RenderToolConfig<S extends StandardSchemaV1> = {\n  name: string;\n  parameters?: S;\n  render: (props: RenderToolProps<S>) => React.ReactElement;\n  agentId?: string;\n};\n\n/**\n * Registers a wildcard (`\"*\"`) renderer for tool calls.\n *\n * The wildcard renderer is used as a fallback when no exact name-matched\n * renderer is registered for a tool call.\n *\n * @param config - Wildcard renderer configuration.\n * @param deps - Optional dependencies to refresh registration.\n *\n * @example\n * ```tsx\n * useRenderTool(\n *   {\n *     name: \"*\",\n *     render: ({ name, status }) => (\n *       <div>\n *         {status === \"complete\" ? \"✓\" : \"⏳\"} {name}\n *       </div>\n *     ),\n *   },\n *   [],\n * );\n * ```\n */\nexport function useRenderTool(\n  config: {\n    name: \"*\";\n    render: (props: any) => React.ReactElement;\n    agentId?: string;\n  },\n  deps?: ReadonlyArray<unknown>,\n): void;\n\n/**\n * Registers a name-scoped renderer for tool calls.\n *\n * The provided `parameters` schema defines the typed shape of `props.parameters`\n * in `render` for `executing` and `complete` states. Accepts any Standard Schema V1\n * compatible library (Zod, Valibot, ArkType, etc.).\n *\n * @typeParam S - Schema type describing tool call parameters.\n * @param config - Named renderer configuration.\n * @param deps - Optional dependencies to refresh registration.\n *\n * @example\n * ```tsx\n * useRenderTool(\n *   {\n *     name: \"searchDocs\",\n *     parameters: z.object({ query: z.string() }),\n *     render: ({ status, parameters, result }) => {\n *       if (status === \"inProgress\") return <div>Preparing...</div>;\n *       if (status === \"executing\") return <div>Searching {parameters.query}</div>;\n *       return <div>{result}</div>;\n *     },\n *   },\n *   [],\n * );\n * ```\n */\nexport function useRenderTool<S extends StandardSchemaV1>(\n  config: {\n    name: string;\n    parameters: S;\n    render: (props: RenderToolProps<S>) => React.ReactElement;\n    agentId?: string;\n  },\n  deps?: ReadonlyArray<unknown>,\n): void;\n\n/**\n * Registers a renderer entry in CopilotKit's `renderToolCalls` registry.\n *\n * Key behavior:\n * - deduplicates by `agentId:name` (latest registration wins),\n * - keeps renderer entries on cleanup so historical chat tool calls can still render,\n * - refreshes registration when `deps` change.\n *\n * @typeParam S - Schema type describing tool call parameters.\n * @param config - Renderer config for wildcard or named tools.\n * @param deps - Optional dependencies to refresh registration.\n *\n * @example\n * ```tsx\n * useRenderTool(\n *   {\n *     name: \"searchDocs\",\n *     parameters: z.object({ query: z.string() }),\n *     render: ({ status, parameters, result }) => {\n *       if (status === \"executing\") return <div>Searching {parameters.query}</div>;\n *       if (status === \"complete\") return <div>{result}</div>;\n *       return <div>Preparing...</div>;\n *     },\n *   },\n *   [],\n * );\n * ```\n *\n * @example\n * ```tsx\n * useRenderTool(\n *   {\n *     name: \"summarize\",\n *     parameters: z.object({ text: z.string() }),\n *     agentId: \"research-agent\",\n *     render: ({ name, status }) => <div>{name}: {status}</div>,\n *   },\n *   [selectedAgentId],\n * );\n * ```\n */\nexport function useRenderTool<S extends StandardSchemaV1>(\n  config: RenderToolConfig<S>,\n  deps?: ReadonlyArray<unknown>,\n): void {\n  const { copilotkit } = useCopilotKit();\n  const extraDeps = deps ?? EMPTY_DEPS;\n\n  useEffect(() => {\n    // Build the ReactToolCallRenderer via defineToolCallRenderer\n    const renderer =\n      config.name === \"*\" && !config.parameters\n        ? defineToolCallRenderer({\n            name: \"*\",\n            render: (props) =>\n              config.render({ ...props, parameters: props.args }),\n            ...(config.agentId ? { agentId: config.agentId } : {}),\n          })\n        : defineToolCallRenderer({\n            name: config.name,\n            args: config.parameters!,\n            render: (props) =>\n              config.render({ ...props, parameters: props.args }),\n            ...(config.agentId ? { agentId: config.agentId } : {}),\n          });\n\n    copilotkit.addHookRenderToolCall(renderer);\n\n    // No cleanup removal — keeps renderer for chat history, same as useFrontendTool\n  }, [config.name, copilotkit, JSON.stringify(extraDeps)]);\n}\n","import 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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"}