Headless Interrupts
Resolve agent interrupts from any UI, without a chat interrupt slot.
Open your coding agent in your project's folder, or in an empty folder for a new app.This runs in a coding agent on your computer.
What is this?#
The #interrupt slot is the 80% path: it keeps the UI attached to a <CopilotChat> transcript and handles when to show the picker. This page covers the escape hatch: set renderInChat: false and render the reactive interrupt state anywhere in your Vue tree. The UI can take any shape — button grid, form, modal, keyboard shortcut — and no chat needs to be mounted.
When should I use this?#
- Testing / Playwright fixtures — a deterministic, chat-less button grid is easier to drive than a picker that appears after an LLM call.
- Non-chat UIs — dashboards, side panels, inspector surfaces, or any place where you want the agent's interrupt without the transcript.
- Custom flow control — when you need to know exactly when the interrupt arrived and when it was resolved.
- Research / debugging — when you want to observe raw interrupt state without the chat abstraction.
If you just want a picker in chat, use useInterrupt with the default renderInChat: true and the #interrupt slot.
Provider setup#
The component calling these composables must be below CopilotKitProvider:
<script setup lang="ts">
import { CopilotKitProvider } from "@copilotkit/vue/v2";
import HeadlessInterruptPanel from "./components/HeadlessInterruptPanel.vue";
</script>
<template>
<CopilotKitProvider runtime-url="/api/copilotkit">
<HeadlessInterruptPanel />
</CopilotKitProvider>
</template>Going further#
- Tool-based HITL with
useHumanInTheLoop— for LLM-initiated pauses where the model decides to ask the user. useInterrupt— the chat-slot path, withenabledgating, handler preprocessing, and standard interrupt details.