Smart Router V3
by @earlvanze
Dynamic AI model router with intent classification and automatic provider discovery
clawhub install smart-router-v2π About This Skill
name: sage-router description: Local-first AI model routing for serious agents. One endpoint. Any provider. The router figures out the rest. env: - SAGE_ROUTER_HOME (required: path to sage-router repo) - SAGE_ROUTER_DISABLED_PROVIDERS (optional: comma-separated provider names to suppress) - SAGE_ROUTER_DISABLED_MODELS (optional: comma-separated model IDs or provider/model keys to suppress) - SAGE_ROUTER_OLLAMA_TIMEOUT_SECONDS (optional, default 120) - SAGE_ROUTER_OLLAMA_AUTO_PULL_PATTERNS (optional, default :cloud) - OPENCLAW_GATEWAY_TOKEN (optional: token for OpenClaw gateway agent bridge)
Sage Router
HTTP server on :8788 that routes chat requests to the optimal provider based on intent classification.
Endpoints
POST /v1/chat/completions β OpenAI-compatible; routes automaticallyPOST /v1/messages β Anthropic Messages API compatible; translates to/from OpenAI format internallyGET /health β Provider status, model lists, routing debugAny Anthropic-compatible tool (Cursor, Aider, Claude Code, Zed, Continue, OpenHands) can point at http://localhost:8788 as the API base URL. Both streaming and non-streaming are supported.
Active Providers
Providers are discovered from ~/.openclaw/openclaw.json at startup.
Rules:
sage-router provider entry to avoid recursion${ENV_VAR} values for baseUrl and apiKeyopenai-codex as a virtual provider when the auth profile existsgenerativelanguage.googleapis.commodels is empty in openclaw.jsonanthropic or Anthropic-hosted anthropic-messages providers onto the local Dario proxy at localhost:3456@askalf/dario and autostarts dario proxy when credentials are mounted at /root/.darioSAGE_ROUTER_DISABLED_PROVIDERS=name1,name2GET /health shows:
configured: all discovered providersproviders: reachable providers with model listsdisabled: providers suppressed by envRouting Logic
The router does not perform mid-stream switching. Once a request is sent to a provider, the full response is returned or the attempt fails. If it fails, the next candidate in the chain is tried sequentially. There is no partial-output fallback or streaming handoff between providers.
Flow:
openclaw.jsonlocal-first, operate as local-strict: reject centralized Internet API providers and only allow local/LAN/Tailnet endpoints plus approved decentralized providers such as Darkbloom, with Ollama :cloud models excludedGENERAL, blend static heuristics with persisted empirical latency stats by provider and modelSAGE_ROUTER_MAX_PROVIDER_ATTEMPTS candidates in ordersage-router provider (the router itself, model auto) is scored as a low-priority recursive fallback, never preferredIntent scoring is generic, for example:
Intent is detected by keyword matching on the latest user message. Complexity is estimated by word count.
API
GET /health β JSON with reachable providers, configured providers, and disabled providersPOST /v1/chat/completions β OpenAI-compatible; routes automaticallyNotes
openai-codex is kept as an optional bridge, not a required first hop.anthropic can stay in openclaw.json while routing locally through dario.systemd unit is template-style and expects local machine values in ~/.config/sage-router/sage-router.env.~/.cache/sage-router/latency-stats.json by default.SAGE_ROUTER_DISABLED_PROVIDERS instead of editing the router.BRANCH_PROTECTION.md for the exact required-check setup on GitHub.provider-profiles.json includes a grok-sso template for the OpenClaw xAI auth plugin's local SuperGrok-backed proxy.Install
Install the user service from the repo copy:
mkdir -p ~/.config/systemd/user ~/.config/sage-router
cp systemd/sage-router.service ~/.config/systemd/user/sage-router.service
cp systemd/sage-router.env.example ~/.config/sage-router/sage-router.env
edit ~/.config/sage-router/sage-router.env for your machine
systemctl --user daemon-reload
systemctl --user enable --now sage-router.service
Notes:
SAGE_ROUTER_HOME to the actual repo path on your machineSAGE_ROUTER_PATH_PREFIX if your Python, Node, or Dario bins are not already on PATHIf an Anthropic provider is detected and Dario is not installed yet, install Dario first:
Service
systemctl --user status sage-router
systemctl --user restart sage-router
journalctl --user -u sage-router -f # live logs
Docker production notes
@askalf/dario.~/.dario:/root/.dario for Anthropic-compatible Claude routing.docker compose --profile classifier up -d and SAGE_ROUTER_INTENT_CLASSIFIER_ENABLED=1.SAGE_ROUTER_INTENT_CLASSIFIER_PROVIDER=llamacpp, SAGE_ROUTER_INTENT_CLASSIFIER_BASE_URL=http://llamacpp-classifier:8080, SAGE_ROUTER_INTENT_CLASSIFIER_MODEL=classifier.Router profiles
Sage Router supports named routing profiles in router-profiles.json next to router.py.
Request a profile with any of:
model: "sage-router/" model: "" profile, routerProfile, or sageRouterProfileProfile fields currently supported:
route: fast, balanced, best, local-first, realtimethinking: low, medium, highrequiresQuality, requiresReasoning, requiresTools, frontierLargeOnly, frontierOrReasoningTools, suppressIntermediateToolText, qualitySensitive, reasoning, tools, preferTools, json, vision, document, longContextallowProviders, denyProviders, allowModels, denyModels, minParamsBCurrent profiles:
discord-public: public-facing quality profile. Forces best/high, reasoning, quality-sensitive, suppresses tool-call narration, and blocks tiny/free filler models.frontier-large: strict frontier-large-only routing.fast-local: low-latency local-first routing.coding-max: high-thinking code route with weak model exclusions.π Tips & Best Practices
openai-codex is kept as an optional bridge, not a required first hop.anthropic can stay in openclaw.json while routing locally through dario.systemd unit is template-style and expects local machine values in ~/.config/sage-router/sage-router.env.~/.cache/sage-router/latency-stats.json by default.SAGE_ROUTER_DISABLED_PROVIDERS instead of editing the router.BRANCH_PROTECTION.md for the exact required-check setup on GitHub.provider-profiles.json includes a grok-sso template for the OpenClaw xAI auth plugin's local SuperGrok-backed proxy.