dsh-context 0.2.3 → 0.3.0
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 +70 -28
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -199,6 +199,11 @@ function makeView(ctx, t) {
|
|
|
199
199
|
|
|
200
200
|
// Plot height in px (the marker lane above it is 18px).
|
|
201
201
|
var CHART_H = 112
|
|
202
|
+
// Fixed column geometry: constant bar width keeps sparse histories from
|
|
203
|
+
// stretching bars, and dense histories scroll horizontally instead of
|
|
204
|
+
// compressing. The turn tick row below mirrors the same column grid.
|
|
205
|
+
var BAR_W = 14
|
|
206
|
+
var BAR_GAP = 2
|
|
202
207
|
|
|
203
208
|
function TrendChart(props) {
|
|
204
209
|
var requests = props.requests
|
|
@@ -218,36 +223,67 @@ function makeView(ctx, t) {
|
|
|
218
223
|
}
|
|
219
224
|
}
|
|
220
225
|
|
|
226
|
+
// Consecutive requests of the same turn collapse into one labeled range.
|
|
227
|
+
var groups = []
|
|
228
|
+
for (var g = 0; g < requests.length; g++) {
|
|
229
|
+
var grp = groups.length > 0 ? groups[groups.length - 1] : null
|
|
230
|
+
if (grp === null || grp.turn !== requests[g].turn) {
|
|
231
|
+
grp = { turn: requests[g].turn, count: 0 }
|
|
232
|
+
groups.push(grp)
|
|
233
|
+
}
|
|
234
|
+
grp.count++
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Stick to the newest bars unless the user scrolled away from the end.
|
|
238
|
+
var scrollRef = React.useRef(null)
|
|
239
|
+
React.useEffect(function () {
|
|
240
|
+
var el = scrollRef.current
|
|
241
|
+
if (el === null) return
|
|
242
|
+
if (el.scrollLeft + el.clientWidth >= el.scrollWidth - 24) el.scrollLeft = el.scrollWidth
|
|
243
|
+
})
|
|
244
|
+
|
|
221
245
|
return h('div', { className: 'lc-chartrow' },
|
|
222
246
|
h('div', { className: 'lc-axis' },
|
|
223
247
|
h('span', { className: 'lc-axis-top' }, fmt(maxTotal)),
|
|
224
248
|
h('span', { className: 'lc-axis-mid' }, fmt(Math.round(maxTotal / 2))),
|
|
225
249
|
h('span', { className: 'lc-axis-bot' }, '0')),
|
|
226
|
-
h('div', { className: 'lc-chart' },
|
|
227
|
-
h('div', { className: 'lc-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
250
|
+
h('div', { className: 'lc-chart-scroll', ref: scrollRef },
|
|
251
|
+
h('div', { className: 'lc-chart' },
|
|
252
|
+
h('div', { className: 'lc-grid lc-grid-top' }),
|
|
253
|
+
h('div', { className: 'lc-grid lc-grid-mid' }),
|
|
254
|
+
requests.map(function (req, i) {
|
|
255
|
+
var selected = props.selectedSeq === req.seq
|
|
256
|
+
var tip = tr('tip.step', { t: req.turn, s: req.step }) + ' · ' + fmtTime(req.time) + '\n'
|
|
257
|
+
+ tr('tip.total', { n: fmt(req.total) })
|
|
258
|
+
+ (req.prompt !== undefined ? tr('tip.actual', { n: fmt(req.prompt) }) : '') + '\n'
|
|
259
|
+
+ CATS.map(function (c) { return catLabel(c.key) + ' ' + fmt(req[c.key] || 0) }).join(' / ')
|
|
260
|
+
return h('div', {
|
|
261
|
+
key: req.seq,
|
|
262
|
+
className: 'lc-bar' + (selected ? ' lc-bar-selected' : ''),
|
|
263
|
+
title: tip,
|
|
264
|
+
onClick: function () { props.onSelect(selected ? null : req.seq) },
|
|
265
|
+
},
|
|
266
|
+
markers[i] ? h('span', { className: 'lc-bar-marker', title: eventLabel(markers[i]) }, '✂') : null,
|
|
267
|
+
h('div', { className: 'lc-bar-stack' },
|
|
268
|
+
CATS.map(function (c) {
|
|
269
|
+
var v = req[c.key] || 0
|
|
270
|
+
if (!v) return null
|
|
271
|
+
// px heights: the stack's height is content-driven, so
|
|
272
|
+
// percentage heights would collapse against an indefinite base.
|
|
273
|
+
return h('div', { key: c.key, style: { height: Math.max(1, Math.round(v / maxTotal * CHART_H)) + 'px', background: c.color } })
|
|
274
|
+
})))
|
|
275
|
+
})),
|
|
276
|
+
h('div', { className: 'lc-turns' },
|
|
277
|
+
groups.map(function (grp, gi) {
|
|
278
|
+
// One column per bar plus the shared gap; the flex gap between
|
|
279
|
+
// ticks restores the inter-group gap, so tick spans line up with
|
|
280
|
+
// their bars exactly.
|
|
281
|
+
return h('span', {
|
|
282
|
+
key: 'turn-' + gi,
|
|
283
|
+
className: 'lc-turn',
|
|
284
|
+
style: { width: (grp.count * (BAR_W + BAR_GAP) - BAR_GAP) + 'px' },
|
|
285
|
+
}, 'T' + grp.turn)
|
|
286
|
+
}))))
|
|
251
287
|
}
|
|
252
288
|
|
|
253
289
|
function RequestDetail(props) {
|
|
@@ -433,21 +469,27 @@ var STYLES = [
|
|
|
433
469
|
'.lc-tools { margin-top: 10px; color: var(--dsw-alias-label-secondary); display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }',
|
|
434
470
|
'.lc-tool-chip { background: var(--dsw-alias-bg-layer-2); border-radius: 4px; padding: 1px 7px; font-size: 12px; color: var(--dsw-alias-label-primary); }',
|
|
435
471
|
'.lc-chartrow { display: flex; gap: 6px; align-items: stretch; }',
|
|
436
|
-
'.lc-axis { position: relative; width: 40px; height:
|
|
472
|
+
'.lc-axis { position: relative; width: 40px; height: 150px; padding-top: 18px; box-sizing: border-box; color: var(--dsw-alias-label-secondary); font-size: 11px; }',
|
|
437
473
|
'.lc-axis span { position: absolute; right: 0; line-height: 1; }',
|
|
438
474
|
'.lc-axis-top { top: 13px; }',
|
|
439
475
|
'.lc-axis-mid { top: 69px; }',
|
|
440
476
|
'.lc-axis-bot { top: 125px; }',
|
|
441
|
-
'.lc-chart {
|
|
477
|
+
'.lc-chart-scroll { flex: 1; overflow-x: auto; overflow-y: hidden; min-width: 0; scrollbar-width: thin; }',
|
|
478
|
+
'.lc-chart-scroll::-webkit-scrollbar { height: 6px; }',
|
|
479
|
+
'.lc-chart-scroll::-webkit-scrollbar-thumb { background: var(--dsw-alias-border-l1); border-radius: 3px; }',
|
|
480
|
+
'.lc-chart-scroll::-webkit-scrollbar-track { background: transparent; }',
|
|
481
|
+
'.lc-chart { position: relative; display: flex; align-items: flex-end; gap: 2px; height: 130px; padding-top: 18px; box-sizing: border-box; width: max-content; min-width: 100%; }',
|
|
442
482
|
'.lc-grid { position: absolute; left: 0; right: 0; border-top: 1px dashed var(--dsw-alias-border-l1); pointer-events: none; }',
|
|
443
483
|
'.lc-grid-top { top: 18px; }',
|
|
444
484
|
'.lc-grid-mid { top: 74px; }',
|
|
445
|
-
'.lc-bar { position: relative;
|
|
485
|
+
'.lc-bar { position: relative; width: 14px; flex: none; height: 100%; display: flex; align-items: flex-end; cursor: pointer; border-radius: 2px; }',
|
|
446
486
|
'.lc-bar:hover { background: var(--dsw-alias-bg-layer-2); }',
|
|
447
487
|
'.lc-bar-selected { outline: 2px solid var(--dsw-alias-brand-primary); outline-offset: 1px; }',
|
|
448
488
|
'.lc-bar-stack { display: flex; flex-direction: column-reverse; width: 100%; }',
|
|
449
489
|
'.lc-bar-stack > div { width: 100%; }',
|
|
450
490
|
'.lc-bar-marker { position: absolute; top: -16px; left: 50%; transform: translateX(-50%); font-size: 11px; color: var(--dsw-alias-state-warn-primary); }',
|
|
491
|
+
'.lc-turns { display: flex; gap: 2px; width: max-content; min-width: 100%; }',
|
|
492
|
+
'.lc-turn { flex: none; min-width: 24px; box-sizing: border-box; text-align: center; font-size: 11px; line-height: 18px; color: var(--dsw-alias-label-secondary); border-top: 1px solid var(--dsw-alias-border-l1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }',
|
|
451
493
|
'.lc-detail { margin-top: 12px; border-top: 1px solid var(--dsw-alias-border-l1); padding-top: 12px; }',
|
|
452
494
|
'.lc-detail-head { display: flex; flex-wrap: wrap; gap: 6px 16px; margin-bottom: 8px; color: var(--dsw-alias-label-secondary); }',
|
|
453
495
|
'.lc-detail-head b { color: var(--dsw-alias-label-primary); }',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-context",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Context insight panel for DeepSeek Harness: a Context tab (beside Chat/Trajectory) showing what the model's context window is made of and how it evolves — composition, per-request history, compactions, injections, and model switches.",
|
|
5
5
|
"author": "bowenliang123",
|
|
6
6
|
"repository": {
|