useInterrupt
React hook for handling agent interrupt events and resuming execution with user input
Overview
useInterrupt listens for agent custom events named on_interrupt, captures the latest interrupt payload for a run, and renders interrupt UI once the run finalizes. Your UI can call resolve(response) to resume the agent with a resume payload.
Re-exported from @copilotkit/react-core/v2. It is identical to the React (V2) useInterrupt; only the import path differs.
By default, interrupt UI is rendered inside CopilotChat automatically. If you set renderInChat: false, the hook returns the element so you can place it manually. The element returned by render is a React Native element.
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.
Signature
import { useInterrupt } from "@copilotkit/react-native";
function useInterrupt<
TResult = never,
TRenderInChat extends boolean | undefined = undefined,
>(
config: UseInterruptConfig<any, TResult, TRenderInChat>,
): TRenderInChat extends false
? React.ReactElement | null
: TRenderInChat extends true | undefined
? void
: React.ReactElement | null | void;Parameters
Prop
Type
Return Value
Prop
Type
Usage
In-chat interrupt UI (default)
import { Text, TouchableOpacity, View } from "react-native";
import { useInterrupt } from "@copilotkit/react-native";
function ApprovalInterrupt() {
useInterrupt({
render: ({ event, resolve }) => (
<View style={{ padding: 12, borderWidth: 1, borderRadius: 8 }}>
<Text>{event.value.question}</Text>
<View style={{ marginTop: 8, flexDirection: "row", gap: 8 }}>
<TouchableOpacity onPress={() => resolve({ approved: true })}>
<Text>Approve</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => resolve({ approved: false })}>
<Text>Reject</Text>
</TouchableOpacity>
</View>
</View>
),
});
return null;
}Manual placement with async preprocessing
import { Text, TouchableOpacity, View } from "react-native";
import { useInterrupt } from "@copilotkit/react-native";
function SidePanelInterrupt() {
const element = useInterrupt({
renderInChat: false,
enabled: (event) => event.value.startsWith("approval:"),
handler: async ({ event }) => ({ label: event.value.toUpperCase() }),
render: ({ event, result, resolve }) => (
<View style={{ borderWidth: 1, borderRadius: 8, padding: 12 }}>
<Text style={{ fontWeight: "500" }}>{result?.label ?? ""}</Text>
<Text style={{ marginTop: 8 }}>{event.value}</Text>
<TouchableOpacity style={{ marginTop: 8 }} onPress={() => resolve({ accepted: true })}>
<Text>Continue</Text>
</TouchableOpacity>
</View>
),
});
return <>{element}</>;
}Behavior
- Interrupts are collected from agent custom events named
on_interrupt. - Interrupt UI is surfaced when the run finalizes.
- Starting a new run clears pending interrupt state.
event.valueisany; type-narrow in your callbacks as needed.render.resultis inferred fromhandlerreturn type and is alwaysTResult | null.- If
handlerthrows or rejects,resultis set tonull.
Related
useHumanInTheLoop: structured interactive tool workflowsuseFrontendTool: client-side tool registrationuseAgent: access and subscribe to agent events- React (V2) reference