dsh-plugin-litellm-bridge 2.0.3 → 2.0.5
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.
|
@@ -279,7 +279,7 @@ window.__ModuleLoader__.load({
|
|
|
279
279
|
},
|
|
280
280
|
}),
|
|
281
281
|
h('span', { style: { fontWeight: 600 } }, 'LiteLLM 网关'),
|
|
282
|
-
h('span', { style: S.badge(tone === 'ok' ? T.success : tone === 'error' ? T.error : T.warn) }, label),
|
|
282
|
+
h('span', { style: S.badge(tone === 'ok' ? T.success : tone === 'error' ? T.error : T.warn) }, safeText(label)),
|
|
283
283
|
st?.owned && h('span', { style: S.badge(T.brand, tint(T.brand, 14)) }, '本插件托管'),
|
|
284
284
|
!st?.owned && st?.alive && h('span', { style: S.badge() }, '外部运行 · 不接管'),
|
|
285
285
|
h('span', { style: { marginLeft: 'auto', display: 'flex', gap: 6 } },
|
|
@@ -290,11 +290,18 @@ window.__ModuleLoader__.load({
|
|
|
290
290
|
),
|
|
291
291
|
),
|
|
292
292
|
h('div', { style: { padding: '0 12px 10px', ...S.mono, fontSize: 11, color: T.labelSecondary, lineHeight: 1.7 } },
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
293
|
+
// 【必须 safeText】这些值来自宿主 RPC,可能是对象 / undefined / Error。
|
|
294
|
+
// 直接插进子节点会触发 React #62(Objects are not valid as a React child),
|
|
295
|
+
// 整个设置页白屏 —— 实测「点测试连通性后白屏」就是这个原因之一。
|
|
296
|
+
h('div', null, `地址:${safeText(st?.url, '—')}`),
|
|
297
|
+
h('div', null,
|
|
298
|
+
`托管策略:${safeText(st?.ownership, '—')}` +
|
|
299
|
+
(st?.autoStart === false ? '(autoStartGateway 已关闭)' : '')),
|
|
300
|
+
st?.lastError && h('div', { style: { color: T.error } },
|
|
301
|
+
`最近错误:${safeText(st.lastError)}`),
|
|
296
302
|
!st?.lastError && st?.lastExit?.abnormal &&
|
|
297
|
-
h('div', { style: { color: T.error } },
|
|
303
|
+
h('div', { style: { color: T.error } },
|
|
304
|
+
`异常退出记录:code=${safeText(st.lastExit.code, '?')}`),
|
|
298
305
|
),
|
|
299
306
|
);
|
|
300
307
|
}
|
|
@@ -338,7 +345,7 @@ window.__ModuleLoader__.load({
|
|
|
338
345
|
h('select', {
|
|
339
346
|
style: { ...S.inputAuto, minWidth: 110 },
|
|
340
347
|
value: pid, onChange: (e) => setPid(e.target.value),
|
|
341
|
-
}, ...(profileIds || []).map((p) => h('option', { key: p, value: p }, p))),
|
|
348
|
+
}, ...(profileIds || []).map((p) => h('option', { key: p, value: p }, safeText(p)))),
|
|
342
349
|
h('select', {
|
|
343
350
|
style: { ...S.inputAuto, minWidth: 110 },
|
|
344
351
|
value: agentType, onChange: (e) => setAgentType(e.target.value),
|
|
@@ -373,7 +380,7 @@ window.__ModuleLoader__.load({
|
|
|
373
380
|
},
|
|
374
381
|
h('span', { style: S.badge() }, String(i + 1)),
|
|
375
382
|
i === 0 && h('span', { style: S.badge(T.brand, tint(T.brand, 14)) }, '首选'),
|
|
376
|
-
h('span', { style: { ...S.mono, flex: 1, wordBreak: 'break-all' } }, m),
|
|
383
|
+
h('span', { style: { ...S.mono, flex: 1, wordBreak: 'break-all' } }, safeText(m)),
|
|
377
384
|
row && h('span', { style: { ...S.mono, fontSize: 11, color: row.ok ? T.success : T.error } },
|
|
378
385
|
row.ok ? '✓' : '✗'),
|
|
379
386
|
row && row.latencyMs != null && h('span', {
|
|
@@ -386,7 +393,7 @@ window.__ModuleLoader__.load({
|
|
|
386
393
|
}),
|
|
387
394
|
),
|
|
388
395
|
|
|
389
|
-
err && h('div', { style: S.notice('error') }, err),
|
|
396
|
+
err && h('div', { style: S.notice('error') }, safeText(err)),
|
|
390
397
|
|
|
391
398
|
result && h('div', null,
|
|
392
399
|
h('div', { style: { ...S.row, marginBottom: 8 } },
|
|
@@ -457,10 +464,18 @@ window.__ModuleLoader__.load({
|
|
|
457
464
|
|
|
458
465
|
test && h('div', { style: S.card },
|
|
459
466
|
h('div', { style: { marginBottom: 8, fontWeight: 600 } },
|
|
467
|
+
// 【血案】这里原来写的是 { style: S.ok } / { style: S.err }。
|
|
468
|
+
// S.ok / S.err 是**颜色字符串**('var(--dsw-alias-...)'),
|
|
469
|
+
// 是给 color: 用的,不是样式对象。
|
|
470
|
+
// React 对 style 收字符串直接抛 Minified React error #62:
|
|
471
|
+
// "The style prop expects a mapping from style properties to
|
|
472
|
+
// values, not a string."
|
|
473
|
+
// 表现:点「测试连通性」→ 整个设置页白屏。
|
|
474
|
+
// 正确写法是 { style: { color: S.ok } }。
|
|
460
475
|
test.ok
|
|
461
|
-
? h('span', { style: S.ok },
|
|
476
|
+
? h('span', { style: { color: S.ok } },
|
|
462
477
|
`✓ 连通正常(${num(test.passed)}/${num(test.total)})`)
|
|
463
|
-
: h('span', { style: S.err },
|
|
478
|
+
: h('span', { style: { color: S.err } },
|
|
464
479
|
`✗ 连通异常(${num(test.passed)}/${num(test.total)})`),
|
|
465
480
|
),
|
|
466
481
|
// 【防御】steps 里任何字段都可能是非字符串(对象/undefined/错误实例)。
|
|
@@ -740,7 +755,7 @@ window.__ModuleLoader__.load({
|
|
|
740
755
|
|
|
741
756
|
return h('div', { key: at },
|
|
742
757
|
h('div', { style: S.h2Row },
|
|
743
|
-
h('h2', { style: S.h2 }, groupLabel),
|
|
758
|
+
h('h2', { style: S.h2 }, safeText(groupLabel)),
|
|
744
759
|
isSub && h('span', { style: S.badge() }, '仅子 Agent 使用'),
|
|
745
760
|
h('span', { style: { ...S.mono, fontSize: 11, color: T.labelSecondary } },
|
|
746
761
|
chainLen ? `链长 ${chainLen}` : '未配置'),
|
|
@@ -931,11 +946,11 @@ window.__ModuleLoader__.load({
|
|
|
931
946
|
h('div', { style: { ...S.row, marginBottom: 10 } },
|
|
932
947
|
h('select', { style: { ...S.input, width: 'auto' }, value: fAgent, onChange: (e) => setFAgent(e.target.value) },
|
|
933
948
|
h('option', { value: '' }, '全部 agent-type'),
|
|
934
|
-
agents.map((a) => h('option', { key: a, value: a }, a)),
|
|
949
|
+
agents.map((a) => h('option', { key: a, value: a }, safeText(a))),
|
|
935
950
|
),
|
|
936
951
|
h('select', { style: { ...S.input, width: 'auto' }, value: fProfile, onChange: (e) => setFProfile(e.target.value) },
|
|
937
952
|
h('option', { value: '' }, '全部 profile'),
|
|
938
|
-
profiles.map((p) => h('option', { key: p, value: p }, p)),
|
|
953
|
+
profiles.map((p) => h('option', { key: p, value: p }, safeText(p))),
|
|
939
954
|
),
|
|
940
955
|
h('span', { style: { marginLeft: 'auto', ...S.mono, fontSize: 11, color: T.labelSecondary } },
|
|
941
956
|
`显示 ${shown.length} / 最多 ${limit} 条`),
|
|
@@ -964,9 +979,9 @@ window.__ModuleLoader__.load({
|
|
|
964
979
|
l.time ? String(l.time).replace('T', ' ').slice(0, 19) : '—'),
|
|
965
980
|
isGwEvent
|
|
966
981
|
? h('span', { style: S.badge(T.brand, tint(T.brand, 14)) }, 'gateway')
|
|
967
|
-
: h('span', { style: S.badge() }, l.agentType),
|
|
968
|
-
!isGwEvent && h('span', { style: S.badge() }, l.profile),
|
|
969
|
-
h('span', { style: { ...S.mono, fontWeight: 600 } }, l.model),
|
|
982
|
+
: h('span', { style: S.badge() }, safeText(l.agentType, '-')),
|
|
983
|
+
!isGwEvent && h('span', { style: S.badge() }, safeText(l.profile, '-')),
|
|
984
|
+
h('span', { style: { ...S.mono, fontWeight: 600 } }, safeText(l.model)),
|
|
970
985
|
l.source === 'local' && !isGwEvent && h('span', { style: S.badge(T.brand, tint(T.brand, 14)) }, 'local'),
|
|
971
986
|
k === 'fallback' && h('span', { style: S.badge(T.warn, tint(T.warn, 14)) }, 'FALLBACK'),
|
|
972
987
|
k === 'failed' && h('span', { style: S.badge(T.error, tint(T.error, 14)) }, '失败'),
|
|
@@ -1054,7 +1069,7 @@ window.__ModuleLoader__.load({
|
|
|
1054
1069
|
style: S.input, value: profile, onChange: (e) => setProfile(e.target.value),
|
|
1055
1070
|
},
|
|
1056
1071
|
h('option', { value: '' }, '(不绑定)'),
|
|
1057
|
-
profileIds.map((p) => h('option', { key: p, value: p }, p)),
|
|
1072
|
+
profileIds.map((p) => h('option', { key: p, value: p }, safeText(p))),
|
|
1058
1073
|
),
|
|
1059
1074
|
h('div', { style: S.hint },
|
|
1060
1075
|
'绑定后:本会话的 root 请求按该 profile 的 root 链走;spawn 的子 Agent 按同 profile 的 coder/research 链走。'),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin-litellm-bridge",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.5",
|
|
4
4
|
"description": "LiteLLM gateway bridge for DSH: assemble root / coder / research fallback chains from the DSH model pool and hand the order to a LiteLLM gateway that executes retries and fallbacks. The plugin performs no routing itself.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dsh",
|