Skip to content

Releases: BlockRunAI/ClawRouter

v0.12.146

10 Apr 16:32
4aed80d

Choose a tag to compare

New Feature

Every routed response now carries a `usage.cost` breakdown.

Users on `blockrun/auto` previously had no visible signal of which model actually answered or how much each call cost. Now every response includes:

```json
{
"model": "google/gemini-2.5-flash",
"usage": {
"prompt_tokens": 120,
"completion_tokens": 80,
"total_tokens": 200,
"cost": {
"total": 0.00023,
"input": 0.000018,
"output": 0.000048,
"baseline": 0.00618,
"savings_pct": 96,
"model": "google/gemini-2.5-flash",
"tier": "SIMPLE"
}
}
}
```

What OpenClaw users see (no OpenClaw changes required)

  • `/usage full` footer now shows session cost totals that increase as you chat
  • `/stats`-style reports aggregate cost per model and per day
  • Works automatically — OpenClaw's `session-cost-usage` module already parses the standard `usage.cost.{total,input,output}` fields

Extra metadata (forward-compat)

`baseline`, `savings_pct`, `model`, and `tier` are non-standard fields that current OpenClaw ignores. Future OpenClaw UI work can render them as an inline per-message badge (e.g. `via free/glm-4.7 · $0.0023 · saved 96%`) without any ClawRouter changes.

No context pollution

`usage` is OpenAI metadata — LLMs never see it when the conversation history is replayed. Safe to emit on every turn.

Technical details

  • Uses ACTUAL upstream token counts (not pre-request estimates) via `calculateModelCost()`
  • Server margin and MIN_PAYMENT_USD floor are applied consistently to both `total` and `baseline`
  • Streaming responses emit a final OpenAI `include_usage`-format chunk before `[DONE]`
  • Non-streaming responses always overwrite the top-level `model` field (some upstreams omit it)
  • 9 new unit tests in `src/proxy.cost.test.ts`

Reported by

This feature was driven by user feedback that "auto" didn't feel transparent — users couldn't tell if it was actually saving money or just a black box.

v0.12.145

10 Apr 12:18
17f3a09

Choose a tag to compare

Improvements

  • eco/premium null fallback (router/strategy.ts): when `ecoTiers` or `premiumTiers` is set to `null`, fall back to regular `tiers` instead of dropping into auto routing. Preserves the eco/premium profile semantics even when the special tier set is disabled.
  • provider.ts: `setActiveProxy` now accepts `null` (used by the deactivate path).
  • debug-command test: 2s client-side timeout so the test no longer hangs on slow upstream.
  • CI green: prettier formatting cleanup in `src/index.ts` and `src/index.lifecycle.test.ts`.

v0.12.144

10 Apr 12:14
a11ad63

Choose a tag to compare

Bug Fixes

`/model` command now actually switches the model.

When a user ran `/model blockrun/free/glm-4.7` in OpenClaw, the bot's next response often still claimed to be the previously pinned model (typically Sonnet). The model wasn't really switching — it was being silently overridden by ClawRouter's session pinning, which was designed to prevent mid-task model switching but was too aggressive.

What changed

  • `SessionEntry` now carries a `userExplicit` flag.
  • When ClawRouter receives an explicit non-profile model (e.g. `blockrun/free/glm-4.7`, `anthropic/claude-opus-4.6`), it pins the session with `userExplicit=true`.
  • Routing-profile requests (`blockrun/auto`, `blockrun/eco`, etc.) respect a user-explicit pin unconditionally — no tier-rank comparison, no escalation. The user's intent wins.
  • The flag is sticky across fallback re-pins; it can only be cleared when the session expires.

User-visible impact

`/model ` actually switches the model, and the choice persists across follow-up messages even when OpenClaw reverts to sending `blockrun/auto` in subsequent chat completions.

v0.12.143

10 Apr 07:13
42132b4

Choose a tag to compare

Chore

Prettier formatting fix in `src/web-search-provider.ts` and `src/web-search-provider.test.ts` to keep CI green. No functional changes.

v0.12.142

10 Apr 07:07
ad35908

Choose a tag to compare

