> ## Documentation Index
> Fetch the complete documentation index at: https://docs.envole.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Approval States

> Understanding approval decisions and their constraints

## 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:

```typescript theme={null}
// ✅ 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.

```typescript theme={null}
// ✅ 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

| Scenario                            | Recommended State       | Reason                                     |
| ----------------------------------- | ----------------------- | ------------------------------------------ |
| Wrong recipient in email            | DENIED                  | Specific tool issue, workflow can continue |
| Incorrect calendar time             | DENIED                  | Specific parameter problem                 |
| Agent misunderstood entire request  | ABORTED\_WITH\_FEEDBACK | Fundamental workflow issue                 |
| About to perform destructive action | ABORTED\_WITH\_FEEDBACK | Safety concern requiring full stop         |
| User wants to provide feedback      | ABORTED\_WITH\_FEEDBACK | Need 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

```typescript theme={null}
// 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

```typescript theme={null}
// 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:

```typescript theme={null}
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:

```typescript theme={null}
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:

```json theme={null}
{
  "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:

```typescript theme={null}
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.

```typescript theme={null}
// ✅ 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

* Learn about [API Integration](/human-in-the-loop/api-integration/index) for proper request formatting
* Review [Best Practices](/human-in-the-loop/best-practices/index) for UX patterns
* See [Error Handling](/human-in-the-loop/error-handling/index) for managing validation failures
