@omdp/dsh-key-fallback 1.0.0 → 1.0.1

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/cordis.patch.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  - insert:
2
2
  - id: key-fallback
3
- name: dsh-key-fallback
3
+ name: '@omdp/dsh-key-fallback'
4
4
  inject: [llm, settings, webServer]
5
5
  config: {}
package/lib/client.js CHANGED
@@ -1,65 +1,77 @@
1
- 'use strict'
2
1
  // @omdp/dsh-key-fallback — Client half
3
2
  // Settings → 插件 里的只读状态卡:显示每个 provider 的 key 数 / 游标 / 冷却。
4
- function apply(ctx) {
5
- const slots = ctx.get('slots')
6
- if (slots === undefined) return
3
+ //
4
+ // Hand-written in the lazy-CJS bundle protocol (window.__ModuleLoader__.load
5
+ // with a factory receiving `require`) — the same zero-dependency stance as the
6
+ // host half. The registered id MUST be the package name (@omdp/dsh-key-fallback):
7
+ // dsh-client-modules rejects any bundle whose __ModuleLoader__.load id does not
8
+ // match the package it was loaded for.
9
+ window.__ModuleLoader__.load({
10
+ id: '@omdp/dsh-key-fallback',
11
+ factory: function (require) {
12
+ var module = { exports: {} }
13
+ var exports = module.exports
14
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
15
+ var React = require('react')
7
16
 
8
- async function fetchJson(url, opts) {
9
- const r = await fetch(url, opts)
10
- return r.json()
11
- }
17
+ function fetchJson(url) {
18
+ return fetch(url).then(function (r) { return r.json() })
19
+ }
12
20
 
13
- function KeyFallbackCard() {
14
- const [state, setState] = React.useState({ loading: true, data: null })
15
- const refresh = React.useCallback(function () {
16
- fetchJson('/dsh-key-fallback/pools')
17
- .then(function (data) { setState({ loading: false, data: (data && data.pools) || {} }) })
18
- .catch(function () { setState({ loading: false, data: null }) })
19
- }, [])
20
- React.useEffect(function () {
21
- refresh()
22
- const t = setInterval(refresh, 2000)
23
- return function () { clearInterval(t) }
24
- }, [refresh])
21
+ function KeyFallbackCard() {
22
+ var s = React.useState({ loading: true, data: null })
23
+ var state = s[0]
24
+ var setState = s[1]
25
+ var refresh = React.useCallback(function () {
26
+ fetchJson('/dsh-key-fallback/pools')
27
+ .then(function (data) { setState({ loading: false, data: (data && data.pools) || {} }) })
28
+ .catch(function () { setState({ loading: false, data: null }) })
29
+ }, [])
30
+ React.useEffect(function () {
31
+ refresh()
32
+ var t = setInterval(refresh, 2000)
33
+ return function () { clearInterval(t) }
34
+ }, [refresh])
25
35
 
26
- if (state.loading) {
27
- return React.createElement('div', { style: { fontSize: '12px', opacity: 0.6 } }, '加载中…')
28
- }
29
- const data = state.data || {}
30
- const providers = Object.keys(data)
31
- if (providers.length === 0) {
32
- return React.createElement('p', { style: { fontSize: '12px', opacity: 0.6, margin: 0 } },
33
- '未在 settings.yaml 配置 keyFallback.providers')
36
+ if (state.loading) {
37
+ return React.createElement('div', { style: { fontSize: '12px', opacity: 0.6 } }, '加载中…')
38
+ }
39
+ var data = state.data || {}
40
+ var providers = Object.keys(data)
41
+ if (providers.length === 0) {
42
+ return React.createElement('p', { style: { fontSize: '12px', opacity: 0.6, margin: 0 } },
43
+ '未在 settings.yaml 配置 keyFallback.providers')
44
+ }
45
+ return React.createElement('div', { style: { fontSize: '12px', display: 'flex', flexDirection: 'column', gap: '8px' } },
46
+ providers.map(function (p) {
47
+ var pd = data[p]
48
+ return React.createElement('div', { key: p, style: { padding: '6px 0', borderTop: '1px solid var(--dsw-alias-border-l2, #eee)' } },
49
+ React.createElement('div', { style: { fontWeight: 600 } }, p + ' (' + pd.env + ')'),
50
+ React.createElement('div', { style: { opacity: 0.8 } }, 'key 数: ' + pd.keyCount + ',当前游标: ' + pd.currentIndex),
51
+ pd.cooling.length > 0
52
+ ? React.createElement('div', { style: { color: '#c62828' } }, '冷却中: ' + pd.cooling.join(', '))
53
+ : null,
54
+ pd.healthy.length > 0
55
+ ? React.createElement('div', { style: { color: '#2e7d32' } }, '健康: ' + pd.healthy.join(', '))
56
+ : null,
57
+ )
58
+ }),
59
+ )
34
60
  }
35
- return React.createElement('div', { style: { fontSize: '12px', display: 'flex', flexDirection: 'column', gap: '8px' } },
36
- providers.map(function (p) {
37
- const pd = data[p]
38
- return React.createElement('div', { key: p, style: { padding: '6px 0', borderTop: '1px solid var(--dsw-alias-border-l2, #eee)' } },
39
- React.createElement('div', { style: { fontWeight: 600 } }, p + ' (' + pd.env + ')'),
40
- React.createElement('div', { style: { opacity: 0.8 } }, 'key 数: ' + pd.keyCount + ',当前游标: ' + pd.currentIndex),
41
- pd.cooling.length > 0
42
- ? React.createElement('div', { style: { color: '#c62828' } }, '冷却中: ' + pd.cooling.join(', '))
43
- : null,
44
- pd.healthy.length > 0
45
- ? React.createElement('div', { style: { color: '#2e7d32' } }, '健康: ' + pd.healthy.join(', '))
46
- : null,
47
- )
48
- }),
49
- )
50
- }
51
61
 
52
- ctx.slots.inject('settings.plugin.item', function* () {
53
- yield ctx.slots.register({
54
- name: 'settings.plugin.item',
55
- key: 'key-fallback',
56
- id: 'key-fallback',
57
- order: 50,
58
- label: () => 'API Key 回退',
59
- inject: () => ({}),
60
- }, KeyFallbackCard)
61
- })
62
- }
62
+ function apply(ctx) {
63
+ var slots = ctx.get('slots')
64
+ if (slots === undefined) return
65
+ // settings.plugin.item 是 root-scope 的 keyed slot(注册只需 key);本卡是只读状态展示,
66
+ // 不需要 settingsScope 绑定可编辑配置。与 resume-stream 的 slots.inject 姿势一致。
67
+ slots.inject('settings.plugin.item', () => slots.register({
68
+ name: 'settings.plugin.item',
69
+ key: 'key-fallback',
70
+ }, KeyFallbackCard))
71
+ }
63
72
 
64
- exports.apply = apply
65
- exports.inject = ['slots']
73
+ exports.apply = apply
74
+ exports.inject = ['slots']
75
+ return module.exports
76
+ },
77
+ })
package/lib/index.js CHANGED
@@ -41,13 +41,6 @@ function readConfig() {
41
41
  }
42
42
 
43
43
  function apply(ctx) {
44
- // 占位命名空间:让只读状态卡出现在 Settings → 插件(keyed slot 要求 key ∈ served)
45
- ctx.inject(['settings'], (sctx) => {
46
- try {
47
- if (typeof zs !== 'undefined') sctx.settings.register('key-fallback', zs.object({}), { base: {} })
48
- } catch (e) { /* 命名空间注册失败不影响核心轮换逻辑 */ }
49
- })
50
-
51
44
  const pools = new Map()
52
45
  const attempts = new Map() // `${turn}:${step}` -> 已尝试次数(防止死循环)
53
46
  const lifetime = new AbortController()
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@omdp/dsh-key-fallback",
3
3
  "description": "Minimal API key fallback for DeepSeek Harness: on a retryable request error, silently retry the same call with the next key in the pool.",
4
- "version": "1.0.0",
4
+ "version": "1.0.1",
5
5
  "type": "commonjs",
6
6
  "main": "lib/index.js",
7
7
  "exports": {