openclaw-freerouter 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +196 -105
  2. package/package.json +4 -2
package/README.md CHANGED
@@ -1,121 +1,96 @@
1
- # FreeRouter — OpenClaw Plugin
1
+ # FreeRouter — Smart LLM Router for OpenClaw
2
2
 
3
- Smart LLM router that classifies your requests and routes them to the best model automatically. Uses a 14-dimension weighted scorer (<1ms) with configurable tier→model mapping.
3
+ **Stop overpaying for AI.** Every message to your AI assistant costs money a simple "hello" shouldn't cost the same as "prove the Riemann hypothesis." FreeRouter automatically routes each request to the right model based on complexity.
4
4
 
5
- ## Install
5
+ ## The Problem
6
6
 
7
- ```bash
8
- # From local directory
9
- openclaw plugins install -l /path/to/freerouter-plugin
7
+ - 🔥 **Wasted money** — Running Claude Opus ($15/$75 per 1M tokens) for every message, even "what's 2+2?"
8
+ - 🤷 **No control** — Can't switch models mid-conversation without editing config files and restarting
9
+ - 📊 **Blind routing** — Your AI shows "freerouter/auto" instead of telling you which model actually answered
10
+ - 🔧 **Complex setup** — Existing routers need separate servers, Docker, complex infra
10
11
 
11
- # Or copy to extensions
12
- openclaw plugins install /path/to/freerouter-plugin
13
- ```
12
+ ## The Solution
14
13
 
15
- ## Configure
14
+ FreeRouter is an OpenClaw plugin that:
15
+ - **Classifies every request in <1ms** using a 14-dimension weighted scorer (no LLM needed for classification)
16
+ - **Routes to the cheapest model that can handle it** — Kimi for "hello", Opus for architecture design
17
+ - **Reports the real model name** — You see `anthropic/claude-opus-4-6`, not `freerouter/auto`
18
+ - **Lets you override anytime** — Just say "use opus" in plain English
16
19
 
17
- After install, configure tiers in `openclaw.json`:
20
+ ## Install
18
21
 
19
- ```json5
20
- {
21
- // Set FreeRouter as your default model
22
- agents: {
23
- defaults: {
24
- model: { primary: "freerouter/auto" }
25
- }
26
- },
22
+ ```bash
23
+ openclaw plugins install openclaw-freerouter
24
+ ```
27
25
 
28
- // Add FreeRouter as a provider pointing to its HTTP proxy
29
- providers: {
30
- freerouter: {
31
- baseUrl: "http://127.0.0.1:18801/v1",
32
- api: "openai-completions"
33
- }
34
- },
26
+ Then run the setup wizard:
35
27
 
36
- // Plugin config
37
- plugins: {
38
- entries: {
39
- freerouter: {
40
- enabled: true,
41
- config: {
42
- port: 18801, // HTTP proxy port (0 = disabled)
43
- host: "127.0.0.1", // Bind address
44
-
45
- // Customize which models handle each tier
46
- tiers: {
47
- SIMPLE: { primary: "kimi-coding/kimi-for-coding", fallback: ["anthropic/claude-haiku-4-5"] },
48
- MEDIUM: { primary: "anthropic/claude-sonnet-4-5", fallback: ["anthropic/claude-opus-4-6"] },
49
- COMPLEX: { primary: "anthropic/claude-opus-4-6", fallback: [] },
50
- REASONING: { primary: "anthropic/claude-opus-4-6", fallback: [] }
51
- },
28
+ ```bash
29
+ openclaw freerouter setup
30
+ ```
52
31
 
53
- // Thinking/reasoning config
54
- thinking: {
55
- adaptive: ["claude-opus-4-6"],
56
- enabled: { models: ["claude-sonnet-4-5"], budget: 4096 }
57
- },
32
+ Or configure manually — see [Configuration](#configure) below.
58
33
 
59
- // Default tier for ambiguous requests
60
- defaultTier: "MEDIUM"
61
- }
62
- }
63
- }
64
- }
65
- }
66
- ```
34
+ ## Switch Models Anytime
67
35
 
68
- ## How It Works
36
+ The killer feature: **switch models using natural language, slash commands, or session locks.**
69
37
 
