@tangle-network/charts 0.21.9 → 0.21.11
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/dist/react/flow-waterfall.css +25 -8
- package/dist/react/index.d.ts +3 -3
- package/dist/react/index.js +16 -7
- package/package.json +1 -1
|
@@ -22,12 +22,16 @@
|
|
|
22
22
|
--fw-failed: light-dark(#d4304a, #ff5c74);
|
|
23
23
|
--fw-ok: var(--status-running, light-dark(#0d8a5f, #34c48c));
|
|
24
24
|
--fw-amber: light-dark(#a35d00, #f2b14c);
|
|
25
|
+
/* Step kinds inside an agent bar: two hues far from each other and from the outcome greens and reds. */
|
|
26
|
+
--fw-kind-model: light-dark(#4f46e5, #8f91f7);
|
|
27
|
+
--fw-kind-tool: light-dark(#0e8fb0, #4cc9e6);
|
|
25
28
|
--fw-neutral-bar: color-mix(in oklab, var(--fw-text) 15%, var(--fw-surface));
|
|
26
29
|
--fw-hatch: color-mix(in oklab, var(--fw-text) 22%, transparent);
|
|
27
30
|
/* Root agent neutral, then five agent hues. Each passes 3:1 against both surfaces as a mark. */
|
|
28
31
|
--fw-h0: light-dark(#6c6f84, #a3a6bb);
|
|
29
32
|
--fw-h1: light-dark(#4b55d6, #8f96ff);
|
|
30
|
-
|
|
33
|
+
/* No warm hue among the agents: amber is kept for the slowest and red for failure. */
|
|
34
|
+
--fw-h2: light-dark(#3d8a52, #6fcb8a);
|
|
31
35
|
--fw-h3: light-dark(#0b87a0, #35c2db);
|
|
32
36
|
--fw-h4: light-dark(#b0418a, #dc72bb);
|
|
33
37
|
--fw-h5: light-dark(#6d44c7, #ab8cf7);
|
|
@@ -126,7 +130,7 @@
|
|
|
126
130
|
.fw-root .fw-marker-layer { position: absolute; top: 0; bottom: 0; left: var(--fw-label-col); right: 0; overflow: hidden; pointer-events: none; z-index: 2; }
|
|
127
131
|
/* An event's line is drawn behind the rows, with the gridlines, so bars and labels cover it; its label stays on top. */
|
|
128
132
|
.fw-root .fw-marker { --fw-marker: var(--fw-muted); position: absolute; top: 0; bottom: 0; width: 0; left: calc(var(--fw-pad) + (var(--s) - var(--fw-v0)) * var(--fw-k) * 1px); }
|
|
129
|
-
.fw-root .fw-marker-line { --fw-marker: var(--fw-muted); position: absolute; top: 0; bottom: 0; border-left: 1px dashed var(--fw-marker); left: calc(var(--fw-pad) + (var(--s) - var(--fw-v0)) * var(--fw-k) * 1px); }
|
|
133
|
+
.fw-root .fw-marker-line { --fw-marker: var(--fw-muted); opacity: .4; position: absolute; top: 0; bottom: 0; border-left: 1px dashed var(--fw-marker); left: calc(var(--fw-pad) + (var(--s) - var(--fw-v0)) * var(--fw-k) * 1px); }
|
|
130
134
|
.fw-root .fw-marker-line[data-tone="ok"] { --fw-marker: var(--fw-ok); }
|
|
131
135
|
.fw-root .fw-marker-line[data-tone="failed"] { --fw-marker: var(--fw-failed); }
|
|
132
136
|
.fw-root .fw-marker[data-tone="ok"] { --fw-marker: var(--fw-ok); }
|
|
@@ -192,7 +196,7 @@
|
|
|
192
196
|
.fw-root .fw-view-agents .fw-names { flex-direction: column; align-items: flex-start; gap: 0; }
|
|
193
197
|
.fw-root .fw-view-agents .fw-span-name { font-weight: 600; line-height: 18px; }
|
|
194
198
|
/* One 16 px line that wraps its last part out of sight: when the line is full the tool count drops whole, never "7 to…". */
|
|
195
|
-
.fw-root .fw-view-agents .fw-subtitle { display: flex; flex-wrap: wrap; align-items: center; column-gap: 4px; height: 16px; overflow: hidden; max-width: 100%; min-width: 0; color: var(--fw-muted); font-size:
|
|
199
|
+
.fw-root .fw-view-agents .fw-subtitle { display: flex; flex-wrap: wrap; align-items: center; column-gap: 4px; height: 16px; overflow: hidden; max-width: 100%; min-width: 0; color: var(--fw-muted); font-size: 13px; line-height: 16px; }
|
|
196
200
|
.fw-root .fw-view-agents .fw-subtitle-extra { flex: none; white-space: nowrap; }
|
|
197
201
|
.fw-root .fw-view-agents .fw-subtitle-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
198
202
|
.fw-root .fw-view-agents .fw-detail-icon { flex: none; width: 16px; height: 16px; align-items: center; justify-content: center; overflow: hidden; }
|
|
@@ -246,17 +250,22 @@
|
|
|
246
250
|
/* Muted agents (the default): one quiet tone for every agent bar, its steps and handoffs; the slowest agent alone takes amber, and
|
|
247
251
|
failure keeps its red glyph, so color only ever means state. */
|
|
248
252
|
.fw-root.fw-fill-muted .fw-view-agents [data-tone] { --tone: var(--fw-h0); }
|
|
249
|
-
.fw-root.fw-fill-muted .fw-view-agents .fw-row[data-slowest], .fw-root.fw-fill-muted .fw-view-agents .fw-row[data-slowest] [data-tone] { --tone: var(--fw-amber); }
|
|
253
|
+
.fw-root:is(.fw-fill-muted, .fw-fill-agent) .fw-view-agents .fw-row[data-slowest], .fw-root:is(.fw-fill-muted, .fw-fill-agent) .fw-view-agents .fw-row[data-slowest] [data-tone] { --tone: var(--fw-amber); }
|
|
250
254
|
.fw-root [data-outcome="ok"], .fw-root [data-outcome="ok"] [data-tone] { --tone: var(--fw-ok); }
|
|
251
255
|
.fw-root [data-outcome="failed"], .fw-root [data-outcome="failed"] [data-tone] { --tone: var(--fw-failed); }
|
|
252
256
|
.fw-root [data-outcome="warn"], .fw-root [data-outcome="warn"] [data-tone] { --tone: var(--fw-amber); }
|
|
253
257
|
.fw-root [data-outcome="neutral"], .fw-root [data-outcome="neutral"] [data-tone] { --tone: var(--fw-muted); }
|
|
254
258
|
.fw-root .fw-legend { display: flex; flex-wrap: wrap; gap: 4px 16px; margin: 8px 0 0; padding: 0; list-style: none; color: var(--fw-muted); font-size: 12px; line-height: 16px; }
|
|
255
259
|
.fw-root .fw-legend li { display: inline-flex; align-items: center; gap: 8px; }
|
|
256
|
-
.fw-root .fw-
|
|
257
|
-
.fw-root .fw-
|
|
258
|
-
.fw-root .fw-kinds
|
|
259
|
-
.fw-root .fw-kinds .fw-swatch-
|
|
260
|
+
.fw-root .fw-legends { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 24px; margin-top: 8px; }
|
|
261
|
+
.fw-root .fw-legends .fw-legend { margin: 0; }
|
|
262
|
+
.fw-root .fw-kinds { margin: 0; padding: 0; justify-content: flex-start; color: var(--fw-muted); }
|
|
263
|
+
.fw-root .fw-kinds .fw-swatch-model { width: 12px; height: 8px; border-radius: 2px; background: var(--fw-kind-model); }
|
|
264
|
+
/* With per-agent hues the key shows kind as shade, as the bars do: darker for a model call, lighter for a tool call. */
|
|
265
|
+
.fw-root.fw-fill-agent .fw-kinds .fw-swatch-model { background: color-mix(in oklab, var(--fw-text) 58%, var(--fw-surface)); }
|
|
266
|
+
.fw-root.fw-fill-agent .fw-kinds .fw-swatch-tool { background: color-mix(in oklab, var(--fw-text) 24%, var(--fw-surface)); }
|
|
267
|
+
.fw-root .fw-kinds .fw-swatch-tool { width: 12px; height: 8px; border-radius: 2px; background: var(--fw-kind-tool); }
|
|
268
|
+
.fw-root .fw-kinds .fw-swatch-wait { width: 12px; height: 8px; border-radius: 2px; background: color-mix(in oklab, var(--fw-text) 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--fw-text) 18%, transparent); }
|
|
260
269
|
.fw-root .fw-kinds .fw-swatch-handoff { width: 10px; height: 8px; border-left: 1.5px solid var(--fw-muted); border-bottom: 1.5px solid var(--fw-muted); border-bottom-left-radius: 3px; }
|
|
261
270
|
.fw-root .fw-kinds .fw-swatch-failed { width: 12px; height: 8px; border-radius: 2px; box-shadow: inset 0 0 0 1px var(--fw-failed); }
|
|
262
271
|
.fw-root .fw-description { margin: 0; color: var(--fw-muted); font-size: 14px; line-height: 20px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
@@ -269,6 +278,14 @@
|
|
|
269
278
|
.fw-root .fw-view-agents .fw-seg { pointer-events: auto; }
|
|
270
279
|
.fw-root .fw-seg-model { background: var(--fill); box-shadow: inset 0 0 0 1px var(--line); }
|
|
271
280
|
.fw-root .fw-seg-tool { background: var(--dim); box-shadow: inset 0 0 0 1px var(--dim-line); }
|
|
281
|
+
/* Without per-agent hues (muted or outcome fill), a step's kind owns its color; with them, kind is the darker and lighter shade of the
|
|
282
|
+
agent's own hue (the rules above), so each agent stays one color. */
|
|
283
|
+
.fw-root:is(.fw-fill-muted, .fw-fill-outcome) .fw-view-agents .fw-seg-model { background: var(--fw-kind-model); box-shadow: none; }
|
|
284
|
+
.fw-root:is(.fw-fill-muted, .fw-fill-outcome) .fw-view-agents .fw-seg-tool { background: var(--fw-kind-tool); box-shadow: none; }
|
|
285
|
+
.fw-root .fw-view-agents .fw-seg-tool { container-type: inline-size; justify-content: flex-start; }
|
|
286
|
+
.fw-root .fw-seg-name { padding: 0 6px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 11px; line-height: 16px; font-weight: 600; color: light-dark(#fff, #06222b); pointer-events: none; }
|
|
287
|
+
@container (max-width: 56px) { .fw-root .fw-seg-name { display: none; } }
|
|
288
|
+
.fw-root:is(.fw-fill-muted, .fw-fill-outcome) .fw-view-agents :is(.fw-seg-alt.fw-seg-model, .fw-seg-alt.fw-seg-tool) { filter: brightness(.88); }
|
|
272
289
|
.fw-root .fw-seg-failed { background: color-mix(in oklab, var(--fw-failed) 18%, var(--fw-surface)); box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--fw-failed) 70%, transparent); color: var(--fw-failed); }
|
|
273
290
|
/* In the agent view a failed turn draws like any turn; the agent's own failure shows once, by its name and its end label. */
|
|
274
291
|
.fw-root .fw-view-agents .fw-seg-failed { background: var(--dim); box-shadow: inset 0 0 0 1px var(--dim-line); }
|
package/dist/react/index.d.ts
CHANGED
|
@@ -399,9 +399,9 @@ interface FlowWaterfallProps {
|
|
|
399
399
|
markers?: FlowMarker[];
|
|
400
400
|
/** The time the reader moved to, in trace ms; `null` when following live or showing the whole trace. */
|
|
401
401
|
onTimeChange?: (t: number | null) => void;
|
|
402
|
-
/** What an agent bar's color means.
|
|
403
|
-
*
|
|
404
|
-
*
|
|
402
|
+
/** What an agent bar's color means. `agent` (default): each agent or family its own muted hue across dot, bar and handoffs, with
|
|
403
|
+
* model and tool steps as darker and lighter shades of it; the outcome stays on the row dot and amber marks the slowest (blind round
|
|
404
|
+
* 25: global step hues made agents blur together). `muted`: one quiet tone, color on state only. `outcome`: the bar takes its outcome. */
|
|
405
405
|
agentFill?: 'muted' | 'outcome' | 'agent';
|
|
406
406
|
/** One line beside the title saying what the run was for, such as its goal. */
|
|
407
407
|
description?: string;
|
package/dist/react/index.js
CHANGED
|
@@ -2586,7 +2586,8 @@ function segmentOf(row) {
|
|
|
2586
2586
|
tone: row.tone,
|
|
2587
2587
|
id: row.id,
|
|
2588
2588
|
count: 1,
|
|
2589
|
-
retry: row.retry
|
|
2589
|
+
retry: row.retry,
|
|
2590
|
+
name: row.name
|
|
2590
2591
|
};
|
|
2591
2592
|
}
|
|
2592
2593
|
/** Search keeps ancestor context and deliberately reveals matches inside collapsed branches. */
|
|
@@ -2760,7 +2761,7 @@ function agentFamilies(agents, open) {
|
|
|
2760
2761
|
costFloor: known.length < members.length || members.some((row) => row.costFloor),
|
|
2761
2762
|
id,
|
|
2762
2763
|
parentId: members[0].parentId,
|
|
2763
|
-
name:
|
|
2764
|
+
name: role,
|
|
2764
2765
|
kind: "pipeline",
|
|
2765
2766
|
durationLabel: formatSpanDuration(endMs - startMs),
|
|
2766
2767
|
approx: members.some((row) => row.approx),
|
|
@@ -2895,7 +2896,8 @@ function stepRuns(steps) {
|
|
|
2895
2896
|
tone: first.tone,
|
|
2896
2897
|
id: step.id,
|
|
2897
2898
|
count: 1,
|
|
2898
|
-
retry: step.retry
|
|
2899
|
+
retry: step.retry,
|
|
2900
|
+
name: step.name
|
|
2899
2901
|
})),
|
|
2900
2902
|
...costs.length ? { rollupCostUsd: costs.reduce((sum, cost) => sum + cost, 0) } : {},
|
|
2901
2903
|
span: {
|
|
@@ -3289,18 +3291,23 @@ const at = (startMs, endMs) => ({
|
|
|
3289
3291
|
const endLabelWidth = (label, slowest, costliest) => label.length * 7 + 8 + (slowest ? 74 : 0) + (costliest ? 84 : 0);
|
|
3290
3292
|
function Segment({ mark, events, agentView, ending }) {
|
|
3291
3293
|
const glyph = mark.kind === "failed" ? agentView && !ending ? null : /* @__PURE__ */ jsx(FailGlyph, {}) : mark.retry ? /* @__PURE__ */ jsx(RetryGlyph, {}) : null;
|
|
3294
|
+
const named = agentView && mark.kind === "tool" && mark.count === 1 && mark.name;
|
|
3292
3295
|
return /* @__PURE__ */ jsx("span", {
|
|
3293
3296
|
className: `fw-seg fw-seg-${mark.kind}${mark.alt ? " fw-seg-alt" : ""}`,
|
|
3294
3297
|
"data-tone": toneKey(mark.tone),
|
|
3295
3298
|
style: at(mark.startMs, mark.endMs),
|
|
3299
|
+
title: mark.name ? `${mark.name}${mark.count > 1 ? ` +${mark.count - 1} more` : ""}` : void 0,
|
|
3296
3300
|
onPointerEnter: agentView ? (event) => events.onInspect(mark.id, event.currentTarget) : void 0,
|
|
3297
3301
|
onClick: agentView ? (event) => {
|
|
3298
3302
|
event.stopPropagation();
|
|
3299
3303
|
events.onPin(mark.id, event.currentTarget);
|
|
3300
3304
|
} : void 0,
|
|
3301
|
-
children: glyph
|
|
3305
|
+
children: glyph ? /* @__PURE__ */ jsx("span", {
|
|
3302
3306
|
className: "fw-glyph",
|
|
3303
3307
|
children: glyph
|
|
3308
|
+
}) : named && /* @__PURE__ */ jsx("span", {
|
|
3309
|
+
className: "fw-seg-name",
|
|
3310
|
+
children: mark.name
|
|
3304
3311
|
})
|
|
3305
3312
|
});
|
|
3306
3313
|
}
|
|
@@ -4489,7 +4496,7 @@ function FlowWaterfall({ trace, live, startedAt, label = "Trace waterfall", defa
|
|
|
4489
4496
|
const [laneElement, setLaneElement] = useState(null);
|
|
4490
4497
|
const observedTotal = Number.isFinite(trace.totalMs) && trace.totalMs >= 0 ? trace.totalMs : 0;
|
|
4491
4498
|
const isLive = live ?? trace.spans.some(spanRunning);
|
|
4492
|
-
const agentFill = fillProp ??
|
|
4499
|
+
const agentFill = fillProp ?? "agent";
|
|
4493
4500
|
const dataEnd = useMemo(() => Math.max(observedTotal, ...trace.spans.map((span) => Number.isFinite(span.endMs) ? span.endMs : 0)), [trace, observedTotal]);
|
|
4494
4501
|
const trackPx = Math.max(40, laneWidth - LANE_PAD - Math.min(END_LABEL_GUTTER[view], laneWidth * .3));
|
|
4495
4502
|
useEffect(() => {
|
|
@@ -4849,7 +4856,10 @@ function FlowWaterfall({ trace, live, startedAt, label = "Trace waterfall", defa
|
|
|
4849
4856
|
done && speedup >= 1.05 ? ` · ${speedup.toFixed(1)}x parallel` : ""
|
|
4850
4857
|
]
|
|
4851
4858
|
}),
|
|
4852
|
-
/* @__PURE__ */
|
|
4859
|
+
/* @__PURE__ */ jsxs("div", {
|
|
4860
|
+
className: "fw-legends",
|
|
4861
|
+
children: [/* @__PURE__ */ jsx(OutcomeLegend, { agents }), view === "agents" && /* @__PURE__ */ jsx(KindLegend, { rows })]
|
|
4862
|
+
})
|
|
4853
4863
|
]
|
|
4854
4864
|
}), /* @__PURE__ */ jsxs("div", {
|
|
4855
4865
|
className: "fw-tools",
|
|
@@ -4915,7 +4925,6 @@ function FlowWaterfall({ trace, live, startedAt, label = "Trace waterfall", defa
|
|
|
4915
4925
|
}, name))
|
|
4916
4926
|
}),
|
|
4917
4927
|
view === "agents" && playback,
|
|
4918
|
-
view === "agents" && /* @__PURE__ */ jsx(KindLegend, { rows }),
|
|
4919
4928
|
/* @__PURE__ */ jsx(FlowBody, {
|
|
4920
4929
|
rows: visible,
|
|
4921
4930
|
byId,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/charts",
|
|
3
|
-
"version": "0.21.
|
|
3
|
+
"version": "0.21.11",
|
|
4
4
|
"description": "Static SVG and HTML figures for benchmarks and operational timing. Draws from producer data and refuses what it cannot draw honestly.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|