footprint-explainable-ui 0.14.0 → 0.14.2
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/index.cjs +140 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +140 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4037,6 +4037,135 @@ var VLinePill = memo4(function VLinePill2({
|
|
|
4037
4037
|
/* @__PURE__ */ jsx18("div", { style: { flex: 1, width: 1, background: theme.border } })
|
|
4038
4038
|
] });
|
|
4039
4039
|
});
|
|
4040
|
+
function detectKeyedSteps(data) {
|
|
4041
|
+
if (!data || typeof data !== "object") return null;
|
|
4042
|
+
const obj = data;
|
|
4043
|
+
for (const val of Object.values(obj)) {
|
|
4044
|
+
if (val && typeof val === "object" && !Array.isArray(val)) {
|
|
4045
|
+
const entries = Object.entries(val);
|
|
4046
|
+
if (entries.length === 0) continue;
|
|
4047
|
+
const allObjectsWithNumbers = entries.every(([, v2]) => {
|
|
4048
|
+
if (!v2 || typeof v2 !== "object" || Array.isArray(v2)) return false;
|
|
4049
|
+
return Object.values(v2).some((f) => typeof f === "number");
|
|
4050
|
+
});
|
|
4051
|
+
if (allObjectsWithNumbers) {
|
|
4052
|
+
const keyType = entries.some(([k]) => k.includes("#")) ? "runtimeStageId" : "stageName";
|
|
4053
|
+
return { steps: val, keyType };
|
|
4054
|
+
}
|
|
4055
|
+
}
|
|
4056
|
+
}
|
|
4057
|
+
return null;
|
|
4058
|
+
}
|
|
4059
|
+
function findNumericField(entry) {
|
|
4060
|
+
for (const [k, v2] of Object.entries(entry)) {
|
|
4061
|
+
if (typeof v2 === "number") return { key: k, value: v2 };
|
|
4062
|
+
}
|
|
4063
|
+
return null;
|
|
4064
|
+
}
|
|
4065
|
+
function KeyedRecorderView({
|
|
4066
|
+
data,
|
|
4067
|
+
description,
|
|
4068
|
+
snapshots,
|
|
4069
|
+
selectedIndex
|
|
4070
|
+
}) {
|
|
4071
|
+
const [showAggregate, setShowAggregate] = useState9(false);
|
|
4072
|
+
const detected = useMemo11(() => detectKeyedSteps(data), [data]);
|
|
4073
|
+
const visibleKeys = useMemo11(() => {
|
|
4074
|
+
const keys = /* @__PURE__ */ new Set();
|
|
4075
|
+
for (let i = 0; i <= selectedIndex && i < snapshots.length; i++) {
|
|
4076
|
+
const snap = snapshots[i];
|
|
4077
|
+
if (detected?.keyType === "runtimeStageId") {
|
|
4078
|
+
if (snap.runtimeStageId) keys.add(snap.runtimeStageId);
|
|
4079
|
+
} else {
|
|
4080
|
+
if (snap.stageName) keys.add(snap.stageName);
|
|
4081
|
+
if (snap.stageLabel) keys.add(snap.stageLabel);
|
|
4082
|
+
}
|
|
4083
|
+
}
|
|
4084
|
+
return keys;
|
|
4085
|
+
}, [snapshots, selectedIndex, detected?.keyType]);
|
|
4086
|
+
const isAtEnd = selectedIndex >= snapshots.length - 1;
|
|
4087
|
+
if (!detected) {
|
|
4088
|
+
return /* @__PURE__ */ jsx18("div", { style: { padding: 12, fontFamily: theme.fontMono, fontSize: 11, whiteSpace: "pre-wrap", overflow: "auto", height: "100%" }, children: typeof data === "string" ? data : JSON.stringify(data, null, 2) });
|
|
4089
|
+
}
|
|
4090
|
+
const steps = detected.steps;
|
|
4091
|
+
const allKeys = Object.keys(steps);
|
|
4092
|
+
const visibleEntries = allKeys.filter((k) => visibleKeys.has(k));
|
|
4093
|
+
const numField = allKeys.length > 0 ? findNumericField(steps[allKeys[0]]) : null;
|
|
4094
|
+
const numFieldKey = numField?.key ?? "";
|
|
4095
|
+
let runningTotal = 0;
|
|
4096
|
+
if (numFieldKey) {
|
|
4097
|
+
for (const k of visibleEntries) {
|
|
4098
|
+
runningTotal += steps[k][numFieldKey] ?? 0;
|
|
4099
|
+
}
|
|
4100
|
+
}
|
|
4101
|
+
let grandTotal = 0;
|
|
4102
|
+
if (numFieldKey) {
|
|
4103
|
+
for (const entry of Object.values(steps)) {
|
|
4104
|
+
grandTotal += entry[numFieldKey] ?? 0;
|
|
4105
|
+
}
|
|
4106
|
+
}
|
|
4107
|
+
return /* @__PURE__ */ jsxs17("div", { style: { overflow: "auto", height: "100%", display: "flex", flexDirection: "column" }, children: [
|
|
4108
|
+
description && /* @__PURE__ */ jsx18("div", { style: { padding: "6px 12px", fontSize: 11, color: theme.textMuted, fontStyle: "italic", borderBottom: `1px solid ${theme.border}`, flexShrink: 0 }, children: description }),
|
|
4109
|
+
/* @__PURE__ */ jsxs17("div", { style: { padding: 12, flex: 1, overflow: "auto" }, children: [
|
|
4110
|
+
visibleEntries.map((key) => {
|
|
4111
|
+
const entry = steps[key];
|
|
4112
|
+
const label = entry.stageName ?? key;
|
|
4113
|
+
const numVal = numFieldKey ? entry[numFieldKey] : void 0;
|
|
4114
|
+
return /* @__PURE__ */ jsxs17("div", { style: { display: "flex", alignItems: "center", padding: "4px 0", fontSize: 12, fontFamily: theme.fontMono, borderBottom: `1px solid ${theme.border}22` }, children: [
|
|
4115
|
+
/* @__PURE__ */ jsx18("span", { style: { color: theme.textMuted, width: 140, flexShrink: 0, fontSize: 10 }, children: key }),
|
|
4116
|
+
/* @__PURE__ */ jsx18("span", { style: { fontWeight: 600, flex: 1 }, children: label }),
|
|
4117
|
+
numVal !== void 0 && /* @__PURE__ */ jsx18("span", { style: { color: theme.primary, fontWeight: 700, marginLeft: 8 }, children: numVal < 1 ? numVal.toFixed(3) : numVal.toFixed(1) })
|
|
4118
|
+
] }, key);
|
|
4119
|
+
}),
|
|
4120
|
+
visibleEntries.length === 0 && /* @__PURE__ */ jsx18("div", { style: { color: theme.textMuted, fontSize: 11, fontStyle: "italic", padding: "8px 0" }, children: "Scrub the slider to reveal entries..." }),
|
|
4121
|
+
numFieldKey && visibleEntries.length > 0 && /* @__PURE__ */ jsxs17("div", { style: { marginTop: 12, padding: "8px 12px", background: `color-mix(in srgb, ${theme.primary} 8%, transparent)`, borderRadius: 6, fontSize: 12 }, children: [
|
|
4122
|
+
/* @__PURE__ */ jsxs17("span", { style: { color: theme.textMuted }, children: [
|
|
4123
|
+
"Running total (",
|
|
4124
|
+
numFieldKey,
|
|
4125
|
+
"):"
|
|
4126
|
+
] }),
|
|
4127
|
+
/* @__PURE__ */ jsx18("span", { style: { fontWeight: 700, marginLeft: 8, color: theme.primary }, children: runningTotal < 1 ? runningTotal.toFixed(3) : runningTotal.toFixed(1) }),
|
|
4128
|
+
/* @__PURE__ */ jsxs17("span", { style: { color: theme.textMuted, marginLeft: 8, fontSize: 10 }, children: [
|
|
4129
|
+
"(",
|
|
4130
|
+
visibleEntries.length,
|
|
4131
|
+
" of ",
|
|
4132
|
+
allKeys.length,
|
|
4133
|
+
" steps)"
|
|
4134
|
+
] })
|
|
4135
|
+
] }),
|
|
4136
|
+
isAtEnd && numFieldKey && /* @__PURE__ */ jsx18("div", { style: { marginTop: 12 }, children: !showAggregate ? /* @__PURE__ */ jsxs17(
|
|
4137
|
+
"button",
|
|
4138
|
+
{
|
|
4139
|
+
onClick: () => setShowAggregate(true),
|
|
4140
|
+
style: {
|
|
4141
|
+
background: theme.primary,
|
|
4142
|
+
color: "#fff",
|
|
4143
|
+
border: "none",
|
|
4144
|
+
borderRadius: 6,
|
|
4145
|
+
padding: "8px 16px",
|
|
4146
|
+
fontSize: 12,
|
|
4147
|
+
fontWeight: 600,
|
|
4148
|
+
cursor: "pointer",
|
|
4149
|
+
fontFamily: "inherit"
|
|
4150
|
+
},
|
|
4151
|
+
children: [
|
|
4152
|
+
"Aggregate (",
|
|
4153
|
+
numFieldKey,
|
|
4154
|
+
")"
|
|
4155
|
+
]
|
|
4156
|
+
}
|
|
4157
|
+
) : /* @__PURE__ */ jsxs17("div", { style: { padding: "10px 14px", background: `color-mix(in srgb, ${theme.success} 12%, transparent)`, borderRadius: 6, border: `1px solid ${theme.success}44` }, children: [
|
|
4158
|
+
/* @__PURE__ */ jsx18("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 4 }, children: "Aggregate \u2014 Grand Total" }),
|
|
4159
|
+
/* @__PURE__ */ jsx18("div", { style: { fontSize: 20, fontWeight: 700, color: theme.success }, children: grandTotal < 1 ? grandTotal.toFixed(3) : grandTotal.toFixed(1) }),
|
|
4160
|
+
/* @__PURE__ */ jsxs17("div", { style: { fontSize: 10, color: theme.textMuted, marginTop: 2 }, children: [
|
|
4161
|
+
allKeys.length,
|
|
4162
|
+
" steps \xB7 ",
|
|
4163
|
+
numFieldKey
|
|
4164
|
+
] })
|
|
4165
|
+
] }) })
|
|
4166
|
+
] })
|
|
4167
|
+
] });
|
|
4168
|
+
}
|
|
4040
4169
|
var DetailsContent = memo4(function DetailsContent2({
|
|
4041
4170
|
snapshots,
|
|
4042
4171
|
selectedIndex,
|
|
@@ -4210,10 +4339,10 @@ function ExplainableShell({
|
|
|
4210
4339
|
const allTabs = useMemo11(() => {
|
|
4211
4340
|
const tabs2 = [
|
|
4212
4341
|
{ id: "result", name: "Result", description: "Final output and console logs" },
|
|
4213
|
-
{ id: "memory", name: "Memory", description: "
|
|
4342
|
+
{ id: "memory", name: "Memory", description: "Accumulator \u2014 progressive shared state at each stage" }
|
|
4214
4343
|
];
|
|
4215
4344
|
if (hasNarrative) {
|
|
4216
|
-
tabs2.push({ id: "narrative", name: "Narrative", description: "
|
|
4345
|
+
tabs2.push({ id: "narrative", name: "Narrative", description: "Translator (SequenceRecorder) \u2014 interleaved flow + data narrative per execution step" });
|
|
4217
4346
|
}
|
|
4218
4347
|
for (const v2 of recorderViews ?? []) {
|
|
4219
4348
|
tabs2.push({ id: v2.id, name: v2.name, description: v2.description });
|
|
@@ -4381,17 +4510,15 @@ function ExplainableShell({
|
|
|
4381
4510
|
}
|
|
4382
4511
|
const autoView = autoRecorderViews.find((v2) => v2.id === activeTab);
|
|
4383
4512
|
if (autoView) {
|
|
4384
|
-
return /* @__PURE__ */
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
/* @__PURE__ */ jsx18("div", { style: { padding: 12, fontFamily: theme.fontMono, fontSize: 11, whiteSpace: "pre-wrap", overflow: "auto", flex: 1 }, children: typeof autoView.data === "string" ? autoView.data : JSON.stringify(autoView.data, null, 2) })
|
|
4394
|
-
] });
|
|
4513
|
+
return /* @__PURE__ */ jsx18(
|
|
4514
|
+
KeyedRecorderView,
|
|
4515
|
+
{
|
|
4516
|
+
data: autoView.data,
|
|
4517
|
+
description: autoView.description,
|
|
4518
|
+
snapshots: activeSnapshots,
|
|
4519
|
+
selectedIndex: safeIdx
|
|
4520
|
+
}
|
|
4521
|
+
);
|
|
4395
4522
|
}
|
|
4396
4523
|
return null;
|
|
4397
4524
|
}, [activeTab, resultData, logs, hideConsole, size, activeSnapshots, safeIdx, activeNarrativeEntries, activeNarrative, recorderViews, autoRecorderViews]);
|