@conductor-oss/conductor-skills 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/.claude-plugin/marketplace.json +20 -0
  2. package/.claude-plugin/plugin.json +13 -0
  3. package/LICENSE.txt +176 -0
  4. package/README.md +352 -0
  5. package/VERSION +1 -0
  6. package/bin/conductor-skills.js +135 -0
  7. package/commands/conductor-optimize.md +18 -0
  8. package/commands/conductor-scaffold-worker.md +19 -0
  9. package/commands/conductor-setup.md +15 -0
  10. package/commands/conductor.md +15 -0
  11. package/install.ps1 +677 -0
  12. package/install.sh +855 -0
  13. package/package.json +50 -0
  14. package/skills/conductor/SKILL.md +151 -0
  15. package/skills/conductor/examples/ai-agent-loop.md +119 -0
  16. package/skills/conductor/examples/ai-agent-mcp.md +129 -0
  17. package/skills/conductor/examples/create-and-run-workflow.md +50 -0
  18. package/skills/conductor/examples/do-while-loop.md +72 -0
  19. package/skills/conductor/examples/fork-join.md +52 -0
  20. package/skills/conductor/examples/llm-chat.md +61 -0
  21. package/skills/conductor/examples/llm-rag.md +115 -0
  22. package/skills/conductor/examples/monitor-and-retry.md +54 -0
  23. package/skills/conductor/examples/review-workflow.md +67 -0
  24. package/skills/conductor/examples/signal-wait-task.md +36 -0
  25. package/skills/conductor/examples/sub-workflow.md +52 -0
  26. package/skills/conductor/examples/workflows/ai-agent-loop.json +88 -0
  27. package/skills/conductor/examples/workflows/ai-agent-mcp.json +69 -0
  28. package/skills/conductor/examples/workflows/child-normalize.json +21 -0
  29. package/skills/conductor/examples/workflows/do-while-loop.json +35 -0
  30. package/skills/conductor/examples/workflows/fork-join.json +61 -0
  31. package/skills/conductor/examples/workflows/llm-chat.json +28 -0
  32. package/skills/conductor/examples/workflows/llm-rag.json +49 -0
  33. package/skills/conductor/examples/workflows/parent-pipeline.json +35 -0
  34. package/skills/conductor/examples/workflows/weather-notification.json +42 -0
  35. package/skills/conductor/references/api-reference.md +111 -0
  36. package/skills/conductor/references/cli-index.md +92 -0
  37. package/skills/conductor/references/fallback-cli.md +36 -0
  38. package/skills/conductor/references/optimization.md +148 -0
  39. package/skills/conductor/references/orkes.md +57 -0
  40. package/skills/conductor/references/schedules.md +81 -0
  41. package/skills/conductor/references/setup.md +126 -0
  42. package/skills/conductor/references/troubleshooting.md +35 -0
  43. package/skills/conductor/references/visualization.md +49 -0
  44. package/skills/conductor/references/workers.md +227 -0
  45. package/skills/conductor/references/workflow-definition.md +672 -0
  46. package/skills/conductor/scripts/conductor_api.py +396 -0
