@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/h3.js CHANGED
@@ -403,11 +403,12 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
403
403
  var DEFAULT_CONTENT_TYPE = "application/json";
404
404
  var NO_CONCURRENCY = 1;
405
405
  var DEFAULT_RETRIES = 3;
406
- var VERSION = "v0.2.7";
406
+ var VERSION = "v0.2.14";
407
407
  var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
408
408
  var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
409
409
  var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
410
410
  var TELEMETRY_HEADER_RUNTIME = "Upstash-Telemetry-Runtime";
411
+ var TELEMETRY_HEADER_AGENT = "Upstash-Telemetry-Agent";
411
412
 
412
413
  // src/error.ts
413
414
  var import_qstash2 = require("@upstash/qstash");
@@ -450,6 +451,12 @@ var formatWorkflowError = (error) => {
450
451
  };
451
452
  };
452
453
 
454
+ // src/context/auto-executor.ts
455
+ var import_qstash5 = require("@upstash/qstash");
456
+
457
+ // src/qstash/headers.ts
458
+ var import_qstash4 = require("@upstash/qstash");
459
+
453
460
  // src/utils.ts
454
461
  var NANOID_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
455
462
  var NANOID_LENGTH = 21;
@@ -475,574 +482,231 @@ function decodeBase64(base64) {
475
482
  }
476
483
  }
477
484
 
