Class InterruptService

java.lang.Object
com.tnsai.security.approval.InterruptService

public class InterruptService extends Object
Service for AG-UI interrupt pattern - blocking agent execution for human approval.

This service implements the AG-UI interrupt-aware run lifecycle, allowing agents to pause execution and wait for human input before proceeding.

AG-UI Interrupt Flow

 1. Agent calls requestInterrupt() before critical action
 2. Service creates interrupt, agent thread BLOCKS
 3. AG-UI emits RUN_FINISHED { outcome: "interrupt", interrupt: {...} }
 4. Frontend shows approval dialog
 5. User approves/rejects
 6. Frontend POSTs to /v1/runs/{runId}/resume
 7. Service completes the future, agent thread UNBLOCKS
 8. Agent continues or aborts based on result
 

Usage Example


 InterruptService interruptService = new InterruptService();

 // In agent action execution:
 InterruptResult result = interruptService.requestInterrupt(
     InterruptReason.HUMAN_APPROVAL,
     Map.of("action", "delete_user", "userId", "123"),
     Duration.ofMinutes(5)
 );

 if (result.isApproved()) {
     // Proceed with action
     deleteUser("123");
 } else {
     // Action rejected or timed out
     throw new ActionRejectedException(result.getRejectionReason());
 }

 // From AG-UI endpoint (when user approves):
 interruptService.resume(interruptId, true, Map.of("approver", "admin"));
 
See Also:
  • Constructor Details

    • InterruptService

      public InterruptService()
      Creates an InterruptService with default 5 minute timeout.
    • InterruptService

      public InterruptService(Consumer<InterruptService.InterruptRequest> listener)
      Creates an InterruptService with a listener for interrupt events.
      Parameters:
      listener - called when interrupt is requested (for AG-UI event emission)
    • InterruptService

      public InterruptService(Consumer<InterruptService.InterruptRequest> listener, Duration defaultTimeout)
      Creates an InterruptService with custom timeout.
      Parameters:
      listener - called when interrupt is requested
      defaultTimeout - default timeout for interrupts
  • Method Details

    • requestInterrupt

      public InterruptResult requestInterrupt(InterruptReason reason, Map<String,Object> payload)
      Requests an interrupt and blocks until resolved or timed out.

      This method will:

      1. Create an interrupt request
      2. Notify any listeners (for AG-UI event emission)
      3. Block the calling thread until approval/rejection/timeout
      4. Return the result
      Parameters:
      reason - the reason for the interrupt
      payload - additional data to show in approval UI
      Returns:
      the interrupt result
    • requestInterrupt

      public InterruptResult requestInterrupt(InterruptReason reason, Map<String,Object> payload, Duration timeout)
      Requests an interrupt with custom timeout.
      Parameters:
      reason - the reason for the interrupt
      payload - additional data to show in approval UI
      timeout - how long to wait before timing out
      Returns:
      the interrupt result
    • requestInterruptAsync

      public CompletableFuture<InterruptResult> requestInterruptAsync(InterruptReason reason, Map<String,Object> payload, Duration timeout)
      Requests an interrupt without blocking (async).
      Parameters:
      reason - the reason for the interrupt
      payload - additional data to show in approval UI
      timeout - how long to wait before timing out
      Returns:
      future that completes with the result
    • resume

      public boolean resume(String interruptId, boolean approved, Map<String,Object> payload)
      Resumes an interrupt with approval.
      Parameters:
      interruptId - the interrupt ID
      approved - whether the action is approved
      payload - optional response payload from user
      Returns:
      true if the interrupt was found and resumed
    • cancel

      public boolean cancel(String interruptId)
      Cancels an interrupt.
      Parameters:
      interruptId - the interrupt ID
      Returns:
      true if found and cancelled
    • getPendingInterrupt

      public Optional<InterruptService.InterruptRequest> getPendingInterrupt(String interruptId)
      Gets details of a pending interrupt.
      Parameters:
      interruptId - the interrupt ID
      Returns:
      interrupt details or empty
    • getPendingCount

      public int getPendingCount()
      Gets count of pending interrupts.
      Returns:
      number of pending interrupts
    • isPending

      public boolean isPending(String interruptId)
      Checks if an interrupt is pending.
      Parameters:
      interruptId - the interrupt ID
      Returns:
      true if pending