windmill-cli 1.643.0 → 1.645.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -32
- package/esm/main.js +160 -30
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -112,39 +112,15 @@ source <(wmill completions zsh)
|
|
|
112
112
|
|
|
113
113
|
### Testing with a local `windmill-yaml-validator`
|
|
114
114
|
|
|
115
|
-
|
|
116
|
-
To test local changes to the validator before publishing, use the Deno compatibility
|
|
117
|
-
script and import map override:
|
|
118
|
-
|
|
119
|
-
1. Make the validator sources Deno-compatible:
|
|
120
|
-
|
|
121
|
-
```bash
|
|
122
|
-
cd ../windmill-yaml-validator
|
|
123
|
-
./deno-compat.sh
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
2. Add the following entries to `cli/deno.json` imports:
|
|
127
|
-
|
|
128
|
-
```json
|
|
129
|
-
"npm:windmill-yaml-validator@1.1.0": "../windmill-yaml-validator/src/index.ts",
|
|
130
|
-
"ajv": "npm:ajv@^8.17.1",
|
|
131
|
-
"@stoplight/yaml": "npm:@stoplight/yaml@^4.3.0"
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
3. Run the CLI directly with Deno:
|
|
135
|
-
|
|
136
|
-
```bash
|
|
137
|
-
deno run -A src/main.ts lint
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
4. When done, restore everything:
|
|
115
|
+
To test local changes to the validator before publishing, use `npm link`:
|
|
141
116
|
|
|
142
117
|
```bash
|
|
143
|
-
#
|
|
144
|
-
|
|
145
|
-
|
|
118
|
+
# In windmill-yaml-validator/
|
|
119
|
+
npm run build
|
|
120
|
+
npm link
|
|
146
121
|
|
|
147
|
-
#
|
|
122
|
+
# In cli/
|
|
123
|
+
npm link windmill-yaml-validator
|
|
148
124
|
```
|
|
149
125
|
|
|
150
126
|
### Running Tests
|
|
@@ -156,13 +132,13 @@ cd ../windmill-yaml-validator
|
|
|
156
132
|
**Run tests locally (full features):**
|
|
157
133
|
|
|
158
134
|
```bash
|
|
159
|
-
|
|
135
|
+
bun test test/
|
|
160
136
|
```
|
|
161
137
|
|
|
162
138
|
**Run tests in CI mode (minimal features, skips EE tests):**
|
|
163
139
|
|
|
164
140
|
```bash
|
|
165
|
-
CI_MINIMAL_FEATURES=true
|
|
141
|
+
CI_MINIMAL_FEATURES=true bun test test/
|
|
166
142
|
```
|
|
167
143
|
|
|
168
144
|
| Variable | Description |
|
package/esm/main.js
CHANGED
|
@@ -5,25 +5,43 @@ var __getProtoOf = Object.getPrototypeOf;
|
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
function __accessProp(key) {
|
|
9
|
+
return this[key];
|
|
10
|
+
}
|
|
11
|
+
var __toESMCache_node;
|
|
12
|
+
var __toESMCache_esm;
|
|
8
13
|
var __toESM = (mod, isNodeMode, target) => {
|
|
14
|
+
var canCache = mod != null && typeof mod === "object";
|
|
15
|
+
if (canCache) {
|
|
16
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
17
|
+
var cached = cache.get(mod);
|
|
18
|
+
if (cached)
|
|
19
|
+
return cached;
|
|
20
|
+
}
|
|
9
21
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
10
22
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
11
23
|
for (let key of __getOwnPropNames(mod))
|
|
12
24
|
if (!__hasOwnProp.call(to, key))
|
|
13
25
|
__defProp(to, key, {
|
|
14
|
-
get: (
|
|
26
|
+
get: __accessProp.bind(mod, key),
|
|
15
27
|
enumerable: true
|
|
16
28
|
});
|
|
29
|
+
if (canCache)
|
|
30
|
+
cache.set(mod, to);
|
|
17
31
|
return to;
|
|
18
32
|
};
|
|
19
33
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
34
|
+
var __returnValue = (v) => v;
|
|
35
|
+
function __exportSetter(name, newValue) {
|
|
36
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
37
|
+
}
|
|
20
38
|
var __export = (target, all) => {
|
|
21
39
|
for (var name in all)
|
|
22
40
|
__defProp(target, name, {
|
|
23
41
|
get: all[name],
|
|
24
42
|
enumerable: true,
|
|
25
43
|
configurable: true,
|
|
26
|
-
set: (
|
|
44
|
+
set: __exportSetter.bind(all, name)
|
|
27
45
|
});
|
|
28
46
|
};
|
|
29
47
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
@@ -11767,7 +11785,7 @@ var init_OpenAPI = __esm(() => {
|
|
|
11767
11785
|
PASSWORD: undefined,
|
|
11768
11786
|
TOKEN: getEnv2("WM_TOKEN"),
|
|
11769
11787
|
USERNAME: undefined,
|
|
11770
|
-
VERSION: "1.
|
|
11788
|
+
VERSION: "1.645.0",
|
|
11771
11789
|
WITH_CREDENTIALS: true,
|
|
11772
11790
|
interceptors: {
|
|
11773
11791
|
request: new Interceptors,
|
|
@@ -16645,7 +16663,9 @@ var backendVersion = () => {
|
|
|
16645
16663
|
channel_id: data2.channelId,
|
|
16646
16664
|
flow_step_id: data2.flowStepId,
|
|
16647
16665
|
default_args_json: data2.defaultArgsJson,
|
|
16648
|
-
dynamic_enums_json: data2.dynamicEnumsJson
|
|
16666
|
+
dynamic_enums_json: data2.dynamicEnumsJson,
|
|
16667
|
+
resume_button_text: data2.resumeButtonText,
|
|
16668
|
+
cancel_button_text: data2.cancelButtonText
|
|
16649
16669
|
}
|
|
16650
16670
|
});
|
|
16651
16671
|
}, getTeamsApprovalPayload = (data2) => {
|
|
@@ -16663,7 +16683,9 @@ var backendVersion = () => {
|
|
|
16663
16683
|
channel_name: data2.channelName,
|
|
16664
16684
|
flow_step_id: data2.flowStepId,
|
|
16665
16685
|
default_args_json: data2.defaultArgsJson,
|
|
16666
|
-
dynamic_enums_json: data2.dynamicEnumsJson
|
|
16686
|
+
dynamic_enums_json: data2.dynamicEnumsJson,
|
|
16687
|
+
resume_button_text: data2.resumeButtonText,
|
|
16688
|
+
cancel_button_text: data2.cancelButtonText
|
|
16667
16689
|
}
|
|
16668
16690
|
});
|
|
16669
16691
|
}, resumeSuspendedJobGet = (data2) => {
|
|
@@ -62024,6 +62046,43 @@ Push aborted: ${lockIssues.length} script(s) missing locks.`));
|
|
|
62024
62046
|
}
|
|
62025
62047
|
await fetchRemoteVersion(workspace);
|
|
62026
62048
|
info(`remote (${workspace.name}) <- local: ${changes.length} changes to apply`);
|
|
62049
|
+
const missingFolders = [];
|
|
62050
|
+
if (changes.length > 0) {
|
|
62051
|
+
const folderNames = new Set;
|
|
62052
|
+
for (const change of changes) {
|
|
62053
|
+
const parts = change.path.split(SEP8);
|
|
62054
|
+
if (parts.length >= 3 && parts[0] === "f" && change.name !== "deleted") {
|
|
62055
|
+
folderNames.add(parts[1]);
|
|
62056
|
+
}
|
|
62057
|
+
}
|
|
62058
|
+
for (const folderName of folderNames) {
|
|
62059
|
+
try {
|
|
62060
|
+
await stat6(path7.join("f", folderName, "folder.meta.yaml"));
|
|
62061
|
+
} catch {
|
|
62062
|
+
missingFolders.push(folderName);
|
|
62063
|
+
}
|
|
62064
|
+
}
|
|
62065
|
+
}
|
|
62066
|
+
if (missingFolders.length > 0) {
|
|
62067
|
+
const folderList = missingFolders.map((f) => ` - ${f}`).join(`
|
|
62068
|
+
`);
|
|
62069
|
+
const user = await whoami({ workspace: workspace.workspaceId });
|
|
62070
|
+
const userIsAdmin = user.is_admin;
|
|
62071
|
+
const msg = `${userIsAdmin ? "Warning: " : ""}Missing folder.meta.yaml for:
|
|
62072
|
+
${folderList}
|
|
62073
|
+
` + `Run 'wmill folder add-missing' to create them locally, then push again.`;
|
|
62074
|
+
if (!userIsAdmin) {
|
|
62075
|
+
if (opts.jsonOutput) {
|
|
62076
|
+
console.log(JSON.stringify({ success: false, error: "missing_folders", missing_folders: missingFolders, message: msg }, null, 2));
|
|
62077
|
+
} else {
|
|
62078
|
+
error(msg);
|
|
62079
|
+
}
|
|
62080
|
+
process.exit(1);
|
|
62081
|
+
}
|
|
62082
|
+
if (!opts.jsonOutput) {
|
|
62083
|
+
warn(msg);
|
|
62084
|
+
}
|
|
62085
|
+
}
|
|
62027
62086
|
if (opts.dryRun && opts.jsonOutput) {
|
|
62028
62087
|
const result = {
|
|
62029
62088
|
success: true,
|
|
@@ -66153,7 +66212,7 @@ var init_app = __esm(async () => {
|
|
|
66153
66212
|
});
|
|
66154
66213
|
|
|
66155
66214
|
// src/commands/folder/folder.ts
|
|
66156
|
-
import { stat as stat9, writeFile as writeFile10, mkdir as mkdir6 } from "node:fs/promises";
|
|
66215
|
+
import { stat as stat9, readdir as readdir7, writeFile as writeFile10, mkdir as mkdir6 } from "node:fs/promises";
|
|
66157
66216
|
import { sep as SEP14 } from "node:path";
|
|
66158
66217
|
async function list5(opts) {
|
|
66159
66218
|
const workspace = await resolveWorkspace(opts);
|
|
@@ -66182,6 +66241,8 @@ async function newFolder(opts, name) {
|
|
|
66182
66241
|
throw e;
|
|
66183
66242
|
}
|
|
66184
66243
|
const template = {
|
|
66244
|
+
summary: opts.summary ?? "",
|
|
66245
|
+
display_name: name,
|
|
66185
66246
|
owners: [],
|
|
66186
66247
|
extra_perms: {}
|
|
66187
66248
|
};
|
|
@@ -66256,20 +66317,59 @@ async function pushFolder(workspace, name, folder, localFolder) {
|
|
|
66256
66317
|
}
|
|
66257
66318
|
}
|
|
66258
66319
|
}
|
|
66259
|
-
async function push5(opts,
|
|
66320
|
+
async function push5(opts, name) {
|
|
66260
66321
|
const workspace = await resolveWorkspace(opts);
|
|
66261
66322
|
await requireLogin(opts);
|
|
66262
|
-
|
|
66263
|
-
|
|
66264
|
-
|
|
66265
|
-
|
|
66266
|
-
|
|
66267
|
-
throw new Error("file path must refer to a file.");
|
|
66323
|
+
const metaPath = `f${SEP14}${name}${SEP14}folder.meta.yaml`;
|
|
66324
|
+
try {
|
|
66325
|
+
await stat9(metaPath);
|
|
66326
|
+
} catch {
|
|
66327
|
+
throw new Error(`Could not find ${metaPath}. Does the folder exist locally?`);
|
|
66268
66328
|
}
|
|
66269
66329
|
console.log(colors.bold.yellow("Pushing folder..."));
|
|
66270
|
-
await pushFolder(workspace.workspaceId,
|
|
66330
|
+
await pushFolder(workspace.workspaceId, name, undefined, parseFromFile(metaPath));
|
|
66271
66331
|
console.log(colors.bold.underline.green("Folder pushed"));
|
|
66272
66332
|
}
|
|
66333
|
+
async function addMissing(opts) {
|
|
66334
|
+
const fDir = `f`;
|
|
66335
|
+
try {
|
|
66336
|
+
await stat9(fDir);
|
|
66337
|
+
} catch {
|
|
66338
|
+
info("No 'f/' directory found. Nothing to do.");
|
|
66339
|
+
return;
|
|
66340
|
+
}
|
|
66341
|
+
const entries = await readdir7(fDir, { withFileTypes: true });
|
|
66342
|
+
const missing = [];
|
|
66343
|
+
for (const entry of entries) {
|
|
66344
|
+
if (!entry.isDirectory())
|
|
66345
|
+
continue;
|
|
66346
|
+
const metaPath = `${fDir}${SEP14}${entry.name}${SEP14}folder.meta.yaml`;
|
|
66347
|
+
try {
|
|
66348
|
+
await stat9(metaPath);
|
|
66349
|
+
} catch {
|
|
66350
|
+
missing.push(entry.name);
|
|
66351
|
+
}
|
|
66352
|
+
}
|
|
66353
|
+
if (missing.length === 0) {
|
|
66354
|
+
info("All folders already have a folder.meta.yaml. Nothing to do.");
|
|
66355
|
+
return;
|
|
66356
|
+
}
|
|
66357
|
+
info(`Missing folder.meta.yaml for:`);
|
|
66358
|
+
for (const name of missing) {
|
|
66359
|
+
info(` - ${name}`);
|
|
66360
|
+
}
|
|
66361
|
+
if (!opts.yes && !await Confirm.prompt({
|
|
66362
|
+
message: `Create ${missing.length} folder.meta.yaml file(s)?`,
|
|
66363
|
+
default: true
|
|
66364
|
+
})) {
|
|
66365
|
+
return;
|
|
66366
|
+
}
|
|
66367
|
+
for (const name of missing) {
|
|
66368
|
+
await newFolder(opts, name);
|
|
66369
|
+
}
|
|
66370
|
+
info(`
|
|
66371
|
+
Created ${missing.length} folder.meta.yaml file(s). You can now run 'wmill sync push' to push them.`);
|
|
66372
|
+
}
|
|
66273
66373
|
var import_yaml23, command12, folder_default;
|
|
66274
66374
|
var init_folder = __esm(async () => {
|
|
66275
66375
|
init_colors2();
|
|
@@ -66278,12 +66378,13 @@ var init_folder = __esm(async () => {
|
|
|
66278
66378
|
init_log();
|
|
66279
66379
|
init_services_gen();
|
|
66280
66380
|
await __promiseAll([
|
|
66381
|
+
init_confirm(),
|
|
66281
66382
|
init_auth(),
|
|
66282
66383
|
init_context(),
|
|
66283
66384
|
init_types()
|
|
66284
66385
|
]);
|
|
66285
66386
|
import_yaml23 = __toESM(require_dist(), 1);
|
|
66286
|
-
command12 = new Command().description("folder related commands").option("--json", "Output as JSON (for piping to jq)").action(list5).command("list", "list all folders").option("--json", "Output as JSON (for piping to jq)").action(list5).command("get", "get a folder's details").arguments("<name:string>").option("--json", "Output as JSON (for piping to jq)").action(get4).command("new", "create a new folder locally").arguments("<name:string>").action(newFolder).command("push", "push a local folder
|
|
66387
|
+
command12 = new Command().description("folder related commands").option("--json", "Output as JSON (for piping to jq)").action(list5).command("list", "list all folders").option("--json", "Output as JSON (for piping to jq)").action(list5).command("get", "get a folder's details").arguments("<name:string>").option("--json", "Output as JSON (for piping to jq)").action(get4).command("new", "create a new folder locally").arguments("<name:string>").option("--summary <summary:string>", "folder summary").action(newFolder).command("push", "push a local folder to the remote by name. This overrides any remote versions.").arguments("<name:string>").action(push5).command("add-missing", "create default folder.meta.yaml for all subdirectories of f/ that are missing one").option("-y, --yes", "skip confirmation prompt").action(addMissing);
|
|
66287
66388
|
folder_default = command12;
|
|
66288
66389
|
});
|
|
66289
66390
|
|
|
@@ -67360,7 +67461,7 @@ var init_settings = __esm(async () => {
|
|
|
67360
67461
|
});
|
|
67361
67462
|
|
|
67362
67463
|
// src/commands/instance/instance.ts
|
|
67363
|
-
import { readFile as readFile13, writeFile as writeFile15, readdir as
|
|
67464
|
+
import { readFile as readFile13, writeFile as writeFile15, readdir as readdir8, mkdir as mkdir7, rm as rm3, stat as stat13 } from "node:fs/promises";
|
|
67364
67465
|
import { appendFile } from "node:fs/promises";
|
|
67365
67466
|
import * as path15 from "node:path";
|
|
67366
67467
|
async function allInstances() {
|
|
@@ -67760,7 +67861,7 @@ async function getLocalWorkspaces(rootDir, localPrefix, folderPerInstance) {
|
|
|
67760
67861
|
await mkdir7(localPrefix);
|
|
67761
67862
|
}
|
|
67762
67863
|
if (folderPerInstance) {
|
|
67763
|
-
const prefixEntries = await
|
|
67864
|
+
const prefixEntries = await readdir8(rootDir + "/" + localPrefix, { withFileTypes: true });
|
|
67764
67865
|
for (const dir of prefixEntries) {
|
|
67765
67866
|
if (dir.isDirectory()) {
|
|
67766
67867
|
const dirName = dir.name;
|
|
@@ -67771,7 +67872,7 @@ async function getLocalWorkspaces(rootDir, localPrefix, folderPerInstance) {
|
|
|
67771
67872
|
}
|
|
67772
67873
|
}
|
|
67773
67874
|
} else {
|
|
67774
|
-
const rootEntries = await
|
|
67875
|
+
const rootEntries = await readdir8(rootDir, { withFileTypes: true });
|
|
67775
67876
|
for (const dir of rootEntries) {
|
|
67776
67877
|
const dirName = dir.name;
|
|
67777
67878
|
if (dirName.startsWith(localPrefix + "_")) {
|
|
@@ -75811,7 +75912,7 @@ Reference a specific resource using \`$res:\` prefix:
|
|
|
75811
75912
|
|
|
75812
75913
|
## OpenFlow Schema
|
|
75813
75914
|
|
|
75814
|
-
{"OpenFlow":{"type":"object","description":"Top-level flow definition containing metadata, configuration, and the flow structure","properties":{"summary":{"type":"string","description":"Short description of what this flow does"},"description":{"type":"string","description":"Detailed documentation for this flow"},"value":{"$ref":"#/components/schemas/FlowValue"},"schema":{"type":"object","description":"JSON Schema for flow inputs. Use this to define input parameters, their types, defaults, and validation. For resource inputs, set type to 'object' and format to 'resource-<type>' (e.g., 'resource-stripe')"}},"required":["summary","value"]},"FlowValue":{"type":"object","description":"The flow structure containing modules and optional preprocessor/failure handlers","properties":{"modules":{"type":"array","description":"Array of steps that execute in sequence. Each step can be a script, subflow, loop, or branch","items":{"$ref":"#/components/schemas/FlowModule"}},"failure_module":{"description":"Special module that executes when the flow fails. Receives error object with message, name, stack, and step_id. Must have id 'failure'. Only supports script/rawscript types","$ref":"#/components/schemas/FlowModule"},"preprocessor_module":{"description":"Special module that runs before the first step on external triggers. Must have id 'preprocessor'. Only supports script/rawscript types. Cannot reference other step results","$ref":"#/components/schemas/FlowModule"},"same_worker":{"type":"boolean","description":"If true, all steps run on the same worker for better performance"},"concurrent_limit":{"type":"number","description":"Maximum number of concurrent executions of this flow"},"concurrency_key":{"type":"string","description":"Expression to group concurrent executions (e.g., by user ID)"},"concurrency_time_window_s":{"type":"number","description":"Time window in seconds for concurrent_limit"},"debounce_delay_s":{"type":"number","description":"Delay in seconds to debounce flow executions"},"debounce_key":{"type":"string","description":"Expression to group debounced executions"},"debounce_args_to_accumulate":{"type":"array","description":"Arguments to accumulate across debounced executions","items":{"type":"string"}},"max_total_debouncing_time":{"type":"number","description":"Maximum total time in seconds that a job can be debounced"},"max_total_debounces_amount":{"type":"number","description":"Maximum number of times a job can be debounced"},"skip_expr":{"type":"string","description":"JavaScript expression to conditionally skip the entire flow"},"cache_ttl":{"type":"number","description":"Cache duration in seconds for flow results"},"cache_ignore_s3_path":{"type":"boolean"},"flow_env":{"type":"object","description":"Environment variables available to all steps","additionalProperties":{"type":"string"}},"priority":{"type":"number","description":"Execution priority (higher numbers run first)"},"early_return":{"type":"string","description":"JavaScript expression to return early from the flow"},"chat_input_enabled":{"type":"boolean","description":"Whether this flow accepts chat-style input"},"notes":{"type":"array","description":"Sticky notes attached to the flow","items":{"$ref":"#/components/schemas/FlowNote"}}},"required":["modules"]},"Retry":{"type":"object","description":"Retry configuration for failed module executions","properties":{"constant":{"type":"object","description":"Retry with constant delay between attempts","properties":{"attempts":{"type":"integer","description":"Number of retry attempts"},"seconds":{"type":"integer","description":"Seconds to wait between retries"}}},"exponential":{"type":"object","description":"Retry with exponential backoff (delay doubles each time)","properties":{"attempts":{"type":"integer","description":"Number of retry attempts"},"multiplier":{"type":"integer","description":"Multiplier for exponential backoff"},"seconds":{"type":"integer","minimum":1,"description":"Initial delay in seconds"},"random_factor":{"type":"integer","minimum":0,"maximum":100,"description":"Random jitter percentage (0-100) to avoid thundering herd"}}},"retry_if":{"$ref":"#/components/schemas/RetryIf"}}},"FlowNote":{"type":"object","description":"A sticky note attached to a flow for documentation and annotation","properties":{"id":{"type":"string","description":"Unique identifier for the note"},"text":{"type":"string","description":"Content of the note"},"position":{"type":"object","description":"Position of the note in the flow editor","properties":{"x":{"type":"number","description":"X coordinate"},"y":{"type":"number","description":"Y coordinate"}},"required":["x","y"]},"size":{"type":"object","description":"Size of the note in the flow editor","properties":{"width":{"type":"number","description":"Width in pixels"},"height":{"type":"number","description":"Height in pixels"}},"required":["width","height"]},"color":{"type":"string","description":"Color of the note (e.g., \\"yellow\\", \\"#ffff00\\")"},"type":{"type":"string","enum":["free","group"],"description":"Type of note - 'free' for standalone notes, 'group' for notes that group other nodes"},"locked":{"type":"boolean","default":false,"description":"Whether the note is locked and cannot be edited or moved"},"contained_node_ids":{"type":"array","items":{"type":"string"},"description":"For group notes, the IDs of nodes contained within this group"}},"required":["id","text","color","type"]},"RetryIf":{"type":"object","description":"Conditional retry based on error or result","properties":{"expr":{"type":"string","description":"JavaScript expression that returns true to retry. Has access to 'result' and 'error' variables"}},"required":["expr"]},"StopAfterIf":{"type":"object","description":"Early termination condition for a module","properties":{"skip_if_stopped":{"type":"boolean","description":"If true, following steps are skipped when this condition triggers"},"expr":{"type":"string","description":"JavaScript expression evaluated after the module runs. Can use 'result' (step's result) or 'flow_input'. Return true to stop"},"error_message":{"type":"string","description":"Custom error message shown when stopping"}},"required":["expr"]},"FlowModule":{"type":"object","description":"A single step in a flow. Can be a script, subflow, loop, or branch","properties":{"id":{"type":"string","description":"Unique identifier for this step. Used to reference results via 'results.step_id'. Must be a valid identifier (alphanumeric, underscore, hyphen)"},"value":{"$ref":"#/components/schemas/FlowModuleValue"},"stop_after_if":{"description":"Early termination condition evaluated after this step completes","$ref":"#/components/schemas/StopAfterIf"},"stop_after_all_iters_if":{"description":"For loops only - early termination condition evaluated after all iterations complete","$ref":"#/components/schemas/StopAfterIf"},"skip_if":{"type":"object","description":"Conditionally skip this step based on previous results or flow inputs","properties":{"expr":{"type":"string","description":"JavaScript expression that returns true to skip. Can use 'flow_input' or 'results.<step_id>'"}},"required":["expr"]},"sleep":{"description":"Delay before executing this step (in seconds or as expression)","$ref":"#/components/schemas/InputTransform"},"cache_ttl":{"type":"number","description":"Cache duration in seconds for this step's results"},"cache_ignore_s3_path":{"type":"boolean"},"timeout":{"description":"Maximum execution time in seconds (static value or expression)","$ref":"#/components/schemas/InputTransform"},"delete_after_use":{"type":"boolean","description":"If true, this step's result is deleted after use to save memory"},"summary":{"type":"string","description":"Short description of what this step does"},"mock":{"type":"object","description":"Mock configuration for testing without executing the actual step","properties":{"enabled":{"type":"boolean","description":"If true, return mock value instead of executing"},"return_value":{"description":"Value to return when mocked"}}},"suspend":{"type":"object","description":"Configuration for approval/resume steps that wait for user input","properties":{"required_events":{"type":"integer","description":"Number of approvals required before continuing"},"timeout":{"type":"integer","description":"Timeout in seconds before auto-continuing or canceling"},"resume_form":{"type":"object","description":"Form schema for collecting input when resuming","properties":{"schema":{"type":"object","description":"JSON Schema for the resume form"}}},"user_auth_required":{"type":"boolean","description":"If true, only authenticated users can approve"},"user_groups_required":{"description":"Expression or list of groups that can approve","$ref":"#/components/schemas/InputTransform"},"self_approval_disabled":{"type":"boolean","description":"If true, the user who started the flow cannot approve"},"hide_cancel":{"type":"boolean","description":"If true, hide the cancel button on the approval form"},"continue_on_disapprove_timeout":{"type":"boolean","description":"If true, continue flow on timeout instead of canceling"}}},"priority":{"type":"number","description":"Execution priority for this step (higher numbers run first)"},"continue_on_error":{"type":"boolean","description":"If true, flow continues even if this step fails"},"retry":{"description":"Retry configuration if this step fails","$ref":"#/components/schemas/Retry"}},"required":["value","id"]},"InputTransform":{"description":"Maps input parameters for a step. Can be a static value or a JavaScript expression that references previous results or flow inputs","oneOf":[{"$ref":"#/components/schemas/StaticTransform"},{"$ref":"#/components/schemas/JavascriptTransform"},{"$ref":"#/components/schemas/AiTransform"}],"discriminator":{"propertyName":"type","mapping":{"static":"#/components/schemas/StaticTransform","javascript":"#/components/schemas/JavascriptTransform","ai":"#/components/schemas/AiTransform"}}},"StaticTransform":{"type":"object","description":"Static value passed directly to the step. Use for hardcoded values or resource references like '$res:path/to/resource'","properties":{"value":{"description":"The static value. For resources, use format '$res:path/to/resource'"},"type":{"type":"string","enum":["static"]}},"required":["type"]},"JavascriptTransform":{"type":"object","description":"JavaScript expression evaluated at runtime. Can reference previous step results via 'results.step_id' or flow inputs via 'flow_input.property'. Inside loops, use 'flow_input.iter.value' for the current iteration value","properties":{"expr":{"type":"string","description":"JavaScript expression returning the value. Available variables - results (object with all previous step results), flow_input (flow inputs), flow_input.iter (in loops)"},"type":{"type":"string","enum":["javascript"]}},"required":["expr","type"]},"AiTransform":{"type":"object","description":"Value resolved by the AI runtime for this input. The AI engine decides how to satisfy the parameter.","properties":{"type":{"type":"string","enum":["ai"]}},"required":["type"]},"AIProviderKind":{"type":"string","description":"Supported AI provider types","enum":["openai","azure_openai","anthropic","mistral","deepseek","googleai","groq","openrouter","togetherai","customai","aws_bedrock"]},"ProviderConfig":{"type":"object","description":"Complete AI provider configuration with resource reference and model selection","properties":{"kind":{"$ref":"#/components/schemas/AIProviderKind"},"resource":{"type":"string","description":"Resource reference in format '$res:{resource_path}' pointing to provider credentials"},"model":{"type":"string","description":"Model identifier (e.g., 'gpt-4', 'claude-3-opus-20240229', 'gemini-pro')"}},"required":["kind","resource","model"]},"StaticProviderTransform":{"type":"object","description":"Static provider configuration passed directly to the AI agent","properties":{"value":{"$ref":"#/components/schemas/ProviderConfig"},"type":{"type":"string","enum":["static"]}},"required":["type","value"]},"ProviderTransform":{"description":"Provider configuration - can be static (ProviderConfig), JavaScript expression, or AI-determined","oneOf":[{"$ref":"#/components/schemas/StaticProviderTransform"},{"$ref":"#/components/schemas/JavascriptTransform"},{"$ref":"#/components/schemas/AiTransform"}],"discriminator":{"propertyName":"type","mapping":{"static":"#/components/schemas/StaticProviderTransform","javascript":"#/components/schemas/JavascriptTransform","ai":"#/components/schemas/AiTransform"}}},"MemoryOff":{"type":"object","description":"No conversation memory/context","properties":{"kind":{"type":"string","enum":["off"]}},"required":["kind"]},"MemoryAuto":{"type":"object","description":"Automatic context management","properties":{"kind":{"type":"string","enum":["auto"]},"context_length":{"type":"integer","description":"Maximum number of messages to retain in context"},"memory_id":{"type":"string","description":"Identifier for persistent memory across agent invocations"}},"required":["kind"]},"MemoryMessage":{"type":"object","description":"A single message in conversation history","properties":{"role":{"type":"string","enum":["user","assistant","system"]},"content":{"type":"string"}},"required":["role","content"]},"MemoryManual":{"type":"object","description":"Explicit message history","properties":{"kind":{"type":"string","enum":["manual"]},"messages":{"type":"array","items":{"$ref":"#/components/schemas/MemoryMessage"}}},"required":["kind","messages"]},"MemoryConfig":{"description":"Conversation memory configuration","oneOf":[{"$ref":"#/components/schemas/MemoryOff"},{"$ref":"#/components/schemas/MemoryAuto"},{"$ref":"#/components/schemas/MemoryManual"}],"discriminator":{"propertyName":"kind","mapping":{"off":"#/components/schemas/MemoryOff","auto":"#/components/schemas/MemoryAuto","manual":"#/components/schemas/MemoryManual"}}},"StaticMemoryTransform":{"type":"object","description":"Static memory configuration passed directly to the AI agent","properties":{"value":{"$ref":"#/components/schemas/MemoryConfig"},"type":{"type":"string","enum":["static"]}},"required":["type","value"]},"MemoryTransform":{"description":"Memory configuration - can be static (MemoryConfig), JavaScript expression, or AI-determined","oneOf":[{"$ref":"#/components/schemas/StaticMemoryTransform"},{"$ref":"#/components/schemas/JavascriptTransform"},{"$ref":"#/components/schemas/AiTransform"}],"discriminator":{"propertyName":"type","mapping":{"static":"#/components/schemas/StaticMemoryTransform","javascript":"#/components/schemas/JavascriptTransform","ai":"#/components/schemas/AiTransform"}}},"FlowModuleValue":{"description":"The actual implementation of a flow step. Can be a script (inline or referenced), subflow, loop, branch, or special module type","oneOf":[{"$ref":"#/components/schemas/RawScript"},{"$ref":"#/components/schemas/PathScript"},{"$ref":"#/components/schemas/PathFlow"},{"$ref":"#/components/schemas/ForloopFlow"},{"$ref":"#/components/schemas/WhileloopFlow"},{"$ref":"#/components/schemas/BranchOne"},{"$ref":"#/components/schemas/BranchAll"},{"$ref":"#/components/schemas/Identity"},{"$ref":"#/components/schemas/AiAgent"}],"discriminator":{"propertyName":"type","mapping":{"rawscript":"#/components/schemas/RawScript","script":"#/components/schemas/PathScript","flow":"#/components/schemas/PathFlow","forloopflow":"#/components/schemas/ForloopFlow","whileloopflow":"#/components/schemas/WhileloopFlow","branchone":"#/components/schemas/BranchOne","branchall":"#/components/schemas/BranchAll","identity":"#/components/schemas/Identity","aiagent":"#/components/schemas/AiAgent"}}},"RawScript":{"type":"object","description":"Inline script with code defined directly in the flow. Use 'bun' as default language if unspecified. The script receives arguments from input_transforms","properties":{"input_transforms":{"type":"object","description":"Map of parameter names to their values (static or JavaScript expressions). These become the script's input arguments","additionalProperties":{"$ref":"#/components/schemas/InputTransform"}},"content":{"type":"string","description":"The script source code. Should export a 'main' function"},"language":{"type":"string","description":"Programming language for this script","enum":["deno","bun","python3","go","bash","powershell","postgresql","mysql","bigquery","snowflake","mssql","oracledb","graphql","nativets","php"]},"path":{"type":"string","description":"Optional path for saving this script"},"lock":{"type":"string","description":"Lock file content for dependencies"},"type":{"type":"string","enum":["rawscript"]},"tag":{"type":"string","description":"Worker group tag for execution routing"},"concurrent_limit":{"type":"number","description":"Maximum concurrent executions of this script"},"concurrency_time_window_s":{"type":"number","description":"Time window for concurrent_limit"},"custom_concurrency_key":{"type":"string","description":"Custom key for grouping concurrent executions"},"is_trigger":{"type":"boolean","description":"If true, this script is a trigger that can start the flow"},"assets":{"type":"array","description":"External resources this script accesses (S3 objects, resources, etc.)","items":{"type":"object","required":["path","kind"],"properties":{"path":{"type":"string","description":"Path to the asset"},"kind":{"type":"string","description":"Type of asset","enum":["s3object","resource","ducklake","datatable"]},"access_type":{"type":"string","description":"Access level for this asset","enum":["r","w","rw"]},"alt_access_type":{"type":"string","description":"Alternative access level","enum":["r","w","rw"]}}}}},"required":["type","content","language","input_transforms"]},"PathScript":{"type":"object","description":"Reference to an existing script by path. Use this when calling a previously saved script instead of writing inline code","properties":{"input_transforms":{"type":"object","description":"Map of parameter names to their values (static or JavaScript expressions). These become the script's input arguments","additionalProperties":{"$ref":"#/components/schemas/InputTransform"}},"path":{"type":"string","description":"Path to the script in the workspace (e.g., 'f/scripts/send_email')"},"hash":{"type":"string","description":"Optional specific version hash of the script to use"},"type":{"type":"string","enum":["script"]},"tag_override":{"type":"string","description":"Override the script's default worker group tag"},"is_trigger":{"type":"boolean","description":"If true, this script is a trigger that can start the flow"}},"required":["type","path","input_transforms"]},"PathFlow":{"type":"object","description":"Reference to an existing flow by path. Use this to call another flow as a subflow","properties":{"input_transforms":{"type":"object","description":"Map of parameter names to their values (static or JavaScript expressions). These become the subflow's input arguments","additionalProperties":{"$ref":"#/components/schemas/InputTransform"}},"path":{"type":"string","description":"Path to the flow in the workspace (e.g., 'f/flows/process_user')"},"type":{"type":"string","enum":["flow"]}},"required":["type","path","input_transforms"]},"ForloopFlow":{"type":"object","description":"Executes nested modules in a loop over an iterator. Inside the loop, use 'flow_input.iter.value' to access the current iteration value, and 'flow_input.iter.index' for the index. Supports parallel execution for better performance on I/O-bound operations","properties":{"modules":{"type":"array","description":"Steps to execute for each iteration. These can reference the iteration value via 'flow_input.iter.value'","items":{"$ref":"#/components/schemas/FlowModule"}},"iterator":{"description":"JavaScript expression that returns an array to iterate over. Can reference 'results.step_id' or 'flow_input'","$ref":"#/components/schemas/InputTransform"},"skip_failures":{"type":"boolean","description":"If true, iteration failures don't stop the loop. Failed iterations return null"},"type":{"type":"string","enum":["forloopflow"]},"parallel":{"type":"boolean","description":"If true, iterations run concurrently (faster for I/O-bound operations). Use with parallelism to control concurrency"},"parallelism":{"description":"Maximum number of concurrent iterations when parallel=true. Limits resource usage. Can be static number or expression","$ref":"#/components/schemas/InputTransform"},"squash":{"type":"boolean"}},"required":["modules","iterator","skip_failures","type"]},"WhileloopFlow":{"type":"object","description":"Executes nested modules repeatedly while a condition is true. The loop checks the condition after each iteration. Use stop_after_if on modules to control loop termination","properties":{"modules":{"type":"array","description":"Steps to execute in each iteration. Use stop_after_if to control when the loop ends","items":{"$ref":"#/components/schemas/FlowModule"}},"skip_failures":{"type":"boolean","description":"If true, iteration failures don't stop the loop. Failed iterations return null"},"type":{"type":"string","enum":["whileloopflow"]},"parallel":{"type":"boolean","description":"If true, iterations run concurrently (use with caution in while loops)"},"parallelism":{"description":"Maximum number of concurrent iterations when parallel=true","$ref":"#/components/schemas/InputTransform"},"squash":{"type":"boolean"}},"required":["modules","skip_failures","type"]},"BranchOne":{"type":"object","description":"Conditional branching where only the first matching branch executes. Branches are evaluated in order, and the first one with a true expression runs. If no branches match, the default branch executes","properties":{"branches":{"type":"array","description":"Array of branches to evaluate in order. The first branch with expr evaluating to true executes","items":{"type":"object","properties":{"summary":{"type":"string","description":"Short description of this branch condition"},"expr":{"type":"string","description":"JavaScript expression that returns boolean. Can use 'results.step_id' or 'flow_input'. First true expr wins"},"modules":{"type":"array","description":"Steps to execute if this branch's expr is true","items":{"$ref":"#/components/schemas/FlowModule"}}},"required":["modules","expr"]}},"default":{"type":"array","description":"Steps to execute if no branch expressions match","items":{"$ref":"#/components/schemas/FlowModule"}},"type":{"type":"string","enum":["branchone"]}},"required":["branches","default","type"]},"BranchAll":{"type":"object","description":"Parallel branching where all branches execute simultaneously. Unlike BranchOne, all branches run regardless of conditions. Useful for executing independent tasks concurrently","properties":{"branches":{"type":"array","description":"Array of branches that all execute (either in parallel or sequentially)","items":{"type":"object","properties":{"summary":{"type":"string","description":"Short description of this branch's purpose"},"skip_failure":{"type":"boolean","description":"If true, failure in this branch doesn't fail the entire flow"},"modules":{"type":"array","description":"Steps to execute in this branch","items":{"$ref":"#/components/schemas/FlowModule"}}},"required":["modules"]}},"type":{"type":"string","enum":["branchall"]},"parallel":{"type":"boolean","description":"If true, all branches execute concurrently. If false, they execute sequentially"}},"required":["branches","type"]},"AgentTool":{"type":"object","description":"A tool available to an AI agent. Can be a flow module or an external MCP (Model Context Protocol) tool","properties":{"id":{"type":"string","description":"Unique identifier for this tool. Cannot contain spaces - use underscores instead (e.g., 'get_user_data' not 'get user data')"},"summary":{"type":"string","description":"Short description of what this tool does (shown to the AI)"},"value":{"$ref":"#/components/schemas/ToolValue"}},"required":["id","value"]},"ToolValue":{"description":"The implementation of a tool. Can be a flow module (script/flow) or an MCP tool reference","oneOf":[{"$ref":"#/components/schemas/FlowModuleTool"},{"$ref":"#/components/schemas/McpToolValue"},{"$ref":"#/components/schemas/WebsearchToolValue"}],"discriminator":{"propertyName":"tool_type","mapping":{"flowmodule":"#/components/schemas/FlowModuleTool","mcp":"#/components/schemas/McpToolValue","websearch":"#/components/schemas/WebsearchToolValue"}}},"FlowModuleTool":{"description":"A tool implemented as a flow module (script, flow, etc.). The AI can call this like any other flow module","allOf":[{"type":"object","properties":{"tool_type":{"type":"string","enum":["flowmodule"]}},"required":["tool_type"]},{"$ref":"#/components/schemas/FlowModuleValue"}]},"WebsearchToolValue":{"type":"object","description":"A tool implemented as a websearch tool. The AI can call this like any other websearch tool","properties":{"tool_type":{"type":"string","enum":["websearch"]}},"required":["tool_type"]},"McpToolValue":{"type":"object","description":"Reference to an external MCP (Model Context Protocol) tool. The AI can call tools from MCP servers","properties":{"tool_type":{"type":"string","enum":["mcp"]},"resource_path":{"type":"string","description":"Path to the MCP resource/server configuration"},"include_tools":{"type":"array","description":"Whitelist of specific tools to include from this MCP server","items":{"type":"string"}},"exclude_tools":{"type":"array","description":"Blacklist of tools to exclude from this MCP server","items":{"type":"string"}}},"required":["tool_type","resource_path"]},"AiAgent":{"type":"object","description":"AI agent step that can use tools to accomplish tasks. The agent receives inputs and can call any of its configured tools to complete the task","properties":{"input_transforms":{"type":"object","description":"Input parameters for the AI agent mapped to their values","properties":{"provider":{"$ref":"#/components/schemas/ProviderTransform"},"output_type":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Output format type.\\nValid values: 'text' (default) - plain text response, 'image' - image generation\\n"},"user_message":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"The user's prompt/message to the AI agent. Supports variable interpolation with flow.input syntax."},"system_prompt":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"System instructions that guide the AI's behavior, persona, and response style. Optional."},"streaming":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Boolean. If true, stream the AI response incrementally.\\nStreaming events include: token_delta, tool_call, tool_call_arguments, tool_execution, tool_result\\n"},"memory":{"$ref":"#/components/schemas/MemoryTransform"},"output_schema":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"JSON Schema object defining structured output format. Used when you need the AI to return data in a specific shape.\\nSupports standard JSON Schema properties: type, properties, required, items, enum, pattern, minLength, maxLength, minimum, maximum, etc.\\nExample: { type: 'object', properties: { name: { type: 'string' }, age: { type: 'integer' } }, required: ['name'] }\\n"},"user_images":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Array of image references for vision-capable models.\\nFormat: Array<{ bucket: string, key: string }> - S3 object references\\nExample: [{ bucket: 'my-bucket', key: 'images/photo.jpg' }]\\n"},"max_completion_tokens":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Integer. Maximum number of tokens the AI will generate in its response.\\nRange: 1 to 4,294,967,295. Typical values: 256-4096 for most use cases.\\n"},"temperature":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Float. Controls randomness/creativity of responses.\\nRange: 0.0 to 2.0 (provider-dependent)\\n- 0.0 = deterministic, focused responses\\n- 0.7 = balanced (common default)\\n- 1.0+ = more creative/random\\n"}},"required":["provider","user_message","output_type"]},"tools":{"type":"array","description":"Array of tools the agent can use. The agent decides which tools to call based on the task","items":{"$ref":"#/components/schemas/AgentTool"}},"type":{"type":"string","enum":["aiagent"]},"parallel":{"type":"boolean","description":"If true, the agent can execute multiple tool calls in parallel"}},"required":["tools","type","input_transforms"]},"Identity":{"type":"object","description":"Pass-through module that returns its input unchanged. Useful for flow structure or as a placeholder","properties":{"type":{"type":"string","enum":["identity"]},"flow":{"type":"boolean","description":"If true, marks this as a flow identity (special handling)"}},"required":["type"]},"FlowStatus":{"type":"object","properties":{"step":{"type":"integer"},"modules":{"type":"array","items":{"$ref":"#/components/schemas/FlowStatusModule"}},"user_states":{"additionalProperties":true},"preprocessor_module":{"allOf":[{"$ref":"#/components/schemas/FlowStatusModule"}]},"failure_module":{"allOf":[{"$ref":"#/components/schemas/FlowStatusModule"},{"type":"object","properties":{"parent_module":{"type":"string"}}}]},"retry":{"type":"object","properties":{"fail_count":{"type":"integer"},"failed_jobs":{"type":"array","items":{"type":"string","format":"uuid"}}}}},"required":["step","modules","failure_module"]},"FlowStatusModule":{"type":"object","properties":{"type":{"type":"string","enum":["WaitingForPriorSteps","WaitingForEvents","WaitingForExecutor","InProgress","Success","Failure"]},"id":{"type":"string"},"job":{"type":"string","format":"uuid"},"count":{"type":"integer"},"progress":{"type":"integer"},"iterator":{"type":"object","properties":{"index":{"type":"integer"},"itered":{"type":"array","items":{}},"itered_len":{"type":"integer"},"args":{}}},"flow_jobs":{"type":"array","items":{"type":"string"}},"flow_jobs_success":{"type":"array","items":{"type":"boolean"}},"flow_jobs_duration":{"type":"object","properties":{"started_at":{"type":"array","items":{"type":"string"}},"duration_ms":{"type":"array","items":{"type":"integer"}}}},"branch_chosen":{"type":"object","properties":{"type":{"type":"string","enum":["branch","default"]},"branch":{"type":"integer"}},"required":["type"]},"branchall":{"type":"object","properties":{"branch":{"type":"integer"},"len":{"type":"integer"}},"required":["branch","len"]},"approvers":{"type":"array","items":{"type":"object","properties":{"resume_id":{"type":"integer"},"approver":{"type":"string"}},"required":["resume_id","approver"]}},"failed_retries":{"type":"array","items":{"type":"string","format":"uuid"}},"skipped":{"type":"boolean"},"agent_actions":{"type":"array","items":{"type":"object","oneOf":[{"type":"object","properties":{"job_id":{"type":"string","format":"uuid"},"function_name":{"type":"string"},"type":{"type":"string","enum":["tool_call"]},"module_id":{"type":"string"}},"required":["job_id","function_name","type","module_id"]},{"type":"object","properties":{"call_id":{"type":"string","format":"uuid"},"function_name":{"type":"string"},"resource_path":{"type":"string"},"type":{"type":"string","enum":["mcp_tool_call"]},"arguments":{"type":"object"}},"required":["call_id","function_name","resource_path","type"]},{"type":"object","properties":{"type":{"type":"string","enum":["web_search"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["message"]}},"required":["content","type"]}]}},"agent_actions_success":{"type":"array","items":{"type":"boolean"}}},"required":["type"]}}`,
|
|
75915
|
+
{"OpenFlow":{"type":"object","description":"Top-level flow definition containing metadata, configuration, and the flow structure","properties":{"summary":{"type":"string","description":"Short description of what this flow does"},"description":{"type":"string","description":"Detailed documentation for this flow"},"value":{"$ref":"#/components/schemas/FlowValue"},"schema":{"type":"object","description":"JSON Schema for flow inputs. Use this to define input parameters, their types, defaults, and validation. For resource inputs, set type to 'object' and format to 'resource-<type>' (e.g., 'resource-stripe')"},"on_behalf_of_email":{"type":"string","description":"The flow will be run with the permissions of the user with this email."}},"required":["summary","value"]},"FlowValue":{"type":"object","description":"The flow structure containing modules and optional preprocessor/failure handlers","properties":{"modules":{"type":"array","description":"Array of steps that execute in sequence. Each step can be a script, subflow, loop, or branch","items":{"$ref":"#/components/schemas/FlowModule"}},"failure_module":{"description":"Special module that executes when the flow fails. Receives error object with message, name, stack, and step_id. Must have id 'failure'. Only supports script/rawscript types","$ref":"#/components/schemas/FlowModule"},"preprocessor_module":{"description":"Special module that runs before the first step on external triggers. Must have id 'preprocessor'. Only supports script/rawscript types. Cannot reference other step results","$ref":"#/components/schemas/FlowModule"},"same_worker":{"type":"boolean","description":"If true, all steps run on the same worker for better performance"},"concurrent_limit":{"type":"number","description":"Maximum number of concurrent executions of this flow"},"concurrency_key":{"type":"string","description":"Expression to group concurrent executions (e.g., by user ID)"},"concurrency_time_window_s":{"type":"number","description":"Time window in seconds for concurrent_limit"},"debounce_delay_s":{"type":"number","description":"Delay in seconds to debounce flow executions"},"debounce_key":{"type":"string","description":"Expression to group debounced executions"},"debounce_args_to_accumulate":{"type":"array","description":"Arguments to accumulate across debounced executions","items":{"type":"string"}},"max_total_debouncing_time":{"type":"number","description":"Maximum total time in seconds that a job can be debounced"},"max_total_debounces_amount":{"type":"number","description":"Maximum number of times a job can be debounced"},"skip_expr":{"type":"string","description":"JavaScript expression to conditionally skip the entire flow"},"cache_ttl":{"type":"number","description":"Cache duration in seconds for flow results"},"cache_ignore_s3_path":{"type":"boolean"},"flow_env":{"type":"object","description":"Environment variables available to all steps","additionalProperties":{"type":"string"}},"priority":{"type":"number","description":"Execution priority (higher numbers run first)"},"early_return":{"type":"string","description":"JavaScript expression to return early from the flow"},"chat_input_enabled":{"type":"boolean","description":"Whether this flow accepts chat-style input"},"notes":{"type":"array","description":"Sticky notes attached to the flow","items":{"$ref":"#/components/schemas/FlowNote"}}},"required":["modules"]},"Retry":{"type":"object","description":"Retry configuration for failed module executions","properties":{"constant":{"type":"object","description":"Retry with constant delay between attempts","properties":{"attempts":{"type":"integer","description":"Number of retry attempts"},"seconds":{"type":"integer","description":"Seconds to wait between retries"}}},"exponential":{"type":"object","description":"Retry with exponential backoff (delay doubles each time)","properties":{"attempts":{"type":"integer","description":"Number of retry attempts"},"multiplier":{"type":"integer","description":"Multiplier for exponential backoff"},"seconds":{"type":"integer","minimum":1,"description":"Initial delay in seconds"},"random_factor":{"type":"integer","minimum":0,"maximum":100,"description":"Random jitter percentage (0-100) to avoid thundering herd"}}},"retry_if":{"$ref":"#/components/schemas/RetryIf"}}},"FlowNote":{"type":"object","description":"A sticky note attached to a flow for documentation and annotation","properties":{"id":{"type":"string","description":"Unique identifier for the note"},"text":{"type":"string","description":"Content of the note"},"position":{"type":"object","description":"Position of the note in the flow editor","properties":{"x":{"type":"number","description":"X coordinate"},"y":{"type":"number","description":"Y coordinate"}},"required":["x","y"]},"size":{"type":"object","description":"Size of the note in the flow editor","properties":{"width":{"type":"number","description":"Width in pixels"},"height":{"type":"number","description":"Height in pixels"}},"required":["width","height"]},"color":{"type":"string","description":"Color of the note (e.g., \\"yellow\\", \\"#ffff00\\")"},"type":{"type":"string","enum":["free","group"],"description":"Type of note - 'free' for standalone notes, 'group' for notes that group other nodes"},"locked":{"type":"boolean","default":false,"description":"Whether the note is locked and cannot be edited or moved"},"contained_node_ids":{"type":"array","items":{"type":"string"},"description":"For group notes, the IDs of nodes contained within this group"}},"required":["id","text","color","type"]},"RetryIf":{"type":"object","description":"Conditional retry based on error or result","properties":{"expr":{"type":"string","description":"JavaScript expression that returns true to retry. Has access to 'result' and 'error' variables"}},"required":["expr"]},"StopAfterIf":{"type":"object","description":"Early termination condition for a module","properties":{"skip_if_stopped":{"type":"boolean","description":"If true, following steps are skipped when this condition triggers"},"expr":{"type":"string","description":"JavaScript expression evaluated after the module runs. Can use 'result' (step's result) or 'flow_input'. Return true to stop"},"error_message":{"type":"string","description":"Custom error message shown when stopping"}},"required":["expr"]},"FlowModule":{"type":"object","description":"A single step in a flow. Can be a script, subflow, loop, or branch","properties":{"id":{"type":"string","description":"Unique identifier for this step. Used to reference results via 'results.step_id'. Must be a valid identifier (alphanumeric, underscore, hyphen)"},"value":{"$ref":"#/components/schemas/FlowModuleValue"},"stop_after_if":{"description":"Early termination condition evaluated after this step completes","$ref":"#/components/schemas/StopAfterIf"},"stop_after_all_iters_if":{"description":"For loops only - early termination condition evaluated after all iterations complete","$ref":"#/components/schemas/StopAfterIf"},"skip_if":{"type":"object","description":"Conditionally skip this step based on previous results or flow inputs","properties":{"expr":{"type":"string","description":"JavaScript expression that returns true to skip. Can use 'flow_input' or 'results.<step_id>'"}},"required":["expr"]},"sleep":{"description":"Delay before executing this step (in seconds or as expression)","$ref":"#/components/schemas/InputTransform"},"cache_ttl":{"type":"number","description":"Cache duration in seconds for this step's results"},"cache_ignore_s3_path":{"type":"boolean"},"timeout":{"description":"Maximum execution time in seconds (static value or expression)","$ref":"#/components/schemas/InputTransform"},"delete_after_use":{"type":"boolean","description":"If true, this step's result is deleted after use to save memory"},"summary":{"type":"string","description":"Short description of what this step does"},"mock":{"type":"object","description":"Mock configuration for testing without executing the actual step","properties":{"enabled":{"type":"boolean","description":"If true, return mock value instead of executing"},"return_value":{"description":"Value to return when mocked"}}},"suspend":{"type":"object","description":"Configuration for approval/resume steps that wait for user input","properties":{"required_events":{"type":"integer","description":"Number of approvals required before continuing"},"timeout":{"type":"integer","description":"Timeout in seconds before auto-continuing or canceling"},"resume_form":{"type":"object","description":"Form schema for collecting input when resuming","properties":{"schema":{"type":"object","description":"JSON Schema for the resume form"}}},"user_auth_required":{"type":"boolean","description":"If true, only authenticated users can approve"},"user_groups_required":{"description":"Expression or list of groups that can approve","$ref":"#/components/schemas/InputTransform"},"self_approval_disabled":{"type":"boolean","description":"If true, the user who started the flow cannot approve"},"hide_cancel":{"type":"boolean","description":"If true, hide the cancel button on the approval form"},"continue_on_disapprove_timeout":{"type":"boolean","description":"If true, continue flow on timeout instead of canceling"}}},"priority":{"type":"number","description":"Execution priority for this step (higher numbers run first)"},"continue_on_error":{"type":"boolean","description":"If true, flow continues even if this step fails"},"retry":{"description":"Retry configuration if this step fails","$ref":"#/components/schemas/Retry"}},"required":["value","id"]},"InputTransform":{"description":"Maps input parameters for a step. Can be a static value or a JavaScript expression that references previous results or flow inputs","oneOf":[{"$ref":"#/components/schemas/StaticTransform"},{"$ref":"#/components/schemas/JavascriptTransform"},{"$ref":"#/components/schemas/AiTransform"}],"discriminator":{"propertyName":"type","mapping":{"static":"#/components/schemas/StaticTransform","javascript":"#/components/schemas/JavascriptTransform","ai":"#/components/schemas/AiTransform"}}},"StaticTransform":{"type":"object","description":"Static value passed directly to the step. Use for hardcoded values or resource references like '$res:path/to/resource'","properties":{"value":{"description":"The static value. For resources, use format '$res:path/to/resource'"},"type":{"type":"string","enum":["static"]}},"required":["type"]},"JavascriptTransform":{"type":"object","description":"JavaScript expression evaluated at runtime. Can reference previous step results via 'results.step_id' or flow inputs via 'flow_input.property'. Inside loops, use 'flow_input.iter.value' for the current iteration value","properties":{"expr":{"type":"string","description":"JavaScript expression returning the value. Available variables - results (object with all previous step results), flow_input (flow inputs), flow_input.iter (in loops)"},"type":{"type":"string","enum":["javascript"]}},"required":["expr","type"]},"AiTransform":{"type":"object","description":"Value resolved by the AI runtime for this input. The AI engine decides how to satisfy the parameter.","properties":{"type":{"type":"string","enum":["ai"]}},"required":["type"]},"AIProviderKind":{"type":"string","description":"Supported AI provider types","enum":["openai","azure_openai","anthropic","mistral","deepseek","googleai","groq","openrouter","togetherai","customai","aws_bedrock"]},"ProviderConfig":{"type":"object","description":"Complete AI provider configuration with resource reference and model selection","properties":{"kind":{"$ref":"#/components/schemas/AIProviderKind"},"resource":{"type":"string","description":"Resource reference in format '$res:{resource_path}' pointing to provider credentials"},"model":{"type":"string","description":"Model identifier (e.g., 'gpt-4', 'claude-3-opus-20240229', 'gemini-pro')"}},"required":["kind","resource","model"]},"StaticProviderTransform":{"type":"object","description":"Static provider configuration passed directly to the AI agent","properties":{"value":{"$ref":"#/components/schemas/ProviderConfig"},"type":{"type":"string","enum":["static"]}},"required":["type","value"]},"ProviderTransform":{"description":"Provider configuration - can be static (ProviderConfig), JavaScript expression, or AI-determined","oneOf":[{"$ref":"#/components/schemas/StaticProviderTransform"},{"$ref":"#/components/schemas/JavascriptTransform"},{"$ref":"#/components/schemas/AiTransform"}],"discriminator":{"propertyName":"type","mapping":{"static":"#/components/schemas/StaticProviderTransform","javascript":"#/components/schemas/JavascriptTransform","ai":"#/components/schemas/AiTransform"}}},"MemoryOff":{"type":"object","description":"No conversation memory/context","properties":{"kind":{"type":"string","enum":["off"]}},"required":["kind"]},"MemoryAuto":{"type":"object","description":"Automatic context management","properties":{"kind":{"type":"string","enum":["auto"]},"context_length":{"type":"integer","description":"Maximum number of messages to retain in context"},"memory_id":{"type":"string","description":"Identifier for persistent memory across agent invocations"}},"required":["kind"]},"MemoryMessage":{"type":"object","description":"A single message in conversation history","properties":{"role":{"type":"string","enum":["user","assistant","system"]},"content":{"type":"string"}},"required":["role","content"]},"MemoryManual":{"type":"object","description":"Explicit message history","properties":{"kind":{"type":"string","enum":["manual"]},"messages":{"type":"array","items":{"$ref":"#/components/schemas/MemoryMessage"}}},"required":["kind","messages"]},"MemoryConfig":{"description":"Conversation memory configuration","oneOf":[{"$ref":"#/components/schemas/MemoryOff"},{"$ref":"#/components/schemas/MemoryAuto"},{"$ref":"#/components/schemas/MemoryManual"}],"discriminator":{"propertyName":"kind","mapping":{"off":"#/components/schemas/MemoryOff","auto":"#/components/schemas/MemoryAuto","manual":"#/components/schemas/MemoryManual"}}},"StaticMemoryTransform":{"type":"object","description":"Static memory configuration passed directly to the AI agent","properties":{"value":{"$ref":"#/components/schemas/MemoryConfig"},"type":{"type":"string","enum":["static"]}},"required":["type","value"]},"MemoryTransform":{"description":"Memory configuration - can be static (MemoryConfig), JavaScript expression, or AI-determined","oneOf":[{"$ref":"#/components/schemas/StaticMemoryTransform"},{"$ref":"#/components/schemas/JavascriptTransform"},{"$ref":"#/components/schemas/AiTransform"}],"discriminator":{"propertyName":"type","mapping":{"static":"#/components/schemas/StaticMemoryTransform","javascript":"#/components/schemas/JavascriptTransform","ai":"#/components/schemas/AiTransform"}}},"FlowModuleValue":{"description":"The actual implementation of a flow step. Can be a script (inline or referenced), subflow, loop, branch, or special module type","oneOf":[{"$ref":"#/components/schemas/RawScript"},{"$ref":"#/components/schemas/PathScript"},{"$ref":"#/components/schemas/PathFlow"},{"$ref":"#/components/schemas/ForloopFlow"},{"$ref":"#/components/schemas/WhileloopFlow"},{"$ref":"#/components/schemas/BranchOne"},{"$ref":"#/components/schemas/BranchAll"},{"$ref":"#/components/schemas/Identity"},{"$ref":"#/components/schemas/AiAgent"}],"discriminator":{"propertyName":"type","mapping":{"rawscript":"#/components/schemas/RawScript","script":"#/components/schemas/PathScript","flow":"#/components/schemas/PathFlow","forloopflow":"#/components/schemas/ForloopFlow","whileloopflow":"#/components/schemas/WhileloopFlow","branchone":"#/components/schemas/BranchOne","branchall":"#/components/schemas/BranchAll","identity":"#/components/schemas/Identity","aiagent":"#/components/schemas/AiAgent"}}},"RawScript":{"type":"object","description":"Inline script with code defined directly in the flow. Use 'bun' as default language if unspecified. The script receives arguments from input_transforms","properties":{"input_transforms":{"type":"object","description":"Map of parameter names to their values (static or JavaScript expressions). These become the script's input arguments","additionalProperties":{"$ref":"#/components/schemas/InputTransform"}},"content":{"type":"string","description":"The script source code. Should export a 'main' function"},"language":{"type":"string","description":"Programming language for this script","enum":["deno","bun","python3","go","bash","powershell","postgresql","mysql","bigquery","snowflake","mssql","oracledb","graphql","nativets","php","rust","ansible","csharp","nu","java","ruby","duckdb"]},"path":{"type":"string","description":"Optional path for saving this script"},"lock":{"type":"string","description":"Lock file content for dependencies"},"type":{"type":"string","enum":["rawscript"]},"tag":{"type":"string","description":"Worker group tag for execution routing"},"concurrent_limit":{"type":"number","description":"Maximum concurrent executions of this script"},"concurrency_time_window_s":{"type":"number","description":"Time window for concurrent_limit"},"custom_concurrency_key":{"type":"string","description":"Custom key for grouping concurrent executions"},"is_trigger":{"type":"boolean","description":"If true, this script is a trigger that can start the flow"},"assets":{"type":"array","description":"External resources this script accesses (S3 objects, resources, etc.)","items":{"type":"object","required":["path","kind"],"properties":{"path":{"type":"string","description":"Path to the asset"},"kind":{"type":"string","description":"Type of asset","enum":["s3object","resource","ducklake","datatable"]},"access_type":{"type":"string","nullable":true,"description":"Access level for this asset","enum":["r","w","rw"]},"alt_access_type":{"type":"string","nullable":true,"description":"Alternative access level","enum":["r","w","rw"]}}}}},"required":["type","content","language","input_transforms"]},"PathScript":{"type":"object","description":"Reference to an existing script by path. Use this when calling a previously saved script instead of writing inline code","properties":{"input_transforms":{"type":"object","description":"Map of parameter names to their values (static or JavaScript expressions). These become the script's input arguments","additionalProperties":{"$ref":"#/components/schemas/InputTransform"}},"path":{"type":"string","description":"Path to the script in the workspace (e.g., 'f/scripts/send_email')"},"hash":{"type":"string","description":"Optional specific version hash of the script to use"},"type":{"type":"string","enum":["script"]},"tag_override":{"type":"string","description":"Override the script's default worker group tag"},"is_trigger":{"type":"boolean","description":"If true, this script is a trigger that can start the flow"}},"required":["type","path","input_transforms"]},"PathFlow":{"type":"object","description":"Reference to an existing flow by path. Use this to call another flow as a subflow","properties":{"input_transforms":{"type":"object","description":"Map of parameter names to their values (static or JavaScript expressions). These become the subflow's input arguments","additionalProperties":{"$ref":"#/components/schemas/InputTransform"}},"path":{"type":"string","description":"Path to the flow in the workspace (e.g., 'f/flows/process_user')"},"type":{"type":"string","enum":["flow"]}},"required":["type","path","input_transforms"]},"ForloopFlow":{"type":"object","description":"Executes nested modules in a loop over an iterator. Inside the loop, use 'flow_input.iter.value' to access the current iteration value, and 'flow_input.iter.index' for the index. Supports parallel execution for better performance on I/O-bound operations","properties":{"modules":{"type":"array","description":"Steps to execute for each iteration. These can reference the iteration value via 'flow_input.iter.value'","items":{"$ref":"#/components/schemas/FlowModule"}},"iterator":{"description":"JavaScript expression that returns an array to iterate over. Can reference 'results.step_id' or 'flow_input'","$ref":"#/components/schemas/InputTransform"},"skip_failures":{"type":"boolean","description":"If true, iteration failures don't stop the loop. Failed iterations return null"},"type":{"type":"string","enum":["forloopflow"]},"parallel":{"type":"boolean","description":"If true, iterations run concurrently (faster for I/O-bound operations). Use with parallelism to control concurrency"},"parallelism":{"description":"Maximum number of concurrent iterations when parallel=true. Limits resource usage. Can be static number or expression","$ref":"#/components/schemas/InputTransform"},"squash":{"type":"boolean"}},"required":["modules","iterator","skip_failures","type"]},"WhileloopFlow":{"type":"object","description":"Executes nested modules repeatedly while a condition is true. The loop checks the condition after each iteration. Use stop_after_if on modules to control loop termination","properties":{"modules":{"type":"array","description":"Steps to execute in each iteration. Use stop_after_if to control when the loop ends","items":{"$ref":"#/components/schemas/FlowModule"}},"skip_failures":{"type":"boolean","description":"If true, iteration failures don't stop the loop. Failed iterations return null"},"type":{"type":"string","enum":["whileloopflow"]},"parallel":{"type":"boolean","description":"If true, iterations run concurrently (use with caution in while loops)"},"parallelism":{"description":"Maximum number of concurrent iterations when parallel=true","$ref":"#/components/schemas/InputTransform"},"squash":{"type":"boolean"}},"required":["modules","skip_failures","type"]},"BranchOne":{"type":"object","description":"Conditional branching where only the first matching branch executes. Branches are evaluated in order, and the first one with a true expression runs. If no branches match, the default branch executes","properties":{"branches":{"type":"array","description":"Array of branches to evaluate in order. The first branch with expr evaluating to true executes","items":{"type":"object","properties":{"summary":{"type":"string","description":"Short description of this branch condition"},"expr":{"type":"string","description":"JavaScript expression that returns boolean. Can use 'results.step_id' or 'flow_input'. First true expr wins"},"modules":{"type":"array","description":"Steps to execute if this branch's expr is true","items":{"$ref":"#/components/schemas/FlowModule"}}},"required":["modules","expr"]}},"default":{"type":"array","description":"Steps to execute if no branch expressions match","items":{"$ref":"#/components/schemas/FlowModule"}},"type":{"type":"string","enum":["branchone"]}},"required":["branches","default","type"]},"BranchAll":{"type":"object","description":"Parallel branching where all branches execute simultaneously. Unlike BranchOne, all branches run regardless of conditions. Useful for executing independent tasks concurrently","properties":{"branches":{"type":"array","description":"Array of branches that all execute (either in parallel or sequentially)","items":{"type":"object","properties":{"summary":{"type":"string","description":"Short description of this branch's purpose"},"skip_failure":{"type":"boolean","description":"If true, failure in this branch doesn't fail the entire flow"},"modules":{"type":"array","description":"Steps to execute in this branch","items":{"$ref":"#/components/schemas/FlowModule"}}},"required":["modules"]}},"type":{"type":"string","enum":["branchall"]},"parallel":{"type":"boolean","description":"If true, all branches execute concurrently. If false, they execute sequentially"}},"required":["branches","type"]},"AgentTool":{"type":"object","description":"A tool available to an AI agent. Can be a flow module or an external MCP (Model Context Protocol) tool","properties":{"id":{"type":"string","description":"Unique identifier for this tool. Cannot contain spaces - use underscores instead (e.g., 'get_user_data' not 'get user data')"},"summary":{"type":"string","description":"Short description of what this tool does (shown to the AI)"},"value":{"$ref":"#/components/schemas/ToolValue"}},"required":["id","value"]},"ToolValue":{"description":"The implementation of a tool. Can be a flow module (script/flow) or an MCP tool reference","oneOf":[{"$ref":"#/components/schemas/FlowModuleTool"},{"$ref":"#/components/schemas/McpToolValue"},{"$ref":"#/components/schemas/WebsearchToolValue"}],"discriminator":{"propertyName":"tool_type","mapping":{"flowmodule":"#/components/schemas/FlowModuleTool","mcp":"#/components/schemas/McpToolValue","websearch":"#/components/schemas/WebsearchToolValue"}}},"FlowModuleTool":{"description":"A tool implemented as a flow module (script, flow, etc.). The AI can call this like any other flow module","allOf":[{"type":"object","properties":{"tool_type":{"type":"string","enum":["flowmodule"]}},"required":["tool_type"]},{"$ref":"#/components/schemas/FlowModuleValue"}]},"WebsearchToolValue":{"type":"object","description":"A tool implemented as a websearch tool. The AI can call this like any other websearch tool","properties":{"tool_type":{"type":"string","enum":["websearch"]}},"required":["tool_type"]},"McpToolValue":{"type":"object","description":"Reference to an external MCP (Model Context Protocol) tool. The AI can call tools from MCP servers","properties":{"tool_type":{"type":"string","enum":["mcp"]},"resource_path":{"type":"string","description":"Path to the MCP resource/server configuration"},"include_tools":{"type":"array","description":"Whitelist of specific tools to include from this MCP server","items":{"type":"string"}},"exclude_tools":{"type":"array","description":"Blacklist of tools to exclude from this MCP server","items":{"type":"string"}}},"required":["tool_type","resource_path"]},"AiAgent":{"type":"object","description":"AI agent step that can use tools to accomplish tasks. The agent receives inputs and can call any of its configured tools to complete the task","properties":{"input_transforms":{"type":"object","description":"Input parameters for the AI agent mapped to their values","properties":{"provider":{"$ref":"#/components/schemas/ProviderTransform"},"output_type":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Output format type.\\nValid values: 'text' (default) - plain text response, 'image' - image generation\\n"},"user_message":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"The user's prompt/message to the AI agent. Supports variable interpolation with flow.input syntax."},"system_prompt":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"System instructions that guide the AI's behavior, persona, and response style. Optional."},"streaming":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Boolean. If true, stream the AI response incrementally.\\nStreaming events include: token_delta, tool_call, tool_call_arguments, tool_execution, tool_result\\n"},"memory":{"$ref":"#/components/schemas/MemoryTransform"},"output_schema":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"JSON Schema object defining structured output format. Used when you need the AI to return data in a specific shape.\\nSupports standard JSON Schema properties: type, properties, required, items, enum, pattern, minLength, maxLength, minimum, maximum, etc.\\nExample: { type: 'object', properties: { name: { type: 'string' }, age: { type: 'integer' } }, required: ['name'] }\\n"},"user_images":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Array of image references for vision-capable models.\\nFormat: Array<{ bucket: string, key: string }> - S3 object references\\nExample: [{ bucket: 'my-bucket', key: 'images/photo.jpg' }]\\n"},"max_completion_tokens":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Integer. Maximum number of tokens the AI will generate in its response.\\nRange: 1 to 4,294,967,295. Typical values: 256-4096 for most use cases.\\n"},"temperature":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Float. Controls randomness/creativity of responses.\\nRange: 0.0 to 2.0 (provider-dependent)\\n- 0.0 = deterministic, focused responses\\n- 0.7 = balanced (common default)\\n- 1.0+ = more creative/random\\n"}},"required":["provider","user_message","output_type"]},"tools":{"type":"array","description":"Array of tools the agent can use. The agent decides which tools to call based on the task","items":{"$ref":"#/components/schemas/AgentTool"}},"type":{"type":"string","enum":["aiagent"]},"parallel":{"type":"boolean","description":"If true, the agent can execute multiple tool calls in parallel"}},"required":["tools","type","input_transforms"]},"Identity":{"type":"object","description":"Pass-through module that returns its input unchanged. Useful for flow structure or as a placeholder","properties":{"type":{"type":"string","enum":["identity"]},"flow":{"type":"boolean","description":"If true, marks this as a flow identity (special handling)"}},"required":["type"]},"FlowStatus":{"type":"object","properties":{"step":{"type":"integer"},"modules":{"type":"array","items":{"$ref":"#/components/schemas/FlowStatusModule"}},"user_states":{"additionalProperties":true},"preprocessor_module":{"allOf":[{"$ref":"#/components/schemas/FlowStatusModule"}]},"failure_module":{"allOf":[{"$ref":"#/components/schemas/FlowStatusModule"},{"type":"object","properties":{"parent_module":{"type":"string"}}}]},"retry":{"type":"object","properties":{"fail_count":{"type":"integer"},"failed_jobs":{"type":"array","items":{"type":"string","format":"uuid"}}}}},"required":["step","modules","failure_module"]},"FlowStatusModule":{"type":"object","properties":{"type":{"type":"string","enum":["WaitingForPriorSteps","WaitingForEvents","WaitingForExecutor","InProgress","Success","Failure"]},"id":{"type":"string"},"job":{"type":"string","format":"uuid"},"count":{"type":"integer"},"progress":{"type":"integer"},"iterator":{"type":"object","properties":{"index":{"type":"integer"},"itered":{"type":"array","items":{}},"itered_len":{"type":"integer"},"args":{}}},"flow_jobs":{"type":"array","items":{"type":"string"}},"flow_jobs_success":{"type":"array","items":{"type":"boolean"}},"flow_jobs_duration":{"type":"object","properties":{"started_at":{"type":"array","items":{"type":"string"}},"duration_ms":{"type":"array","items":{"type":"integer"}}}},"branch_chosen":{"type":"object","properties":{"type":{"type":"string","enum":["branch","default"]},"branch":{"type":"integer"}},"required":["type"]},"branchall":{"type":"object","properties":{"branch":{"type":"integer"},"len":{"type":"integer"}},"required":["branch","len"]},"approvers":{"type":"array","items":{"type":"object","properties":{"resume_id":{"type":"integer"},"approver":{"type":"string"}},"required":["resume_id","approver"]}},"failed_retries":{"type":"array","items":{"type":"string","format":"uuid"}},"skipped":{"type":"boolean"},"agent_actions":{"type":"array","items":{"type":"object","oneOf":[{"type":"object","properties":{"job_id":{"type":"string","format":"uuid"},"function_name":{"type":"string"},"type":{"type":"string","enum":["tool_call"]},"module_id":{"type":"string"}},"required":["job_id","function_name","type","module_id"]},{"type":"object","properties":{"call_id":{"type":"string","format":"uuid"},"function_name":{"type":"string"},"resource_path":{"type":"string"},"type":{"type":"string","enum":["mcp_tool_call"]},"arguments":{"type":"object"}},"required":["call_id","function_name","resource_path","type"]},{"type":"object","properties":{"type":{"type":"string","enum":["web_search"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["message"]}},"required":["content","type"]}]}},"agent_actions_success":{"type":"array","items":{"type":"boolean"}}},"required":["type"]}}`,
|
|
75815
75916
|
"raw-app": `---
|
|
75816
75917
|
name: raw-app
|
|
75817
75918
|
description: MUST use when creating raw apps.
|
|
@@ -76406,7 +76507,7 @@ description: MUST use when using the CLI.
|
|
|
76406
76507
|
|
|
76407
76508
|
The Windmill CLI (\`wmill\`) provides commands for managing scripts, flows, apps, and other resources.
|
|
76408
76509
|
|
|
76409
|
-
Current version: 1.
|
|
76510
|
+
Current version: 1.642.0
|
|
76410
76511
|
|
|
76411
76512
|
## Global Options
|
|
76412
76513
|
|
|
@@ -76432,7 +76533,7 @@ app related commands
|
|
|
76432
76533
|
- \`--json\` - Output as JSON (for piping to jq)
|
|
76433
76534
|
- \`app get <path:string>\` - get an app's details
|
|
76434
76535
|
- \`--json\` - Output as JSON (for piping to jq)
|
|
76435
|
-
- \`app push <file_path:string> <remote_path:string>\` - push a local app
|
|
76536
|
+
- \`app push <file_path:string> <remote_path:string>\` - push a local app
|
|
76436
76537
|
- \`app dev [app_folder:string]\` - Start a development server for building apps with live reload and hot module replacement
|
|
76437
76538
|
- \`--port <port:number>\` - Port to run the dev server on (will find next available port if occupied)
|
|
76438
76539
|
- \`--host <host:string>\` - Host to bind the dev server to
|
|
@@ -76493,7 +76594,7 @@ flow related commands
|
|
|
76493
76594
|
- \`flow new <flow_path:string>\` - create a new empty flow
|
|
76494
76595
|
- \`--summary <summary:string>\` - flow summary
|
|
76495
76596
|
- \`--description <description:string>\` - flow description
|
|
76496
|
-
- \`flow bootstrap <flow_path:string>\` - create a new empty flow (alias for new
|
|
76597
|
+
- \`flow bootstrap <flow_path:string>\` - create a new empty flow (alias for new
|
|
76497
76598
|
- \`--summary <summary:string>\` - flow summary
|
|
76498
76599
|
- \`--description <description:string>\` - flow description
|
|
76499
76600
|
|
|
@@ -76511,7 +76612,10 @@ folder related commands
|
|
|
76511
76612
|
- \`folder get <name:string>\` - get a folder's details
|
|
76512
76613
|
- \`--json\` - Output as JSON (for piping to jq)
|
|
76513
76614
|
- \`folder new <name:string>\` - create a new folder locally
|
|
76514
|
-
-
|
|
76615
|
+
- \`--summary <summary:string>\` - folder summary
|
|
76616
|
+
- \`folder push <name:string>\` - push a local folder to the remote by name. This overrides any remote versions.
|
|
76617
|
+
- \`folder add-missing\` - create default folder.meta.yaml for all subdirectories of f/ that are missing one
|
|
76618
|
+
- \`-y, --yes\` - skip confirmation prompt
|
|
76515
76619
|
|
|
76516
76620
|
### gitsync-settings
|
|
76517
76621
|
|
|
@@ -76590,6 +76694,9 @@ sync local with a remote instance or the opposite (push or pull)
|
|
|
76590
76694
|
- \`--prefix <prefix:string>\` - Prefix of the local workspaces folders to push
|
|
76591
76695
|
- \`--prefix-settings\` - Store instance yamls inside prefixed folders when using --prefix and --folder-per-instance
|
|
76592
76696
|
- \`instance whoami\` - Display information about the currently logged-in user
|
|
76697
|
+
- \`instance get-config\` - Dump the current instance config (global settings + worker configs) as YAML
|
|
76698
|
+
- \`-o, --output-file <file:string>\` - Write YAML to a file instead of stdout
|
|
76699
|
+
- \`--instance <instance:string>\` - Name of the instance, override the active instance
|
|
76593
76700
|
|
|
76594
76701
|
### jobs
|
|
76595
76702
|
|
|
@@ -76607,6 +76714,17 @@ Pull completed and queued jobs from workspace
|
|
|
76607
76714
|
- \`jobs pull\`
|
|
76608
76715
|
- \`jobs push\`
|
|
76609
76716
|
|
|
76717
|
+
### lint
|
|
76718
|
+
|
|
76719
|
+
Validate Windmill flow, schedule, and trigger YAML files in a directory
|
|
76720
|
+
|
|
76721
|
+
**Arguments:** \`[directory:string]\`
|
|
76722
|
+
|
|
76723
|
+
**Options:**
|
|
76724
|
+
- \`--json\` - Output results in JSON format
|
|
76725
|
+
- \`--fail-on-warn\` - Exit with code 1 when warnings are emitted
|
|
76726
|
+
- \`--locks-required\` - Fail if scripts or flow inline scripts that need locks have no locks
|
|
76727
|
+
|
|
76610
76728
|
### queues
|
|
76611
76729
|
|
|
76612
76730
|
List all queues with their metrics
|
|
@@ -76680,10 +76798,10 @@ script related commands
|
|
|
76680
76798
|
- \`script list\` - list all scripts
|
|
76681
76799
|
- \`--show-archived\` - Enable archived scripts in output
|
|
76682
76800
|
- \`--json\` - Output as JSON (for piping to jq)
|
|
76801
|
+
- \`script push <path:file>\` - push a local script spec. This overrides any remote versions. Use the script file (.ts, .js, .py, .sh
|
|
76683
76802
|
- \`script get <path:file>\` - get a script's details
|
|
76684
76803
|
- \`--json\` - Output as JSON (for piping to jq)
|
|
76685
|
-
- \`script show <path:file>\` - show a script's content (alias for get
|
|
76686
|
-
- \`script push <path:file>\` - push a local script spec. This overrides any remote versions. Use the script file (.ts, .js, .py, .sh)
|
|
76804
|
+
- \`script show <path:file>\` - show a script's content (alias for get
|
|
76687
76805
|
- \`script run <path:file>\` - run a script by path
|
|
76688
76806
|
- \`-d --data <data:file>\` - Inputs specified as a JSON string or a file using @<filename> or stdin using @-.
|
|
76689
76807
|
- \`-s --silent\` - Do not output anything other then the final output. Useful for scripting.
|
|
@@ -76693,10 +76811,10 @@ script related commands
|
|
|
76693
76811
|
- \`script new <path:file> <language:string>\` - create a new script
|
|
76694
76812
|
- \`--summary <summary:string>\` - script summary
|
|
76695
76813
|
- \`--description <description:string>\` - script description
|
|
76696
|
-
- \`script bootstrap <path:file> <language:string>\` - create a new script (alias for new
|
|
76814
|
+
- \`script bootstrap <path:file> <language:string>\` - create a new script (alias for new
|
|
76697
76815
|
- \`--summary <summary:string>\` - script summary
|
|
76698
76816
|
- \`--description <description:string>\` - script description
|
|
76699
|
-
- \`script generate-metadata [script:file]\` - re-generate the metadata file updating the lock and the script schema (for flows, use \`wmill flow generate-locks\`
|
|
76817
|
+
- \`script generate-metadata [script:file]\` - re-generate the metadata file updating the lock and the script schema (for flows, use \`wmill flow generate-locks\`
|
|
76700
76818
|
- \`--yes\` - Skip confirmation prompt
|
|
76701
76819
|
- \`--dry-run\` - Perform a dry run without making changes
|
|
76702
76820
|
- \`--lock-only\` - re-generate only the lock
|
|
@@ -76769,6 +76887,8 @@ sync local with a remote workspaces or the opposite (push or pull)
|
|
|
76769
76887
|
- \`--parallel <number>\` - Number of changes to process in parallel
|
|
76770
76888
|
- \`--repository <repo:string>\` - Specify repository path (e.g., u/user/repo) when multiple repositories exist
|
|
76771
76889
|
- \`--branch <branch:string>\` - Override the current git branch (works even outside a git repository)
|
|
76890
|
+
- \`--lint\` - Run lint validation before pushing
|
|
76891
|
+
- \`--locks-required\` - Fail if scripts or flow inline scripts that need locks have no locks
|
|
76772
76892
|
|
|
76773
76893
|
### trigger
|
|
76774
76894
|
|
|
@@ -76783,7 +76903,7 @@ trigger related commands
|
|
|
76783
76903
|
- \`--json\` - Output as JSON (for piping to jq)
|
|
76784
76904
|
- \`trigger get <path:string>\` - get a trigger's details
|
|
76785
76905
|
- \`--json\` - Output as JSON (for piping to jq)
|
|
76786
|
-
- \`--kind <kind:string>\` - Trigger kind (http, websocket, kafka, nats, postgres, mqtt, sqs, gcp, email)
|
|
76906
|
+
- \`--kind <kind:string>\` - Trigger kind (http, websocket, kafka, nats, postgres, mqtt, sqs, gcp, email). Recommended for faster lookup
|
|
76787
76907
|
- \`trigger new <path:string>\` - create a new trigger locally
|
|
76788
76908
|
- \`--kind <kind:string>\` - Trigger kind (required: http, websocket, kafka, nats, postgres, mqtt, sqs, gcp, email)
|
|
76789
76909
|
- \`trigger push <file_path:string> <remote_path:string>\` - push a local trigger spec. This overrides any remote versions.
|
|
@@ -76865,7 +76985,8 @@ workspace related commands
|
|
|
76865
76985
|
- \`--create-username <username:string>\` - Specify your own username in the newly created workspace. Ignored if --create is not specified, the workspace already exists or automatic username creation is enabled on the instance.
|
|
76866
76986
|
- \`workspace remove <workspace_name:string>\` - Remove a workspace
|
|
76867
76987
|
- \`workspace whoami\` - Show the currently active user
|
|
76868
|
-
- \`workspace list\` - List
|
|
76988
|
+
- \`workspace list\` - List local workspace profiles
|
|
76989
|
+
- \`workspace list-remote\` - List workspaces on the remote server that you have access to
|
|
76869
76990
|
- \`workspace bind\` - Bind the current Git branch to the active workspace
|
|
76870
76991
|
- \`--branch <branch:string>\` - Specify branch (defaults to current)
|
|
76871
76992
|
- \`workspace unbind\` - Remove workspace binding from the current Git branch
|
|
@@ -77116,6 +77237,14 @@ properties:
|
|
|
77116
77237
|
items:
|
|
77117
77238
|
type: string
|
|
77118
77239
|
description: Array of Kafka topic names to subscribe to
|
|
77240
|
+
filters:
|
|
77241
|
+
type: array
|
|
77242
|
+
items:
|
|
77243
|
+
type: object
|
|
77244
|
+
properties:
|
|
77245
|
+
key:
|
|
77246
|
+
type: string
|
|
77247
|
+
value: {}
|
|
77119
77248
|
error_handler_path:
|
|
77120
77249
|
type: string
|
|
77121
77250
|
description: Path to a script or flow to run when the triggered job fails
|
|
@@ -77163,6 +77292,7 @@ required:
|
|
|
77163
77292
|
- kafka_resource_path
|
|
77164
77293
|
- group_id
|
|
77165
77294
|
- topics
|
|
77295
|
+
- filters
|
|
77166
77296
|
`,
|
|
77167
77297
|
mqtt_trigger: `type: object
|
|
77168
77298
|
properties:
|
|
@@ -78105,7 +78235,7 @@ var jobs_default = command28;
|
|
|
78105
78235
|
|
|
78106
78236
|
// src/main.ts
|
|
78107
78237
|
await init_context();
|
|
78108
|
-
var VERSION = "1.
|
|
78238
|
+
var VERSION = "1.645.0";
|
|
78109
78239
|
var command29 = new Command().name("wmill").action(() => info(`Welcome to Windmill CLI ${VERSION}. Use -h for help.`)).description("Windmill CLI").globalOption("--workspace <workspace:string>", "Specify the target workspace. This overrides the default workspace.").globalOption("--debug --verbose", "Show debug/verbose logs").globalOption("--show-diffs", "Show diff informations when syncing (may show sensitive informations)").globalOption("--token <token:string>", "Specify an API token. This will override any stored token.").globalOption("--base-url <baseUrl:string>", "Specify the base URL of the API. If used, --token and --workspace are required and no local remote/workspace already set will be used.").globalOption("--config-dir <configDir:string>", "Specify a custom config directory. Overrides WMILL_CONFIG_DIR environment variable and default ~/.config location.").env("HEADERS <headers:string>", `Specify headers to use for all requests. e.g: "HEADERS='h1: v1, h2: v2'"`).version(VERSION).versionOption(false).command("init", init_default).command("app", app_default).command("flow", flow_default).command("script", script_default).command("workspace", workspace_default).command("resource", resource_default).command("resource-type", resource_type_default).command("user", user_default).command("variable", variable_default).command("hub", hub_default).command("folder", folder_default).command("schedule", schedule_default).command("trigger", trigger_default).command("dev", dev_default2).command("sync", sync_default).command("lint", lint_default).command("gitsync-settings", gitsync_settings_default).command("instance", instance_default).command("worker-groups", worker_groups_default).command("workers", workers_default).command("queues", queues_default).command("dependencies", dependencies_default).command("jobs", jobs_default).command("version --version", "Show version information").action(async (opts) => {
|
|
78110
78240
|
console.log("CLI version: " + VERSION);
|
|
78111
78241
|
try {
|