@genfeedai/workflow-ui 0.2.3 → 0.2.5

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.
Files changed (45) hide show
  1. package/dist/canvas.d.ts +22 -22
  2. package/dist/canvas.mjs +16 -16
  3. package/dist/{chunk-XPZAHIWY.mjs → chunk-2FUPL67V.mjs} +1592 -1044
  4. package/dist/{chunk-HWVTD2LC.mjs → chunk-53XDE62A.mjs} +818 -623
  5. package/dist/{chunk-PCIWWD37.mjs → chunk-7LV4UAUS.mjs} +19 -19
  6. package/dist/{chunk-7SKSRSS7.mjs → chunk-B4EAAKYF.mjs} +16 -16
  7. package/dist/{chunk-ZJD5WMR3.mjs → chunk-C6MQBJFC.mjs} +45 -13
  8. package/dist/{chunk-7H3WJJYS.mjs → chunk-ESVULCFY.mjs} +12 -6
  9. package/dist/{chunk-GWBGK3KL.mjs → chunk-FWJIAW2E.mjs} +82 -47
  10. package/dist/{chunk-R727OFBR.mjs → chunk-GPYIIWD5.mjs} +404 -350
  11. package/dist/{chunk-OQREHJXK.mjs → chunk-IYFWAJBB.mjs} +208 -203
  12. package/dist/{chunk-N5NJZTK4.mjs → chunk-MGLAKMDP.mjs} +23 -21
  13. package/dist/{chunk-LT3ZJJL6.mjs → chunk-OJWVEEMM.mjs} +497 -399
  14. package/dist/{chunk-ZD2BADZO.mjs → chunk-ORVDYXDP.mjs} +221 -175
  15. package/dist/{chunk-CV4M7CNU.mjs → chunk-QQVHGJ2G.mjs} +149 -142
  16. package/dist/{chunk-6PSJTBNV.mjs → chunk-U4QPE4CY.mjs} +387 -347
  17. package/dist/{chunk-EFXQT23N.mjs → chunk-VVQ4CH77.mjs} +5 -5
  18. package/dist/{chunk-VRN3UWE5.mjs → chunk-XRC3O5GK.mjs} +73 -73
  19. package/dist/{chunk-FT33LFII.mjs → chunk-YUIK4AHM.mjs} +1 -1
  20. package/dist/{chunk-FMJPFB6W.mjs → chunk-ZSITTZ4S.mjs} +630 -569
  21. package/dist/hooks.d.ts +37 -37
  22. package/dist/hooks.mjs +10 -10
  23. package/dist/index.d.ts +26 -11
  24. package/dist/index.mjs +105 -19
  25. package/dist/lib.d.ts +203 -203
  26. package/dist/lib.mjs +228 -198
  27. package/dist/nodes.d.ts +2 -2
  28. package/dist/nodes.mjs +12 -12
  29. package/dist/panels.d.ts +2 -3
  30. package/dist/panels.mjs +3 -3
  31. package/dist/provider.d.ts +2 -2
  32. package/dist/provider.mjs +2 -2
  33. package/dist/stores.d.ts +5 -5
  34. package/dist/stores.mjs +5 -5
  35. package/dist/toolbar.d.ts +42 -24
  36. package/dist/toolbar.mjs +4 -4
  37. package/dist/ui.d.ts +2 -2
  38. package/dist/ui.mjs +2 -2
  39. package/dist/{useCommentNavigation-BakbiiIc.d.ts → useRequiredInputs-ByoIS-fT.d.ts} +160 -160
  40. package/dist/{promptLibraryStore-Dl3Q3cP6.d.ts → workflowStore-Bsz0nd5c.d.ts} +368 -368
  41. package/dist/workflowStore-N2F7WIG3.mjs +2 -0
  42. package/package.json +77 -75
  43. package/src/styles/workflow-ui.css +56 -19
  44. package/dist/workflowStore-UAAKOOIK.mjs +0 -2
  45. package/dist/{types-IEKYuYhu.d.ts → types-CRXJnajq.d.ts} +1 -1
