@ebony-vinyl/dsh-our-free-model 2.7.4 → 2.8.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
@@ -39,9 +39,9 @@
39
39
  ## 交流群
40
40
 
41
41
  <div align="center">
42
- <img src="docs/images/qq-group-12.png" alt="ai交流群12入群二维码(群号:1130235133)" width="300">
42
+ <img src="docs/images/qq-group-13.png" alt="ai技术交流群13入群二维码(群号:1023181017)" width="300">
43
43
  <br>
44
- <b>QQ 群:1130235133(ai交流群12)</b>
44
+ <b>QQ 群:1023181017(ai技术交流群13)</b>
45
45
  <br>
46
46
  扫码或搜索群号加入群聊,一起交流插件使用心得、反馈问题与分享玩法。
47
47
  </div>
@@ -115,16 +115,26 @@ Chat Completions、Responses API,以及独立网页管理(模型、统计、
115
115
 
116
116
  ## 安装
117
117
 
118
- > **⚠️ 不要通过 npm 安装本插件。**
118
+ > **⚠️ 不要安装 npm 上那个裸名的 `dsh-our-free-model`。**
119
119
  >
120
120
  > npm 上的 `dsh-our-free-model` 包**不是本仓库发布的**。它由第三方打包,内容与本仓库
121
121
  > 不一致:`index.js`、`client.js` 被改动,并额外包含本仓库从未有过的
122
122
  > `src/channel-visibility.js`。装到它得不到本项目审核过的构建,也拿不到本仓库的签名
123
123
  > 清单校验与应用内升级。
124
124
  >
125
- > 请只按本文档下方的方式安装:使用本仓库的 Release 发布包,或本地源码目录。
125
+ > 本仓库自己发布的是带 scope 的 **`@ebony-vinyl/dsh-our-free-model`**,与 Release 的
126
+ > `dsh-our-free-model-<版本>.tgz` 同源、同版本。只想走 npm 时可以装它:
127
+ >
128
+ > ```
129
+ > dsh plugin --profile web add @ebony-vinyl/dsh-our-free-model@2.8.0
130
+ > ```
131
+ >
132
+ > 注意它的包名带 scope,因此挂载条目是 `@ebony-vinyl/dsh-our-free-model`,与下文
133
+ > 裸包名的本地安装方式不能混用(同一个 profile 里只选一种)。
134
+ >
126
135
  > 其它渠道出现的同名包一律以本仓库为准。
127
136
 
137
+
128
138
  **命令行(纯 dsh web)**
129
139
 
130
140
  ```
@@ -148,7 +158,7 @@ PROFILE_UPGRADE_REQUIRED: offline dependency migration is not yet available
148
158
  以真实目录手工安装时,使用可信源码打出的本地 tarball:
149
159
 
150
160
  1. 创建 `<DSH_HOME>/profiles/<profile>/vendor/`,在审核过的本仓库目录运行 `npm pack --ignore-scripts --pack-destination "<DSH_HOME>/profiles/<profile>/vendor"`,或将本仓库正式发布的同版本 tarball 放入该目录。本地打包不执行 npm 发布。
151
- 2. 在 profile 的 `package.json` 的 dependencies 中加入 `"dsh-our-free-model": "file:./vendor/dsh-our-free-model-2.7.4.tgz"`。文件名版本跟随仓库 `package.json`,不要改成同名 npm 注册表版本;再通过宿主的安装流程解析依赖。
161
+ 2. 在 profile 的 `package.json` 的 dependencies 中加入 `"dsh-our-free-model": "file:./vendor/dsh-our-free-model-2.8.0.tgz"`。文件名版本跟随仓库 `package.json`,不要改成同名 npm 注册表版本;再通过宿主的安装流程解析依赖。
152
162
  3. 在 dsh.profile.bundles 末尾追加 `"dsh-our-free-model"`。
153
163
 
154
164
  包管理器拥有这份安装的字节时,同时将 bundle config 或插件 `settings.json` 的 `distribution` 设为 `managed`,由包管理器统一更新;应用内升级、公告 feed 与热重载会停用,模型功能保留。以后更新时替换可信 tarball 并同步依赖路径,避免包管理器按旧锁文件恢复旧版本。
package/cordis.patch.yml CHANGED
@@ -4,5 +4,5 @@
4
4
  # 并绑定在 name 为裸包名的这一行上(子路径行不会携带半身)。
5
5
  - insert:
6
6
  - id: our-free-model
7
- name: '@ebony-vinyl/dsh-our-free-model'
7
+ name: 'dsh-our-free-model'
8
8
  config: {}
package/index.js CHANGED
@@ -56,7 +56,7 @@ import { getProvider, listProviders } from './src/providers/index.js'
56
56
  import { addSavings, describeSavingsTotal, emptySavings, saverConfig, savingsPercent } from './src/token-saver.js'
57
57
  import { CAVEMAN_LEVELS, PONYTAIL_LEVELS } from './src/token-saver.js'
58
58
  import { OPTIMIZATIONS } from './src/local-optimize.js'
59
- import { createModelRuntime, createRuntimeStores } from './src/core/runtime.js'
59
+ import { createModelRuntime, createRuntimeStores } from './src/core.js'
60
60
  import { createSubscriptions } from './src/subscriptions.js'
61
61
  import { createSubscriptionRuntime } from './src/subscription-completion.js'
62
62
  import { isSubscriptionEntry } from './src/subscription-adapter.js'
@@ -64,8 +64,8 @@ import { createMagpieEngine } from './src/magpie-engine.js'
64
64
  import { createMagpieModels, combineSubscriptionRuntimes } from './src/magpie-models.js'
65
65
  import { DISCLAIMER, DISCLAIMER_VERSION, disclaimerAcknowledged } from './src/disclaimer.js'
66
66
 
67
- export { fromOpenAiMessages } from './src/core/completion.js'
68
- import { buildStats } from './src/core/stats.js'
67
+ export { fromOpenAiMessages } from './src/core.js'
68
+ import { buildStats } from './src/core.js'
69
69
  export { buildStats }
70
70
 
71
71
  export const name = 'our-free-model'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ebony-vinyl/dsh-our-free-model",
3
- "version": "2.7.4",
3
+ "version": "2.8.0",
4
4
  "type": "module",
5
5
  "description": "Our Free Model — 在 dsh 里装上这个插件即可,无需登录、注册或填 API Key,就能使用包括 DeepSeek V4.1 Flash、Kimi K3 在内的前沿模型,桌面端另有 EAC 协付渠道;2.0 起接入 LobsterAI、Qoder、TRAE、Cline、Loomy、Raccoon、MiniMax、ZCode、Gemini 十个账号渠道(原有匿名免费通道保留)(登录、账号池、积分领取、本地 OpenAI 网关与局域网转发、数据看板与运行日志),六页毛玻璃界面统一呈现。",
6
6
  "repository": {
@@ -71,9 +71,10 @@
71
71
  "src/vault.js",
72
72
  "src/token-saver.js",
73
73
  "src/engine-parts",
74
- "src/core",
74
+ "src/core.js",
75
75
  "src/providers",
76
76
  "src/route",
77
+ "src/o2a.js",
77
78
  "vendor/channel-pack/pack.js",
78
79
  "vendor/channel-pack/qoder-auth-wasm.wasm",
79
80
  "vendor/channel-pack/NOTICE.md",
package/src/catalog.js CHANGED
@@ -273,66 +273,101 @@ export const EAC_TAG = 'EAC'
273
273
 
274
274
  const EAC_DISPLAY_NAMES = {
275
275
  // The OpenCode free lane is relayed server-side; the org prefix is routing
276
- // detail, so the picker shows the model's own name with the lane's Free mark.
277
- 'opencode/deepseek-v4.1-flash-free': 'deepseek-v4.1-flash-free 1017',
278
- 'opencode/glm-5.3-flash-free': 'GLM 5.3 Flash Free',
276
+ // detail, so the picker shows the model's own name with the lane's mark.
277
+ 'opencode/deepseek-v4.1-flash-free': 'DeepSeek V4.1 Flash Highspeed',
278
+ 'opencode/glm-5.3-flash-free': 'GLM 5.3 Flash Highspeed',
279
279
  'deepseek-ai/deepseek-v4.1-flash': 'DeepSeek V4.1 Flash',
280
280
  'moonshotai/kimi-k2.6': 'Kimi K2.6',
281
281
  'moonshotai/kimi-k3': 'Kimi K3',
282
282
  'openai/gpt-oss-20b': 'GPT-OSS 20B',
283
283
  'z-ai/glm-5.3': 'GLM 5.3',
284
284
  'z-ai/glm-5.3-flash': 'GLM 5.3 Flash',
285
+ 'mistralai/mistral-large-4-1t-a52b': 'Mistral Large 4 1T A52B',
285
286
  }
286
287
 
287
288
  /**
288
- * Capacities per model: published specs cross-checked against this lane where
289
- * the relay allowed a probe (2026-10-03), and the thinking-level menu copied
290
- * from ZCode's built-in provider config (`config/provider/zcode-builtin.json`,
291
- * the `modelRules`/`modelApiRules`/`providerSiteRules` buckets) — the same
292
- * per-model declaration shape that product ships: a list of levels plus a
293
- * JSON merge patch the level maps onto the request body. `vision` records what
294
- * the relay actually accepted under a direct image-input probe — DeepSeek V4.1
295
- * Flash and GLM 5.3 Flash answered a 1×1 image with its colour; the Kimi
296
- * models carry native vision encoders per their model cards but the relay's
297
- * kimi routes were down during the probe, so their flag follows the published
298
- * spec. These numbers bound the client-side truncation estimates and the sent
299
- * max_tokens; the relay enforces its own ceilings on the wire.
289
+ * Capacities per model, read from NVIDIA's own model pages
290
+ * (`build.nvidia.com/<org>/<model>`, fetched 2026-10-31) — the platform that
291
+ * actually serves these ids through the co-paid lane's NVIDIA Build channel.
300
292
  *
301
- * `efforts`/`effortDefault`/`effortPatch` mirror ZCode's declaration for the
302
- * model families it names; `effortPatch` uses `$effort` as the selected
303
- * level's placeholder, and `effortOffPatch` (when present) replaces the patch
304
- * for the off level. Models ZCode does not declare (kimi-k2.6, gpt-oss-20b)
305
- * fall back to the family-standard `reasoning_effort` field.
293
+ * Each page embeds its request schema and its `specifications` block; those are
294
+ * the figures below, not a guess:
295
+ *
296
+ * - `mistralai/mistral-large-4-1t-a52b`: `contextLength` 262144, `parameters`
297
+ * 1050B, `inputModalities` Text+Image, `reasoning: true`. Its schema declares
298
+ * `reasoning_effort` as `enum: ["none","high"]`, default `"high"`, and states
299
+ * that an omitted field is served as `none` — so its menu is exactly Off and
300
+ * High, with High as the default. The wire accepted `medium` too, but a value
301
+ * the published schema does not list is not offered.
302
+ * - `deepseek-ai/deepseek-v4.1-flash`: `contextLength` 1048576, `parameters`
303
+ * 552B, `inputModalities` Text+Image, `reasoning: true`.
304
+ * - `z-ai/glm-5.3-flash`: served on the same NVIDIA Build platform; its page
305
+ * carries no embedded spec block (a client-rendered page), so its window and
306
+ * output follow the same NVIDIA Build schema family as the two above, and its
307
+ * menu is the shared `reasoning_effort` enum.
308
+ *
309
+ * NVIDIA Build's chat schema validates `reasoning_effort` against
310
+ * `none|minimal|low|medium|high|xhigh|max` — a value outside that set answers
311
+ * 400 naming the accepted list. A model's menu here is the intersection of that
312
+ * enum with what the model's own page declares, so every rung is one the
313
+ * platform accepts; a model whose page declares only `none|high` gets exactly
314
+ * those two rather than a generic ladder.
315
+ *
316
+ * `vision` follows `inputModalities` on each page. `maxOutput` is not published
317
+ * per model there, so it is the platform's chat ceiling for these recipes, and
318
+ * the relay still enforces its own limit on the wire.
306
319
  */
307
320
  const EAC_CAPABILITIES = [
308
- // The OpenCode free lane. models.dev declares reasoning_options
309
- // [{type:"effort", values:["low","high","max"]}] for both ids, and the upstream
310
- // answers on its OpenAI wire, so the selected level rides `reasoning_effort`
311
- // verbatim. `disabled` maps to the upstream's own off value ("none"), which
312
- // zeroes the reasoning tokens — a level that is enforced, not a hint.
313
- // Capacities are the underlying model's own, not the free listing's rounded
314
- // floor: both are the same model the canonical entries below describe, so the
315
- // numbers are copied from them (1M window; 384K / 131K output) and were
316
- // re-checked against the upstream, which accepts max_tokens up to 384000.
321
+ // NVIDIA Build — the ids the co-paid lane relays from integrate.api.nvidia.com.
322
+ {
323
+ match: /^mistralai\/mistral-large-4-1t-a52b/,
324
+ vision: true, reasoning: true, contextWindow: 262144, maxOutput: 32768,
325
+ efforts: ['disabled', 'high'], effortDefault: 'high',
326
+ effortPatch: { reasoning_effort: '$effort' },
327
+ effortOffPatch: { reasoning_effort: 'none' },
328
+ },
329
+ {
330
+ match: /^deepseek-ai\/deepseek-v4\.1-flash/,
331
+ vision: true, reasoning: true, contextWindow: 1048576, maxOutput: 32768,
332
+ efforts: ['disabled', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'], effortDefault: 'high',
333
+ effortPatch: { reasoning_effort: '$effort' },
334
+ effortOffPatch: { reasoning_effort: 'none' },
335
+ },
336
+ {
337
+ match: /^z-ai\/glm-5\.3-flash/,
338
+ vision: true, reasoning: true, contextWindow: 1048576, maxOutput: 32768,
339
+ efforts: ['disabled', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'], effortDefault: 'high',
340
+ effortPatch: { reasoning_effort: '$effort' },
341
+ effortOffPatch: { reasoning_effort: 'none' },
342
+ },
343
+ // The OpenCode lane's two ids, relayed through the highspeed NVIDIA Build
344
+ // channel. The model is the same one the NVIDIA entries above describe, so
345
+ // its window and its menu are theirs: the shared `reasoning_effort` enum
346
+ // NVIDIA Build validates, with `none` as the off rung. `maxOutput` stays the
347
+ // free relay's own re-verified ceiling (384000 / 131072) — the relay enforces
348
+ // its own limit on the wire, which is tighter than NVIDIA's published one.
349
+ // The upstream id keeps its `-free` suffix (routing detail); the card's label
350
+ // says highspeed.
317
351
  {
318
352
  match: /^opencode\/deepseek-v4/,
319
353
  vision: true, reasoning: true, contextWindow: 1048576, maxOutput: 384000,
320
- efforts: ['disabled', 'low', 'high', 'max'], effortDefault: 'high',
354
+ efforts: ['disabled', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'], effortDefault: 'high',
321
355
  effortPatch: { reasoning_effort: '$effort' },
322
356
  effortOffPatch: { reasoning_effort: 'none' },
323
357
  },
324
358
  {
325
359
  match: /^opencode\/glm-5\.3-flash/,
326
360
  vision: true, reasoning: true, contextWindow: 1048576, maxOutput: 131072,
327
- efforts: ['low', 'high', 'max'], effortDefault: 'high',
361
+ efforts: ['disabled', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'], effortDefault: 'high',
328
362
  effortPatch: { reasoning_effort: '$effort' },
363
+ effortOffPatch: { reasoning_effort: 'none' },
329
364
  },
330
365
  {
331
366
  match: /^deepseek-ai\/deepseek-v4/,
332
- vision: true, reasoning: true, contextWindow: 1048576, maxOutput: 384000,
333
- efforts: ['disabled', 'low', 'high', 'max'], effortDefault: 'high',
367
+ vision: true, reasoning: true, contextWindow: 1048576, maxOutput: 32768,
368
+ efforts: ['disabled', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'], effortDefault: 'high',
334
369
  effortPatch: { reasoning_effort: '$effort' },
335
- effortOffPatch: { reasoning: { enabled: false } },
370
+ effortOffPatch: { reasoning_effort: 'none' },
336
371
  },
337
372
  {
338
373
  match: /^moonshotai\/kimi-k3/,
@@ -346,12 +381,6 @@ const EAC_CAPABILITIES = [
346
381
  efforts: ['low', 'high', 'max'], effortDefault: 'high',
347
382
  effortPatch: { reasoning_effort: '$effort' },
348
383
  },
349
- {
350
- match: /^z-ai\/glm-5\.3-flash/,
351
- vision: true, reasoning: true, contextWindow: 1048576, maxOutput: 131072,
352
- efforts: ['low', 'high', 'max'], effortDefault: 'high',
353
- effortPatch: { thinking: { type: 'enabled' }, output_config: { effort: '$effort' } },
354
- },
355
384
  {
356
385
  match: /^z-ai\/glm-5/,
357
386
  vision: false, reasoning: true, contextWindow: 1048576, maxOutput: 131072,
@@ -375,6 +404,30 @@ const EAC_FEATURED = new Set([
375
404
  'opencode/glm-5.3-flash-free',
376
405
  ])
377
406
 
407
+ /**
408
+ * Display-only ids for the card's small line.
409
+ *
410
+ * The OpenCode lane serves its ids with a `-free` suffix that is upstream
411
+ * routing detail; this build relays those two models through the highspeed
412
+ * NVIDIA Build channel, so the line shows the id the channel actually names
413
+ * (`deepseek-v4.1-flash-free 1017` → `deepseek-v4.1-flash-highspeed 1017`).
414
+ * Only the label moves: the catalog `id` is what the adapter matches, and it
415
+ * keeps the upstream spelling.
416
+ */
417
+ const EAC_LABELS = {
418
+ 'opencode/deepseek-v4.1-flash-free': 'deepseek-v4.1-flash-highspeed 1017',
419
+ 'opencode/glm-5.3-flash-free': 'glm-5.3-flash-highspeed',
420
+ }
421
+
422
+ function eacLabel(modelId) {
423
+ const known = EAC_LABELS[modelId]
424
+ if (known !== undefined) return known
425
+ const bare = modelId.includes('/') ? modelId.slice(modelId.indexOf('/') + 1) : modelId
426
+ // Any remaining `-free` suffix is the same upstream detail; it is shown as
427
+ // the channel's highspeed mark rather than leaked into the card.
428
+ return bare.replace(/(?:^|[-_])free(?:$|[-_.])/, match => match.replace('free', 'highspeed'))
429
+ }
430
+
378
431
  /** `org/model` → the model's own name under the channel tag. */
379
432
  export function eacDisplayName(modelId) {
380
433
  const base = String(modelId ?? '').trim()
@@ -415,8 +468,11 @@ export function buildEacCatalog(ids) {
415
468
  // that is what keeps this row distinct from the free lane's same-named
416
469
  // model during the merge — but the prefix is routing detail, so the line
417
470
  // shows the model's own id, with a display-only version marker where needed.
418
- label: id === 'opencode/deepseek-v4.1-flash-free' ? 'deepseek-v4.1-flash-free 1017'
419
- : id.includes('/') ? id.slice(id.indexOf('/') + 1) : id,
471
+ // The OpenCode lane's two ids are shown as their highspeed ids: the lane
472
+ // relays them through the highspeed NVIDIA Build channel, and the raw
473
+ // upstream id keeps its `-free` suffix, which is routing detail the line
474
+ // must not show. The catalog id is untouched, so routing still matches.
475
+ label: eacLabel(id),
420
476
  channel: EAC_CHANNEL,
421
477
  wire: 'chat',
422
478
  vision: caps.vision === true,