dsh-context 0.26.1 → 0.28.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 +106 -29
- package/lib/index.d.ts +24 -10
- package/lib/index.js +61 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -69,7 +69,7 @@ In **Step** granularity, hovering any bar shows that single step's context info
|
|
|
69
69
|
|
|
70
70
|
### ⚡ Context events — when and why the window changed
|
|
71
71
|
|
|
72
|
-
Every compaction, tool-output prune, skill or plugin context injection,
|
|
72
|
+
Every compaction, tool-output prune, skill or plugin context injection, model switch, and plan-mode toggle — each labeled with its producer source (instruction file paths, plugin id, skill name), its token delta (compactions/prunes show the **net** reclaimed amount, matching the chart's drop), turn/step attribution, and timestamp. Filter by category (**Inject / Compact / Prune / Switch / Mode**) to see exactly when each kind of event happened and its impact — e.g. when a skill was injected, when instructions were added, or how much a compaction reclaimed:
|
|
73
73
|
|
|
74
74
|

|
|
75
75
|
|
package/lib/client.js
CHANGED
|
@@ -20,12 +20,13 @@ window.__ModuleLoader__.load({
|
|
|
20
20
|
"overview.ofUsed": "占已用上下文",
|
|
21
21
|
"overview.compactReserve": "自动压缩预留:占用达 {pct}% 窗口时触发压缩,此区域一般不实际占用",
|
|
22
22
|
"stats.title": "上下文统计",
|
|
23
|
-
"stats.hint": "
|
|
23
|
+
"stats.hint": "当前上下文存在和包含的内容",
|
|
24
24
|
"stats.turns": "轮次",
|
|
25
25
|
"stats.steps": "步数",
|
|
26
26
|
"stats.injects": "注入",
|
|
27
27
|
"stats.compactions": "压缩",
|
|
28
28
|
"stats.prunes": "剪枝",
|
|
29
|
+
"stats.toolCalls": "工具调用",
|
|
29
30
|
"stats.images": "图片",
|
|
30
31
|
"stats.cacheHit": "缓存命中",
|
|
31
32
|
"stats.cost": "预估费用",
|
|
@@ -63,6 +64,7 @@ window.__ModuleLoader__.load({
|
|
|
63
64
|
"kind.compaction": "压缩",
|
|
64
65
|
"kind.prune": "剪枝",
|
|
65
66
|
"kind.model": "切换",
|
|
67
|
+
"kind.mode": "模式",
|
|
66
68
|
"nodes.title": "消息构成",
|
|
67
69
|
"nodes.hint": "当前模型可见的消息,最新在前",
|
|
68
70
|
"nodes.more": "… 更早的 {n} 条消息已省略",
|
|
@@ -80,6 +82,8 @@ window.__ModuleLoader__.load({
|
|
|
80
82
|
"ev.prune": "剪枝工具输出",
|
|
81
83
|
"ev.skill": "Skill 注入({name})",
|
|
82
84
|
"ev.model": "模型切换:{a} → {b}",
|
|
85
|
+
"ev.mode.plan.on": "进入计划模式",
|
|
86
|
+
"ev.mode.plan.off": "退出计划模式",
|
|
83
87
|
"form.instructions": "指令注入",
|
|
84
88
|
"form.catalog": "目录更新",
|
|
85
89
|
"form.snapshot": "状态快照",
|
|
@@ -125,6 +129,8 @@ window.__ModuleLoader__.load({
|
|
|
125
129
|
"attach.other": "其他内容",
|
|
126
130
|
"attach.image": "图片",
|
|
127
131
|
"attach.open": "查看原图",
|
|
132
|
+
"attach.preview": "图片预览",
|
|
133
|
+
"attach.close": "关闭",
|
|
128
134
|
"attach.loading": "…",
|
|
129
135
|
"attach.loadFailed": "加载失败 · 点击重试",
|
|
130
136
|
"attach.raw": "原图",
|
|
@@ -147,12 +153,13 @@ window.__ModuleLoader__.load({
|
|
|
147
153
|
"overview.ofUsed": "of used context",
|
|
148
154
|
"overview.compactReserve": "Auto-compaction reserve: auto-compaction triggers at {pct}% of the window — this area is normally kept as headroom, not actually used",
|
|
149
155
|
"stats.title": "Context Stats",
|
|
150
|
-
"stats.hint": "
|
|
156
|
+
"stats.hint": "Present in the current context",
|
|
151
157
|
"stats.turns": "Turns",
|
|
152
158
|
"stats.steps": "Steps",
|
|
153
159
|
"stats.injects": "Injections",
|
|
154
160
|
"stats.compactions": "Compactions",
|
|
155
161
|
"stats.prunes": "Prunes",
|
|
162
|
+
"stats.toolCalls": "Tool Calls",
|
|
156
163
|
"stats.images": "Images",
|
|
157
164
|
"stats.cacheHit": "Cache Hit",
|
|
158
165
|
"stats.cost": "Cost",
|
|
@@ -190,6 +197,7 @@ window.__ModuleLoader__.load({
|
|
|
190
197
|
"kind.compaction": "Compact",
|
|
191
198
|
"kind.prune": "Prune",
|
|
192
199
|
"kind.model": "Switch",
|
|
200
|
+
"kind.mode": "Mode",
|
|
193
201
|
"nodes.title": "Messages",
|
|
194
202
|
"nodes.hint": "currently model-visible, newest first",
|
|
195
203
|
"nodes.more": "… {n} earlier messages omitted",
|
|
@@ -207,6 +215,8 @@ window.__ModuleLoader__.load({
|
|
|
207
215
|
"ev.prune": "Tool output pruned",
|
|
208
216
|
"ev.skill": "Skill injected ({name})",
|
|
209
217
|
"ev.model": "Model switched: {a} → {b}",
|
|
218
|
+
"ev.mode.plan.on": "Plan mode on",
|
|
219
|
+
"ev.mode.plan.off": "Plan mode off",
|
|
210
220
|
"form.instructions": "Instructions",
|
|
211
221
|
"form.catalog": "Catalog Update",
|
|
212
222
|
"form.snapshot": "State Snapshot",
|
|
@@ -252,6 +262,8 @@ window.__ModuleLoader__.load({
|
|
|
252
262
|
"attach.other": "Other content",
|
|
253
263
|
"attach.image": "Image",
|
|
254
264
|
"attach.open": "Open full image",
|
|
265
|
+
"attach.preview": "Image preview",
|
|
266
|
+
"attach.close": "Close",
|
|
255
267
|
"attach.loading": "…",
|
|
256
268
|
"attach.loadFailed": "Load failed · click to retry",
|
|
257
269
|
"attach.raw": "Raw",
|
|
@@ -541,6 +553,7 @@ window.__ModuleLoader__.load({
|
|
|
541
553
|
nodes: objectsOf(data.nodes),
|
|
542
554
|
droppedNodes: numOf(data.droppedNodes),
|
|
543
555
|
...typeof data.images === "number" ? { images: data.images } : {},
|
|
556
|
+
...typeof data.toolCalls === "number" ? { toolCalls: data.toolCalls } : {},
|
|
544
557
|
archive: objectsOf(data.archive),
|
|
545
558
|
...cost !== void 0 ? { cost } : {},
|
|
546
559
|
...typeof data.surfaceFloor === "number" ? { surfaceFloor: data.surfaceFloor } : {},
|
|
@@ -649,6 +662,7 @@ window.__ModuleLoader__.load({
|
|
|
649
662
|
//#region src/client/react.ts
|
|
650
663
|
const React = require("react");
|
|
651
664
|
const h = React.createElement;
|
|
665
|
+
const ReactDOM = require("react-dom");
|
|
652
666
|
//#endregion
|
|
653
667
|
//#region src/client/components/nodes.tsx
|
|
654
668
|
/** One-line preview of a surface node (shared by the node list and the Context browser's element rows). */
|
|
@@ -873,12 +887,58 @@ window.__ModuleLoader__.load({
|
|
|
873
887
|
};
|
|
874
888
|
}
|
|
875
889
|
/**
|
|
876
|
-
*
|
|
877
|
-
*
|
|
878
|
-
*
|
|
879
|
-
*
|
|
880
|
-
*
|
|
881
|
-
*
|
|
890
|
+
* Document-level original-image preview — the chat history's ImageLightbox
|
|
891
|
+
* recipe (dsh ui-attachment, which the browser module table does not seed)
|
|
892
|
+
* ported onto the plugin's lc-* classes: body portal so a transformed or
|
|
893
|
+
* filtered ancestor cannot trap the fixed backdrop, blurred mask layer,
|
|
894
|
+
* contain-fit image, circular close control, Escape/mask close, and focus
|
|
895
|
+
* restored to the opener on unmount.
|
|
896
|
+
*/
|
|
897
|
+
function AttachmentLightbox(props) {
|
|
898
|
+
const { src, alt, labels, onClose } = props;
|
|
899
|
+
const closeRef = React.useRef(null);
|
|
900
|
+
const restoreRef = React.useRef(null);
|
|
901
|
+
React.useEffect(() => {
|
|
902
|
+
restoreRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
903
|
+
closeRef.current?.focus();
|
|
904
|
+
const onKeyDown = (event) => {
|
|
905
|
+
if (event.key === "Escape") onClose();
|
|
906
|
+
};
|
|
907
|
+
window.addEventListener("keydown", onKeyDown);
|
|
908
|
+
return () => {
|
|
909
|
+
window.removeEventListener("keydown", onKeyDown);
|
|
910
|
+
restoreRef.current?.focus();
|
|
911
|
+
};
|
|
912
|
+
}, [onClose]);
|
|
913
|
+
return ReactDOM.createPortal(/* @__PURE__ */ React.createElement("div", {
|
|
914
|
+
className: "lc-att-lightbox",
|
|
915
|
+
role: "dialog",
|
|
916
|
+
"aria-modal": "true",
|
|
917
|
+
"aria-label": labels.dialog
|
|
918
|
+
}, /* @__PURE__ */ React.createElement("div", {
|
|
919
|
+
className: "lc-att-lightbox-mask",
|
|
920
|
+
"aria-hidden": "true",
|
|
921
|
+
onMouseDown: onClose
|
|
922
|
+
}), /* @__PURE__ */ React.createElement("img", {
|
|
923
|
+
className: "lc-att-lightbox-img",
|
|
924
|
+
src,
|
|
925
|
+
alt
|
|
926
|
+
}), /* @__PURE__ */ React.createElement("button", {
|
|
927
|
+
ref: closeRef,
|
|
928
|
+
type: "button",
|
|
929
|
+
className: "lc-att-lightbox-close",
|
|
930
|
+
"aria-label": labels.close,
|
|
931
|
+
onClick: onClose
|
|
932
|
+
}, /* @__PURE__ */ React.createElement(_deepseek_ai_dsh_client_ui_primitives.IconCloseOutline16, { size: 16 }))), document.body);
|
|
933
|
+
}
|
|
934
|
+
/**
|
|
935
|
+
* One attachment card: the WHOLE card is the click target — a 64px cover
|
|
936
|
+
* tile beside a metadata column (display name, then one labeled row per
|
|
937
|
+
* known fact: Raw, the pre-normalization raster dsh 0.1.1 records when
|
|
938
|
+
* normalization reduced the image; Sent, the normalized raster the model
|
|
939
|
+
* receives, with its stored byte size; and the estimated provider-billed
|
|
940
|
+
* tokens). Clicking opens the chat-style lightbox preview (load failures
|
|
941
|
+
* retry on click instead). Unknown facts leave no row behind.
|
|
882
942
|
*/
|
|
883
943
|
function makeImageCard(kit) {
|
|
884
944
|
const { t, fmt } = kit;
|
|
@@ -887,6 +947,10 @@ window.__ModuleLoader__.load({
|
|
|
887
947
|
const [src, setSrc] = React.useState(null);
|
|
888
948
|
const [error, setError] = React.useState(false);
|
|
889
949
|
const [attempt, setAttempt] = React.useState(0);
|
|
950
|
+
const [preview, setPreview] = React.useState(false);
|
|
951
|
+
const closePreview = React.useCallback(() => {
|
|
952
|
+
setPreview(false);
|
|
953
|
+
}, []);
|
|
890
954
|
React.useEffect(() => {
|
|
891
955
|
if (load === void 0) return;
|
|
892
956
|
let live = true;
|
|
@@ -924,30 +988,37 @@ window.__ModuleLoader__.load({
|
|
|
924
988
|
value: `≈${fmt(tokens)}`,
|
|
925
989
|
tip: t("attach.tokensTip")
|
|
926
990
|
});
|
|
927
|
-
const
|
|
928
|
-
if (
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
}
|
|
991
|
+
const activate = () => {
|
|
992
|
+
if (error) {
|
|
993
|
+
setAttempt((a) => a + 1);
|
|
994
|
+
return;
|
|
995
|
+
}
|
|
996
|
+
if (src !== null) setPreview(true);
|
|
932
997
|
};
|
|
933
|
-
return /* @__PURE__ */ React.createElement(
|
|
998
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("button", {
|
|
934
999
|
type: "button",
|
|
935
|
-
className: "lc-att-
|
|
1000
|
+
className: "lc-att-item",
|
|
936
1001
|
title: error ? t("attach.loadFailed") : t("attach.open"),
|
|
937
|
-
onClick:
|
|
938
|
-
|
|
939
|
-
} : open
|
|
940
|
-
}, src !== null ? /* @__PURE__ */ React.createElement("img", {
|
|
1002
|
+
onClick: activate
|
|
1003
|
+
}, /* @__PURE__ */ React.createElement("span", { className: "lc-att-thumb" }, src !== null ? /* @__PURE__ */ React.createElement("img", {
|
|
941
1004
|
src,
|
|
942
1005
|
alt: name
|
|
943
|
-
}) : /* @__PURE__ */ React.createElement("span", { className: error ? "lc-att-err" : "lc-att-ph" }, error ? "⚠" : load === void 0 ? "🖼" : t("attach.loading"))), /* @__PURE__ */ React.createElement("
|
|
1006
|
+
}) : /* @__PURE__ */ React.createElement("span", { className: error ? "lc-att-err" : "lc-att-ph" }, error ? "⚠" : load === void 0 ? "🖼" : t("attach.loading"))), /* @__PURE__ */ React.createElement("span", { className: "lc-att-meta" }, /* @__PURE__ */ React.createElement("span", {
|
|
944
1007
|
className: "lc-att-name",
|
|
945
1008
|
title: name
|
|
946
1009
|
}, name), rows.map((r) => /* @__PURE__ */ React.createElement("span", {
|
|
947
1010
|
key: r.label,
|
|
948
1011
|
className: "lc-att-row",
|
|
949
1012
|
title: r.tip
|
|
950
|
-
}, /* @__PURE__ */ React.createElement("b", { className: "lc-att-row-label" }, r.label), r.value))))
|
|
1013
|
+
}, /* @__PURE__ */ React.createElement("b", { className: "lc-att-row-label" }, r.label), r.value)))), preview && src !== null && /* @__PURE__ */ React.createElement(AttachmentLightbox, {
|
|
1014
|
+
src,
|
|
1015
|
+
alt: name,
|
|
1016
|
+
labels: {
|
|
1017
|
+
dialog: t("attach.preview"),
|
|
1018
|
+
close: t("attach.close")
|
|
1019
|
+
},
|
|
1020
|
+
onClose: closePreview
|
|
1021
|
+
}));
|
|
951
1022
|
};
|
|
952
1023
|
}
|
|
953
1024
|
//#endregion
|
|
@@ -1864,7 +1935,8 @@ window.__ModuleLoader__.load({
|
|
|
1864
1935
|
compaction: "✂",
|
|
1865
1936
|
prune: "✂",
|
|
1866
1937
|
inject: "+",
|
|
1867
|
-
model: "⇄"
|
|
1938
|
+
model: "⇄",
|
|
1939
|
+
mode: "⇄"
|
|
1868
1940
|
};
|
|
1869
1941
|
/** Build the event text helpers bound to the translate function. */
|
|
1870
1942
|
function makeEventText(t) {
|
|
@@ -1875,9 +1947,12 @@ window.__ModuleLoader__.load({
|
|
|
1875
1947
|
a: ev.from || "?",
|
|
1876
1948
|
b: ev.to || "?"
|
|
1877
1949
|
});
|
|
1950
|
+
if (ev.kind === "mode") return t("ev.mode." + (ev.name || "?"));
|
|
1878
1951
|
if (ev.sub === "skill") return t("ev.skill", { name: ev.name || "?" });
|
|
1879
1952
|
const base = t("form." + (ev.form || "context"));
|
|
1880
|
-
|
|
1953
|
+
let label = ev.name ? base + " · " + ev.name : base;
|
|
1954
|
+
if (ev.detail) label += " · " + ev.detail;
|
|
1955
|
+
return label;
|
|
1881
1956
|
}
|
|
1882
1957
|
/**
|
|
1883
1958
|
* Where this event sits in the request timeline, as a label or null.
|
|
@@ -2001,7 +2076,7 @@ window.__ModuleLoader__.load({
|
|
|
2001
2076
|
return function PluginInfo() {
|
|
2002
2077
|
const [latest, setLatest] = React.useState(null);
|
|
2003
2078
|
React.useEffect(() => {
|
|
2004
|
-
if ("0.
|
|
2079
|
+
if ("0.28.0".includes("-dev")) return;
|
|
2005
2080
|
let on = true;
|
|
2006
2081
|
fetchLatestVersion().then((v) => {
|
|
2007
2082
|
if (on && v) setLatest(v);
|
|
@@ -2010,8 +2085,8 @@ window.__ModuleLoader__.load({
|
|
|
2010
2085
|
on = false;
|
|
2011
2086
|
};
|
|
2012
2087
|
}, []);
|
|
2013
|
-
const update = latest !== null && isNewerVersion(latest, "0.
|
|
2014
|
-
const nameValue = ["dsh-context (v0.
|
|
2088
|
+
const update = latest !== null && isNewerVersion(latest, "0.28.0") ? latest : null;
|
|
2089
|
+
const nameValue = ["dsh-context (v0.28.0)"];
|
|
2015
2090
|
if (update) nameValue.push(/* @__PURE__ */ React.createElement("span", {
|
|
2016
2091
|
key: "update",
|
|
2017
2092
|
className: "lc-pi-update"
|
|
@@ -2210,7 +2285,7 @@ window.__ModuleLoader__.load({
|
|
|
2210
2285
|
className: "lc-stat-tip",
|
|
2211
2286
|
role: "tooltip"
|
|
2212
2287
|
}, tip));
|
|
2213
|
-
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"), fmt(turns.size)), cell(t("stats.steps"), fmt(steps)), cell(t("stats.injects"), fmt(injects)), cell(t("stats.compactions"), fmt(compactions)), cell(t("stats.prunes"), fmt(prunes)), cell(t("stats.images"), fmt(props.images ?? 0)), cell(t("stats.cacheHit"), hit === null ? "—" : hit + "%"), cell(t("stats.cost"), cost === null ? "—" : formatCost(cost, currency), costTip)));
|
|
2288
|
+
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"), fmt(turns.size)), cell(t("stats.steps"), fmt(steps)), cell(t("stats.injects"), fmt(injects)), cell(t("stats.compactions"), fmt(compactions)), cell(t("stats.prunes"), fmt(prunes)), cell(t("stats.toolCalls"), fmt(props.toolCalls ?? 0)), cell(t("stats.images"), fmt(props.images ?? 0)), cell(t("stats.cacheHit"), hit === null ? "—" : hit + "%"), cell(t("stats.cost"), cost === null ? "—" : formatCost(cost, currency), costTip)));
|
|
2214
2289
|
};
|
|
2215
2290
|
}
|
|
2216
2291
|
//#endregion
|
|
@@ -2463,7 +2538,8 @@ window.__ModuleLoader__.load({
|
|
|
2463
2538
|
"inject",
|
|
2464
2539
|
"compaction",
|
|
2465
2540
|
"prune",
|
|
2466
|
-
"model"
|
|
2541
|
+
"model",
|
|
2542
|
+
"mode"
|
|
2467
2543
|
];
|
|
2468
2544
|
function makeContextView(ctx, kit) {
|
|
2469
2545
|
const { t } = kit;
|
|
@@ -2576,6 +2652,7 @@ window.__ModuleLoader__.load({
|
|
|
2576
2652
|
requests,
|
|
2577
2653
|
events,
|
|
2578
2654
|
usage,
|
|
2655
|
+
toolCalls: data.toolCalls,
|
|
2579
2656
|
images: data.images,
|
|
2580
2657
|
cost: data.cost,
|
|
2581
2658
|
locale: activeLocale
|
|
@@ -2674,7 +2751,7 @@ window.__ModuleLoader__.load({
|
|
|
2674
2751
|
}
|
|
2675
2752
|
//#endregion
|
|
2676
2753
|
//#region \0dsh-global-css:/home/runner/work/dsh-context/dsh-context/src/client/styles.css.mjs
|
|
2677
|
-
const css = ".lc-root{box-sizing:border-box;height:100%;color:var(--dsw-alias-label-primary);padding:16px 20px 32px;font-size:13px;overflow-y:auto}.lc-card{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);border-radius:10px;margin-bottom:14px;padding:14px 16px}.lc-card-title{align-items:baseline;gap:8px;margin-bottom:10px;font-weight:600;display:flex}.lc-card-title-text{white-space:nowrap;flex:none}.lc-stats{grid-template-columns:repeat(auto-fit,minmax(76px,1fr));gap:8px;display:grid}.lc-stat{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:8px;flex-direction:column;gap:2px;min-width:0;padding:8px;display:flex}.lc-stat-label{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;font-weight:600;overflow:hidden}.lc-stat-value{color:var(--dsw-alias-label-primary);white-space:nowrap;text-overflow:ellipsis;text-align:center;font-size:14px;font-weight:600;overflow:hidden}.lc-stat-sub{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;overflow:hidden}.lc-stat-tipped{position:relative}.lc-stat-q{text-align:center;width:11px;height:11px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);cursor:help;border-radius:50%;margin-left:4px;font-size:9px;font-style:normal;font-weight:700;line-height:11px;display:inline-block}.lc-stat-tipped:hover .lc-stat-q{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-primary)}.lc-stat-tip{z-index:6;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);width:max-content;max-width:280px;color:var(--dsw-alias-label-primary);pointer-events:none;opacity:0;border-radius:6px;padding:6px 10px;font-size:12px;font-weight:400;line-height:1.5;transition:opacity .12s;position:absolute;top:calc(100% + 6px);left:0;box-shadow:0 2px 8px #0000002e}.lc-stat-tipped:hover .lc-stat-tip{opacity:1}.lc-stat-tip-prices{border-top:1px dashed var(--dsw-alias-border-l1);margin-top:5px;padding-top:5px;display:block}.lc-stat-tip-head{font-weight:600;display:block}.lc-stat-tip-row{margin-top:2px;display:block}.lc-stat-tip-model{color:var(--dsw-alias-label-primary)}.lc-card-sub{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:400}.lc-gran,.lc-kinds{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:6px;gap:2px;margin-left:auto;padding:1px;display:flex}.lc-trend-ctl{align-items:center;gap:6px;margin-left:auto;display:flex}.lc-trend-ctl .lc-gran{margin-left:0}.lc-gran-btn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:5px;padding:3px 8px;font-family:inherit;font-size:11px;line-height:1}.lc-gran-btn:hover{color:var(--dsw-alias-label-primary)}.lc-gran-on,.lc-gran-on:hover{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}.lc-overview-num{align-items:baseline;gap:6px;margin-bottom:8px;display:flex}.lc-overview-num>b{font-size:20px}.lc-overview-num span{color:var(--dsw-alias-label-secondary)}.lc-overview-pct{margin-left:auto;font-size:11px}.lc-overview-pct b{color:var(--dsw-alias-label-primary);margin-right:4px;font-size:20px}.lc-stacked-wrap{width:100%;position:relative}.lc-stacked{background:#8080802e;border-radius:5px;width:100%;display:flex;position:relative;overflow:hidden}.lc-occupied-box{border:2px solid var(--dsw-alias-label-tertiary);box-sizing:border-box;pointer-events:none;opacity:0;box-shadow:0 0 0 1px var(--dsw-alias-bg-layer-2);border-radius:5px;transition:opacity .12s;position:absolute;top:0;bottom:0;left:0}.lc-occupied-box-on{opacity:1}.lc-bar-tip{z-index:5;white-space:nowrap;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);pointer-events:none;opacity:0;border-radius:6px;padding:3px 8px;font-size:12px;transition:opacity .12s;position:absolute;bottom:calc(100% + 6px);transform:translate(-50%);box-shadow:0 2px 8px #0000002e}.lc-bar-tip-on{opacity:1}.lc-stacked>div{height:100%}.lc-stacked-seg{transition:filter .12s,opacity .12s}.lc-stacked-free{box-sizing:border-box;transition:box-shadow .12s,opacity .12s}.lc-stacked-seg-on{filter:brightness(1.18)}.lc-reserve{z-index:1;pointer-events:auto;cursor:help;background:repeating-linear-gradient(45deg, color-mix(in srgb, var(--dsw-alias-state-warn-primary) 24%, transparent) 0 5px, transparent 5px 10px);position:absolute;top:0;bottom:0}.lc-stacked-free-on{border:2px dashed var(--dsw-alias-label-secondary);border-radius:3px}.lc-stacked-dim .lc-stacked-seg{opacity:.35}.lc-stacked-dim .lc-stacked-seg-on{opacity:1}.lc-stacked-dim .lc-stacked-free{opacity:.35}.lc-stacked-dim .lc-stacked-free-on{opacity:1}.lc-legend{grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:6px 14px;margin-top:10px;display:grid}.lc-chip{min-width:0;color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;align-items:center;gap:5px;padding:1px 6px;transition:background-color .12s;display:flex}.lc-chip-label{white-space:nowrap;text-overflow:ellipsis;min-width:0;font-weight:600;overflow:hidden}.lc-chip-nums{white-space:nowrap;flex:none;align-items:baseline;gap:6px;margin-left:auto;display:inline-flex}.lc-chip i,.lc-detail-row i,.lc-node i{border-radius:2px;width:8px;height:8px;display:inline-block}.lc-chip i{transition:box-shadow .12s}.lc-chip em{color:var(--dsw-alias-label-secondary);font-style:normal}.lc-chip-on{background:var(--dsw-alias-interactive-bg-hover);font-weight:600}.lc-chip-on i{box-shadow:0 0 0 1px var(--dsw-alias-brand-primary)}.lc-tools{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;align-items:center;gap:6px;margin-top:10px;display:flex}.lc-tools-label,.lc-tools-more{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;padding:0;font-family:inherit;font-size:12px}.lc-tools-label:hover,.lc-tools-more:hover{text-decoration:underline}.lc-tool-chip{background:var(--dsw-alias-bg-layer-2);font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:0;border-radius:4px;padding:1px 7px;font-size:12px}.lc-tool-chip:hover{text-decoration:underline}.lc-chartrow{align-items:stretch;gap:6px;display:flex}.lc-axis{box-sizing:border-box;width:40px;height:150px;color:var(--dsw-alias-label-secondary);padding-top:18px;font-size:11px;position:relative}.lc-axis span{line-height:1;position:absolute;right:0}.lc-axis-top{top:13px}.lc-axis-mid{top:69px}.lc-axis-bot{top:125px}.lc-chart-scroll{scrollbar-width:thin;flex:1;min-width:0;padding-bottom:8px;position:relative;overflow:auto hidden}.lc-chart-fade{pointer-events:none;z-index:2;width:26px;position:absolute;top:0;bottom:0}.lc-chart-fade-l{background:linear-gradient(to right, var(--dsw-alias-bg-layer-1), transparent);left:0}.lc-chart-fade-r{background:linear-gradient(to left, var(--dsw-alias-bg-layer-1), transparent);right:0}.lc-chart{box-sizing:border-box;align-items:flex-end;gap:2px;width:max-content;min-width:100%;height:130px;padding-top:18px;display:flex;position:relative}.lc-grid{border-top:1px dashed var(--dsw-alias-border-l1);pointer-events:none;position:absolute;left:0;right:0}.lc-grid-top{top:18px}.lc-grid-mid{top:74px}.lc-bar{cursor:pointer;border-radius:2px;flex:none;align-items:flex-end;width:14px;height:100%;transition:opacity .12s,background-color .12s;display:flex;position:relative}.lc-chart-dim .lc-bar{opacity:.35}.lc-chart-dim .lc-bar-in-turn{opacity:1}.lc-chart-dim .lc-turn{opacity:.35}.lc-chart-dim .lc-turn-on{opacity:1}.lc-chart-tip{z-index:5;white-space:nowrap;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);pointer-events:none;border-radius:6px;padding:3px 8px;font-size:12px;position:absolute;top:0;transform:translate(-50%);box-shadow:0 2px 8px #0000002e}.lc-bar:hover{background:var(--dsw-alias-bg-layer-2)}.lc-bar-hovered{outline:1px dashed var(--dsw-alias-brand-primary);outline-offset:1px}.lc-bar-selected{outline:2px solid var(--dsw-alias-label-primary);outline-offset:1px}.lc-bar-in-turn{background:#80808024}.lc-bar-stack{flex-direction:column-reverse;width:100%;display:flex}.lc-bar-stack>div{width:100%}.lc-bar-marker{color:var(--dsw-alias-state-warn-primary);font-size:11px;position:absolute;top:-16px;left:50%;transform:translate(-50%)}.lc-turns{gap:2px;width:max-content;min-width:100%;margin-top:4px;display:flex}.lc-turn{box-sizing:border-box;text-align:center;color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;cursor:pointer;border-radius:3px;flex:none;height:14px;font-size:10px;font-weight:600;line-height:14px;transition:filter .12s,opacity .12s;overflow:hidden}.lc-turn-on{filter:brightness(1.35);color:var(--dsw-alias-label-primary)}.lc-detail{border-top:1px solid var(--dsw-alias-border-l1);margin-top:12px;padding-top:12px}.lc-detail-head{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;gap:6px 16px;margin-bottom:8px;display:flex}.lc-detail-head b{color:var(--dsw-alias-label-primary)}.lc-detail-marker{color:var(--dsw-alias-state-warn-primary);background:var(--dsw-alias-bg-layer-2);border-radius:6px;padding:1px 7px;font-size:11px}.lc-detail-head .lc-actual{color:var(--dsw-alias-state-success-primary)}.lc-detail-tag{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary);border-radius:4px;padding:0 6px;font-size:11px}.lc-detail-rows{grid-template-columns:1fr 1fr;gap:4px 24px;margin-top:10px;display:grid}.lc-detail-row{align-items:center;gap:8px;display:flex}.lc-detail-label{white-space:nowrap;min-width:70px;color:var(--dsw-alias-label-secondary)}.lc-bar-track{background:#8080802e;border-radius:3px;flex:1;height:5px;display:block;overflow:hidden}.lc-bar-fill{border-radius:3px;height:100%;display:block}.lc-detail-num{text-align:right;width:44px}.lc-detail-pct{text-align:right;width:34px;color:var(--dsw-alias-label-secondary)}.lc-cols{flex-wrap:wrap;gap:14px;margin-bottom:14px;display:flex}.lc-col{flex:1;min-width:280px}.lc-cols>.lc-card,.lc-col>.lc-card:last-child{margin-bottom:0}.lc-col-browser{flex-direction:column;display:flex}.lc-col-browser>.lc-card{flex:1}.lc-head>.lc-card:first-child{flex:7 1 0;min-width:360px}.lc-head>.lc-card:last-child{flex:3 1 0;min-width:220px}.lc-pi-grid{grid-template-columns:1fr;gap:8px;display:grid}.lc-pi-row{min-width:0;color:inherit;flex-direction:row;justify-content:space-between;align-items:baseline;gap:12px;text-decoration:none;display:flex}.lc-pi-row:hover .lc-pi-value{text-decoration:underline}.lc-pi-update{color:var(--dsw-alias-state-warn-primary);white-space:nowrap;margin-left:6px;font-size:11px}.lc-pi-label{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;flex:none;font-size:11px;font-weight:600;overflow:hidden}.lc-pi-value{min-width:0;color:var(--dsw-alias-label-primary);white-space:nowrap;text-overflow:ellipsis;text-align:right;font-size:13px;font-weight:600;overflow:hidden}.lc-events,.lc-nodes{flex-direction:column;gap:2px;max-height:320px;display:flex;overflow-y:auto}.lc-event{align-items:center;gap:8px;padding:3px 0;display:flex}.lc-event-icon{text-align:center;width:18px;color:var(--dsw-alias-state-warn-primary)}.lc-event-icon.lc-event-inject{color:#a855f7}.lc-event-icon.lc-event-model{color:var(--dsw-alias-brand-primary)}.lc-kind{white-space:nowrap;border-radius:4px;flex:none;padding:1px 6px;font-size:10px;font-weight:600}.lc-kind-inject{background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 15%, transparent);color:var(--dsw-alias-state-success-primary)}.lc-kind-compaction{background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 15%, transparent);color:var(--dsw-alias-state-error-primary)}.lc-kind-prune{color:#8b5cf6;background:#8b5cf626}.lc-kind-model{background:color-mix(in srgb, var(--dsw-alias-brand-primary) 15%, transparent);color:var(--dsw-alias-brand-primary)}.lc-event-label{text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}.lc-event-at{color:var(--dsw-alias-label-secondary);white-space:nowrap;flex:none;font-size:11px}.lc-event-tokens{color:var(--dsw-alias-state-success-primary);white-space:nowrap;font-weight:600}.lc-event-tokens.lc-up{color:var(--dsw-alias-state-warn-primary)}.lc-event-time{color:var(--dsw-alias-label-secondary);font-size:12px}.lc-node{align-items:center;gap:8px;padding:3px 0;display:flex}.lc-node-preview{text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-primary);flex:1;overflow:hidden}.lc-node-time{color:var(--dsw-alias-label-secondary);text-align:right;min-width:54px;font-size:12px}.lc-node-tokens{color:var(--dsw-alias-label-secondary)}.lc-nodes-more{color:var(--dsw-alias-label-secondary);padding:3px 0}.lc-empty{color:var(--dsw-alias-label-secondary);text-align:center;padding:18px 0}.lc-error{flex-direction:column;align-items:center;gap:8px;padding:40px 16px;display:flex}.lc-error-msg{color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);overflow-wrap:anywhere;border-radius:6px;max-width:100%;padding:4px 8px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}.lc-error-retry{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;border-radius:6px;padding:4px 14px;font-size:12px}.lc-error-retry:hover{border-color:var(--dsw-alias-label-primary)}.lc-foot{color:var(--dsw-alias-label-secondary);margin-top:4px;font-size:12px}.lc-modal-backdrop{z-index:200;background:#00000073;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.lc-modal-card{box-sizing:border-box;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);width:min(720px,100vw - 48px);max-height:min(82vh,760px);box-shadow:var(--dsw-shadow-lv3,0 12px 32px #0006);color:var(--dsw-alias-label-primary);border-radius:12px;padding:16px 18px 18px;font-size:13px;overflow-y:auto}.lc-modal-head{align-items:baseline;gap:8px;margin-bottom:12px;display:flex}.lc-modal-title{font-size:14px;font-weight:600}.lc-modal-close{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:6px;margin-left:auto;padding:2px 6px;font-family:inherit;font-size:18px;line-height:1}.lc-modal-close:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}.lc-br-hint{color:var(--dsw-alias-label-secondary);white-space:nowrap;margin-left:auto;font-size:11px;font-weight:400}.lc-br-pick{font:inherit;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:6px;max-width:240px;padding:3px 6px;font-size:12px}.lc-br-meta{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;gap:6px 16px;margin-bottom:8px;display:flex}.lc-br-meta b{color:var(--dsw-alias-label-primary)}.lc-br-meta .lc-actual{color:var(--dsw-alias-state-success-primary)}.lc-br-note{color:var(--dsw-alias-label-secondary);margin-top:8px;font-size:12px}.lc-br-cats{flex-direction:column;gap:4px;margin-top:10px;display:flex}.lc-br-cat{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);border-radius:8px;overflow:hidden}.lc-br-cat-empty{opacity:.55}.lc-br-cat-row{width:100%;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;text-align:left;background:0 0;border:0;align-items:center;gap:8px;padding:7px 10px;transition:background-color .12s;display:flex}.lc-br-cat-row:hover,.lc-br-cat-on{background:var(--dsw-alias-interactive-bg-hover)}.lc-br-cat-on i{box-shadow:0 0 0 1px var(--dsw-alias-brand-primary)}.lc-br-cat-row i{border-radius:2px;flex:none;width:8px;height:8px;transition:box-shadow .12s;display:inline-block}.lc-br-cat-label{font-weight:600}.lc-br-cat-count{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:12px}.lc-br-count-grp{flex:1;align-items:center;gap:4px;min-width:0;display:inline-flex}.lc-br-chev{width:12px;color:var(--dsw-alias-label-secondary);flex:none;transition:transform .12s}.lc-br-chev-on{transform:rotate(90deg)}.lc-br-tokens{color:var(--dsw-alias-label-secondary);flex:none;font-size:12px}.lc-br-delta,.lc-br-tdelta{white-space:nowrap;border-radius:4px;flex:none;padding:0 5px;font-size:11px;font-weight:600}.lc-br-delta-up,.lc-br-tdelta-up{color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 15%, transparent)}.lc-br-delta-down,.lc-br-tdelta-down{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 15%, transparent)}.lc-br-tokens-grp{flex:none;align-items:center;gap:4px;min-width:0;display:inline-flex}.lc-br-pct{text-align:right;width:36px;color:var(--dsw-alias-label-secondary);flex:none;font-size:12px}.lc-br-body{border-top:1px solid var(--dsw-alias-border-l1);flex-direction:column;gap:2px;padding:4px 6px;display:flex}.lc-br-elem{border-radius:6px}.lc-br-elem-on{background:var(--dsw-alias-interactive-bg-active)}.lc-br-elem-row{width:100%;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;text-align:left;background:0 0;border:0;border-radius:6px;align-items:center;gap:8px;padding:5px 6px;font-size:12px;transition:background-color .12s;display:flex}.lc-br-elem-row:hover{background:var(--dsw-alias-interactive-bg-hover)}.lc-br-tag{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);text-overflow:ellipsis;white-space:nowrap;border-radius:4px;flex:none;max-width:220px;padding:0 6px;font-size:11px;overflow:hidden}.lc-br-preview{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.lc-br-time{color:var(--dsw-alias-label-secondary);flex:none;font-size:11px}.lc-br-content{flex-direction:column;gap:6px;padding:2px 6px 8px 26px;display:flex}.lc-br-dim{color:var(--dsw-alias-label-secondary)}.lc-ts-card{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:6px;overflow:hidden}.lc-ts-card-head{color:var(--dsw-alias-label-secondary);border-bottom:1px solid var(--dsw-alias-border-l1);align-items:center;gap:8px;padding:6px 10px;font-size:11px;font-weight:600;display:flex}.lc-ts-card-head b{color:var(--dsw-alias-label-primary)}.lc-ts-call-name{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px}.lc-ts-card-count{margin-left:auto}.lc-ts-desc-body{color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;scrollbar-width:thin;max-height:320px;margin:0;padding:8px 10px;font-size:12px;line-height:1.55;overflow-y:auto}.lc-ts-param-row{border-top:1px solid var(--dsw-alias-border-l1);grid-template-columns:140px 90px 56px 1fr;align-items:baseline;gap:2px 10px;padding:6px 10px;font-size:12px;display:grid}.lc-ts-param-row:first-of-type{border-top:0}.lc-ts-param-name{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.lc-ts-param-type{color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;overflow:hidden}.lc-ts-param-req{color:var(--dsw-alias-state-warn-primary);font-size:11px;font-weight:600}.lc-ts-param-req-off{color:var(--dsw-alias-label-secondary);font-size:11px}.lc-ts-param-desc{color:var(--dsw-alias-label-secondary);grid-column:1/-1;line-height:1.5}.lc-ts-params-empty{color:var(--dsw-alias-label-secondary);padding:8px 10px;font-size:12px}.lc-ts-arg-row{border-top:1px solid var(--dsw-alias-border-l1);grid-template-columns:minmax(0,96px) 1fr;align-items:start;column-gap:12px;padding:6px 10px;font-size:12px;display:grid}.lc-ts-arg-row:first-of-type{border-top:0}.lc-ts-arg-row .lc-ts-param-name{text-overflow:unset;white-space:normal;overflow-wrap:anywhere;overflow:visible}.lc-ts-arg-val{color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;scrollbar-width:thin;max-height:200px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;line-height:1.55;overflow-y:auto}.lc-ts-json{flex-direction:column;gap:4px;display:flex}.lc-ts-json-toggle{color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;background:0 0;border:0;align-self:flex-start;padding:0;font-size:11px}.lc-ts-json-toggle:hover{color:var(--dsw-alias-label-primary);text-decoration:underline}.lc-rich-seg{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:6px;gap:2px;margin-left:auto;padding:1px;display:flex}.lc-rich-seg-btn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:5px;padding:3px 8px;font-family:inherit;font-size:11px;line-height:1}.lc-rich-seg-btn:hover{color:var(--dsw-alias-label-primary)}.lc-rich-seg-on,.lc-rich-seg-on:hover{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}.lc-ts-desc-md{color:var(--dsw-alias-label-primary);word-break:break-word;scrollbar-width:thin;max-height:320px;padding:4px 10px;font-size:12px;line-height:1.55;overflow-y:auto}.lc-ts-desc-md>div{font-size:13px;line-height:1.55}.lc-ts-desc-md div :is(h1,h2,h3,h4,h5,h6){margin:10px 0 4px;font-size:13px;font-weight:600}.lc-ts-desc-md div p,.lc-ts-desc-md div pre{margin:6px 0}.lc-ts-desc-md div :not(pre)>code{box-decoration-break:clone;padding:1px 5px;line-height:1.3;font-size:1em!important}.lc-ts-desc-md div table code{font-size:inherit}.lc-att-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;padding:8px 10px;display:grid}.lc-att-item{align-items:center;gap:8px;min-width:0;display:flex}.lc-att-thumb{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);cursor:pointer;width:64px;height:64px;font:inherit;border-radius:6px;flex:none;justify-content:center;align-items:center;padding:0;display:flex;overflow:hidden}.lc-att-thumb img{object-fit:cover;width:100%;height:100%;display:block}.lc-att-ph,.lc-att-err{color:var(--dsw-alias-label-secondary);text-align:center;padding:2px;font-size:10px}.lc-att-meta{flex-direction:column;gap:2px;min-width:0;display:flex}.lc-att-name{color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;word-break:break-word;font-size:12px;line-height:1.3}.lc-att-row{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;font-size:11px}.lc-att-row-label{min-width:3.2em;font-weight:400;display:inline-block}[data-conversation-scroll]:has(.lc-root)>[data-composer-seat]:not(:has([data-approval-key],[data-question-key],[data-plan-review-key])){display:none}";
|
|
2754
|
+
const css = ".lc-root{box-sizing:border-box;height:100%;color:var(--dsw-alias-label-primary);padding:16px 20px 32px;font-size:13px;overflow-y:auto}.lc-card{background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);border-radius:10px;margin-bottom:14px;padding:14px 16px}.lc-card-title{align-items:baseline;gap:8px;margin-bottom:10px;font-weight:600;display:flex}.lc-card-title-text{white-space:nowrap;flex:none}.lc-stats{grid-template-columns:repeat(auto-fit,minmax(62px,1fr));gap:6px;display:grid}.lc-stat{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:8px;flex-direction:column;gap:2px;min-width:0;padding:6px;display:flex}.lc-stat-label{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;font-weight:600;overflow:hidden}.lc-stat-value{color:var(--dsw-alias-label-primary);white-space:nowrap;text-overflow:ellipsis;text-align:center;font-size:14px;font-weight:600;overflow:hidden}.lc-stat-sub{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;font-size:11px;overflow:hidden}.lc-stat-tipped{position:relative}.lc-stat-q{text-align:center;width:11px;height:11px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);cursor:help;border-radius:50%;margin-left:4px;font-size:9px;font-style:normal;font-weight:700;line-height:11px;display:inline-block}.lc-stat-tipped:hover .lc-stat-q{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-primary)}.lc-stat-tip{z-index:6;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);width:max-content;max-width:280px;color:var(--dsw-alias-label-primary);pointer-events:none;opacity:0;border-radius:6px;padding:6px 10px;font-size:12px;font-weight:400;line-height:1.5;transition:opacity .12s;position:absolute;top:calc(100% + 6px);left:0;box-shadow:0 2px 8px #0000002e}.lc-stat-tipped:hover .lc-stat-tip{opacity:1}.lc-stat-tip-prices{border-top:1px dashed var(--dsw-alias-border-l1);margin-top:5px;padding-top:5px;display:block}.lc-stat-tip-head{font-weight:600;display:block}.lc-stat-tip-row{margin-top:2px;display:block}.lc-stat-tip-model{color:var(--dsw-alias-label-primary)}.lc-card-sub{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:400}.lc-gran,.lc-kinds{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:6px;gap:2px;margin-left:auto;padding:1px;display:flex}.lc-trend-ctl{align-items:center;gap:6px;margin-left:auto;display:flex}.lc-trend-ctl .lc-gran{margin-left:0}.lc-gran-btn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:5px;padding:3px 8px;font-family:inherit;font-size:11px;line-height:1}.lc-gran-btn:hover{color:var(--dsw-alias-label-primary)}.lc-gran-on,.lc-gran-on:hover{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}.lc-overview-num{align-items:baseline;gap:6px;margin-bottom:8px;display:flex}.lc-overview-num>b{font-size:20px}.lc-overview-num span{color:var(--dsw-alias-label-secondary)}.lc-overview-pct{margin-left:auto;font-size:11px}.lc-overview-pct b{color:var(--dsw-alias-label-primary);margin-right:4px;font-size:20px}.lc-stacked-wrap{width:100%;position:relative}.lc-stacked{background:#8080802e;border-radius:5px;width:100%;display:flex;position:relative;overflow:hidden}.lc-occupied-box{border:2px solid var(--dsw-alias-label-tertiary);box-sizing:border-box;pointer-events:none;opacity:0;box-shadow:0 0 0 1px var(--dsw-alias-bg-layer-2);border-radius:5px;transition:opacity .12s;position:absolute;top:0;bottom:0;left:0}.lc-occupied-box-on{opacity:1}.lc-bar-tip{z-index:5;white-space:nowrap;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);pointer-events:none;opacity:0;border-radius:6px;padding:3px 8px;font-size:12px;transition:opacity .12s;position:absolute;bottom:calc(100% + 6px);transform:translate(-50%);box-shadow:0 2px 8px #0000002e}.lc-bar-tip-on{opacity:1}.lc-stacked>div{height:100%}.lc-stacked-seg{transition:filter .12s,opacity .12s}.lc-stacked-free{box-sizing:border-box;transition:box-shadow .12s,opacity .12s}.lc-stacked-seg-on{filter:brightness(1.18)}.lc-reserve{z-index:1;pointer-events:auto;cursor:help;background:repeating-linear-gradient(45deg, color-mix(in srgb, var(--dsw-alias-state-warn-primary) 24%, transparent) 0 5px, transparent 5px 10px);position:absolute;top:0;bottom:0}.lc-stacked-free-on{border:2px dashed var(--dsw-alias-label-secondary);border-radius:3px}.lc-stacked-dim .lc-stacked-seg{opacity:.35}.lc-stacked-dim .lc-stacked-seg-on{opacity:1}.lc-stacked-dim .lc-stacked-free{opacity:.35}.lc-stacked-dim .lc-stacked-free-on{opacity:1}.lc-legend{grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:6px 14px;margin-top:10px;display:grid}.lc-chip{min-width:0;color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:6px;align-items:center;gap:5px;padding:1px 6px;transition:background-color .12s;display:flex}.lc-chip-label{white-space:nowrap;text-overflow:ellipsis;min-width:0;font-weight:600;overflow:hidden}.lc-chip-nums{white-space:nowrap;flex:none;align-items:baseline;gap:6px;margin-left:auto;display:inline-flex}.lc-chip i,.lc-detail-row i,.lc-node i{border-radius:2px;width:8px;height:8px;display:inline-block}.lc-chip i{transition:box-shadow .12s}.lc-chip em{color:var(--dsw-alias-label-secondary);font-style:normal}.lc-chip-on{background:var(--dsw-alias-interactive-bg-hover);font-weight:600}.lc-chip-on i{box-shadow:0 0 0 1px var(--dsw-alias-brand-primary)}.lc-tools{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;align-items:center;gap:6px;margin-top:10px;display:flex}.lc-tools-label,.lc-tools-more{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;padding:0;font-family:inherit;font-size:12px}.lc-tools-label:hover,.lc-tools-more:hover{text-decoration:underline}.lc-tool-chip{background:var(--dsw-alias-bg-layer-2);font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:0;border-radius:4px;padding:1px 7px;font-size:12px}.lc-tool-chip:hover{text-decoration:underline}.lc-chartrow{align-items:stretch;gap:6px;display:flex}.lc-axis{box-sizing:border-box;width:40px;height:150px;color:var(--dsw-alias-label-secondary);padding-top:18px;font-size:11px;position:relative}.lc-axis span{line-height:1;position:absolute;right:0}.lc-axis-top{top:13px}.lc-axis-mid{top:69px}.lc-axis-bot{top:125px}.lc-chart-scroll{scrollbar-width:thin;flex:1;min-width:0;padding-bottom:8px;position:relative;overflow:auto hidden}.lc-chart-fade{pointer-events:none;z-index:2;width:26px;position:absolute;top:0;bottom:0}.lc-chart-fade-l{background:linear-gradient(to right, var(--dsw-alias-bg-layer-1), transparent);left:0}.lc-chart-fade-r{background:linear-gradient(to left, var(--dsw-alias-bg-layer-1), transparent);right:0}.lc-chart{box-sizing:border-box;align-items:flex-end;gap:2px;width:max-content;min-width:100%;height:130px;padding-top:18px;display:flex;position:relative}.lc-grid{border-top:1px dashed var(--dsw-alias-border-l1);pointer-events:none;position:absolute;left:0;right:0}.lc-grid-top{top:18px}.lc-grid-mid{top:74px}.lc-bar{cursor:pointer;border-radius:2px;flex:none;align-items:flex-end;width:14px;height:100%;transition:opacity .12s,background-color .12s;display:flex;position:relative}.lc-chart-dim .lc-bar{opacity:.35}.lc-chart-dim .lc-bar-in-turn{opacity:1}.lc-chart-dim .lc-turn{opacity:.35}.lc-chart-dim .lc-turn-on{opacity:1}.lc-chart-tip{z-index:5;white-space:nowrap;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-primary);pointer-events:none;border-radius:6px;padding:3px 8px;font-size:12px;position:absolute;top:0;transform:translate(-50%);box-shadow:0 2px 8px #0000002e}.lc-bar:hover{background:var(--dsw-alias-bg-layer-2)}.lc-bar-hovered{outline:1px dashed var(--dsw-alias-brand-primary);outline-offset:1px}.lc-bar-selected{outline:2px solid var(--dsw-alias-label-primary);outline-offset:1px}.lc-bar-in-turn{background:#80808024}.lc-bar-stack{flex-direction:column-reverse;width:100%;display:flex}.lc-bar-stack>div{width:100%}.lc-bar-marker{color:var(--dsw-alias-state-warn-primary);font-size:11px;position:absolute;top:-16px;left:50%;transform:translate(-50%)}.lc-turns{gap:2px;width:max-content;min-width:100%;margin-top:4px;display:flex}.lc-turn{box-sizing:border-box;text-align:center;color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;cursor:pointer;border-radius:3px;flex:none;height:14px;font-size:10px;font-weight:600;line-height:14px;transition:filter .12s,opacity .12s;overflow:hidden}.lc-turn-on{filter:brightness(1.35);color:var(--dsw-alias-label-primary)}.lc-detail{border-top:1px solid var(--dsw-alias-border-l1);margin-top:12px;padding-top:12px}.lc-detail-head{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;gap:6px 16px;margin-bottom:8px;display:flex}.lc-detail-head b{color:var(--dsw-alias-label-primary)}.lc-detail-marker{color:var(--dsw-alias-state-warn-primary);background:var(--dsw-alias-bg-layer-2);border-radius:6px;padding:1px 7px;font-size:11px}.lc-detail-head .lc-actual{color:var(--dsw-alias-state-success-primary)}.lc-detail-tag{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-label-secondary);border-radius:4px;padding:0 6px;font-size:11px}.lc-detail-rows{grid-template-columns:1fr 1fr;gap:4px 24px;margin-top:10px;display:grid}.lc-detail-row{align-items:center;gap:8px;display:flex}.lc-detail-label{white-space:nowrap;min-width:70px;color:var(--dsw-alias-label-secondary)}.lc-bar-track{background:#8080802e;border-radius:3px;flex:1;height:5px;display:block;overflow:hidden}.lc-bar-fill{border-radius:3px;height:100%;display:block}.lc-detail-num{text-align:right;width:44px}.lc-detail-pct{text-align:right;width:34px;color:var(--dsw-alias-label-secondary)}.lc-cols{flex-wrap:wrap;gap:14px;margin-bottom:14px;display:flex}.lc-col{flex:1;min-width:280px}.lc-cols>.lc-card,.lc-col>.lc-card:last-child{margin-bottom:0}.lc-col-browser{flex-direction:column;display:flex}.lc-col-browser>.lc-card{flex:1}.lc-head>.lc-card:first-child{flex:7 1 0;min-width:360px}.lc-head>.lc-card:last-child{flex:3 1 0;min-width:220px}.lc-pi-grid{grid-template-columns:1fr;gap:8px;display:grid}.lc-pi-row{min-width:0;color:inherit;flex-direction:row;justify-content:space-between;align-items:baseline;gap:12px;text-decoration:none;display:flex}.lc-pi-row:hover .lc-pi-value{text-decoration:underline}.lc-pi-update{color:var(--dsw-alias-state-warn-primary);white-space:nowrap;margin-left:6px;font-size:11px}.lc-pi-label{color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;flex:none;font-size:11px;font-weight:600;overflow:hidden}.lc-pi-value{min-width:0;color:var(--dsw-alias-label-primary);white-space:nowrap;text-overflow:ellipsis;text-align:right;font-size:13px;font-weight:600;overflow:hidden}.lc-events,.lc-nodes{flex-direction:column;gap:2px;max-height:320px;display:flex;overflow-y:auto}.lc-event{align-items:center;gap:8px;padding:3px 0;display:flex}.lc-event-icon{text-align:center;width:18px;color:var(--dsw-alias-state-warn-primary)}.lc-event-icon.lc-event-inject{color:#a855f7}.lc-event-icon.lc-event-model{color:var(--dsw-alias-brand-primary)}.lc-event-icon.lc-event-mode{color:var(--dsw-alias-label-secondary)}.lc-kind{white-space:nowrap;border-radius:4px;flex:none;padding:1px 6px;font-size:10px;font-weight:600}.lc-kind-inject{background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 15%, transparent);color:var(--dsw-alias-state-success-primary)}.lc-kind-compaction{background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 15%, transparent);color:var(--dsw-alias-state-error-primary)}.lc-kind-prune{color:#8b5cf6;background:#8b5cf626}.lc-kind-model{background:color-mix(in srgb, var(--dsw-alias-brand-primary) 15%, transparent);color:var(--dsw-alias-brand-primary)}.lc-kind-mode{background:color-mix(in srgb, var(--dsw-alias-label-secondary) 15%, transparent);color:var(--dsw-alias-label-secondary)}.lc-event-label{text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}.lc-event-at{color:var(--dsw-alias-label-secondary);white-space:nowrap;flex:none;font-size:11px}.lc-event-tokens{color:var(--dsw-alias-state-success-primary);white-space:nowrap;font-weight:600}.lc-event-tokens.lc-up{color:var(--dsw-alias-state-warn-primary)}.lc-event-time{color:var(--dsw-alias-label-secondary);font-size:12px}.lc-node{align-items:center;gap:8px;padding:3px 0;display:flex}.lc-node-preview{text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-primary);flex:1;overflow:hidden}.lc-node-time{color:var(--dsw-alias-label-secondary);text-align:right;min-width:54px;font-size:12px}.lc-node-tokens{color:var(--dsw-alias-label-secondary)}.lc-nodes-more{color:var(--dsw-alias-label-secondary);padding:3px 0}.lc-empty{color:var(--dsw-alias-label-secondary);text-align:center;padding:18px 0}.lc-error{flex-direction:column;align-items:center;gap:8px;padding:40px 16px;display:flex}.lc-error-msg{color:var(--dsw-alias-state-error-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);overflow-wrap:anywhere;border-radius:6px;max-width:100%;padding:4px 8px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px}.lc-error-retry{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;border-radius:6px;padding:4px 14px;font-size:12px}.lc-error-retry:hover{border-color:var(--dsw-alias-label-primary)}.lc-foot{color:var(--dsw-alias-label-secondary);margin-top:4px;font-size:12px}.lc-modal-backdrop{z-index:200;background:#00000073;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.lc-modal-card{box-sizing:border-box;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);width:min(720px,100vw - 48px);max-height:min(82vh,760px);box-shadow:var(--dsw-shadow-lv3,0 12px 32px #0006);color:var(--dsw-alias-label-primary);border-radius:12px;padding:16px 18px 18px;font-size:13px;overflow-y:auto}.lc-modal-head{align-items:baseline;gap:8px;margin-bottom:12px;display:flex}.lc-modal-title{font-size:14px;font-weight:600}.lc-modal-close{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:6px;margin-left:auto;padding:2px 6px;font-family:inherit;font-size:18px;line-height:1}.lc-modal-close:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2)}.lc-br-hint{color:var(--dsw-alias-label-secondary);white-space:nowrap;margin-left:auto;font-size:11px;font-weight:400}.lc-br-pick{font:inherit;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:6px;max-width:240px;padding:3px 6px;font-size:12px}.lc-br-meta{color:var(--dsw-alias-label-secondary);flex-wrap:wrap;gap:6px 16px;margin-bottom:8px;display:flex}.lc-br-meta b{color:var(--dsw-alias-label-primary)}.lc-br-meta .lc-actual{color:var(--dsw-alias-state-success-primary)}.lc-br-note{color:var(--dsw-alias-label-secondary);margin-top:8px;font-size:12px}.lc-br-cats{flex-direction:column;gap:4px;margin-top:10px;display:flex}.lc-br-cat{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);border-radius:8px;overflow:hidden}.lc-br-cat-empty{opacity:.55}.lc-br-cat-row{width:100%;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;text-align:left;background:0 0;border:0;align-items:center;gap:8px;padding:7px 10px;transition:background-color .12s;display:flex}.lc-br-cat-row:hover,.lc-br-cat-on{background:var(--dsw-alias-interactive-bg-hover)}.lc-br-cat-on i{box-shadow:0 0 0 1px var(--dsw-alias-brand-primary)}.lc-br-cat-row i{border-radius:2px;flex:none;width:8px;height:8px;transition:box-shadow .12s;display:inline-block}.lc-br-cat-label{font-weight:600}.lc-br-cat-count{color:var(--dsw-alias-label-secondary);white-space:nowrap;font-size:12px}.lc-br-count-grp{flex:1;align-items:center;gap:4px;min-width:0;display:inline-flex}.lc-br-chev{width:12px;color:var(--dsw-alias-label-secondary);flex:none;transition:transform .12s}.lc-br-chev-on{transform:rotate(90deg)}.lc-br-tokens{color:var(--dsw-alias-label-secondary);flex:none;font-size:12px}.lc-br-delta,.lc-br-tdelta{white-space:nowrap;border-radius:4px;flex:none;padding:0 5px;font-size:11px;font-weight:600}.lc-br-delta-up,.lc-br-tdelta-up{color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 15%, transparent)}.lc-br-delta-down,.lc-br-tdelta-down{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 15%, transparent)}.lc-br-tokens-grp{flex:none;align-items:center;gap:4px;min-width:0;display:inline-flex}.lc-br-pct{text-align:right;width:36px;color:var(--dsw-alias-label-secondary);flex:none;font-size:12px}.lc-br-body{border-top:1px solid var(--dsw-alias-border-l1);flex-direction:column;gap:2px;padding:4px 6px;display:flex}.lc-br-elem{border-radius:6px}.lc-br-elem-on{background:var(--dsw-alias-interactive-bg-active)}.lc-br-elem-row{width:100%;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;text-align:left;background:0 0;border:0;border-radius:6px;align-items:center;gap:8px;padding:5px 6px;font-size:12px;transition:background-color .12s;display:flex}.lc-br-elem-row:hover{background:var(--dsw-alias-interactive-bg-hover)}.lc-br-tag{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);text-overflow:ellipsis;white-space:nowrap;border-radius:4px;flex:none;max-width:220px;padding:0 6px;font-size:11px;overflow:hidden}.lc-br-preview{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.lc-br-time{color:var(--dsw-alias-label-secondary);flex:none;font-size:11px}.lc-br-content{flex-direction:column;gap:6px;padding:2px 6px 8px 26px;display:flex}.lc-br-dim{color:var(--dsw-alias-label-secondary)}.lc-ts-card{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:6px;overflow:hidden}.lc-ts-card-head{color:var(--dsw-alias-label-secondary);border-bottom:1px solid var(--dsw-alias-border-l1);align-items:center;gap:8px;padding:6px 10px;font-size:11px;font-weight:600;display:flex}.lc-ts-card-head b{color:var(--dsw-alias-label-primary)}.lc-ts-call-name{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px}.lc-ts-card-count{margin-left:auto}.lc-ts-desc-body{color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;scrollbar-width:thin;max-height:320px;margin:0;padding:8px 10px;font-size:12px;line-height:1.55;overflow-y:auto}.lc-ts-param-row{border-top:1px solid var(--dsw-alias-border-l1);grid-template-columns:140px 90px 56px 1fr;align-items:baseline;gap:2px 10px;padding:6px 10px;font-size:12px;display:grid}.lc-ts-param-row:first-of-type{border-top:0}.lc-ts-param-name{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.lc-ts-param-type{color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;overflow:hidden}.lc-ts-param-req{color:var(--dsw-alias-state-warn-primary);font-size:11px;font-weight:600}.lc-ts-param-req-off{color:var(--dsw-alias-label-secondary);font-size:11px}.lc-ts-param-desc{color:var(--dsw-alias-label-secondary);grid-column:1/-1;line-height:1.5}.lc-ts-params-empty{color:var(--dsw-alias-label-secondary);padding:8px 10px;font-size:12px}.lc-ts-arg-row{border-top:1px solid var(--dsw-alias-border-l1);grid-template-columns:minmax(0,96px) 1fr;align-items:start;column-gap:12px;padding:6px 10px;font-size:12px;display:grid}.lc-ts-arg-row:first-of-type{border-top:0}.lc-ts-arg-row .lc-ts-param-name{text-overflow:unset;white-space:normal;overflow-wrap:anywhere;overflow:visible}.lc-ts-arg-val{color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;scrollbar-width:thin;max-height:200px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;line-height:1.55;overflow-y:auto}.lc-ts-json{flex-direction:column;gap:4px;display:flex}.lc-ts-json-toggle{color:var(--dsw-alias-label-secondary);font:inherit;cursor:pointer;background:0 0;border:0;align-self:flex-start;padding:0;font-size:11px}.lc-ts-json-toggle:hover{color:var(--dsw-alias-label-primary);text-decoration:underline}.lc-rich-seg{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);border-radius:6px;gap:2px;margin-left:auto;padding:1px;display:flex}.lc-rich-seg-btn{color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:5px;padding:3px 8px;font-family:inherit;font-size:11px;line-height:1}.lc-rich-seg-btn:hover{color:var(--dsw-alias-label-primary)}.lc-rich-seg-on,.lc-rich-seg-on:hover{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}.lc-ts-desc-md{color:var(--dsw-alias-label-primary);word-break:break-word;scrollbar-width:thin;max-height:320px;padding:4px 10px;font-size:12px;line-height:1.55;overflow-y:auto}.lc-ts-desc-md>div{font-size:13px;line-height:1.55}.lc-ts-desc-md div :is(h1,h2,h3,h4,h5,h6){margin:10px 0 4px;font-size:13px;font-weight:600}.lc-ts-desc-md div p,.lc-ts-desc-md div pre{margin:6px 0}.lc-ts-desc-md div :not(pre)>code{box-decoration-break:clone;padding:1px 5px;line-height:1.3;font-size:1em!important}.lc-ts-desc-md div table code{font-size:inherit}.lc-att-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;padding:8px 10px;display:grid}.lc-att-item{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l1);width:100%;min-width:0;font:inherit;text-align:left;cursor:pointer;background:0 0;border-radius:8px;align-items:center;gap:8px;padding:6px;display:flex}.lc-att-item:hover{border-color:var(--dsw-alias-border-l2,var(--dsw-alias-border-l1));background:var(--dsw-alias-interactive-bg-hover,var(--dsw-alias-bg-layer-2))}.lc-att-thumb{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:6px;flex:none;justify-content:center;align-items:center;width:64px;height:64px;padding:0;display:flex;overflow:hidden}.lc-att-thumb img{object-fit:cover;width:100%;height:100%;display:block}.lc-att-ph,.lc-att-err{color:var(--dsw-alias-label-secondary);text-align:center;padding:2px;font-size:10px}.lc-att-meta{flex-direction:column;gap:2px;min-width:0;display:flex}.lc-att-name{color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;word-break:break-word;font-size:12px;line-height:1.3}.lc-att-row{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;font-size:11px}.lc-att-row-label{min-width:3.2em;font-weight:400;display:inline-block}.lc-att-lightbox{z-index:1000;place-items:center;padding:40px;display:grid;position:fixed;inset:0}.lc-att-lightbox-mask{background:var(--dsw-alias-bg-mask-1,#00000073);backdrop-filter:var(--dsw-mask-blur,blur(2px));position:absolute;inset:0}.lc-att-lightbox-img{object-fit:contain;background:var(--dsw-specific-input-major,var(--dsw-alias-bg-layer-1));max-width:min(100%,1600px);max-height:calc(100vh - 80px);box-shadow:var(--dsw-shadow-lv3,0 12px 32px #0006);border-radius:12px;position:relative}.lc-att-lightbox-close{z-index:1;border:1px solid var(--dsw-alias-border-l2-darkmode-thin,var(--dsw-alias-border-l1));background:var(--dsw-specific-input-major,var(--dsw-alias-bg-layer-1));width:36px;height:36px;color:var(--dsw-alias-label-primary);cursor:pointer;border-radius:999px;place-items:center;padding:0;display:grid;position:fixed;top:20px;right:20px}[data-conversation-scroll]:has(.lc-root)>[data-composer-seat]:not(:has([data-approval-key],[data-question-key],[data-plan-review-key])){display:none}";
|
|
2678
2755
|
const tagId = "dsh-context/styles.css";
|
|
2679
2756
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
2680
2757
|
const tag = document.createElement("style");
|
package/lib/index.d.ts
CHANGED
|
@@ -109,11 +109,19 @@ interface Snapshot {
|
|
|
109
109
|
tokens: number;
|
|
110
110
|
}[];
|
|
111
111
|
/**
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
112
|
+
* Image blocks live in the CURRENT context (user uploads plus tool-result
|
|
113
|
+
* images, nested blocks included) — the sum over the live surface nodes'
|
|
114
|
+
* `imgs`, so compaction/prune shrink it. Absent from older hosts; clients
|
|
115
|
+
* treat absence as zero.
|
|
115
116
|
*/
|
|
116
117
|
images?: number;
|
|
118
|
+
/**
|
|
119
|
+
* Tool calls whose result is live in the CURRENT context (one `tool/result`
|
|
120
|
+
* folds to one `tool` surface node). Calls still in flight and results
|
|
121
|
+
* compacted/pruned out of the surface are not counted. Absent from older
|
|
122
|
+
* hosts; clients treat absence as zero.
|
|
123
|
+
*/
|
|
124
|
+
toolCalls?: number;
|
|
117
125
|
requests: RequestRecord[];
|
|
118
126
|
events: ContextEventRecord[];
|
|
119
127
|
/**
|
|
@@ -198,6 +206,8 @@ interface SurfaceNode {
|
|
|
198
206
|
time?: number;
|
|
199
207
|
cat: Category;
|
|
200
208
|
tokens: number;
|
|
209
|
+
/** Image blocks inside this node's message (absent when zero). */
|
|
210
|
+
imgs?: number;
|
|
201
211
|
/**
|
|
202
212
|
* Removal marker, present only on `archive` entries: the seq of the
|
|
203
213
|
* replacement surface event that shadowed this node (compaction/prune).
|
|
@@ -243,12 +253,14 @@ interface RequestRecord {
|
|
|
243
253
|
interface ContextEventRecord {
|
|
244
254
|
seq: number;
|
|
245
255
|
time: number;
|
|
246
|
-
kind: 'compaction' | 'prune' | 'inject' | 'model';
|
|
256
|
+
kind: 'compaction' | 'prune' | 'inject' | 'model' | 'mode';
|
|
247
257
|
form?: string;
|
|
248
258
|
tokens?: number;
|
|
249
259
|
count?: number;
|
|
250
260
|
sub?: string;
|
|
251
261
|
name?: string;
|
|
262
|
+
/** One-line producer account (notice-form summary), shown after the name. */
|
|
263
|
+
detail?: string;
|
|
252
264
|
from?: string;
|
|
253
265
|
to?: string;
|
|
254
266
|
/** Turn/step of the request logged right BEFORE the event (host-stamped). */
|
|
@@ -339,12 +351,6 @@ interface TimelineState {
|
|
|
339
351
|
* Absent until a v4-flash / v4-pro request reports usage.
|
|
340
352
|
*/
|
|
341
353
|
cost?: SessionCostUsage;
|
|
342
|
-
/**
|
|
343
|
-
* Cumulative image-block count over the COMPLETE session log (user uploads
|
|
344
|
-
* plus tool-result images, nested blocks included) — running total, never
|
|
345
|
-
* trimmed, so the stats board's image cell stays whole-session like cost.
|
|
346
|
-
*/
|
|
347
|
-
images: number;
|
|
348
354
|
/** Newest `gone` among archive entries dropped by the retention bounds. */
|
|
349
355
|
archiveFloor?: number;
|
|
350
356
|
/**
|
|
@@ -365,6 +371,14 @@ interface TimelineState {
|
|
|
365
371
|
* to keep the state plain JSON for the projection cache.
|
|
366
372
|
*/
|
|
367
373
|
pendingShadowedSeqs?: number[];
|
|
374
|
+
/**
|
|
375
|
+
* The seq of the compaction/prune event that armed `pendingShadowedSeqs` —
|
|
376
|
+
* the shadowed path rewrites that event's `tokens` from the gross shadow
|
|
377
|
+
* price to the NET freed amount (removed nodes minus the synchronous
|
|
378
|
+
* replacement), so the row matches the drop the trend chart shows. Same
|
|
379
|
+
* arm/remove lifecycle as `pendingShadowedSeqs`.
|
|
380
|
+
*/
|
|
381
|
+
pendingShadowEventSeq?: number;
|
|
368
382
|
}
|
|
369
383
|
//#endregion
|
|
370
384
|
//#region node_modules/.pnpm/@deepseek-ai+dsh-session-projection@0.1.0-rc.8_@deepseek-ai+cordis@4.0.1_@deepseek-ai+d_c0ffab70d18276fadfe75ed916313ea3/node_modules/@deepseek-ai/dsh-session-projection/lib/types/types.d.ts
|
package/lib/index.js
CHANGED
|
@@ -254,8 +254,27 @@ function toolCallNames(blocks) {
|
|
|
254
254
|
for (const b of blocks) if (b.type === "tool-call" && typeof b.name === "string") names.push(b.name);
|
|
255
255
|
return names;
|
|
256
256
|
}
|
|
257
|
+
/**
|
|
258
|
+
* Producer label for an injection event, mirroring the dsh transcript's
|
|
259
|
+
* context provenance (client-runtime context-provenance.ts): workspace
|
|
260
|
+
* instructions name the files they were reconciled from, a plugin source its
|
|
261
|
+
* plugin id, and any other producer its own durable kind. Returns '' when
|
|
262
|
+
* the source carries no readable identity at all.
|
|
263
|
+
*/
|
|
264
|
+
function injectionSourceName(source) {
|
|
265
|
+
if (source.kind === "agent-instructions" && Array.isArray(source.changes)) {
|
|
266
|
+
const paths = [];
|
|
267
|
+
for (const change of source.changes) {
|
|
268
|
+
const path = change?.path;
|
|
269
|
+
if (typeof path === "string" && path !== "" && !paths.includes(path)) paths.push(path);
|
|
270
|
+
}
|
|
271
|
+
if (paths.length > 0) return paths.join(", ");
|
|
272
|
+
}
|
|
273
|
+
if (typeof source.plugin === "string" && source.plugin !== "") return source.plugin;
|
|
274
|
+
return typeof source.kind === "string" && source.kind !== "" ? source.kind : "";
|
|
275
|
+
}
|
|
257
276
|
function isInjection(source) {
|
|
258
|
-
return source !== null && source !== void 0 && (source.kind === "
|
|
277
|
+
return source !== null && source !== void 0 && (typeof source.kind === "string" && source.kind !== "" && source.kind !== "user" || typeof source.form === "string");
|
|
259
278
|
}
|
|
260
279
|
//#endregion
|
|
261
280
|
//#region src/host/headers.ts
|
|
@@ -416,8 +435,7 @@ function createTimelineState() {
|
|
|
416
435
|
requests: [],
|
|
417
436
|
events: [],
|
|
418
437
|
archived: [],
|
|
419
|
-
callNames: {}
|
|
420
|
-
images: 0
|
|
438
|
+
callNames: {}
|
|
421
439
|
};
|
|
422
440
|
}
|
|
423
441
|
function categoryOf(type, message) {
|
|
@@ -465,13 +483,14 @@ function skillNameOf(msg) {
|
|
|
465
483
|
}
|
|
466
484
|
function applySurface(st, ev, type, data, message) {
|
|
467
485
|
const cat = categoryOf(type, message ?? void 0);
|
|
468
|
-
st.images = st.images + imageCountOf(message?.content);
|
|
469
486
|
const node = {
|
|
470
487
|
seq: ev.seq,
|
|
471
488
|
time: ev.time,
|
|
472
489
|
cat,
|
|
473
490
|
tokens: estimateMessage(message, type === "assistant/message")
|
|
474
491
|
};
|
|
492
|
+
const imgs = imageCountOf(message?.content);
|
|
493
|
+
if (imgs > 0) node.imgs = imgs;
|
|
475
494
|
const source = message?.source;
|
|
476
495
|
const form = source?.form;
|
|
477
496
|
if (typeof form === "string") node.form = form;
|
|
@@ -507,7 +526,9 @@ function applySurface(st, ev, type, data, message) {
|
|
|
507
526
|
if (utext !== "") node.text = utext;
|
|
508
527
|
}
|
|
509
528
|
const shadowedSeqs = st.pendingShadowedSeqs;
|
|
529
|
+
const shadowEventSeq = st.pendingShadowEventSeq;
|
|
510
530
|
delete st.pendingShadowedSeqs;
|
|
531
|
+
delete st.pendingShadowEventSeq;
|
|
511
532
|
const op = ev.surfaceOp;
|
|
512
533
|
if (op !== null && typeof op === "object" && op.op === "replace") {
|
|
513
534
|
if (Array.isArray(shadowedSeqs) && shadowedSeqs.length > 0) {
|
|
@@ -522,6 +543,14 @@ function applySurface(st, ev, type, data, message) {
|
|
|
522
543
|
st.surface = kept;
|
|
523
544
|
st.sums[cat] += node.tokens;
|
|
524
545
|
st.surface.push(node);
|
|
546
|
+
if (shadowEventSeq !== void 0) {
|
|
547
|
+
const removedSum = removed.reduce((sum, n) => sum + n.tokens, 0);
|
|
548
|
+
const i = st.events.findIndex((e) => e.seq === shadowEventSeq);
|
|
549
|
+
if (i >= 0) st.events[i] = {
|
|
550
|
+
...st.events[i],
|
|
551
|
+
tokens: Math.max(0, removedSum - node.tokens)
|
|
552
|
+
};
|
|
553
|
+
}
|
|
525
554
|
return node;
|
|
526
555
|
}
|
|
527
556
|
let si = -1;
|
|
@@ -633,7 +662,7 @@ function applyTimeline(state, event, bounds) {
|
|
|
633
662
|
s.systemTokens = estimateSystem(header.system);
|
|
634
663
|
if (header.config && typeof header.config.model === "string") s.model = header.config.model;
|
|
635
664
|
if (header.config && typeof header.config.provider === "string") s.provider = header.config.provider;
|
|
636
|
-
if (data?.reason === "change" && s.model && s.lastModel && s.model !== s.lastModel) s.events.push({
|
|
665
|
+
if ((data?.reason === "change" || data?.reason === "resume") && s.model && s.lastModel && s.model !== s.lastModel) s.events.push({
|
|
637
666
|
seq: event.seq,
|
|
638
667
|
time: event.time,
|
|
639
668
|
kind: "model",
|
|
@@ -672,7 +701,11 @@ function applyTimeline(state, event, bounds) {
|
|
|
672
701
|
if (source.kind === "skill-invocation") {
|
|
673
702
|
rec.sub = "skill";
|
|
674
703
|
rec.name = typeof source.name === "string" ? source.name : "?";
|
|
675
|
-
} else
|
|
704
|
+
} else {
|
|
705
|
+
const label = injectionSourceName(source);
|
|
706
|
+
if (label !== "") rec.name = label;
|
|
707
|
+
if (source.form === "notice" && typeof source.summary === "string" && source.summary !== "") rec.detail = source.summary;
|
|
708
|
+
}
|
|
676
709
|
s.events.push(rec);
|
|
677
710
|
}
|
|
678
711
|
break;
|
|
@@ -725,10 +758,21 @@ function applyTimeline(state, event, bounds) {
|
|
|
725
758
|
applySurface(s, event, event.type, data, asstMsg);
|
|
726
759
|
break;
|
|
727
760
|
}
|
|
761
|
+
case "plan/mode":
|
|
762
|
+
if (data && typeof data.active === "boolean") ensure().events.push({
|
|
763
|
+
seq: event.seq,
|
|
764
|
+
time: event.time,
|
|
765
|
+
kind: "mode",
|
|
766
|
+
name: data.active ? "plan.on" : "plan.off"
|
|
767
|
+
});
|
|
768
|
+
break;
|
|
728
769
|
case "compaction/summary":
|
|
729
770
|
case "compaction/prune": {
|
|
730
771
|
const s = ensure();
|
|
731
|
-
if (data && Array.isArray(data.shadowedSeqs))
|
|
772
|
+
if (data && Array.isArray(data.shadowedSeqs)) {
|
|
773
|
+
s.pendingShadowedSeqs = data.shadowedSeqs.filter((x) => typeof x === "number");
|
|
774
|
+
s.pendingShadowEventSeq = event.seq;
|
|
775
|
+
}
|
|
732
776
|
s.events.push({
|
|
733
777
|
seq: event.seq,
|
|
734
778
|
time: event.time,
|
|
@@ -769,7 +813,8 @@ function buildTimelineView(state, bounds) {
|
|
|
769
813
|
total: surfaceTotal + state.systemTokens + state.toolsTokens
|
|
770
814
|
},
|
|
771
815
|
toolList: state.toolList,
|
|
772
|
-
images: state.
|
|
816
|
+
images: state.surface.reduce((n, node) => n + (node.imgs ?? 0), 0),
|
|
817
|
+
toolCalls: state.surface.reduce((n, node) => node.cat === "tool" ? n + 1 : n, 0),
|
|
773
818
|
requests: state.requests.map((r) => ({ ...r })),
|
|
774
819
|
events: state.events.map((e) => ({ ...e })),
|
|
775
820
|
nodes: [],
|
|
@@ -852,6 +897,7 @@ const surfaceNodeSchema = z.object({
|
|
|
852
897
|
"tool"
|
|
853
898
|
]),
|
|
854
899
|
tokens: z.number().int().nonnegative(),
|
|
900
|
+
imgs: z.number().int().nonnegative().optional(),
|
|
855
901
|
gone: z.number().int().nonnegative().optional(),
|
|
856
902
|
form: z.string().optional(),
|
|
857
903
|
text: z.string().optional(),
|
|
@@ -883,13 +929,15 @@ const contextEventSchema = z.object({
|
|
|
883
929
|
"compaction",
|
|
884
930
|
"prune",
|
|
885
931
|
"inject",
|
|
886
|
-
"model"
|
|
932
|
+
"model",
|
|
933
|
+
"mode"
|
|
887
934
|
]),
|
|
888
935
|
form: z.string().optional(),
|
|
889
936
|
tokens: z.number().optional(),
|
|
890
937
|
count: z.number().optional(),
|
|
891
938
|
sub: z.string().optional(),
|
|
892
939
|
name: z.string().optional(),
|
|
940
|
+
detail: z.string().optional(),
|
|
893
941
|
from: z.string().optional(),
|
|
894
942
|
to: z.string().optional(),
|
|
895
943
|
fromTurn: z.number().optional(),
|
|
@@ -927,6 +975,7 @@ const contextTimelineSchema = z.object({
|
|
|
927
975
|
tokens: z.number().int().nonnegative()
|
|
928
976
|
}).strict()),
|
|
929
977
|
images: z.number().int().nonnegative().optional(),
|
|
978
|
+
toolCalls: z.number().int().nonnegative().optional(),
|
|
930
979
|
requests: z.array(requestRecordSchema),
|
|
931
980
|
events: z.array(contextEventSchema),
|
|
932
981
|
cost: z.object({
|
|
@@ -970,10 +1019,10 @@ const timelineStateSchema = z.object({
|
|
|
970
1019
|
flash: costFamilySchema.optional(),
|
|
971
1020
|
pro: costFamilySchema.optional()
|
|
972
1021
|
}).strict().optional(),
|
|
973
|
-
images: z.number().int().nonnegative().optional(),
|
|
974
1022
|
archiveFloor: z.number().optional(),
|
|
975
1023
|
callNames: z.record(z.string(), z.string()),
|
|
976
|
-
pendingShadowedSeqs: z.array(z.number()).optional()
|
|
1024
|
+
pendingShadowedSeqs: z.array(z.number()).optional(),
|
|
1025
|
+
pendingShadowEventSeq: z.number().optional()
|
|
977
1026
|
});
|
|
978
1027
|
/**
|
|
979
1028
|
* The context-timeline projection unit, created per plugin instance with its
|
|
@@ -1006,7 +1055,7 @@ function createContextTimelineDefinition(config) {
|
|
|
1006
1055
|
},
|
|
1007
1056
|
init: () => createTimelineState(),
|
|
1008
1057
|
apply: (state, event) => applyTimeline(state, event, bounds),
|
|
1009
|
-
stateVersion:
|
|
1058
|
+
stateVersion: 8
|
|
1010
1059
|
};
|
|
1011
1060
|
}
|
|
1012
1061
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-context",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.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": {
|