Skip to main content

Available Approval States

The system supports three approval decisions for each tool execution:
  • APPROVED: Tool will execute with provided arguments
  • DENIED: Tool execution will be skipped
  • ABORTED_WITH_FEEDBACK_WITH_FEEDBACK: Tool execution cancelled with user feedback

State Combination Rules

Mixed States (Allowed)

Within a single batch, you can mix APPROVED and DENIED states:
// ✅ VALID: Mix of approvals and denials
const validBatchResponse = [
  {
    toolExecutionId: 'exec_123',
    toolExecutionBatchId: 'batch_456',
    approvalResult: 'APPROVED'
  },
  {
    toolExecutionId: 'exec_124', 
    toolExecutionBatchId: 'batch_456',
    approvalResult: 'DENIED'
  },
  {
    toolExecutionId: 'exec_125',
    toolExecutionBatchId: 'batch_456', 
    approvalResult: 'APPROVED'
  }
];

Abort Restrictions (System Limitation)

Critical Constraint: If any tool in a batch has an ABORTED_WITH_FEEDBACK state, ALL tools in that batch must be ABORTED_WITH_FEEDBACK. You cannot mix ABORTED_WITH_FEEDBACK with APPROVED or DENIED states.
// ✅ VALID: All tools aborted
const validAbortResponse = [
  {
    toolExecutionId: 'exec_123',
    toolExecutionBatchId: 'batch_456',
    approvalResult: 'ABORTED_WITH_FEEDBACK'
  },
  {
    toolExecutionId: 'exec_124',
    toolExecutionBatchId: 'batch_456', 
    approvalResult: 'ABORTED_WITH_FEEDBACK'
  }
];

// ❌ INVALID: Mixed abort with other states - will return error
const invalidMixedResponse = [
  {
    toolExecutionId: 'exec_123',
    toolExecutionBatchId: 'batch_456',
    approvalResult: 'APPROVED'  // Error: cannot mix with abort
  },
  {
    toolExecutionId: 'exec_124',
    toolExecutionBatchId: 'batch_456',
    approvalResult: 'ABORTED_WITH_FEEDBACK'
  }
];

When to Use Each State

APPROVED

Use when the tool execution should proceed as planned:
  • Tool arguments look correct
  • User authorizes the action
  • No concerns about the operation
Example: User reviews calendar event creation and confirms the meeting details are accurate.

DENIED

Use when the tool should not execute but the overall workflow can continue:
  • Tool arguments are incorrect but fixable
  • User doesn’t want this specific action
  • Timing isn’t right for this operation
Example: User denies sending an email because the recipient list needs revision, but approves creating a draft.

ABORTED_WITH_FEEDBACK

Use when there are fundamental issues requiring workflow termination:
  • Tool arguments indicate a serious problem
  • User wants to stop the entire process
  • Additional context/feedback is needed
Example: User sees the agent is about to delete important data and wants to abort the entire operation with feedback about what went wrong.

Abort vs Deny Decision Matrix

ScenarioRecommended StateReason
Wrong recipient in emailDENIEDSpecific tool issue, workflow can continue
Incorrect calendar timeDENIEDSpecific parameter problem
Agent misunderstood entire requestABORTED_WITH_FEEDBACKFundamental workflow issue
About to perform destructive actionABORTED_WITH_FEEDBACKSafety concern requiring full stop
User wants to provide feedbackABORTED_WITH_FEEDBACKNeed to communicate back to agent

UX Recommendations for State Handling

Button vs Text Input Patterns

Based on system constraints and UX best practices: For APPROVED/DENIED: Use individual buttons per tool
// Safe to handle individually since they can be mixed
function handleApprove(toolExecutionId: string) {
  setBatchDecision(toolExecutionId, 'APPROVED');
}

function handleDeny(toolExecutionId: string) {
  setBatchDecision(toolExecutionId, 'DENIED');  
}
For ABORTED_WITH_FEEDBACK: Use text input for feedback
// When user types feedback, abort entire batch
function handleFeedbackSubmit(feedback: string, batchId: string) {
  // Abort ALL tools in batch with user feedback
  const allToolsAborted = batchTools.map(tool => ({
    toolExecutionId: tool.toolExecutionId,
    toolExecutionBatchId: batchId,
    approvalResult: 'ABORTED_WITH_FEEDBACK'
  }));
  
  submitBatchResponse(allToolsAborted, feedback);
}

State Validation

Implement client-side validation to prevent invalid state combinations:
function validateBatchStates(decisions: Map<string, ApprovalState>): ValidationResult {
  const states = Array.from(decisions.values());
  const hasAbort = states.includes('ABORTED_WITH_FEEDBACK');
  const hasOtherStates = states.some(state => state !== 'ABORTED_WITH_FEEDBACK');
  
  if (hasAbort && hasOtherStates) {
    return {
      valid: false,
      error: 'Cannot mix ABORTED_WITH_FEEDBACK with APPROVED or DENIED states'
    };
  }
  
  return { valid: true };
}

function onSubmitBatch(batchId: string) {
  const decisions = getBatchDecisions(batchId);
  const validation = validateBatchStates(decisions);
  
  if (!validation.valid) {
    showError(validation.error);
    return;
  }
  
  submitBatch(batchId, decisions);
}

Progressive State Selection

Guide users away from problematic state combinations:
function handleStateChange(toolId: string, newState: ApprovalState) {
  const currentBatch = getBatchForTool(toolId);
  
  if (newState === 'ABORTED_WITH_FEEDBACK') {
    // Warn user about batch-wide impact
    showWarning('Aborting will cancel all tools in this batch. Continue?');
    
    // Auto-abort other tools in batch
    currentBatch.tools.forEach(tool => {
      if (tool.toolExecutionId !== toolId) {
        setBatchDecision(tool.toolExecutionId, 'ABORTED_WITH_FEEDBACK');
      }
    });
  }
  
  setBatchDecision(toolId, newState);
}

Error Scenarios

Mixed Abort Error Response

When you attempt to submit invalid mixed states:
{
  "error": "Invalid approval batch: cannot mix ABORTED_WITH_FEEDBACK with other approval states",
  "batchId": "batch_456",
  "invalidStates": [
    {
      "toolExecutionId": "exec_123", 
      "state": "APPROVED"
    },
    {
      "toolExecutionId": "exec_124",
      "state": "ABORTED_WITH_FEEDBACK" 
    }
  ]
}
Handle this error by enforcing consistent batch states:
function handleBatchError(error: BatchError) {
  if (error.type === 'mixed_abort_states') {
    // Force user to choose: abort all or none
    showStateConflictDialog(error.batchId, error.invalidStates);
  }
}

Content Field Considerations

Tool approval responses that are not abortions cannot include files or images in the content field - these will be ignored by the system.
// ✅ VALID: Abort with file attachment
const abortWithFile = {
  content: [
    {
      type: 'tool_approval_result',
      tool_approval_results: [/* aborted tools */]
    },
    {
      type: 'image',
      image_url: { url: 'screenshot_of_issue.png' }  // Allowed for aborts
    }
  ]
};

// ❌ INVALID: Approval/denial with file (file will be ignored)
const approvalWithFile = {
  content: [
    {
      type: 'tool_approval_result', 
      tool_approval_results: [/* approved tools */]
    },
    {
      type: 'image', 
      image_url: { url: 'reference.png' }  // Will be ignored
    }
  ]
};

Next Steps

I