dsh-model-rotation 0.8.1 → 0.8.2
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 +10 -0
- package/README.md +2 -0
- package/client.js +39 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
本文件记录 `dsh-model-rotation` 的对外变更。版本号遵循 `MAJOR.MINOR.PATCH`。
|
|
4
4
|
|
|
5
|
+
## 0.8.2
|
|
6
|
+
|
|
7
|
+
**健壮性 / 向后兼容**
|
|
8
|
+
|
|
9
|
+
- 客户端取 provider 显示名时同时兼容 `/catalog` 的两种形状:新版顶层 `labels` 映射,
|
|
10
|
+
旧版只有 `groups[].providers[].name`(宿主还在跑旧版本时标签也不会丢);
|
|
11
|
+
- 模型选择器分组标题兜底链改为 `分组名 → provider 自报名字 → provider id`,并且标题加了 `title`
|
|
12
|
+
提示、对比度略调高,避免浅色主题下看不清;
|
|
13
|
+
- 不写死任何厂家名、分组顺序或字段名,宿主/provider 插件升级换代不需要改本插件。
|
|
14
|
+
|
|
5
15
|
## 0.8.1
|
|
6
16
|
|
|
7
17
|
**兼容性 / 维护成本**
|
package/README.md
CHANGED
|
@@ -329,6 +329,8 @@ deepseek-official/deepseek-flash 内置 DeepSeek:DeepSeek Flash(兜
|
|
|
329
329
|
|
|
330
330
|
## 安装
|
|
331
331
|
|
|
332
|
+
**已发布到 npm**:<https://www.npmjs.com/package/dsh-model-rotation>(`npm i -g dsh-model-rotation` 可取到包,但本机 DSH 仍需下面的 generation 通道才会真正加载)。
|
|
333
|
+
|
|
332
334
|
**不能**用 `dsh plugin --profile web add <目录>`:那条命令只是 `pnpm` 的薄包装,
|
|
333
335
|
不维护 `dsh.profile.bundles`,装进去不会被加载。用桌面端的「generation」安装通道(仓库自带脚本):
|
|
334
336
|
|
package/client.js
CHANGED
|
@@ -849,16 +849,46 @@ window.__ModuleLoader__.load({
|
|
|
849
849
|
|
|
850
850
|
/** 各 provider 的显示名:优先用宿主 /catalog 里 provider 自报的名字(不写死任何厂家/型号) */
|
|
851
851
|
const LABELS = { data: {}, at: 0, inflight: null }
|
|
852
|
+
/**
|
|
853
|
+
* /catalog 的形状可能是新版(顶层 labels 映射)或旧版(只有 groups[].providers[]),
|
|
854
|
+
* 这里两种都认,避免宿主版本不同就丢标签 —— 标签只做兜底,不参与任何逻辑。
|
|
855
|
+
*/
|
|
856
|
+
const labelsFromCatalog = (data) => {
|
|
857
|
+
const out = {}
|
|
858
|
+
if (!data || typeof data !== 'object') return out
|
|
859
|
+
if (data.labels && typeof data.labels === 'object') {
|
|
860
|
+
for (const id of Object.keys(data.labels)) {
|
|
861
|
+
const name = asStr(data.labels[id])
|
|
862
|
+
if (id && name) out[id] = name
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
const groups = Array.isArray(data.groups) ? data.groups : []
|
|
866
|
+
for (const group of groups) {
|
|
867
|
+
if (!group || typeof group !== 'object') continue
|
|
868
|
+
const providers = Array.isArray(group.providers) ? group.providers : []
|
|
869
|
+
for (const provider of providers) {
|
|
870
|
+
if (!provider || typeof provider !== 'object') continue
|
|
871
|
+
const id = asStr(provider.id)
|
|
872
|
+
if (!id || out[id]) continue
|
|
873
|
+
const name = asStr(provider.name) || asStr(provider.displayName)
|
|
874
|
+
if (name) out[id] = name
|
|
875
|
+
}
|
|
876
|
+
const groupId = asStr(group.id)
|
|
877
|
+
if (groupId && !out[groupId]) {
|
|
878
|
+
const groupName = asStr(group.label) || asStr(group.name)
|
|
879
|
+
if (groupName) out[groupId] = groupName
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
return out
|
|
883
|
+
}
|
|
852
884
|
function loadProviderLabels() {
|
|
853
885
|
if (LABELS.inflight) return
|
|
854
|
-
if (Date.now() - LABELS.at < 60000) return
|
|
886
|
+
if (Date.now() - LABELS.at < 60000 && Object.keys(LABELS.data).length > 0) return
|
|
855
887
|
LABELS.inflight = getJson(CATALOG_URL)
|
|
856
888
|
.then((data) => {
|
|
857
|
-
const
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
LABELS.at = Date.now()
|
|
861
|
-
}
|
|
889
|
+
const map = labelsFromCatalog(data)
|
|
890
|
+
LABELS.data = map
|
|
891
|
+
LABELS.at = Date.now()
|
|
862
892
|
})
|
|
863
893
|
.catch(() => {})
|
|
864
894
|
.finally(() => {
|
|
@@ -906,7 +936,7 @@ window.__ModuleLoader__.load({
|
|
|
906
936
|
'.mrot-search{display:flex;padding:2px 3px 6px}',
|
|
907
937
|
'.mrot-search input{flex:1;min-width:0;padding:5px 7px;border:0;border-radius:6px;background:transparent;color:var(--dsw-alias-label-primary);font-size:12px;outline:none}',
|
|
908
938
|
'.mrot-list{display:flex;flex-direction:column;overflow-y:auto;min-height:0}',
|
|
909
|
-
'.mrot-group{padding:
|
|
939
|
+
'.mrot-group{padding:8px 7px 3px;font-size:11px;font-weight:600;letter-spacing:.02em;color:var(--dsw-alias-label-primary);opacity:.62;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}',
|
|
910
940
|
'.mrot-row{display:flex;align-items:center;gap:6px;min-height:32px;padding:4px 7px;border:0;border-radius:6px;background:transparent;color:var(--dsw-alias-label-primary);font-size:13px;text-align:left;cursor:pointer}',
|
|
911
941
|
'.mrot-row:hover:not(:disabled){background:var(--dsw-alias-bg-layer-2)}',
|
|
912
942
|
'.mrot-row[data-on="true"]{background:var(--dsw-alias-bg-layer-2)}',
|
|
@@ -1177,7 +1207,8 @@ window.__ModuleLoader__.load({
|
|
|
1177
1207
|
)
|
|
1178
1208
|
}
|
|
1179
1209
|
for (const group of filteredGroups) {
|
|
1180
|
-
|
|
1210
|
+
const groupText = group.name || providerLabel(group.id) || group.id || '模型'
|
|
1211
|
+
rows.push(h('div', { key: 'g:' + group.id, className: 'mrot-group', title: groupText }, groupText))
|
|
1181
1212
|
for (const model of group.models) {
|
|
1182
1213
|
const on = current !== null && current.provider === group.id && current.model === model.id
|
|
1183
1214
|
rows.push(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-model-rotation",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
4
4
|
"description": "Model rotation with source grouping for DeepSeek Harness: order models from any provider (agy / Codex / DeepSeek APIs / built-in) manually or automatically, pack model + reasoning effort into presets, fail over automatically when quota runs out (including a step-level auto-resend), pin an Auto entry at the top of the composer model picker, and show which model actually answered in the session header.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|