Files
openclaw/tools/jarvis-delegate.sh
Clawd Bot ca9b510922 chore: align with upstream openclaw/openclaw and overlay local additions
- Reset master to upstream/main (16,697 commits)
- Overlay 2,271 local-only files (skills, tools, workspace, configs, apps)
- Restore IDENTITY.md and USER.md templates
- Build verified, gateway running, Discord working

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 07:40:46 +01:00

253 lines
7.3 KiB
Bash

#!/usr/bin/env bash
# Jarvis Auto-Delegation System
# Intelligently routes Kanban tasks to specialist agents
set -euo pipefail
KANBAN_API="http://192.168.1.220:5003/api/tasks"
KANBAN_CLI="/home/alex/clawd/tools/kanban-cli.sh"
LOG_FILE="/home/alex/clawd/logs/jarvis-delegation.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"
}
# Get agent-ready tasks from Kanban
get_delegatable_tasks() {
curl -sf "$KANBAN_API?status=queue" | jq -r '
.[] | select(.tags | contains("agent:")) |
"\(.id)|\(.tags)|\(.title)"
' 2>/dev/null || true
}
# Extract agent preference from tags
get_agent_from_tags() {
local tags="$1"
echo "$tags" | grep -oP 'agent:\K[a-z-]+' | head -1
}
# Get task size for timeout calculation
get_task_size() {
local tags="$1"
if echo "$tags" | grep -q "size:xs"; then
echo "300" # 5 min
elif echo "$tags" | grep -q "size:s"; then
echo "600" # 10 min
elif echo "$tags" | grep -q "size:m"; then
echo "1800" # 30 min
elif echo "$tags" | grep -q "size:l"; then
echo "3600" # 1 hour
elif echo "$tags" | grep -q "size:xl"; then
echo "7200" # 2 hours
else
echo "1800" # default 30 min
fi
}
# Map agent tag to model
map_agent_to_model() {
local agent="$1"
case "$agent" in
gemini-flash) echo "google/gemini-3-flash-preview" ;;
gemini-pro) echo "google/gemini-3-pro-preview" ;;
nvidia) echo "nvidia/qwen/qwen3-235b-a22b" ;;
deepseek) echo "nvidia/deepseek-ai/deepseek-v3.2" ;;
llama4) echo "nvidia/meta/llama-4-maverick-17b-128e-instruct" ;;
*) echo "google/gemini-3-flash-preview" ;; # fallback
esac
}
# Self-healing: analyze failure and propose fix
heal_task_failure() {
local task_id="$1"
local agent_tag="$2"
local failure_log="$3"
local retry_count="$4"
log "🔧 Analyzing task #$task_id failure (retry $retry_count/3)"
# Extract error context (last 100 lines of failure)
local error_context=$(tail -100 "$failure_log" 2>/dev/null || echo "No log available")
# Build healing prompt
local healing_prompt="**Self-Healing Task Analysis**
A Kanban task delegation failed. Diagnose and fix it.
**Task ID:** $task_id
**Agent:** $agent_tag
**Retry:** $retry_count/3
**Error Output:**
\`\`\`
$error_context
\`\`\`
**Your Tasks:**
1. Identify root cause
2. Propose specific fix (code/config/deps/params)
3. Apply fix if possible
4. Recommend: retry (yes/no)
Be concise. Make changes. Report decision."
# Spawn healing agent (sonnet for troubleshooting)
local healing_result=$(openclaw agent \
--agent free \
--model "anthropic/claude-sonnet-4-5" \
--thinking medium \
--timeout 300 \
--message "$healing_prompt" \
2>&1)
# Check if healing recommends retry
if echo "$healing_result" | grep -qi "retry.*yes\|should.*retry\|recommend.*retry"; then
log "✅ Healing suggests retry for task #$task_id"
return 0
else
log "❌ Healing recommends stop for task #$task_id"
return 1
fi
}
# Delegate task to agent with self-healing retry
delegate_task() {
local task_id="$1"
local task_title="$2"
local agent_tag="$3"
local timeout="$4"
local model=$(map_agent_to_model "$agent_tag")
local max_retries=3
local retry_count=0
local success=false
log "🤖 Delegating task #$task_id ($task_title) to $agent_tag (model: $model, timeout: ${timeout}s)"
# Get full task details
local task_desc=$(curl -sf "$KANBAN_API/$task_id" | jq -r '.description // ""')
# Build agent prompt
local prompt="Kanban Task #$task_id: $task_title
$task_desc
**Instructions:**
1. Analyze the task requirements
2. Execute necessary actions
3. Report completion with summary
4. If you need approval or encounter blockers, stop and ask
When done, update Kanban status to 'done' using:
bash /home/alex/clawd/tools/kanban-cli.sh update $task_id --status done
"
# Update Kanban status to in_progress
"$KANBAN_CLI" update "$task_id" --status in_progress 2>/dev/null || true
# Self-healing retry loop
while [[ $retry_count -le $max_retries ]]; do
if [[ $retry_count -gt 0 ]]; then
log "🔄 Retry $retry_count/$max_retries for task #$task_id"
fi
# Create temp log for this attempt
local attempt_log="/tmp/jarvis-task-$task_id-attempt-$retry_count.log"
# Spawn isolated agent
set +e
openclaw agent \
--agent free \
--isolated \
--model "$model" \
--thinking low \
--timeout "$timeout" \
--message "$prompt" \
--label "kanban-task-$task_id" \
2>&1 | tee -a "$LOG_FILE" > "$attempt_log"
local exit_code=$?
set -e
# Check for success
if [[ $exit_code -eq 0 ]]; then
# Verify task completion heuristically
if grep -qiE "(completed|done|success|finished|✅)" "$attempt_log"; then
log "✅ Task #$task_id completed successfully"
success=true
break
fi
fi
# Task failed
log "⚠️ Task #$task_id failed (exit: $exit_code)"
# Attempt healing if retries remain
if [[ $retry_count -lt $max_retries ]]; then
if heal_task_failure "$task_id" "$agent_tag" "$attempt_log" "$((retry_count + 1))"; then
retry_count=$((retry_count + 1))
sleep 5 # Brief pause before retry
continue
else
log "❌ Healing failed - stopping retries for task #$task_id"
break
fi
else
log "❌ Max retries exceeded for task #$task_id"
break
fi
done
if [[ $success == true ]]; then
log "🎉 Task #$task_id succeeded after $retry_count retries"
else
log "💥 Task #$task_id failed after $retry_count attempts"
"$KANBAN_CLI" update "$task_id" --status queue 2>/dev/null || true # Return to queue
fi
}
# Main delegation loop
main() {
log "=== JARVIS AUTO-DELEGATION STARTED ==="
local tasks=$(get_delegatable_tasks)
if [ -z "$tasks" ]; then
log "📭 No delegatable tasks found"
exit 0
fi
local delegated=0
local max_concurrent=3
while IFS='|' read -r task_id tags title; do
# Check concurrent limit
local running=$(pgrep -f "kanban-task-" | wc -l)
if [ "$running" -ge "$max_concurrent" ]; then
log "⏸️ Max concurrent tasks ($max_concurrent) reached, stopping"
break
fi
local agent=$(get_agent_from_tags "$tags")
if [ -z "$agent" ]; then
log "⚠️ Task #$task_id has no valid agent tag, skipping"
continue
fi
local timeout=$(get_task_size "$tags")
delegate_task "$task_id" "$title" "$agent" "$timeout"
((delegated++))
# Rate limit
sleep 2
done <<< "$tasks"
log "=== DELEGATION COMPLETE: $delegated tasks delegated ==="
}
# Create log directory
mkdir -p "$(dirname "$LOG_FILE")"
main "$@"