chore: bump version to 1.4.0, document cooldown probing and elastic pools

README: new "冷却与半冷却探测(自愈调度)" section with the per-class cooldown
table (5xx exponential to 5min / 401-403 10min / 429 30s fixed / quota aligned
to its window), the probe-slot formula and the ordering rule that probes are
tried last. The LuaJIT section now says the pool is an elastic ceiling rather
than a preallocation and documents both step formulas. Headline figures replaced
with measured ones: idle ~10 MB, ~19 MB starting with a 29 MB audit log, and a
new bullet for on-demand log loading.

package.json also loses a `\u2014` escape and the broken indentation that an
earlier edit left in the electron-builder block.
This commit is contained in:
JianFeeeee
2026-08-30 08:07:01 +08:00
parent 23705042ee
commit 3e27f4db24
3 changed files with 44 additions and 9 deletions

View File

@ -16,7 +16,8 @@
### 极致轻量
- **单二进制**:编译后约 10MB零运行时依赖仅依赖系统 libc部署即用
- **极低内存占用**:空闲状态仅 ~15MB RSS满载并发 100+ 请求时峰值 < 100MB
- **极低内存占用**:空闲 ~10MB RSS带 29MB 历史审计日志启动仅 ~19MB满载并发 100+ 请求时峰值 < 100MB
- **日志按需加载**审计日志不常驻内存——默认只加载首屏下滚自动分页CSV 导出流式写出O(1) 内存离页即释放
- **零运行时依赖** Go + LuaJIT 静态链接无需安装 Python/Node/Java 等运行时
- **启动极快**冷启动 < 200ms热重载配置 < 10ms
@ -24,6 +25,7 @@
- **多密钥多租户**支持无限密钥每个密钥独立角色模型范围Token 配额重置周期
- **AUTO 智能调度**基于优先级档位的分级调度同优先级源自动轮询负载均衡故障自动毫秒级故障转移
- **自愈冷却**冷却上限 5 分钟过半后放行 1 个探测请求上游/额度恢复即刻回归轮询无需等满冷却窗口
- **Token 配额管理**精确到模型级别的 Token 配额控制支持小时///自定义小时周期自动重置
- **同优先级源负载均衡**同一优先级档位的多个源请求自动 Round-Robin 均匀分发故障毫秒级故障转移
- **Source-Model 前缀路由**支持 `source-model`/`source:model`/`source/model` 精确指定上游源
@ -37,7 +39,7 @@
### 灵活的协议适配
- **LuaJIT VM**每个适配器独立 VM + worker 安全并发Lua 脚本热加载无需重启
- **LuaJIT VM**每个适配器独立 VM + **弹性 worker 池**按需扩缩容空闲时自动回收安全并发Lua 脚本热加载无需重启
- **Lua 适配器协议**`transform_request` / `transform_response` / `transform_stream_chunk` 双向转换
- **动态请求头钩子**`build_headers(meta)` 支持 HMAC 签名动态 Header 注入
- **多模态透传**`image_url` 等多模态内容在多源间无损透传Anthropic/Gemini/Ollama 自动转换
@ -60,6 +62,12 @@ Groq、Mistral、Ollama、KimiCode…通过 **Lua 适配器** 做协议转换
- **生图**`POST /v1/images/generations``kind: image` 的模型独立路由
- **多模态**`content` 数组`image_url` 在多源间无损透传Anthropic/Gemini/Ollama 自动转换
- **LuaJIT VM**基于 golua 绑定的 LuaJIT每个适配器独立 VM + worker 安全并发
池是 **弹性** `Σ max_concurrent` 只是上限而非预分配状态按需创建空闲时自动回收
因此空载网关几乎不持有 Lua 状态启动 0 )。
- 扩容步长由适配器最大并发决定`clamp(ceil(max/8), 1, 8)`且仅在**真实并发争用**
所有现有状态均已占用时批量预热顺序流量始终只用 1 个状态
- 缩容步长由当前连接数决定`clamp(ceil(冗余/(1+占用)), 1, 冗余)`——无连接时一轮收到
常驻下限忙时每轮只释放 1 保护热路径WebUI适配器页展示实时池指标
- **disable_thinking**请求 `disable_thinking:true`或上游对应字段动态开关推理
- **Lua 适配协议**每个源挂一个 `.lua` 适配器完成 `transform_request` /
`transform_response` / `transform_stream_chunk` 双向转换协议差异全在 Lua
@ -203,6 +211,33 @@ AUTO 调度**只**由优先级页保存的规则决定,源配置里的 `models
- 同 tier 内按「偏好分」排序,失败槽位冷却后自动跳过;冷却 / 配额耗尽 / hard
错误会顺延到下一 tier全部失败时返回 503 并附上每档失败摘要。
### 冷却与半冷却探测(自愈调度)
槽位失败后进入指数退避冷却5s → 10s → 20s …,上限 **5 分钟**)。冷却不是全时段
硬闸:
- **前半段完全静默**:刚失败的槽位不接任何流量,避免对故障上游持续施压。
- **后半段放行 1 个探测**:窗口过半后,同一 `(源, 模型)` 最多允许 **一个** 请求作为
探测通过。探测槽数 = `clamp(max_concurrent / 10, 1, 2)`——`max_concurrent: 10`
的源恰好放行 1 个探测请求。
- **探测排在最后**:同 tier 内探测候选永远排在健康候选之后,只有没有正常槽可用时
才承接真实流量,因此探测不会抢走可用容量。
- **探测即真实请求**:成功则立即清零失败计数与冷却,槽位当场回到正常轮询——
上游恢复/额度恢复后不必等满整个冷却窗口。失败则重开一个新窗口,下次探测顺延到
新窗口的中点,不会连续重试。
分类冷却策略:
| 情况 | 冷却 | 说明 |
|---|---|---|
| 传输错误 / 5xx | 5s→10s→20s…上限 5min | 指数退避 |
| 401 / 403 凭据错误 | 10min | 换 key 后由下一次探测自动接回 |
| 429 限流 | 30s 固定 | 「太快」不等于「坏了」,不进指数阶梯 |
| 配额耗尽(`insufficient_quota` / `余额不足` 等) | 对齐配额窗口,上限 30min | **不进指数阶梯、不涨失败计数**,额度恢复即可用 |
WebUI「优先级」页的槽位健康标签会区分 `冷却` / `待探测` / `探测中`,悬停可看窗口
起点、探测放行时刻与完全恢复时刻。
### 源Source与适配器Adapter的关系
- **源** 是到某个上游的连接描述:`name``base_url``api_key`、模型列表与优先级。
@ -220,7 +255,7 @@ AUTO 调度**只**由优先级页保存的规则决定,源配置里的 `models
2. `config.Load` 读取 `config.yaml``config.NewStore(runtime_file)` 读 WebUI 改动的
运行时源,二者按名称合并成完整源列表。
3. `rebuildRegistry` 为每个源创建 `provider.Provider`(持有目标适配器),并按源的
并发上限配置适配器 worker 池大小
并发上限配置适配器 worker 池**上限**(不预分配,见下)
4. 请求进来时 `Registry``model` 路由到 ProviderProvider 调适配器
`transform_request` → HTTP 发送 → `transform_response` / `transform_stream_chunk`

View File

@ -1,12 +1,12 @@
{
"name": "modelrouter-gui",
"version": "1.2.0",
"version": "1.4.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "modelrouter-gui",
"version": "1.2.0",
"version": "1.4.0",
"license": "Proprietary",
"devDependencies": {
"electron": "^33.0.0",

View File

@ -1,6 +1,6 @@
{
"name": "modelrouter-gui",
"version": "1.2.0",
"version": "1.4.0",
"description": "ModelRouter Desktop — embedded ModelRouter core with tray",
"author": "ModelRouter",
"main": "main.js",
@ -22,7 +22,7 @@
"build": {
"appId": "com.modelrouter.gui",
"productName": "ModelRouter",
"linux": {
"linux": {
"target": [
"deb",
"rpm",
@ -32,9 +32,9 @@
"icon": "build/icon.png",
"maintainer": "ModelRouter",
"synopsis": "ModelRouter Desktop",
"desktop": {
"desktop": {
"entry": {
"StartupWMClass": "modelrouter-gui"
"StartupWMClass": "modelrouter-gui"
}
},
"extraResources": [