Skip to content

Releases: BlockRunAI/ClawRouter

v0.12.5

04 Mar 06:04
2c998d8

Choose a tag to compare

Bug Fix

  • Force agentic tiers when tools are present in API request — OpenClaw (and other agentic clients) always send tools in their API requests, but the router only checked prompt keywords to decide whether to use agentic-capable models. Simple prompts like "create a markdown file" scored too low on keyword detection and got routed to cheaper models that don't handle tool use reliably (the "model just talks instead of creating files" bug). Now when the request contains tools, agentic tiers are forced automatically — ensuring Claude, GPT, and other proven tool-calling models are used.

Thanks to @carlosdss22 for reporting!

v0.12.4

04 Mar 05:36
a1f07eb

Choose a tag to compare

Bug Fix

  • Fix Solana wallet migration missing signaturessignTransactionMessageWithSigners was producing unsigned transactions because only plain Address strings were in the instruction account metas. Added addSignersToTransactionMessage to bind both the fee payer (new wallet) and token transfer authority (old wallet) before signing. Fixes "Transaction is missing signatures for addresses" error on /wallet migrate-solana.

v0.12.3

04 Mar 05:01
288c689

Choose a tag to compare

Fixes

  • [P1] Multi-account sweep: Transfer from each USDC token account individually instead of accumulating balance but only keeping the last account — fixes failure when USDC is split across multiple accounts
  • [P2] Partial file reads: fs-read now loops until all bytes are consumed, respecting bytesRead return value
  • [P3] JSONL resilience: Stats parser skips malformed lines instead of dropping all entries when one line fails

Full Changelog: v0.12.2...v0.12.3

v0.12.2

04 Mar 04:57
6c5ff78

Choose a tag to compare

Fix: Correct SPL Token Program ID in migration sweep

The TOKEN_PROGRAM constant in solana-sweep.ts had an invalid address (TokenkegQfeN4jV6bme4LphiJbfPe2VopRsimuVSoZ5K) that decoded to 33 bytes instead of the required 32, causing the sweep to fail with:

Expected base58 encoded address to decode to a byte array of length 32. Actual length: 33.

Fixed to the correct SPL Token Program address: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA

Full Changelog: v0.12.1...v0.12.2

v0.12.1

04 Mar 04:44
e74bb4b

Choose a tag to compare

Fix: New wallet pays gas for migration sweep

When migrating from the old (BIP-32 secp256k1) Solana wallet to the new (SLIP-10 Ed25519) wallet, the new wallet now funds the gas for the sweep transaction.

Previously the old wallet was expected to pay gas, but users can't access the old wallet from Phantom to top up SOL — making migration impossible if the old wallet had zero SOL balance.

Full Changelog: v0.12.0...v0.12.1

v0.12.0 — SLIP-10 Ed25519 Solana Derivation

04 Mar 01:07
bdb2406

Choose a tag to compare

Breaking Change: Solana Wallet Derivation Fixed

Existing Solana wallets will derive a different address. Run /wallet migrate-solana to sweep funds from old → new wallet.

What Changed

The Solana key derivation was using secp256k1 BIP-32 (@scure/bip32 HDKey), but all Solana wallets (Phantom, Solflare, Backpack) use SLIP-10 Ed25519. Same mnemonic + same path (m/44'/501'/0'/0') + different elliptic curve = completely different address.

Before: Mnemonic recovery in Phantom produced a different wallet — funds appeared lost.
After: Mnemonic recovery in any standard Solana wallet produces the correct address.

Migration

On startup, ClawRouter detects the derivation change and logs both addresses:

[ClawRouter] ⚠ SOLANA WALLET MIGRATION DETECTED
[ClawRouter]   Old address (secp256k1): FML75Ca...
[ClawRouter]   New address (SLIP-10):   3Cy3YNT...
[ClawRouter]   Run: /wallet migrate-solana

The /wallet migrate-solana command:

  1. Checks old wallet USDC balance
  2. Transfers all USDC to the new (correct) wallet
  3. Confirms with transaction signature

New Files

  • src/solana-sweep.ts — USDC sweep from legacy to new wallet
  • src/wallet.tsderiveSolanaKeyBytesLegacy() preserved for sweep

Test Vectors

Derivation Key (hex) Address
SLIP-10 Ed25519 7c139e1a... 3Cy3YNTFywCmxoxt8n7UH6hg6dLo5uACowX3CFceaSnx
Legacy secp256k1 39193f92... FML75CaYR4MPYVcLVp41bpXUipL1WanDz6Xwo21ejkgh

Full Changelog

v0.11.14...v0.12.0

v0.10.18 — Re-pin session to fallback model after provider failure

27 Feb 04:13
c293612

Choose a tag to compare

Problem

