Skip to content

Agent Action Approval

The Agent Action Approval feature enables AI peers to request human approval before executing potentially sensitive or critical tool actions. This adds a safety layer for operations that require human oversight.

Overview

Agent Action Approval allows you to:

  • Require Confirmation: AI requests approval before executing specific tools
  • Custom Messages: Show contextual approval requests to users
  • Maintain Flow: Conversation continues seamlessly after approval/rejection
  • Audit Trail: Track all approval decisions
  • Flexible Control: Configure per-tool or per-action

When to Use

Action Approval is essential for:

  • ✅ Database modifications (DELETE, UPDATE operations)
  • ✅ Financial transactions (payments, transfers)
  • ✅ External API calls with side effects (sending emails, SMS)
  • ✅ System changes (user management, settings)
  • ✅ Publishing or distribution actions

Quick Start

1. Configure Peer Action

  1. Navigate to Peer SettingsActions
  2. Select an action that should require approval
  3. Enable "Require Approval" toggle
  4. Save settings

2. Test in Chat

  1. Send a message that triggers the action
  2. AI peer recognizes approval is needed
  3. User sees approval request with context
  4. Click Approve or Reject
  5. Action executes (if approved) and conversation continues

Configuration

Per-Action Approval

Configure approval requirements for specific actions:

json
{
  "action": {
    "_id": "delete-user",
    "name": "Delete User",
    "requiresApproval": true,
    "approvalMessage": "This will permanently delete the user account. Are you sure?"
  }
}

Dynamic Approval Messages

Use variables in approval messages for context:

json
{
  "approvalMessage": "Delete {{username}} ({{email}})? This cannot be undone."
}

The AI peer automatically fills in values:

Result: "Delete john_doe (john@example.com)? This cannot be undone."

User Experience

In Chat Interface

When approval is needed:

┌─────────────────────────────────────────────┐
│ AI: I need your approval to proceed.       │
│                                             │
│ 🔧 Action: Delete User                     │
│ Delete john_doe (john@example.com)?        │
│ This cannot be undone.                     │
│                                             │
│  [Approve ✓]    [Reject ✗]                 │
└─────────────────────────────────────────────┘

After decision:

User: [Clicked Approve]
AI: User deleted successfully. ✓

or

User: [Clicked Reject]
AI: Action cancelled. The user account was not deleted.

In WebChat

Approval requests integrate seamlessly:

html
<div class="approval-request">
  <p class="action-name">Delete User</p>
  <p class="description">Delete john_doe (john@example.com)?</p>
  <div class="buttons">
    <button class="approve">Approve</button>
    <button class="reject">Reject</button>
  </div>
</div>

How It Works

Agent Decision Flow

1. User sends message

2. AI peer analyzes request

3. AI determines action needed (e.g., "delete user")

4. System checks if action requires approval
    ├─ Yes → Pause & show approval UI
    │         ↓
    │    User approves/rejects
    │         ↓
    │    Resume agent
    │         ├─ Approved → Execute action → Return result
    │         └─ Rejected → Skip action → Inform user
    └─ No → Execute action directly

State Preservation

During approval wait:

  • Agent state is serialized and saved
  • Conversation context is preserved
  • All variables remain available
  • Agent can resume exactly where it paused

API Integration

Client API Resume Endpoint

For custom integrations:

http
POST /api/v1/client/peer/message/:messageId/resume

Request:

json
{
  "decision": "approve"  // or "reject"
}

Response:

json
{
  "success": true,
  "message": {
    "_id": "msg_789",
    "status": "completed",
    "content": "User deleted successfully.",
    "approval": {
      "action": "delete-user",
      "decision": "approve",
      "timestamp": "2025-10-23T00:25:30Z"
    }
  }
}

JavaScript Example

javascript
// Resume with approval
async function approveAction(messageId) {
  const response = await fetch(
    `/api/v1/client/peer/message/${messageId}/resume`,
    {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ decision: 'approve' })
    }
  );
  
  return response.json();
}

// Resume with rejection
async function rejectAction(messageId) {
  const response = await fetch(
    `/api/v1/client/peer/message/${messageId}/resume`,
    {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ decision: 'reject' })
    }
  );
  
  return response.json();
}

Python Example

python
import requests

def approve_action(message_id: str, api_key: str) -> dict:
    """Approve a pending action"""
    response = requests.post(
        f'/api/v1/client/peer/message/{message_id}/resume',
        headers={
            'Authorization': f'Bearer {api_key}',
            'Content-Type': 'application/json'
        },
        json={'decision': 'approve'}
    )
    return response.json()

def reject_action(message_id: str, api_key: str) -> dict:
    """Reject a pending action"""
    response = requests.post(
        f'/api/v1/client/peer/message/{message_id}/resume',
        headers={
            'Authorization': f'Bearer {api_key}',
            'Content-Type': 'application/json'
        },
        json={'decision': 'reject'}
    )
    return response.json()

Configuration Examples

Example 1: Database Operations

json
{
  "actions": [
    {
      "name": "Delete Record",
      "requiresApproval": true,
      "approvalMessage": "Permanently delete {{recordType}} #{{recordId}}?"
    },
    {
      "name": "Update Settings",
      "requiresApproval": true,
      "approvalMessage": "Update {{settingName}} from {{oldValue}} to {{newValue}}?"
    }
  ]
}

Example 2: Financial Actions

