@arbidocs/blocks 0.4.75 → 0.4.76
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/agents/index.cjs +265 -253
- package/dist/agents/index.js +3 -3
- package/dist/agents/tasks/TaskActivityTimeline.d.ts +1 -1
- package/dist/agents/tasks/WorkflowThreadStrip.d.ts +38 -1
- package/dist/agents/tasks/index.d.ts +2 -1
- package/dist/agents/tasks/linkedRuns.d.ts +31 -0
- package/dist/agents/workflows/index.d.ts +1 -1
- package/dist/agents/workflows/planSteps.d.ts +3 -1
- package/dist/agents/workflows/types.d.ts +27 -0
- package/dist/{chunk-YWYVIQ7T.js → chunk-22P5KNIM.js} +24 -4
- package/dist/chunk-22P5KNIM.js.map +1 -0
- package/dist/{chunk-F4LUD3YC.cjs → chunk-7FKARMA3.cjs} +158 -53
- package/dist/chunk-7FKARMA3.cjs.map +1 -0
- package/dist/{chunk-LT2UORRG.js → chunk-TKB7TVMW.js} +132 -29
- package/dist/chunk-TKB7TVMW.js.map +1 -0
- package/dist/{chunk-P2RBE3FD.cjs → chunk-VYRKO3XU.cjs} +24 -3
- package/dist/chunk-VYRKO3XU.cjs.map +1 -0
- package/dist/connect/index.cjs +10 -10
- package/dist/connect/index.js +3 -3
- package/dist/facts/index.cjs +1 -1
- package/dist/facts/index.js +1 -1
- package/dist/files/index.cjs +1 -1
- package/dist/files/index.js +1 -1
- package/dist/home/index.cjs +1 -1
- package/dist/home/index.js +1 -1
- package/dist/index.cjs +430 -418
- package/dist/index.js +7 -7
- package/dist/settings/index.cjs +1 -1
- package/dist/settings/index.js +1 -1
- package/dist/shell/index.cjs +1 -1
- package/dist/shell/index.js +1 -1
- package/dist/studio/index.cjs +1 -1
- package/dist/studio/index.js +1 -1
- package/dist/workflow-canvas/SignalsEditor.d.ts +41 -0
- package/dist/workflow-canvas/StepInspector.d.ts +4 -1
- package/dist/workflow-canvas/TriggerInspector.d.ts +11 -2
- package/dist/workflow-canvas/WorkflowBuilder.d.ts +7 -2
- package/dist/workflow-canvas/index.cjs +443 -149
- package/dist/workflow-canvas/index.cjs.map +1 -1
- package/dist/workflow-canvas/index.d.ts +2 -1
- package/dist/workflow-canvas/index.js +410 -123
- package/dist/workflow-canvas/index.js.map +1 -1
- package/dist/workflow-canvas/trigger.d.ts +20 -1
- package/package.json +4 -4
- package/dist/chunk-F4LUD3YC.cjs.map +0 -1
- package/dist/chunk-LT2UORRG.js.map +0 -1
- package/dist/chunk-P2RBE3FD.cjs.map +0 -1
- package/dist/chunk-YWYVIQ7T.js.map +0 -1
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var chunkMUMH3Z6K_cjs = require('../chunk-MUMH3Z6K.cjs');
|
|
5
|
-
var
|
|
5
|
+
var chunk7FKARMA3_cjs = require('../chunk-7FKARMA3.cjs');
|
|
6
6
|
require('../chunk-YJQVLVBJ.cjs');
|
|
7
7
|
require('../chunk-ZW6FPIFC.cjs');
|
|
8
|
-
var
|
|
8
|
+
var chunkVYRKO3XU_cjs = require('../chunk-VYRKO3XU.cjs');
|
|
9
9
|
require('../chunk-7RGLTF76.cjs');
|
|
10
10
|
require('../chunk-3AFWGEDJ.cjs');
|
|
11
11
|
require('../chunk-VFUWWH52.cjs');
|
|
@@ -16,11 +16,11 @@ require('../chunk-IXALYQT7.cjs');
|
|
|
16
16
|
require('../chunk-Z5VUZ6YD.cjs');
|
|
17
17
|
require('../chunk-7D737FLE.cjs');
|
|
18
18
|
require('../chunk-OB5F4577.cjs');
|
|
19
|
+
require('../chunk-C54XEN5T.cjs');
|
|
19
20
|
require('../chunk-B4SRYJLM.cjs');
|
|
20
21
|
require('../chunk-7UTB4PHM.cjs');
|
|
21
22
|
require('../chunk-FX3K6LNZ.cjs');
|
|
22
23
|
require('../chunk-PPCATBOY.cjs');
|
|
23
|
-
require('../chunk-C54XEN5T.cjs');
|
|
24
24
|
require('../chunk-KDG6FER6.cjs');
|
|
25
25
|
require('../chunk-ULWRNGGE.cjs');
|
|
26
26
|
require('../chunk-MHVNT4J3.cjs');
|
|
@@ -48,11 +48,11 @@ function withSteps(workflow, steps, layout) {
|
|
|
48
48
|
const run = workflow.run.kind === "steps" ? workflow.run : { kind: "steps", steps: [] };
|
|
49
49
|
return {
|
|
50
50
|
...workflow,
|
|
51
|
-
run: { ...run, steps:
|
|
51
|
+
run: { ...run, steps: chunkVYRKO3XU_cjs.orderSteps(steps), layout: layout ?? run.layout }
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
54
|
var layoutOf = (workflow) => workflow.run.kind === "steps" && workflow.run.layout || {};
|
|
55
|
-
var explicit = (steps) => steps.map((s) => ({ ...s, after:
|
|
55
|
+
var explicit = (steps) => steps.map((s) => ({ ...s, after: chunkVYRKO3XU_cjs.stepDependencies(steps, s.id) }));
|
|
56
56
|
function stepIdFor(steps, title) {
|
|
57
57
|
const base = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").replace(/^[^a-z]+/, "") || "step";
|
|
58
58
|
const taken = new Set(steps.map((s) => s.id));
|
|
@@ -80,7 +80,7 @@ function blankStep(kind, id, title) {
|
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
function addStep(workflow, kind, options = {}) {
|
|
83
|
-
const steps = explicit(
|
|
83
|
+
const steps = explicit(chunkVYRKO3XU_cjs.workflowSteps(workflow));
|
|
84
84
|
const title = options.title ?? DEFAULT_TITLES[kind];
|
|
85
85
|
const id = stepIdFor(steps, title);
|
|
86
86
|
const step = { ...blankStep(kind, id, title), after: options.after ? [options.after] : [] };
|
|
@@ -89,7 +89,7 @@ function addStep(workflow, kind, options = {}) {
|
|
|
89
89
|
return { workflow: withSteps(workflow, [...steps, step], layout), id };
|
|
90
90
|
}
|
|
91
91
|
function removeStep(workflow, id) {
|
|
92
|
-
const steps = explicit(
|
|
92
|
+
const steps = explicit(chunkVYRKO3XU_cjs.workflowSteps(workflow));
|
|
93
93
|
const removed = steps.find((s) => s.id === id);
|
|
94
94
|
if (!removed) return workflow;
|
|
95
95
|
const bridged = steps.filter((s) => s.id !== id).map(
|
|
@@ -102,8 +102,8 @@ function removeStep(workflow, id) {
|
|
|
102
102
|
return withSteps(workflow, bridged, layout);
|
|
103
103
|
}
|
|
104
104
|
function connectSteps(workflow, from, to) {
|
|
105
|
-
const steps = explicit(
|
|
106
|
-
if (from === to || !steps.some((s) => s.id === from) ||
|
|
105
|
+
const steps = explicit(chunkVYRKO3XU_cjs.workflowSteps(workflow));
|
|
106
|
+
if (from === to || !steps.some((s) => s.id === from) || chunkVYRKO3XU_cjs.dependsOn(steps, from, to)) {
|
|
107
107
|
return workflow;
|
|
108
108
|
}
|
|
109
109
|
return withSteps(
|
|
@@ -113,16 +113,16 @@ function connectSteps(workflow, from, to) {
|
|
|
113
113
|
)
|
|
114
114
|
);
|
|
115
115
|
}
|
|
116
|
-
var wouldCycle = (workflow, from, to) => from === to ||
|
|
116
|
+
var wouldCycle = (workflow, from, to) => from === to || chunkVYRKO3XU_cjs.dependsOn(chunkVYRKO3XU_cjs.workflowSteps(workflow), from, to);
|
|
117
117
|
function disconnectSteps(workflow, from, to) {
|
|
118
|
-
const steps = explicit(
|
|
118
|
+
const steps = explicit(chunkVYRKO3XU_cjs.workflowSteps(workflow));
|
|
119
119
|
return withSteps(
|
|
120
120
|
workflow,
|
|
121
121
|
steps.map((s) => s.id === to ? { ...s, after: (s.after ?? []).filter((d) => d !== from) } : s)
|
|
122
122
|
);
|
|
123
123
|
}
|
|
124
124
|
function updateStep(workflow, id, patch) {
|
|
125
|
-
const steps = explicit(
|
|
125
|
+
const steps = explicit(chunkVYRKO3XU_cjs.workflowSteps(workflow));
|
|
126
126
|
return withSteps(
|
|
127
127
|
workflow,
|
|
128
128
|
steps.map(
|
|
@@ -136,7 +136,7 @@ var renameIn = (text, from, to) => text.replace(
|
|
|
136
136
|
);
|
|
137
137
|
function renameInput(workflow, from, to) {
|
|
138
138
|
if (from === to) return workflow;
|
|
139
|
-
const steps =
|
|
139
|
+
const steps = chunkVYRKO3XU_cjs.workflowSteps(workflow).map((s) => {
|
|
140
140
|
if (s.kind === "agent")
|
|
141
141
|
return {
|
|
142
142
|
...s,
|
|
@@ -150,13 +150,13 @@ function renameInput(workflow, from, to) {
|
|
|
150
150
|
return withSteps(workflow, steps);
|
|
151
151
|
}
|
|
152
152
|
function moveStep(workflow, id, position) {
|
|
153
|
-
return withSteps(workflow,
|
|
153
|
+
return withSteps(workflow, chunkVYRKO3XU_cjs.workflowSteps(workflow), { ...layoutOf(workflow), [id]: position });
|
|
154
154
|
}
|
|
155
155
|
var COLUMN = 300;
|
|
156
156
|
var ROW = 140;
|
|
157
157
|
function autoLayout(steps) {
|
|
158
158
|
const layout = {};
|
|
159
|
-
|
|
159
|
+
chunkVYRKO3XU_cjs.stepLevels(steps).forEach(
|
|
160
160
|
(level, x) => level.forEach((s, y) => {
|
|
161
161
|
layout[s.id] = { x: x * COLUMN, y: (y - (level.length - 1) / 2) * ROW };
|
|
162
162
|
})
|
|
@@ -164,9 +164,225 @@ function autoLayout(steps) {
|
|
|
164
164
|
return layout;
|
|
165
165
|
}
|
|
166
166
|
function layoutWithDefaults(workflow) {
|
|
167
|
-
const auto = autoLayout(
|
|
167
|
+
const auto = autoLayout(chunkVYRKO3XU_cjs.workflowSteps(workflow));
|
|
168
168
|
return { ...auto, ...layoutOf(workflow) };
|
|
169
169
|
}
|
|
170
|
+
var DEFAULT_SIGNALS_EDITOR_LABELS = {
|
|
171
|
+
heading: "When done, signal\u2026",
|
|
172
|
+
hint: "Another workflow can start on a signal (\u201CWhen a step signals\u201D), as its own thread linked to this one.",
|
|
173
|
+
add: "Add signal",
|
|
174
|
+
name: "Signal",
|
|
175
|
+
namePlaceholder: "e.g. risk-high",
|
|
176
|
+
when: "When",
|
|
177
|
+
always: "Whenever it is done",
|
|
178
|
+
fieldEquals: "A field equals",
|
|
179
|
+
answerContains: "The answer contains",
|
|
180
|
+
answerMatches: "The answer matches (regex)",
|
|
181
|
+
approved: "It is approved",
|
|
182
|
+
field: "Field",
|
|
183
|
+
value: "Value",
|
|
184
|
+
phrase: "Phrase",
|
|
185
|
+
phrasePlaceholder: "e.g. Risk rating: High",
|
|
186
|
+
pattern: "Pattern",
|
|
187
|
+
remove: "Remove signal"
|
|
188
|
+
};
|
|
189
|
+
function signalConditions(kind) {
|
|
190
|
+
switch (kind) {
|
|
191
|
+
case "form":
|
|
192
|
+
return ["always", "field"];
|
|
193
|
+
case "agent":
|
|
194
|
+
return ["always", "contains", "matches"];
|
|
195
|
+
case "review":
|
|
196
|
+
return ["approved", "always"];
|
|
197
|
+
default:
|
|
198
|
+
return ["always"];
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
function conditionOf(when) {
|
|
202
|
+
if (!when) return "always";
|
|
203
|
+
if ("field" in when) return "field";
|
|
204
|
+
if ("contains" in when) return "contains";
|
|
205
|
+
if ("matches" in when) return "matches";
|
|
206
|
+
return "approved";
|
|
207
|
+
}
|
|
208
|
+
function signalSlug(text) {
|
|
209
|
+
return text.toLowerCase().replace(/[^a-z0-9_.-]+/g, "-").replace(/^[^a-z0-9]+/, "").slice(0, 64);
|
|
210
|
+
}
|
|
211
|
+
function startCondition(kind, step) {
|
|
212
|
+
switch (kind) {
|
|
213
|
+
case "field":
|
|
214
|
+
return { field: step.kind === "form" ? step.inputs[0]?.name ?? "" : "", equals: "" };
|
|
215
|
+
case "contains":
|
|
216
|
+
return { contains: "" };
|
|
217
|
+
case "matches":
|
|
218
|
+
return { matches: "" };
|
|
219
|
+
case "approved":
|
|
220
|
+
return { approved: true };
|
|
221
|
+
default:
|
|
222
|
+
return void 0;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
function newSignal(step, taken) {
|
|
226
|
+
const base = signalSlug(step.id) || "signal";
|
|
227
|
+
let name = `${base}-done`;
|
|
228
|
+
let n = 2;
|
|
229
|
+
while (taken.includes(name)) name = `${base}-done-${n++}`;
|
|
230
|
+
const when = startCondition(signalConditions(step.kind)[0], step);
|
|
231
|
+
return when ? { name, when } : { name };
|
|
232
|
+
}
|
|
233
|
+
var selectClass = "flex h-8 w-full rounded-md border border-input bg-background px-2 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring";
|
|
234
|
+
function SignalsEditor({
|
|
235
|
+
step,
|
|
236
|
+
onChange,
|
|
237
|
+
labels,
|
|
238
|
+
testId = "signals-editor"
|
|
239
|
+
}) {
|
|
240
|
+
const l = { ...DEFAULT_SIGNALS_EDITOR_LABELS, ...labels };
|
|
241
|
+
const signals = step.signals ?? [];
|
|
242
|
+
const conditions = signalConditions(step.kind);
|
|
243
|
+
const conditionLabel = {
|
|
244
|
+
always: l.always,
|
|
245
|
+
field: l.fieldEquals,
|
|
246
|
+
contains: l.answerContains,
|
|
247
|
+
matches: l.answerMatches,
|
|
248
|
+
approved: l.approved
|
|
249
|
+
};
|
|
250
|
+
const emit = (next) => onChange(next.length ? next : void 0);
|
|
251
|
+
const set = (i, signal) => emit(signals.map((s, j) => j === i ? signal : s));
|
|
252
|
+
const fields = step.kind === "form" ? step.inputs : [];
|
|
253
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", "data-testid": testId, children: [
|
|
254
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { className: "text-xs", children: l.heading }),
|
|
255
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
256
|
+
signals.map((signal, i) => {
|
|
257
|
+
const condition = conditionOf(signal.when);
|
|
258
|
+
const when = signal.when;
|
|
259
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
260
|
+
"div",
|
|
261
|
+
{
|
|
262
|
+
className: ui.cn(
|
|
263
|
+
"space-y-1.5 rounded-md border p-2",
|
|
264
|
+
chunkVYRKO3XU_cjs.isIncompleteSignal(signal) ? "border-destructive/50" : "border-border"
|
|
265
|
+
),
|
|
266
|
+
"data-incomplete": chunkVYRKO3XU_cjs.isIncompleteSignal(signal) || void 0,
|
|
267
|
+
"data-testid": `${testId}-${i}`,
|
|
268
|
+
children: [
|
|
269
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
270
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
271
|
+
ui.Input,
|
|
272
|
+
{
|
|
273
|
+
value: signal.name,
|
|
274
|
+
"aria-label": l.name,
|
|
275
|
+
placeholder: l.namePlaceholder,
|
|
276
|
+
onChange: (e) => set(i, { ...signal, name: signalSlug(e.target.value) }),
|
|
277
|
+
className: "h-8 font-mono text-xs",
|
|
278
|
+
"data-testid": `${testId}-${i}-name`
|
|
279
|
+
}
|
|
280
|
+
),
|
|
281
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
282
|
+
"button",
|
|
283
|
+
{
|
|
284
|
+
type: "button",
|
|
285
|
+
"aria-label": l.remove,
|
|
286
|
+
onClick: () => emit(signals.filter((_, j) => j !== i)),
|
|
287
|
+
"data-testid": `${testId}-${i}-remove`,
|
|
288
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-4 text-muted-foreground" })
|
|
289
|
+
}
|
|
290
|
+
)
|
|
291
|
+
] }),
|
|
292
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
293
|
+
"select",
|
|
294
|
+
{
|
|
295
|
+
"aria-label": l.when,
|
|
296
|
+
className: selectClass,
|
|
297
|
+
value: condition,
|
|
298
|
+
onChange: (e) => {
|
|
299
|
+
const nextWhen = startCondition(e.target.value, step);
|
|
300
|
+
set(i, nextWhen ? { name: signal.name, when: nextWhen } : { name: signal.name });
|
|
301
|
+
},
|
|
302
|
+
"data-testid": `${testId}-${i}-when`,
|
|
303
|
+
children: [...conditions, ...conditions.includes(condition) ? [] : [condition]].map(
|
|
304
|
+
(c) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: c, children: conditionLabel[c] }, c)
|
|
305
|
+
)
|
|
306
|
+
}
|
|
307
|
+
),
|
|
308
|
+
when && "field" in when && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
309
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
310
|
+
"select",
|
|
311
|
+
{
|
|
312
|
+
"aria-label": l.field,
|
|
313
|
+
className: ui.cn(selectClass, "flex-1"),
|
|
314
|
+
value: when.field,
|
|
315
|
+
onChange: (e) => set(i, { ...signal, when: { ...when, field: e.target.value } }),
|
|
316
|
+
"data-testid": `${testId}-${i}-field`,
|
|
317
|
+
children: [
|
|
318
|
+
fields.map((f) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: f.name, children: f.label }, f.name)),
|
|
319
|
+
!fields.some((f) => f.name === when.field) && /* @__PURE__ */ jsxRuntime.jsx("option", { value: when.field, children: when.field || "\u2014" })
|
|
320
|
+
]
|
|
321
|
+
}
|
|
322
|
+
),
|
|
323
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
324
|
+
ui.Input,
|
|
325
|
+
{
|
|
326
|
+
"aria-label": l.value,
|
|
327
|
+
placeholder: l.value,
|
|
328
|
+
value: String(when.equals),
|
|
329
|
+
onChange: (e) => set(i, { ...signal, when: { ...when, equals: e.target.value } }),
|
|
330
|
+
className: "h-8 flex-1",
|
|
331
|
+
"data-testid": `${testId}-${i}-equals`
|
|
332
|
+
}
|
|
333
|
+
)
|
|
334
|
+
] }),
|
|
335
|
+
when && "contains" in when && /* @__PURE__ */ jsxRuntime.jsx(
|
|
336
|
+
ui.Input,
|
|
337
|
+
{
|
|
338
|
+
"aria-label": l.phrase,
|
|
339
|
+
placeholder: l.phrasePlaceholder,
|
|
340
|
+
value: when.contains,
|
|
341
|
+
onChange: (e) => set(i, { ...signal, when: { contains: e.target.value } }),
|
|
342
|
+
className: "h-8",
|
|
343
|
+
"data-testid": `${testId}-${i}-contains`
|
|
344
|
+
}
|
|
345
|
+
),
|
|
346
|
+
when && "matches" in when && /* @__PURE__ */ jsxRuntime.jsx(
|
|
347
|
+
ui.Input,
|
|
348
|
+
{
|
|
349
|
+
"aria-label": l.pattern,
|
|
350
|
+
placeholder: "risk rating:\\s*high",
|
|
351
|
+
value: when.matches,
|
|
352
|
+
onChange: (e) => set(i, { ...signal, when: { matches: e.target.value } }),
|
|
353
|
+
className: "h-8 font-mono text-xs",
|
|
354
|
+
"data-testid": `${testId}-${i}-matches`
|
|
355
|
+
}
|
|
356
|
+
)
|
|
357
|
+
]
|
|
358
|
+
},
|
|
359
|
+
i
|
|
360
|
+
);
|
|
361
|
+
}),
|
|
362
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
363
|
+
ui.Button,
|
|
364
|
+
{
|
|
365
|
+
variant: "outline",
|
|
366
|
+
size: "sm",
|
|
367
|
+
onClick: () => emit([
|
|
368
|
+
...signals,
|
|
369
|
+
newSignal(
|
|
370
|
+
step,
|
|
371
|
+
signals.map((s) => s.name)
|
|
372
|
+
)
|
|
373
|
+
]),
|
|
374
|
+
"data-testid": `${testId}-add`,
|
|
375
|
+
children: [
|
|
376
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "size-4" }),
|
|
377
|
+
" ",
|
|
378
|
+
l.add
|
|
379
|
+
]
|
|
380
|
+
}
|
|
381
|
+
)
|
|
382
|
+
] }),
|
|
383
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: l.hint })
|
|
384
|
+
] });
|
|
385
|
+
}
|
|
170
386
|
var DEFAULT_STEP_INSPECTOR_LABELS = {
|
|
171
387
|
workflow: "Workflow",
|
|
172
388
|
title: "Title",
|
|
@@ -199,7 +415,7 @@ var DEFAULT_STEP_INSPECTOR_LABELS = {
|
|
|
199
415
|
deleteStep: "Delete step"
|
|
200
416
|
};
|
|
201
417
|
var FIELD_TYPES = ["text", "longtext", "boolean", "number", "date", "scope"];
|
|
202
|
-
var
|
|
418
|
+
var selectClass2 = "flex h-9 w-full rounded-md border border-input bg-background px-2 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring";
|
|
203
419
|
function Field({ label, children, hint }) {
|
|
204
420
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
205
421
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { className: "text-xs", children: label }),
|
|
@@ -221,10 +437,11 @@ function StepInspector({
|
|
|
221
437
|
onSelect,
|
|
222
438
|
workflows = [],
|
|
223
439
|
labels,
|
|
440
|
+
signalLabels,
|
|
224
441
|
testId = "step-inspector"
|
|
225
442
|
}) {
|
|
226
443
|
const l = { ...DEFAULT_STEP_INSPECTOR_LABELS, ...labels };
|
|
227
|
-
const steps =
|
|
444
|
+
const steps = chunkVYRKO3XU_cjs.workflowSteps(workflow);
|
|
228
445
|
const step = steps.find((s) => s.id === stepId);
|
|
229
446
|
const run = workflow.run.kind === "steps" ? workflow.run : void 0;
|
|
230
447
|
if (!step || !run) {
|
|
@@ -249,7 +466,7 @@ function StepInspector({
|
|
|
249
466
|
] });
|
|
250
467
|
}
|
|
251
468
|
const patch = (p) => onChange(updateStep(workflow, step.id, p));
|
|
252
|
-
const deps =
|
|
469
|
+
const deps = chunkVYRKO3XU_cjs.stepDependencies(steps, step.id);
|
|
253
470
|
const titleOf = (id) => steps.find((s) => s.id === id)?.title ?? id;
|
|
254
471
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", "data-testid": `${testId}-step`, children: [
|
|
255
472
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
@@ -338,7 +555,7 @@ function StepInspector({
|
|
|
338
555
|
{
|
|
339
556
|
step,
|
|
340
557
|
workflows,
|
|
341
|
-
fields:
|
|
558
|
+
fields: chunkVYRKO3XU_cjs.runFields(workflow).map((f) => f.name),
|
|
342
559
|
patch,
|
|
343
560
|
l,
|
|
344
561
|
testId
|
|
@@ -353,6 +570,15 @@ function StepInspector({
|
|
|
353
570
|
"data-testid": `${testId}-instructions`
|
|
354
571
|
}
|
|
355
572
|
) }),
|
|
573
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
574
|
+
SignalsEditor,
|
|
575
|
+
{
|
|
576
|
+
step,
|
|
577
|
+
onChange: (signals) => patch({ signals }),
|
|
578
|
+
labels: signalLabels,
|
|
579
|
+
testId: `${testId}-signals`
|
|
580
|
+
}
|
|
581
|
+
),
|
|
356
582
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
357
583
|
ui.Button,
|
|
358
584
|
{
|
|
@@ -414,7 +640,7 @@ function FormFields({
|
|
|
414
640
|
"select",
|
|
415
641
|
{
|
|
416
642
|
"aria-label": l.fieldType,
|
|
417
|
-
className: ui.cn(
|
|
643
|
+
className: ui.cn(selectClass2, "h-8"),
|
|
418
644
|
value: f.type,
|
|
419
645
|
onChange: (e) => set(i, { type: e.target.value }),
|
|
420
646
|
children: FIELD_TYPES.map((t) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: t, children: t }, t))
|
|
@@ -481,7 +707,7 @@ function AgentSettings({
|
|
|
481
707
|
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.runs, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
482
708
|
"select",
|
|
483
709
|
{
|
|
484
|
-
className:
|
|
710
|
+
className: selectClass2,
|
|
485
711
|
value,
|
|
486
712
|
onChange: (e) => {
|
|
487
713
|
const id = e.target.value;
|
|
@@ -538,7 +764,7 @@ function AgentSettings({
|
|
|
538
764
|
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.thread, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
539
765
|
"select",
|
|
540
766
|
{
|
|
541
|
-
className:
|
|
767
|
+
className: selectClass2,
|
|
542
768
|
value: step.branch ? "branch" : "main",
|
|
543
769
|
onChange: (e) => patch({ branch: e.target.value === "branch" || void 0 }),
|
|
544
770
|
"data-testid": `${testId}-thread`,
|
|
@@ -551,7 +777,7 @@ function AgentSettings({
|
|
|
551
777
|
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: l.output, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
552
778
|
"select",
|
|
553
779
|
{
|
|
554
|
-
className:
|
|
780
|
+
className: selectClass2,
|
|
555
781
|
value: step.output ?? "answer",
|
|
556
782
|
onChange: (e) => patch({ output: e.target.value === "artifact" ? "artifact" : void 0 }),
|
|
557
783
|
children: [
|
|
@@ -562,6 +788,138 @@ function AgentSettings({
|
|
|
562
788
|
) })
|
|
563
789
|
] });
|
|
564
790
|
}
|
|
791
|
+
|
|
792
|
+
// src/workflow-canvas/trigger.ts
|
|
793
|
+
var WORKFLOW_SIGNAL_EVENT = "workflow_signal";
|
|
794
|
+
var DEFAULT_WORKFLOW_TRIGGER = {
|
|
795
|
+
start: "manual",
|
|
796
|
+
runAt: "",
|
|
797
|
+
rrule: "",
|
|
798
|
+
timezone: typeof Intl !== "undefined" ? Intl.DateTimeFormat().resolvedOptions().timeZone : "UTC",
|
|
799
|
+
eventKind: "",
|
|
800
|
+
signal: "",
|
|
801
|
+
afterTaskId: "",
|
|
802
|
+
agentId: "",
|
|
803
|
+
access: "ask_each_run"
|
|
804
|
+
};
|
|
805
|
+
function triggerProblem(trigger) {
|
|
806
|
+
if (trigger.start === "once" && !trigger.runAt) return "runAt";
|
|
807
|
+
if (trigger.start === "repeat" && !trigger.rrule.trim()) return "rrule";
|
|
808
|
+
if (trigger.start === "event" && !trigger.eventKind.trim()) return "event";
|
|
809
|
+
if (isSignalTrigger(trigger) && !trigger.signal.trim()) return "signal";
|
|
810
|
+
if (trigger.start === "task" && !trigger.afterTaskId) return "task";
|
|
811
|
+
return null;
|
|
812
|
+
}
|
|
813
|
+
var isSignalTrigger = (trigger) => trigger.start === "event" && trigger.eventKind.trim() === WORKFLOW_SIGNAL_EVENT;
|
|
814
|
+
function eventFilter(trigger) {
|
|
815
|
+
if (trigger.start !== "event") return null;
|
|
816
|
+
if (isSignalTrigger(trigger)) return { signal: trigger.signal.trim() };
|
|
817
|
+
return trigger.eventFilter && Object.keys(trigger.eventFilter).length ? trigger.eventFilter : null;
|
|
818
|
+
}
|
|
819
|
+
function triggerFields(trigger, clearOthers) {
|
|
820
|
+
const none = clearOthers ? null : void 0;
|
|
821
|
+
const filter = eventFilter(trigger);
|
|
822
|
+
return {
|
|
823
|
+
timezone: trigger.timezone,
|
|
824
|
+
rrule: trigger.start === "repeat" ? trigger.rrule.trim() : none,
|
|
825
|
+
run_at: trigger.start === "once" ? chunk7FKARMA3_cjs.localInputToIso(trigger.runAt) : none,
|
|
826
|
+
event_kind: trigger.start === "event" ? trigger.eventKind.trim() : none,
|
|
827
|
+
// A step signal is `workflow_signal` narrowed to one signal name.
|
|
828
|
+
event_filter: filter ?? none,
|
|
829
|
+
after_conversation_ext_id: trigger.start === "task" ? trigger.afterTaskId : none,
|
|
830
|
+
on_demand: trigger.start === "manual"
|
|
831
|
+
};
|
|
832
|
+
}
|
|
833
|
+
var authMode = (trigger) => trigger.start === "manual" ? "run_now_temp" : trigger.access === "standing" ? "scheduled_permanent" : "scheduled_require_auth";
|
|
834
|
+
var withoutUndefined = (o) => Object.fromEntries(Object.entries(o).filter(([, v]) => v !== void 0));
|
|
835
|
+
function plan(value, options) {
|
|
836
|
+
return {
|
|
837
|
+
goal: value.workflow.description,
|
|
838
|
+
criteria: [],
|
|
839
|
+
max_passes: 3,
|
|
840
|
+
documents: [],
|
|
841
|
+
steps: chunkVYRKO3XU_cjs.toPlanSteps(value.workflow, options)
|
|
842
|
+
};
|
|
843
|
+
}
|
|
844
|
+
function builderToWorkflowRequest(value, workspaceId, options = {}) {
|
|
845
|
+
return withoutUndefined({
|
|
846
|
+
workspace_ext_id: workspaceId,
|
|
847
|
+
name: value.workflow.title,
|
|
848
|
+
description: value.workflow.description,
|
|
849
|
+
active: true,
|
|
850
|
+
shared: true,
|
|
851
|
+
...triggerFields(value.trigger, false),
|
|
852
|
+
prompt: "",
|
|
853
|
+
skill_ref: null,
|
|
854
|
+
skill_inputs: null,
|
|
855
|
+
agent_ext_id: value.trigger.agentId || null,
|
|
856
|
+
auth_mode: authMode(value.trigger),
|
|
857
|
+
plan: plan(value, options)
|
|
858
|
+
});
|
|
859
|
+
}
|
|
860
|
+
function builderToWorkflowUpdate(value, options = {}) {
|
|
861
|
+
return withoutUndefined({
|
|
862
|
+
name: value.workflow.title,
|
|
863
|
+
description: value.workflow.description,
|
|
864
|
+
...triggerFields(value.trigger, true),
|
|
865
|
+
// The steps are what runs (a classic automation's single prompt or skill becomes its one step).
|
|
866
|
+
prompt: "",
|
|
867
|
+
skill_ref: null,
|
|
868
|
+
skill_inputs: null,
|
|
869
|
+
agent_ext_id: value.trigger.agentId || null,
|
|
870
|
+
auth_mode: authMode(value.trigger),
|
|
871
|
+
plan: plan(value, options)
|
|
872
|
+
});
|
|
873
|
+
}
|
|
874
|
+
function workflowRecordToBuilder(record) {
|
|
875
|
+
const planned = record.plan?.steps ?? [];
|
|
876
|
+
const steps = planned.length ? chunkVYRKO3XU_cjs.fromPlanSteps(planned) : record.prompt || record.skill_ref ? [
|
|
877
|
+
{
|
|
878
|
+
id: "work",
|
|
879
|
+
kind: "agent",
|
|
880
|
+
title: record.name,
|
|
881
|
+
...record.skill_ref ? { workflow: record.skill_ref } : { run: { kind: "prompt", promptTemplate: record.prompt } }
|
|
882
|
+
}
|
|
883
|
+
] : [];
|
|
884
|
+
const when = chunk7FKARMA3_cjs.workflowWhen(record);
|
|
885
|
+
return {
|
|
886
|
+
workflow: {
|
|
887
|
+
id: record.external_id,
|
|
888
|
+
title: record.name,
|
|
889
|
+
description: record.description ?? "",
|
|
890
|
+
inputs: [],
|
|
891
|
+
landing: "chat",
|
|
892
|
+
schedulable: false,
|
|
893
|
+
run: { kind: "steps", steps, layout: chunkVYRKO3XU_cjs.layoutFromPlanSteps(planned ?? []) }
|
|
894
|
+
},
|
|
895
|
+
trigger: {
|
|
896
|
+
...DEFAULT_WORKFLOW_TRIGGER,
|
|
897
|
+
start: when === "now" ? "manual" : when,
|
|
898
|
+
runAt: chunk7FKARMA3_cjs.isoToLocalInput(record.run_at),
|
|
899
|
+
rrule: record.rrule ?? "",
|
|
900
|
+
timezone: record.timezone || DEFAULT_WORKFLOW_TRIGGER.timezone,
|
|
901
|
+
eventKind: record.event_kind ?? "",
|
|
902
|
+
signal: record.event_kind === WORKFLOW_SIGNAL_EVENT && typeof record.event_filter?.signal === "string" ? record.event_filter.signal : "",
|
|
903
|
+
eventFilter: record.event_kind && record.event_kind !== WORKFLOW_SIGNAL_EVENT && record.event_filter ? record.event_filter : void 0,
|
|
904
|
+
afterTaskId: record.after_conversation_ext_id ?? "",
|
|
905
|
+
agentId: record.agent_ext_id ?? "",
|
|
906
|
+
access: record.auth_mode === "scheduled_permanent" ? "standing" : "ask_each_run"
|
|
907
|
+
}
|
|
908
|
+
};
|
|
909
|
+
}
|
|
910
|
+
function declaredSignals(records, current) {
|
|
911
|
+
const out = /* @__PURE__ */ new Map();
|
|
912
|
+
const add = (workflow, steps) => {
|
|
913
|
+
for (const step of steps)
|
|
914
|
+
for (const signal of step.signals ?? [])
|
|
915
|
+
if (signal.name && !out.has(signal.name))
|
|
916
|
+
out.set(signal.name, { value: signal.name, label: `${workflow} \u203A ${step.title}` });
|
|
917
|
+
};
|
|
918
|
+
for (const record of records)
|
|
919
|
+
add(record.name, record.plan?.steps ?? []);
|
|
920
|
+
if (current?.run.kind === "steps") add(current.title, current.run.steps);
|
|
921
|
+
return [...out.values()];
|
|
922
|
+
}
|
|
565
923
|
var DEFAULT_TRIGGER_INSPECTOR_LABELS = {
|
|
566
924
|
heading: "Start",
|
|
567
925
|
start: "Starts",
|
|
@@ -575,6 +933,11 @@ var DEFAULT_TRIGGER_INSPECTOR_LABELS = {
|
|
|
575
933
|
runAt: "When",
|
|
576
934
|
event: "Event",
|
|
577
935
|
eventPlaceholder: "Pick an event",
|
|
936
|
+
stepSignals: "When a step signals",
|
|
937
|
+
signal: "Signal",
|
|
938
|
+
signalPlaceholder: "e.g. risk-high",
|
|
939
|
+
signalHint: "Starts as its own thread, linked to the thread whose step raised it, with that run\u2019s inputs.",
|
|
940
|
+
signalSummary: "When a step signals \u201C{signal}\u201D",
|
|
578
941
|
afterTask: "After this task",
|
|
579
942
|
afterTaskPlaceholder: "Pick a task",
|
|
580
943
|
agent: "Runs as",
|
|
@@ -588,8 +951,10 @@ function triggerSummary(trigger, options = {}) {
|
|
|
588
951
|
case "once":
|
|
589
952
|
return trigger.runAt ? new Date(trigger.runAt).toLocaleString() : l.starts.once;
|
|
590
953
|
case "repeat":
|
|
591
|
-
return trigger.rrule ?
|
|
954
|
+
return trigger.rrule ? chunk7FKARMA3_cjs.describeRRule(trigger.rrule) : l.starts.repeat;
|
|
592
955
|
case "event":
|
|
956
|
+
if (isSignalTrigger(trigger))
|
|
957
|
+
return trigger.signal ? l.signalSummary.replace("{signal}", trigger.signal) : l.stepSignals;
|
|
593
958
|
return trigger.eventKind && options.eventLabel?.(trigger.eventKind) || trigger.eventKind || l.starts.event;
|
|
594
959
|
case "task":
|
|
595
960
|
return trigger.afterTaskId && options.taskLabel?.(trigger.afterTaskId) || l.starts.task;
|
|
@@ -597,7 +962,7 @@ function triggerSummary(trigger, options = {}) {
|
|
|
597
962
|
return l.starts.manual;
|
|
598
963
|
}
|
|
599
964
|
}
|
|
600
|
-
var
|
|
965
|
+
var selectClass3 = "flex h-9 w-full rounded-md border border-input bg-background px-2 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring";
|
|
601
966
|
var STARTS = ["manual", "once", "repeat", "event", "task"];
|
|
602
967
|
function TriggerInspector({
|
|
603
968
|
trigger,
|
|
@@ -605,11 +970,13 @@ function TriggerInspector({
|
|
|
605
970
|
agents = [],
|
|
606
971
|
eventKinds = [],
|
|
607
972
|
tasks = [],
|
|
973
|
+
signals = [],
|
|
608
974
|
labels,
|
|
609
975
|
testId = "trigger-inspector"
|
|
610
976
|
}) {
|
|
611
977
|
const l = { ...DEFAULT_TRIGGER_INSPECTOR_LABELS, ...labels };
|
|
612
978
|
const set = (patch) => onChange({ ...trigger, ...patch });
|
|
979
|
+
const events = eventKinds.some((k) => k.value === WORKFLOW_SIGNAL_EVENT) ? eventKinds : [...eventKinds, { value: WORKFLOW_SIGNAL_EVENT, label: l.stepSignals }];
|
|
613
980
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", "data-testid": testId, children: [
|
|
614
981
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold", children: l.heading }),
|
|
615
982
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
@@ -643,29 +1010,45 @@ function TriggerInspector({
|
|
|
643
1010
|
}
|
|
644
1011
|
)
|
|
645
1012
|
] }),
|
|
646
|
-
trigger.start === "repeat" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1013
|
+
trigger.start === "repeat" && /* @__PURE__ */ jsxRuntime.jsx(chunk7FKARMA3_cjs.RecurrenceBuilder, { rrule: trigger.rrule, onChange: (rrule) => set({ rrule }) }),
|
|
647
1014
|
trigger.start === "event" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
648
1015
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { className: "text-xs", children: l.event }),
|
|
649
1016
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
650
1017
|
"select",
|
|
651
1018
|
{
|
|
652
|
-
className:
|
|
1019
|
+
className: selectClass3,
|
|
653
1020
|
value: trigger.eventKind,
|
|
654
|
-
onChange: (e) => set({ eventKind: e.target.value }),
|
|
1021
|
+
onChange: (e) => set({ eventKind: e.target.value, eventFilter: void 0 }),
|
|
655
1022
|
"data-testid": `${testId}-event`,
|
|
656
1023
|
children: [
|
|
657
1024
|
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: l.eventPlaceholder }),
|
|
658
|
-
|
|
1025
|
+
events.map((k) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: k.value, children: k.label }, k.value))
|
|
659
1026
|
]
|
|
660
1027
|
}
|
|
661
1028
|
)
|
|
662
1029
|
] }),
|
|
1030
|
+
isSignalTrigger(trigger) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
1031
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { className: "text-xs", htmlFor: `${testId}-signal`, children: l.signal }),
|
|
1032
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1033
|
+
ui.Input,
|
|
1034
|
+
{
|
|
1035
|
+
id: `${testId}-signal`,
|
|
1036
|
+
list: `${testId}-signal-options`,
|
|
1037
|
+
value: trigger.signal,
|
|
1038
|
+
placeholder: l.signalPlaceholder,
|
|
1039
|
+
onChange: (e) => set({ signal: e.target.value.trim().toLowerCase() }),
|
|
1040
|
+
"data-testid": `${testId}-signal`
|
|
1041
|
+
}
|
|
1042
|
+
),
|
|
1043
|
+
/* @__PURE__ */ jsxRuntime.jsx("datalist", { id: `${testId}-signal-options`, children: signals.map((s) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: s.value, children: s.label }, s.value)) }),
|
|
1044
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: l.signalHint })
|
|
1045
|
+
] }),
|
|
663
1046
|
trigger.start === "task" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
664
1047
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { className: "text-xs", children: l.afterTask }),
|
|
665
1048
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
666
1049
|
"select",
|
|
667
1050
|
{
|
|
668
|
-
className:
|
|
1051
|
+
className: selectClass3,
|
|
669
1052
|
value: trigger.afterTaskId,
|
|
670
1053
|
onChange: (e) => set({ afterTaskId: e.target.value }),
|
|
671
1054
|
"data-testid": `${testId}-after-task`,
|
|
@@ -679,7 +1062,7 @@ function TriggerInspector({
|
|
|
679
1062
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
680
1063
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { className: "text-xs", children: l.agent }),
|
|
681
1064
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
682
|
-
|
|
1065
|
+
chunk7FKARMA3_cjs.AgentSelect,
|
|
683
1066
|
{
|
|
684
1067
|
agents,
|
|
685
1068
|
value: trigger.agentId,
|
|
@@ -694,7 +1077,7 @@ function TriggerInspector({
|
|
|
694
1077
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
695
1078
|
"select",
|
|
696
1079
|
{
|
|
697
|
-
className:
|
|
1080
|
+
className: selectClass3,
|
|
698
1081
|
value: trigger.access,
|
|
699
1082
|
onChange: (e) => set({ access: e.target.value === "standing" ? "standing" : "ask_each_run" }),
|
|
700
1083
|
"data-testid": `${testId}-access`,
|
|
@@ -928,12 +1311,12 @@ function WorkflowCanvas({
|
|
|
928
1311
|
testId = "workflow-canvas"
|
|
929
1312
|
}) {
|
|
930
1313
|
const l = react.useMemo(() => ({ ...DEFAULT_WORKFLOW_CANVAS_LABELS, ...labels }), [labels]);
|
|
931
|
-
const steps =
|
|
1314
|
+
const steps = chunkVYRKO3XU_cjs.workflowSteps(workflow);
|
|
932
1315
|
const editable = !!onChange;
|
|
933
1316
|
const built = react.useMemo(() => {
|
|
934
1317
|
const layout = layoutWithDefaults(workflow);
|
|
935
|
-
const all =
|
|
936
|
-
const roots = all.filter((s) =>
|
|
1318
|
+
const all = chunkVYRKO3XU_cjs.workflowSteps(workflow);
|
|
1319
|
+
const roots = all.filter((s) => chunkVYRKO3XU_cjs.stepDependencies(all, s.id).length === 0);
|
|
937
1320
|
const triggerNode = trigger ? [
|
|
938
1321
|
{
|
|
939
1322
|
id: TRIGGER_NODE,
|
|
@@ -970,7 +1353,7 @@ function WorkflowCanvas({
|
|
|
970
1353
|
react.useEffect(() => setNodes(built), [built]);
|
|
971
1354
|
const edges = react.useMemo(
|
|
972
1355
|
() => steps.flatMap((s) => {
|
|
973
|
-
const deps =
|
|
1356
|
+
const deps = chunkVYRKO3XU_cjs.stepDependencies(steps, s.id);
|
|
974
1357
|
const from = deps.length ? deps : trigger ? [TRIGGER_NODE] : [];
|
|
975
1358
|
return from.map((d) => ({
|
|
976
1359
|
id: `${d}->${s.id}`,
|
|
@@ -1190,6 +1573,7 @@ function WorkflowBuilder({
|
|
|
1190
1573
|
agents = [],
|
|
1191
1574
|
eventKinds = [],
|
|
1192
1575
|
tasks = [],
|
|
1576
|
+
signals = [],
|
|
1193
1577
|
compose,
|
|
1194
1578
|
renderIcon,
|
|
1195
1579
|
actions,
|
|
@@ -1210,8 +1594,8 @@ function WorkflowBuilder({
|
|
|
1210
1594
|
const [mode, setMode] = react.useState("design");
|
|
1211
1595
|
const [adding, setAdding] = react.useState(false);
|
|
1212
1596
|
const { workflow, trigger } = value;
|
|
1213
|
-
const steps =
|
|
1214
|
-
const problems =
|
|
1597
|
+
const steps = chunkVYRKO3XU_cjs.workflowSteps(workflow);
|
|
1598
|
+
const problems = chunkVYRKO3XU_cjs.validateWorkflowGraph(steps);
|
|
1215
1599
|
const titles = react.useMemo(() => new Map(workflows.map((w) => [w.id, w.title])), [workflows]);
|
|
1216
1600
|
const setWorkflow = (next) => onChange({ ...value, workflow: next });
|
|
1217
1601
|
const addAfter = (from, kind) => {
|
|
@@ -1372,6 +1756,12 @@ function WorkflowBuilder({
|
|
|
1372
1756
|
agents,
|
|
1373
1757
|
eventKinds,
|
|
1374
1758
|
tasks,
|
|
1759
|
+
signals: [
|
|
1760
|
+
...signals,
|
|
1761
|
+
...declaredSignals([], workflow).filter(
|
|
1762
|
+
(d) => !signals.some((s) => s.value === d.value)
|
|
1763
|
+
)
|
|
1764
|
+
],
|
|
1375
1765
|
labels: triggerLabels,
|
|
1376
1766
|
testId: `${testId}-trigger`
|
|
1377
1767
|
}
|
|
@@ -1426,13 +1816,13 @@ function WorkflowPreview({
|
|
|
1426
1816
|
renderIcon,
|
|
1427
1817
|
testId
|
|
1428
1818
|
}) {
|
|
1429
|
-
const run =
|
|
1819
|
+
const run = chunk7FKARMA3_cjs.useWorkflowPreview(workflow, {
|
|
1430
1820
|
resolveWorkflow: (id) => workflows.find((w) => w.id === id),
|
|
1431
1821
|
compose,
|
|
1432
1822
|
answer
|
|
1433
1823
|
});
|
|
1434
1824
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1435
|
-
|
|
1825
|
+
chunkVYRKO3XU_cjs.WorkflowRunner,
|
|
1436
1826
|
{
|
|
1437
1827
|
workflow,
|
|
1438
1828
|
run,
|
|
@@ -1449,111 +1839,6 @@ function WorkflowPreview({
|
|
|
1449
1839
|
}
|
|
1450
1840
|
);
|
|
1451
1841
|
}
|
|
1452
|
-
|
|
1453
|
-
// src/workflow-canvas/trigger.ts
|
|
1454
|
-
var DEFAULT_WORKFLOW_TRIGGER = {
|
|
1455
|
-
start: "manual",
|
|
1456
|
-
runAt: "",
|
|
1457
|
-
rrule: "",
|
|
1458
|
-
timezone: typeof Intl !== "undefined" ? Intl.DateTimeFormat().resolvedOptions().timeZone : "UTC",
|
|
1459
|
-
eventKind: "",
|
|
1460
|
-
afterTaskId: "",
|
|
1461
|
-
agentId: "",
|
|
1462
|
-
access: "ask_each_run"
|
|
1463
|
-
};
|
|
1464
|
-
function triggerProblem(trigger) {
|
|
1465
|
-
if (trigger.start === "once" && !trigger.runAt) return "runAt";
|
|
1466
|
-
if (trigger.start === "repeat" && !trigger.rrule.trim()) return "rrule";
|
|
1467
|
-
if (trigger.start === "event" && !trigger.eventKind.trim()) return "event";
|
|
1468
|
-
if (trigger.start === "task" && !trigger.afterTaskId) return "task";
|
|
1469
|
-
return null;
|
|
1470
|
-
}
|
|
1471
|
-
function triggerFields(trigger, clearOthers) {
|
|
1472
|
-
const none = clearOthers ? null : void 0;
|
|
1473
|
-
return {
|
|
1474
|
-
timezone: trigger.timezone,
|
|
1475
|
-
rrule: trigger.start === "repeat" ? trigger.rrule.trim() : none,
|
|
1476
|
-
run_at: trigger.start === "once" ? chunkF4LUD3YC_cjs.localInputToIso(trigger.runAt) : none,
|
|
1477
|
-
event_kind: trigger.start === "event" ? trigger.eventKind.trim() : none,
|
|
1478
|
-
after_conversation_ext_id: trigger.start === "task" ? trigger.afterTaskId : none,
|
|
1479
|
-
on_demand: trigger.start === "manual"
|
|
1480
|
-
};
|
|
1481
|
-
}
|
|
1482
|
-
var authMode = (trigger) => trigger.start === "manual" ? "run_now_temp" : trigger.access === "standing" ? "scheduled_permanent" : "scheduled_require_auth";
|
|
1483
|
-
var withoutUndefined = (o) => Object.fromEntries(Object.entries(o).filter(([, v]) => v !== void 0));
|
|
1484
|
-
function plan(value, options) {
|
|
1485
|
-
return {
|
|
1486
|
-
goal: value.workflow.description,
|
|
1487
|
-
criteria: [],
|
|
1488
|
-
max_passes: 3,
|
|
1489
|
-
documents: [],
|
|
1490
|
-
steps: chunkP2RBE3FD_cjs.toPlanSteps(value.workflow, options)
|
|
1491
|
-
};
|
|
1492
|
-
}
|
|
1493
|
-
function builderToWorkflowRequest(value, workspaceId, options = {}) {
|
|
1494
|
-
return withoutUndefined({
|
|
1495
|
-
workspace_ext_id: workspaceId,
|
|
1496
|
-
name: value.workflow.title,
|
|
1497
|
-
description: value.workflow.description,
|
|
1498
|
-
active: true,
|
|
1499
|
-
shared: true,
|
|
1500
|
-
...triggerFields(value.trigger, false),
|
|
1501
|
-
prompt: "",
|
|
1502
|
-
skill_ref: null,
|
|
1503
|
-
skill_inputs: null,
|
|
1504
|
-
agent_ext_id: value.trigger.agentId || null,
|
|
1505
|
-
auth_mode: authMode(value.trigger),
|
|
1506
|
-
plan: plan(value, options)
|
|
1507
|
-
});
|
|
1508
|
-
}
|
|
1509
|
-
function builderToWorkflowUpdate(value, options = {}) {
|
|
1510
|
-
return withoutUndefined({
|
|
1511
|
-
name: value.workflow.title,
|
|
1512
|
-
description: value.workflow.description,
|
|
1513
|
-
...triggerFields(value.trigger, true),
|
|
1514
|
-
// The steps are what runs (a classic automation's single prompt or skill becomes its one step).
|
|
1515
|
-
prompt: "",
|
|
1516
|
-
skill_ref: null,
|
|
1517
|
-
skill_inputs: null,
|
|
1518
|
-
agent_ext_id: value.trigger.agentId || null,
|
|
1519
|
-
auth_mode: authMode(value.trigger),
|
|
1520
|
-
plan: plan(value, options)
|
|
1521
|
-
});
|
|
1522
|
-
}
|
|
1523
|
-
function workflowRecordToBuilder(record) {
|
|
1524
|
-
const planned = record.plan?.steps ?? [];
|
|
1525
|
-
const steps = planned.length ? chunkP2RBE3FD_cjs.fromPlanSteps(planned) : record.prompt || record.skill_ref ? [
|
|
1526
|
-
{
|
|
1527
|
-
id: "work",
|
|
1528
|
-
kind: "agent",
|
|
1529
|
-
title: record.name,
|
|
1530
|
-
...record.skill_ref ? { workflow: record.skill_ref } : { run: { kind: "prompt", promptTemplate: record.prompt } }
|
|
1531
|
-
}
|
|
1532
|
-
] : [];
|
|
1533
|
-
const when = chunkF4LUD3YC_cjs.workflowWhen(record);
|
|
1534
|
-
return {
|
|
1535
|
-
workflow: {
|
|
1536
|
-
id: record.external_id,
|
|
1537
|
-
title: record.name,
|
|
1538
|
-
description: record.description ?? "",
|
|
1539
|
-
inputs: [],
|
|
1540
|
-
landing: "chat",
|
|
1541
|
-
schedulable: false,
|
|
1542
|
-
run: { kind: "steps", steps, layout: chunkP2RBE3FD_cjs.layoutFromPlanSteps(planned ?? []) }
|
|
1543
|
-
},
|
|
1544
|
-
trigger: {
|
|
1545
|
-
...DEFAULT_WORKFLOW_TRIGGER,
|
|
1546
|
-
start: when === "now" ? "manual" : when,
|
|
1547
|
-
runAt: chunkF4LUD3YC_cjs.isoToLocalInput(record.run_at),
|
|
1548
|
-
rrule: record.rrule ?? "",
|
|
1549
|
-
timezone: record.timezone || DEFAULT_WORKFLOW_TRIGGER.timezone,
|
|
1550
|
-
eventKind: record.event_kind ?? "",
|
|
1551
|
-
afterTaskId: record.after_conversation_ext_id ?? "",
|
|
1552
|
-
agentId: record.agent_ext_id ?? "",
|
|
1553
|
-
access: record.auth_mode === "scheduled_permanent" ? "standing" : "ask_each_run"
|
|
1554
|
-
}
|
|
1555
|
-
};
|
|
1556
|
-
}
|
|
1557
1842
|
var DEFAULT_CONNECTED_WORKFLOW_BUILDER_LABELS = {
|
|
1558
1843
|
save: "Save",
|
|
1559
1844
|
saving: "Saving\u2026",
|
|
@@ -1566,7 +1851,8 @@ var DEFAULT_WORKFLOW_EVENT_KINDS = [
|
|
|
1566
1851
|
{ value: "conversation_ready", label: "Work is ready for me" },
|
|
1567
1852
|
{ value: "mention", label: "Someone mentions me" },
|
|
1568
1853
|
{ value: "workflow_completed", label: "Another workflow finishes" },
|
|
1569
|
-
{ value: "workflow_failed", label: "Another workflow fails" }
|
|
1854
|
+
{ value: "workflow_failed", label: "Another workflow fails" },
|
|
1855
|
+
{ value: "workflow_signal", label: "When a step signals" }
|
|
1570
1856
|
];
|
|
1571
1857
|
function ConnectedWorkflowBuilder({
|
|
1572
1858
|
workflowId,
|
|
@@ -1605,7 +1891,7 @@ function ConnectedWorkflowBuilder({
|
|
|
1605
1891
|
() => [
|
|
1606
1892
|
...hostWorkflows,
|
|
1607
1893
|
...(skills.data ?? []).map(
|
|
1608
|
-
(s) =>
|
|
1894
|
+
(s) => chunkVYRKO3XU_cjs.skillToWorkflow({
|
|
1609
1895
|
name: s.name,
|
|
1610
1896
|
slug: s.slug,
|
|
1611
1897
|
description: s.description,
|
|
@@ -1621,7 +1907,7 @@ function ConnectedWorkflowBuilder({
|
|
|
1621
1907
|
}));
|
|
1622
1908
|
const tasks = (conversations.data ?? []).filter((c) => c.status && c.status !== "done").map((c) => ({ value: c.external_id, label: c.title || c.external_id }));
|
|
1623
1909
|
const options = { resolveWorkflow: (wid) => workflows.find((w) => w.id === wid), compose };
|
|
1624
|
-
const problem = triggerProblem(value.trigger) ?? (
|
|
1910
|
+
const problem = triggerProblem(value.trigger) ?? (chunkVYRKO3XU_cjs.validateWorkflowGraph(chunkVYRKO3XU_cjs.workflowSteps(value.workflow)).length ? "graph" : null);
|
|
1625
1911
|
const busy = create.isPending || update.isPending || run.isPending;
|
|
1626
1912
|
const save = async () => {
|
|
1627
1913
|
if (!workspaceId) return void 0;
|
|
@@ -1643,6 +1929,7 @@ function ConnectedWorkflowBuilder({
|
|
|
1643
1929
|
agents,
|
|
1644
1930
|
eventKinds,
|
|
1645
1931
|
tasks,
|
|
1932
|
+
signals: declaredSignals(saved.data ?? []),
|
|
1646
1933
|
compose,
|
|
1647
1934
|
testId,
|
|
1648
1935
|
actions: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -1689,15 +1976,18 @@ function ConnectedWorkflowBuilder({
|
|
|
1689
1976
|
|
|
1690
1977
|
exports.ConnectedWorkflowBuilder = ConnectedWorkflowBuilder;
|
|
1691
1978
|
exports.DEFAULT_CONNECTED_WORKFLOW_BUILDER_LABELS = DEFAULT_CONNECTED_WORKFLOW_BUILDER_LABELS;
|
|
1979
|
+
exports.DEFAULT_SIGNALS_EDITOR_LABELS = DEFAULT_SIGNALS_EDITOR_LABELS;
|
|
1692
1980
|
exports.DEFAULT_STEP_INSPECTOR_LABELS = DEFAULT_STEP_INSPECTOR_LABELS;
|
|
1693
1981
|
exports.DEFAULT_TRIGGER_INSPECTOR_LABELS = DEFAULT_TRIGGER_INSPECTOR_LABELS;
|
|
1694
1982
|
exports.DEFAULT_WORKFLOW_BUILDER_LABELS = DEFAULT_WORKFLOW_BUILDER_LABELS;
|
|
1695
1983
|
exports.DEFAULT_WORKFLOW_CANVAS_LABELS = DEFAULT_WORKFLOW_CANVAS_LABELS;
|
|
1696
1984
|
exports.DEFAULT_WORKFLOW_EVENT_KINDS = DEFAULT_WORKFLOW_EVENT_KINDS;
|
|
1697
1985
|
exports.DEFAULT_WORKFLOW_TRIGGER = DEFAULT_WORKFLOW_TRIGGER;
|
|
1986
|
+
exports.SignalsEditor = SignalsEditor;
|
|
1698
1987
|
exports.StepInspector = StepInspector;
|
|
1699
1988
|
exports.TRIGGER_NODE = TRIGGER_NODE;
|
|
1700
1989
|
exports.TriggerInspector = TriggerInspector;
|
|
1990
|
+
exports.WORKFLOW_SIGNAL_EVENT = WORKFLOW_SIGNAL_EVENT;
|
|
1701
1991
|
exports.WorkflowBuilder = WorkflowBuilder;
|
|
1702
1992
|
exports.WorkflowCanvas = WorkflowCanvas;
|
|
1703
1993
|
exports.addStep = addStep;
|
|
@@ -1705,11 +1995,15 @@ exports.autoLayout = autoLayout;
|
|
|
1705
1995
|
exports.builderToWorkflowRequest = builderToWorkflowRequest;
|
|
1706
1996
|
exports.builderToWorkflowUpdate = builderToWorkflowUpdate;
|
|
1707
1997
|
exports.connectSteps = connectSteps;
|
|
1998
|
+
exports.declaredSignals = declaredSignals;
|
|
1708
1999
|
exports.disconnectSteps = disconnectSteps;
|
|
2000
|
+
exports.isSignalTrigger = isSignalTrigger;
|
|
1709
2001
|
exports.layoutWithDefaults = layoutWithDefaults;
|
|
1710
2002
|
exports.moveStep = moveStep;
|
|
1711
2003
|
exports.newSteppedWorkflow = newSteppedWorkflow;
|
|
1712
2004
|
exports.removeStep = removeStep;
|
|
2005
|
+
exports.signalConditions = signalConditions;
|
|
2006
|
+
exports.signalSlug = signalSlug;
|
|
1713
2007
|
exports.stepIdFor = stepIdFor;
|
|
1714
2008
|
exports.triggerProblem = triggerProblem;
|
|
1715
2009
|
exports.triggerSummary = triggerSummary;
|