@genfeedai/workflow-ui 0.2.2 → 0.2.4

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 (47) hide show
  1. package/README.md +11 -33
  2. package/dist/canvas.d.ts +22 -22
  3. package/dist/canvas.mjs +16 -17
  4. package/dist/{chunk-WBR34V4L.mjs → chunk-2FUPL67V.mjs} +1593 -1045
  5. package/dist/{chunk-4VEN4UN7.mjs → chunk-53XDE62A.mjs} +818 -623
  6. package/dist/{chunk-PCIWWD37.mjs → chunk-7LV4UAUS.mjs} +19 -19
  7. package/dist/{chunk-7SKSRSS7.mjs → chunk-B4EAAKYF.mjs} +16 -16
  8. package/dist/{chunk-ZJD5WMR3.mjs → chunk-C6MQBJFC.mjs} +45 -13
  9. package/dist/{chunk-7H3WJJYS.mjs → chunk-ESVULCFY.mjs} +12 -6
  10. package/dist/{chunk-GWBGK3KL.mjs → chunk-FWJIAW2E.mjs} +82 -47
  11. package/dist/{chunk-R727OFBR.mjs → chunk-GPYIIWD5.mjs} +404 -350
  12. package/dist/{chunk-OQREHJXK.mjs → chunk-IYFWAJBB.mjs} +208 -203
  13. package/dist/{chunk-2JQSKIWR.mjs → chunk-MGLAKMDP.mjs} +24 -23
  14. package/dist/{chunk-LT3ZJJL6.mjs → chunk-OJWVEEMM.mjs} +497 -399
  15. package/dist/{chunk-ZD2BADZO.mjs → chunk-ORVDYXDP.mjs} +221 -175
  16. package/dist/{chunk-CV4M7CNU.mjs → chunk-QQVHGJ2G.mjs} +149 -142
  17. package/dist/{chunk-6PSJTBNV.mjs → chunk-U4QPE4CY.mjs} +387 -347
  18. package/dist/{chunk-EFXQT23N.mjs → chunk-VVQ4CH77.mjs} +5 -5
  19. package/dist/{chunk-VRN3UWE5.mjs → chunk-XRC3O5GK.mjs} +73 -73
  20. package/dist/{chunk-FT33LFII.mjs → chunk-YUIK4AHM.mjs} +1 -1
  21. package/dist/{chunk-JT4Y5H3U.mjs → chunk-ZSITTZ4S.mjs} +630 -569
  22. package/dist/hooks.d.ts +37 -37
  23. package/dist/hooks.mjs +10 -10
  24. package/dist/index.d.ts +26 -11
  25. package/dist/index.mjs +99 -20
  26. package/dist/lib.d.ts +203 -203
  27. package/dist/lib.mjs +228 -199
  28. package/dist/nodes.d.ts +2 -2
  29. package/dist/nodes.mjs +12 -13
  30. package/dist/panels.d.ts +2 -3
  31. package/dist/panels.mjs +3 -3
  32. package/dist/provider.d.ts +2 -2
  33. package/dist/provider.mjs +2 -2
  34. package/dist/stores.d.ts +5 -5
  35. package/dist/stores.mjs +5 -5
  36. package/dist/toolbar.d.ts +42 -24
  37. package/dist/toolbar.mjs +4 -5
  38. package/dist/ui.d.ts +2 -2
  39. package/dist/ui.mjs +2 -2
  40. package/dist/{useCommentNavigation-BakbiiIc.d.ts → useRequiredInputs-ByoIS-fT.d.ts} +160 -160
  41. package/dist/{promptLibraryStore-Dl3Q3cP6.d.ts → workflowStore-Bsz0nd5c.d.ts} +368 -368
  42. package/dist/workflowStore-N2F7WIG3.mjs +2 -0
  43. package/package.json +79 -77
  44. package/src/styles/workflow-ui.css +56 -19
  45. package/dist/chunk-OY7BRSGG.mjs +0 -60
  46. package/dist/workflowStore-UAAKOOIK.mjs +0 -2
  47. 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 };
@@ -1,6 +1,5 @@
1
- import { PRICING, DEFAULT_VIDEO_DURATION, IMAGE_NODE_TYPES, VIDEO_NODE_TYPES, LUMA_NODE_TYPES, TOPAZ_NODE_TYPES } from './chunk-OY7BRSGG.mjs';
1
+ import { PRICING, DEFAULT_VIDEO_DURATION, IMAGE_NODE_TYPES, VIDEO_NODE_TYPES, LUMA_NODE_TYPES, TOPAZ_NODE_TYPES } from '@genfeedai/core';
2
2
 