Bug Fixes (#147)

User routing config in openclaw.json was silently ignored.

OpenClaw calls `register()` twice during gateway startup. The first call runs in a pre-gateway phase before `openclaw.json` has been parsed, so `api.pluginConfig` is empty. The previous `proxyAlreadyStarted` guard caused the proxy to start with `DEFAULT_ROUTING_CONFIG` on that first call, then the second call (the one with the user's actual `plugins.entries.clawrouter.config.routing`) bailed out as a no-op.

Result: any custom `routing`, `walletKey`, `maxCostPerRun`, etc. defined in `openclaw.json` was silently ignored.

Fix

  • When `pluginConfig` is empty on a `register()` call, defer proxy startup for 250ms instead of starting immediately.
  • If a second `register()` call arrives within that window with a populated `pluginConfig`, it cancels the deferred timer and starts the proxy with the real config.
  • If no second call ever arrives (user has no plugin config at all), the timer fires and the proxy starts with defaults — no deadlock.

Reported by @jeegankones in #147.

v0.12.141

10 Apr 07:03
99b4dd6

Choose a tag to compare

Bug Fixes (#148)

Fixes two related bugs that prevented users from customizing agent routing via `routingConfig`:

  1. Custom tier sets weren't merged. `mergeRoutingConfig` only deep-merged `tiers`, ignoring `agenticTiers`, `ecoTiers`, and `premiumTiers`. Users defining custom `agenticTiers` had no effect on routing — agent requests always used the defaults.

  2. `overrides.agenticMode: false` didn't disable agentic tiers. `hasToolsInRequest` was OR'ed in unconditionally, so any request with tools (i.e. every agent request) still routed through `agenticTiers`.

Changes

  • `mergeRoutingConfig`: deep-merges `agenticTiers`/`ecoTiers`/`premiumTiers` (per-tier override), and `null` explicitly disables a tier set
  • `agenticMode` now has clear three-state semantics:
    • `true` → force agentic tiers
    • `false` → disable agentic tiers entirely (even with tools)
    • `undefined` → auto-detect via tools/agenticScore (default)
  • `agenticTiers`/`ecoTiers`/`premiumTiers` types now accept `null`
  • Regression tests for both bugs

Reported by @jeegankones in #148.

v0.12.140

10 Apr 06:30
ee79204

Choose a tag to compare

Bug Fixes

  • Fix doctor on Solana chainnpx @blockrun/clawrouter doctor was hardcoding an EVM signer and sending test requests to blockrun.ai regardless of the user's configured payment chain. On Solana users, it produced a misleading `Payment verification failed` error showing an EVM payer address that didn't match their actual Solana wallet.

Now doctor registers the Solana scheme and routes to `sol.blockrun.ai` when `paymentChain=solana`.

v0.12.139

09 Apr 15:00
d071dbe

Choose a tag to compare

Bug Fixes

  • Fix baseUrl overwrite after plugin install — OpenClaw's async config persistence was overwriting the correct local proxy URL (127.0.0.1:8402) with the remote blockrun.ai/api fallback. Root cause: provider.ts models getter returned the remote URL before proxy startup; OpenClaw serialized that into openclaw.json. Now always returns the local proxy URL. (reported by Cheetah)
  • Post-install baseUrl verificationupdate.sh and reinstall.sh now re-verify and fix baseUrl after openclaw plugins install, not just before.

Improvements

  • Added GLM models to allowlistzai/glm-5, zai/glm-5.1, zai/glm-5-turbo now appear in OpenClaw's /model picker. (reported by Aston)

v0.12.92 — Fix multi-turn chat for reasoning models (continue.dev #135)

31 Mar 21:33
0da922b

Choose a tag to compare

Bug Fix: Existing chat always fails in continue.dev (#135)

Root cause

moonshot/kimi-k2.5 (primary MEDIUM-tier model in blockrun/auto) is a reasoning model that requires reasoning_content on all assistant messages in multi-turn history — not just tool-call messages. When continue.dev sent an existing chat, the plain-text assistant message from the previous turn was missing reasoning_content, causing a 400 from the model.

Since that 400 didn't match any PROVIDER_ERROR_PATTERNS, isProviderError=false and the fallback loop broke on the first attempt. All models failed → SSE error sent → OpenAI SDK in continue.dev threw "Unexpected error".

New chats (no assistant history) were unaffected — only existing chats broke.

Fixes

  • normalizeMessagesForThinking — now adds reasoning_content: "" to all assistant messages (not just tool-call ones) when targeting a reasoning model
  • SSE error format — error events now always use {"error":{...}} OpenAI wrapper; raw upstream JSON was previously forwarded as-is, hiding the real error message
  • PROVIDER_ERROR_PATTERNS — added reasoning_content.*missing as a safety net for proper fallback

Verification

  • E2E: 3-turn SSE streaming test passed (turn 2 was the broken case)
  • Unit: 7 new regression tests for normalizeMessagesForThinking
  • Full suite: 364/364 passing

Update

npx @blockrun/clawrouter@latest

v0.12.90 — Fix empty-turn fallback for eco/agentic requests

31 Mar 17:01
38bc08b

Choose a tag to compare

What's Fixed

Empty turn responses now trigger model fallback

Problem: Under the eco profile (and sometimes auto), agentic clients like Roo Code would receive silent empty responses — the model returned HTTP 200 with no content and no tool calls, just finish_reason: stop. The proxy treated this as success and forwarded the empty turn to the client, causing the agent to loop or stall.

Root cause: Models like gemini-3.1-flash-lite sometimes refuse complex agentic requests (large Roo Code tool schemas) by producing a zero-output response instead of an error. ClawRouter's degraded-response detector didn't catch this pattern, so it never fell back to the next model.

Fix: detectDegradedSuccessResponse now flags responses where:

  • choices[0].message.content is empty and
  • no tool_calls and
  • finish_reason === "stop"

These are treated as degraded response: empty turn → fallback fires → next model in chain is tried automatically.

Upgrade

npm i -g @blockrun/clawrouter@latest