@upstash/workflow 0.2.8-rc-invoke → 0.2.9
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/astro.d.mts +4 -4
- package/astro.d.ts +4 -4
- package/astro.js +282 -135
- package/astro.mjs +17 -15
- package/{chunk-IWAW7GIG.mjs → chunk-IPXJZU3K.mjs} +851 -592
- package/cloudflare.d.mts +4 -4
- package/cloudflare.d.ts +4 -4
- package/cloudflare.js +278 -135
- package/cloudflare.mjs +13 -15
- package/express.d.mts +4 -4
- package/express.d.ts +4 -4
- package/express.js +281 -144
- package/express.mjs +16 -22
- package/h3.d.mts +4 -4
- package/h3.d.ts +4 -4
- package/h3.js +275 -135
- package/h3.mjs +10 -15
- package/hono.d.mts +4 -4
- package/hono.d.ts +4 -4
- package/hono.js +277 -134
- package/hono.mjs +12 -14
- package/index.d.mts +268 -5
- package/index.d.ts +268 -5
- package/index.js +297 -43
- package/index.mjs +60 -3
- package/nextjs.d.mts +6 -6
- package/nextjs.d.ts +6 -6
- package/nextjs.js +286 -143
- package/nextjs.mjs +21 -23
- package/package.json +1 -1
- package/serve-many-BVDpPsF-.d.mts +13 -0
- package/serve-many-e4zufyXN.d.ts +13 -0
- package/solidjs.d.mts +1 -1
- package/solidjs.d.ts +1 -1
- package/solidjs.js +207 -41
- package/solidjs.mjs +1 -1
- package/svelte.d.mts +8 -9
- package/svelte.d.ts +8 -9
- package/svelte.js +278 -135
- package/svelte.mjs +13 -15
- package/{types-C7Y7WUQd.d.mts → types-CYhDXnf8.d.mts} +110 -18
- package/{types-C7Y7WUQd.d.ts → types-CYhDXnf8.d.ts} +110 -18
- package/chunk-LCZMBGEM.mjs +0 -95
- package/serve-many-BlBvXfBS.d.mts +0 -10
- package/serve-many-Dw-UUnH6.d.ts +0 -10
package/index.js
CHANGED
|
@@ -26,6 +26,7 @@ __export(src_exports, {
|
|
|
26
26
|
WorkflowContext: () => WorkflowContext,
|
|
27
27
|
WorkflowError: () => WorkflowError,
|
|
28
28
|
WorkflowLogger: () => WorkflowLogger,
|
|
29
|
+
WorkflowTool: () => WorkflowTool,
|
|
29
30
|
serve: () => serve
|
|
30
31
|
});
|
|
31
32
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -96,6 +97,7 @@ var WORKFLOW_INIT_HEADER = "Upstash-Workflow-Init";
|
|
|
96
97
|
var WORKFLOW_URL_HEADER = "Upstash-Workflow-Url";
|
|
97
98
|
var WORKFLOW_FAILURE_HEADER = "Upstash-Workflow-Is-Failure";
|
|
98
99
|
var WORKFLOW_FEATURE_HEADER = "Upstash-Feature-Set";
|
|
100
|
+
var WORKFLOW_INVOKE_COUNT_HEADER = "Upstash-Workflow-Invoke-Count";
|
|
99
101
|
var WORKFLOW_PROTOCOL_VERSION = "1";
|
|
100
102
|
var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
|
|
101
103
|
var DEFAULT_CONTENT_TYPE = "application/json";
|
|
@@ -277,8 +279,9 @@ var LazyCallStep = class extends BaseLazyStep {
|
|
|
277
279
|
headers;
|
|
278
280
|
retries;
|
|
279
281
|
timeout;
|
|
282
|
+
flowControl;
|
|
280
283
|
stepType = "Call";
|
|
281
|
-
constructor(stepName, url, method, body, headers, retries, timeout) {
|
|
284
|
+
constructor(stepName, url, method, body, headers, retries, timeout, flowControl) {
|
|
282
285
|
super(stepName);
|
|
283
286
|
this.url = url;
|
|
284
287
|
this.method = method;
|
|
@@ -286,6 +289,7 @@ var LazyCallStep = class extends BaseLazyStep {
|
|
|
286
289
|
this.headers = headers;
|
|
287
290
|
this.retries = retries;
|
|
288
291
|
this.timeout = timeout;
|
|
292
|
+
this.flowControl = flowControl;
|
|
289
293
|
}
|
|
290
294
|
getPlanStep(concurrent, targetStep) {
|
|
291
295
|
return {
|
|
@@ -356,14 +360,22 @@ var LazyNotifyStep = class extends LazyFunctionStep {
|
|
|
356
360
|
var LazyInvokeStep = class extends BaseLazyStep {
|
|
357
361
|
stepType = "Invoke";
|
|
358
362
|
params;
|
|
359
|
-
constructor(stepName, {
|
|
363
|
+
constructor(stepName, {
|
|
364
|
+
workflow,
|
|
365
|
+
body,
|
|
366
|
+
headers = {},
|
|
367
|
+
workflowRunId,
|
|
368
|
+
retries,
|
|
369
|
+
flowControl
|
|
370
|
+
}) {
|
|
360
371
|
super(stepName);
|
|
361
372
|
this.params = {
|
|
362
373
|
workflow,
|
|
363
374
|
body,
|
|
364
375
|
headers,
|
|
365
376
|
workflowRunId: getWorkflowRunId(workflowRunId),
|
|
366
|
-
retries
|
|
377
|
+
retries,
|
|
378
|
+
flowControl
|
|
367
379
|
};
|
|
368
380
|
}
|
|
369
381
|
getPlanStep(concurrent, targetStep) {
|
|
@@ -822,7 +834,8 @@ var triggerFirstInvocation = async ({
|
|
|
822
834
|
workflowContext,
|
|
823
835
|
useJSONContent,
|
|
824
836
|
telemetry,
|
|
825
|
-
debug
|
|
837
|
+
debug,
|
|
838
|
+
invokeCount
|
|
826
839
|
}) => {
|
|
827
840
|
const { headers } = getHeaders({
|
|
828
841
|
initHeaderValue: "true",
|
|
@@ -831,7 +844,9 @@ var triggerFirstInvocation = async ({
|
|
|
831
844
|
userHeaders: workflowContext.headers,
|
|
832
845
|
failureUrl: workflowContext.failureUrl,
|
|
833
846
|
retries: workflowContext.retries,
|
|
834
|
-
telemetry
|
|
847
|
+
telemetry,
|
|
848
|
+
invokeCount,
|
|
849
|
+
flowControl: workflowContext.flowControl
|
|
835
850
|
});
|
|
836
851
|
if (workflowContext.headers.get("content-type")) {
|
|
837
852
|
headers["content-type"] = workflowContext.headers.get("content-type");
|
|
@@ -937,6 +952,7 @@ var handleThirdPartyCallResult = async ({
|
|
|
937
952
|
failureUrl,
|
|
938
953
|
retries,
|
|
939
954
|
telemetry,
|
|
955
|
+
flowControl,
|
|
940
956
|
debug
|
|
941
957
|
}) => {
|
|
942
958
|
try {
|
|
@@ -984,6 +1000,7 @@ ${atob(callbackMessage.body ?? "")}`
|
|
|
984
1000
|
const stepType = request.headers.get("Upstash-Workflow-StepType");
|
|
985
1001
|
const concurrentString = request.headers.get("Upstash-Workflow-Concurrent");
|
|
986
1002
|
const contentType = request.headers.get("Upstash-Workflow-ContentType");
|
|
1003
|
+
const invokeCount = request.headers.get(WORKFLOW_INVOKE_COUNT_HEADER);
|
|
987
1004
|
if (!(workflowRunId && stepIdString && stepName && StepTypes.includes(stepType) && concurrentString && contentType)) {
|
|
988
1005
|
throw new Error(
|
|
989
1006
|
`Missing info in callback message source header: ${JSON.stringify({
|
|
@@ -1004,7 +1021,9 @@ ${atob(callbackMessage.body ?? "")}`
|
|
|
1004
1021
|
userHeaders,
|
|
1005
1022
|
failureUrl,
|
|
1006
1023
|
retries,
|
|
1007
|
-
telemetry
|
|
1024
|
+
telemetry,
|
|
1025
|
+
invokeCount: Number(invokeCount),
|
|
1026
|
+
flowControl
|
|
1008
1027
|
});
|
|
1009
1028
|
const callResponse = {
|
|
1010
1029
|
status: callbackMessage.status,
|
|
@@ -1060,7 +1079,10 @@ var getHeaders = ({
|
|
|
1060
1079
|
step,
|
|
1061
1080
|
callRetries,
|
|
1062
1081
|
callTimeout,
|
|
1063
|
-
telemetry
|
|
1082
|
+
telemetry,
|
|
1083
|
+
invokeCount,
|
|
1084
|
+
flowControl,
|
|
1085
|
+
callFlowControl
|
|
1064
1086
|
}) => {
|
|
1065
1087
|
const contentType = (userHeaders ? userHeaders.get("Content-Type") : void 0) ?? DEFAULT_CONTENT_TYPE;
|
|
1066
1088
|
const baseHeaders = {
|
|
@@ -1072,6 +1094,9 @@ var getHeaders = ({
|
|
|
1072
1094
|
"content-type": contentType,
|
|
1073
1095
|
...telemetry ? getTelemetryHeaders(telemetry) : {}
|
|
1074
1096
|
};
|
|
1097
|
+
if (invokeCount !== void 0 && !step?.callUrl) {
|
|
1098
|
+
baseHeaders[`Upstash-Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`] = invokeCount.toString();
|
|
1099
|
+
}
|
|
1075
1100
|
if (!step?.callUrl) {
|
|
1076
1101
|
baseHeaders[`Upstash-Forward-${WORKFLOW_PROTOCOL_VERSION_HEADER}`] = WORKFLOW_PROTOCOL_VERSION;
|
|
1077
1102
|
}
|
|
@@ -1080,13 +1105,23 @@ var getHeaders = ({
|
|
|
1080
1105
|
}
|
|
1081
1106
|
if (failureUrl) {
|
|
1082
1107
|
baseHeaders[`Upstash-Failure-Callback-Forward-${WORKFLOW_FAILURE_HEADER}`] = "true";
|
|
1108
|
+
baseHeaders[`Upstash-Failure-Callback-Forward-Upstash-Workflow-Failure-Callback`] = "true";
|
|
1109
|
+
baseHeaders["Upstash-Failure-Callback-Workflow-Runid"] = workflowRunId;
|
|
1110
|
+
baseHeaders["Upstash-Failure-Callback-Workflow-Init"] = "false";
|
|
1111
|
+
baseHeaders["Upstash-Failure-Callback-Workflow-Url"] = workflowUrl;
|
|
1112
|
+
baseHeaders["Upstash-Failure-Callback-Workflow-Calltype"] = "failureCall";
|
|
1113
|
+
if (retries !== void 0) {
|
|
1114
|
+
baseHeaders["Upstash-Failure-Callback-Retries"] = retries.toString();
|
|
1115
|
+
}
|
|
1116
|
+
if (flowControl) {
|
|
1117
|
+
const { flowControlKey, flowControlValue } = prepareFlowControl(flowControl);
|
|
1118
|
+
baseHeaders["Upstash-Failure-Callback-Flow-Control-Key"] = flowControlKey;
|
|
1119
|
+
baseHeaders["Upstash-Failure-Callback-Flow-Control-Value"] = flowControlValue;
|
|
1120
|
+
}
|
|
1083
1121
|
if (!step?.callUrl) {
|
|
1084
1122
|
baseHeaders["Upstash-Failure-Callback"] = failureUrl;
|
|
1085
1123
|
}
|
|
1086
1124
|
}
|
|
1087
|
-
if (step?.stepType === "Invoke") {
|
|
1088
|
-
baseHeaders["upstash-workflow-invoke"] = "true";
|
|
1089
|
-
}
|
|
1090
1125
|
if (step?.callUrl) {
|
|
1091
1126
|
baseHeaders["Upstash-Retries"] = callRetries?.toString() ?? "0";
|
|
1092
1127
|
baseHeaders[WORKFLOW_FEATURE_HEADER] = "WF_NoDelete,InitialBody";
|
|
@@ -1094,9 +1129,26 @@ var getHeaders = ({
|
|
|
1094
1129
|
baseHeaders["Upstash-Callback-Retries"] = retries.toString();
|
|
1095
1130
|
baseHeaders["Upstash-Failure-Callback-Retries"] = retries.toString();
|
|
1096
1131
|
}
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1132
|
+
if (callFlowControl) {
|
|
1133
|
+
const { flowControlKey, flowControlValue } = prepareFlowControl(callFlowControl);
|
|
1134
|
+
baseHeaders["Upstash-Flow-Control-Key"] = flowControlKey;
|
|
1135
|
+
baseHeaders["Upstash-Flow-Control-Value"] = flowControlValue;
|
|
1136
|
+
}
|
|
1137
|
+
if (flowControl) {
|
|
1138
|
+
const { flowControlKey, flowControlValue } = prepareFlowControl(flowControl);
|
|
1139
|
+
baseHeaders["Upstash-Callback-Flow-Control-Key"] = flowControlKey;
|
|
1140
|
+
baseHeaders["Upstash-Callback-Flow-Control-Value"] = flowControlValue;
|
|
1141
|
+
}
|
|
1142
|
+
} else {
|
|
1143
|
+
if (flowControl) {
|
|
1144
|
+
const { flowControlKey, flowControlValue } = prepareFlowControl(flowControl);
|
|
1145
|
+
baseHeaders["Upstash-Flow-Control-Key"] = flowControlKey;
|
|
1146
|
+
baseHeaders["Upstash-Flow-Control-Value"] = flowControlValue;
|
|
1147
|
+
}
|
|
1148
|
+
if (retries !== void 0) {
|
|
1149
|
+
baseHeaders["Upstash-Retries"] = retries.toString();
|
|
1150
|
+
baseHeaders["Upstash-Failure-Callback-Retries"] = retries.toString();
|
|
1151
|
+
}
|
|
1100
1152
|
}
|
|
1101
1153
|
if (userHeaders) {
|
|
1102
1154
|
for (const header of userHeaders.keys()) {
|
|
@@ -1131,6 +1183,7 @@ var getHeaders = ({
|
|
|
1131
1183
|
"Upstash-Callback-Forward-Upstash-Workflow-StepType": step.stepType,
|
|
1132
1184
|
"Upstash-Callback-Forward-Upstash-Workflow-Concurrent": step.concurrent.toString(),
|
|
1133
1185
|
"Upstash-Callback-Forward-Upstash-Workflow-ContentType": contentType,
|
|
1186
|
+
[`Upstash-Callback-Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`]: (invokeCount ?? 0).toString(),
|
|
1134
1187
|
"Upstash-Workflow-CallType": "toCallback"
|
|
1135
1188
|
}
|
|
1136
1189
|
};
|
|
@@ -1188,9 +1241,98 @@ If you want to disable QStash Verification, you should clear env variables QSTAS
|
|
|
1188
1241
|
);
|
|
1189
1242
|
}
|
|
1190
1243
|
};
|
|
1244
|
+
var prepareFlowControl = (flowControl) => {
|
|
1245
|
+
const parallelism = flowControl.parallelism?.toString();
|
|
1246
|
+
const rate = flowControl.ratePerSecond?.toString();
|
|
1247
|
+
const controlValue = [
|
|
1248
|
+
parallelism ? `parallelism=${parallelism}` : void 0,
|
|
1249
|
+
rate ? `rate=${rate}` : void 0
|
|
1250
|
+
].filter(Boolean);
|
|
1251
|
+
if (controlValue.length === 0) {
|
|
1252
|
+
throw new import_qstash3.QstashError("Provide at least one of parallelism or ratePerSecond for flowControl");
|
|
1253
|
+
}
|
|
1254
|
+
return {
|
|
1255
|
+
flowControlKey: flowControl.key,
|
|
1256
|
+
flowControlValue: controlValue.join(", ")
|
|
1257
|
+
};
|
|
1258
|
+
};
|
|
1191
1259
|
|
|
1192
1260
|
// src/context/auto-executor.ts
|
|
1193
1261
|
var import_qstash4 = require("@upstash/qstash");
|
|
1262
|
+
|
|
1263
|
+
// src/serve/serve-many.ts
|
|
1264
|
+
var invokeWorkflow = async ({
|
|
1265
|
+
settings,
|
|
1266
|
+
invokeStep,
|
|
1267
|
+
context,
|
|
1268
|
+
invokeCount,
|
|
1269
|
+
telemetry
|
|
1270
|
+
}) => {
|
|
1271
|
+
const {
|
|
1272
|
+
body,
|
|
1273
|
+
workflow,
|
|
1274
|
+
headers = {},
|
|
1275
|
+
workflowRunId = getWorkflowRunId(),
|
|
1276
|
+
retries,
|
|
1277
|
+
flowControl
|
|
1278
|
+
} = settings;
|
|
1279
|
+
const { workflowId } = workflow;
|
|
1280
|
+
const {
|
|
1281
|
+
retries: workflowRetries,
|
|
1282
|
+
failureFunction,
|
|
1283
|
+
failureUrl,
|
|
1284
|
+
useJSONContent,
|
|
1285
|
+
flowControl: workflowFlowControl
|
|
1286
|
+
} = workflow.options;
|
|
1287
|
+
if (!workflowId) {
|
|
1288
|
+
throw new WorkflowError("You can only invoke workflow which has a workflowId");
|
|
1289
|
+
}
|
|
1290
|
+
const { headers: invokerHeaders } = getHeaders({
|
|
1291
|
+
initHeaderValue: "false",
|
|
1292
|
+
workflowRunId: context.workflowRunId,
|
|
1293
|
+
workflowUrl: context.url,
|
|
1294
|
+
userHeaders: context.headers,
|
|
1295
|
+
failureUrl: context.failureUrl,
|
|
1296
|
+
retries: context.retries,
|
|
1297
|
+
telemetry,
|
|
1298
|
+
invokeCount,
|
|
1299
|
+
flowControl: context.flowControl
|
|
1300
|
+
});
|
|
1301
|
+
invokerHeaders["Upstash-Workflow-Runid"] = context.workflowRunId;
|
|
1302
|
+
const newUrl = context.url.replace(/[^/]+$/, workflowId);
|
|
1303
|
+
const { headers: triggerHeaders } = getHeaders({
|
|
1304
|
+
initHeaderValue: "true",
|
|
1305
|
+
workflowRunId,
|
|
1306
|
+
workflowUrl: newUrl,
|
|
1307
|
+
userHeaders: new Headers(headers),
|
|
1308
|
+
retries: retries ?? workflowRetries,
|
|
1309
|
+
telemetry,
|
|
1310
|
+
failureUrl: failureFunction ? newUrl : failureUrl,
|
|
1311
|
+
invokeCount: invokeCount + 1,
|
|
1312
|
+
flowControl: flowControl ?? workflowFlowControl
|
|
1313
|
+
});
|
|
1314
|
+
triggerHeaders["Upstash-Workflow-Invoke"] = "true";
|
|
1315
|
+
if (useJSONContent) {
|
|
1316
|
+
triggerHeaders["content-type"] = "application/json";
|
|
1317
|
+
}
|
|
1318
|
+
const request = {
|
|
1319
|
+
body: JSON.stringify(body),
|
|
1320
|
+
headers: Object.fromEntries(
|
|
1321
|
+
Object.entries(invokerHeaders).map((pairs) => [pairs[0], [pairs[1]]])
|
|
1322
|
+
),
|
|
1323
|
+
workflowRunId,
|
|
1324
|
+
workflowUrl: context.url,
|
|
1325
|
+
step: invokeStep
|
|
1326
|
+
};
|
|
1327
|
+
await context.qstashClient.publish({
|
|
1328
|
+
headers: triggerHeaders,
|
|
1329
|
+
method: "POST",
|
|
1330
|
+
body: JSON.stringify(request),
|
|
1331
|
+
url: newUrl
|
|
1332
|
+
});
|
|
1333
|
+
};
|
|
1334
|
+
|
|
1335
|
+
// src/context/auto-executor.ts
|
|
1194
1336
|
var AutoExecutor = class _AutoExecutor {
|
|
1195
1337
|
context;
|
|
1196
1338
|
promises = /* @__PURE__ */ new WeakMap();
|
|
@@ -1199,14 +1341,16 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1199
1341
|
nonPlanStepCount;
|
|
1200
1342
|
steps;
|
|
1201
1343
|
indexInCurrentList = 0;
|
|
1344
|
+
invokeCount;
|
|
1202
1345
|
telemetry;
|
|
1203
1346
|
stepCount = 0;
|
|
1204
1347
|
planStepCount = 0;
|
|
1205
1348
|
executingStep = false;
|
|
1206
|
-
constructor(context, steps, telemetry, debug) {
|
|
1349
|
+
constructor(context, steps, telemetry, invokeCount, debug) {
|
|
1207
1350
|
this.context = context;
|
|
1208
1351
|
this.steps = steps;
|
|
1209
1352
|
this.telemetry = telemetry;
|
|
1353
|
+
this.invokeCount = invokeCount ?? 0;
|
|
1210
1354
|
this.debug = debug;
|
|
1211
1355
|
this.nonPlanStepCount = this.steps.filter((step) => !step.targetStep).length;
|
|
1212
1356
|
}
|
|
@@ -1429,7 +1573,9 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1429
1573
|
step: waitStep,
|
|
1430
1574
|
failureUrl: this.context.failureUrl,
|
|
1431
1575
|
retries: this.context.retries,
|
|
1432
|
-
telemetry: this.telemetry
|
|
1576
|
+
telemetry: this.telemetry,
|
|
1577
|
+
invokeCount: this.invokeCount,
|
|
1578
|
+
flowControl: this.context.flowControl
|
|
1433
1579
|
});
|
|
1434
1580
|
const waitBody = {
|
|
1435
1581
|
url: this.context.url,
|
|
@@ -1457,17 +1603,13 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1457
1603
|
if (steps.length === 1 && lazySteps[0] instanceof LazyInvokeStep) {
|
|
1458
1604
|
const invokeStep = steps[0];
|
|
1459
1605
|
const lazyInvokeStep = lazySteps[0];
|
|
1460
|
-
await
|
|
1461
|
-
|
|
1462
|
-
body: lazyInvokeStep.params.body,
|
|
1463
|
-
headers: lazyInvokeStep.params.headers,
|
|
1464
|
-
workflowRunId: lazyInvokeStep.params.workflowRunId,
|
|
1465
|
-
workflow: lazyInvokeStep.params.workflow,
|
|
1466
|
-
retries: lazyInvokeStep.params.retries
|
|
1467
|
-
},
|
|
1606
|
+
await invokeWorkflow({
|
|
1607
|
+
settings: lazyInvokeStep.params,
|
|
1468
1608
|
invokeStep,
|
|
1469
|
-
this.context
|
|
1470
|
-
|
|
1609
|
+
context: this.context,
|
|
1610
|
+
invokeCount: this.invokeCount,
|
|
1611
|
+
telemetry: this.telemetry
|
|
1612
|
+
});
|
|
1471
1613
|
throw new WorkflowAbort(invokeStep.stepName, invokeStep);
|
|
1472
1614
|
}
|
|
1473
1615
|
const result = await this.context.qstashClient.batchJSON(
|
|
@@ -1483,11 +1625,14 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1483
1625
|
retries: this.context.retries,
|
|
1484
1626
|
callRetries: lazyStep instanceof LazyCallStep ? lazyStep.retries : void 0,
|
|
1485
1627
|
callTimeout: lazyStep instanceof LazyCallStep ? lazyStep.timeout : void 0,
|
|
1486
|
-
telemetry: this.telemetry
|
|
1628
|
+
telemetry: this.telemetry,
|
|
1629
|
+
invokeCount: this.invokeCount,
|
|
1630
|
+
flowControl: this.context.flowControl,
|
|
1631
|
+
callFlowControl: lazyStep instanceof LazyCallStep ? lazyStep.flowControl : void 0
|
|
1487
1632
|
});
|
|
1488
1633
|
const willWait = singleStep.concurrent === NO_CONCURRENCY || singleStep.stepId === 0;
|
|
1489
1634
|
singleStep.out = JSON.stringify(singleStep.out);
|
|
1490
|
-
return singleStep.callUrl ? (
|
|
1635
|
+
return singleStep.callUrl && lazyStep instanceof LazyCallStep ? (
|
|
1491
1636
|
// if the step is a third party call, we call the third party
|
|
1492
1637
|
// url (singleStep.callUrl) and pass information about the workflow
|
|
1493
1638
|
// in the headers (handled in getHeaders). QStash makes the request
|
|
@@ -1787,9 +1932,10 @@ var wrapTools = ({
|
|
|
1787
1932
|
return Object.fromEntries(
|
|
1788
1933
|
Object.entries(tools).map((toolInfo) => {
|
|
1789
1934
|
const [toolName, tool3] = toolInfo;
|
|
1935
|
+
const executeAsStep = "executeAsStep" in tool3 ? tool3.executeAsStep : true;
|
|
1790
1936
|
const aiSDKTool = convertToAISDKTool(tool3);
|
|
1791
1937
|
const execute = aiSDKTool.execute;
|
|
1792
|
-
if (execute) {
|
|
1938
|
+
if (execute && executeAsStep) {
|
|
1793
1939
|
const wrappedExecute = (...params) => {
|
|
1794
1940
|
return context.run(`Run tool ${toolName}`, () => execute(...params));
|
|
1795
1941
|
};
|
|
@@ -1810,6 +1956,37 @@ var convertLangchainTool = (langchainTool) => {
|
|
|
1810
1956
|
execute: async (...param) => langchainTool.invoke(...param)
|
|
1811
1957
|
});
|
|
1812
1958
|
};
|
|
1959
|
+
var WorkflowTool = class {
|
|
1960
|
+
/**
|
|
1961
|
+
* description of the tool
|
|
1962
|
+
*/
|
|
1963
|
+
description;
|
|
1964
|
+
/**
|
|
1965
|
+
* schema of the tool
|
|
1966
|
+
*/
|
|
1967
|
+
schema;
|
|
1968
|
+
/**
|
|
1969
|
+
* function to invoke the tool
|
|
1970
|
+
*/
|
|
1971
|
+
invoke;
|
|
1972
|
+
/**
|
|
1973
|
+
* whether the invoke method of the tool is to be wrapped with `context.run`
|
|
1974
|
+
*/
|
|
1975
|
+
executeAsStep;
|
|
1976
|
+
/**
|
|
1977
|
+
*
|
|
1978
|
+
* @param description description of the tool
|
|
1979
|
+
* @param schema schema of the tool
|
|
1980
|
+
* @param invoke function to invoke the tool
|
|
1981
|
+
* @param executeAsStep whether the invoke method of the tool is to be wrapped with `context.run`
|
|
1982
|
+
*/
|
|
1983
|
+
constructor(params) {
|
|
1984
|
+
this.description = params.description;
|
|
1985
|
+
this.schema = params.schema;
|
|
1986
|
+
this.invoke = params.invoke;
|
|
1987
|
+
this.executeAsStep = params.executeAsStep ?? true;
|
|
1988
|
+
}
|
|
1989
|
+
};
|
|
1813
1990
|
|
|
1814
1991
|
// src/agents/agent.ts
|
|
1815
1992
|
var import_zod = require("zod");
|
|
@@ -2143,6 +2320,11 @@ var WorkflowContext = class {
|
|
|
2143
2320
|
* Number of retries
|
|
2144
2321
|
*/
|
|
2145
2322
|
retries;
|
|
2323
|
+
/**
|
|
2324
|
+
* Settings for controlling the number of active requests
|
|
2325
|
+
* and number of requests per second with the same key.
|
|
2326
|
+
*/
|
|
2327
|
+
flowControl;
|
|
2146
2328
|
constructor({
|
|
2147
2329
|
qstashClient,
|
|
2148
2330
|
workflowRunId,
|
|
@@ -2154,7 +2336,9 @@ var WorkflowContext = class {
|
|
|
2154
2336
|
initialPayload,
|
|
2155
2337
|
env,
|
|
2156
2338
|
retries,
|
|
2157
|
-
telemetry
|
|
2339
|
+
telemetry,
|
|
2340
|
+
invokeCount,
|
|
2341
|
+
flowControl
|
|
2158
2342
|
}) {
|
|
2159
2343
|
this.qstashClient = qstashClient;
|
|
2160
2344
|
this.workflowRunId = workflowRunId;
|
|
@@ -2165,7 +2349,8 @@ var WorkflowContext = class {
|
|
|
2165
2349
|
this.requestPayload = initialPayload;
|
|
2166
2350
|
this.env = env ?? {};
|
|
2167
2351
|
this.retries = retries ?? DEFAULT_RETRIES;
|
|
2168
|
-
this.
|
|
2352
|
+
this.flowControl = flowControl;
|
|
2353
|
+
this.executor = new AutoExecutor(this, this.steps, telemetry, invokeCount, debug);
|
|
2169
2354
|
}
|
|
2170
2355
|
/**
|
|
2171
2356
|
* Executes a workflow step
|
|
@@ -2267,7 +2452,7 @@ var WorkflowContext = class {
|
|
|
2267
2452
|
* }
|
|
2268
2453
|
*/
|
|
2269
2454
|
async call(stepName, settings) {
|
|
2270
|
-
const { url, method = "GET", body, headers = {}, retries = 0, timeout } = settings;
|
|
2455
|
+
const { url, method = "GET", body, headers = {}, retries = 0, timeout, flowControl } = settings;
|
|
2271
2456
|
const result = await this.addStep(
|
|
2272
2457
|
new LazyCallStep(
|
|
2273
2458
|
stepName,
|
|
@@ -2276,7 +2461,8 @@ var WorkflowContext = class {
|
|
|
2276
2461
|
body,
|
|
2277
2462
|
headers,
|
|
2278
2463
|
retries,
|
|
2279
|
-
timeout
|
|
2464
|
+
timeout,
|
|
2465
|
+
flowControl
|
|
2280
2466
|
)
|
|
2281
2467
|
);
|
|
2282
2468
|
if (typeof result === "string") {
|
|
@@ -2513,7 +2699,8 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
2513
2699
|
failureUrl: context.failureUrl,
|
|
2514
2700
|
initialPayload: context.requestPayload,
|
|
2515
2701
|
env: context.env,
|
|
2516
|
-
retries: context.retries
|
|
2702
|
+
retries: context.retries,
|
|
2703
|
+
flowControl: context.flowControl
|
|
2517
2704
|
});
|
|
2518
2705
|
try {
|
|
2519
2706
|
await routeFunction(disabledContext);
|
|
@@ -2666,7 +2853,7 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
|
|
|
2666
2853
|
};
|
|
2667
2854
|
}
|
|
2668
2855
|
};
|
|
2669
|
-
var handleFailure = async (request, requestPayload, qstashClient, initialPayloadParser, routeFunction, failureFunction, env, retries, debug) => {
|
|
2856
|
+
var handleFailure = async (request, requestPayload, qstashClient, initialPayloadParser, routeFunction, failureFunction, env, retries, flowControl, debug) => {
|
|
2670
2857
|
if (request.headers.get(WORKFLOW_FAILURE_HEADER) !== "true") {
|
|
2671
2858
|
return ok("not-failure-callback");
|
|
2672
2859
|
}
|
|
@@ -2678,22 +2865,21 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
|
|
|
2678
2865
|
);
|
|
2679
2866
|
}
|
|
2680
2867
|
try {
|
|
2681
|
-
const { status, header, body, url,
|
|
2682
|
-
requestPayload
|
|
2683
|
-
);
|
|
2868
|
+
const { status, header, body, url, sourceBody, workflowRunId } = JSON.parse(requestPayload);
|
|
2684
2869
|
const decodedBody = body ? decodeBase64(body) : "{}";
|
|
2685
2870
|
const errorPayload = JSON.parse(decodedBody);
|
|
2686
2871
|
const workflowContext = new WorkflowContext({
|
|
2687
2872
|
qstashClient,
|
|
2688
2873
|
workflowRunId,
|
|
2689
2874
|
initialPayload: sourceBody ? initialPayloadParser(decodeBase64(sourceBody)) : void 0,
|
|
2690
|
-
headers: recreateUserHeaders(
|
|
2875
|
+
headers: recreateUserHeaders(request.headers),
|
|
2691
2876
|
steps: [],
|
|
2692
2877
|
url,
|
|
2693
2878
|
failureUrl: url,
|
|
2694
2879
|
debug,
|
|
2695
2880
|
env,
|
|
2696
2881
|
retries,
|
|
2882
|
+
flowControl,
|
|
2697
2883
|
telemetry: void 0
|
|
2698
2884
|
// not going to make requests in authentication check
|
|
2699
2885
|
});
|
|
@@ -2820,7 +3006,8 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
2820
3006
|
env,
|
|
2821
3007
|
retries,
|
|
2822
3008
|
useJSONContent,
|
|
2823
|
-
disableTelemetry
|
|
3009
|
+
disableTelemetry,
|
|
3010
|
+
flowControl
|
|
2824
3011
|
} = processOptions(options);
|
|
2825
3012
|
telemetry = disableTelemetry ? void 0 : telemetry;
|
|
2826
3013
|
const debug = WorkflowLogger.getLogger(verbose);
|
|
@@ -2861,6 +3048,7 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
2861
3048
|
failureFunction,
|
|
2862
3049
|
env,
|
|
2863
3050
|
retries,
|
|
3051
|
+
flowControl,
|
|
2864
3052
|
debug
|
|
2865
3053
|
);
|
|
2866
3054
|
if (failureCheck.isErr()) {
|
|
@@ -2869,6 +3057,7 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
2869
3057
|
await debug?.log("WARN", "RESPONSE_DEFAULT", "failureFunction executed");
|
|
2870
3058
|
return onStepFinish(workflowRunId, "failure-callback");
|
|
2871
3059
|
}
|
|
3060
|
+
const invokeCount = Number(request.headers.get(WORKFLOW_INVOKE_COUNT_HEADER) ?? "0");
|
|
2872
3061
|
const workflowContext = new WorkflowContext({
|
|
2873
3062
|
qstashClient,
|
|
2874
3063
|
workflowRunId,
|
|
@@ -2880,7 +3069,9 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
2880
3069
|
debug,
|
|
2881
3070
|
env,
|
|
2882
3071
|
retries,
|
|
2883
|
-
telemetry
|
|
3072
|
+
telemetry,
|
|
3073
|
+
invokeCount,
|
|
3074
|
+
flowControl
|
|
2884
3075
|
});
|
|
2885
3076
|
const authCheck = await DisabledWorkflowContext.tryAuthentication(
|
|
2886
3077
|
routeFunction,
|
|
@@ -2903,6 +3094,7 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
2903
3094
|
workflowUrl,
|
|
2904
3095
|
failureUrl: workflowFailureUrl,
|
|
2905
3096
|
retries,
|
|
3097
|
+
flowControl,
|
|
2906
3098
|
telemetry,
|
|
2907
3099
|
debug
|
|
2908
3100
|
});
|
|
@@ -2912,7 +3104,13 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
2912
3104
|
});
|
|
2913
3105
|
throw callReturnCheck.error;
|
|
2914
3106
|
} else if (callReturnCheck.value === "continue-workflow") {
|
|
2915
|
-
const result = isFirstInvocation ? await triggerFirstInvocation({
|
|
3107
|
+
const result = isFirstInvocation ? await triggerFirstInvocation({
|
|
3108
|
+
workflowContext,
|
|
3109
|
+
useJSONContent,
|
|
3110
|
+
telemetry,
|
|
3111
|
+
debug,
|
|
3112
|
+
invokeCount
|
|
3113
|
+
}) : await triggerRouteFunction({
|
|
2916
3114
|
onStep: async () => routeFunction(workflowContext),
|
|
2917
3115
|
onCleanup: async (result2) => {
|
|
2918
3116
|
await triggerWorkflowDelete(workflowContext, result2, debug);
|
|
@@ -3118,7 +3316,8 @@ var Client4 = class {
|
|
|
3118
3316
|
body,
|
|
3119
3317
|
headers,
|
|
3120
3318
|
workflowRunId,
|
|
3121
|
-
retries
|
|
3319
|
+
retries,
|
|
3320
|
+
flowControl
|
|
3122
3321
|
}) {
|
|
3123
3322
|
const finalWorkflowRunId = getWorkflowRunId(workflowRunId);
|
|
3124
3323
|
const context = new WorkflowContext({
|
|
@@ -3130,8 +3329,9 @@ var Client4 = class {
|
|
|
3130
3329
|
url,
|
|
3131
3330
|
workflowRunId: finalWorkflowRunId,
|
|
3132
3331
|
retries,
|
|
3133
|
-
telemetry: void 0
|
|
3332
|
+
telemetry: void 0,
|
|
3134
3333
|
// can't know workflow telemetry here
|
|
3334
|
+
flowControl
|
|
3135
3335
|
});
|
|
3136
3336
|
const result = await triggerFirstInvocation({
|
|
3137
3337
|
workflowContext: context,
|
|
@@ -3144,6 +3344,59 @@ var Client4 = class {
|
|
|
3144
3344
|
throw result.error;
|
|
3145
3345
|
}
|
|
3146
3346
|
}
|
|
3347
|
+
/**
|
|
3348
|
+
* Fetches logs for workflow runs.
|
|
3349
|
+
*
|
|
3350
|
+
* @param workflowRunId - The ID of the workflow run to fetch logs for.
|
|
3351
|
+
* @param cursor - The cursor for pagination.
|
|
3352
|
+
* @param count - Number of runs to fetch. Default value is 10.
|
|
3353
|
+
* @param state - The state of the workflow run.
|
|
3354
|
+
* @param workflowUrl - The URL of the workflow. Should be an exact match.
|
|
3355
|
+
* @param workflowCreatedAt - The creation time of the workflow. If you have two workflow runs with the same URL, you can use this to filter them.
|
|
3356
|
+
* @returns A promise that resolves to either a `WorkflowRunLog` or a `WorkflowRunResponse`.
|
|
3357
|
+
*
|
|
3358
|
+
* @example
|
|
3359
|
+
* Fetch logs for a specific workflow run:
|
|
3360
|
+
* ```typescript
|
|
3361
|
+
* const { runs } = await client.logs({ workflowRunId: '12345' });
|
|
3362
|
+
* const steps = runs[0].steps; // access steps
|
|
3363
|
+
* ```
|
|
3364
|
+
*
|
|
3365
|
+
* @example
|
|
3366
|
+
* Fetch logs with pagination:
|
|
3367
|
+
* ```typescript
|
|
3368
|
+
* const { runs, cursor } = await client.logs();
|
|
3369
|
+
* const steps = runs[0].steps // access steps
|
|
3370
|
+
*
|
|
3371
|
+
* const { runs: nextRuns, cursor: nextCursor } = await client.logs({ cursor, count: 2 });
|
|
3372
|
+
* ```
|
|
3373
|
+
*/
|
|
3374
|
+
async logs(params) {
|
|
3375
|
+
const { workflowRunId, cursor, count, state, workflowUrl, workflowCreatedAt } = params ?? {};
|
|
3376
|
+
const urlParams = new URLSearchParams({ groupBy: "workflowRunId" });
|
|
3377
|
+
if (workflowRunId) {
|
|
3378
|
+
urlParams.append("workflowRunId", workflowRunId);
|
|
3379
|
+
}
|
|
3380
|
+
if (cursor) {
|
|
3381
|
+
urlParams.append("cursor", cursor);
|
|
3382
|
+
}
|
|
3383
|
+
if (count) {
|
|
3384
|
+
urlParams.append("count", count.toString());
|
|
3385
|
+
}
|
|
3386
|
+
if (state) {
|
|
3387
|
+
urlParams.append("state", state);
|
|
3388
|
+
}
|
|
3389
|
+
if (workflowUrl) {
|
|
3390
|
+
urlParams.append("workflowUrl", workflowUrl);
|
|
3391
|
+
}
|
|
3392
|
+
if (workflowCreatedAt) {
|
|
3393
|
+
urlParams.append("workflowCreatedAt", workflowCreatedAt.toString());
|
|
3394
|
+
}
|
|
3395
|
+
const result = await this.client.http.request({
|
|
3396
|
+
path: ["v2", "workflows", `events?${urlParams.toString()}`]
|
|
3397
|
+
});
|
|
3398
|
+
return result;
|
|
3399
|
+
}
|
|
3147
3400
|
};
|
|
3148
3401
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3149
3402
|
0 && (module.exports = {
|
|
@@ -3153,5 +3406,6 @@ var Client4 = class {
|
|
|
3153
3406
|
WorkflowContext,
|
|
3154
3407
|
WorkflowError,
|
|
3155
3408
|
WorkflowLogger,
|
|
3409
|
+
WorkflowTool,
|
|
3156
3410
|
serve
|
|
3157
3411
|
});
|