70
- 1. OpenClaw sends a request with model `freerouter/auto`
71
- 2. FreeRouter's HTTP proxy receives it
72
- 3. The 14-dimension classifier scores the request in <1ms
73
- 4. Routes to the best model for the task (e.g., Kimi for simple, Opus for reasoning)
74
- 5. Forwards to the real provider API
75
- 6. **Returns the actual model name** (e.g., `anthropic/claude-opus-4-6`) so OpenClaw displays what's really running
38
+ ### Just Say It (Natural Language)
76
39
 
77
- ## Tiers
40
+ No slash commands needed. Just talk:
78
41
 
79
- | Tier | Default Model | Use Case |
80
- |------|--------------|----------|
81
- | SIMPLE | kimi-coding/kimi-for-coding | Quick lookups, translations, simple Q&A |
82
- | MEDIUM | anthropic/claude-sonnet-4-5 | Code generation, creative writing, moderate complexity |
83
- | COMPLEX | anthropic/claude-opus-4-6 | Architecture design, multi-step reasoning |
84
- | REASONING | anthropic/claude-opus-4-6 | Mathematical proofs, formal logic, deep analysis |
42
+ | What you say | What happens |
43
+ |---|---|
44
+ | `use opus` | Switches to Claude Opus for this message |
45
+ | `switch to sonnet` | Switches to Claude Sonnet |
46
+ | `try kimi` | Switches to Kimi |
47
+ | `let's use opus` | Switches to Opus |
48
+ | `please use sonnet` | Switches to Sonnet |
49
+ | `can you use haiku` | Switches to Haiku |
50
+ | `use opus: explain quantum computing` | Uses Opus for this specific prompt |
51
+ | `use opus, what is 2+2?` | Same — model + prompt in one message |
52
+ | `go back to auto` | Return to automatic routing |
85
53
 
86
- ## Per-Prompt Model Override
54
+ ### Lock a Model for the Whole Session
87
55
 
88
- Force a specific model for one message:
56
+ When you know the task is important and you want Opus (or any model) for everything:
89
57
 
90
- - `/opus Explain quantum computing` Claude Opus 4.6
91
- - `/sonnet Write a poem` → Claude Sonnet 4.5
92
- - `/kimi What's 2+2?` Kimi K2.5
93
- - `/haiku Translate this` Claude Haiku 4.5
94
- - `[opus] Deep analysis...` Claude Opus 4.6
58
+ | What you say | What happens |
59
+ |---|---|
60
+ | `use opus for this session` | 🔒 Locks ALL messages to Opus |
61
+ | `switch to sonnet from now on` | 🔒 Locks to Sonnet |
62
+ | `stick with opus` | 🔒 Locks to Opus |
63
+ | `keep using sonnet` | 🔒 Locks to Sonnet |
64
+ | `/lock opus` | 🔒 Same thing, slash command |
65
+ | `/unlock` | 🔓 Back to auto-routing |
66
+ | `/lock status` | Shows current lock state |
95
67
 
96
- ## Per-Prompt Tier Override
68
+ Session locks expire after 4 hours of inactivity.
97
69
 
