@zhz8888/dsh-radeon-cloud-patcher 1.2.1 → 1.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 +30 -13
- package/cordis.plugin.patch.yml +37 -8
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +5 -2
- package/provider/radeon-cloud.yml +37 -8
- package/scripts/probe-efforts.mjs +48 -6
package/README.md
CHANGED
|
@@ -30,13 +30,15 @@
|
|
|
30
30
|
命令行执行
|
|
31
31
|
`dsh plugin --profile <profile> add @zhz8888/dsh-radeon-cloud-patcher`。
|
|
32
32
|
装不上(pnpm 报 404)就改用[安装](#安装)里的方式三,从源码装同一个包。
|
|
33
|
+
装好后插件列表里显示的条目名是 **Radeon Cloud**(中文界面为「Radeon Cloud 提供方」),
|
|
34
|
+
而不是上面那串包名——名称取自包内的 `locale/`,见[项目结构](#项目结构)。
|
|
33
35
|
2. **重启 DSH** —— 定义写在补丁层的 config 行里,插件管理器对这类变更只会给出
|
|
34
36
|
`restart-required`,不会在运行中生效。重启后 provider 就位,没有其它后置步骤。
|
|
35
37
|
3. **填密钥** —— 左下角「账号菜单 → 设置 → 模型」,找到 **Radeon Cloud** 一行,
|
|
36
38
|
点「编辑」,在「API 密钥」里粘贴密钥,点「保存」。
|
|
37
39
|
|
|
38
40
|
装好之后:那一行右侧出现**绿点**(悬停显示「API 密钥已配置」);回到对话,点输入框下方的
|
|
39
|
-
模型选择器,Radeon 的
|
|
41
|
+
模型选择器,Radeon 的 10 个模型会出现在列表里;选中模型后再选「推理等级」就是思考档位。
|
|
40
42
|
|
|
41
43
|
**怎么确认真的装好了** —— 三个现象同时成立,说明插件与它的补丁层都到位:
|
|
42
44
|
|
|
@@ -109,7 +111,7 @@ Radeon 的响应体与流式分片都存在一个容易致错的形态:思考
|
|
|
109
111
|
|
|
110
112
|
### 其他
|
|
111
113
|
|
|
112
|
-
-
|
|
114
|
+
- 10 个对话模型全部可选,思考档位按模型独立声明
|
|
113
115
|
- 视觉模型支持图片输入
|
|
114
116
|
- 限流退避遵循服务端 `Retry-After`
|
|
115
117
|
- 附带离线校验、回归测试与档位实测工具
|
|
@@ -282,13 +284,15 @@ RADEON_CLOUD_API_KEY=rc-你的密钥 dsh --profile <profile>
|
|
|
282
284
|
|
|
283
285
|
对话输入框下方点模型选择器 → 选 Radeon Cloud 的模型 → 再选「推理等级」,
|
|
284
286
|
那就是思考档位。档位按模型逐个声明(见[可用模型](#可用模型)):
|
|
285
|
-
GLM 不接受 `none
|
|
286
|
-
|
|
287
|
+
GLM-5.3-Flash 与 MiniCPM-V-4.7-1B 不接受 `none`,因此没有关闭档位;
|
|
288
|
+
`MiniCPM5-2B` 不是推理模型,不会出现档位下拉。
|
|
289
|
+
选了服务端不接受的档位是**硬失败**(400 / 422),不会静默降级。
|
|
287
290
|
|
|
288
291
|
### 3. 图片输入
|
|
289
292
|
|
|
290
293
|
支持图片:DeepSeek-V4.1-Flash、DeepSeek-V4-Flash-Vision-Exp、MiMo-V2.6-Flash、
|
|
291
|
-
Qwen3.8-27B、Qwen3.8-Flash-Next
|
|
294
|
+
MiniCPM-V-4.7-1B、MiniCPM-V-4.7-35B-A3B、Qwen3.8-27B、Qwen3.8-Flash-Next。
|
|
295
|
+
只收文本:DeepSeek-V4-Flash、GLM-5.3-Flash、MiniCPM5-2B。
|
|
292
296
|
|
|
293
297
|
### 4. 升级与卸载
|
|
294
298
|
|
|
@@ -385,6 +389,10 @@ dsh-radeon-cloud-patcher/
|
|
|
385
389
|
├── client/ 客户端补丁
|
|
386
390
|
│ └── client.js 隐藏本行的「自定义」标签(DSH 客户端模块格式,非 ESM)
|
|
387
391
|
│
|
|
392
|
+
├── locale/ 插件页显示名称(DSH 按包内 locale 读取,缺了就回落成 npm 包名)
|
|
393
|
+
│ ├── en.json 英文:{"meta":{"title":"Radeon Cloud",…}}
|
|
394
|
+
│ └── zh.json 中文:{"meta":{"title":"Radeon Cloud 提供方",…}}
|
|
395
|
+
│
|
|
388
396
|
├── src/ 插件实现(薄壳,不含 provider 逻辑)
|
|
389
397
|
│ ├── index.js 插件入口:启动校验、所有权判定、收尾核验
|
|
390
398
|
│ ├── ownership.js 所有权判定的纯函数(四种归属结局 + dynamic 哨兵、差异定位)
|
|
@@ -401,8 +409,9 @@ dsh-radeon-cloud-patcher/
|
|
|
401
409
|
│ └── radeon-api.sh API 调用助手(密钥取自环境变量或凭据存储)
|
|
402
410
|
│
|
|
403
411
|
├── test/ 离线测试(自研 runner,无测试框架)
|
|
404
|
-
│ ├── *.test.mjs
|
|
405
|
-
│ │
|
|
412
|
+
│ ├── *.test.mjs 清单不变式、插件页元信息、合并语义、
|
|
413
|
+
│ │ 文本级编辑、所有权判定、启动看护、
|
|
414
|
+
│ │ 补丁与客户端一致性
|
|
406
415
|
│ ├── verify-reasoning.mjs 思考文本取回的回归测试
|
|
407
416
|
│ └── fixtures/stream-reasoning.sse 实测抓取的真实流
|
|
408
417
|
│
|
|
@@ -420,13 +429,16 @@ dsh-radeon-cloud-patcher/
|
|
|
420
429
|
## 常用命令
|
|
421
430
|
|
|
422
431
|
```bash
|
|
423
|
-
#
|
|
432
|
+
# 全量测试(清单不变式、插件页元信息、合并语义、所有权判定、启动看护、补丁一致性、思考字段取回)
|
|
424
433
|
pnpm test
|
|
425
434
|
|
|
426
435
|
# 只跑启动看护(四种归属结局 + dynamic 跳过)与补丁一致性
|
|
427
436
|
pnpm test:guard
|
|
428
437
|
pnpm test:patch
|
|
429
438
|
|
|
439
|
+
# 只跑插件页显示名称的契约(locale 文件 + exports 模式 + files 白名单)
|
|
440
|
+
pnpm test:meta
|
|
441
|
+
|
|
430
442
|
# 校验 provider 定义:结构校验 + llm-pi-ai 真实 schema 校验
|
|
431
443
|
# 这是判断「字段在当前 DSH 版本里是否仍然有效」的那道校验,建议升级 DSH 后跑一次
|
|
432
444
|
pnpm validate
|
|
@@ -448,7 +460,7 @@ pnpm probe --only Qwen3.8-27B
|
|
|
448
460
|
|
|
449
461
|
## 可用模型
|
|
450
462
|
|
|
451
|
-
> 采集日期:**2026-10-
|
|
463
|
+
> 采集日期:**2026-10-16**
|
|
452
464
|
|
|
453
465
|
| 模型 | 上下文 | 图片 | 思考档位 |
|
|
454
466
|
| --- | --- | --- | --- |
|
|
@@ -456,13 +468,16 @@ pnpm probe --only Qwen3.8-27B
|
|
|
456
468
|
| DeepSeek-V4-Flash | 1,048,576 | ❌ | off/minimal/low/medium/high/xhigh/max |
|
|
457
469
|
| DeepSeek-V4-Flash-Vision-Exp | 1,048,576 | ✅ | off/minimal/low/medium/high/xhigh/max |
|
|
458
470
|
| MiMo-V2.6-Flash | 1,048,576 | ✅ | off/minimal/low/medium/high/xhigh/max |
|
|
471
|
+
| MiniCPM-V-4.7-35B-A3B | 262,144 | ✅ | off/minimal/low/medium/high/xhigh/max |
|
|
459
472
|
| Qwen3.8-27B | 262,144 | ✅ | off/low/medium/xhigh |
|
|
460
473
|
| Qwen3.8-Flash-Next | 262,144 | ✅ | off/low/medium/xhigh |
|
|
461
474
|
| GLM-5.3-Flash | 262,144 | ❌ | low/medium/high |
|
|
475
|
+
| MiniCPM-V-4.7-1B | 262,144 | ✅ | low/medium/high |
|
|
462
476
|
| MiniCPM5-2B | 131,072 | ❌ | (不返回分离思考,故不提供档位) |
|
|
463
477
|
|
|
464
478
|
`off` 表示发送 `reasoning_effort: "none"` 关闭思考。
|
|
465
|
-
**GLM-5.3-Flash 不接受 `none`**,因此没有关闭档位;Qwen 系靠 `none` 关闭,而**不传档位时仍会思考**(AMD 服务端行为)。
|
|
479
|
+
**GLM-5.3-Flash 与 MiniCPM-V-4.7-1B 不接受 `none`**,因此没有关闭档位;Qwen 系靠 `none` 关闭,而**不传档位时仍会思考**(AMD 服务端行为)。
|
|
480
|
+
`MiniCPM-V-4.7-35B-A3B` 与 `MiniCPM-V-4.7-1B` 同属 MiniCPM 系,但档位表并不相同——**不要按模型名的相近程度推断档位**。
|
|
466
481
|
|
|
467
482
|
> **档位表不在 API 里**(`GET /v1/models` 不返回该信息),只能实测。模型上下架会导致此表过期,
|
|
468
483
|
> 请用 `pnpm probe` 复测后再更新 `provider/radeon-cloud.yml`。
|
|
@@ -496,8 +511,10 @@ DSH 的 `dsh-llm-pi-ai` 会对此抛 `UNSUPPORTED_OPTION`,属于响亮失败
|
|
|
496
511
|
|
|
497
512
|
### 3. 部分模型不接受 `developer` 角色
|
|
498
513
|
|
|
499
|
-
DSH 默认对 OpenAI 兼容端点使用 `developer` 承载系统提示词,
|
|
500
|
-
`unknown role: developer
|
|
514
|
+
DSH 默认对 OpenAI 兼容端点使用 `developer` 承载系统提示词,10 个模型中有 6 个会拒绝,
|
|
515
|
+
且报错文本分两种:GLM-5.3-Flash、MiniCPM5-2B、MiniCPM-V-4.7-1B 报 `422 unknown role: developer`;
|
|
516
|
+
Qwen 系两个与 MiniCPM-V-4.7-35B-A3B 报 `400 Unexpected message role.`。
|
|
517
|
+
已通过 `compat.supportsDeveloperRole: false` 关闭,改用 `system` 角色。
|
|
501
518
|
|
|
502
519
|
### 4. 档位被拒是硬失败
|
|
503
520
|
|
|
@@ -532,7 +549,7 @@ node ~/.dsh/profiles/<profile>/node_modules/@zhz8888/dsh-radeon-cloud-patcher/sc
|
|
|
532
549
|
|
|
533
550
|
```
|
|
534
551
|
【写入】 ~/.dsh/profiles/desktop/cordis.patch.yml
|
|
535
|
-
新增 providers.radeon-cloud(
|
|
552
|
+
新增 providers.radeon-cloud(10 个模型)
|
|
536
553
|
保留的其它 provider:my-corp-proxy, another-one
|
|
537
554
|
顶层条目 12 个,增减 0 个
|
|
538
555
|
```
|
package/cordis.plugin.patch.yml
CHANGED
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
baseURL: https://developer.amd.com.cn/radeon/api/v1
|
|
50
50
|
displayName: Radeon Cloud
|
|
51
51
|
|
|
52
|
-
# 默认思考档位。medium 在全部
|
|
52
|
+
# 默认思考档位。medium 在全部 10 个已收录模型上均被接受。
|
|
53
53
|
reasoning: medium
|
|
54
54
|
|
|
55
55
|
# Radeon 的思考与答案共用同一个 max_tokens 预算,预算不足时 content
|
|
@@ -76,7 +76,9 @@
|
|
|
76
76
|
# ── 协议兼容开关 ──────────────────────────────────────────────
|
|
77
77
|
compat:
|
|
78
78
|
# ★ 关键:DSH 默认对普通 OpenAI 兼容端点发送 developer 角色,
|
|
79
|
-
# 而
|
|
79
|
+
# 而 10 个模型中有 6 个直接拒绝——GLM-5.3-Flash、MiniCPM5-2B、
|
|
80
|
+
# MiniCPM-V-4.7-1B 报 422 unknown role: developer,Qwen 系两个与
|
|
81
|
+
# MiniCPM-V-4.7-35B-A3B 报 400 Unexpected message role。
|
|
80
82
|
supportsDeveloperRole: false
|
|
81
83
|
supportsReasoningEffort: true
|
|
82
84
|
# Radeon 的网关只按白名单转发字段,thinking_budget /
|
|
@@ -87,11 +89,14 @@
|
|
|
87
89
|
thinkingFormat: openai
|
|
88
90
|
|
|
89
91
|
# ── 模型目录 ──────────────────────────────────────────────────
|
|
90
|
-
# 共收录
|
|
92
|
+
# 共收录 10 个对话模型。目录接口里还有 MinerU2.5-Pro,但它的
|
|
91
93
|
# context_length 为 0、tools 为 false,走的是独立的 /v1/ocr
|
|
92
94
|
# 文档识别端点而非对话接口,故不收录。
|
|
95
|
+
#
|
|
96
|
+
# 下面的分组按「档位表的形状」而非厂商划分——同一个厂商的模型档位
|
|
97
|
+
# 未必相同(MiniCPM 系即是如此),按厂商分组会把读者引向错误预期。
|
|
93
98
|
models:
|
|
94
|
-
# ──
|
|
99
|
+
# ── 全档接受:none 可关闭思考 ──
|
|
95
100
|
- id: DeepSeek-V4.1-Flash
|
|
96
101
|
name: DeepSeek-V4.1-Flash
|
|
97
102
|
contextWindow: 1048576
|
|
@@ -144,6 +149,21 @@
|
|
|
144
149
|
xhigh: xhigh
|
|
145
150
|
max: max
|
|
146
151
|
|
|
152
|
+
# 同一个 MiniCPM 系里两个模型档位形状并不相同:35B-A3B 全档接受,
|
|
153
|
+
# 1B 只接受 low/medium/high。实测确认两者都返回分离的思考内容。
|
|
154
|
+
- id: MiniCPM-V-4.7-35B-A3B
|
|
155
|
+
name: MiniCPM-V-4.7-35B-A3B
|
|
156
|
+
contextWindow: 262144
|
|
157
|
+
input: [text, image]
|
|
158
|
+
reasoningEfforts:
|
|
159
|
+
off: none
|
|
160
|
+
minimal: minimal
|
|
161
|
+
low: low
|
|
162
|
+
medium: medium
|
|
163
|
+
high: high
|
|
164
|
+
xhigh: xhigh
|
|
165
|
+
max: max
|
|
166
|
+
|
|
147
167
|
# ── Qwen 系:无 minimal/max/high,仅 none/low/medium/xhigh ──
|
|
148
168
|
# 这两个模型唯一能关闭思考的方式是 none;传入 high 会返回 400。
|
|
149
169
|
- id: Qwen3.8-27B
|
|
@@ -166,8 +186,8 @@
|
|
|
166
186
|
medium: medium
|
|
167
187
|
xhigh: xhigh
|
|
168
188
|
|
|
169
|
-
# ──
|
|
170
|
-
# 不声明 off
|
|
189
|
+
# ── 仅 low/medium/high:不接受 none/minimal/xhigh/max ──
|
|
190
|
+
# 不声明 off 键:这两个模型没有「关闭思考」的档位。
|
|
171
191
|
- id: GLM-5.3-Flash
|
|
172
192
|
name: GLM-5.3-Flash
|
|
173
193
|
contextWindow: 262144
|
|
@@ -177,9 +197,18 @@
|
|
|
177
197
|
medium: medium
|
|
178
198
|
high: high
|
|
179
199
|
|
|
200
|
+
- id: MiniCPM-V-4.7-1B
|
|
201
|
+
name: MiniCPM-V-4.7-1B
|
|
202
|
+
contextWindow: 262144
|
|
203
|
+
input: [text, image]
|
|
204
|
+
reasoningEfforts:
|
|
205
|
+
low: low
|
|
206
|
+
medium: medium
|
|
207
|
+
high: high
|
|
208
|
+
|
|
180
209
|
# MiniCPM5-2B 接受 low/medium/high,但不返回分离的思考内容
|
|
181
|
-
#
|
|
182
|
-
#
|
|
210
|
+
# (实测 reasoning 恒为空、reasoning_tokens 为 0)。
|
|
211
|
+
# 给出档位控件会误导用户,故显式声明为非推理模型。
|
|
183
212
|
- id: MiniCPM5-2B
|
|
184
213
|
name: MiniCPM5-2B
|
|
185
214
|
contextWindow: 131072
|
package/locale/en.json
ADDED
package/locale/zh.json
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhz8888/dsh-radeon-cloud-patcher",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "为 DeepSeek Harness 接入 AMD Radeon Cloud,完整支持模型思考(reasoning)功能。provider 定义由插件自带的补丁层声明,交由 DSH 自带的 dsh-llm-pi-ai 承载,不修改 DSH 本体、不写用户 profile,也不自研适配器。",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"amd",
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"./merge": "./src/merge.js",
|
|
35
35
|
"./provider": "./provider/radeon-cloud.yml",
|
|
36
36
|
"./client": "./client/client.js",
|
|
37
|
+
"./locale/*.json": "./locale/*.json",
|
|
37
38
|
"./package.json": "./package.json"
|
|
38
39
|
},
|
|
39
40
|
"dsh": {
|
|
@@ -59,14 +60,16 @@
|
|
|
59
60
|
"src",
|
|
60
61
|
"client",
|
|
61
62
|
"provider",
|
|
63
|
+
"locale",
|
|
62
64
|
"scripts",
|
|
63
65
|
"cordis.plugin.patch.yml",
|
|
64
66
|
"LICENSE",
|
|
65
67
|
"README.md"
|
|
66
68
|
],
|
|
67
69
|
"scripts": {
|
|
68
|
-
"test": "node test/manifest.test.mjs && node test/merge.test.mjs && node test/patch-text.test.mjs && node test/ownership.test.mjs && node test/apply-guard.test.mjs && node test/patch-sync.test.mjs && node test/client-patch.test.mjs && node test/verify-reasoning.mjs",
|
|
70
|
+
"test": "node test/manifest.test.mjs && node test/plugin-meta.test.mjs && node test/merge.test.mjs && node test/patch-text.test.mjs && node test/ownership.test.mjs && node test/apply-guard.test.mjs && node test/patch-sync.test.mjs && node test/client-patch.test.mjs && node test/verify-reasoning.mjs",
|
|
69
71
|
"test:manifest": "node test/manifest.test.mjs",
|
|
72
|
+
"test:meta": "node test/plugin-meta.test.mjs",
|
|
70
73
|
"test:merge": "node test/merge.test.mjs && node test/patch-text.test.mjs && node test/ownership.test.mjs",
|
|
71
74
|
"test:guard": "node test/apply-guard.test.mjs",
|
|
72
75
|
"test:patch": "node test/patch-sync.test.mjs && node test/client-patch.test.mjs",
|
|
@@ -17,7 +17,7 @@ api: openai-completions
|
|
|
17
17
|
baseURL: https://developer.amd.com.cn/radeon/api/v1
|
|
18
18
|
displayName: Radeon Cloud
|
|
19
19
|
|
|
20
|
-
# 默认思考档位。medium 在全部
|
|
20
|
+
# 默认思考档位。medium 在全部 10 个已收录模型上均被接受。
|
|
21
21
|
reasoning: medium
|
|
22
22
|
|
|
23
23
|
# Radeon 的思考与答案共用同一个 max_tokens 预算,预算不足时 content
|
|
@@ -44,7 +44,9 @@ retryPolicy:
|
|
|
44
44
|
# ── 协议兼容开关 ──────────────────────────────────────────────
|
|
45
45
|
compat:
|
|
46
46
|
# ★ 关键:DSH 默认对普通 OpenAI 兼容端点发送 developer 角色,
|
|
47
|
-
# 而
|
|
47
|
+
# 而 10 个模型中有 6 个直接拒绝——GLM-5.3-Flash、MiniCPM5-2B、
|
|
48
|
+
# MiniCPM-V-4.7-1B 报 422 unknown role: developer,Qwen 系两个与
|
|
49
|
+
# MiniCPM-V-4.7-35B-A3B 报 400 Unexpected message role。
|
|
48
50
|
supportsDeveloperRole: false
|
|
49
51
|
supportsReasoningEffort: true
|
|
50
52
|
# Radeon 的网关只按白名单转发字段,thinking_budget /
|
|
@@ -55,11 +57,14 @@ compat:
|
|
|
55
57
|
thinkingFormat: openai
|
|
56
58
|
|
|
57
59
|
# ── 模型目录 ──────────────────────────────────────────────────
|
|
58
|
-
# 共收录
|
|
60
|
+
# 共收录 10 个对话模型。目录接口里还有 MinerU2.5-Pro,但它的
|
|
59
61
|
# context_length 为 0、tools 为 false,走的是独立的 /v1/ocr
|
|
60
62
|
# 文档识别端点而非对话接口,故不收录。
|
|
63
|
+
#
|
|
64
|
+
# 下面的分组按「档位表的形状」而非厂商划分——同一个厂商的模型档位
|
|
65
|
+
# 未必相同(MiniCPM 系即是如此),按厂商分组会把读者引向错误预期。
|
|
61
66
|
models:
|
|
62
|
-
# ──
|
|
67
|
+
# ── 全档接受:none 可关闭思考 ──
|
|
63
68
|
- id: DeepSeek-V4.1-Flash
|
|
64
69
|
name: DeepSeek-V4.1-Flash
|
|
65
70
|
contextWindow: 1048576
|
|
@@ -112,6 +117,21 @@ models:
|
|
|
112
117
|
xhigh: xhigh
|
|
113
118
|
max: max
|
|
114
119
|
|
|
120
|
+
# 同一个 MiniCPM 系里两个模型档位形状并不相同:35B-A3B 全档接受,
|
|
121
|
+
# 1B 只接受 low/medium/high。实测确认两者都返回分离的思考内容。
|
|
122
|
+
- id: MiniCPM-V-4.7-35B-A3B
|
|
123
|
+
name: MiniCPM-V-4.7-35B-A3B
|
|
124
|
+
contextWindow: 262144
|
|
125
|
+
input: [text, image]
|
|
126
|
+
reasoningEfforts:
|
|
127
|
+
off: none
|
|
128
|
+
minimal: minimal
|
|
129
|
+
low: low
|
|
130
|
+
medium: medium
|
|
131
|
+
high: high
|
|
132
|
+
xhigh: xhigh
|
|
133
|
+
max: max
|
|
134
|
+
|
|
115
135
|
# ── Qwen 系:无 minimal/max/high,仅 none/low/medium/xhigh ──
|
|
116
136
|
# 这两个模型唯一能关闭思考的方式是 none;传入 high 会返回 400。
|
|
117
137
|
- id: Qwen3.8-27B
|
|
@@ -134,8 +154,8 @@ models:
|
|
|
134
154
|
medium: medium
|
|
135
155
|
xhigh: xhigh
|
|
136
156
|
|
|
137
|
-
# ──
|
|
138
|
-
# 不声明 off
|
|
157
|
+
# ── 仅 low/medium/high:不接受 none/minimal/xhigh/max ──
|
|
158
|
+
# 不声明 off 键:这两个模型没有「关闭思考」的档位。
|
|
139
159
|
- id: GLM-5.3-Flash
|
|
140
160
|
name: GLM-5.3-Flash
|
|
141
161
|
contextWindow: 262144
|
|
@@ -145,9 +165,18 @@ models:
|
|
|
145
165
|
medium: medium
|
|
146
166
|
high: high
|
|
147
167
|
|
|
168
|
+
- id: MiniCPM-V-4.7-1B
|
|
169
|
+
name: MiniCPM-V-4.7-1B
|
|
170
|
+
contextWindow: 262144
|
|
171
|
+
input: [text, image]
|
|
172
|
+
reasoningEfforts:
|
|
173
|
+
low: low
|
|
174
|
+
medium: medium
|
|
175
|
+
high: high
|
|
176
|
+
|
|
148
177
|
# MiniCPM5-2B 接受 low/medium/high,但不返回分离的思考内容
|
|
149
|
-
#
|
|
150
|
-
#
|
|
178
|
+
# (实测 reasoning 恒为空、reasoning_tokens 为 0)。
|
|
179
|
+
# 给出档位控件会误导用户,故显式声明为非推理模型。
|
|
151
180
|
- id: MiniCPM5-2B
|
|
152
181
|
name: MiniCPM5-2B
|
|
153
182
|
contextWindow: 131072
|
|
@@ -9,11 +9,14 @@
|
|
|
9
9
|
*
|
|
10
10
|
* 探测手法:对每个「模型 × 档位」组合发一次 max_tokens 为 1 的极小请求,
|
|
11
11
|
* 只看 HTTP 状态码,200 即视为接受,不关心回复内容;这样单次探测的产出
|
|
12
|
-
* token
|
|
12
|
+
* token 成本可忽略。
|
|
13
13
|
*
|
|
14
|
-
*
|
|
14
|
+
* 只有 200 才是「接受」;400 与 422 才是「拒绝」。429(限流)与 5xx
|
|
15
|
+
* (上游偶发故障,README 记录过 504 被包装成 500)都不构成结论,本脚本会
|
|
16
|
+
* 自动重测,避免把「测不出来」写成档位表里的一个 ✗——那会让用户在选择器里
|
|
17
|
+
* 少一个本来可用的档位,且全程不产生任何报错。
|
|
15
18
|
*
|
|
16
|
-
* 用法: node scripts/probe-efforts.mjs [--only ModelId] [--tiers a,b,c]
|
|
19
|
+
* 用法: node scripts/probe-efforts.mjs [--only ModelId] [--tiers a,b,c] [--interval 毫秒]
|
|
17
20
|
*/
|
|
18
21
|
import { execFile } from 'node:child_process'
|
|
19
22
|
import { promisify } from 'node:util'
|
|
@@ -48,8 +51,22 @@ const only = argOf('--only')
|
|
|
48
51
|
/** 只探测这些档位,逗号分隔;未指定时用 ALL_TIERS。 */
|
|
49
52
|
const tiers = (argOf('--tiers') ?? ALL_TIERS.join(',')).split(',')
|
|
50
53
|
|
|
51
|
-
/**
|
|
52
|
-
|
|
54
|
+
/** 相邻两次请求之间的默认最小间隔。
|
|
55
|
+
*
|
|
56
|
+
* 网关的账户限流是每分钟 20 次(响应头 x-ratelimit-limit-user-rpm)。原先取
|
|
57
|
+
* 3100 毫秒看似合规(≈19.4 次/分),但节流判据是「距上次请求满 3.1 秒」,
|
|
58
|
+
* 第 21 次请求会落在与第 1 次同一个滚动窗口内,实测必踩 429。取 4500 毫秒
|
|
59
|
+
* 把网关这一层躲开;上游自身仍会偶发限流,那由下面的重测兜住。 */
|
|
60
|
+
const DEFAULT_INTERVAL_MS = 4500
|
|
61
|
+
/** 相邻两次请求之间的最小间隔,可用 --interval 覆盖。 */
|
|
62
|
+
const MIN_INTERVAL_MS = Number(argOf('--interval') ?? DEFAULT_INTERVAL_MS)
|
|
63
|
+
/** 命中 429 后的冷却时长:服务端 Retry-After 为 60 秒,多留几秒余量。 */
|
|
64
|
+
const RATE_LIMIT_COOLDOWN_MS = 65000
|
|
65
|
+
/** 命中 5xx 后的重试间隔。上游偶发故障,等几秒再问通常就好了。 */
|
|
66
|
+
const UPSTREAM_RETRY_DELAY_MS = 5000
|
|
67
|
+
/** 单个「模型 × 档位」组合命中可重试错误后最多重测的次数。 */
|
|
68
|
+
const MAX_RETRIES = 2
|
|
69
|
+
|
|
53
70
|
/** 上一次请求发出的时间戳,用于计算需要等待多久。 */
|
|
54
71
|
let lastAt = 0
|
|
55
72
|
|
|
@@ -73,6 +90,30 @@ async function throttle() {
|
|
|
73
90
|
* @returns {Promise<{status: number, error?: string}>} HTTP 状态码;取不到时为 -1
|
|
74
91
|
*/
|
|
75
92
|
async function call(model, effort) {
|
|
93
|
+
for (let attempt = 0; ; attempt += 1) {
|
|
94
|
+
const res = await once(model, effort)
|
|
95
|
+
// 429 是限流,5xx 是上游故障,两者都测不出该档位的真实结论。直接返回会把
|
|
96
|
+
// 「没测到」写成「不接受」,进而从档位表里删掉一个本来可用的档位,所以必须重测。
|
|
97
|
+
const delay = res.status === 429
|
|
98
|
+
? RATE_LIMIT_COOLDOWN_MS
|
|
99
|
+
: res.status >= 500 ? UPSTREAM_RETRY_DELAY_MS : 0
|
|
100
|
+
if (delay === 0 || attempt >= MAX_RETRIES) return res
|
|
101
|
+
process.stderr.write(
|
|
102
|
+
` ${model.padEnd(30)} ${effort.padEnd(9)} ${res.status} 非结论,`
|
|
103
|
+
+ `${delay / 1000} 秒后重测(第 ${attempt + 1} 次)\n`,
|
|
104
|
+
)
|
|
105
|
+
await new Promise((r) => setTimeout(r, delay))
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* 发起一次探测请求,不做限流重试。
|
|
111
|
+
*
|
|
112
|
+
* @param {string} model 模型 id
|
|
113
|
+
* @param {string} effort reasoning_effort 取值
|
|
114
|
+
* @returns {Promise<{status: number, error?: string}>} HTTP 状态码;取不到时为 -1
|
|
115
|
+
*/
|
|
116
|
+
async function once(model, effort) {
|
|
76
117
|
await throttle()
|
|
77
118
|
// max_tokens 压到 1,让这次请求只为确认档位是否被接受,不产生实际产出。
|
|
78
119
|
const body = JSON.stringify({
|
|
@@ -118,7 +159,8 @@ for (const model of models) {
|
|
|
118
159
|
for (const effort of tiers) {
|
|
119
160
|
const { status } = await call(model, effort)
|
|
120
161
|
result[model][effort] = status
|
|
121
|
-
// 200 为接受;400 与 422
|
|
162
|
+
// 200 为接受;400 与 422 为档位不被接受;冷却重测后仍非这三者的
|
|
163
|
+
// (例如持续 429、5xx)说明这次没测出结论,须人工复测后手工入表。
|
|
122
164
|
const mark = status === 200 ? '✓' : status === 400 ? '✗400' : status === 422 ? '✗422' : `?${status}`
|
|
123
165
|
process.stderr.write(` ${model.padEnd(30)} ${effort.padEnd(9)} ${mark}\n`)
|
|
124
166
|
}
|