@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/express.js CHANGED
@@ -23710,11 +23710,12 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
23710
23710
  var DEFAULT_CONTENT_TYPE = "application/json";
23711
23711
  var NO_CONCURRENCY = 1;
23712
23712
  var DEFAULT_RETRIES = 3;
23713
- var VERSION = "v0.2.7";
23713
+ var VERSION = "v0.2.14";
23714
23714
  var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
23715
23715
  var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
23716
23716
  var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
23717
23717
  var TELEMETRY_HEADER_RUNTIME = "Upstash-Telemetry-Runtime";
23718
+ var TELEMETRY_HEADER_AGENT = "Upstash-Telemetry-Agent";
23718
23719
 
23719
23720
  // src/client/utils.ts
23720
23721
  var import_qstash = require("@upstash/qstash");
@@ -23810,6 +23811,12 @@ var formatWorkflowError = (error) => {
23810
23811
  };
23811
23812
  };
23812
23813
 
23814
+ // src/context/auto-executor.ts
23815
+ var import_qstash5 = require("@upstash/qstash");
23816
+
23817
+ // src/qstash/headers.ts
23818
+ var import_qstash4 = require("@upstash/qstash");
23819
+
23813
23820
  // src/utils.ts
23814
23821
  var NANOID_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
23815
23822
  var NANOID_LENGTH = 21;
@@ -23835,574 +23842,231 @@ function decodeBase64(base64) {
23835
23842
  }
23836
23843
  }
23837
23844
 
