← Back to Plugins
Tools

Baton

tektual By tektual 👁 10 views ▲ 0 votes

Baton OpenClaw plugin: planner-first sub-agent orchestration, model routing, provider rate-limit coordination, and conversational model management.

GitHub

Install

openclaw plugins install ./baton-plugin-v2

README

# Baton v2.12.3 OpenClaw Plugin

Baton is a hybrid OpenClaw plugin + tiny skill shim for planner-first sub-agent orchestration, model routing, conversational model management, and provider/model rate-limit coordination.

## Why plugin instead of skill-only?

The v1 Baton skill proved the orchestration pattern, but model discovery, routing, leases, multi-main-agent coordination, and conversational model management are runtime concerns. Baton v2 moves those into plugin tools and keeps the prompt-facing skill tiny.

## Capabilities

- Always-plan orchestration via `baton_plan`.
- Broad role planning for development, research, content, social media, marketing, support, product, data, education, media, operations, automation, and agentic workflows.
- Conversational model management: scan, list, allow, remove, block, tier, and validate models.
- Rate-limit-aware routing with soft leases, rolling minute/hour/day request quotas per provider/model, provider block/unblock controls, and stale lock recovery.
- Per-agent state support through `.openclaw/baton/agents/<agentId>/`.
- Plugin-shipped skill under `skills/baton`.
- Safe JSON/JSONC-ish OpenClaw config scanning without `eval`, `Function`, or dynamic execution.

## Install

Package name: `@tektual/openclaw-plugin-baton`.

Local development example:

```bash
openclaw plugins install ./baton-plugin-v2
openclaw plugins enable baton
```


For OpenClaw deployments that use an explicit plugin allowlist, add Baton to the allowlist as well as enabling the plugin:

```json5
{
  plugins: {
    allow: ["baton"],
    entries: {
      baton: { enabled: true }
    }
  }
}
```

If `plugins.allow` is empty or does not include `baton`, OpenClaw may still load the extension in dev setups but warn on startup.

Then configure if needed:

```json5
{
  plugins: {
    entries: {
      baton: {
        enabled: true,
        config: {
          defaultMode: "standard",
          alwaysSpawn: true,
          maxConcurrentPerProvider: 3,
          maxConcurrentPerModel: 1,
          prioritizeRecentModels: true,
          modelRecencyPreferredFraction: 0.3,
          rateLimits: {
            providers: { openai: { minute: 20, hour: 500, day: 5000 } },
            models: { "anthropic/claude-sonnet": { minute: 10, hour: 200, day: 2000 } }
          }
        }
      }
    }
  }
}
```



## Adaptive reasoning effort

Baton v2.12.3 returns reasoning/thinking effort hints from `baton_route_model` when the selected model appears to support controllable reasoning. Planner, validator, security, automation, high-risk routes, and coding routes get maximum effort by default; creative tier routes get high effort by default, while designer/UI/UX/product-design/art-direction and generic design-family roles and creative director roles request max when available. Fast/support/content routes stay lower unless overridden. See `docs/reasoning-effort.md`.

Example config:

```json5
{
  plugins: {
    entries: {
      baton: {
        config: {
          reasoningEffort: {
            enabled: true,
            default: "medium",
            highRiskDefault: "max",
            byTier: { fast: "low", balanced: "medium", code: "max", creative: "high", strong_reasoning: "high" },
            providerAliases: { nvidia3: { supported: true, maxEffort: "max", parameter: "reasoningEffort" } }
          }
        }
      }
    }
  }
}
```

## Model resync and stale-provider protection

Baton treats its allowlist as a user policy, not as proof that a provider/model still exists. Before routing, Baton validates candidate models against the current model registry and blocks stale refs by default.

Use these commands when OpenClaw providers change:

```text
baton_resync_models
baton_scan_models with reconcile=true
```

`baton_resync_models` rescans current OpenClaw models and prunes stale entries from the global and per-agent Baton allowlists/tiers. This prevents phantom routes such as `ok:true` for a provider removed from `openclaw.json`.

Baton stores model refs internally as `provider/model`, even when the model part contains `/` or `:`. Do not mirror Baton refs directly into OpenClaw config object keys unless your sync tool converts them into schema-safe provider/model structures accepted by OpenClaw. Baton itself writes only Baton state files under `.openclaw/baton/` and does not rewrite `openclaw.json`.

## Interactive menu

Baton now includes a terminal menu for setup and day-to-day configuration:

```bash
npm run menu -- --config /path/to/openclaw.json
npm run setup -- --config /path/to/openclaw.json
npm run menu -- --config /path/to/openclaw.json --scan --no-live
npx baton-menu --config /path/to/openclaw.json
```

The menu covers:

