const require_runtime = require('../_virtual/_rolldown/runtime.cjs'); const require_CopilotKitProvider = require('../providers/CopilotKitProvider.cjs'); const require_use_agent = require('./use-agent.cjs'); let react = require("react"); //#region src/hooks/use-interrupt.tsx const INTERRUPT_EVENT_NAME = "on_interrupt"; function isPromiseLike(value) { return (typeof value === "object" || typeof value === "function") && value !== null && typeof Reflect.get(value, "then") === "function"; } /** * Handles agent interrupts (`on_interrupt`) with optional filtering, preprocessing, and resume behavior. * * The hook listens to custom events on the active agent, stores interrupt payloads per run, * and surfaces a render callback once the run finalizes. Call `resolve` from your UI to resume * execution with user-provided data. * * - `renderInChat: true` (default): the element is published into `` and this hook returns `void`. * - `renderInChat: false`: the hook returns the interrupt element so you can place it anywhere in your component tree. * * `event.value` is typed as `any` since the interrupt payload shape depends on your agent. * Type-narrow it in your callbacks (e.g. `handler`, `enabled`, `render`) as needed. * * @typeParam TResult - Inferred from `handler` return type. Exposed as `result` in `render`. * @param config - Interrupt configuration (renderer, optional handler/filter, and render mode). * @returns When `renderInChat` is `false`, returns the interrupt element (or `null` when idle). * Otherwise returns `void` and publishes the element into chat. In `render`, `result` is always * either the handler's resolved return value or `null` (including when no handler is provided, * when filtering skips the interrupt, or when handler execution fails). * * @example * ```tsx * import { useInterrupt } from "@copilotkitnext/react"; * * function InterruptUI() { * useInterrupt({ * render: ({ event, resolve }) => ( *
*

{event.value.question}

* * *
* ), * }); * * return null; * } * ``` * * @example * ```tsx * import { useInterrupt } from "@copilotkitnext/react"; * * function CustomPanel() { * const interruptElement = useInterrupt({ * renderInChat: false, * enabled: (event) => event.value.startsWith("approval:"), * handler: async ({ event }) => ({ label: event.value.toUpperCase() }), * render: ({ event, result, resolve }) => ( * * ), * }); * * return <>{interruptElement}; * } * ``` */ function useInterrupt(config) { const { copilotkit } = require_CopilotKitProvider.useCopilotKit(); const { agent } = require_use_agent.useAgent({ agentId: config.agentId }); const [pendingEvent, setPendingEvent] = (0, react.useState)(null); const [handlerResult, setHandlerResult] = (0, react.useState)(null); (0, react.useEffect)(() => { let localInterrupt = null; const subscription = agent.subscribe({ onCustomEvent: ({ event }) => { if (event.name === INTERRUPT_EVENT_NAME) localInterrupt = { name: event.name, value: event.value }; }, onRunStartedEvent: () => { localInterrupt = null; setPendingEvent(null); }, onRunFinalized: () => { if (localInterrupt) { setPendingEvent(localInterrupt); localInterrupt = null; } }, onRunFailed: () => { localInterrupt = null; } }); return () => subscription.unsubscribe(); }, [agent]); const resolve = (0, react.useCallback)((response) => { setPendingEvent(null); copilotkit.runAgent({ agent, forwardedProps: { command: { resume: response } } }); }, [agent, copilotkit]); (0, react.useEffect)(() => { if (!pendingEvent) { setHandlerResult(null); return; } if (config.enabled && !config.enabled(pendingEvent)) { setHandlerResult(null); return; } const handler = config.handler; if (!handler) { setHandlerResult(null); return; } let cancelled = false; const maybePromise = handler({ event: pendingEvent, resolve }); if (isPromiseLike(maybePromise)) Promise.resolve(maybePromise).then((resolved) => { if (!cancelled) setHandlerResult(resolved); }).catch(() => { if (!cancelled) setHandlerResult(null); }); else setHandlerResult(maybePromise); return () => { cancelled = true; }; }, [ pendingEvent, config.enabled, config.handler, resolve ]); const element = (0, react.useMemo)(() => { if (!pendingEvent) return null; if (config.enabled && !config.enabled(pendingEvent)) return null; return config.render({ event: pendingEvent, result: handlerResult, resolve }); }, [ pendingEvent, handlerResult, config.enabled, config.render, resolve ]); (0, react.useEffect)(() => { if (config.renderInChat === false) return; copilotkit.setInterruptElement(element); return () => copilotkit.setInterruptElement(null); }, [ element, config.renderInChat, copilotkit ]); if (config.renderInChat === false) return element; } //#endregion exports.useInterrupt = useInterrupt; //# sourceMappingURL=use-interrupt.cjs.map