🎁 Get the FREE AI Skills Starter Guide β€” Subscribe β†’
BytesAgainBytesAgain
πŸ¦€ ClawHub

Agent Swarm

by @austindixson

IMPORTANT: OpenRouter is required. Routes tasks to the right model and always delegates work through sessions_spawn.

Versionv1.7.19
Downloads3,074
Installs28
Stars⭐ 4
Comments2
TERMINAL
clawhub install agent-swarm

πŸ“– About This Skill


name: agent-swarm displayName: Agent Swarm | OpenClaw Skill description: IMPORTANT: OpenRouter is required. Routes tasks to the right model and always delegates work through sessions_spawn. Rejects prompt-injection patterns in task strings (v1.7.6+). version: 1.7.8

Agent Swarm | OpenClaw Skill

Description

IMPORTANT: OpenRouter is required. Routes tasks to the right model and always delegates work through sessions_spawn.

Before installing

  • OPENCLAW_HOME: Not required. The skill uses OPENCLAW_HOME only if set; otherwise it defaults to ~/.openclaw. This is consistent in both metadata (_meta.json: listed in optionalEnv, not in env) and behavior.
  • openclaw.json read access: The skill reads the local file openclaw.json (at $OPENCLAW_HOME/openclaw.json or ~/.openclaw/openclaw.json). Only the fields tools.exec.host and tools.exec.node are used; no gateway secrets or API keys are read. Verify you are comfortable granting read access to that file before installing.
  • Examples

    Single task

    Router output: {"task":"write a poem","model":"openrouter/moonshotai/kimi-k2.5","sessionTarget":"isolated"}

    Then call: sessions_spawn(task="write a poem", model="openrouter/moonshotai/kimi-k2.5", sessionTarget="isolated")

    Parallel tasks

    python3 workspace/skills/agent-swarm/scripts/router.py spawn --json --multi "fix bug and write poem"
    

    This returns multiple spawn configs. Start one sub-agent per config.

    Commands

    Manual/CLI use only. The examples below pass the task as a single argument; for programmatic use with untrusted user input, always invoke the router via subprocess.run(..., [..., user_message], ...) with a list of arguments (see Security). Do not build a shell command string from user input.

    python scripts/router.py default
    python scripts/router.py classify "fix lint errors"
    python scripts/router.py spawn --json "write a poem"
    python scripts/router.py spawn --json --multi "fix bug and write poem"
    python scripts/router.py models
    

    What this skill does

    Agent Swarm is a traffic cop for AI models. It picks the best model for each task, then starts a sub-agent to do the work.

    IMPORTANT: OpenRouter is required

    Required Platform Configuration:

  • OpenRouter API key: Must be configured in OpenClaw platform settings (not provided by this skill)
  • OPENCLAW_HOME (optional): Environment variable pointing to OpenClaw workspace root. If not set, defaults to ~/.openclaw
  • openclaw.json access: The router reads tools.exec.host and tools.exec.node from openclaw.json (located at $OPENCLAW_HOME/openclaw.json or ~/.openclaw/openclaw.json). Only these two fields are accessed; no gateway secrets or API keys are read.
  • Model Requirements:

  • Model IDs must use openrouter/... prefix
  • If OpenRouter is not configured in OpenClaw, delegation will fail
  • Why this helps

  • Faster replies (cheap orchestrator, smart sub-agent routing)
  • Better quality (code tasks go to code models, writing tasks go to writing models)
  • Lower cost (you do not run every task on the most expensive model)
  • Core rule (non-negotiable)

    For user tasks, the orchestrator must delegate. It must NOT answer the task itself.

    Use this flow every time:

    1. Run router. From orchestrator code, use subprocess with a list of arguments (never shell interpolation with user input):

       import subprocess
       result = subprocess.run(
           ["python3", "/path/to/workspace/skills/agent-swarm/scripts/router.py", "spawn", "--json", user_message],
           capture_output=True,
           text=True
       )
       data = json.loads(result.stdout) if result.returncode == 0 else {}
       
    CLI only (manual testing; do not use from code with untrusted user input): python3 workspace/skills/agent-swarm/scripts/router.py spawn --json "your task here" Use OPENCLAW_HOME or absolute path for the script when not in workspace root. 2. If needs_config_patch is true: stop and report that patch to the user. 3. Otherwise call: sessions_spawn(task=..., model=..., sessionTarget=...) 4. Wait for sessions_spawn result. 5. Return the sub-agent result to the user.

    If sessions_spawn fails, return only a delegation failure message. Do not do the task yourself.

    Config basics

    Edit config.json in the skill root (parent of scripts/) to change routing.

    What you can change

    | What | Key | Purpose | |------|-----|--------| | Orchestrator / session default | default_model | Main agent and new sessions (e.g. Gemini 2.5 Flash) | | Task-specific model per tier | routing_rules..primary | Model used when a task matches that tier | | Backup models if primary fails | routing_rules..fallback | Array of model IDs to try next |

    All task-specific tiers (change the model for each)

    | Tier | Key to change primary | Typical use | |------|------------------------|-------------| | FAST | routing_rules.FAST.primary | Simple tasks: check, list, status, fetch | | REASONING | routing_rules.REASONING.primary | Logic, math, step-by-step analysis | | CREATIVE | routing_rules.CREATIVE.primary | Writing, stories, UI/UX, design | | RESEARCH | routing_rules.RESEARCH.primary | Research, search, fact-finding | | CODE | routing_rules.CODE.primary | Code, debug, refactor, implement | | QUALITY | routing_rules.QUALITY.primary | Complex/architecture tasks | | COMPLEX | routing_rules.COMPLEX.primary | Multi-step / complex system tasks | | VISION | routing_rules.VISION.primary | Image analysis, screenshots, visual |

    To change all task-specific models: edit each routing_rules..primary above. Use model IDs from the models array in config.json (must start with openrouter/).

    Simple config examples

    Orchestrator only (keep defaults for tiers):

    {
      "default_model": "openrouter/google/gemini-2.5-flash"
    }
    
    (Other keys like routing_rules and models can stay as in the shipped config.json.)

    Change one tier (e.g. CODE to MiniMax):

    "routing_rules": {
      "CODE": {
        "primary": "openrouter/minimax/minimax-m2.5",
        "fallback": ["openrouter/qwen/qwen3-coder-flash"]
      }
    }
    

    Change multiple tiers (primaries only):

    "routing_rules": {
      "CREATIVE": { "primary": "openrouter/moonshotai/kimi-k2.5", "fallback": [] },
      "CODE":     { "primary": "openrouter/z-ai/glm-4.7-flash", "fallback": ["openrouter/minimax/minimax-m2.5"] },
      "RESEARCH": { "primary": "openrouter/x-ai/grok-4.1-fast", "fallback": [] }
    }
    
    Only include tiers you want to override; the rest are read from the full config.json.

    Security

    Input Validation

    The router validates and sanitizes all inputs to prevent injection attacks:

  • Task strings: Validated for length (max 10KB), null bytes; rejects prompt-injection patterns (script tags, javascript: protocol, event-handler attributes). Invalid tasks raise ValueError with a clear message.
  • Config patches: Only allows modifications to tools.exec.host and tools.exec.node (whitelist approach)
  • Labels: Validated for length and null bytes
  • Safe Execution

    Critical: When calling router.py from orchestrator code, always use subprocess with a list of arguments, never shell string interpolation:

    # βœ… SAFE: Use subprocess with list arguments
    import subprocess
    result = subprocess.run(
        ["python3", "/path/to/router.py", "spawn", "--json", user_message],
        capture_output=True,
        text=True
    )

    ❌ UNSAFE: Shell string interpolation (vulnerable to injection)

    import os os.system(f'python3 router.py spawn --json "{user_message}"') # DON'T DO THIS

    The router uses Python's argparse, which safely handles arguments when passed as a list. Shell string interpolation is vulnerable to command injection if the user message contains shell metacharacters.

    Config Patch Safety

    The recommended_config_patch only modifies safe fields:

  • tools.exec.host (must be 'sandbox' or 'node')
  • tools.exec.node (only when host is 'node')
  • All config patches are validated before being returned. The orchestrator should validate patches again before applying them to openclaw.json.

    Prompt Injection Mitigation

    The router rejects task strings that contain prompt-injection patterns (e.g.