23838
- // src/context/steps.ts
23839
- var BaseLazyStep = class _BaseLazyStep {
23840
- stepName;
23841
- constructor(stepName) {
23842
- if (!stepName) {
23843
- throw new WorkflowError(
23844
- "A workflow step name cannot be undefined or an empty string. Please provide a name for your workflow step."
23845
- );
23846
- }
23847
- this.stepName = stepName;
23845
+ // node_modules/neverthrow/dist/index.es.js
23846
+ var defaultErrorConfig = {
23847
+ withStackTrace: false
23848
+ };
23849
+ var createNeverThrowError = (message, result, config = defaultErrorConfig) => {
23850
+ const data = result.isOk() ? { type: "Ok", value: result.value } : { type: "Err", value: result.error };
23851
+ const maybeStack = config.withStackTrace ? new Error().stack : void 0;
23852
+ return {
23853
+ data,
23854
+ message,
23855
+ stack: maybeStack
23856
+ };
23857
+ };
23858
+ function __awaiter(thisArg, _arguments, P, generator) {
23859
+ function adopt(value) {
23860
+ return value instanceof P ? value : new P(function(resolve) {
23861
+ resolve(value);
23862
+ });
23848
23863
  }
23849
- /**
23850
- * parse the out field of a step result.
23851
- *
23852
- * will be called when returning the steps to the context from auto executor
23853
- *
23854
- * @param out field of the step
23855
- * @returns parsed out field
23856
- */
23857
- parseOut(out) {
23858
- if (out === void 0) {
23859
- if (this.allowUndefinedOut) {
23860
- return void 0;
23861
- } else {
23862
- throw new WorkflowError(
23863
- `Error while parsing output of ${this.stepType} step. Expected a string, but got: undefined`
23864
- );
23864
+ return new (P || (P = Promise))(function(resolve, reject) {
23865
+ function fulfilled(value) {
23866
+ try {
23867
+ step(generator.next(value));
23868
+ } catch (e) {
23869
+ reject(e);
23865
23870
  }
23866
23871
  }
23867
- if (typeof out === "object") {
23868
- if (this.stepType !== "Wait") {
23869
- console.warn(
23870
- `Error while parsing ${this.stepType} step output. Expected a string, but got object. Please reach out to Upstash Support.`
23871
- );
23872
- return out;
23872
+ function rejected(value) {
23873
+ try {
23874
+ step(generator["throw"](value));
23875
+ } catch (e) {
23876
+ reject(e);
23873
23877
  }
23874
- return {
23875
- ...out,
23876
- eventData: _BaseLazyStep.tryParsing(out.eventData)
23877
- };
23878
23878
  }
23879
- if (typeof out !== "string") {
23880
- throw new WorkflowError(
23881
- `Error while parsing output of ${this.stepType} step. Expected a string or undefined, but got: ${typeof out}`
23882
- );
23879
+ function step(result) {
23880
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
23883
23881
  }
23884
- return this.safeParseOut(out);
23885
- }
23886
- safeParseOut(out) {
23887
- return _BaseLazyStep.tryParsing(out);
23882
+ step((generator = generator.apply(thisArg, [])).next());
23883
+ });
23884
+ }
23885
+ function __values(o) {
23886
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
23887
+ if (m) return m.call(o);
23888
+ if (o && typeof o.length === "number") return {
23889
+ next: function() {
23890
+ if (o && i >= o.length) o = void 0;
23891
+ return { value: o && o[i++], done: !o };
23892
+ }
23893
+ };
23894
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
23895
+ }
23896
+ function __await(v) {
23897
+ return this instanceof __await ? (this.v = v, this) : new __await(v);
23898
+ }
23899
+ function __asyncGenerator(thisArg, _arguments, generator) {
23900
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
23901
+ var g = generator.apply(thisArg, _arguments || []), i, q = [];
23902
+ return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() {
23903
+ return this;
23904
+ }, i;
23905
+ function verb(n) {
23906
+ if (g[n]) i[n] = function(v) {
23907
+ return new Promise(function(a, b) {
23908
+ q.push([n, v, a, b]) > 1 || resume(n, v);
23909
+ });
23910
+ };
23888
23911
  }
23889
- static tryParsing(stepOut) {
23912
+ function resume(n, v) {
23890
23913
  try {
23891
- return JSON.parse(stepOut);
23892
- } catch {
23893
- return stepOut;
23914
+ step(g[n](v));
23915
+ } catch (e) {
23916
+ settle(q[0][3], e);
23894
23917
  }
23895
23918
  }
23896
- };
23897
- var LazyFunctionStep = class extends BaseLazyStep {
23898
- stepFunction;
23899
- stepType = "Run";
23900
- allowUndefinedOut = true;
23901
- constructor(stepName, stepFunction) {
23902
- super(stepName);
23903
- this.stepFunction = stepFunction;
23919
+ function step(r) {
23920
+ r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r);
23904
23921
  }
23905
- getPlanStep(concurrent, targetStep) {
23906
- return {
23907
- stepId: 0,
23908
- stepName: this.stepName,
23909
- stepType: this.stepType,
23910
- concurrent,
23911
- targetStep
23912
- };
23922
+ function fulfill(value) {
23923
+ resume("next", value);
23913
23924
  }
23914
- async getResultStep(concurrent, stepId) {
23915
- let result = this.stepFunction();
23916
- if (result instanceof Promise) {
23917
- result = await result;
23918
- }
23919
- return {
23920
- stepId,
23921
- stepName: this.stepName,
23922
- stepType: this.stepType,
23923
- out: result,
23924
- concurrent
23925
- };
23925
+ function reject(value) {
23926
+ resume("throw", value);
23926
23927
  }
23927
- };
23928
- var LazySleepStep = class extends BaseLazyStep {
23929
- sleep;
23930
- stepType = "SleepFor";
23931
- allowUndefinedOut = true;
23932
- constructor(stepName, sleep) {
23933
- super(stepName);
23934
- this.sleep = sleep;
23928
+ function settle(f, v) {
23929
+ if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]);
23935
23930
  }
23936
- getPlanStep(concurrent, targetStep) {
23937
- return {
23938
- stepId: 0,
23939
- stepName: this.stepName,
23940
- stepType: this.stepType,
23941
- sleepFor: this.sleep,
23942
- concurrent,
23943
- targetStep
23931
+ }
23932
+ function __asyncDelegator(o) {
23933
+ var i, p;
23934
+ return i = {}, verb("next"), verb("throw", function(e) {
23935
+ throw e;
23936
+ }), verb("return"), i[Symbol.iterator] = function() {
23937
+ return this;
23938
+ }, i;
23939
+ function verb(n, f) {
23940
+ i[n] = o[n] ? function(v) {
23941
+ return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v;
23942
+ } : f;
23943
+ }
23944
+ }
23945
+ function __asyncValues(o) {
23946
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
23947
+ var m = o[Symbol.asyncIterator], i;
23948
+ 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() {
23949
+ return this;
23950
+ }, i);
23951
+ function verb(n) {
23952
+ i[n] = o[n] && function(v) {
23953
+ return new Promise(function(resolve, reject) {
23954
+ v = o[n](v), settle(resolve, reject, v.done, v.value);
23955
+ });
23944
23956
  };
23945
23957
  }
23946
- async getResultStep(concurrent, stepId) {
23947
- return await Promise.resolve({
23948
- stepId,
23949
- stepName: this.stepName,
23950
- stepType: this.stepType,
23951
- sleepFor: this.sleep,
23952
- concurrent
23953
- });
23958
+ function settle(resolve, reject, d, v) {
23959
+ Promise.resolve(v).then(function(v2) {
23960
+ resolve({ value: v2, done: d });
23961
+ }, reject);
23954
23962
  }
23955
- };
23956
- var LazySleepUntilStep = class extends BaseLazyStep {
23957
- sleepUntil;
23958
- stepType = "SleepUntil";
23959
- allowUndefinedOut = true;
23960
- constructor(stepName, sleepUntil) {
23961
- super(stepName);
23962
- this.sleepUntil = sleepUntil;
23963
+ }
23964
+ var ResultAsync = class _ResultAsync {
23965
+ constructor(res) {
23966
+ this._promise = res;
23963
23967
  }
23964
- getPlanStep(concurrent, targetStep) {
23965
- return {
23966
- stepId: 0,
23967
- stepName: this.stepName,
23968
- stepType: this.stepType,
23969
- sleepUntil: this.sleepUntil,
23970
- concurrent,
23971
- targetStep
23972
- };
23968
+ static fromSafePromise(promise) {
23969
+ const newPromise = promise.then((value) => new Ok(value));
23970
+ return new _ResultAsync(newPromise);
23973
23971
  }
23974
- async getResultStep(concurrent, stepId) {
23975
- return await Promise.resolve({
23976
- stepId,
23977
- stepName: this.stepName,
23978
- stepType: this.stepType,
23979
- sleepUntil: this.sleepUntil,
23980
- concurrent
23981
- });
23972
+ static fromPromise(promise, errorFn) {
23973
+ const newPromise = promise.then((value) => new Ok(value)).catch((e) => new Err(errorFn(e)));
23974
+ return new _ResultAsync(newPromise);
23982
23975
  }
23983
- safeParseOut() {
23984
- return void 0;
23976
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
23977
+ static fromThrowable(fn, errorFn) {
23978
+ return (...args) => {
23979
+ return new _ResultAsync((() => __awaiter(this, void 0, void 0, function* () {
23980
+ try {
23981
+ return new Ok(yield fn(...args));
23982
+ } catch (error) {
23983
+ return new Err(errorFn ? errorFn(error) : error);
23984
+ }
23985
+ }))());
23986
+ };
23985
23987
  }
23986
- };
23987
- var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
23988
- url;
23989
- method;
23990
- body;
23991
- headers;
23992
- retries;
23993
- timeout;
23994
- flowControl;
23995
- stepType = "Call";
23996
- allowUndefinedOut = false;
23997
- constructor(stepName, url, method, body, headers, retries, timeout, flowControl) {
23998
- super(stepName);
23999
- this.url = url;
24000
- this.method = method;
24001
- this.body = body;
24002
- this.headers = headers;
24003
- this.retries = retries;
24004
- this.timeout = timeout;
24005
- this.flowControl = flowControl;
24006
- }
24007
- getPlanStep(concurrent, targetStep) {
24008
- return {
24009
- stepId: 0,
24010
- stepName: this.stepName,
24011
- stepType: this.stepType,
24012
- concurrent,
24013
- targetStep
24014
- };
23988
+ static combine(asyncResultList) {
23989
+ return combineResultAsyncList(asyncResultList);
24015
23990
  }
24016
- async getResultStep(concurrent, stepId) {
24017
- return await Promise.resolve({
24018
- stepId,
24019
- stepName: this.stepName,
24020
- stepType: this.stepType,
24021
- concurrent,
24022
- callUrl: this.url,
24023
- callMethod: this.method,
24024
- callBody: this.body,
24025
- callHeaders: this.headers
24026
- });
23991
+ static combineWithAllErrors(asyncResultList) {
23992
+ return combineResultAsyncListWithAllErrors(asyncResultList);
24027
23993
  }
24028
- safeParseOut(out) {
24029
- const { header, status, body } = JSON.parse(out);
24030
- const responseHeaders = new Headers(header);
24031
- if (_LazyCallStep.isText(responseHeaders.get("content-type"))) {
24032
- const bytes = new Uint8Array(out.length);
24033
- for (let i = 0; i < out.length; i++) {
24034
- bytes[i] = out.charCodeAt(i);
23994
+ map(f) {
23995
+ return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
23996
+ if (res.isErr()) {
23997
+ return new Err(res.error);
24035
23998
  }
24036
- const processedResult = new TextDecoder().decode(bytes);
24037
- const newBody = JSON.parse(processedResult).body;
24038
- return {
24039
- status,
24040
- header,
24041
- body: BaseLazyStep.tryParsing(newBody)
24042
- };
24043
- } else {
24044
- return { header, status, body };
24045
- }
24046
- }
24047
- static applicationHeaders = /* @__PURE__ */ new Set([
24048
- "application/json",
24049
- "application/xml",
24050
- "application/javascript",
24051
- "application/x-www-form-urlencoded",
24052
- "application/xhtml+xml",
24053
- "application/ld+json",
24054
- "application/rss+xml",
24055
- "application/atom+xml"
24056
- ]);
24057
- static isText = (contentTypeHeader) => {
24058
- if (!contentTypeHeader) {
24059
- return false;
24060
- }
24061
- if (_LazyCallStep.applicationHeaders.has(contentTypeHeader)) {
24062
- return true;
24063
- }
24064
- if (contentTypeHeader.startsWith("text/")) {
24065
- return true;
24066
- }
24067
- return false;
24068
- };
24069
- };
24070
- var LazyWaitForEventStep = class extends BaseLazyStep {
24071
- eventId;
24072
- timeout;
24073
- stepType = "Wait";
24074
- allowUndefinedOut = false;
24075
- constructor(stepName, eventId, timeout) {
24076
- super(stepName);
24077
- this.eventId = eventId;
24078
- this.timeout = timeout;
23999
+ return new Ok(yield f(res.value));
24000
+ })));
24079
24001
  }
24080
- getPlanStep(concurrent, targetStep) {
24081
- return {
24082
- stepId: 0,
24083
- stepName: this.stepName,
24084
- stepType: this.stepType,
24085
- waitEventId: this.eventId,
24086
- timeout: this.timeout,
24087
- concurrent,
24088
- targetStep
24089
- };
24002
+ andThrough(f) {
24003
+ return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
24004
+ if (res.isErr()) {
24005
+ return new Err(res.error);
24006
+ }
24007
+ const newRes = yield f(res.value);
24008
+ if (newRes.isErr()) {
24009
+ return new Err(newRes.error);
24010
+ }
24011
+ return new Ok(res.value);
24012
+ })));
24090
24013
  }
24091
- async getResultStep(concurrent, stepId) {
24092
- return await Promise.resolve({
24093
- stepId,
24094
- stepName: this.stepName,
24095
- stepType: this.stepType,
24096
- waitEventId: this.eventId,
24097
- timeout: this.timeout,
24098
- concurrent
24099
- });
24014
+ andTee(f) {
24015
+ return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
24016
+ if (res.isErr()) {
24017
+ return new Err(res.error);
24018
+ }
24019
+ try {
24020
+ yield f(res.value);
24021
+ } catch (e) {
24022
+ }
24023
+ return new Ok(res.value);
24024
+ })));
24100
24025
  }
24101
- safeParseOut(out) {
24102
- const result = JSON.parse(out);
24103
- return {
24104
- ...result,
24105
- eventData: BaseLazyStep.tryParsing(result.eventData)
24106
- };
24026
+ mapErr(f) {
24027
+ return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
24028
+ if (res.isOk()) {
24029
+ return new Ok(res.value);
24030
+ }
24031
+ return new Err(yield f(res.error));
24032
+ })));
24107
24033
  }
24108
- };
24109
- var LazyNotifyStep = class extends LazyFunctionStep {
24110
- stepType = "Notify";
24111
- constructor(stepName, eventId, eventData, requester) {
24112
- super(stepName, async () => {
24113
- const notifyResponse = await makeNotifyRequest(requester, eventId, eventData);
24114
- return {
24115
- eventId,
24116
- eventData,
24117
- notifyResponse
24118
- };
24119
- });
24034
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
24035
+ andThen(f) {
24036
+ return new _ResultAsync(this._promise.then((res) => {
24037
+ if (res.isErr()) {
24038
+ return new Err(res.error);
24039
+ }
24040
+ const newValue = f(res.value);
24041
+ return newValue instanceof _ResultAsync ? newValue._promise : newValue;
24042
+ }));
24120
24043
  }
24121
- safeParseOut(out) {
24122
- const result = JSON.parse(out);
24123
- return {
24124
- ...result,
24125
- eventData: BaseLazyStep.tryParsing(result.eventData)
24126
- };
24044
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
24045
+ orElse(f) {
24046
+ return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
24047
+ if (res.isErr()) {
24048
+ return f(res.error);
24049
+ }
24050
+ return new Ok(res.value);
24051
+ })));
24127
24052
  }
24128
- };
24129
- var LazyInvokeStep = class extends BaseLazyStep {
24130
- stepType = "Invoke";
24131
- params;
24132
- allowUndefinedOut = false;
24133
- constructor(stepName, {
24134
- workflow,
24135
- body,
24136
- headers = {},
24137
- workflowRunId,
24138
- retries,
24139
- flowControl
24140
- }) {
24141
- super(stepName);
24142
- this.params = {
24143
- workflow,
24144
- body,
24145
- headers,
24146
- workflowRunId: getWorkflowRunId(workflowRunId),
24147
- retries,
24148
- flowControl
24149
- };
24053
+ match(ok2, _err) {
24054
+ return this._promise.then((res) => res.match(ok2, _err));
24150
24055
  }
24151
- getPlanStep(concurrent, targetStep) {
24152
- return {
24153
- stepId: 0,
24154
- stepName: this.stepName,
24155
- stepType: this.stepType,
24156
- concurrent,
24157
- targetStep
24158
- };
24056
+ unwrapOr(t) {
24057
+ return this._promise.then((res) => res.unwrapOr(t));
24159
24058
  }
24160
24059
  /**
24161
- * won't be used as it's the server who will add the result step
24162
- * in Invoke step.
24060
+ * Emulates Rust's `?` operator in `safeTry`'s body. See also `safeTry`.
24163
24061
  */
24164
- getResultStep(concurrent, stepId) {
24165
- return Promise.resolve({
24166
- stepId,
24167
- stepName: this.stepName,
24168
- stepType: this.stepType,
24169
- concurrent
24062
+ safeUnwrap() {
24063
+ return __asyncGenerator(this, arguments, function* safeUnwrap_1() {
24064
+ return yield __await(yield __await(yield* __asyncDelegator(__asyncValues(yield __await(this._promise.then((res) => res.safeUnwrap()))))));
24170
24065
  });
24171
24066
  }
24172
- safeParseOut(out) {
24173
- const result = JSON.parse(out);
24174
- return {
24175
- ...result,
24176
- body: BaseLazyStep.tryParsing(result.body)
24177
- };
24178
- }
24179
- };
24180
-
24181
- // node_modules/neverthrow/dist/index.es.js
24182
- var defaultErrorConfig = {
24183
- withStackTrace: false
24184
- };
24185
- var createNeverThrowError = (message, result, config = defaultErrorConfig) => {
24186
- const data = result.isOk() ? { type: "Ok", value: result.value } : { type: "Err", value: result.error };
24187
- const maybeStack = config.withStackTrace ? new Error().stack : void 0;
24188
- return {
24189
- data,
24190
- message,
24191
- stack: maybeStack
24192
- };
24193
- };
24194
- function __awaiter(thisArg, _arguments, P, generator) {
24195
- function adopt(value) {
24196
- return value instanceof P ? value : new P(function(resolve) {
24197
- resolve(value);
24198
- });
24199
- }
24200
- return new (P || (P = Promise))(function(resolve, reject) {
24201
- function fulfilled(value) {
24202
- try {
24203
- step(generator.next(value));
24204
- } catch (e) {
24205
- reject(e);
24206
- }
24207
- }
24208
- function rejected(value) {
24209
- try {
24210
- step(generator["throw"](value));
24211
- } catch (e) {
24212
- reject(e);
24213
- }
24214
- }
24215
- function step(result) {
24216
- result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
24217
- }
24218
- step((generator = generator.apply(thisArg, [])).next());
24219
- });
24220
- }
24221
- function __values(o) {
24222
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
24223
- if (m) return m.call(o);
24224
- if (o && typeof o.length === "number") return {
24225
- next: function() {
24226
- if (o && i >= o.length) o = void 0;
24227
- return { value: o && o[i++], done: !o };
24228
- }
24229
- };
24230
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
24231
- }
24232
- function __await(v) {
24233
- return this instanceof __await ? (this.v = v, this) : new __await(v);
24234
- }
24235
- function __asyncGenerator(thisArg, _arguments, generator) {
24236
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
24237
- var g = generator.apply(thisArg, _arguments || []), i, q = [];
24238
- return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() {
24239
- return this;
24240
- }, i;
24241
- function verb(n) {
24242
- if (g[n]) i[n] = function(v) {
24243
- return new Promise(function(a, b) {
24244
- q.push([n, v, a, b]) > 1 || resume(n, v);
24245
- });
24246
- };
24247
- }
24248
- function resume(n, v) {
24249
- try {
24250
- step(g[n](v));
24251
- } catch (e) {
24252
- settle(q[0][3], e);
24253
- }
24254
- }
24255
- function step(r) {
24256
- r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r);
24257
- }
24258
- function fulfill(value) {
24259
- resume("next", value);
24260
- }
24261
- function reject(value) {
24262
- resume("throw", value);
24263
- }
24264
- function settle(f, v) {
24265
- if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]);
24266
- }
24267
- }
24268
- function __asyncDelegator(o) {
24269
- var i, p;
24270
- return i = {}, verb("next"), verb("throw", function(e) {
24271
- throw e;
24272
- }), verb("return"), i[Symbol.iterator] = function() {
24273
- return this;
24274
- }, i;
24275
- function verb(n, f) {
24276
- i[n] = o[n] ? function(v) {
24277
- return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v;
24278
- } : f;
24279
- }
24280
- }
24281
- function __asyncValues(o) {
24282
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
24283
- var m = o[Symbol.asyncIterator], i;
24284
- 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() {
24285
- return this;
24286
- }, i);
24287
- function verb(n) {
24288
- i[n] = o[n] && function(v) {
24289
- return new Promise(function(resolve, reject) {
24290
- v = o[n](v), settle(resolve, reject, v.done, v.value);
24291
- });
24292
- };
24293
- }
24294
- function settle(resolve, reject, d, v) {
24295
- Promise.resolve(v).then(function(v2) {
24296
- resolve({ value: v2, done: d });
24297
- }, reject);
24298
- }
24299
- }
24300
- var ResultAsync = class _ResultAsync {
24301
- constructor(res) {
24302
- this._promise = res;
24303
- }
24304
- static fromSafePromise(promise) {
24305
- const newPromise = promise.then((value) => new Ok(value));
24306
- return new _ResultAsync(newPromise);
24307
- }
24308
- static fromPromise(promise, errorFn) {
24309
- const newPromise = promise.then((value) => new Ok(value)).catch((e) => new Err(errorFn(e)));
24310
- return new _ResultAsync(newPromise);
24311
- }
24312
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
24313
- static fromThrowable(fn, errorFn) {
24314
- return (...args) => {
24315
- return new _ResultAsync((() => __awaiter(this, void 0, void 0, function* () {
24316
- try {
24317
- return new Ok(yield fn(...args));
24318
- } catch (error) {
24319
- return new Err(errorFn ? errorFn(error) : error);
24320
- }
24321
- }))());
24322
- };
24323
- }
24324
- static combine(asyncResultList) {
24325
- return combineResultAsyncList(asyncResultList);
24326
- }
24327
- static combineWithAllErrors(asyncResultList) {
24328
- return combineResultAsyncListWithAllErrors(asyncResultList);
24329
- }
24330
- map(f) {
24331
- return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
24332
- if (res.isErr()) {
24333
- return new Err(res.error);
24334
- }
24335
- return new Ok(yield f(res.value));
24336
- })));
24337
- }
24338
- andThrough(f) {
24339
- return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
24340
- if (res.isErr()) {
24341
- return new Err(res.error);
24342
- }
24343
- const newRes = yield f(res.value);
24344
- if (newRes.isErr()) {
24345
- return new Err(newRes.error);
24346
- }
24347
- return new Ok(res.value);
24348
- })));
24349
- }
24350
- andTee(f) {
24351
- return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
24352
- if (res.isErr()) {
24353
- return new Err(res.error);
24354
- }
24355
- try {
24356
- yield f(res.value);
24357
- } catch (e) {
24358
- }
24359
- return new Ok(res.value);
24360
- })));
24361
- }
24362
- mapErr(f) {
24363
- return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
24364
- if (res.isOk()) {
24365
- return new Ok(res.value);
24366
- }
24367
- return new Err(yield f(res.error));
24368
- })));
24369
- }
24370
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
24371
- andThen(f) {
24372
- return new _ResultAsync(this._promise.then((res) => {
24373
- if (res.isErr()) {
24374
- return new Err(res.error);
24375
- }
24376
- const newValue = f(res.value);
24377
- return newValue instanceof _ResultAsync ? newValue._promise : newValue;
24378
- }));
24379
- }
24380
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
24381
- orElse(f) {
24382
- return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
24383
- if (res.isErr()) {
24384
- return f(res.error);
24385
- }
24386
- return new Ok(res.value);
24387
- })));
24388
- }
24389
- match(ok2, _err) {
24390
- return this._promise.then((res) => res.match(ok2, _err));
24391
- }
24392
- unwrapOr(t) {
24393
- return this._promise.then((res) => res.unwrapOr(t));
24394
- }
24395
- /**
24396
- * Emulates Rust's `?` operator in `safeTry`'s body. See also `safeTry`.
24397
- */
24398
- safeUnwrap() {
24399
- return __asyncGenerator(this, arguments, function* safeUnwrap_1() {
24400
- return yield __await(yield __await(yield* __asyncDelegator(__asyncValues(yield __await(this._promise.then((res) => res.safeUnwrap()))))));
24401
- });
24402
- }
24403
- // Makes ResultAsync implement PromiseLike<Result>
24404
- then(successCallback, failureCallback) {
24405
- return this._promise.then(successCallback, failureCallback);
24067
+ // Makes ResultAsync implement PromiseLike<Result>
24068
+ then(successCallback, failureCallback) {
24069
+ return this._promise.then(successCallback, failureCallback);
24406
24070
  }
24407
24071
  };