478
- // src/context/steps.ts
479
- var BaseLazyStep = class _BaseLazyStep {
480
- stepName;
481
- constructor(stepName) {
482
- if (!stepName) {
483
- throw new WorkflowError(
484
- "A workflow step name cannot be undefined or an empty string. Please provide a name for your workflow step."
485
- );
486
- }
487
- this.stepName = stepName;
485
+ // node_modules/neverthrow/dist/index.es.js
486
+ var defaultErrorConfig = {
487
+ withStackTrace: false
488
+ };
489
+ var createNeverThrowError = (message, result, config = defaultErrorConfig) => {
490
+ const data = result.isOk() ? { type: "Ok", value: result.value } : { type: "Err", value: result.error };
491
+ const maybeStack = config.withStackTrace ? new Error().stack : void 0;
492
+ return {
493
+ data,
494
+ message,
495
+ stack: maybeStack
496
+ };
497
+ };
498
+ function __awaiter(thisArg, _arguments, P, generator) {
499
+ function adopt(value) {
500
+ return value instanceof P ? value : new P(function(resolve) {
501
+ resolve(value);
502
+ });
488
503
  }
489
- /**
490
- * parse the out field of a step result.
491
- *
492
- * will be called when returning the steps to the context from auto executor
493
- *
494
- * @param out field of the step
495
- * @returns parsed out field
496
- */
497
- parseOut(out) {
498
- if (out === void 0) {
499
- if (this.allowUndefinedOut) {
500
- return void 0;
501
- } else {
502
- throw new WorkflowError(
503
- `Error while parsing output of ${this.stepType} step. Expected a string, but got: undefined`
504
- );
504
+ return new (P || (P = Promise))(function(resolve, reject) {
505
+ function fulfilled(value) {
506
+ try {
507
+ step(generator.next(value));
508
+ } catch (e) {
509
+ reject(e);
505
510
  }
506
511
  }
507
- if (typeof out === "object") {
508
- if (this.stepType !== "Wait") {
509
- console.warn(
510
- `Error while parsing ${this.stepType} step output. Expected a string, but got object. Please reach out to Upstash Support.`
511
- );
512
- return out;
512
+ function rejected(value) {
513
+ try {
514
+ step(generator["throw"](value));
515
+ } catch (e) {
516
+ reject(e);
513
517
  }
514
- return {
515
- ...out,
516
- eventData: _BaseLazyStep.tryParsing(out.eventData)
517
- };
518
518
  }
519
- if (typeof out !== "string") {
520
- throw new WorkflowError(
521
- `Error while parsing output of ${this.stepType} step. Expected a string or undefined, but got: ${typeof out}`
522
- );
519
+ function step(result) {
520
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
523
521
  }
524
- return this.safeParseOut(out);
525
- }
526
- safeParseOut(out) {
527
- return _BaseLazyStep.tryParsing(out);
522
+ step((generator = generator.apply(thisArg, [])).next());
523
+ });
524
+ }
525
+ function __values(o) {
526
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
527
+ if (m) return m.call(o);
528
+ if (o && typeof o.length === "number") return {
529
+ next: function() {
530
+ if (o && i >= o.length) o = void 0;
531
+ return { value: o && o[i++], done: !o };
532
+ }
533
+ };
534
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
535
+ }
536
+ function __await(v) {
537
+ return this instanceof __await ? (this.v = v, this) : new __await(v);
538
+ }
539
+ function __asyncGenerator(thisArg, _arguments, generator) {
540
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
541
+ var g = generator.apply(thisArg, _arguments || []), i, q = [];
542
+ return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() {
543
+ return this;
544
+ }, i;
545
+ function verb(n) {
546
+ if (g[n]) i[n] = function(v) {
547
+ return new Promise(function(a, b) {
548
+ q.push([n, v, a, b]) > 1 || resume(n, v);
549
+ });
550
+ };
528
551
  }
529
- static tryParsing(stepOut) {
552
+ function resume(n, v) {
530
553
  try {
531
- return JSON.parse(stepOut);
532
- } catch {
533
- return stepOut;
554
+ step(g[n](v));
555
+ } catch (e) {
556
+ settle(q[0][3], e);
534
557
  }
535
558
  }
536
- };
537
- var LazyFunctionStep = class extends BaseLazyStep {
538
- stepFunction;
539
- stepType = "Run";
540
- allowUndefinedOut = true;
541
- constructor(stepName, stepFunction) {
542
- super(stepName);
543
- this.stepFunction = stepFunction;
559
+ function step(r) {
560
+ r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r);
544
561
  }
545
- getPlanStep(concurrent, targetStep) {
546
- return {
547
- stepId: 0,
548
- stepName: this.stepName,
549
- stepType: this.stepType,
550
- concurrent,
551
- targetStep
552
- };
562
+ function fulfill(value) {
563
+ resume("next", value);
553
564
  }
554
- async getResultStep(concurrent, stepId) {
555
- let result = this.stepFunction();
556
- if (result instanceof Promise) {
557
- result = await result;
558
- }
559
- return {
560
- stepId,
561
- stepName: this.stepName,
562
- stepType: this.stepType,
563
- out: result,
564
- concurrent
565
- };
565
+ function reject(value) {
566
+ resume("throw", value);
566
567
  }
567
- };
568
- var LazySleepStep = class extends BaseLazyStep {
569
- sleep;
570
- stepType = "SleepFor";
571
- allowUndefinedOut = true;
572
- constructor(stepName, sleep) {
573
- super(stepName);
574
- this.sleep = sleep;
568
+ function settle(f, v) {
569
+ if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]);
575
570
  }
576
- getPlanStep(concurrent, targetStep) {
577
- return {
578
- stepId: 0,
579
- stepName: this.stepName,
580
- stepType: this.stepType,
581
- sleepFor: this.sleep,
582
- concurrent,
583
- targetStep
571
+ }
572
+ function __asyncDelegator(o) {
573
+ var i, p;
574
+ return i = {}, verb("next"), verb("throw", function(e) {
575
+ throw e;
576
+ }), verb("return"), i[Symbol.iterator] = function() {
577
+ return this;
578
+ }, i;
579
+ function verb(n, f) {
580
+ i[n] = o[n] ? function(v) {
581
+ return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v;
582
+ } : f;
583
+ }
584
+ }
585
+ function __asyncValues(o) {
586
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
587
+ var m = o[Symbol.asyncIterator], i;
588
+ 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() {
589
+ return this;
590
+ }, i);
591
+ function verb(n) {
592
+ i[n] = o[n] && function(v) {
593
+ return new Promise(function(resolve, reject) {
594
+ v = o[n](v), settle(resolve, reject, v.done, v.value);
595
+ });
584
596
  };
585
597
  }
586
- async getResultStep(concurrent, stepId) {
587
- return await Promise.resolve({
588
- stepId,
589
- stepName: this.stepName,
590
- stepType: this.stepType,
591
- sleepFor: this.sleep,
592
- concurrent
593
- });
598
+ function settle(resolve, reject, d, v) {
599
+ Promise.resolve(v).then(function(v2) {
600
+ resolve({ value: v2, done: d });
601
+ }, reject);
594
602
  }
595
- };
596
- var LazySleepUntilStep = class extends BaseLazyStep {
597
- sleepUntil;
598
- stepType = "SleepUntil";
599
- allowUndefinedOut = true;
600
- constructor(stepName, sleepUntil) {
601
- super(stepName);
602
- this.sleepUntil = sleepUntil;
603
+ }
604
+ var ResultAsync = class _ResultAsync {
605
+ constructor(res) {
606
+ this._promise = res;
603
607
  }
604
- getPlanStep(concurrent, targetStep) {
605
- return {
606
- stepId: 0,
607
- stepName: this.stepName,
608
- stepType: this.stepType,
609
- sleepUntil: this.sleepUntil,
610
- concurrent,
611
- targetStep
612
- };
608
+ static fromSafePromise(promise) {
609
+ const newPromise = promise.then((value) => new Ok(value));
610
+ return new _ResultAsync(newPromise);
613
611
  }
614
- async getResultStep(concurrent, stepId) {
615
- return await Promise.resolve({
616
- stepId,
617
- stepName: this.stepName,
618
- stepType: this.stepType,
619
- sleepUntil: this.sleepUntil,
620
- concurrent
621
- });
612
+ static fromPromise(promise, errorFn) {
613
+ const newPromise = promise.then((value) => new Ok(value)).catch((e) => new Err(errorFn(e)));
614
+ return new _ResultAsync(newPromise);
622
615
  }
623
- safeParseOut() {
624
- return void 0;
616
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
617
+ static fromThrowable(fn, errorFn) {
618
+ return (...args) => {
619
+ return new _ResultAsync((() => __awaiter(this, void 0, void 0, function* () {
620
+ try {
621
+ return new Ok(yield fn(...args));
622
+ } catch (error) {
623
+ return new Err(errorFn ? errorFn(error) : error);
624
+ }
625
+ }))());
626
+ };
625
627
  }
626
- };
627
- var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
628
- url;
629
- method;
630
- body;
631
- headers;
632
- retries;
633
- timeout;
634
- flowControl;
635
- stepType = "Call";
636
- allowUndefinedOut = false;
637
- constructor(stepName, url, method, body, headers, retries, timeout, flowControl) {
638
- super(stepName);
639
- this.url = url;
640
- this.method = method;
641
- this.body = body;
642
- this.headers = headers;
643
- this.retries = retries;
644
- this.timeout = timeout;
645
- this.flowControl = flowControl;
646
- }
647
- getPlanStep(concurrent, targetStep) {
648
- return {
649
- stepId: 0,
650
- stepName: this.stepName,
651
- stepType: this.stepType,
652
- concurrent,
653
- targetStep
654
- };
628
+ static combine(asyncResultList) {
629
+ return combineResultAsyncList(asyncResultList);
655
630
  }
656
- async getResultStep(concurrent, stepId) {
657
- return await Promise.resolve({
658
- stepId,
659
- stepName: this.stepName,
660
- stepType: this.stepType,
661
- concurrent,
662
- callUrl: this.url,
663
- callMethod: this.method,
664
- callBody: this.body,
665
- callHeaders: this.headers
666
- });
631
+ static combineWithAllErrors(asyncResultList) {
632
+ return combineResultAsyncListWithAllErrors(asyncResultList);
667
633
  }
668
- safeParseOut(out) {
669
- const { header, status, body } = JSON.parse(out);
670
- const responseHeaders = new Headers(header);
671
- if (_LazyCallStep.isText(responseHeaders.get("content-type"))) {
672
- const bytes = new Uint8Array(out.length);
673
- for (let i = 0; i < out.length; i++) {
674
- bytes[i] = out.charCodeAt(i);
634
+ map(f) {
635
+ return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
636
+ if (res.isErr()) {
637
+ return new Err(res.error);
675
638
  }
676
- const processedResult = new TextDecoder().decode(bytes);
677
- const newBody = JSON.parse(processedResult).body;
678
- return {
679
- status,
680
- header,
681
- body: BaseLazyStep.tryParsing(newBody)
682
- };
683
- } else {
684
- return { header, status, body };
685
- }
686
- }
687
- static applicationHeaders = /* @__PURE__ */ new Set([
688
- "application/json",
689
- "application/xml",
690
- "application/javascript",
691
- "application/x-www-form-urlencoded",
692
- "application/xhtml+xml",
693
- "application/ld+json",
694
- "application/rss+xml",
695
- "application/atom+xml"
696
- ]);
697
- static isText = (contentTypeHeader) => {
698
- if (!contentTypeHeader) {
699
- return false;
700
- }
701
- if (_LazyCallStep.applicationHeaders.has(contentTypeHeader)) {
702
- return true;
703
- }
704
- if (contentTypeHeader.startsWith("text/")) {
705
- return true;
706
- }
707
- return false;
708
- };
709
- };
710
- var LazyWaitForEventStep = class extends BaseLazyStep {
711
- eventId;
712
- timeout;
713
- stepType = "Wait";
714
- allowUndefinedOut = false;
715
- constructor(stepName, eventId, timeout) {
716
- super(stepName);
717
- this.eventId = eventId;
718
- this.timeout = timeout;
639
+ return new Ok(yield f(res.value));
640
+ })));
719
641
  }
720
- getPlanStep(concurrent, targetStep) {
721
- return {
722
- stepId: 0,
723
- stepName: this.stepName,
724
- stepType: this.stepType,
725
- waitEventId: this.eventId,
726
- timeout: this.timeout,
727
- concurrent,
728
- targetStep
729
- };
642
+ andThrough(f) {
643
+ return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
644
+ if (res.isErr()) {
645
+ return new Err(res.error);
646
+ }
647
+ const newRes = yield f(res.value);
648
+ if (newRes.isErr()) {
649
+ return new Err(newRes.error);
650
+ }
651
+ return new Ok(res.value);
652
+ })));
730
653
  }
731
- async getResultStep(concurrent, stepId) {
732
- return await Promise.resolve({
733
- stepId,
734
- stepName: this.stepName,
735
- stepType: this.stepType,
736
- waitEventId: this.eventId,
737
- timeout: this.timeout,
738
- concurrent
739
- });
654
+ andTee(f) {
655
+ return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
656
+ if (res.isErr()) {
657
+ return new Err(res.error);
658
+ }
659
+ try {
660
+ yield f(res.value);
661
+ } catch (e) {
662
+ }
663
+ return new Ok(res.value);
664
+ })));
740
665
  }
741
- safeParseOut(out) {
742
- const result = JSON.parse(out);
743
- return {
744
- ...result,
745
- eventData: BaseLazyStep.tryParsing(result.eventData)
746
- };
666
+ mapErr(f) {
667
+ return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
668
+ if (res.isOk()) {
669
+ return new Ok(res.value);
670
+ }
671
+ return new Err(yield f(res.error));
672
+ })));
747
673
  }
748
- };
749
- var LazyNotifyStep = class extends LazyFunctionStep {
750
- stepType = "Notify";
751
- constructor(stepName, eventId, eventData, requester) {
752
- super(stepName, async () => {
753
- const notifyResponse = await makeNotifyRequest(requester, eventId, eventData);
754
- return {
755
- eventId,
756
- eventData,
757
- notifyResponse
758
- };
759
- });
674
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
675
+ andThen(f) {
676
+ return new _ResultAsync(this._promise.then((res) => {
677
+ if (res.isErr()) {
678
+ return new Err(res.error);
679
+ }
680
+ const newValue = f(res.value);
681
+ return newValue instanceof _ResultAsync ? newValue._promise : newValue;
682
+ }));
760
683
  }
761
- safeParseOut(out) {
762
- const result = JSON.parse(out);
763
- return {
764
- ...result,
765
- eventData: BaseLazyStep.tryParsing(result.eventData)
766
- };
684
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
685
+ orElse(f) {
686
+ return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
687
+ if (res.isErr()) {
688
+ return f(res.error);
689
+ }
690
+ return new Ok(res.value);
691
+ })));
767
692
  }
768
- };
769
- var LazyInvokeStep = class extends BaseLazyStep {
770
- stepType = "Invoke";
771
- params;
772
- allowUndefinedOut = false;
773
- constructor(stepName, {
774
- workflow,
775
- body,
776
- headers = {},
777
- workflowRunId,
778
- retries,
779
- flowControl
780
- }) {
781
- super(stepName);
782
- this.params = {
783
- workflow,
784
- body,
785
- headers,
786
- workflowRunId: getWorkflowRunId(workflowRunId),
787
- retries,
788
- flowControl
789
- };
693
+ match(ok2, _err) {
694
+ return this._promise.then((res) => res.match(ok2, _err));
790
695
  }
791
- getPlanStep(concurrent, targetStep) {
792
- return {
793
- stepId: 0,
794
- stepName: this.stepName,
795
- stepType: this.stepType,
796
- concurrent,
797
- targetStep
798
- };
696
+ unwrapOr(t) {
697
+ return this._promise.then((res) => res.unwrapOr(t));
799
698
  }
800
699
  /**
801
- * won't be used as it's the server who will add the result step
802
- * in Invoke step.
700
+ * Emulates Rust's `?` operator in `safeTry`'s body. See also `safeTry`.
803
701
  */
804
- getResultStep(concurrent, stepId) {
805
- return Promise.resolve({
806
- stepId,
807
- stepName: this.stepName,
808
- stepType: this.stepType,
809
- concurrent
702
+ safeUnwrap() {
703
+ return __asyncGenerator(this, arguments, function* safeUnwrap_1() {
704
+ return yield __await(yield __await(yield* __asyncDelegator(__asyncValues(yield __await(this._promise.then((res) => res.safeUnwrap()))))));
810
705
  });
811
706
  }
812
- safeParseOut(out) {
813
- const result = JSON.parse(out);
814
- return {
815
- ...result,
816
- body: BaseLazyStep.tryParsing(result.body)
817
- };
818
- }
819
- };
820
-
821
- // node_modules/neverthrow/dist/index.es.js
822
- var defaultErrorConfig = {
823
- withStackTrace: false
824
- };
825
- var createNeverThrowError = (message, result, config = defaultErrorConfig) => {
826
- const data = result.isOk() ? { type: "Ok", value: result.value } : { type: "Err", value: result.error };
827
- const maybeStack = config.withStackTrace ? new Error().stack : void 0;
828
- return {
829
- data,
830
- message,
831
- stack: maybeStack
832
- };
833
- };
834
- function __awaiter(thisArg, _arguments, P, generator) {
835
- function adopt(value) {
836
- return value instanceof P ? value : new P(function(resolve) {
837
- resolve(value);
838
- });
839
- }
840
- return new (P || (P = Promise))(function(resolve, reject) {
841
- function fulfilled(value) {
842
- try {
843
- step(generator.next(value));
844
- } catch (e) {
845
- reject(e);
846
- }
847
- }
848
- function rejected(value) {
849
- try {
850
- step(generator["throw"](value));
851
- } catch (e) {
852
- reject(e);
853
- }
854
- }
855
- function step(result) {
856
- result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
857
- }
858
- step((generator = generator.apply(thisArg, [])).next());
859
- });
860
- }
861
- function __values(o) {
862
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
863
- if (m) return m.call(o);
864
- if (o && typeof o.length === "number") return {
865
- next: function() {
866
- if (o && i >= o.length) o = void 0;
867
- return { value: o && o[i++], done: !o };
868
- }
869
- };
870
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
871
- }
872
- function __await(v) {
873
- return this instanceof __await ? (this.v = v, this) : new __await(v);
874
- }
875
- function __asyncGenerator(thisArg, _arguments, generator) {
876
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
877
- var g = generator.apply(thisArg, _arguments || []), i, q = [];
878
- return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() {
879
- return this;
880
- }, i;
881
- function verb(n) {
882
- if (g[n]) i[n] = function(v) {
883
- return new Promise(function(a, b) {
884
- q.push([n, v, a, b]) > 1 || resume(n, v);
885
- });
886
- };
887
- }
888
- function resume(n, v) {
889
- try {
890
- step(g[n](v));
891
- } catch (e) {
892
- settle(q[0][3], e);
893
- }
894
- }
895
- function step(r) {
896
- r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r);
897
- }
898
- function fulfill(value) {
899
- resume("next", value);
900
- }
901
- function reject(value) {
902
- resume("throw", value);
903
- }
904
- function settle(f, v) {
905
- if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]);
906
- }
907
- }
908
- function __asyncDelegator(o) {
909
- var i, p;
910
- return i = {}, verb("next"), verb("throw", function(e) {
911
- throw e;
912
- }), verb("return"), i[Symbol.iterator] = function() {
913
- return this;
914
- }, i;
915
- function verb(n, f) {
916
- i[n] = o[n] ? function(v) {
917
- return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v;
918
- } : f;
919
- }
920
- }
921
- function __asyncValues(o) {
922
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
923
- var m = o[Symbol.asyncIterator], i;
924
- 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() {
925
- return this;
926
- }, i);
927
- function verb(n) {
928
- i[n] = o[n] && function(v) {
929
- return new Promise(function(resolve, reject) {
930
- v = o[n](v), settle(resolve, reject, v.done, v.value);
931
- });
932
- };
933
- }
934
- function settle(resolve, reject, d, v) {
935
- Promise.resolve(v).then(function(v2) {
936
- resolve({ value: v2, done: d });
937
- }, reject);
938
- }
939
- }
940
- var ResultAsync = class _ResultAsync {
941
- constructor(res) {
942
- this._promise = res;
943
- }
944
- static fromSafePromise(promise) {
945
- const newPromise = promise.then((value) => new Ok(value));
946
- return new _ResultAsync(newPromise);
947
- }
948
- static fromPromise(promise, errorFn) {
949
- const newPromise = promise.then((value) => new Ok(value)).catch((e) => new Err(errorFn(e)));
950
- return new _ResultAsync(newPromise);
951
- }
952
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
953
- static fromThrowable(fn, errorFn) {
954
- return (...args) => {
955
- return new _ResultAsync((() => __awaiter(this, void 0, void 0, function* () {
956
- try {
957
- return new Ok(yield fn(...args));
958
- } catch (error) {
959
- return new Err(errorFn ? errorFn(error) : error);
960
- }
961
- }))());
962
- };
963
- }
964
- static combine(asyncResultList) {
965
- return combineResultAsyncList(asyncResultList);
966
- }
967
- static combineWithAllErrors(asyncResultList) {
968
- return combineResultAsyncListWithAllErrors(asyncResultList);
969
- }
970
- map(f) {
971
- return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
972
- if (res.isErr()) {
973
- return new Err(res.error);
974
- }
975
- return new Ok(yield f(res.value));
976
- })));
977
- }
978
- andThrough(f) {
979
- return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
980
- if (res.isErr()) {
981
- return new Err(res.error);
982
- }
983
- const newRes = yield f(res.value);
984
- if (newRes.isErr()) {
985
- return new Err(newRes.error);
986
- }
987
- return new Ok(res.value);
988
- })));
989
- }
990
- andTee(f) {
991
- return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
992
- if (res.isErr()) {
993
- return new Err(res.error);
994
- }
995
- try {
996
- yield f(res.value);
997
- } catch (e) {
998
- }
999
- return new Ok(res.value);
1000
- })));
1001
- }
1002
- mapErr(f) {
1003
- return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
1004
- if (res.isOk()) {
1005
- return new Ok(res.value);
1006
- }
1007
- return new Err(yield f(res.error));
1008
- })));
1009
- }
1010
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
1011
- andThen(f) {
1012
- return new _ResultAsync(this._promise.then((res) => {
1013
- if (res.isErr()) {
1014
- return new Err(res.error);
1015
- }
1016
- const newValue = f(res.value);
1017
- return newValue instanceof _ResultAsync ? newValue._promise : newValue;
1018
- }));
1019
- }
1020
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
1021
- orElse(f) {
1022
- return new _ResultAsync(this._promise.then((res) => __awaiter(this, void 0, void 0, function* () {
1023
- if (res.isErr()) {
1024
- return f(res.error);
1025
- }
1026
- return new Ok(res.value);
1027
- })));
1028
- }
1029
- match(ok2, _err) {
1030
- return this._promise.then((res) => res.match(ok2, _err));
1031
- }
1032
- unwrapOr(t) {
1033
- return this._promise.then((res) => res.unwrapOr(t));
1034
- }
1035
- /**
1036
- * Emulates Rust's `?` operator in `safeTry`'s body. See also `safeTry`.
1037
- */
1038
- safeUnwrap() {
1039
- return __asyncGenerator(this, arguments, function* safeUnwrap_1() {
1040
- return yield __await(yield __await(yield* __asyncDelegator(__asyncValues(yield __await(this._promise.then((res) => res.safeUnwrap()))))));
1041
- });
1042
- }
1043
- // Makes ResultAsync implement PromiseLike<Result>
1044
- then(successCallback, failureCallback) {
1045
- return this._promise.then(successCallback, failureCallback);
707
+ // Makes ResultAsync implement PromiseLike<Result>
708
+ then(successCallback, failureCallback) {
709
+ return this._promise.then(successCallback, failureCallback);
1046
710
  }
1047
711
  };
1048
712
  var errAsync = (err2) => new ResultAsync(Promise.resolve(new Err(err2)));
