@upstash/workflow 0.2.12 → 0.2.14
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 +2 -2
- package/astro.d.ts +2 -2
- package/astro.js +1254 -1072
- package/astro.mjs +1 -1
- package/{chunk-4GTHIL7S.mjs → chunk-RMS2NQ3K.mjs} +918 -734
- package/cloudflare.d.mts +2 -2
- package/cloudflare.d.ts +2 -2
- package/cloudflare.js +1254 -1072
- package/cloudflare.mjs +1 -1
- package/express.d.mts +2 -2
- package/express.d.ts +2 -2
- package/express.js +1270 -1088
- package/express.mjs +1 -1
- package/h3.d.mts +2 -2
- package/h3.d.ts +2 -2
- package/h3.js +1254 -1072
- package/h3.mjs +1 -1
- package/hono.d.mts +2 -2
- package/hono.d.ts +2 -2
- package/hono.js +1255 -1073
- package/hono.mjs +2 -2
- package/index.d.mts +124 -15
- package/index.d.ts +124 -15
- package/index.js +1259 -1101
- package/index.mjs +32 -56
- package/nextjs.d.mts +2 -2
- package/nextjs.d.ts +2 -2
- package/nextjs.js +1254 -1072
- package/nextjs.mjs +1 -1
- package/package.json +1 -1
- package/{serve-many-DLguU9iR.d.mts → serve-many-BF71QZHQ.d.mts} +1 -1
- package/{serve-many-BdMq5rFX.d.ts → serve-many-BMlN2PAB.d.ts} +1 -1
- package/solidjs.d.mts +1 -1
- package/solidjs.d.ts +1 -1
- package/solidjs.js +1220 -1038
- package/solidjs.mjs +1 -1
- package/svelte.d.mts +2 -2
- package/svelte.d.ts +2 -2
- package/svelte.js +1254 -1072
- package/svelte.mjs +1 -1
- package/{types-D1W0VOpy.d.ts → types-C1WIgVLA.d.mts} +58 -45
- package/{types-D1W0VOpy.d.mts → types-C1WIgVLA.d.ts} +58 -45
package/index.js
CHANGED
|
@@ -103,11 +103,12 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
|
|
|
103
103
|
var DEFAULT_CONTENT_TYPE = "application/json";
|
|
104
104
|
var NO_CONCURRENCY = 1;
|
|
105
105
|
var DEFAULT_RETRIES = 3;
|
|
106
|
-
var VERSION = "v0.2.
|
|
106
|
+
var VERSION = "v0.2.14";
|
|
107
107
|
var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
|
|
108
108
|
var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
|
|
109
109
|
var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
|
|
110
110
|
var TELEMETRY_HEADER_RUNTIME = "Upstash-Telemetry-Runtime";
|
|
111
|
+
var TELEMETRY_HEADER_AGENT = "Upstash-Telemetry-Agent";
|
|
111
112
|
|
|
112
113
|
// src/error.ts
|
|
113
114
|
var import_qstash2 = require("@upstash/qstash");
|
|
@@ -150,6 +151,12 @@ var formatWorkflowError = (error) => {
|
|
|
150
151
|
};
|
|
151
152
|
};
|
|
152
153
|
|
|
154
|
+
// src/context/auto-executor.ts
|
|
155
|
+
var import_qstash5 = require("@upstash/qstash");
|
|
156
|
+
|
|
157
|
+
// src/qstash/headers.ts
|
|
158
|
+
var import_qstash4 = require("@upstash/qstash");
|
|
159
|
+
|
|
153
160
|
// src/utils.ts
|
|
154
161
|
var NANOID_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
|
|
155
162
|
var NANOID_LENGTH = 21;
|
|
@@ -175,574 +182,231 @@ function decodeBase64(base64) {
|
|
|
175
182
|
}
|
|
176
183
|
}
|
|
177
184
|
|
|
178
|
-
//
|
|
179
|
-
var
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
185
|
+
// node_modules/neverthrow/dist/index.es.js
|
|
186
|
+
var defaultErrorConfig = {
|
|
187
|
+
withStackTrace: false
|
|
188
|
+
};
|
|
189
|
+
var createNeverThrowError = (message, result, config = defaultErrorConfig) => {
|
|
190
|
+
const data = result.isOk() ? { type: "Ok", value: result.value } : { type: "Err", value: result.error };
|
|
191
|
+
const maybeStack = config.withStackTrace ? new Error().stack : void 0;
|
|
192
|
+
return {
|
|
193
|
+
data,
|
|
194
|
+
message,
|
|
195
|
+
stack: maybeStack
|
|
196
|
+
};
|
|
197
|
+
};
|
|
198
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
199
|
+
function adopt(value) {
|
|
200
|
+
return value instanceof P ? value : new P(function(resolve) {
|
|
201
|
+
resolve(value);
|
|
202
|
+
});
|
|
188
203
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
* @returns parsed out field
|
|
196
|
-
*/
|
|
197
|
-
parseOut(out) {
|
|
198
|
-
if (out === void 0) {
|
|
199
|
-
if (this.allowUndefinedOut) {
|
|
200
|
-
return void 0;
|
|
201
|
-
} else {
|
|
202
|
-
throw new WorkflowError(
|
|
203
|
-
`Error while parsing output of ${this.stepType} step. Expected a string, but got: undefined`
|
|
204
|
-
);
|
|
204
|
+
return new (P || (P = Promise))(function(resolve, reject) {
|
|
205
|
+
function fulfilled(value) {
|
|
206
|
+
try {
|
|
207
|
+
step(generator.next(value));
|
|
208
|
+
} catch (e) {
|
|
209
|
+
reject(e);
|
|
205
210
|
}
|
|
206
211
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
);
|
|
212
|
-
return out;
|
|
212
|
+
function rejected(value) {
|
|
213
|
+
try {
|
|
214
|
+
step(generator["throw"](value));
|
|
215
|
+
} catch (e) {
|
|
216
|
+
reject(e);
|
|
213
217
|
}
|
|
214
|
-
return {
|
|
215
|
-
...out,
|
|
216
|
-
eventData: _BaseLazyStep.tryParsing(out.eventData)
|
|
217
|
-
};
|
|
218
218
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
`Error while parsing output of ${this.stepType} step. Expected a string or undefined, but got: ${typeof out}`
|
|
222
|
-
);
|
|
219
|
+
function step(result) {
|
|
220
|
+
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
223
221
|
}
|
|
224
|
-
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
|
|
222
|
+
step((generator = generator.apply(thisArg, [])).next());
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
function __values(o) {
|
|
226
|
+
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
227
|
+
if (m) return m.call(o);
|
|
228
|
+
if (o && typeof o.length === "number") return {
|
|
229
|
+
next: function() {
|
|
230
|
+
if (o && i >= o.length) o = void 0;
|
|
231
|
+
return { value: o && o[i++], done: !o };
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
235
|
+
}
|
|
236
|
+
function __await(v) {
|
|
237
|
+
return this instanceof __await ? (this.v = v, this) : new __await(v);
|
|
238
|
+
}
|
|
239
|
+
function __asyncGenerator(thisArg, _arguments, generator) {
|
|
240
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
241
|
+
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
|
242
|
+
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() {
|
|
243
|
+
return this;
|
|
244
|
+
}, i;
|
|
245
|
+
function verb(n) {
|
|
246
|
+
if (g[n]) i[n] = function(v) {
|
|
247
|
+
return new Promise(function(a, b) {
|
|
248
|
+
q.push([n, v, a, b]) > 1 || resume(n, v);
|
|
249
|
+
});
|
|
250
|
+
};
|
|
228
251
|
}
|
|
229
|
-
|
|
252
|
+
function resume(n, v) {
|
|
230
253
|
try {
|
|
231
|
-
|
|
232
|
-
} catch {
|
|
233
|
-
|
|
254
|
+
step(g[n](v));
|
|
255
|
+
} catch (e) {
|
|
256
|
+
settle(q[0][3], e);
|
|
234
257
|
}
|
|
235
258
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
stepFunction;
|
|
239
|
-
stepType = "Run";
|
|
240
|
-
allowUndefinedOut = true;
|
|
241
|
-
constructor(stepName, stepFunction) {
|
|
242
|
-
super(stepName);
|
|
243
|
-
this.stepFunction = stepFunction;
|
|
259
|
+
function step(r) {
|
|
260
|
+
r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r);
|
|
244
261
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
stepId: 0,
|
|
248
|
-
stepName: this.stepName,
|
|
249
|
-
stepType: this.stepType,
|
|
250
|
-
concurrent,
|
|
251
|
-
targetStep
|
|
252
|
-
};
|
|
262
|
+
function fulfill(value) {
|
|
263
|
+
resume("next", value);
|
|
253
264
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
if (result instanceof Promise) {
|
|
257
|
-
result = await result;
|
|
258
|
-
}
|
|
259
|
-
return {
|
|
260
|
-
stepId,
|
|
261
|
-
stepName: this.stepName,
|
|
262
|
-
stepType: this.stepType,
|
|
263
|
-
out: result,
|
|
264
|
-
concurrent
|
|
265
|
-
};
|
|
265
|
+
function reject(value) {
|
|
266
|
+
resume("throw", value);
|
|
266
267
|
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
sleep;
|
|
270
|
-
stepType = "SleepFor";
|
|
271
|
-
allowUndefinedOut = true;
|
|
272
|
-
constructor(stepName, sleep) {
|
|
273
|
-
super(stepName);
|
|
274
|
-
this.sleep = sleep;
|
|
268
|
+
function settle(f, v) {
|
|
269
|
+
if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]);
|
|
275
270
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
271
|
+
}
|
|
272
|
+
function __asyncDelegator(o) {
|
|
273
|
+
var i, p;
|
|
274
|
+
return i = {}, verb("next"), verb("throw", function(e) {
|
|
275
|
+
throw e;
|
|
276
|
+
}), verb("return"), i[Symbol.iterator] = function() {
|
|
277
|
+
return this;
|
|
278
|
+
}, i;
|
|
279
|
+
function verb(n, f) {
|
|
280
|
+
i[n] = o[n] ? function(v) {
|
|
281
|
+
return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v;
|
|
282
|
+
} : f;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
function __asyncValues(o) {
|
|
286
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
287
|
+
var m = o[Symbol.asyncIterator], i;
|
|
288
|
+
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() {
|
|
289
|
+
return this;
|
|
290
|
+
}, i);
|
|
291
|
+
function verb(n) {
|
|
292
|
+
i[n] = o[n] && function(v) {
|
|
293
|
+
return new Promise(function(resolve, reject) {
|
|
294
|
+
v = o[n](v), settle(resolve, reject, v.done, v.value);
|
|
295
|
+
});
|
|
284
296
|
};
|
|
285
297
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
stepType: this.stepType,
|
|
291
|
-
sleepFor: this.sleep,
|
|
292
|
-
concurrent
|
|
293
|
-
});
|
|
298
|
+
function settle(resolve, reject, d, v) {
|
|
299
|
+
Promise.resolve(v).then(function(v2) {
|
|
300
|
+
resolve({ value: v2, done: d });
|
|
301
|
+
}, reject);
|
|
294
302
|
}
|
|
295
|
-
}
|
|
296
|
-
var
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
allowUndefinedOut = true;
|
|
300
|
-
constructor(stepName, sleepUntil) {
|
|
301
|
-
super(stepName);
|
|
302
|
-
this.sleepUntil = sleepUntil;
|
|
303
|
+
}
|
|
304
|
+
var ResultAsync = class _ResultAsync {
|
|
305
|
+
constructor(res) {
|
|
306
|
+
this._promise = res;
|
|
303
307
|
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
stepName: this.stepName,
|
|
308
|
-
stepType: this.stepType,
|
|
309
|
-
sleepUntil: this.sleepUntil,
|
|
310
|
-
concurrent,
|
|
311
|
-
targetStep
|
|
312
|
-
};
|
|
308
|
+
static fromSafePromise(promise) {
|
|
309
|
+
const newPromise = promise.then((value) => new Ok(value));
|
|
310
|
+
return new _ResultAsync(newPromise);
|
|
313
311
|
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
stepName: this.stepName,
|
|
318
|
-
stepType: this.stepType,
|
|
319
|
-
sleepUntil: this.sleepUntil,
|
|
320
|
-
concurrent
|
|
321
|
-
});
|
|
312
|
+
static fromPromise(promise, errorFn) {
|
|
313
|
+
const newPromise = promise.then((value) => new Ok(value)).catch((e) => new Err(errorFn(e)));
|
|
314
|
+
return new _ResultAsync(newPromise);
|
|
322
315
|
}
|
|
323
|
-
|
|
324
|
-
|
|
316
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
317
|
+
static fromThrowable(fn, errorFn) {
|
|
318
|
+
return (...args) => {
|
|
319
|
+
return new _ResultAsync((() => __awaiter(this, void 0, void 0, function* () {
|
|
320
|
+
try {
|
|
321
|
+
return new Ok(yield fn(...args));
|
|
322
|
+
} catch (error) {
|
|
323
|
+
return new Err(errorFn ? errorFn(error) : error);
|
|
324
|
+
}
|
|
325
|
+
}))());
|
|
326
|
+
};
|
|
325
327
|
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
url;
|
|
329
|
-
method;
|
|
330
|
-
body;
|
|
331
|
-
headers;
|
|
332
|
-
retries;
|
|
333
|
-
timeout;
|
|
334
|
-
flowControl;
|
|
335
|
-
stepType = "Call";
|
|
336
|
-
allowUndefinedOut = false;
|
|
337
|
-
constructor(stepName, url, method, body, headers, retries, timeout, flowControl) {
|
|
338
|
-
super(stepName);
|
|
339
|
-
this.url = url;
|
|
340
|
-
this.method = method;
|
|
341
|
-
this.body = body;
|
|
342
|
-
this.headers = headers;
|
|
343
|
-
this.retries = retries;
|
|
344
|
-
this.timeout = timeout;
|
|
345
|
-
this.flowControl = flowControl;
|
|
346
|
-
}
|
|
347
|
-
getPlanStep(concurrent, targetStep) {
|
|
348
|
-
return {
|
|
349
|
-
stepId: 0,
|
|
350
|
-
stepName: this.stepName,
|
|
351
|
-
stepType: this.stepType,
|
|
352
|
-
concurrent,
|
|
353
|
-
targetStep
|
|
354
|
-
};
|
|
328
|
+
static combine(asyncResultList) {
|
|
329
|
+
return combineResultAsyncList(asyncResultList);
|
|
355
330
|
}
|
|
356
|
-
|
|
357
|
-
return
|
|
358
|
-
stepId,
|
|
359
|
-
stepName: this.stepName,
|
|
360
|
-
stepType: this.stepType,
|
|
361
|
-
concurrent,
|
|
362
|
-
callUrl: this.url,
|
|
363
|
-
callMethod: this.method,
|
|
364
|
-
callBody: this.body,
|
|
365
|
-
callHeaders: this.headers
|
|
366
|
-
});
|
|
331
|
+
static combineWithAllErrors(asyncResultList) {
|
|
332
|
+
return combineResultAsyncListWithAllErrors(asyncResultList);
|
|
367
333
|
}
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
const bytes = new Uint8Array(out.length);
|
|
373
|
-
for (let i = 0; i < out.length; i++) {
|
|
374
|
-
bytes[i] = out.charCodeAt(i);
|
|
334
|
+
map(f) {
|
|
335
|
+
return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
|
|
336
|
+
if (res.isErr()) {
|
|
337
|
+
return new Err(res.error);
|
|
375
338
|
}
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
return {
|
|
379
|
-
status,
|
|
380
|
-
header,
|
|
381
|
-
body: BaseLazyStep.tryParsing(newBody)
|
|
382
|
-
};
|
|
383
|
-
} else {
|
|
384
|
-
return { header, status, body };
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
static applicationHeaders = /* @__PURE__ */ new Set([
|
|
388
|
-
"application/json",
|
|
389
|
-
"application/xml",
|
|
390
|
-
"application/javascript",
|
|
391
|
-
"application/x-www-form-urlencoded",
|
|
392
|
-
"application/xhtml+xml",
|
|
393
|
-
"application/ld+json",
|
|
394
|
-
"application/rss+xml",
|
|
395
|
-
"application/atom+xml"
|
|
396
|
-
]);
|
|
397
|
-
static isText = (contentTypeHeader) => {
|
|
398
|
-
if (!contentTypeHeader) {
|
|
399
|
-
return false;
|
|
400
|
-
}
|
|
401
|
-
if (_LazyCallStep.applicationHeaders.has(contentTypeHeader)) {
|
|
402
|
-
return true;
|
|
403
|
-
}
|
|
404
|
-
if (contentTypeHeader.startsWith("text/")) {
|
|
405
|
-
return true;
|
|
406
|
-
}
|
|
407
|
-
return false;
|
|
408
|
-
};
|
|
409
|
-
};
|
|
410
|
-
var LazyWaitForEventStep = class extends BaseLazyStep {
|
|
411
|
-
eventId;
|
|
412
|
-
timeout;
|
|
413
|
-
stepType = "Wait";
|
|
414
|
-
allowUndefinedOut = false;
|
|
415
|
-
constructor(stepName, eventId, timeout) {
|
|
416
|
-
super(stepName);
|
|
417
|
-
this.eventId = eventId;
|
|
418
|
-
this.timeout = timeout;
|
|
339
|
+
return new Ok(yield f(res.value));
|
|
340
|
+
})));
|
|
419
341
|
}
|
|
420
|
-
|
|
421
|
-
return {
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
342
|
+
andThrough(f) {
|
|
343
|
+
return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
|
|
344
|
+
if (res.isErr()) {
|
|
345
|
+
return new Err(res.error);
|
|
346
|
+
}
|
|
347
|
+
const newRes = yield f(res.value);
|
|
348
|
+
if (newRes.isErr()) {
|
|
349
|
+
return new Err(newRes.error);
|
|
350
|
+
}
|
|
351
|
+
return new Ok(res.value);
|
|
352
|
+
})));
|
|
430
353
|
}
|
|
431
|
-
|
|
432
|
-
return
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
354
|
+
andTee(f) {
|
|
355
|
+
return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
|
|
356
|
+
if (res.isErr()) {
|
|
357
|
+
return new Err(res.error);
|
|
358
|
+
}
|
|
359
|
+
try {
|
|
360
|
+
yield f(res.value);
|
|
361
|
+
} catch (e) {
|
|
362
|
+
}
|
|
363
|
+
return new Ok(res.value);
|
|
364
|
+
})));
|
|
440
365
|
}
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
366
|
+
mapErr(f) {
|
|
367
|
+
return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
|
|
368
|
+
if (res.isOk()) {
|
|
369
|
+
return new Ok(res.value);
|
|
370
|
+
}
|
|
371
|
+
return new Err(yield f(res.error));
|
|
372
|
+
})));
|
|
447
373
|
}
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
notifyResponse
|
|
458
|
-
};
|
|
459
|
-
});
|
|
374
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
|
|
375
|
+
andThen(f) {
|
|
376
|
+
return new _ResultAsync(this._promise.then((res) => {
|
|
377
|
+
if (res.isErr()) {
|
|
378
|
+
return new Err(res.error);
|
|
379
|
+
}
|
|
380
|
+
const newValue = f(res.value);
|
|
381
|
+
return newValue instanceof _ResultAsync ? newValue._promise : newValue;
|
|
382
|
+
}));
|
|
460
383
|
}
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
return {
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
384
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
|
|
385
|
+
orElse(f) {
|
|
386
|
+
return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
|
|
387
|
+
if (res.isErr()) {
|
|
388
|
+
return f(res.error);
|
|
389
|
+
}
|
|
390
|
+
return new Ok(res.value);
|
|
391
|
+
})));
|
|
467
392
|
}
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
stepType = "Invoke";
|
|
471
|
-
params;
|
|
472
|
-
allowUndefinedOut = false;
|
|
473
|
-
constructor(stepName, {
|
|
474
|
-
workflow,
|
|
475
|
-
body,
|
|
476
|
-
headers = {},
|
|
477
|
-
workflowRunId,
|
|
478
|
-
retries,
|
|
479
|
-
flowControl
|
|
480
|
-
}) {
|
|
481
|
-
super(stepName);
|
|
482
|
-
this.params = {
|
|
483
|
-
workflow,
|
|
484
|
-
body,
|
|
485
|
-
headers,
|
|
486
|
-
workflowRunId: getWorkflowRunId(workflowRunId),
|
|
487
|
-
retries,
|
|
488
|
-
flowControl
|
|
489
|
-
};
|
|
393
|
+
match(ok2, _err) {
|
|
394
|
+
return this._promise.then((res) => res.match(ok2, _err));
|
|
490
395
|
}
|
|
491
|
-
|
|
492
|
-
return
|
|
493
|
-
stepId: 0,
|
|
494
|
-
stepName: this.stepName,
|
|
495
|
-
stepType: this.stepType,
|
|
496
|
-
concurrent,
|
|
497
|
-
targetStep
|
|
498
|
-
};
|
|
396
|
+
unwrapOr(t) {
|
|
397
|
+
return this._promise.then((res) => res.unwrapOr(t));
|
|
499
398
|
}
|
|
500
399
|
/**
|
|
501
|
-
*
|
|
502
|
-
* in Invoke step.
|
|
400
|
+
* Emulates Rust's `?` operator in `safeTry`'s body. See also `safeTry`.
|
|
503
401
|
*/
|
|
504
|
-
|
|
505
|
-
return
|
|
506
|
-
|
|
507
|
-
stepName: this.stepName,
|
|
508
|
-
stepType: this.stepType,
|
|
509
|
-
concurrent
|
|
402
|
+
safeUnwrap() {
|
|
403
|
+
return __asyncGenerator(this, arguments, function* safeUnwrap_1() {
|
|
404
|
+
return yield __await(yield __await(yield* __asyncDelegator(__asyncValues(yield __await(this._promise.then((res) => res.safeUnwrap()))))));
|
|
510
405
|
});
|
|
511
406
|
}
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
return
|
|
515
|
-
...result,
|
|
516
|
-
body: BaseLazyStep.tryParsing(result.body)
|
|
517
|
-
};
|
|
518
|
-
}
|
|
519
|
-
};
|
|
520
|
-
|
|
521
|
-
// node_modules/neverthrow/dist/index.es.js
|
|
522
|
-
var defaultErrorConfig = {
|
|
523
|
-
withStackTrace: false
|
|
524
|
-
};
|
|
525
|
-
var createNeverThrowError = (message, result, config = defaultErrorConfig) => {
|
|
526
|
-
const data = result.isOk() ? { type: "Ok", value: result.value } : { type: "Err", value: result.error };
|
|
527
|
-
const maybeStack = config.withStackTrace ? new Error().stack : void 0;
|
|
528
|
-
return {
|
|
529
|
-
data,
|
|
530
|
-
message,
|
|
531
|
-
stack: maybeStack
|
|
532
|
-
};
|
|
533
|
-
};
|
|
534
|
-
function __awaiter(thisArg, _arguments, P, generator) {
|
|
535
|
-
function adopt(value) {
|
|
536
|
-
return value instanceof P ? value : new P(function(resolve) {
|
|
537
|
-
resolve(value);
|
|
538
|
-
});
|
|
539
|
-
}
|
|
540
|
-
return new (P || (P = Promise))(function(resolve, reject) {
|
|
541
|
-
function fulfilled(value) {
|
|
542
|
-
try {
|
|
543
|
-
step(generator.next(value));
|
|
544
|
-
} catch (e) {
|
|
545
|
-
reject(e);
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
function rejected(value) {
|
|
549
|
-
try {
|
|
550
|
-
step(generator["throw"](value));
|
|
551
|
-
} catch (e) {
|
|
552
|
-
reject(e);
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
function step(result) {
|
|
556
|
-
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
557
|
-
}
|
|
558
|
-
step((generator = generator.apply(thisArg, [])).next());
|
|
559
|
-
});
|
|
560
|
-
}
|
|
561
|
-
function __values(o) {
|
|
562
|
-
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
563
|
-
if (m) return m.call(o);
|
|
564
|
-
if (o && typeof o.length === "number") return {
|
|
565
|
-
next: function() {
|
|
566
|
-
if (o && i >= o.length) o = void 0;
|
|
567
|
-
return { value: o && o[i++], done: !o };
|
|
568
|
-
}
|
|
569
|
-
};
|
|
570
|
-
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
571
|
-
}
|
|
572
|
-
function __await(v) {
|
|
573
|
-
return this instanceof __await ? (this.v = v, this) : new __await(v);
|
|
574
|
-
}
|
|
575
|
-
function __asyncGenerator(thisArg, _arguments, generator) {
|
|
576
|
-
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
577
|
-
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
|
578
|
-
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() {
|
|
579
|
-
return this;
|
|
580
|
-
}, i;
|
|
581
|
-
function verb(n) {
|
|
582
|
-
if (g[n]) i[n] = function(v) {
|
|
583
|
-
return new Promise(function(a, b) {
|
|
584
|
-
q.push([n, v, a, b]) > 1 || resume(n, v);
|
|
585
|
-
});
|
|
586
|
-
};
|
|
587
|
-
}
|
|
588
|
-
function resume(n, v) {
|
|
589
|
-
try {
|
|
590
|
-
step(g[n](v));
|
|
591
|
-
} catch (e) {
|
|
592
|
-
settle(q[0][3], e);
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
function step(r) {
|
|
596
|
-
r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r);
|
|
597
|
-
}
|
|
598
|
-
function fulfill(value) {
|
|
599
|
-
resume("next", value);
|
|
600
|
-
}
|
|
601
|
-
function reject(value) {
|
|
602
|
-
resume("throw", value);
|
|
603
|
-
}
|
|
604
|
-
function settle(f, v) {
|
|
605
|
-
if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]);
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
function __asyncDelegator(o) {
|
|
609
|
-
var i, p;
|
|
610
|
-
return i = {}, verb("next"), verb("throw", function(e) {
|
|
611
|
-
throw e;
|
|
612
|
-
}), verb("return"), i[Symbol.iterator] = function() {
|
|
613
|
-
return this;
|
|
614
|
-
}, i;
|
|
615
|
-
function verb(n, f) {
|
|
616
|
-
i[n] = o[n] ? function(v) {
|
|
617
|
-
return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v;
|
|
618
|
-
} : f;
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
function __asyncValues(o) {
|
|
622
|
-
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
623
|
-
var m = o[Symbol.asyncIterator], i;
|
|
624
|
-
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() {
|
|
625
|
-
return this;
|
|
626
|
-
}, i);
|
|
627
|
-
function verb(n) {
|
|
628
|
-
i[n] = o[n] && function(v) {
|
|
629
|
-
return new Promise(function(resolve, reject) {
|
|
630
|
-
v = o[n](v), settle(resolve, reject, v.done, v.value);
|
|
631
|
-
});
|
|
632
|
-
};
|
|
633
|
-
}
|
|
634
|
-
function settle(resolve, reject, d, v) {
|
|
635
|
-
Promise.resolve(v).then(function(v2) {
|
|
636
|
-
resolve({ value: v2, done: d });
|
|
637
|
-
}, reject);
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
var ResultAsync = class _ResultAsync {
|
|
641
|
-
constructor(res) {
|
|
642
|
-
this._promise = res;
|
|
643
|
-
}
|
|
644
|
-
static fromSafePromise(promise) {
|
|
645
|
-
const newPromise = promise.then((value) => new Ok(value));
|
|
646
|
-
return new _ResultAsync(newPromise);
|
|
647
|
-
}
|
|
648
|
-
static fromPromise(promise, errorFn) {
|
|
649
|
-
const newPromise = promise.then((value) => new Ok(value)).catch((e) => new Err(errorFn(e)));
|
|
650
|
-
return new _ResultAsync(newPromise);
|
|
651
|
-
}
|
|
652
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
653
|
-
static fromThrowable(fn, errorFn) {
|
|
654
|
-
return (...args) => {
|
|
655
|
-
return new _ResultAsync((() => __awaiter(this, void 0, void 0, function* () {
|
|
656
|
-
try {
|
|
657
|
-
return new Ok(yield fn(...args));
|
|
658
|
-
} catch (error) {
|
|
659
|
-
return new Err(errorFn ? errorFn(error) : error);
|
|
660
|
-
}
|
|
661
|
-
}))());
|
|
662
|
-
};
|
|
663
|
-
}
|
|
664
|
-
static combine(asyncResultList) {
|
|
665
|
-
return combineResultAsyncList(asyncResultList);
|
|
666
|
-
}
|
|
667
|
-
static combineWithAllErrors(asyncResultList) {
|
|
668
|
-
return combineResultAsyncListWithAllErrors(asyncResultList);
|
|
669
|
-
}
|
|
670
|
-
map(f) {
|
|
671
|
-
return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
|
|
672
|
-
if (res.isErr()) {
|
|
673
|
-
return new Err(res.error);
|
|
674
|
-
}
|
|
675
|
-
return new Ok(yield f(res.value));
|
|
676
|
-
})));
|
|
677
|
-
}
|
|
678
|
-
andThrough(f) {
|
|
679
|
-
return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
|
|
680
|
-
if (res.isErr()) {
|
|
681
|
-
return new Err(res.error);
|
|
682
|
-
}
|
|
683
|
-
const newRes = yield f(res.value);
|
|
684
|
-
if (newRes.isErr()) {
|
|
685
|
-
return new Err(newRes.error);
|
|
686
|
-
}
|
|
687
|
-
return new Ok(res.value);
|
|
688
|
-
})));
|
|
689
|
-
}
|
|
690
|
-
andTee(f) {
|
|
691
|
-
return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
|
|
692
|
-
if (res.isErr()) {
|
|
693
|
-
return new Err(res.error);
|
|
694
|
-
}
|
|
695
|
-
try {
|
|
696
|
-
yield f(res.value);
|
|
697
|
-
} catch (e) {
|
|
698
|
-
}
|
|
699
|
-
return new Ok(res.value);
|
|
700
|
-
})));
|
|
701
|
-
}
|
|
702
|
-
mapErr(f) {
|
|
703
|
-
return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
|
|
704
|
-
if (res.isOk()) {
|
|
705
|
-
return new Ok(res.value);
|
|
706
|
-
}
|
|
707
|
-
return new Err(yield f(res.error));
|
|
708
|
-
})));
|
|
709
|
-
}
|
|
710
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
|
|
711
|
-
andThen(f) {
|
|
712
|
-
return new _ResultAsync(this._promise.then((res) => {
|
|
713
|
-
if (res.isErr()) {
|
|
714
|
-
return new Err(res.error);
|
|
715
|
-
}
|
|
716
|
-
const newValue = f(res.value);
|
|
717
|
-
return newValue instanceof _ResultAsync ? newValue._promise : newValue;
|
|
718
|
-
}));
|
|
719
|
-
}
|
|
720
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
|
|
721
|
-
orElse(f) {
|
|
722
|
-
return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
|
|
723
|
-
if (res.isErr()) {
|
|
724
|
-
return f(res.error);
|
|
725
|
-
}
|
|
726
|
-
return new Ok(res.value);
|
|
727
|
-
})));
|
|
728
|
-
}
|
|
729
|
-
match(ok2, _err) {
|
|
730
|
-
return this._promise.then((res) => res.match(ok2, _err));
|
|
731
|
-
}
|
|
732
|
-
unwrapOr(t) {
|
|
733
|
-
return this._promise.then((res) => res.unwrapOr(t));
|
|
734
|
-
}
|
|
735
|
-
/**
|
|
736
|
-
* Emulates Rust's `?` operator in `safeTry`'s body. See also `safeTry`.
|
|
737
|
-
*/
|
|
738
|
-
safeUnwrap() {
|
|
739
|
-
return __asyncGenerator(this, arguments, function* safeUnwrap_1() {
|
|
740
|
-
return yield __await(yield __await(yield* __asyncDelegator(__asyncValues(yield __await(this._promise.then((res) => res.safeUnwrap()))))));
|
|
741
|
-
});
|
|
742
|
-
}
|
|
743
|
-
// Makes ResultAsync implement PromiseLike<Result>
|
|
744
|
-
then(successCallback, failureCallback) {
|
|
745
|
-
return this._promise.then(successCallback, failureCallback);
|
|
407
|
+
// Makes ResultAsync implement PromiseLike<Result>
|
|
408
|
+
then(successCallback, failureCallback) {
|
|
409
|
+
return this._promise.then(successCallback, failureCallback);
|
|
746
410
|
}
|
|
747
411
|
};
|
|
748
412
|
var errAsync = (err2) => new ResultAsync(Promise.resolve(new Err(err2)));
|
|
@@ -947,54 +611,72 @@ var StepTypes = [
|
|
|
947
611
|
|
|
948
612
|
// src/workflow-requests.ts
|
|
949
613
|
var import_qstash3 = require("@upstash/qstash");
|
|
950
|
-
var triggerFirstInvocation = async ({
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
headers,
|
|
978
|
-
method: "POST",
|
|
979
|
-
body,
|
|
980
|
-
url: workflowContext.url
|
|
981
|
-
});
|
|
982
|
-
if (result.deduplicated) {
|
|
983
|
-
await debug?.log("WARN", "SUBMIT_FIRST_INVOCATION", {
|
|
984
|
-
message: `Workflow run ${workflowContext.workflowRunId} already exists. A new one isn't created.`,
|
|
614
|
+
var triggerFirstInvocation = async (params) => {
|
|
615
|
+
const firstInvocationParams = Array.isArray(params) ? params : [params];
|
|
616
|
+
const workflowContextClient = firstInvocationParams[0].workflowContext.qstashClient;
|
|
617
|
+
const invocationBatch = firstInvocationParams.map(
|
|
618
|
+
({ workflowContext, useJSONContent, telemetry, invokeCount, delay }) => {
|
|
619
|
+
const { headers } = getHeaders({
|
|
620
|
+
initHeaderValue: "true",
|
|
621
|
+
workflowConfig: {
|
|
622
|
+
workflowRunId: workflowContext.workflowRunId,
|
|
623
|
+
workflowUrl: workflowContext.url,
|
|
624
|
+
failureUrl: workflowContext.failureUrl,
|
|
625
|
+
retries: workflowContext.retries,
|
|
626
|
+
telemetry,
|
|
627
|
+
flowControl: workflowContext.flowControl,
|
|
628
|
+
useJSONContent: useJSONContent ?? false
|
|
629
|
+
},
|
|
630
|
+
invokeCount: invokeCount ?? 0,
|
|
631
|
+
userHeaders: workflowContext.headers
|
|
632
|
+
});
|
|
633
|
+
if (workflowContext.headers.get("content-type")) {
|
|
634
|
+
headers["content-type"] = workflowContext.headers.get("content-type");
|
|
635
|
+
}
|
|
636
|
+
if (useJSONContent) {
|
|
637
|
+
headers["content-type"] = "application/json";
|
|
638
|
+
}
|
|
639
|
+
const body = typeof workflowContext.requestPayload === "string" ? workflowContext.requestPayload : JSON.stringify(workflowContext.requestPayload);
|
|
640
|
+
return {
|
|
985
641
|
headers,
|
|
986
|
-
|
|
642
|
+
method: "POST",
|
|
643
|
+
body,
|
|
987
644
|
url: workflowContext.url,
|
|
988
|
-
|
|
989
|
-
}
|
|
645
|
+
delay
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
);
|
|
649
|
+
try {
|
|
650
|
+
const results = await workflowContextClient.batch(invocationBatch);
|
|
651
|
+
const invocationStatuses = [];
|
|
652
|
+
for (let i = 0; i < results.length; i++) {
|
|
653
|
+
const result = results[i];
|
|
654
|
+
const invocationParams = firstInvocationParams[i];
|
|
655
|
+
if (result.deduplicated) {
|
|
656
|
+
await invocationParams.debug?.log("WARN", "SUBMIT_FIRST_INVOCATION", {
|
|
657
|
+
message: `Workflow run ${invocationParams.workflowContext.workflowRunId} already exists. A new one isn't created.`,
|
|
658
|
+
headers: invocationBatch[i].headers,
|
|
659
|
+
requestPayload: invocationParams.workflowContext.requestPayload,
|
|
660
|
+
url: invocationParams.workflowContext.url,
|
|
661
|
+
messageId: result.messageId
|
|
662
|
+
});
|
|
663
|
+
invocationStatuses.push("workflow-run-already-exists");
|
|
664
|
+
} else {
|
|
665
|
+
await invocationParams.debug?.log("SUBMIT", "SUBMIT_FIRST_INVOCATION", {
|
|
666
|
+
headers: invocationBatch[i].headers,
|
|
667
|
+
requestPayload: invocationParams.workflowContext.requestPayload,
|
|
668
|
+
url: invocationParams.workflowContext.url,
|
|
669
|
+
messageId: result.messageId
|
|
670
|
+
});
|
|
671
|
+
invocationStatuses.push("success");
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
const hasAnyDeduplicated = invocationStatuses.some(
|
|
675
|
+
(status) => status === "workflow-run-already-exists"
|
|
676
|
+
);
|
|
677
|
+
if (hasAnyDeduplicated) {
|
|
990
678
|
return ok("workflow-run-already-exists");
|
|
991
679
|
} else {
|
|
992
|
-
await debug?.log("SUBMIT", "SUBMIT_FIRST_INVOCATION", {
|
|
993
|
-
headers,
|
|
994
|
-
requestPayload: workflowContext.requestPayload,
|
|
995
|
-
url: workflowContext.url,
|
|
996
|
-
messageId: result.messageId
|
|
997
|
-
});
|
|
998
680
|
return ok("success");
|
|
999
681
|
}
|
|
1000
682
|
} catch (error) {
|
|
@@ -1133,14 +815,16 @@ ${atob(callbackMessage.body ?? "")}`
|
|
|
1133
815
|
const userHeaders = recreateUserHeaders(request.headers);
|
|
1134
816
|
const { headers: requestHeaders } = getHeaders({
|
|
1135
817
|
initHeaderValue: "false",
|
|
1136
|
-
|
|
1137
|
-
|
|
818
|
+
workflowConfig: {
|
|
819
|
+
workflowRunId,
|
|
820
|
+
workflowUrl,
|
|
821
|
+
failureUrl,
|
|
822
|
+
retries,
|
|
823
|
+
telemetry,
|
|
824
|
+
flowControl
|
|
825
|
+
},
|
|
1138
826
|
userHeaders,
|
|
1139
|
-
|
|
1140
|
-
retries,
|
|
1141
|
-
telemetry,
|
|
1142
|
-
invokeCount: Number(invokeCount),
|
|
1143
|
-
flowControl
|
|
827
|
+
invokeCount: Number(invokeCount)
|
|
1144
828
|
});
|
|
1145
829
|
const callResponse = {
|
|
1146
830
|
status: callbackMessage.status,
|
|
@@ -1172,282 +856,913 @@ ${atob(callbackMessage.body ?? "")}`
|
|
|
1172
856
|
} else {
|
|
1173
857
|
return ok("continue-workflow");
|
|
1174
858
|
}
|
|
1175
|
-
} catch (error) {
|
|
1176
|
-
const isCallReturn = request.headers.get("Upstash-Workflow-Callback");
|
|
1177
|
-
return err(
|
|
1178
|
-
new WorkflowError(`Error when handling call return (isCallReturn=${isCallReturn}): ${error}`)
|
|
1179
|
-
);
|
|
859
|
+
} catch (error) {
|
|
860
|
+
const isCallReturn = request.headers.get("Upstash-Workflow-Callback");
|
|
861
|
+
return err(
|
|
862
|
+
new WorkflowError(`Error when handling call return (isCallReturn=${isCallReturn}): ${error}`)
|
|
863
|
+
);
|
|
864
|
+
}
|
|
865
|
+
};
|
|
866
|
+
var getTelemetryHeaders = (telemetry) => {
|
|
867
|
+
return {
|
|
868
|
+
[TELEMETRY_HEADER_SDK]: telemetry.sdk,
|
|
869
|
+
[TELEMETRY_HEADER_FRAMEWORK]: telemetry.framework,
|
|
870
|
+
[TELEMETRY_HEADER_RUNTIME]: telemetry.runtime ?? "unknown"
|
|
871
|
+
};
|
|
872
|
+
};
|
|
873
|
+
var verifyRequest = async (body, signature, verifier) => {
|
|
874
|
+
if (!verifier) {
|
|
875
|
+
return;
|
|
876
|
+
}
|
|
877
|
+
try {
|
|
878
|
+
if (!signature) {
|
|
879
|
+
throw new Error("`Upstash-Signature` header is not passed.");
|
|
880
|
+
}
|
|
881
|
+
const isValid = await verifier.verify({
|
|
882
|
+
body,
|
|
883
|
+
signature
|
|
884
|
+
});
|
|
885
|
+
if (!isValid) {
|
|
886
|
+
throw new Error("Signature in `Upstash-Signature` header is not valid");
|
|
887
|
+
}
|
|
888
|
+
} catch (error) {
|
|
889
|
+
throw new WorkflowError(
|
|
890
|
+
`Failed to verify that the Workflow request comes from QStash: ${error}
|
|
891
|
+
|
|
892
|
+
If signature is missing, trigger the workflow endpoint by publishing your request to QStash instead of calling it directly.
|
|
893
|
+
|
|
894
|
+
If you want to disable QStash Verification, you should clear env variables QSTASH_CURRENT_SIGNING_KEY and QSTASH_NEXT_SIGNING_KEY`
|
|
895
|
+
);
|
|
896
|
+
}
|
|
897
|
+
};
|
|
898
|
+
|
|
899
|
+
// src/context/steps.ts
|
|
900
|
+
var BaseLazyStep = class _BaseLazyStep {
|
|
901
|
+
stepName;
|
|
902
|
+
constructor(stepName) {
|
|
903
|
+
if (!stepName) {
|
|
904
|
+
throw new WorkflowError(
|
|
905
|
+
"A workflow step name cannot be undefined or an empty string. Please provide a name for your workflow step."
|
|
906
|
+
);
|
|
907
|
+
}
|
|
908
|
+
if (typeof stepName !== "string") {
|
|
909
|
+
console.warn(
|
|
910
|
+
"Workflow Warning: A workflow step name must be a string. In a future release, this will throw an error."
|
|
911
|
+
);
|
|
912
|
+
}
|
|
913
|
+
this.stepName = stepName;
|
|
914
|
+
}
|
|
915
|
+
/**
|
|
916
|
+
* parse the out field of a step result.
|
|
917
|
+
*
|
|
918
|
+
* will be called when returning the steps to the context from auto executor
|
|
919
|
+
*
|
|
920
|
+
* @param out field of the step
|
|
921
|
+
* @returns parsed out field
|
|
922
|
+
*/
|
|
923
|
+
parseOut(out) {
|
|
924
|
+
if (out === void 0) {
|
|
925
|
+
if (this.allowUndefinedOut) {
|
|
926
|
+
return void 0;
|
|
927
|
+
} else {
|
|
928
|
+
throw new WorkflowError(
|
|
929
|
+
`Error while parsing output of ${this.stepType} step. Expected a string, but got: undefined`
|
|
930
|
+
);
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
if (typeof out === "object") {
|
|
934
|
+
if (this.stepType !== "Wait") {
|
|
935
|
+
console.warn(
|
|
936
|
+
`Error while parsing ${this.stepType} step output. Expected a string, but got object. Please reach out to Upstash Support.`
|
|
937
|
+
);
|
|
938
|
+
return out;
|
|
939
|
+
}
|
|
940
|
+
return {
|
|
941
|
+
...out,
|
|
942
|
+
eventData: _BaseLazyStep.tryParsing(out.eventData)
|
|
943
|
+
};
|
|
944
|
+
}
|
|
945
|
+
if (typeof out !== "string") {
|
|
946
|
+
throw new WorkflowError(
|
|
947
|
+
`Error while parsing output of ${this.stepType} step. Expected a string or undefined, but got: ${typeof out}`
|
|
948
|
+
);
|
|
949
|
+
}
|
|
950
|
+
return this.safeParseOut(out);
|
|
951
|
+
}
|
|
952
|
+
safeParseOut(out) {
|
|
953
|
+
return _BaseLazyStep.tryParsing(out);
|
|
954
|
+
}
|
|
955
|
+
static tryParsing(stepOut) {
|
|
956
|
+
try {
|
|
957
|
+
return JSON.parse(stepOut);
|
|
958
|
+
} catch {
|
|
959
|
+
return stepOut;
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
getBody({ step }) {
|
|
963
|
+
step.out = JSON.stringify(step.out);
|
|
964
|
+
return JSON.stringify(step);
|
|
965
|
+
}
|
|
966
|
+
getHeaders({ context, telemetry, invokeCount, step }) {
|
|
967
|
+
return getHeaders({
|
|
968
|
+
initHeaderValue: "false",
|
|
969
|
+
workflowConfig: {
|
|
970
|
+
workflowRunId: context.workflowRunId,
|
|
971
|
+
workflowUrl: context.url,
|
|
972
|
+
failureUrl: context.failureUrl,
|
|
973
|
+
retries: context.retries,
|
|
974
|
+
useJSONContent: false,
|
|
975
|
+
telemetry,
|
|
976
|
+
flowControl: context.flowControl
|
|
977
|
+
},
|
|
978
|
+
userHeaders: context.headers,
|
|
979
|
+
invokeCount,
|
|
980
|
+
stepInfo: {
|
|
981
|
+
step,
|
|
982
|
+
lazyStep: this
|
|
983
|
+
}
|
|
984
|
+
});
|
|
985
|
+
}
|
|
986
|
+
async submitStep({ context, body, headers }) {
|
|
987
|
+
return await context.qstashClient.batch([
|
|
988
|
+
{
|
|
989
|
+
body,
|
|
990
|
+
headers,
|
|
991
|
+
method: "POST",
|
|
992
|
+
url: context.url
|
|
993
|
+
}
|
|
994
|
+
]);
|
|
995
|
+
}
|
|
996
|
+
};
|
|
997
|
+
var LazyFunctionStep = class extends BaseLazyStep {
|
|
998
|
+
stepFunction;
|
|
999
|
+
stepType = "Run";
|
|
1000
|
+
allowUndefinedOut = true;
|
|
1001
|
+
constructor(stepName, stepFunction) {
|
|
1002
|
+
super(stepName);
|
|
1003
|
+
this.stepFunction = stepFunction;
|
|
1004
|
+
}
|
|
1005
|
+
getPlanStep(concurrent, targetStep) {
|
|
1006
|
+
return {
|
|
1007
|
+
stepId: 0,
|
|
1008
|
+
stepName: this.stepName,
|
|
1009
|
+
stepType: this.stepType,
|
|
1010
|
+
concurrent,
|
|
1011
|
+
targetStep
|
|
1012
|
+
};
|
|
1013
|
+
}
|
|
1014
|
+
async getResultStep(concurrent, stepId) {
|
|
1015
|
+
let result = this.stepFunction();
|
|
1016
|
+
if (result instanceof Promise) {
|
|
1017
|
+
result = await result;
|
|
1018
|
+
}
|
|
1019
|
+
return {
|
|
1020
|
+
stepId,
|
|
1021
|
+
stepName: this.stepName,
|
|
1022
|
+
stepType: this.stepType,
|
|
1023
|
+
out: result,
|
|
1024
|
+
concurrent
|
|
1025
|
+
};
|
|
1026
|
+
}
|
|
1027
|
+
};
|
|
1028
|
+
var LazySleepStep = class extends BaseLazyStep {
|
|
1029
|
+
sleep;
|
|
1030
|
+
stepType = "SleepFor";
|
|
1031
|
+
allowUndefinedOut = true;
|
|
1032
|
+
constructor(stepName, sleep) {
|
|
1033
|
+
super(stepName);
|
|
1034
|
+
this.sleep = sleep;
|
|
1035
|
+
}
|
|
1036
|
+
getPlanStep(concurrent, targetStep) {
|
|
1037
|
+
return {
|
|
1038
|
+
stepId: 0,
|
|
1039
|
+
stepName: this.stepName,
|
|
1040
|
+
stepType: this.stepType,
|
|
1041
|
+
sleepFor: this.sleep,
|
|
1042
|
+
concurrent,
|
|
1043
|
+
targetStep
|
|
1044
|
+
};
|
|
1045
|
+
}
|
|
1046
|
+
async getResultStep(concurrent, stepId) {
|
|
1047
|
+
return await Promise.resolve({
|
|
1048
|
+
stepId,
|
|
1049
|
+
stepName: this.stepName,
|
|
1050
|
+
stepType: this.stepType,
|
|
1051
|
+
sleepFor: this.sleep,
|
|
1052
|
+
concurrent
|
|
1053
|
+
});
|
|
1054
|
+
}
|
|
1055
|
+
async submitStep({ context, body, headers, isParallel }) {
|
|
1056
|
+
return await context.qstashClient.batch([
|
|
1057
|
+
{
|
|
1058
|
+
body,
|
|
1059
|
+
headers,
|
|
1060
|
+
method: "POST",
|
|
1061
|
+
url: context.url,
|
|
1062
|
+
delay: isParallel ? void 0 : this.sleep
|
|
1063
|
+
}
|
|
1064
|
+
]);
|
|
1065
|
+
}
|
|
1066
|
+
};
|
|
1067
|
+
var LazySleepUntilStep = class extends BaseLazyStep {
|
|
1068
|
+
sleepUntil;
|
|
1069
|
+
stepType = "SleepUntil";
|
|
1070
|
+
allowUndefinedOut = true;
|
|
1071
|
+
constructor(stepName, sleepUntil) {
|
|
1072
|
+
super(stepName);
|
|
1073
|
+
this.sleepUntil = sleepUntil;
|
|
1074
|
+
}
|
|
1075
|
+
getPlanStep(concurrent, targetStep) {
|
|
1076
|
+
return {
|
|
1077
|
+
stepId: 0,
|
|
1078
|
+
stepName: this.stepName,
|
|
1079
|
+
stepType: this.stepType,
|
|
1080
|
+
sleepUntil: this.sleepUntil,
|
|
1081
|
+
concurrent,
|
|
1082
|
+
targetStep
|
|
1083
|
+
};
|
|
1084
|
+
}
|
|
1085
|
+
async getResultStep(concurrent, stepId) {
|
|
1086
|
+
return await Promise.resolve({
|
|
1087
|
+
stepId,
|
|
1088
|
+
stepName: this.stepName,
|
|
1089
|
+
stepType: this.stepType,
|
|
1090
|
+
sleepUntil: this.sleepUntil,
|
|
1091
|
+
concurrent
|
|
1092
|
+
});
|
|
1093
|
+
}
|
|
1094
|
+
safeParseOut() {
|
|
1095
|
+
return void 0;
|
|
1096
|
+
}
|
|
1097
|
+
async submitStep({ context, body, headers, isParallel }) {
|
|
1098
|
+
return await context.qstashClient.batch([
|
|
1099
|
+
{
|
|
1100
|
+
body,
|
|
1101
|
+
headers,
|
|
1102
|
+
method: "POST",
|
|
1103
|
+
url: context.url,
|
|
1104
|
+
notBefore: isParallel ? void 0 : this.sleepUntil
|
|
1105
|
+
}
|
|
1106
|
+
]);
|
|
1107
|
+
}
|
|
1108
|
+
};
|
|
1109
|
+
var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
|
|
1110
|
+
url;
|
|
1111
|
+
method;
|
|
1112
|
+
body;
|
|
1113
|
+
headers;
|
|
1114
|
+
retries;
|
|
1115
|
+
timeout;
|
|
1116
|
+
flowControl;
|
|
1117
|
+
stepType = "Call";
|
|
1118
|
+
allowUndefinedOut = false;
|
|
1119
|
+
constructor(stepName, url, method, body, headers, retries, timeout, flowControl) {
|
|
1120
|
+
super(stepName);
|
|
1121
|
+
this.url = url;
|
|
1122
|
+
this.method = method;
|
|
1123
|
+
this.body = body;
|
|
1124
|
+
this.headers = headers;
|
|
1125
|
+
this.retries = retries;
|
|
1126
|
+
this.timeout = timeout;
|
|
1127
|
+
this.flowControl = flowControl;
|
|
1128
|
+
}
|
|
1129
|
+
getPlanStep(concurrent, targetStep) {
|
|
1130
|
+
return {
|
|
1131
|
+
stepId: 0,
|
|
1132
|
+
stepName: this.stepName,
|
|
1133
|
+
stepType: this.stepType,
|
|
1134
|
+
concurrent,
|
|
1135
|
+
targetStep
|
|
1136
|
+
};
|
|
1137
|
+
}
|
|
1138
|
+
async getResultStep(concurrent, stepId) {
|
|
1139
|
+
return await Promise.resolve({
|
|
1140
|
+
stepId,
|
|
1141
|
+
stepName: this.stepName,
|
|
1142
|
+
stepType: this.stepType,
|
|
1143
|
+
concurrent,
|
|
1144
|
+
callUrl: this.url,
|
|
1145
|
+
callMethod: this.method,
|
|
1146
|
+
callBody: this.body,
|
|
1147
|
+
callHeaders: this.headers
|
|
1148
|
+
});
|
|
1149
|
+
}
|
|
1150
|
+
safeParseOut(out) {
|
|
1151
|
+
const { header, status, body } = JSON.parse(out);
|
|
1152
|
+
const responseHeaders = new Headers(header);
|
|
1153
|
+
if (_LazyCallStep.isText(responseHeaders.get("content-type"))) {
|
|
1154
|
+
const bytes = new Uint8Array(out.length);
|
|
1155
|
+
for (let i = 0; i < out.length; i++) {
|
|
1156
|
+
bytes[i] = out.charCodeAt(i);
|
|
1157
|
+
}
|
|
1158
|
+
const processedResult = new TextDecoder().decode(bytes);
|
|
1159
|
+
const newBody = JSON.parse(processedResult).body;
|
|
1160
|
+
return {
|
|
1161
|
+
status,
|
|
1162
|
+
header,
|
|
1163
|
+
body: BaseLazyStep.tryParsing(newBody)
|
|
1164
|
+
};
|
|
1165
|
+
} else {
|
|
1166
|
+
return { header, status, body };
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
static applicationContentTypes = [
|
|
1170
|
+
"application/json",
|
|
1171
|
+
"application/xml",
|
|
1172
|
+
"application/javascript",
|
|
1173
|
+
"application/x-www-form-urlencoded",
|
|
1174
|
+
"application/xhtml+xml",
|
|
1175
|
+
"application/ld+json",
|
|
1176
|
+
"application/rss+xml",
|
|
1177
|
+
"application/atom+xml"
|
|
1178
|
+
];
|
|
1179
|
+
static isText = (contentTypeHeader) => {
|
|
1180
|
+
if (!contentTypeHeader) {
|
|
1181
|
+
return false;
|
|
1182
|
+
}
|
|
1183
|
+
if (_LazyCallStep.applicationContentTypes.some((type) => contentTypeHeader.includes(type))) {
|
|
1184
|
+
return true;
|
|
1185
|
+
}
|
|
1186
|
+
if (contentTypeHeader.startsWith("text/")) {
|
|
1187
|
+
return true;
|
|
1188
|
+
}
|
|
1189
|
+
return false;
|
|
1190
|
+
};
|
|
1191
|
+
getBody({ step }) {
|
|
1192
|
+
if (!step.callUrl) {
|
|
1193
|
+
throw new WorkflowError("Incompatible step received in LazyCallStep.getBody");
|
|
1194
|
+
}
|
|
1195
|
+
return JSON.stringify(step.callBody);
|
|
1196
|
+
}
|
|
1197
|
+
getHeaders({ context, telemetry, invokeCount, step }) {
|
|
1198
|
+
const { headers, contentType } = super.getHeaders({ context, telemetry, invokeCount, step });
|
|
1199
|
+
headers["Upstash-Retries"] = this.retries.toString();
|
|
1200
|
+
headers[WORKFLOW_FEATURE_HEADER] = "WF_NoDelete,InitialBody";
|
|
1201
|
+
if (this.flowControl) {
|
|
1202
|
+
const { flowControlKey, flowControlValue } = prepareFlowControl(this.flowControl);
|
|
1203
|
+
headers["Upstash-Flow-Control-Key"] = flowControlKey;
|
|
1204
|
+
headers["Upstash-Flow-Control-Value"] = flowControlValue;
|
|
1205
|
+
}
|
|
1206
|
+
if (this.timeout) {
|
|
1207
|
+
headers["Upstash-Timeout"] = this.timeout.toString();
|
|
1208
|
+
}
|
|
1209
|
+
const forwardedHeaders = Object.fromEntries(
|
|
1210
|
+
Object.entries(this.headers).map(([header, value]) => [`Upstash-Forward-${header}`, value])
|
|
1211
|
+
);
|
|
1212
|
+
return {
|
|
1213
|
+
headers: {
|
|
1214
|
+
...headers,
|
|
1215
|
+
...forwardedHeaders,
|
|
1216
|
+
"Upstash-Callback": context.url,
|
|
1217
|
+
"Upstash-Callback-Workflow-RunId": context.workflowRunId,
|
|
1218
|
+
"Upstash-Callback-Workflow-CallType": "fromCallback",
|
|
1219
|
+
"Upstash-Callback-Workflow-Init": "false",
|
|
1220
|
+
"Upstash-Callback-Workflow-Url": context.url,
|
|
1221
|
+
"Upstash-Callback-Feature-Set": "LazyFetch,InitialBody",
|
|
1222
|
+
"Upstash-Callback-Forward-Upstash-Workflow-Callback": "true",
|
|
1223
|
+
"Upstash-Callback-Forward-Upstash-Workflow-StepId": step.stepId.toString(),
|
|
1224
|
+
"Upstash-Callback-Forward-Upstash-Workflow-StepName": this.stepName,
|
|
1225
|
+
"Upstash-Callback-Forward-Upstash-Workflow-StepType": this.stepType,
|
|
1226
|
+
"Upstash-Callback-Forward-Upstash-Workflow-Concurrent": step.concurrent.toString(),
|
|
1227
|
+
"Upstash-Callback-Forward-Upstash-Workflow-ContentType": contentType,
|
|
1228
|
+
"Upstash-Workflow-CallType": "toCallback"
|
|
1229
|
+
},
|
|
1230
|
+
contentType
|
|
1231
|
+
};
|
|
1232
|
+
}
|
|
1233
|
+
async submitStep({ context, headers }) {
|
|
1234
|
+
return await context.qstashClient.batch([
|
|
1235
|
+
{
|
|
1236
|
+
headers,
|
|
1237
|
+
body: JSON.stringify(this.body),
|
|
1238
|
+
method: this.method,
|
|
1239
|
+
url: this.url
|
|
1240
|
+
}
|
|
1241
|
+
]);
|
|
1242
|
+
}
|
|
1243
|
+
};
|
|
1244
|
+
var LazyWaitForEventStep = class extends BaseLazyStep {
|
|
1245
|
+
eventId;
|
|
1246
|
+
timeout;
|
|
1247
|
+
stepType = "Wait";
|
|
1248
|
+
allowUndefinedOut = false;
|
|
1249
|
+
constructor(stepName, eventId, timeout) {
|
|
1250
|
+
super(stepName);
|
|
1251
|
+
this.eventId = eventId;
|
|
1252
|
+
this.timeout = timeout;
|
|
1253
|
+
}
|
|
1254
|
+
getPlanStep(concurrent, targetStep) {
|
|
1255
|
+
return {
|
|
1256
|
+
stepId: 0,
|
|
1257
|
+
stepName: this.stepName,
|
|
1258
|
+
stepType: this.stepType,
|
|
1259
|
+
waitEventId: this.eventId,
|
|
1260
|
+
timeout: this.timeout,
|
|
1261
|
+
concurrent,
|
|
1262
|
+
targetStep
|
|
1263
|
+
};
|
|
1264
|
+
}
|
|
1265
|
+
async getResultStep(concurrent, stepId) {
|
|
1266
|
+
return await Promise.resolve({
|
|
1267
|
+
stepId,
|
|
1268
|
+
stepName: this.stepName,
|
|
1269
|
+
stepType: this.stepType,
|
|
1270
|
+
waitEventId: this.eventId,
|
|
1271
|
+
timeout: this.timeout,
|
|
1272
|
+
concurrent
|
|
1273
|
+
});
|
|
1274
|
+
}
|
|
1275
|
+
safeParseOut(out) {
|
|
1276
|
+
const result = JSON.parse(out);
|
|
1277
|
+
return {
|
|
1278
|
+
...result,
|
|
1279
|
+
eventData: BaseLazyStep.tryParsing(result.eventData)
|
|
1280
|
+
};
|
|
1281
|
+
}
|
|
1282
|
+
getHeaders({ context, telemetry, invokeCount, step }) {
|
|
1283
|
+
const headers = super.getHeaders({ context, telemetry, invokeCount, step });
|
|
1284
|
+
headers.headers["Upstash-Workflow-CallType"] = "step";
|
|
1285
|
+
return headers;
|
|
1286
|
+
}
|
|
1287
|
+
getBody({ context, step, headers, telemetry }) {
|
|
1288
|
+
if (!step.waitEventId) {
|
|
1289
|
+
throw new WorkflowError("Incompatible step received in LazyWaitForEventStep.getBody");
|
|
1290
|
+
}
|
|
1291
|
+
const timeoutHeaders = {
|
|
1292
|
+
// to include user headers:
|
|
1293
|
+
...Object.fromEntries(Object.entries(headers).map(([header, value]) => [header, [value]])),
|
|
1294
|
+
// to include telemetry headers:
|
|
1295
|
+
...telemetry ? Object.fromEntries(
|
|
1296
|
+
Object.entries(getTelemetryHeaders(telemetry)).map(([header, value]) => [
|
|
1297
|
+
header,
|
|
1298
|
+
[value]
|
|
1299
|
+
])
|
|
1300
|
+
) : {},
|
|
1301
|
+
// note: using WORKFLOW_ID_HEADER doesn't work, because Runid -> RunId:
|
|
1302
|
+
"Upstash-Workflow-Runid": [context.workflowRunId],
|
|
1303
|
+
[WORKFLOW_INIT_HEADER]: ["false"],
|
|
1304
|
+
[WORKFLOW_URL_HEADER]: [context.url],
|
|
1305
|
+
"Upstash-Workflow-CallType": ["step"]
|
|
1306
|
+
};
|
|
1307
|
+
const waitBody = {
|
|
1308
|
+
url: context.url,
|
|
1309
|
+
timeout: step.timeout,
|
|
1310
|
+
timeoutBody: void 0,
|
|
1311
|
+
timeoutUrl: context.url,
|
|
1312
|
+
timeoutHeaders,
|
|
1313
|
+
step: {
|
|
1314
|
+
stepId: step.stepId,
|
|
1315
|
+
stepType: "Wait",
|
|
1316
|
+
stepName: step.stepName,
|
|
1317
|
+
concurrent: step.concurrent,
|
|
1318
|
+
targetStep: step.targetStep
|
|
1319
|
+
}
|
|
1320
|
+
};
|
|
1321
|
+
return JSON.stringify(waitBody);
|
|
1322
|
+
}
|
|
1323
|
+
async submitStep({ context, body, headers }) {
|
|
1324
|
+
const result = await context.qstashClient.http.request({
|
|
1325
|
+
path: ["v2", "wait", this.eventId],
|
|
1326
|
+
body,
|
|
1327
|
+
headers,
|
|
1328
|
+
method: "POST",
|
|
1329
|
+
parseResponseAsJson: false
|
|
1330
|
+
});
|
|
1331
|
+
return [result];
|
|
1332
|
+
}
|
|
1333
|
+
};
|
|
1334
|
+
var LazyNotifyStep = class extends LazyFunctionStep {
|
|
1335
|
+
stepType = "Notify";
|
|
1336
|
+
constructor(stepName, eventId, eventData, requester) {
|
|
1337
|
+
super(stepName, async () => {
|
|
1338
|
+
const notifyResponse = await makeNotifyRequest(requester, eventId, eventData);
|
|
1339
|
+
return {
|
|
1340
|
+
eventId,
|
|
1341
|
+
eventData,
|
|
1342
|
+
notifyResponse
|
|
1343
|
+
};
|
|
1344
|
+
});
|
|
1345
|
+
}
|
|
1346
|
+
safeParseOut(out) {
|
|
1347
|
+
const result = JSON.parse(out);
|
|
1348
|
+
return {
|
|
1349
|
+
...result,
|
|
1350
|
+
eventData: BaseLazyStep.tryParsing(result.eventData)
|
|
1351
|
+
};
|
|
1352
|
+
}
|
|
1353
|
+
};
|
|
1354
|
+
var LazyInvokeStep = class extends BaseLazyStep {
|
|
1355
|
+
stepType = "Invoke";
|
|
1356
|
+
params;
|
|
1357
|
+
allowUndefinedOut = false;
|
|
1358
|
+
/**
|
|
1359
|
+
* workflow id of the invoked workflow
|
|
1360
|
+
*/
|
|
1361
|
+
workflowId;
|
|
1362
|
+
constructor(stepName, {
|
|
1363
|
+
workflow,
|
|
1364
|
+
body,
|
|
1365
|
+
headers = {},
|
|
1366
|
+
workflowRunId,
|
|
1367
|
+
retries,
|
|
1368
|
+
flowControl
|
|
1369
|
+
}) {
|
|
1370
|
+
super(stepName);
|
|
1371
|
+
this.params = {
|
|
1372
|
+
workflow,
|
|
1373
|
+
body,
|
|
1374
|
+
headers,
|
|
1375
|
+
workflowRunId: getWorkflowRunId(workflowRunId),
|
|
1376
|
+
retries,
|
|
1377
|
+
flowControl
|
|
1378
|
+
};
|
|
1379
|
+
const { workflowId } = workflow;
|
|
1380
|
+
if (!workflowId) {
|
|
1381
|
+
throw new WorkflowError("You can only invoke workflow which has a workflowId");
|
|
1382
|
+
}
|
|
1383
|
+
this.workflowId = workflowId;
|
|
1384
|
+
}
|
|
1385
|
+
getPlanStep(concurrent, targetStep) {
|
|
1386
|
+
return {
|
|
1387
|
+
stepId: 0,
|
|
1388
|
+
stepName: this.stepName,
|
|
1389
|
+
stepType: this.stepType,
|
|
1390
|
+
concurrent,
|
|
1391
|
+
targetStep
|
|
1392
|
+
};
|
|
1393
|
+
}
|
|
1394
|
+
/**
|
|
1395
|
+
* won't be used as it's the server who will add the result step
|
|
1396
|
+
* in Invoke step.
|
|
1397
|
+
*/
|
|
1398
|
+
getResultStep(concurrent, stepId) {
|
|
1399
|
+
return Promise.resolve({
|
|
1400
|
+
stepId,
|
|
1401
|
+
stepName: this.stepName,
|
|
1402
|
+
stepType: this.stepType,
|
|
1403
|
+
concurrent
|
|
1404
|
+
});
|
|
1405
|
+
}
|
|
1406
|
+
safeParseOut(out) {
|
|
1407
|
+
const result = JSON.parse(out);
|
|
1408
|
+
return {
|
|
1409
|
+
...result,
|
|
1410
|
+
body: BaseLazyStep.tryParsing(result.body)
|
|
1411
|
+
};
|
|
1412
|
+
}
|
|
1413
|
+
getBody({ context, step, telemetry, invokeCount }) {
|
|
1414
|
+
const { headers: invokerHeaders } = getHeaders({
|
|
1415
|
+
initHeaderValue: "false",
|
|
1416
|
+
workflowConfig: {
|
|
1417
|
+
workflowRunId: context.workflowRunId,
|
|
1418
|
+
workflowUrl: context.url,
|
|
1419
|
+
failureUrl: context.failureUrl,
|
|
1420
|
+
retries: context.retries,
|
|
1421
|
+
telemetry,
|
|
1422
|
+
flowControl: context.flowControl,
|
|
1423
|
+
useJSONContent: false
|
|
1424
|
+
},
|
|
1425
|
+
userHeaders: context.headers,
|
|
1426
|
+
invokeCount
|
|
1427
|
+
});
|
|
1428
|
+
invokerHeaders["Upstash-Workflow-Runid"] = context.workflowRunId;
|
|
1429
|
+
const request = {
|
|
1430
|
+
body: JSON.stringify(this.params.body),
|
|
1431
|
+
headers: Object.fromEntries(
|
|
1432
|
+
Object.entries(invokerHeaders).map((pairs) => [pairs[0], [pairs[1]]])
|
|
1433
|
+
),
|
|
1434
|
+
workflowRunId: context.workflowRunId,
|
|
1435
|
+
workflowUrl: context.url,
|
|
1436
|
+
step
|
|
1437
|
+
};
|
|
1438
|
+
return JSON.stringify(request);
|
|
1439
|
+
}
|
|
1440
|
+
getHeaders({ context, telemetry, invokeCount }) {
|
|
1441
|
+
const {
|
|
1442
|
+
workflow,
|
|
1443
|
+
headers = {},
|
|
1444
|
+
workflowRunId = getWorkflowRunId(),
|
|
1445
|
+
retries,
|
|
1446
|
+
flowControl
|
|
1447
|
+
} = this.params;
|
|
1448
|
+
const newUrl = context.url.replace(/[^/]+$/, this.workflowId);
|
|
1449
|
+
const {
|
|
1450
|
+
retries: workflowRetries,
|
|
1451
|
+
failureFunction,
|
|
1452
|
+
failureUrl,
|
|
1453
|
+
useJSONContent,
|
|
1454
|
+
flowControl: workflowFlowControl
|
|
1455
|
+
} = workflow.options;
|
|
1456
|
+
const { headers: triggerHeaders, contentType } = getHeaders({
|
|
1457
|
+
initHeaderValue: "true",
|
|
1458
|
+
workflowConfig: {
|
|
1459
|
+
workflowRunId,
|
|
1460
|
+
workflowUrl: newUrl,
|
|
1461
|
+
retries: retries ?? workflowRetries,
|
|
1462
|
+
telemetry,
|
|
1463
|
+
failureUrl: failureFunction ? newUrl : failureUrl,
|
|
1464
|
+
flowControl: flowControl ?? workflowFlowControl,
|
|
1465
|
+
useJSONContent: useJSONContent ?? false
|
|
1466
|
+
},
|
|
1467
|
+
invokeCount: invokeCount + 1,
|
|
1468
|
+
userHeaders: new Headers(headers)
|
|
1469
|
+
});
|
|
1470
|
+
triggerHeaders["Upstash-Workflow-Invoke"] = "true";
|
|
1471
|
+
return { headers: triggerHeaders, contentType };
|
|
1472
|
+
}
|
|
1473
|
+
async submitStep({ context, body, headers }) {
|
|
1474
|
+
const newUrl = context.url.replace(/[^/]+$/, this.workflowId);
|
|
1475
|
+
const result = await context.qstashClient.publish({
|
|
1476
|
+
headers,
|
|
1477
|
+
method: "POST",
|
|
1478
|
+
body,
|
|
1479
|
+
url: newUrl
|
|
1480
|
+
});
|
|
1481
|
+
return [result];
|
|
1482
|
+
}
|
|
1483
|
+
};
|
|
1484
|
+
|
|
1485
|
+
// src/agents/constants.ts
|
|
1486
|
+
var AGENT_NAME_HEADER = "upstash-agent-name";
|
|
1487
|
+
var MANAGER_AGENT_PROMPT = `You are an agent orchestrating other AI Agents.
|
|
1488
|
+
|
|
1489
|
+
These other agents have tools available to them.
|
|
1490
|
+
|
|
1491
|
+
Given a prompt, utilize these agents to address requests.
|
|
1492
|
+
|
|
1493
|
+
Don't always call all the agents provided to you at the same time. You can call one and use it's response to call another.
|
|
1494
|
+
|
|
1495
|
+
Avoid calling the same agent twice in one turn. Instead, prefer to call it once but provide everything
|
|
1496
|
+
you need from that agent.
|
|
1497
|
+
`;
|
|
1498
|
+
|
|
1499
|
+
// src/qstash/headers.ts
|
|
1500
|
+
var WorkflowHeaders = class {
|
|
1501
|
+
userHeaders;
|
|
1502
|
+
workflowConfig;
|
|
1503
|
+
invokeCount;
|
|
1504
|
+
initHeaderValue;
|
|
1505
|
+
stepInfo;
|
|
1506
|
+
headers;
|
|
1507
|
+
constructor({
|
|
1508
|
+
userHeaders,
|
|
1509
|
+
workflowConfig,
|
|
1510
|
+
invokeCount,
|
|
1511
|
+
initHeaderValue,
|
|
1512
|
+
stepInfo
|
|
1513
|
+
}) {
|
|
1514
|
+
this.userHeaders = userHeaders;
|
|
1515
|
+
this.workflowConfig = workflowConfig;
|
|
1516
|
+
this.invokeCount = invokeCount;
|
|
1517
|
+
this.initHeaderValue = initHeaderValue;
|
|
1518
|
+
this.stepInfo = stepInfo;
|
|
1519
|
+
this.headers = {
|
|
1520
|
+
rawHeaders: {},
|
|
1521
|
+
workflowHeaders: {},
|
|
1522
|
+
failureHeaders: {}
|
|
1523
|
+
};
|
|
1524
|
+
}
|
|
1525
|
+
getHeaders() {
|
|
1526
|
+
this.addBaseHeaders();
|
|
1527
|
+
this.addRetries();
|
|
1528
|
+
this.addFlowControl();
|
|
1529
|
+
this.addUserHeaders();
|
|
1530
|
+
this.addInvokeCount();
|
|
1531
|
+
this.addFailureUrl();
|
|
1532
|
+
const contentType = this.addContentType();
|
|
1533
|
+
return this.prefixHeaders(contentType);
|
|
1534
|
+
}
|
|
1535
|
+
addBaseHeaders() {
|
|
1536
|
+
this.headers.rawHeaders = {
|
|
1537
|
+
...this.headers.rawHeaders,
|
|
1538
|
+
[WORKFLOW_INIT_HEADER]: this.initHeaderValue,
|
|
1539
|
+
[WORKFLOW_ID_HEADER]: this.workflowConfig.workflowRunId,
|
|
1540
|
+
[WORKFLOW_URL_HEADER]: this.workflowConfig.workflowUrl,
|
|
1541
|
+
[WORKFLOW_FEATURE_HEADER]: "LazyFetch,InitialBody",
|
|
1542
|
+
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION,
|
|
1543
|
+
...this.workflowConfig.telemetry ? getTelemetryHeaders(this.workflowConfig.telemetry) : {},
|
|
1544
|
+
...this.workflowConfig.telemetry && this.stepInfo?.lazyStep instanceof LazyCallStep && this.stepInfo.lazyStep.headers[AGENT_NAME_HEADER] ? { [TELEMETRY_HEADER_AGENT]: "true" } : {}
|
|
1545
|
+
};
|
|
1546
|
+
if (this.stepInfo?.lazyStep.stepType !== "Call") {
|
|
1547
|
+
this.headers.rawHeaders[`Upstash-Forward-${WORKFLOW_PROTOCOL_VERSION_HEADER}`] = WORKFLOW_PROTOCOL_VERSION;
|
|
1548
|
+
}
|
|
1180
1549
|
}
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
[TELEMETRY_HEADER_SDK]: telemetry.sdk,
|
|
1185
|
-
[TELEMETRY_HEADER_FRAMEWORK]: telemetry.framework,
|
|
1186
|
-
[TELEMETRY_HEADER_RUNTIME]: telemetry.runtime ?? "unknown"
|
|
1187
|
-
};
|
|
1188
|
-
};
|
|
1189
|
-
var getHeaders = ({
|
|
1190
|
-
initHeaderValue,
|
|
1191
|
-
workflowRunId,
|
|
1192
|
-
workflowUrl,
|
|
1193
|
-
userHeaders,
|
|
1194
|
-
failureUrl,
|
|
1195
|
-
retries,
|
|
1196
|
-
step,
|
|
1197
|
-
callRetries,
|
|
1198
|
-
callTimeout,
|
|
1199
|
-
telemetry,
|
|
1200
|
-
invokeCount,
|
|
1201
|
-
flowControl,
|
|
1202
|
-
callFlowControl
|
|
1203
|
-
}) => {
|
|
1204
|
-
const callHeaders = new Headers(step?.callHeaders);
|
|
1205
|
-
const contentType = (callHeaders.get("content-type") ? callHeaders.get("content-type") : userHeaders?.get("Content-Type") ? userHeaders.get("Content-Type") : void 0) ?? DEFAULT_CONTENT_TYPE;
|
|
1206
|
-
const baseHeaders = {
|
|
1207
|
-
[WORKFLOW_INIT_HEADER]: initHeaderValue,
|
|
1208
|
-
[WORKFLOW_ID_HEADER]: workflowRunId,
|
|
1209
|
-
[WORKFLOW_URL_HEADER]: workflowUrl,
|
|
1210
|
-
[WORKFLOW_FEATURE_HEADER]: "LazyFetch,InitialBody",
|
|
1211
|
-
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION,
|
|
1212
|
-
"content-type": contentType,
|
|
1213
|
-
...telemetry ? getTelemetryHeaders(telemetry) : {}
|
|
1214
|
-
};
|
|
1215
|
-
if (invokeCount !== void 0 && !step?.callUrl) {
|
|
1216
|
-
baseHeaders[`Upstash-Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`] = invokeCount.toString();
|
|
1217
|
-
}
|
|
1218
|
-
if (!step?.callUrl) {
|
|
1219
|
-
baseHeaders[`Upstash-Forward-${WORKFLOW_PROTOCOL_VERSION_HEADER}`] = WORKFLOW_PROTOCOL_VERSION;
|
|
1220
|
-
}
|
|
1221
|
-
if (callTimeout) {
|
|
1222
|
-
baseHeaders[`Upstash-Timeout`] = callTimeout.toString();
|
|
1223
|
-
}
|
|
1224
|
-
if (failureUrl) {
|
|
1225
|
-
baseHeaders[`Upstash-Failure-Callback-Forward-${WORKFLOW_FAILURE_HEADER}`] = "true";
|
|
1226
|
-
baseHeaders[`Upstash-Failure-Callback-Forward-Upstash-Workflow-Failure-Callback`] = "true";
|
|
1227
|
-
baseHeaders["Upstash-Failure-Callback-Workflow-Runid"] = workflowRunId;
|
|
1228
|
-
baseHeaders["Upstash-Failure-Callback-Workflow-Init"] = "false";
|
|
1229
|
-
baseHeaders["Upstash-Failure-Callback-Workflow-Url"] = workflowUrl;
|
|
1230
|
-
baseHeaders["Upstash-Failure-Callback-Workflow-Calltype"] = "failureCall";
|
|
1231
|
-
if (retries !== void 0) {
|
|
1232
|
-
baseHeaders["Upstash-Failure-Callback-Retries"] = retries.toString();
|
|
1233
|
-
}
|
|
1234
|
-
if (flowControl) {
|
|
1235
|
-
const { flowControlKey, flowControlValue } = prepareFlowControl(flowControl);
|
|
1236
|
-
baseHeaders["Upstash-Failure-Callback-Flow-Control-Key"] = flowControlKey;
|
|
1237
|
-
baseHeaders["Upstash-Failure-Callback-Flow-Control-Value"] = flowControlValue;
|
|
1238
|
-
}
|
|
1239
|
-
if (!step?.callUrl) {
|
|
1240
|
-
baseHeaders["Upstash-Failure-Callback"] = failureUrl;
|
|
1241
|
-
}
|
|
1242
|
-
}
|
|
1243
|
-
if (step?.callUrl) {
|
|
1244
|
-
baseHeaders["Upstash-Retries"] = callRetries?.toString() ?? "0";
|
|
1245
|
-
baseHeaders[WORKFLOW_FEATURE_HEADER] = "WF_NoDelete,InitialBody";
|
|
1246
|
-
if (retries !== void 0) {
|
|
1247
|
-
baseHeaders["Upstash-Callback-Retries"] = retries.toString();
|
|
1248
|
-
baseHeaders["Upstash-Failure-Callback-Retries"] = retries.toString();
|
|
1249
|
-
}
|
|
1250
|
-
if (callFlowControl) {
|
|
1251
|
-
const { flowControlKey, flowControlValue } = prepareFlowControl(callFlowControl);
|
|
1252
|
-
baseHeaders["Upstash-Flow-Control-Key"] = flowControlKey;
|
|
1253
|
-
baseHeaders["Upstash-Flow-Control-Value"] = flowControlValue;
|
|
1254
|
-
}
|
|
1255
|
-
if (flowControl) {
|
|
1256
|
-
const { flowControlKey, flowControlValue } = prepareFlowControl(flowControl);
|
|
1257
|
-
baseHeaders["Upstash-Callback-Flow-Control-Key"] = flowControlKey;
|
|
1258
|
-
baseHeaders["Upstash-Callback-Flow-Control-Value"] = flowControlValue;
|
|
1550
|
+
addInvokeCount() {
|
|
1551
|
+
if (this.invokeCount === void 0 || this.invokeCount === 0) {
|
|
1552
|
+
return;
|
|
1259
1553
|
}
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
baseHeaders["Upstash-Flow-Control-Value"] = flowControlValue;
|
|
1554
|
+
const invokeCount = this.invokeCount.toString();
|
|
1555
|
+
this.headers.workflowHeaders[`Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`] = invokeCount;
|
|
1556
|
+
if (this.workflowConfig.failureUrl) {
|
|
1557
|
+
this.headers.failureHeaders[`Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`] = invokeCount;
|
|
1265
1558
|
}
|
|
1266
|
-
if (
|
|
1267
|
-
|
|
1268
|
-
baseHeaders["Upstash-Failure-Callback-Retries"] = retries.toString();
|
|
1559
|
+
if (this.stepInfo?.lazyStep instanceof LazyCallStep) {
|
|
1560
|
+
this.headers.rawHeaders[`Upstash-Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`] = invokeCount;
|
|
1269
1561
|
}
|
|
1270
1562
|
}
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1563
|
+
addRetries() {
|
|
1564
|
+
if (this.workflowConfig.retries === void 0 || this.workflowConfig.retries === DEFAULT_RETRIES) {
|
|
1565
|
+
return;
|
|
1566
|
+
}
|
|
1567
|
+
const retries = this.workflowConfig.retries.toString();
|
|
1568
|
+
this.headers.workflowHeaders["Retries"] = retries;
|
|
1569
|
+
if (this.workflowConfig.failureUrl) {
|
|
1570
|
+
this.headers.failureHeaders["Retries"] = retries;
|
|
1279
1571
|
}
|
|
1280
1572
|
}
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1573
|
+
addFlowControl() {
|
|
1574
|
+
if (!this.workflowConfig.flowControl) {
|
|
1575
|
+
return;
|
|
1576
|
+
}
|
|
1577
|
+
const { flowControlKey, flowControlValue } = prepareFlowControl(
|
|
1578
|
+
this.workflowConfig.flowControl
|
|
1287
1579
|
);
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
"Upstash-Callback-Forward-Upstash-Workflow-StepType": step.stepType,
|
|
1302
|
-
"Upstash-Callback-Forward-Upstash-Workflow-Concurrent": step.concurrent.toString(),
|
|
1303
|
-
"Upstash-Callback-Forward-Upstash-Workflow-ContentType": contentType,
|
|
1304
|
-
[`Upstash-Callback-Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`]: (invokeCount ?? 0).toString(),
|
|
1305
|
-
"Upstash-Workflow-CallType": "toCallback"
|
|
1580
|
+
this.headers.workflowHeaders["Flow-Control-Key"] = flowControlKey;
|
|
1581
|
+
this.headers.workflowHeaders["Flow-Control-Value"] = flowControlValue;
|
|
1582
|
+
if (this.workflowConfig.failureUrl) {
|
|
1583
|
+
this.headers.failureHeaders["Flow-Control-Key"] = flowControlKey;
|
|
1584
|
+
this.headers.failureHeaders["Flow-Control-Value"] = flowControlValue;
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
addUserHeaders() {
|
|
1588
|
+
for (const [key, value] of this.userHeaders.entries()) {
|
|
1589
|
+
const forwardKey = `Forward-${key}`;
|
|
1590
|
+
this.headers.workflowHeaders[forwardKey] = value;
|
|
1591
|
+
if (this.workflowConfig.failureUrl) {
|
|
1592
|
+
this.headers.failureHeaders[forwardKey] = value;
|
|
1306
1593
|
}
|
|
1307
|
-
}
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
addFailureUrl() {
|
|
1597
|
+
if (!this.workflowConfig.failureUrl) {
|
|
1598
|
+
return;
|
|
1599
|
+
}
|
|
1600
|
+
this.headers.workflowHeaders["Failure-Callback"] = this.workflowConfig.failureUrl;
|
|
1601
|
+
this.headers.failureHeaders[`Forward-${WORKFLOW_FAILURE_HEADER}`] = "true";
|
|
1602
|
+
this.headers.failureHeaders[`Forward-Upstash-Workflow-Failure-Callback`] = "true";
|
|
1603
|
+
this.headers.failureHeaders["Workflow-Runid"] = this.workflowConfig.workflowRunId;
|
|
1604
|
+
this.headers.failureHeaders["Workflow-Init"] = "false";
|
|
1605
|
+
this.headers.failureHeaders["Workflow-Url"] = this.workflowConfig.workflowUrl;
|
|
1606
|
+
this.headers.failureHeaders["Workflow-Calltype"] = "failureCall";
|
|
1607
|
+
this.headers.failureHeaders["Feature-Set"] = "LazyFetch,InitialBody";
|
|
1608
|
+
if (this.workflowConfig.retries !== void 0 && this.workflowConfig.retries !== DEFAULT_RETRIES) {
|
|
1609
|
+
this.headers.failureHeaders["Retries"] = this.workflowConfig.retries.toString();
|
|
1610
|
+
}
|
|
1611
|
+
}
|
|
1612
|
+
addContentType() {
|
|
1613
|
+
if (this.workflowConfig.useJSONContent) {
|
|
1614
|
+
this.headers.rawHeaders["content-type"] = "application/json";
|
|
1615
|
+
return "application/json";
|
|
1616
|
+
}
|
|
1617
|
+
const callHeaders = new Headers(
|
|
1618
|
+
this.stepInfo?.lazyStep instanceof LazyCallStep ? this.stepInfo.lazyStep.headers : {}
|
|
1619
|
+
);
|
|
1620
|
+
const contentType = (callHeaders.get("content-type") ? callHeaders.get("content-type") : this.userHeaders?.get("Content-Type") ? this.userHeaders.get("Content-Type") : void 0) ?? DEFAULT_CONTENT_TYPE;
|
|
1621
|
+
this.headers.rawHeaders["content-type"] = contentType;
|
|
1622
|
+
return contentType;
|
|
1308
1623
|
}
|
|
1309
|
-
|
|
1624
|
+
prefixHeaders(contentType) {
|
|
1625
|
+
const { rawHeaders, workflowHeaders, failureHeaders } = this.headers;
|
|
1626
|
+
const isCall = this.stepInfo?.lazyStep.stepType === "Call";
|
|
1310
1627
|
return {
|
|
1311
1628
|
headers: {
|
|
1312
|
-
...
|
|
1313
|
-
"Upstash-
|
|
1629
|
+
...rawHeaders,
|
|
1630
|
+
...addPrefixToHeaders(workflowHeaders, isCall ? "Upstash-Callback-" : "Upstash-"),
|
|
1631
|
+
...addPrefixToHeaders(failureHeaders, "Upstash-Failure-Callback-"),
|
|
1632
|
+
...isCall ? addPrefixToHeaders(failureHeaders, "Upstash-Callback-Failure-Callback-") : {}
|
|
1314
1633
|
},
|
|
1315
|
-
|
|
1316
|
-
// to include user headers:
|
|
1317
|
-
...Object.fromEntries(
|
|
1318
|
-
Object.entries(baseHeaders).map(([header, value]) => [header, [value]])
|
|
1319
|
-
),
|
|
1320
|
-
// to include telemetry headers:
|
|
1321
|
-
...telemetry ? Object.fromEntries(
|
|
1322
|
-
Object.entries(getTelemetryHeaders(telemetry)).map(([header, value]) => [
|
|
1323
|
-
header,
|
|
1324
|
-
[value]
|
|
1325
|
-
])
|
|
1326
|
-
) : {},
|
|
1327
|
-
// note: using WORKFLOW_ID_HEADER doesn't work, because Runid -> RunId:
|
|
1328
|
-
"Upstash-Workflow-Runid": [workflowRunId],
|
|
1329
|
-
[WORKFLOW_INIT_HEADER]: ["false"],
|
|
1330
|
-
[WORKFLOW_URL_HEADER]: [workflowUrl],
|
|
1331
|
-
"Upstash-Workflow-CallType": ["step"]
|
|
1332
|
-
}
|
|
1634
|
+
contentType
|
|
1333
1635
|
};
|
|
1334
1636
|
}
|
|
1335
|
-
return { headers: baseHeaders };
|
|
1336
1637
|
};
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
try {
|
|
1342
|
-
if (!signature) {
|
|
1343
|
-
throw new Error("`Upstash-Signature` header is not passed.");
|
|
1344
|
-
}
|
|
1345
|
-
const isValid = await verifier.verify({
|
|
1346
|
-
body,
|
|
1347
|
-
signature
|
|
1348
|
-
});
|
|
1349
|
-
if (!isValid) {
|
|
1350
|
-
throw new Error("Signature in `Upstash-Signature` header is not valid");
|
|
1351
|
-
}
|
|
1352
|
-
} catch (error) {
|
|
1353
|
-
throw new WorkflowError(
|
|
1354
|
-
`Failed to verify that the Workflow request comes from QStash: ${error}
|
|
1355
|
-
|
|
1356
|
-
If signature is missing, trigger the workflow endpoint by publishing your request to QStash instead of calling it directly.
|
|
1357
|
-
|
|
1358
|
-
If you want to disable QStash Verification, you should clear env variables QSTASH_CURRENT_SIGNING_KEY and QSTASH_NEXT_SIGNING_KEY`
|
|
1359
|
-
);
|
|
1638
|
+
function addPrefixToHeaders(headers, prefix) {
|
|
1639
|
+
const prefixedHeaders = {};
|
|
1640
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
1641
|
+
prefixedHeaders[`${prefix}${key}`] = value;
|
|
1360
1642
|
}
|
|
1361
|
-
|
|
1643
|
+
return prefixedHeaders;
|
|
1644
|
+
}
|
|
1362
1645
|
var prepareFlowControl = (flowControl) => {
|
|
1363
1646
|
const parallelism = flowControl.parallelism?.toString();
|
|
1364
|
-
const rate = flowControl.ratePerSecond?.toString();
|
|
1647
|
+
const rate = (flowControl.rate ?? flowControl.ratePerSecond)?.toString();
|
|
1648
|
+
const period = typeof flowControl.period === "number" ? `${flowControl.period}s` : flowControl.period;
|
|
1365
1649
|
const controlValue = [
|
|
1366
1650
|
parallelism ? `parallelism=${parallelism}` : void 0,
|
|
1367
|
-
rate ? `rate=${rate}` : void 0
|
|
1651
|
+
rate ? `rate=${rate}` : void 0,
|
|
1652
|
+
period ? `period=${period}` : void 0
|
|
1368
1653
|
].filter(Boolean);
|
|
1369
1654
|
if (controlValue.length === 0) {
|
|
1370
|
-
throw new
|
|
1655
|
+
throw new import_qstash4.QstashError("Provide at least one of parallelism or ratePerSecond for flowControl");
|
|
1371
1656
|
}
|
|
1372
1657
|
return {
|
|
1373
1658
|
flowControlKey: flowControl.key,
|
|
1374
1659
|
flowControlValue: controlValue.join(", ")
|
|
1375
1660
|
};
|
|
1376
1661
|
};
|
|
1662
|
+
var getHeaders = (params) => {
|
|
1663
|
+
const workflowHeaders = new WorkflowHeaders(params);
|
|
1664
|
+
return workflowHeaders.getHeaders();
|
|
1665
|
+
};
|
|
1377
1666
|
|
|
1378
|
-
// src/
|
|
1379
|
-
var
|
|
1380
|
-
|
|
1381
|
-
// src/serve/serve-many.ts
|
|
1382
|
-
var invokeWorkflow = async ({
|
|
1383
|
-
settings,
|
|
1384
|
-
invokeStep,
|
|
1667
|
+
// src/qstash/submit-steps.ts
|
|
1668
|
+
var submitParallelSteps = async ({
|
|
1385
1669
|
context,
|
|
1670
|
+
steps,
|
|
1671
|
+
initialStepCount,
|
|
1386
1672
|
invokeCount,
|
|
1387
|
-
telemetry
|
|
1673
|
+
telemetry,
|
|
1674
|
+
debug
|
|
1388
1675
|
}) => {
|
|
1389
|
-
const
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1676
|
+
const planSteps = steps.map(
|
|
1677
|
+
(step, index) => step.getPlanStep(steps.length, initialStepCount + index)
|
|
1678
|
+
);
|
|
1679
|
+
await debug?.log("SUBMIT", "SUBMIT_STEP", {
|
|
1680
|
+
length: planSteps.length,
|
|
1681
|
+
steps: planSteps
|
|
1682
|
+
});
|
|
1683
|
+
const result = await context.qstashClient.batch(
|
|
1684
|
+
planSteps.map((planStep) => {
|
|
1685
|
+
const { headers } = getHeaders({
|
|
1686
|
+
initHeaderValue: "false",
|
|
1687
|
+
workflowConfig: {
|
|
1688
|
+
workflowRunId: context.workflowRunId,
|
|
1689
|
+
workflowUrl: context.url,
|
|
1690
|
+
failureUrl: context.failureUrl,
|
|
1691
|
+
retries: context.retries,
|
|
1692
|
+
flowControl: context.flowControl,
|
|
1693
|
+
telemetry
|
|
1694
|
+
},
|
|
1695
|
+
userHeaders: context.headers,
|
|
1696
|
+
invokeCount
|
|
1697
|
+
});
|
|
1698
|
+
return {
|
|
1699
|
+
headers,
|
|
1700
|
+
method: "POST",
|
|
1701
|
+
url: context.url,
|
|
1702
|
+
body: JSON.stringify(planStep),
|
|
1703
|
+
notBefore: planStep.sleepUntil,
|
|
1704
|
+
delay: planStep.sleepFor
|
|
1705
|
+
};
|
|
1706
|
+
})
|
|
1707
|
+
);
|
|
1708
|
+
await debug?.log("INFO", "SUBMIT_STEP", {
|
|
1709
|
+
messageIds: result.map((message) => {
|
|
1710
|
+
return {
|
|
1711
|
+
message: message.messageId
|
|
1712
|
+
};
|
|
1713
|
+
})
|
|
1714
|
+
});
|
|
1715
|
+
throw new WorkflowAbort(planSteps[0].stepName, planSteps[0]);
|
|
1716
|
+
};
|
|
1717
|
+
var submitSingleStep = async ({
|
|
1718
|
+
context,
|
|
1719
|
+
lazyStep,
|
|
1720
|
+
stepId,
|
|
1721
|
+
invokeCount,
|
|
1722
|
+
concurrency,
|
|
1723
|
+
telemetry,
|
|
1724
|
+
debug
|
|
1725
|
+
}) => {
|
|
1726
|
+
const resultStep = await lazyStep.getResultStep(concurrency, stepId);
|
|
1727
|
+
await debug?.log("INFO", "RUN_SINGLE", {
|
|
1728
|
+
fromRequest: false,
|
|
1729
|
+
step: resultStep,
|
|
1730
|
+
stepCount: stepId
|
|
1731
|
+
});
|
|
1732
|
+
const { headers } = lazyStep.getHeaders({
|
|
1733
|
+
context,
|
|
1734
|
+
step: resultStep,
|
|
1416
1735
|
invokeCount,
|
|
1417
|
-
|
|
1736
|
+
telemetry
|
|
1418
1737
|
});
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
userHeaders: new Headers(headers),
|
|
1426
|
-
retries: retries ?? workflowRetries,
|
|
1427
|
-
telemetry,
|
|
1428
|
-
failureUrl: failureFunction ? newUrl : failureUrl,
|
|
1429
|
-
invokeCount: invokeCount + 1,
|
|
1430
|
-
flowControl: flowControl ?? workflowFlowControl
|
|
1738
|
+
const body = lazyStep.getBody({
|
|
1739
|
+
context,
|
|
1740
|
+
step: resultStep,
|
|
1741
|
+
headers,
|
|
1742
|
+
invokeCount,
|
|
1743
|
+
telemetry
|
|
1431
1744
|
});
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
}
|
|
1436
|
-
const
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
};
|
|
1445
|
-
await
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1745
|
+
await debug?.log("SUBMIT", "SUBMIT_STEP", {
|
|
1746
|
+
length: 1,
|
|
1747
|
+
steps: [resultStep]
|
|
1748
|
+
});
|
|
1749
|
+
const submitResult = await lazyStep.submitStep({
|
|
1750
|
+
context,
|
|
1751
|
+
body,
|
|
1752
|
+
headers,
|
|
1753
|
+
isParallel: concurrency !== NO_CONCURRENCY,
|
|
1754
|
+
invokeCount,
|
|
1755
|
+
step: resultStep,
|
|
1756
|
+
telemetry
|
|
1757
|
+
});
|
|
1758
|
+
await debug?.log("INFO", "SUBMIT_STEP", {
|
|
1759
|
+
messageIds: submitResult.map((message) => {
|
|
1760
|
+
return {
|
|
1761
|
+
message: message.messageId
|
|
1762
|
+
};
|
|
1763
|
+
})
|
|
1450
1764
|
});
|
|
1765
|
+
return resultStep;
|
|
1451
1766
|
};
|
|
1452
1767
|
|
|
1453
1768
|
// src/context/auto-executor.ts
|
|
@@ -1554,14 +1869,16 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1554
1869
|
});
|
|
1555
1870
|
return lazyStep.parseOut(step.out);
|
|
1556
1871
|
}
|
|
1557
|
-
const resultStep = await
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1872
|
+
const resultStep = await submitSingleStep({
|
|
1873
|
+
context: this.context,
|
|
1874
|
+
lazyStep,
|
|
1875
|
+
stepId: this.stepCount,
|
|
1876
|
+
invokeCount: this.invokeCount,
|
|
1877
|
+
concurrency: 1,
|
|
1878
|
+
telemetry: this.telemetry,
|
|
1879
|
+
debug: this.debug
|
|
1562
1880
|
});
|
|
1563
|
-
|
|
1564
|
-
return resultStep.out;
|
|
1881
|
+
throw new WorkflowAbort(lazyStep.stepName, resultStep);
|
|
1565
1882
|
}
|
|
1566
1883
|
/**
|
|
1567
1884
|
* Runs steps in parallel.
|
|
@@ -1589,10 +1906,14 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1589
1906
|
});
|
|
1590
1907
|
switch (parallelCallState) {
|
|
1591
1908
|
case "first": {
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1909
|
+
await submitParallelSteps({
|
|
1910
|
+
context: this.context,
|
|
1911
|
+
steps: parallelSteps,
|
|
1912
|
+
initialStepCount,
|
|
1913
|
+
invokeCount: this.invokeCount,
|
|
1914
|
+
telemetry: this.telemetry,
|
|
1915
|
+
debug: this.debug
|
|
1916
|
+
});
|
|
1596
1917
|
break;
|
|
1597
1918
|
}
|
|
1598
1919
|
case "partial": {
|
|
@@ -1606,13 +1927,18 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1606
1927
|
validateStep(parallelSteps[stepIndex], planStep);
|
|
1607
1928
|
try {
|
|
1608
1929
|
const parallelStep = parallelSteps[stepIndex];
|
|
1609
|
-
const resultStep = await
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1930
|
+
const resultStep = await submitSingleStep({
|
|
1931
|
+
context: this.context,
|
|
1932
|
+
lazyStep: parallelStep,
|
|
1933
|
+
stepId: planStep.targetStep,
|
|
1934
|
+
invokeCount: this.invokeCount,
|
|
1935
|
+
concurrency: parallelSteps.length,
|
|
1936
|
+
telemetry: this.telemetry,
|
|
1937
|
+
debug: this.debug
|
|
1938
|
+
});
|
|
1939
|
+
throw new WorkflowAbort(parallelStep.stepName, resultStep);
|
|
1614
1940
|
} catch (error) {
|
|
1615
|
-
if (error instanceof WorkflowAbort || error instanceof
|
|
1941
|
+
if (error instanceof WorkflowAbort || error instanceof import_qstash5.QstashError && error.status === 400) {
|
|
1616
1942
|
throw error;
|
|
1617
1943
|
}
|
|
1618
1944
|
throw new WorkflowError(
|
|
@@ -1668,128 +1994,6 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1668
1994
|
return "discard";
|
|
1669
1995
|
}
|
|
1670
1996
|
}
|
|
1671
|
-
/**
|
|
1672
|
-
* sends the steps to QStash as batch
|
|
1673
|
-
*
|
|
1674
|
-
* @param steps steps to send
|
|
1675
|
-
*/
|
|
1676
|
-
async submitStepsToQStash(steps, lazySteps) {
|
|
1677
|
-
if (steps.length === 0) {
|
|
1678
|
-
throw new WorkflowError(
|
|
1679
|
-
`Unable to submit steps to QStash. Provided list is empty. Current step: ${this.stepCount}`
|
|
1680
|
-
);
|
|
1681
|
-
}
|
|
1682
|
-
await this.debug?.log("SUBMIT", "SUBMIT_STEP", {
|
|
1683
|
-
length: steps.length,
|
|
1684
|
-
steps
|
|
1685
|
-
});
|
|
1686
|
-
if (steps[0].waitEventId && steps.length === 1) {
|
|
1687
|
-
const waitStep = steps[0];
|
|
1688
|
-
const { headers, timeoutHeaders } = getHeaders({
|
|
1689
|
-
initHeaderValue: "false",
|
|
1690
|
-
workflowRunId: this.context.workflowRunId,
|
|
1691
|
-
workflowUrl: this.context.url,
|
|
1692
|
-
userHeaders: this.context.headers,
|
|
1693
|
-
step: waitStep,
|
|
1694
|
-
failureUrl: this.context.failureUrl,
|
|
1695
|
-
retries: this.context.retries,
|
|
1696
|
-
telemetry: this.telemetry,
|
|
1697
|
-
invokeCount: this.invokeCount,
|
|
1698
|
-
flowControl: this.context.flowControl
|
|
1699
|
-
});
|
|
1700
|
-
const waitBody = {
|
|
1701
|
-
url: this.context.url,
|
|
1702
|
-
timeout: waitStep.timeout,
|
|
1703
|
-
timeoutBody: void 0,
|
|
1704
|
-
timeoutUrl: this.context.url,
|
|
1705
|
-
timeoutHeaders,
|
|
1706
|
-
step: {
|
|
1707
|
-
stepId: waitStep.stepId,
|
|
1708
|
-
stepType: "Wait",
|
|
1709
|
-
stepName: waitStep.stepName,
|
|
1710
|
-
concurrent: waitStep.concurrent,
|
|
1711
|
-
targetStep: waitStep.targetStep
|
|
1712
|
-
}
|
|
1713
|
-
};
|
|
1714
|
-
await this.context.qstashClient.http.request({
|
|
1715
|
-
path: ["v2", "wait", waitStep.waitEventId],
|
|
1716
|
-
body: JSON.stringify(waitBody),
|
|
1717
|
-
headers,
|
|
1718
|
-
method: "POST",
|
|
1719
|
-
parseResponseAsJson: false
|
|
1720
|
-
});
|
|
1721
|
-
throw new WorkflowAbort(waitStep.stepName, waitStep);
|
|
1722
|
-
}
|
|
1723
|
-
if (steps.length === 1 && lazySteps[0] instanceof LazyInvokeStep) {
|
|
1724
|
-
const invokeStep = steps[0];
|
|
1725
|
-
const lazyInvokeStep = lazySteps[0];
|
|
1726
|
-
await invokeWorkflow({
|
|
1727
|
-
settings: lazyInvokeStep.params,
|
|
1728
|
-
invokeStep,
|
|
1729
|
-
context: this.context,
|
|
1730
|
-
invokeCount: this.invokeCount,
|
|
1731
|
-
telemetry: this.telemetry
|
|
1732
|
-
});
|
|
1733
|
-
throw new WorkflowAbort(invokeStep.stepName, invokeStep);
|
|
1734
|
-
}
|
|
1735
|
-
const result = await this.context.qstashClient.batch(
|
|
1736
|
-
steps.map((singleStep, index) => {
|
|
1737
|
-
const lazyStep = lazySteps[index];
|
|
1738
|
-
const { headers } = getHeaders({
|
|
1739
|
-
initHeaderValue: "false",
|
|
1740
|
-
workflowRunId: this.context.workflowRunId,
|
|
1741
|
-
workflowUrl: this.context.url,
|
|
1742
|
-
userHeaders: this.context.headers,
|
|
1743
|
-
step: singleStep,
|
|
1744
|
-
failureUrl: this.context.failureUrl,
|
|
1745
|
-
retries: this.context.retries,
|
|
1746
|
-
callRetries: lazyStep instanceof LazyCallStep ? lazyStep.retries : void 0,
|
|
1747
|
-
callTimeout: lazyStep instanceof LazyCallStep ? lazyStep.timeout : void 0,
|
|
1748
|
-
telemetry: this.telemetry,
|
|
1749
|
-
invokeCount: this.invokeCount,
|
|
1750
|
-
flowControl: this.context.flowControl,
|
|
1751
|
-
callFlowControl: lazyStep instanceof LazyCallStep ? lazyStep.flowControl : void 0
|
|
1752
|
-
});
|
|
1753
|
-
const willWait = singleStep.concurrent === NO_CONCURRENCY || singleStep.stepId === 0;
|
|
1754
|
-
singleStep.out = JSON.stringify(singleStep.out);
|
|
1755
|
-
return singleStep.callUrl && lazyStep instanceof LazyCallStep ? (
|
|
1756
|
-
// if the step is a third party call, we call the third party
|
|
1757
|
-
// url (singleStep.callUrl) and pass information about the workflow
|
|
1758
|
-
// in the headers (handled in getHeaders). QStash makes the request
|
|
1759
|
-
// to callUrl and returns the result to Workflow endpoint.
|
|
1760
|
-
// handleThirdPartyCallResult method sends the result of the third
|
|
1761
|
-
// party call to QStash.
|
|
1762
|
-
{
|
|
1763
|
-
headers,
|
|
1764
|
-
method: singleStep.callMethod,
|
|
1765
|
-
body: JSON.stringify(singleStep.callBody),
|
|
1766
|
-
url: singleStep.callUrl
|
|
1767
|
-
}
|
|
1768
|
-
) : (
|
|
1769
|
-
// if the step is not a third party call, we use workflow
|
|
1770
|
-
// endpoint (context.url) as URL when calling QStash. QStash
|
|
1771
|
-
// calls us back with the updated steps list.
|
|
1772
|
-
{
|
|
1773
|
-
headers,
|
|
1774
|
-
method: "POST",
|
|
1775
|
-
body: JSON.stringify(singleStep),
|
|
1776
|
-
url: this.context.url,
|
|
1777
|
-
notBefore: willWait ? singleStep.sleepUntil : void 0,
|
|
1778
|
-
delay: willWait ? singleStep.sleepFor : void 0
|
|
1779
|
-
}
|
|
1780
|
-
);
|
|
1781
|
-
})
|
|
1782
|
-
);
|
|
1783
|
-
const _result = result;
|
|
1784
|
-
await this.debug?.log("INFO", "SUBMIT_STEP", {
|
|
1785
|
-
messageIds: _result.map((message) => {
|
|
1786
|
-
return {
|
|
1787
|
-
message: message.messageId
|
|
1788
|
-
};
|
|
1789
|
-
})
|
|
1790
|
-
});
|
|
1791
|
-
throw new WorkflowAbort(steps[0].stepName, steps[0]);
|
|
1792
|
-
}
|
|
1793
1997
|
/**
|
|
1794
1998
|
* Get the promise by executing the lazt steps list. If there is a single
|
|
1795
1999
|
* step, we call `runSingle`. Otherwise `runParallel` is called.
|
|
@@ -1863,7 +2067,7 @@ var sortSteps = (steps) => {
|
|
|
1863
2067
|
};
|
|
1864
2068
|
|
|
1865
2069
|
// src/context/api/anthropic.ts
|
|
1866
|
-
var
|
|
2070
|
+
var import_qstash6 = require("@upstash/qstash");
|
|
1867
2071
|
|
|
1868
2072
|
// src/context/provider.ts
|
|
1869
2073
|
var getProviderInfo = (api) => {
|
|
@@ -1927,7 +2131,7 @@ var AnthropicAPI = class extends BaseWorkflowApi {
|
|
|
1927
2131
|
return await this.callApi(stepName, {
|
|
1928
2132
|
api: {
|
|
1929
2133
|
name: "llm",
|
|
1930
|
-
provider: (0,
|
|
2134
|
+
provider: (0, import_qstash6.anthropic)({ token })
|
|
1931
2135
|
},
|
|
1932
2136
|
...parameters
|
|
1933
2137
|
});
|
|
@@ -1935,12 +2139,12 @@ var AnthropicAPI = class extends BaseWorkflowApi {
|
|
|
1935
2139
|
};
|
|
1936
2140
|
|
|
1937
2141
|
// src/context/api/openai.ts
|
|
1938
|
-
var
|
|
2142
|
+
var import_qstash7 = require("@upstash/qstash");
|
|
1939
2143
|
var OpenAIAPI = class extends BaseWorkflowApi {
|
|
1940
2144
|
async call(stepName, settings) {
|
|
1941
2145
|
const { token, organization, operation, baseURL, ...parameters } = settings;
|
|
1942
2146
|
const useOpenAI = baseURL === void 0;
|
|
1943
|
-
const provider = useOpenAI ? (0,
|
|
2147
|
+
const provider = useOpenAI ? (0, import_qstash7.openai)({ token, organization }) : (0, import_qstash7.custom)({ baseUrl: baseURL, token });
|
|
1944
2148
|
return await this.callApi(stepName, {
|
|
1945
2149
|
api: {
|
|
1946
2150
|
name: "llm",
|
|
@@ -1952,14 +2156,14 @@ var OpenAIAPI = class extends BaseWorkflowApi {
|
|
|
1952
2156
|
};
|
|
1953
2157
|
|
|
1954
2158
|
// src/context/api/resend.ts
|
|
1955
|
-
var
|
|
2159
|
+
var import_qstash8 = require("@upstash/qstash");
|
|
1956
2160
|
var ResendAPI = class extends BaseWorkflowApi {
|
|
1957
2161
|
async call(stepName, settings) {
|
|
1958
2162
|
const { token, batch = false, ...parameters } = settings;
|
|
1959
2163
|
return await this.callApi(stepName, {
|
|
1960
2164
|
api: {
|
|
1961
2165
|
name: "email",
|
|
1962
|
-
provider: (0,
|
|
2166
|
+
provider: (0, import_qstash8.resend)({ token, batch })
|
|
1963
2167
|
},
|
|
1964
2168
|
...parameters
|
|
1965
2169
|
});
|
|
@@ -1986,28 +2190,11 @@ var WorkflowApi = class extends BaseWorkflowApi {
|
|
|
1986
2190
|
};
|
|
1987
2191
|
|
|
1988
2192
|
// src/agents/index.ts
|
|
1989
|
-
var import_openai3 = require("@ai-sdk/openai");
|
|
1990
|
-
|
|
1991
|
-
// src/agents/adapters.ts
|
|
1992
2193
|
var import_openai2 = require("@ai-sdk/openai");
|
|
1993
|
-
var import_ai = require("ai");
|
|
1994
|
-
|
|
1995
|
-
// src/agents/constants.ts
|
|
1996
|
-
var AGENT_NAME_HEADER = "upstash-agent-name";
|
|
1997
|
-
var MANAGER_AGENT_PROMPT = `You are an agent orchestrating other AI Agents.
|
|
1998
|
-
|
|
1999
|
-
These other agents have tools available to them.
|
|
2000
|
-
|
|
2001
|
-
Given a prompt, utilize these agents to address requests.
|
|
2002
|
-
|
|
2003
|
-
Don't always call all the agents provided to you at the same time. You can call one and use it's response to call another.
|
|
2004
|
-
|
|
2005
|
-
Avoid calling the same agent twice in one turn. Instead, prefer to call it once but provide everything
|
|
2006
|
-
you need from that agent.
|
|
2007
|
-
`;
|
|
2008
2194
|
|
|
2009
2195
|
// src/agents/adapters.ts
|
|
2010
|
-
var
|
|
2196
|
+
var import_ai = require("ai");
|
|
2197
|
+
var fetchWithContextCall = async (context, agentCallParams, ...params) => {
|
|
2011
2198
|
const [input, init] = params;
|
|
2012
2199
|
try {
|
|
2013
2200
|
const headers = init?.headers ? Object.fromEntries(new Headers(init.headers).entries()) : {};
|
|
@@ -2018,7 +2205,10 @@ var fetchWithContextCall = async (context, ...params) => {
|
|
|
2018
2205
|
url: input.toString(),
|
|
2019
2206
|
method: init?.method,
|
|
2020
2207
|
headers,
|
|
2021
|
-
body
|
|
2208
|
+
body,
|
|
2209
|
+
timeout: agentCallParams?.timeout,
|
|
2210
|
+
retries: agentCallParams?.retries,
|
|
2211
|
+
flowControl: agentCallParams?.flowControl
|
|
2022
2212
|
});
|
|
2023
2213
|
const responseHeaders = new Headers(
|
|
2024
2214
|
Object.entries(responseInfo.header).reduce(
|
|
@@ -2045,10 +2235,11 @@ var fetchWithContextCall = async (context, ...params) => {
|
|
|
2045
2235
|
var createWorkflowModel = ({
|
|
2046
2236
|
context,
|
|
2047
2237
|
provider,
|
|
2048
|
-
providerParams
|
|
2238
|
+
providerParams,
|
|
2239
|
+
agentCallParams
|
|
2049
2240
|
}) => {
|
|
2050
2241
|
return provider({
|
|
2051
|
-
fetch: (...params) => fetchWithContextCall(context, ...params),
|
|
2242
|
+
fetch: (...params) => fetchWithContextCall(context, agentCallParams, ...params),
|
|
2052
2243
|
...providerParams
|
|
2053
2244
|
});
|
|
2054
2245
|
};
|
|
@@ -2319,17 +2510,26 @@ var WorkflowAgents = class {
|
|
|
2319
2510
|
*/
|
|
2320
2511
|
openai(...params) {
|
|
2321
2512
|
const [model, settings] = params;
|
|
2322
|
-
const { baseURL, apiKey, ...otherSettings } = settings ?? {};
|
|
2513
|
+
const { baseURL, apiKey, callSettings, ...otherSettings } = settings ?? {};
|
|
2323
2514
|
const openaiModel = this.AISDKModel({
|
|
2324
2515
|
context: this.context,
|
|
2325
|
-
provider:
|
|
2326
|
-
providerParams: { baseURL, apiKey, compatibility: "strict" }
|
|
2516
|
+
provider: import_openai2.createOpenAI,
|
|
2517
|
+
providerParams: { baseURL, apiKey, compatibility: "strict" },
|
|
2518
|
+
agentCallParams: callSettings
|
|
2327
2519
|
});
|
|
2328
2520
|
return openaiModel(model, otherSettings);
|
|
2329
2521
|
}
|
|
2330
2522
|
AISDKModel = createWorkflowModel;
|
|
2331
2523
|
};
|
|
2332
2524
|
|
|
2525
|
+
// src/serve/serve-many.ts
|
|
2526
|
+
var getNewUrlFromWorkflowId = (url, workflowId) => {
|
|
2527
|
+
if (!workflowId) {
|
|
2528
|
+
throw new WorkflowError("You can only call workflow which has a workflowId");
|
|
2529
|
+
}
|
|
2530
|
+
return url.replace(/[^/]+$/, workflowId);
|
|
2531
|
+
};
|
|
2532
|
+
|
|
2333
2533
|
// src/context/context.ts
|
|
2334
2534
|
var WorkflowContext = class {
|
|
2335
2535
|
executor;
|
|
@@ -2551,60 +2751,42 @@ var WorkflowContext = class {
|
|
|
2551
2751
|
}
|
|
2552
2752
|
await this.addStep(new LazySleepUntilStep(stepName, time));
|
|
2553
2753
|
}
|
|
2554
|
-
/**
|
|
2555
|
-
* Makes a third party call through QStash in order to make a
|
|
2556
|
-
* network call without consuming any runtime.
|
|
2557
|
-
*
|
|
2558
|
-
* ```ts
|
|
2559
|
-
* const { status, body } = await context.call<string>(
|
|
2560
|
-
* "post call step",
|
|
2561
|
-
* {
|
|
2562
|
-
* url: "https://www.some-endpoint.com/api",
|
|
2563
|
-
* method: "POST",
|
|
2564
|
-
* body: "my-payload"
|
|
2565
|
-
* }
|
|
2566
|
-
* );
|
|
2567
|
-
* ```
|
|
2568
|
-
*
|
|
2569
|
-
* tries to parse the result of the request as JSON. If it's
|
|
2570
|
-
* not a JSON which can be parsed, simply returns the response
|
|
2571
|
-
* body as it is.
|
|
2572
|
-
*
|
|
2573
|
-
* @param stepName
|
|
2574
|
-
* @param url url to call
|
|
2575
|
-
* @param method call method. "GET" by default.
|
|
2576
|
-
* @param body call body
|
|
2577
|
-
* @param headers call headers
|
|
2578
|
-
* @param retries number of call retries. 0 by default
|
|
2579
|
-
* @param timeout max duration to wait for the endpoint to respond. in seconds.
|
|
2580
|
-
* @returns call result as {
|
|
2581
|
-
* status: number;
|
|
2582
|
-
* body: unknown;
|
|
2583
|
-
* header: Record<string, string[]>
|
|
2584
|
-
* }
|
|
2585
|
-
*/
|
|
2586
2754
|
async call(stepName, settings) {
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2755
|
+
let callStep;
|
|
2756
|
+
if ("workflow" in settings) {
|
|
2757
|
+
const url = getNewUrlFromWorkflowId(this.url, settings.workflow.workflowId);
|
|
2758
|
+
callStep = new LazyCallStep(
|
|
2759
|
+
stepName,
|
|
2760
|
+
url,
|
|
2761
|
+
"POST",
|
|
2762
|
+
settings.body,
|
|
2763
|
+
settings.headers || {},
|
|
2764
|
+
settings.retries || 0,
|
|
2765
|
+
settings.timeout,
|
|
2766
|
+
settings.flowControl ?? settings.workflow.options.flowControl
|
|
2767
|
+
);
|
|
2768
|
+
} else {
|
|
2769
|
+
const {
|
|
2770
|
+
url,
|
|
2771
|
+
method = "GET",
|
|
2772
|
+
body,
|
|
2773
|
+
headers = {},
|
|
2774
|
+
retries = 0,
|
|
2775
|
+
timeout,
|
|
2776
|
+
flowControl
|
|
2777
|
+
} = settings;
|
|
2778
|
+
callStep = new LazyCallStep(
|
|
2598
2779
|
stepName,
|
|
2599
2780
|
url,
|
|
2600
2781
|
method,
|
|
2601
|
-
|
|
2782
|
+
body,
|
|
2602
2783
|
headers,
|
|
2603
2784
|
retries,
|
|
2604
2785
|
timeout,
|
|
2605
2786
|
flowControl
|
|
2606
|
-
)
|
|
2607
|
-
|
|
2787
|
+
);
|
|
2788
|
+
}
|
|
2789
|
+
return await this.addStep(callStep);
|
|
2608
2790
|
}
|
|
2609
2791
|
/**
|
|
2610
2792
|
* Pauses workflow execution until a specific event occurs or a timeout is reached.
|
|
@@ -2752,7 +2934,7 @@ var WorkflowLogger = class _WorkflowLogger {
|
|
|
2752
2934
|
};
|
|
2753
2935
|
|
|
2754
2936
|
// src/serve/authorization.ts
|
|
2755
|
-
var
|
|
2937
|
+
var import_qstash9 = require("@upstash/qstash");
|
|
2756
2938
|
var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowContext {
|
|
2757
2939
|
static disabledMessage = "disabled-qstash-worklfow-run";
|
|
2758
2940
|
disabled = true;
|
|
@@ -2784,7 +2966,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
2784
2966
|
*/
|
|
2785
2967
|
static async tryAuthentication(routeFunction, context) {
|
|
2786
2968
|
const disabledContext = new _DisabledWorkflowContext({
|
|
2787
|
-
qstashClient: new
|
|
2969
|
+
qstashClient: new import_qstash9.Client({
|
|
2788
2970
|
baseUrl: "disabled-client",
|
|
2789
2971
|
token: "disabled-client"
|
|
2790
2972
|
}),
|
|
@@ -2998,15 +3180,15 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
|
|
|
2998
3180
|
};
|
|
2999
3181
|
|
|
3000
3182
|
// src/serve/options.ts
|
|
3001
|
-
var import_qstash9 = require("@upstash/qstash");
|
|
3002
3183
|
var import_qstash10 = require("@upstash/qstash");
|
|
3184
|
+
var import_qstash11 = require("@upstash/qstash");
|
|
3003
3185
|
var processOptions = (options) => {
|
|
3004
3186
|
const environment = options?.env ?? (typeof process === "undefined" ? {} : process.env);
|
|
3005
3187
|
const receiverEnvironmentVariablesSet = Boolean(
|
|
3006
3188
|
environment.QSTASH_CURRENT_SIGNING_KEY && environment.QSTASH_NEXT_SIGNING_KEY
|
|
3007
3189
|
);
|
|
3008
3190
|
return {
|
|
3009
|
-
qstashClient: new
|
|
3191
|
+
qstashClient: new import_qstash11.Client({
|
|
3010
3192
|
baseUrl: environment.QSTASH_URL,
|
|
3011
3193
|
token: environment.QSTASH_TOKEN
|
|
3012
3194
|
}),
|
|
@@ -3041,7 +3223,7 @@ var processOptions = (options) => {
|
|
|
3041
3223
|
throw error;
|
|
3042
3224
|
}
|
|
3043
3225
|
},
|
|
3044
|
-
receiver: receiverEnvironmentVariablesSet ? new
|
|
3226
|
+
receiver: receiverEnvironmentVariablesSet ? new import_qstash10.Receiver({
|
|
3045
3227
|
currentSigningKey: environment.QSTASH_CURRENT_SIGNING_KEY,
|
|
3046
3228
|
nextSigningKey: environment.QSTASH_NEXT_SIGNING_KEY
|
|
3047
3229
|
}) : void 0,
|
|
@@ -3261,7 +3443,7 @@ var serve = (routeFunction, options) => {
|
|
|
3261
3443
|
};
|
|
3262
3444
|
|
|
3263
3445
|
// src/client/index.ts
|
|
3264
|
-
var
|
|
3446
|
+
var import_qstash12 = require("@upstash/qstash");
|
|
3265
3447
|
var Client4 = class {
|
|
3266
3448
|
client;
|
|
3267
3449
|
constructor(clientConfig) {
|
|
@@ -3270,7 +3452,7 @@ var Client4 = class {
|
|
|
3270
3452
|
"QStash token is required for Upstash Workflow!\n\nTo fix this:\n1. Get your token from the Upstash Console (https://console.upstash.com/qstash)\n2. Initialize the workflow client with:\n\n const client = new Client({\n token: '<YOUR_QSTASH_TOKEN>'\n });"
|
|
3271
3453
|
);
|
|
3272
3454
|
}
|
|
3273
|
-
this.client = new
|
|
3455
|
+
this.client = new import_qstash12.Client(clientConfig);
|
|
3274
3456
|
}
|
|
3275
3457
|
/**
|
|
3276
3458
|
* Cancel an ongoing workflow
|
|
@@ -3388,63 +3570,39 @@ var Client4 = class {
|
|
|
3388
3570
|
async getWaiters({ eventId }) {
|
|
3389
3571
|
return await makeGetWaitersRequest(this.client.http, eventId);
|
|
3390
3572
|
}
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
* @returns workflow run id
|
|
3418
|
-
*/
|
|
3419
|
-
async trigger({
|
|
3420
|
-
url,
|
|
3421
|
-
body,
|
|
3422
|
-
headers,
|
|
3423
|
-
workflowRunId,
|
|
3424
|
-
retries,
|
|
3425
|
-
flowControl
|
|
3426
|
-
}) {
|
|
3427
|
-
const finalWorkflowRunId = getWorkflowRunId(workflowRunId);
|
|
3428
|
-
const context = new WorkflowContext({
|
|
3429
|
-
qstashClient: this.client,
|
|
3430
|
-
// @ts-expect-error headers type mismatch
|
|
3431
|
-
headers: new Headers(headers ?? {}),
|
|
3432
|
-
initialPayload: body,
|
|
3433
|
-
steps: [],
|
|
3434
|
-
url,
|
|
3435
|
-
workflowRunId: finalWorkflowRunId,
|
|
3436
|
-
retries,
|
|
3437
|
-
telemetry: void 0,
|
|
3438
|
-
// can't know workflow telemetry here
|
|
3439
|
-
flowControl
|
|
3440
|
-
});
|
|
3441
|
-
const result = await triggerFirstInvocation({
|
|
3442
|
-
workflowContext: context,
|
|
3443
|
-
telemetry: void 0
|
|
3444
|
-
// can't know workflow telemetry here
|
|
3573
|
+
async trigger(params) {
|
|
3574
|
+
const isBatchInput = Array.isArray(params);
|
|
3575
|
+
const options = isBatchInput ? params : [params];
|
|
3576
|
+
const invocations = options.map((option) => {
|
|
3577
|
+
const failureUrl = option.useFailureFunction ? option.url : option.failureUrl;
|
|
3578
|
+
const finalWorkflowRunId = getWorkflowRunId(option.workflowRunId);
|
|
3579
|
+
const context = new WorkflowContext({
|
|
3580
|
+
qstashClient: this.client,
|
|
3581
|
+
// @ts-expect-error headers type mismatch
|
|
3582
|
+
headers: new Headers(option.headers ?? {}),
|
|
3583
|
+
initialPayload: option.body,
|
|
3584
|
+
steps: [],
|
|
3585
|
+
url: option.url,
|
|
3586
|
+
workflowRunId: finalWorkflowRunId,
|
|
3587
|
+
retries: option.retries,
|
|
3588
|
+
telemetry: void 0,
|
|
3589
|
+
// can't know workflow telemetry here
|
|
3590
|
+
flowControl: option.flowControl,
|
|
3591
|
+
failureUrl
|
|
3592
|
+
});
|
|
3593
|
+
return {
|
|
3594
|
+
workflowContext: context,
|
|
3595
|
+
telemetry: void 0,
|
|
3596
|
+
// can't know workflow telemetry here
|
|
3597
|
+
delay: option.delay
|
|
3598
|
+
};
|
|
3445
3599
|
});
|
|
3600
|
+
const result = await triggerFirstInvocation(invocations);
|
|
3601
|
+
const workflowRunIds = invocations.map(
|
|
3602
|
+
(invocation) => invocation.workflowContext.workflowRunId
|
|
3603
|
+
);
|
|
3446
3604
|
if (result.isOk()) {
|
|
3447
|
-
return { workflowRunId:
|
|
3605
|
+
return isBatchInput ? workflowRunIds.map((id) => ({ workflowRunId: id })) : { workflowRunId: workflowRunIds[0] };
|
|
3448
3606
|
} else {
|
|
3449
3607
|
throw result.error;
|
|
3450
3608
|
}
|