DocsChatComponentsChatInterruptPanelComponent

ChatInterruptPanelComponent

ChatInterruptPanelComponent is a composition that renders a styled interrupt card when the LangGraph agent pauses for human input. It displays the interrupt payload and provides action buttons for the user to accept, edit, respond to, or ignore the interrupt.

Selector: chat-interrupt-panel

Import:

import { ChatInterruptPanelComponent } from '@ngaf/chat';
import type { InterruptAction } from '@ngaf/chat';

How It Works

LangGraph agents can pause execution using interrupts -- checkpoints where the agent waits for human input before proceeding. The ChatInterruptPanelComponent reads the interrupt state from an Agent and renders a warning card with action buttons.

When no interrupt is active, the component renders nothing.

Basic Usage

<chat-interrupt-panel
  [agent]="chatRef"
  (action)="handleInterrupt($event)"
/>
import type { InterruptAction } from '@ngaf/chat';
 
handleInterrupt(action: InterruptAction) {
  switch (action) {
    case 'accept':
      this.chatRef.submit({ resume: true });
      break;
    case 'edit':
      this.openEditor();
      break;
    case 'respond':
      this.focusInput();
      break;
    case 'ignore':
      // Do nothing, dismiss the panel
      break;
  }
}

API

Inputs

InputTypeDefaultDescription
agentAgentRequiredThe agent providing interrupt state

Outputs

OutputTypeDescription
actionInterruptActionEmits when the user clicks an action button

InterruptAction Type

type InterruptAction = 'accept' | 'edit' | 'respond' | 'ignore';
ActionButton LabelTypical Use
'accept'AcceptApprove the agent's proposed action and resume execution
'edit'EditOpen an editor to modify the agent's proposal before resuming
'respond'RespondSend a text response back to the agent
'ignore'IgnoreDismiss the interrupt without taking action

Interrupt Payload Display

The component extracts the interrupt payload and displays it as text:

  • If the interrupt value is a string, it is displayed directly
  • If the interrupt value is an object, it is serialized with JSON.stringify()

Styling

The panel uses the chat theme's warning variables:

VariableApplied To
--ngaf-chat-warning-bgPanel background
--ngaf-chat-warning-textHeader and message text
--ngaf-chat-separatorPanel border
--ngaf-chat-radius-cardPanel border radius
--ngaf-chat-surface-altAction button backgrounds
--ngaf-chat-textAction button text
--ngaf-chat-text-mutedIgnore button text

Primitive Alternative: ChatInterruptComponent

If you need full control over the interrupt UI, use the lower-level ChatInterruptComponent primitive instead. It provides content projection via an ng-template:

<chat-interrupt [agent]="chatRef">
  <ng-template let-interrupt>
    <div class="my-custom-interrupt">
      <p>Agent paused: {{ interrupt.value }}</p>
      <button (click)="resume()">Continue</button>
    </div>
  </ng-template>
</chat-interrupt>

The primitive also exports a getInterrupt() helper function:

import { getInterrupt } from '@ngaf/chat';
 
const interrupt = getInterrupt(chatRef); // Interrupt<any> | undefined

Full Example

import { Component, signal, ChangeDetectionStrategy } from '@angular/core';
import { agent } from '@ngaf/langgraph';
import { ChatComponent, ChatInterruptPanelComponent } from '@ngaf/chat';
import type { InterruptAction } from '@ngaf/chat';
 
@Component({
  selector: 'app-interrupt-demo',
  standalone: true,
  imports: [ChatComponent, ChatInterruptPanelComponent],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <div style="height: 100vh; display: flex; flex-direction: column;">
      <div style="flex: 1;">
        <chat [agent]="chatRef" />
      </div>
 
      <chat-interrupt-panel
        [agent]="chatRef"
        (action)="onInterruptAction($event)"
      />
    </div>
  `,
})
export class InterruptDemoComponent {
  chatRef = agent({
    assistantId: 'interrupt_agent',
    threadId: signal(null),
  });
 
  onInterruptAction(action: InterruptAction) {
    if (action === 'accept') {
      this.chatRef.submit({ resume: true });
    }
  }
}