@yzj01/llm-router 1.0.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/LICENSE +21 -0
- package/README.md +160 -0
- package/dist/cli.d.ts +23 -0
- package/dist/cli.js +2490 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +370 -0
- package/dist/index.js +2726 -0
- package/dist/index.js.map +1 -0
- package/dist/proxy-CrRX9deF.d.ts +222 -0
- package/openclaw.plugin.json +37 -0
- package/package.json +63 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Xiaoyi Router contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# LLM Router
|
|
2
|
+
|
|
3
|
+
LLM Router is a small local routing proxy for OpenAI-compatible Chat Completions APIs.
|
|
4
|
+
|
|
5
|
+
## Public Model Semantics
|
|
6
|
+
|
|
7
|
+
LLM Router currently accepts exactly one client-facing request model ID: `auto`.
|
|
8
|
+
|
|
9
|
+
`config.publicModels` can still define aliases such as `flash` and `pro`, but those
|
|
10
|
+
aliases are internal routing vocabulary. They are used by `routing.tiers.*`,
|
|
11
|
+
response headers, traces, and diagnostics — not as public request IDs.
|
|
12
|
+
|
|
13
|
+
The sample `config.example.json` publishes:
|
|
14
|
+
|
|
15
|
+
- `flash`
|
|
16
|
+
- `pro`
|
|
17
|
+
|
|
18
|
+
These example aliases are not protocol constants. You can rename them, remove
|
|
19
|
+
them, or add more aliases as long as `auto` remains the router entry and
|
|
20
|
+
`routing.tiers.*.publicModel` points to alias entries.
|
|
21
|
+
|
|
22
|
+
`auto` is routed locally with a Flash-first policy. Simple summaries, short
|
|
23
|
+
text, ordinary Q&A, lightweight code edits, simple agentic work, and routine
|
|
24
|
+
structured output usually land on `flash`. Complex reasoning and natural
|
|
25
|
+
multi-file debugging or repair workflows usually land on `pro`.
|
|
26
|
+
|
|
27
|
+
Clients, OpenClaw, and SDK integrations should always send `auto`. Routed
|
|
28
|
+
aliases such as `flash` and `pro` appear in `x-xy-router-model`, traces, and
|
|
29
|
+
internal configuration only.
|
|
30
|
+
|
|
31
|
+
## Routing Thresholds
|
|
32
|
+
|
|
33
|
+
`routing.tierBoundaries` and `routing.confidenceThreshold` are the only public
|
|
34
|
+
scoring knobs.
|
|
35
|
+
|
|
36
|
+
- `routing.tierBoundaries` controls the score boundaries between `SIMPLE`,
|
|
37
|
+
`MEDIUM`, `COMPLEX`, and `REASONING`.
|
|
38
|
+
- `routing.confidenceThreshold` controls when a score is treated as ambiguous by
|
|
39
|
+
the built-in classifier.
|
|
40
|
+
|
|
41
|
+
Dimension weights, keyword lists, token thresholds, and confidence steepness
|
|
42
|
+
remain internal implementation constants and are not part of the public config
|
|
43
|
+
surface.
|
|
44
|
+
|
|
45
|
+
## Install
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npm install
|
|
49
|
+
npm run build
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Documentation
|
|
53
|
+
|
|
54
|
+
- [使用手册](./docs/usage.md)
|
|
55
|
+
- [开发文档](./docs/development.md)
|
|
56
|
+
- [设计说明](./docs/design.md)
|
|
57
|
+
- [迁移指南](./docs/migration-guide.md)
|
|
58
|
+
|
|
59
|
+
## Reference Project
|
|
60
|
+
|
|
61
|
+
For related routing and OpenClaw ecosystem context, see
|
|
62
|
+
[BlockRunAI/ClawRouter](https://github.com/BlockRunAI/ClawRouter).
|
|
63
|
+
|
|
64
|
+
## OpenClaw Compatibility
|
|
65
|
+
|
|
66
|
+
For OpenClaw v2026.4.11 and v2026.3.24, LLM Router does not register a provider
|
|
67
|
+
and does not declare providers in `openclaw.plugin.json`.
|
|
68
|
+
|
|
69
|
+
When loaded by OpenClaw, the router still writes or repairs
|
|
70
|
+
`models.providers.xiaoyiprovider` so that:
|
|
71
|
+
|
|
72
|
+
- `baseUrl` points to the local router API, for example
|
|
73
|
+
`http://127.0.0.1:8402/v1`
|
|
74
|
+
- `api` is `openai-completions`
|
|
75
|
+
- `models` only exposes `auto`, even if the routing config contains aliases such
|
|
76
|
+
as `flash` and `pro`
|
|
77
|
+
|
|
78
|
+
Existing `apiKey`, `api_key`, `headers`, `request`, and unknown provider fields
|
|
79
|
+
are preserved across Gateway restarts. The router only repairs its managed
|
|
80
|
+
fields.
|
|
81
|
+
|
|
82
|
+
## CLI Usage
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# 启动代理(必须提供配置文件)
|
|
86
|
+
llm-router --config config.json
|
|
87
|
+
|
|
88
|
+
# 自定义端口
|
|
89
|
+
llm-router --config config.json --port 9000
|
|
90
|
+
|
|
91
|
+
# Override API key
|
|
92
|
+
llm-router --config config.json --api-key sk-your-key
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**注意**:v0.2.0 起不再支持纯环境变量启动。所有基础配置必须通过 `--config`
|
|
96
|
+
指定,运行时覆写项再通过 CLI 参数传入。
|
|
97
|
+
|
|
98
|
+
## OpenClaw Plugin Usage
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# 内联配置
|
|
102
|
+
openclaw config set plugins.entries.llm-router.config.config '{"version":1,...}'
|
|
103
|
+
|
|
104
|
+
# 文件路径
|
|
105
|
+
openclaw config set plugins.entries.llm-router.config.configPath "/path/to/config.json"
|
|
106
|
+
|
|
107
|
+
# 查看 Router 注入的 provider 配置
|
|
108
|
+
openclaw config get models.providers.xiaoyiprovider
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
OpenClaw 应始终向本地 Router 请求 `auto`,再由 Router 在内部决定最终落到哪
|
|
112
|
+
个 alias / physical model。
|
|
113
|
+
|
|
114
|
+
## API
|
|
115
|
+
|
|
116
|
+
Implemented:
|
|
117
|
+
|
|
118
|
+
```text
|
|
119
|
+
GET /health
|
|
120
|
+
POST /v1/chat/completions
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Not implemented:
|
|
124
|
+
|
|
125
|
+
```text
|
|
126
|
+
GET /v1/models
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Unsupported model IDs return HTTP 400. Supported request IDs are currently only
|
|
130
|
+
`auto`. Configured aliases remain internal routing outputs and are surfaced via
|
|
131
|
+
response headers, not accepted in request bodies.
|
|
132
|
+
|
|
133
|
+
## Response Headers
|
|
134
|
+
|
|
135
|
+
The proxy adds routing headers:
|
|
136
|
+
|
|
137
|
+
- `x-xy-router-model`
|
|
138
|
+
- `x-xy-router-actual-model`
|
|
139
|
+
- `x-xy-router-tier`
|
|
140
|
+
- `x-xy-router-trace`
|
|
141
|
+
- `x-xy-router-routed`
|
|
142
|
+
- `x-xy-router-fallback`
|
|
143
|
+
- `x-xy-router-upstream`
|
|
144
|
+
|
|
145
|
+
`x-xy-router-model` is the routed alias chosen inside the router.
|
|
146
|
+
`x-xy-router-actual-model` is the physical upstream model ID used in the
|
|
147
|
+
forwarded request.
|
|
148
|
+
|
|
149
|
+
## Phase 2 Candidate: Response Cache
|
|
150
|
+
|
|
151
|
+
Response caching is intentionally not included in v0.2.0.
|
|
152
|
+
|
|
153
|
+
It is reserved as a future opt-in cost optimization for non-streaming,
|
|
154
|
+
deterministic requests. A cache key must include at least `model`, `messages`,
|
|
155
|
+
`tools`, `temperature`, `max_tokens`, and `baseUrl`, and it must distinguish
|
|
156
|
+
between routed aliases and the resolved physical upstream model.
|
|
157
|
+
|
|
158
|
+
## License
|
|
159
|
+
|
|
160
|
+
This project is licensed under the MIT License. See [LICENSE](./LICENSE).
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { P as ProxyOptions, a as ProxyHandle } from './proxy-CrRX9deF.js';
|
|
2
|
+
|
|
3
|
+
type CliRuntime = {
|
|
4
|
+
log: (msg: string) => void;
|
|
5
|
+
error: (msg: string) => void;
|
|
6
|
+
exit: (code: number) => void;
|
|
7
|
+
onSignal: (signal: string, handler: () => void) => void;
|
|
8
|
+
startProxy: (options: ProxyOptions) => Promise<ProxyHandle>;
|
|
9
|
+
};
|
|
10
|
+
type ParsedArgs = {
|
|
11
|
+
help: boolean;
|
|
12
|
+
version: boolean;
|
|
13
|
+
config?: string;
|
|
14
|
+
port?: number;
|
|
15
|
+
baseUrl?: string;
|
|
16
|
+
apiKey?: string;
|
|
17
|
+
unknown: string[];
|
|
18
|
+
};
|
|
19
|
+
declare function parseArgs(rawArgs: string[]): ParsedArgs;
|
|
20
|
+
declare function runCli(rawArgs: string[], runtime?: Partial<CliRuntime>): Promise<void>;
|
|
21
|
+
declare function isMain(): boolean;
|
|
22
|
+
|
|
23
|
+
export { type CliRuntime, type ParsedArgs, isMain, parseArgs, runCli };
|