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

# Batch Management

> Critical concepts for handling grouped tool approvals

## Why Batch Management Matters

**Critical System Requirement**: All tool approvals within the same `toolExecutionBatchId` must be responded to simultaneously in a single API call. Individual responses will cause the batch to complete prematurely, potentially leaving some tools unprocessed.

This is a fundamental constraint of the approval system that directly impacts both backend processing and user experience design.

## Understanding Tool Execution Batches

### Batch Identification

Every tool requiring approval includes a `toolExecutionBatchId` field that groups related tool executions:

```json theme={null}
{
  "toolExecutionApprovalRequest": [
    {
      "toolExecutionId": "exec_123",
      "toolExecutionBatchId": "batch_456",
      "toolName": "send_email",
      // ... other fields
    },
    {
      "toolExecutionId": "exec_124", 
      "toolExecutionBatchId": "batch_456",
      "toolName": "create_calendar_event",
      // ... other fields
    }
  ]
}
```

Both tools share `batch_456`, meaning they must be approved or denied together.

### Why Batches Exist

Batches ensure atomic operations and maintain workflow integrity:

* **Atomic Operations**: Related tools succeed or fail together
* **Workflow Consistency**: Prevents partial execution of multi-step processes
* **User Context**: Groups logically related actions for easier decision-making

## Batch Response Requirements

### Single Response Rule

The backend expects exactly one response containing decisions for all tools in a batch:

```typescript theme={null}
// ✅ CORRECT: Single response with all approvals
const batchResponse = {
  content: [
    {
      type: 'tool_approval_result',
      tool_approval_results: [
        {
          toolExecutionId: 'exec_123',
          toolExecutionBatchId: 'batch_456',
          approvalResult: 'APPROVED'
        },
        {
          toolExecutionId: 'exec_124',
          toolExecutionBatchId: 'batch_456', 
          approvalResult: 'DENIED'
        }
      ]
    }
  ]
};

// ❌ INCORRECT: Separate responses
// This will cause premature batch completion
await approveIndividualTool('exec_123', 'APPROVED');
await approveIndividualTool('exec_124', 'DENIED');
```

### Incomplete Batch Consequences

When a batch receives partial responses:

1. **Premature Completion**: The agent may respond before all tools are processed
2. **Undefined State**: Unresponded tools may be left in pending state
3. **Workflow Failure**: Multi-step processes may fail due to missing tool results

## UX Implications

### Batch Processing Patterns

**Recommended**: Collect all decisions before submitting

```typescript theme={null}
// Collect user decisions for entire batch
const batchDecisions = new Map();
const batchId = 'batch_456';

// User makes decisions through UI
batchDecisions.set('exec_123', 'APPROVED');
batchDecisions.set('exec_124', 'DENIED');

// Submit all decisions at once when batch is complete
if (batchDecisions.size === totalToolsInBatch) {
  submitBatchResponse(batchId, batchDecisions);
}
```

**Avoid**: Immediate individual processing

```typescript theme={null}
// ❌ This pattern causes batch completion issues
function onApproveButtonClick(toolExecutionId) {
  // Don't immediately submit individual approvals
  submitApproval(toolExecutionId, 'APPROVED'); // WRONG
}
```

### UI Design Patterns

**Batch-Aware Interface**:

* Group tools by `toolExecutionBatchId` in the UI
* Show batch completion progress (e.g., "2 of 3 tools decided")
* Disable submission until all tools in batch are decided
* Provide batch-level actions ("Approve All", "Deny All")

**Example Batch UI State**:

```typescript theme={null}
interface BatchState {
  batchId: string;
  tools: ToolApprovalRequest[];
  decisions: Map<string, ApprovalDecision>;
  isComplete: boolean;
  canSubmit: boolean;
}

const batchState = {
  batchId: 'batch_456',
  tools: [tool1, tool2, tool3],
  decisions: new Map([
    ['exec_123', 'APPROVED'],
    ['exec_124', 'PENDING'], // Still waiting
    ['exec_125', 'DENIED']
  ]),
  isComplete: false,
  canSubmit: false
};
```

## Implementation Strategies

### Batch Collection Pattern

```typescript theme={null}
class ApprovalBatchManager {
  private batches = new Map<string, BatchState>();
  
  addApprovalRequest(request: ToolApprovalRequest) {
    const batchId = request.toolExecutionBatchId;
    
    if (!this.batches.has(batchId)) {
      this.batches.set(batchId, {
        batchId,
        tools: [],
        decisions: new Map(),
        isComplete: false
      });
    }
    
    const batch = this.batches.get(batchId)!;
    batch.tools.push(request);
  }
  
  setDecision(toolExecutionId: string, decision: ApprovalDecision) {
    for (const batch of this.batches.values()) {
      if (batch.tools.find(t => t.toolExecutionId === toolExecutionId)) {
        batch.decisions.set(toolExecutionId, decision);
        
        // Check if batch is complete
        if (batch.decisions.size === batch.tools.length) {
          batch.isComplete = true;
          this.submitBatch(batch);
        }
        break;
      }
    }
  }
  
  private submitBatch(batch: BatchState) {
    const approvalResults = Array.from(batch.decisions.entries()).map(
      ([toolExecutionId, decision]) => ({
        toolExecutionId,
        toolExecutionBatchId: batch.batchId,
        approvalResult: decision
      })
    );
    
    // Submit all approvals in single API call
    submitApprovalResponse(approvalResults);
  }
}
```

## Common Pitfalls

1. **Immediate Processing**: Don't submit approvals as soon as user clicks buttons
2. **Ignoring Batch ID**: Always group tools by `toolExecutionBatchId`
3. **Partial Submissions**: Never submit incomplete batches
4. **State Management**: Don't lose track of pending decisions across UI updates

## Next Steps

* Learn about [Approval States](/human-in-the-loop/approval-states/index) and their constraints
* Review [API Integration](/human-in-the-loop/api-integration/index) for proper request formatting
* See [Best Practices](/human-in-the-loop/best-practices/index) for UX recommendations
