Agent and Action Termination

Embabel provides mechanisms to terminate agents and actions early, either gracefully (at the next checkpoint) or immediately. This is useful for scenarios like user cancellation, timeout handling, resource limits, or ctitical error handling.

Choosing Between Signal and Exception

MechanismWhen to UseBehavior
Graceful (Signal)"Let me finish my work, then stop" - side effects need to completeTerminates at next checkpoint; current operation completes normally
Immediate (Exception)"Stop now, nothing left to do" - no further processing neededTerminates immediately; nothing executes after the exception being thrown

Agent Termination

Agent termination stops the entire agent process. The process status becomes TERMINATED.

Graceful Agent Termination (Signal)

Use terminateAgent() when the current operation should complete before stopping. The agent terminates before the next checkpoint tick.

  // Signal: "Let me finish my work, then stop the agent"
  @LlmTool(description = "Save all pending work and shutdown")
  fun saveAndShutdown(ctx: ProcessContext): String {
      repository.saveAll(pendingRecords)  // side effect completes
      ctx.terminateAgent("All work saved, shutting down")
      return "Saved $\{pendingRecords.size} records"  // tool finishes normally
  }

Immediate Agent Termination (Exception)

Use TerminateAgentException when the agent must stop immediately. No further tool calls or actions execute.

  // Exception: "Stop now, nothing left to do"
  @LlmTool(description = "Validate critical prerequisites")
  fun validatePrerequisites(): String {
      if (!authService.hasRequiredPermissions()) {
          throw TerminateAgentException("Missing required permissions")
          // nothing after this runs
      }
      return "Prerequisites validated"
  }

Action Termination

Action termination stops only the current action. The agent continues with the next planned action. This is useful for skipping problematic steps while allowing the overall goal to proceed.

true`.

Graceful Action Termination (Signal)

Use terminateAction() when the current tool call should complete before stopping the action. The action terminates between tool calls.

For simple transformation actions, use TerminateActionException instead.

  // Signal: "Let me finish my work, then stop"
  @LlmTool(description = "Save and shutdown")
  fun saveAndStop(ctx: ProcessContext): String {
      customerRepository.save(record)  // side effect completes
      ctx.terminateAction("Save complete, no more work needed")
      return "Saved"  // tool finishes normally
  }

Immediate Action Termination (Exception)

Use TerminateActionException when the action must stop immediately. Remaining tool calls in the current batch are skipped.

  // Exception: "Stop now, nothing left to do"
  @LlmTool(description = "Check service health")
  fun checkHealth(): String {
      if (!mcpClient.isConnected("required_service")) {
          throw TerminateActionException("Service unavailable")
          // nothing after this runs
      }
      return "Healthy"
  }

Catching Both Exception Types

Both TerminateAgentException and TerminateActionException extend TerminationException, allowing you to catch them together:

  try {
      tool.execute()
  } catch (e: TerminationException) {
      logger.info("Terminated: $\{e.reason}")
      // Handle both agent and action termination
  }

Summary

ScopeMechanismMethod/ExceptionUse Case
AgentGracefulprocessContext.terminateAgent(reason)"Finish current work, then stop agent"
AgentImmediatethrow TerminateAgentException(reason)"Stop now - critical error, no recovery"
ActionGracefulprocessContext.terminateAction(reason)"Finish current tool, then stop action"
ActionImmediatethrow TerminateActionException(reason)"Stop now - try different approach"

Was this page helpful?

Share