showcase/shell-docs/src/content/docs/integrations/mastra/human-in-the-loop/interrupt-flow.mdx
For working Human-in-the-Loop functionality with Mastra, use the tool-based approach with useHumanInTheLoop instead.
</Callout>
Some frameworks (like LangGraph) provide native interrupt capabilities where tools can pause their own execution mid-stream via an interrupt() or suspend() call, emit an AG-UI interrupt event to the frontend, and wait for the user's response before resuming. CopilotKit's useInterrupt hook captures these events and renders custom UI.
Mastra does not emit AG-UI interrupt events. While Mastra has a suspend() API for tool approval workflows, it operates within Mastra's own execution model and does not integrate with CopilotKit's interrupt handling via the AG-UI protocol. Any useInterrupt hook in a Mastra application will listen for events that never arrive, leaving the UI stuck on tool-call placeholders.
Use the tool-based approach with useHumanInTheLoop. This is the supported and working pattern for Mastra:
Define a frontend tool that renders UI and waits for the user's response:
import { useHumanInTheLoop } from "@copilotkit/react-core/v2";
import { z } from "zod";
function YourMainContent() {
useHumanInTheLoop({
agentId: "my-agent",
name: "confirm_action",
description: "Ask the user to confirm before performing a critical action",
parameters: z.object({
action: z.string().describe("Description of the action to confirm"),
}),
render: ({ args, respond }) => {
if (!respond) return null;
return (
<div>
<p>{args.action}</p>
<button onClick={() => respond({ confirmed: true })}>
Approve
</button>
<button onClick={() => respond({ confirmed: false })}>
Reject
</button>
</div>
);
},
});
return <div></div>;
}
Mastra natively supports the AG-UI protocol. When your agent calls the confirm_action tool (defined on the frontend), CopilotKit automatically routes the call to your useHumanInTheLoop handler, renders the UI, and waits for the user's response.
No backend tool definition is needed—the frontend tool registration is sufficient. </Step>
<Step> ### Give it a tryAsk your agent something that requires confirmation:
Can you delete all inactive user accounts?
The agent will call the confirm_action tool, render your approval UI, and wait for the user's response before continuing.
</Step>
</Steps>
For a complete implementation, see the tool-based Human-in-the-Loop guide, which includes:
| Feature | Interrupts (LangGraph) | Tool-based (Mastra) |
|---|---|---|
| Backend support | ✅ Native interrupt() | ❌ No interrupt events |
| Frontend hook | useInterrupt | useHumanInTheLoop |
| Execution model | Tool pauses mid-execution | Agent calls frontend tool |
| When to use | LangGraph, frameworks with native interrupt support | Mastra, frameworks without interrupt primitives |
| Works with Mastra? | ❌ No | ✅ Yes |
Ready to implement HITL with Mastra? Head to the tool-based approach guide for working examples and best practices.