windmill-cli 1.745.0 → 1.746.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/esm/main.js +196 -22
- package/package.json +1 -1
package/esm/main.js
CHANGED
|
@@ -16784,7 +16784,7 @@ var init_OpenAPI = __esm(() => {
|
|
|
16784
16784
|
PASSWORD: undefined,
|
|
16785
16785
|
TOKEN: getEnv3("WM_TOKEN"),
|
|
16786
16786
|
USERNAME: undefined,
|
|
16787
|
-
VERSION: "1.
|
|
16787
|
+
VERSION: "1.746.0",
|
|
16788
16788
|
WITH_CREDENTIALS: true,
|
|
16789
16789
|
interceptors: {
|
|
16790
16790
|
request: new Interceptors,
|
|
@@ -17260,6 +17260,7 @@ __export(exports_services_gen, {
|
|
|
17260
17260
|
listWsSpecific: () => listWsSpecific,
|
|
17261
17261
|
listWorkspacesAsSuperAdmin: () => listWorkspacesAsSuperAdmin,
|
|
17262
17262
|
listWorkspaces: () => listWorkspaces,
|
|
17263
|
+
listWorkspaceMacros: () => listWorkspaceMacros,
|
|
17263
17264
|
listWorkspaceInvites: () => listWorkspaceInvites,
|
|
17264
17265
|
listWorkspaceDependencies: () => listWorkspaceDependencies,
|
|
17265
17266
|
listWorkers: () => listWorkers,
|
|
@@ -17371,6 +17372,7 @@ __export(exports_services_gen, {
|
|
|
17371
17372
|
listAssetsByUsage: () => listAssetsByUsage,
|
|
17372
17373
|
listAssets: () => listAssets,
|
|
17373
17374
|
listAssetSchemas: () => listAssetSchemas,
|
|
17375
|
+
listAssetPartitionsInRange: () => listAssetPartitionsInRange,
|
|
17374
17376
|
listAssetPartitions: () => listAssetPartitions,
|
|
17375
17377
|
listAssetDispatchEdges: () => listAssetDispatchEdges,
|
|
17376
17378
|
listApps: () => listApps,
|
|
@@ -17426,6 +17428,7 @@ __export(exports_services_gen, {
|
|
|
17426
17428
|
getTemplateScript: () => getTemplateScript,
|
|
17427
17429
|
getTeamsApprovalPayload: () => getTeamsApprovalPayload,
|
|
17428
17430
|
getSuspendedJobFlow: () => getSuspendedJobFlow,
|
|
17431
|
+
getStorageUsage: () => getStorageUsage,
|
|
17429
17432
|
getStats: () => getStats,
|
|
17430
17433
|
getStartedAtByIds: () => getStartedAtByIds,
|
|
17431
17434
|
getSqsTrigger: () => getSqsTrigger,
|
|
@@ -24929,6 +24932,17 @@ var backendVersion = () => {
|
|
|
24929
24932
|
storage: data3.storage
|
|
24930
24933
|
}
|
|
24931
24934
|
});
|
|
24935
|
+
}, getStorageUsage = (data3) => {
|
|
24936
|
+
return request(OpenAPI, {
|
|
24937
|
+
method: "GET",
|
|
24938
|
+
url: "/w/{workspace}/job_helpers/storage_usage",
|
|
24939
|
+
path: {
|
|
24940
|
+
workspace: data3.workspace
|
|
24941
|
+
},
|
|
24942
|
+
query: {
|
|
24943
|
+
refresh: data3.refresh
|
|
24944
|
+
}
|
|
24945
|
+
});
|
|
24932
24946
|
}, listStoredFiles = (data3) => {
|
|
24933
24947
|
return request(OpenAPI, {
|
|
24934
24948
|
method: "GET",
|
|
@@ -25389,6 +25403,14 @@ var backendVersion = () => {
|
|
|
25389
25403
|
folder: data3.folder
|
|
25390
25404
|
}
|
|
25391
25405
|
});
|
|
25406
|
+
}, listWorkspaceMacros = (data3) => {
|
|
25407
|
+
return request(OpenAPI, {
|
|
25408
|
+
method: "GET",
|
|
25409
|
+
url: "/w/{workspace}/assets/macros",
|
|
25410
|
+
path: {
|
|
25411
|
+
workspace: data3.workspace
|
|
25412
|
+
}
|
|
25413
|
+
});
|
|
25392
25414
|
}, listPipelineFolders = (data3) => {
|
|
25393
25415
|
return request(OpenAPI, {
|
|
25394
25416
|
method: "GET",
|
|
@@ -25408,6 +25430,19 @@ var backendVersion = () => {
|
|
|
25408
25430
|
path: data3.path
|
|
25409
25431
|
}
|
|
25410
25432
|
});
|
|
25433
|
+
}, listAssetPartitionsInRange = (data3) => {
|
|
25434
|
+
return request(OpenAPI, {
|
|
25435
|
+
method: "GET",
|
|
25436
|
+
url: "/w/{workspace}/assets/partitions_in_range",
|
|
25437
|
+
path: {
|
|
25438
|
+
workspace: data3.workspace
|
|
25439
|
+
},
|
|
25440
|
+
query: {
|
|
25441
|
+
path: data3.path,
|
|
25442
|
+
from: data3.from,
|
|
25443
|
+
to: data3.to
|
|
25444
|
+
}
|
|
25445
|
+
});
|
|
25411
25446
|
}, listAssetSchemas = (data3) => {
|
|
25412
25447
|
return request(OpenAPI, {
|
|
25413
25448
|
method: "GET",
|
|
@@ -25608,7 +25643,7 @@ var init_auth = __esm(async () => {
|
|
|
25608
25643
|
});
|
|
25609
25644
|
|
|
25610
25645
|
// src/core/constants.ts
|
|
25611
|
-
var WM_FORK_PREFIX = "wm-fork", VERSION = "1.
|
|
25646
|
+
var WM_FORK_PREFIX = "wm-fork", VERSION = "1.746.0";
|
|
25612
25647
|
|
|
25613
25648
|
// src/utils/git.ts
|
|
25614
25649
|
var exports_git = {};
|
|
@@ -84276,7 +84311,7 @@ Reference a specific resource using \`$res:\` prefix:
|
|
|
84276
84311
|
|
|
84277
84312
|
## OpenFlow Schema
|
|
84278
84313
|
|
|
84279
|
-
{"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"},"preserve_step_tags":{"type":"boolean","description":"If true and the flow runs on a custom worker tag, steps that declare their own non-empty tag run on it instead of inheriting the flow tag. Steps without their own tag still inherit the flow tag."},"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":"integer","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":"integer","description":"Maximum total time in seconds that a job can be debounced"},"max_total_debounces_amount":{"type":"integer","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"},"delete_after_secs":{"type":"integer","description":"If set, delete the flow job's args, result and logs after this many seconds following job completion"},"flow_env":{"type":"object","description":"Environment variables available to all steps. Values can be strings, JSON values, or special references: '$var:path' (workspace variable) or '$res:path' (resource).","additionalProperties":{}},"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"}},"groups":{"type":"array","description":"Semantic groups of modules for organizational purposes","items":{"$ref":"#/components/schemas/FlowGroup"}}},"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"]},"FlowGroup":{"type":"object","description":"A semantic group of flow modules for organizational purposes. Does not affect execution \\u2014 modules remain in their original position in the flow. Groups provide naming and collapsibility in the editor. Members are computed dynamically from all nodes on paths between start_id and end_id.","properties":{"summary":{"type":"string","description":"Display name for this group"},"note":{"type":"string","description":"Markdown note shown below the group header"},"autocollapse":{"type":"boolean","default":false,"description":"If true, this group is collapsed by default in the flow editor. UI hint only."},"start_id":{"type":"string","description":"ID of the first flow module in this group (topological entry point)"},"end_id":{"type":"string","description":"ID of the last flow module in this group (topological exit point)"},"color":{"type":"string","description":"Color for the group in the flow editor"}},"required":["start_id","end_id"]},"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","nullable":true,"description":"Custom error message when stopping with an error. Mutually exclusive with skip_if_stopped. If set to a non-empty string, the flow stops with this error. If empty string, a default error message is used. If null or omitted, no error is raised."},"error_include_result":{"type":"boolean","description":"When stopping with an error (error_message set), embed the stopping step's own result inside the raised error object (as error.result) instead of discarding it. The top-level result stays { error }. Defaults to false."}},"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_secs":{"type":"integer","description":"If set, delete the step's args, result and logs after this many seconds following job completion"},"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"},"debouncing":{"description":"Debounce configuration for this step (EE only)","type":"object","properties":{"debounce_delay_s":{"type":"integer","description":"Delay in seconds to debounce this step's executions across flow runs"},"debounce_key":{"type":"string","description":"Expression to group debounced executions. Supports $workspace and $args[name]. Default: $workspace/flow/<flow_path>-<step_id>"},"debounce_args_to_accumulate":{"type":"array","description":"Array-type arguments to accumulate across debounced executions","items":{"type":"string"}},"max_total_debouncing_time":{"type":"integer","description":"Maximum total time in seconds before forced execution"},"max_total_debounces_amount":{"type":"integer","description":"Maximum number of debounces before forced execution"}}}},"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","rlang","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","volume"]},"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_attachments":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Array of file references (images or PDFs) for the AI agent.\\nFormat: Array<{ bucket: string, key: string }> - S3 object references\\nExample: [{ bucket: 'my-bucket', key: 'documents/report.pdf' }]\\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"},"max_iterations":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Number. Limits how many times the agent can loop through reasoning and tool use.\\nRange: 1-1000.\\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"]},"tag":{"type":"string","description":"Worker group tag for execution routing. If not set, the AI agent step runs on the flow's tag (default \`flow\`)"},"omit_output_from_conversation":{"type":"boolean","default":false,"description":"If true, this AI agent step does not persist its assistant or tool messages to the flow conversation when chat mode is enabled."},"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"]}}`,
|
|
84314
|
+
{"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"},"preserve_step_tags":{"type":"boolean","description":"If true and the flow runs on a custom worker tag, steps that declare their own non-empty tag run on it instead of inheriting the flow tag. Steps without their own tag still inherit the flow tag."},"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":"integer","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":"integer","description":"Maximum total time in seconds that a job can be debounced"},"max_total_debounces_amount":{"type":"integer","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"},"delete_after_secs":{"type":"integer","description":"If set, delete the flow job's args, result and logs after this many seconds following job completion"},"flow_env":{"type":"object","description":"Environment variables available to all steps. Values can be strings, JSON values, or special references: '$var:path' (workspace variable) or '$res:path' (resource).","additionalProperties":{}},"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"}},"groups":{"type":"array","description":"Semantic groups of modules for organizational purposes","items":{"$ref":"#/components/schemas/FlowGroup"}}},"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"]},"FlowGroup":{"type":"object","description":"A semantic group of flow modules for organizational purposes. Does not affect execution \\u2014 modules remain in their original position in the flow. Groups provide naming and collapsibility in the editor. Members are computed dynamically from all nodes on paths between start_id and end_id.","properties":{"summary":{"type":"string","description":"Display name for this group"},"note":{"type":"string","description":"Markdown note shown below the group header"},"autocollapse":{"type":"boolean","default":false,"description":"If true, this group is collapsed by default in the flow editor. UI hint only."},"start_id":{"type":"string","description":"ID of the first flow module in this group (topological entry point)"},"end_id":{"type":"string","description":"ID of the last flow module in this group (topological exit point)"},"color":{"type":"string","description":"Color for the group in the flow editor"}},"required":["start_id","end_id"]},"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","nullable":true,"description":"Custom error message when stopping with an error. Mutually exclusive with skip_if_stopped. If set to a non-empty string, the flow stops with this error. If empty string, a default error message is used. If null or omitted, no error is raised."},"error_include_result":{"type":"boolean","description":"When stopping with an error (error_message set), embed the stopping step's own result inside the raised error object (as error.result) instead of discarding it. The top-level result stays { error }. Defaults to false."}},"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_secs":{"type":"integer","description":"If set, delete the step's args, result and logs after this many seconds following job completion"},"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"},"debouncing":{"description":"Debounce configuration for this step (EE only)","type":"object","properties":{"debounce_delay_s":{"type":"integer","description":"Delay in seconds to debounce this step's executions across flow runs"},"debounce_key":{"type":"string","description":"Expression to group debounced executions. Supports $workspace and $args[name]. Default: $workspace/flow/<flow_path>-<step_id>"},"debounce_args_to_accumulate":{"type":"array","description":"Array-type arguments to accumulate across debounced executions","items":{"type":"string"}},"max_total_debouncing_time":{"type":"integer","description":"Maximum total time in seconds before forced execution"},"max_total_debounces_amount":{"type":"integer","description":"Maximum number of debounces before forced execution"}}}},"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","azure_foundry","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","rlang","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","volume"]},"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_attachments":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Array of file references (images or PDFs) for the AI agent.\\nFormat: Array<{ bucket: string, key: string }> - S3 object references\\nExample: [{ bucket: 'my-bucket', key: 'documents/report.pdf' }]\\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"},"max_iterations":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Number. Limits how many times the agent can loop through reasoning and tool use.\\nRange: 1-1000.\\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"]},"tag":{"type":"string","description":"Worker group tag for execution routing. If not set, the AI agent step runs on the flow's tag (default \`flow\`)"},"omit_output_from_conversation":{"type":"boolean","default":false,"description":"If true, this AI agent step does not persist its assistant or tool messages to the flow conversation when chat mode is enabled."},"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"]}}`,
|
|
84280
84315
|
"raw-app": `---
|
|
84281
84316
|
name: raw-app
|
|
84282
84317
|
description: MUST use when creating raw apps.
|
|
@@ -85910,6 +85945,8 @@ inspect asset-driven pipelines (scripts marked \`// pipeline\`, wired by \`// on
|
|
|
85910
85945
|
- \`--json\` - Output the plan as JSON (for piping to jq).
|
|
85911
85946
|
- \`--local\` - Run the local working-tree scripts via preview (no deploy) instead of the deployed versions; the graph is built from local files.
|
|
85912
85947
|
- \`--upload <binding:string>\` - Bind an object to a data_upload/webhook entry point so it runs in the cascade, as SCRIPT[:PARAM]=SOURCE (SOURCE is a local file or an s3://key). Local files are uploaded to the workspace store; the S3Object param is inferred when the script has exactly one. Repeatable.
|
|
85948
|
+
- \`--arg <binding:string>\` - Pass a plain run arg to a script in the cascade, as SCRIPT:PARAM=VALUE (VALUE is parsed as JSON when possible, else taken as a string — e.g. daily_report:partition=2026-07-02). Repeatable.
|
|
85949
|
+
- \`--partition <value:string>\` - Partition value for \`// partitioned\` scripts in the run (e.g. 2026-06-30) — use it to backfill a past slice. With --local, time kinds (daily/hourly/weekly/monthly) default to the current UTC period when omitted; \`dynamic\` always needs it. Deployed runs without it defer to backend run-start resolution.
|
|
85913
85950
|
- \`pipeline docs <folder:string>\` - generate PIPELINE.md (+ AGENTS.md pointer) describing a folder's pipeline graph and datatable schemas, for an editor / agentic loop
|
|
85914
85951
|
- \`--local\` - Build the graph from local working-tree files instead of the deployed workspace.
|
|
85915
85952
|
- \`pipeline dev [folder:string]\` - Live-preview a data pipeline from local files: watch an \`f/<folder>\` of \`// pipeline\` scripts, push the working-tree graph to the dev page, and run the cascade via preview (no deploy).
|
|
@@ -95133,6 +95170,34 @@ function fallbackParse(content, language) {
|
|
|
95133
95170
|
}
|
|
95134
95171
|
return out;
|
|
95135
95172
|
}
|
|
95173
|
+
function recoverHeaderNativeTriggers(content, language) {
|
|
95174
|
+
const raw = commentPrefix(language);
|
|
95175
|
+
const p3 = raw.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
95176
|
+
const out = [];
|
|
95177
|
+
const seen = new Set;
|
|
95178
|
+
for (const line of content.split(`
|
|
95179
|
+
`)) {
|
|
95180
|
+
const trimmed = line.trim();
|
|
95181
|
+
if (trimmed === "")
|
|
95182
|
+
continue;
|
|
95183
|
+
if (!trimmed.startsWith(raw))
|
|
95184
|
+
break;
|
|
95185
|
+
const marker = line.match(new RegExp(`^\\s*${p3}\\s*on\\s+(\\S+)\\s*$`));
|
|
95186
|
+
if (!marker)
|
|
95187
|
+
continue;
|
|
95188
|
+
const kind = marker[1];
|
|
95189
|
+
if (!NATIVE_KINDS.has(kind) || seen.has(kind))
|
|
95190
|
+
continue;
|
|
95191
|
+
seen.add(kind);
|
|
95192
|
+
out.push(kind);
|
|
95193
|
+
}
|
|
95194
|
+
return out;
|
|
95195
|
+
}
|
|
95196
|
+
function normalizeRetry(retry) {
|
|
95197
|
+
if (!retry?.delay)
|
|
95198
|
+
return retry;
|
|
95199
|
+
return { ...retry, delay: retry.delay.replace(/^delay=/, "") };
|
|
95200
|
+
}
|
|
95136
95201
|
function volumeCommentPrefix(language) {
|
|
95137
95202
|
switch (language) {
|
|
95138
95203
|
case "python3":
|
|
@@ -95250,6 +95315,8 @@ async function buildLocalPipelineGraph(args) {
|
|
|
95250
95315
|
const out = await inferScriptAssets(s2.content, s2.language);
|
|
95251
95316
|
if (!out.in_pipeline)
|
|
95252
95317
|
continue;
|
|
95318
|
+
const retry = normalizeRetry(out.retry);
|
|
95319
|
+
const nativeTriggers = recoverHeaderNativeTriggers(s2.content, s2.language);
|
|
95253
95320
|
pipelineScripts.push(out.tag ? { ...s2, tag: out.tag } : s2);
|
|
95254
95321
|
const mat = out.materialize;
|
|
95255
95322
|
const materialize_strategy = mat && !mat.manual ? mat.append ? "append" : mat.unique_key ? "merge" : "replace" : undefined;
|
|
@@ -95260,7 +95327,7 @@ async function buildLocalPipelineGraph(args) {
|
|
|
95260
95327
|
...out.partition ? { partition_kind: out.partition.kind } : {},
|
|
95261
95328
|
...out.freshness ? { freshness: out.freshness.duration } : {},
|
|
95262
95329
|
...out.tag ? { tag: out.tag } : {},
|
|
95263
|
-
...
|
|
95330
|
+
...retry ? { retry } : {},
|
|
95264
95331
|
...out.data_tests && out.data_tests.length > 0 ? { data_tests: out.data_tests } : {},
|
|
95265
95332
|
...out.column_lineage && out.column_lineage.length > 0 ? { column_lineage: out.column_lineage } : {},
|
|
95266
95333
|
...mat ? { materialize_target: { kind: mat.target_kind, path: mat.target_path } } : {},
|
|
@@ -95292,6 +95359,7 @@ async function buildLocalPipelineGraph(args) {
|
|
|
95292
95359
|
});
|
|
95293
95360
|
}
|
|
95294
95361
|
}
|
|
95362
|
+
const existingNativeTriggers = new Set;
|
|
95295
95363
|
for (const t2 of out.triggers ?? []) {
|
|
95296
95364
|
if (t2.kind === "asset") {
|
|
95297
95365
|
const at = t2;
|
|
@@ -95307,6 +95375,7 @@ async function buildLocalPipelineGraph(args) {
|
|
|
95307
95375
|
runnable_path: s2.path
|
|
95308
95376
|
});
|
|
95309
95377
|
} else {
|
|
95378
|
+
existingNativeTriggers.add(t2.kind);
|
|
95310
95379
|
triggers.push({
|
|
95311
95380
|
trigger_kind: t2.kind,
|
|
95312
95381
|
runnable_kind: "script",
|
|
@@ -95314,6 +95383,15 @@ async function buildLocalPipelineGraph(args) {
|
|
|
95314
95383
|
});
|
|
95315
95384
|
}
|
|
95316
95385
|
}
|
|
95386
|
+
for (const kind of nativeTriggers) {
|
|
95387
|
+
if (existingNativeTriggers.has(kind))
|
|
95388
|
+
continue;
|
|
95389
|
+
triggers.push({
|
|
95390
|
+
trigger_kind: kind,
|
|
95391
|
+
runnable_kind: "script",
|
|
95392
|
+
runnable_path: s2.path
|
|
95393
|
+
});
|
|
95394
|
+
}
|
|
95317
95395
|
}
|
|
95318
95396
|
return {
|
|
95319
95397
|
graph: {
|
|
@@ -95647,8 +95725,6 @@ upstream assets.
|
|
|
95647
95725
|
return md;
|
|
95648
95726
|
}
|
|
95649
95727
|
async function generatePipelineDocs(opts, folder) {
|
|
95650
|
-
const workspace = await resolveWorkspace(opts);
|
|
95651
|
-
await requireLogin(opts);
|
|
95652
95728
|
const f3 = folder.replace(/^f\//, "").replace(/\/$/, "");
|
|
95653
95729
|
if (f3.split("/").includes("..")) {
|
|
95654
95730
|
error(colors.red(`Invalid folder '${folder}': '..' path segments are not allowed.`));
|
|
@@ -95656,6 +95732,9 @@ async function generatePipelineDocs(opts, folder) {
|
|
|
95656
95732
|
}
|
|
95657
95733
|
const root = workspaceRoot();
|
|
95658
95734
|
const merged = await mergeConfigWithConfigFile(opts);
|
|
95735
|
+
const workspace = opts.local ? undefined : await resolveWorkspace(opts);
|
|
95736
|
+
if (!opts.local)
|
|
95737
|
+
await requireLogin(opts);
|
|
95659
95738
|
const graph = opts.local ? (await buildLocalPipelineGraph({ root, folder: f3, defaultTs: merged.defaultTs })).graph : await fetchDeployedGraph(workspace.workspaceId, f3);
|
|
95660
95739
|
if (graph.runnables.length === 0) {
|
|
95661
95740
|
if (!opts.local) {
|
|
@@ -95671,10 +95750,16 @@ async function generatePipelineDocs(opts, folder) {
|
|
|
95671
95750
|
return;
|
|
95672
95751
|
}
|
|
95673
95752
|
let datatableSchemas = [];
|
|
95674
|
-
|
|
95675
|
-
|
|
95676
|
-
|
|
95677
|
-
|
|
95753
|
+
const hasExplicitWorkspace = !!opts.workspace || !!opts.baseUrl && !!opts.token || !!process.env["WM_WORKSPACE"] && !!process.env["WM_TOKEN"] && !!(process.env["BASE_INTERNAL_URL"] ?? process.env["BASE_URL"]);
|
|
95754
|
+
if (!opts.local || hasExplicitWorkspace) {
|
|
95755
|
+
try {
|
|
95756
|
+
const schemaWorkspace = workspace ?? await resolveWorkspace(opts);
|
|
95757
|
+
if (opts.local)
|
|
95758
|
+
await requireLogin(opts);
|
|
95759
|
+
datatableSchemas = await listDataTableSchemas({ workspace: schemaWorkspace.workspaceId });
|
|
95760
|
+
} catch (err) {
|
|
95761
|
+
warn(colors.yellow(`Could not fetch datatable schemas: ${err.message}`));
|
|
95762
|
+
}
|
|
95678
95763
|
}
|
|
95679
95764
|
const md = generatePipelineMarkdown(f3, graph, datatableSchemas, !!opts.local);
|
|
95680
95765
|
const folderDir = path25.join(root, "f", f3);
|
|
@@ -95725,9 +95810,28 @@ function parseUploadBinding(spec) {
|
|
|
95725
95810
|
}
|
|
95726
95811
|
return { scriptTok, param, source };
|
|
95727
95812
|
}
|
|
95813
|
+
function parseArgBinding(spec) {
|
|
95814
|
+
const eq = spec.indexOf("=");
|
|
95815
|
+
const left = eq < 0 ? "" : spec.slice(0, eq).trim();
|
|
95816
|
+
const raw = eq < 0 ? "" : spec.slice(eq + 1).trim();
|
|
95817
|
+
const colon = left.indexOf(":");
|
|
95818
|
+
const scriptTok = colon < 0 ? "" : left.slice(0, colon).trim();
|
|
95819
|
+
const param = colon < 0 ? "" : left.slice(colon + 1).trim();
|
|
95820
|
+
if (!scriptTok || !param) {
|
|
95821
|
+
throw new Error(`--arg '${spec}' must be <script>:<param>=<json-or-string>`);
|
|
95822
|
+
}
|
|
95823
|
+
let value;
|
|
95824
|
+
try {
|
|
95825
|
+
value = JSON.parse(raw);
|
|
95826
|
+
} catch {
|
|
95827
|
+
value = raw;
|
|
95828
|
+
}
|
|
95829
|
+
return { scriptTok, param, value };
|
|
95830
|
+
}
|
|
95728
95831
|
function s3ObjectParams(schema) {
|
|
95729
95832
|
const props = schema?.properties ?? {};
|
|
95730
|
-
|
|
95833
|
+
const isS3Object = (format6) => typeof format6 === "string" && format6.startsWith("resource-") && format6.slice("resource-".length).replaceAll("_", "").toLowerCase() === "s3object";
|
|
95834
|
+
return Object.keys(props).filter((k2) => isS3Object(props[k2]?.format));
|
|
95731
95835
|
}
|
|
95732
95836
|
function devUploadKey(scriptPath, param, source) {
|
|
95733
95837
|
return `wmilldev/pipeline/${scriptPath}/${param}/${basename10(source)}`;
|
|
@@ -96009,6 +96113,27 @@ async function resolveUploadArgs(bindings, scriptPath, workspaceId, local, local
|
|
|
96009
96113
|
}
|
|
96010
96114
|
return args;
|
|
96011
96115
|
}
|
|
96116
|
+
function defaultPartitionValue(kind, now = new Date) {
|
|
96117
|
+
const pad = (n2) => String(n2).padStart(2, "0");
|
|
96118
|
+
const date = `${now.getUTCFullYear()}-${pad(now.getUTCMonth() + 1)}-${pad(now.getUTCDate())}`;
|
|
96119
|
+
switch (kind) {
|
|
96120
|
+
case "hourly":
|
|
96121
|
+
return `${date}T${pad(now.getUTCHours())}`;
|
|
96122
|
+
case "weekly": {
|
|
96123
|
+
const d3 = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
|
|
96124
|
+
const dow = d3.getUTCDay() || 7;
|
|
96125
|
+
d3.setUTCDate(d3.getUTCDate() + 4 - dow);
|
|
96126
|
+
const week = Math.ceil(((d3.getTime() - Date.UTC(d3.getUTCFullYear(), 0, 1)) / 86400000 + 1) / 7);
|
|
96127
|
+
return `${d3.getUTCFullYear()}-W${pad(week)}`;
|
|
96128
|
+
}
|
|
96129
|
+
case "monthly":
|
|
96130
|
+
return date.slice(0, 7);
|
|
96131
|
+
case "daily":
|
|
96132
|
+
return date;
|
|
96133
|
+
default:
|
|
96134
|
+
return;
|
|
96135
|
+
}
|
|
96136
|
+
}
|
|
96012
96137
|
async function run5(opts, folder) {
|
|
96013
96138
|
if (opts.json)
|
|
96014
96139
|
setSilent(true);
|
|
@@ -96036,22 +96161,36 @@ async function run5(opts, folder) {
|
|
|
96036
96161
|
graph = await apiGet(`/w/${workspace.workspaceId}/assets/graph?folder=${encodeURIComponent(f3)}&asset_kinds=${ASSET_KINDS2}`);
|
|
96037
96162
|
await enrichDeployedNonAutorunTriggers(workspace.workspaceId, graph);
|
|
96038
96163
|
}
|
|
96039
|
-
const
|
|
96040
|
-
|
|
96041
|
-
for (const spec of opts.upload ?? []) {
|
|
96042
|
-
const binding = parseUploadBinding(spec);
|
|
96043
|
-
const id = resolveToken(graph, binding.scriptTok);
|
|
96164
|
+
const resolveScriptTokenOrThrow = (tok, flag) => {
|
|
96165
|
+
const id = resolveToken(graph, tok);
|
|
96044
96166
|
if (!id || !id.startsWith("script:")) {
|
|
96045
|
-
const matches = graph.runnables.filter((r2) => r2.usage_kind === "script" && (r2.path.split("/").pop() ?? r2.path) ===
|
|
96167
|
+
const matches = graph.runnables.filter((r2) => r2.usage_kind === "script" && (r2.path.split("/").pop() ?? r2.path) === tok);
|
|
96046
96168
|
if (matches.length > 1) {
|
|
96047
|
-
throw new Error(
|
|
96169
|
+
throw new Error(`${flag} '${tok}' matches multiple scripts (${matches.map((r2) => r2.path).sort().join(", ")}) — use the full path.`);
|
|
96048
96170
|
}
|
|
96049
|
-
throw new Error(
|
|
96171
|
+
throw new Error(`${flag} '${tok}' matched no script in f/${f3}.`);
|
|
96050
96172
|
}
|
|
96173
|
+
return id;
|
|
96174
|
+
};
|
|
96175
|
+
const boundBindingsByPath = new Map;
|
|
96176
|
+
const boundNodeIds = new Set;
|
|
96177
|
+
for (const spec of opts.upload ?? []) {
|
|
96178
|
+
const binding = parseUploadBinding(spec);
|
|
96179
|
+
const id = resolveScriptTokenOrThrow(binding.scriptTok, "--upload");
|
|
96051
96180
|
const p3 = scriptPathOf(id);
|
|
96052
96181
|
(boundBindingsByPath.get(p3) ?? boundBindingsByPath.set(p3, []).get(p3)).push(binding);
|
|
96053
96182
|
boundNodeIds.add(id);
|
|
96054
96183
|
}
|
|
96184
|
+
const plainArgsByPath = new Map;
|
|
96185
|
+
for (const spec of opts.arg ?? []) {
|
|
96186
|
+
const b2 = parseArgBinding(spec);
|
|
96187
|
+
const p3 = scriptPathOf(resolveScriptTokenOrThrow(b2.scriptTok, "--arg"));
|
|
96188
|
+
const merged = plainArgsByPath.get(p3) ?? plainArgsByPath.set(p3, {}).get(p3);
|
|
96189
|
+
if (Object.hasOwn(merged, b2.param)) {
|
|
96190
|
+
throw new Error(`--arg binds ${p3}:${b2.param} more than once.`);
|
|
96191
|
+
}
|
|
96192
|
+
merged[b2.param] = b2.value;
|
|
96193
|
+
}
|
|
96055
96194
|
const starts = new Set([...validStarts(graph), ...boundNodeIds]);
|
|
96056
96195
|
let runAll = false;
|
|
96057
96196
|
let start;
|
|
@@ -96125,12 +96264,33 @@ async function run5(opts, folder) {
|
|
|
96125
96264
|
if (cyclic.length > 0) {
|
|
96126
96265
|
warn(`Skipping ${cyclic.length} script(s) on a dependency cycle: ${cyclic.sort().join(", ")}`);
|
|
96127
96266
|
}
|
|
96267
|
+
const partitionKindByPath = new Map(graph.runnables.filter((r2) => r2.usage_kind === "script" && r2.partition_kind).map((r2) => [r2.path, r2.partition_kind]));
|
|
96268
|
+
const partitionValueFor = (nodePath2) => {
|
|
96269
|
+
const kind = partitionKindByPath.get(nodePath2);
|
|
96270
|
+
if (!kind)
|
|
96271
|
+
return;
|
|
96272
|
+
if (opts.partition)
|
|
96273
|
+
return opts.partition;
|
|
96274
|
+
if (!opts.local)
|
|
96275
|
+
return;
|
|
96276
|
+
return defaultPartitionValue(kind);
|
|
96277
|
+
};
|
|
96278
|
+
if (opts.local && !opts.partition) {
|
|
96279
|
+
const unresolvable = order.filter((p3) => partitionKindByPath.get(p3) === "dynamic");
|
|
96280
|
+
if (unresolvable.length > 0) {
|
|
96281
|
+
throw new Error(`dynamic \`// partitioned\` script(s) need an explicit partition for a local run: ${unresolvable.sort().join(", ")} — pass --partition <value>.`);
|
|
96282
|
+
}
|
|
96283
|
+
}
|
|
96128
96284
|
const orderSet = new Set(order);
|
|
96129
96285
|
const boundInOrder = [...boundBindingsByPath.keys()].filter((p3) => orderSet.has(p3)).sort();
|
|
96130
96286
|
for (const p3 of boundBindingsByPath.keys()) {
|
|
96131
96287
|
if (!orderSet.has(p3))
|
|
96132
96288
|
warn(`--upload for ${p3} is unused — it isn't in the run selection.`);
|
|
96133
96289
|
}
|
|
96290
|
+
for (const p3 of plainArgsByPath.keys()) {
|
|
96291
|
+
if (!orderSet.has(p3))
|
|
96292
|
+
warn(`--arg for ${p3} is unused — it isn't in the run selection.`);
|
|
96293
|
+
}
|
|
96134
96294
|
if (opts.json) {
|
|
96135
96295
|
console.log(JSON.stringify({
|
|
96136
96296
|
start: runAll ? null : scriptPathOf(start),
|
|
@@ -96150,7 +96310,15 @@ async function run5(opts, folder) {
|
|
|
96150
96310
|
if (opts.dryRun) {
|
|
96151
96311
|
if (!opts.json) {
|
|
96152
96312
|
info(colors.bold(`Bounded run plan — ${order.length} script${order.length === 1 ? "" : "s"}`) + colors.dim(runAll ? ` (whole pipeline)` : ` (from ${shortName(scriptPathOf(start))})`));
|
|
96153
|
-
order.forEach((p3, i) =>
|
|
96313
|
+
order.forEach((p3, i) => {
|
|
96314
|
+
const pv = partitionValueFor(p3);
|
|
96315
|
+
const marks = [
|
|
96316
|
+
boundBindingsByPath.has(p3) ? " (← --upload)" : "",
|
|
96317
|
+
plainArgsByPath.has(p3) ? " (← --arg)" : "",
|
|
96318
|
+
pv ? ` (partition=${pv})` : partitionKindByPath.has(p3) ? " (partition resolved by backend at run start)" : ""
|
|
96319
|
+
].join("");
|
|
96320
|
+
info(` ${i + 1}. ${p3}${marks ? colors.dim(marks) : ""}`);
|
|
96321
|
+
});
|
|
96154
96322
|
}
|
|
96155
96323
|
return;
|
|
96156
96324
|
}
|
|
@@ -96161,7 +96329,13 @@ async function run5(opts, folder) {
|
|
|
96161
96329
|
for (const nodePath2 of order) {
|
|
96162
96330
|
if (!opts.json)
|
|
96163
96331
|
info(colors.gray(`▶ running ${nodePath2}…`));
|
|
96164
|
-
const
|
|
96332
|
+
const partitionValue = partitionValueFor(nodePath2);
|
|
96333
|
+
const nodeArgs = {
|
|
96334
|
+
...partitionValue !== undefined ? { partition: partitionValue } : {},
|
|
96335
|
+
...uploadArgs.get(nodePath2) ?? {},
|
|
96336
|
+
...plainArgsByPath.get(nodePath2) ?? {},
|
|
96337
|
+
_wmill_skip_asset_dispatch: true
|
|
96338
|
+
};
|
|
96165
96339
|
let id;
|
|
96166
96340
|
if (opts.local) {
|
|
96167
96341
|
const ls = localScripts.get(nodePath2);
|
|
@@ -96197,7 +96371,7 @@ async function run5(opts, folder) {
|
|
|
96197
96371
|
info(colors.green.bold(`Bounded run complete — ${order.length} script(s) succeeded.`));
|
|
96198
96372
|
}
|
|
96199
96373
|
}
|
|
96200
|
-
var command42 = new Command().description("inspect asset-driven pipelines (scripts marked `// pipeline`, wired by `// on <spec>` annotations)").command("list", "list pipeline folders in the workspace").option("--json", "Output as JSON (for piping to jq)").action(list18).command("show", "render a pipeline folder's DAG (sources, lineage, subscriptions) in the terminal").arguments("<folder:string>").option("--json", "Output the raw asset graph as JSON").option("--local", "Build the graph from local working-tree files (// pipeline scripts) instead of the deployed workspace — no deploy needed.").action(show2).command("run", "run a bounded cascade: from a schedule/manual root, fan downstream up to the --to end node(s)").arguments("<folder:string>").option("--from <script:string>", "Start script (short name or path). Defaults to the folder's sole schedule/manual root.").option("--to <node:string>", "End node(s) to stop at — script names/paths or asset URIs (e.g. datatable://main/staged). Repeatable or comma-separated. Omit to run the full downstream.", { collect: true }).option("--dry-run", "Print the topological run plan without executing.").option("--json", "Output the plan as JSON (for piping to jq).").option("--local", "Run the local working-tree scripts via preview (no deploy) instead of the deployed versions; the graph is built from local files.").option("--upload <binding:string>", "Bind an object to a data_upload/webhook entry point so it runs in the cascade, as SCRIPT[:PARAM]=SOURCE (SOURCE is a local file or an s3://key). Local files are uploaded to the workspace store; the S3Object param is inferred when the script has exactly one. Repeatable.", { collect: true }).action(run5).command("docs", "generate PIPELINE.md (+ AGENTS.md pointer) describing a folder's pipeline graph and datatable schemas, for an editor / agentic loop").arguments("<folder:string>").option("--local", "Build the graph from local working-tree files instead of the deployed workspace.").action(generatePipelineDocs).command("dev", dev_default3);
|
|
96374
|
+
var command42 = new Command().description("inspect asset-driven pipelines (scripts marked `// pipeline`, wired by `// on <spec>` annotations)").command("list", "list pipeline folders in the workspace").option("--json", "Output as JSON (for piping to jq)").action(list18).command("show", "render a pipeline folder's DAG (sources, lineage, subscriptions) in the terminal").arguments("<folder:string>").option("--json", "Output the raw asset graph as JSON").option("--local", "Build the graph from local working-tree files (// pipeline scripts) instead of the deployed workspace — no deploy needed.").action(show2).command("run", "run a bounded cascade: from a schedule/manual root, fan downstream up to the --to end node(s)").arguments("<folder:string>").option("--from <script:string>", "Start script (short name or path). Defaults to the folder's sole schedule/manual root.").option("--to <node:string>", "End node(s) to stop at — script names/paths or asset URIs (e.g. datatable://main/staged). Repeatable or comma-separated. Omit to run the full downstream.", { collect: true }).option("--dry-run", "Print the topological run plan without executing.").option("--json", "Output the plan as JSON (for piping to jq).").option("--local", "Run the local working-tree scripts via preview (no deploy) instead of the deployed versions; the graph is built from local files.").option("--upload <binding:string>", "Bind an object to a data_upload/webhook entry point so it runs in the cascade, as SCRIPT[:PARAM]=SOURCE (SOURCE is a local file or an s3://key). Local files are uploaded to the workspace store; the S3Object param is inferred when the script has exactly one. Repeatable.", { collect: true }).option("--arg <binding:string>", "Pass a plain run arg to a script in the cascade, as SCRIPT:PARAM=VALUE (VALUE is parsed as JSON when possible, else taken as a string — e.g. daily_report:partition=2026-07-02). Repeatable.", { collect: true }).option("--partition <value:string>", "Partition value for `// partitioned` scripts in the run (e.g. 2026-06-30) — use it to backfill a past slice. With --local, time kinds (daily/hourly/weekly/monthly) default to the current UTC period when omitted; `dynamic` always needs it. Deployed runs without it defer to backend run-start resolution.").action(run5).command("docs", "generate PIPELINE.md (+ AGENTS.md pointer) describing a folder's pipeline graph and datatable schemas, for an editor / agentic loop").arguments("<folder:string>").option("--local", "Build the graph from local working-tree files instead of the deployed workspace.").action(generatePipelineDocs).command("dev", dev_default3);
|
|
96201
96375
|
var pipeline_default = command42;
|
|
96202
96376
|
|
|
96203
96377
|
// src/commands/ducklake/ducklake.ts
|