@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 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/anjieyang/UncommonRoute), the local LLM router that sends easy requests to cheaper models and saves stronger models for harder work.
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 profiles like `uncommon-route/auto`
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/eco` for cheapest capable routing
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, applies session-aware routing, and exposes a local dashboard at `http://127.0.0.1:8403/dashboard/`.
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\|weak\|strong` | Rate the last routing decision |
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/anjieyang/UncommonRoute)
99
+ - [GitHub](https://github.com/CommonstackAI/UncommonRoute)
98
100
  - [PyPI](https://pypi.org/project/uncommon-route/)
99
- - [Full README](https://github.com/anjieyang/UncommonRoute#readme)
101
+ - [Full README](https://github.com/CommonstackAI/UncommonRoute#readme)
100
102
 
101
103
  ## License
102
104
 
@@ -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, sessions, and spend control",
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anjieyang/uncommon-route",
3
- "version": "0.2.8",
3
+ "version": "0.3.0",
4
4
  "description": "OpenClaw plugin for UncommonRoute, the local LLM router that cuts premium-model spend",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
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, /sessions
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.2.8";
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/eco", name: "UncommonRoute Eco", reasoning: false, input: 0, output: 0, ctx: 200_000, max: 16_384 },
29
- { id: "uncommon-route/premium", name: "UncommonRoute Premium", reasoning: true, input: 0, output: 0, ctx: 200_000, max: 16_384 },
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/anjieyang/UncommonRoute",
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",