{
  "schemaVersion": "1.0",
  "item": {
    "slug": "task-router-skill",
    "name": "Task Router Skill",
    "source": "tencent",
    "type": "skill",
    "category": "AI 智能",
    "sourceUrl": "https://clawhub.ai/capt-marbles/task-router-skill",
    "canonicalUrl": "https://clawhub.ai/capt-marbles/task-router-skill",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/task-router-skill",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=task-router-skill",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/task-router-skill"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/task-router-skill",
    "agentPageUrl": "https://openagent3.xyz/skills/task-router-skill/agent",
    "manifestUrl": "https://openagent3.xyz/skills/task-router-skill/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/task-router-skill/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Task Router",
        "body": "Distributed task queue for OpenClaw multi-agent systems. Central coordination, async handoffs, capability-based routing."
      },
      {
        "title": "Quick Start",
        "body": "# Install skill\nclawhub install task-router\n\n# Register an agent\ntask agent register watson --capabilities \"research analysis\" --max-concurrent 3\n\n# Create a task\ntask create --type research --title \"Competitor analysis\" --priority high\n\n# Router runs automatically via heartbeat\n# Check task status\ntask list --status pending\ntask show task-abc123"
      },
      {
        "title": "What This Does",
        "body": "Core Functions:\n\nEnqueue: Create tasks from any session (main or sub-agent)\nRoute: Match tasks to agents by capabilities\nTrack: Monitor task lifecycle (pending → active → complete/failed)\nAsync Coordination: Hand off work, check back later\nDead Letter: Handle timeouts and failures\nRebalance: Move stuck tasks, retry with fallbacks\n\nUse Cases:\n\nHeartbeat creates research task → auto-routes to research agent\nMain agent spawns work → goes async, checks later\nMulti-step workflows: Task A output → Task B input\nAgent failure → task reassigned to backup agent\nLoad balancing across multiple agents with same capabilities"
      },
      {
        "title": "File Layout",
        "body": "~/.openclaw/task-router/\n├── config.yaml           # Router settings, timeouts\n├── agents.yaml           # Agent registry + capabilities\n├── queue/                # Task state\n│   ├── pending/          # Waiting for assignment\n│   ├── active/           # Assigned to agent\n│   ├── completed/        # Finished successfully\n│   └── failed/           # Failed, exhausted retries\n└── logs/\n    └── router.log        # Routing decisions"
      },
      {
        "title": "config.yaml",
        "body": "router:\n  check_interval: 30           # Seconds between router runs\n  default_ttl: 3600            # Default task timeout\n  max_retries: 2\n  \n  strategies:\n    default: least-loaded      # round-robin | least-loaded | priority\n    by_type:\n      research: least-loaded\n      image_gen: round-robin\n      urgent: priority\n\n  health:\n    agent_timeout: 300           # Mark agent unhealthy after seconds\n    task_timeout:\n      warning: 1800              # Alert at 30 min\n      critical: 3600             # Fail at 1 hour\n\n  notifications:\n    on_complete: true\n    on_fail: true\n    channels: [main_session]   # Could add Discord, etc."
      },
      {
        "title": "agents.yaml (auto-maintained)",
        "body": "agents:\n  watson:\n    id: watson\n    emoji: 🔬\n    capabilities: [research, analysis, web_search]\n    max_concurrent: 3\n    current_tasks: [task-abc123, task-def456]\n    stats:\n      completed: 47\n      failed: 2\n      avg_duration: 180\n    health:\n      last_ping: 2026-02-13T09:15:00Z\n      status: healthy\n    \n  picasso:\n    id: picasso\n    emoji: 🎨\n    capabilities: [image_gen, image_edit]\n    max_concurrent: 2\n    current_tasks: []"
      },
      {
        "title": "Task Schema",
        "body": "id: task-abc123\ntype: research               # Matches agent capability\ntitle: Research Gameye competitors\ndescription: Deep competitive analysis\n\npayload:\n  query: Gameye vs competitors\n  sources: [web, apollo]\n  output_format: markdown\n  \ncreated_by: main             # Session label that created it\nassigned_to: watson          # null until routed\nassigned_by: router          # router | manual | agent\n\ncreated_at: 2026-02-13T09:00:00Z\nassigned_at: 2026-02-13T09:05:00Z\nstarted_at: 2026-02-13T09:06:00Z\ncompleted_at: null\nexpires_at: 2026-02-13T10:00:00Z  # created_at + ttl\n\npriority: high               # low | normal | high | urgent\nttl: 3600                    # Seconds\nretries: 0\nmax_retries: 2\n\ndependencies: []             # Block until these complete\nblocked_by: []               # Populated by router\n\nstatus: assigned             # pending | assigned | running | complete | failed\nresult: null                 # Path to result file\nerror: null                  # Error message if failed\n\nmetadata:\n  source: heartbeat\n  tags: [gameye, competitors]"
      },
      {
        "title": "Task Management",
        "body": "# Create task\ntask create --type research \\\n  --title \"Research Gameye competitors\" \\\n  --data '{\"query\": \"Gameye pricing\"}' \\\n  --priority high \\\n  --ttl 3600\n\n# Create with dependencies\ntask create --type analysis \\\n  --title \"Analyze research results\" \\\n  --depends-on task-abc123\n\n# List tasks\ntask list                    # All non-completed\ntask list --status pending\ntask list --assigned-to watson\ntask list --type research --limit 10\ntask list --created-after 2026-02-13\n\n# Show task\ntask show task-abc123        # Full details + result preview\n\n# Manage tasks\ntask cancel task-abc123      # Cancel pending or active\ntask retry task-abc123       # Move failed back to pending\ntask reprioritize task-abc123 --priority urgent\n\n# Results\ntask result task-abc123      # View result file\ntask export --status completed --since 2026-02-13 > ~/reports/tasks.ndjson"
      },
      {
        "title": "Agent Management",
        "body": "# Register agent (required before routing)\ntask agent register watson \\\n  --capabilities \"research analysis web_search\" \\\n  --max-concurrent 3 \\\n  --emoji 🔬\n\n# Update agent\ntask agent update watson --add-capability \"competitive-analysis\"\ntask agent update watson --max-concurrent 5\n\n# Check agent health\ntask agent status watson     # Current tasks, health, stats\ntask agent ping watson       # Health check ping\n\n# List agents\ntask agent list              # All agents\ntask agent list --capable-of research\n\n# Unregister\ntask agent unregister watson --reassign-tasks"
      },
      {
        "title": "Router Control",
        "body": "# Status\ntask router status           # Queue depth, agent health\n\n# Control flow\ntask router pause            # Stop new assignments\ntask router resume           # Resume routing\ntask router rebalance        # Redistribute stuck tasks\n\n# Maintenance  \ntask router cleanup          # Archive old completed tasks\ntask router drain            # Finish active, no new pending"
      },
      {
        "title": "Programmatic API",
        "body": "import * as Task from \"~/.openclaw/task-router/sdk\";\n\n// === Creating Tasks ===\n\n// Simple create\nconst task = await Task.create({\n  type: \"research\",\n  title: \"Competitor analysis\",\n  payload: { query: \"Gameye vs competitors\" }\n});\n\n// With options\nconst task = await Task.create({\n  type: \"image_gen\",\n  title: \"Generate hero image\",\n  payload: { prompt: \"Futuristic game server...\", size: \"1024x1024\" },\n  priority: \"high\",\n  ttl: 1800,\n  max_retries: 1,\n  dependencies: [previousTaskId],  // Waits for these first\n  created_by: \"main\"\n});\n\n// === Querying ===\n\n// Get status\nconst status = await Task.status(task.id);\n// { id, status, assigned_to, created_at, expires_at }\n\n// Wait for completion (blocking)\nconst result = await Task.wait(task.id, { timeout: 300, pollInterval: 5 });\n\n// List with filters\nconst pending = await Task.query({\n  status: \"pending\",\n  type: \"research\",\n  priority: \"high\",\n  limit: 10\n});\n\nconst myTasks = await Task.query({\n  created_by: \"main\",\n  status: [\"assigned\", \"running\"]\n});\n\n// === Agent Integration ===\n\n// Agent picks up work (if auto-assign disabled)\nawait Task.claim({\n  agentId: \"watson\",\n  capableOf: \"research\",\n  limit: 1\n});\n\n// Complete task\nawait Task.complete(task.id, {\n  result_path: \"~/agents/watson/memory/results/competitors.md\",\n  summary: \"Found 5 competitors: GameLift, Multiplay, Hathora, Edgegap, Agones\",\n  metadata: { competitors_count: 5 }\n});\n\n// Fail task\nawait Task.fail(task.id, {\n  reason: \"API quota exceeded\",\n  retryable: true  // Will auto-retry\n});\n\n// === Multi-Step Workflows ===\n\n// Chain tasks\nconst analysisTask = await Task.chain(researchTask.id, {\n  type: \"analysis\",\n  title: \"Analyze research findings\",\n  payload: { input_task: researchTask.id }\n});\n\n// Parallel tasks\nconst tasks = await Task.parallel([\n  { type: \"research\", title: \"Research A\", payload: {} },\n  { type: \"research\", title: \"Research B\", payload: {} },\n  { type: \"research\", title: \"Research C\", payload: {} }\n]);\nawait Task.waitAll(tasks.map(t => t.id));\n\n// === Agent Session Integration ===\n\n// Spawn via task router (recommended for async work)\nconst spawnResult = await Task.spawn({\n  taskId: task.id,\n  agentId: \"watson\",      // Optional: auto-route if omitted\n  useSession: true      // Use sessions_spawn vs sessions_send\n});\n\n// Router will call:\n// sessions_spawn({ agentId, task, label: task.id })"
      },
      {
        "title": "HEARTBEAT Integration",
        "body": "Create ~/.openclaw/workspace/HEARTBEAT.md:\n\n# Task Router Heartbeat\n\n## Router Cycle (runs every 30s)\n```typescript\nimport * as Task from \"~/.openclaw/task-router/sdk\";\n\n// 1. Auto-route pending tasks\nconst routed = await Task.router.cycle();\nif (routed.length > 0) {\n  Task.log(`Routed ${routed.length} tasks:`, routed.map(t => `${t.id} → ${t.assigned_to}`));\n}\n\n// 2. Check for timeouts\nconst timeouts = await Task.router.checkTimeouts();\nfor (const task of timeouts) {\n  if (task.retries < task.max_retries) {\n    Task.log(`Retrying ${task.id} after timeout`);\n    await Task.retry(task.id);\n  } else {\n    Task.log(`Dead lettering ${task.id}`);\n    await Task.router.moveToDeadLetter(task);\n  }\n}\n\n// 3. Check agent health\nconst unhealthy = await Task.agents.checkHealth();\nfor (const agent of unhealthy) {\n  // Reassign their tasks\n  await Task.router.reassignFrom(agent.id);\n}\n\n// 4. Notify on completions\nconst recent = await Task.query({\n  status: \"completed\",\n  completed_after: Date.now() - 60000  // Last minute\n});\nfor (const task of recent) {\n  if (task.created_by === \"main\") {\n    sessions_send({\n      message: `✅ Task complete: ${task.title}\\nResult: ${task.result}`\n    });\n  }\n}"
      },
      {
        "title": "Routing Strategies",
        "body": "StrategyUse CaseDescriptionround-robinEven loadCycle through agentsleast-loadedPrevent overloadAgent with fewest active tasksfastestLatency criticalAgent with best completion timepriorityUrgent tasksSort by priority firststickySequential workSame agent for related tasks\n\n# config.yaml\nstrategies:\n  default: least-loaded\n  \n  # Per-task-type strategies\n  by_type:\n    research: least-loaded      # Don't overwhelm one researcher\n    image_gen: round-robin      # Even GPU utilization\n    urgent: priority             # Always pick best agent\n    \n  # Custom rules\n  rules:\n    - if: priority == urgent\n      then: fastest\n    - if: tags includes \"sticky\"\n      then: sticky"
      },
      {
        "title": "Task Lifecycle Details",
        "body": "PENDING ──assign──→ ASSIGNED ──ack──→ RUNNING ──complete──→ COMPLETE\n   │           │          │              │                      │\n   │           │          │              └──fail────┐            │\n   │           │          │                        ↓            │\n   │           │          │                     FAILED ──retry──┘\n timeout      │       timeout        (if retries < max)        │\n   │           │          │                (else dead letter)    │\n   │           │          │                                     │\n   └───────────┴──────────┘─────────────────────────────────────┘\n\nState Definitions:\n\npending: Created, waiting for router\nassigned: Routed to agent, waiting for acceptance\nrunning: Agent acknowledged, working on it\ncomplete: Success, result available\nfailed: Final failure (retries exhausted)\ndead_letter: Failed permanently, needs manual review"
      },
      {
        "title": "Dead Letter Queue",
        "body": "When a task exhausts retries:\n\n~/.openclaw/task-router/dead-letter/\n├── task-failed-001.yaml       # Task with final error state\n├── task-failed-002.yaml\n└── index.yaml                 # Summary for admin review\n\n# Review failed tasks\ntask dead-letter list\ntask dead-letter show task-failed-001\n\n# Actions\ntask dead-letter retry task-failed-001      # Force retry\ntask dead-letter reassign task-failed-001 --to watson\ntask dead-letter archive task-failed-001   # Ack and archive"
      },
      {
        "title": "Best Practices",
        "body": "Task Design:\n\nKeep payloads JSON-serializable (no circular refs)\nInclude output format hints in payload\nUse dependencies for true sequencing\nSet reasonable TTLs (don't block forever)\n\nAgent Design:\n\nRegister capabilities narrowly at first\nSet conservative max_concurrent\nHeartbeat should check for assigned tasks\nAlways acknowledge → complete/fail cleanly\n\nCoordination Patterns:\n\nUse Task.spawn() for fire-and-forget\nUse Task.wait() when user needs result now\nChain dependent tasks vs one mega-task\nLet router handle retries, not agents"
      },
      {
        "title": "Multi-Agent Example",
        "body": "// User asks: \"Research competitors and create a presentation\"\n\n// Main agent (you) orchestrates:\n\n// 1. Create research tasks\nconst research = await Task.create({\n  type: \"research\",\n  title: \"Research Gameye competitors\",\n  payload: { query: \"Gameye vs competitors\" }\n});\n\n// 2. Create analysis task (depends on research)\nconst analysis = await Task.create({\n  type: \"analysis\",\n  title: \"Analyze competitive landscape\",\n  dependencies: [research.id],\n  payload: { input_task: research.id }\n});\n\n// 3. Create image task (independent, async)\nconst images = await Task.parallel([\n  { type: \"image_gen\", title: \"Competitor comparison chart\", payload: {} },\n  { type: \"image_gen\", title: \"Market positioning diagram\", payload: {} }\n]);\n\n// 4. Create presentation task (depends on all above)\nconst deck = await Task.create({\n  type: \"presentation\",\n  title: \"Gameye competitive analysis deck\",\n  dependencies: [analysis.id, ...images.map(i => i.id)],\n  payload: { \n    research: analysis.id,\n    images: images.map(i => i.result)\n  }\n});\n\n// 5. Wait for final result\nconst result = await Task.wait(deck.id, { timeout: 600 });\n\n// Result: orchestrated 4 agents, 5 tasks, handled dependencies"
      },
      {
        "title": "Troubleshooting",
        "body": "# Nothing routing?\ntask router status           # Check paused?\ntask agent list             # Any healthy agents?\ntask list --status pending  # Tasks waiting?\n\n# Task stuck?\ntask show task-abc123        # Check assigned_to, started_at\ntask agent status watson     # Is agent healthy?\n\n# Agent not picking up?\n# - Check agent's HEARTBEAT checks for tasks\n# - Verify sessions_send to agent works\n\n# Too many failures?\ntask dead-letter list       # Review patterns\ntask router logs            # See routing decisions\n\n# Clear everything (nuke)\ntask router drain           # Wait for active\ntask list --status pending | xargs task cancel\ntask dead-letter clear"
      },
      {
        "title": "Requirements",
        "body": "OpenClaw with sessions_send/sessions_spawn/sessions_list\nAgents with proper HEARTBEAT.md checking for tasks\nOptional: cron job for router if heartbeat not reliable"
      },
      {
        "title": "Future Extensions",
        "body": "Metrics: Prometheus-compatible stats\nWeb UI: Dashboard at localhost:3333\nPlugins: Slack/Discord notifications\n**Priority Queues"
      }
    ],
    "body": "Task Router\n\nDistributed task queue for OpenClaw multi-agent systems. Central coordination, async handoffs, capability-based routing.\n\nQuick Start\n# Install skill\nclawhub install task-router\n\n# Register an agent\ntask agent register watson --capabilities \"research analysis\" --max-concurrent 3\n\n# Create a task\ntask create --type research --title \"Competitor analysis\" --priority high\n\n# Router runs automatically via heartbeat\n# Check task status\ntask list --status pending\ntask show task-abc123\n\nWhat This Does\n\nCore Functions:\n\nEnqueue: Create tasks from any session (main or sub-agent)\nRoute: Match tasks to agents by capabilities\nTrack: Monitor task lifecycle (pending → active → complete/failed)\nAsync Coordination: Hand off work, check back later\nDead Letter: Handle timeouts and failures\nRebalance: Move stuck tasks, retry with fallbacks\n\nUse Cases:\n\nHeartbeat creates research task → auto-routes to research agent\nMain agent spawns work → goes async, checks later\nMulti-step workflows: Task A output → Task B input\nAgent failure → task reassigned to backup agent\nLoad balancing across multiple agents with same capabilities\nConfiguration\nFile Layout\n~/.openclaw/task-router/\n├── config.yaml           # Router settings, timeouts\n├── agents.yaml           # Agent registry + capabilities\n├── queue/                # Task state\n│   ├── pending/          # Waiting for assignment\n│   ├── active/           # Assigned to agent\n│   ├── completed/        # Finished successfully\n│   └── failed/           # Failed, exhausted retries\n└── logs/\n    └── router.log        # Routing decisions\n\nconfig.yaml\nrouter:\n  check_interval: 30           # Seconds between router runs\n  default_ttl: 3600            # Default task timeout\n  max_retries: 2\n  \n  strategies:\n    default: least-loaded      # round-robin | least-loaded | priority\n    by_type:\n      research: least-loaded\n      image_gen: round-robin\n      urgent: priority\n\n  health:\n    agent_timeout: 300           # Mark agent unhealthy after seconds\n    task_timeout:\n      warning: 1800              # Alert at 30 min\n      critical: 3600             # Fail at 1 hour\n\n  notifications:\n    on_complete: true\n    on_fail: true\n    channels: [main_session]   # Could add Discord, etc.\n\nagents.yaml (auto-maintained)\nagents:\n  watson:\n    id: watson\n    emoji: 🔬\n    capabilities: [research, analysis, web_search]\n    max_concurrent: 3\n    current_tasks: [task-abc123, task-def456]\n    stats:\n      completed: 47\n      failed: 2\n      avg_duration: 180\n    health:\n      last_ping: 2026-02-13T09:15:00Z\n      status: healthy\n    \n  picasso:\n    id: picasso\n    emoji: 🎨\n    capabilities: [image_gen, image_edit]\n    max_concurrent: 2\n    current_tasks: []\n\nTask Schema\nid: task-abc123\ntype: research               # Matches agent capability\ntitle: Research Gameye competitors\ndescription: Deep competitive analysis\n\npayload:\n  query: Gameye vs competitors\n  sources: [web, apollo]\n  output_format: markdown\n  \ncreated_by: main             # Session label that created it\nassigned_to: watson          # null until routed\nassigned_by: router          # router | manual | agent\n\ncreated_at: 2026-02-13T09:00:00Z\nassigned_at: 2026-02-13T09:05:00Z\nstarted_at: 2026-02-13T09:06:00Z\ncompleted_at: null\nexpires_at: 2026-02-13T10:00:00Z  # created_at + ttl\n\npriority: high               # low | normal | high | urgent\nttl: 3600                    # Seconds\nretries: 0\nmax_retries: 2\n\ndependencies: []             # Block until these complete\nblocked_by: []               # Populated by router\n\nstatus: assigned             # pending | assigned | running | complete | failed\nresult: null                 # Path to result file\nerror: null                  # Error message if failed\n\nmetadata:\n  source: heartbeat\n  tags: [gameye, competitors]\n\nCLI Commands\nTask Management\n# Create task\ntask create --type research \\\n  --title \"Research Gameye competitors\" \\\n  --data '{\"query\": \"Gameye pricing\"}' \\\n  --priority high \\\n  --ttl 3600\n\n# Create with dependencies\ntask create --type analysis \\\n  --title \"Analyze research results\" \\\n  --depends-on task-abc123\n\n# List tasks\ntask list                    # All non-completed\ntask list --status pending\ntask list --assigned-to watson\ntask list --type research --limit 10\ntask list --created-after 2026-02-13\n\n# Show task\ntask show task-abc123        # Full details + result preview\n\n# Manage tasks\ntask cancel task-abc123      # Cancel pending or active\ntask retry task-abc123       # Move failed back to pending\ntask reprioritize task-abc123 --priority urgent\n\n# Results\ntask result task-abc123      # View result file\ntask export --status completed --since 2026-02-13 > ~/reports/tasks.ndjson\n\nAgent Management\n# Register agent (required before routing)\ntask agent register watson \\\n  --capabilities \"research analysis web_search\" \\\n  --max-concurrent 3 \\\n  --emoji 🔬\n\n# Update agent\ntask agent update watson --add-capability \"competitive-analysis\"\ntask agent update watson --max-concurrent 5\n\n# Check agent health\ntask agent status watson     # Current tasks, health, stats\ntask agent ping watson       # Health check ping\n\n# List agents\ntask agent list              # All agents\ntask agent list --capable-of research\n\n# Unregister\ntask agent unregister watson --reassign-tasks\n\nRouter Control\n# Status\ntask router status           # Queue depth, agent health\n\n# Control flow\ntask router pause            # Stop new assignments\ntask router resume           # Resume routing\ntask router rebalance        # Redistribute stuck tasks\n\n# Maintenance  \ntask router cleanup          # Archive old completed tasks\ntask router drain            # Finish active, no new pending\n\nProgrammatic API\nimport * as Task from \"~/.openclaw/task-router/sdk\";\n\n// === Creating Tasks ===\n\n// Simple create\nconst task = await Task.create({\n  type: \"research\",\n  title: \"Competitor analysis\",\n  payload: { query: \"Gameye vs competitors\" }\n});\n\n// With options\nconst task = await Task.create({\n  type: \"image_gen\",\n  title: \"Generate hero image\",\n  payload: { prompt: \"Futuristic game server...\", size: \"1024x1024\" },\n  priority: \"high\",\n  ttl: 1800,\n  max_retries: 1,\n  dependencies: [previousTaskId],  // Waits for these first\n  created_by: \"main\"\n});\n\n// === Querying ===\n\n// Get status\nconst status = await Task.status(task.id);\n// { id, status, assigned_to, created_at, expires_at }\n\n// Wait for completion (blocking)\nconst result = await Task.wait(task.id, { timeout: 300, pollInterval: 5 });\n\n// List with filters\nconst pending = await Task.query({\n  status: \"pending\",\n  type: \"research\",\n  priority: \"high\",\n  limit: 10\n});\n\nconst myTasks = await Task.query({\n  created_by: \"main\",\n  status: [\"assigned\", \"running\"]\n});\n\n// === Agent Integration ===\n\n// Agent picks up work (if auto-assign disabled)\nawait Task.claim({\n  agentId: \"watson\",\n  capableOf: \"research\",\n  limit: 1\n});\n\n// Complete task\nawait Task.complete(task.id, {\n  result_path: \"~/agents/watson/memory/results/competitors.md\",\n  summary: \"Found 5 competitors: GameLift, Multiplay, Hathora, Edgegap, Agones\",\n  metadata: { competitors_count: 5 }\n});\n\n// Fail task\nawait Task.fail(task.id, {\n  reason: \"API quota exceeded\",\n  retryable: true  // Will auto-retry\n});\n\n// === Multi-Step Workflows ===\n\n// Chain tasks\nconst analysisTask = await Task.chain(researchTask.id, {\n  type: \"analysis\",\n  title: \"Analyze research findings\",\n  payload: { input_task: researchTask.id }\n});\n\n// Parallel tasks\nconst tasks = await Task.parallel([\n  { type: \"research\", title: \"Research A\", payload: {} },\n  { type: \"research\", title: \"Research B\", payload: {} },\n  { type: \"research\", title: \"Research C\", payload: {} }\n]);\nawait Task.waitAll(tasks.map(t => t.id));\n\n// === Agent Session Integration ===\n\n// Spawn via task router (recommended for async work)\nconst spawnResult = await Task.spawn({\n  taskId: task.id,\n  agentId: \"watson\",      // Optional: auto-route if omitted\n  useSession: true      // Use sessions_spawn vs sessions_send\n});\n\n// Router will call:\n// sessions_spawn({ agentId, task, label: task.id })\n\nHEARTBEAT Integration\n\nCreate ~/.openclaw/workspace/HEARTBEAT.md:\n\n# Task Router Heartbeat\n\n## Router Cycle (runs every 30s)\n```typescript\nimport * as Task from \"~/.openclaw/task-router/sdk\";\n\n// 1. Auto-route pending tasks\nconst routed = await Task.router.cycle();\nif (routed.length > 0) {\n  Task.log(`Routed ${routed.length} tasks:`, routed.map(t => `${t.id} → ${t.assigned_to}`));\n}\n\n// 2. Check for timeouts\nconst timeouts = await Task.router.checkTimeouts();\nfor (const task of timeouts) {\n  if (task.retries < task.max_retries) {\n    Task.log(`Retrying ${task.id} after timeout`);\n    await Task.retry(task.id);\n  } else {\n    Task.log(`Dead lettering ${task.id}`);\n    await Task.router.moveToDeadLetter(task);\n  }\n}\n\n// 3. Check agent health\nconst unhealthy = await Task.agents.checkHealth();\nfor (const agent of unhealthy) {\n  // Reassign their tasks\n  await Task.router.reassignFrom(agent.id);\n}\n\n// 4. Notify on completions\nconst recent = await Task.query({\n  status: \"completed\",\n  completed_after: Date.now() - 60000  // Last minute\n});\nfor (const task of recent) {\n  if (task.created_by === \"main\") {\n    sessions_send({\n      message: `✅ Task complete: ${task.title}\\nResult: ${task.result}`\n    });\n  }\n}\n\nRouting Strategies\nStrategy\tUse Case\tDescription\nround-robin\tEven load\tCycle through agents\nleast-loaded\tPrevent overload\tAgent with fewest active tasks\nfastest\tLatency critical\tAgent with best completion time\npriority\tUrgent tasks\tSort by priority first\nsticky\tSequential work\tSame agent for related tasks\n# config.yaml\nstrategies:\n  default: least-loaded\n  \n  # Per-task-type strategies\n  by_type:\n    research: least-loaded      # Don't overwhelm one researcher\n    image_gen: round-robin      # Even GPU utilization\n    urgent: priority             # Always pick best agent\n    \n  # Custom rules\n  rules:\n    - if: priority == urgent\n      then: fastest\n    - if: tags includes \"sticky\"\n      then: sticky\n\nTask Lifecycle Details\nPENDING ──assign──→ ASSIGNED ──ack──→ RUNNING ──complete──→ COMPLETE\n   │           │          │              │                      │\n   │           │          │              └──fail────┐            │\n   │           │          │                        ↓            │\n   │           │          │                     FAILED ──retry──┘\n timeout      │       timeout        (if retries < max)        │\n   │           │          │                (else dead letter)    │\n   │           │          │                                     │\n   └───────────┴──────────┘─────────────────────────────────────┘\n\n\nState Definitions:\n\npending: Created, waiting for router\nassigned: Routed to agent, waiting for acceptance\nrunning: Agent acknowledged, working on it\ncomplete: Success, result available\nfailed: Final failure (retries exhausted)\ndead_letter: Failed permanently, needs manual review\nDead Letter Queue\n\nWhen a task exhausts retries:\n\n~/.openclaw/task-router/dead-letter/\n├── task-failed-001.yaml       # Task with final error state\n├── task-failed-002.yaml\n└── index.yaml                 # Summary for admin review\n\n# Review failed tasks\ntask dead-letter list\ntask dead-letter show task-failed-001\n\n# Actions\ntask dead-letter retry task-failed-001      # Force retry\ntask dead-letter reassign task-failed-001 --to watson\ntask dead-letter archive task-failed-001   # Ack and archive\n\nBest Practices\n\nTask Design:\n\nKeep payloads JSON-serializable (no circular refs)\nInclude output format hints in payload\nUse dependencies for true sequencing\nSet reasonable TTLs (don't block forever)\n\nAgent Design:\n\nRegister capabilities narrowly at first\nSet conservative max_concurrent\nHeartbeat should check for assigned tasks\nAlways acknowledge → complete/fail cleanly\n\nCoordination Patterns:\n\nUse Task.spawn() for fire-and-forget\nUse Task.wait() when user needs result now\nChain dependent tasks vs one mega-task\nLet router handle retries, not agents\nMulti-Agent Example\n// User asks: \"Research competitors and create a presentation\"\n\n// Main agent (you) orchestrates:\n\n// 1. Create research tasks\nconst research = await Task.create({\n  type: \"research\",\n  title: \"Research Gameye competitors\",\n  payload: { query: \"Gameye vs competitors\" }\n});\n\n// 2. Create analysis task (depends on research)\nconst analysis = await Task.create({\n  type: \"analysis\",\n  title: \"Analyze competitive landscape\",\n  dependencies: [research.id],\n  payload: { input_task: research.id }\n});\n\n// 3. Create image task (independent, async)\nconst images = await Task.parallel([\n  { type: \"image_gen\", title: \"Competitor comparison chart\", payload: {} },\n  { type: \"image_gen\", title: \"Market positioning diagram\", payload: {} }\n]);\n\n// 4. Create presentation task (depends on all above)\nconst deck = await Task.create({\n  type: \"presentation\",\n  title: \"Gameye competitive analysis deck\",\n  dependencies: [analysis.id, ...images.map(i => i.id)],\n  payload: { \n    research: analysis.id,\n    images: images.map(i => i.result)\n  }\n});\n\n// 5. Wait for final result\nconst result = await Task.wait(deck.id, { timeout: 600 });\n\n// Result: orchestrated 4 agents, 5 tasks, handled dependencies\n\nTroubleshooting\n# Nothing routing?\ntask router status           # Check paused?\ntask agent list             # Any healthy agents?\ntask list --status pending  # Tasks waiting?\n\n# Task stuck?\ntask show task-abc123        # Check assigned_to, started_at\ntask agent status watson     # Is agent healthy?\n\n# Agent not picking up?\n# - Check agent's HEARTBEAT checks for tasks\n# - Verify sessions_send to agent works\n\n# Too many failures?\ntask dead-letter list       # Review patterns\ntask router logs            # See routing decisions\n\n# Clear everything (nuke)\ntask router drain           # Wait for active\ntask list --status pending | xargs task cancel\ntask dead-letter clear\n\nRequirements\nOpenClaw with sessions_send/sessions_spawn/sessions_list\nAgents with proper HEARTBEAT.md checking for tasks\nOptional: cron job for router if heartbeat not reliable\nFuture Extensions\nMetrics: Prometheus-compatible stats\nWeb UI: Dashboard at localhost:3333\nPlugins: Slack/Discord notifications\n**Priority Queues"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/capt-marbles/task-router-skill",
    "publisherUrl": "https://clawhub.ai/capt-marbles/task-router-skill",
    "owner": "capt-marbles",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/task-router-skill",
    "downloadUrl": "https://openagent3.xyz/downloads/task-router-skill",
    "agentUrl": "https://openagent3.xyz/skills/task-router-skill/agent",
    "manifestUrl": "https://openagent3.xyz/skills/task-router-skill/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/task-router-skill/agent.md"
  }
}