dsh-context 0.40.1 → 0.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/client.js +39 -20
- package/lib/index.d.ts +20 -12
- package/lib/index.js +39 -5
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -37,10 +37,11 @@ window.__ModuleLoader__.load({
|
|
|
37
37
|
"timing.title": "耗时统计",
|
|
38
38
|
"timing.hint": "整个会话的活跃时长分布",
|
|
39
39
|
"timing.total": "总活跃时长",
|
|
40
|
-
"timing.
|
|
40
|
+
"timing.ttft": "模型等待",
|
|
41
|
+
"timing.gen": "模型生成",
|
|
41
42
|
"timing.tools": "工具执行",
|
|
42
43
|
"timing.other": "其他开销",
|
|
43
|
-
"timing.
|
|
44
|
+
"timing.callTimes": "{n}次",
|
|
44
45
|
"timing.toolTimes": "{n}次",
|
|
45
46
|
"timing.empty": "暂无耗时数据 · 对话开始后这里会显示时长分布",
|
|
46
47
|
"tokens.title": "Token 统计",
|
|
@@ -312,10 +313,11 @@ window.__ModuleLoader__.load({
|
|
|
312
313
|
"timing.title": "Timing Stats",
|
|
313
314
|
"timing.hint": "Whole-session active-time split",
|
|
314
315
|
"timing.total": "Active Time",
|
|
315
|
-
"timing.
|
|
316
|
+
"timing.ttft": "TTFT",
|
|
317
|
+
"timing.gen": "LLM Gen",
|
|
316
318
|
"timing.tools": "Tool runs",
|
|
317
319
|
"timing.other": "Overhead",
|
|
318
|
-
"timing.
|
|
320
|
+
"timing.callTimes": "{n} calls",
|
|
319
321
|
"timing.toolTimes": "{n} runs",
|
|
320
322
|
"timing.empty": "No timing data yet — durations appear as the conversation runs",
|
|
321
323
|
"tokens.title": "Token Stats",
|
|
@@ -997,7 +999,8 @@ window.__ModuleLoader__.load({
|
|
|
997
999
|
const t = value;
|
|
998
1000
|
for (const k of [
|
|
999
1001
|
"wallMs",
|
|
1000
|
-
"
|
|
1002
|
+
"ttftMs",
|
|
1003
|
+
"genMs",
|
|
1001
1004
|
"calls",
|
|
1002
1005
|
"toolsMs",
|
|
1003
1006
|
"toolCalls"
|
|
@@ -1038,7 +1041,8 @@ window.__ModuleLoader__.load({
|
|
|
1038
1041
|
}
|
|
1039
1042
|
return {
|
|
1040
1043
|
wallMs: msNumOf(data.wallMs),
|
|
1041
|
-
|
|
1044
|
+
ttftMs: msNumOf(data.ttftMs),
|
|
1045
|
+
genMs: msNumOf(data.genMs),
|
|
1042
1046
|
calls: msNumOf(data.calls),
|
|
1043
1047
|
toolsMs: msNumOf(data.toolsMs),
|
|
1044
1048
|
toolCalls: msNumOf(data.toolCalls),
|
|
@@ -5059,7 +5063,7 @@ window.__ModuleLoader__.load({
|
|
|
5059
5063
|
return function PluginInfo() {
|
|
5060
5064
|
const [latest, setLatest] = React.useState(null);
|
|
5061
5065
|
React.useEffect(() => {
|
|
5062
|
-
if ("0.
|
|
5066
|
+
if ("0.41.0".includes("-dev")) return;
|
|
5063
5067
|
let on = true;
|
|
5064
5068
|
fetchLatestVersion().then((v) => {
|
|
5065
5069
|
if (on && v) setLatest(v);
|
|
@@ -5068,8 +5072,8 @@ window.__ModuleLoader__.load({
|
|
|
5068
5072
|
on = false;
|
|
5069
5073
|
};
|
|
5070
5074
|
}, []);
|
|
5071
|
-
const update = latest !== null && isNewerVersion(latest, "0.
|
|
5072
|
-
const nameText = "dsh-context (v0.
|
|
5075
|
+
const update = latest !== null && isNewerVersion(latest, "0.41.0") ? latest : null;
|
|
5076
|
+
const nameText = "dsh-context (v0.41.0)";
|
|
5073
5077
|
const nameValue = [nameText];
|
|
5074
5078
|
if (update) nameValue.push(/* @__PURE__ */ React.createElement("span", {
|
|
5075
5079
|
key: "update",
|
|
@@ -5477,20 +5481,27 @@ window.__ModuleLoader__.load({
|
|
|
5477
5481
|
let segments = [];
|
|
5478
5482
|
let rows = [];
|
|
5479
5483
|
if (timing !== null && (wall > 0 || timing.calls > 0 || timing.toolCalls > 0)) {
|
|
5480
|
-
const
|
|
5481
|
-
const
|
|
5482
|
-
const
|
|
5484
|
+
const ttft = Math.min(timing.ttftMs, wall);
|
|
5485
|
+
const gen = Math.max(0, Math.min(timing.genMs, wall - ttft));
|
|
5486
|
+
const toolRing = Math.max(0, Math.min(timing.toolsMs, wall - ttft - gen));
|
|
5487
|
+
const other = Math.max(0, wall - ttft - gen - toolRing);
|
|
5483
5488
|
const share = (ms) => wall > 0 ? ms / wall : 0;
|
|
5484
5489
|
const countOf = (ms, times) => {
|
|
5485
5490
|
const dur = fmtDuration(ms, lang);
|
|
5486
5491
|
if (times === void 0) return dur;
|
|
5487
5492
|
return ms > 0 ? `${dur} · ${times}` : times;
|
|
5488
5493
|
};
|
|
5494
|
+
const callTimes = t("timing.callTimes", { n: fmt(timing.calls) });
|
|
5489
5495
|
segments = [
|
|
5490
5496
|
{
|
|
5491
|
-
key: "
|
|
5497
|
+
key: "ttft",
|
|
5492
5498
|
color: "#3b82f6",
|
|
5493
|
-
value: share(
|
|
5499
|
+
value: share(ttft)
|
|
5500
|
+
},
|
|
5501
|
+
{
|
|
5502
|
+
key: "gen",
|
|
5503
|
+
color: "#8b5cf6",
|
|
5504
|
+
value: share(gen)
|
|
5494
5505
|
},
|
|
5495
5506
|
{
|
|
5496
5507
|
key: "tools",
|
|
@@ -5505,12 +5516,20 @@ window.__ModuleLoader__.load({
|
|
|
5505
5516
|
];
|
|
5506
5517
|
rows = [
|
|
5507
5518
|
{
|
|
5508
|
-
key: "
|
|
5519
|
+
key: "ttft",
|
|
5509
5520
|
color: "#3b82f6",
|
|
5510
|
-
label: t("timing.
|
|
5511
|
-
dim: timing.
|
|
5512
|
-
pct: fmtShare(timing.
|
|
5513
|
-
count: countOf(timing.
|
|
5521
|
+
label: t("timing.ttft"),
|
|
5522
|
+
dim: timing.ttftMs === 0,
|
|
5523
|
+
pct: fmtShare(timing.ttftMs, wall),
|
|
5524
|
+
count: countOf(timing.ttftMs, callTimes)
|
|
5525
|
+
},
|
|
5526
|
+
{
|
|
5527
|
+
key: "gen",
|
|
5528
|
+
color: "#8b5cf6",
|
|
5529
|
+
label: t("timing.gen"),
|
|
5530
|
+
dim: timing.genMs === 0,
|
|
5531
|
+
pct: fmtShare(timing.genMs, wall),
|
|
5532
|
+
count: countOf(timing.genMs, callTimes)
|
|
5514
5533
|
},
|
|
5515
5534
|
{
|
|
5516
5535
|
key: "tools",
|
|
@@ -6431,7 +6450,7 @@ window.__ModuleLoader__.load({
|
|
|
6431
6450
|
}
|
|
6432
6451
|
//#endregion
|
|
6433
6452
|
//#region \0dsh-global-css:/home/runner/work/dsh-context/dsh-context/src/client/styles/base.css.mjs
|
|
6434
|
-
const css$13 = ".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-l2);border-radius:10px;margin-bottom:14px;padding:14px 16px}.lc-card-title{flex-wrap:wrap;align-items:baseline;gap:8px;margin-bottom:10px;font-weight:600;display:flex}.lc-card-title-text{white-space:nowrap;flex:none}.lc-gran,.lc-kinds{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);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;transition:color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);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-tip{z-index:6;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);width:max-content;color:var(--dsw-alias-label-primary);box-shadow:var(--dsw-shadow-lv3,0 2px 8px #0000002e);pointer-events:none;opacity:0;transition:opacity var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:6px;padding:6px 10px;font-size:12px;position:absolute}.lc-events,.lc-fa-list{flex-direction:column;gap:2px;height:320px;display:flex;overflow-y:auto}.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{flex:1 1 0;min-width:0;container:lc-head-card/inline-size}.lc-head>.lc-card:first-child{flex-direction:column;display:flex}.lc-head>.lc-card:first-child .lc-stats{flex:1;align-content:stretch}.lc-head>.lc-card:first-child .lc-stat{justify-content:center}.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{font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, monospace);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-size:12px}.lc-error-retry{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;transition:border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);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}[data-conversation-scroll]:has(.lc-root)>[data-composer-seat]:not(:has([data-approval-key],[data-question-key],[data-plan-review-key])){display:none}";
|
|
6453
|
+
const css$13 = ".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-l2);border-radius:10px;margin-bottom:14px;padding:14px 16px}.lc-root .lc-card{margin-bottom:7px;padding:7px 8px}.lc-root .lc-cols{gap:7px;margin-bottom:7px}.lc-card-title{flex-wrap:wrap;align-items:baseline;gap:8px;margin-bottom:10px;font-weight:600;display:flex}.lc-card-title-text{white-space:nowrap;flex:none}.lc-gran,.lc-kinds{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);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;transition:color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);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-tip{z-index:6;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l1);width:max-content;color:var(--dsw-alias-label-primary);box-shadow:var(--dsw-shadow-lv3,0 2px 8px #0000002e);pointer-events:none;opacity:0;transition:opacity var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);border-radius:6px;padding:6px 10px;font-size:12px;position:absolute}.lc-events,.lc-fa-list{flex-direction:column;gap:2px;height:320px;display:flex;overflow-y:auto}.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{flex:1 1 0;min-width:0;container:lc-head-card/inline-size}.lc-head>.lc-card:first-child{flex-direction:column;display:flex}.lc-head>.lc-card:first-child .lc-stats{flex:1;align-content:stretch}.lc-head>.lc-card:first-child .lc-stat{justify-content:center}.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{font-family:var(--ds-font-family-code,ui-monospace, SFMono-Regular, Menlo, monospace);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-size:12px}.lc-error-retry{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;transition:border-color var(--ds-transition-duration,.2s) var(--ds-ease-in-out,ease-in-out);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}[data-conversation-scroll]:has(.lc-root)>[data-composer-seat]:not(:has([data-approval-key],[data-question-key],[data-plan-review-key])){display:none}";
|
|
6435
6454
|
const tagId$13 = "dsh-context/base.css";
|
|
6436
6455
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$13) + "]") === null) {
|
|
6437
6456
|
const tag = document.createElement("style");
|
package/lib/index.d.ts
CHANGED
|
@@ -112,14 +112,18 @@ interface TimelineState {
|
|
|
112
112
|
timing?: TimingTotals;
|
|
113
113
|
/**
|
|
114
114
|
* The open step's start instant, armed by `step/start` and consumed by the
|
|
115
|
-
* `assistant/message` (
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
115
|
+
* `assistant/message` (TTFT/generation split) and `step/end` (wall time)
|
|
116
|
+
* that follow it; `assistant/chunk` stamps `firstToken` on the step's first
|
|
117
|
+
* token delta — absent when the stream carried none (legacy or aborted
|
|
118
|
+
* steps), which leaves that call's model time unattributed. One slot, not a
|
|
119
|
+
* map: steps are sequential in the log, so the newest `step/start` is the
|
|
120
|
+
* one those events close — a hostile interleaved log degrades to skipped
|
|
121
|
+
* durations, never to unbounded state. Same arm/remove lifecycle as
|
|
122
|
+
* `pendingShadowedSeqs`.
|
|
120
123
|
*/
|
|
121
124
|
stepStart?: {
|
|
122
125
|
time: number;
|
|
126
|
+
firstToken?: number;
|
|
123
127
|
};
|
|
124
128
|
/**
|
|
125
129
|
* Tool callId → the call's name and start instant, armed by `tool/call` and
|
|
@@ -288,18 +292,22 @@ interface ToolTimingTotals {
|
|
|
288
292
|
}
|
|
289
293
|
/**
|
|
290
294
|
* Whole-session timing totals, host-folded from the durable `step/start` /
|
|
291
|
-
`step/end` / `tool/call` / `tool/result` lifecycle
|
|
292
|
-
* COMPLETE session log — the same never-trimmed
|
|
293
|
-
* are wall-clock milliseconds: `wallMs` sums
|
|
294
|
-
* step-start →
|
|
295
|
-
*
|
|
295
|
+
`step/end` / `assistant/chunk` / `tool/call` / `tool/result` lifecycle
|
|
296
|
+
* (running totals over the COMPLETE session log — the same never-trimmed
|
|
297
|
+
* framing as `cost`). Durations are wall-clock milliseconds: `wallMs` sums
|
|
298
|
+
* whole steps, `ttftMs` the step-start → first-token slice (the model wait)
|
|
299
|
+
* and `genMs` the first-token → assistant-message slice (the generation) —
|
|
300
|
+
* both only over calls whose stream carried a token delta, `toolsMs` the sum
|
|
301
|
+
* of per-call tool durations (parallel calls each count, so it can overlap).
|
|
296
302
|
* Absent until the first step lifecycle completes in the log.
|
|
297
303
|
*/
|
|
298
304
|
interface TimingTotals {
|
|
299
305
|
/** Summed wall time of completed steps (the session's active time). */
|
|
300
306
|
wallMs: number;
|
|
301
|
-
/** Summed step-start →
|
|
302
|
-
|
|
307
|
+
/** Summed step-start → first-token time (the model wait, TTFT). */
|
|
308
|
+
ttftMs: number;
|
|
309
|
+
/** Summed first-token → assistant-message time (the generation). */
|
|
310
|
+
genMs: number;
|
|
303
311
|
/** Completed model calls (assistant messages folded). */
|
|
304
312
|
calls: number;
|
|
305
313
|
/** Summed per-call durations of completed tool calls. */
|
package/lib/index.js
CHANGED
|
@@ -993,6 +993,21 @@ function durOf(from, to) {
|
|
|
993
993
|
return Math.max(0, to - from);
|
|
994
994
|
}
|
|
995
995
|
/**
|
|
996
|
+
* Whether a stream chunk carries a non-empty token delta — the first-token
|
|
997
|
+
* marker the TTFT fold waits for (the same rule as the harness's own
|
|
998
|
+
* session-stats fold). Shape-guarded: a malformed chunk is just not a token.
|
|
999
|
+
*/
|
|
1000
|
+
function isTokenDelta(chunk) {
|
|
1001
|
+
if (chunk === null || typeof chunk !== "object") return false;
|
|
1002
|
+
const c = chunk;
|
|
1003
|
+
switch (c.type) {
|
|
1004
|
+
case "text-delta":
|
|
1005
|
+
case "reasoning-delta": return typeof c.text === "string" && c.text !== "";
|
|
1006
|
+
case "tool-call-delta": return typeof c.argumentsDelta === "string" && c.argumentsDelta !== "" || c.name !== void 0;
|
|
1007
|
+
default: return false;
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
/**
|
|
996
1011
|
* The fold's private timing accumulator: created on first use, and CLONED on
|
|
997
1012
|
* every later ensure() (see `applyTimeline`) — the object left in the
|
|
998
1013
|
* persisted previous state is never written into in place.
|
|
@@ -1000,7 +1015,8 @@ function durOf(from, to) {
|
|
|
1000
1015
|
function ensureTiming(st) {
|
|
1001
1016
|
if (st.timing === void 0) st.timing = {
|
|
1002
1017
|
wallMs: 0,
|
|
1003
|
-
|
|
1018
|
+
ttftMs: 0,
|
|
1019
|
+
genMs: 0,
|
|
1004
1020
|
calls: 0,
|
|
1005
1021
|
toolsMs: 0,
|
|
1006
1022
|
toolCalls: 0,
|
|
@@ -1091,6 +1107,17 @@ function applyTimeline(state, event, bounds) {
|
|
|
1091
1107
|
};
|
|
1092
1108
|
}
|
|
1093
1109
|
break;
|
|
1110
|
+
case "assistant/chunk": {
|
|
1111
|
+
const start = state.stepStart;
|
|
1112
|
+
if (start === void 0 || start.firstToken !== void 0) return state;
|
|
1113
|
+
if (!isTokenDelta(data?.chunk)) return state;
|
|
1114
|
+
const s = ensure();
|
|
1115
|
+
s.stepStart = {
|
|
1116
|
+
time: start.time,
|
|
1117
|
+
firstToken: event.time
|
|
1118
|
+
};
|
|
1119
|
+
break;
|
|
1120
|
+
}
|
|
1094
1121
|
case "step/start": {
|
|
1095
1122
|
const s = ensure();
|
|
1096
1123
|
s.stepStart = { time: event.time };
|
|
@@ -1177,7 +1204,10 @@ function applyTimeline(state, event, bounds) {
|
|
|
1177
1204
|
const timing = ensureTiming(s);
|
|
1178
1205
|
timing.calls += 1;
|
|
1179
1206
|
const stepStart = state.stepStart;
|
|
1180
|
-
if (stepStart !== void 0
|
|
1207
|
+
if (stepStart !== void 0 && stepStart.firstToken !== void 0) {
|
|
1208
|
+
timing.ttftMs += durOf(stepStart.time, stepStart.firstToken);
|
|
1209
|
+
timing.genMs += durOf(stepStart.firstToken, event.time);
|
|
1210
|
+
}
|
|
1181
1211
|
const asstMsg = deriveEventMessage(event);
|
|
1182
1212
|
applySurface(s, event, event.type, data, asstMsg);
|
|
1183
1213
|
break;
|
|
@@ -1404,7 +1434,8 @@ const toolTimingSchema = z.object({
|
|
|
1404
1434
|
}).strict();
|
|
1405
1435
|
const timingTotalsSchema = z.object({
|
|
1406
1436
|
wallMs: z.number().nonnegative(),
|
|
1407
|
-
|
|
1437
|
+
ttftMs: z.number().nonnegative(),
|
|
1438
|
+
genMs: z.number().nonnegative(),
|
|
1408
1439
|
calls: z.number().int().nonnegative(),
|
|
1409
1440
|
toolsMs: z.number().nonnegative(),
|
|
1410
1441
|
toolCalls: z.number().int().nonnegative(),
|
|
@@ -1460,7 +1491,10 @@ const timelineStateSchema = z.object({
|
|
|
1460
1491
|
}).strict().optional(),
|
|
1461
1492
|
archiveFloor: z.number().optional(),
|
|
1462
1493
|
timing: timingTotalsSchema.optional(),
|
|
1463
|
-
stepStart: z.object({
|
|
1494
|
+
stepStart: z.object({
|
|
1495
|
+
time: z.number(),
|
|
1496
|
+
firstToken: z.number().optional()
|
|
1497
|
+
}).strict().optional(),
|
|
1464
1498
|
callNames: z.record(z.string(), z.object({
|
|
1465
1499
|
name: z.string(),
|
|
1466
1500
|
start: z.number()
|
|
@@ -1499,7 +1533,7 @@ function createContextTimelineDefinition(config) {
|
|
|
1499
1533
|
},
|
|
1500
1534
|
init: () => createTimelineState(),
|
|
1501
1535
|
apply: (state, event) => applyTimeline(state, event, bounds),
|
|
1502
|
-
stateVersion:
|
|
1536
|
+
stateVersion: 12
|
|
1503
1537
|
};
|
|
1504
1538
|
}
|
|
1505
1539
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-context",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.41.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": {
|