@upstash/workflow 0.2.21 → 0.2.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -83,6 +83,15 @@ waiting for an event or get the workflows waiting for an event:
83
83
  import { Client } from "@upstash/workflow";
84
84
  const client = new Client({ token: "<QSTASH_TOKEN>" });
85
85
 
86
+ // trigger a workflow
87
+ const { workflowRunId } = await client.trigger({
88
+ url: "https://workflow-endpoint.com",
89
+ body: "hello there!", // Optional body
90
+ headers: { ... }, // Optional headers
91
+ workflowRunId: "my-workflow", // Optional workflow run ID
92
+ retries: 3 // Optional retries for the initial request
93
+ });
94
+
86
95
  // cancel workflow:
87
96
  await client.cancel({ workflowRunId: "<WORKFLOW_RUN_ID>" });
88
97
 
@@ -98,6 +107,36 @@ const result = await client.getWaiters({
98
107
  });
99
108
  ```
100
109
 
110
+ ## Telemetry
111
+
112
+ This sdk sends anonymous telemetry headers to help us improve your experience.
113
+ We collect the following:
114
+
115
+ - SDK version
116
+ - Platform (Cloudflare, AWS or Vercel)
117
+ - Runtime version (node@18.x)
118
+
119
+ You can opt out by setting `disableTelemetry: true` when triggering the workflow and in the serve options:
120
+
121
+ ```ts
122
+ // client
123
+ const client = new Client(/***/);
124
+ await client.trigger({
125
+ // ...
126
+ disableTelemetry: true,
127
+ });
128
+
129
+ // workflow endpoint
130
+ export const { POST } = serve(
131
+ async (context) => {
132
+ // ...
133
+ },
134
+ {
135
+ disableTelemetry: true,
136
+ }
137
+ );
138
+ ```
139
+
101
140
  ## Contributing
102
141
 
103
142
  ### Setup
package/astro.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { APIContext, APIRoute } from 'astro';
2
- import { g as WorkflowContext, n as PublicServeOptions, y as InvokableWorkflow } from './types-Q3dM0UlR.mjs';
3
- import { s as serveManyBase } from './serve-many-BNusWYgt.mjs';
2
+ import { h as WorkflowContext, o as PublicServeOptions, z as InvokableWorkflow } from './types-9nCq6bRP.mjs';
3
+ import { s as serveManyBase } from './serve-many-CctdYIfB.mjs';
4
4
  import '@upstash/qstash';
5
5
  import 'zod';
6
6
  import 'ai';
package/astro.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { APIContext, APIRoute } from 'astro';
2
- import { g as WorkflowContext, n as PublicServeOptions, y as InvokableWorkflow } from './types-Q3dM0UlR.js';
3
- import { s as serveManyBase } from './serve-many-CXqQP3RI.js';
2
+ import { h as WorkflowContext, o as PublicServeOptions, z as InvokableWorkflow } from './types-9nCq6bRP.js';
3
+ import { s as serveManyBase } from './serve-many-BXDr30rl.js';
4
4
  import '@upstash/qstash';
5
5
  import 'zod';
6
6
  import 'ai';
package/astro.js CHANGED
@@ -27,7 +27,95 @@ __export(astro_exports, {
27
27
  module.exports = __toCommonJS(astro_exports);
28
28
 
29
29
  // src/client/utils.ts
30
+ var import_qstash2 = require("@upstash/qstash");
31
+
32
+ // src/error.ts
30
33
  var import_qstash = require("@upstash/qstash");
34
+ var WorkflowError = class extends import_qstash.QstashError {
35
+ constructor(message) {
36
+ super(message);
37
+ this.name = "WorkflowError";
38
+ }
39
+ };
40
+ var WorkflowAbort = class extends Error {
41
+ stepInfo;
42
+ stepName;
43
+ /**
44
+ * whether workflow is to be canceled on abort
45
+ */
46
+ cancelWorkflow;
47
+ /**
48
+ *
49
+ * @param stepName name of the aborting step
50
+ * @param stepInfo step information
51
+ * @param cancelWorkflow
52
+ */
53
+ constructor(stepName, stepInfo, cancelWorkflow = false) {
54
+ super(
55
+ `This is an Upstash Workflow error thrown after a step executes. It is expected to be raised. Make sure that you await for each step. Also, if you are using try/catch blocks, you should not wrap context.run/sleep/sleepUntil/call methods with try/catch. Aborting workflow after executing step '${stepName}'.`
56
+ );
57
+ this.name = "WorkflowAbort";
58
+ this.stepName = stepName;
59
+ this.stepInfo = stepInfo;
60
+ this.cancelWorkflow = cancelWorkflow;
61
+ }
62
+ };
63
+ var WorkflowNonRetryableError = class extends WorkflowAbort {
64
+ /**
65
+ * @param message error message to be displayed
66
+ */
67
+ constructor(message) {
68
+ super("fail", void 0, false);
69
+ this.name = "WorkflowNonRetryableError";
70
+ if (message) this.message = message;
71
+ }
72
+ };
73
+ var WorkflowRetryAfterError = class extends WorkflowAbort {
74
+ retryAfter;
75
+ /**
76
+ * @param retryAfter time in seconds after which the workflow should be retried
77
+ * @param message error message to be displayed
78
+ */
79
+ constructor(message, retryAfter) {
80
+ super("retry", void 0, false);
81
+ this.name = "WorkflowRetryAfterError";
82
+ this.retryAfter = retryAfter;
83
+ if (message) this.message = message;
84
+ }
85
+ };
86
+ var formatWorkflowError = (error) => {
87
+ return error instanceof Error ? {
88
+ error: error.name,
89
+ message: error.message,
90
+ stack: error.stack
91
+ } : {
92
+ error: "Error",
93
+ message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
94
+ };
95
+ };
96
+ function getConstructorName(obj) {
97
+ if (obj === null || obj === void 0) {
98
+ return null;
99
+ }
100
+ const ctor = obj.constructor;
101
+ if (!ctor || ctor.name === "Object") {
102
+ return null;
103
+ }
104
+ return ctor.name;
105
+ }
106
+ function getConstructorNames(obj) {
107
+ const proto = Object.getPrototypeOf(obj);
108
+ const name = getConstructorName(proto);
109
+ if (name === null) {
110
+ return [];
111
+ }
112
+ return [name, ...getConstructorNames(proto)];
113
+ }
114
+ function isInstanceOf(v, ctor) {
115
+ return getConstructorNames(v).includes(ctor.name);
116
+ }
117
+
118
+ // src/client/utils.ts
31
119
  var makeNotifyRequest = async (requester, eventId, eventData) => {
32
120
  const result = await requester.request({
33
121
  path: ["v2", "notify", eventId],
@@ -67,7 +155,7 @@ var getSteps = async (requester, workflowRunId, messageId, debug) => {
67
155
  return { steps: filteredSteps, workflowRunEnded: false };
68
156
  }
69
157
  } catch (error) {
70
- if (error instanceof import_qstash.QstashError && error.status === 404) {
158
+ if (isInstanceOf(error, import_qstash2.QstashError) && error.status === 404) {
71
159
  await debug?.log("WARN", "ENDPOINT_START", {
72
160
  message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
73
161
  error
@@ -92,65 +180,13 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
92
180
  var DEFAULT_CONTENT_TYPE = "application/json";
93
181
  var NO_CONCURRENCY = 1;
94
182
  var DEFAULT_RETRIES = 3;
95
- var VERSION = "v0.2.21";
183
+ var VERSION = "v0.2.22";
96
184
  var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
97
185
  var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
98
186
  var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
99
187
  var TELEMETRY_HEADER_RUNTIME = "Upstash-Telemetry-Runtime";
100
188
  var TELEMETRY_HEADER_AGENT = "Upstash-Telemetry-Agent";
101
189
 
102
- // src/error.ts
103
- var import_qstash2 = require("@upstash/qstash");
104
- var WorkflowError = class extends import_qstash2.QstashError {
105
- constructor(message) {
106
- super(message);
107
- this.name = "WorkflowError";
108
- }
109
- };
110
- var WorkflowAbort = class extends Error {
111
- stepInfo;
112
- stepName;
113
- /**
114
- * whether workflow is to be canceled on abort
115
- */
116
- cancelWorkflow;
117
- /**
118
- *
119
- * @param stepName name of the aborting step
120
- * @param stepInfo step information
121
- * @param cancelWorkflow
122
- */
123
- constructor(stepName, stepInfo, cancelWorkflow = false) {
124
- super(
125
- `This is an Upstash Workflow error thrown after a step executes. It is expected to be raised. Make sure that you await for each step. Also, if you are using try/catch blocks, you should not wrap context.run/sleep/sleepUntil/call methods with try/catch. Aborting workflow after executing step '${stepName}'.`
126
- );
127
- this.name = "WorkflowAbort";
128
- this.stepName = stepName;
129
- this.stepInfo = stepInfo;
130
- this.cancelWorkflow = cancelWorkflow;
131
- }
132
- };
133
- var WorkflowNonRetryableError = class extends WorkflowAbort {
134
- /**
135
- * @param message error message to be displayed
136
- */
137
- constructor(message) {
138
- super("fail", void 0, false);
139
- this.name = "WorkflowNonRetryableError";
140
- if (message) this.message = message;
141
- }
142
- };
143
- var formatWorkflowError = (error) => {
144
- return error instanceof Error ? {
145
- error: error.name,
146
- message: error.message,
147
- stack: error.stack
148
- } : {
149
- error: "Error",
150
- message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
151
- };
152
- };
153
-
154
190
  // src/context/auto-executor.ts
155
191
  var import_qstash5 = require("@upstash/qstash");
156
192
 
@@ -710,17 +746,17 @@ var triggerRouteFunction = async ({
710
746
  return ok("workflow-finished");
711
747
  } catch (error) {
712
748
  const error_ = error;
713
- if (error instanceof import_qstash3.QstashError && error.status === 400) {
749
+ if (isInstanceOf(error, import_qstash3.QstashError) && error.status === 400) {
714
750
  await debug?.log("WARN", "RESPONSE_WORKFLOW", {
715
751
  message: `tried to append to a cancelled workflow. exiting without publishing.`,
716
752
  name: error.name,
717
753
  errorMessage: error.message
718
754
  });
719
755
  return ok("workflow-was-finished");
720
- } else if (!(error_ instanceof WorkflowAbort)) {
721
- return err(error_);
722
- } else if (error_ instanceof WorkflowNonRetryableError) {
756
+ } else if (isInstanceOf(error_, WorkflowNonRetryableError) || isInstanceOf(error_, WorkflowRetryAfterError)) {
723
757
  return ok(error_);
758
+ } else if (!isInstanceOf(error_, WorkflowAbort)) {
759
+ return err(error_);
724
760
  } else if (error_.cancelWorkflow) {
725
761
  await onCancel();
726
762
  return ok("workflow-finished");
@@ -2027,7 +2063,7 @@ var AutoExecutor = class _AutoExecutor {
2027
2063
  });
2028
2064
  throw new WorkflowAbort(parallelStep.stepName, resultStep);
2029
2065
  } catch (error) {
2030
- if (error instanceof WorkflowAbort || error instanceof import_qstash5.QstashError && error.status === 400) {
2066
+ if (isInstanceOf(error, WorkflowAbort) || isInstanceOf(error, import_qstash5.QstashError) && error.status === 400) {
2031
2067
  throw error;
2032
2068
  }
2033
2069
  throw new WorkflowError(
@@ -2134,7 +2170,7 @@ var validateParallelSteps = (lazySteps, stepsFromRequest) => {
2134
2170
  validateStep(lazySteps[index], stepFromRequest);
2135
2171
  }
2136
2172
  } catch (error) {
2137
- if (error instanceof WorkflowError) {
2173
+ if (isInstanceOf(error, WorkflowError)) {
2138
2174
  const lazyStepNames = lazySteps.map((lazyStep) => lazyStep.stepName);
2139
2175
  const lazyStepTypes = lazySteps.map((lazyStep) => lazyStep.stepType);
2140
2176
  const requestStepNames = stepsFromRequest.map((step) => step.stepName);
@@ -2315,7 +2351,7 @@ var fetchWithContextCall = async (context, agentCallParams, ...params) => {
2315
2351
  headers: responseHeaders
2316
2352
  });
2317
2353
  } catch (error) {
2318
- if (error instanceof Error && error.name === "WorkflowAbort") {
2354
+ if (error instanceof Error && isInstanceOf(error, WorkflowAbort)) {
2319
2355
  throw error;
2320
2356
  } else {
2321
2357
  console.error("Error in fetch implementation:", error);
@@ -2417,10 +2453,10 @@ var Agent = class {
2417
2453
  });
2418
2454
  return { text: result.text };
2419
2455
  } catch (error) {
2420
- if (error instanceof import_ai2.ToolExecutionError) {
2421
- if (error.cause instanceof Error && error.cause.name === "WorkflowAbort") {
2456
+ if (isInstanceOf(error, import_ai2.ToolExecutionError)) {
2457
+ if (error.cause instanceof Error && isInstanceOf(error.cause, WorkflowAbort)) {
2422
2458
  throw error.cause;
2423
- } else if (error.cause instanceof import_ai2.ToolExecutionError && error.cause.cause instanceof Error && error.cause.cause.name === "WorkflowAbort") {
2459
+ } else if (isInstanceOf(error.cause, import_ai2.ToolExecutionError) && isInstanceOf(error.cause.cause, WorkflowAbort)) {
2424
2460
  throw error.cause.cause;
2425
2461
  } else {
2426
2462
  throw error;
@@ -3169,7 +3205,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
3169
3205
  try {
3170
3206
  await routeFunction(disabledContext);
3171
3207
  } catch (error) {
3172
- if (error instanceof WorkflowAbort && error.stepName === this.disabledMessage || error instanceof WorkflowNonRetryableError) {
3208
+ if (isInstanceOf(error, WorkflowAbort) && error.stepName === this.disabledMessage || isInstanceOf(error, WorkflowNonRetryableError) || isInstanceOf(error, WorkflowRetryAfterError)) {
3173
3209
  return ok("step-found");
3174
3210
  }
3175
3211
  console.warn(
@@ -3422,13 +3458,24 @@ var processOptions = (options) => {
3422
3458
  },
3423
3459
  status: 489
3424
3460
  });
3425
- } else if (detailedFinishCondition?.condition === "failure-callback") {
3426
- return new Response(detailedFinishCondition.result ?? void 0, {
3427
- status: 200,
3461
+ } else if (detailedFinishCondition?.condition === "retry-after-error") {
3462
+ return new Response(JSON.stringify(formatWorkflowError(detailedFinishCondition.result)), {
3428
3463
  headers: {
3464
+ "Retry-After": detailedFinishCondition.result.retryAfter.toString(),
3429
3465
  [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
3430
- }
3466
+ },
3467
+ status: 429
3431
3468
  });
3469
+ } else if (detailedFinishCondition?.condition === "failure-callback") {
3470
+ return new Response(
3471
+ JSON.stringify({ result: detailedFinishCondition.result ?? void 0 }),
3472
+ {
3473
+ status: 200,
3474
+ headers: {
3475
+ [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
3476
+ }
3477
+ }
3478
+ );
3432
3479
  }
3433
3480
  return new Response(JSON.stringify({ workflowRunId }), {
3434
3481
  status: 200,
@@ -3638,12 +3685,18 @@ var serveBase = (routeFunction, telemetry2, options) => {
3638
3685
  },
3639
3686
  debug
3640
3687
  });
3641
- if (result.isOk() && result.value instanceof WorkflowNonRetryableError) {
3688
+ if (result.isOk() && isInstanceOf(result.value, WorkflowNonRetryableError)) {
3642
3689
  return onStepFinish(workflowRunId, result.value, {
3643
3690
  condition: "non-retryable-error",
3644
3691
  result: result.value
3645
3692
  });
3646
3693
  }
3694
+ if (result.isOk() && isInstanceOf(result.value, WorkflowRetryAfterError)) {
3695
+ return onStepFinish(workflowRunId, result.value, {
3696
+ condition: "retry-after-error",
3697
+ result: result.value
3698
+ });
3699
+ }
3647
3700
  if (result.isErr()) {
3648
3701
  await debug?.log("ERROR", "ERROR", { error: result.error.message });
3649
3702
  throw result.error;
@@ -3674,7 +3727,7 @@ var serveBase = (routeFunction, telemetry2, options) => {
3674
3727
  const errorMessage = `Error while running onError callback: '${formattedOnErrorError.message}'.
