Back to Copilotkit

Interrupts (Not Supported)

showcase/shell-docs/src/content/docs/integrations/mastra/human-in-the-loop/interrupt-flow.mdx

1.63.24.0 KB
Original Source
<Callout type="warning"> **Mastra does not support native interrupt flow.** The framework lacks LangGraph-style `interrupt()` primitives that pause execution mid-tool and emit AG-UI interrupt events. This page documents the interrupt pattern for reference, but it **will not work** with Mastra.

For working Human-in-the-Loop functionality with Mastra, use the tool-based approach with useHumanInTheLoop instead. </Callout>

What are interrupts?

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.

Why doesn't Mastra support this?

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.

What should I use instead?

Use the tool-based approach with useHumanInTheLoop. This is the supported and working pattern for Mastra:

<Steps> <Step> ### Register a frontend tool

Define a frontend tool that renders UI and waits for the user's response:

tsx
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>;
}
</Step> <Step> ### Agent automatically uses the tool

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 try

Ask 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>

Full working example

For a complete implementation, see the tool-based Human-in-the-Loop guide, which includes:

  • Multiple frontend tools with different UI patterns
  • Parameter validation with Zod schemas
  • Error handling and loading states
  • Production-ready examples

Comparison: Interrupts vs. Tool-based

FeatureInterrupts (LangGraph)Tool-based (Mastra)
Backend support✅ Native interrupt()❌ No interrupt events
Frontend hookuseInterruptuseHumanInTheLoop
Execution modelTool pauses mid-executionAgent calls frontend tool
When to useLangGraph, frameworks with native interrupt supportMastra, 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.