dsh-link-pulse 0.1.0 → 0.1.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/CHANGELOG.md +9 -1
- package/package.json +1 -1
- package/src/client.js +110 -17
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.1.1] - 2026-08-25
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- 主动清理模型选择器文本中夹带的「default / 推理等级 / 模型」等 UI 标签残留,让长模型 ID(如 `opencode minimax-m3`)能正确识别为单个 token。
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
- 恢复并改写侧边栏条目 hover 悬浮预览:220ms 悬停延迟后在按钮上方弹出小卡片,展示当前模型 / 供应商 / 实时延迟以及全部 Provider 链路测速对比。
|
|
10
|
+
|
|
3
11
|
## [0.1.0] - 2026-08-25
|
|
4
12
|
|
|
5
13
|
### Added
|
|
6
14
|
- 初始版本发布:支持从 `settings.yaml` 动态读取 Providers。
|
|
7
15
|
- 侧边栏常驻条目与当前会话模型动态感知。
|
|
8
16
|
- 多通道实时测速浮层看板。
|
|
9
|
-
- 遵循 Cordis@4 扁平依赖注入规范。
|
|
17
|
+
- 遵循 Cordis@4 扁平依赖注入规范。
|
package/package.json
CHANGED
package/src/client.js
CHANGED
|
@@ -107,8 +107,13 @@ window.__ModuleLoader__.load({
|
|
|
107
107
|
'[data-slot="conversation.input.model"], button[class*="modelSelect"], div[class*="modelSelector"]',
|
|
108
108
|
)
|
|
109
109
|
if (modelButton && modelButton.textContent) {
|
|
110
|
-
|
|
111
|
-
|
|
110
|
+
let text = modelButton.textContent.trim()
|
|
111
|
+
// 剥离开关/标签 UI 残留,如「default」「推理等级」「high」等
|
|
112
|
+
text = text
|
|
113
|
+
.split(/[\n|·•]/)[0]
|
|
114
|
+
.replace(/\s*(default|推理等级|模型|model)\s*/gi, '')
|
|
115
|
+
.trim()
|
|
116
|
+
if (text && text.length < 30 && /[a-zA-Z0-9\-_.]/.test(text)) {
|
|
112
117
|
setActiveModel(text)
|
|
113
118
|
return
|
|
114
119
|
}
|
|
@@ -128,8 +133,10 @@ window.__ModuleLoader__.load({
|
|
|
128
133
|
function FooterEntry(props) {
|
|
129
134
|
const { wide } = props
|
|
130
135
|
const [isOpen, setIsOpen] = useState(overlayOpen)
|
|
136
|
+
const [hovering, setHovering] = useState(false)
|
|
131
137
|
const [data, setData] = useState(null)
|
|
132
138
|
const [loading, setLoading] = useState(false)
|
|
139
|
+
const hoverTimerRef = React.useRef(null)
|
|
133
140
|
|
|
134
141
|
useEffect(() => {
|
|
135
142
|
listeners.add(setIsOpen)
|
|
@@ -171,26 +178,22 @@ window.__ModuleLoader__.load({
|
|
|
171
178
|
const providerDisplayName = activeProviderInfo?.name || 'CPA'
|
|
172
179
|
const modelShortName = formatModelShortName(activeModel)
|
|
173
180
|
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
const lat = p.probe?.latencyMs > 0 ? `${p.probe.latencyMs}ms` : '离线'
|
|
183
|
-
lines.push(`• ${p.name}: ${lat}`)
|
|
184
|
-
}
|
|
185
|
-
return lines.join('\n')
|
|
186
|
-
}, [data, activeModel, providerDisplayName, currentLatency])
|
|
181
|
+
const onMouseEnter = useCallback(() => {
|
|
182
|
+
clearTimeout(hoverTimerRef.current)
|
|
183
|
+
hoverTimerRef.current = setTimeout(() => setHovering(true), 220)
|
|
184
|
+
}, [])
|
|
185
|
+
const onMouseLeave = useCallback(() => {
|
|
186
|
+
clearTimeout(hoverTimerRef.current)
|
|
187
|
+
setHovering(false)
|
|
188
|
+
}, [])
|
|
187
189
|
|
|
188
|
-
|
|
190
|
+
const node = h(
|
|
189
191
|
'button',
|
|
190
192
|
{
|
|
191
193
|
className: 'pulse-btn',
|
|
192
194
|
onClick: () => setOverlay(!isOpen),
|
|
193
|
-
|
|
195
|
+
onMouseEnter: onMouseEnter,
|
|
196
|
+
onMouseLeave: onMouseLeave,
|
|
194
197
|
style: {
|
|
195
198
|
...btnBase,
|
|
196
199
|
width: '100%',
|
|
@@ -246,6 +249,96 @@ window.__ModuleLoader__.load({
|
|
|
246
249
|
),
|
|
247
250
|
),
|
|
248
251
|
)
|
|
252
|
+
|
|
253
|
+
if (!hovering || isOpen) return node
|
|
254
|
+
|
|
255
|
+
const providers = data?.providers || []
|
|
256
|
+
return h(
|
|
257
|
+
'div',
|
|
258
|
+
{
|
|
259
|
+
style: { position: 'relative', width: '100%' },
|
|
260
|
+
onMouseEnter: onMouseEnter,
|
|
261
|
+
onMouseLeave: onMouseLeave,
|
|
262
|
+
},
|
|
263
|
+
node,
|
|
264
|
+
h(
|
|
265
|
+
'div',
|
|
266
|
+
{
|
|
267
|
+
className: 'pulse-panel-enter',
|
|
268
|
+
style: {
|
|
269
|
+
position: 'absolute',
|
|
270
|
+
left: 0,
|
|
271
|
+
right: 0,
|
|
272
|
+
bottom: 'calc(100% + 6px)',
|
|
273
|
+
background: T.bg,
|
|
274
|
+
border: `1px solid ${T.border2}`,
|
|
275
|
+
borderRadius: '10px',
|
|
276
|
+
boxShadow: '0 8px 24px rgba(0,0,0,.18)',
|
|
277
|
+
padding: '10px 12px',
|
|
278
|
+
fontSize: '11px',
|
|
279
|
+
lineHeight: '17px',
|
|
280
|
+
color: T.label,
|
|
281
|
+
whiteSpace: 'pre',
|
|
282
|
+
z: 100,
|
|
283
|
+
fontFamily: 'system-ui, -apple-system, sans-serif',
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
h('div', { style: { fontWeight: 600, fontSize: '12px', marginBottom: 4 } }, `🎯 ${activeModel}`),
|
|
287
|
+
h('div', { style: { color: T.secondary } }, `🏢 ${providerDisplayName}`),
|
|
288
|
+
h(
|
|
289
|
+
'div',
|
|
290
|
+
{
|
|
291
|
+
style: {
|
|
292
|
+
color: statusColor,
|
|
293
|
+
fontWeight: 600,
|
|
294
|
+
marginTop: 2,
|
|
295
|
+
marginBottom: 6,
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
`⚡ ${currentLatency > 0 ? currentLatency + ' ms' : '检测中'}`,
|
|
299
|
+
),
|
|
300
|
+
h(
|
|
301
|
+
'div',
|
|
302
|
+
{
|
|
303
|
+
style: {
|
|
304
|
+
borderTop: `1px dashed ${T.border}`,
|
|
305
|
+
paddingTop: 6,
|
|
306
|
+
color: T.secondary,
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
'🌐 Provider 链路一览',
|
|
310
|
+
),
|
|
311
|
+
providers.map((p, i) =>
|
|
312
|
+
h(
|
|
313
|
+
'div',
|
|
314
|
+
{
|
|
315
|
+
key: i,
|
|
316
|
+
style: {
|
|
317
|
+
display: 'flex',
|
|
318
|
+
justifyContent: 'space-between',
|
|
319
|
+
gap: 12,
|
|
320
|
+
},
|
|
321
|
+
},
|
|
322
|
+
h(
|
|
323
|
+
'span',
|
|
324
|
+
{ style: { display: 'flex', alignItems: 'center', gap: 4 } },
|
|
325
|
+
h('span', { style: { ...dotStyle(getQualityColor(p.probe?.quality, p.probe?.latencyMs)), width: 5, height: 5 } }),
|
|
326
|
+
p.name,
|
|
327
|
+
),
|
|
328
|
+
h(
|
|
329
|
+
'span',
|
|
330
|
+
{
|
|
331
|
+
style: {
|
|
332
|
+
color: getQualityColor(p.probe?.quality, p.probe?.latencyMs),
|
|
333
|
+
fontWeight: 600,
|
|
334
|
+
},
|
|
335
|
+
},
|
|
336
|
+
p.probe?.latencyMs > 0 ? `${p.probe.latencyMs} ms` : '离线',
|
|
337
|
+
),
|
|
338
|
+
),
|
|
339
|
+
),
|
|
340
|
+
),
|
|
341
|
+
)
|
|
249
342
|
}
|
|
250
343
|
|
|
251
344
|
function OverlayPanel() {
|