dsh-context 0.13.0 → 0.15.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/README.md +1 -1
- package/lib/client.js +168 -106
- package/lib/index.js +1 -8
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+

|
|
2
2
|
|
|
3
3
|
# dsh-context
|
|
4
4
|
|
package/lib/client.js
CHANGED
|
@@ -9,17 +9,16 @@ window.__ModuleLoader__.load({
|
|
|
9
9
|
// src/client/i18n.ts
|
|
10
10
|
var DICT_ZH = {
|
|
11
11
|
"tab": "\u4E0A\u4E0B\u6587",
|
|
12
|
-
"cat.system": "\u7CFB\u7EDF\u63D0\u793A",
|
|
12
|
+
"cat.system": "\u7CFB\u7EDF\u63D0\u793A\u8BCD",
|
|
13
13
|
"cat.tools": "\u5DE5\u5177\u5B9A\u4E49",
|
|
14
14
|
"cat.user": "\u7528\u6237\u6D88\u606F",
|
|
15
|
-
"cat.inject": "\u6CE8\u5165\
|
|
16
|
-
"cat.assistant": "\u52A9\u624B\
|
|
15
|
+
"cat.inject": "\u6CE8\u5165\u5185\u5BB9",
|
|
16
|
+
"cat.assistant": "\u52A9\u624B\u6D88\u606F",
|
|
17
17
|
"cat.tool": "\u5DE5\u5177\u7ED3\u679C",
|
|
18
18
|
"overview.title": "\u5F53\u524D\u6784\u6210",
|
|
19
|
-
"overview.ofWindow": "tokens\uFF08\u7EA6 {p}%\uFF09",
|
|
20
19
|
"overview.estimate": "tokens\uFF08\u4F30\u7B97\uFF09",
|
|
21
20
|
"overview.free": "\u5269\u4F59\u7A97\u53E3",
|
|
22
|
-
"overview.
|
|
21
|
+
"overview.used": "\u4E0A\u4E0B\u6587\u5DF2\u7528",
|
|
23
22
|
"overview.ofUsed": "\u5360\u5DF2\u7528\u4E0A\u4E0B\u6587",
|
|
24
23
|
"stats.title": "\u4E0A\u4E0B\u6587\u7EDF\u8BA1",
|
|
25
24
|
"stats.hint": "\u7EDF\u8BA1\u5F53\u524D\u4FDD\u7559\u7684\u5386\u53F2\u7A97\u53E3\uFF08\u4E0E\u8D8B\u52BF\u56FE\u4E00\u81F4\uFF09",
|
|
@@ -90,50 +89,49 @@ var DICT_ZH = {
|
|
|
90
89
|
"browser.missingLive": "\u2026 \u53E6\u6709 {n} \u6761\u66F4\u65E9\u7684\u6D88\u606F\u4E5F\u5728\u4E0A\u4E0B\u6587\u4E2D\uFF08\u8D85\u51FA\u5C55\u793A\u7A97\u53E3\uFF09",
|
|
91
90
|
"browser.approx": "\u8BE5\u6B65\u9AA4\u6D89\u53CA\u7684\u90E8\u5206\u5DF2\u79FB\u9664\u6D88\u606F\u8D85\u51FA\u4FDD\u7559\u8303\u56F4\uFF0C\u4EE5\u4E0B\u4E3A\u8FD1\u4F3C\u6784\u6210",
|
|
92
91
|
"browser.noHeader": "\u6B64\u6570\u636E\u6765\u81EA\u65E7\u7248\u63D2\u4EF6\uFF1A\u4EC5\u63D0\u4F9B token \u4F30\u7B97\uFF0C\u65E0\u5B9E\u9645\u5185\u5BB9",
|
|
93
|
-
"browser.noEpoch": "\u8BE5\u6B65\u9AA4\u7684\u5934\u90E8\u5185\u5BB9\uFF08\u7CFB\u7EDF\u63D0\u793A / \u5DE5\u5177\u5B9A\u4E49\uFF09\u4E0D\u5728\u4FDD\u7559\u8303\u56F4\u5185",
|
|
92
|
+
"browser.noEpoch": "\u8BE5\u6B65\u9AA4\u7684\u5934\u90E8\u5185\u5BB9\uFF08\u7CFB\u7EDF\u63D0\u793A\u8BCD / \u5DE5\u5177\u5B9A\u4E49\uFF09\u4E0D\u5728\u4FDD\u7559\u8303\u56F4\u5185",
|
|
94
93
|
"browser.noContent": "\u5B8C\u6574\u5185\u5BB9\u4E0D\u5728\u5F53\u524D\u52A0\u8F7D\u7684\u6D88\u606F\u7A97\u53E3\u5185\uFF08\u5728\u804A\u5929\u9875\u52A0\u8F7D\u66F4\u65E9\u5386\u53F2\u540E\u53EF\u67E5\u770B\uFF09",
|
|
95
94
|
"browser.loading": "\u6B63\u5728\u4ECE\u66F4\u65E9\u7684\u4F1A\u8BDD\u5386\u53F2\u52A0\u8F7D\u5B8C\u6574\u5185\u5BB9\u2026",
|
|
96
95
|
"browser.preview": "\u9884\u89C8"
|
|
97
96
|
};
|
|
98
97
|
var DICT_EN = {
|
|
99
98
|
"tab": "Context",
|
|
100
|
-
"cat.system": "System",
|
|
101
|
-
"cat.tools": "Tool
|
|
102
|
-
"cat.user": "User",
|
|
103
|
-
"cat.inject": "Injected",
|
|
104
|
-
"cat.assistant": "Assistant",
|
|
105
|
-
"cat.tool": "Tool
|
|
106
|
-
"overview.title": "Current
|
|
107
|
-
"overview.ofWindow": "tokens (~{p}%)",
|
|
99
|
+
"cat.system": "System Prompt",
|
|
100
|
+
"cat.tools": "Tool Schemas",
|
|
101
|
+
"cat.user": "User Messages",
|
|
102
|
+
"cat.inject": "Injected Context",
|
|
103
|
+
"cat.assistant": "Assistant Messages",
|
|
104
|
+
"cat.tool": "Tool Results",
|
|
105
|
+
"overview.title": "Current Context",
|
|
108
106
|
"overview.estimate": "tokens (estimated)",
|
|
109
|
-
"overview.free": "Free
|
|
110
|
-
"overview.
|
|
107
|
+
"overview.free": "Free Window",
|
|
108
|
+
"overview.used": "of context used",
|
|
111
109
|
"overview.ofUsed": "of used context",
|
|
112
|
-
"stats.title": "Context
|
|
110
|
+
"stats.title": "Context Stats",
|
|
113
111
|
"stats.hint": "Over the retained history window (same as the History chart)",
|
|
114
112
|
"stats.turns": "Turns",
|
|
115
113
|
"stats.steps": "Steps",
|
|
116
114
|
"stats.injects": "Injections",
|
|
117
115
|
"stats.compactions": "Compactions",
|
|
118
116
|
"stats.prunes": "Prunes",
|
|
119
|
-
"plugin.title": "Plugin
|
|
117
|
+
"plugin.title": "Plugin Info",
|
|
120
118
|
"plugin.hint": "The best DSH context plugin \u2B50",
|
|
121
119
|
"plugin.name": "Plugin",
|
|
122
120
|
"plugin.github": "GitHub",
|
|
123
|
-
"tools.top": "Top
|
|
121
|
+
"tools.top": "Top Tool Schemas:",
|
|
124
122
|
"tools.more": "of {n}",
|
|
125
|
-
"trend.title": "History",
|
|
123
|
+
"trend.title": "Context History",
|
|
126
124
|
"gran.step": "Step",
|
|
127
125
|
"gran.turn": "Turn",
|
|
128
|
-
"trend.hint": "
|
|
126
|
+
"trend.hint": "Hover to view details, \u2702 marks compaction/prune, Step/Turn switches granularity",
|
|
129
127
|
"trend.empty": "Send a message and each model request\u2019s context makeup shows up here",
|
|
130
128
|
"detail.step": "Turn {t} \xB7 Step {s}",
|
|
131
129
|
"detail.turn": "Turn {t} \xB7 {n} steps",
|
|
132
|
-
"detail.lastStep": "
|
|
133
|
-
"detail.estTotal": "
|
|
134
|
-
"detail.actual": "
|
|
135
|
-
"detail.output": "
|
|
136
|
-
"events.title": "Context
|
|
130
|
+
"detail.lastStep": "Last Step",
|
|
131
|
+
"detail.estTotal": "Estimated \u2248 {n}",
|
|
132
|
+
"detail.actual": "Actual Prompt {n}",
|
|
133
|
+
"detail.output": "Output {n}",
|
|
134
|
+
"events.title": "Context Events",
|
|
137
135
|
"events.empty": "No context events yet (compaction, injections, model switches appear here)",
|
|
138
136
|
"events.at": "Turn {t} \xB7 Step {s}",
|
|
139
137
|
"events.range": "Turn {t} \xB7 Step {a}\u2192{b}",
|
|
@@ -151,37 +149,37 @@ var DICT_EN = {
|
|
|
151
149
|
"footer": "Estimate: same fixed-density heuristic as dsh\u2019s built-in tokenMeter (~4 chars \u2248 1 token); \u201Cactual\u201D is provider-reported usage.",
|
|
152
150
|
"tip.step": "Turn {t} \xB7 Step {s}",
|
|
153
151
|
"tip.turn": "Turn {t} \xB7 {n} steps",
|
|
154
|
-
"tip.total": "
|
|
152
|
+
"tip.total": "Total \u2248 {n}",
|
|
155
153
|
"tip.actual": " (actual {n})",
|
|
156
154
|
"ev.compaction": "Context compacted (summary replaced {n} messages)",
|
|
157
155
|
"ev.prune": "Tool output pruned",
|
|
158
156
|
"ev.skill": "Skill injected ({name})",
|
|
159
157
|
"ev.model": "Model switched: {a} \u2192 {b}",
|
|
160
158
|
"form.instructions": "Instructions",
|
|
161
|
-
"form.catalog": "Catalog
|
|
162
|
-
"form.snapshot": "State
|
|
159
|
+
"form.catalog": "Catalog Update",
|
|
160
|
+
"form.snapshot": "State Snapshot",
|
|
163
161
|
"form.notice": "Notice",
|
|
164
|
-
"form.relay": "Agent
|
|
162
|
+
"form.relay": "Agent Relay",
|
|
165
163
|
"form.recall": "Recall",
|
|
166
|
-
"form.context": "Context
|
|
167
|
-
"node.toolResult": "Tool
|
|
168
|
-
"node.calls": "
|
|
164
|
+
"form.context": "Context Injection",
|
|
165
|
+
"node.toolResult": "Tool Result",
|
|
166
|
+
"node.calls": "Calls ",
|
|
169
167
|
"node.empty": "(empty reply)",
|
|
170
168
|
"node.nonText": "(non-text message)",
|
|
171
|
-
"node.snapshot": "
|
|
169
|
+
"node.snapshot": "Snapshot: ",
|
|
172
170
|
"cmd.desc": "View context makeup and how it evolves",
|
|
173
171
|
"cmd.close": "Close",
|
|
174
|
-
"browser.title": "Context
|
|
175
|
-
"browser.live": "Live (
|
|
176
|
-
"browser.liveNow": "Live \xB7
|
|
177
|
-
"browser.items": "{n}
|
|
172
|
+
"browser.title": "Context Browser",
|
|
173
|
+
"browser.live": "Live (Next Request)",
|
|
174
|
+
"browser.liveNow": "Live \xB7 Next Request",
|
|
175
|
+
"browser.items": "{n} Items",
|
|
178
176
|
"browser.missingLive": "\u2026 {n} earlier messages are also part of the context (outside the served window)",
|
|
179
177
|
"browser.approx": "Some removed messages of this step exceed retention \u2014 the makeup below is approximate",
|
|
180
178
|
"browser.noHeader": "Served by an older plugin build: token estimates only, no content",
|
|
181
|
-
"browser.noEpoch": "The header content (
|
|
179
|
+
"browser.noEpoch": "The header content (System Prompt / Tool Schemas) of this step is outside retention",
|
|
182
180
|
"browser.noContent": "Full content is outside the loaded message window (load older history in Chat to view)",
|
|
183
181
|
"browser.loading": "Loading full content from older session history\u2026",
|
|
184
|
-
"browser.preview": "
|
|
182
|
+
"browser.preview": "Preview"
|
|
185
183
|
};
|
|
186
184
|
|
|
187
185
|
// src/client/modalStore.ts
|
|
@@ -286,23 +284,19 @@ function headlineOf(data, pressure = null) {
|
|
|
286
284
|
const tokens = occupancyTokens ?? current.total;
|
|
287
285
|
const pct = window2 !== void 0 && window2 > 0 ? Math.min(100, Math.round(tokens / window2 * 100)) : null;
|
|
288
286
|
const parts = anchoredParts(partsOf(current), occupancyTokens !== null && tokens > 0 ? tokens : null);
|
|
289
|
-
return { tokens, window: window2, pct, parts
|
|
287
|
+
return { tokens, window: window2, pct, parts };
|
|
290
288
|
}
|
|
291
289
|
|
|
292
290
|
// src/client/services.ts
|
|
293
|
-
function
|
|
294
|
-
if (value === null || value === void 0 || typeof value !== "object") return null;
|
|
295
|
-
return value;
|
|
296
|
-
}
|
|
297
|
-
function contextPressureOf(value) {
|
|
291
|
+
function asRecord(value) {
|
|
298
292
|
if (value === null || value === void 0 || typeof value !== "object") return null;
|
|
299
293
|
return value;
|
|
300
294
|
}
|
|
295
|
+
var timelineOf = (value) => asRecord(value);
|
|
296
|
+
var contextPressureOf = (value) => asRecord(value);
|
|
301
297
|
function headersOf(value) {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
if (!Array.isArray(headers)) return null;
|
|
305
|
-
return value;
|
|
298
|
+
const headers = asRecord(value);
|
|
299
|
+
return headers !== null && Array.isArray(headers.headers) ? headers : null;
|
|
306
300
|
}
|
|
307
301
|
|
|
308
302
|
// src/client/react.ts
|
|
@@ -311,15 +305,15 @@ var h = React.createElement;
|
|
|
311
305
|
|
|
312
306
|
// src/client/components/requestDetail.tsx
|
|
313
307
|
function makeRequestDetail(kit, StackedBar) {
|
|
314
|
-
const { t,
|
|
308
|
+
const { t, fmt: fmt3, fmtTime: fmtTime2, catLabel, eventLabel, eventAt } = kit;
|
|
315
309
|
return function RequestDetail(props) {
|
|
316
310
|
const req = props.request;
|
|
317
311
|
if (!req) return null;
|
|
318
312
|
const isTurn = req.stepCount !== void 0 && req.stepCount > 1;
|
|
319
|
-
const head = isTurn ?
|
|
313
|
+
const head = isTurn ? t("detail.turn", { t: req.turn ?? 0, n: req.stepCount ?? 0 }) : t("detail.step", { t: req.turn ?? 0, s: req.step ?? 0 });
|
|
320
314
|
const marker = props.marker ?? null;
|
|
321
315
|
const markerAt = marker !== null ? eventAt(marker) : null;
|
|
322
|
-
return /* @__PURE__ */ React.createElement("div", { className: "lc-detail" }, /* @__PURE__ */ React.createElement("div", { className: "lc-detail-head" }, /* @__PURE__ */ React.createElement("b", null, head), marker !== null && markerAt !== null ? /* @__PURE__ */ React.createElement("span", { className: "lc-detail-marker", title: eventLabel(marker) }, "\u2702 " + markerAt) : null, isTurn ? /* @__PURE__ */ React.createElement("span", { className: "lc-detail-tag" }, t("detail.lastStep")) : null, /* @__PURE__ */ React.createElement("span", null, fmtTime2(req.time)), /* @__PURE__ */ React.createElement("span", null,
|
|
316
|
+
return /* @__PURE__ */ React.createElement("div", { className: "lc-detail" }, /* @__PURE__ */ React.createElement("div", { className: "lc-detail-head" }, /* @__PURE__ */ React.createElement("b", null, head), marker !== null && markerAt !== null ? /* @__PURE__ */ React.createElement("span", { className: "lc-detail-marker", title: eventLabel(marker) }, "\u2702 " + markerAt) : null, isTurn ? /* @__PURE__ */ React.createElement("span", { className: "lc-detail-tag" }, t("detail.lastStep")) : null, /* @__PURE__ */ React.createElement("span", null, fmtTime2(req.time)), /* @__PURE__ */ React.createElement("span", null, t("detail.estTotal", { n: fmt3(req.total) })), req.prompt !== void 0 ? /* @__PURE__ */ React.createElement("span", { className: "lc-actual" }, t("detail.actual", { n: fmt3(req.prompt) })) : null, req.output !== void 0 ? /* @__PURE__ */ React.createElement("span", null, t("detail.output", { n: fmt3(req.output) })) : null), /* @__PURE__ */ React.createElement(StackedBar, { parts: partsOf(req), height: 10 }), /* @__PURE__ */ React.createElement("div", { className: "lc-detail-rows" }, CATS.map((c) => {
|
|
323
317
|
const v = req[c.key] || 0;
|
|
324
318
|
return /* @__PURE__ */ React.createElement("div", { key: c.key, className: "lc-detail-row" }, /* @__PURE__ */ React.createElement("i", { style: { background: c.color } }), /* @__PURE__ */ React.createElement("span", { className: "lc-detail-label" }, catLabel(c.key)), /* @__PURE__ */ React.createElement("span", { className: "lc-bar-track" }, /* @__PURE__ */ React.createElement("span", { className: "lc-bar-fill", style: { width: (req.total > 0 ? v / req.total * 100 : 0) + "%", background: c.color } })), /* @__PURE__ */ React.createElement("span", { className: "lc-detail-num" }, "\u2248" + fmt3(v)), /* @__PURE__ */ React.createElement("span", { className: "lc-detail-pct" }, req.total > 0 ? Math.round(v / req.total * 100) + "%" : ""));
|
|
325
319
|
})));
|
|
@@ -328,7 +322,7 @@ function makeRequestDetail(kit, StackedBar) {
|
|
|
328
322
|
|
|
329
323
|
// src/client/components/stackedBar.tsx
|
|
330
324
|
function makeStackedBar(kit) {
|
|
331
|
-
const { t,
|
|
325
|
+
const { t, fmt: fmt3, catLabel } = kit;
|
|
332
326
|
return function StackedBar(props) {
|
|
333
327
|
let total = 0;
|
|
334
328
|
for (const p of props.parts) total += p.value;
|
|
@@ -353,7 +347,7 @@ function makeStackedBar(kit) {
|
|
|
353
347
|
tip = {
|
|
354
348
|
// "(pct%)" is a share of the OCCUPIED total — the dashed box
|
|
355
349
|
// that appears on hover frames exactly this reference region.
|
|
356
|
-
text: catLabel(p.key) + " \u2248" + fmt3(p.value) + " (" + Math.round(p.value / total * 100) + "%) " +
|
|
350
|
+
text: catLabel(p.key) + " \u2248" + fmt3(p.value) + " (" + Math.round(p.value / total * 100) + "%) " + t("overview.ofUsed"),
|
|
357
351
|
leftPct: Math.max(12, Math.min(acc + pct / 2, 88))
|
|
358
352
|
};
|
|
359
353
|
break;
|
|
@@ -397,12 +391,25 @@ function makeStackedBar(kit) {
|
|
|
397
391
|
}
|
|
398
392
|
}
|
|
399
393
|
) : null,
|
|
400
|
-
|
|
401
|
-
|
|
394
|
+
/* @__PURE__ */ React.createElement(
|
|
395
|
+
"div",
|
|
396
|
+
{
|
|
397
|
+
className: "lc-occupied-box" + (showBox ? " lc-occupied-box-on" : ""),
|
|
398
|
+
style: { width: usedPct + "%" }
|
|
399
|
+
}
|
|
400
|
+
)
|
|
401
|
+
), props.tip !== false ? /* @__PURE__ */ React.createElement(
|
|
402
|
+
"div",
|
|
403
|
+
{
|
|
404
|
+
className: "lc-bar-tip" + (tip ? " lc-bar-tip-on" : ""),
|
|
405
|
+
style: { left: tip ? tip.leftPct + "%" : "50%" }
|
|
406
|
+
},
|
|
407
|
+
tip ? tip.text : ""
|
|
408
|
+
) : null);
|
|
402
409
|
};
|
|
403
410
|
}
|
|
404
411
|
function makeLegend(kit) {
|
|
405
|
-
const {
|
|
412
|
+
const { t, fmt: fmt3, catLabel } = kit;
|
|
406
413
|
return function Legend(props) {
|
|
407
414
|
let total = 0;
|
|
408
415
|
for (const p of props.parts) total += p.value;
|
|
@@ -413,7 +420,7 @@ function makeLegend(kit) {
|
|
|
413
420
|
{
|
|
414
421
|
key: p.key,
|
|
415
422
|
className: "lc-chip" + (on ? " lc-chip-on" : ""),
|
|
416
|
-
title:
|
|
423
|
+
title: t("overview.ofUsed"),
|
|
417
424
|
onMouseEnter: () => {
|
|
418
425
|
if (props.onHoverKey !== void 0) props.onHoverKey(p.key);
|
|
419
426
|
},
|
|
@@ -459,7 +466,7 @@ function attachMarkers(requests, events) {
|
|
|
459
466
|
return markers;
|
|
460
467
|
}
|
|
461
468
|
function makeTrendChart(kit) {
|
|
462
|
-
const { t,
|
|
469
|
+
const { t, fmt: fmt3, fmtTime: fmtTime2, catLabel, eventLabel, eventAt } = kit;
|
|
463
470
|
const CHART_H = 112;
|
|
464
471
|
const BAR_W = 14;
|
|
465
472
|
const BAR_GAP = 2;
|
|
@@ -513,8 +520,8 @@ function makeTrendChart(kit) {
|
|
|
513
520
|
updateEdges(el);
|
|
514
521
|
});
|
|
515
522
|
const tipOf = (req) => {
|
|
516
|
-
const head = req.stepCount !== void 0 && req.stepCount > 1 ?
|
|
517
|
-
return head + " \xB7 " + fmtTime2(req.time) + " \xB7 " +
|
|
523
|
+
const head = req.stepCount !== void 0 && req.stepCount > 1 ? t("tip.turn", { t: req.turn ?? 0, n: req.stepCount }) : t("tip.step", { t: req.turn ?? 0, s: req.step ?? 0 });
|
|
524
|
+
return head + " \xB7 " + fmtTime2(req.time) + " \xB7 " + t("tip.total", { n: fmt3(req.total) }) + (req.prompt !== void 0 ? " \xB7 " + t("tip.actual", { n: fmt3(req.prompt) }) : "");
|
|
518
525
|
};
|
|
519
526
|
const hoveredIdx = props.hoveredSeq !== null ? requests.findIndex((r) => r.seq === props.hoveredSeq) : -1;
|
|
520
527
|
const hoveredReq = hoveredIdx >= 0 ? requests[hoveredIdx] : null;
|
|
@@ -610,7 +617,7 @@ function makeTrendChart(kit) {
|
|
|
610
617
|
// src/client/components/contextModal.tsx
|
|
611
618
|
var TREND_TURNS = 10;
|
|
612
619
|
function makeContextModal(ctx, kit) {
|
|
613
|
-
const { t,
|
|
620
|
+
const { t, fmt: fmt3 } = kit;
|
|
614
621
|
const sessions = ctx.get("sessions");
|
|
615
622
|
const StackedBar = makeStackedBar(kit);
|
|
616
623
|
const Legend = makeLegend(kit);
|
|
@@ -667,7 +674,7 @@ function makeContextModal(ctx, kit) {
|
|
|
667
674
|
const head = data !== null ? headlineOf(data, pressure) : null;
|
|
668
675
|
return /* @__PURE__ */ React.createElement("div", { className: "lc-modal-backdrop", onClick: close }, /* @__PURE__ */ React.createElement("div", { className: "lc-modal-card", onClick: (ev) => {
|
|
669
676
|
ev.stopPropagation();
|
|
670
|
-
} }, /* @__PURE__ */ React.createElement("div", { className: "lc-modal-head" }, /* @__PURE__ */ React.createElement("span", { className: "lc-modal-title" }, t("tab")), data !== null && (data.model || data.provider) ? /* @__PURE__ */ React.createElement("span", { className: "lc-card-sub" }, (data.model ? data.model : "") + (data.provider ? " \xB7 " + data.provider : "")) : null, /* @__PURE__ */ React.createElement("button", { className: "lc-modal-close", "aria-label": t("cmd.close"), onClick: close }, "\xD7")), data === null || head === null ? /* @__PURE__ */ React.createElement("div", { className: "lc-empty" }, t("loading")) : /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "lc-overview-num" }, /* @__PURE__ */ React.createElement("b", null, fmt3(head.tokens)), /* @__PURE__ */ React.createElement("span", null, head.window ? " / " + fmt3(head.window) + " "
|
|
677
|
+
} }, /* @__PURE__ */ React.createElement("div", { className: "lc-modal-head" }, /* @__PURE__ */ React.createElement("span", { className: "lc-modal-title" }, t("tab")), data !== null && (data.model || data.provider) ? /* @__PURE__ */ React.createElement("span", { className: "lc-card-sub" }, (data.model ? data.model : "") + (data.provider ? " \xB7 " + data.provider : "")) : null, /* @__PURE__ */ React.createElement("button", { className: "lc-modal-close", "aria-label": t("cmd.close"), onClick: close }, "\xD7")), data === null || head === null ? /* @__PURE__ */ React.createElement("div", { className: "lc-empty" }, t("loading")) : /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "lc-overview-num" }, /* @__PURE__ */ React.createElement("b", null, fmt3(head.tokens)), /* @__PURE__ */ React.createElement("span", null, head.window ? " / " + fmt3(head.window) + " tokens" : " " + t("overview.estimate")), head.pct !== null ? /* @__PURE__ */ React.createElement("span", { className: "lc-overview-pct" }, /* @__PURE__ */ React.createElement("b", null, head.pct + "%"), t("overview.used")) : null), /* @__PURE__ */ React.createElement(StackedBar, { parts: head.parts, height: 16, max: head.window, hoverKey: hoverCat, onHoverKey: setHoverCat }), /* @__PURE__ */ React.createElement(Legend, { parts: head.parts, hoverKey: hoverCat, onHoverKey: setHoverCat }), /* @__PURE__ */ React.createElement("div", { className: "lc-card-title lc-modal-trend" }, /* @__PURE__ */ React.createElement("span", { className: "lc-card-title-text" }, t("trend.title"))), turns.length === 0 ? /* @__PURE__ */ React.createElement("div", { className: "lc-empty" }, t("trend.empty")) : /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(
|
|
671
678
|
TrendChart,
|
|
672
679
|
{
|
|
673
680
|
requests: turns,
|
|
@@ -690,6 +697,7 @@ var STYLES = [
|
|
|
690
697
|
".lc-root { padding: 16px 20px 32px; overflow-y: auto; height: 100%; box-sizing: border-box; color: var(--dsw-alias-label-primary); font-size: 13px; }",
|
|
691
698
|
".lc-card { background: var(--dsw-alias-bg-layer-1); border: 1px solid var(--dsw-alias-border-l1); border-radius: 10px; padding: 14px 16px; margin-bottom: 14px; }",
|
|
692
699
|
".lc-card-title { font-weight: 600; margin-bottom: 10px; display: flex; align-items: baseline; gap: 8px; }",
|
|
700
|
+
".lc-card-title-text { flex: none; white-space: nowrap; }",
|
|
693
701
|
".lc-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(92px, 1fr)); gap: 8px; }",
|
|
694
702
|
".lc-stat { background: var(--dsw-alias-bg-layer-2); border: 1px solid var(--dsw-alias-border-l1); border-radius: 8px; padding: 8px 10px; display: flex; flex-direction: column; gap: 2px; min-width: 0; }",
|
|
695
703
|
".lc-stat-label { color: var(--dsw-alias-label-secondary); font-size: 11px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }",
|
|
@@ -700,9 +708,13 @@ var STYLES = [
|
|
|
700
708
|
".lc-gran-btn { border: 0; background: transparent; color: var(--dsw-alias-label-secondary); font-size: 11px; line-height: 1; padding: 3px 8px; border-radius: 5px; cursor: pointer; font-family: inherit; }",
|
|
701
709
|
".lc-gran-btn:hover { color: var(--dsw-alias-label-primary); }",
|
|
702
710
|
".lc-gran-on, .lc-gran-on:hover { background: var(--dsw-alias-button-primary-fill); color: var(--dsw-alias-label-primary-foreground); }",
|
|
703
|
-
".lc-overview-num { margin-bottom: 8px; }",
|
|
704
|
-
".lc-overview-num b { font-size: 20px; }",
|
|
711
|
+
".lc-overview-num { display: flex; align-items: baseline; gap: 6px; margin-bottom: 8px; }",
|
|
712
|
+
".lc-overview-num > b { font-size: 20px; }",
|
|
705
713
|
".lc-overview-num span { color: var(--dsw-alias-label-secondary); }",
|
|
714
|
+
// The used-percentage figure is the emphasis of the line: pushed to the
|
|
715
|
+
// right edge, large and primary-colored, with a small "used" caption.
|
|
716
|
+
".lc-overview-pct { margin-left: auto; font-size: 11px; }",
|
|
717
|
+
".lc-overview-pct b { font-size: 20px; color: var(--dsw-alias-label-primary); margin-right: 4px; }",
|
|
706
718
|
".lc-stacked-wrap { position: relative; width: 100%; }",
|
|
707
719
|
".lc-stacked { display: flex; width: 100%; border-radius: 5px; overflow: hidden; background: rgba(128,128,128,0.18); position: relative; }",
|
|
708
720
|
// Hover reference frame around the OCCUPIED region of the composition bar:
|
|
@@ -711,9 +723,16 @@ var STYLES = [
|
|
|
711
723
|
// sits outside it). pointer-events: none keeps hover on the segments/free.
|
|
712
724
|
// Deliberately high-contrast (label-primary) and thick so the frame reads at
|
|
713
725
|
// a glance, and the other parts dim underneath it (`.lc-stacked-dim`).
|
|
714
|
-
".lc-occupied-box { position: absolute; top: 0; bottom: 0; left: 0; border: 2px dashed var(--dsw-alias-label-primary); border-radius: 5px; box-sizing: border-box; pointer-events: none; opacity:
|
|
715
|
-
".lc-
|
|
726
|
+
".lc-occupied-box { position: absolute; top: 0; bottom: 0; left: 0; border: 2px dashed var(--dsw-alias-label-primary); border-radius: 5px; box-sizing: border-box; pointer-events: none; opacity: 0; box-shadow: 0 0 0 1px var(--dsw-alias-bg-layer-2); transition: opacity 120ms ease; }",
|
|
727
|
+
".lc-occupied-box-on { opacity: 1; }",
|
|
728
|
+
".lc-bar-tip { position: absolute; bottom: calc(100% + 6px); transform: translateX(-50%); z-index: 5; white-space: nowrap; background: var(--dsw-alias-bg-layer-2); border: 1px solid var(--dsw-alias-border-l1); border-radius: 6px; padding: 3px 8px; font-size: 12px; color: var(--dsw-alias-label-primary); box-shadow: 0 2px 8px rgba(0,0,0,0.18); pointer-events: none; opacity: 0; transition: opacity 120ms ease; }",
|
|
729
|
+
".lc-bar-tip-on { opacity: 1; }",
|
|
716
730
|
".lc-stacked > div { height: 100%; }",
|
|
731
|
+
// Hover eases: the shared composition hover (dim + segment brighten, on the
|
|
732
|
+
// overview or the mirrored browser bar) glides in and out — same 120ms
|
|
733
|
+
// rhythm as the rest of the view.
|
|
734
|
+
".lc-stacked-seg { transition: filter 120ms ease, opacity 120ms ease; }",
|
|
735
|
+
".lc-stacked-free { transition: box-shadow 120ms ease, opacity 120ms ease; }",
|
|
717
736
|
".lc-stacked-seg-on { filter: brightness(1.18); }",
|
|
718
737
|
".lc-stacked-free-on { box-shadow: inset 0 0 0 1px var(--dsw-alias-label-secondary); border-radius: 3px; }",
|
|
719
738
|
// Hover focus: everything except the hovered part (segment, legend chip, or
|
|
@@ -724,10 +743,14 @@ var STYLES = [
|
|
|
724
743
|
".lc-stacked-dim .lc-stacked-free { opacity: 0.35; }",
|
|
725
744
|
".lc-stacked-dim .lc-stacked-free-on { opacity: 1; }",
|
|
726
745
|
".lc-legend { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 10px; }",
|
|
727
|
-
".lc-chip { display: inline-flex; align-items: center; gap: 5px; color: var(--dsw-alias-label-primary); }",
|
|
746
|
+
".lc-chip { display: inline-flex; align-items: center; gap: 5px; color: var(--dsw-alias-label-primary); padding: 1px 6px; border-radius: 6px; transition: background-color 120ms ease; }",
|
|
728
747
|
".lc-chip i, .lc-detail-row i, .lc-node i { display: inline-block; width: 8px; height: 8px; border-radius: 2px; }",
|
|
748
|
+
".lc-chip i { transition: box-shadow 120ms ease; }",
|
|
729
749
|
".lc-chip em { font-style: normal; color: var(--dsw-alias-label-secondary); }",
|
|
730
|
-
|
|
750
|
+
// The selected chip glows with the shared hover tint (smoothly, like the
|
|
751
|
+
// browser rows) instead of snapping its weight; the dot ring on top marks
|
|
752
|
+
// the exact segment.
|
|
753
|
+
".lc-chip-on { font-weight: 600; background: var(--dsw-alias-interactive-bg-hover); }",
|
|
731
754
|
".lc-chip-on i { box-shadow: 0 0 0 1px var(--dsw-alias-brand-primary); }",
|
|
732
755
|
".lc-tools { margin-top: 10px; color: var(--dsw-alias-label-secondary); display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }",
|
|
733
756
|
".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); }",
|
|
@@ -745,7 +768,7 @@ var STYLES = [
|
|
|
745
768
|
".lc-grid { position: absolute; left: 0; right: 0; border-top: 1px dashed var(--dsw-alias-border-l1); pointer-events: none; }",
|
|
746
769
|
".lc-grid-top { top: 18px; }",
|
|
747
770
|
".lc-grid-mid { top: 74px; }",
|
|
748
|
-
".lc-bar { position: relative; width: 14px; flex: none; height: 100%; display: flex; align-items: flex-end; cursor: pointer; border-radius: 2px; transition: opacity 120ms ease; }",
|
|
771
|
+
".lc-bar { position: relative; width: 14px; flex: none; height: 100%; display: flex; align-items: flex-end; cursor: pointer; border-radius: 2px; transition: opacity 120ms ease, background-color 120ms ease; }",
|
|
749
772
|
// Turn-aware dimming: while a turn is focused, bars OUTSIDE the active
|
|
750
773
|
// turn fade to 35% and the whole current turn stays fully opaque.
|
|
751
774
|
".lc-chart-dim .lc-bar { opacity: 0.35; }",
|
|
@@ -856,9 +879,14 @@ var STYLES = [
|
|
|
856
879
|
".lc-br-cats { margin-top: 10px; display: flex; flex-direction: column; gap: 4px; }",
|
|
857
880
|
".lc-br-cat { border: 1px solid var(--dsw-alias-border-l1); border-radius: 8px; background: var(--dsw-alias-bg-layer-2); overflow: hidden; }",
|
|
858
881
|
".lc-br-cat-empty { opacity: 0.55; }",
|
|
859
|
-
".lc-br-cat-row { display: flex; align-items: center; gap: 8px; width: 100%; border: 0; background: transparent; color: var(--dsw-alias-label-primary); font: inherit; padding: 7px 10px; cursor: pointer; text-align: left; }",
|
|
860
|
-
".lc-br-cat-row:hover { background: var(--dsw-alias-bg-
|
|
861
|
-
|
|
882
|
+
".lc-br-cat-row { display: flex; align-items: center; gap: 8px; width: 100%; border: 0; background: transparent; color: var(--dsw-alias-label-primary); font: inherit; padding: 7px 10px; cursor: pointer; text-align: left; transition: background-color 120ms ease; }",
|
|
883
|
+
".lc-br-cat-row:hover { background: var(--dsw-alias-interactive-bg-hover); }",
|
|
884
|
+
// Current-composition hover echo: the category row lit by the shared hover
|
|
885
|
+
// link (hovering the Current Composition card's bar/legend) looks hovered
|
|
886
|
+
// too — same tint as the physical hover, plus a ring on its color dot.
|
|
887
|
+
".lc-br-cat-on { background: var(--dsw-alias-interactive-bg-hover); }",
|
|
888
|
+
".lc-br-cat-on i { box-shadow: 0 0 0 1px var(--dsw-alias-brand-primary); }",
|
|
889
|
+
".lc-br-cat-row i { display: inline-block; width: 8px; height: 8px; border-radius: 2px; flex: none; transition: box-shadow 120ms ease; }",
|
|
862
890
|
".lc-br-cat-label { font-weight: 600; }",
|
|
863
891
|
".lc-br-cat-count { color: var(--dsw-alias-label-secondary); font-size: 12px; flex: 1; }",
|
|
864
892
|
".lc-br-chev { flex: none; width: 12px; color: var(--dsw-alias-label-secondary); transition: transform 120ms ease; }",
|
|
@@ -867,9 +895,9 @@ var STYLES = [
|
|
|
867
895
|
".lc-br-pct { flex: none; width: 36px; text-align: right; color: var(--dsw-alias-label-secondary); font-size: 12px; }",
|
|
868
896
|
".lc-br-body { border-top: 1px solid var(--dsw-alias-border-l1); padding: 4px 6px; display: flex; flex-direction: column; gap: 2px; }",
|
|
869
897
|
".lc-br-elem { border-radius: 6px; }",
|
|
870
|
-
".lc-br-elem-on { background: var(--dsw-alias-bg-
|
|
871
|
-
".lc-br-elem-row { display: flex; align-items: center; gap: 8px; width: 100%; border: 0; background: transparent; color: var(--dsw-alias-label-primary); font: inherit; font-size: 12px; padding: 5px 6px; cursor: pointer; text-align: left; border-radius: 6px; }",
|
|
872
|
-
".lc-br-elem-row:hover { background: var(--dsw-alias-bg-
|
|
898
|
+
".lc-br-elem-on { background: var(--dsw-alias-interactive-bg-active); }",
|
|
899
|
+
".lc-br-elem-row { display: flex; align-items: center; gap: 8px; width: 100%; border: 0; background: transparent; color: var(--dsw-alias-label-primary); font: inherit; font-size: 12px; padding: 5px 6px; cursor: pointer; text-align: left; border-radius: 6px; transition: background-color 120ms ease; }",
|
|
900
|
+
".lc-br-elem-row:hover { background: var(--dsw-alias-interactive-bg-hover); }",
|
|
873
901
|
".lc-br-tag { flex: none; font-size: 11px; color: var(--dsw-alias-label-secondary); background: var(--dsw-alias-bg-layer-1); border: 1px solid var(--dsw-alias-border-l1); border-radius: 4px; padding: 0 6px; max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }",
|
|
874
902
|
".lc-br-preview { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }",
|
|
875
903
|
".lc-br-time { flex: none; color: var(--dsw-alias-label-secondary); font-size: 11px; }",
|
|
@@ -930,7 +958,7 @@ function makeNodeText(kit) {
|
|
|
930
958
|
};
|
|
931
959
|
}
|
|
932
960
|
function makeNodeList(kit) {
|
|
933
|
-
const { t,
|
|
961
|
+
const { t, fmt: fmt3, fmtTime: fmtTime2 } = kit;
|
|
934
962
|
const nodeText = makeNodeText(kit);
|
|
935
963
|
return function NodeList(props) {
|
|
936
964
|
if (props.nodes.length === 0) {
|
|
@@ -939,7 +967,7 @@ function makeNodeList(kit) {
|
|
|
939
967
|
const catColor = {};
|
|
940
968
|
for (const c of CATS) catColor[c.key] = c.color;
|
|
941
969
|
const rows = props.nodes.slice().reverse();
|
|
942
|
-
return /* @__PURE__ */ React.createElement("div", { className: "lc-nodes" }, props.dropped > 0 ? /* @__PURE__ */ React.createElement("div", { className: "lc-nodes-more" },
|
|
970
|
+
return /* @__PURE__ */ React.createElement("div", { className: "lc-nodes" }, props.dropped > 0 ? /* @__PURE__ */ React.createElement("div", { className: "lc-nodes-more" }, t("nodes.more", { n: props.dropped })) : null, rows.map((n) => {
|
|
943
971
|
const text = nodeText(n);
|
|
944
972
|
return /* @__PURE__ */ React.createElement("div", { key: n.seq, className: "lc-node" }, /* @__PURE__ */ React.createElement("i", { style: { background: catColor[n.cat] || "#999" } }), /* @__PURE__ */ React.createElement("span", { className: "lc-node-preview", title: text }, text), typeof n.time === "number" ? /* @__PURE__ */ React.createElement("span", { className: "lc-node-time" }, fmtTime2(n.time)) : null, /* @__PURE__ */ React.createElement("span", { className: "lc-node-tokens" }, fmt3(n.tokens)));
|
|
945
973
|
}));
|
|
@@ -991,7 +1019,7 @@ function NodeContent(props) {
|
|
|
991
1019
|
return /* @__PURE__ */ React.createElement("div", { className: "lc-br-content" }, /* @__PURE__ */ React.createElement("div", { className: "lc-br-note" }, props.hint));
|
|
992
1020
|
}
|
|
993
1021
|
function makeContextBrowser(kit, StackedBar) {
|
|
994
|
-
const { t,
|
|
1022
|
+
const { t, fmt: fmt3, fmtTime: fmtTime2, catLabel } = kit;
|
|
995
1023
|
const nodeText = makeNodeText(kit);
|
|
996
1024
|
const catColor = {};
|
|
997
1025
|
for (const c of CATS) catColor[c.key] = c.color;
|
|
@@ -1032,11 +1060,19 @@ function makeContextBrowser(kit, StackedBar) {
|
|
|
1032
1060
|
React.useEffect(() => {
|
|
1033
1061
|
if (!hasMore && missingSeq !== null && !exhausted) setExhausted(true);
|
|
1034
1062
|
}, [hasMore, missingSeq, exhausted]);
|
|
1063
|
+
const pinSeq = props.pinSeq;
|
|
1064
|
+
React.useEffect(() => {
|
|
1065
|
+
setSel(pinSeq === null || pinSeq === void 0 ? "live" : pinSeq);
|
|
1066
|
+
setOpenCat(null);
|
|
1067
|
+
setOpenElem(null);
|
|
1068
|
+
}, [pinSeq]);
|
|
1035
1069
|
const awaiting = missingSeq !== null && !exhausted && loadOlderHistory !== void 0 && hasMore;
|
|
1036
1070
|
const requests = data.requests || [];
|
|
1037
1071
|
const hoverReq = props.previewSeq !== null && props.previewSeq !== void 0 ? requests.find((r) => r.seq === props.previewSeq) ?? null : null;
|
|
1038
1072
|
const req = hoverReq ?? (sel === "live" ? null : requests.find((r) => r.seq === sel) ?? null);
|
|
1039
1073
|
const seq = req !== null ? req.seq : null;
|
|
1074
|
+
const linked = req === null && props.onHoverKey !== void 0;
|
|
1075
|
+
const linkKey = linked && props.hoverKey !== null && props.hoverKey !== "free" ? props.hoverKey : null;
|
|
1040
1076
|
const view = assemble(data, headers, seq);
|
|
1041
1077
|
const breakdown = req !== null ? req : data.current;
|
|
1042
1078
|
const parts = partsOf(breakdown);
|
|
@@ -1124,7 +1160,7 @@ function makeContextBrowser(kit, StackedBar) {
|
|
|
1124
1160
|
);
|
|
1125
1161
|
});
|
|
1126
1162
|
};
|
|
1127
|
-
return /* @__PURE__ */ React.createElement("div", { className: "lc-card" }, /* @__PURE__ */ React.createElement("div", { className: "lc-card-title" }, t("browser.title"), /* @__PURE__ */ React.createElement(
|
|
1163
|
+
return /* @__PURE__ */ React.createElement("div", { className: "lc-card" }, /* @__PURE__ */ React.createElement("div", { className: "lc-card-title" }, /* @__PURE__ */ React.createElement("span", { className: "lc-card-title-text" }, t("browser.title")), /* @__PURE__ */ React.createElement(
|
|
1128
1164
|
"select",
|
|
1129
1165
|
{
|
|
1130
1166
|
className: "lc-br-pick",
|
|
@@ -1134,15 +1170,43 @@ function makeContextBrowser(kit, StackedBar) {
|
|
|
1134
1170
|
}
|
|
1135
1171
|
},
|
|
1136
1172
|
/* @__PURE__ */ React.createElement("option", { value: "live" }, t("browser.live")),
|
|
1137
|
-
requests.slice().reverse().map((r) => /* @__PURE__ */ React.createElement("option", { key: r.seq, value: String(r.seq) },
|
|
1138
|
-
)), /* @__PURE__ */ React.createElement("div", { className: "lc-br-meta" }, /* @__PURE__ */ React.createElement("b", null, req !== null ?
|
|
1173
|
+
requests.slice().reverse().map((r) => /* @__PURE__ */ React.createElement("option", { key: r.seq, value: String(r.seq) }, t("detail.step", { t: r.turn ?? 0, s: r.step ?? 0 }) + " \xB7 " + fmtTime2(r.time)))
|
|
1174
|
+
)), /* @__PURE__ */ React.createElement("div", { className: "lc-br-meta" }, /* @__PURE__ */ React.createElement("b", null, req !== null ? t("detail.step", { t: req.turn ?? 0, s: req.step ?? 0 }) : t("browser.liveNow")), req !== null ? /* @__PURE__ */ React.createElement("span", null, fmtTime2(req.time)) : null, hoverReq !== null ? /* @__PURE__ */ React.createElement("span", { className: "lc-card-sub" }, t("browser.preview")) : null, /* @__PURE__ */ React.createElement("span", null, t("detail.estTotal", { n: fmt3(total) })), req !== null && req.prompt !== void 0 ? /* @__PURE__ */ React.createElement("span", { className: "lc-actual" }, t("detail.actual", { n: fmt3(req.prompt) })) : null), /* @__PURE__ */ React.createElement("div", { className: "lc-br-bar" }, /* @__PURE__ */ React.createElement(
|
|
1175
|
+
StackedBar,
|
|
1176
|
+
{
|
|
1177
|
+
parts,
|
|
1178
|
+
height: 10,
|
|
1179
|
+
hoverKey: linked ? linkKey : void 0,
|
|
1180
|
+
onHoverKey: linked ? props.onHoverKey : void 0,
|
|
1181
|
+
tip: false
|
|
1182
|
+
}
|
|
1183
|
+
)), view.missingLive > 0 ? /* @__PURE__ */ React.createElement("div", { className: "lc-br-note" }, t("browser.missingLive", { n: view.missingLive })) : null, view.approximate ? /* @__PURE__ */ React.createElement("div", { className: "lc-br-note" }, t("browser.approx")) : null, /* @__PURE__ */ React.createElement("div", { className: "lc-br-cats" }, CATS.map((c) => {
|
|
1139
1184
|
const count = toolCount(c.key);
|
|
1140
1185
|
const v = breakdown[c.key] || 0;
|
|
1141
1186
|
const openable = count > 0 || (c.key === "system" || c.key === "tools") && view.header === null;
|
|
1142
1187
|
const open = openCat === c.key && openable;
|
|
1143
|
-
return /* @__PURE__ */ React.createElement("div", { key: c.key, className: "lc-br-cat" + (openable ? "" : " lc-br-cat-empty") }, /* @__PURE__ */ React.createElement(
|
|
1144
|
-
|
|
1145
|
-
|
|
1188
|
+
return /* @__PURE__ */ React.createElement("div", { key: c.key, className: "lc-br-cat" + (openable ? "" : " lc-br-cat-empty") }, /* @__PURE__ */ React.createElement(
|
|
1189
|
+
"button",
|
|
1190
|
+
{
|
|
1191
|
+
type: "button",
|
|
1192
|
+
className: "lc-br-cat-row" + (linked && props.hoverKey === c.key ? " lc-br-cat-on" : ""),
|
|
1193
|
+
onMouseEnter: linked ? () => {
|
|
1194
|
+
if (props.onHoverKey !== void 0) props.onHoverKey(c.key);
|
|
1195
|
+
} : void 0,
|
|
1196
|
+
onMouseLeave: linked ? () => {
|
|
1197
|
+
if (props.onHoverKey !== void 0) props.onHoverKey(null);
|
|
1198
|
+
} : void 0,
|
|
1199
|
+
onClick: () => {
|
|
1200
|
+
toggleCat(c.key);
|
|
1201
|
+
}
|
|
1202
|
+
},
|
|
1203
|
+
/* @__PURE__ */ React.createElement("span", { className: "lc-br-chev" + (open ? " lc-br-chev-on" : "") }, "\u25B8"),
|
|
1204
|
+
/* @__PURE__ */ React.createElement("i", { style: { background: c.color } }),
|
|
1205
|
+
/* @__PURE__ */ React.createElement("span", { className: "lc-br-cat-label" }, catLabel(c.key)),
|
|
1206
|
+
/* @__PURE__ */ React.createElement("span", { className: "lc-br-cat-count" }, t("browser.items", { n: count })),
|
|
1207
|
+
/* @__PURE__ */ React.createElement("span", { className: "lc-br-tokens" }, "\u2248" + fmt3(v)),
|
|
1208
|
+
/* @__PURE__ */ React.createElement("span", { className: "lc-br-pct" }, total > 0 ? Math.round(v / total * 100) + "%" : "")
|
|
1209
|
+
), open ? /* @__PURE__ */ React.createElement("div", { className: "lc-br-body" }, catBody(c.key)) : null);
|
|
1146
1210
|
})));
|
|
1147
1211
|
};
|
|
1148
1212
|
}
|
|
@@ -1158,22 +1222,18 @@ function fmt(n) {
|
|
|
1158
1222
|
return String(Math.round(n));
|
|
1159
1223
|
}
|
|
1160
1224
|
function fmtTime(t) {
|
|
1161
|
-
|
|
1162
|
-
function p(x) {
|
|
1163
|
-
return (x < 10 ? "0" : "") + x;
|
|
1164
|
-
}
|
|
1165
|
-
return p(d.getHours()) + ":" + p(d.getMinutes()) + ":" + p(d.getSeconds());
|
|
1225
|
+
return new Date(t).toLocaleTimeString("en-GB", { hour12: false });
|
|
1166
1226
|
}
|
|
1167
1227
|
|
|
1168
1228
|
// src/client/components/events.tsx
|
|
1169
1229
|
var EVENT_ICONS = { compaction: "\u2702", prune: "\u2702", inject: "\uFF0B", model: "\u21C4" };
|
|
1170
|
-
function makeEventText(t
|
|
1230
|
+
function makeEventText(t) {
|
|
1171
1231
|
function eventLabel(ev) {
|
|
1172
|
-
if (ev.kind === "compaction") return
|
|
1232
|
+
if (ev.kind === "compaction") return t("ev.compaction", { n: ev.count || 0 });
|
|
1173
1233
|
if (ev.kind === "prune") return t("ev.prune");
|
|
1174
|
-
if (ev.kind === "model") return
|
|
1234
|
+
if (ev.kind === "model") return t("ev.model", { a: ev.from || "?", b: ev.to || "?" });
|
|
1175
1235
|
if (ev.kind === "inject") {
|
|
1176
|
-
if (ev.sub === "skill") return
|
|
1236
|
+
if (ev.sub === "skill") return t("ev.skill", { name: ev.name || "?" });
|
|
1177
1237
|
const base = t("form." + (ev.form || "context"));
|
|
1178
1238
|
return ev.name ? base + " \xB7 " + ev.name : base;
|
|
1179
1239
|
}
|
|
@@ -1228,7 +1288,7 @@ function makeEventList(kit) {
|
|
|
1228
1288
|
|
|
1229
1289
|
// src/client/meta.ts
|
|
1230
1290
|
var PLUGIN_NAME = "dsh-context";
|
|
1231
|
-
var PLUGIN_VERSION = true ? "0.
|
|
1291
|
+
var PLUGIN_VERSION = true ? "0.15.0" : "0.0.0-dev";
|
|
1232
1292
|
var PLUGIN_REPO = true ? "https://github.com/bowenliang123/dsh-context" : "https://github.com/bowenliang123/dsh-context";
|
|
1233
1293
|
var PLUGIN_REPO_SHORT = PLUGIN_REPO.replace(/^https?:\/\/github\.com\//, "");
|
|
1234
1294
|
|
|
@@ -1276,7 +1336,7 @@ function makePluginInfo(kit) {
|
|
|
1276
1336
|
const update = latest !== null && isNewerVersion(latest, PLUGIN_VERSION) ? latest : null;
|
|
1277
1337
|
const nameValue = [PLUGIN_NAME + " (v" + PLUGIN_VERSION + ")"];
|
|
1278
1338
|
if (update) nameValue.push(/* @__PURE__ */ React.createElement("span", { key: "update", className: "lc-pi-update" }, "\u2191 v" + update));
|
|
1279
|
-
return /* @__PURE__ */ React.createElement("div", { className: "lc-card" }, /* @__PURE__ */ React.createElement("div", { className: "lc-card-title" }, t("plugin.title"), /* @__PURE__ */ React.createElement("span", { className: "lc-card-sub" }, t("plugin.hint"))), /* @__PURE__ */ React.createElement("div", { className: "lc-pi-grid" }, row(t("plugin.name"), nameValue, PLUGIN_REPO + "/releases"), row(t("plugin.github"), PLUGIN_REPO_SHORT, PLUGIN_REPO)));
|
|
1339
|
+
return /* @__PURE__ */ React.createElement("div", { className: "lc-card" }, /* @__PURE__ */ React.createElement("div", { className: "lc-card-title" }, /* @__PURE__ */ React.createElement("span", { className: "lc-card-title-text" }, t("plugin.title")), /* @__PURE__ */ React.createElement("span", { className: "lc-card-sub" }, t("plugin.hint"))), /* @__PURE__ */ React.createElement("div", { className: "lc-pi-grid" }, row(t("plugin.name"), nameValue, PLUGIN_REPO + "/releases"), row(t("plugin.github"), PLUGIN_REPO_SHORT, PLUGIN_REPO)));
|
|
1280
1340
|
};
|
|
1281
1341
|
}
|
|
1282
1342
|
|
|
@@ -1296,7 +1356,7 @@ function makeStatsBoard(kit) {
|
|
|
1296
1356
|
else if (ev.kind === "inject") injects++;
|
|
1297
1357
|
}
|
|
1298
1358
|
const cell = (label, value) => /* @__PURE__ */ React.createElement("div", { className: "lc-stat" }, /* @__PURE__ */ React.createElement("span", { className: "lc-stat-label" }, label), /* @__PURE__ */ React.createElement("b", { className: "lc-stat-value" }, value));
|
|
1299
|
-
return /* @__PURE__ */ React.createElement("div", { className: "lc-card lc-col lc-col-stats" }, /* @__PURE__ */ React.createElement("div", { className: "lc-card-title" }, t("stats.title"), /* @__PURE__ */ React.createElement("span", { className: "lc-card-sub" }, t("stats.hint"))), /* @__PURE__ */ React.createElement("div", { className: "lc-stats" }, cell(t("stats.turns"), fmt3(turns.size)), cell(t("stats.steps"), fmt3(steps)), cell(t("stats.injects"), fmt3(injects)), cell(t("stats.compactions"), fmt3(compactions)), cell(t("stats.prunes"), fmt3(prunes))));
|
|
1359
|
+
return /* @__PURE__ */ React.createElement("div", { className: "lc-card lc-col lc-col-stats" }, /* @__PURE__ */ React.createElement("div", { className: "lc-card-title" }, /* @__PURE__ */ React.createElement("span", { className: "lc-card-title-text" }, t("stats.title")), /* @__PURE__ */ React.createElement("span", { className: "lc-card-sub" }, t("stats.hint"))), /* @__PURE__ */ React.createElement("div", { className: "lc-stats" }, cell(t("stats.turns"), fmt3(turns.size)), cell(t("stats.steps"), fmt3(steps)), cell(t("stats.injects"), fmt3(injects)), cell(t("stats.compactions"), fmt3(compactions)), cell(t("stats.prunes"), fmt3(prunes))));
|
|
1300
1360
|
};
|
|
1301
1361
|
}
|
|
1302
1362
|
|
|
@@ -1304,7 +1364,7 @@ function makeStatsBoard(kit) {
|
|
|
1304
1364
|
var viewScroll = /* @__PURE__ */ new Map();
|
|
1305
1365
|
var EVENT_KINDS = ["inject", "compaction", "prune", "model"];
|
|
1306
1366
|
function makeContextView(ctx, kit) {
|
|
1307
|
-
const { t,
|
|
1367
|
+
const { t, fmt: fmt3, fmtTime: fmtTime2, catLabel } = kit;
|
|
1308
1368
|
const StackedBar = makeStackedBar(kit);
|
|
1309
1369
|
const Legend = makeLegend(kit);
|
|
1310
1370
|
const TrendChart = makeTrendChart(kit);
|
|
@@ -1388,9 +1448,9 @@ function makeContextView(ctx, kit) {
|
|
|
1388
1448
|
}
|
|
1389
1449
|
}
|
|
1390
1450
|
const head = headlineOf(data, pressure);
|
|
1391
|
-
return /* @__PURE__ */ React.createElement("div", { className: "lc-root", ref: rootRef }, /* @__PURE__ */ React.createElement("div", { className: "lc-cols lc-head" }, /* @__PURE__ */ React.createElement(StatsBoard, { requests, events }), /* @__PURE__ */ React.createElement(PluginInfo, null)), /* @__PURE__ */ React.createElement("div", { className: "lc-cols" }, /* @__PURE__ */ React.createElement("div", { className: "lc-col" }, /* @__PURE__ */ React.createElement("div", { className: "lc-card" }, /* @__PURE__ */ React.createElement("div", { className: "lc-card-title" }, t("overview.title"), /* @__PURE__ */ React.createElement("span", { className: "lc-card-sub" }, (data.model ? data.model : "") + (data.provider ? " \xB7 " + data.provider : ""))), /* @__PURE__ */ React.createElement("div", { className: "lc-overview-num" }, /* @__PURE__ */ React.createElement("b", null, fmt3(head.tokens)), /* @__PURE__ */ React.createElement("span", null, head.window ? " / " + fmt3(head.window) + " "
|
|
1451
|
+
return /* @__PURE__ */ React.createElement("div", { className: "lc-root", ref: rootRef }, /* @__PURE__ */ React.createElement("div", { className: "lc-cols lc-head" }, /* @__PURE__ */ React.createElement(StatsBoard, { requests, events }), /* @__PURE__ */ React.createElement(PluginInfo, null)), /* @__PURE__ */ React.createElement("div", { className: "lc-cols" }, /* @__PURE__ */ React.createElement("div", { className: "lc-col" }, /* @__PURE__ */ React.createElement("div", { className: "lc-card" }, /* @__PURE__ */ React.createElement("div", { className: "lc-card-title" }, /* @__PURE__ */ React.createElement("span", { className: "lc-card-title-text" }, t("overview.title")), /* @__PURE__ */ React.createElement("span", { className: "lc-card-sub" }, (data.model ? data.model : "") + (data.provider ? " \xB7 " + data.provider : ""))), /* @__PURE__ */ React.createElement("div", { className: "lc-overview-num" }, /* @__PURE__ */ React.createElement("b", null, fmt3(head.tokens)), /* @__PURE__ */ React.createElement("span", null, head.window ? " / " + fmt3(head.window) + " tokens" : " " + t("overview.estimate")), head.pct !== null ? /* @__PURE__ */ React.createElement("span", { className: "lc-overview-pct" }, /* @__PURE__ */ React.createElement("b", null, head.pct + "%"), t("overview.used")) : null), /* @__PURE__ */ React.createElement(StackedBar, { parts: head.parts, height: 16, max: head.window, hoverKey: hoverCat, onHoverKey: setHoverCat }), /* @__PURE__ */ React.createElement(Legend, { parts: head.parts, hoverKey: hoverCat, onHoverKey: setHoverCat }), data.toolList && data.toolList.length > 0 ? /* @__PURE__ */ React.createElement("div", { className: "lc-tools" }, t("tools.top"), data.toolList.slice().sort((a, b) => b.tokens - a.tokens).slice(0, 5).map((tool) => {
|
|
1392
1452
|
return /* @__PURE__ */ React.createElement("span", { key: tool.name, className: "lc-tool-chip" }, tool.name + " " + fmt3(tool.tokens));
|
|
1393
|
-
}), data.toolList.length > 5 ? /* @__PURE__ */ React.createElement("span", { className: "lc-card-sub" }, " " +
|
|
1453
|
+
}), data.toolList.length > 5 ? /* @__PURE__ */ React.createElement("span", { className: "lc-card-sub" }, " " + t("tools.more", { n: data.toolList.length })) : null) : null), /* @__PURE__ */ React.createElement("div", { className: "lc-card" }, /* @__PURE__ */ React.createElement("div", { className: "lc-card-title" }, /* @__PURE__ */ React.createElement("span", { className: "lc-card-title-text" }, t("trend.title")), /* @__PURE__ */ React.createElement("span", { className: "lc-card-sub" }, t("trend.hint")), /* @__PURE__ */ React.createElement("div", { className: "lc-gran" }, /* @__PURE__ */ React.createElement(
|
|
1394
1454
|
"button",
|
|
1395
1455
|
{
|
|
1396
1456
|
className: "lc-gran-btn" + (granularity === "step" ? " lc-gran-on" : ""),
|
|
@@ -1429,9 +1489,12 @@ function makeContextView(ctx, kit) {
|
|
|
1429
1489
|
headers,
|
|
1430
1490
|
useSession: props.useSession,
|
|
1431
1491
|
loadOlderHistory: props.loadOlderHistory,
|
|
1432
|
-
previewSeq: hoveredSeq
|
|
1492
|
+
previewSeq: hoveredSeq,
|
|
1493
|
+
pinSeq: pinnedReq !== null ? pinnedReq.seq : null,
|
|
1494
|
+
hoverKey: hoverCat,
|
|
1495
|
+
onHoverKey: setHoverCat
|
|
1433
1496
|
}
|
|
1434
|
-
))), /* @__PURE__ */ React.createElement("div", { className: "lc-cols" }, /* @__PURE__ */ React.createElement("div", { className: "lc-card lc-col" }, /* @__PURE__ */ React.createElement("div", { className: "lc-card-title" }, t("events.title"), /* @__PURE__ */ React.createElement("div", { className: "lc-kinds" }, EVENT_KINDS.map((k) => /* @__PURE__ */ React.createElement(
|
|
1497
|
+
))), /* @__PURE__ */ React.createElement("div", { className: "lc-cols" }, /* @__PURE__ */ React.createElement("div", { className: "lc-card lc-col" }, /* @__PURE__ */ React.createElement("div", { className: "lc-card-title" }, /* @__PURE__ */ React.createElement("span", { className: "lc-card-title-text" }, t("events.title")), /* @__PURE__ */ React.createElement("div", { className: "lc-kinds" }, EVENT_KINDS.map((k) => /* @__PURE__ */ React.createElement(
|
|
1435
1498
|
"button",
|
|
1436
1499
|
{
|
|
1437
1500
|
key: k,
|
|
@@ -1441,16 +1504,15 @@ function makeContextView(ctx, kit) {
|
|
|
1441
1504
|
}
|
|
1442
1505
|
},
|
|
1443
1506
|
t("kind." + k)
|
|
1444
|
-
)))), /* @__PURE__ */ React.createElement(EventList, { events: shownEvents })), /* @__PURE__ */ React.createElement("div", { className: "lc-card lc-col" }, /* @__PURE__ */ React.createElement("div", { className: "lc-card-title" }, t("nodes.title"), /* @__PURE__ */ React.createElement("span", { className: "lc-card-sub" }, t("nodes.hint"))), /* @__PURE__ */ React.createElement(NodeList, { nodes, dropped: data.droppedNodes || 0 }))), /* @__PURE__ */ React.createElement("div", { className: "lc-foot" }, t("footer")));
|
|
1507
|
+
)))), /* @__PURE__ */ React.createElement(EventList, { events: shownEvents })), /* @__PURE__ */ React.createElement("div", { className: "lc-card lc-col" }, /* @__PURE__ */ React.createElement("div", { className: "lc-card-title" }, /* @__PURE__ */ React.createElement("span", { className: "lc-card-title-text" }, t("nodes.title")), /* @__PURE__ */ React.createElement("span", { className: "lc-card-sub" }, t("nodes.hint"))), /* @__PURE__ */ React.createElement(NodeList, { nodes, dropped: data.droppedNodes || 0 }))), /* @__PURE__ */ React.createElement("div", { className: "lc-foot" }, t("footer")));
|
|
1445
1508
|
};
|
|
1446
1509
|
}
|
|
1447
1510
|
|
|
1448
1511
|
// src/client/viewkit.ts
|
|
1449
1512
|
function makeViewKit(t) {
|
|
1450
|
-
const { eventLabel, eventAt } = makeEventText(t
|
|
1513
|
+
const { eventLabel, eventAt } = makeEventText(t);
|
|
1451
1514
|
return {
|
|
1452
1515
|
t,
|
|
1453
|
-
tr: t,
|
|
1454
1516
|
fmt,
|
|
1455
1517
|
fmtTime,
|
|
1456
1518
|
catLabel: (key) => t("cat." + key),
|
package/lib/index.js
CHANGED
|
@@ -18,14 +18,7 @@ var Config = z.preprocess(
|
|
|
18
18
|
}).strict()
|
|
19
19
|
);
|
|
20
20
|
function resolveBounds(config) {
|
|
21
|
-
|
|
22
|
-
return {
|
|
23
|
-
maxRequestSteps: parsed.maxRequestSteps,
|
|
24
|
-
maxKeptTurns: parsed.maxKeptTurns,
|
|
25
|
-
maxEvents: parsed.maxEvents,
|
|
26
|
-
maxNodes: parsed.maxNodes,
|
|
27
|
-
maxArchiveNodes: parsed.maxArchiveNodes
|
|
28
|
-
};
|
|
21
|
+
return Config.parse(config ?? {});
|
|
29
22
|
}
|
|
30
23
|
|
|
31
24
|
// src/host/headers.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-context",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "A DeepSeek Harness plugin for context insight and management, with context dashboard and context command, for understanding how the context is made of, and how it evolves.",
|
|
5
5
|
"author": "bowenliang123",
|
|
6
6
|
"repository": {
|
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
"test": "npm run typecheck && node tests/host.test.mjs && node tests/client.test.mjs",
|
|
32
32
|
"release": "bash scripts/publish.sh",
|
|
33
33
|
"hooks": "bash scripts/install-hooks.sh",
|
|
34
|
-
"repro": "node tests/repro-real-react.mjs"
|
|
34
|
+
"repro": "node tests/repro-real-react.mjs",
|
|
35
|
+
"social-preview": "node docs/social-preview/generate.mjs"
|
|
35
36
|
},
|
|
36
37
|
"dsh": {
|
|
37
38
|
"bundle": {
|
|
@@ -58,7 +59,6 @@
|
|
|
58
59
|
],
|
|
59
60
|
"license": "Apache-2.0",
|
|
60
61
|
"dependencies": {
|
|
61
|
-
"playwright-core": "^1.62.1",
|
|
62
62
|
"zod": "^4.4.3"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
@@ -70,6 +70,7 @@
|
|
|
70
70
|
"@types/react": "^18.3.31",
|
|
71
71
|
"esbuild": "^0.28.2",
|
|
72
72
|
"jsdom": "^30.0.1",
|
|
73
|
+
"playwright-core": "^1.62.1",
|
|
73
74
|
"react": "^18.3.1",
|
|
74
75
|
"react-dom": "^18.3.1",
|
|
75
76
|
"typescript": "^7.0.2"
|