- scanning/rescanning OpenClaw models;
- selecting which discovered models Baton may use;
- assigning models to routing tiers;
- provider/model block and unblock controls;
- per-provider and per-model minute/hour/day quotas;
- runtime mode and concurrency settings;
- per-main-agent model profiles;
- status and validation checks.

The menu writes the same Baton state files used by the plugin tools, so configuration changes made in the menu are immediately visible to conversational Baton tools.


## In-chat/session menu

Baton also exposes a conversational menu for agents that cannot or should not use the terminal menu. Ask the main agent:

```text
Open the Baton menu.
Configure Baton in this chat.
Show the Baton model menu.
```

The agent should call `baton_chat_menu`, display the numbered menu, then call `baton_chat_menu_select` when you reply with a number or value. The chat menu can scan models, allow/remove models, assign tiers, block providers/models, set minute/hour/day quotas, change runtime mode, switch per-agent profiles, test routing, and validate setup.

## First setup through conversation

Ask the main agent:

```text
Rescan Baton models and show me the models it found.
Allow Baton to use openai/gpt-5-mini for fast tasks and anthropic/claude-sonnet for strong reasoning.
Set Baton to rate-safe mode.
```

The skill shim maps those to plugin tools.

## Tool summary

- `baton_plan` — produce a compact Planner-Orchestrator plan.
- `baton_route_model` — select an allowed model and optionally create a lease.
- `baton_release_lease` — release a lease and record timeout/rate-limit outcomes.
- `baton_scan_models` — scan OpenClaw configured/live models.
- `baton_list_models` — show discovered/allowed/blocked/tiered models.
- `baton_allow_model` — add a model to Baton allowlist.
- `baton_remove_model` — remove a model and all tier assignments.
- `baton_block_model` / `baton_unblock_model` — block or unblock a model from routing.
- `baton_block_provider` / `baton_unblock_provider` — block or unblock an entire provider.
- `baton_assign_tier` — assign or remove a model from a routing tier.
- `baton_set_mode` — set runtime mode.
- `baton_set_rate_limit` — set rolling minute/hour/day request quotas for a provider or model.
- `baton_clear_rate_limit` — remove a configured provider/model request quota.
- `baton_chat_menu` — open the in-chat/session configuration menu.
- `baton_chat_menu_select` — handle the next user menu selection/value.
- `baton_status` — summarize readiness, tier coverage, leases, cooldowns.
- `baton_validate` — find missing setup/state issues.

## State files

By default Baton stores mutable runtime state under the OpenClaw state directory if exposed by the runtime, otherwise under:

```text
~/.openclaw/baton/
```

Important files:

```text
model-registry.json
model-allowlist.json
baton.config.json
runtime/rate-state.json
runtime/model-routing-ledger.jsonl
agents/<agentId>/model-allowlist.json
```

## Release note

This package is a working plugin release aligned with the documented OpenClaw plugin manifest surfaces. The tool registration layer supports common OpenClaw host registration APIs while keeping service logic isolated.

## Production defaults

Baton v2.12.3 is intentionally conservative:

- custom `configPath` scanning is disabled unless `allowCustomConfigPath=true`;
- undiscovered model allowlisting is disabled unless `allowUndiscoveredModels=true`;
- model changes should normally follow `baton_scan_models` so Baton routes only models OpenClaw actually knows about.


## Model scanning notes

`baton_scan_models` scans full OpenClaw provider catalogs from `models.providers`, not only `agents.defaults.model`. The registry includes diagnostics with total discovered models, provider count, provider breakdown, and scan sources. If a scan unexpectedly returns only a few models, check the diagnostics first; the plugin may be seeing a narrowed `api.config` instead of the full on-disk `openclaw.json`. Baton therefore also attempts common config locations such as `~/.openclaw/openclaw.json` when no explicit path is configured.

## Tier heuristic notes

Auto-suggested tiers are conservative. `balanced` is no longer a catch-all for every model. Legacy/deprecated models, known-old reasoning models such as `deepseek-r1`, and tiny/small models are not auto-added to `balanced` or `strong_reasoning`. Operators can still assign any discovered model explicitly to a tier when they know their local provider behavior.

## Model age prioritisation

Baton annotates scanned models with a `metadata.batonRecency` object. By default, the newest 30% of non-legacy discovered models are marked `preferred`; the rest remain available but are treated as fallbacks during routing. This means a manually allowed older model can still be used when newer candidates are exhausted, but it should not win the default route unless the operator explicitly places it first and accepts the tradeoff.

Configure this with:

```json5
{
  plugins: {
    entries: {
      baton: {
        config: {
          prioritizeRecentModels: true,
          modelRecencyPreferredFraction: 0.3
        }
      }
    }
  }
}
```

Baton uses explicit metadata such as release dates when present, then falls back to model-family/versi

... (truncated)
tools

Comments

Sign in to leave a comment

Loading comments...