@goodandready/dsh-subscriptions 0.6.70 → 0.6.72
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/README.md +7 -1
- package/README.ru.md +7 -1
- package/README.zh.md +7 -1
- package/lib/accounts-view.js +4 -0
- package/lib/accounts.js +13 -0
- package/lib/adapter-manager.js +2 -0
- package/lib/adapter.js +8 -0
- package/lib/client.js +637 -807
- package/lib/config-schema.js +4 -0
- package/lib/diagnostics.js +2 -0
- package/lib/doctor.js +163 -0
- package/lib/instructions.js +138 -0
- package/lib/quarantine.js +6 -2
- package/lib/reset-clock.js +87 -0
- package/lib/rotate.js +34 -3
- package/lib/routes/accounts.js +72 -0
- package/lib/routes/status.js +99 -5
- package/lib/sentinel.js +136 -0
- package/lib/stream-rotate.js +26 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -207,7 +207,13 @@ const res = await ctx.subscriptions.request('codex', '/backend-api/codex/images/
|
|
|
207
207
|
* **In-App Toast Alerts (`enableToasts`)**: Lightweight floating toast alerts in the DSH chat interface notifying you when accounts enter quarantine, recover from cooldowns, or exceed quota safety thresholds.
|
|
208
208
|
* **Automated Webhook Integration**: Instant event notifications dispatched via `notifyQuarantineEntered` and `notifyQuarantineReleased`.
|
|
209
209
|
|
|
210
|
-
###
|
|
210
|
+
### 25. 🩺 Vendor Auth Doctor, Latency RTT Indicator, Dynamic Model Sync & Client Bundle Relief (v0.6.72)
|
|
211
|
+
* **Vendor Auth Doctor (#543)**: Intelligent classification and explanation of provider authentication and connection errors (Cloudflare 403 / Geoblock, expired tokens, revoked sessions, missing model scopes, exhausted quotas). Displays diagnostic verdict with actionable recommendations in the account card.
|
|
212
|
+
* **Latency RTT Indicator & Fast Ping Probe (#542)**: Live round-trip time measurement to vendor APIs with color-coded badges (🟢 <250ms, 🟡 <750ms, 🔴 >750ms). Dedicated ping endpoint (POST /dsh-subscriptions/ping) and latency metrics in connection tests.
|
|
213
|
+
* **Dynamic Model Catalog Discovery & Sync (#541)**: One-click "Sync Models" button on account cards querying live vendor /v1/models endpoints to discover newly released and subscription-specific models dynamically without waiting for plugin updates.
|
|
214
|
+
* **Client Bundle Modularization & Store Limit Relief (#540)**: Reduced lib/client.js bundle size from 217.3 KiB to < 199 KiB (>57 KiB buffer below the 256 KiB DSH Store ceiling) via createElement aliasing, CSS minification, and dynamic instruction loading.
|
|
215
|
+
|
|
216
|
+
### 24. 🛡️ Resilience, Diagnostics & Fallback Enhancements (v0.6.71)
|
|
211
217
|
* **Cross-Vendor Cascading Fallback & Provider Priority Ordering (#536)**: Configure fallback ordering across subscription providers with interactive reordering in WebUI.
|
|
212
218
|
* **1-Click Connection Smoke Test & Latency Ping (#536)**: Test individual account connections on the spot with real-time latency badges.
|
|
213
219
|
* **Live Cooldown Countdown & Availability Toasts (#536)**: Exact countdown timer for cooled-down accounts and automated toast alerts upon recovery.
|
package/README.ru.md
CHANGED
|
@@ -183,7 +183,13 @@ const res = await ctx.subscriptions.request('codex', '/backend-api/codex/images/
|
|
|
183
183
|
* **Всплывающие уведомления (Toast Alerts)**: Легковесные всплывающие тосты в веб-интерфейсе DSH при событиях карантина (с отображением причины), восстановлении доступа и критическом расходе квоты. Включение управляется параметром `enableToasts` (по умолчанию `true`).
|
|
184
184
|
* **Интеграция с вебхуками**: Автоматическая отправка уведомлений через `notifyQuarantineEntered` и `notifyQuarantineReleased`.
|
|
185
185
|
|
|
186
|
-
###
|
|
186
|
+
### 21. 🩺 Доктор авторизации вендоров, индикатор задержки RTT, синхронизация моделей и оптимизация бандла (v0.6.72)
|
|
187
|
+
* **Доктор ошибок авторизации (#543)**: Интеллектуальный анализ и расшифровка ошибок подключения и аутентификации (Cloudflare 403 / геоблокировка, истекшие токены, отозванные сессии, нехватка разрешений на модель, исчерпанные квоты) с выводом рекомендаций в карточке аккаунта.
|
|
188
|
+
* **Индикатор RTT и быстрый пинг (#542)**: Замер времени отклика до API провайдеров в реальном времени с цветными бейджами задержки (зеленый < 250ms, желтый < 750ms, красный > 750ms) и отдельным эндпоинтом POST /dsh-subscriptions/ping.
|
|
189
|
+
* **Динамическая синхронизация моделей (#541)**: Кнопка «Синхронизировать модели» в карточке аккаунта, запрашивающая актуальный каталог моделей напрямую из API вендора (/v1/models) без ожидания новых релизов плагина.
|
|
190
|
+
* **Оптимизация клиентского бандла (#540)**: Снижение размера lib/client.js с 217.3 KiB до < 199 KiB (запас более 57 KiB до жесткого лимита DSH Store в 256 KiB) за счет сжатия CSS, алиасинга createElement и динамической загрузки инструкций.
|
|
191
|
+
|
|
192
|
+
### 20. 🛡️ Отказоустойчивость, диагностика и порядок фолбэка (v0.6.71)
|
|
187
193
|
* **Межвендорный каскадный фолбэк с настройкой очередности (#536)**: Настройка порядка переключения провайдеров при исчерпании квот с интерактивным изменением приоритета (▲/▼) в WebUI.
|
|
188
194
|
* **1-Click проверка подключения и пинг задержки (#536)**: Проверка конкретного аккаунта в один клик с отображением задержки (`✓ 240ms`).
|
|
189
195
|
* **Живой таймер кулдауна и уведомления о восстановлении (#536)**: Точный обратный отсчет кулдауна и всплывающие in-app тосты при возвращении аккаунта в строй.
|
package/README.zh.md
CHANGED
|
@@ -132,7 +132,13 @@ graph LR
|
|
|
132
132
|
queueTimeoutMs: 30000 # v0.6.62: 队列最大等待超时时间(毫秒)
|
|
133
133
|
* **自动化 Webhook 告警集成**:通过 `notifyQuarantineEntered` 与 `notifyQuarantineReleased` 自动向外部通知系统派发隔离生命周期事件。
|
|
134
134
|
|
|
135
|
-
###
|
|
135
|
+
### 🩺 服务商鉴权诊断、网络延迟 RTT 指标、动态模型同步与客户端轻量化 (v0.6.72)
|
|
136
|
+
* **服务商错误诊断系统 (#543)**: 智能分析与解读服务商连接和鉴权失败原因(Cloudflare 403 / 地区限制、令牌过期、会话失效、模型权限不足、用量配额耗尽),并在卡片中直接展示修复建议。
|
|
137
|
+
* **延迟 RTT 指标与快速 Ping 测试 (#542)**: 实时测量至服务商 API 的网络往返时间,支持色彩标记状态徽章(🟢 <250ms, 🟡 <750ms, 🔴 >750ms)及独立 POST /dsh-subscriptions/ping 接口。
|
|
138
|
+
* **动态模型列表同步 (#541)**: 账户卡片一键「同步模型」按钮,直接从服务商 /v1/models 接口获取最新及账号专享模型,无需等待插件版本更新。
|
|
139
|
+
* **客户端包体积优化 (#540)**: 将 lib/client.js 体积从 217.3 KiB 缩减至 199 KiB 以下(距离 256 KiB DSH Store 门禁阈值预留超 57 KiB 安全冗余空间)。
|
|
140
|
+
|
|
141
|
+
### 🛡️ 弹性容灾、故障诊断与跨服务商回退 (v0.6.71)
|
|
136
142
|
* **跨服务商级联故障转移与优先级排序 (#536)**: 支持自定义跨服务商回退顺序,可在 WebUI 中通过 ▲/▼ 交互调整优先级。
|
|
137
143
|
* **一键链路测试与延迟检测 (#536)**: 在账户列表或状态弹窗中一键发起探活并显示往返延迟。
|
|
138
144
|
* **冷却倒计时与就绪通知 (#536)**: 实时展示受限账户恢复倒计时,解除冷却时自动弹出就绪通知。
|
package/lib/accounts-view.js
CHANGED
|
@@ -78,6 +78,10 @@ export async function createAccountsView({ live, store, fetch, pmL }) {
|
|
|
78
78
|
validationMessage: info.validationMessage || '',
|
|
79
79
|
accountNotice: info.accountNotice || '',
|
|
80
80
|
paidTierName: info.paidTierName || '',
|
|
81
|
+
lastPingMs: info.lastPingMs ?? null,
|
|
82
|
+
latencyGrade: info.latencyGrade ?? null,
|
|
83
|
+
lastDoctorVerdict: info.lastDoctorVerdict || null,
|
|
84
|
+
availableModels: info.availableModels || null,
|
|
81
85
|
})
|
|
82
86
|
}
|
|
83
87
|
return out
|
package/lib/accounts.js
CHANGED
|
@@ -118,6 +118,9 @@ export function createAccountStore({ credentials, getConfig, fetchImpl, fetchFor
|
|
|
118
118
|
const requestCounts = new Map()
|
|
119
119
|
const windows = new Map()
|
|
120
120
|
const usageFetched = new Map()
|
|
121
|
+
const pings = new Map()
|
|
122
|
+
const doctorVerdicts = new Map()
|
|
123
|
+
const dynamicModels = new Map()
|
|
121
124
|
const doFetch = fetchImpl || fetch
|
|
122
125
|
// #88: per-account proxy fetch for token refresh / usage (falls back to doFetch).
|
|
123
126
|
const rawFetchFor = (ref) => (typeof fetchForRef === 'function' && fetchForRef(ref)) || doFetch
|
|
@@ -246,6 +249,10 @@ export function createAccountStore({ credentials, getConfig, fetchImpl, fetchFor
|
|
|
246
249
|
validationMessage: base.validationMessage || '',
|
|
247
250
|
accountNotice: base.accountNotice || '',
|
|
248
251
|
paidTierName: base.paidTierName || '',
|
|
252
|
+
lastPingMs: pings.get(ref)?.latencyMs ?? null,
|
|
253
|
+
latencyGrade: pings.get(ref)?.latencyGrade ?? null,
|
|
254
|
+
lastDoctorVerdict: doctorVerdicts.get(ref) || null,
|
|
255
|
+
availableModels: dynamicModels.get(ref)?.models || null,
|
|
249
256
|
}
|
|
250
257
|
}
|
|
251
258
|
|
|
@@ -550,5 +557,11 @@ export function createAccountStore({ credentials, getConfig, fetchImpl, fetchFor
|
|
|
550
557
|
},
|
|
551
558
|
rememberRequest(ref) { requestCounts.set(ref, (requestCounts.get(ref) || 0) + 1) },
|
|
552
559
|
getRequestCount(ref) { return requestCounts.get(ref) || 0 },
|
|
560
|
+
rememberPing(ref, { latencyMs, latencyGrade }) { pings.set(ref, { latencyMs, latencyGrade, at: Date.now() }) },
|
|
561
|
+
getPing(ref) { return pings.get(ref) || null },
|
|
562
|
+
rememberDoctorVerdict(ref, verdict) { if (verdict) doctorVerdicts.set(ref, { ...verdict, at: Date.now() }); else doctorVerdicts.delete(ref); },
|
|
563
|
+
getDoctorVerdict(ref) { return doctorVerdicts.get(ref) || null },
|
|
564
|
+
rememberDynamicModels(ref, models) { if (Array.isArray(models)) dynamicModels.set(ref, { models, at: Date.now() }) },
|
|
565
|
+
getDynamicModels(ref) { return dynamicModels.get(ref)?.models || null },
|
|
553
566
|
}
|
|
554
567
|
}
|
package/lib/adapter-manager.js
CHANGED
|
@@ -45,6 +45,8 @@ export function createAdapterManager({
|
|
|
45
45
|
drainBeforeReset: () => live().drainBeforeReset,
|
|
46
46
|
drainSafetyPercent: () => live().drainSafetyPercent,
|
|
47
47
|
switchAtRemaining: () => live().switchAtRemaining,
|
|
48
|
+
rotationStrategy: () => live().rotationStrategy,
|
|
49
|
+
enableSoftFailureSentinel: () => live().enableSoftFailureSentinel,
|
|
48
50
|
rememberCooldown: (ref, until, families) => store.rememberCooldown(ref, until, families),
|
|
49
51
|
rememberQuarantine: (ref, reason, until, attempts) => store.rememberQuarantine(ref, reason, until, attempts),
|
|
50
52
|
getQuarantine: (ref) => store.getQuarantine(ref),
|
package/lib/adapter.js
CHANGED
|
@@ -142,6 +142,12 @@ export class SubscriptionAdapter extends LlmAdapter {
|
|
|
142
142
|
const effectiveDrainSafetyPercent = options.drainSafetyPercent !== undefined
|
|
143
143
|
? options.drainSafetyPercent
|
|
144
144
|
: (typeof deps.drainSafetyPercent === 'function' ? deps.drainSafetyPercent() : (deps.drainSafetyPercent ?? 5))
|
|
145
|
+
const effectiveRotationStrategy = options.rotationStrategy !== undefined
|
|
146
|
+
? options.rotationStrategy
|
|
147
|
+
: (typeof deps.rotationStrategy === 'function' ? deps.rotationStrategy() : (deps.rotationStrategy ?? 'round-robin'))
|
|
148
|
+
const effectiveSoftFailureSentinel = options.enableSoftFailureSentinel !== undefined
|
|
149
|
+
? options.enableSoftFailureSentinel
|
|
150
|
+
: (typeof deps.enableSoftFailureSentinel === 'function' ? deps.enableSoftFailureSentinel() : (deps.enableSoftFailureSentinel ?? true))
|
|
145
151
|
const sessionId = options.sessionId || options.session_id || options.conversationId
|
|
146
152
|
const effectiveReasoning = resolveEffectiveReasoning(sessionId, options)
|
|
147
153
|
const decisionTrace = {}
|
|
@@ -153,6 +159,8 @@ export class SubscriptionAdapter extends LlmAdapter {
|
|
|
153
159
|
autoPacing: effectiveAutoPacing,
|
|
154
160
|
drainBeforeReset: effectiveDrainBeforeReset,
|
|
155
161
|
drainSafetyPercent: effectiveDrainSafetyPercent,
|
|
162
|
+
rotationStrategy: effectiveRotationStrategy,
|
|
163
|
+
enableSoftFailureSentinel: effectiveSoftFailureSentinel,
|
|
156
164
|
}
|
|
157
165
|
for await (const event of streamWithRotation({
|
|
158
166
|
accounts: await deps.listAccounts(provider),
|