"IMPORTANT: OpenRouter is required. Routes tasks to the right model
Scanned 9/7/2026
Install to Claude Code
npx -y skills add modbender/skill-library-mcp --skill agent-swarm --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Agent Swarm?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/modbender-agent-swarm)More formats (shields.io, HTML) on the badges page.
---
name: agent-swarm
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+)."
---
# 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
```bash
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.
```bash
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):**
```python
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.<TIER>.primary` | Model used when a task matches that tier |
| Backup models if primary fails | `routing_rules.<TIER>.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.<TIER>.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):**
```json
{
"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):**
```json
"routing_rules": {
"CODE": {
"primary": "openrouter/minimax/minimax-m2.5",
"fallback": ["openrouter/qwen/qwen3-coder-flash"]
}
}
```
**Change multiple tiers (primaries only):**
```json
"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:
```python
# ✅ 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. `<script>`, `javascript:`, `onclick=`). Rejected tasks raise `ValueError`; the orchestrator should surface a clear message and not pass the task to sub-agents. Additional layers:
1. The orchestrator (validating task strings and handling rejections)
2. The sub-agent LLM (resisting prompt injection)
3. The OpenClaw platform (sanitizing `sessions_spawn` inputs)
### File Access
**Required File Access:**
- **Read**: `openclaw.json` (located via `OPENCLAW_HOME` environment variable or `~/.openclaw/openclaw.json`)
- **Fields accessed**: `tools.exec.host` and `tools.exec.node` only
- **Purpose**: Determine execution environment for spawned sub-agents
- **Security**: The router does NOT read gateway secrets, API keys, or any other sensitive configuration
**Write Access:**
- **Write**: None (no files are written by this skill)
- **Config patches**: The skill may return `recommended_config_patch` JSON that the orchestrator can apply, but the skill itself does not write to `openclaw.json`
**Security Guarantees:**
- The router does not persist, upload, or transmit any tokens or credentials
- Only `tools.exec.host` and `tools.exec.node` are accessed from `openclaw.json`
- All file access is read-only except for validated config patches (whitelisted to `tools.exec.*` only)
### Other Security Notes
- This skill does not expose gateway secrets.
- Use `gateway-guard` separately for gateway/auth management.
- The router does not execute arbitrary code or modify files outside of config patches.
- The phrase "saves tokens" in documentation refers to **cost savings** (using cheaper models for simple tasks), not token storage or collection.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!