@@ -1,78 +1,228 @@
1
- import { useExecutionStore, useUIStore } from './chunk-LT3ZJJL6.mjs';
2
- import { getNodesByCategory } from '@genfeedai/types';
3
- import { Bug, Trash2, X, ChevronDown, ChevronRight, Copy, PanelLeftClose, Search, GitBranch, ArrowLeftFromLine, ArrowRightToLine, Download, Eye, CheckCircle, Columns2, LayoutGrid, Subtitles, Pencil, Grid3X3, Maximize, Crop, Film, Scissors, Layers, Wand2, Maximize2, Navigation, AudioLines, Mic, Brain, Video, Sparkles, Puzzle, Volume2, FileVideo, FileText, MessageSquare, Image } from 'lucide-react';
1
+ import { useExecutionStore, useUIStore } from './chunk-OJWVEEMM.mjs';
2
+ import { Bug, Trash2, X, ChevronDown, ChevronRight, Copy, PanelLeftClose, Search, Wand2, Volume2, Video, Subtitles, Sparkles, Scissors, Puzzle, Pencil, Navigation, Mic, MessageSquare, Maximize2, Maximize, LayoutGrid, Layers, Image, Grid3X3, GitBranch, Film, FileVideo, FileText, Eye, Download, Crop, Columns2, CheckCircle, Brain, AudioLines, ArrowRightToLine, ArrowLeftFromLine } from 'lucide-react';
4
3
  import { forwardRef, memo, useCallback, useState, useMemo } from 'react';
5
4
  import { jsx, jsxs } from 'react/jsx-runtime';
5
+ import { getNodesByCategory } from '@genfeedai/types';
6
6
 
