Human-in-the-Loop
Require approval before executing complex or sensitive workflows
Give users control over complex operations. MUXI can present execution plans and wait for approval before proceeding - preventing unwanted actions and building trust.
Why Approvals Matter
Without approvals:
User: "Deploy to production"
↓
MUXI immediately deploys
↓
User: "Wait, I didn't mean NOW!"
Too late - deployment already happened.
With approvals:
User: "Deploy to production"
↓
MUXI: "I'll deploy version 2.1.0 to production.
This affects 10,000 users. Proceed? [y/N]"
↓
User: "Actually, let me check something first..."
↓
Deployment prevented
Safe, controlled execution.
When to Use Approvals
Sensitive operations:
- ✅ Production deployments
- ✅ Data deletion
- ✅ Financial transactions
- ✅ External communications (emails, posts)
- ✅ User account modifications
Complex workflows:
- ✅ Multi-step operations
- ✅ Long-running tasks
- ✅ Resource-intensive operations
- ✅ Operations affecting multiple systems
Learning scenarios:
- ✅ New agent testing
- ✅ Unfamiliar operations
- ✅ Compliance requirements
- ✅ Training/demo purposes
Configuration
The plan_approval_threshold controls when approvals are required based on complexity scoring (1-10).
Default Configuration
overlord:
workflow:
plan_approval_threshold: 7 # Default: require approval for complexity ≥ 7
Require Approval for Complex Tasks
overlord:
workflow:
plan_approval_threshold: 8 # Only very complex tasks require approval
Start with a lower threshold in production. Better to approve too often than to let something slip through. Raise the threshold as you build confidence in your agents.
Require Approval for Most Tasks
overlord:
workflow:
plan_approval_threshold: 5 # Most tasks require approval
Require Approval for Everything
overlord:
workflow:
plan_approval_threshold: 1 # All tasks require approval (even simple ones)
Disable Approvals
overlord:
workflow:
plan_approval_threshold: 10 # Never require approval (max score is 10)
How It Works
1. User makes request
↓
2. Overlord calculates complexity score (1-10)
↓
3. Score ≥ plan_approval_threshold?
↓
4. YES → Create execution plan
↓
5. Present plan to user
↓
6. Wait for approval
↓
7. User approves? → Execute
User rejects? → Cancel
Approval Flow Example
Simple Request (No Approval)
User: "What's the weather in SF?"
Complexity: 2/10 (below threshold)
↓
Execute immediately (no approval needed)
↓
Response: "It's 68°F and sunny in San Francisco."
Complex Request (Approval Required)
User: "Research competitors, create comparison report, post to Slack"
Overlord analyzes:
- Multiple steps required
- Different skills needed
- External communication
- Complexity score: 9/10
↓
Score ≥ plan_approval_threshold (7 by default)
↓
MUXI presents plan:
"I've created a plan for this task:
1. Research competitors (researcher agent)
- Search for top 5 competitors
- Analyze their offerings
- Estimated time: 2-3 minutes
2. Create comparison report (analyst + writer agents)
- Compare features and pricing
- Generate PDF report
- Estimated time: 1-2 minutes
3. Post to Slack (slack-agent)
- Post to #marketing channel
- Include report as attachment
- Estimated time: <10 seconds
Total estimated time: 3-6 minutes
Proceed? [y/N]"
↓
User types: y
↓
Execute workflow
↓
Complete and return results
Approval Messages
Basic Approval
MUXI: I'll execute this workflow:
1. Research data
2. Create report
3. Send email
Proceed? [y/N]
Detailed Approval
MUXI: I've created a plan for this task:
**What I'll do:**
1. Research competitors (researcher)
- Tools: web-search, company-db
- Output: competitor_analysis.json
2. Compare features (analyst)
- Input: competitor_analysis.json
- Tools: data-analysis
- Output: comparison_matrix.csv
3. Create presentation (writer)
- Input: comparison_matrix.csv
- Tools: document-creation
- Output: presentation.pdf
**Impact:**
- External API calls: ~15 requests
- Estimated cost: $0.12
- Estimated time: 5-7 minutes
**Proceed? [y/N]**
Sensitive Operation Approval
MUXI: ⚠️ PRODUCTION DEPLOYMENT
I'll deploy version 2.1.0 to production:
**Changes:**
- 12 files modified
- 3 new migrations
- API endpoint /v2/users updated
**Impact:**
- Affects: 10,234 active users
- Downtime: ~30 seconds (rolling update)
- Rollback available: Yes
**Last deployed:** 2 hours ago (v2.0.9)
This is a PRODUCTION change. Are you sure? [y/N]
Approval Responses
Approve
User: y
User: yes
User: proceed
User: go ahead
All trigger execution.
Reject
User: n
User: no
User: cancel
User: abort
All cancel execution.
Modify
User: "Actually, skip the Slack post"
↓
MUXI: "Updated plan:
1. Research competitors
2. Create comparison report
(Removed: Post to Slack)
Proceed? [y/N]"
Adjusting the Threshold
The threshold determines which requests require approval. Lower threshold = more approvals.
| Threshold | When Approvals Trigger |
|---|---|
| 1 | All requests (even "What's the weather?") |
| 3 | Most requests with any complexity |
| 5 | Moderate and complex requests |
| 7 | Complex requests only (default) |
| 9 | Only very complex multi-step workflows |
| 10 | Never (effectively disables approvals) |
Example: Strict control for production
overlord:
workflow:
plan_approval_threshold: 5 # Require approval for most tasks
Example: Testing/development
overlord:
workflow:
plan_approval_threshold: 10 # No approvals during development
Approval in Different Modes
Synchronous (Default)
User: "Complex task"
↓
MUXI: "Plan... Proceed? [y/N]"
↓
User: "y"
↓
MUXI executes and returns result
Connection stays open, user waits.
Asynchronous
User: "Complex task" (async: true)
↓
MUXI: "Plan... Proceed? [y/N]"
↓
MUXI: Returns request_id immediately
↓
User: "y" (to /requests/{id}/approve)
↓
MUXI executes in background
↓
User polls or receives webhook when complete
Non-blocking, user can do other things.
SDK Examples
from muxi import FormationClient
formation = FormationClient(
server_url="http://localhost:7890",
formation_id="my-assistant",
client_key="...",
)
# Streaming chat - approvals are handled via events
for event in formation.chat_stream(
{"message": "Deploy to production"},
user_id="user_123"
):
if event.get("type") == "approval_required":
print("Plan:", event.get("plan"))
# User approval handled via separate endpoint
elif event.get("type") == "text":
print(event.get("text"), end="")
# Check async request status
status = formation.get_request_status(request_id="req_abc123")
# Later, approve
formation.approve_request(request.id)
# Or reject
formation.reject_request(request.id)
import { FormationClient } from "@muxi-ai/muxi-typescript";
const formation = new FormationClient({
serverUrl: "http://localhost:7890",
formationId: "my-assistant",
clientKey: "...",
});
// Streaming chat - approvals are handled via events
for await (const event of await formation.chatStream(
{ message: "Deploy to production" },
"user_123"
)) {
if (event.type === "approval_required") {
console.log("Plan:", event.plan);
} else if (event.type === "text") {
process.stdout.write(event.text);
}
}
// Check async request status
const status = await formation.getRequestStatus("req_abc123");
// Later, approve or reject
await formation.approveRequest(request.id);
await formation.rejectRequest(request.id);
import "github.com/muxi-ai/muxi-go"
formation := muxi.NewFormationClient(muxi.Config{
ServerURL: "http://localhost:7890",
FormationID: "my-assistant",
ClientKey: "...",
})
// Streaming chat - approvals are handled via events
stream, _ := formation.ChatStream(ctx, muxi.ChatRequest{
Message: "Deploy to production",
}, "user_123")
for event := range stream {
switch event.Type {
case "approval_required":
fmt.Println("Plan:", event.Plan)
case "text":
fmt.Print(event.Text)
}
}
// Check async request status
status, _ := formation.GetRequestStatus(ctx, "req_abc123")
// Later, approve or reject
formation.ApproveRequest(ctx, request.ID)
formation.RejectRequest(ctx, request.ID)
API Endpoints
Get Approval Status
GET /v1/requests/{request_id}
Response:
{
"request_id": "req_abc123",
"status": "awaiting_approval",
"plan": {
"tasks": [...],
"estimated_time": "5-7 minutes",
"estimated_cost": "$0.12"
}
}
Approve Request
POST /v1/requests/{request_id}/approve
Reject Request
POST /v1/requests/{request_id}/reject
Use Cases
1. Production Deployments
overlord:
workflow:
approval_rules:
- match: "deploy.*production"
requires_approval: true
show_impact: true
Flow:
User: "Deploy version 2.1.0 to production"
MUXI: Shows deployment plan with impact analysis
User: Reviews and approves
MUXI: Executes deployment
2. Data Deletion
overlord:
workflow:
approval_rules:
- match: "delete|remove|drop"
requires_approval: true
require_confirmation: true
Flow:
User: "Delete all test users"
MUXI: "This will delete 1,234 users. Type 'CONFIRM' to proceed:"
User: "CONFIRM"
MUXI: Executes deletion
3. External Communications
overlord:
workflow:
approval_rules:
- match: "send email|post.*slack|tweet"
requires_approval: true
show_preview: true
Flow:
User: "Send weekly update email to customers"
MUXI: Shows email preview and recipient count
User: Approves
MUXI: Sends emails
4. Financial Transactions
overlord:
workflow:
approval_rules:
- match: "transfer|payment|refund"
requires_approval: true
require_explicit_amount: true
Flow:
User: "Process refund for order #12345"
MUXI: "This will refund $249.99 to customer. Proceed? [y/N]"
User: "y"
MUXI: Processes refund
Best Practices
DO:
- ✅ Use approvals for sensitive operations
- ✅ Show clear impact in approval messages
- ✅ Include estimated time and cost
- ✅ Set reasonable timeouts
- ✅ Test approval flows before production
DON'T:
- ❌ Require approval for everything (annoying)
- ❌ Use vague approval messages
- ❌ Set timeout too short (rushed decisions)
- ❌ Skip approval for destructive operations
- ❌ Approve without reading (defeats purpose)
Monitoring Approvals
Use logging to track approval patterns:
logging:
enabled: true
streams:
- transport: file
level: info
destination: /var/log/muxi/approvals.log
This captures when approvals are requested, approved, or rejected for audit purposes.
Troubleshooting
Approval Not Showing
# Configuration
overlord:
workflow:
plan_approval_threshold: 8 # Requires approval for complexity ≥ 8
# Request complexity calculated as 7 (below threshold)
# Solution: Lower threshold to 7 or 6
overlord:
workflow:
plan_approval_threshold: 6 # Now complexity 7 will require approval
Too Many Approvals
# Was: Approving everything
overlord:
workflow:
plan_approval_threshold: 3 # Almost all requests need approval
# Solution: Raise threshold
overlord:
workflow:
plan_approval_threshold: 8 # Only very complex requests need approval
Not Enough Control
# Was: Too few approvals
overlord:
workflow:
plan_approval_threshold: 9 # Only extremely complex requests
# Solution: Lower threshold for production environments
overlord:
workflow:
plan_approval_threshold: 6 # More requests require approval
Learn More
- Approvals Reference - Full approval configuration
- Workflows & Task Decomposition - How workflows are created
- The Overlord - Orchestration engine
- Async Processing - Background task execution