24408
24072
  var errAsync = (err2) => new ResultAsync(Promise.resolve(new Err(err2)));
@@ -24607,54 +24271,72 @@ var StepTypes = [
24607
24271
 
24608
24272
  // src/workflow-requests.ts
24609
24273
  var import_qstash3 = require("@upstash/qstash");
24610
- var triggerFirstInvocation = async ({
24611
- workflowContext,
24612
- useJSONContent,
24613
- telemetry: telemetry2,
24614
- debug,
24615
- invokeCount
24616
- }) => {
24617
- const { headers } = getHeaders({
24618
- initHeaderValue: "true",
24619
- workflowRunId: workflowContext.workflowRunId,
24620
- workflowUrl: workflowContext.url,
24621
- userHeaders: workflowContext.headers,
24622
- failureUrl: workflowContext.failureUrl,
24623
- retries: workflowContext.retries,
24624
- telemetry: telemetry2,
24625
- invokeCount,
24626
- flowControl: workflowContext.flowControl
24627
- });
24628
- if (workflowContext.headers.get("content-type")) {
24629
- headers["content-type"] = workflowContext.headers.get("content-type");
24630
- }
24631
- if (useJSONContent) {
24632
- headers["content-type"] = "application/json";
24633
- }
24634
- try {
24635
- const body = typeof workflowContext.requestPayload === "string" ? workflowContext.requestPayload : JSON.stringify(workflowContext.requestPayload);
24636
- const result = await workflowContext.qstashClient.publish({
24637
- headers,
24638
- method: "POST",
24639
- body,
24640
- url: workflowContext.url
24641
- });
24642
- if (result.deduplicated) {
24643
- await debug?.log("WARN", "SUBMIT_FIRST_INVOCATION", {
24644
- message: `Workflow run ${workflowContext.workflowRunId} already exists. A new one isn't created.`,
24274
+ var triggerFirstInvocation = async (params) => {
24275
+ const firstInvocationParams = Array.isArray(params) ? params : [params];
24276
+ const workflowContextClient = firstInvocationParams[0].workflowContext.qstashClient;
24277
+ const invocationBatch = firstInvocationParams.map(
24278
+ ({ workflowContext, useJSONContent, telemetry: telemetry2, invokeCount, delay }) => {
24279
+ const { headers } = getHeaders({
24280
+ initHeaderValue: "true",
24281
+ workflowConfig: {
24282
+ workflowRunId: workflowContext.workflowRunId,
24283
+ workflowUrl: workflowContext.url,
24284
+ failureUrl: workflowContext.failureUrl,
24285
+ retries: workflowContext.retries,
24286
+ telemetry: telemetry2,
24287
+ flowControl: workflowContext.flowControl,
24288
+ useJSONContent: useJSONContent ?? false
24289
+ },
24290
+ invokeCount: invokeCount ?? 0,
24291
+ userHeaders: workflowContext.headers
24292
+ });
24293
+ if (workflowContext.headers.get("content-type")) {
24294
+ headers["content-type"] = workflowContext.headers.get("content-type");
24295
+ }
24296
+ if (useJSONContent) {
24297
+ headers["content-type"] = "application/json";
24298
+ }
24299
+ const body = typeof workflowContext.requestPayload === "string" ? workflowContext.requestPayload : JSON.stringify(workflowContext.requestPayload);
24300
+ return {
24645
24301
  headers,
24646
- requestPayload: workflowContext.requestPayload,
24302
+ method: "POST",
24303
+ body,
24647
24304
  url: workflowContext.url,
24648
- messageId: result.messageId
24649
- });
24305
+ delay
24306
+ };
24307
+ }
24308
+ );
24309
+ try {
24310
+ const results = await workflowContextClient.batch(invocationBatch);
24311
+ const invocationStatuses = [];
24312
+ for (let i = 0; i < results.length; i++) {
24313
+ const result = results[i];
24314
+ const invocationParams = firstInvocationParams[i];
24315
+ if (result.deduplicated) {
24316
+ await invocationParams.debug?.log("WARN", "SUBMIT_FIRST_INVOCATION", {
24317
+ message: `Workflow run ${invocationParams.workflowContext.workflowRunId} already exists. A new one isn't created.`,
24318
+ headers: invocationBatch[i].headers,
24319
+ requestPayload: invocationParams.workflowContext.requestPayload,
24320
+ url: invocationParams.workflowContext.url,
24321
+ messageId: result.messageId
24322
+ });
24323
+ invocationStatuses.push("workflow-run-already-exists");
24324
+ } else {
24325
+ await invocationParams.debug?.log("SUBMIT", "SUBMIT_FIRST_INVOCATION", {
24326
+ headers: invocationBatch[i].headers,
24327
+ requestPayload: invocationParams.workflowContext.requestPayload,
24328
+ url: invocationParams.workflowContext.url,
24329
+ messageId: result.messageId
24330
+ });
24331
+ invocationStatuses.push("success");
24332
+ }
24333
+ }
24334
+ const hasAnyDeduplicated = invocationStatuses.some(
24335
+ (status) => status === "workflow-run-already-exists"
24336
+ );
24337
+ if (hasAnyDeduplicated) {
24650
24338
  return ok("workflow-run-already-exists");
24651
24339
  } else {
24652
- await debug?.log("SUBMIT", "SUBMIT_FIRST_INVOCATION", {
24653
- headers,
24654
- requestPayload: workflowContext.requestPayload,
24655
- url: workflowContext.url,
24656
- messageId: result.messageId
24657
- });
24658
24340
  return ok("success");
24659
24341
  }
24660
24342
  } catch (error) {
@@ -24793,14 +24475,16 @@ ${atob(callbackMessage.body ?? "")}`
24793
24475
  const userHeaders = recreateUserHeaders(request.headers);
24794
24476
  const { headers: requestHeaders } = getHeaders({
24795
24477
  initHeaderValue: "false",
24796
- workflowRunId,
24797
- workflowUrl,
24478
+ workflowConfig: {
24479
+ workflowRunId,
24480
+ workflowUrl,
24481
+ failureUrl,
24482
+ retries,
24483
+ telemetry: telemetry2,
24484
+ flowControl
24485
+ },
24798
24486
  userHeaders,
24799
- failureUrl,
24800
- retries,
24801
- telemetry: telemetry2,
24802
- invokeCount: Number(invokeCount),
24803
- flowControl
24487
+ invokeCount: Number(invokeCount)
24804
24488
  });
24805
24489
  const callResponse = {
24806
24490
  status: callbackMessage.status,
@@ -24832,343 +24516,913 @@ ${atob(callbackMessage.body ?? "")}`
24832
24516
  } else {
24833
24517
  return ok("continue-workflow");
24834
24518
  }
24835
- } catch (error) {
24836
- const isCallReturn = request.headers.get("Upstash-Workflow-Callback");
24837
- return err(
24838
- new WorkflowError(`Error when handling call return (isCallReturn=${isCallReturn}): ${error}`)
24839
- );
24840
- }
24841
- };
24842
- var getTelemetryHeaders = (telemetry2) => {
24843
- return {
24844
- [TELEMETRY_HEADER_SDK]: telemetry2.sdk,
24845
- [TELEMETRY_HEADER_FRAMEWORK]: telemetry2.framework,
24846
- [TELEMETRY_HEADER_RUNTIME]: telemetry2.runtime ?? "unknown"
24847
- };
24848
- };
24849
- var getHeaders = ({
24850
- initHeaderValue,
24851
- workflowRunId,
24852
- workflowUrl,
24853
- userHeaders,
24854
- failureUrl,
24855
- retries,
24856
- step,
24857
- callRetries,
24858
- callTimeout,
24859
- telemetry: telemetry2,
24860
- invokeCount,
24861
- flowControl,
24862
- callFlowControl
24863
- }) => {
24864
- const callHeaders = new Headers(step?.callHeaders);
24865
- const contentType = (callHeaders.get("content-type") ? callHeaders.get("content-type") : userHeaders?.get("Content-Type") ? userHeaders.get("Content-Type") : void 0) ?? DEFAULT_CONTENT_TYPE;
24866
- const baseHeaders = {
24867
- [WORKFLOW_INIT_HEADER]: initHeaderValue,
24868
- [WORKFLOW_ID_HEADER]: workflowRunId,
24869
- [WORKFLOW_URL_HEADER]: workflowUrl,
24870
- [WORKFLOW_FEATURE_HEADER]: "LazyFetch,InitialBody",
24871
- [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION,
24872
- "content-type": contentType,
24873
- ...telemetry2 ? getTelemetryHeaders(telemetry2) : {}
24874
- };
24875
- if (invokeCount !== void 0 && !step?.callUrl) {
24876
- baseHeaders[`Upstash-Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`] = invokeCount.toString();
24877
- }
24878
- if (!step?.callUrl) {
24879
- baseHeaders[`Upstash-Forward-${WORKFLOW_PROTOCOL_VERSION_HEADER}`] = WORKFLOW_PROTOCOL_VERSION;
24880
- }
24881
- if (callTimeout) {
24882
- baseHeaders[`Upstash-Timeout`] = callTimeout.toString();
24883
- }
24884
- if (failureUrl) {
24885
- baseHeaders[`Upstash-Failure-Callback-Forward-${WORKFLOW_FAILURE_HEADER}`] = "true";
24886
- baseHeaders[`Upstash-Failure-Callback-Forward-Upstash-Workflow-Failure-Callback`] = "true";
24887
- baseHeaders["Upstash-Failure-Callback-Workflow-Runid"] = workflowRunId;
24888
- baseHeaders["Upstash-Failure-Callback-Workflow-Init"] = "false";
24889
- baseHeaders["Upstash-Failure-Callback-Workflow-Url"] = workflowUrl;
24890
- baseHeaders["Upstash-Failure-Callback-Workflow-Calltype"] = "failureCall";
24891
- if (retries !== void 0) {
24892
- baseHeaders["Upstash-Failure-Callback-Retries"] = retries.toString();
24893
- }
24894
- if (flowControl) {
24895
- const { flowControlKey, flowControlValue } = prepareFlowControl(flowControl);
24896
- baseHeaders["Upstash-Failure-Callback-Flow-Control-Key"] = flowControlKey;
24897
- baseHeaders["Upstash-Failure-Callback-Flow-Control-Value"] = flowControlValue;
24898
- }
24899
- if (!step?.callUrl) {
24900
- baseHeaders["Upstash-Failure-Callback"] = failureUrl;
24901
- }
24902
- }
24903
- if (step?.callUrl) {
24904
- baseHeaders["Upstash-Retries"] = callRetries?.toString() ?? "0";
24905
- baseHeaders[WORKFLOW_FEATURE_HEADER] = "WF_NoDelete,InitialBody";
24906
- if (retries !== void 0) {
24907
- baseHeaders["Upstash-Callback-Retries"] = retries.toString();
24908
- baseHeaders["Upstash-Failure-Callback-Retries"] = retries.toString();
24909
- }
24910
- if (callFlowControl) {
24911
- const { flowControlKey, flowControlValue } = prepareFlowControl(callFlowControl);
24912
- baseHeaders["Upstash-Flow-Control-Key"] = flowControlKey;
24913
- baseHeaders["Upstash-Flow-Control-Value"] = flowControlValue;
24914
- }
24915
- if (flowControl) {
24916
- const { flowControlKey, flowControlValue } = prepareFlowControl(flowControl);
24917
- baseHeaders["Upstash-Callback-Flow-Control-Key"] = flowControlKey;
24918
- baseHeaders["Upstash-Callback-Flow-Control-Value"] = flowControlValue;
24519
+ } catch (error) {
24520
+ const isCallReturn = request.headers.get("Upstash-Workflow-Callback");
24521
+ return err(
24522
+ new WorkflowError(`Error when handling call return (isCallReturn=${isCallReturn}): ${error}`)
24523
+ );
24524
+ }
24525
+ };
24526
+ var getTelemetryHeaders = (telemetry2) => {
24527
+ return {
24528
+ [TELEMETRY_HEADER_SDK]: telemetry2.sdk,
24529
+ [TELEMETRY_HEADER_FRAMEWORK]: telemetry2.framework,
24530
+ [TELEMETRY_HEADER_RUNTIME]: telemetry2.runtime ?? "unknown"
24531
+ };
24532
+ };
24533
+ var verifyRequest = async (body, signature, verifier) => {
24534
+ if (!verifier) {
24535
+ return;
24536
+ }
24537
+ try {
24538
+ if (!signature) {
24539
+ throw new Error("`Upstash-Signature` header is not passed.");
24540
+ }
24541
+ const isValid = await verifier.verify({
24542
+ body,
24543
+ signature
24544
+ });
24545
+ if (!isValid) {
24546
+ throw new Error("Signature in `Upstash-Signature` header is not valid");
24547
+ }
24548
+ } catch (error) {
24549
+ throw new WorkflowError(
24550
+ `Failed to verify that the Workflow request comes from QStash: ${error}
24551
+
24552
+ If signature is missing, trigger the workflow endpoint by publishing your request to QStash instead of calling it directly.
24553
+
24554
+ If you want to disable QStash Verification, you should clear env variables QSTASH_CURRENT_SIGNING_KEY and QSTASH_NEXT_SIGNING_KEY`
24555
+ );
24556
+ }
24557
+ };
24558
+
24559
+ // src/context/steps.ts
24560
+ var BaseLazyStep = class _BaseLazyStep {
24561
+ stepName;
24562
+ constructor(stepName) {
24563
+ if (!stepName) {
24564
+ throw new WorkflowError(
24565
+ "A workflow step name cannot be undefined or an empty string. Please provide a name for your workflow step."
24566
+ );
24567
+ }
24568
+ if (typeof stepName !== "string") {
24569
+ console.warn(
24570
+ "Workflow Warning: A workflow step name must be a string. In a future release, this will throw an error."
24571
+ );
24572
+ }
24573
+ this.stepName = stepName;
24574
+ }
24575
+ /**
24576
+ * parse the out field of a step result.
24577
+ *
24578
+ * will be called when returning the steps to the context from auto executor
24579
+ *
24580
+ * @param out field of the step
24581
+ * @returns parsed out field
24582
+ */
24583
+ parseOut(out) {
24584
+ if (out === void 0) {
24585
+ if (this.allowUndefinedOut) {
24586
+ return void 0;
24587
+ } else {
24588
+ throw new WorkflowError(
24589
+ `Error while parsing output of ${this.stepType} step. Expected a string, but got: undefined`
24590
+ );
24591
+ }
24592
+ }
24593
+ if (typeof out === "object") {
24594
+ if (this.stepType !== "Wait") {
24595
+ console.warn(
24596
+ `Error while parsing ${this.stepType} step output. Expected a string, but got object. Please reach out to Upstash Support.`
24597
+ );
24598
+ return out;
24599
+ }
24600
+ return {
24601
+ ...out,
24602
+ eventData: _BaseLazyStep.tryParsing(out.eventData)
24603
+ };
24604
+ }
24605
+ if (typeof out !== "string") {
24606
+ throw new WorkflowError(
24607
+ `Error while parsing output of ${this.stepType} step. Expected a string or undefined, but got: ${typeof out}`
24608
+ );
24609
+ }
24610
+ return this.safeParseOut(out);
24611
+ }
24612
+ safeParseOut(out) {
24613
+ return _BaseLazyStep.tryParsing(out);
24614
+ }
24615
+ static tryParsing(stepOut) {
24616
+ try {
24617
+ return JSON.parse(stepOut);
24618
+ } catch {
24619
+ return stepOut;
24620
+ }
24621
+ }
24622
+ getBody({ step }) {
24623
+ step.out = JSON.stringify(step.out);
24624
+ return JSON.stringify(step);
24625
+ }
24626
+ getHeaders({ context, telemetry: telemetry2, invokeCount, step }) {
24627
+ return getHeaders({
24628
+ initHeaderValue: "false",
24629
+ workflowConfig: {
24630
+ workflowRunId: context.workflowRunId,
24631
+ workflowUrl: context.url,
24632
+ failureUrl: context.failureUrl,
24633
+ retries: context.retries,
24634
+ useJSONContent: false,
24635
+ telemetry: telemetry2,
24636
+ flowControl: context.flowControl
24637
+ },
24638
+ userHeaders: context.headers,
24639
+ invokeCount,
24640
+ stepInfo: {
24641
+ step,
24642
+ lazyStep: this
24643
+ }
24644
+ });
24645
+ }
24646
+ async submitStep({ context, body, headers }) {
24647
+ return await context.qstashClient.batch([
24648
+ {
24649
+ body,
24650
+ headers,
24651
+ method: "POST",
24652
+ url: context.url
24653
+ }
24654
+ ]);
24655
+ }
24656
+ };
24657
+ var LazyFunctionStep = class extends BaseLazyStep {
24658
+ stepFunction;
24659
+ stepType = "Run";
24660
+ allowUndefinedOut = true;
24661
+ constructor(stepName, stepFunction) {
24662
+ super(stepName);
24663
+ this.stepFunction = stepFunction;
24664
+ }
24665
+ getPlanStep(concurrent, targetStep) {
24666
+ return {
24667
+ stepId: 0,
24668
+ stepName: this.stepName,
24669
+ stepType: this.stepType,
24670
+ concurrent,
24671
+ targetStep
24672
+ };
24673
+ }
24674
+ async getResultStep(concurrent, stepId) {
24675
+ let result = this.stepFunction();
24676
+ if (result instanceof Promise) {
24677
+ result = await result;
24678
+ }
24679
+ return {
24680
+ stepId,
24681
+ stepName: this.stepName,
24682
+ stepType: this.stepType,
24683
+ out: result,
24684
+ concurrent
24685
+ };
24686
+ }
24687
+ };
24688
+ var LazySleepStep = class extends BaseLazyStep {
24689
+ sleep;
24690
+ stepType = "SleepFor";
24691
+ allowUndefinedOut = true;
24692
+ constructor(stepName, sleep) {
24693
+ super(stepName);
24694
+ this.sleep = sleep;
24695
+ }
24696
+ getPlanStep(concurrent, targetStep) {
24697
+ return {
24698
+ stepId: 0,
24699
+ stepName: this.stepName,
24700
+ stepType: this.stepType,
24701
+ sleepFor: this.sleep,
24702
+ concurrent,
24703
+ targetStep
24704
+ };
24705
+ }
24706
+ async getResultStep(concurrent, stepId) {
24707
+ return await Promise.resolve({
24708
+ stepId,
24709
+ stepName: this.stepName,
24710
+ stepType: this.stepType,
24711
+ sleepFor: this.sleep,
24712
+ concurrent
24713
+ });
24714
+ }
24715
+ async submitStep({ context, body, headers, isParallel }) {
24716
+ return await context.qstashClient.batch([
24717
+ {
24718
+ body,
24719
+ headers,
24720
+ method: "POST",
24721
+ url: context.url,
24722
+ delay: isParallel ? void 0 : this.sleep
24723
+ }
24724
+ ]);
24725
+ }
24726
+ };
24727
+ var LazySleepUntilStep = class extends BaseLazyStep {
24728
+ sleepUntil;
24729
+ stepType = "SleepUntil";
24730
+ allowUndefinedOut = true;
24731
+ constructor(stepName, sleepUntil) {
24732
+ super(stepName);
24733
+ this.sleepUntil = sleepUntil;
24734
+ }
24735
+ getPlanStep(concurrent, targetStep) {
24736
+ return {
24737
+ stepId: 0,
24738
+ stepName: this.stepName,
24739
+ stepType: this.stepType,
24740
+ sleepUntil: this.sleepUntil,
24741
+ concurrent,
24742
+ targetStep
24743
+ };
24744
+ }
24745
+ async getResultStep(concurrent, stepId) {
24746
+ return await Promise.resolve({
24747
+ stepId,
24748
+ stepName: this.stepName,
24749
+ stepType: this.stepType,
24750
+ sleepUntil: this.sleepUntil,
24751
+ concurrent
24752
+ });
24753
+ }
24754
+ safeParseOut() {
24755
+ return void 0;
24756
+ }
24757
+ async submitStep({ context, body, headers, isParallel }) {
24758
+ return await context.qstashClient.batch([
24759
+ {
24760
+ body,
24761
+ headers,
24762
+ method: "POST",
24763
+ url: context.url,
24764
+ notBefore: isParallel ? void 0 : this.sleepUntil
24765
+ }
24766
+ ]);
24767
+ }
24768
+ };
24769
+ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
24770
+ url;
24771
+ method;
24772
+ body;
24773
+ headers;
24774
+ retries;
24775
+ timeout;
24776
+ flowControl;
24777
+ stepType = "Call";
24778
+ allowUndefinedOut = false;
24779
+ constructor(stepName, url, method, body, headers, retries, timeout, flowControl) {
24780
+ super(stepName);
24781
+ this.url = url;
24782
+ this.method = method;
24783
+ this.body = body;
24784
+ this.headers = headers;
24785
+ this.retries = retries;
24786
+ this.timeout = timeout;
24787
+ this.flowControl = flowControl;
24788
+ }
24789
+ getPlanStep(concurrent, targetStep) {
24790
+ return {
24791
+ stepId: 0,
24792
+ stepName: this.stepName,
24793
+ stepType: this.stepType,
24794
+ concurrent,
24795
+ targetStep
24796
+ };
24797
+ }
24798
+ async getResultStep(concurrent, stepId) {
24799
+ return await Promise.resolve({
24800
+ stepId,
24801
+ stepName: this.stepName,
24802
+ stepType: this.stepType,
24803
+ concurrent,
24804
+ callUrl: this.url,
24805
+ callMethod: this.method,
24806
+ callBody: this.body,
24807
+ callHeaders: this.headers
24808
+ });
24809
+ }
24810
+ safeParseOut(out) {
24811
+ const { header, status, body } = JSON.parse(out);
24812
+ const responseHeaders = new Headers(header);
24813
+ if (_LazyCallStep.isText(responseHeaders.get("content-type"))) {
24814
+ const bytes = new Uint8Array(out.length);
24815
+ for (let i = 0; i < out.length; i++) {
24816
+ bytes[i] = out.charCodeAt(i);
24817
+ }
24818
+ const processedResult = new TextDecoder().decode(bytes);
24819
+ const newBody = JSON.parse(processedResult).body;
24820
+ return {
24821
+ status,
24822
+ header,
24823
+ body: BaseLazyStep.tryParsing(newBody)
24824
+ };
24825
+ } else {
24826
+ return { header, status, body };
24827
+ }
24828
+ }
24829
+ static applicationContentTypes = [
24830
+ "application/json",
24831
+ "application/xml",
24832
+ "application/javascript",
24833
+ "application/x-www-form-urlencoded",
24834
+ "application/xhtml+xml",
24835
+ "application/ld+json",
24836
+ "application/rss+xml",
24837
+ "application/atom+xml"
24838
+ ];
24839
+ static isText = (contentTypeHeader) => {
24840
+ if (!contentTypeHeader) {
24841
+ return false;
24842
+ }
24843
+ if (_LazyCallStep.applicationContentTypes.some((type) => contentTypeHeader.includes(type))) {
24844
+ return true;
24919
24845
  }
24920
- } else {
24921
- if (flowControl) {
24922
- const { flowControlKey, flowControlValue } = prepareFlowControl(flowControl);
24923
- baseHeaders["Upstash-Flow-Control-Key"] = flowControlKey;
24924
- baseHeaders["Upstash-Flow-Control-Value"] = flowControlValue;
24846
+ if (contentTypeHeader.startsWith("text/")) {
24847
+ return true;
24925
24848
  }
24926
- if (retries !== void 0) {
24927
- baseHeaders["Upstash-Retries"] = retries.toString();
24928
- baseHeaders["Upstash-Failure-Callback-Retries"] = retries.toString();
24849
+ return false;
24850
+ };
24851
+ getBody({ step }) {
24852
+ if (!step.callUrl) {
24853
+ throw new WorkflowError("Incompatible step received in LazyCallStep.getBody");
24929
24854
  }
24855
+ return JSON.stringify(step.callBody);
24930
24856
  }
24931
- if (userHeaders) {
24932
- for (const header of userHeaders.keys()) {
24933
- if (step?.callHeaders) {
24934
- baseHeaders[`Upstash-Callback-Forward-${header}`] = userHeaders.get(header);
24935
- } else {
24936
- baseHeaders[`Upstash-Forward-${header}`] = userHeaders.get(header);
24937
- }
24938
- baseHeaders[`Upstash-Failure-Callback-Forward-${header}`] = userHeaders.get(header);
24857
+ getHeaders({ context, telemetry: telemetry2, invokeCount, step }) {
24858
+ const { headers, contentType } = super.getHeaders({ context, telemetry: telemetry2, invokeCount, step });
24859
+ headers["Upstash-Retries"] = this.retries.toString();
24860
+ headers[WORKFLOW_FEATURE_HEADER] = "WF_NoDelete,InitialBody";
24861
+ if (this.flowControl) {
24862
+ const { flowControlKey, flowControlValue } = prepareFlowControl(this.flowControl);
24863
+ headers["Upstash-Flow-Control-Key"] = flowControlKey;
24864
+ headers["Upstash-Flow-Control-Value"] = flowControlValue;
24865
+ }
24866
+ if (this.timeout) {
24867
+ headers["Upstash-Timeout"] = this.timeout.toString();
24939
24868
  }
24940
- }
24941
- if (step?.callHeaders) {
24942
24869
  const forwardedHeaders = Object.fromEntries(
24943
- Object.entries(step.callHeaders).map(([header, value]) => [
24944
- `Upstash-Forward-${header}`,
24945
- value
24946
- ])
24870
+ Object.entries(this.headers).map(([header, value]) => [`Upstash-Forward-${header}`, value])
24947
24871
  );
24948
24872
  return {
24949
24873
  headers: {
24950
- ...baseHeaders,
24874
+ ...headers,
24951
24875
  ...forwardedHeaders,
24952
- "Upstash-Callback": workflowUrl,
24953
- "Upstash-Callback-Workflow-RunId": workflowRunId,
24876
+ "Upstash-Callback": context.url,
24877
+ "Upstash-Callback-Workflow-RunId": context.workflowRunId,
24954
24878
  "Upstash-Callback-Workflow-CallType": "fromCallback",
24955
24879
  "Upstash-Callback-Workflow-Init": "false",
24956
- "Upstash-Callback-Workflow-Url": workflowUrl,
24880
+ "Upstash-Callback-Workflow-Url": context.url,
24957
24881
  "Upstash-Callback-Feature-Set": "LazyFetch,InitialBody",
24958
24882
  "Upstash-Callback-Forward-Upstash-Workflow-Callback": "true",
24959
24883
  "Upstash-Callback-Forward-Upstash-Workflow-StepId": step.stepId.toString(),
24960
- "Upstash-Callback-Forward-Upstash-Workflow-StepName": step.stepName,
24961
- "Upstash-Callback-Forward-Upstash-Workflow-StepType": step.stepType,
24884
+ "Upstash-Callback-Forward-Upstash-Workflow-StepName": this.stepName,
24885
+ "Upstash-Callback-Forward-Upstash-Workflow-StepType": this.stepType,
24962
24886
  "Upstash-Callback-Forward-Upstash-Workflow-Concurrent": step.concurrent.toString(),
24963
24887
  "Upstash-Callback-Forward-Upstash-Workflow-ContentType": contentType,
24964
- [`Upstash-Callback-Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`]: (invokeCount ?? 0).toString(),
24965
24888
  "Upstash-Workflow-CallType": "toCallback"
24889
+ },
24890
+ contentType
24891
+ };
24892
+ }
24893
+ async submitStep({ context, headers }) {
24894
+ return await context.qstashClient.batch([
24895
+ {
24896
+ headers,
24897
+ body: JSON.stringify(this.body),
24898
+ method: this.method,
24899
+ url: this.url
24966
24900
  }
24901
+ ]);
24902
+ }
24903
+ };
24904
+ var LazyWaitForEventStep = class extends BaseLazyStep {
24905
+ eventId;
24906
+ timeout;
24907
+ stepType = "Wait";
24908
+ allowUndefinedOut = false;
24909
+ constructor(stepName, eventId, timeout) {
24910
+ super(stepName);
24911
+ this.eventId = eventId;
24912
+ this.timeout = timeout;
24913
+ }
24914
+ getPlanStep(concurrent, targetStep) {
24915
+ return {
24916
+ stepId: 0,
24917
+ stepName: this.stepName,
24918
+ stepType: this.stepType,
24919
+ waitEventId: this.eventId,
24920
+ timeout: this.timeout,
24921
+ concurrent,
24922
+ targetStep
24967
24923
  };
24968
24924
  }
24969
- if (step?.waitEventId) {
24925
+ async getResultStep(concurrent, stepId) {
24926
+ return await Promise.resolve({
24927
+ stepId,
24928
+ stepName: this.stepName,
24929
+ stepType: this.stepType,
24930
+ waitEventId: this.eventId,
24931
+ timeout: this.timeout,
24932
+ concurrent
24933
+ });
24934
+ }
24935
+ safeParseOut(out) {
24936
+ const result = JSON.parse(out);
24970
24937
  return {
24971
- headers: {
24972
- ...baseHeaders,
24973
- "Upstash-Workflow-CallType": "step"
24974
- },
24975
- timeoutHeaders: {
24976
- // to include user headers:
24977
- ...Object.fromEntries(
24978
- Object.entries(baseHeaders).map(([header, value]) => [header, [value]])
24979
- ),
24980
- // to include telemetry headers:
24981
- ...telemetry2 ? Object.fromEntries(
24982
- Object.entries(getTelemetryHeaders(telemetry2)).map(([header, value]) => [
24983
- header,
24984
- [value]
24985
- ])
24986
- ) : {},
24987
- // note: using WORKFLOW_ID_HEADER doesn't work, because Runid -> RunId:
24988
- "Upstash-Workflow-Runid": [workflowRunId],
24989
- [WORKFLOW_INIT_HEADER]: ["false"],
24990
- [WORKFLOW_URL_HEADER]: [workflowUrl],
24991
- "Upstash-Workflow-CallType": ["step"]
24992
- }
24993
- };
24994
- }
24995
- return { headers: baseHeaders };
24938
+ ...result,
24939
+ eventData: BaseLazyStep.tryParsing(result.eventData)
24940
+ };
24941
+ }
24942
+ getHeaders({ context, telemetry: telemetry2, invokeCount, step }) {
24943
+ const headers = super.getHeaders({ context, telemetry: telemetry2, invokeCount, step });
24944
+ headers.headers["Upstash-Workflow-CallType"] = "step";
24945
+ return headers;
24946
+ }
24947
+ getBody({ context, step, headers, telemetry: telemetry2 }) {
24948
+ if (!step.waitEventId) {
24949
+ throw new WorkflowError("Incompatible step received in LazyWaitForEventStep.getBody");
24950
+ }
24951
+ const timeoutHeaders = {
24952
+ // to include user headers:
24953
+ ...Object.fromEntries(Object.entries(headers).map(([header, value]) => [header, [value]])),
24954
+ // to include telemetry headers:
24955
+ ...telemetry2 ? Object.fromEntries(
24956
+ Object.entries(getTelemetryHeaders(telemetry2)).map(([header, value]) => [
24957
+ header,
24958
+ [value]
24959
+ ])
24960
+ ) : {},
24961
+ // note: using WORKFLOW_ID_HEADER doesn't work, because Runid -> RunId:
24962
+ "Upstash-Workflow-Runid": [context.workflowRunId],
24963
+ [WORKFLOW_INIT_HEADER]: ["false"],
24964
+ [WORKFLOW_URL_HEADER]: [context.url],
24965
+ "Upstash-Workflow-CallType": ["step"]
24966
+ };
24967
+ const waitBody = {
24968
+ url: context.url,
24969
+ timeout: step.timeout,
24970
+ timeoutBody: void 0,
24971
+ timeoutUrl: context.url,
24972
+ timeoutHeaders,
24973
+ step: {
24974
+ stepId: step.stepId,
24975
+ stepType: "Wait",
24976
+ stepName: step.stepName,
24977
+ concurrent: step.concurrent,
24978
+ targetStep: step.targetStep
24979
+ }
24980
+ };
24981
+ return JSON.stringify(waitBody);
24982
+ }
24983
+ async submitStep({ context, body, headers }) {
24984
+ const result = await context.qstashClient.http.request({
24985
+ path: ["v2", "wait", this.eventId],
24986
+ body,
24987
+ headers,
24988
+ method: "POST",
24989
+ parseResponseAsJson: false
24990
+ });
24991
+ return [result];
24992
+ }
24996
24993
  };
24997
- var verifyRequest = async (body, signature, verifier) => {
24998
- if (!verifier) {
24999
- return;
24994
+ var LazyNotifyStep = class extends LazyFunctionStep {
24995
+ stepType = "Notify";
24996
+ constructor(stepName, eventId, eventData, requester) {
24997
+ super(stepName, async () => {
24998
+ const notifyResponse = await makeNotifyRequest(requester, eventId, eventData);
24999
+ return {
25000
+ eventId,
25001
+ eventData,
25002
+ notifyResponse
25003
+ };
25004
+ });
25000
25005
  }
25001
- try {
25002
- if (!signature) {
25003
- throw new Error("`Upstash-Signature` header is not passed.");
25006
+ safeParseOut(out) {
25007
+ const result = JSON.parse(out);
25008
+ return {
25009
+ ...result,
25010
+ eventData: BaseLazyStep.tryParsing(result.eventData)
25011
+ };
25012
+ }
25013
+ };
25014
+ var LazyInvokeStep = class extends BaseLazyStep {
25015
+ stepType = "Invoke";
25016
+ params;
25017
+ allowUndefinedOut = false;
25018
+ /**
25019
+ * workflow id of the invoked workflow
25020
+ */
25021
+ workflowId;
25022
+ constructor(stepName, {
25023
+ workflow,
25024
+ body,
25025
+ headers = {},
25026
+ workflowRunId,
25027
+ retries,
25028
+ flowControl
25029
+ }) {
25030
+ super(stepName);
25031
+ this.params = {
25032
+ workflow,
25033
+ body,
25034
+ headers,
25035
+ workflowRunId: getWorkflowRunId(workflowRunId),
25036
+ retries,
25037
+ flowControl
25038
+ };
25039
+ const { workflowId } = workflow;
25040
+ if (!workflowId) {
25041
+ throw new WorkflowError("You can only invoke workflow which has a workflowId");
25004
25042
  }
25005
- const isValid = await verifier.verify({
25043
+ this.workflowId = workflowId;
25044
+ }
25045
+ getPlanStep(concurrent, targetStep) {
25046
+ return {
25047
+ stepId: 0,
25048
+ stepName: this.stepName,
25049
+ stepType: this.stepType,
25050
+ concurrent,
25051
+ targetStep
25052
+ };
25053
+ }
25054
+ /**
25055
+ * won't be used as it's the server who will add the result step
25056
+ * in Invoke step.
25057
+ */
25058
+ getResultStep(concurrent, stepId) {
25059
+ return Promise.resolve({
25060
+ stepId,
25061
+ stepName: this.stepName,
25062
+ stepType: this.stepType,
25063
+ concurrent
25064
+ });
25065
+ }
25066
+ safeParseOut(out) {
25067
+ const result = JSON.parse(out);
25068
+ return {
25069
+ ...result,
25070
+ body: BaseLazyStep.tryParsing(result.body)
25071
+ };
25072
+ }
25073
+ getBody({ context, step, telemetry: telemetry2, invokeCount }) {
25074
+ const { headers: invokerHeaders } = getHeaders({
25075
+ initHeaderValue: "false",
25076
+ workflowConfig: {
25077
+ workflowRunId: context.workflowRunId,
25078
+ workflowUrl: context.url,
25079
+ failureUrl: context.failureUrl,
25080
+ retries: context.retries,
25081
+ telemetry: telemetry2,
25082
+ flowControl: context.flowControl,
25083
+ useJSONContent: false
25084
+ },
25085
+ userHeaders: context.headers,
25086
+ invokeCount
25087
+ });
25088
+ invokerHeaders["Upstash-Workflow-Runid"] = context.workflowRunId;
25089
+ const request = {
25090
+ body: JSON.stringify(this.params.body),
25091
+ headers: Object.fromEntries(
25092
+ Object.entries(invokerHeaders).map((pairs) => [pairs[0], [pairs[1]]])
25093
+ ),
25094
+ workflowRunId: context.workflowRunId,
25095
+ workflowUrl: context.url,
25096
+ step
25097
+ };
25098
+ return JSON.stringify(request);
25099
+ }
25100
+ getHeaders({ context, telemetry: telemetry2, invokeCount }) {
25101
+ const {
25102
+ workflow,
25103
+ headers = {},
25104
+ workflowRunId = getWorkflowRunId(),
25105
+ retries,
25106
+ flowControl
25107
+ } = this.params;
25108
+ const newUrl = context.url.replace(/[^/]+$/, this.workflowId);
25109
+ const {
25110
+ retries: workflowRetries,
25111
+ failureFunction,
25112
+ failureUrl,
25113
+ useJSONContent,
25114
+ flowControl: workflowFlowControl
25115
+ } = workflow.options;
25116
+ const { headers: triggerHeaders, contentType } = getHeaders({
25117
+ initHeaderValue: "true",
25118
+ workflowConfig: {
25119
+ workflowRunId,
25120
+ workflowUrl: newUrl,
25121
+ retries: retries ?? workflowRetries,
25122
+ telemetry: telemetry2,
25123
+ failureUrl: failureFunction ? newUrl : failureUrl,
25124
+ flowControl: flowControl ?? workflowFlowControl,
25125
+ useJSONContent: useJSONContent ?? false
25126
+ },
25127
+ invokeCount: invokeCount + 1,
25128
+ userHeaders: new Headers(headers)
25129
+ });
25130
+ triggerHeaders["Upstash-Workflow-Invoke"] = "true";
25131
+ return { headers: triggerHeaders, contentType };
25132
+ }
25133
+ async submitStep({ context, body, headers }) {
25134
+ const newUrl = context.url.replace(/[^/]+$/, this.workflowId);
25135
+ const result = await context.qstashClient.publish({
25136
+ headers,
25137
+ method: "POST",
25006
25138
  body,
25007
- signature
25139
+ url: newUrl
25008
25140
  });
25009
- if (!isValid) {
25010
- throw new Error("Signature in `Upstash-Signature` header is not valid");
25011
- }
25012
- } catch (error) {
25013
- throw new WorkflowError(
25014
- `Failed to verify that the Workflow request comes from QStash: ${error}
25141
+ return [result];
25142
+ }
25143
+ };
25015
25144
 
25016
- If signature is missing, trigger the workflow endpoint by publishing your request to QStash instead of calling it directly.
25145
+ // src/agents/constants.ts
25146
+ var AGENT_NAME_HEADER = "upstash-agent-name";
25147
+ var MANAGER_AGENT_PROMPT = `You are an agent orchestrating other AI Agents.
25017
25148
 
25018
- If you want to disable QStash Verification, you should clear env variables QSTASH_CURRENT_SIGNING_KEY and QSTASH_NEXT_SIGNING_KEY`
25149
+ These other agents have tools available to them.
25150
+
25151
+ Given a prompt, utilize these agents to address requests.
25152
+
25153
+ 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.
25154
+
25155
+ Avoid calling the same agent twice in one turn. Instead, prefer to call it once but provide everything
25156
+ you need from that agent.
25157
+ `;
25158
+
25159
+ // src/qstash/headers.ts
25160
+ var WorkflowHeaders = class {
25161
+ userHeaders;
25162
+ workflowConfig;
25163
+ invokeCount;
25164
+ initHeaderValue;
25165
+ stepInfo;
25166
+ headers;
25167
+ constructor({
25168
+ userHeaders,
25169
+ workflowConfig,
25170
+ invokeCount,
25171
+ initHeaderValue,
25172
+ stepInfo
25173
+ }) {
25174
+ this.userHeaders = userHeaders;
25175
+ this.workflowConfig = workflowConfig;
25176
+ this.invokeCount = invokeCount;
25177
+ this.initHeaderValue = initHeaderValue;
25178
+ this.stepInfo = stepInfo;
25179
+ this.headers = {
25180
+ rawHeaders: {},
25181
+ workflowHeaders: {},
25182
+ failureHeaders: {}
25183
+ };
25184
+ }
25185
+ getHeaders() {
25186
+ this.addBaseHeaders();
25187
+ this.addRetries();
25188
+ this.addFlowControl();
25189
+ this.addUserHeaders();
25190
+ this.addInvokeCount();
25191
+ this.addFailureUrl();
25192
+ const contentType = this.addContentType();
25193
+ return this.prefixHeaders(contentType);
25194
+ }
25195
+ addBaseHeaders() {
25196
+ this.headers.rawHeaders = {
25197
+ ...this.headers.rawHeaders,
25198
+ [WORKFLOW_INIT_HEADER]: this.initHeaderValue,
25199
+ [WORKFLOW_ID_HEADER]: this.workflowConfig.workflowRunId,
25200
+ [WORKFLOW_URL_HEADER]: this.workflowConfig.workflowUrl,
25201
+ [WORKFLOW_FEATURE_HEADER]: "LazyFetch,InitialBody",
25202
+ [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION,
25203
+ ...this.workflowConfig.telemetry ? getTelemetryHeaders(this.workflowConfig.telemetry) : {},
25204
+ ...this.workflowConfig.telemetry && this.stepInfo?.lazyStep instanceof LazyCallStep && this.stepInfo.lazyStep.headers[AGENT_NAME_HEADER] ? { [TELEMETRY_HEADER_AGENT]: "true" } : {}
25205
+ };
25206
+ if (this.stepInfo?.lazyStep.stepType !== "Call") {
25207
+ this.headers.rawHeaders[`Upstash-Forward-${WORKFLOW_PROTOCOL_VERSION_HEADER}`] = WORKFLOW_PROTOCOL_VERSION;
25208
+ }
25209
+ }
25210
+ addInvokeCount() {
25211
+ if (this.invokeCount === void 0 || this.invokeCount === 0) {
25212
+ return;
25213
+ }
25214
+ const invokeCount = this.invokeCount.toString();
25215
+ this.headers.workflowHeaders[`Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`] = invokeCount;
25216
+ if (this.workflowConfig.failureUrl) {
25217
+ this.headers.failureHeaders[`Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`] = invokeCount;
25218
+ }
25219
+ if (this.stepInfo?.lazyStep instanceof LazyCallStep) {
25220
+ this.headers.rawHeaders[`Upstash-Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`] = invokeCount;
25221
+ }
25222
+ }
25223
+ addRetries() {
25224
+ if (this.workflowConfig.retries === void 0 || this.workflowConfig.retries === DEFAULT_RETRIES) {
25225
+ return;
25226
+ }
25227
+ const retries = this.workflowConfig.retries.toString();
25228
+ this.headers.workflowHeaders["Retries"] = retries;
25229
+ if (this.workflowConfig.failureUrl) {
25230
+ this.headers.failureHeaders["Retries"] = retries;
25231
+ }
25232
+ }
25233
+ addFlowControl() {
25234
+ if (!this.workflowConfig.flowControl) {
25235
+ return;
25236
+ }
25237
+ const { flowControlKey, flowControlValue } = prepareFlowControl(
25238
+ this.workflowConfig.flowControl
25019
25239
  );
25240
+ this.headers.workflowHeaders["Flow-Control-Key"] = flowControlKey;
25241
+ this.headers.workflowHeaders["Flow-Control-Value"] = flowControlValue;
25242
+ if (this.workflowConfig.failureUrl) {
25243
+ this.headers.failureHeaders["Flow-Control-Key"] = flowControlKey;
25244
+ this.headers.failureHeaders["Flow-Control-Value"] = flowControlValue;
25245
+ }
25246
+ }
25247
+ addUserHeaders() {
25248
+ for (const [key, value] of this.userHeaders.entries()) {
25249
+ const forwardKey = `Forward-${key}`;
25250
+ this.headers.workflowHeaders[forwardKey] = value;
25251
+ if (this.workflowConfig.failureUrl) {
25252
+ this.headers.failureHeaders[forwardKey] = value;
25253
+ }
25254
+ }
25255
+ }
25256
+ addFailureUrl() {
25257
+ if (!this.workflowConfig.failureUrl) {
25258
+ return;
25259
+ }
25260
+ this.headers.workflowHeaders["Failure-Callback"] = this.workflowConfig.failureUrl;
25261
+ this.headers.failureHeaders[`Forward-${WORKFLOW_FAILURE_HEADER}`] = "true";
25262
+ this.headers.failureHeaders[`Forward-Upstash-Workflow-Failure-Callback`] = "true";
25263
+ this.headers.failureHeaders["Workflow-Runid"] = this.workflowConfig.workflowRunId;
25264
+ this.headers.failureHeaders["Workflow-Init"] = "false";
25265
+ this.headers.failureHeaders["Workflow-Url"] = this.workflowConfig.workflowUrl;
25266
+ this.headers.failureHeaders["Workflow-Calltype"] = "failureCall";
25267
+ this.headers.failureHeaders["Feature-Set"] = "LazyFetch,InitialBody";
25268
+ if (this.workflowConfig.retries !== void 0 && this.workflowConfig.retries !== DEFAULT_RETRIES) {
25269
+ this.headers.failureHeaders["Retries"] = this.workflowConfig.retries.toString();
25270
+ }
25271
+ }
25272
+ addContentType() {
25273
+ if (this.workflowConfig.useJSONContent) {
25274
+ this.headers.rawHeaders["content-type"] = "application/json";
25275
+ return "application/json";
25276
+ }
25277
+ const callHeaders = new Headers(
25278
+ this.stepInfo?.lazyStep instanceof LazyCallStep ? this.stepInfo.lazyStep.headers : {}
25279
+ );
25280
+ 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;
25281
+ this.headers.rawHeaders["content-type"] = contentType;
25282
+ return contentType;
25283
+ }
25284
+ prefixHeaders(contentType) {
25285
+ const { rawHeaders, workflowHeaders, failureHeaders } = this.headers;
25286
+ const isCall = this.stepInfo?.lazyStep.stepType === "Call";
25287
+ return {
25288
+ headers: {
25289
+ ...rawHeaders,
25290
+ ...addPrefixToHeaders(workflowHeaders, isCall ? "Upstash-Callback-" : "Upstash-"),
25291
+ ...addPrefixToHeaders(failureHeaders, "Upstash-Failure-Callback-"),
25292
+ ...isCall ? addPrefixToHeaders(failureHeaders, "Upstash-Callback-Failure-Callback-") : {}
25293
+ },
25294
+ contentType
25295
+ };
25020
25296
  }
25021
25297
  };
25298
+ function addPrefixToHeaders(headers, prefix) {
25299
+ const prefixedHeaders = {};
25300
+ for (const [key, value] of Object.entries(headers)) {
25301
+ prefixedHeaders[`${prefix}${key}`] = value;
25302
+ }
25303
+ return prefixedHeaders;
25304
+ }
25022
25305
  var prepareFlowControl = (flowControl) => {
25023
25306
  const parallelism = flowControl.parallelism?.toString();
25024
- const rate = flowControl.ratePerSecond?.toString();
25307
+ const rate = (flowControl.rate ?? flowControl.ratePerSecond)?.toString();
25308
+ const period = typeof flowControl.period === "number" ? `${flowControl.period}s` : flowControl.period;
25025
25309
  const controlValue = [
25026
25310
  parallelism ? `parallelism=${parallelism}` : void 0,
25027
- rate ? `rate=${rate}` : void 0
25311
+ rate ? `rate=${rate}` : void 0,
25312
+ period ? `period=${period}` : void 0
25028
25313
  ].filter(Boolean);
25029
25314
  if (controlValue.length === 0) {
25030
- throw new import_qstash3.QstashError("Provide at least one of parallelism or ratePerSecond for flowControl");
25315
+ throw new import_qstash4.QstashError("Provide at least one of parallelism or ratePerSecond for flowControl");
25031
25316
  }
25032
25317
  return {
25033
25318
  flowControlKey: flowControl.key,
25034
25319
  flowControlValue: controlValue.join(", ")
25035
- };
25036
- };
25037
-
25038
- // src/context/auto-executor.ts
25039
- var import_qstash4 = require("@upstash/qstash");
25040
-
25041
- // src/serve/serve-many.ts
25042
- var getWorkflowId = (url) => {
25043
- const components = url.split("/");
25044
- const lastComponent = components[components.length - 1];
25045
- return lastComponent.split("?")[0];
25046
- };
25047
- var serveManyBase = ({
25048
- workflows,
25049
- getUrl,
25050
- serveMethod,
25051
- options
25320
+ };
25321
+ };
25322
+ var getHeaders = (params) => {
25323
+ const workflowHeaders = new WorkflowHeaders(params);
25324
+ return workflowHeaders.getHeaders();
25325
+ };
25326
+
25327
+ // src/qstash/submit-steps.ts
25328
+ var submitParallelSteps = async ({
25329
+ context,
25330
+ steps,
25331
+ initialStepCount,
25332
+ invokeCount,
25333
+ telemetry: telemetry2,
25334
+ debug
25052
25335
  }) => {
25053
- const workflowIds = [];
25054
- const workflowMap = Object.fromEntries(
25055
- Object.entries(workflows).map((workflow) => {
25056
- const workflowId = workflow[0];
25057
- if (workflowIds.includes(workflowId)) {
25058
- throw new WorkflowError(
25059
- `Duplicate workflow name found: '${workflowId}'. Please set different workflow names in serveMany.`
25060
- );
25061
- }
25062
- if (workflowId.includes("/")) {
25063
- throw new WorkflowError(
25064
- `Invalid workflow name found: '${workflowId}'. Workflow name cannot contain '/'.`
25065
- );
25066
- }
25067
- workflowIds.push(workflowId);
25068
- workflow[1].workflowId = workflowId;
25069
- workflow[1].options = {
25070
- ...options,
25071
- ...workflow[1].options
25336
+ const planSteps = steps.map(
25337
+ (step, index) => step.getPlanStep(steps.length, initialStepCount + index)
25338
+ );
25339
+ await debug?.log("SUBMIT", "SUBMIT_STEP", {
25340
+ length: planSteps.length,
25341
+ steps: planSteps
25342
+ });
25343
+ const result = await context.qstashClient.batch(
25344
+ planSteps.map((planStep) => {
25345
+ const { headers } = getHeaders({
25346
+ initHeaderValue: "false",
25347
+ workflowConfig: {
25348
+ workflowRunId: context.workflowRunId,
25349
+ workflowUrl: context.url,
25350
+ failureUrl: context.failureUrl,
25351
+ retries: context.retries,
25352
+ flowControl: context.flowControl,
25353
+ telemetry: telemetry2
25354
+ },
25355
+ userHeaders: context.headers,
25356
+ invokeCount
25357
+ });
25358
+ return {
25359
+ headers,
25360
+ method: "POST",
25361
+ url: context.url,
25362
+ body: JSON.stringify(planStep),
25363
+ notBefore: planStep.sleepUntil,
25364
+ delay: planStep.sleepFor
25072
25365
  };
25073
- const params = [workflow[1].routeFunction, workflow[1].options];
25074
- const handler = serveMethod(...params);
25075
- return [workflowId, handler];
25076
25366
  })
25077
25367
  );
25078
- return {
25079
- handler: async (...params) => {
25080
- const url = getUrl(...params);
25081
- const pickedWorkflowId = getWorkflowId(url);
25082
- if (!pickedWorkflowId) {
25083
- return new Response(
25084
- `Unexpected request in serveMany. workflowId not set. Please update the URL of your request.`,
25085
- {
25086
- status: 404
25087
- }
25088
- );
25089
- }
25090
- const workflow = workflowMap[pickedWorkflowId];
25091
- if (!workflow) {
25092
- return new Response(
25093
- `No workflows in serveMany found for '${pickedWorkflowId}'. Please update the URL of your request.`,
25094
- {
25095
- status: 404
25096
- }
25097
- );
25098
- }
25099
- return await workflow(...params);
25100
- }
25101
- };
25368
+ await debug?.log("INFO", "SUBMIT_STEP", {
25369
+ messageIds: result.map((message) => {
25370
+ return {
25371
+ message: message.messageId
25372
+ };
25373
+ })
25374
+ });
25375
+ throw new WorkflowAbort(planSteps[0].stepName, planSteps[0]);
25102
25376
  };
25103
- var invokeWorkflow = async ({
25104
- settings,
25105
- invokeStep,
25377
+ var submitSingleStep = async ({
25106
25378
  context,
25379
+ lazyStep,
25380
+ stepId,
25107
25381
  invokeCount,
25108
- telemetry: telemetry2
25382
+ concurrency,
25383
+ telemetry: telemetry2,
25384
+ debug
25109
25385
  }) => {
25110
- const {
25111
- body,
25112
- workflow,
25113
- headers = {},
25114
- workflowRunId = getWorkflowRunId(),
25115
- retries,
25116
- flowControl
25117
- } = settings;
25118
- const { workflowId } = workflow;
25119
- const {
25120
- retries: workflowRetries,
25121
- failureFunction,
25122
- failureUrl,
25123
- useJSONContent,
25124
- flowControl: workflowFlowControl
25125
- } = workflow.options;
25126
- if (!workflowId) {
25127
- throw new WorkflowError("You can only invoke workflow which has a workflowId");
25128
- }
25129
- const { headers: invokerHeaders } = getHeaders({
25130
- initHeaderValue: "false",
25131
- workflowRunId: context.workflowRunId,
25132
- workflowUrl: context.url,
25133
- userHeaders: context.headers,
25134
- failureUrl: context.failureUrl,
25135
- retries: context.retries,
25136
- telemetry: telemetry2,
25386
+ const resultStep = await lazyStep.getResultStep(concurrency, stepId);
25387
+ await debug?.log("INFO", "RUN_SINGLE", {
25388
+ fromRequest: false,
25389
+ step: resultStep,
25390
+ stepCount: stepId
25391
+ });
25392
+ const { headers } = lazyStep.getHeaders({
25393
+ context,
25394
+ step: resultStep,
25137
25395
  invokeCount,
25138
- flowControl: context.flowControl
25396
+ telemetry: telemetry2
25139
25397
  });
25140
- invokerHeaders["Upstash-Workflow-Runid"] = context.workflowRunId;
25141
- const newUrl = context.url.replace(/[^/]+$/, workflowId);
25142
- const { headers: triggerHeaders } = getHeaders({
25143
- initHeaderValue: "true",
25144
- workflowRunId,
25145
- workflowUrl: newUrl,
25146
- userHeaders: new Headers(headers),
25147
- retries: retries ?? workflowRetries,
25148
- telemetry: telemetry2,
25149
- failureUrl: failureFunction ? newUrl : failureUrl,
25150
- invokeCount: invokeCount + 1,
25151
- flowControl: flowControl ?? workflowFlowControl
25398
+ const body = lazyStep.getBody({
25399
+ context,
25400
+ step: resultStep,
25401
+ headers,
25402
+ invokeCount,
25403
+ telemetry: telemetry2
25152
25404
  });
25153
- triggerHeaders["Upstash-Workflow-Invoke"] = "true";
25154
- if (useJSONContent) {
25155
- triggerHeaders["content-type"] = "application/json";
25156
- }
25157
- const request = {
25158
- body: JSON.stringify(body),
25159
- headers: Object.fromEntries(
25160
- Object.entries(invokerHeaders).map((pairs) => [pairs[0], [pairs[1]]])
25161
- ),
25162
- workflowRunId: context.workflowRunId,
25163
- workflowUrl: context.url,
25164
- step: invokeStep
25165
- };
25166
- await context.qstashClient.publish({
25167
- headers: triggerHeaders,
25168
- method: "POST",
25169
- body: JSON.stringify(request),
25170
- url: newUrl
25405
+ await debug?.log("SUBMIT", "SUBMIT_STEP", {
25406
+ length: 1,
25407
+ steps: [resultStep]
25408
+ });
25409
+ const submitResult = await lazyStep.submitStep({
25410
+ context,
25411
+ body,
25412
+ headers,
25413
+ isParallel: concurrency !== NO_CONCURRENCY,
25414
+ invokeCount,
25415
+ step: resultStep,
25416
+ telemetry: telemetry2
25417
+ });
25418
+ await debug?.log("INFO", "SUBMIT_STEP", {
25419
+ messageIds: submitResult.map((message) => {
25420
+ return {
25421
+ message: message.messageId
25422
+ };
25423
+ })
25171
25424
  });
25425
+ return resultStep;
25172
25426
  };
25173
25427
 
25174
25428
  // src/context/auto-executor.ts
@@ -25275,14 +25529,16 @@ var AutoExecutor = class _AutoExecutor {
25275
25529
  });
25276
25530
  return lazyStep.parseOut(step.out);
25277
25531
  }
25278
- const resultStep = await lazyStep.getResultStep(NO_CONCURRENCY, this.stepCount);
25279
- await this.debug?.log("INFO", "RUN_SINGLE", {
25280
- fromRequest: false,
25281
- step: resultStep,
25282
- stepCount: this.stepCount
25532
+ const resultStep = await submitSingleStep({
25533
+ context: this.context,
25534
+ lazyStep,
25535
+ stepId: this.stepCount,
25536
+ invokeCount: this.invokeCount,
25537
+ concurrency: 1,
25538
+ telemetry: this.telemetry,
25539
+ debug: this.debug
25283
25540
  });
25284
- await this.submitStepsToQStash([resultStep], [lazyStep]);
25285
- return resultStep.out;
25541
+ throw new WorkflowAbort(lazyStep.stepName, resultStep);
25286
25542
  }
25287
25543
  /**
25288
25544
  * Runs steps in parallel.
@@ -25310,10 +25566,14 @@ var AutoExecutor = class _AutoExecutor {
25310
25566
  });
25311
25567
  switch (parallelCallState) {
25312
25568
  case "first": {
25313
- const planSteps = parallelSteps.map(
25314
- (parallelStep, index) => parallelStep.getPlanStep(parallelSteps.length, initialStepCount + index)
25315
- );
25316
- await this.submitStepsToQStash(planSteps, parallelSteps);
25569
+ await submitParallelSteps({
25570
+ context: this.context,
25571
+ steps: parallelSteps,
25572
+ initialStepCount,
25573
+ invokeCount: this.invokeCount,
25574
+ telemetry: this.telemetry,
25575
+ debug: this.debug
25576
+ });
25317
25577
  break;
25318
25578
  }
25319
25579
  case "partial": {
@@ -25327,13 +25587,18 @@ var AutoExecutor = class _AutoExecutor {
25327
25587
  validateStep(parallelSteps[stepIndex], planStep);
25328
25588
  try {
25329
25589
  const parallelStep = parallelSteps[stepIndex];
25330
- const resultStep = await parallelStep.getResultStep(
25331
- parallelSteps.length,
25332
- planStep.targetStep
25333
- );
25334
- await this.submitStepsToQStash([resultStep], [parallelStep]);
25590
+ const resultStep = await submitSingleStep({
25591
+ context: this.context,
25592
+ lazyStep: parallelStep,
25593
+ stepId: planStep.targetStep,
25594
+ invokeCount: this.invokeCount,
25595
+ concurrency: parallelSteps.length,
25596
+ telemetry: this.telemetry,
25597
+ debug: this.debug
25598
+ });
25599
+ throw new WorkflowAbort(parallelStep.stepName, resultStep);
25335
25600
  } catch (error) {
25336
- if (error instanceof WorkflowAbort || error instanceof import_qstash4.QstashError && error.status === 400) {
25601
+ if (error instanceof WorkflowAbort || error instanceof import_qstash5.QstashError && error.status === 400) {
25337
25602
  throw error;
25338
25603
  }
25339
25604
  throw new WorkflowError(
@@ -25389,128 +25654,6 @@ var AutoExecutor = class _AutoExecutor {
25389
25654
  return "discard";
25390
25655
  }
25391
25656
  }
25392
- /**
25393
- * sends the steps to QStash as batch
25394
- *
25395
- * @param steps steps to send
25396
- */
25397
- async submitStepsToQStash(steps, lazySteps) {
25398
- if (steps.length === 0) {
25399
- throw new WorkflowError(
25400
- `Unable to submit steps to QStash. Provided list is empty. Current step: ${this.stepCount}`
25401
- );
25402
- }
25403
- await this.debug?.log("SUBMIT", "SUBMIT_STEP", {
25404
- length: steps.length,
25405
- steps
25406
- });
25407
- if (steps[0].waitEventId && steps.length === 1) {
25408
- const waitStep = steps[0];
25409
- const { headers, timeoutHeaders } = getHeaders({
25410
- initHeaderValue: "false",
25411
- workflowRunId: this.context.workflowRunId,
25412
- workflowUrl: this.context.url,
25413
- userHeaders: this.context.headers,
25414
- step: waitStep,
25415
- failureUrl: this.context.failureUrl,
25416
- retries: this.context.retries,
25417
- telemetry: this.telemetry,
25418
- invokeCount: this.invokeCount,
25419
- flowControl: this.context.flowControl
25420
- });
25421
- const waitBody = {
25422
- url: this.context.url,
25423
- timeout: waitStep.timeout,
25424
- timeoutBody: void 0,
25425
- timeoutUrl: this.context.url,
25426
- timeoutHeaders,
25427
- step: {
25428
- stepId: waitStep.stepId,
25429
- stepType: "Wait",
25430
- stepName: waitStep.stepName,
25431
- concurrent: waitStep.concurrent,
25432
- targetStep: waitStep.targetStep
25433
- }
25434
- };
25435
- await this.context.qstashClient.http.request({
25436
- path: ["v2", "wait", waitStep.waitEventId],
25437
- body: JSON.stringify(waitBody),
25438
- headers,
25439
- method: "POST",
25440
- parseResponseAsJson: false
25441
- });
25442
- throw new WorkflowAbort(waitStep.stepName, waitStep);
25443
- }
25444
- if (steps.length === 1 && lazySteps[0] instanceof LazyInvokeStep) {
25445
- const invokeStep = steps[0];
25446
- const lazyInvokeStep = lazySteps[0];
25447
- await invokeWorkflow({
25448
- settings: lazyInvokeStep.params,
25449
- invokeStep,
25450
- context: this.context,
25451
- invokeCount: this.invokeCount,
25452
- telemetry: this.telemetry
25453
- });
25454
- throw new WorkflowAbort(invokeStep.stepName, invokeStep);
25455
- }
25456
- const result = await this.context.qstashClient.batch(
25457
- steps.map((singleStep, index) => {
25458
- const lazyStep = lazySteps[index];
25459
- const { headers } = getHeaders({
25460
- initHeaderValue: "false",
25461
- workflowRunId: this.context.workflowRunId,
25462
- workflowUrl: this.context.url,
25463
- userHeaders: this.context.headers,
25464
- step: singleStep,
25465
- failureUrl: this.context.failureUrl,
25466
- retries: this.context.retries,
25467
- callRetries: lazyStep instanceof LazyCallStep ? lazyStep.retries : void 0,
25468
- callTimeout: lazyStep instanceof LazyCallStep ? lazyStep.timeout : void 0,
25469
- telemetry: this.telemetry,
25470
- invokeCount: this.invokeCount,
25471
- flowControl: this.context.flowControl,
25472
- callFlowControl: lazyStep instanceof LazyCallStep ? lazyStep.flowControl : void 0
25473
- });
25474
- const willWait = singleStep.concurrent === NO_CONCURRENCY || singleStep.stepId === 0;
25475
- singleStep.out = JSON.stringify(singleStep.out);
25476
- return singleStep.callUrl && lazyStep instanceof LazyCallStep ? (
25477
- // if the step is a third party call, we call the third party
25478
- // url (singleStep.callUrl) and pass information about the workflow
25479
- // in the headers (handled in getHeaders). QStash makes the request
25480
- // to callUrl and returns the result to Workflow endpoint.
25481
- // handleThirdPartyCallResult method sends the result of the third
25482
- // party call to QStash.
25483
- {
25484
- headers,
25485
- method: singleStep.callMethod,
25486
- body: JSON.stringify(singleStep.callBody),
25487
- url: singleStep.callUrl
25488
- }
25489
- ) : (
25490
- // if the step is not a third party call, we use workflow
25491
- // endpoint (context.url) as URL when calling QStash. QStash
25492
- // calls us back with the updated steps list.
25493
- {
25494
- headers,
25495
- method: "POST",
25496
- body: JSON.stringify(singleStep),
25497
- url: this.context.url,
25498
- notBefore: willWait ? singleStep.sleepUntil : void 0,
25499
- delay: willWait ? singleStep.sleepFor : void 0
25500
- }
25501
- );
25502
- })
25503
- );
25504
- const _result = result;
25505
- await this.debug?.log("INFO", "SUBMIT_STEP", {
25506
- messageIds: _result.map((message) => {
25507
- return {
25508
- message: message.messageId
25509
- };
25510
- })
25511
- });
25512
- throw new WorkflowAbort(steps[0].stepName, steps[0]);
25513
- }
25514
25657
  /**
25515
25658
  * Get the promise by executing the lazt steps list. If there is a single
25516
25659
  * step, we call `runSingle`. Otherwise `runParallel` is called.
@@ -25584,7 +25727,7 @@ var sortSteps = (steps) => {
25584
25727
  };
25585
25728
 
25586
25729
  // src/context/api/anthropic.ts
25587
- var import_qstash5 = require("@upstash/qstash");
25730
+ var import_qstash6 = require("@upstash/qstash");
25588
25731
 
25589
25732
  // src/context/provider.ts
25590
25733
  var getProviderInfo = (api) => {
@@ -25648,7 +25791,7 @@ var AnthropicAPI = class extends BaseWorkflowApi {
25648
25791
  return await this.callApi(stepName, {
25649
25792
  api: {
25650
25793
  name: "llm",
25651
- provider: (0, import_qstash5.anthropic)({ token })
25794
+ provider: (0, import_qstash6.anthropic)({ token })
25652
25795
  },
25653
25796
  ...parameters
25654
25797
  });
@@ -25656,12 +25799,12 @@ var AnthropicAPI = class extends BaseWorkflowApi {
25656
25799
  };
25657
25800
 
25658
25801
  // src/context/api/openai.ts
25659
- var import_qstash6 = require("@upstash/qstash");
25802
+ var import_qstash7 = require("@upstash/qstash");
25660
25803
  var OpenAIAPI = class extends BaseWorkflowApi {
25661
25804
  async call(stepName, settings) {
25662
25805
  const { token, organization, operation, baseURL, ...parameters } = settings;
25663
25806
  const useOpenAI = baseURL === void 0;
25664
- const provider = useOpenAI ? (0, import_qstash6.openai)({ token, organization }) : (0, import_qstash6.custom)({ baseUrl: baseURL, token });
25807
+ const provider = useOpenAI ? (0, import_qstash7.openai)({ token, organization }) : (0, import_qstash7.custom)({ baseUrl: baseURL, token });
25665
25808
  return await this.callApi(stepName, {
25666
25809
  api: {
25667
25810
  name: "llm",
@@ -25673,14 +25816,14 @@ var OpenAIAPI = class extends BaseWorkflowApi {
25673
25816
  };
25674
25817
 
25675
25818
  // src/context/api/resend.ts
25676
- var import_qstash7 = require("@upstash/qstash");
25819
+ var import_qstash8 = require("@upstash/qstash");
25677
25820
  var ResendAPI = class extends BaseWorkflowApi {
25678
25821
  async call(stepName, settings) {
25679
25822
  const { token, batch = false, ...parameters } = settings;
25680
25823
  return await this.callApi(stepName, {
25681
25824
  api: {
25682
25825
  name: "email",
25683
- provider: (0, import_qstash7.resend)({ token, batch })
25826
+ provider: (0, import_qstash8.resend)({ token, batch })
25684
25827
  },
25685
25828
  ...parameters
25686
25829
  });
@@ -25707,28 +25850,11 @@ var WorkflowApi = class extends BaseWorkflowApi {
25707
25850
  };
25708
25851
 
25709
25852
  // src/agents/index.ts
25710
- var import_openai3 = require("@ai-sdk/openai");
25711
-
25712
- // src/agents/adapters.ts
25713
25853
  var import_openai2 = require("@ai-sdk/openai");
25714
- var import_ai = require("ai");
25715
-
25716
- // src/agents/constants.ts
25717
- var AGENT_NAME_HEADER = "upstash-agent-name";
25718
- var MANAGER_AGENT_PROMPT = `You are an agent orchestrating other AI Agents.
25719
-
25720
- These other agents have tools available to them.
25721
-
25722
- Given a prompt, utilize these agents to address requests.
25723
-
25724
- 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.
25725
-
25726
- Avoid calling the same agent twice in one turn. Instead, prefer to call it once but provide everything
25727
- you need from that agent.
25728
- `;
25729
25854
 
25730
25855
  // src/agents/adapters.ts
25731
- var fetchWithContextCall = async (context, ...params) => {
25856
+ var import_ai = require("ai");
25857
+ var fetchWithContextCall = async (context, agentCallParams, ...params) => {
25732
25858
  const [input, init] = params;
25733
25859
  try {
25734
25860
  const headers = init?.headers ? Object.fromEntries(new Headers(init.headers).entries()) : {};
@@ -25739,7 +25865,10 @@ var fetchWithContextCall = async (context, ...params) => {
25739
25865
  url: input.toString(),
25740
25866
  method: init?.method,
25741
25867
  headers,
25742
- body
25868
+ body,
25869
+ timeout: agentCallParams?.timeout,
25870
+ retries: agentCallParams?.retries,
25871
+ flowControl: agentCallParams?.flowControl
25743
25872
  });
25744
25873
  const responseHeaders = new Headers(
25745
25874
  Object.entries(responseInfo.header).reduce(
@@ -25766,10 +25895,11 @@ var fetchWithContextCall = async (context, ...params) => {
25766
25895
  var createWorkflowModel = ({
25767
25896
  context,
25768
25897
  provider,
25769
- providerParams
25898
+ providerParams,
25899
+ agentCallParams
25770
25900
  }) => {
25771
25901
  return provider({
25772
- fetch: (...params) => fetchWithContextCall(context, ...params),
25902
+ fetch: (...params) => fetchWithContextCall(context, agentCallParams, ...params),
25773
25903
  ...providerParams
25774
25904
  });
25775
25905
  };
@@ -26009,17 +26139,87 @@ var WorkflowAgents = class {
26009
26139
  */
26010
26140
  openai(...params) {
26011
26141
  const [model, settings] = params;
26012
- const { baseURL, apiKey, ...otherSettings } = settings ?? {};
26142
+ const { baseURL, apiKey, callSettings, ...otherSettings } = settings ?? {};
26013
26143
  const openaiModel = this.AISDKModel({
26014
26144
  context: this.context,
26015
- provider: import_openai3.createOpenAI,
26016
- providerParams: { baseURL, apiKey, compatibility: "strict" }
26145
+ provider: import_openai2.createOpenAI,
26146
+ providerParams: { baseURL, apiKey, compatibility: "strict" },
26147
+ agentCallParams: callSettings
26017
26148
  });
26018
26149
  return openaiModel(model, otherSettings);
26019
26150
  }
26020
26151
  AISDKModel = createWorkflowModel;
26021
26152
  };
26022
26153
 
26154
+ // src/serve/serve-many.ts
26155
+ var getWorkflowId = (url) => {
26156
+ const components = url.split("/");
26157
+ const lastComponent = components[components.length - 1];
26158
+ return lastComponent.split("?")[0];
26159
+ };
26160
+ var serveManyBase = ({
26161
+ workflows,
26162
+ getUrl,
26163
+ serveMethod,
26164
+ options
26165
+ }) => {
26166
+ const workflowIds = [];
26167
+ const workflowMap = Object.fromEntries(
26168
+ Object.entries(workflows).map((workflow) => {
26169
+ const workflowId = workflow[0];
26170
+ if (workflowIds.includes(workflowId)) {
26171
+ throw new WorkflowError(
26172
+ `Duplicate workflow name found: '${workflowId}'. Please set different workflow names in serveMany.`
26173
+ );
26174
+ }
26175
+ if (workflowId.includes("/")) {
26176
+ throw new WorkflowError(
26177
+ `Invalid workflow name found: '${workflowId}'. Workflow name cannot contain '/'.`
26178
+ );
26179
+ }
26180
+ workflowIds.push(workflowId);
26181
+ workflow[1].workflowId = workflowId;
26182
+ workflow[1].options = {
26183
+ ...options,
26184
+ ...workflow[1].options
26185
+ };
26186
+ const params = [workflow[1].routeFunction, workflow[1].options];
26187
+ const handler = serveMethod(...params);
26188
+ return [workflowId, handler];
26189
+ })
26190
+ );
26191
+ return {
26192
+ handler: async (...params) => {
26193
+ const url = getUrl(...params);
26194
+ const pickedWorkflowId = getWorkflowId(url);
26195
+ if (!pickedWorkflowId) {
26196
+ return new Response(
26197
+ `Unexpected request in serveMany. workflowId not set. Please update the URL of your request.`,
26198
+ {
26199
+ status: 404
26200
+ }
26201
+ );
26202
+ }
26203
+ const workflow = workflowMap[pickedWorkflowId];
26204
+ if (!workflow) {
26205
+ return new Response(
26206
+ `No workflows in serveMany found for '${pickedWorkflowId}'. Please update the URL of your request.`,
26207
+ {
26208
+ status: 404
26209
+ }
26210
+ );
26211
+ }
26212
+ return await workflow(...params);
26213
+ }
26214
+ };
26215
+ };
26216
+ var getNewUrlFromWorkflowId = (url, workflowId) => {
26217
+ if (!workflowId) {
26218
+ throw new WorkflowError("You can only call workflow which has a workflowId");
26219
+ }
26220
+ return url.replace(/[^/]+$/, workflowId);
26221
+ };
26222
+
26023
26223
  // src/context/context.ts
26024
26224
  var WorkflowContext = class {
26025
26225
  executor;
@@ -26241,60 +26441,42 @@ var WorkflowContext = class {
26241
26441
  }
26242
26442
  await this.addStep(new LazySleepUntilStep(stepName, time));
26243
26443
  }
26244
- /**
26245
- * Makes a third party call through QStash in order to make a
26246
- * network call without consuming any runtime.
26247
- *
26248
- * ```ts
26249
- * const { status, body } = await context.call<string>(
26250
- * "post call step",
26251
- * {
26252
- * url: "https://www.some-endpoint.com/api",
26253
- * method: "POST",
26254
- * body: "my-payload"
26255
- * }
26256
- * );
26257
- * ```
26258
- *
26259
- * tries to parse the result of the request as JSON. If it's
26260
- * not a JSON which can be parsed, simply returns the response
26261
- * body as it is.
26262
- *
26263
- * @param stepName
26264
- * @param url url to call
26265
- * @param method call method. "GET" by default.
26266
- * @param body call body
26267
- * @param headers call headers
26268
- * @param retries number of call retries. 0 by default
26269
- * @param timeout max duration to wait for the endpoint to respond. in seconds.
26270
- * @returns call result as {
26271
- * status: number;
26272
- * body: unknown;
26273
- * header: Record<string, string[]>
26274
- * }
26275
- */
26276
26444
  async call(stepName, settings) {
26277
- const {
26278
- url,
26279
- method = "GET",
26280
- body: requestBody,
26281
- headers = {},
26282
- retries = 0,
26283
- timeout,
26284
- flowControl
26285
- } = settings;
26286
- return await this.addStep(
26287
- new LazyCallStep(
26445
+ let callStep;
26446
+ if ("workflow" in settings) {
26447
+ const url = getNewUrlFromWorkflowId(this.url, settings.workflow.workflowId);
26448
+ callStep = new LazyCallStep(
26449
+ stepName,
26450
+ url,
26451
+ "POST",
26452
+ settings.body,
26453
+ settings.headers || {},
26454
+ settings.retries || 0,
26455
+ settings.timeout,
26456
+ settings.flowControl ?? settings.workflow.options.flowControl
26457
+ );
26458
+ } else {
26459
+ const {
26460
+ url,
26461
+ method = "GET",
26462
+ body,
26463
+ headers = {},
26464
+ retries = 0,
26465
+ timeout,
26466
+ flowControl
26467
+ } = settings;
26468
+ callStep = new LazyCallStep(
26288
26469
  stepName,
26289
26470
  url,
26290
26471
  method,
26291
- requestBody,
26472
+ body,
26292
26473
  headers,
26293
26474
  retries,
26294
26475
  timeout,
26295
26476
  flowControl
26296
- )
26297
- );
26477
+ );
26478
+ }
26479
+ return await this.addStep(callStep);
26298
26480
  }
26299
26481
  /**
26300
26482
  * Pauses workflow execution until a specific event occurs or a timeout is reached.
@@ -26442,7 +26624,7 @@ var WorkflowLogger = class _WorkflowLogger {
26442
26624
  };
26443
26625
 
26444
26626
  // src/serve/authorization.ts
26445
- var import_qstash8 = require("@upstash/qstash");
26627
+ var import_qstash9 = require("@upstash/qstash");
26446
26628
  var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowContext {
26447
26629
  static disabledMessage = "disabled-qstash-worklfow-run";
26448
26630
  disabled = true;
@@ -26474,7 +26656,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
26474
26656
  */
26475
26657
  static async tryAuthentication(routeFunction, context) {
26476
26658
  const disabledContext = new _DisabledWorkflowContext({
26477
- qstashClient: new import_qstash8.Client({
26659
+ qstashClient: new import_qstash9.Client({
26478
26660
  baseUrl: "disabled-client",
26479
26661
  token: "disabled-client"
26480
26662
  }),
@@ -26688,15 +26870,15 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
26688
26870
  };
26689
26871
 
26690
26872
  // src/serve/options.ts
26691
- var import_qstash9 = require("@upstash/qstash");
26692
26873
  var import_qstash10 = require("@upstash/qstash");
26874
+ var import_qstash11 = require("@upstash/qstash");
26693
26875
  var processOptions = (options) => {
26694
26876
  const environment = options?.env ?? (typeof process === "undefined" ? {} : process.env);
26695
26877
  const receiverEnvironmentVariablesSet = Boolean(
26696
26878
  environment.QSTASH_CURRENT_SIGNING_KEY && environment.QSTASH_NEXT_SIGNING_KEY
26697
26879
  );
26698
26880
  return {
26699
- qstashClient: new import_qstash10.Client({
26881
+ qstashClient: new import_qstash11.Client({
26700
26882
  baseUrl: environment.QSTASH_URL,
26701
26883
  token: environment.QSTASH_TOKEN
26702
26884
  }),
@@ -26731,7 +26913,7 @@ var processOptions = (options) => {
26731
26913
  throw error;
26732
26914
  }
26733
26915
  },
26734
- receiver: receiverEnvironmentVariablesSet ? new import_qstash9.Receiver({
26916
+ receiver: receiverEnvironmentVariablesSet ? new import_qstash10.Receiver({
26735
26917
  currentSigningKey: environment.QSTASH_CURRENT_SIGNING_KEY,
26736
26918
  nextSigningKey: environment.QSTASH_NEXT_SIGNING_KEY
26737
26919
  }) : void 0,