7
+ var PanelContainer = forwardRef(
8
+ ({ children, className, ...props }, ref) => {
9
+ const stopPropagation = (e) => {
10
+ e.stopPropagation();
11
+ };
12
+ return /* @__PURE__ */ jsx(
13
+ "div",
14
+ {
15
+ ref,
16
+ className,
17
+ onClick: stopPropagation,
18
+ onMouseDown: stopPropagation,
19
+ onPointerDown: stopPropagation,
20
+ onDoubleClick: stopPropagation,
21
+ ...props,
22
+ children
23
+ }
24
+ );
25
+ }
26
+ );
27
+ PanelContainer.displayName = "PanelContainer";
28
+ function PayloadCard({ payload }) {
29
+ const [isExpanded, setIsExpanded] = useState(false);
30
+ const [copied, setCopied] = useState(false);
31
+ const handleCopy = useCallback(
32
+ async (e) => {
33
+ e.stopPropagation();
34
+ try {
35
+ await navigator.clipboard.writeText(
36
+ JSON.stringify(payload.input, null, 2)
37
+ );
38
+ setCopied(true);
39
+ setTimeout(() => setCopied(false), 2e3);
40
+ } catch {
41
+ const textArea = document.createElement("textarea");
42
+ textArea.value = JSON.stringify(payload.input, null, 2);
43
+ textArea.style.position = "fixed";
44
+ textArea.style.left = "-9999px";
45
+ document.body.appendChild(textArea);
46
+ textArea.select();
47
+ try {
48
+ document.execCommand("copy");
49
+ setCopied(true);
50
+ setTimeout(() => setCopied(false), 2e3);
51
+ } catch {
52
+ }
53
+ document.body.removeChild(textArea);
54
+ }
55
+ },
56
+ [payload.input]
57
+ );
58
+ const timestamp = new Date(payload.timestamp).toLocaleTimeString();
59
+ return /* @__PURE__ */ jsxs("div", { className: "border border-[var(--border)] rounded-lg overflow-hidden", children: [
60
+ /* @__PURE__ */ jsxs(
61
+ "button",
62
+ {
63
+ onClick: () => setIsExpanded(!isExpanded),
64
+ className: "w-full flex items-center gap-2 p-3 text-left hover:bg-[var(--muted)]/50 transition",
65
+ children: [
66
+ isExpanded ? /* @__PURE__ */ jsx(ChevronDown, { className: "w-4 h-4 text-[var(--muted-foreground)] shrink-0" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "w-4 h-4 text-[var(--muted-foreground)] shrink-0" }),
67
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
68
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
69
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-[var(--foreground)] truncate", children: payload.nodeName || payload.nodeId }),
70
+ /* @__PURE__ */ jsx("span", { className: "text-[10px] px-1.5 py-0.5 bg-amber-500/10 text-amber-500 rounded", children: payload.nodeType })
71
+ ] }),
72
+ /* @__PURE__ */ jsxs("div", { className: "text-[10px] text-[var(--muted-foreground)] mt-0.5", children: [
73
+ payload.model,
74
+ " \u2022 ",
75
+ timestamp
76
+ ] })
77
+ ] })
78
+ ]
79
+ }
80
+ ),
81
+ isExpanded && /* @__PURE__ */ jsxs("div", { className: "border-t border-[var(--border)] p-3 bg-[var(--muted)]/30", children: [
82
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-2", children: [
83
+ /* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium text-[var(--muted-foreground)] uppercase", children: "Payload" }),
84
+ /* @__PURE__ */ jsxs(
85
+ "button",
86
+ {
87
+ onClick: handleCopy,
88
+ className: "flex items-center gap-1 text-[10px] text-[var(--primary)] hover:underline",
89
+ children: [
90
+ /* @__PURE__ */ jsx(Copy, { className: "w-3 h-3" }),
91
+ copied ? "Copied!" : "Copy"
92
+ ]
93
+ }
94
+ )
95
+ ] }),
96
+ /* @__PURE__ */ jsx("pre", { className: "text-[11px] font-mono text-[var(--muted-foreground)] bg-[var(--background)] p-2 rounded border border-[var(--border)] overflow-x-auto max-h-64 overflow-y-auto", children: JSON.stringify(payload.input, null, 2) })
97
+ ] })
98
+ ] });
99
+ }
100
+ function DebugPanelComponent() {
101
+ const debugPayloads = useExecutionStore((s) => s.debugPayloads);
102
+ const clearDebugPayloads = useExecutionStore((s) => s.clearDebugPayloads);
103
+ const setShowDebugPanel = useUIStore((s) => s.setShowDebugPanel);
104
+ const handleClose = useCallback(() => {
105
+ setShowDebugPanel(false);
106
+ }, [setShowDebugPanel]);
107
+ return /* @__PURE__ */ jsxs(PanelContainer, { className: "w-80 h-full border-l border-[var(--border)] bg-[var(--background)] flex flex-col", children: [
108
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between p-3 border-b border-[var(--border)]", children: [
109
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
110
+ /* @__PURE__ */ jsx(Bug, { className: "w-4 h-4 text-amber-500" }),
111
+ /* @__PURE__ */ jsx("span", { className: "font-medium text-sm", children: "Debug Console" }),
112
+ debugPayloads.length > 0 && /* @__PURE__ */ jsx("span", { className: "text-[10px] px-1.5 py-0.5 bg-amber-500/10 text-amber-500 rounded-full", children: debugPayloads.length })
113
+ ] }),
114
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
115
+ debugPayloads.length > 0 && /* @__PURE__ */ jsx(
116
+ "button",
117
+ {
118
+ onClick: clearDebugPayloads,
119
+ className: "p-1.5 hover:bg-[var(--muted)] rounded transition",
120
+ title: "Clear all payloads",
121
+ children: /* @__PURE__ */ jsx(Trash2, { className: "w-4 h-4 text-[var(--muted-foreground)]" })
122
+ }
123
+ ),
124
+ /* @__PURE__ */ jsx(
125
+ "button",
126
+ {
127
+ onClick: handleClose,
128
+ className: "p-1.5 hover:bg-[var(--muted)] rounded transition",
129
+ children: /* @__PURE__ */ jsx(X, { className: "w-4 h-4" })
130
+ }
131
+ )
132
+ ] })
133
+ ] }),
134
+ /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto p-3 space-y-2", children: debugPayloads.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "text-center py-8 text-[var(--muted-foreground)]", children: [
135
+ /* @__PURE__ */ jsx(Bug, { className: "w-12 h-12 mx-auto mb-3 opacity-50 text-amber-500/50" }),
136
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium mb-2", children: "No payloads captured" }),
137
+ /* @__PURE__ */ jsx("p", { className: "text-xs", children: "Run a workflow with debug mode enabled to capture API payloads." })
138
+ ] }) : debugPayloads.map((payload, index) => /* @__PURE__ */ jsx(
139
+ PayloadCard,
140
+ {
141
+ payload
142
+ },
143
+ `${payload.nodeId}-${payload.timestamp}-${index}`
144
+ )) }),
145
+ debugPayloads.length > 0 && /* @__PURE__ */ jsx("div", { className: "p-3 border-t border-[var(--border)] bg-[var(--muted)]/30", children: /* @__PURE__ */ jsxs("p", { className: "text-[10px] text-[var(--muted-foreground)]", children: [
146
+ debugPayloads.length,
147
+ " payload",
148
+ debugPayloads.length !== 1 ? "s" : "",
149
+ " captured. Click to expand and view details."
150
+ ] }) })
151
+ ] });
152
+ }
153
+ var MemoizedDebugPanel = memo(DebugPanelComponent);
154
+ function DebugPanel() {
155
+ return /* @__PURE__ */ jsx(MemoizedDebugPanel, {});
156
+ }
7
157
  var ICONS = {
158
+ ArrowLeftFromLine,
159
+ // Composition
160
+ ArrowRightToLine,
161
+ AudioLines,
162
+ Brain,
163
+ // Output
164
+ CheckCircle,
165
+ Columns2,
166
+ Crop,
167
+ Download,
168
+ Eye,
169
+ FileText,
170
+ FileVideo,
171
+ Film,
172
+ GitBranch,
173
+ Grid3X3,
8
174
  // Input
9
175
  Image,
176
+ Layers,
177
+ LayoutGrid,
178
+ Maximize,
179
+ // Processing
180
+ Maximize2,
10
181
  MessageSquare,
11
- FileText,
12
- FileVideo,
13
- Volume2,
14
- Puzzle,
15
- // AI
16
- Sparkles,
17
- Video,
18
- Brain,
19
182
  Mic,
20
- AudioLines,
21
183
  Navigation,
22
- // Processing
23
- Maximize2,
24
- Wand2,
25
- Layers,
26
- Scissors,
27
- Film,
28
- Crop,
29
- Maximize,
30
- Grid3X3,
31
184
  Pencil,
185
+ Puzzle,
186
+ Scissors,
187
+ // AI
188
+ Sparkles,
32
189
  Subtitles,
33
- LayoutGrid,
34
- Columns2,
35
- // Output
36
- CheckCircle,
37
- Eye,
38
- Download,
39
- // Composition
40
- ArrowRightToLine,
41
- ArrowLeftFromLine,
42
- GitBranch
190
+ Video,
191
+ Volume2,
192
+ Wand2
43
193
  };
