footprint-explainable-ui 0.14.0 → 0.14.1
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 +128 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +128 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -4086,6 +4086,123 @@ var VLinePill = (0, import_react19.memo)(function VLinePill2({
|
|
|
4086
4086
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { flex: 1, width: 1, background: theme.border } })
|
|
4087
4087
|
] });
|
|
4088
4088
|
});
|
|
4089
|
+
function detectKeyedSteps(data) {
|
|
4090
|
+
if (!data || typeof data !== "object") return null;
|
|
4091
|
+
const obj = data;
|
|
4092
|
+
for (const val of Object.values(obj)) {
|
|
4093
|
+
if (val && typeof val === "object" && !Array.isArray(val)) {
|
|
4094
|
+
const keys = Object.keys(val);
|
|
4095
|
+
if (keys.length > 0 && keys.every((k) => k.includes("#"))) {
|
|
4096
|
+
return val;
|
|
4097
|
+
}
|
|
4098
|
+
}
|
|
4099
|
+
}
|
|
4100
|
+
return null;
|
|
4101
|
+
}
|
|
4102
|
+
function findNumericField(entry) {
|
|
4103
|
+
for (const [k, v2] of Object.entries(entry)) {
|
|
4104
|
+
if (typeof v2 === "number") return { key: k, value: v2 };
|
|
4105
|
+
}
|
|
4106
|
+
return null;
|
|
4107
|
+
}
|
|
4108
|
+
function KeyedRecorderView({
|
|
4109
|
+
data,
|
|
4110
|
+
description,
|
|
4111
|
+
snapshots,
|
|
4112
|
+
selectedIndex
|
|
4113
|
+
}) {
|
|
4114
|
+
const [showAggregate, setShowAggregate] = (0, import_react19.useState)(false);
|
|
4115
|
+
const steps = (0, import_react19.useMemo)(() => detectKeyedSteps(data), [data]);
|
|
4116
|
+
const visibleIds = (0, import_react19.useMemo)(() => {
|
|
4117
|
+
const ids = /* @__PURE__ */ new Set();
|
|
4118
|
+
for (let i = 0; i <= selectedIndex && i < snapshots.length; i++) {
|
|
4119
|
+
const id = snapshots[i].runtimeStageId;
|
|
4120
|
+
if (id) ids.add(id);
|
|
4121
|
+
}
|
|
4122
|
+
return ids;
|
|
4123
|
+
}, [snapshots, selectedIndex]);
|
|
4124
|
+
const isAtEnd = selectedIndex >= snapshots.length - 1;
|
|
4125
|
+
if (!steps) {
|
|
4126
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("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) });
|
|
4127
|
+
}
|
|
4128
|
+
const allKeys = Object.keys(steps);
|
|
4129
|
+
const visibleEntries = allKeys.filter((k) => visibleIds.has(k));
|
|
4130
|
+
const numField = allKeys.length > 0 ? findNumericField(steps[allKeys[0]]) : null;
|
|
4131
|
+
const numFieldKey = numField?.key ?? "";
|
|
4132
|
+
let runningTotal = 0;
|
|
4133
|
+
if (numFieldKey) {
|
|
4134
|
+
for (const k of visibleEntries) {
|
|
4135
|
+
runningTotal += steps[k][numFieldKey] ?? 0;
|
|
4136
|
+
}
|
|
4137
|
+
}
|
|
4138
|
+
let grandTotal = 0;
|
|
4139
|
+
if (numFieldKey) {
|
|
4140
|
+
for (const entry of Object.values(steps)) {
|
|
4141
|
+
grandTotal += entry[numFieldKey] ?? 0;
|
|
4142
|
+
}
|
|
4143
|
+
}
|
|
4144
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { overflow: "auto", height: "100%", display: "flex", flexDirection: "column" }, children: [
|
|
4145
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { padding: "6px 12px", fontSize: 11, color: theme.textMuted, fontStyle: "italic", borderBottom: `1px solid ${theme.border}`, flexShrink: 0 }, children: description }),
|
|
4146
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { padding: 12, flex: 1, overflow: "auto" }, children: [
|
|
4147
|
+
visibleEntries.map((key) => {
|
|
4148
|
+
const entry = steps[key];
|
|
4149
|
+
const label = entry.stageName ?? key;
|
|
4150
|
+
const numVal = numFieldKey ? entry[numFieldKey] : void 0;
|
|
4151
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", alignItems: "center", padding: "4px 0", fontSize: 12, fontFamily: theme.fontMono, borderBottom: `1px solid ${theme.border}22` }, children: [
|
|
4152
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: { color: theme.textMuted, width: 140, flexShrink: 0, fontSize: 10 }, children: key }),
|
|
4153
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: { fontWeight: 600, flex: 1 }, children: label }),
|
|
4154
|
+
numVal !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: { color: theme.primary, fontWeight: 700, marginLeft: 8 }, children: numVal < 1 ? numVal.toFixed(3) : numVal.toFixed(1) })
|
|
4155
|
+
] }, key);
|
|
4156
|
+
}),
|
|
4157
|
+
visibleEntries.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { color: theme.textMuted, fontSize: 11, fontStyle: "italic", padding: "8px 0" }, children: "Scrub the slider to reveal entries..." }),
|
|
4158
|
+
numFieldKey && visibleEntries.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { marginTop: 12, padding: "8px 12px", background: `color-mix(in srgb, ${theme.primary} 8%, transparent)`, borderRadius: 6, fontSize: 12 }, children: [
|
|
4159
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { style: { color: theme.textMuted }, children: [
|
|
4160
|
+
"Running total (",
|
|
4161
|
+
numFieldKey,
|
|
4162
|
+
"):"
|
|
4163
|
+
] }),
|
|
4164
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: { fontWeight: 700, marginLeft: 8, color: theme.primary }, children: runningTotal < 1 ? runningTotal.toFixed(3) : runningTotal.toFixed(1) }),
|
|
4165
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { style: { color: theme.textMuted, marginLeft: 8, fontSize: 10 }, children: [
|
|
4166
|
+
"(",
|
|
4167
|
+
visibleEntries.length,
|
|
4168
|
+
" of ",
|
|
4169
|
+
allKeys.length,
|
|
4170
|
+
" steps)"
|
|
4171
|
+
] })
|
|
4172
|
+
] }),
|
|
4173
|
+
isAtEnd && numFieldKey && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { marginTop: 12 }, children: !showAggregate ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
4174
|
+
"button",
|
|
4175
|
+
{
|
|
4176
|
+
onClick: () => setShowAggregate(true),
|
|
4177
|
+
style: {
|
|
4178
|
+
background: theme.primary,
|
|
4179
|
+
color: "#fff",
|
|
4180
|
+
border: "none",
|
|
4181
|
+
borderRadius: 6,
|
|
4182
|
+
padding: "8px 16px",
|
|
4183
|
+
fontSize: 12,
|
|
4184
|
+
fontWeight: 600,
|
|
4185
|
+
cursor: "pointer",
|
|
4186
|
+
fontFamily: "inherit"
|
|
4187
|
+
},
|
|
4188
|
+
children: [
|
|
4189
|
+
"Aggregate (",
|
|
4190
|
+
numFieldKey,
|
|
4191
|
+
")"
|
|
4192
|
+
]
|
|
4193
|
+
}
|
|
4194
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { padding: "10px 14px", background: `color-mix(in srgb, ${theme.success} 12%, transparent)`, borderRadius: 6, border: `1px solid ${theme.success}44` }, children: [
|
|
4195
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 4 }, children: "Aggregate \u2014 Grand Total" }),
|
|
4196
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { fontSize: 20, fontWeight: 700, color: theme.success }, children: grandTotal < 1 ? grandTotal.toFixed(3) : grandTotal.toFixed(1) }),
|
|
4197
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { fontSize: 10, color: theme.textMuted, marginTop: 2 }, children: [
|
|
4198
|
+
allKeys.length,
|
|
4199
|
+
" steps \xB7 ",
|
|
4200
|
+
numFieldKey
|
|
4201
|
+
] })
|
|
4202
|
+
] }) })
|
|
4203
|
+
] })
|
|
4204
|
+
] });
|
|
4205
|
+
}
|
|
4089
4206
|
var DetailsContent = (0, import_react19.memo)(function DetailsContent2({
|
|
4090
4207
|
snapshots,
|
|
4091
4208
|
selectedIndex,
|
|
@@ -4259,10 +4376,10 @@ function ExplainableShell({
|
|
|
4259
4376
|
const allTabs = (0, import_react19.useMemo)(() => {
|
|
4260
4377
|
const tabs2 = [
|
|
4261
4378
|
{ id: "result", name: "Result", description: "Final output and console logs" },
|
|
4262
|
-
{ id: "memory", name: "Memory", description: "
|
|
4379
|
+
{ id: "memory", name: "Memory", description: "Accumulator \u2014 progressive shared state at each stage" }
|
|
4263
4380
|
];
|
|
4264
4381
|
if (hasNarrative) {
|
|
4265
|
-
tabs2.push({ id: "narrative", name: "Narrative", description: "
|
|
4382
|
+
tabs2.push({ id: "narrative", name: "Narrative", description: "Translator (SequenceRecorder) \u2014 interleaved flow + data narrative per execution step" });
|
|
4266
4383
|
}
|
|
4267
4384
|
for (const v2 of recorderViews ?? []) {
|
|
4268
4385
|
tabs2.push({ id: v2.id, name: v2.name, description: v2.description });
|
|
@@ -4430,17 +4547,15 @@ function ExplainableShell({
|
|
|
4430
4547
|
}
|
|
4431
4548
|
const autoView = autoRecorderViews.find((v2) => v2.id === activeTab);
|
|
4432
4549
|
if (autoView) {
|
|
4433
|
-
return /* @__PURE__ */ (0, import_jsx_runtime18.
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("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) })
|
|
4443
|
-
] });
|
|
4550
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4551
|
+
KeyedRecorderView,
|
|
4552
|
+
{
|
|
4553
|
+
data: autoView.data,
|
|
4554
|
+
description: autoView.description,
|
|
4555
|
+
snapshots: activeSnapshots,
|
|
4556
|
+
selectedIndex: safeIdx
|
|
4557
|
+
}
|
|
4558
|
+
);
|
|
4444
4559
|
}
|
|
4445
4560
|
return null;
|
|
4446
4561
|
}, [activeTab, resultData, logs, hideConsole, size, activeSnapshots, safeIdx, activeNarrativeEntries, activeNarrative, recorderViews, autoRecorderViews]);
|