Releases: BlockRunAI/ClawRouter
v0.12.5
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
Bug Fix
- Fix Solana wallet migration missing signatures —
signTransactionMessageWithSignerswas producing unsigned transactions because only plainAddressstrings were in the instruction account metas. AddedaddSignersToTransactionMessageto 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
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-readnow loops until all bytes are consumed, respectingbytesReadreturn 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
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
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
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:
- Checks old wallet USDC balance
- Transfers all USDC to the new (correct) wallet
- Confirms with transaction signature
New Files
src/solana-sweep.ts— USDC sweep from legacy to new walletsrc/wallet.ts—deriveSolanaKeyBytesLegacy()preserved for sweep
Test Vectors
| Derivation | Key (hex) | Address |
|---|---|---|
| SLIP-10 Ed25519 | 7c139e1a... |
3Cy3YNTFywCmxoxt8n7UH6hg6dLo5uACowX3CFceaSnx |
| Legacy secp256k1 | 39193f92... |
FML75CaYR4MPYVcLVp41bpXUipL1WanDz6Xwo21ejkgh |
Full Changelog
v0.10.18 — Re-pin session to fallback model after provider failure
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)
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:
- Session persistence was disabled by default — `SessionStore` had `enabled: false`, so model pinning never activated
- 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
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 withouttoolCalling: truefrom 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.15v0.10.14 — Fix 'talking to itself' bug (remove grok-code-fast-1 from tool-use paths)
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