v0.10.17 pinned the session to the routing decision (primary model), not the actual model used. When the primary was rate-limited and fell back to gemini-flash:

  • Session pinned to kimi-k2.5 (the routing decision)
  • Next request: session says kimi-k2.5 → rate-limited again → falls back to gemini-flash again
  • Conversation stayed stuck in a retry-and-fallback loop

Fix

After the fallback loop resolves `actualModelUsed`, update the session pin to the actual responding model:

```
Request 1: routes → kimi-k2.5 (pinned) → rate-limited → falls back to gemini-flash
session updated: kimi-k2.5 → gemini-flash
Request 2: session says gemini-flash → used directly, no retry
Request 3: session says gemini-flash → stable
```

The conversation now stays on the working model for the full 30-minute session window.

Upgrade

```bash
~/.blockrun/scripts/update.sh
```

v0.10.17 — Session persistence fix (no more model jumping)

27 Feb 03:56
9fb30af

Choose a tag to compare

Problem

Users in group chats reported models constantly jumping back to `gemini-flash`, even after setting a primary model in the dashboard. Each message was being re-routed from scratch.

Root Cause

Two bugs working together:

  1. Session persistence was disabled by default — `SessionStore` had `enabled: false`, so model pinning never activated
  2. No session ID without the header — `getSessionId()` only read the `x-session-id` header. OpenClaw sends no such header, so every request got `undefined` → full re-routing on every turn

Fix

  • `DEFAULT_SESSION_CONFIG.enabled`: `false` → `true`
  • Added `deriveSessionId()`: stable 8-char hex derived from SHA-256 of the first user message — same opening message anchors the same session across all turns
  • `proxy.ts`: `getSessionId(headers) ?? deriveSessionId(parsedMessages)`

Now model selection is pinned for 30 minutes per conversation without requiring any client-side session header.

Upgrade

```bash
~/.blockrun/scripts/update.sh
```

v0.10.15 — Root-cause fix: toolCalling capability flag prevents routing tool requests to incompatible models

26 Feb 19:40
8f89499

Choose a tag to compare

feat: toolCalling capability flag + routing filter

Why v0.10.14 was directionally correct but incomplete

v0.10.14 removed grok-code-fast-1 from tier configs. That stopped the immediate bleeding, but the root cause remained: ClawRouter had no mechanism to prevent incompatible models from entering the routing chain when a request includes tool schemas. Any future model added to tier configs with the same issue would cause the same bug.

What v0.10.15 adds

A toolCalling capability flag on every model definition and a routing filter that enforces it.

models.ts — new flag on BlockRunModel:

toolCalling?: boolean
// true  → supports OpenAI-compatible structured function/tool calling
// false/omitted → outputs tool invocations as plain text (skipped when request has tools)

Models WITHOUT toolCalling:

  • xai/grok-code-fast-1 — outputs {"command":"..."} as plain text (the original bug)
  • nvidia/gpt-oss-120b — free model, structured function call support unverified

selector.ts — new filterByToolCalling() function:

  • When request has tools, removes models without toolCalling: true from the fallback chain
  • If no capable model remains, returns the full chain (API error beats silent failure)

proxy.ts — applies the filter after context-window filtering:

[ClawRouter] Tool-calling filter: excluded xai/grok-code-fast-1 (no structured function call support)

Upgrade

openclaw plugins update clawrouter
# or
openclaw plugins install @blockrun/clawrouter@0.10.15

v0.10.14 — Fix 'talking to itself' bug (remove grok-code-fast-1 from tool-use paths)

26 Feb 18:02
b90aef3

Choose a tag to compare

Fix: Replace grok-code-fast-1 with kimi-k2.5 in MEDIUM routing tiers

Problem

Multiple users reported that ClawRouter was "talking to itself" — showing raw JSON like {"command":"..."} as visible chat messages instead of silently executing tool calls. A large error block would sometimes appear in the chat as a result.

Root cause: xai/grok-code-fast-1 (Grok Code Fast) does not properly handle OpenClaw's function call format. When given tool schemas, it outputs tool invocations as plain text JSON in the response body rather than as structured function calls. OpenClaw displays this raw JSON as a visible message, making it look like the AI is narrating its own actions.

Fix

Replaced grok-code-fast-1 with moonshot/kimi-k2.5 as the primary model for MEDIUM-complexity tasks in both the default and agentic tier configs. Kimi K2.5 has strong tool-use support and correctly uses OpenClaw's structured function call format.

Config path Before After
tiers.MEDIUM.primary xai/grok-code-fast-1 moonshot/kimi-k2.5
agenticTiers.MEDIUM.primary xai/grok-code-fast-1 moonshot/kimi-k2.5
premiumTiers.SIMPLE.fallback[2] xai/grok-code-fast-1 deepseek/deepseek-chat

grok-code-fast-1 is no longer used in any routing path.

Upgrade

openclaw plugins update clawrouter
# or
openclaw plugins install @blockrun/clawrouter@0.10.14