@tangle-network/sandbox-ui 0.74.0 → 0.75.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.
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
COMPACT_NODE_SIZE,
|
|
6
6
|
buildWorkflowGraph,
|
|
7
7
|
providerLabel
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-FNE5QLU3.js";
|
|
9
9
|
import "./chunk-U67V476Y.js";
|
|
10
10
|
|
|
11
11
|
// src/workflows/WorkflowGraph.tsx
|
|
@@ -21,19 +21,7 @@ import {
|
|
|
21
21
|
useNodesState
|
|
22
22
|
} from "@xyflow/react";
|
|
23
23
|
import "@xyflow/react/dist/style.css";
|
|
24
|
-
import {
|
|
25
|
-
Bell,
|
|
26
|
-
Box,
|
|
27
|
-
Cable,
|
|
28
|
-
Circle,
|
|
29
|
-
Clock,
|
|
30
|
-
Maximize2,
|
|
31
|
-
Minimize2,
|
|
32
|
-
Repeat,
|
|
33
|
-
Sparkles,
|
|
34
|
-
Split,
|
|
35
|
-
Webhook
|
|
36
|
-
} from "lucide-react";
|
|
24
|
+
import { Maximize2, Minimize2 } from "lucide-react";
|
|
37
25
|
import {
|
|
38
26
|
createContext,
|
|
39
27
|
useCallback,
|
|
@@ -125,7 +113,10 @@ function fmtCost(usd) {
|
|
|
125
113
|
return usd < 0.01 ? `$${usd.toFixed(4)}` : `$${usd.toFixed(2)}`;
|
|
126
114
|
}
|
|
127
115
|
function clampPreview(text, max = 200) {
|
|
128
|
-
|
|
116
|
+
if (text.length <= max) return text;
|
|
117
|
+
const lastCode = text.charCodeAt(max - 1);
|
|
118
|
+
const end = lastCode >= 55296 && lastCode <= 56319 ? max - 1 : max;
|
|
119
|
+
return `${text.slice(0, end)}\u2026`;
|
|
129
120
|
}
|
|
130
121
|
function fmtTokens(input, output) {
|
|
131
122
|
const valid = (n) => n !== void 0 && Number.isFinite(n) && n >= 0 ? n : void 0;
|
|
@@ -135,23 +126,103 @@ function fmtTokens(input, output) {
|
|
|
135
126
|
return `${i ?? 0}/${o ?? 0} tok`;
|
|
136
127
|
}
|
|
137
128
|
|
|
138
|
-
// src/workflows/
|
|
139
|
-
import {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
129
|
+
// src/workflows/node-output.tsx
|
|
130
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
131
|
+
var MAX_JSON_ENTRIES = 6;
|
|
132
|
+
function scalar(value) {
|
|
133
|
+
if (value === null) return "null";
|
|
134
|
+
if (typeof value === "string") return value;
|
|
135
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
136
|
+
return String(value);
|
|
137
|
+
}
|
|
138
|
+
if (Array.isArray(value)) {
|
|
139
|
+
return `[${value.length} item${value.length === 1 ? "" : "s"}]`;
|
|
140
|
+
}
|
|
141
|
+
if (typeof value === "object") return "{\u2026}";
|
|
142
|
+
return "";
|
|
143
|
+
}
|
|
144
|
+
function classifyOutput(preview) {
|
|
145
|
+
let trimmed = preview?.trim() ?? "";
|
|
146
|
+
trimmed = trimmed.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])/g, "").replace(/(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "").trimEnd();
|
|
147
|
+
if (trimmed === "") return { kind: "empty" };
|
|
148
|
+
const structured = trimmed.startsWith("{") || trimmed.startsWith("[");
|
|
149
|
+
if (structured) {
|
|
150
|
+
try {
|
|
151
|
+
const parsed = JSON.parse(trimmed);
|
|
152
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
153
|
+
const all = Object.entries(parsed);
|
|
154
|
+
const entries = all.slice(0, MAX_JSON_ENTRIES).map(([k, v]) => [k, scalar(v)]);
|
|
155
|
+
if (entries.length > 0) {
|
|
156
|
+
return { kind: "json", entries, truncated: all.length > entries.length };
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return { kind: "code", text: trimmed };
|
|
160
|
+
} catch {
|
|
161
|
+
return { kind: "code", text: trimmed };
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return { kind: "text", text: trimmed };
|
|
165
|
+
}
|
|
166
|
+
var CLAMP_BY_ROWS = {
|
|
167
|
+
1: "truncate",
|
|
168
|
+
2: "line-clamp-2",
|
|
169
|
+
3: "line-clamp-3"
|
|
170
|
+
};
|
|
171
|
+
function NodeOutputBody({
|
|
172
|
+
shape,
|
|
173
|
+
rows = 2,
|
|
174
|
+
tone = "default"
|
|
175
|
+
}) {
|
|
176
|
+
const clampClass = CLAMP_BY_ROWS[rows] ?? "line-clamp-2";
|
|
177
|
+
const codeWrap = rows === 1 ? "" : "whitespace-pre-wrap break-all";
|
|
178
|
+
if (shape.kind === "empty") return null;
|
|
179
|
+
if (shape.kind === "json") {
|
|
180
|
+
const overflow = shape.truncated || shape.entries.length > rows;
|
|
181
|
+
const visible = shape.entries.slice(0, overflow ? Math.max(0, rows - 1) : rows);
|
|
182
|
+
const isError = tone === "error";
|
|
183
|
+
const keyClass = isError ? "text-red-400/80" : "text-muted-foreground";
|
|
184
|
+
const valueClass = isError ? "text-red-400" : "text-foreground";
|
|
185
|
+
return /* @__PURE__ */ jsxs("dl", { className: "space-y-0.5 font-mono text-[10px] leading-tight", children: [
|
|
186
|
+
visible.map(([key, value]) => /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5", children: [
|
|
187
|
+
/* @__PURE__ */ jsx("dt", { className: `max-w-[45%] shrink-0 truncate ${keyClass}`, title: key, children: key }),
|
|
188
|
+
/* @__PURE__ */ jsx("dd", { className: `min-w-0 flex-1 truncate ${valueClass}`, title: value, children: value })
|
|
189
|
+
] }, key)),
|
|
190
|
+
overflow && /* @__PURE__ */ jsx("div", { className: `text-[9px] ${keyClass}`, children: "\u2026" })
|
|
191
|
+
] });
|
|
192
|
+
}
|
|
193
|
+
if (shape.kind === "code") {
|
|
194
|
+
return /* @__PURE__ */ jsx(
|
|
195
|
+
"pre",
|
|
196
|
+
{
|
|
197
|
+
className: `${clampClass} ${codeWrap} font-mono text-[10px] leading-tight ${tone === "error" ? "text-red-400" : "text-foreground/80"}`,
|
|
198
|
+
title: shape.text,
|
|
199
|
+
children: shape.text
|
|
200
|
+
}
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
return /* @__PURE__ */ jsx(
|
|
204
|
+
"p",
|
|
205
|
+
{
|
|
206
|
+
className: `${clampClass} text-[10px] leading-snug ${tone === "error" ? "text-red-400" : "text-muted-foreground"}`,
|
|
207
|
+
title: shape.text,
|
|
208
|
+
children: shape.text
|
|
209
|
+
}
|
|
143
210
|
);
|
|
144
|
-
useEffect(() => {
|
|
145
|
-
const el = document.documentElement;
|
|
146
|
-
const update = () => setMode(el.classList.contains("dark") ? "dark" : "light");
|
|
147
|
-
update();
|
|
148
|
-
const observer = new MutationObserver(update);
|
|
149
|
-
observer.observe(el, { attributes: true, attributeFilter: ["class"] });
|
|
150
|
-
return () => observer.disconnect();
|
|
151
|
-
}, []);
|
|
152
|
-
return mode;
|
|
153
211
|
}
|
|
154
|
-
|
|
212
|
+
|
|
213
|
+
// src/workflows/node-ui.tsx
|
|
214
|
+
import {
|
|
215
|
+
Bell,
|
|
216
|
+
Box,
|
|
217
|
+
Cable,
|
|
218
|
+
Circle,
|
|
219
|
+
Clock,
|
|
220
|
+
Repeat,
|
|
221
|
+
Sparkles,
|
|
222
|
+
Split,
|
|
223
|
+
Webhook
|
|
224
|
+
} from "lucide-react";
|
|
225
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
155
226
|
var TONE_ACCENT = {
|
|
156
227
|
trigger: "hsl(var(--primary))",
|
|
157
228
|
structural: "var(--surface-warning-text)",
|
|
@@ -167,7 +238,45 @@ var STATUS_COLOR = {
|
|
|
167
238
|
succeeded: EDGE_DONE,
|
|
168
239
|
failed: EDGE_FAIL
|
|
169
240
|
};
|
|
170
|
-
|
|
241
|
+
function edgeColor(status) {
|
|
242
|
+
switch (status) {
|
|
243
|
+
case "running":
|
|
244
|
+
return EDGE_RUNNING;
|
|
245
|
+
case "succeeded":
|
|
246
|
+
return EDGE_DONE;
|
|
247
|
+
case "failed":
|
|
248
|
+
return EDGE_FAIL;
|
|
249
|
+
default:
|
|
250
|
+
return EDGE_MUTED;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
var STATUS_LABEL = {
|
|
254
|
+
queued: "Queued",
|
|
255
|
+
running: "Running",
|
|
256
|
+
succeeded: "Done",
|
|
257
|
+
failed: "Failed"
|
|
258
|
+
};
|
|
259
|
+
var STATUS_BADGE = {
|
|
260
|
+
queued: "bg-surface-container-high text-muted-foreground",
|
|
261
|
+
running: "bg-primary/15 text-primary",
|
|
262
|
+
succeeded: "bg-green-600/10 text-green-600",
|
|
263
|
+
failed: "bg-red-500/10 text-red-400"
|
|
264
|
+
};
|
|
265
|
+
function statusBorder(status) {
|
|
266
|
+
switch (status) {
|
|
267
|
+
case "running":
|
|
268
|
+
return "border-primary ring-1 ring-primary/40";
|
|
269
|
+
case "succeeded":
|
|
270
|
+
return "border-green-500";
|
|
271
|
+
case "failed":
|
|
272
|
+
return "border-red-500";
|
|
273
|
+
default:
|
|
274
|
+
return "opacity-70";
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
function progressFill(status) {
|
|
278
|
+
return status === "succeeded" || status === "failed" ? "100%" : status === "running" ? "58%" : "6%";
|
|
279
|
+
}
|
|
171
280
|
var KIND_ICON = {
|
|
172
281
|
schedule: Clock,
|
|
173
282
|
provider_event: Webhook,
|
|
@@ -186,7 +295,7 @@ function NodeIcon({
|
|
|
186
295
|
glyph
|
|
187
296
|
}) {
|
|
188
297
|
const Icon = kind && KIND_ICON[kind] || Circle;
|
|
189
|
-
return /* @__PURE__ */
|
|
298
|
+
return /* @__PURE__ */ jsx2(
|
|
190
299
|
"span",
|
|
191
300
|
{
|
|
192
301
|
"aria-hidden": "true",
|
|
@@ -197,76 +306,64 @@ function NodeIcon({
|
|
|
197
306
|
background: `color-mix(in srgb, ${accent} 16%, transparent)`,
|
|
198
307
|
color: accent
|
|
199
308
|
},
|
|
200
|
-
children: /* @__PURE__ */
|
|
309
|
+
children: /* @__PURE__ */ jsx2(Icon, { size: glyph, strokeWidth: 2 })
|
|
201
310
|
}
|
|
202
311
|
);
|
|
203
312
|
}
|
|
204
|
-
function
|
|
313
|
+
function MetaChip({
|
|
314
|
+
children,
|
|
315
|
+
title
|
|
316
|
+
}) {
|
|
317
|
+
return /* @__PURE__ */ jsx2(
|
|
318
|
+
"span",
|
|
319
|
+
{
|
|
320
|
+
title,
|
|
321
|
+
className: "inline-block max-w-[150px] truncate rounded bg-surface-container-high px-1.5 py-0.5 align-middle text-[10px] text-muted-foreground",
|
|
322
|
+
children
|
|
323
|
+
}
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// src/workflows/WorkflowGraph.tsx
|
|
328
|
+
import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
329
|
+
var MUTED_TRACK = "color-mix(in srgb, hsl(var(--muted-foreground)) 22%, transparent)";
|
|
330
|
+
function useColorMode() {
|
|
331
|
+
const [mode, setMode] = useState(
|
|
332
|
+
() => typeof document !== "undefined" && document.documentElement.classList.contains("dark") ? "dark" : "light"
|
|
333
|
+
);
|
|
334
|
+
useEffect(() => {
|
|
335
|
+
const el = document.documentElement;
|
|
336
|
+
const update = () => setMode(el.classList.contains("dark") ? "dark" : "light");
|
|
337
|
+
update();
|
|
338
|
+
const observer = new MutationObserver(update);
|
|
339
|
+
observer.observe(el, { attributes: true, attributeFilter: ["class"] });
|
|
340
|
+
return () => observer.disconnect();
|
|
341
|
+
}, []);
|
|
342
|
+
return mode;
|
|
343
|
+
}
|
|
344
|
+
var DirectionContext = createContext("LR");
|
|
345
|
+
var DensityContext = createContext(false);
|
|
346
|
+
function StatusFooter({
|
|
205
347
|
status,
|
|
206
348
|
rounds,
|
|
207
349
|
elapsed
|
|
208
350
|
}) {
|
|
209
|
-
const color = STATUS_COLOR[status];
|
|
210
|
-
const fill = status === "succeeded" || status === "failed" ? "100%" : status === "running" ? "58%" : "6%";
|
|
211
351
|
const roundsLabel = rounds !== void 0 ? `${rounds} round${rounds === 1 ? "" : "s"}` : void 0;
|
|
212
|
-
return /* @__PURE__ */
|
|
213
|
-
/* @__PURE__ */
|
|
352
|
+
return /* @__PURE__ */ jsxs2("div", { className: "mt-auto border-border/60 border-t", children: [
|
|
353
|
+
/* @__PURE__ */ jsx3("div", { className: "h-1 w-full overflow-hidden", style: { background: MUTED_TRACK }, children: /* @__PURE__ */ jsx3(
|
|
214
354
|
"div",
|
|
215
355
|
{
|
|
216
|
-
className:
|
|
217
|
-
style: {
|
|
218
|
-
background: "color-mix(in srgb, hsl(var(--muted-foreground)) 22%, transparent)"
|
|
219
|
-
},
|
|
220
|
-
children: /* @__PURE__ */ jsx(
|
|
221
|
-
"div",
|
|
222
|
-
{
|
|
223
|
-
className: `h-full rounded-full ${status === "running" ? "animate-pulse" : ""}`,
|
|
224
|
-
style: { width: fill, background: color }
|
|
225
|
-
}
|
|
226
|
-
)
|
|
356
|
+
className: `h-full ${status === "running" ? "animate-pulse" : ""}`,
|
|
357
|
+
style: { width: progressFill(status), background: STATUS_COLOR[status] }
|
|
227
358
|
}
|
|
228
|
-
),
|
|
229
|
-
|
|
230
|
-
/* @__PURE__ */
|
|
231
|
-
elapsed && /* @__PURE__ */
|
|
359
|
+
) }),
|
|
360
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between gap-2 px-3 py-1 text-[9px] text-muted-foreground", children: [
|
|
361
|
+
/* @__PURE__ */ jsx3("span", { className: "truncate", children: roundsLabel ?? "" }),
|
|
362
|
+
elapsed && /* @__PURE__ */ jsx3("span", { className: "shrink-0", children: elapsed })
|
|
232
363
|
] })
|
|
233
364
|
] });
|
|
234
365
|
}
|
|
235
366
|
var HANDLE_CLASS = "!h-2 !w-2 !min-w-0 !border-0 !bg-transparent opacity-0";
|
|
236
|
-
var STATUS_LABEL = {
|
|
237
|
-
queued: "Queued",
|
|
238
|
-
running: "Running",
|
|
239
|
-
succeeded: "Done",
|
|
240
|
-
failed: "Failed"
|
|
241
|
-
};
|
|
242
|
-
var STATUS_BADGE = {
|
|
243
|
-
queued: "bg-surface-container-high text-muted-foreground",
|
|
244
|
-
running: "bg-primary/15 text-primary",
|
|
245
|
-
succeeded: "bg-green-600/10 text-green-600",
|
|
246
|
-
failed: "bg-red-500/10 text-red-400"
|
|
247
|
-
};
|
|
248
|
-
function statusBorder(status) {
|
|
249
|
-
switch (status) {
|
|
250
|
-
case "running":
|
|
251
|
-
return "border-primary ring-1 ring-primary/40";
|
|
252
|
-
case "succeeded":
|
|
253
|
-
return "border-green-500";
|
|
254
|
-
case "failed":
|
|
255
|
-
return "border-red-500";
|
|
256
|
-
default:
|
|
257
|
-
return "opacity-70";
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
function MetaChip({ children, title }) {
|
|
261
|
-
return /* @__PURE__ */ jsx(
|
|
262
|
-
"span",
|
|
263
|
-
{
|
|
264
|
-
title,
|
|
265
|
-
className: "inline-block max-w-[150px] truncate rounded bg-surface-container-high px-1.5 py-0.5 align-middle text-[10px] text-muted-foreground",
|
|
266
|
-
children
|
|
267
|
-
}
|
|
268
|
-
);
|
|
269
|
-
}
|
|
270
367
|
function WorkflowNode({ data }) {
|
|
271
368
|
const d = data;
|
|
272
369
|
const state = d.state;
|
|
@@ -281,49 +378,55 @@ function WorkflowNode({ data }) {
|
|
|
281
378
|
const duration = fmtDuration(state?.durationMs);
|
|
282
379
|
const cost = fmtCost(state?.costUsd);
|
|
283
380
|
const tokens = isAgent ? fmtTokens(state?.inputTokens, state?.outputTokens) : void 0;
|
|
284
|
-
const
|
|
285
|
-
|
|
381
|
+
const runOutput = (() => {
|
|
382
|
+
const source = state?.status === "failed" && state.error ? { text: state.error, tone: "error", label: "Error" } : state && state.status !== "failed" && state.outputPreview ? { text: state.outputPreview, tone: "default", label: "Output" } : null;
|
|
383
|
+
if (!source) return null;
|
|
384
|
+
const trimmed = source.text.trim();
|
|
385
|
+
if (!trimmed) return null;
|
|
386
|
+
const shape = classifyOutput(clampPreview(trimmed));
|
|
387
|
+
return shape.kind === "empty" ? null : { shape, tone: source.tone, label: source.label };
|
|
388
|
+
})();
|
|
286
389
|
const wrapperClass = `relative flex h-full w-full flex-col overflow-hidden rounded-lg border bg-card shadow-sm transition-colors ${state ? statusBorder(state.status) : ""}`;
|
|
287
390
|
const wrapperStyle = state ? state.status === "running" ? { boxShadow: "0 0 22px -6px hsl(var(--primary))" } : void 0 : {
|
|
288
391
|
borderColor: `color-mix(in srgb, ${accent} 42%, transparent)`,
|
|
289
392
|
backgroundColor: `color-mix(in srgb, ${accent} 6%, hsl(var(--card)))`
|
|
290
393
|
};
|
|
291
|
-
const handles = /* @__PURE__ */
|
|
292
|
-
!d.isRoot && /* @__PURE__ */
|
|
293
|
-
/* @__PURE__ */
|
|
394
|
+
const handles = /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
395
|
+
!d.isRoot && /* @__PURE__ */ jsx3(Handle, { type: "target", position: targetPos, className: HANDLE_CLASS }),
|
|
396
|
+
/* @__PURE__ */ jsx3(Handle, { type: "source", position: sourcePos, className: HANDLE_CLASS })
|
|
294
397
|
] });
|
|
295
398
|
if (compact) {
|
|
296
|
-
return /* @__PURE__ */
|
|
399
|
+
return /* @__PURE__ */ jsxs2("div", { className: `${wrapperClass} justify-center px-2.5`, style: wrapperStyle, children: [
|
|
297
400
|
handles,
|
|
298
|
-
/* @__PURE__ */
|
|
299
|
-
/* @__PURE__ */
|
|
300
|
-
/* @__PURE__ */
|
|
301
|
-
/* @__PURE__ */
|
|
302
|
-
/* @__PURE__ */
|
|
303
|
-
state ? /* @__PURE__ */
|
|
401
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2.5", children: [
|
|
402
|
+
/* @__PURE__ */ jsx3(NodeIcon, { kind: d.kind, accent, box: 32, glyph: 16 }),
|
|
403
|
+
/* @__PURE__ */ jsxs2("div", { className: "min-w-0 flex-1", children: [
|
|
404
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-1.5", children: [
|
|
405
|
+
/* @__PURE__ */ jsx3("span", { className: "truncate font-medium text-[12px] text-foreground", children: d.title }),
|
|
406
|
+
state ? /* @__PURE__ */ jsx3(
|
|
304
407
|
"span",
|
|
305
408
|
{
|
|
306
409
|
className: "ml-auto h-1.5 w-1.5 shrink-0 rounded-full",
|
|
307
410
|
style: { backgroundColor: STATUS_COLOR[state.status] }
|
|
308
411
|
}
|
|
309
|
-
) : d.badge && /* @__PURE__ */
|
|
412
|
+
) : d.badge && /* @__PURE__ */ jsx3("span", { className: "ml-auto shrink-0 rounded bg-surface-container-high px-1 py-0.5 text-[9px] text-muted-foreground", children: d.badge })
|
|
310
413
|
] }),
|
|
311
|
-
/* @__PURE__ */
|
|
312
|
-
/* @__PURE__ */
|
|
313
|
-
cost && /* @__PURE__ */
|
|
314
|
-
duration && /* @__PURE__ */
|
|
414
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-1.5 text-[10px] text-muted-foreground", children: [
|
|
415
|
+
/* @__PURE__ */ jsx3("span", { className: "truncate", children: model ?? d.subtitle ?? d.kind }),
|
|
416
|
+
cost && /* @__PURE__ */ jsx3("span", { className: "ml-auto shrink-0", children: cost }),
|
|
417
|
+
duration && /* @__PURE__ */ jsxs2("span", { className: "shrink-0", children: [
|
|
315
418
|
"\xB7 ",
|
|
316
419
|
duration
|
|
317
420
|
] })
|
|
318
421
|
] })
|
|
319
422
|
] })
|
|
320
423
|
] }),
|
|
321
|
-
state?.status === "running" && /* @__PURE__ */
|
|
424
|
+
state?.status === "running" && /* @__PURE__ */ jsx3(
|
|
322
425
|
"div",
|
|
323
426
|
{
|
|
324
427
|
className: "mt-1.5 h-0.5 w-full overflow-hidden rounded-full",
|
|
325
|
-
style: { background:
|
|
326
|
-
children: /* @__PURE__ */
|
|
428
|
+
style: { background: MUTED_TRACK },
|
|
429
|
+
children: /* @__PURE__ */ jsx3(
|
|
327
430
|
"div",
|
|
328
431
|
{
|
|
329
432
|
className: "h-full w-1/2 animate-pulse rounded-full",
|
|
@@ -334,83 +437,61 @@ function WorkflowNode({ data }) {
|
|
|
334
437
|
)
|
|
335
438
|
] });
|
|
336
439
|
}
|
|
337
|
-
return /* @__PURE__ */
|
|
440
|
+
return /* @__PURE__ */ jsxs2("div", { className: wrapperClass, style: wrapperStyle, children: [
|
|
338
441
|
handles,
|
|
339
|
-
/* @__PURE__ */
|
|
340
|
-
/* @__PURE__ */
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
442
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex min-h-0 flex-1 flex-col px-3 pt-2 pb-2", children: [
|
|
443
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2", children: [
|
|
444
|
+
/* @__PURE__ */ jsx3(NodeIcon, { kind: d.kind, accent, box: 24, glyph: 14 }),
|
|
445
|
+
/* @__PURE__ */ jsx3("span", { className: "truncate font-medium text-[12px] text-foreground", children: d.title }),
|
|
446
|
+
state ? /* @__PURE__ */ jsx3(
|
|
447
|
+
"span",
|
|
448
|
+
{
|
|
449
|
+
className: `ml-auto shrink-0 rounded px-1.5 py-0.5 text-[10px] ${STATUS_BADGE[state.status]}`,
|
|
450
|
+
children: STATUS_LABEL[state.status]
|
|
451
|
+
}
|
|
452
|
+
) : d.badge && /* @__PURE__ */ jsx3("span", { className: "ml-auto shrink-0 rounded bg-surface-container-high px-1.5 py-0.5 text-[10px] text-muted-foreground", children: d.badge })
|
|
453
|
+
] }),
|
|
454
|
+
d.subtitle && /* @__PURE__ */ jsx3(
|
|
455
|
+
"p",
|
|
344
456
|
{
|
|
345
|
-
className:
|
|
346
|
-
|
|
457
|
+
className: "mt-1 truncate text-[11px] text-muted-foreground",
|
|
458
|
+
title: d.subtitle,
|
|
459
|
+
children: d.subtitle
|
|
347
460
|
}
|
|
348
|
-
)
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
tokens && /* @__PURE__ */
|
|
461
|
+
),
|
|
462
|
+
d.provider && /* @__PURE__ */ jsxs2("span", { className: "mt-1.5 inline-flex w-fit items-center gap-1 rounded bg-surface-container-high px-1.5 py-0.5 text-[10px] text-muted-foreground", children: [
|
|
463
|
+
/* @__PURE__ */ jsx3(
|
|
464
|
+
ProviderIcon,
|
|
465
|
+
{
|
|
466
|
+
id: d.provider,
|
|
467
|
+
displayName: providerLabel(d.provider),
|
|
468
|
+
size: 12,
|
|
469
|
+
className: "rounded-[2px]"
|
|
470
|
+
}
|
|
471
|
+
),
|
|
472
|
+
providerLabel(d.provider)
|
|
473
|
+
] }),
|
|
474
|
+
(model || cost || tokens) && /* @__PURE__ */ jsxs2("div", { className: "mt-1.5 flex flex-wrap items-center gap-1", children: [
|
|
475
|
+
model && /* @__PURE__ */ jsx3(MetaChip, { title: model, children: model }),
|
|
476
|
+
cost && /* @__PURE__ */ jsx3(MetaChip, { children: cost }),
|
|
477
|
+
tokens && /* @__PURE__ */ jsx3(MetaChip, { children: tokens })
|
|
478
|
+
] }),
|
|
479
|
+
runOutput && /* @__PURE__ */ jsxs2("div", { className: "mt-1.5 min-h-0", children: [
|
|
480
|
+
/* @__PURE__ */ jsx3("div", { className: "mb-0.5 font-medium text-[8px] text-muted-foreground/70 uppercase tracking-[0.08em]", children: runOutput.label }),
|
|
481
|
+
/* @__PURE__ */ jsx3(NodeOutputBody, { shape: runOutput.shape, tone: runOutput.tone, rows: 2 })
|
|
482
|
+
] })
|
|
362
483
|
] }),
|
|
363
|
-
state
|
|
364
|
-
|
|
365
|
-
{
|
|
366
|
-
className: "mt-1.5 line-clamp-2 text-[10px] text-red-400",
|
|
367
|
-
title: errorText,
|
|
368
|
-
children: errorText
|
|
369
|
-
}
|
|
370
|
-
),
|
|
371
|
-
outputText && state?.status !== "failed" && /* @__PURE__ */ jsx(
|
|
372
|
-
"p",
|
|
373
|
-
{
|
|
374
|
-
className: "mt-1.5 line-clamp-2 text-[10px] text-muted-foreground",
|
|
375
|
-
title: outputText,
|
|
376
|
-
children: outputText
|
|
377
|
-
}
|
|
378
|
-
),
|
|
379
|
-
state && d.tone !== "trigger" && /* @__PURE__ */ jsx(
|
|
380
|
-
ProgressStrip,
|
|
484
|
+
state && d.tone !== "trigger" && /* @__PURE__ */ jsx3(
|
|
485
|
+
StatusFooter,
|
|
381
486
|
{
|
|
382
487
|
status: state.status,
|
|
383
488
|
rounds: isAgent ? state.rounds : void 0,
|
|
384
489
|
elapsed: duration
|
|
385
490
|
}
|
|
386
|
-
)
|
|
387
|
-
d.provider && /* @__PURE__ */ jsxs("span", { className: "mt-1.5 inline-flex w-fit items-center gap-1 rounded bg-surface-container-high px-1.5 py-0.5 text-[10px] text-muted-foreground", children: [
|
|
388
|
-
/* @__PURE__ */ jsx(
|
|
389
|
-
ProviderIcon,
|
|
390
|
-
{
|
|
391
|
-
id: d.provider,
|
|
392
|
-
displayName: providerLabel(d.provider),
|
|
393
|
-
size: 12,
|
|
394
|
-
className: "rounded-[2px]"
|
|
395
|
-
}
|
|
396
|
-
),
|
|
397
|
-
providerLabel(d.provider)
|
|
398
|
-
] })
|
|
491
|
+
)
|
|
399
492
|
] });
|
|
400
493
|
}
|
|
401
494
|
var NODE_TYPES = { wfNode: WorkflowNode };
|
|
402
|
-
function edgeColor(status) {
|
|
403
|
-
switch (status) {
|
|
404
|
-
case "running":
|
|
405
|
-
return EDGE_RUNNING;
|
|
406
|
-
case "succeeded":
|
|
407
|
-
return EDGE_DONE;
|
|
408
|
-
case "failed":
|
|
409
|
-
return EDGE_FAIL;
|
|
410
|
-
default:
|
|
411
|
-
return EDGE_MUTED;
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
495
|
function buildStyledEdges(base, nodeState) {
|
|
415
496
|
return base.map((e) => {
|
|
416
497
|
const status = nodeState?.[e.target]?.status;
|
|
@@ -486,7 +567,7 @@ function WorkflowGraph({
|
|
|
486
567
|
[onNodeClick]
|
|
487
568
|
);
|
|
488
569
|
if (structural.error || structural.nodes.length === 0) {
|
|
489
|
-
return /* @__PURE__ */
|
|
570
|
+
return /* @__PURE__ */ jsx3(
|
|
490
571
|
"div",
|
|
491
572
|
{
|
|
492
573
|
className: `flex items-center justify-center rounded-lg border border-border border-dashed p-4 text-center text-muted-foreground text-xs ${className ?? ""}`,
|
|
@@ -494,7 +575,7 @@ function WorkflowGraph({
|
|
|
494
575
|
}
|
|
495
576
|
);
|
|
496
577
|
}
|
|
497
|
-
return /* @__PURE__ */
|
|
578
|
+
return /* @__PURE__ */ jsx3(DirectionContext.Provider, { value: direction, children: /* @__PURE__ */ jsx3(DensityContext.Provider, { value: compact, children: /* @__PURE__ */ jsx3("div", { className: `wf-graph ${className ?? ""}`, children: /* @__PURE__ */ jsxs2(
|
|
498
579
|
ReactFlow,
|
|
499
580
|
{
|
|
500
581
|
nodes,
|
|
@@ -524,10 +605,10 @@ function WorkflowGraph({
|
|
|
524
605
|
minZoom: 0.2,
|
|
525
606
|
maxZoom: 1.5,
|
|
526
607
|
children: [
|
|
527
|
-
/* @__PURE__ */
|
|
528
|
-
!isPreview && /* @__PURE__ */
|
|
529
|
-
/* @__PURE__ */
|
|
530
|
-
/* @__PURE__ */
|
|
608
|
+
/* @__PURE__ */ jsx3(Background, { gap: 18 }),
|
|
609
|
+
!isPreview && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
610
|
+
/* @__PURE__ */ jsx3(Controls, { showInteractive: false, position: "bottom-right" }),
|
|
611
|
+
/* @__PURE__ */ jsx3(Panel, { position: "top-left", children: /* @__PURE__ */ jsxs2(
|
|
531
612
|
"button",
|
|
532
613
|
{
|
|
533
614
|
type: "button",
|
|
@@ -536,7 +617,7 @@ function WorkflowGraph({
|
|
|
536
617
|
title: userCompact ? "Expand nodes" : "Collapse nodes",
|
|
537
618
|
className: "flex items-center gap-1 rounded-md border border-border bg-card/80 px-2 py-1 text-[11px] text-muted-foreground shadow-sm backdrop-blur transition hover:text-foreground",
|
|
538
619
|
children: [
|
|
539
|
-
userCompact ? /* @__PURE__ */
|
|
620
|
+
userCompact ? /* @__PURE__ */ jsx3(Maximize2, { size: 12 }) : /* @__PURE__ */ jsx3(Minimize2, { size: 12 }),
|
|
540
621
|
userCompact ? "Expand" : "Compact"
|
|
541
622
|
]
|
|
542
623
|
}
|
|
@@ -18,19 +18,19 @@ import { parse as parseYaml } from "yaml";
|
|
|
18
18
|
var NODE_W = 244;
|
|
19
19
|
var RANK_SEP = 76;
|
|
20
20
|
var CROSS_SEP = 22;
|
|
21
|
-
var CARD_CHROME =
|
|
22
|
-
var HEADER_ROW =
|
|
21
|
+
var CARD_CHROME = 18;
|
|
22
|
+
var HEADER_ROW = 28;
|
|
23
23
|
var TEXT_ROW = 20;
|
|
24
24
|
var META_ROW = 46;
|
|
25
|
-
var
|
|
26
|
-
var
|
|
25
|
+
var OUTPUT_ROW = 44;
|
|
26
|
+
var FOOTER_ROW = 26;
|
|
27
27
|
var COMPACT_NODE_SIZE = { width: 240, height: 64 };
|
|
28
28
|
function nodeHeight(data, withRunState) {
|
|
29
29
|
let h = CARD_CHROME + HEADER_ROW;
|
|
30
30
|
if (data.subtitle) h += TEXT_ROW;
|
|
31
|
-
if (withRunState || data.model) h += META_ROW;
|
|
32
|
-
if (withRunState) h += PREVIEW_ROW + PROGRESS_ROW;
|
|
33
31
|
if (data.provider) h += TEXT_ROW;
|
|
32
|
+
if (withRunState || data.model) h += META_ROW;
|
|
33
|
+
if (withRunState) h += OUTPUT_ROW + FOOTER_ROW;
|
|
34
34
|
return h;
|
|
35
35
|
}
|
|
36
36
|
function asRecord(v) {
|
package/dist/globals.css
CHANGED
|
@@ -75,6 +75,7 @@
|
|
|
75
75
|
--tracking-wider: 0.05em;
|
|
76
76
|
--tracking-widest: 0.1em;
|
|
77
77
|
--leading-tight: 1.25;
|
|
78
|
+
--leading-snug: 1.375;
|
|
78
79
|
--leading-relaxed: 1.625;
|
|
79
80
|
--radius-sm: 0.25rem;
|
|
80
81
|
--radius-md: 0.375rem;
|
|
@@ -542,6 +543,9 @@
|
|
|
542
543
|
.mt-6 {
|
|
543
544
|
margin-top: calc(var(--spacing) * 6);
|
|
544
545
|
}
|
|
546
|
+
.mt-auto {
|
|
547
|
+
margin-top: auto;
|
|
548
|
+
}
|
|
545
549
|
.mr-1 {
|
|
546
550
|
margin-right: calc(var(--spacing) * 1);
|
|
547
551
|
}
|
|
@@ -626,6 +630,12 @@
|
|
|
626
630
|
-webkit-box-orient: vertical;
|
|
627
631
|
-webkit-line-clamp: 2;
|
|
628
632
|
}
|
|
633
|
+
.line-clamp-3 {
|
|
634
|
+
overflow: hidden;
|
|
635
|
+
display: -webkit-box;
|
|
636
|
+
-webkit-box-orient: vertical;
|
|
637
|
+
-webkit-line-clamp: 3;
|
|
638
|
+
}
|
|
629
639
|
.block {
|
|
630
640
|
display: block;
|
|
631
641
|
}
|
|
@@ -1186,6 +1196,9 @@
|
|
|
1186
1196
|
.max-w-\[14rem\] {
|
|
1187
1197
|
max-width: 14rem;
|
|
1188
1198
|
}
|
|
1199
|
+
.max-w-\[45\%\] {
|
|
1200
|
+
max-width: 45%;
|
|
1201
|
+
}
|
|
1189
1202
|
.max-w-\[75\%\] {
|
|
1190
1203
|
max-width: 75%;
|
|
1191
1204
|
}
|
|
@@ -1922,6 +1935,12 @@
|
|
|
1922
1935
|
.border-border {
|
|
1923
1936
|
border-color: var(--color-border);
|
|
1924
1937
|
}
|
|
1938
|
+
.border-border\/60 {
|
|
1939
|
+
border-color: color-mix(in srgb, hsl(var(--border)) 60%, transparent);
|
|
1940
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1941
|
+
border-color: color-mix(in oklab, var(--color-border) 60%, transparent);
|
|
1942
|
+
}
|
|
1943
|
+
}
|
|
1925
1944
|
.border-destructive\/20 {
|
|
1926
1945
|
border-color: color-mix(in srgb, hsl(var(--destructive)) 20%, transparent);
|
|
1927
1946
|
@supports (color: color-mix(in lab, red, red)) {
|
|
@@ -2961,6 +2980,10 @@
|
|
|
2961
2980
|
--tw-leading: var(--leading-relaxed);
|
|
2962
2981
|
line-height: var(--leading-relaxed);
|
|
2963
2982
|
}
|
|
2983
|
+
.leading-snug {
|
|
2984
|
+
--tw-leading: var(--leading-snug);
|
|
2985
|
+
line-height: var(--leading-snug);
|
|
2986
|
+
}
|
|
2964
2987
|
.leading-tight {
|
|
2965
2988
|
--tw-leading: var(--leading-tight);
|
|
2966
2989
|
line-height: var(--leading-tight);
|
|
@@ -3286,6 +3309,12 @@
|
|
|
3286
3309
|
.text-red-400 {
|
|
3287
3310
|
color: var(--color-red-400);
|
|
3288
3311
|
}
|
|
3312
|
+
.text-red-400\/80 {
|
|
3313
|
+
color: color-mix(in srgb, oklch(70.4% 0.191 22.216) 80%, transparent);
|
|
3314
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
3315
|
+
color: color-mix(in oklab, var(--color-red-400) 80%, transparent);
|
|
3316
|
+
}
|
|
3317
|
+
}
|
|
3289
3318
|
.text-secondary-foreground {
|
|
3290
3319
|
color: var(--color-secondary-foreground);
|
|
3291
3320
|
}
|
package/dist/styles.css
CHANGED
|
@@ -75,6 +75,7 @@
|
|
|
75
75
|
--tracking-wider: 0.05em;
|
|
76
76
|
--tracking-widest: 0.1em;
|
|
77
77
|
--leading-tight: 1.25;
|
|
78
|
+
--leading-snug: 1.375;
|
|
78
79
|
--leading-relaxed: 1.625;
|
|
79
80
|
--radius-sm: 0.25rem;
|
|
80
81
|
--radius-md: 0.375rem;
|
|
@@ -542,6 +543,9 @@
|
|
|
542
543
|
.mt-6 {
|
|
543
544
|
margin-top: calc(var(--spacing) * 6);
|
|
544
545
|
}
|
|
546
|
+
.mt-auto {
|
|
547
|
+
margin-top: auto;
|
|
548
|
+
}
|
|
545
549
|
.mr-1 {
|
|
546
550
|
margin-right: calc(var(--spacing) * 1);
|
|
547
551
|
}
|
|
@@ -626,6 +630,12 @@
|
|
|
626
630
|
-webkit-box-orient: vertical;
|
|
627
631
|
-webkit-line-clamp: 2;
|
|
628
632
|
}
|
|
633
|
+
.line-clamp-3 {
|
|
634
|
+
overflow: hidden;
|
|
635
|
+
display: -webkit-box;
|
|
636
|
+
-webkit-box-orient: vertical;
|
|
637
|
+
-webkit-line-clamp: 3;
|
|
638
|
+
}
|
|
629
639
|
.block {
|
|
630
640
|
display: block;
|
|
631
641
|
}
|
|
@@ -1186,6 +1196,9 @@
|
|
|
1186
1196
|
.max-w-\[14rem\] {
|
|
1187
1197
|
max-width: 14rem;
|
|
1188
1198
|
}
|
|
1199
|
+
.max-w-\[45\%\] {
|
|
1200
|
+
max-width: 45%;
|
|
1201
|
+
}
|
|
1189
1202
|
.max-w-\[75\%\] {
|
|
1190
1203
|
max-width: 75%;
|
|
1191
1204
|
}
|
|
@@ -1922,6 +1935,12 @@
|
|
|
1922
1935
|
.border-border {
|
|
1923
1936
|
border-color: var(--color-border);
|
|
1924
1937
|
}
|
|
1938
|
+
.border-border\/60 {
|
|
1939
|
+
border-color: color-mix(in srgb, hsl(var(--border)) 60%, transparent);
|
|
1940
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1941
|
+
border-color: color-mix(in oklab, var(--color-border) 60%, transparent);
|
|
1942
|
+
}
|
|
1943
|
+
}
|
|
1925
1944
|
.border-destructive\/20 {
|
|
1926
1945
|
border-color: color-mix(in srgb, hsl(var(--destructive)) 20%, transparent);
|
|
1927
1946
|
@supports (color: color-mix(in lab, red, red)) {
|
|
@@ -2961,6 +2980,10 @@
|
|
|
2961
2980
|
--tw-leading: var(--leading-relaxed);
|
|
2962
2981
|
line-height: var(--leading-relaxed);
|
|
2963
2982
|
}
|
|
2983
|
+
.leading-snug {
|
|
2984
|
+
--tw-leading: var(--leading-snug);
|
|
2985
|
+
line-height: var(--leading-snug);
|
|
2986
|
+
}
|
|
2964
2987
|
.leading-tight {
|
|
2965
2988
|
--tw-leading: var(--leading-tight);
|
|
2966
2989
|
line-height: var(--leading-tight);
|
|
@@ -3286,6 +3309,12 @@
|
|
|
3286
3309
|
.text-red-400 {
|
|
3287
3310
|
color: var(--color-red-400);
|
|
3288
3311
|
}
|
|
3312
|
+
.text-red-400\/80 {
|
|
3313
|
+
color: color-mix(in srgb, oklch(70.4% 0.191 22.216) 80%, transparent);
|
|
3314
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
3315
|
+
color: color-mix(in oklab, var(--color-red-400) 80%, transparent);
|
|
3316
|
+
}
|
|
3317
|
+
}
|
|
3289
3318
|
.text-secondary-foreground {
|
|
3290
3319
|
color: var(--color-secondary-foreground);
|
|
3291
3320
|
}
|
package/dist/workflows.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
buildWorkflowGraph
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-FNE5QLU3.js";
|
|
4
4
|
import "./chunk-U67V476Y.js";
|
|
5
5
|
|
|
6
6
|
// src/workflows/WorkflowGraphLazy.tsx
|
|
@@ -26,7 +26,7 @@ function retryImport(factory, retries = 2, delayMs = 350) {
|
|
|
26
26
|
function lazyWorkflowGraph() {
|
|
27
27
|
return lazy(
|
|
28
28
|
() => retryImport(
|
|
29
|
-
() => import("./WorkflowGraph-
|
|
29
|
+
() => import("./WorkflowGraph-RA7ZHN4I.js").then((m) => ({ default: m.WorkflowGraph }))
|
|
30
30
|
)
|
|
31
31
|
);
|
|
32
32
|
}
|
package/package.json
CHANGED