@@ -0,0 +1,672 @@
1
+ # Conductor Workflow Definition Reference
2
+
3
+ ## Workflow definition schema
4
+
5
+ | Field | Type | Required | Description |
6
+ |-------|------|----------|-------------|
7
+ | `name` | string | yes | Workflow name (unique identifier) |
8
+ | `description` | string | no | Human-readable description |
9
+ | `version` | integer | no | Version number (default: 1) |
10
+ | `tasks` | array | yes | Ordered list of task definitions |
11
+ | `inputParameters` | array | no | Expected input parameter names |
12
+ | `outputParameters` | object | no | Mapping of output keys to expressions |
13
+ | `schemaVersion` | integer | no | Schema version (use 2) |
14
+ | `restartable` | boolean | no | Whether workflow can be restarted (default: true) |
15
+ | `ownerEmail` | string | no | Owner email for notifications |
16
+ | `timeoutPolicy` | string | no | `ALERT_ONLY` or `TIME_OUT_WF` |
17
+ | `timeoutSeconds` | long | no | Workflow timeout (0 = no timeout) |
18
+ | `failureWorkflow` | string | no | Workflow to run on failure |
19
+ | `variables` | object | no | Workflow-level variables |
20
+
21
+ ## Task definition in workflow
22
+
23
+ | Field | Type | Required | Description |
24
+ |-------|------|----------|-------------|
25
+ | `name` | string | yes | Task name (must match task definition for SIMPLE tasks) |
26
+ | `taskReferenceName` | string | yes | **Must be unique** across the entire workflow definition |
27
+ | `type` | string | yes | Task type (see below) |
28
+ | `inputParameters` | object | no | Input mapping using `${...}` expressions |
29
+ | `optional` | boolean | no | If true, failure won't fail the workflow |
30
+ | `startDelay` | integer | no | Delay in seconds before starting |
31
+ | `asyncComplete` | boolean | no | If true, task completes via external signal |
32
+
33
+ ## Input expressions
34
+
35
+ Reference workflow input, task output, or variables:
36
+
37
+ - `${workflow.input.paramName}` — workflow input
38
+ - `${taskRefName.output.fieldName}` — output from a prior task
39
+ - `${workflow.variables.varName}` — workflow variable
40
+
41
+ ---
42
+
43
+ ## System task types
44
+
45
+ ### SIMPLE
46
+ Worker task polled and executed by external workers.
47
+ ```json
48
+ {"name": "my_task", "taskReferenceName": "my_task_ref", "type": "SIMPLE", "inputParameters": {"param1": "${workflow.input.data}"}}
49
+ ```
50
+
51
+ ### HTTP
52
+ Make HTTP requests. Supports GET, POST, PUT, DELETE, OPTIONS, HEAD with headers, body, and timeouts.
53
+ ```json
54
+ {
55
+ "name": "http_call", "taskReferenceName": "call_api", "type": "HTTP",
56
+ "inputParameters": {
57
+ "http_request": {
58
+ "uri": "https://api.example.com/data",
59
+ "method": "POST",
60
+ "headers": {"Authorization": "Bearer ${workflow.input.token}"},
61
+ "body": {"key": "${workflow.input.value}"},
62
+ "accept": "application/json",
63
+ "contentType": "application/json",
64
+ "connectionTimeOut": 3000,
65
+ "readTimeOut": 3000
66
+ }
67
+ }
68
+ }
69
+ ```
70
+ **Input schema** (inside `http_request`):
71
+
72
+ | Parameter | Type | Required | Default | Description |
73
+ |-----------|------|----------|---------|-------------|
74
+ | `uri` | string | yes | — | Full URL to call |
75
+ | `method` | string | yes | — | HTTP method: `GET`, `POST`, `PUT`, `DELETE`, `OPTIONS`, `HEAD` |
76
+ | `headers` | map\<string, object\> | no | `{}` | Request headers as key-value pairs |
77
+ | `body` | object/string | no | — | Request body (auto-serialized to JSON) |
78
+ | `accept` | string | no | `"application/json"` | Accept header MIME type |
79
+ | `contentType` | string | no | `"application/json"` | Content-Type header MIME type |
80
+ | `connectionTimeOut` | integer | no | `3000` | Connection timeout in milliseconds |
81
+ | `readTimeOut` | integer | no | `3000` | Read timeout in milliseconds |
82
+ | `vipAddress` | string | no | — | Discovery-based address (Eureka) |
83
+ | `appName` | string | no | — | Application name for discovery |
84
+
85
+ **Output schema** — the task outputs a `response` object:
86
+ ```json
87
+ {
88
+ "response": {
89
+ "statusCode": 200,
90
+ "reasonPhrase": "OK",
91
+ "headers": {"Content-Type": ["application/json"]},
92
+ "body": { }
93
+ }
94
+ }
95
+ ```
96
+ - `response.statusCode` (int) — HTTP status code
97
+ - `response.reasonPhrase` (string) — HTTP reason phrase (e.g. `"OK"`, `"Not Found"`)
98
+ - `response.headers` (map) — response headers (each value is an array of strings)
99
+ - `response.body` (object/array/string/number) — parsed response body (auto-parsed as JSON if possible, otherwise raw string)
100
+
101
+ To reference in subsequent tasks: `${call_api.output.response.body.fieldName}`, `${call_api.output.response.statusCode}`.
102
+
103
+ ### JSON_JQ_TRANSFORM
104
+ Transform data using jq expressions. Powerful for reshaping, filtering, and aggregating JSON.
105
+ ```json
106
+ {
107
+ "name": "transform", "taskReferenceName": "jq_ref", "type": "JSON_JQ_TRANSFORM",
108
+ "inputParameters": {
109
+ "data": "${workflow.input.items}",
110
+ "queryExpression": "[.[] | {name: .name, id: .id}]"
111
+ }
112
+ }
113
+ ```
114
+ Common jq patterns:
115
+ - Filter: `[.[] | select(.status == "active")]`
116
+ - Map: `[.[] | {id: .id, label: .name}]`
117
+ - Aggregate: `{total: ([.[].amount] | add), count: length}`
118
+ - Flatten: `[.[][] | .field]`
119
+
120
+ > **Rule for all JavaScript-evaluated tasks (INLINE, DO_WHILE, SWITCH with `javascript` evaluator):**
121
+ > Every variable referenced as `$.varName` inside a script or condition **must** be declared as an `inputParameters` key on that task. The `$` object in the script is the task's resolved `inputParameters` map.
122
+
123
+ ### INLINE
124
+ Execute lightweight scripts (JavaScript via GraalVM).
125
+ ```json
126
+ {
127
+ "name": "inline_task", "taskReferenceName": "compute", "type": "INLINE",
128
+ "inputParameters": {
129
+ "evaluatorType": "graaljs",
130
+ "expression": "function e() { return $.value * 2; } e();",
131
+ "value": "${workflow.input.number}"
132
+ }
133
+ }
134
+ ```
135
+ **Important**: Every variable referenced as `$.varName` inside the script **must** be declared as an `inputParameters` key. For example, if the script uses `$.value` and `$.name`, both `value` and `name` must be present in `inputParameters`:
136
+ ```json
137
+ {
138
+ "name": "inline_task", "taskReferenceName": "compute", "type": "INLINE",
139
+ "inputParameters": {
140
+ "evaluatorType": "graaljs",
141
+ "expression": "function e() { return $.name + ' is ' + $.age; } e();",
142
+ "name": "${workflow.input.name}",
143
+ "age": "${workflow.input.age}"
144
+ }
145
+ }
146
+ ```
147
+ The `$` object inside the script is the task's resolved `inputParameters` map (excluding `evaluatorType` and `expression`).
148
+
149
+ ### SWITCH
150
+ Conditional branching based on a value or JavaScript expression.
151
+ ```json
152
+ {
153
+ "name": "switch_task", "taskReferenceName": "route", "type": "SWITCH",
154
+ "evaluatorType": "value-param",
155
+ "expression": "switchCaseValue",
156
+ "inputParameters": {"switchCaseValue": "${workflow.input.type}"},
157
+ "decisionCases": {
158
+ "typeA": [{"...task A...": ""}],
159
+ "typeB": [{"...task B...": ""}]
160
+ },
161
+ "defaultCase": [{"...default task...": ""}]
162
+ }
163
+ ```
164
+ When using `evaluatorType: "javascript"`, the same `$.varName` rule applies — all variables referenced in the expression must be declared in `inputParameters`:
165
+ ```json
166
+ {
167
+ "name": "switch_task", "taskReferenceName": "js_route", "type": "SWITCH",
168
+ "evaluatorType": "javascript",
169
+ "expression": "$.priority > 5 ? 'high' : 'low'",
170
+ "inputParameters": {"priority": "${workflow.input.priority}"},
171
+ "decisionCases": {
172
+ "high": [{"...urgent task...": ""}],
173
+ "low": [{"...normal task...": ""}]
174
+ },
175
+ "defaultCase": [{"...default task...": ""}]
176
+ }
177
+ ```
178
+
179
+ ### FORK_JOIN / JOIN
180
+ Execute tasks in parallel. Always pair FORK_JOIN with a JOIN task.
181
+ ```json
182
+ {"name": "fork", "taskReferenceName": "parallel", "type": "FORK_JOIN", "forkTasks": [[{"...task A...": ""}], [{"...task B...": ""}]]}
183
+ ```
184
+ ```json
185
+ {"name": "join", "taskReferenceName": "join_ref", "type": "JOIN", "joinOn": ["taskA_ref", "taskB_ref"]}
186
+ ```
187
+
188
+ ### DO_WHILE
189
+ Loop until a condition is met.
190
+ ```json
191
+ {
192
+ "name": "loop", "taskReferenceName": "loop_ref", "type": "DO_WHILE",
193
+ "loopCondition": "if ($.loop_ref['iteration'] < $.value) true; else false;",
194
+ "loopOver": [{"...task...": ""}],
195
+ "inputParameters": {
196
+ "value": "${workflow.input.count}",
197
+ "loop_ref": "${loop_ref.output}"
198
+ }
199
+ }
200
+ ```
201
+ **Important**: The `loopCondition` is evaluated as JavaScript. The same `$.varName` rule applies — every variable referenced as `$.varName` must be declared in `inputParameters`. Here, `$.loop_ref['iteration']` requires `loop_ref` to be declared.
202
+
203
+ The mapping `"loop_ref": "${loop_ref.output}"` looks like a typo — referencing a task before it has output — but **it is the canonical pattern**, not a mistake. Conductor resolves the reference lazily on each iteration, exposing the running `iteration` counter (and prior iterations' task outputs) inside the script. See [examples/do-while-loop.md](../examples/do-while-loop.md) for a runnable workflow.
204
+
205
+ ### WAIT
206
+ Pause execution until a signal, a duration elapses, or a specific date/time is reached. Use `conductor task signal` to resume a signal-based wait.
207
+
208
+ **Wait forever (signal mode)** — pauses until explicitly signaled via API or CLI:
209
+ ```json
210
+ {"name": "wait_task", "taskReferenceName": "wait_for_signal", "type": "WAIT", "inputParameters": {}}
211
+ ```
212
+
213
+ **Wait for a duration** — resumes automatically after the specified time:
214
+ ```json
215
+ {"name": "wait_task", "taskReferenceName": "wait_10m", "type": "WAIT", "inputParameters": {"duration": "10m"}}
216
+ ```
217
+ Duration format: `[Xd] [Xh] [Xm] [Xs]` — combine any units, case-insensitive, integers only (no decimals).
218
+ - Days: `days`, `day`, `d`
219
+ - Hours: `hours`, `hour`, `hrs`, `hr`, `h`
220
+ - Minutes: `minutes`, `minute`, `mins`, `min`, `m`
221
+ - Seconds: `seconds`, `second`, `secs`, `sec`, `s`
222
+ - Examples: `"5s"`, `"5m"`, `"2h"`, `"5d"`, `"5d 5h 5m 5s"`, `"30m 10s"`
223
+ - Invalid: `"5"` (no unit), `"5.0s"` (no decimals)
224
+
225
+ **Wait until a specific date/time** — resumes at the given timestamp:
226
+ ```json
227
+ {"name": "wait_task", "taskReferenceName": "wait_until", "type": "WAIT", "inputParameters": {"until": "2026-01-15 17:00"}}
228
+ ```
229
+ Until format (parsed in order): `yyyy-MM-dd HH:mm`, `yyyy-MM-dd HH:mm z`, or `yyyy-MM-dd`.
230
+ - With timezone: `"2026-01-15 17:00 GMT+04:00"`, `"2026-01-15 17:00 PST"`
231
+ - Without timezone: `"2026-01-15 17:00"` (uses server timezone)
232
+ - Date only: `"2026-01-15"` (midnight)
233
+ - Dynamic: `"until": "${workflow.input.scheduledTime}"`
234
+
235
+ Note: you cannot specify both `duration` and `until` — the task will fail with `FAILED_WITH_TERMINAL_ERROR`.
236
+
237
+ ### HUMAN
238
+ Wait for human input (similar to WAIT but designed for human-in-the-loop).
239
+ ```json
240
+ {"name": "human_task", "taskReferenceName": "approval", "type": "HUMAN"}
241
+ ```
242
+
243
+ ### SUB_WORKFLOW
244
+ Execute another workflow as a task. The parent workflow waits for the sub-workflow to complete.
245
+ ```json
246
+ {"name": "sub", "taskReferenceName": "sub_ref", "type": "SUB_WORKFLOW", "subWorkflowParam": {"name": "child_workflow", "version": 1}, "inputParameters": {"data": "${workflow.input.payload}"}}
247
+ ```
248
+
249
+ ### START_WORKFLOW
250
+ Start another workflow asynchronously (fire-and-forget). Unlike SUB_WORKFLOW, the parent does NOT wait — it immediately completes and outputs the child's workflowId.
251
+ ```json
252
+ {
253
+ "name": "start_wf", "taskReferenceName": "start_ref", "type": "START_WORKFLOW",
254
+ "inputParameters": {
255
+ "startWorkflow": {
256
+ "name": "child_workflow",
257
+ "version": 1,
258
+ "input": {"key": "${workflow.input.value}"},
259
+ "correlationId": "${workflow.correlationId}"
260
+ }
261
+ }
262
+ }
263
+ ```
264
+ **Outputs**: `workflowId` (the started workflow's ID).
265
+
266
+ ### DYNAMIC
267
+ Dynamically resolve the task type at runtime. The `dynamicTaskNameParam` input specifies which input parameter holds the actual task name to execute.
268
+ ```json
269
+ {
270
+ "name": "dynamic_task", "taskReferenceName": "dynamic_ref", "type": "DYNAMIC",
271
+ "dynamicTaskNameParam": "taskToExecute",
272
+ "inputParameters": {
273
+ "taskToExecute": "${workflow.input.taskName}",
274
+ "param1": "${workflow.input.data}"
275
+ }
276
+ }
277
+ ```
278
+
279
+ ### FORK_JOIN_DYNAMIC
280
+ Dynamically create parallel branches at runtime. A `dynamicForkTasksParam` input provides the list of tasks, and `dynamicForkTasksInputParamName` provides their inputs.
281
+ ```json
282
+ {
283
+ "name": "dynamic_fork", "taskReferenceName": "dfork_ref", "type": "FORK_JOIN_DYNAMIC",
284
+ "dynamicForkTasksParam": "dynamicTasks",
285
+ "dynamicForkTasksInputParamName": "dynamicTasksInput",
286
+ "inputParameters": {
287
+ "dynamicTasks": "${generate_tasks.output.tasks}",
288
+ "dynamicTasksInput": "${generate_tasks.output.inputs}"
289
+ }
290
+ }
291
+ ```
292
+ Always follow with a JOIN task. The `dynamicTasks` value is an array of task definitions, and `dynamicTasksInput` is a map of taskReferenceName to input objects.
293
+
294
+ ### EXCLUSIVE_JOIN
295
+ Like JOIN but completes as soon as any ONE of the specified tasks completes (instead of waiting for all). Used after FORK_JOIN for exclusive/race patterns.
296
+ ```json
297
+ {
298
+ "name": "exclusive_join", "taskReferenceName": "ejoin_ref", "type": "EXCLUSIVE_JOIN",
299
+ "inputParameters": {},
300
+ "joinOn": ["taskA_ref", "taskB_ref"],
301
+ "defaultExclusiveJoinTask": ["taskA_ref"]
302
+ }
303
+ ```
304
+
305
+ ### EVENT
306
+ Publish an event to a sink (e.g. SQS, Conductor internal).
307
+ ```json
308
+ {"name": "event", "taskReferenceName": "publish", "type": "EVENT", "sink": "conductor:event_name", "inputParameters": {"payload": "${workflow.input.data}"}}
309
+ ```
310
+
311
+ ### KAFKA_PUBLISH
312
+ Publish a message to a Kafka topic. Requires the Kafka module to be enabled.
313
+ ```json
314
+ {
315
+ "name": "kafka_task", "taskReferenceName": "kafka_ref", "type": "KAFKA_PUBLISH",
316
+ "inputParameters": {
317
+ "kafka_request": {
318
+ "topic": "my-topic",
319
+ "bootStrapServers": "kafka-broker:9092",
320
+ "value": {"data": "${workflow.input.payload}"},
321
+ "key": "${workflow.input.messageKey}",
322
+ "headers": {"source": "conductor"}
323
+ }
324
+ }
325
+ }
326
+ ```
327
+ **Inputs** (inside `kafka_request`): `topic` (required), `bootStrapServers` (required), `value` (required), `key`, `headers`.
328
+
329
+ ### SET_VARIABLE
330
+ Set workflow-level variables accessible by subsequent tasks.
331
+ ```json
332
+ {"name": "set_var", "taskReferenceName": "set_ref", "type": "SET_VARIABLE", "inputParameters": {"myVar": "${some_task.output.result}"}}
333
+ ```
334
+
335
+ ### TERMINATE
336
+ End the workflow immediately with a status and output.
337
+ ```json
338
+ {"name": "end", "taskReferenceName": "terminate_ref", "type": "TERMINATE", "inputParameters": {"terminationStatus": "COMPLETED", "workflowOutput": {"result": "${task_ref.output.data}"}}}
339
+ ```
340
+ `terminationStatus` can be `COMPLETED` or `FAILED`.
341
+
342
+ ### NOOP
343
+ No-operation task. Immediately completes with no side effects. Useful as a placeholder or default branch in SWITCH.
344
+ ```json
345
+ {"name": "noop", "taskReferenceName": "noop_ref", "type": "NOOP"}
346
+ ```
347
+
348
+
349
+ ---
350
+
351
+ ## AI task types
352
+
353
+ Conductor has built-in AI tasks supporting 12 LLM providers (OpenAI, Anthropic, Google Vertex AI, Azure OpenAI, AWS Bedrock, Mistral, Cohere, Grok, Perplexity, HuggingFace, Ollama, Stability AI) and vector databases (Pinecone, Postgres pgvector, MongoDB Atlas).
354
+
355
+ ### LLM_CHAT_COMPLETE
356
+ Multi-turn conversational AI with optional tool calling. Supports all LLM providers.
357
+ ```json
358
+ {
359
+ "name": "chat_task", "taskReferenceName": "chat", "type": "LLM_CHAT_COMPLETE",
360
+ "inputParameters": {
361
+ "llmProvider": "openai",
362
+ "model": "gpt-4o",
363
+ "messages": [
364
+ {"role": "system", "message": "You are a helpful assistant."},
365
+ {"role": "user", "message": "${workflow.input.question}"}
366
+ ],
367
+ "temperature": 0.7,
368
+ "maxTokens": 500
369
+ }
370
+ }
371
+ ```
372
+ **Inputs**: `llmProvider` (required), `model` (required), `messages` (required, array of `{role, message}`), `temperature`, `maxTokens`, `topP`, `stopSequences`, `tools` (for function calling).
373
+ **Outputs**: `result` (response text), `finishReason` (`STOP`, `TOOL_CALLS`, `LENGTH`), `tokenUsed`, `promptTokens`, `completionTokens`, `toolCalls`.
374
+
375
+ ### LLM_TEXT_COMPLETE
376
+ Single prompt text completion.
377
+ ```json
378
+ {
379
+ "name": "text_task", "taskReferenceName": "complete", "type": "LLM_TEXT_COMPLETE",
380
+ "inputParameters": {
381
+ "llmProvider": "anthropic",
382
+ "model": "claude-3-5-sonnet-20241022",
383
+ "prompt": "Summarize: ${workflow.input.text}",
384
+ "temperature": 0.3,
385
+ "maxTokens": 1000
386
+ }
387
+ }
388
+ ```
389
+ **Inputs**: `llmProvider`, `model`, `prompt` (all required), `temperature`, `maxTokens`.
390
+ **Outputs**: `result`, `tokenUsed`.
391
+
392
+ ### LLM_GENERATE_EMBEDDINGS
393
+ Convert text to vector embeddings.
394
+ ```json
395
+ {
396
+ "name": "embed_task", "taskReferenceName": "embed", "type": "LLM_GENERATE_EMBEDDINGS",
397
+ "inputParameters": {
398
+ "llmProvider": "openai",
399
+ "model": "text-embedding-3-small",
400
+ "text": "${workflow.input.document}"
401
+ }
402
+ }
403
+ ```
404
+ **Inputs**: `llmProvider`, `model`, `text` (all required).
405
+ **Outputs**: `result` (array of floats, e.g. 1536 dimensions for OpenAI).
406
+
407
+ ### GENERATE_IMAGE
408
+ Generate images from text prompts. Supports OpenAI (DALL-E-3), Vertex AI (Imagen), Azure OpenAI, Stability AI.
409
+ ```json
410
+ {
411
+ "name": "img_task", "taskReferenceName": "img", "type": "GENERATE_IMAGE",
412
+ "inputParameters": {
413
+ "llmProvider": "openai",
414
+ "model": "dall-e-3",
415
+ "prompt": "A futuristic cityscape at sunset",
416
+ "width": 1024,
417
+ "height": 1024,
418
+ "style": "vivid"
419
+ }
420
+ }
421
+ ```
422
+ **Inputs**: `llmProvider`, `model`, `prompt` (all required), `width`, `height`, `n`, `style`.
423
+ **Outputs**: `url` or `b64_json`.
424
+
425
+ ### GENERATE_AUDIO
426
+ Text-to-speech synthesis. Supports OpenAI TTS.
427
+ ```json
428
+ {
429
+ "name": "audio_task", "taskReferenceName": "audio", "type": "GENERATE_AUDIO",
430
+ "inputParameters": {
431
+ "llmProvider": "openai",
432
+ "model": "tts-1-hd",
433
+ "text": "${workflow.input.narration}",
434
+ "voice": "nova"
435
+ }
436
+ }
437
+ ```
438
+ **Inputs**: `llmProvider`, `model`, `text` (all required), `voice` (e.g. `alloy`, `echo`, `nova`).
439
+ **Outputs**: `media` (array with `location` URL and `mimeType`).
440
+
441
+ ### GENERATE_VIDEO
442
+ Generate videos from text/image prompts (async). Supports OpenAI Sora and Google Vertex AI Veo.
443
+ ```json
444
+ {
445
+ "name": "video_task", "taskReferenceName": "video", "type": "GENERATE_VIDEO",
446
+ "inputParameters": {
447
+ "llmProvider": "openai",
448
+ "model": "sora-2",
449
+ "prompt": "A drone flying over a mountain landscape",
450
+ "duration": 8,
451
+ "size": "1280x720"
452
+ }
453
+ }
454
+ ```
455
+ **Inputs**: `llmProvider`, `model`, `prompt` (all required), `duration`, `size`, `aspectRatio`, `resolution`, `style`, `n`, `inputImage` (for image-to-video), `negativePrompt`, `generateAudio` (Veo 3+).
456
+ **Outputs**: `media` (array with video URL and optional thumbnail), `jobId`, `status`, `pollCount`.
457
+
458
+ ### LLM_INDEX_TEXT
459
+ Store text with auto-generated embeddings in a vector database.
460
+ ```json
461
+ {
462
+ "name": "index_task", "taskReferenceName": "index", "type": "LLM_INDEX_TEXT",
463
+ "inputParameters": {
464
+ "vectorDB": "pinecone-prod",
465
+ "namespace": "docs",
466
+ "index": "knowledge-base",
467
+ "embeddingModelProvider": "openai",
468
+ "embeddingModel": "text-embedding-3-small",
469
+ "text": "${workflow.input.document}",
470
+ "docId": "${workflow.input.docId}",
471
+ "metadata": {"source": "upload", "category": "${workflow.input.category}"}
472
+ }
473
+ }
474
+ ```
475
+ **Inputs**: `vectorDB`, `namespace`, `index`, `embeddingModelProvider`, `embeddingModel`, `text` (all required), `docId`, `metadata`.
476
+
477
+ ### LLM_STORE_EMBEDDINGS
478
+ Store pre-computed embeddings in a vector database.
479
+ ```json
480
+ {
481
+ "name": "store_task", "taskReferenceName": "store", "type": "LLM_STORE_EMBEDDINGS",
482
+ "inputParameters": {
483
+ "vectorDB": "postgres-prod",
484
+ "namespace": "docs",
485
+ "index": "articles",
486
+ "embeddings": "${embed.output.result}",
487
+ "docId": "${workflow.input.docId}"
488
+ }
489
+ }
490
+ ```
491
+ **Inputs**: `vectorDB`, `namespace`, `index`, `embeddings` (all required), `docId`, `metadata`.
492
+
493
+ ### LLM_SEARCH_INDEX
494
+ Semantic search using a text query (auto-generates embeddings from the query).
495
+ ```json
496
+ {
497
+ "name": "search_task", "taskReferenceName": "search", "type": "LLM_SEARCH_INDEX",
498
+ "inputParameters": {
499
+ "vectorDB": "postgres-prod",
500
+ "namespace": "kb",
501
+ "index": "articles",
502
+ "embeddingModelProvider": "openai",
503
+ "embeddingModel": "text-embedding-3-small",
504
+ "query": "${workflow.input.question}",
505
+ "llmMaxResults": 5
506
+ }
507
+ }
508
+ ```
509
+ **Inputs**: `vectorDB`, `namespace`, `index`, `embeddingModelProvider`, `embeddingModel`, `query` (all required), `llmMaxResults`.
510
+
511
+ ### LLM_SEARCH_EMBEDDINGS
512
+ Search using a pre-computed embedding vector.
513
+ **Inputs**: `vectorDB`, `namespace`, `index`, `embeddings` (all required), `llmMaxResults`.
514
+
515
+ ### LLM_GET_EMBEDDINGS
516
+ Retrieve stored embeddings by document ID.
517
+ **Inputs**: `vectorDB`, `namespace`, `index`, `docId` (all required).
518
+ **Outputs**: `result` (array of floats).
519
+
520
+ ### LIST_MCP_TOOLS
521
+ List available tools from an MCP (Model Context Protocol) server.
522
+ ```json
523
+ {
524
+ "name": "list_tools", "taskReferenceName": "mcp_tools", "type": "LIST_MCP_TOOLS",
525
+ "inputParameters": {
526
+ "mcpServer": "http://localhost:3001/mcp",
527
+ "headers": {"Authorization": "Bearer ${workflow.input.mcpToken}"}
528
+ }
529
+ }
530
+ ```
531
+ **Inputs**: `mcpServer` (required), `headers`.
532
+ **Outputs**: `tools` (array of `{name, description, inputSchema}`).
533
+
534
+ ### CALL_MCP_TOOL
535
+ Call a specific tool on an MCP server. All extra inputParameters are passed as tool arguments.
536
+ ```json
537
+ {
538
+ "name": "call_tool", "taskReferenceName": "mcp_call", "type": "CALL_MCP_TOOL",
539
+ "inputParameters": {
540
+ "mcpServer": "http://localhost:3001/mcp",
541
+ "method": "get_weather",
542
+ "location": "New York",
543
+ "units": "fahrenheit"
544
+ }
545
+ }
546
+ ```
547
+ **Inputs**: `mcpServer`, `method` (both required), `headers`, plus any tool-specific parameters.
548
+ **Outputs**: `content` (array of result items), `isError`.
549
+
550
+ ---
551
+
552
+ ## Complete examples
553
+
554
+ ### Example 1: Data pipeline with HTTP, transform, and approval
555
+
556
+ ```json
557
+ {
558
+ "name": "data_pipeline",
559
+ "description": "Fetch, transform, and approve data",
560
+ "version": 1,
561
+ "schemaVersion": 2,
562
+ "inputParameters": ["apiUrl", "authToken"],
563
+ "tasks": [
564
+ {
565
+ "name": "fetch_data",
566
+ "taskReferenceName": "fetch",
567
+ "type": "HTTP",
568
+ "inputParameters": {
569
+ "http_request": {
570
+ "uri": "${workflow.input.apiUrl}",
571
+ "method": "GET",
572
+ "headers": {"Authorization": "Bearer ${workflow.input.authToken}"}
573
+ }
574
+ }
575
+ },
576
+ {
577
+ "name": "transform_data",
578
+ "taskReferenceName": "transform",
579
+ "type": "JSON_JQ_TRANSFORM",
580
+ "inputParameters": {
581
+ "data": "${fetch.output.response.body.items}",
582
+ "queryExpression": "[.[] | {id: .id, name: .name, status: .status}]"
583
+ }
584
+ },
585
+ {
586
+ "name": "wait_for_approval",
587
+ "taskReferenceName": "approval",
588
+ "type": "WAIT"
589
+ }
590
+ ],
591
+ "outputParameters": {
592
+ "transformedData": "${transform.output.result}",
593
+ "approvalStatus": "${approval.output.approved}"
594
+ }
595
+ }
596
+ ```
597
+
598
+ ### Example 2: RAG workflow (search + AI chat)
599
+
600
+ ```json
601
+ {
602
+ "name": "rag_workflow",
603
+ "description": "Retrieval-augmented generation: search knowledge base then answer",
604
+ "version": 1,
605
+ "schemaVersion": 2,
606
+ "inputParameters": ["question"],
607
+ "tasks": [
608
+ {
609
+ "name": "search_knowledge_base",
610
+ "taskReferenceName": "search",
611
+ "type": "LLM_SEARCH_INDEX",
612
+ "inputParameters": {
613
+ "vectorDB": "postgres-prod",
614
+ "namespace": "kb",
615
+ "index": "articles",
616
+ "embeddingModelProvider": "openai",
617
+ "embeddingModel": "text-embedding-3-small",
618
+ "query": "${workflow.input.question}",
619
+ "llmMaxResults": 3
620
+ }
621
+ },
622
+ {
623
+ "name": "generate_answer",
624
+ "taskReferenceName": "answer",
625
+ "type": "LLM_CHAT_COMPLETE",
626
+ "inputParameters": {
627
+ "llmProvider": "anthropic",
628
+ "model": "claude-3-5-sonnet-20241022",
629
+ "messages": [
630
+ {"role": "system", "message": "Answer based on the following context: ${search.output.result}"},
631
+ {"role": "user", "message": "${workflow.input.question}"}
632
+ ],
633
+ "temperature": 0.3
634
+ }
635
+ }
636
+ ],
637
+ "outputParameters": {
638
+ "answer": "${answer.output.result}",
639
+ "sources": "${search.output.result}"
640
+ }
641
+ }
642
+ ```
643
+
644
+ ### Example 3: MCP tool call
645
+
646
+ ```json
647
+ {
648
+ "name": "mcp_weather_workflow",
649
+ "description": "Call an MCP tool to get weather data",
650
+ "version": 1,
651
+ "schemaVersion": 2,
652
+ "tasks": [
653
+ {
654
+ "name": "get_weather",
655
+ "taskReferenceName": "weather",
656
+ "type": "CALL_MCP_TOOL",
657
+ "inputParameters": {
658
+ "mcpServer": "http://localhost:3001/mcp",
659
+ "method": "get_weather",
660
+ "location": "${workflow.input.city}",
661
+ "units": "fahrenheit"
662
+ }
663
+ }
664
+ ]
665
+ }
666
+ ```
667
+
668
+ ---
669
+
670
+ ## Visualization
671
+
672
+ To generate a Mermaid diagram of any workflow definition, see [visualization.md](visualization.md). It maps Conductor constructs (SWITCH, FORK_JOIN, DO_WHILE, WAIT, etc.) to flowchart syntax and covers the Conductor UI link format.