dsh-modelscope-pool 0.11.0 → 0.11.1

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
@@ -22,6 +22,7 @@
22
22
  - [界面](#界面)
23
23
  - [多语言](#多语言)
24
24
  - [网页版与桌面版](#网页版与桌面版)
25
+ - [模型上下文与最大输出](#模型上下文与最大输出)
25
26
  - [HTTP 接口](#http-接口)
26
27
  - [接入其它客户端](#接入其它客户端)
27
28
  - [常见问题](#常见问题)
@@ -321,6 +322,24 @@ dsh-go 里更进一步:这个插件会把自己注册成一个叫 **魔搭 Key
321
322
 
322
323
  ---
323
324
 
325
+ ## 模型上下文与最大输出
326
+
327
+ 魔搭的 `/v1/models` 只回 `id / owned_by / created`,详情接口和模型页也没有上下文字段——官方数字只写在**模型卡片的说明里**。所以插件对能确认的旗舰模型逐个填真实值,其余不声明、走插件默认(上下文 128K)。
328
+
329
+ | 模型 | 上下文 | 最大输出 | 卡片依据 |
330
+ |---|---|---|---|
331
+ | `DeepSeek-V4-Pro` | 1,000,000 | — | 参数表 Context Length = 1M |
332
+ | `DeepSeek-V4-Pro-0813` | 1,000,000 | 393,216 | 正文「最大输出长度 384K」 |
333
+ | `DeepSeek-V4.1-Flash` | 1,000,000 | — | 正文「up to one million tokens」 |
334
+ | `DeepSeek-V4.1-Flash-1017` | 1,000,000 | 262,144 | 参数表 `context_window` 1M / `max_tokens` ≥ 256K |
335
+ | `GLM-5.2` | 1,000,000 | — | 正文「Solid 1M Context」 |
336
+
337
+ 「—」表示卡片没写,就不填:DSH 没拿到最大输出时用它自己的默认,比瞎编一个安全。
338
+
339
+ > 最大输出只在**明显小于上下文**时才填。`Step-5-Preview` 卡片写的是上下文 1M、最大输出也是 1M,两边相等会让 DSH 的「预留回复额度」把整个窗口吃掉,压缩预算变成 0,切模型反而报错,所以这个型号只按默认走。
340
+
341
+ 新增模型:在 `lib/specs.js` 里加一行 `简化名 → { contextWindow, maxTokens }` 即可,键不区分大小写,没列到的自动回落到插件默认。
342
+
324
343
  ## 常见问题
325
344
 
326
345
  **导入后一堆 Key 显示「令牌无效」?**
package/lib/catalog.js CHANGED
@@ -2,6 +2,8 @@
2
2
  // 各有一份模型表,两边取并集并按「简化名」合并:同一个模型在两个站点的 id 可能不同
3
3
  // (例如 zai-org/GLM-4.7-Flash 与 ZhipuAI/GLM-4.7-Flash),合并后只出现一行,
4
4
  // 真正请求时按 Key 所属站点换成那边的真实 id。
5
+ import { specFor } from './specs.js'
6
+
5
7
  const REGION_LABEL = { ai: '国际版', cn: '国内版' }
6
8
 
7
9
  /**
@@ -74,6 +76,8 @@ export function createCatalog({ regions, preferred = ['ai', 'cn'], ttlMs = 300_0
74
76
  regions: preferred.filter((key) => Boolean(row.variants[key])),
75
77
  variants: row.variants,
76
78
  rawIds: row.rawIds,
79
+ // 官方规格只对列在 specs.js 里的旗舰模型有值,其余为空。
80
+ ...specFor(row.name),
77
81
  }))
78
82
  .sort((a, b) => a.name.localeCompare(b.name))
79
83
  cache = { at: Date.now(), entries }
package/lib/provider.js CHANGED
@@ -148,8 +148,9 @@ export async function registerPoolProvider(ctx, { providerId, displayName, getPo
148
148
  provider: providerId,
149
149
  baseUrl: baseUrl(),
150
150
  input: ['text'],
151
- // DSH 拒绝没有正整数上下文的模型,这里给保守值。
152
- contextWindow: DEFAULT_CONTEXT_WINDOW,
151
+ // 有官方规格的用官方值;其余给保守默认,DSH 拒绝没有正整数上下文的模型。
152
+ contextWindow: Number(entry.contextWindow) > 0 ? Number(entry.contextWindow) : DEFAULT_CONTEXT_WINDOW,
153
+ ...(Number(entry.maxTokens) > 0 ? { maxTokens: Number(entry.maxTokens) } : {}),
153
154
  cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
154
155
  reasoning: false,
155
156
  }))
@@ -216,7 +217,13 @@ export async function registerPoolProvider(ctx, { providerId, displayName, getPo
216
217
  let off
217
218
  try {
218
219
  off = ctx.llm.registerModelDiscovery(entryId, async () =>
219
- buildModels().map((model) => ({ id: model.id, name: model.name, contextWindow: model.contextWindow, inputModalities: ['text'] })),
220
+ buildModels().map((model) => ({
221
+ id: model.id,
222
+ name: model.name,
223
+ contextWindow: model.contextWindow,
224
+ ...(model.maxTokens === undefined ? {} : { maxTokens: model.maxTokens }),
225
+ inputModalities: ['text'],
226
+ })),
220
227
  )
221
228
  } catch (error) {
222
229
  logger?.warn?.(`modelscope-pool: 模型发现注册失败(${String(error?.message ?? error)})`)
package/lib/specs.js ADDED
@@ -0,0 +1,27 @@
1
+ // 官方规格:只收录能在模型卡片里找到明确写法的模型,其余不声明,走插件默认。
2
+ // 数据来源是 ModelScope 模型卡片(README.md),不是接口字段 —— 魔搭的 /v1/models
3
+ // 只回 id / owned_by / created,详情接口也没有上下文字段,所以只能按卡片逐个确认。
4
+ //
5
+ // 字段含义(DSH 模型发现契约):
6
+ // contextWindow 请求 + 回复合计的最大上下文
7
+ // maxTokens 最大输出 token 数(仅当卡片明确给出,且明显小于上下文时才填;
8
+ // 两者相等时填了会让 DSH 的压缩预算归零,反而切不过去)
9
+ export const OFFICIAL_SPECS = {
10
+ // 卡片表格:Context Length = 1M(正文:both supporting a context length of one million tokens)
11
+ 'deepseek-v4-pro': { contextWindow: 1_000_000 },
12
+ // 卡片正文:recommend a maximum output length of 384K tokens
13
+ 'deepseek-v4-pro-0813': { contextWindow: 1_000_000, maxTokens: 384 * 1024 },
14
+ // 卡片正文:support for contexts of up to one million tokens
15
+ 'deepseek-v4.1-flash': { contextWindow: 1_000_000 },
16
+ // 卡片参数表:context_window = 1M tokens,max_tokens ≥ 256K
17
+ 'deepseek-v4.1-flash-1017': { contextWindow: 1_000_000, maxTokens: 256 * 1024 },
18
+ // 卡片正文:Solid 1M Context
19
+ 'glm-5.2': { contextWindow: 1_000_000 },
20
+ }
21
+
22
+ /** 按简化名查官方规格(大小写不敏感),查不到返回空对象。 */
23
+ export function specFor(name) {
24
+ const key = String(name ?? '').trim().toLowerCase()
25
+ if (!key) return {}
26
+ return OFFICIAL_SPECS[key] ?? {}
27
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-modelscope-pool",
3
- "version": "0.11.0",
3
+ "version": "0.11.1",
4
4
  "description": "魔搭多 Key 聚合网关 + DSH 原生插件:模型不变,Key 遇限流、额度不足、无权限或令牌失效自动无感换下一个;自动识别国际版/国内版令牌;Key 池管理、魔粒用量、多语言界面;也可在网页版/桌面版管理。",
5
5
  "license": "MIT",
6
6
  "author": "Yizutt",