@anjieyang/uncommon-route 0.2.8 → 0.3.0
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.
- package/README.md +15 -13
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/src/index.js +5 -24
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
<p align="right"><strong>English</strong> | <a href="https://github.com/CommonstackAI/UncommonRoute/blob/main/README.zh-CN.md">简体中文</a></p>
|
|
2
|
+
|
|
1
3
|
# @anjieyang/uncommon-route
|
|
2
4
|
|
|
3
|
-
OpenClaw plugin for [UncommonRoute](https://github.com/
|
|
5
|
+
OpenClaw plugin for [UncommonRoute](https://github.com/CommonstackAI/UncommonRoute), the local LLM router that sends easy requests to cheaper models and saves stronger models for harder work.
|
|
4
6
|
|
|
5
7
|
If you use OpenClaw and want one local endpoint with smart routing behind it, this plugin is the shortest path.
|
|
6
8
|
|
|
@@ -15,7 +17,7 @@ This plugin:
|
|
|
15
17
|
- installs the Python `uncommon-route` package if needed
|
|
16
18
|
- starts `uncommon-route serve`
|
|
17
19
|
- registers the local provider with OpenClaw
|
|
18
|
-
- exposes the virtual routing
|
|
20
|
+
- exposes the virtual routing modes like `uncommon-route/auto`
|
|
19
21
|
|
|
20
22
|
## Install
|
|
21
23
|
|
|
@@ -48,32 +50,32 @@ plugins:
|
|
|
48
50
|
Common upstream choices:
|
|
49
51
|
|
|
50
52
|
| Provider | URL |
|
|
51
|
-
|
|
53
|
+
| --- | --- |
|
|
54
|
+
| [Parallax](https://github.com/GradientHQ/parallax) | `http://127.0.0.1:3001/v1` |
|
|
52
55
|
| [Commonstack](https://commonstack.ai) | `https://api.commonstack.ai/v1` |
|
|
53
56
|
| OpenAI | `https://api.openai.com/v1` |
|
|
54
57
|
| Local Ollama / vLLM | `http://127.0.0.1:11434/v1` |
|
|
55
58
|
|
|
56
59
|
If your upstream needs a key, set `UNCOMMON_ROUTE_API_KEY` in the environment where OpenClaw runs.
|
|
57
60
|
|
|
61
|
+
Parallax is best treated as an experimental local upstream for now: its public docs show `POST /v1/chat/completions`, but UncommonRoute model discovery may be limited because a public `/v1/models` route was not obvious in the repo.
|
|
62
|
+
|
|
58
63
|
## What You Get
|
|
59
64
|
|
|
65
|
+
- a local OpenClaw provider backed by `http://127.0.0.1:8403/v1`
|
|
60
66
|
- `uncommon-route/auto` for balanced smart routing
|
|
61
|
-
- `uncommon-route/
|
|
62
|
-
- `uncommon-route/premium` for quality-first routing
|
|
63
|
-
- `uncommon-route/free` for free-first routing
|
|
64
|
-
- `uncommon-route/agentic` for tool-heavy workflows
|
|
67
|
+
- hardcoded additional virtual modes: `uncommon-route/fast` and `uncommon-route/best`
|
|
65
68
|
|
|
66
|
-
The router also keeps a fallback chain,
|
|
69
|
+
The router also keeps a fallback chain, records local feedback, and exposes a local dashboard at `http://127.0.0.1:8403/dashboard/`.
|
|
67
70
|
|
|
68
71
|
## OpenClaw Commands
|
|
69
72
|
|
|
70
73
|
| Command | Description |
|
|
71
|
-
|
|
74
|
+
| --- | --- |
|
|
72
75
|
| `/route <prompt>` | Preview which model the router would pick |
|
|
73
76
|
| `/spend status` | Show current spending and limits |
|
|
74
77
|
| `/spend set hourly 5.00` | Set an hourly spend limit |
|
|
75
|
-
| `/feedback ok
|
|
76
|
-
| `/sessions` | Show active routing sessions |
|
|
78
|
+
| `/feedback <signal>` | Use `ok`, `weak`, `strong`, `status`, or `rollback` to rate the last routing decision or inspect feedback state |
|
|
77
79
|
|
|
78
80
|
## Troubleshooting
|
|
79
81
|
|
|
@@ -94,9 +96,9 @@ Current repo benchmarks:
|
|
|
94
96
|
|
|
95
97
|
## Links
|
|
96
98
|
|
|
97
|
-
- [GitHub](https://github.com/
|
|
99
|
+
- [GitHub](https://github.com/CommonstackAI/UncommonRoute)
|
|
98
100
|
- [PyPI](https://pypi.org/project/uncommon-route/)
|
|
99
|
-
- [Full README](https://github.com/
|
|
101
|
+
- [Full README](https://github.com/CommonstackAI/UncommonRoute#readme)
|
|
100
102
|
|
|
101
103
|
## License
|
|
102
104
|
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "@anjieyang/uncommon-route",
|
|
3
3
|
"name": "UncommonRoute",
|
|
4
|
-
"description": "Local LLM router that cuts premium-model spend with smart routing,
|
|
4
|
+
"description": "Local LLM router that cuts premium-model spend with smart routing, local feedback, and spend control",
|
|
5
5
|
"configSchema": {
|
|
6
6
|
"type": "object",
|
|
7
7
|
"properties": {
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
* → ensures `uncommon-route` Python package is installed (pipx/uv/pip)
|
|
11
11
|
* → spawns `uncommon-route serve` as a managed subprocess
|
|
12
12
|
* → registerProvider pointing at localhost proxy
|
|
13
|
-
* → registerCommand for /route, /spend, /
|
|
13
|
+
* → registerCommand for /route, /spend, /feedback
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
import { spawn, execSync } from "node:child_process";
|
|
17
17
|
import { setTimeout as sleep } from "node:timers/promises";
|
|
18
18
|
|
|
19
|
-
const VERSION = "0.
|
|
19
|
+
const VERSION = "0.3.0";
|
|
20
20
|
const DEFAULT_PORT = 8403;
|
|
21
21
|
const DEFAULT_UPSTREAM = "";
|
|
22
22
|
const HEALTH_TIMEOUT_MS = 15_000;
|
|
@@ -25,10 +25,8 @@ const PY_PACKAGE = "uncommon-route";
|
|
|
25
25
|
|
|
26
26
|
const MODELS = [
|
|
27
27
|
{ id: "uncommon-route/auto", name: "UncommonRoute Auto", reasoning: false, input: 0, output: 0, ctx: 200_000, max: 16_384 },
|
|
28
|
-
{ id: "uncommon-route/
|
|
29
|
-
{ id: "uncommon-route/
|
|
30
|
-
{ id: "uncommon-route/free", name: "UncommonRoute Free", reasoning: false, input: 0, output: 0, ctx: 200_000, max: 16_384 },
|
|
31
|
-
{ id: "uncommon-route/agentic", name: "UncommonRoute Agentic", reasoning: true, input: 0, output: 0, ctx: 200_000, max: 16_384 },
|
|
28
|
+
{ id: "uncommon-route/fast", name: "UncommonRoute Fast", reasoning: false, input: 0, output: 0, ctx: 200_000, max: 16_384 },
|
|
29
|
+
{ id: "uncommon-route/best", name: "UncommonRoute Best", reasoning: true, input: 0, output: 0, ctx: 200_000, max: 16_384 },
|
|
32
30
|
{ id: "moonshot/kimi-k2.5", name: "Kimi K2.5", reasoning: false, input: 0.60, output: 3.00, ctx: 128_000, max: 8_192 },
|
|
33
31
|
{ id: "google/gemini-3.1-pro", name: "Gemini 3.1 Pro", reasoning: false, input: 2.00, output: 12.00, ctx: 200_000, max: 16_384 },
|
|
34
32
|
{ id: "xai/grok-4-1-fast-reasoning", name: "Grok 4.1 Fast", reasoning: true, input: 0.20, output: 0.50, ctx: 200_000, max: 16_384 },
|
|
@@ -220,7 +218,7 @@ const plugin = {
|
|
|
220
218
|
api.registerProvider({
|
|
221
219
|
id: "uncommon-route",
|
|
222
220
|
label: "UncommonRoute",
|
|
223
|
-
docsPath: "https://github.com/
|
|
221
|
+
docsPath: "https://github.com/CommonstackAI/UncommonRoute",
|
|
224
222
|
aliases: ["ur", "uncommon"],
|
|
225
223
|
envVars: [],
|
|
226
224
|
get models() { return buildModels(baseUrl); },
|
|
@@ -350,23 +348,6 @@ const plugin = {
|
|
|
350
348
|
},
|
|
351
349
|
});
|
|
352
350
|
|
|
353
|
-
api.registerCommand({
|
|
354
|
-
name: "sessions",
|
|
355
|
-
description: "View active routing sessions",
|
|
356
|
-
acceptsArgs: false,
|
|
357
|
-
requireAuth: false,
|
|
358
|
-
handler: async () => {
|
|
359
|
-
const data = await fetchJson(`http://127.0.0.1:${port}/v1/sessions`);
|
|
360
|
-
if (!data) return { text: "Proxy not running.", isError: true };
|
|
361
|
-
if (data.count === 0) return { text: "No active sessions" };
|
|
362
|
-
const lines = [`**Active Sessions** (${data.count})`, ""];
|
|
363
|
-
for (const s of data.sessions) {
|
|
364
|
-
lines.push(`• \`${s.id}\` model=${s.model} tier=${s.tier} requests=${s.requests} age=${s.age_s}s`);
|
|
365
|
-
}
|
|
366
|
-
return { text: lines.join("\n") };
|
|
367
|
-
},
|
|
368
|
-
});
|
|
369
|
-
|
|
370
351
|
// 3. Register service for lifecycle
|
|
371
352
|
api.registerService({
|
|
372
353
|
id: "uncommon-route-proxy",
|