@goodandready/dsh-subscriptions 0.7.30 → 0.7.31
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/lib/client.js +80 -1
- package/lib/models-catalog.js +12 -0
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -202,6 +202,10 @@ window.__ModuleLoader__.load({
|
|
|
202
202
|
"modelShowMore": "Show more",
|
|
203
203
|
"modelShowAll": "Show all",
|
|
204
204
|
"modelNoMatches": "No models match this search.",
|
|
205
|
+
"modelCatalogSourceHint": "Catalog source: live, cached or builtin",
|
|
206
|
+
"modelNamesTitle": "Model display names",
|
|
207
|
+
"modelNamesHint": "Presentation only: routing, reasoning and model ids stay unchanged. Reset restores the catalog name.",
|
|
208
|
+
"modelNameReset": "Reset",
|
|
205
209
|
"rotationDecisionsTitle": "Rotation & Routing Decisions",
|
|
206
210
|
"rotationDecisionsDesc": "Real-time decision trace explaining account selection, skips, and fallback reasons.",
|
|
207
211
|
"rotationAttempt": "attempt",
|
|
@@ -308,7 +312,10 @@ window.__ModuleLoader__.load({
|
|
|
308
312
|
"maxQueueSizeSlot": "Queue",
|
|
309
313
|
"save": "Save",
|
|
310
314
|
"saved": "Saved",
|
|
315
|
+
"cancel": "Cancel",
|
|
316
|
+
"unsavedChanges": "Unsaved changes",
|
|
311
317
|
"accountLabel": "Account",
|
|
318
|
+
"usageRemaining": "Remaining quota",
|
|
312
319
|
"plan": "Plan",
|
|
313
320
|
"storedAs": "Stored as",
|
|
314
321
|
"slashFast": "Toggle Codex Speed (fast/standard)",
|
|
@@ -594,6 +601,10 @@ window.__ModuleLoader__.load({
|
|
|
594
601
|
"modelShowMore": "显示更多",
|
|
595
602
|
"modelShowAll": "显示全部",
|
|
596
603
|
"modelNoMatches": "没有匹配的模型。",
|
|
604
|
+
"modelCatalogSourceHint": "目录来源:实时、缓存或内置",
|
|
605
|
+
"modelNamesTitle": "模型显示名称",
|
|
606
|
+
"modelNamesHint": "仅影响显示:路由、推理和模型 ID 不变。重置恢复目录名称。",
|
|
607
|
+
"modelNameReset": "重置",
|
|
597
608
|
"rotationDecisionsTitle": "轮询调度与路由决策",
|
|
598
609
|
"rotationDecisionsDesc": "实时决策追踪,透明展示每次请求的账号选择、跳过与回退原因。",
|
|
599
610
|
"rotationAttempt": "次尝试",
|
|
@@ -700,7 +711,10 @@ window.__ModuleLoader__.load({
|
|
|
700
711
|
"maxQueueSizeSlot": "队列",
|
|
701
712
|
"save": "保存",
|
|
702
713
|
"saved": "已保存",
|
|
714
|
+
"cancel": "取消",
|
|
715
|
+
"unsavedChanges": "有未保存的更改",
|
|
703
716
|
"accountLabel": "账户",
|
|
717
|
+
"usageRemaining": "剩余配额",
|
|
704
718
|
"plan": "套餐方案",
|
|
705
719
|
"storedAs": "存储标识",
|
|
706
720
|
"slashFast": "切换 Codex 加速模式(快速/标准)",
|
|
@@ -1419,6 +1433,7 @@ window.__ModuleLoader__.load({
|
|
|
1419
1433
|
}
|
|
1420
1434
|
const [checking, setChecking] = React.useState({})
|
|
1421
1435
|
const [saved, setSaved] = React.useState(false)
|
|
1436
|
+
const [savedSnapshot, setSavedSnapshot] = React.useState(null)
|
|
1422
1437
|
const [tokenDraft, setTokenDraft] = React.useState({})
|
|
1423
1438
|
const [openHelp, setOpenHelp] = React.useState({})
|
|
1424
1439
|
const [err, setErr] = React.useState('')
|
|
@@ -1440,7 +1455,9 @@ window.__ModuleLoader__.load({
|
|
|
1440
1455
|
|
|
1441
1456
|
const applyPayload = (data) => {
|
|
1442
1457
|
if (data && data.revision != null) setRevision(data.revision)
|
|
1443
|
-
|
|
1458
|
+
const next = JSON.parse(JSON.stringify((data && data.config) || {}))
|
|
1459
|
+
setDraft(next)
|
|
1460
|
+
setSavedSnapshot(JSON.parse(JSON.stringify(next)))
|
|
1444
1461
|
setAccounts((data && data.accounts) || [])
|
|
1445
1462
|
setProviders((data && data.providers) || [])
|
|
1446
1463
|
setModelsCatalog((data && data.modelsCatalog) || [])
|
|
@@ -1492,6 +1509,18 @@ window.__ModuleLoader__.load({
|
|
|
1492
1509
|
return () => timers.forEach(clearInterval)
|
|
1493
1510
|
}, [device])
|
|
1494
1511
|
|
|
1512
|
+
const dirty = Boolean(draft && savedSnapshot && JSON.stringify(draft) !== JSON.stringify(savedSnapshot))
|
|
1513
|
+
React.useEffect(() => {
|
|
1514
|
+
if (!dirty) return undefined
|
|
1515
|
+
const warn = (event) => {
|
|
1516
|
+
event.preventDefault()
|
|
1517
|
+
event.returnValue = ''
|
|
1518
|
+
return ''
|
|
1519
|
+
}
|
|
1520
|
+
window.addEventListener('beforeunload', warn)
|
|
1521
|
+
return () => window.removeEventListener('beforeunload', warn)
|
|
1522
|
+
}, [dirty])
|
|
1523
|
+
|
|
1495
1524
|
// #81: settings snapshot status - never render phantom inputs before the
|
|
1496
1525
|
// config snapshot arrives, and offer a retry when the store is unavailable.
|
|
1497
1526
|
if (!draft) {
|
|
@@ -2378,6 +2407,7 @@ h('div', { className: 'dsub-row' },
|
|
|
2378
2407
|
m.provider ? h('span', { className: 'dsub-brand dsub-brand-' + m.provider, style: { fontSize: '9px', padding: '1px 4px' } }, m.provider.toUpperCase()) : null,
|
|
2379
2408
|
h('code', null, m.name || m.id),
|
|
2380
2409
|
tags.length ? h('span', { className: 'dsub-model-tag' }, tags.join(' · ')) : null,
|
|
2410
|
+
Array.isArray(m.catalogSources) && m.catalogSources.length ? h('span', { className: 'dsub-model-tag', title: t('modelCatalogSourceHint') }, '📚 ' + m.catalogSources.join('/')) : null,
|
|
2381
2411
|
h('span', { className: 'dsub-model-tag ' + statusClass }, poolLabel),
|
|
2382
2412
|
)
|
|
2383
2413
|
})
|
|
@@ -2394,6 +2424,46 @@ h('div', { className: 'dsub-row' },
|
|
|
2394
2424
|
}, t('modelShowAll')),
|
|
2395
2425
|
) : null,
|
|
2396
2426
|
),
|
|
2427
|
+
h('details', { className: 'dsub-group', 'data-pane': 'models' },
|
|
2428
|
+
h('summary', { className: 'dsub-groupHead' }, '🏷 ' + t('modelNamesTitle')),
|
|
2429
|
+
h('div', { className: 'dsub-sub', style: { marginTop: 4 } }, t('modelNamesHint')),
|
|
2430
|
+
h('div', { style: { maxHeight: 260, overflow: 'auto', marginTop: 6 } },
|
|
2431
|
+
catalogShown.slice(0, 50).map((model) => {
|
|
2432
|
+
const current = (Array.isArray(draft.modelDisplayNames) ? draft.modelDisplayNames : [])
|
|
2433
|
+
.find((row) => row && row.provider === model.provider && String(row.id) === String(model.id))
|
|
2434
|
+
return h('div', { key: 'name:' + model.provider + ':' + model.id, className: 'dsub-row', style: { gap: 6 } },
|
|
2435
|
+
h('code', { style: { minWidth: 120, fontSize: 11 } }, model.id),
|
|
2436
|
+
h('input', {
|
|
2437
|
+
className: 'dsub-inp dsub-grow',
|
|
2438
|
+
value: current ? current.name : '',
|
|
2439
|
+
placeholder: model.name || model.id,
|
|
2440
|
+
onChange: (e) => {
|
|
2441
|
+
const value = e.target.value
|
|
2442
|
+
setDraft((d) => {
|
|
2443
|
+
const list = Array.isArray(d.modelDisplayNames) ? d.modelDisplayNames.slice() : []
|
|
2444
|
+
const idx = list.findIndex((row) => row && row.provider === model.provider && String(row.id) === String(model.id))
|
|
2445
|
+
if (value.trim()) {
|
|
2446
|
+
const next = { provider: model.provider, id: String(model.id), name: value.slice(0, 80) }
|
|
2447
|
+
if (idx >= 0) list[idx] = next
|
|
2448
|
+
else list.push(next)
|
|
2449
|
+
} else if (idx >= 0) {
|
|
2450
|
+
list.splice(idx, 1)
|
|
2451
|
+
}
|
|
2452
|
+
return Object.assign({}, d, { modelDisplayNames: list })
|
|
2453
|
+
})
|
|
2454
|
+
},
|
|
2455
|
+
}),
|
|
2456
|
+
h('button', {
|
|
2457
|
+
type: 'button', className: 'dsub-mini',
|
|
2458
|
+
onClick: () => setDraft((d) => Object.assign({}, d, {
|
|
2459
|
+
modelDisplayNames: (Array.isArray(d.modelDisplayNames) ? d.modelDisplayNames : [])
|
|
2460
|
+
.filter((row) => !(row && row.provider === model.provider && String(row.id) === String(model.id))),
|
|
2461
|
+
})),
|
|
2462
|
+
}, t('modelNameReset')),
|
|
2463
|
+
)
|
|
2464
|
+
})
|
|
2465
|
+
),
|
|
2466
|
+
),
|
|
2397
2467
|
h('details', { className: 'dsub-group', 'data-pane': 'models' },
|
|
2398
2468
|
h('summary', { className: 'dsub-groupHead' }, '🧠 ' + t('reasoningEffortTitle')),
|
|
2399
2469
|
h('div', { className: 'dsub-sub', style: { marginTop: '4px' } }, t('reasoningEffortDesc')),
|
|
@@ -2908,6 +2978,9 @@ h('div', { className: 'dsub-row' },
|
|
|
2908
2978
|
},
|
|
2909
2979
|
}, '\u00d7'),
|
|
2910
2980
|
),
|
|
2981
|
+
(account && (account.quota?.remainingPercent != null || account.usagePercent != null)) ? h('div', { className: 'dsub-sub', style: { marginTop: 4 } },
|
|
2982
|
+
'📊 ' + t('usageRemaining') + ' ' + Math.round(account.quota?.remainingPercent != null ? Number(account.quota.remainingPercent) : (100 - Number(account.usagePercent))) + '%'
|
|
2983
|
+
) : null,
|
|
2911
2984
|
(account && account.quarantineUntil && Number(account.quarantineUntil) > Date.now()) ? h('div', { className: 'dsub-row', style: { marginTop: 4 } },
|
|
2912
2985
|
h('span', { className: 'dsub-sub', style: { color: 'var(--dsw-alias-state-error-primary)', fontVariantNumeric: 'tabular-nums' } },
|
|
2913
2986
|
'⛔ ' + (account.quarantineReason || 'QUARANTINE') + ' · ' + t('resetsIn') + ' ' + formatRelativeReset(account.quarantineUntil, t('lang'), Date.now())
|
|
@@ -3538,6 +3611,12 @@ h('div', { className: 'dsub-row' },
|
|
|
3538
3611
|
type: 'button', className: 'dsub-save',
|
|
3539
3612
|
onClick: () => save().catch((e) => setErr(cleanErrorMessage(e.message || e))),
|
|
3540
3613
|
}, t('save')),
|
|
3614
|
+
h('button', {
|
|
3615
|
+
type: 'button', className: 'dsub-mini',
|
|
3616
|
+
disabled: !dirty,
|
|
3617
|
+
onClick: () => reload().catch((e) => setErr(cleanErrorMessage(e.message || e))),
|
|
3618
|
+
}, t('cancel')),
|
|
3619
|
+
dirty ? h('span', { className: 'dsub-sub' }, t('unsavedChanges')) : null,
|
|
3541
3620
|
saved ? h('span', { className: 'dsub-ok' }, t('saved')) : null,
|
|
3542
3621
|
info ? h('span', { className: 'dsub-ok' }, info) : null,
|
|
3543
3622
|
err ? h('span', { className: 'dsub-bad' }, err) : null,
|
package/lib/models-catalog.js
CHANGED
|
@@ -279,6 +279,17 @@ export function buildEnrichedCatalog({
|
|
|
279
279
|
|
|
280
280
|
const modelName = (typeof item === 'object' && (item.name || item.display_name)) ? (item.name || item.display_name) : modelId
|
|
281
281
|
const caps = inferModelCapabilities(provId, modelId)
|
|
282
|
+
const catalogSources = new Set()
|
|
283
|
+
for (const account of accounts) {
|
|
284
|
+
if (!account || String(account.provider || '').toLowerCase() !== String(provId).toLowerCase()) continue
|
|
285
|
+
const available = Array.isArray(account.availableModels) ? account.availableModels : []
|
|
286
|
+
const hasModel = available.some((model) => {
|
|
287
|
+
const id = typeof model === 'string' ? model : (model && (model.id || model.slug || model.name))
|
|
288
|
+
return String(id || '') === String(modelId)
|
|
289
|
+
})
|
|
290
|
+
if (hasModel) catalogSources.add(account.modelsSource || 'live')
|
|
291
|
+
}
|
|
292
|
+
if (!catalogSources.size) catalogSources.add('builtin')
|
|
282
293
|
|
|
283
294
|
result.push({
|
|
284
295
|
id: modelId,
|
|
@@ -288,6 +299,7 @@ export function buildEnrichedCatalog({
|
|
|
288
299
|
contextWindow: caps.contextWindow,
|
|
289
300
|
contextLabel: caps.contextLabel,
|
|
290
301
|
capabilities: caps.capabilities,
|
|
302
|
+
catalogSources: Array.from(catalogSources),
|
|
291
303
|
pool,
|
|
292
304
|
})
|
|
293
305
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goodandready/dsh-subscriptions",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.31",
|
|
4
4
|
"description": "Use ChatGPT Codex, Claude, Grok, Antigravity, Kimi, GLM, Cursor, Kiro, Copilot, Qwen, ERNIE, Spark, JetBrains, Perplexity, Replit, and Cody subscriptions as DeepSeek Harness LLM providers via OAuth.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|