@unstable-dev/unmeshed-mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -0
- package/dist/auth.d.ts +6 -0
- package/dist/auth.js +11 -0
- package/dist/client.d.ts +46 -0
- package/dist/client.js +97 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.js +31 -0
- package/dist/get-docs.d.ts +8 -0
- package/dist/get-docs.js +64 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +35 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.js +203 -0
- package/knowledge/README.md +16 -0
- package/knowledge/SKILL.md +359 -0
- package/knowledge/assets/patterns.md +637 -0
- package/knowledge/execution/debugging-guide.md +18 -0
- package/knowledge/execution/process-run.schema.md +24 -0
- package/knowledge/execution/step-run.schema.md +21 -0
- package/knowledge/process-definition.schema.md +36 -0
- package/knowledge/references/integrations.md +914 -0
- package/knowledge/references/steps-knowledge.md +834 -0
- package/knowledge/step-definition.schema.md +140 -0
- package/knowledge/step-output-paths.md +45 -0
- package/knowledge/steps/DECISION_ENGINE.md +248 -0
- package/knowledge/steps/DEPENDSON.md +296 -0
- package/knowledge/steps/EXIT.md +220 -0
- package/knowledge/steps/FAIL.md +198 -0
- package/knowledge/steps/FLOW_GATEWAY.md +405 -0
- package/knowledge/steps/FOREACH.md +250 -0
- package/knowledge/steps/HTTP.md +183 -0
- package/knowledge/steps/JAVASCRIPT.md +192 -0
- package/knowledge/steps/JQ.md +189 -0
- package/knowledge/steps/LIST.md +279 -0
- package/knowledge/steps/NOOP.md +165 -0
- package/knowledge/steps/PARALLEL.md +366 -0
- package/knowledge/steps/PYTHON.md +206 -0
- package/knowledge/steps/SEND_RESPONSE.md +301 -0
- package/knowledge/steps/SQLITE.md +301 -0
- package/knowledge/steps/SUB_PROCESS.md +296 -0
- package/knowledge/steps/SWITCH.md +369 -0
- package/knowledge/steps/UPDATE_STEP.md +257 -0
- package/knowledge/steps/WAIT.md +218 -0
- package/knowledge/steps/WHILE.md +328 -0
- package/knowledge/steps/WORKER.md +233 -0
- package/knowledge/system-prompt.md +274 -0
- package/package.json +39 -0
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
# Parallel Step Schema
|
|
2
|
+
|
|
3
|
+
`PARALLEL` is a container step that runs multiple child step paths at the same
|
|
4
|
+
time. Use it when one path does not depend on another path's result and both can
|
|
5
|
+
progress independently.
|
|
6
|
+
|
|
7
|
+
Example use case: fetch search results from two external sources concurrently,
|
|
8
|
+
then merge both outputs in a later JavaScript step after the parallel children
|
|
9
|
+
complete.
|
|
10
|
+
|
|
11
|
+
Container steps can be nested. Use `LIST` children inside a `PARALLEL` step when
|
|
12
|
+
one parallel path needs to run multiple steps sequentially.
|
|
13
|
+
|
|
14
|
+
## Execution Semantics
|
|
15
|
+
|
|
16
|
+
Unmeshed parallel steps do not immediately abandon all work when one parallel
|
|
17
|
+
thread fails. The engine completes all parallel threads and then marks the
|
|
18
|
+
parallel step/process failed if failure rules require it. This avoids leaving
|
|
19
|
+
tasks hanging or partially complete.
|
|
20
|
+
|
|
21
|
+
## Definition Input Schema
|
|
22
|
+
|
|
23
|
+
The parallel paths are defined in `children`.
|
|
24
|
+
|
|
25
|
+
The example runtime input may include `failIfAnyBranchFails`:
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"failIfAnyBranchFails": false
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`children` contains the steps or branch containers to run concurrently:
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"type": "PARALLEL",
|
|
38
|
+
"ref": "parallel_1",
|
|
39
|
+
"children": [
|
|
40
|
+
{
|
|
41
|
+
"type": "HTTP",
|
|
42
|
+
"ref": "http_1"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"type": "HTTP",
|
|
46
|
+
"ref": "http_2"
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"input": {
|
|
50
|
+
"failIfAnyBranchFails": false
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Runtime Output Schema
|
|
56
|
+
|
|
57
|
+
The PARALLEL container's own step output is usually an empty object:
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Child steps produce their own outputs under their own refs. For example, HTTP
|
|
64
|
+
children inside a PARALLEL still expose:
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{
|
|
68
|
+
"response": {
|
|
69
|
+
"randomId": "abb5ca43-3835-4dae-8556-b72aa4d42e64",
|
|
70
|
+
"counter": 2
|
|
71
|
+
},
|
|
72
|
+
"statusCode": 200
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
In process run records, child steps are linked back to the PARALLEL by
|
|
77
|
+
`parentId` and `parentRef`.
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"ref": "http_1",
|
|
82
|
+
"parentRef": "parallel_1",
|
|
83
|
+
"type": "HTTP",
|
|
84
|
+
"status": "COMPLETED"
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Output Access Paths
|
|
89
|
+
|
|
90
|
+
Use:
|
|
91
|
+
- `steps.<child_ref>.output...` to access a child step's output directly.
|
|
92
|
+
- `steps.<http_child_ref>.output.response` for a native HTTP child response body.
|
|
93
|
+
- `steps.<javascript_child_ref>.output.result` for a JavaScript child result.
|
|
94
|
+
- `steps.<python_child_ref>.output.result` for a Python child result.
|
|
95
|
+
- `stepRecords[].parentRef` when debugging executed process data.
|
|
96
|
+
|
|
97
|
+
Do not use:
|
|
98
|
+
- `steps.<parallel_ref>.output.result`
|
|
99
|
+
- `steps.<parallel_ref>.output.response`
|
|
100
|
+
- `steps.<parallel_ref>.children.<child_ref>.output`
|
|
101
|
+
- `steps.<parallel_ref>.output.<child_ref>`
|
|
102
|
+
|
|
103
|
+
## Generation Rules
|
|
104
|
+
|
|
105
|
+
- Use uppercase step type: `"PARALLEL"`.
|
|
106
|
+
- Put independent child paths in `children`.
|
|
107
|
+
- Use `input: { "failIfAnyBranchFails": false }` when matching the observed example behavior.
|
|
108
|
+
- Children must be complete step definitions with the same required fields as top-level steps.
|
|
109
|
+
- Child `ref` values must be unique across the whole workflow, not only inside the PARALLEL.
|
|
110
|
+
- Use child `LIST` containers when a parallel branch requires multiple sequential steps.
|
|
111
|
+
- Do not put dependent steps directly as sibling children if one needs another child's output.
|
|
112
|
+
- Add a later merge/normalize step after PARALLEL if the workflow needs to combine child outputs.
|
|
113
|
+
- Do not invent a special PARALLEL result wrapper for child outputs.
|
|
114
|
+
- Later steps should reference child outputs by child refs directly.
|
|
115
|
+
|
|
116
|
+
## Debugging Rules
|
|
117
|
+
|
|
118
|
+
When debugging a PARALLEL:
|
|
119
|
+
- Check the PARALLEL step record status first.
|
|
120
|
+
- Inspect child step records whose `parentRef` equals the PARALLEL ref.
|
|
121
|
+
- Inspect all failed child records, not only the first one.
|
|
122
|
+
- Remember that Unmeshed completes all parallel children before failing the PARALLEL due to child failures.
|
|
123
|
+
- Do not stop at the PARALLEL step's own `output: {}`; inspect child outputs.
|
|
124
|
+
- If process-level output mirrors one child output, explain which child produced it.
|
|
125
|
+
- Use child step type rules to interpret child outputs.
|
|
126
|
+
|
|
127
|
+
Common failures:
|
|
128
|
+
- Assistant tries to read child output from `steps.<parallel_ref>.output.result`.
|
|
129
|
+
- A child step fails but the explanation only mentions the PARALLEL container.
|
|
130
|
+
- A later step assumes child execution order inside PARALLEL.
|
|
131
|
+
- A child depends on another child result even though they run concurrently.
|
|
132
|
+
- Duplicate child refs collide with refs elsewhere in the workflow.
|
|
133
|
+
- A multi-step parallel path is modeled as sibling children instead of a child `LIST`.
|
|
134
|
+
|
|
135
|
+
## Minimal Process Definition Example
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"orgId": 1,
|
|
140
|
+
"namespace": "default",
|
|
141
|
+
"name": "kebab-case-name",
|
|
142
|
+
"version": 1,
|
|
143
|
+
"type": "API_ORCHESTRATION",
|
|
144
|
+
"description": "Run two HTTP calls concurrently.",
|
|
145
|
+
"configuration": null,
|
|
146
|
+
"steps": [
|
|
147
|
+
{
|
|
148
|
+
"orgId": 1,
|
|
149
|
+
"namespace": "default",
|
|
150
|
+
"name": "parallel",
|
|
151
|
+
"type": "PARALLEL",
|
|
152
|
+
"ref": "parallel_1",
|
|
153
|
+
"optional": false,
|
|
154
|
+
"createdBy": "system",
|
|
155
|
+
"updatedBy": "system",
|
|
156
|
+
"description": null,
|
|
157
|
+
"label": null,
|
|
158
|
+
"created": 1700000000000,
|
|
159
|
+
"updated": 1700000000000,
|
|
160
|
+
"configuration": {
|
|
161
|
+
"errorPolicyName": null,
|
|
162
|
+
"useCache": false,
|
|
163
|
+
"cacheKey": null,
|
|
164
|
+
"cacheTimeoutSeconds": 0,
|
|
165
|
+
"stream": false,
|
|
166
|
+
"streamAllStatuses": false,
|
|
167
|
+
"preExecutionScript": null,
|
|
168
|
+
"constructInputFromScript": false,
|
|
169
|
+
"scriptLanguage": null,
|
|
170
|
+
"jqTransformer": null,
|
|
171
|
+
"rateLimitMaxRequests": 0,
|
|
172
|
+
"rateLimitWindowSeconds": 0
|
|
173
|
+
},
|
|
174
|
+
"children": [
|
|
175
|
+
{
|
|
176
|
+
"orgId": 1,
|
|
177
|
+
"namespace": "default",
|
|
178
|
+
"name": "http",
|
|
179
|
+
"type": "HTTP",
|
|
180
|
+
"ref": "http_2",
|
|
181
|
+
"optional": false,
|
|
182
|
+
"createdBy": "system",
|
|
183
|
+
"updatedBy": "system",
|
|
184
|
+
"description": null,
|
|
185
|
+
"label": null,
|
|
186
|
+
"created": 1700000000000,
|
|
187
|
+
"updated": 1700000000000,
|
|
188
|
+
"configuration": {
|
|
189
|
+
"errorPolicyName": null,
|
|
190
|
+
"useCache": false,
|
|
191
|
+
"cacheKey": null,
|
|
192
|
+
"cacheTimeoutSeconds": 0,
|
|
193
|
+
"stream": false,
|
|
194
|
+
"streamAllStatuses": false,
|
|
195
|
+
"preExecutionScript": null,
|
|
196
|
+
"constructInputFromScript": false,
|
|
197
|
+
"scriptLanguage": null,
|
|
198
|
+
"jqTransformer": null,
|
|
199
|
+
"rateLimitMaxRequests": 0,
|
|
200
|
+
"rateLimitWindowSeconds": 0
|
|
201
|
+
},
|
|
202
|
+
"children": [],
|
|
203
|
+
"input": {
|
|
204
|
+
"method": "POST",
|
|
205
|
+
"url": "http://localhost:8080/api/test/post",
|
|
206
|
+
"headers": {
|
|
207
|
+
"Content-Type": "application/json",
|
|
208
|
+
"Accept": "application/json",
|
|
209
|
+
"Authorization": "Bearer {{secrets.test_token}}"
|
|
210
|
+
},
|
|
211
|
+
"params": {
|
|
212
|
+
"sampleKey": "sampleValue"
|
|
213
|
+
},
|
|
214
|
+
"body": {
|
|
215
|
+
"type": "json",
|
|
216
|
+
"content": {
|
|
217
|
+
"title": "foo",
|
|
218
|
+
"body": "bar",
|
|
219
|
+
"userId": 1
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
"repeatUntilEnabled": null,
|
|
223
|
+
"repeatUntilCondition": {
|
|
224
|
+
"script": "(steps, context) => {\n return steps.__self.output.response.counter === 100;\n}"
|
|
225
|
+
},
|
|
226
|
+
"repeatIntervalSeconds": null,
|
|
227
|
+
"maxRepeatCount": null,
|
|
228
|
+
"includeFullResponseString": false,
|
|
229
|
+
"noEncode": false,
|
|
230
|
+
"extraLongTimeouts": false
|
|
231
|
+
},
|
|
232
|
+
"output": null
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
"orgId": 1,
|
|
236
|
+
"namespace": "default",
|
|
237
|
+
"name": "http",
|
|
238
|
+
"type": "HTTP",
|
|
239
|
+
"ref": "http_1",
|
|
240
|
+
"optional": false,
|
|
241
|
+
"createdBy": "system",
|
|
242
|
+
"updatedBy": "system",
|
|
243
|
+
"description": null,
|
|
244
|
+
"label": null,
|
|
245
|
+
"created": 1700000000000,
|
|
246
|
+
"updated": 1700000000000,
|
|
247
|
+
"configuration": {
|
|
248
|
+
"errorPolicyName": null,
|
|
249
|
+
"useCache": false,
|
|
250
|
+
"cacheKey": null,
|
|
251
|
+
"cacheTimeoutSeconds": 0,
|
|
252
|
+
"stream": false,
|
|
253
|
+
"streamAllStatuses": false,
|
|
254
|
+
"preExecutionScript": null,
|
|
255
|
+
"constructInputFromScript": false,
|
|
256
|
+
"scriptLanguage": null,
|
|
257
|
+
"jqTransformer": null,
|
|
258
|
+
"rateLimitMaxRequests": 0,
|
|
259
|
+
"rateLimitWindowSeconds": 0
|
|
260
|
+
},
|
|
261
|
+
"children": [],
|
|
262
|
+
"input": {
|
|
263
|
+
"method": "GET",
|
|
264
|
+
"url": "http://localhost:8080/api/test/get",
|
|
265
|
+
"headers": {
|
|
266
|
+
"Content-Type": "application/json",
|
|
267
|
+
"Accept": "application/json",
|
|
268
|
+
"Authorization": "Bearer {{secrets.test_token}}"
|
|
269
|
+
},
|
|
270
|
+
"params": {
|
|
271
|
+
"sampleKey": "sampleValue"
|
|
272
|
+
},
|
|
273
|
+
"repeatUntilEnabled": null,
|
|
274
|
+
"repeatUntilCondition": {
|
|
275
|
+
"script": "(steps, context) => {\n return steps.__self.output.response.counter === 100;\n}"
|
|
276
|
+
},
|
|
277
|
+
"repeatIntervalSeconds": null,
|
|
278
|
+
"maxRepeatCount": null,
|
|
279
|
+
"includeFullResponseString": false,
|
|
280
|
+
"noEncode": false,
|
|
281
|
+
"extraLongTimeouts": false
|
|
282
|
+
},
|
|
283
|
+
"output": null
|
|
284
|
+
}
|
|
285
|
+
],
|
|
286
|
+
"input": {
|
|
287
|
+
"failIfAnyBranchFails": false
|
|
288
|
+
},
|
|
289
|
+
"output": null
|
|
290
|
+
}
|
|
291
|
+
],
|
|
292
|
+
"defaultInput": null,
|
|
293
|
+
"defaultOutput": null,
|
|
294
|
+
"outputMapping": null,
|
|
295
|
+
"signature": null,
|
|
296
|
+
"metadata": null,
|
|
297
|
+
"tags": null,
|
|
298
|
+
"dependencies": null,
|
|
299
|
+
"dependents": null
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
## Minimal Executed Step Records Example
|
|
304
|
+
|
|
305
|
+
PARALLEL container step record:
|
|
306
|
+
|
|
307
|
+
```json
|
|
308
|
+
{
|
|
309
|
+
"id": 28800016,
|
|
310
|
+
"processId": 28800014,
|
|
311
|
+
"ref": "parallel_1",
|
|
312
|
+
"parentId": null,
|
|
313
|
+
"parentRef": null,
|
|
314
|
+
"namespace": "default",
|
|
315
|
+
"name": "parallel",
|
|
316
|
+
"type": "PARALLEL",
|
|
317
|
+
"status": "COMPLETED",
|
|
318
|
+
"input": {
|
|
319
|
+
"failIfAnyBranchFails": false,
|
|
320
|
+
"__currentExecutionStartTime": 1778183464807
|
|
321
|
+
},
|
|
322
|
+
"output": {},
|
|
323
|
+
"optional": false
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
HTTP child step record:
|
|
328
|
+
|
|
329
|
+
```json
|
|
330
|
+
{
|
|
331
|
+
"id": 28800018,
|
|
332
|
+
"processId": 28800014,
|
|
333
|
+
"ref": "http_1",
|
|
334
|
+
"parentId": 28800016,
|
|
335
|
+
"parentRef": "parallel_1",
|
|
336
|
+
"namespace": "default",
|
|
337
|
+
"name": "http",
|
|
338
|
+
"type": "HTTP",
|
|
339
|
+
"status": "COMPLETED",
|
|
340
|
+
"output": {
|
|
341
|
+
"response": {
|
|
342
|
+
"counter": 2,
|
|
343
|
+
"randomId": "abb5ca43-3835-4dae-8556-b72aa4d42e64"
|
|
344
|
+
},
|
|
345
|
+
"statusCode": 200
|
|
346
|
+
},
|
|
347
|
+
"optional": false
|
|
348
|
+
}
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
## Example: Merge Outputs After PARALLEL
|
|
352
|
+
|
|
353
|
+
Use child refs directly in a later JavaScript step:
|
|
354
|
+
|
|
355
|
+
```javascript
|
|
356
|
+
(steps, context) => {
|
|
357
|
+
const getResult = steps.http_1.output.response || {};
|
|
358
|
+
const postResult = steps.http_2.output.response || {};
|
|
359
|
+
return {
|
|
360
|
+
getCounter: getResult.counter,
|
|
361
|
+
postCounter: postResult.counter,
|
|
362
|
+
randomIds: [getResult.randomId, postResult.randomId].filter(Boolean)
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
```
|
|
366
|
+
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Python Step Schema
|
|
2
|
+
|
|
3
|
+
`PYTHON` steps run inline Python inside a process definition. Use them for file
|
|
4
|
+
I/O, base64 or binary handling, data transformation, validation, assertions,
|
|
5
|
+
and Python-friendly utility logic.
|
|
6
|
+
|
|
7
|
+
Python steps receive two default dictionary arguments:
|
|
8
|
+
- `steps`: runtime data for the current step and previously executed steps.
|
|
9
|
+
- `context`: runtime process context, including process id, input, state, and metadata.
|
|
10
|
+
|
|
11
|
+
## Definition Input Schema
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
{
|
|
15
|
+
"script": "# Do not change the parameters count, order, or types.\n# The parameter names must remain the same.\n# `steps` and `context` are Python dictionaries provided by default.\ndef main(steps, context):\n return {\n \"processId\": context.get(\"id\"),\n \"currentStepId\": steps[\"__self\"][\"id\"],\n \"statusMessage\": \"Process completed\",\n \"isSuccessful\": True\n }\n"
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Runtime Output Schema
|
|
20
|
+
|
|
21
|
+
The Python `main` function's returned value is stored in `output.result`.
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"result": {
|
|
26
|
+
"processId": 28800007,
|
|
27
|
+
"currentStepId": {
|
|
28
|
+
"ref": "python_1",
|
|
29
|
+
"processId": 28800007,
|
|
30
|
+
"id": 28800009
|
|
31
|
+
},
|
|
32
|
+
"statusMessage": "Process completed",
|
|
33
|
+
"isSuccessful": true
|
|
34
|
+
},
|
|
35
|
+
"logs": []
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Process-level output for a single Python-step workflow can mirror the Python
|
|
40
|
+
step output:
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"result": {
|
|
45
|
+
"processId": 28800007,
|
|
46
|
+
"statusMessage": "Process completed",
|
|
47
|
+
"isSuccessful": true
|
|
48
|
+
},
|
|
49
|
+
"logs": []
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Output Access Paths
|
|
54
|
+
|
|
55
|
+
Use from later JavaScript/template steps:
|
|
56
|
+
- `steps.<ref>.output.result` for the complete returned value.
|
|
57
|
+
- `steps.<ref>.output.result.<field>` for returned object fields.
|
|
58
|
+
- `steps.<ref>.output.logs` for captured logs.
|
|
59
|
+
|
|
60
|
+
Use inside Python scripts:
|
|
61
|
+
- `context.get("id")` for the process id.
|
|
62
|
+
- `context.get("input", {}).get("<field>")` for process input fields.
|
|
63
|
+
- `steps["__self"]["id"]` for the current step id object.
|
|
64
|
+
- `steps["<ref>"]["output"]["result"]` for previous Python or JavaScript result output.
|
|
65
|
+
- `steps["<http_ref>"]["output"]["response"]` for previous native HTTP response body.
|
|
66
|
+
|
|
67
|
+
Do not use:
|
|
68
|
+
- `steps.<ref>.output.response` for Python step output.
|
|
69
|
+
- `steps.<ref>.output.results` for Python step output.
|
|
70
|
+
- `steps.<ref>.output.<field>` for returned object fields.
|
|
71
|
+
- `steps["<http_ref>"]["output"]["result"]` for native HTTP output.
|
|
72
|
+
|
|
73
|
+
## Generation Rules
|
|
74
|
+
|
|
75
|
+
- Use uppercase step type: `"PYTHON"`.
|
|
76
|
+
- Put executable code in `input.script`.
|
|
77
|
+
- Define exactly `def main(steps, context):`.
|
|
78
|
+
- Do not change the parameter count, order, names, or expected dictionary types.
|
|
79
|
+
- The script should explicitly `return` the value that later steps need.
|
|
80
|
+
- Prefer returning a dictionary, even for one value, so later references are stable.
|
|
81
|
+
- Use safe dictionary access with `.get()` when reading uncertain keys.
|
|
82
|
+
- Read native HTTP responses from `steps["<http_ref>"]["output"]["response"]`, not `result`.
|
|
83
|
+
- Read JavaScript or Python results from `steps["<ref>"]["output"]["result"]`.
|
|
84
|
+
- Do not hardcode secrets or credentials in scripts.
|
|
85
|
+
|
|
86
|
+
## Debugging Rules
|
|
87
|
+
|
|
88
|
+
When a Python step fails:
|
|
89
|
+
- Inspect the step record's `input.script`.
|
|
90
|
+
- Confirm it defines `def main(steps, context):`.
|
|
91
|
+
- Inspect the previous step outputs referenced by the script.
|
|
92
|
+
- Verify dictionary paths against each referenced step type.
|
|
93
|
+
- If the script reads an HTTP step with `["output"]["result"]`, explain that native HTTP uses `["output"]["response"]`.
|
|
94
|
+
- If the script returns nothing, explain that `output.result` will be missing or null.
|
|
95
|
+
- If process output is unexpected, compare process-level `output` with the Python step's `stepRecords[].output`.
|
|
96
|
+
|
|
97
|
+
Common failures:
|
|
98
|
+
- Missing `def main(steps, context):`.
|
|
99
|
+
- Missing `return`.
|
|
100
|
+
- Changing parameter names or order.
|
|
101
|
+
- Referencing native HTTP output as `steps["<http_ref>"]["output"]["result"]`.
|
|
102
|
+
- Assuming an upstream value is a list without checking `isinstance(value, list)`.
|
|
103
|
+
- Returning a primitive when later steps expect object fields.
|
|
104
|
+
- Key errors from direct dictionary indexing on optional data.
|
|
105
|
+
|
|
106
|
+
## Minimal Process Definition Example
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"orgId": 1,
|
|
111
|
+
"namespace": "default",
|
|
112
|
+
"name": "kebab-case-name",
|
|
113
|
+
"version": 1,
|
|
114
|
+
"type": "API_ORCHESTRATION",
|
|
115
|
+
"description": "Return process status fields from Python.",
|
|
116
|
+
"configuration": null,
|
|
117
|
+
"steps": [
|
|
118
|
+
{
|
|
119
|
+
"orgId": 1,
|
|
120
|
+
"namespace": "default",
|
|
121
|
+
"name": "python",
|
|
122
|
+
"type": "PYTHON",
|
|
123
|
+
"ref": "python_1",
|
|
124
|
+
"optional": false,
|
|
125
|
+
"createdBy": "system",
|
|
126
|
+
"updatedBy": "system",
|
|
127
|
+
"description": null,
|
|
128
|
+
"label": null,
|
|
129
|
+
"created": 1700000000000,
|
|
130
|
+
"updated": 1700000000000,
|
|
131
|
+
"configuration": {
|
|
132
|
+
"errorPolicyName": null,
|
|
133
|
+
"useCache": false,
|
|
134
|
+
"cacheKey": null,
|
|
135
|
+
"cacheTimeoutSeconds": 0,
|
|
136
|
+
"stream": false,
|
|
137
|
+
"streamAllStatuses": false,
|
|
138
|
+
"preExecutionScript": null,
|
|
139
|
+
"constructInputFromScript": false,
|
|
140
|
+
"scriptLanguage": null,
|
|
141
|
+
"jqTransformer": null,
|
|
142
|
+
"rateLimitMaxRequests": 0,
|
|
143
|
+
"rateLimitWindowSeconds": 0
|
|
144
|
+
},
|
|
145
|
+
"children": [],
|
|
146
|
+
"input": {
|
|
147
|
+
"script": "# Do not change the parameters count, order, or types.\n# The parameter names must remain the same.\n# `steps` and `context` are Python dictionaries provided by default.\ndef main(steps, context):\n return {\n \"processId\": context.get(\"id\"),\n \"currentStepId\": steps[\"__self\"][\"id\"],\n \"statusMessage\": \"Process completed\",\n \"isSuccessful\": True\n }\n"
|
|
148
|
+
},
|
|
149
|
+
"output": null
|
|
150
|
+
}
|
|
151
|
+
],
|
|
152
|
+
"defaultInput": null,
|
|
153
|
+
"defaultOutput": null,
|
|
154
|
+
"outputMapping": null,
|
|
155
|
+
"signature": null,
|
|
156
|
+
"metadata": null,
|
|
157
|
+
"tags": null,
|
|
158
|
+
"dependencies": null,
|
|
159
|
+
"dependents": null
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Minimal Executed Step Example
|
|
164
|
+
|
|
165
|
+
```json
|
|
166
|
+
{
|
|
167
|
+
"id": 28800009,
|
|
168
|
+
"processId": 28800007,
|
|
169
|
+
"ref": "python_1",
|
|
170
|
+
"namespace": "default",
|
|
171
|
+
"name": "python",
|
|
172
|
+
"type": "PYTHON",
|
|
173
|
+
"status": "COMPLETED",
|
|
174
|
+
"input": {
|
|
175
|
+
"script": "# Do not change the parameters count, order, or types.\n# The parameter names must remain the same.\n# `steps` and `context` are Python dictionaries provided by default.\ndef main(steps, context):\n return {\n \"processId\": context.get(\"id\"),\n \"currentStepId\": steps[\"__self\"][\"id\"],\n \"statusMessage\": \"Process completed\",\n \"isSuccessful\": True\n }\n",
|
|
176
|
+
"__currentExecutionStartTime": 1778182855381
|
|
177
|
+
},
|
|
178
|
+
"output": {
|
|
179
|
+
"result": {
|
|
180
|
+
"currentStepId": {
|
|
181
|
+
"ref": "python_1",
|
|
182
|
+
"processId": 28800007,
|
|
183
|
+
"id": 28800009
|
|
184
|
+
},
|
|
185
|
+
"isSuccessful": true,
|
|
186
|
+
"processId": 28800007,
|
|
187
|
+
"statusMessage": "Process completed"
|
|
188
|
+
},
|
|
189
|
+
"logs": []
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Example: Count Native HTTP Response Array
|
|
195
|
+
|
|
196
|
+
Use this when a previous native `HTTP` step with ref `fetch_posts_1` returns an
|
|
197
|
+
array response body:
|
|
198
|
+
|
|
199
|
+
```python
|
|
200
|
+
def main(steps, context):
|
|
201
|
+
posts = steps.get("fetch_posts_1", {}).get("output", {}).get("response", [])
|
|
202
|
+
return {
|
|
203
|
+
"count": len(posts) if isinstance(posts, list) else 0
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|