44
194
  var CATEGORY_LABELS = {
45
- input: "Input",
46
195
  ai: "AI Generation",
47
- processing: "Processing",
196
+ composition: "Composition",
197
+ input: "Input",
48
198
  output: "Output",
49
- composition: "Composition"
199
+ processing: "Processing"
50
200
  };
51
201
  var CATEGORY_COLORS = {
52
- input: {
53
- icon: "bg-[var(--category-input)]/20 text-[var(--category-input)]",
54
- hover: "hover:border-[var(--category-input)]",
55
- cssVar: "var(--category-input)"
56
- },
57
202
  ai: {
58
- icon: "bg-[var(--category-ai)]/20 text-[var(--category-ai)]",
203
+ cssVar: "var(--category-ai)",
59
204
  hover: "hover:border-[var(--category-ai)]",
60
- cssVar: "var(--category-ai)"
205
+ icon: "bg-[var(--category-ai)]/20 text-[var(--category-ai)]"
61
206
  },
62
- processing: {
63
- icon: "bg-[var(--category-processing)]/20 text-[var(--category-processing)]",
64
- hover: "hover:border-[var(--category-processing)]",
65
- cssVar: "var(--category-processing)"
207
+ composition: {
208
+ cssVar: "var(--category-composition)",
209
+ hover: "hover:border-[var(--category-composition)]",
210
+ icon: "bg-[var(--category-composition)]/20 text-[var(--category-composition)]"
211
+ },
212
+ input: {
213
+ cssVar: "var(--category-input)",
214
+ hover: "hover:border-[var(--category-input)]",
215
+ icon: "bg-[var(--category-input)]/20 text-[var(--category-input)]"
66
216
  },
67
217
  output: {
68
- icon: "bg-[var(--category-output)]/20 text-[var(--category-output)]",
218
+ cssVar: "var(--category-output)",
69
219
  hover: "hover:border-[var(--category-output)]",
70
- cssVar: "var(--category-output)"
220
+ icon: "bg-[var(--category-output)]/20 text-[var(--category-output)]"
71
221
  },
72
- composition: {
73
- icon: "bg-[var(--category-composition)]/20 text-[var(--category-composition)]",
74
- hover: "hover:border-[var(--category-composition)]",
75
- cssVar: "var(--category-composition)"
222
+ processing: {
223
+ cssVar: "var(--category-processing)",
224
+ hover: "hover:border-[var(--category-processing)]",
225
+ icon: "bg-[var(--category-processing)]/20 text-[var(--category-processing)]"
76
226
  }
77
227
  };
78
228
  function NodeCard({ type, label, description, icon, category }) {
@@ -101,7 +251,11 @@ function NodeCard({ type, label, description, icon, category }) {
101
251
  }
102
252
  );
103
253
  }
104
- function CategorySection({ category, isExpanded, onToggle }) {
254
+ function CategorySection({
255
+ category,
256
+ isExpanded,
257
+ onToggle
258
+ }) {
105
259
  const nodes = getNodesByCategory()[category];
106
260
  return /* @__PURE__ */ jsxs("div", { className: "border-b border-[var(--border)] last:border-0", children: [
107
261
  /* @__PURE__ */ jsxs(
@@ -132,9 +286,7 @@ function CategorySection({ category, isExpanded, onToggle }) {
132
286
  function NodePalette() {
133
287
  const { togglePalette } = useUIStore();
134
288
  const [searchQuery, setSearchQuery] = useState("");
135
- const [expandedCategories, setExpandedCategories] = useState(
136
- /* @__PURE__ */ new Set(["input"])
137
- );
289
+ const [expandedCategories, setExpandedCategories] = useState(/* @__PURE__ */ new Set(["input"]));
138
290
  const nodesByCategory = useMemo(() => getNodesByCategory(), []);
139
291
  const filteredNodes = useMemo(() => {
140
292
  if (!searchQuery.trim()) return null;
@@ -161,9 +313,7 @@ function NodePalette() {
161
313
  });
162
314
  }, []);
163
315
  const categories = useMemo(
164
- () => ["input", "ai", "processing", "output", "composition"].filter(
165
- (cat) => nodesByCategory[cat].length > 0
166
- ),
316
+ () => ["input", "ai", "processing", "output", "composition"].filter((cat) => nodesByCategory[cat].length > 0),
167
317
  [nodesByCategory]
168
318
  );
169
319
  return /* @__PURE__ */ jsxs("div", { className: "w-64 min-w-64 h-full bg-[var(--background)] border-r border-[var(--border)] flex flex-col overflow-hidden", children: [
@@ -222,150 +372,5 @@ function NodePalette() {
222
372
  ) })
223
373
  ] });
224
374
  }
225
- var PanelContainer = forwardRef(
226
- ({ children, className, ...props }, ref) => {
227
- const stopPropagation = (e) => {
228
- e.stopPropagation();
229
- };
230
- return /* @__PURE__ */ jsx(
231
- "div",
232
- {
233
- ref,
234
- className,
235
- onClick: stopPropagation,
236
- onMouseDown: stopPropagation,
237
- onPointerDown: stopPropagation,
238
- onDoubleClick: stopPropagation,
239
- ...props,
240
- children
241
- }
242
- );
243
- }
244
- );
245
- PanelContainer.displayName = "PanelContainer";
246
- function PayloadCard({ payload }) {
247
- const [isExpanded, setIsExpanded] = useState(false);
248
- const [copied, setCopied] = useState(false);
249
- const handleCopy = useCallback(
250
- async (e) => {
251
- e.stopPropagation();
252
- try {
253
- await navigator.clipboard.writeText(JSON.stringify(payload.input, null, 2));
254
- setCopied(true);
255
- setTimeout(() => setCopied(false), 2e3);
256
- } catch {
257
- const textArea = document.createElement("textarea");
258
- textArea.value = JSON.stringify(payload.input, null, 2);
259
- textArea.style.position = "fixed";
260
- textArea.style.left = "-9999px";
261
- document.body.appendChild(textArea);
262
- textArea.select();
263
- try {
264
- document.execCommand("copy");
265
- setCopied(true);
266
- setTimeout(() => setCopied(false), 2e3);
267
- } catch {
268
- }
269
- document.body.removeChild(textArea);
270
- }
271
- },
272
- [payload.input]
273
- );
274
- const timestamp = new Date(payload.timestamp).toLocaleTimeString();
275
- return /* @__PURE__ */ jsxs("div", { className: "border border-[var(--border)] rounded-lg overflow-hidden", children: [
276
- /* @__PURE__ */ jsxs(
277
- "button",
278
- {
279
- onClick: () => setIsExpanded(!isExpanded),
280
- className: "w-full flex items-center gap-2 p-3 text-left hover:bg-[var(--muted)]/50 transition",
281
- children: [
282
- isExpanded ? /* @__PURE__ */ jsx(ChevronDown, { className: "w-4 h-4 text-[var(--muted-foreground)] shrink-0" }) : /* @__PURE__ */ jsx(ChevronRight, { className: "w-4 h-4 text-[var(--muted-foreground)] shrink-0" }),
283
- /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
284
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
285
- /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-[var(--foreground)] truncate", children: payload.nodeName || payload.nodeId }),
286
- /* @__PURE__ */ jsx("span", { className: "text-[10px] px-1.5 py-0.5 bg-amber-500/10 text-amber-500 rounded", children: payload.nodeType })
287
- ] }),
288
- /* @__PURE__ */ jsxs("div", { className: "text-[10px] text-[var(--muted-foreground)] mt-0.5", children: [
289
- payload.model,
290
- " \u2022 ",
291
- timestamp
292
- ] })
293
- ] })
294
- ]
295
- }
296
- ),
297
- isExpanded && /* @__PURE__ */ jsxs("div", { className: "border-t border-[var(--border)] p-3 bg-[var(--muted)]/30", children: [
298
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-2", children: [
299
- /* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium text-[var(--muted-foreground)] uppercase", children: "Payload" }),
300
- /* @__PURE__ */ jsxs(
301
- "button",
302
- {
303
- onClick: handleCopy,
304
- className: "flex items-center gap-1 text-[10px] text-[var(--primary)] hover:underline",
305
- children: [
306
- /* @__PURE__ */ jsx(Copy, { className: "w-3 h-3" }),
307
- copied ? "Copied!" : "Copy"
308
- ]
309
- }
310
- )
311
- ] }),
312
- /* @__PURE__ */ jsx("pre", { className: "text-[11px] font-mono text-[var(--muted-foreground)] bg-[var(--background)] p-2 rounded border border-[var(--border)] overflow-x-auto max-h-64 overflow-y-auto", children: JSON.stringify(payload.input, null, 2) })
313
- ] })
314
- ] });
315
- }
316
- function DebugPanelComponent() {
317
- const debugPayloads = useExecutionStore((s) => s.debugPayloads);
318
- const clearDebugPayloads = useExecutionStore((s) => s.clearDebugPayloads);
319
- const setShowDebugPanel = useUIStore((s) => s.setShowDebugPanel);
320
- const handleClose = useCallback(() => {
321
- setShowDebugPanel(false);
322
- }, [setShowDebugPanel]);
323
- return /* @__PURE__ */ jsxs(PanelContainer, { className: "w-80 h-full border-l border-[var(--border)] bg-[var(--background)] flex flex-col", children: [
324
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between p-3 border-b border-[var(--border)]", children: [
325
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
326
- /* @__PURE__ */ jsx(Bug, { className: "w-4 h-4 text-amber-500" }),
327
- /* @__PURE__ */ jsx("span", { className: "font-medium text-sm", children: "Debug Console" }),
328
- debugPayloads.length > 0 && /* @__PURE__ */ jsx("span", { className: "text-[10px] px-1.5 py-0.5 bg-amber-500/10 text-amber-500 rounded-full", children: debugPayloads.length })
329
- ] }),
330
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
331
- debugPayloads.length > 0 && /* @__PURE__ */ jsx(
332
- "button",
333
- {
334
- onClick: clearDebugPayloads,
335
- className: "p-1.5 hover:bg-[var(--muted)] rounded transition",
336
- title: "Clear all payloads",
337
- children: /* @__PURE__ */ jsx(Trash2, { className: "w-4 h-4 text-[var(--muted-foreground)]" })
338
- }
339
- ),
340
- /* @__PURE__ */ jsx(
341
- "button",
342
- {
343
- onClick: handleClose,
344
- className: "p-1.5 hover:bg-[var(--muted)] rounded transition",
345
- children: /* @__PURE__ */ jsx(X, { className: "w-4 h-4" })
346
- }
347
- )
348
- ] })
349
- ] }),
350
- /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto p-3 space-y-2", children: debugPayloads.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "text-center py-8 text-[var(--muted-foreground)]", children: [
351
- /* @__PURE__ */ jsx(Bug, { className: "w-12 h-12 mx-auto mb-3 opacity-50 text-amber-500/50" }),
352
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium mb-2", children: "No payloads captured" }),
353
- /* @__PURE__ */ jsx("p", { className: "text-xs", children: "Run a workflow with debug mode enabled to capture API payloads." })
354
- ] }) : debugPayloads.map((payload, index) => /* @__PURE__ */ jsx(
355
- PayloadCard,
356
- {
357
- payload
358
- },
359
- `${payload.nodeId}-${payload.timestamp}-${index}`
360
- )) }),
361
- debugPayloads.length > 0 && /* @__PURE__ */ jsx("div", { className: "p-3 border-t border-[var(--border)] bg-[var(--muted)]/30", children: /* @__PURE__ */ jsxs("p", { className: "text-[10px] text-[var(--muted-foreground)]", children: [
362
- debugPayloads.length,
363
- " payload",
364
- debugPayloads.length !== 1 ? "s" : "",
365
- " captured. Click to expand and view details."
366
- ] }) })
367
- ] });
368
- }
369
- var DebugPanel = memo(DebugPanelComponent);
370
375
 