@@ -1247,54 +911,72 @@ var StepTypes = [
1247
911
 
1248
912
  // src/workflow-requests.ts
1249
913
  var import_qstash3 = require("@upstash/qstash");
1250
- var triggerFirstInvocation = async ({
1251
- workflowContext,
1252
- useJSONContent,
1253
- telemetry: telemetry2,
1254
- debug,
1255
- invokeCount
1256
- }) => {
1257
- const { headers } = getHeaders({
1258
- initHeaderValue: "true",
1259
- workflowRunId: workflowContext.workflowRunId,
1260
- workflowUrl: workflowContext.url,
1261
- userHeaders: workflowContext.headers,
1262
- failureUrl: workflowContext.failureUrl,
1263
- retries: workflowContext.retries,
1264
- telemetry: telemetry2,
1265
- invokeCount,
1266
- flowControl: workflowContext.flowControl
1267
- });
1268
- if (workflowContext.headers.get("content-type")) {
1269
- headers["content-type"] = workflowContext.headers.get("content-type");
1270
- }
1271
- if (useJSONContent) {
1272
- headers["content-type"] = "application/json";
1273
- }
1274
- try {
1275
- const body = typeof workflowContext.requestPayload === "string" ? workflowContext.requestPayload : JSON.stringify(workflowContext.requestPayload);
1276
- const result = await workflowContext.qstashClient.publish({
1277
- headers,
1278
- method: "POST",
1279
- body,
1280
- url: workflowContext.url
1281
- });
1282
- if (result.deduplicated) {
1283
- await debug?.log("WARN", "SUBMIT_FIRST_INVOCATION", {
1284
- message: `Workflow run ${workflowContext.workflowRunId} already exists. A new one isn't created.`,
914
+ var triggerFirstInvocation = async (params) => {
915
+ const firstInvocationParams = Array.isArray(params) ? params : [params];
916
+ const workflowContextClient = firstInvocationParams[0].workflowContext.qstashClient;
917
+ const invocationBatch = firstInvocationParams.map(
918
+ ({ workflowContext, useJSONContent, telemetry: telemetry2, invokeCount, delay }) => {
919
+ const { headers } = getHeaders({
920
+ initHeaderValue: "true",
921
+ workflowConfig: {
922
+ workflowRunId: workflowContext.workflowRunId,
923
+ workflowUrl: workflowContext.url,
924
+ failureUrl: workflowContext.failureUrl,
925
+ retries: workflowContext.retries,
926
+ telemetry: telemetry2,
927
+ flowControl: workflowContext.flowControl,
928
+ useJSONContent: useJSONContent ?? false
929
+ },
930
+ invokeCount: invokeCount ?? 0,
931
+ userHeaders: workflowContext.headers
932
+ });
933
+ if (workflowContext.headers.get("content-type")) {
934
+ headers["content-type"] = workflowContext.headers.get("content-type");
935
+ }
936
+ if (useJSONContent) {
937
+ headers["content-type"] = "application/json";
938
+ }
939
+ const body = typeof workflowContext.requestPayload === "string" ? workflowContext.requestPayload : JSON.stringify(workflowContext.requestPayload);
940
+ return {
1285
941
  headers,
1286
- requestPayload: workflowContext.requestPayload,
942
+ method: "POST",
943
+ body,
1287
944
  url: workflowContext.url,
1288
- messageId: result.messageId
1289
- });
945
+ delay
946
+ };
947
+ }
948
+ );
949
+ try {
950
+ const results = await workflowContextClient.batch(invocationBatch);
951
+ const invocationStatuses = [];
952
+ for (let i = 0; i < results.length; i++) {
953
+ const result = results[i];
954
+ const invocationParams = firstInvocationParams[i];
955
+ if (result.deduplicated) {
956
+ await invocationParams.debug?.log("WARN", "SUBMIT_FIRST_INVOCATION", {
957
+ message: `Workflow run ${invocationParams.workflowContext.workflowRunId} already exists. A new one isn't created.`,
958
+ headers: invocationBatch[i].headers,
959
+ requestPayload: invocationParams.workflowContext.requestPayload,
960
+ url: invocationParams.workflowContext.url,
961
+ messageId: result.messageId
962
+ });
963
+ invocationStatuses.push("workflow-run-already-exists");
964
+ } else {
965
+ await invocationParams.debug?.log("SUBMIT", "SUBMIT_FIRST_INVOCATION", {
966
+ headers: invocationBatch[i].headers,
967
+ requestPayload: invocationParams.workflowContext.requestPayload,
968
+ url: invocationParams.workflowContext.url,
969
+ messageId: result.messageId
970
+ });
971
+ invocationStatuses.push("success");
972
+ }
973
+ }
974
+ const hasAnyDeduplicated = invocationStatuses.some(
975
+ (status) => status === "workflow-run-already-exists"
976
+ );
977
+ if (hasAnyDeduplicated) {
1290
978
  return ok("workflow-run-already-exists");
1291
979
  } else {
1292
- await debug?.log("SUBMIT", "SUBMIT_FIRST_INVOCATION", {
1293
- headers,
1294
- requestPayload: workflowContext.requestPayload,
1295
- url: workflowContext.url,
1296
- messageId: result.messageId
1297
- });
1298
980
  return ok("success");
1299
981
  }
1300
982
  } catch (error) {
@@ -1433,14 +1115,16 @@ ${atob(callbackMessage.body ?? "")}`
1433
1115
  const userHeaders = recreateUserHeaders(request.headers);
1434
1116
  const { headers: requestHeaders } = getHeaders({
1435
1117
  initHeaderValue: "false",
1436
- workflowRunId,
1437
- workflowUrl,
1118
+ workflowConfig: {
1119
+ workflowRunId,
1120
+ workflowUrl,
1121
+ failureUrl,
1122
+ retries,
1123
+ telemetry: telemetry2,
1124
+ flowControl
1125
+ },
1438
1126
  userHeaders,
1439
- failureUrl,
1440
- retries,
1441
- telemetry: telemetry2,
1442
- invokeCount: Number(invokeCount),
1443
- flowControl
1127
+ invokeCount: Number(invokeCount)
1444
1128
  });
1445
1129
  const callResponse = {
1446
1130
  status: callbackMessage.status,
@@ -1486,329 +1170,899 @@ var getTelemetryHeaders = (telemetry2) => {
1486
1170
  [TELEMETRY_HEADER_RUNTIME]: telemetry2.runtime ?? "unknown"
1487
1171
  };
1488
1172
  };
1489
- var getHeaders = ({
1490
- initHeaderValue,
1491
- workflowRunId,
1492
- workflowUrl,
1493
- userHeaders,
1494
- failureUrl,
1495
- retries,
1496
- step,
1497
- callRetries,
1498
- callTimeout,
1499
- telemetry: telemetry2,
1500
- invokeCount,
1501
- flowControl,
1502
- callFlowControl
1503
- }) => {
1504
- const callHeaders = new Headers(step?.callHeaders);
1505
- const contentType = (callHeaders.get("content-type") ? callHeaders.get("content-type") : userHeaders?.get("Content-Type") ? userHeaders.get("Content-Type") : void 0) ?? DEFAULT_CONTENT_TYPE;
1506
- const baseHeaders = {
1507
- [WORKFLOW_INIT_HEADER]: initHeaderValue,
1508
- [WORKFLOW_ID_HEADER]: workflowRunId,
1509
- [WORKFLOW_URL_HEADER]: workflowUrl,
1510
- [WORKFLOW_FEATURE_HEADER]: "LazyFetch,InitialBody",
1511
- [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION,
1512
- "content-type": contentType,
1513
- ...telemetry2 ? getTelemetryHeaders(telemetry2) : {}
1514
- };
1515
- if (invokeCount !== void 0 && !step?.callUrl) {
1516
- baseHeaders[`Upstash-Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`] = invokeCount.toString();
1517
- }
1518
- if (!step?.callUrl) {
1519
- baseHeaders[`Upstash-Forward-${WORKFLOW_PROTOCOL_VERSION_HEADER}`] = WORKFLOW_PROTOCOL_VERSION;
1520
- }
1521
- if (callTimeout) {
1522
- baseHeaders[`Upstash-Timeout`] = callTimeout.toString();
1523
- }
1524
- if (failureUrl) {
1525
- baseHeaders[`Upstash-Failure-Callback-Forward-${WORKFLOW_FAILURE_HEADER}`] = "true";
1526
- baseHeaders[`Upstash-Failure-Callback-Forward-Upstash-Workflow-Failure-Callback`] = "true";
1527
- baseHeaders["Upstash-Failure-Callback-Workflow-Runid"] = workflowRunId;
1528
- baseHeaders["Upstash-Failure-Callback-Workflow-Init"] = "false";
1529
- baseHeaders["Upstash-Failure-Callback-Workflow-Url"] = workflowUrl;
1530
- baseHeaders["Upstash-Failure-Callback-Workflow-Calltype"] = "failureCall";
1531
- if (retries !== void 0) {
1532
- baseHeaders["Upstash-Failure-Callback-Retries"] = retries.toString();
1533
- }
1534
- if (flowControl) {
1535
- const { flowControlKey, flowControlValue } = prepareFlowControl(flowControl);
1536
- baseHeaders["Upstash-Failure-Callback-Flow-Control-Key"] = flowControlKey;
1537
- baseHeaders["Upstash-Failure-Callback-Flow-Control-Value"] = flowControlValue;
1538
- }
1539
- if (!step?.callUrl) {
1540
- baseHeaders["Upstash-Failure-Callback"] = failureUrl;
1541
- }
1542
- }
1543
- if (step?.callUrl) {
1544
- baseHeaders["Upstash-Retries"] = callRetries?.toString() ?? "0";
1545
- baseHeaders[WORKFLOW_FEATURE_HEADER] = "WF_NoDelete,InitialBody";
1546
- if (retries !== void 0) {
1547
- baseHeaders["Upstash-Callback-Retries"] = retries.toString();
1548
- baseHeaders["Upstash-Failure-Callback-Retries"] = retries.toString();
1549
- }
1550
- if (callFlowControl) {
1551
- const { flowControlKey, flowControlValue } = prepareFlowControl(callFlowControl);
1552
- baseHeaders["Upstash-Flow-Control-Key"] = flowControlKey;
1553
- baseHeaders["Upstash-Flow-Control-Value"] = flowControlValue;
1554
- }
1555
- if (flowControl) {
1556
- const { flowControlKey, flowControlValue } = prepareFlowControl(flowControl);
1557
- baseHeaders["Upstash-Callback-Flow-Control-Key"] = flowControlKey;
1558
- baseHeaders["Upstash-Callback-Flow-Control-Value"] = flowControlValue;
1173
+ var verifyRequest = async (body, signature, verifier) => {
1174
+ if (!verifier) {
1175
+ return;
1176
+ }
1177
+ try {
1178
+ if (!signature) {
1179
+ throw new Error("`Upstash-Signature` header is not passed.");
1180
+ }
1181
+ const isValid = await verifier.verify({
1182
+ body,
1183
+ signature
1184
+ });
1185
+ if (!isValid) {
1186
+ throw new Error("Signature in `Upstash-Signature` header is not valid");
1187
+ }
1188
+ } catch (error) {
1189
+ throw new WorkflowError(
1190
+ `Failed to verify that the Workflow request comes from QStash: ${error}
1191
+
1192
+ If signature is missing, trigger the workflow endpoint by publishing your request to QStash instead of calling it directly.
1193
+
1194
+ If you want to disable QStash Verification, you should clear env variables QSTASH_CURRENT_SIGNING_KEY and QSTASH_NEXT_SIGNING_KEY`
1195
+ );
1196
+ }
1197
+ };
1198
+
1199
+ // src/context/steps.ts
1200
+ var BaseLazyStep = class _BaseLazyStep {
1201
+ stepName;
1202
+ constructor(stepName) {
1203
+ if (!stepName) {
1204
+ throw new WorkflowError(
1205
+ "A workflow step name cannot be undefined or an empty string. Please provide a name for your workflow step."
1206
+ );
1207
+ }
1208
+ if (typeof stepName !== "string") {
1209
+ console.warn(
1210
+ "Workflow Warning: A workflow step name must be a string. In a future release, this will throw an error."
1211
+ );
1212
+ }
1213
+ this.stepName = stepName;
1214
+ }
1215
+ /**
1216
+ * parse the out field of a step result.
1217
+ *
1218
+ * will be called when returning the steps to the context from auto executor
1219
+ *
1220
+ * @param out field of the step
1221
+ * @returns parsed out field
1222
+ */
1223
+ parseOut(out) {
1224
+ if (out === void 0) {
1225
+ if (this.allowUndefinedOut) {
1226
+ return void 0;
1227
+ } else {
1228
+ throw new WorkflowError(
1229
+ `Error while parsing output of ${this.stepType} step. Expected a string, but got: undefined`
1230
+ );
1231
+ }
1232
+ }
1233
+ if (typeof out === "object") {
1234
+ if (this.stepType !== "Wait") {
1235
+ console.warn(
1236
+ `Error while parsing ${this.stepType} step output. Expected a string, but got object. Please reach out to Upstash Support.`
1237
+ );
1238
+ return out;
1239
+ }
1240
+ return {
1241
+ ...out,
1242
+ eventData: _BaseLazyStep.tryParsing(out.eventData)
1243
+ };
1244
+ }
1245
+ if (typeof out !== "string") {
1246
+ throw new WorkflowError(
1247
+ `Error while parsing output of ${this.stepType} step. Expected a string or undefined, but got: ${typeof out}`
1248
+ );
1249
+ }
1250
+ return this.safeParseOut(out);
1251
+ }
1252
+ safeParseOut(out) {
1253
+ return _BaseLazyStep.tryParsing(out);
1254
+ }
1255
+ static tryParsing(stepOut) {
1256
+ try {
1257
+ return JSON.parse(stepOut);
1258
+ } catch {
1259
+ return stepOut;
1260
+ }
1261
+ }
1262
+ getBody({ step }) {
1263
+ step.out = JSON.stringify(step.out);
1264
+ return JSON.stringify(step);
1265
+ }
1266
+ getHeaders({ context, telemetry: telemetry2, invokeCount, step }) {
1267
+ return getHeaders({
1268
+ initHeaderValue: "false",
1269
+ workflowConfig: {
1270
+ workflowRunId: context.workflowRunId,
1271
+ workflowUrl: context.url,
1272
+ failureUrl: context.failureUrl,
1273
+ retries: context.retries,
1274
+ useJSONContent: false,
1275
+ telemetry: telemetry2,
1276
+ flowControl: context.flowControl
1277
+ },
1278
+ userHeaders: context.headers,
1279
+ invokeCount,
1280
+ stepInfo: {
1281
+ step,
1282
+ lazyStep: this
1283
+ }
1284
+ });
1285
+ }
1286
+ async submitStep({ context, body, headers }) {
1287
+ return await context.qstashClient.batch([
1288
+ {
1289
+ body,
1290
+ headers,
1291
+ method: "POST",
1292
+ url: context.url
1293
+ }
1294
+ ]);
1295
+ }
1296
+ };
1297
+ var LazyFunctionStep = class extends BaseLazyStep {
1298
+ stepFunction;
1299
+ stepType = "Run";
1300
+ allowUndefinedOut = true;
1301
+ constructor(stepName, stepFunction) {
1302
+ super(stepName);
1303
+ this.stepFunction = stepFunction;
1304
+ }
1305
+ getPlanStep(concurrent, targetStep) {
1306
+ return {
1307
+ stepId: 0,
1308
+ stepName: this.stepName,
1309
+ stepType: this.stepType,
1310
+ concurrent,
1311
+ targetStep
1312
+ };
1313
+ }
1314
+ async getResultStep(concurrent, stepId) {
1315
+ let result = this.stepFunction();
1316
+ if (result instanceof Promise) {
1317
+ result = await result;
1318
+ }
1319
+ return {
1320
+ stepId,
1321
+ stepName: this.stepName,
1322
+ stepType: this.stepType,
1323
+ out: result,
1324
+ concurrent
1325
+ };
1326
+ }
1327
+ };
1328
+ var LazySleepStep = class extends BaseLazyStep {
1329
+ sleep;
1330
+ stepType = "SleepFor";
1331
+ allowUndefinedOut = true;
1332
+ constructor(stepName, sleep) {
1333
+ super(stepName);
1334
+ this.sleep = sleep;
1335
+ }
1336
+ getPlanStep(concurrent, targetStep) {
1337
+ return {
1338
+ stepId: 0,
1339
+ stepName: this.stepName,
1340
+ stepType: this.stepType,
1341
+ sleepFor: this.sleep,
1342
+ concurrent,
1343
+ targetStep
1344
+ };
1345
+ }
1346
+ async getResultStep(concurrent, stepId) {
1347
+ return await Promise.resolve({
1348
+ stepId,
1349
+ stepName: this.stepName,
1350
+ stepType: this.stepType,
1351
+ sleepFor: this.sleep,
1352
+ concurrent
1353
+ });
1354
+ }
1355
+ async submitStep({ context, body, headers, isParallel }) {
1356
+ return await context.qstashClient.batch([
1357
+ {
1358
+ body,
1359
+ headers,
1360
+ method: "POST",
1361
+ url: context.url,
1362
+ delay: isParallel ? void 0 : this.sleep
1363
+ }
1364
+ ]);
1365
+ }
1366
+ };
1367
+ var LazySleepUntilStep = class extends BaseLazyStep {
1368
+ sleepUntil;
1369
+ stepType = "SleepUntil";
1370
+ allowUndefinedOut = true;
1371
+ constructor(stepName, sleepUntil) {
1372
+ super(stepName);
1373
+ this.sleepUntil = sleepUntil;
1374
+ }
1375
+ getPlanStep(concurrent, targetStep) {
1376
+ return {
1377
+ stepId: 0,
1378
+ stepName: this.stepName,
1379
+ stepType: this.stepType,
1380
+ sleepUntil: this.sleepUntil,
1381
+ concurrent,
1382
+ targetStep
1383
+ };
1384
+ }
1385
+ async getResultStep(concurrent, stepId) {
1386
+ return await Promise.resolve({
1387
+ stepId,
1388
+ stepName: this.stepName,
1389
+ stepType: this.stepType,
1390
+ sleepUntil: this.sleepUntil,
1391
+ concurrent
1392
+ });
1393
+ }
1394
+ safeParseOut() {
1395
+ return void 0;
1396
+ }
1397
+ async submitStep({ context, body, headers, isParallel }) {
1398
+ return await context.qstashClient.batch([
1399
+ {
1400
+ body,
1401
+ headers,
1402
+ method: "POST",
1403
+ url: context.url,
1404
+ notBefore: isParallel ? void 0 : this.sleepUntil
1405
+ }
1406
+ ]);
1407
+ }
1408
+ };
1409
+ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
1410
+ url;
1411
+ method;
1412
+ body;
1413
+ headers;
1414
+ retries;
1415
+ timeout;
1416
+ flowControl;
1417
+ stepType = "Call";
1418
+ allowUndefinedOut = false;
1419
+ constructor(stepName, url, method, body, headers, retries, timeout, flowControl) {
1420
+ super(stepName);
1421
+ this.url = url;
1422
+ this.method = method;
1423
+ this.body = body;
1424
+ this.headers = headers;
1425
+ this.retries = retries;
1426
+ this.timeout = timeout;
1427
+ this.flowControl = flowControl;
1428
+ }
1429
+ getPlanStep(concurrent, targetStep) {
1430
+ return {
1431
+ stepId: 0,
1432
+ stepName: this.stepName,
1433
+ stepType: this.stepType,
1434
+ concurrent,
1435
+ targetStep
1436
+ };
1437
+ }
1438
+ async getResultStep(concurrent, stepId) {
1439
+ return await Promise.resolve({
1440
+ stepId,
1441
+ stepName: this.stepName,
1442
+ stepType: this.stepType,
1443
+ concurrent,
1444
+ callUrl: this.url,
1445
+ callMethod: this.method,
1446
+ callBody: this.body,
1447
+ callHeaders: this.headers
1448
+ });
1449
+ }
1450
+ safeParseOut(out) {
1451
+ const { header, status, body } = JSON.parse(out);
1452
+ const responseHeaders = new Headers(header);
1453
+ if (_LazyCallStep.isText(responseHeaders.get("content-type"))) {
1454
+ const bytes = new Uint8Array(out.length);
1455
+ for (let i = 0; i < out.length; i++) {
1456
+ bytes[i] = out.charCodeAt(i);
1457
+ }
1458
+ const processedResult = new TextDecoder().decode(bytes);
1459
+ const newBody = JSON.parse(processedResult).body;
1460
+ return {
1461
+ status,
1462
+ header,
1463
+ body: BaseLazyStep.tryParsing(newBody)
1464
+ };
1465
+ } else {
1466
+ return { header, status, body };
1559
1467
  }
1560
- } else {
1561
- if (flowControl) {
1562
- const { flowControlKey, flowControlValue } = prepareFlowControl(flowControl);
1563
- baseHeaders["Upstash-Flow-Control-Key"] = flowControlKey;
1564
- baseHeaders["Upstash-Flow-Control-Value"] = flowControlValue;
1468
+ }
1469
+ static applicationContentTypes = [
1470
+ "application/json",
1471
+ "application/xml",
1472
+ "application/javascript",
1473
+ "application/x-www-form-urlencoded",
1474
+ "application/xhtml+xml",
1475
+ "application/ld+json",
1476
+ "application/rss+xml",
1477
+ "application/atom+xml"
1478
+ ];
1479
+ static isText = (contentTypeHeader) => {
1480
+ if (!contentTypeHeader) {
1481
+ return false;
1565
1482
  }
1566
- if (retries !== void 0) {
1567
- baseHeaders["Upstash-Retries"] = retries.toString();
1568
- baseHeaders["Upstash-Failure-Callback-Retries"] = retries.toString();
1483
+ if (_LazyCallStep.applicationContentTypes.some((type) => contentTypeHeader.includes(type))) {
1484
+ return true;
1569
1485
  }
1570
- }
1571
- if (userHeaders) {
1572
- for (const header of userHeaders.keys()) {
1573
- if (step?.callHeaders) {
1574
- baseHeaders[`Upstash-Callback-Forward-${header}`] = userHeaders.get(header);
1575
- } else {
1576
- baseHeaders[`Upstash-Forward-${header}`] = userHeaders.get(header);
1577
- }
1578
- baseHeaders[`Upstash-Failure-Callback-Forward-${header}`] = userHeaders.get(header);
1486
+ if (contentTypeHeader.startsWith("text/")) {
1487
+ return true;
1579
1488
  }
1489
+ return false;
1490
+ };
1491
+ getBody({ step }) {
1492
+ if (!step.callUrl) {
1493
+ throw new WorkflowError("Incompatible step received in LazyCallStep.getBody");
1494
+ }
1495
+ return JSON.stringify(step.callBody);
1580
1496
  }
1581
- if (step?.callHeaders) {
1497
+ getHeaders({ context, telemetry: telemetry2, invokeCount, step }) {
1498
+ const { headers, contentType } = super.getHeaders({ context, telemetry: telemetry2, invokeCount, step });
1499
+ headers["Upstash-Retries"] = this.retries.toString();
1500
+ headers[WORKFLOW_FEATURE_HEADER] = "WF_NoDelete,InitialBody";
1501
+ if (this.flowControl) {
1502
+ const { flowControlKey, flowControlValue } = prepareFlowControl(this.flowControl);
1503
+ headers["Upstash-Flow-Control-Key"] = flowControlKey;
1504
+ headers["Upstash-Flow-Control-Value"] = flowControlValue;
1505
+ }
1506
+ if (this.timeout) {
1507
+ headers["Upstash-Timeout"] = this.timeout.toString();
1508
+ }
1582
1509
  const forwardedHeaders = Object.fromEntries(
1583
- Object.entries(step.callHeaders).map(([header, value]) => [
1584
- `Upstash-Forward-${header}`,
1585
- value
1586
- ])
1510
+ Object.entries(this.headers).map(([header, value]) => [`Upstash-Forward-${header}`, value])
1587
1511
  );
1588
1512
  return {
1589
1513
  headers: {
1590
- ...baseHeaders,
1514
+ ...headers,
1591
1515
  ...forwardedHeaders,
1592
- "Upstash-Callback": workflowUrl,
1593
- "Upstash-Callback-Workflow-RunId": workflowRunId,
1516
+ "Upstash-Callback": context.url,
1517
+ "Upstash-Callback-Workflow-RunId": context.workflowRunId,
1594
1518
  "Upstash-Callback-Workflow-CallType": "fromCallback",
1595
1519
  "Upstash-Callback-Workflow-Init": "false",
1596
- "Upstash-Callback-Workflow-Url": workflowUrl,
1520
+ "Upstash-Callback-Workflow-Url": context.url,
1597
1521
  "Upstash-Callback-Feature-Set": "LazyFetch,InitialBody",
1598
1522
  "Upstash-Callback-Forward-Upstash-Workflow-Callback": "true",
1599
1523
  "Upstash-Callback-Forward-Upstash-Workflow-StepId": step.stepId.toString(),
1600
- "Upstash-Callback-Forward-Upstash-Workflow-StepName": step.stepName,
1601
- "Upstash-Callback-Forward-Upstash-Workflow-StepType": step.stepType,
1524
+ "Upstash-Callback-Forward-Upstash-Workflow-StepName": this.stepName,
1525
+ "Upstash-Callback-Forward-Upstash-Workflow-StepType": this.stepType,
1602
1526
  "Upstash-Callback-Forward-Upstash-Workflow-Concurrent": step.concurrent.toString(),
1603
1527
  "Upstash-Callback-Forward-Upstash-Workflow-ContentType": contentType,
1604
- [`Upstash-Callback-Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`]: (invokeCount ?? 0).toString(),
1605
1528
  "Upstash-Workflow-CallType": "toCallback"
1529
+ },
1530
+ contentType
1531
+ };
1532
+ }
1533
+ async submitStep({ context, headers }) {
1534
+ return await context.qstashClient.batch([
1535
+ {
1536
+ headers,
1537
+ body: JSON.stringify(this.body),
1538
+ method: this.method,
1539
+ url: this.url
1606
1540
  }
1541
+ ]);
1542
+ }
1543
+ };
1544
+ var LazyWaitForEventStep = class extends BaseLazyStep {
1545
+ eventId;
1546
+ timeout;
1547
+ stepType = "Wait";
1548
+ allowUndefinedOut = false;
1549
+ constructor(stepName, eventId, timeout) {
1550
+ super(stepName);
1551
+ this.eventId = eventId;
1552
+ this.timeout = timeout;
1553
+ }
1554
+ getPlanStep(concurrent, targetStep) {
1555
+ return {
1556
+ stepId: 0,
1557
+ stepName: this.stepName,
1558
+ stepType: this.stepType,
1559
+ waitEventId: this.eventId,
1560
+ timeout: this.timeout,
1561
+ concurrent,
1562
+ targetStep
1607
1563
  };
1608
1564
  }
1609
- if (step?.waitEventId) {
1565
+ async getResultStep(concurrent, stepId) {
1566
+ return await Promise.resolve({
1567
+ stepId,
1568
+ stepName: this.stepName,
1569
+ stepType: this.stepType,
1570
+ waitEventId: this.eventId,
1571
+ timeout: this.timeout,
1572
+ concurrent
1573
+ });
1574
+ }
1575
+ safeParseOut(out) {
1576
+ const result = JSON.parse(out);
1610
1577
  return {
1611
- headers: {
1612
- ...baseHeaders,
1613
- "Upstash-Workflow-CallType": "step"
1614
- },
1615
- timeoutHeaders: {
1616
- // to include user headers:
1617
- ...Object.fromEntries(
1618
- Object.entries(baseHeaders).map(([header, value]) => [header, [value]])
1619
- ),
1620
- // to include telemetry headers:
1621
- ...telemetry2 ? Object.fromEntries(
1622
- Object.entries(getTelemetryHeaders(telemetry2)).map(([header, value]) => [
1623
- header,
1624
- [value]
1625
- ])
1626
- ) : {},
1627
- // note: using WORKFLOW_ID_HEADER doesn't work, because Runid -> RunId:
1628
- "Upstash-Workflow-Runid": [workflowRunId],
1629
- [WORKFLOW_INIT_HEADER]: ["false"],
1630
- [WORKFLOW_URL_HEADER]: [workflowUrl],
1631
- "Upstash-Workflow-CallType": ["step"]
1578
+ ...result,
1579
+ eventData: BaseLazyStep.tryParsing(result.eventData)
1580
+ };
1581
+ }
1582
+ getHeaders({ context, telemetry: telemetry2, invokeCount, step }) {
1583
+ const headers = super.getHeaders({ context, telemetry: telemetry2, invokeCount, step });
1584
+ headers.headers["Upstash-Workflow-CallType"] = "step";
1585
+ return headers;
1586
+ }
1587
+ getBody({ context, step, headers, telemetry: telemetry2 }) {
1588
+ if (!step.waitEventId) {
1589
+ throw new WorkflowError("Incompatible step received in LazyWaitForEventStep.getBody");
1590
+ }
1591
+ const timeoutHeaders = {
1592
+ // to include user headers:
1593
+ ...Object.fromEntries(Object.entries(headers).map(([header, value]) => [header, [value]])),
1594
+ // to include telemetry headers:
1595
+ ...telemetry2 ? Object.fromEntries(
1596
+ Object.entries(getTelemetryHeaders(telemetry2)).map(([header, value]) => [
1597
+ header,
1598
+ [value]
1599
+ ])
1600
+ ) : {},
1601
+ // note: using WORKFLOW_ID_HEADER doesn't work, because Runid -> RunId:
1602
+ "Upstash-Workflow-Runid": [context.workflowRunId],
1603
+ [WORKFLOW_INIT_HEADER]: ["false"],
1604
+ [WORKFLOW_URL_HEADER]: [context.url],
1605
+ "Upstash-Workflow-CallType": ["step"]
1606
+ };
1607
+ const waitBody = {
1608
+ url: context.url,
1609
+ timeout: step.timeout,
1610
+ timeoutBody: void 0,
1611
+ timeoutUrl: context.url,
1612
+ timeoutHeaders,
1613
+ step: {
1614
+ stepId: step.stepId,
1615
+ stepType: "Wait",
1616
+ stepName: step.stepName,
1617
+ concurrent: step.concurrent,
1618
+ targetStep: step.targetStep
1632
1619
  }
1633
1620
  };
1621
+ return JSON.stringify(waitBody);
1622
+ }
1623
+ async submitStep({ context, body, headers }) {
1624
+ const result = await context.qstashClient.http.request({
1625
+ path: ["v2", "wait", this.eventId],
1626
+ body,
1627
+ headers,
1628
+ method: "POST",
1629
+ parseResponseAsJson: false
1630
+ });
1631
+ return [result];
1634
1632
  }
1635
- return { headers: baseHeaders };
1636
1633
  };
1637
- var verifyRequest = async (body, signature, verifier) => {
1638
- if (!verifier) {
1639
- return;
1634
+ var LazyNotifyStep = class extends LazyFunctionStep {
1635
+ stepType = "Notify";
1636
+ constructor(stepName, eventId, eventData, requester) {
1637
+ super(stepName, async () => {
1638
+ const notifyResponse = await makeNotifyRequest(requester, eventId, eventData);
1639
+ return {
1640
+ eventId,
1641
+ eventData,
1642
+ notifyResponse
1643
+ };
1644
+ });
1640
1645
  }
1641
- try {
1642
- if (!signature) {
1643
- throw new Error("`Upstash-Signature` header is not passed.");
1646
+ safeParseOut(out) {
1647
+ const result = JSON.parse(out);
1648
+ return {
1649
+ ...result,
1650
+ eventData: BaseLazyStep.tryParsing(result.eventData)
1651
+ };
1652
+ }
1653
+ };
1654
+ var LazyInvokeStep = class extends BaseLazyStep {
1655
+ stepType = "Invoke";
1656
+ params;
1657
+ allowUndefinedOut = false;
1658
+ /**
1659
+ * workflow id of the invoked workflow
1660
+ */
1661
+ workflowId;
1662
+ constructor(stepName, {
1663
+ workflow,
1664
+ body,
1665
+ headers = {},
1666
+ workflowRunId,
1667
+ retries,
1668
+ flowControl
1669
+ }) {
1670
+ super(stepName);
1671
+ this.params = {
1672
+ workflow,
1673
+ body,
1674
+ headers,
1675
+ workflowRunId: getWorkflowRunId(workflowRunId),
1676
+ retries,
1677
+ flowControl
1678
+ };
1679
+ const { workflowId } = workflow;
1680
+ if (!workflowId) {
1681
+ throw new WorkflowError("You can only invoke workflow which has a workflowId");
1644
1682
  }
1645
- const isValid = await verifier.verify({
1683
+ this.workflowId = workflowId;
1684
+ }
1685
+ getPlanStep(concurrent, targetStep) {
1686
+ return {
1687
+ stepId: 0,
1688
+ stepName: this.stepName,
1689
+ stepType: this.stepType,
1690
+ concurrent,
1691
+ targetStep
1692
+ };
1693
+ }
1694
+ /**
1695
+ * won't be used as it's the server who will add the result step
1696
+ * in Invoke step.
1697
+ */
1698
+ getResultStep(concurrent, stepId) {
1699
+ return Promise.resolve({
1700
+ stepId,
1701
+ stepName: this.stepName,
1702
+ stepType: this.stepType,
1703
+ concurrent
1704
+ });
1705
+ }
1706
+ safeParseOut(out) {
1707
+ const result = JSON.parse(out);
1708
+ return {
1709
+ ...result,
1710
+ body: BaseLazyStep.tryParsing(result.body)
1711
+ };
1712
+ }
1713
+ getBody({ context, step, telemetry: telemetry2, invokeCount }) {
1714
+ const { headers: invokerHeaders } = getHeaders({
1715
+ initHeaderValue: "false",
1716
+ workflowConfig: {
1717
+ workflowRunId: context.workflowRunId,
1718
+ workflowUrl: context.url,
1719
+ failureUrl: context.failureUrl,
1720
+ retries: context.retries,
1721
+ telemetry: telemetry2,
1722
+ flowControl: context.flowControl,
1723
+ useJSONContent: false
1724
+ },
1725
+ userHeaders: context.headers,
1726
+ invokeCount
1727
+ });
1728
+ invokerHeaders["Upstash-Workflow-Runid"] = context.workflowRunId;
1729
+ const request = {
1730
+ body: JSON.stringify(this.params.body),
1731
+ headers: Object.fromEntries(
1732
+ Object.entries(invokerHeaders).map((pairs) => [pairs[0], [pairs[1]]])
1733
+ ),
1734
+ workflowRunId: context.workflowRunId,
1735
+ workflowUrl: context.url,
1736
+ step
1737
+ };
1738
+ return JSON.stringify(request);
1739
+ }
1740
+ getHeaders({ context, telemetry: telemetry2, invokeCount }) {
1741
+ const {
1742
+ workflow,
1743
+ headers = {},
1744
+ workflowRunId = getWorkflowRunId(),
1745
+ retries,
1746
+ flowControl
1747
+ } = this.params;
1748
+ const newUrl = context.url.replace(/[^/]+$/, this.workflowId);
1749
+ const {
1750
+ retries: workflowRetries,
1751
+ failureFunction,
1752
+ failureUrl,
1753
+ useJSONContent,
1754
+ flowControl: workflowFlowControl
1755
+ } = workflow.options;
1756
+ const { headers: triggerHeaders, contentType } = getHeaders({
1757
+ initHeaderValue: "true",
1758
+ workflowConfig: {
1759
+ workflowRunId,
1760
+ workflowUrl: newUrl,
1761
+ retries: retries ?? workflowRetries,
1762
+ telemetry: telemetry2,
1763
+ failureUrl: failureFunction ? newUrl : failureUrl,
1764
+ flowControl: flowControl ?? workflowFlowControl,
1765
+ useJSONContent: useJSONContent ?? false
1766
+ },
1767
+ invokeCount: invokeCount + 1,
1768
+ userHeaders: new Headers(headers)
1769
+ });
1770
+ triggerHeaders["Upstash-Workflow-Invoke"] = "true";
1771
+ return { headers: triggerHeaders, contentType };
1772
+ }
1773
+ async submitStep({ context, body, headers }) {
1774
+ const newUrl = context.url.replace(/[^/]+$/, this.workflowId);
1775
+ const result = await context.qstashClient.publish({
1776
+ headers,
1777
+ method: "POST",
1646
1778
  body,
1647
- signature
1779
+ url: newUrl
1648
1780
  });
1649
- if (!isValid) {
1650
- throw new Error("Signature in `Upstash-Signature` header is not valid");
1651
- }
1652
- } catch (error) {
1653
- throw new WorkflowError(
1654
- `Failed to verify that the Workflow request comes from QStash: ${error}
1781
+ return [result];
1782
+ }
1783
+ };
1655
1784
 
1656
- If signature is missing, trigger the workflow endpoint by publishing your request to QStash instead of calling it directly.
1785
+ // src/agents/constants.ts
1786
+ var AGENT_NAME_HEADER = "upstash-agent-name";
1787
+ var MANAGER_AGENT_PROMPT = `You are an agent orchestrating other AI Agents.
1657
1788
 
1658
- If you want to disable QStash Verification, you should clear env variables QSTASH_CURRENT_SIGNING_KEY and QSTASH_NEXT_SIGNING_KEY`
1789
+ These other agents have tools available to them.
1790
+
1791
+ Given a prompt, utilize these agents to address requests.
1792
+
1793
+ 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.
1794
+
1795
+ Avoid calling the same agent twice in one turn. Instead, prefer to call it once but provide everything
1796
+ you need from that agent.
1797
+ `;
1798
+
1799
+ // src/qstash/headers.ts
1800
+ var WorkflowHeaders = class {
1801
+ userHeaders;
1802
+ workflowConfig;
1803
+ invokeCount;
1804
+ initHeaderValue;
1805
+ stepInfo;
1806
+ headers;
1807
+ constructor({
1808
+ userHeaders,
1809
+ workflowConfig,
1810
+ invokeCount,
1811
+ initHeaderValue,
1812
+ stepInfo
1813
+ }) {
1814
+ this.userHeaders = userHeaders;
1815
+ this.workflowConfig = workflowConfig;
1816
+ this.invokeCount = invokeCount;
1817
+ this.initHeaderValue = initHeaderValue;
1818
+ this.stepInfo = stepInfo;
1819
+ this.headers = {
1820
+ rawHeaders: {},
1821
+ workflowHeaders: {},
1822
+ failureHeaders: {}
1823
+ };
1824
+ }
1825
+ getHeaders() {
1826
+ this.addBaseHeaders();
1827
+ this.addRetries();
1828
+ this.addFlowControl();
1829
+ this.addUserHeaders();
1830
+ this.addInvokeCount();
1831
+ this.addFailureUrl();
1832
+ const contentType = this.addContentType();
1833
+ return this.prefixHeaders(contentType);
1834
+ }
1835
+ addBaseHeaders() {
1836
+ this.headers.rawHeaders = {
1837
+ ...this.headers.rawHeaders,
1838
+ [WORKFLOW_INIT_HEADER]: this.initHeaderValue,
1839
+ [WORKFLOW_ID_HEADER]: this.workflowConfig.workflowRunId,
1840
+ [WORKFLOW_URL_HEADER]: this.workflowConfig.workflowUrl,
1841
+ [WORKFLOW_FEATURE_HEADER]: "LazyFetch,InitialBody",
1842
+ [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION,
1843
+ ...this.workflowConfig.telemetry ? getTelemetryHeaders(this.workflowConfig.telemetry) : {},
1844
+ ...this.workflowConfig.telemetry && this.stepInfo?.lazyStep instanceof LazyCallStep && this.stepInfo.lazyStep.headers[AGENT_NAME_HEADER] ? { [TELEMETRY_HEADER_AGENT]: "true" } : {}
1845
+ };
1846
+ if (this.stepInfo?.lazyStep.stepType !== "Call") {
1847
+ this.headers.rawHeaders[`Upstash-Forward-${WORKFLOW_PROTOCOL_VERSION_HEADER}`] = WORKFLOW_PROTOCOL_VERSION;
1848
+ }
1849
+ }
1850
+ addInvokeCount() {
1851
+ if (this.invokeCount === void 0 || this.invokeCount === 0) {
1852
+ return;
1853
+ }
1854
+ const invokeCount = this.invokeCount.toString();
1855
+ this.headers.workflowHeaders[`Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`] = invokeCount;
1856
+ if (this.workflowConfig.failureUrl) {
1857
+ this.headers.failureHeaders[`Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`] = invokeCount;
1858
+ }
1859
+ if (this.stepInfo?.lazyStep instanceof LazyCallStep) {
1860
+ this.headers.rawHeaders[`Upstash-Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`] = invokeCount;
1861
+ }
1862
+ }
1863
+ addRetries() {
1864
+ if (this.workflowConfig.retries === void 0 || this.workflowConfig.retries === DEFAULT_RETRIES) {
1865
+ return;
1866
+ }
1867
+ const retries = this.workflowConfig.retries.toString();
1868
+ this.headers.workflowHeaders["Retries"] = retries;
1869
+ if (this.workflowConfig.failureUrl) {
1870
+ this.headers.failureHeaders["Retries"] = retries;
1871
+ }
1872
+ }
1873
+ addFlowControl() {
1874
+ if (!this.workflowConfig.flowControl) {
1875
+ return;
1876
+ }
1877
+ const { flowControlKey, flowControlValue } = prepareFlowControl(
1878
+ this.workflowConfig.flowControl
1879
+ );
1880
+ this.headers.workflowHeaders["Flow-Control-Key"] = flowControlKey;
1881
+ this.headers.workflowHeaders["Flow-Control-Value"] = flowControlValue;
1882
+ if (this.workflowConfig.failureUrl) {
1883
+ this.headers.failureHeaders["Flow-Control-Key"] = flowControlKey;
1884
+ this.headers.failureHeaders["Flow-Control-Value"] = flowControlValue;
1885
+ }
1886
+ }
1887
+ addUserHeaders() {
1888
+ for (const [key, value] of this.userHeaders.entries()) {
1889
+ const forwardKey = `Forward-${key}`;
1890
+ this.headers.workflowHeaders[forwardKey] = value;
1891
+ if (this.workflowConfig.failureUrl) {
1892
+ this.headers.failureHeaders[forwardKey] = value;
1893
+ }
1894
+ }
1895
+ }
1896
+ addFailureUrl() {
1897
+ if (!this.workflowConfig.failureUrl) {
1898
+ return;
1899
+ }
1900
+ this.headers.workflowHeaders["Failure-Callback"] = this.workflowConfig.failureUrl;
1901
+ this.headers.failureHeaders[`Forward-${WORKFLOW_FAILURE_HEADER}`] = "true";
1902
+ this.headers.failureHeaders[`Forward-Upstash-Workflow-Failure-Callback`] = "true";
1903
+ this.headers.failureHeaders["Workflow-Runid"] = this.workflowConfig.workflowRunId;
1904
+ this.headers.failureHeaders["Workflow-Init"] = "false";
1905
+ this.headers.failureHeaders["Workflow-Url"] = this.workflowConfig.workflowUrl;
1906
+ this.headers.failureHeaders["Workflow-Calltype"] = "failureCall";
1907
+ this.headers.failureHeaders["Feature-Set"] = "LazyFetch,InitialBody";
1908
+ if (this.workflowConfig.retries !== void 0 && this.workflowConfig.retries !== DEFAULT_RETRIES) {
1909
+ this.headers.failureHeaders["Retries"] = this.workflowConfig.retries.toString();
1910
+ }
1911
+ }
1912
+ addContentType() {
1913
+ if (this.workflowConfig.useJSONContent) {
1914
+ this.headers.rawHeaders["content-type"] = "application/json";
1915
+ return "application/json";
1916
+ }
1917
+ const callHeaders = new Headers(
1918
+ this.stepInfo?.lazyStep instanceof LazyCallStep ? this.stepInfo.lazyStep.headers : {}
1659
1919
  );
1920
+ 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;
1921
+ this.headers.rawHeaders["content-type"] = contentType;
1922
+ return contentType;
1923
+ }
1924
+ prefixHeaders(contentType) {
1925
+ const { rawHeaders, workflowHeaders, failureHeaders } = this.headers;
1926
+ const isCall = this.stepInfo?.lazyStep.stepType === "Call";
1927
+ return {
1928
+ headers: {
1929
+ ...rawHeaders,
1930
+ ...addPrefixToHeaders(workflowHeaders, isCall ? "Upstash-Callback-" : "Upstash-"),
1931
+ ...addPrefixToHeaders(failureHeaders, "Upstash-Failure-Callback-"),
1932
+ ...isCall ? addPrefixToHeaders(failureHeaders, "Upstash-Callback-Failure-Callback-") : {}
1933
+ },
1934
+ contentType
1935
+ };
1660
1936
  }
1661
1937
  };
1938
+ function addPrefixToHeaders(headers, prefix) {
1939
+ const prefixedHeaders = {};
1940
+ for (const [key, value] of Object.entries(headers)) {
1941
+ prefixedHeaders[`${prefix}${key}`] = value;
1942
+ }
1943
+ return prefixedHeaders;
1944
+ }
1662
1945
  var prepareFlowControl = (flowControl) => {
1663
1946
  const parallelism = flowControl.parallelism?.toString();
1664
- const rate = flowControl.ratePerSecond?.toString();
1947
+ const rate = (flowControl.rate ?? flowControl.ratePerSecond)?.toString();
1948
+ const period = typeof flowControl.period === "number" ? `${flowControl.period}s` : flowControl.period;
1665
1949
  const controlValue = [
1666
1950
  parallelism ? `parallelism=${parallelism}` : void 0,
1667
- rate ? `rate=${rate}` : void 0
1951
+ rate ? `rate=${rate}` : void 0,
1952
+ period ? `period=${period}` : void 0
1668
1953
  ].filter(Boolean);
1669
1954
  if (controlValue.length === 0) {
1670
- throw new import_qstash3.QstashError("Provide at least one of parallelism or ratePerSecond for flowControl");
1955
+ throw new import_qstash4.QstashError("Provide at least one of parallelism or ratePerSecond for flowControl");
1671
1956
  }
1672
1957
  return {
1673
1958
  flowControlKey: flowControl.key,
1674
- flowControlValue: controlValue.join(", ")
1675
- };
1676
- };
1677
-
1678
- // src/context/auto-executor.ts
1679
- var import_qstash4 = require("@upstash/qstash");
1680
-
1681
- // src/serve/serve-many.ts
1682
- var getWorkflowId = (url) => {
1683
- const components = url.split("/");
1684
- const lastComponent = components[components.length - 1];
1685
- return lastComponent.split("?")[0];
1686
- };
1687
- var serveManyBase = ({
1688
- workflows,
1689
- getUrl: getUrl2,
1690
- serveMethod,
1691
- options
1959
+ flowControlValue: controlValue.join(", ")
1960
+ };
1961
+ };
1962
+ var getHeaders = (params) => {
1963
+ const workflowHeaders = new WorkflowHeaders(params);
1964
+ return workflowHeaders.getHeaders();
1965
+ };
1966
+
1967
+ // src/qstash/submit-steps.ts
1968
+ var submitParallelSteps = async ({
1969
+ context,
1970
+ steps,
1971
+ initialStepCount,
1972
+ invokeCount,
1973
+ telemetry: telemetry2,
1974
+ debug
1692
1975
  }) => {
1693
- const workflowIds = [];
1694
- const workflowMap = Object.fromEntries(
1695
- Object.entries(workflows).map((workflow) => {
1696
- const workflowId = workflow[0];
1697
- if (workflowIds.includes(workflowId)) {
1698
- throw new WorkflowError(
1699
- `Duplicate workflow name found: '${workflowId}'. Please set different workflow names in serveMany.`
1700
- );
1701
- }
1702
- if (workflowId.includes("/")) {
1703
- throw new WorkflowError(
1704
- `Invalid workflow name found: '${workflowId}'. Workflow name cannot contain '/'.`
1705
- );
1706
- }
1707
- workflowIds.push(workflowId);
1708
- workflow[1].workflowId = workflowId;
1709
- workflow[1].options = {
1710
- ...options,
1711
- ...workflow[1].options
1976
+ const planSteps = steps.map(
1977
+ (step, index) => step.getPlanStep(steps.length, initialStepCount + index)
1978
+ );
1979
+ await debug?.log("SUBMIT", "SUBMIT_STEP", {
1980
+ length: planSteps.length,
1981
+ steps: planSteps
1982
+ });
1983
+ const result = await context.qstashClient.batch(
1984
+ planSteps.map((planStep) => {
1985
+ const { headers } = getHeaders({
1986
+ initHeaderValue: "false",
1987
+ workflowConfig: {
1988
+ workflowRunId: context.workflowRunId,
1989
+ workflowUrl: context.url,
1990
+ failureUrl: context.failureUrl,
1991
+ retries: context.retries,
1992
+ flowControl: context.flowControl,
1993
+ telemetry: telemetry2
1994
+ },
1995
+ userHeaders: context.headers,
1996
+ invokeCount
1997
+ });
1998
+ return {
1999
+ headers,
2000
+ method: "POST",
2001
+ url: context.url,
2002
+ body: JSON.stringify(planStep),
2003
+ notBefore: planStep.sleepUntil,
2004
+ delay: planStep.sleepFor
1712
2005
  };
1713
- const params = [workflow[1].routeFunction, workflow[1].options];
1714
- const handler = serveMethod(...params);
1715
- return [workflowId, handler];
1716
2006
  })
1717
2007
  );
1718
- return {
1719
- handler: async (...params) => {
1720
- const url = getUrl2(...params);
1721
- const pickedWorkflowId = getWorkflowId(url);
1722
- if (!pickedWorkflowId) {
1723
- return new Response(
1724
- `Unexpected request in serveMany. workflowId not set. Please update the URL of your request.`,
1725
- {
1726
- status: 404
1727
- }
1728
- );
1729
- }
1730
- const workflow = workflowMap[pickedWorkflowId];
1731
- if (!workflow) {
1732
- return new Response(
1733
- `No workflows in serveMany found for '${pickedWorkflowId}'. Please update the URL of your request.`,
1734
- {
1735
- status: 404
1736
- }
1737
- );
1738
- }
1739
- return await workflow(...params);
1740
- }
1741
- };
2008
+ await debug?.log("INFO", "SUBMIT_STEP", {
2009
+ messageIds: result.map((message) => {
2010
+ return {
2011
+ message: message.messageId
2012
+ };
2013
+ })
2014
+ });
2015
+ throw new WorkflowAbort(planSteps[0].stepName, planSteps[0]);
1742
2016
  };
1743
- var invokeWorkflow = async ({
1744
- settings,
1745
- invokeStep,
2017
+ var submitSingleStep = async ({
1746
2018
  context,
2019
+ lazyStep,
2020
+ stepId,
1747
2021
  invokeCount,
1748
- telemetry: telemetry2
2022
+ concurrency,
2023
+ telemetry: telemetry2,
2024
+ debug
1749
2025
  }) => {
1750
- const {
1751
- body,
1752
- workflow,
1753
- headers = {},
1754
- workflowRunId = getWorkflowRunId(),
1755
- retries,
1756
- flowControl
1757
- } = settings;
1758
- const { workflowId } = workflow;
1759
- const {
1760
- retries: workflowRetries,
1761
- failureFunction,
1762
- failureUrl,
1763
- useJSONContent,
1764
- flowControl: workflowFlowControl
1765
- } = workflow.options;
1766
- if (!workflowId) {
1767
- throw new WorkflowError("You can only invoke workflow which has a workflowId");
1768
- }
1769
- const { headers: invokerHeaders } = getHeaders({
1770
- initHeaderValue: "false",
1771
- workflowRunId: context.workflowRunId,
1772
- workflowUrl: context.url,
1773
- userHeaders: context.headers,
1774
- failureUrl: context.failureUrl,
1775
- retries: context.retries,
1776
- telemetry: telemetry2,
2026
+ const resultStep = await lazyStep.getResultStep(concurrency, stepId);
2027
+ await debug?.log("INFO", "RUN_SINGLE", {
2028
+ fromRequest: false,
2029
+ step: resultStep,
2030
+ stepCount: stepId
2031
+ });
2032
+ const { headers } = lazyStep.getHeaders({
2033
+ context,
2034
+ step: resultStep,
1777
2035
  invokeCount,
1778
- flowControl: context.flowControl
2036
+ telemetry: telemetry2
1779
2037
  });
1780
- invokerHeaders["Upstash-Workflow-Runid"] = context.workflowRunId;
1781
- const newUrl = context.url.replace(/[^/]+$/, workflowId);
1782
- const { headers: triggerHeaders } = getHeaders({
1783
- initHeaderValue: "true",
1784
- workflowRunId,
1785
- workflowUrl: newUrl,
1786
- userHeaders: new Headers(headers),
1787
- retries: retries ?? workflowRetries,
1788
- telemetry: telemetry2,
1789
- failureUrl: failureFunction ? newUrl : failureUrl,
1790
- invokeCount: invokeCount + 1,
1791
- flowControl: flowControl ?? workflowFlowControl
2038
+ const body = lazyStep.getBody({
2039
+ context,
2040
+ step: resultStep,
2041
+ headers,
2042
+ invokeCount,
2043
+ telemetry: telemetry2
1792
2044
  });
1793
- triggerHeaders["Upstash-Workflow-Invoke"] = "true";
1794
- if (useJSONContent) {
1795
- triggerHeaders["content-type"] = "application/json";
1796
- }
1797
- const request = {
1798
- body: JSON.stringify(body),
1799
- headers: Object.fromEntries(
1800
- Object.entries(invokerHeaders).map((pairs) => [pairs[0], [pairs[1]]])
1801
- ),
1802
- workflowRunId: context.workflowRunId,
1803
- workflowUrl: context.url,
1804
- step: invokeStep
1805
- };
1806
- await context.qstashClient.publish({
1807
- headers: triggerHeaders,
1808
- method: "POST",
1809
- body: JSON.stringify(request),
1810
- url: newUrl
2045
+ await debug?.log("SUBMIT", "SUBMIT_STEP", {
2046
+ length: 1,
2047
+ steps: [resultStep]
2048
+ });
2049
+ const submitResult = await lazyStep.submitStep({
2050
+ context,
2051
+ body,
2052
+ headers,
2053
+ isParallel: concurrency !== NO_CONCURRENCY,
2054
+ invokeCount,
2055
+ step: resultStep,
2056
+ telemetry: telemetry2
1811
2057
  });
2058
+ await debug?.log("INFO", "SUBMIT_STEP", {
2059
+ messageIds: submitResult.map((message) => {
2060
+ return {
2061
+ message: message.messageId
2062
+ };
2063
+ })
2064
+ });
2065
+ return resultStep;
1812
2066
  };
1813
2067
 
1814
2068
  // src/context/auto-executor.ts
@@ -1915,14 +2169,16 @@ var AutoExecutor = class _AutoExecutor {
1915
2169
  });
1916
2170
  return lazyStep.parseOut(step.out);
1917
2171
  }
1918
- const resultStep = await lazyStep.getResultStep(NO_CONCURRENCY, this.stepCount);
1919
- await this.debug?.log("INFO", "RUN_SINGLE", {
1920
- fromRequest: false,
1921
- step: resultStep,
1922
- stepCount: this.stepCount
2172
+ const resultStep = await submitSingleStep({
2173
+ context: this.context,
2174
+ lazyStep,
2175
+ stepId: this.stepCount,
2176
+ invokeCount: this.invokeCount,
2177
+ concurrency: 1,
2178
+ telemetry: this.telemetry,
2179
+ debug: this.debug
1923
2180
  });
1924
- await this.submitStepsToQStash([resultStep], [lazyStep]);
1925
- return resultStep.out;
2181
+ throw new WorkflowAbort(lazyStep.stepName, resultStep);
1926
2182
  }
1927
2183
  /**
1928
2184
  * Runs steps in parallel.
@@ -1950,10 +2206,14 @@ var AutoExecutor = class _AutoExecutor {
1950
2206
  });
1951
2207
  switch (parallelCallState) {
1952
2208
  case "first": {
1953
- const planSteps = parallelSteps.map(
1954
- (parallelStep, index) => parallelStep.getPlanStep(parallelSteps.length, initialStepCount + index)
1955
- );
1956
- await this.submitStepsToQStash(planSteps, parallelSteps);
2209
+ await submitParallelSteps({
2210
+ context: this.context,
2211
+ steps: parallelSteps,
2212
+ initialStepCount,
2213
+ invokeCount: this.invokeCount,
2214
+ telemetry: this.telemetry,
2215
+ debug: this.debug
2216
+ });
1957
2217
  break;
1958
2218
  }
1959
2219
  case "partial": {
@@ -1967,13 +2227,18 @@ var AutoExecutor = class _AutoExecutor {
1967
2227
  validateStep(parallelSteps[stepIndex], planStep);
1968
2228
  try {
1969
2229
  const parallelStep = parallelSteps[stepIndex];
1970
- const resultStep = await parallelStep.getResultStep(
1971
- parallelSteps.length,
1972
- planStep.targetStep
1973
- );
1974
- await this.submitStepsToQStash([resultStep], [parallelStep]);
2230
+ const resultStep = await submitSingleStep({
2231
+ context: this.context,
2232
+ lazyStep: parallelStep,
2233
+ stepId: planStep.targetStep,
2234
+ invokeCount: this.invokeCount,
2235
+ concurrency: parallelSteps.length,
2236
+ telemetry: this.telemetry,
2237
+ debug: this.debug
2238
+ });
2239
+ throw new WorkflowAbort(parallelStep.stepName, resultStep);
1975
2240
  } catch (error) {
1976
- if (error instanceof WorkflowAbort || error instanceof import_qstash4.QstashError && error.status === 400) {
2241
+ if (error instanceof WorkflowAbort || error instanceof import_qstash5.QstashError && error.status === 400) {
1977
2242
  throw error;
1978
2243
  }
1979
2244
  throw new WorkflowError(
@@ -2029,128 +2294,6 @@ var AutoExecutor = class _AutoExecutor {
2029
2294
  return "discard";
2030
2295
  }
2031
2296
  }
2032
- /**
2033
- * sends the steps to QStash as batch
2034
- *
2035
- * @param steps steps to send
2036
- */
2037
- async submitStepsToQStash(steps, lazySteps) {
2038
- if (steps.length === 0) {
2039
- throw new WorkflowError(
2040
- `Unable to submit steps to QStash. Provided list is empty. Current step: ${this.stepCount}`
2041
- );
2042
- }
2043
- await this.debug?.log("SUBMIT", "SUBMIT_STEP", {
2044
- length: steps.length,
2045
- steps
2046
- });
2047
- if (steps[0].waitEventId && steps.length === 1) {
2048
- const waitStep = steps[0];
2049
- const { headers, timeoutHeaders } = getHeaders({
2050
- initHeaderValue: "false",
2051
- workflowRunId: this.context.workflowRunId,
2052
- workflowUrl: this.context.url,
2053
- userHeaders: this.context.headers,
2054
- step: waitStep,
2055
- failureUrl: this.context.failureUrl,
2056
- retries: this.context.retries,
2057
- telemetry: this.telemetry,
2058
- invokeCount: this.invokeCount,
2059
- flowControl: this.context.flowControl
2060
- });
2061
- const waitBody = {
2062
- url: this.context.url,
2063
- timeout: waitStep.timeout,
2064
- timeoutBody: void 0,
2065
- timeoutUrl: this.context.url,
2066
- timeoutHeaders,
2067
- step: {
2068
- stepId: waitStep.stepId,
2069
- stepType: "Wait",
2070
- stepName: waitStep.stepName,
2071
- concurrent: waitStep.concurrent,
2072
- targetStep: waitStep.targetStep
2073
- }
2074
- };
2075
- await this.context.qstashClient.http.request({
2076
- path: ["v2", "wait", waitStep.waitEventId],
2077
- body: JSON.stringify(waitBody),
2078
- headers,
2079
- method: "POST",
2080
- parseResponseAsJson: false
2081
- });
2082
- throw new WorkflowAbort(waitStep.stepName, waitStep);
2083
- }
2084
- if (steps.length === 1 && lazySteps[0] instanceof LazyInvokeStep) {
2085
- const invokeStep = steps[0];
2086
- const lazyInvokeStep = lazySteps[0];
2087
- await invokeWorkflow({
2088
- settings: lazyInvokeStep.params,
2089
- invokeStep,
2090
- context: this.context,
2091
- invokeCount: this.invokeCount,
2092
- telemetry: this.telemetry
2093
- });
2094
- throw new WorkflowAbort(invokeStep.stepName, invokeStep);
2095
- }
2096
- const result = await this.context.qstashClient.batch(
2097
- steps.map((singleStep, index) => {
2098
- const lazyStep = lazySteps[index];
2099
- const { headers } = getHeaders({
2100
- initHeaderValue: "false",
2101
- workflowRunId: this.context.workflowRunId,
2102
- workflowUrl: this.context.url,
2103
- userHeaders: this.context.headers,
2104
- step: singleStep,
2105
- failureUrl: this.context.failureUrl,
2106
- retries: this.context.retries,
2107
- callRetries: lazyStep instanceof LazyCallStep ? lazyStep.retries : void 0,
2108
- callTimeout: lazyStep instanceof LazyCallStep ? lazyStep.timeout : void 0,
2109
- telemetry: this.telemetry,
2110
- invokeCount: this.invokeCount,
2111
- flowControl: this.context.flowControl,
2112
- callFlowControl: lazyStep instanceof LazyCallStep ? lazyStep.flowControl : void 0
2113
- });
2114
- const willWait = singleStep.concurrent === NO_CONCURRENCY || singleStep.stepId === 0;
2115
- singleStep.out = JSON.stringify(singleStep.out);
2116
- return singleStep.callUrl && lazyStep instanceof LazyCallStep ? (
2117
- // if the step is a third party call, we call the third party
2118
- // url (singleStep.callUrl) and pass information about the workflow
2119
- // in the headers (handled in getHeaders). QStash makes the request
2120
- // to callUrl and returns the result to Workflow endpoint.
2121
- // handleThirdPartyCallResult method sends the result of the third
2122
- // party call to QStash.
2123
- {
2124
- headers,
2125
- method: singleStep.callMethod,
2126
- body: JSON.stringify(singleStep.callBody),
2127
- url: singleStep.callUrl
2128
- }
2129
- ) : (
2130
- // if the step is not a third party call, we use workflow
2131
- // endpoint (context.url) as URL when calling QStash. QStash
2132
- // calls us back with the updated steps list.
2133
- {
2134
- headers,
2135
- method: "POST",
2136
- body: JSON.stringify(singleStep),
2137
- url: this.context.url,
2138
- notBefore: willWait ? singleStep.sleepUntil : void 0,
2139
- delay: willWait ? singleStep.sleepFor : void 0
2140
- }
2141
- );
2142
- })
2143
- );
2144
- const _result = result;
2145
- await this.debug?.log("INFO", "SUBMIT_STEP", {
2146
- messageIds: _result.map((message) => {
2147
- return {
2148
- message: message.messageId
2149
- };
2150
- })
2151
- });
2152
- throw new WorkflowAbort(steps[0].stepName, steps[0]);
2153
- }
2154
2297
  /**
2155
2298
  * Get the promise by executing the lazt steps list. If there is a single
2156
2299
  * step, we call `runSingle`. Otherwise `runParallel` is called.
@@ -2224,7 +2367,7 @@ var sortSteps = (steps) => {
2224
2367
  };
2225
2368
 
2226
2369
  // src/context/api/anthropic.ts
2227
- var import_qstash5 = require("@upstash/qstash");
2370
+ var import_qstash6 = require("@upstash/qstash");
2228
2371
 
2229
2372
  // src/context/provider.ts
2230
2373
  var getProviderInfo = (api) => {
@@ -2288,7 +2431,7 @@ var AnthropicAPI = class extends BaseWorkflowApi {
2288
2431
  return await this.callApi(stepName, {
2289
2432
  api: {
2290
2433
  name: "llm",
2291
- provider: (0, import_qstash5.anthropic)({ token })
2434
+ provider: (0, import_qstash6.anthropic)({ token })
2292
2435
  },
2293
2436
  ...parameters
2294
2437
  });
@@ -2296,12 +2439,12 @@ var AnthropicAPI = class extends BaseWorkflowApi {
2296
2439
  };
2297
2440
 
2298
2441
  // src/context/api/openai.ts
2299
- var import_qstash6 = require("@upstash/qstash");
2442
+ var import_qstash7 = require("@upstash/qstash");
2300
2443
  var OpenAIAPI = class extends BaseWorkflowApi {
2301
2444
  async call(stepName, settings) {
2302
2445
  const { token, organization, operation, baseURL, ...parameters } = settings;
2303
2446
  const useOpenAI = baseURL === void 0;
2304
- const provider = useOpenAI ? (0, import_qstash6.openai)({ token, organization }) : (0, import_qstash6.custom)({ baseUrl: baseURL, token });
2447
+ const provider = useOpenAI ? (0, import_qstash7.openai)({ token, organization }) : (0, import_qstash7.custom)({ baseUrl: baseURL, token });
2305
2448
  return await this.callApi(stepName, {
2306
2449
  api: {
2307
2450
  name: "llm",
@@ -2313,14 +2456,14 @@ var OpenAIAPI = class extends BaseWorkflowApi {
2313
2456
  };
2314
2457
 
2315
2458
  // src/context/api/resend.ts
2316
- var import_qstash7 = require("@upstash/qstash");
2459
+ var import_qstash8 = require("@upstash/qstash");
2317
2460
  var ResendAPI = class extends BaseWorkflowApi {
2318
2461
  async call(stepName, settings) {
2319
2462
  const { token, batch = false, ...parameters } = settings;
2320
2463
  return await this.callApi(stepName, {
2321
2464
  api: {
2322
2465
  name: "email",
2323
- provider: (0, import_qstash7.resend)({ token, batch })
2466
+ provider: (0, import_qstash8.resend)({ token, batch })
2324
2467
  },
2325
2468
  ...parameters
2326
2469
  });
@@ -2347,28 +2490,11 @@ var WorkflowApi = class extends BaseWorkflowApi {
2347
2490
  };
2348
2491
 
2349
2492
  // src/agents/index.ts
2350
- var import_openai3 = require("@ai-sdk/openai");
2351
-
2352
- // src/agents/adapters.ts
2353
2493
  var import_openai2 = require("@ai-sdk/openai");
2354
- var import_ai = require("ai");
2355
-
2356
- // src/agents/constants.ts
2357
- var AGENT_NAME_HEADER = "upstash-agent-name";
2358
- var MANAGER_AGENT_PROMPT = `You are an agent orchestrating other AI Agents.
2359
-
2360
- These other agents have tools available to them.
2361
-
2362
- Given a prompt, utilize these agents to address requests.
2363
-
2364
- 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.
2365
-
2366
- Avoid calling the same agent twice in one turn. Instead, prefer to call it once but provide everything
2367
- you need from that agent.
2368
- `;
2369
2494
 
2370
2495
  // src/agents/adapters.ts
2371
- var fetchWithContextCall = async (context, ...params) => {
2496
+ var import_ai = require("ai");
2497
+ var fetchWithContextCall = async (context, agentCallParams, ...params) => {
2372
2498
  const [input, init] = params;
2373
2499
  try {
2374
2500
  const headers = init?.headers ? Object.fromEntries(new Headers(init.headers).entries()) : {};
@@ -2379,7 +2505,10 @@ var fetchWithContextCall = async (context, ...params) => {
2379
2505
  url: input.toString(),
2380
2506
  method: init?.method,
2381
2507
  headers,
2382
- body
2508
+ body,
2509
+ timeout: agentCallParams?.timeout,
2510
+ retries: agentCallParams?.retries,
2511
+ flowControl: agentCallParams?.flowControl
2383
2512
  });
2384
2513
  const responseHeaders = new Headers(
2385
2514
  Object.entries(responseInfo.header).reduce(
@@ -2406,10 +2535,11 @@ var fetchWithContextCall = async (context, ...params) => {
2406
2535
  var createWorkflowModel = ({
2407
2536
  context,
2408
2537
  provider,
2409
- providerParams
2538
+ providerParams,
2539
+ agentCallParams
2410
2540
  }) => {
2411
2541
  return provider({
2412
- fetch: (...params) => fetchWithContextCall(context, ...params),
2542
+ fetch: (...params) => fetchWithContextCall(context, agentCallParams, ...params),
2413
2543
  ...providerParams
2414
2544
  });
2415
2545
  };
@@ -2649,17 +2779,87 @@ var WorkflowAgents = class {
2649
2779
  */
2650
2780
  openai(...params) {
2651
2781
  const [model, settings] = params;
2652
- const { baseURL, apiKey, ...otherSettings } = settings ?? {};
2782
+ const { baseURL, apiKey, callSettings, ...otherSettings } = settings ?? {};
2653
2783
  const openaiModel = this.AISDKModel({
2654
2784
  context: this.context,
2655
- provider: import_openai3.createOpenAI,
2656
- providerParams: { baseURL, apiKey, compatibility: "strict" }
2785
+ provider: import_openai2.createOpenAI,
2786
+ providerParams: { baseURL, apiKey, compatibility: "strict" },
2787
+ agentCallParams: callSettings
2657
2788
  });
2658
2789
  return openaiModel(model, otherSettings);
2659
2790
  }
2660
2791
  AISDKModel = createWorkflowModel;
2661
2792
  };
2662
2793
 
2794
+ // src/serve/serve-many.ts
2795
+ var getWorkflowId = (url) => {
2796
+ const components = url.split("/");
2797
+ const lastComponent = components[components.length - 1];
2798
+ return lastComponent.split("?")[0];
2799
+ };
2800
+ var serveManyBase = ({
2801
+ workflows,
2802
+ getUrl: getUrl2,
2803
+ serveMethod,
2804
+ options
2805
+ }) => {
2806
+ const workflowIds = [];
2807
+ const workflowMap = Object.fromEntries(
2808
+ Object.entries(workflows).map((workflow) => {
2809
+ const workflowId = workflow[0];
2810
+ if (workflowIds.includes(workflowId)) {
2811
+ throw new WorkflowError(
2812
+ `Duplicate workflow name found: '${workflowId}'. Please set different workflow names in serveMany.`
2813
+ );
2814
+ }
2815
+ if (workflowId.includes("/")) {
2816
+ throw new WorkflowError(
2817
+ `Invalid workflow name found: '${workflowId}'. Workflow name cannot contain '/'.`
2818
+ );
2819
+ }
2820
+ workflowIds.push(workflowId);
2821
+ workflow[1].workflowId = workflowId;
2822
+ workflow[1].options = {
2823
+ ...options,
2824
+ ...workflow[1].options
2825
+ };
2826
+ const params = [workflow[1].routeFunction, workflow[1].options];
2827
+ const handler = serveMethod(...params);
2828
+ return [workflowId, handler];
2829
+ })
2830
+ );
2831
+ return {
2832
+ handler: async (...params) => {
2833
+ const url = getUrl2(...params);
2834
+ const pickedWorkflowId = getWorkflowId(url);
2835
+ if (!pickedWorkflowId) {
2836
+ return new Response(
2837
+ `Unexpected request in serveMany. workflowId not set. Please update the URL of your request.`,
2838
+ {
2839
+ status: 404
2840
+ }
2841
+ );
2842
+ }
2843
+ const workflow = workflowMap[pickedWorkflowId];
2844
+ if (!workflow) {
2845
+ return new Response(
2846
+ `No workflows in serveMany found for '${pickedWorkflowId}'. Please update the URL of your request.`,
2847
+ {
2848
+ status: 404
2849
+ }
2850
+ );
2851
+ }
2852
+ return await workflow(...params);
2853
+ }
2854
+ };
2855
+ };
2856
+ var getNewUrlFromWorkflowId = (url, workflowId) => {
2857
+ if (!workflowId) {
2858
+ throw new WorkflowError("You can only call workflow which has a workflowId");
2859
+ }
2860
+ return url.replace(/[^/]+$/, workflowId);
2861
+ };
2862
+
2663
2863
  // src/context/context.ts
2664
2864
  var WorkflowContext = class {
2665
2865
  executor;
@@ -2881,60 +3081,42 @@ var WorkflowContext = class {
2881
3081
  }
2882
3082
  await this.addStep(new LazySleepUntilStep(stepName, time));
2883
3083
  }
2884
- /**
2885
- * Makes a third party call through QStash in order to make a
2886
- * network call without consuming any runtime.
2887
- *
2888
- * ```ts
2889
- * const { status, body } = await context.call<string>(
2890
- * "post call step",
2891
- * {
2892
- * url: "https://www.some-endpoint.com/api",
2893
- * method: "POST",
2894
- * body: "my-payload"
2895
- * }
2896
- * );
2897
- * ```
2898
- *
2899
- * tries to parse the result of the request as JSON. If it's
2900
- * not a JSON which can be parsed, simply returns the response
2901
- * body as it is.
2902
- *
2903
- * @param stepName
2904
- * @param url url to call
2905
- * @param method call method. "GET" by default.
2906
- * @param body call body
2907
- * @param headers call headers
2908
- * @param retries number of call retries. 0 by default
2909
- * @param timeout max duration to wait for the endpoint to respond. in seconds.
2910
- * @returns call result as {
2911
- * status: number;
2912
- * body: unknown;
2913
- * header: Record<string, string[]>
2914
- * }
2915
- */
2916
3084
  async call(stepName, settings) {
2917
- const {
2918
- url,
2919
- method = "GET",
2920
- body: requestBody,
2921
- headers = {},
2922
- retries = 0,
2923
- timeout,
2924
- flowControl
2925
- } = settings;
2926
- return await this.addStep(
2927
- new LazyCallStep(
3085
+ let callStep;
3086
+ if ("workflow" in settings) {
3087
+ const url = getNewUrlFromWorkflowId(this.url, settings.workflow.workflowId);
3088
+ callStep = new LazyCallStep(
3089
+ stepName,
3090
+ url,
3091
+ "POST",
3092
+ settings.body,
3093
+ settings.headers || {},
3094
+ settings.retries || 0,
3095
+ settings.timeout,
3096
+ settings.flowControl ?? settings.workflow.options.flowControl
3097
+ );
3098
+ } else {
3099
+ const {
3100
+ url,
3101
+ method = "GET",
3102
+ body,
3103
+ headers = {},
3104
+ retries = 0,
3105
+ timeout,
3106
+ flowControl
3107
+ } = settings;
3108
+ callStep = new LazyCallStep(
2928
3109
  stepName,
2929
3110
  url,
2930
3111
  method,
2931
- requestBody,
3112
+ body,
2932
3113
  headers,
2933
3114
  retries,
2934
3115
  timeout,
2935
3116
  flowControl
2936
- )
2937
- );
3117
+ );
3118
+ }
3119
+ return await this.addStep(callStep);
2938
3120
  }
2939
3121
  /**
2940
3122
  * Pauses workflow execution until a specific event occurs or a timeout is reached.
@@ -3082,7 +3264,7 @@ var WorkflowLogger = class _WorkflowLogger {
3082
3264
  };
3083
3265
 
3084
3266
  // src/serve/authorization.ts
3085
- var import_qstash8 = require("@upstash/qstash");
3267
+ var import_qstash9 = require("@upstash/qstash");
3086
3268
  var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowContext {
3087
3269
  static disabledMessage = "disabled-qstash-worklfow-run";
3088
3270
  disabled = true;
@@ -3114,7 +3296,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
3114
3296
  */
3115
3297
  static async tryAuthentication(routeFunction, context) {
3116
3298
  const disabledContext = new _DisabledWorkflowContext({
3117
- qstashClient: new import_qstash8.Client({
3299
+ qstashClient: new import_qstash9.Client({
3118
3300
  baseUrl: "disabled-client",
3119
3301
  token: "disabled-client"
3120
3302
  }),
@@ -3328,15 +3510,15 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
3328
3510
  };
3329
3511
 
3330
3512
  // src/serve/options.ts
3331
- var import_qstash9 = require("@upstash/qstash");
3332
3513
  var import_qstash10 = require("@upstash/qstash");
3514
+ var import_qstash11 = require("@upstash/qstash");
3333
3515
  var processOptions = (options) => {
3334
3516
  const environment = options?.env ?? (typeof process === "undefined" ? {} : process.env);
3335
3517
  const receiverEnvironmentVariablesSet = Boolean(
3336
3518
  environment.QSTASH_CURRENT_SIGNING_KEY && environment.QSTASH_NEXT_SIGNING_KEY
3337
3519
  );
3338
3520
  return {
3339
- qstashClient: new import_qstash10.Client({
3521
+ qstashClient: new import_qstash11.Client({
3340
3522
  baseUrl: environment.QSTASH_URL,
3341
3523
  token: environment.QSTASH_TOKEN
3342
3524
  }),
@@ -3371,7 +3553,7 @@ var processOptions = (options) => {
3371
3553
  throw error;
3372
3554
  }
3373
3555
  },
3374
- receiver: receiverEnvironmentVariablesSet ? new import_qstash9.Receiver({
3556
+ receiver: receiverEnvironmentVariablesSet ? new import_qstash10.Receiver({
3375
3557
  currentSigningKey: environment.QSTASH_CURRENT_SIGNING_KEY,
3376
3558
  nextSigningKey: environment.QSTASH_NEXT_SIGNING_KEY
3377
3559
  }) : void 0,