98
- Force a tier (uses that tier's primary model):
70
+ ### When FreeRouter Isn't Sure
99
71
 
100
- - `/simple What's 2+2?` SIMPLE tier
101
- - `/max Prove the Riemann hypothesis` → REASONING tier
102
- - `[reasoning] Analyze this code...` → REASONING tier
72
+ If your request is ambiguous, FreeRouter asks before switching:
103
73
 
104
- ## Session Lock
74
+ > **You:** "opus please"
75
+ > **FreeRouter:** 🤔 Did you want to switch to **anthropic/claude-opus-4-6**? Reply **yes** or **no**.
76
+ > **You:** "yes"
77
+ > **FreeRouter:** ✅ Confirmed!
105
78
 
106
- Lock an entire session to a specific model:
79
+ This prevents accidental switches when you're just talking *about* a model.
107
80
 
108
- - `/lock opus` 🔒 All messages use Opus until unlocked
109
- - `/lock sonnet` → 🔒 All messages use Sonnet
110
- - `/lock simple` → 🔒 Lock to SIMPLE tier's primary model
111
- - `/lock anthropic/claude-opus-4-6` → 🔒 Full model ID
112
- - `/unlock` → 🔓 Return to auto-routing
113
- - `/lock auto` → 🔓 Same as unlock
114
- - `/lock status` → Show current lock state
81
+ ### Slash Commands (Power Users)
115
82
 
116
- Session locks expire after 4 hours of inactivity.
83
+ | Command | Effect |
84
+ |---|---|
85
+ | `/opus What is 2+2?` | Per-prompt: Opus for this message only |
86
+ | `/sonnet Write a poem` | Per-prompt: Sonnet |
87
+ | `/kimi Quick answer` | Per-prompt: Kimi |
88
+ | `/haiku Translate this` | Per-prompt: Haiku |
89
+ | `/simple What is 2+2?` | Per-prompt: use SIMPLE tier model |
90
+ | `/max Prove this theorem` | Per-prompt: use REASONING tier model |
91
+ | `[opus] Deep analysis` | Bracket syntax (same as /opus) |
117
92
 
118
- ### Supported Aliases
93
+ ### Supported Model Aliases
119
94
 
120
95
  | Alias | Model |
121
96
  |-------|-------|
@@ -125,37 +100,153 @@ Session locks expire after 4 hours of inactivity.
125
100
  | `haiku`, `haiku-4`, `haiku-4.5` | anthropic/claude-haiku-4-5 |
126
101
  | `kimi`, `kimi-k2`, `k2.5` | kimi-coding/kimi-for-coding |
127
102
 
128
- ## Scoring Dimensions
103
+ ## How Routing Works
104
+
105
+ 1. You send a message → OpenClaw forwards to FreeRouter
106
+ 2. FreeRouter's 14-dimension classifier scores the request in **<1ms** (0.035ms average)
107
+ 3. Based on the score, it picks the best tier:
129
108
 
130
- The classifier evaluates 14 weighted dimensions:
109
+ | Tier | Default Model | Use Case | Cost |
110
+ |------|--------------|----------|------|
111
+ | SIMPLE | Kimi K2.5 | Quick lookups, translations, "hello" | $0.50/1M |
112
+ | MEDIUM | Claude Sonnet 4.5 | Code, creative writing, moderate tasks | $3/$15/1M |
113
+ | COMPLEX | Claude Opus 4.6 | Architecture, deep analysis | $15/$75/1M |
114
+ | REASONING | Claude Opus 4.6 | Proofs, formal logic, step-by-step | $15/$75/1M |
115
+
116
+ 4. Forwards to the real provider API (Anthropic, Kimi, OpenAI, etc.)
117
+ 5. Returns the response with the **actual model name** — not "freerouter/auto"
118
+
119
+ ### Scoring Dimensions
120
+
121
+ The classifier evaluates 14 weighted dimensions without calling any LLM:
131
122
  - Token count, code presence, reasoning markers, technical terms
132
123
  - Creative markers, simple indicators, multi-step patterns
133
124
  - Question complexity, imperative verbs, constraints
134
125
  - Output format, references, negation, domain specificity
135
- - Agentic task indicators
126
+ - Agentic task indicators (multi-tool, multi-step workflows)
127
+
128
+ Supports multilingual classification: English, Chinese, Japanese, Russian, German, Vietnamese, Arabic, Korean, and more.
129
+
130
+ ## Configure
131
+
132
+ After install, add to your `openclaw.json`:
133
+
134
+ ```json5
135
+ {
136
+ // 1. Set FreeRouter as your default model
137
+ "agents": {
138
+ "defaults": {
139
+ "model": {
140
+ "primary": "freerouter/freerouter/auto",
141
+ "fallbacks": ["anthropic/claude-opus-4-6"]
142
+ }
143
+ }
144
+ },
145
+
146
+ // 2. Add FreeRouter as a provider
147
+ "providers": {
148
+ "freerouter": {
149
+ "baseUrl": "http://127.0.0.1:18801/v1",
150
+ "api": "openai-completions"
151
+ }
152
+ },
153
+
154
+ // 3. Plugin config
155
+ "plugins": {
156
+ "entries": {
157
+ "freerouter": {
158
+ "enabled": true,
159
+ "config": {
160
+ "port": 18801,
161
+ "host": "127.0.0.1",
162
+ "tiers": {
163
+ "SIMPLE": { "primary": "kimi-coding/kimi-for-coding", "fallback": ["anthropic/claude-haiku-4-5"] },
164
+ "MEDIUM": { "primary": "anthropic/claude-sonnet-4-5", "fallback": ["anthropic/claude-opus-4-6"] },
165
+ "COMPLEX": { "primary": "anthropic/claude-opus-4-6", "fallback": [] },
166
+ "REASONING": { "primary": "anthropic/claude-opus-4-6", "fallback": [] }
167
+ },
168
+ "thinking": {
169
+ "adaptive": ["claude-opus-4-6"],
170
+ "enabled": { "models": ["claude-sonnet-4-5"], "budget": 4096 }
171
+ },
172
+ "defaultTier": "MEDIUM"
173
+ }
174
+ }
175
+ }
176
+ }
177
+ }
178
+ ```
179
+
180
+ Then restart: `openclaw gateway restart`
181
+
182
+ ## CLI Commands
183
+
184
+ | Command | Description |
185
+ |---|---|
186
+ | `openclaw freerouter status` | Show config, tier mapping, and live stats |
187
+ | `openclaw freerouter setup` | Interactive setup wizard |
188
+ | `openclaw freerouter test` | Quick 5-query classification smoke test |
189
+ | `openclaw freerouter doctor` | Diagnose issues (port conflicts, missing config, etc.) |
190
+ | `openclaw freerouter port <n>` | Change the proxy port |
191
+ | `openclaw freerouter reset` | Show default config for recovery |
192
+
193
+ ### Chat Commands
194
+
195
+ | Command | Description |
196
+ |---|---|
197
+ | `/freerouter` | Show routing stats in chat |
198
+ | `/freerouter-doctor` | Quick health check |
136
199
 
137
200
  ## Port Conflicts
138
201
 
139
- If port 18801 is in use, change it in the plugin config:
202
+ If port 18801 is in use, change it:
140
203
 
141
204
  ```json5
142
- { plugins: { entries: { freerouter: { config: { port: 18802 } } } } }
205
+ { "plugins": { "entries": { "freerouter": { "config": { "port": 18802 } } } } }
143
206
  ```
144
207
 
145
- Set `port: 0` to disable the HTTP proxy entirely.
208
+ Set `"port": 0` to disable the HTTP proxy entirely.
209
+
210
+ ## Troubleshooting
211
+
212
+ ```bash
213
+ # Check if everything is working
214
+ openclaw freerouter doctor
146
215
 
147
- ## Commands
216
+ # Quick classification test
217
+ openclaw freerouter test
148
218
 
149
- - `/freerouter` Show routing stats in chat
150
- - `openclaw freerouter status` — CLI status and stats
219
+ # Reset to defaults
220
+ openclaw freerouter reset
221
+ ```
151
222
 
152
223
  ## Response Headers
153
224
 
154
- Every proxied response includes:
155
- - `X-FreeRouter-Model` — Actual model used
156
- - `X-FreeRouter-Tier` — Classification tier
225
+ Every proxied response includes metadata headers:
226
+ - `X-FreeRouter-Model` — Actual model used (e.g., `anthropic/claude-opus-4-6`)
227
+ - `X-FreeRouter-Tier` — Classification tier (SIMPLE/MEDIUM/COMPLEX/REASONING)
157
228
  - `X-FreeRouter-Thinking` — Thinking mode (off/adaptive/enabled)
158
- - `X-FreeRouter-Reasoning` — Classification reasoning
229
+ - `X-FreeRouter-Reasoning` — Why this model was chosen
230
+
231
+ ## API Endpoints
232
+
233
+ The HTTP proxy exposes:
234
+ - `POST /v1/chat/completions` — OpenAI-compatible chat endpoint
235
+ - `GET /v1/models` — List available models
236
+ - `GET /health` — Health check
237
+ - `GET /stats` — Routing statistics
238
+ - `GET /sessions/locks` — Active session locks
239
+ - `DELETE /sessions/locks` — Clear all session locks
240
+
241
+ ## Tests
242
+
243
+ ```bash
244
+ npm test # Runs all 212 tests
245
+ ```
246
+
247
+ - `test-freerouter.mjs` — Classification, multilingual, edge cases, performance
248
+ - `test-resilience.mjs` — Fallback chains, bad configs, recovery, port conflicts
249
+ - `test-overrides.mjs` — Model overrides, session locks, natural language switching
159
250
 
160
251
  ## License
161
252
 
package/package.json CHANGED
@@ -1,10 +1,12 @@
1
1
  {
2
2
  "name": "openclaw-freerouter",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Smart LLM router plugin for OpenClaw — classify requests and route to the best model using your own API keys. 14-dimension scoring, <1ms classification, per-prompt/session model switching.",
5
5
  "type": "module",
6
6
  "openclaw": {
7
- "extensions": ["./src/index.ts"]
7
+ "extensions": [
8
+ "./src/index.ts"
9
+ ]
8
10
  },
9
11
  "main": "src/index.ts",
10
12
  "scripts": {