dsh-multi-router 0.6.2 → 0.6.4
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 +11 -0
- package/README.md +5 -1
- package/cordis.patch.yml +2 -2
- package/lib/accounts.js +2 -2
- package/lib/api-service.js +3 -3
- package/lib/{chunk-4EO5V6FW.js → chunk-3U6KCQEP.js} +31 -10
- package/lib/chunk-3U6KCQEP.js.map +7 -0
- package/lib/{chunk-KGVTRS5K.js → chunk-BVH4K6WH.js} +2 -2
- package/lib/{chunk-Q34JSMGN.js → chunk-GQEKAQXE.js} +3 -3
- package/lib/{chunk-5KYJADJ4.js → chunk-JJE6NRHN.js} +2 -2
- package/lib/{chunk-5R3IOPSF.js → chunk-PNFQDYBK.js} +2 -1
- package/lib/{chunk-5R3IOPSF.js.map → chunk-PNFQDYBK.js.map} +2 -2
- package/lib/{chunk-74WQLVJO.js → chunk-R3UQQMSV.js} +3 -3
- package/lib/{chunk-3O3L3526.js → chunk-XAND4QBY.js} +3 -3
- package/lib/cli.js +4 -4
- package/lib/client.js +82 -15
- package/lib/client.js.map +2 -2
- package/lib/clients.js +3 -3
- package/lib/{host-v0.6.2.js → host-v0.6.4.js} +7 -7
- package/lib/host.js +7 -7
- package/lib/index.js +7 -7
- package/lib/manager.js +6 -6
- package/lib/router.js +2 -2
- package/lib/shim.js +3 -3
- package/package.json +1 -1
- package/lib/chunk-4EO5V6FW.js.map +0 -7
- /package/lib/{chunk-KGVTRS5K.js.map → chunk-BVH4K6WH.js.map} +0 -0
- /package/lib/{chunk-Q34JSMGN.js.map → chunk-GQEKAQXE.js.map} +0 -0
- /package/lib/{chunk-5KYJADJ4.js.map → chunk-JJE6NRHN.js.map} +0 -0
- /package/lib/{chunk-74WQLVJO.js.map → chunk-R3UQQMSV.js.map} +0 -0
- /package/lib/{chunk-3O3L3526.js.map → chunk-XAND4QBY.js.map} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
本项目遵循 [语义化版本](https://semver.org/lang/zh-CN/)。版本号从 `0.1` 起以功能迭代为主,接口在 `1.0` 前可能变化。
|
|
4
4
|
|
|
5
|
+
## 0.6.4
|
|
6
|
+
|
|
7
|
+
- 路由编辑的上下文容量与默认思考深度合并至名称下方的「模型参数」区域;宽窗口并排、窄窗口上下排列,容量变化后仍自动核对可用思考档位。
|
|
8
|
+
- 更新路由设置的合成数据截图与说明。
|
|
9
|
+
|
|
10
|
+
## 0.6.3
|
|
11
|
+
|
|
12
|
+
- 普通预配置及自定义路由的编辑弹窗新增「默认思考深度」,支持平台默认及渠道声明的关闭 / 深度档位;按当前目标、指定账号和上下文容量核对选项,仅读取本机模型缓存,不发送供应商探测请求。
|
|
13
|
+
- 保存校验所选档位;会话手动选择及 API `reasoning_effort` 优先于路由默认,仅向支持所选档位的账号切换。暂缺目录时保留已有默认值,不静默降档。
|
|
14
|
+
- 路由默认思考深度随配置导入导出迁移,覆盖保存、重载、跨设备迁移及真实 DSH 请求的回归验证。
|
|
15
|
+
|
|
5
16
|
## 0.6.2
|
|
6
17
|
|
|
7
18
|
- 修复旧用户升级后缺少新预制路由:启用或热加载时自动补齐 Qwen3.8-Max、Qwen3.8-Flash 与 Hy4 Preview,更新后直接出现在路由列表与模型选择器,无需手动补齐或重启。
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
一个插件内置 WorkBuddy、Trae、Qoder 的认证、模型发现和聊天传输,提供三家的多账号池及集中路由。运行不依赖原来三个 DSH 插件;三家代码随安装包一起打包。基于 MIT 上游,固定版本见 `upstream-lock.json`,许可见 `THIRD_PARTY_NOTICES.md`。
|
|
8
8
|
|
|
9
|
-
版本:0.6.
|
|
9
|
+
版本:0.6.4。适配 DSH Desktop / Web 0.2.0-rc.2,Node.js ^22.19.0 或 >=24。
|
|
10
10
|
|
|
11
11
|
## 在 DSH 里管理
|
|
12
12
|
|
|
@@ -347,6 +347,10 @@ Free 不使用临期积分或 Token / 积分额度策略,避免将「消耗赠
|
|
|
347
347
|
|
|
348
348
|
## 统一路由推理模式
|
|
349
349
|
|
|
350
|
+
「路由规则 → 编辑路由 → 模型参数」集中设置上下文容量与默认思考深度,宽窗口并排显示、窄窗口自动上下排列。可为普通预配置与自定义路由设置平台默认、关闭思考或具体档位。选项根据当前目标、指定账号及上下文容量,从本机目录实时核对;保存立即生效,DSH 会话的手动选择及 API 的 `reasoning_effort` 优先。没有声明可调档位时只使用平台默认,已有档位暂不可用时保留设置并显示提示,不自动降档。默认值随配置导入导出保留。
|
|
351
|
+
|
|
352
|
+

|
|
353
|
+
|
|
350
354
|
所有预配置与自定义路由保留各目标明确声明的全部档位,包括支持的 Off、Minimal、Low、Medium、High、XHigh、Max。不同渠道存在差异时使用并集,并按会话所选档位筛选实际账号 / 模型候选,不静默降级,也不因某个目标未声明档位而删掉其他目标的能力。WorkBuddy 国内 onlyReasoning 的模型仍遵守上游禁止 Off 的约束。平台默认与显式 Off 通过每次请求独立的本机 shim 头区分,头不发送到三家上游;实际请求仍使用各渠道本来的字段映射。
|
|
351
355
|
|
|
352
356
|
## 开发与验证
|
package/cordis.patch.yml
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
- insert:
|
|
2
|
-
- id: llm-multi-router-v2-0.6.
|
|
3
|
-
name: ./lib/host-v0.6.
|
|
2
|
+
- id: llm-multi-router-v2-0.6.4
|
|
3
|
+
name: ./lib/host-v0.6.4.js
|
package/lib/accounts.js
CHANGED
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
localAccountKey,
|
|
5
5
|
normalizeLocalAccountKey,
|
|
6
6
|
readPortableCredential
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-BVH4K6WH.js";
|
|
8
8
|
import "./chunk-OK2T2UAZ.js";
|
|
9
9
|
import "./chunk-TEZ2FMEO.js";
|
|
10
10
|
import "./chunk-S5KMFAQM.js";
|
|
11
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-PNFQDYBK.js";
|
|
12
12
|
export {
|
|
13
13
|
discoverLocalAccounts,
|
|
14
14
|
importAccount,
|
package/lib/api-service.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ApiService
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-GQEKAQXE.js";
|
|
4
4
|
import "./chunk-4V52V5GO.js";
|
|
5
5
|
import "./chunk-DNQPZMPF.js";
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-JJE6NRHN.js";
|
|
7
|
+
import "./chunk-PNFQDYBK.js";
|
|
8
8
|
export {
|
|
9
9
|
ApiService
|
|
10
10
|
};
|
|
@@ -6,20 +6,20 @@ import {
|
|
|
6
6
|
refreshWorkBuddyCheckinCredential,
|
|
7
7
|
supportsCheckin,
|
|
8
8
|
workbuddyToken
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-R3UQQMSV.js";
|
|
10
10
|
import {
|
|
11
11
|
discoverLocalAccounts,
|
|
12
12
|
importAccount,
|
|
13
13
|
localAccountKey,
|
|
14
14
|
normalizeLocalAccountKey,
|
|
15
15
|
readPortableCredential
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-BVH4K6WH.js";
|
|
17
17
|
import {
|
|
18
18
|
modelWithCurrentPromotion
|
|
19
19
|
} from "./chunk-TEZ2FMEO.js";
|
|
20
20
|
import {
|
|
21
21
|
ApiService
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-GQEKAQXE.js";
|
|
23
23
|
import {
|
|
24
24
|
hostIsLoopback
|
|
25
25
|
} from "./chunk-DNQPZMPF.js";
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
contextInfo,
|
|
29
29
|
matchModel,
|
|
30
30
|
resolveContext
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-JJE6NRHN.js";
|
|
32
32
|
import {
|
|
33
33
|
PROVIDERS,
|
|
34
34
|
PROVIDER_NAMES,
|
|
@@ -38,13 +38,13 @@ import {
|
|
|
38
38
|
routeReasoning,
|
|
39
39
|
validateConfig,
|
|
40
40
|
writePrivateJson
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-PNFQDYBK.js";
|
|
42
42
|
|
|
43
43
|
// src/manager.mjs
|
|
44
44
|
import { createHash, randomBytes as randomBytes3, timingSafeEqual } from "node:crypto";
|
|
45
45
|
|
|
46
46
|
// package.json
|
|
47
|
-
var version = "0.6.
|
|
47
|
+
var version = "0.6.4";
|
|
48
48
|
|
|
49
49
|
// src/manager.mjs
|
|
50
50
|
import { readFile as readFile4, mkdir as mkdir2, mkdtemp as mkdtemp2, rm as rm3 } from "node:fs/promises";
|
|
@@ -113,7 +113,7 @@ function settings(config) {
|
|
|
113
113
|
models: Object.fromEntries(Object.entries(config.models ?? {}).map(([p, rows]) => [p, Object.fromEntries(Object.entries(rows).map(([id, pref]) => [id, pick(pref, ["name", "visible", "contextWindow", "supportsImages", "reasoningEffort"])]))])),
|
|
114
114
|
accounts: config.accounts.map((a) => pick(a, ["id", "provider", "name", "enabled", "autoCheckin"])),
|
|
115
115
|
routes: Object.fromEntries(Object.entries(config.routes).map(([id, r]) => [id, {
|
|
116
|
-
...pick(r, ["name", "visible", "strategy", "contextMode", "contextWindow", "maxTokens", "preferExpiringCredits", "expiringWithinDays", "freeOnly", "freeModels"]),
|
|
116
|
+
...pick(r, ["name", "visible", "strategy", "contextMode", "contextWindow", "maxTokens", "reasoningEffort", "preferExpiringCredits", "expiringWithinDays", "freeOnly", "freeModels"]),
|
|
117
117
|
targets: r.targets.map((t) => pick(t, ["provider", "account", "model", "models", "weight", "tokenBudget", "creditBudget"]))
|
|
118
118
|
}]))
|
|
119
119
|
};
|
|
@@ -1376,8 +1376,8 @@ var Manager = class {
|
|
|
1376
1376
|
modelVisible(provider, id) {
|
|
1377
1377
|
return this.config.models[provider]?.[id]?.visible ?? this.config.modelVisibility[provider] ?? false;
|
|
1378
1378
|
}
|
|
1379
|
-
routeModels() {
|
|
1380
|
-
return Object.entries(
|
|
1379
|
+
routeModels(routes = this.config.routes) {
|
|
1380
|
+
return Object.entries(routes).sort(([, a], [, b]) => Number(!!b.freeOnly) - Number(!!a.freeOnly)).map(([id, row]) => {
|
|
1381
1381
|
const effectiveTargets = row.freeOnly ? this.freeRoutes(id, row).flatMap((r) => r.targets) : row.targets;
|
|
1382
1382
|
const sources = effectiveTargets.flatMap((target) => this.config.accounts.filter((a) => a.enabled !== false && a.provider === target.provider && (!target.account || target.account === a.id)).flatMap((a) => {
|
|
1383
1383
|
const catalog = this.catalogs.get(a.id)?.models ?? [];
|
|
@@ -1489,6 +1489,17 @@ var Manager = class {
|
|
|
1489
1489
|
}
|
|
1490
1490
|
async action(input) {
|
|
1491
1491
|
if (!input || typeof input !== "object" || Array.isArray(input)) bad("\u8BF7\u6C42\u683C\u5F0F\u65E0\u6548");
|
|
1492
|
+
if (input.action === "route.preview") {
|
|
1493
|
+
if (input.route?.freeOnly) bad("\u514D\u8D39\u6A21\u578B\u8BF7\u9010\u9879\u8BBE\u7F6E\u63A8\u7406\u7B49\u7EA7");
|
|
1494
|
+
let config;
|
|
1495
|
+
try {
|
|
1496
|
+
config = validateConfig({ ...this.raw, routes: { [input.id || "preview"]: input.route } }, this.file);
|
|
1497
|
+
} catch {
|
|
1498
|
+
bad("\u8BF7\u5148\u9009\u62E9\u6709\u6548\u7684\u76EE\u6807\u6A21\u578B\u4E0E\u4E0A\u4E0B\u6587\u5BB9\u91CF");
|
|
1499
|
+
}
|
|
1500
|
+
const { reasoning, contextKnown } = this.routeModels(config.routes)[0];
|
|
1501
|
+
return { routePreview: { reasoning, contextKnown } };
|
|
1502
|
+
}
|
|
1492
1503
|
if (input.action === "model.test") {
|
|
1493
1504
|
const model = this.providerModels(input.provider).find((m) => m.id === input.id);
|
|
1494
1505
|
if (!model) bad("\u8BF7\u5148\u5237\u65B0\u5E76\u9009\u62E9\u5DF2\u53D1\u73B0\u7684\u6A21\u578B");
|
|
@@ -1911,6 +1922,16 @@ var Manager = class {
|
|
|
1911
1922
|
} catch (error) {
|
|
1912
1923
|
bad(error.message);
|
|
1913
1924
|
}
|
|
1925
|
+
if (input.action === "route.save" && input.route.reasoningEffort != null) {
|
|
1926
|
+
const previous = this.config.routes[input.previousId], route = config.routes[input.id];
|
|
1927
|
+
const bindings = (r) => JSON.stringify(r.targets.map((t) => ({
|
|
1928
|
+
provider: t.provider,
|
|
1929
|
+
account: t.account,
|
|
1930
|
+
models: t.models ?? (t.model ? [t.model] : [])
|
|
1931
|
+
})));
|
|
1932
|
+
const unchanged = previous?.reasoningEffort === route.reasoningEffort && bindings(previous) === bindings(route) && previous.contextMode === route.contextMode && (route.contextMode === "maximum" || previous.contextWindow === route.contextWindow);
|
|
1933
|
+
if (!unchanged && !this.routeModels({ [input.id]: route })[0].reasoning?.supportedEfforts.includes(route.reasoningEffort)) bad("\u76EE\u6807\u6A21\u578B\u5728\u5F53\u524D\u4E0A\u4E0B\u6587\u5BB9\u91CF\u4E0B\u4E0D\u652F\u6301\u6240\u9009\u601D\u8003\u6DF1\u5EA6\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9");
|
|
1934
|
+
}
|
|
1914
1935
|
await writePrivateJson(this.file, raw);
|
|
1915
1936
|
staging = void 0;
|
|
1916
1937
|
this.raw = raw;
|
|
@@ -2027,4 +2048,4 @@ export {
|
|
|
2027
2048
|
Manager,
|
|
2028
2049
|
managementHandler
|
|
2029
2050
|
};
|
|
2030
|
-
//# sourceMappingURL=chunk-
|
|
2051
|
+
//# sourceMappingURL=chunk-3U6KCQEP.js.map
|