3
- // src/lib/costCalculator.ts
4
3
  function isNodeType(type, list) {
5
4
  return list.includes(type);
6
5
  }
@@ -24,14 +23,14 @@ function calculateWorkflowCost(nodes) {
24
23
  cost = priceEntry[resolution] ?? Object.values(priceEntry)[0] ?? 0;
25
24
  }
26
25
  estimates.push({
26
+ model,
27
27
  nodeId: node.id,
28
28
  nodeLabel: label,
29
29
  nodeType: type,
30
- model,
31
- unitPrice: cost,
32
30
  quantity: 1,
33
31
  subtotal: cost,
34
- unit: "per image"
32
+ unit: "per image",
33
+ unitPrice: cost
35
34
  });
36
35
  continue;
37
36
  }
@@ -47,15 +46,15 @@ function calculateWorkflowCost(nodes) {
47
46
  }
48
47
  const subtotal = perSecond * duration;
49
48
  estimates.push({
49
+ duration,
50
+ model,
50
51
  nodeId: node.id,
51
52
  nodeLabel: label,
52
53
  nodeType: type,
53
- model,
54
- unitPrice: perSecond,
55
54
  quantity: duration,
56
55
  subtotal,
57
56
  unit: `${duration}s video`,
58
- duration,
57
+ unitPrice: perSecond,
59
58
  withAudio: generateAudio
60
59
  });
61
60
  continue;
@@ -71,14 +70,14 @@ function calculateWorkflowCost(nodes) {
71
70
  subtotal = imageEntry[model] ?? 0.01;
72
71
  }
73
72
  estimates.push({
73
+ model,
74
74
  nodeId: node.id,
75
75
  nodeLabel: label,
76
76
  nodeType: type,
77
- model,
78
- unitPrice: subtotal,
79
77
  quantity: 1,
80
78
  subtotal,
81
- unit: inputType === "video" ? "per video" : "per image"
79
+ unit: inputType === "video" ? "per video" : "per image",
80
+ unitPrice: subtotal
82
81
  });
83
82
  continue;
84
83
  }
@@ -92,27 +91,29 @@ function calculateWorkflowCost(nodes) {
92
91
  const duration = DEFAULT_VIDEO_DURATION;
93
92
  const chunks = Math.ceil(duration / 5);
94
93
  estimates.push({
94
+ duration,
95
+ model: "topaz-video",
95
96
  nodeId: node.id,
96
97
  nodeLabel: label,
97
98
  nodeType: type,
98
- model: "topaz-video",
99
- unitPrice: pricePerChunk,
100
99
  quantity: chunks,
101
100
  subtotal: pricePerChunk * chunks,
102
101
  unit: `${duration}s video`,
103
- duration
102
+ unitPrice: pricePerChunk
104
103
  });
105
104
  } else {
106
- 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];
107
108
  estimates.push({
109
+ model: getDataField(data, "model", "topaz-standard-v2"),
108
110
  nodeId: node.id,
109
111
  nodeLabel: label,
110
112
  nodeType: type,
111
- model: getDataField(data, "model", "topaz-standard-v2"),
112
- unitPrice: tier.price,
113
113
  quantity: 1,
114
114
  subtotal: tier.price,
115
- unit: "per image"
115
+ unit: "per image",
116
+ unitPrice: tier.price
116
117
  });
117
118
  }
118
119
  continue;
@@ -122,20 +123,20 @@ function calculateWorkflowCost(nodes) {
122
123
  const estimatedTokens = maxTokens * 3;
123
124
  const subtotal = estimatedTokens * PRICING.llama;
124
125
  estimates.push({
126
+ model: getDataField(data, "model", "llama"),
125
127
  nodeId: node.id,
126
128
  nodeLabel: label,
127
129
  nodeType: type,
128
- model: getDataField(data, "model", "llama"),
129
- unitPrice: PRICING.llama,
130
130
  quantity: estimatedTokens,
131
131
  subtotal,
132
- unit: `~${estimatedTokens} tokens`
132
+ unit: `~${estimatedTokens} tokens`,
133
+ unitPrice: PRICING.llama
133
134
  });
134
135
  }
135
136
  }
136
137
  return {
137
- total: estimates.reduce((sum, e) => sum + e.subtotal, 0),
138
- items: estimates
138
+ items: estimates,
139
+ total: estimates.reduce((sum, e) => sum + e.subtotal, 0)
139
140
  };
140
141
  }
141
142
  function formatCost(amount) {