task-router-skillDistributed task queue for OpenClaw multi-agent systems that routes tasks by capability, tracks lifecycle, coordinates async handoffs, rebalances load, and m...
Install via ClawdBot CLI:
clawdbot install capt-marbles/task-router-skillDistributed task queue for OpenClaw multi-agent systems. Central coordination, async handoffs, capability-based routing.
# Install skill
clawhub install task-router
# Register an agent
task agent register watson --capabilities "research analysis" --max-concurrent 3
# Create a task
task create --type research --title "Competitor analysis" --priority high
# Router runs automatically via heartbeat
# Check task status
task list --status pending
task show task-abc123
Core Functions:
Use Cases:
~/.openclaw/task-router/
βββ config.yaml # Router settings, timeouts
βββ agents.yaml # Agent registry + capabilities
βββ queue/ # Task state
β βββ pending/ # Waiting for assignment
β βββ active/ # Assigned to agent
β βββ completed/ # Finished successfully
β βββ failed/ # Failed, exhausted retries
βββ logs/
βββ router.log # Routing decisions
router:
check_interval: 30 # Seconds between router runs
default_ttl: 3600 # Default task timeout
max_retries: 2
strategies:
default: least-loaded # round-robin | least-loaded | priority
by_type:
research: least-loaded
image_gen: round-robin
urgent: priority
health:
agent_timeout: 300 # Mark agent unhealthy after seconds
task_timeout:
warning: 1800 # Alert at 30 min
critical: 3600 # Fail at 1 hour
notifications:
on_complete: true
on_fail: true
channels: [main_session] # Could add Discord, etc.
agents:
watson:
id: watson
emoji: π¬
capabilities: [research, analysis, web_search]
max_concurrent: 3
current_tasks: [task-abc123, task-def456]
stats:
completed: 47
failed: 2
avg_duration: 180
health:
last_ping: 2026-02-13T09:15:00Z
status: healthy
picasso:
id: picasso
emoji: π¨
capabilities: [image_gen, image_edit]
max_concurrent: 2
current_tasks: []
id: task-abc123
type: research # Matches agent capability
title: Research Gameye competitors
description: Deep competitive analysis
payload:
query: Gameye vs competitors
sources: [web, apollo]
output_format: markdown
created_by: main # Session label that created it
assigned_to: watson # null until routed
assigned_by: router # router | manual | agent
created_at: 2026-02-13T09:00:00Z
assigned_at: 2026-02-13T09:05:00Z
started_at: 2026-02-13T09:06:00Z
completed_at: null
expires_at: 2026-02-13T10:00:00Z # created_at + ttl
priority: high # low | normal | high | urgent
ttl: 3600 # Seconds
retries: 0
max_retries: 2
dependencies: [] # Block until these complete
blocked_by: [] # Populated by router
status: assigned # pending | assigned | running | complete | failed
result: null # Path to result file
error: null # Error message if failed
metadata:
source: heartbeat
tags: [gameye, competitors]
# Create task
task create --type research \
--title "Research Gameye competitors" \
--data '{"query": "Gameye pricing"}' \
--priority high \
--ttl 3600
# Create with dependencies
task create --type analysis \
--title "Analyze research results" \
--depends-on task-abc123
# List tasks
task list # All non-completed
task list --status pending
task list --assigned-to watson
task list --type research --limit 10
task list --created-after 2026-02-13
# Show task
task show task-abc123 # Full details + result preview
# Manage tasks
task cancel task-abc123 # Cancel pending or active
task retry task-abc123 # Move failed back to pending
task reprioritize task-abc123 --priority urgent
# Results
task result task-abc123 # View result file
task export --status completed --since 2026-02-13 > ~/reports/tasks.ndjson
# Register agent (required before routing)
task agent register watson \
--capabilities "research analysis web_search" \
--max-concurrent 3 \
--emoji π¬
# Update agent
task agent update watson --add-capability "competitive-analysis"
task agent update watson --max-concurrent 5
# Check agent health
task agent status watson # Current tasks, health, stats
task agent ping watson # Health check ping
# List agents
task agent list # All agents
task agent list --capable-of research
# Unregister
task agent unregister watson --reassign-tasks
# Status
task router status # Queue depth, agent health
# Control flow
task router pause # Stop new assignments
task router resume # Resume routing
task router rebalance # Redistribute stuck tasks
# Maintenance
task router cleanup # Archive old completed tasks
task router drain # Finish active, no new pending
import * as Task from "~/.openclaw/task-router/sdk";
// === Creating Tasks ===
// Simple create
const task = await Task.create({
type: "research",
title: "Competitor analysis",
payload: { query: "Gameye vs competitors" }
});
// With options
const task = await Task.create({
type: "image_gen",
title: "Generate hero image",
payload: { prompt: "Futuristic game server...", size: "1024x1024" },
priority: "high",
ttl: 1800,
max_retries: 1,
dependencies: [previousTaskId], // Waits for these first
created_by: "main"
});
// === Querying ===
// Get status
const status = await Task.status(task.id);
// { id, status, assigned_to, created_at, expires_at }
// Wait for completion (blocking)
const result = await Task.wait(task.id, { timeout: 300, pollInterval: 5 });
// List with filters
const pending = await Task.query({
status: "pending",
type: "research",
priority: "high",
limit: 10
});
const myTasks = await Task.query({
created_by: "main",
status: ["assigned", "running"]
});
// === Agent Integration ===
// Agent picks up work (if auto-assign disabled)
await Task.claim({
agentId: "watson",
capableOf: "research",
limit: 1
});
// Complete task
await Task.complete(task.id, {
result_path: "~/agents/watson/memory/results/competitors.md",
summary: "Found 5 competitors: GameLift, Multiplay, Hathora, Edgegap, Agones",
metadata: { competitors_count: 5 }
});
// Fail task
await Task.fail(task.id, {
reason: "API quota exceeded",
retryable: true // Will auto-retry
});
// === Multi-Step Workflows ===
// Chain tasks
const analysisTask = await Task.chain(researchTask.id, {
type: "analysis",
title: "Analyze research findings",
payload: { input_task: researchTask.id }
});
// Parallel tasks
const tasks = await Task.parallel([
{ type: "research", title: "Research A", payload: {} },
{ type: "research", title: "Research B", payload: {} },
{ type: "research", title: "Research C", payload: {} }
]);
await Task.waitAll(tasks.map(t => t.id));
// === Agent Session Integration ===
// Spawn via task router (recommended for async work)
const spawnResult = await Task.spawn({
taskId: task.id,
agentId: "watson", // Optional: auto-route if omitted
useSession: true // Use sessions_spawn vs sessions_send
});
// Router will call:
// sessions_spawn({ agentId, task, label: task.id })
Create ~/.openclaw/workspace/HEARTBEAT.md:
# Task Router Heartbeat
## Router Cycle (runs every 30s)typescript
import * as Task from "~/.openclaw/task-router/sdk";
// 1. Auto-route pending tasks
const routed = await Task.router.cycle();
if (routed.length > 0) {
Task.log(Routed ${routed.length} tasks:, routed.map(t => ${t.id} β ${t.assigned_to}));
}
// 2. Check for timeouts
const timeouts = await Task.router.checkTimeouts();
for (const task of timeouts) {
if (task.retries < task.max_retries) {
Task.log(Retrying ${task.id} after timeout);
await Task.retry(task.id);
} else {
Task.log(Dead lettering ${task.id});
await Task.router.moveToDeadLetter(task);
}
}
// 3. Check agent health
const unhealthy = await Task.agents.checkHealth();
for (const agent of unhealthy) {
// Reassign their tasks
await Task.router.reassignFrom(agent.id);
}
// 4. Notify on completions
const recent = await Task.query({
status: "completed",
completed_after: Date.now() - 60000 // Last minute
});
for (const task of recent) {
if (task.created_by === "main") {
sessions_send({
message: β
Task complete: ${task.title}\nResult: ${task.result}
});
}
}
## Routing Strategies
| Strategy | Use Case | Description |
|----------|----------|-------------|
| **round-robin** | Even load | Cycle through agents |
| **least-loaded** | Prevent overload | Agent with fewest active tasks |
| **fastest** | Latency critical | Agent with best completion time |
| **priority** | Urgent tasks | Sort by priority first |
| **sticky** | Sequential work | Same agent for related tasks |yaml
strategies:
default: least-loaded
# Per-task-type strategies
by_type:
research: least-loaded # Don't overwhelm one researcher
image_gen: round-robin # Even GPU utilization
urgent: priority # Always pick best agent
# Custom rules
rules:
then: fastest
then: sticky
## Task Lifecycle Details
PENDING ββassignβββ ASSIGNED ββackβββ RUNNING ββcompleteβββ COMPLETE
β β β β β
β β β βββfailβββββ β
β β β β β
β β β FAILED ββretryβββ
timeout β timeout (if retries < max) β
β β β (else dead letter) β
β β β β
βββββββββββββ΄βββββββββββββββββββββββββββββββββββββββββββββββββ
**State Definitions:**
- `pending`: Created, waiting for router
- `assigned`: Routed to agent, waiting for acceptance
- `running`: Agent acknowledged, working on it
- `complete`: Success, result available
- `failed`: Final failure (retries exhausted)
- `dead_letter`: Failed permanently, needs manual review
## Dead Letter Queue
When a task exhausts retries:
~/.openclaw/task-router/dead-letter/
βββ task-failed-001.yaml # Task with final error state
βββ task-failed-002.yaml
βββ index.yaml # Summary for admin review
bash
task dead-letter list
task dead-letter show task-failed-001
task dead-letter retry task-failed-001 # Force retry
task dead-letter reassign task-failed-001 --to watson
task dead-letter archive task-failed-001 # Ack and archive
## Best Practices
**Task Design:**
- Keep payloads JSON-serializable (no circular refs)
- Include output format hints in payload
- Use dependencies for true sequencing
- Set reasonable TTLs (don't block forever)
**Agent Design:**
- Register capabilities narrowly at first
- Set conservative max_concurrent
- Heartbeat should check for assigned tasks
- Always acknowledge β complete/fail cleanly
**Coordination Patterns:**
- Use `Task.spawn()` for fire-and-forget
- Use `Task.wait()` when user needs result now
- Chain dependent tasks vs one mega-task
- Let router handle retries, not agents
## Multi-Agent Exampletypescript
// User asks: "Research competitors and create a presentation"
// Main agent (you) orchestrates:
// 1. Create research tasks
const research = await Task.create({
type: "research",
title: "Research Gameye competitors",
payload: { query: "Gameye vs competitors" }
});
// 2. Create analysis task (depends on research)
const analysis = await Task.create({
type: "analysis",
title: "Analyze competitive landscape",
dependencies: [research.id],
payload: { input_task: research.id }
});
// 3. Create image task (independent, async)
const images = await Task.parallel([
{ type: "image_gen", title: "Competitor comparison chart", payload: {} },
{ type: "image_gen", title: "Market positioning diagram", payload: {} }
]);
// 4. Create presentation task (depends on all above)
const deck = await Task.create({
type: "presentation",
title: "Gameye competitive analysis deck",
dependencies: [analysis.id, ...images.map(i => i.id)],
payload: {
research: analysis.id,
images: images.map(i => i.result)
}
});
// 5. Wait for final result
const result = await Task.wait(deck.id, { timeout: 600 });
// Result: orchestrated 4 agents, 5 tasks, handled dependencies
## Troubleshootingbash
task router status # Check paused?
task agent list # Any healthy agents?
task list --status pending # Tasks waiting?
task show task-abc123 # Check assigned_to, started_at
task agent status watson # Is agent healthy?
task dead-letter list # Review patterns
task router logs # See routing decisions
task router drain # Wait for active
task list --status pending | xargs task cancel
task dead-letter clear
```
Generated Mar 1, 2026
A market research firm uses the Task Router to automate competitor analysis. The system creates research tasks from client requests, routes them to specialized agents with web search and analysis capabilities, and compiles reports. This enables asynchronous workflow coordination and load balancing across multiple research agents.
A digital marketing agency employs the Task Router to manage multi-step content workflows. Tasks for research, writing, and image generation are created and routed to agents based on capabilities, with dependencies ensuring proper sequencing. This handles async handoffs and rebalances loads to meet tight deadlines.
A tech company uses the Task Router to distribute support tickets to specialized agents by matching ticket types to agent capabilities like technical troubleshooting or billing. The system tracks task lifecycles, handles timeouts with dead letters, and rebalances loads during peak hours for efficient resolution.
A financial services firm leverages the Task Router to coordinate data collection, analysis, and report generation tasks across agents. Tasks are created programmatically from data feeds, routed to agents with analysis capabilities, and monitored for completion, enabling async coordination without blocking main sessions.
An e-commerce platform uses the Task Router to handle product research, image generation, and description writing tasks. The system routes tasks to specialized agents based on capabilities, tracks progress, and reassigns failed tasks to backup agents, ensuring consistent workflow across large catalogs.
Offer the Task Router as a cloud-based service with tiered pricing based on task volume, agent count, and advanced features like priority routing. Revenue comes from monthly subscriptions, with upsells for premium support and custom integrations.
Sell on-premise licenses to large organizations needing high customization and data control. Revenue includes upfront licensing fees, annual maintenance contracts, and consulting for deployment and workflow integration.
Charge based on actual usage metrics such as number of tasks routed, agents managed, or storage consumed. This model appeals to startups and SMBs with variable workloads, with revenue scaling directly with customer activity.
π¬ Integration Tip
Start by registering agents with clear capabilities and configuring routing strategies in config.yaml to match your workflow needs, then test with simple tasks before scaling.
Captures learnings, errors, and corrections to enable continuous improvement. Use when: (1) A command or operation fails unexpectedly, (2) User corrects Clau...
Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
Search and analyze your own session logs (older/parent conversations) using jq.
Typed knowledge graph for structured agent memory and composable skills. Use when creating/querying entities (Person, Project, Task, Event, Document), linking related objects, enforcing constraints, planning multi-step actions as graph transformations, or when skills need to share state. Trigger on "remember", "what do I know about", "link X to Y", "show dependencies", entity CRUD, or cross-skill data access.
Ultimate AI agent memory system for Cursor, Claude, ChatGPT & Copilot. WAL protocol + vector search + git-notes + cloud backup. Never lose context again. Vibe-coding ready.
Headless browser automation CLI optimized for AI agents with accessibility tree snapshots and ref-based element selection