371
376
  export { DebugPanel, NodePalette, PanelContainer };
@@ -23,14 +23,14 @@ function calculateWorkflowCost(nodes) {
23
23
  cost = priceEntry[resolution] ?? Object.values(priceEntry)[0] ?? 0;
24
24
  }
25
25
  estimates.push({
26
+ model,
26
27
  nodeId: node.id,
27
28
  nodeLabel: label,
28
29
  nodeType: type,
29
- model,
30
- unitPrice: cost,
31
30
  quantity: 1,
32
31
  subtotal: cost,
33
- unit: "per image"
32
+ unit: "per image",
33
+ unitPrice: cost
34
34
  });
35
35
  continue;
36
36
  }
@@ -46,15 +46,15 @@ function calculateWorkflowCost(nodes) {
46
46
  }
47
47
  const subtotal = perSecond * duration;
48
48
  estimates.push({
49
+ duration,
50
+ model,
49
51
  nodeId: node.id,
50
52
  nodeLabel: label,
51
53
  nodeType: type,
52
- model,
53
- unitPrice: perSecond,
54
54
  quantity: duration,
55
55
  subtotal,
56
56
  unit: `${duration}s video`,
57
- duration,
57
+ unitPrice: perSecond,
58
58
  withAudio: generateAudio
59
59
  });
