dsh-connect-modelscope-token-plan 0.1.0 → 0.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/CHANGELOG.md +129 -161
- package/README.md +43 -7
- package/client.js +781 -91
- package/cordis.patch.yml +37 -5
- package/lib/{host-config-DBCiZOBW.js → host-config.js} +207 -48
- package/lib/index.js +2033 -349
- package/lib/{llm-adapter-CpcQ3gC5.js → llm-adapter.js} +33 -18
- package/locale/en.json +2 -1
- package/package.json +13 -5
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { T as redactSecrets, c as LLM_PROVIDER_ID, g as CODE, i as name, l as buildDescriptors, o as LLM_API_KEY_NAME, s as LLM_DISPLAY_NAME, y as reclassifyStream } from "./host-config.js";
|
|
2
2
|
import { createProvider } from "@earendil-works/pi-ai";
|
|
3
3
|
import { openAICompletionsApi } from "@earendil-works/pi-ai/api/openai-completions.lazy";
|
|
4
4
|
import { PiAiAdapter } from "@deepseek-ai/dsh-llm-pi-ai";
|
|
@@ -16,8 +16,9 @@ import { resolveImageAttachmentAccess, resolveRetryPolicy } from "@deepseek-ai/d
|
|
|
16
16
|
* shape without importing that peer.
|
|
17
17
|
*
|
|
18
18
|
* The peer classifies a ModelScope 429 into two codes (`isQuotaExceededError` →
|
|
19
|
-
* `rate.?limit` inside `classifyPiAiError
|
|
20
|
-
*
|
|
19
|
+
* `rate.?limit` inside `classifyPiAiError`). That classification ORDER is not
|
|
20
|
+
* pinned by any test — verifying it needs the runtime peer, which is not
|
|
21
|
+
* vendored here (see docs/ROADMAP.md Backlog). Read on with that in mind:
|
|
21
22
|
*
|
|
22
23
|
* - `QUOTA` / `ACCOUNT_QUOTA` — the Token Plan pool is depleted. Retrying
|
|
23
24
|
* cannot refill it, and the pool is SHARED across every model on this key,
|
|
@@ -85,10 +86,11 @@ function retryableCodes() {
|
|
|
85
86
|
* accepts (`mode: "normal"` → `{ mode, maxRetries, retryableCodes, backoff }`).
|
|
86
87
|
* We pin it explicitly rather than passing `undefined` so a future change to
|
|
87
88
|
* the peer's default policy cannot silently alter this provider's behaviour.
|
|
88
|
-
* This module's shape is pinned by `test/retry.test.mjs
|
|
89
|
-
* `resolveRetryPolicy` contract is covered by
|
|
90
|
-
*
|
|
91
|
-
* `npm test` gate.
|
|
89
|
+
* This module's shape is pinned by `test/retry.test.mjs`. The live peer's
|
|
90
|
+
* `resolveRetryPolicy` contract is NOT covered by any test: verifying it needs
|
|
91
|
+
* the runtime peer, which is not vendored here and so cannot run inside the
|
|
92
|
+
* offline `npm test` gate (docs/ROADMAP.md Backlog). If the peer ever changes
|
|
93
|
+
* its policy shape, this provider fails silently at runtime — no gate turns red.
|
|
92
94
|
*
|
|
93
95
|
* Tuned for ModelScope's daytime rate ceiling (rpm/tpm), which the peer mislabels
|
|
94
96
|
* as `QUOTA` — `llm-error-fix.ts` pulls those back to `RATE_LIMIT` so they
|
|
@@ -129,7 +131,9 @@ function buildRetryPolicyConfig() {
|
|
|
129
131
|
* 读取的凭据解析器——那是真正的领域差异。
|
|
130
132
|
*
|
|
131
133
|
* peer-dependent:import `pi-ai` / `dsh-llm` / `dsh-llm-pi-ai`,它们随 Host
|
|
132
|
-
*
|
|
134
|
+
* 发行。装配链由 `test/llm-adapter.test.mjs` 用记录式假 peer 钉住调用形状
|
|
135
|
+
* (见 `llm-adapter.ts` 文件头的诚实边界:peer 真身漂移仍需 ROADMAP Backlog
|
|
136
|
+
* 的 e2e / 真机冒烟去抓,本套件只钉我们自己这一侧)。
|
|
133
137
|
*
|
|
134
138
|
* @module dsh-connect-modelscope-token-plan/llm-adapter-core
|
|
135
139
|
*/
|
|
@@ -187,7 +191,7 @@ function withReclassifiedStream(inner) {
|
|
|
187
191
|
const value = Reflect.get(target, prop, receiver);
|
|
188
192
|
if (prop === "stream") {
|
|
189
193
|
const stream = target.stream;
|
|
190
|
-
return (options) => reclassifyStream(stream(options));
|
|
194
|
+
return (options) => reclassifyStream(stream.call(target, options));
|
|
191
195
|
}
|
|
192
196
|
if (typeof value === "function" && prop === "prepareCall") {
|
|
193
197
|
const prepare = target.prepareCall;
|
|
@@ -274,10 +278,11 @@ function assemblePiAiAdapter({ providerId, displayName, apiKeyName, models, reso
|
|
|
274
278
|
* usage-store 的天桶/单模型计数与 429 事件流。
|
|
275
279
|
*
|
|
276
280
|
* 为什么不是「在 adapter 里随便挂个钩子」,而是独立一层:M4 之前
|
|
277
|
-
* `usageStore.recordCall`
|
|
278
|
-
*
|
|
279
|
-
*
|
|
280
|
-
* 429 事件流」四块面板恒为 0
|
|
281
|
+
* `usageStore.recordCall` 的唯一生产者是 `routes/probe.ts` 的 usage 试调,而那个
|
|
282
|
+
* 按钮已随目录表删除、validity 探针按设计不记调用——于是本地计数层在接入
|
|
283
|
+
* provider 之后**没有任何生产者**,「今日次数 / 单模型分布 / 趋势 /
|
|
284
|
+
* 429 事件流」四块面板恒为 0 与空。本模块补上这条缺失的生产者,也就成了**唯一**
|
|
285
|
+
* 的常驻写入侧(`probe` 路由的 `kind:"usage"` 分支随后一并删除,见 probe.ts)。
|
|
281
286
|
*
|
|
282
287
|
* ## 与 harness 自己的账本的分工(别再造第二本账)
|
|
283
288
|
*
|
|
@@ -315,8 +320,13 @@ function assemblePiAiAdapter({ providerId, displayName, apiKeyName, models, reso
|
|
|
315
320
|
* 一次被打上限频的请求同样是一次上游调用。token 数在上游给出时带上,给不出
|
|
316
321
|
* 时传 `null`(wire 语义基线:null 是「上游没给」,绝不写成 0)。
|
|
317
322
|
*
|
|
318
|
-
*
|
|
319
|
-
*
|
|
323
|
+
* 已知偏差(不是「少记」,是「按流计次」):重试不在一条流内部发生,而在
|
|
324
|
+
* `dsh-agent-loop` 消费完流之后由 `agent/request-error` 瀑布决定
|
|
325
|
+
* (`dsh-agent-loop/lib/index.js:1116-1134`),`dsh-llm-retry` 据此**重新发起一次
|
|
326
|
+
* 请求**、产生**新的流**。观察器套在流出口上,于是**每次重试各记一次 call**——
|
|
327
|
+
* 按「魔搭按次数计费」的口径这反而是对的(每次重发都真打了一次上游),但它与
|
|
328
|
+
* 早先本文件「重试掉的那些次不单独计」的说法相反,故此处一并更正。
|
|
329
|
+
* 2026-10-05 读 peer 源码(`@deepseek-ai/dsh-llm-retry`、`dsh-agent-loop`)核实。
|
|
320
330
|
*
|
|
321
331
|
* peer-free:只 import 本仓库的 peer-free 模块(`llm-error-fix` / `util`)与
|
|
322
332
|
* `shared/wire` 的类型,离线可测——与 `llm-error-fix` 同一纪律。
|
|
@@ -460,7 +470,7 @@ function withUsageObserver(inner, sinks) {
|
|
|
460
470
|
const value = Reflect.get(target, prop, receiver);
|
|
461
471
|
if (prop === "stream") {
|
|
462
472
|
const stream = target.stream;
|
|
463
|
-
return typeof stream === "function" ? (options) => wrapStream(stream, options) : value;
|
|
473
|
+
return typeof stream === "function" ? (options) => wrapStream(stream.bind(target), options) : value;
|
|
464
474
|
}
|
|
465
475
|
if (typeof value === "function" && prop === "prepareCall") {
|
|
466
476
|
const prepare = target.prepareCall;
|
|
@@ -491,8 +501,13 @@ function withUsageObserver(inner, sinks) {
|
|
|
491
501
|
* 魔搭 provider 注册的 peer-dependent 半边。
|
|
492
502
|
*
|
|
493
503
|
* 这里的一切都跑在 Host 发行的 peer 上(`pi-ai`、`dsh-llm`、`dsh-llm-pi-ai`)——这
|
|
494
|
-
* 正是 descriptor 映射要住在 peer-free 的 `llm-models.ts`
|
|
495
|
-
*
|
|
504
|
+
* 正是 descriptor 映射要住在 peer-free 的 `llm-models.ts` 的原因。本模块的装配链
|
|
505
|
+
* 由 `test/llm-adapter.test.mjs` 用**记录式假 peer**(`test/helpers/peer-stub-loader.mjs`,
|
|
506
|
+
* Node module customization hooks 拦截四个 peer 入口)钉住——断言的是「我们对 peer
|
|
507
|
+
* 的调用形状」:descriptor 契约、retryPolicy 传参、PiAiAdapter 构造、usage 观察层
|
|
508
|
+
* 包装与重分类顺序。**诚实边界**:假 peer 是我们写的,钉不住 peer 真身的漂移——peer
|
|
509
|
+
* 升级改形状仍由 docs/ROADMAP.md Backlog 的 e2e / 真机冒烟去抓,本套件只保证
|
|
510
|
+
* 这一侧不再静默改坏。
|
|
496
511
|
*
|
|
497
512
|
* 形状对齐已知可用的 qoder 适配器:
|
|
498
513
|
*
|
package/locale/en.json
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"meta": {
|
|
3
|
-
"title": "ModelScope Quota Connect"
|
|
3
|
+
"title": "ModelScope Quota Connect",
|
|
4
|
+
"description": "ModelScope API-Inference free-quota panel: official Magicube balance, local call counts and trends, rate-limit event stream, auth-free model catalog and zero-quota token validation, plus optional registration of ModelScope as an OpenAI-compatible DSH provider (roadmap)."
|
|
4
5
|
}
|
|
5
6
|
}
|
package/package.json
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
"name": "dsh-connect-modelscope-token-plan",
|
|
3
3
|
"displayName": "DSH Connect ModelScope Token Plan",
|
|
4
4
|
"icon": "./icon.svg",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.3.0",
|
|
6
6
|
"homepage": "https://github.com/eghrhegpe/dsh-connect-modelscope-token-plan",
|
|
7
7
|
"bugs": {
|
|
8
8
|
"url": "https://github.com/eghrhegpe/dsh-connect-modelscope-token-plan/issues"
|
|
9
9
|
},
|
|
10
10
|
"author": "eghrhegpe",
|
|
11
|
-
"description": "ModelScope (modelscope.cn) connect bundle for the Harness Web UI:
|
|
11
|
+
"description": "ModelScope (modelscope.cn) connect bundle for the Harness Web UI: the official Magicube balance plus, for calls made through this plugin, per-model counts, a daily trend, and a 429 error event list on the Plugins-page panel, plus a default-off switch that registers ModelScope models as a DSH LLM provider.",
|
|
12
12
|
"keywords": [
|
|
13
13
|
"dsh-plugin",
|
|
14
14
|
"deepseek-harness",
|
|
@@ -41,7 +41,8 @@
|
|
|
41
41
|
"typecheck": "tsc -p tsconfig.json",
|
|
42
42
|
"build:client": "tsdown -c tsdown.config.mjs",
|
|
43
43
|
"duplicate-check": "jscpd src --min-tokens 70 --reporters console-full",
|
|
44
|
-
"test": "node test/wire.test.mjs && node test/config.test.mjs && node test/state-store.test.mjs && node test/usage-store.test.mjs && node test/routes.test.mjs && node test/provider.test.mjs && node test/inference-vision.test.mjs && node test/provider-routes.test.mjs && node test/provider-publish.test.mjs && node test/panel.test.mjs && node test/doctor.test.mjs && node test/catalog.test.mjs && node test/switch-precedence.test.mjs && node test/credentials.test.mjs && node test/codes.test.mjs && node test/retry.test.mjs && node test/error-fix.test.mjs && node test/usage-observer.test.mjs && node test/release.test.mjs && node test/build-gate.mjs",
|
|
44
|
+
"test": "node test/wire.test.mjs && node test/config.test.mjs && node test/docs.test.mjs && node test/env-hermetic.test.mjs && node test/deps-wiring.test.mjs && node test/state-store.test.mjs && node test/usage-store.test.mjs && node test/routes.test.mjs && node test/provider.test.mjs && node test/inference-vision.test.mjs && node test/context-catalog.test.mjs && node test/provider-routes.test.mjs && node test/provider-publish.test.mjs && node test/llm-adapter.test.mjs && node test/panel.test.mjs && node test/composer-pill.test.mjs && node test/dom-render.test.mjs && node test/dom-render-react.test.mjs && node test/snapshot.test.mjs && node test/doctor.test.mjs && node test/catalog.test.mjs && node test/switch-precedence.test.mjs && node test/credentials.test.mjs && node test/codes.test.mjs && node test/retry.test.mjs && node test/error-fix.test.mjs && node test/draw.test.mjs && node test/draw-runtime.test.mjs && node test/draw-routes.test.mjs && node test/usage-observer.test.mjs && node test/release.test.mjs && node test/build-gate.mjs",
|
|
45
|
+
"test:mutate": "node tools/dev/mutate.mjs tools/dev/mutate-spec.json",
|
|
45
46
|
"doctor": "node tools/doctor.mjs",
|
|
46
47
|
"doctor:json": "node tools/doctor.mjs --json",
|
|
47
48
|
"build": "tsdown -c tsdown.config.mjs",
|
|
@@ -99,9 +100,16 @@
|
|
|
99
100
|
},
|
|
100
101
|
"license": "MIT",
|
|
101
102
|
"devDependencies": {
|
|
102
|
-
"@types/node": "^
|
|
103
|
+
"@types/node": "^22.19.0",
|
|
103
104
|
"jscpd": "^5.4.0",
|
|
104
|
-
"
|
|
105
|
+
"jsdom": "^30.1.3",
|
|
106
|
+
"react": "18.3.1",
|
|
107
|
+
"react-dom": "18.3.1",
|
|
108
|
+
"tsdown": "0.23.0",
|
|
105
109
|
"typescript": "5.9.3"
|
|
110
|
+
},
|
|
111
|
+
"overrides": {
|
|
112
|
+
"rolldown": "1.2.12",
|
|
113
|
+
"rolldown-plugin-dts": "0.28.6"
|
|
106
114
|
}
|
|
107
115
|
}
|