json
{
  "actions": [
    {
      "name": "Process Payment",
      "requiresApproval": true,
      "approvalMessage": "Charge {{amount}} {{currency}} to card ending in {{cardLast4}}?"
    },
    {
      "name": "Issue Refund",
      "requiresApproval": true,
      "approvalMessage": "Issue refund of {{amount}} {{currency}} to {{customerName}}?"
    }
  ]
}

Example 3: Communication Actions

json
{
  "actions": [
    {
      "name": "Send Email",
      "requiresApproval": true,
      "approvalMessage": "Send email to {{recipient}} with subject '{{subject}}'?"
    },
    {
      "name": "Send SMS",
      "requiresApproval": true,
      "approvalMessage": "Send SMS to {{phoneNumber}}: '{{message}}'?"
    },
    {
      "name": "Publish Post",
      "requiresApproval": true,
      "approvalMessage": "Publish '{{title}}' to {{platform}}?"
    }
  ]
}

Best Practices

Approval Message Design

Good Messages:

"Delete invoice #12345 (total: $1,250.00)?"
"Send reminder email to 50 overdue customers?"
"Grant admin access to user@example.com?"
"Process refund of $99.99 to card ending in 4242?"

Avoid:

"Continue?" (too vague)
"Execute action?" (no context)
"Are you sure?" (doesn't explain what)
"Approve?" (missing details)

Which Actions Need Approval?

Always Require Approval:

  • Irreversible deletions
  • Financial transactions
  • Publishing/sending communications
  • Privilege escalation
  • External system changes

Consider Approval:

  • Bulk operations
  • Cost-incurring API calls
  • Compliance-sensitive actions
  • Cross-system updates

No Approval Needed:

  • Read-only operations
  • Internal calculations
  • Temporary data changes
  • User's own data access

Security Considerations

  1. Validate Requests: Always verify the action details before approving
  2. Audit Trail: Log all approval decisions for compliance
  3. Timeout: Consider implementing approval timeouts for critical actions
  4. Permissions: Ensure only authorized users can approve actions
  5. Context: Always show sufficient context for informed decisions

Troubleshooting

Approval Not Triggered

Possible Causes:

  • Action not configured to require approval
  • Peer not using the action
  • Configuration not saved

Solutions:

  • Verify action settings in Peer configuration
  • Check peer is using the correct tool/action
  • Ensure changes were saved

Agent Doesn't Resume

Possible Causes:

  • Resume endpoint not called
  • Invalid message ID
  • State data corrupted

Solutions:

  • Check API call is reaching the server
  • Verify message ID in request
  • Review server logs for errors

Approval Message Missing Variables

Possible Causes:

  • Variables not available in agent context
  • Typo in variable name
  • Tool not providing expected parameters

Solutions:

  • Check tool output includes required fields
  • Verify variable names match exactly
  • Test tool execution separately

Advanced Features

Conditional Approval

Configure approval rules based on conditions:

javascript
// In action configuration
{
  "requiresApproval": {
    "condition": "{{amount}} > 1000",
    "message": "Large transaction detected: {{amount}} {{currency}}"
  }
}

Multi-Level Approval

Chain approvals for sensitive operations:

User Request

AI determines action

Manager Approval (via webhook)
    ├─ Approved → Director Approval
    │              ├─ Approved → Execute
    │              └─ Rejected → Cancel
    └─ Rejected → Cancel

Approval History

Track approval decisions:

javascript
{
  "messageId": "msg_789",
  "approvals": [
    {
      "action": "delete-user",
      "decision": "approve",
      "userId": "user_123",
      "timestamp": "2025-10-23T00:25:30Z",
      "ipAddress": "192.168.1.1"
    }
  ]
}

Integration Patterns

Pattern 1: WebChat with Approval

html
<!-- In your webpage -->
<div id="chat-widget"></div>

<script src="https://app.cognipeer.com/scripts/cognipeer.sdk.js"></script>
<script>
  window.cognipeer.chat({
    hookId: "YOUR_HOOK_ID",
    onApprovalRequest: (data) => {
      // Custom approval UI
      showCustomApprovalDialog(data);
    }
  });
</script>

Pattern 2: Slack Integration

javascript
// Slack bot receives approval request
app.message(async ({ message, say }) => {
  if (message.approval_required) {
    await say({
      text: message.approval_message,
      blocks: [
        {
          type: "actions",
          elements: [
            {
              type: "button",
              text: { type: "plain_text", text: "Approve" },
              action_id: "approve",
              value: message.id
            },
            {
              type: "button",
              text: { type: "plain_text", text: "Reject" },
              action_id: "reject",
              value: message.id
            }
          ]
        }
      ]
    });
  }
});

Pattern 3: Mobile App

swift
// iOS example
func handleApprovalRequest(_ request: ApprovalRequest) {
    let alert = UIAlertController(
        title: request.actionName,
        message: request.message,
        preferredStyle: .alert
    )
    
    alert.addAction(UIAlertAction(title: "Approve", style: .default) { _ in
        self.approveAction(request.messageId)
    })
    
    alert.addAction(UIAlertAction(title: "Reject", style: .cancel) { _ in
        self.rejectAction(request.messageId)
    })
    
    present(alert, animated: true)
}

Summary

Agent Action Approval provides essential human oversight for AI-driven operations:

  • Safety: Prevent unintended actions
  • Compliance: Meet regulatory requirements
  • Control: Maintain human authority over critical decisions
  • Flexibility: Configure per-action or per-tool
  • Seamless: Integrated into chat and API flows

Key Benefits:

  • Reduces risk of AI errors
  • Provides audit trail
  • Maintains user trust
  • Enables gradual automation

Use Agent Action Approval to safely automate sensitive operations while keeping humans in control!

Built with VitePress