3675
3728
  Original error: '${formattedError.message}'`;
3676
3729
  console.error(errorMessage);
3677
- return new Response(errorMessage, {
3730
+ return new Response(JSON.stringify({ error: errorMessage }), {
3678
3731
  status: 500,
3679
3732
  headers: {
3680
3733
  [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
package/astro.mjs CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  SDK_TELEMETRY,
3
3
  serveBase,
4
4
  serveManyBase
5
- } from "./chunk-NQDNC5P4.mjs";
5
+ } from "./chunk-BON2RKOR.mjs";
6
6
 
7
7
  // platforms/astro.ts
8
8
  var telemetry = {
@@ -1,55 +1,3 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
8
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
9
- }) : x)(function(x) {
10
- if (typeof require !== "undefined") return require.apply(this, arguments);
11
- throw Error('Dynamic require of "' + x + '" is not supported');
12
- });
13
- var __commonJS = (cb, mod) => function __require2() {
14
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
15
- };
16
- var __copyProps = (to, from, except, desc) => {
17
- if (from && typeof from === "object" || typeof from === "function") {
18
- for (let key of __getOwnPropNames(from))
19
- if (!__hasOwnProp.call(to, key) && key !== except)
20
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
21
- }
22
- return to;
23
- };
24
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
25
- // If the importer is in node compatibility mode or this is not an ESM
26
- // file that has been converted to a CommonJS file using a Babel-
27
- // compatible transform (i.e. "__esModule" has not been set), then set
28
- // "default" to the CommonJS "module.exports" for node compatibility.
29
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
30
- mod
31
- ));
32
-
33
- // src/constants.ts
34
- var WORKFLOW_ID_HEADER = "Upstash-Workflow-RunId";
35
- var WORKFLOW_INIT_HEADER = "Upstash-Workflow-Init";
36
- var WORKFLOW_URL_HEADER = "Upstash-Workflow-Url";
37
- var WORKFLOW_FAILURE_HEADER = "Upstash-Workflow-Is-Failure";
38
- var WORKFLOW_FEATURE_HEADER = "Upstash-Feature-Set";
39
- var WORKFLOW_INVOKE_COUNT_HEADER = "Upstash-Workflow-Invoke-Count";
40
- var WORKFLOW_LABEL_HEADER = "Upstash-Label";
41
- var WORKFLOW_PROTOCOL_VERSION = "1";
42
- var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
43
- var DEFAULT_CONTENT_TYPE = "application/json";
44
- var NO_CONCURRENCY = 1;
45
- var DEFAULT_RETRIES = 3;
46
- var VERSION = "v0.2.21";
47
- var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
48
- var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
49
- var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
50
- var TELEMETRY_HEADER_RUNTIME = "Upstash-Telemetry-Runtime";
51
- var TELEMETRY_HEADER_AGENT = "Upstash-Telemetry-Agent";
52
-
53
1
  // src/error.ts
54
2
  import { QstashError } from "@upstash/qstash";
55
3
  var WorkflowError = class extends QstashError {
@@ -91,6 +39,19 @@ var WorkflowNonRetryableError = class extends WorkflowAbort {
91
39
  if (message) this.message = message;
92
40
  }
93
41
  };
42
+ var WorkflowRetryAfterError = class extends WorkflowAbort {
43
+ retryAfter;
44
+ /**
45
+ * @param retryAfter time in seconds after which the workflow should be retried
46
+ * @param message error message to be displayed
47
+ */
48
+ constructor(message, retryAfter) {
49
+ super("retry", void 0, false);
50
+ this.name = "WorkflowRetryAfterError";
51
+ this.retryAfter = retryAfter;
52
+ if (message) this.message = message;
53
+ }
54
+ };
94
55
  var formatWorkflowError = (error) => {
95
56
  return error instanceof Error ? {
96
57
  error: error.name,
@@ -101,6 +62,47 @@ var formatWorkflowError = (error) => {
101
62
  message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
102
63
  };
103
64
  };
65
+ function getConstructorName(obj) {
66
+ if (obj === null || obj === void 0) {
67
+ return null;
68
+ }
69
+ const ctor = obj.constructor;
70
+ if (!ctor || ctor.name === "Object") {
71
+ return null;
72
+ }
73
+ return ctor.name;
74
+ }
75
+ function getConstructorNames(obj) {
76
+ const proto = Object.getPrototypeOf(obj);
77
+ const name = getConstructorName(proto);
78
+ if (name === null) {
79
+ return [];
80
+ }
81
+ return [name, ...getConstructorNames(proto)];
82
+ }
83
+ function isInstanceOf(v, ctor) {
84
+ return getConstructorNames(v).includes(ctor.name);
85
+ }
86
+
87
+ // src/constants.ts
88
+ var WORKFLOW_ID_HEADER = "Upstash-Workflow-RunId";
89
+ var WORKFLOW_INIT_HEADER = "Upstash-Workflow-Init";
90
+ var WORKFLOW_URL_HEADER = "Upstash-Workflow-Url";
91
+ var WORKFLOW_FAILURE_HEADER = "Upstash-Workflow-Is-Failure";
92
+ var WORKFLOW_FEATURE_HEADER = "Upstash-Feature-Set";
93
+ var WORKFLOW_INVOKE_COUNT_HEADER = "Upstash-Workflow-Invoke-Count";
94
+ var WORKFLOW_LABEL_HEADER = "Upstash-Label";
95
+ var WORKFLOW_PROTOCOL_VERSION = "1";
96
+ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
97
+ var DEFAULT_CONTENT_TYPE = "application/json";
98
+ var NO_CONCURRENCY = 1;
99
+ var DEFAULT_RETRIES = 3;
100
+ var VERSION = "v0.2.22";
101
+ var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
102
+ var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
103
+ var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
104
+ var TELEMETRY_HEADER_RUNTIME = "Upstash-Telemetry-Runtime";
105
+ var TELEMETRY_HEADER_AGENT = "Upstash-Telemetry-Agent";
104
106
 
105
107
  // src/types.ts
106
108
  var StepTypes = [
@@ -163,7 +165,7 @@ var fetchWithContextCall = async (context, agentCallParams, ...params) => {
163
165
  headers: responseHeaders
164
166
  });
165
167
  } catch (error) {
166
- if (error instanceof Error && error.name === "WorkflowAbort") {
168
+ if (error instanceof Error && isInstanceOf(error, WorkflowAbort)) {
167
169
  throw error;
168
170
  } else {
169
171
  console.error("Error in fetch implementation:", error);
@@ -374,7 +376,7 @@ var getSteps = async (requester, workflowRunId, messageId, debug) => {
374
376
  return { steps: filteredSteps, workflowRunEnded: false };
375
377
  }
376
378
  } catch (error) {
377
- if (error instanceof QstashError2 && error.status === 404) {
379
+ if (isInstanceOf(error, QstashError2) && error.status === 404) {
378
380
  await debug?.log("WARN", "ENDPOINT_START", {
379
381
  message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
380
382
  error
@@ -927,17 +929,17 @@ var triggerRouteFunction = async ({
927
929
  return ok("workflow-finished");
928
930
  } catch (error) {
929
931
  const error_ = error;
930
- if (error instanceof QstashError3 && error.status === 400) {
932
+ if (isInstanceOf(error, QstashError3) && error.status === 400) {
931
933
  await debug?.log("WARN", "RESPONSE_WORKFLOW", {
932
934
  message: `tried to append to a cancelled workflow. exiting without publishing.`,
933
935
  name: error.name,
934
936
  errorMessage: error.message
935
937
  });
936
938
  return ok("workflow-was-finished");
937
- } else if (!(error_ instanceof WorkflowAbort)) {
938
- return err(error_);
939
- } else if (error_ instanceof WorkflowNonRetryableError) {
939
+ } else if (isInstanceOf(error_, WorkflowNonRetryableError) || isInstanceOf(error_, WorkflowRetryAfterError)) {
940
940
  return ok(error_);
941
+ } else if (!isInstanceOf(error_, WorkflowAbort)) {
942
+ return err(error_);
941
943
  } else if (error_.cancelWorkflow) {
942
944
  await onCancel();
943
945
  return ok("workflow-finished");
@@ -2230,7 +2232,7 @@ var AutoExecutor = class _AutoExecutor {
2230
2232
  });
2231
2233
  throw new WorkflowAbort(parallelStep.stepName, resultStep);
2232
2234
  } catch (error) {
2233
- if (error instanceof WorkflowAbort || error instanceof QstashError5 && error.status === 400) {
2235
+ if (isInstanceOf(error, WorkflowAbort) || isInstanceOf(error, QstashError5) && error.status === 400) {
2234
2236
  throw error;
2235
2237
  }
2236
2238
  throw new WorkflowError(
@@ -2337,7 +2339,7 @@ var validateParallelSteps = (lazySteps, stepsFromRequest) => {
2337
2339
  validateStep(lazySteps[index], stepFromRequest);
2338
2340
  }
2339
2341
  } catch (error) {
2340
- if (error instanceof WorkflowError) {
2342
+ if (isInstanceOf(error, WorkflowError)) {
2341
2343
  const lazyStepNames = lazySteps.map((lazyStep) => lazyStep.stepName);
2342
2344
  const lazyStepTypes = lazySteps.map((lazyStep) => lazyStep.stepType);
2343
2345
  const requestStepNames = stepsFromRequest.map((step) => step.stepName);
@@ -2536,10 +2538,10 @@ var Agent = class {
2536
2538
  });
2537
2539
  return { text: result.text };
2538
2540
  } catch (error) {
2539
- if (error instanceof ToolExecutionError) {
2540
- if (error.cause instanceof Error && error.cause.name === "WorkflowAbort") {
2541
+ if (isInstanceOf(error, ToolExecutionError)) {
2542
+ if (error.cause instanceof Error && isInstanceOf(error.cause, WorkflowAbort)) {
2541
2543
  throw error.cause;
2542
- } else if (error.cause instanceof ToolExecutionError && error.cause.cause instanceof Error && error.cause.cause.name === "WorkflowAbort") {
2544
+ } else if (isInstanceOf(error.cause, ToolExecutionError) && isInstanceOf(error.cause.cause, WorkflowAbort)) {
2543
2545
  throw error.cause.cause;
2544
2546
  } else {
2545
2547
  throw error;
@@ -3213,7 +3215,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
3213
3215
  try {
3214
3216
  await routeFunction(disabledContext);
3215
3217
  } catch (error) {
3216
- if (error instanceof WorkflowAbort && error.stepName === this.disabledMessage || error instanceof WorkflowNonRetryableError) {
3218
+ if (isInstanceOf(error, WorkflowAbort) && error.stepName === this.disabledMessage || isInstanceOf(error, WorkflowNonRetryableError) || isInstanceOf(error, WorkflowRetryAfterError)) {
3217
3219
  return ok("step-found");
3218
3220
  }
3219
3221
  console.warn(
@@ -3466,13 +3468,24 @@ var processOptions = (options) => {
3466
3468
  },
3467
3469
  status: 489
3468
3470
  });
3469
- } else if (detailedFinishCondition?.condition === "failure-callback") {
3470
- return new Response(detailedFinishCondition.result ?? void 0, {
3471
- status: 200,
3471
+ } else if (detailedFinishCondition?.condition === "retry-after-error") {
3472
+ return new Response(JSON.stringify(formatWorkflowError(detailedFinishCondition.result)), {
3472
3473
  headers: {
3474
+ "Retry-After": detailedFinishCondition.result.retryAfter.toString(),
3473
3475
  [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
3474
- }
3476
+ },
3477
+ status: 429
3475
3478
  });
3479
+ } else if (detailedFinishCondition?.condition === "failure-callback") {
3480
+ return new Response(
3481
+ JSON.stringify({ result: detailedFinishCondition.result ?? void 0 }),
3482
+ {
3483
+ status: 200,
3484
+ headers: {
3485
+ [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
3486
+ }
3487
+ }
3488
+ );
3476
3489
  }
3477
3490
  return new Response(JSON.stringify({ workflowRunId }), {
3478
3491
  status: 200,
@@ -3682,12 +3695,18 @@ var serveBase = (routeFunction, telemetry, options) => {
3682
3695
  },
3683
3696
  debug
3684
3697
  });
3685
- if (result.isOk() && result.value instanceof WorkflowNonRetryableError) {
3698
+ if (result.isOk() && isInstanceOf(result.value, WorkflowNonRetryableError)) {
3686
3699
  return onStepFinish(workflowRunId, result.value, {
3687
3700
  condition: "non-retryable-error",
3688
3701
  result: result.value
3689
3702
  });
3690
3703
  }
3704
+ if (result.isOk() && isInstanceOf(result.value, WorkflowRetryAfterError)) {
3705
+ return onStepFinish(workflowRunId, result.value, {
3706
+ condition: "retry-after-error",
3707
+ result: result.value
3708
+ });
3709
+ }
3691
3710
  if (result.isErr()) {
3692
3711
  await debug?.log("ERROR", "ERROR", { error: result.error.message });
3693
3712
  throw result.error;
@@ -3718,7 +3737,7 @@ var serveBase = (routeFunction, telemetry, options) => {
3718
3737
  const errorMessage = `Error while running onError callback: '${formattedOnErrorError.message}'.