60
60
  continue;
@@ -70,14 +70,14 @@ function calculateWorkflowCost(nodes) {
70
70
  subtotal = imageEntry[model] ?? 0.01;
71
71
  }
72
72
  estimates.push({
73
+ model,
73
74
  nodeId: node.id,
74
75
  nodeLabel: label,
75
76
  nodeType: type,
76
- model,
77
- unitPrice: subtotal,
78
77
  quantity: 1,
79
78
  subtotal,
80
- unit: inputType === "video" ? "per video" : "per image"
79
+ unit: inputType === "video" ? "per video" : "per image",
80
+ unitPrice: subtotal
81
81
  });
82
82
  continue;
83
83
  }
@@ -91,27 +91,29 @@ function calculateWorkflowCost(nodes) {
91
91
  const duration = DEFAULT_VIDEO_DURATION;
92
92
  const chunks = Math.ceil(duration / 5);
93
93
  estimates.push({
94
+ duration,
95
+ model: "topaz-video",
94
96
  nodeId: node.id,
95
97
  nodeLabel: label,
96
98
  nodeType: type,
97
- model: "topaz-video",
98
- unitPrice: pricePerChunk,
99
99
  quantity: chunks,
100
100
  subtotal: pricePerChunk * chunks,
101
101
  unit: `${duration}s video`,
102
- duration
102
+ unitPrice: pricePerChunk
103
103
  });
104
104
  } else {
105
- const tier = PRICING["topaz-image-upscale"].find((t) => 1 <= t.maxMP) ?? PRICING["topaz-image-upscale"][0];
105
+ const tier = PRICING["topaz-image-upscale"].find(
106
+ (t) => 1 <= t.maxMP
107
+ ) ?? PRICING["topaz-image-upscale"][0];
106
108
  estimates.push({
109
+ model: getDataField(data, "model", "topaz-standard-v2"),
107
110
  nodeId: node.id,
108
111
  nodeLabel: label,
109
112
  nodeType: type,
110
- model: getDataField(data, "model", "topaz-standard-v2"),
111
- unitPrice: tier.price,
112
113
  quantity: 1,
113
114
  subtotal: tier.price,
114
- unit: "per image"
115
+ unit: "per image",
116
+ unitPrice: tier.price
115
117
  });
116
118
  }
117
119
  continue;
@@ -121,20 +123,20 @@ function calculateWorkflowCost(nodes) {
121
123
  const estimatedTokens = maxTokens * 3;
122
124
  const subtotal = estimatedTokens * PRICING.llama;
123
125
  estimates.push({
126
+ model: getDataField(data, "model", "llama"),
124
127
  nodeId: node.id,
125
128
  nodeLabel: label,
126
129
  nodeType: type,
127
- model: getDataField(data, "model", "llama"),
128
- unitPrice: PRICING.llama,
129
130
  quantity: estimatedTokens,
130
131
  subtotal,
131
- unit: `~${estimatedTokens} tokens`
132
+ unit: `~${estimatedTokens} tokens`,
133
+ unitPrice: PRICING.llama
132
134
  });
133
135
  }
134
136
  }
135
137
  return {
136
- total: estimates.reduce((sum, e) => sum + e.subtotal, 0),
137
- items: estimates
138
+ items: estimates,
139
+ total: estimates.reduce((sum, e) => sum + e.subtotal, 0)
138
140
  };
139
141
  }
140
142
  function formatCost(amount) {