mslxdff 0.1.231 → 0.1.233
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/bin/mslxdff.js +3 -3
- package/package.json +1 -1
- package/src/auto.js +264 -254
- package/src/bench/cline-bench.js +42 -42
- package/src/bench/probe.js +70 -70
- package/src/bench/report.js +162 -162
- package/src/bench/runner.js +77 -77
- package/src/bench/via-probe.js +124 -124
- package/src/bench/via-routes.js +87 -87
- package/src/bench/workbuddy-bench.js +54 -54
- package/src/chat/engine.js +160 -160
- package/src/chat/gateway.js +163 -163
- package/src/chat/orchestrator.js +234 -234
- package/src/chat/prompt.js +70 -70
- package/src/chat/repl.js +88 -88
- package/src/chat/terminal.js +135 -135
- package/src/chat/tools.js +306 -306
- package/src/chat-pipeline/index.js +155 -145
- package/src/chat-pipeline/policy.js +84 -84
- package/src/cli/commands/group.js +266 -266
- package/src/cli/commands/model/picks.js +50 -50
- package/src/cli/commands/provider/bench-via.js +247 -247
- package/src/cli/commands/provider/bench.js +141 -141
- package/src/cli/commands/provider/index.js +139 -139
- package/src/cli/commands/provider/models.js +149 -149
- package/src/cli/commands/provider/qwenwork-login.js +119 -119
- package/src/cli/commands/provider/raccoon-quota.js +156 -156
- package/src/cli/commands/sync.js +310 -310
- package/src/cli/status.js +279 -279
- package/src/daemon.js +246 -246
- package/src/model-capabilities/enrich.js +86 -86
- package/src/model-capabilities/index.js +183 -183
- package/src/model-capabilities/parse.js +70 -70
- package/src/model-trace.js +10 -2
- package/src/models.js +292 -225
- package/src/peers.js +345 -345
- package/src/providers/agentrouter.js +238 -238
- package/src/providers/base.js +164 -164
- package/src/providers/cline/auth.js +228 -228
- package/src/providers/cline/chat.js +307 -307
- package/src/providers/cline.js +2 -2
- package/src/providers/codearts/chat.js +207 -207
- package/src/providers/dispatcher.js +147 -147
- package/src/providers/globalqwenwork/cosy.js +123 -123
- package/src/providers/globalqwenwork/crypto.js +218 -218
- package/src/providers/globalqwenwork/http.js +20 -20
- package/src/providers/globalqwenwork/rsa.js +54 -54
- package/src/providers/globalqwenwork/sse.js +268 -268
- package/src/providers/globalqwenwork/stream.js +130 -130
- package/src/providers/globalqwenwork/upstream.js +122 -122
- package/src/providers/keyring.js +60 -60
- package/src/providers/qoder/account-store.js +18 -0
- package/src/providers/qoder/chat.js +292 -203
- package/src/providers/qoder/checkin.js +25 -12
- package/src/providers/qoder/index.js +311 -249
- package/src/providers/qoder/models.js +64 -2
- package/src/providers/qoder/oauth.js +42 -1
- package/src/providers/qoder/payload.js +116 -80
- package/src/providers/qoder/request.js +7 -2
- package/src/providers/qoder/session.js +26 -10
- package/src/providers/qoder/sse.js +233 -145
- package/src/providers/qoder/sticky.js +5 -2
- package/src/providers/qoder/wire-messages.js +242 -0
- package/src/providers/qwenwork/account-store.js +133 -133
- package/src/providers/qwenwork/constants.js +67 -67
- package/src/providers/qwenwork/cosy.js +120 -120
- package/src/providers/qwenwork/crypto.js +218 -218
- package/src/providers/qwenwork/http.js +20 -20
- package/src/providers/qwenwork/index.js +337 -337
- package/src/providers/qwenwork/payload.js +144 -144
- package/src/providers/qwenwork/rsa.js +54 -54
- package/src/providers/qwenwork/sse.js +268 -268
- package/src/providers/qwenwork/stream.js +130 -130
- package/src/providers/qwenwork/upstream.js +120 -120
- package/src/providers/qwenwork.js +1 -1
- package/src/providers/raccoon/chat.js +1 -1
- package/src/providers/raccoon/const.js +219 -202
- package/src/providers/raccoon/credits.js +285 -285
- package/src/providers/raccoon/index.js +15 -2
- package/src/providers/raccoon/models.js +68 -17
- package/src/providers/registry.js +89 -89
- package/src/providers/workbuddy/auth.js +16 -0
- package/src/providers/workbuddy/chat.js +298 -264
- package/src/providers/workbuddy/client-headers.js +148 -0
- package/src/providers/workbuddy/desktop-info.js +17 -1
- package/src/providers/workbuddy/models.js +8 -20
- package/src/providers/workbuddy/reshape.js +152 -152
- package/src/providers/workbuddy.js +2 -2
- package/src/reasoning.js +32 -32
- package/src/routes/chat/broadband-handler.js +80 -80
- package/src/routes/chat/gateway.js +46 -46
- package/src/routes/chat/relay-pipeline.js +282 -282
- package/src/routes/chat/via-route-handler.js +156 -156
- package/src/routes/hedge.js +260 -260
- package/src/routes/models-route.js +167 -167
- package/src/routes/peers.js +373 -373
- package/src/routes/stream.js +364 -347
- package/src/runtime/bootstrap.js +75 -75
- package/src/runtime/keep-warm.js +135 -135
- package/src/runtime/provider-gate.js +75 -75
- package/src/runtime/providers-setup.js +187 -187
- package/src/runtime/raccoon-checkin.js +175 -175
- package/src/server.js +85 -85
- package/src/state/schemas/allowlist.js +92 -92
- package/src/sync-opencode.js +280 -280
- package/src/transport/index.js +244 -244
- package/src/transport/pool.js +56 -56
- package/src/transport/retry.js +24 -24
- package/src/transport/sse.js +93 -93
- package/src/upstream-probe/display.js +52 -52
- package/src/upstream-probe/probe.js +49 -49
- package/src/upstream-probe/rotate.js +110 -110
- package/src/upstream-probe/start.js +45 -45
- package/src/upstream.js +355 -355
- package/docs/cli_help_mini.md +0 -148
- package/src/providers/AGENTS.md +0 -49
- package/src/routes/AGENTS.md +0 -37
|
@@ -1,70 +1,70 @@
|
|
|
1
|
-
// models.dev 能力目录 → mslxdff 能力形状的纯函数解析层(无 IO,测试接缝 S1)
|
|
2
|
-
// 源数据形态(实测 models.opencode.ai/api.json 2026-09-11):
|
|
3
|
-
// reasoning_options: [{type:"effort",values:["low","medium","high","max"]} | {type:"toggle"} | {type:"budget_tokens",min}]
|
|
4
|
-
// modalities.input 含 "image" 即可读图;limit.context/output;cost.input/output 为 $/M tokens
|
|
5
|
-
export function normalizeModelCaps(_id, m) {
|
|
6
|
-
const opts = Array.isArray(m?.reasoning_options) ? m.reasoning_options : [];
|
|
7
|
-
const effort = opts.find((o) => o?.type === "effort");
|
|
8
|
-
const toggle = opts.some((o) => o?.type === "toggle");
|
|
9
|
-
const budget = opts.find((o) => o?.type === "budget_tokens");
|
|
10
|
-
const input = Array.isArray(m?.modalities?.input) ? m.modalities.input : [];
|
|
11
|
-
return {
|
|
12
|
-
reasoning: Boolean(m?.reasoning),
|
|
13
|
-
effortType: effort ? "effort" : toggle ? "toggle" : budget ? "budget_tokens" : null,
|
|
14
|
-
effortValues: effort && Array.isArray(effort.values) ? effort.values.map(String) : null,
|
|
15
|
-
imageInput: input.includes("image"),
|
|
16
|
-
toolCall: Boolean(m?.tool_call),
|
|
17
|
-
context: Number(m?.limit?.context) || null,
|
|
18
|
-
maxOutput: Number(m?.limit?.output) || null,
|
|
19
|
-
costIn: Number(m?.cost?.input) || null,
|
|
20
|
-
costOut: Number(m?.cost?.output) || null,
|
|
21
|
-
// opencode Model 形状补充字段(-setto opencode 条目注入用)
|
|
22
|
-
attachment: Boolean(m?.attachment),
|
|
23
|
-
temperature: Boolean(m?.temperature),
|
|
24
|
-
releaseDate: typeof m?.release_date === "string" && m.release_date ? m.release_date : null,
|
|
25
|
-
inputModalities: input.length ? input : ["text"],
|
|
26
|
-
outputModalities: Array.isArray(m?.modalities?.output) && m.modalities.output.length ? m.modalities.output : ["text"],
|
|
27
|
-
// 模型级 SDK 覆盖(models.dev provider.npm):@ai-sdk/openai → responses 端点;null = 继承 provider 默认
|
|
28
|
-
npm: typeof m?.provider?.npm === "string" && m.provider.npm ? m.provider.npm : null,
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// provider.models 对象({ [modelId]: rawModel })→ { [modelId]: caps }
|
|
33
|
-
export function normalizeProviderModels(modelsObj) {
|
|
34
|
-
const out = {};
|
|
35
|
-
if (!modelsObj || typeof modelsObj !== "object") return out;
|
|
36
|
-
for (const [id, m] of Object.entries(modelsObj)) {
|
|
37
|
-
if (!m || typeof m !== "object") continue;
|
|
38
|
-
out[id] = normalizeModelCaps(id, m);
|
|
39
|
-
}
|
|
40
|
-
return out;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// workbuddy 上游原生字段(/v3/config 产品文档,first-party 最准)→ 统一 caps 形状
|
|
44
|
-
// 实测字段(2026-09-11,29 模型全覆盖):maxInputTokens/maxOutputTokens/supportsImages/
|
|
45
|
-
// supportsReasoning/reasoning{effort,summary}/supportsToolCall/disabledMultimodal/credits/tags/name/vendor
|
|
46
|
-
// reasoning 是"当前档位"非档位列表 → effortType=effort 但 effortValues=null、defaultEffort 记默认档
|
|
47
|
-
export function normalizeWorkbuddyCaps(_id, m) {
|
|
48
|
-
const imageOk = Boolean(m?.supportsImages) && !m?.disabledMultimodal;
|
|
49
|
-
const reasoning = Boolean(m?.supportsReasoning);
|
|
50
|
-
const effort = reasoning && m?.reasoning && typeof m.reasoning === "object" ? String(m.reasoning.effort || "").trim() : "";
|
|
51
|
-
return {
|
|
52
|
-
reasoning,
|
|
53
|
-
effortType: reasoning ? "effort" : null,
|
|
54
|
-
// 上游只给当前档位不给档位列表;实测 hy3 reasoning_effort low/high 均生效(思考块 99 vs 210),
|
|
55
|
-
// 网关层按 OpenAI 兼容标准给通用三档(上游不识别时忽略,无害)
|
|
56
|
-
effortValues: reasoning ? ["low", "medium", "high"] : null,
|
|
57
|
-
defaultEffort: effort || null,
|
|
58
|
-
imageInput: imageOk,
|
|
59
|
-
toolCall: Boolean(m?.supportsToolCall),
|
|
60
|
-
context: Number(m?.maxInputTokens) || null,
|
|
61
|
-
maxOutput: Number(m?.maxOutputTokens) || null,
|
|
62
|
-
costIn: null,
|
|
63
|
-
costOut: null,
|
|
64
|
-
attachment: false,
|
|
65
|
-
temperature: m?.temperature != null,
|
|
66
|
-
releaseDate: null,
|
|
67
|
-
inputModalities: imageOk ? ["text", "image"] : ["text"],
|
|
68
|
-
outputModalities: ["text"],
|
|
69
|
-
};
|
|
70
|
-
}
|
|
1
|
+
// models.dev 能力目录 → mslxdff 能力形状的纯函数解析层(无 IO,测试接缝 S1)
|
|
2
|
+
// 源数据形态(实测 models.opencode.ai/api.json 2026-09-11):
|
|
3
|
+
// reasoning_options: [{type:"effort",values:["low","medium","high","max"]} | {type:"toggle"} | {type:"budget_tokens",min}]
|
|
4
|
+
// modalities.input 含 "image" 即可读图;limit.context/output;cost.input/output 为 $/M tokens
|
|
5
|
+
export function normalizeModelCaps(_id, m) {
|
|
6
|
+
const opts = Array.isArray(m?.reasoning_options) ? m.reasoning_options : [];
|
|
7
|
+
const effort = opts.find((o) => o?.type === "effort");
|
|
8
|
+
const toggle = opts.some((o) => o?.type === "toggle");
|
|
9
|
+
const budget = opts.find((o) => o?.type === "budget_tokens");
|
|
10
|
+
const input = Array.isArray(m?.modalities?.input) ? m.modalities.input : [];
|
|
11
|
+
return {
|
|
12
|
+
reasoning: Boolean(m?.reasoning),
|
|
13
|
+
effortType: effort ? "effort" : toggle ? "toggle" : budget ? "budget_tokens" : null,
|
|
14
|
+
effortValues: effort && Array.isArray(effort.values) ? effort.values.map(String) : null,
|
|
15
|
+
imageInput: input.includes("image"),
|
|
16
|
+
toolCall: Boolean(m?.tool_call),
|
|
17
|
+
context: Number(m?.limit?.context) || null,
|
|
18
|
+
maxOutput: Number(m?.limit?.output) || null,
|
|
19
|
+
costIn: Number(m?.cost?.input) || null,
|
|
20
|
+
costOut: Number(m?.cost?.output) || null,
|
|
21
|
+
// opencode Model 形状补充字段(-setto opencode 条目注入用)
|
|
22
|
+
attachment: Boolean(m?.attachment),
|
|
23
|
+
temperature: Boolean(m?.temperature),
|
|
24
|
+
releaseDate: typeof m?.release_date === "string" && m.release_date ? m.release_date : null,
|
|
25
|
+
inputModalities: input.length ? input : ["text"],
|
|
26
|
+
outputModalities: Array.isArray(m?.modalities?.output) && m.modalities.output.length ? m.modalities.output : ["text"],
|
|
27
|
+
// 模型级 SDK 覆盖(models.dev provider.npm):@ai-sdk/openai → responses 端点;null = 继承 provider 默认
|
|
28
|
+
npm: typeof m?.provider?.npm === "string" && m.provider.npm ? m.provider.npm : null,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// provider.models 对象({ [modelId]: rawModel })→ { [modelId]: caps }
|
|
33
|
+
export function normalizeProviderModels(modelsObj) {
|
|
34
|
+
const out = {};
|
|
35
|
+
if (!modelsObj || typeof modelsObj !== "object") return out;
|
|
36
|
+
for (const [id, m] of Object.entries(modelsObj)) {
|
|
37
|
+
if (!m || typeof m !== "object") continue;
|
|
38
|
+
out[id] = normalizeModelCaps(id, m);
|
|
39
|
+
}
|
|
40
|
+
return out;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// workbuddy 上游原生字段(/v3/config 产品文档,first-party 最准)→ 统一 caps 形状
|
|
44
|
+
// 实测字段(2026-09-11,29 模型全覆盖):maxInputTokens/maxOutputTokens/supportsImages/
|
|
45
|
+
// supportsReasoning/reasoning{effort,summary}/supportsToolCall/disabledMultimodal/credits/tags/name/vendor
|
|
46
|
+
// reasoning 是"当前档位"非档位列表 → effortType=effort 但 effortValues=null、defaultEffort 记默认档
|
|
47
|
+
export function normalizeWorkbuddyCaps(_id, m) {
|
|
48
|
+
const imageOk = Boolean(m?.supportsImages) && !m?.disabledMultimodal;
|
|
49
|
+
const reasoning = Boolean(m?.supportsReasoning);
|
|
50
|
+
const effort = reasoning && m?.reasoning && typeof m.reasoning === "object" ? String(m.reasoning.effort || "").trim() : "";
|
|
51
|
+
return {
|
|
52
|
+
reasoning,
|
|
53
|
+
effortType: reasoning ? "effort" : null,
|
|
54
|
+
// 上游只给当前档位不给档位列表;实测 hy3 reasoning_effort low/high 均生效(思考块 99 vs 210),
|
|
55
|
+
// 网关层按 OpenAI 兼容标准给通用三档(上游不识别时忽略,无害)
|
|
56
|
+
effortValues: reasoning ? ["low", "medium", "high"] : null,
|
|
57
|
+
defaultEffort: effort || null,
|
|
58
|
+
imageInput: imageOk,
|
|
59
|
+
toolCall: Boolean(m?.supportsToolCall),
|
|
60
|
+
context: Number(m?.maxInputTokens) || null,
|
|
61
|
+
maxOutput: Number(m?.maxOutputTokens) || null,
|
|
62
|
+
costIn: null,
|
|
63
|
+
costOut: null,
|
|
64
|
+
attachment: false,
|
|
65
|
+
temperature: m?.temperature != null,
|
|
66
|
+
releaseDate: null,
|
|
67
|
+
inputModalities: imageOk ? ["text", "image"] : ["text"],
|
|
68
|
+
outputModalities: ["text"],
|
|
69
|
+
};
|
|
70
|
+
}
|
package/src/model-trace.js
CHANGED
|
@@ -84,6 +84,8 @@ const DECISION_FIELDS = [
|
|
|
84
84
|
"latencyMs", "ttfMs", "hedged", "hops", "hasShare", "elapsedMs", "threshold",
|
|
85
85
|
"stallHits", "maxGapMs", "interrupted", "providers", "via",
|
|
86
86
|
"retry", "step", "max", "delayMs", "upstream", "account", "pick", "cooled", "queued", "nudged", "retries", "waitedMs", "raiseFrom", "raiseTo",
|
|
87
|
+
// qoder 判决定点日志(2026-10-22):login/额度/排队判决各走各的路径,没有这三项,403 盲飞无从分辨
|
|
88
|
+
"login", "nocapacity", "retryAfter",
|
|
87
89
|
"heldOpen", "terminalForm", "requestWaitedMs", "budgetMs", "budgetOut",
|
|
88
90
|
// 终局判决(ADR-0058):取证时第一眼要看的三件——判的哪种、命中哪条判据、是否因此没问组员
|
|
89
91
|
"kind", "marker", "peersSkipped",
|
|
@@ -103,8 +105,10 @@ function decisionKv(data = {}) {
|
|
|
103
105
|
return out.join(" ");
|
|
104
106
|
}
|
|
105
107
|
|
|
106
|
-
// provider 回显头 → 日志字段(谁上的 / 打哪个站 / 为什么选它 / 是否被冷却 /
|
|
108
|
+
// provider 回显头 → 日志字段(谁上的 / 打哪个站 / 为什么选它 / 是否被冷却 / 是否被判排队 / 判决命中哪种):
|
|
107
109
|
// 单一来源,防各处重复写法漂移;取不到时返回空对象(其它供应商零变化)。
|
|
110
|
+
// login/nocapacity/retryAfter(2026-10-22 补):qoder 判决链曾全程盲飞——403 直出日志里只有状态码,
|
|
111
|
+
// 看不出内部是 login 误伤、queue 漏检还是根本没命中,三轮排查全靠猜(用户实证批评:没多打日志)。
|
|
108
112
|
export function upstreamEcho(res) {
|
|
109
113
|
const h = res?.headers;
|
|
110
114
|
if (typeof h?.get !== "function") return {};
|
|
@@ -115,6 +119,10 @@ export function upstreamEcho(res) {
|
|
|
115
119
|
pick: pick("x-mslxdff-qoder-account"),
|
|
116
120
|
cooled: pick("x-mslxdff-qoder-cooldown"),
|
|
117
121
|
queued: pick("x-mslxdff-qoder-queued"),
|
|
122
|
+
login: pick("x-mslxdff-qoder-login"),
|
|
123
|
+
nocapacity: pick("x-mslxdff-qoder-nocapacity"),
|
|
124
|
+
verdict: pick("x-mslxdff-qoder-verdict"),
|
|
125
|
+
qoderRetry: pick("x-mslxdff-qoder-retry-after"),
|
|
118
126
|
};
|
|
119
127
|
}
|
|
120
128
|
|
|
@@ -128,7 +136,7 @@ export function formatModelTrace({ type, reqId, model, data = {}, request = null
|
|
|
128
136
|
else if (type === "alias") detail = `rawModel=${data.rawModel || "-"} requested=${data.requested || model || "-"}`;
|
|
129
137
|
else if (type === "exhausted-local" || type === "exhausted-all") detail = `last=${data.lastModel || model || "-"} status=${data.lastStatus ?? "-"} order=${(data.order || []).join(" | ")}`;
|
|
130
138
|
else if (type === "upstream-try") detail = `target=${data.model || model || "-"} attempt=${data.attempt ?? "-"} payload=${kv(data.payload || {})}`;
|
|
131
|
-
else if (type === "upstream-done" || type === "upstream-error") detail = `upstream status=${data.status ?? "-"} timing=${data.timing?.totalMs ?? "-"}ms${data.upstream ? ` via=${data.upstream}` : ""}${data.account ? ` account=${data.account}` : ""}${data.pick ? ` pick=${data.pick}` : ""}${data.cooled ? ` cooled=${data.cooled}` : ""}${data.queued ? ` queued=1` : ""} ${safeText(data.message || data.error || "")}`;
|
|
139
|
+
else if (type === "upstream-done" || type === "upstream-error") detail = `upstream status=${data.status ?? "-"} timing=${data.timing?.totalMs ?? "-"}ms${data.upstream ? ` via=${data.upstream}` : ""}${data.account ? ` account=${data.account}` : ""}${data.pick ? ` pick=${data.pick}` : ""}${data.cooled ? ` cooled=${data.cooled}` : ""}${data.queued ? ` queued=1` : ""}${data.login ? ` login=1` : ""}${data.nocapacity ? ` nocapacity=1` : ""}${data.verdict ? ` verdict=${data.verdict}` : ""}${data.qoderRetry ? ` retry=${data.qoderRetry}s` : ""} ${safeText(data.message || data.error || "")}`;
|
|
132
140
|
else if (type === "empty-turn-retry") detail = `空转重试:retry ${data.retry ?? "-"}/${data.max ?? "-"}${data.step != null ? ` step=${data.step}` : ""} delay=${data.delayMs ?? "-"}ms${data.waitedMs ? ` waited=${data.waitedMs}ms` : ""}${data.requestWaitedMs != null ? ` 请求级累计=${data.requestWaitedMs}ms/预算${data.budgetMs ?? "-"}ms` : ""}${data.raiseTo ? ` max_tokens ${data.raiseFrom}→${data.raiseTo}` : ""}${data.upstream ? ` after=${data.upstream}` : ""}${data.account ? ` account=${data.account}` : ""}${data.pick ? ` pick=${data.pick}` : ""}${data.nudged ? ` nudged=1` : ""} reason=empty turn${data.reason ? ` :: ${safeText(data.reason, 120)}` : ""}`;
|
|
133
141
|
else if (type === "empty-turn-recovered") detail = `空转重试成功:第 ${data.retries ?? "-"}/${data.max ?? "-"} 次重拉拿到真实输出,本轮共白等 ${data.waitedMs ?? "-"}ms${data.upstream ? ` via=${data.upstream}` : ""}${data.account ? ` account=${data.account}` : ""}${data.pick ? ` pick=${data.pick}` : ""}`;
|
|
134
142
|
else if (type === "empty-turn-exhausted") detail = `空转重试已用尽:重试 ${data.retries ?? 0}/${data.max ?? "-"} 次仍零输出(累计等待 ${data.waitedMs ?? 0}ms${data.budgetOut ? `,请求级等待预算 ${data.budgetMs ?? "-"}ms 用尽` : ""}),交回换候选${data.heldOpen ? "(响应仍开着,换过去的正文还能送达)" : "(响应已封口,重拉只为省额度)"}${data.upstream ? ` after=${data.upstream}` : ""}${data.account ? ` account=${data.account}` : ""}${data.pick ? ` pick=${data.pick}` : ""}${data.reason ? ` :: ${safeText(data.reason, 120)}` : ""}`;
|