3719
3738
  Original error: '${formattedError.message}'`;
3720
3739
  console.error(errorMessage);
3721
- return new Response(errorMessage, {
3740
+ return new Response(JSON.stringify({ error: errorMessage }), {
3722
3741
  status: 500,
3723
3742
  headers: {
3724
3743
  [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
@@ -3747,16 +3766,14 @@ var serve = (routeFunction, options) => {
3747
3766
  };
3748
3767
 
3749
3768
  export {
3750
- __require,
3751
- __commonJS,
3752
- __toESM,
3769
+ WorkflowError,
3770
+ WorkflowAbort,
3771
+ WorkflowNonRetryableError,
3772
+ WorkflowRetryAfterError,
3753
3773
  makeNotifyRequest,
3754
3774
  makeGetWaitersRequest,
3755
3775
  WORKFLOW_LABEL_HEADER,
3756
3776
  SDK_TELEMETRY,
3757
- WorkflowError,
3758
- WorkflowAbort,
3759
- WorkflowNonRetryableError,
3760
3777
  getWorkflowRunId,
3761
3778
  StepTypes,
3762
3779
  triggerFirstInvocation,
package/cloudflare.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as RouteFunction, n as PublicServeOptions, y as InvokableWorkflow } from './types-Q3dM0UlR.mjs';
2
- import { s as serveManyBase } from './serve-many-BNusWYgt.mjs';
1
+ import { R as RouteFunction, o as PublicServeOptions, z as InvokableWorkflow } from './types-9nCq6bRP.mjs';
2
+ import { s as serveManyBase } from './serve-many-CctdYIfB.mjs';
3
3
  import '@upstash/qstash';
4
4
  import 'zod';
5
5
  import 'ai';
package/cloudflare.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as RouteFunction, n as PublicServeOptions, y as InvokableWorkflow } from './types-Q3dM0UlR.js';
2
- import { s as serveManyBase } from './serve-many-CXqQP3RI.js';
1
+ import { R as RouteFunction, o as PublicServeOptions, z as InvokableWorkflow } from './types-9nCq6bRP.js';
2
+ import { s as serveManyBase } from './serve-many-BXDr30rl.js';
3
3
  import '@upstash/qstash';
4
4
  import 'zod';
5
5
  import 'ai';