@upstash/workflow 0.2.15 → 0.2.17

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.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as h3 from 'h3';
2
- import { R as RouteFunction, n as PublicServeOptions, w as InvokableWorkflow } from './types-Dd-3bPoU.mjs';
3
- import { s as serveManyBase } from './serve-many-AFwJPR3S.mjs';
2
+ import { R as RouteFunction, n as PublicServeOptions, x as InvokableWorkflow } from './types--R_3XZXz.mjs';
3
+ import { s as serveManyBase } from './serve-many-DgDSOvQs.mjs';
4
4
  import '@upstash/qstash';
5
5
  import 'zod';
6
6
  import 'ai';
package/h3.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as h3 from 'h3';
2
- import { R as RouteFunction, n as PublicServeOptions, w as InvokableWorkflow } from './types-Dd-3bPoU.js';
3
- import { s as serveManyBase } from './serve-many-AaKSQyi7.js';
2
+ import { R as RouteFunction, n as PublicServeOptions, x as InvokableWorkflow } from './types--R_3XZXz.js';
3
+ import { s as serveManyBase } from './serve-many-B3DfoTFt.js';
4
4
  import '@upstash/qstash';
5
5
  import 'zod';
6
6
  import 'ai';
package/h3.js CHANGED
@@ -403,7 +403,7 @@ 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.15";
406
+ var VERSION = "v0.2.17";
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";
@@ -933,6 +933,7 @@ var triggerFirstInvocation = async (params) => {
933
933
  workflowUrl: workflowContext.url,
934
934
  failureUrl: workflowContext.failureUrl,
935
935
  retries: workflowContext.retries,
936
+ retryDelay: workflowContext.retryDelay,
936
937
  telemetry: telemetry2,
937
938
  flowControl: workflowContext.flowControl,
938
939
  useJSONContent: useJSONContent ?? false
@@ -1062,6 +1063,7 @@ var handleThirdPartyCallResult = async ({
1062
1063
  workflowUrl,
1063
1064
  failureUrl,
1064
1065
  retries,
1066
+ retryDelay,
1065
1067
  telemetry: telemetry2,
1066
1068
  flowControl,
1067
1069
  debug
@@ -1132,6 +1134,7 @@ ${atob(callbackMessage.body ?? "")}`
1132
1134
  workflowUrl,
1133
1135
  failureUrl,
1134
1136
  retries,
1137
+ retryDelay,
1135
1138
  telemetry: telemetry2,
1136
1139
  flowControl
1137
1140
  },
@@ -1282,7 +1285,8 @@ var BaseLazyStep = class _BaseLazyStep {
1282
1285
  workflowRunId: context.workflowRunId,
1283
1286
  workflowUrl: context.url,
1284
1287
  failureUrl: context.failureUrl,
1285
- retries: context.retries,
1288
+ retries: DEFAULT_RETRIES === context.retries ? void 0 : context.retries,
1289
+ retryDelay: context.retryDelay,
1286
1290
  useJSONContent: false,
1287
1291
  telemetry: telemetry2,
1288
1292
  flowControl: context.flowControl
@@ -1301,6 +1305,9 @@ var BaseLazyStep = class _BaseLazyStep {
1301
1305
  body,
1302
1306
  headers,
1303
1307
  method: "POST",
1308
+ retries: DEFAULT_RETRIES === context.retries ? void 0 : context.retries,
1309
+ retryDelay: context.retryDelay,
1310
+ flowControl: context.flowControl,
1304
1311
  url: context.url
1305
1312
  }
1306
1313
  ]);
@@ -1371,6 +1378,9 @@ var LazySleepStep = class extends BaseLazyStep {
1371
1378
  headers,
1372
1379
  method: "POST",
1373
1380
  url: context.url,
1381
+ retries: DEFAULT_RETRIES === context.retries ? void 0 : context.retries,
1382
+ retryDelay: context.retryDelay,
1383
+ flowControl: context.flowControl,
1374
1384
  delay: isParallel ? void 0 : this.sleep
1375
1385
  }
1376
1386
  ]);
@@ -1413,6 +1423,9 @@ var LazySleepUntilStep = class extends BaseLazyStep {
1413
1423
  headers,
1414
1424
  method: "POST",
1415
1425
  url: context.url,
1426
+ retries: DEFAULT_RETRIES === context.retries ? void 0 : context.retries,
1427
+ retryDelay: context.retryDelay,
1428
+ flowControl: context.flowControl,
1416
1429
  notBefore: isParallel ? void 0 : this.sleepUntil
1417
1430
  }
1418
1431
  ]);
@@ -1424,17 +1437,19 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
1424
1437
  body;
1425
1438
  headers;
1426
1439
  retries;
1440
+ retryDelay;
1427
1441
  timeout;
1428
1442
  flowControl;
1429
1443
  stepType = "Call";
1430
1444
  allowUndefinedOut = false;
1431
- constructor(stepName, url, method, body, headers, retries, timeout, flowControl) {
1445
+ constructor(stepName, url, method, body, headers, retries, retryDelay, timeout, flowControl) {
1432
1446
  super(stepName);
1433
1447
  this.url = url;
1434
1448
  this.method = method;
1435
1449
  this.body = body;
1436
1450
  this.headers = headers;
1437
1451
  this.retries = retries;
1452
+ this.retryDelay = retryDelay;
1438
1453
  this.timeout = timeout;
1439
1454
  this.flowControl = flowControl;
1440
1455
  }
@@ -1509,6 +1524,9 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
1509
1524
  getHeaders({ context, telemetry: telemetry2, invokeCount, step }) {
1510
1525
  const { headers, contentType } = super.getHeaders({ context, telemetry: telemetry2, invokeCount, step });
1511
1526
  headers["Upstash-Retries"] = this.retries.toString();
1527
+ if (this.retryDelay) {
1528
+ headers["Upstash-Retry-Delay"] = this.retryDelay;
1529
+ }
1512
1530
  headers[WORKFLOW_FEATURE_HEADER] = "WF_NoDelete,InitialBody";
1513
1531
  if (this.flowControl) {
1514
1532
  const { flowControlKey, flowControlValue } = prepareFlowControl(this.flowControl);
@@ -1530,7 +1548,7 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
1530
1548
  "Upstash-Callback-Workflow-CallType": "fromCallback",
1531
1549
  "Upstash-Callback-Workflow-Init": "false",
1532
1550
  "Upstash-Callback-Workflow-Url": context.url,
1533
- "Upstash-Callback-Feature-Set": "LazyFetch,InitialBody",
1551
+ "Upstash-Callback-Feature-Set": "LazyFetch,InitialBody,WF_DetectTrigger",
1534
1552
  "Upstash-Callback-Forward-Upstash-Workflow-Callback": "true",
1535
1553
  "Upstash-Callback-Forward-Upstash-Workflow-StepId": step.stepId.toString(),
1536
1554
  "Upstash-Callback-Forward-Upstash-Workflow-StepName": this.stepName,
@@ -1548,7 +1566,10 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
1548
1566
  headers,
1549
1567
  body: JSON.stringify(this.body),
1550
1568
  method: this.method,
1551
- url: this.url
1569
+ url: this.url,
1570
+ retries: DEFAULT_RETRIES === this.retries ? void 0 : this.retries,
1571
+ retryDelay: this.retryDelay,
1572
+ flowControl: this.flowControl
1552
1573
  }
1553
1574
  ]);
1554
1575
  }
@@ -1677,6 +1698,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
1677
1698
  headers = {},
1678
1699
  workflowRunId,
1679
1700
  retries,
1701
+ retryDelay,
1680
1702
  flowControl
1681
1703
  }) {
1682
1704
  super(stepName);
@@ -1686,6 +1708,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
1686
1708
  headers,
1687
1709
  workflowRunId: getWorkflowRunId(workflowRunId),
1688
1710
  retries,
1711
+ retryDelay,
1689
1712
  flowControl
1690
1713
  };
1691
1714
  const { workflowId } = workflow;
@@ -1730,6 +1753,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
1730
1753
  workflowUrl: context.url,
1731
1754
  failureUrl: context.failureUrl,
1732
1755
  retries: context.retries,
1756
+ retryDelay: context.retryDelay,
1733
1757
  telemetry: telemetry2,
1734
1758
  flowControl: context.flowControl,
1735
1759
  useJSONContent: false
@@ -1755,11 +1779,13 @@ var LazyInvokeStep = class extends BaseLazyStep {
1755
1779
  headers = {},
1756
1780
  workflowRunId = getWorkflowRunId(),
1757
1781
  retries,
1782
+ retryDelay,
1758
1783
  flowControl
1759
1784
  } = this.params;
1760
1785
  const newUrl = context.url.replace(/[^/]+$/, this.workflowId);
1761
1786
  const {
1762
1787
  retries: workflowRetries,
1788
+ retryDelay: workflowRetryDelay,
1763
1789
  failureFunction,
1764
1790
  failureUrl,
1765
1791
  useJSONContent,
@@ -1771,6 +1797,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
1771
1797
  workflowRunId,
1772
1798
  workflowUrl: newUrl,
1773
1799
  retries: retries ?? workflowRetries,
1800
+ retryDelay: retryDelay ?? workflowRetryDelay,
1774
1801
  telemetry: telemetry2,
1775
1802
  failureUrl: failureFunction ? newUrl : failureUrl,
1776
1803
  flowControl: flowControl ?? workflowFlowControl,
@@ -1837,6 +1864,7 @@ var WorkflowHeaders = class {
1837
1864
  getHeaders() {
1838
1865
  this.addBaseHeaders();
1839
1866
  this.addRetries();
1867
+ this.addRetryDelay();
1840
1868
  this.addFlowControl();
1841
1869
  this.addUserHeaders();
1842
1870
  this.addInvokeCount();
@@ -1850,7 +1878,7 @@ var WorkflowHeaders = class {
1850
1878
  [WORKFLOW_INIT_HEADER]: this.initHeaderValue,
1851
1879
  [WORKFLOW_ID_HEADER]: this.workflowConfig.workflowRunId,
1852
1880
  [WORKFLOW_URL_HEADER]: this.workflowConfig.workflowUrl,
1853
- [WORKFLOW_FEATURE_HEADER]: "LazyFetch,InitialBody",
1881
+ [WORKFLOW_FEATURE_HEADER]: "LazyFetch,InitialBody,WF_DetectTrigger",
1854
1882
  [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION,
1855
1883
  ...this.workflowConfig.telemetry ? getTelemetryHeaders(this.workflowConfig.telemetry) : {},
1856
1884
  ...this.workflowConfig.telemetry && this.stepInfo?.lazyStep instanceof LazyCallStep && this.stepInfo.lazyStep.headers[AGENT_NAME_HEADER] ? { [TELEMETRY_HEADER_AGENT]: "true" } : {}
@@ -1882,6 +1910,16 @@ var WorkflowHeaders = class {
1882
1910
  this.headers.failureHeaders["Retries"] = retries;
1883
1911
  }
1884
1912
  }
1913
+ addRetryDelay() {
1914
+ if (this.workflowConfig.retryDelay === void 0 || this.workflowConfig.retryDelay === "") {
1915
+ return;
1916
+ }
1917
+ const retryDelay = this.workflowConfig.retryDelay.toString();
1918
+ this.headers.workflowHeaders["Retry-Delay"] = retryDelay;
1919
+ if (this.workflowConfig.failureUrl) {
1920
+ this.headers.failureHeaders["Retry-Delay"] = retryDelay;
1921
+ }
1922
+ }
1885
1923
  addFlowControl() {
1886
1924
  if (!this.workflowConfig.flowControl) {
1887
1925
  return;
@@ -1916,10 +1954,13 @@ var WorkflowHeaders = class {
1916
1954
  this.headers.failureHeaders["Workflow-Init"] = "false";
1917
1955
  this.headers.failureHeaders["Workflow-Url"] = this.workflowConfig.workflowUrl;
1918
1956
  this.headers.failureHeaders["Workflow-Calltype"] = "failureCall";
1919
- this.headers.failureHeaders["Feature-Set"] = "LazyFetch,InitialBody";
1957
+ this.headers.failureHeaders["Feature-Set"] = "LazyFetch,InitialBody,WF_DetectTrigger";
1920
1958
  if (this.workflowConfig.retries !== void 0 && this.workflowConfig.retries !== DEFAULT_RETRIES) {
1921
1959
  this.headers.failureHeaders["Retries"] = this.workflowConfig.retries.toString();
1922
1960
  }
1961
+ if (this.workflowConfig.retryDelay !== void 0 && this.workflowConfig.retryDelay !== "") {
1962
+ this.headers.failureHeaders["Retry-Delay"] = this.workflowConfig.retryDelay.toString();
1963
+ }
1923
1964
  }
1924
1965
  addContentType() {
1925
1966
  if (this.workflowConfig.useJSONContent) {
@@ -2001,6 +2042,7 @@ var submitParallelSteps = async ({
2001
2042
  workflowUrl: context.url,
2002
2043
  failureUrl: context.failureUrl,
2003
2044
  retries: context.retries,
2045
+ retryDelay: context.retryDelay,
2004
2046
  flowControl: context.flowControl,
2005
2047
  telemetry: telemetry2
2006
2048
  },
@@ -2421,7 +2463,7 @@ var BaseWorkflowApi = class {
2421
2463
  */
2422
2464
  async callApi(stepName, settings) {
2423
2465
  const { url, appendHeaders, method } = getProviderInfo(settings.api);
2424
- const { method: userMethod, body, headers = {}, retries = 0, timeout } = settings;
2466
+ const { method: userMethod, body, headers = {}, retries = 0, retryDelay, timeout } = settings;
2425
2467
  return await this.context.call(stepName, {
2426
2468
  url,
2427
2469
  method: userMethod ?? method,
@@ -2431,6 +2473,7 @@ var BaseWorkflowApi = class {
2431
2473
  ...headers
2432
2474
  },
2433
2475
  retries,
2476
+ retryDelay,
2434
2477
  timeout
2435
2478
  });
2436
2479
  }
@@ -2520,6 +2563,7 @@ var fetchWithContextCall = async (context, agentCallParams, ...params) => {
2520
2563
  body,
2521
2564
  timeout: agentCallParams?.timeout,
2522
2565
  retries: agentCallParams?.retries,
2566
+ retryDelay: agentCallParams?.retryDelay,
2523
2567
  flowControl: agentCallParams?.flowControl
2524
2568
  });
2525
2569
  const responseHeaders = new Headers(
@@ -2848,7 +2892,10 @@ var serveManyBase = ({
2848
2892
  return new Response(
2849
2893
  `Unexpected request in serveMany. workflowId not set. Please update the URL of your request.`,
2850
2894
  {
2851
- status: 404
2895
+ status: 404,
2896
+ headers: {
2897
+ [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
2898
+ }
2852
2899
  }
2853
2900
  );
2854
2901
  }
@@ -2857,7 +2904,10 @@ var serveManyBase = ({
2857
2904
  return new Response(
2858
2905
  `No workflows in serveMany found for '${pickedWorkflowId}'. Please update the URL of your request.`,
2859
2906
  {
2860
- status: 404
2907
+ status: 404,
2908
+ headers: {
2909
+ [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
2910
+ }
2861
2911
  }
2862
2912
  );
2863
2913
  }
@@ -2994,6 +3044,37 @@ var WorkflowContext = class {
2994
3044
  * Number of retries
2995
3045
  */
2996
3046
  retries;
3047
+ /**
3048
+ * Delay between retries.
3049
+ *
3050
+ * By default, the `retryDelay` is exponential backoff.
3051
+ * More details can be found in: https://upstash.com/docs/qstash/features/retry.
3052
+ *
3053
+ * The `retryDelay` option allows you to customize the delay (in milliseconds) between retry attempts when message delivery fails.
3054
+ *
3055
+ * You can use mathematical expressions and the following built-in functions to calculate the delay dynamically.
3056
+ * The special variable `retried` represents the current retry attempt count (starting from 0).
3057
+ *
3058
+ * Supported functions:
3059
+ * - `pow`
3060
+ * - `sqrt`
3061
+ * - `abs`
3062
+ * - `exp`
3063
+ * - `floor`
3064
+ * - `ceil`
3065
+ * - `round`
3066
+ * - `min`
3067
+ * - `max`
3068
+ *
3069
+ * Examples of valid `retryDelay` values:
3070
+ * ```ts
3071
+ * 1000 // 1 second
3072
+ * 1000 * (1 + retried) // 1 second multiplied by the current retry attempt
3073
+ * pow(2, retried) // 2 to the power of the current retry attempt
3074
+ * max(10, pow(2, retried)) // The greater of 10 or 2^retried
3075
+ * ```
3076
+ */
3077
+ retryDelay;
2997
3078
  /**
2998
3079
  * Settings for controlling the number of active requests
2999
3080
  * and number of requests per second with the same key.
@@ -3010,6 +3091,7 @@ var WorkflowContext = class {
3010
3091
  initialPayload,
3011
3092
  env,
3012
3093
  retries,
3094
+ retryDelay,
3013
3095
  telemetry: telemetry2,
3014
3096
  invokeCount,
3015
3097
  flowControl
@@ -3023,6 +3105,7 @@ var WorkflowContext = class {
3023
3105
  this.requestPayload = initialPayload;
3024
3106
  this.env = env ?? {};
3025
3107
  this.retries = retries ?? DEFAULT_RETRIES;
3108
+ this.retryDelay = retryDelay;
3026
3109
  this.flowControl = flowControl;
3027
3110
  this.executor = new AutoExecutor(this, this.steps, telemetry2, invokeCount, debug);
3028
3111
  }
@@ -3104,6 +3187,7 @@ var WorkflowContext = class {
3104
3187
  settings.body,
3105
3188
  settings.headers || {},
3106
3189
  settings.retries || 0,
3190
+ settings.retryDelay,
3107
3191
  settings.timeout,
3108
3192
  settings.flowControl ?? settings.workflow.options.flowControl
3109
3193
  );
@@ -3114,6 +3198,7 @@ var WorkflowContext = class {
3114
3198
  body,
3115
3199
  headers = {},
3116
3200
  retries = 0,
3201
+ retryDelay,
3117
3202
  timeout,
3118
3203
  flowControl
3119
3204
  } = settings;
@@ -3124,6 +3209,7 @@ var WorkflowContext = class {
3124
3209
  body,
3125
3210
  headers,
3126
3211
  retries,
3212
+ retryDelay,
3127
3213
  timeout,
3128
3214
  flowControl
3129
3215
  );
@@ -3134,7 +3220,7 @@ var WorkflowContext = class {
3134
3220
  * Pauses workflow execution until a specific event occurs or a timeout is reached.
3135
3221
  *
3136
3222
  *```ts
3137
- * const result = await workflow.waitForEvent("payment-confirmed", {
3223
+ * const result = await workflow.waitForEvent("payment-confirmed", "payment.confirmed", {
3138
3224
  * timeout: "5m"
3139
3225
  * });
3140
3226
  *```
@@ -3160,7 +3246,7 @@ var WorkflowContext = class {
3160
3246
  * @param stepName
3161
3247
  * @param eventId - Unique identifier for the event to wait for
3162
3248
  * @param options - Configuration options.
3163
- * @returns `{ timeout: boolean, eventData: unknown }`.
3249
+ * @returns `{ timeout: boolean, eventData: TEventData }`.
3164
3250
  * The `timeout` property specifies if the workflow has timed out. The `eventData`
3165
3251
  * is the data passed when notifying this workflow of an event.
3166
3252
  */
@@ -3320,6 +3406,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
3320
3406
  initialPayload: context.requestPayload,
3321
3407
  env: context.env,
3322
3408
  retries: context.retries,
3409
+ retryDelay: context.retryDelay,
3323
3410
  flowControl: context.flowControl
3324
3411
  });
3325
3412
  try {
@@ -3328,6 +3415,9 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
3328
3415
  if (error instanceof WorkflowAbort && error.stepName === this.disabledMessage || error instanceof WorkflowNonRetryableError) {
3329
3416
  return ok("step-found");
3330
3417
  }
3418
+ console.warn(
3419
+ "Upstash Workflow: Received an error while authorizing request. Please avoid throwing errors before the first step of your workflow."
3420
+ );
3331
3421
  return err(error);
3332
3422
  }
3333
3423
  return ok("run-ended");
@@ -3469,9 +3559,9 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
3469
3559
  };
3470
3560
  }
3471
3561
  };
3472
- var handleFailure = async (request, requestPayload, qstashClient, initialPayloadParser, routeFunction, failureFunction, env, retries, flowControl, debug) => {
3562
+ var handleFailure = async (request, requestPayload, qstashClient, initialPayloadParser, routeFunction, failureFunction, env, retries, retryDelay, flowControl, debug) => {
3473
3563
  if (request.headers.get(WORKFLOW_FAILURE_HEADER) !== "true") {
3474
- return ok("not-failure-callback");
3564
+ return ok({ result: "not-failure-callback" });
3475
3565
  }
3476
3566
  if (!failureFunction) {
3477
3567
  return err(
@@ -3483,7 +3573,17 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
3483
3573
  try {
3484
3574
  const { status, header, body, url, sourceBody, workflowRunId } = JSON.parse(requestPayload);
3485
3575
  const decodedBody = body ? decodeBase64(body) : "{}";
3486
- const errorPayload = JSON.parse(decodedBody);
3576
+ let errorMessage = "";
3577
+ try {
3578
+ const errorPayload = JSON.parse(decodedBody);
3579
+ if (errorPayload.message) {
3580
+ errorMessage = errorPayload.message;
3581
+ }
3582
+ } catch {
3583
+ }
3584
+ if (!errorMessage) {
3585
+ errorMessage = `Couldn't parse 'failResponse' in 'failureFunction', received: '${decodedBody}'`;
3586
+ }
3487
3587
  const workflowContext = new WorkflowContext({
3488
3588
  qstashClient,
3489
3589
  workflowRunId,
@@ -3495,6 +3595,7 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
3495
3595
  debug,
3496
3596
  env,
3497
3597
  retries,
3598
+ retryDelay,
3498
3599
  flowControl,
3499
3600
  telemetry: void 0
3500
3601
  // not going to make requests in authentication check
@@ -3509,16 +3610,16 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
3509
3610
  } else if (authCheck.value === "run-ended") {
3510
3611
  return err(new WorkflowError("Not authorized to run the failure function."));
3511
3612
  }
3512
- await failureFunction({
3613
+ const failureResponse = await failureFunction({
3513
3614
  context: workflowContext,
3514
3615
  failStatus: status,
3515
- failResponse: errorPayload.message,
3616
+ failResponse: errorMessage,
3516
3617
  failHeaders: header
3517
3618
  });
3619
+ return ok({ result: "is-failure-callback", response: failureResponse });
3518
3620
  } catch (error) {
3519
3621
  return err(error);
3520
3622
  }
3521
- return ok("is-failure-callback");
3522
3623
  };
3523
3624
 
3524
3625
  // src/serve/options.ts
@@ -3534,8 +3635,8 @@ var processOptions = (options) => {
3534
3635
  baseUrl: environment.QSTASH_URL,
3535
3636
  token: environment.QSTASH_TOKEN
3536
3637
  }),
3537
- onStepFinish: (workflowRunId, finishCondition) => {
3538
- if (finishCondition === "auth-fail") {
3638
+ onStepFinish: (workflowRunId, _finishCondition, detailedFinishCondition) => {
3639
+ if (detailedFinishCondition?.condition === "auth-fail") {
3539
3640
  console.error(AUTH_FAIL_MESSAGE);
3540
3641
  return new Response(
3541
3642
  JSON.stringify({
@@ -3543,19 +3644,33 @@ var processOptions = (options) => {
3543
3644
  workflowRunId
3544
3645
  }),
3545
3646
  {
3546
- status: 400
3647
+ status: 400,
3648
+ headers: {
3649
+ [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
3650
+ }
3547
3651
  }
3548
3652
  );
3549
- } else if (finishCondition instanceof WorkflowNonRetryableError) {
3550
- return new Response(JSON.stringify(formatWorkflowError(finishCondition)), {
3653
+ } else if (detailedFinishCondition?.condition === "non-retryable-error") {
3654
+ return new Response(JSON.stringify(formatWorkflowError(detailedFinishCondition.result)), {
3551
3655
  headers: {
3552
- "Upstash-NonRetryable-Error": "true"
3656
+ "Upstash-NonRetryable-Error": "true",
3657
+ [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
3553
3658
  },
3554
3659
  status: 489
3555
3660
  });
3661
+ } else if (detailedFinishCondition?.condition === "failure-callback") {
3662
+ return new Response(detailedFinishCondition.result ?? void 0, {
3663
+ status: 200,
3664
+ headers: {
3665
+ [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
3666
+ }
3667
+ });
3556
3668
  }
3557
3669
  return new Response(JSON.stringify({ workflowRunId }), {
3558
- status: 200
3670
+ status: 200,
3671
+ headers: {
3672
+ [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
3673
+ }
3559
3674
  });
3560
3675
  },
3561
3676
  initialPayloadParser: (initialRequest) => {
@@ -3629,6 +3744,7 @@ var serveBase = (routeFunction, telemetry2, options) => {
3629
3744
  baseUrl,
3630
3745
  env,
3631
3746
  retries,
3747
+ retryDelay,
3632
3748
  useJSONContent,
3633
3749
  disableTelemetry,
3634
3750
  flowControl,
@@ -3659,10 +3775,14 @@ var serveBase = (routeFunction, telemetry2, options) => {
3659
3775
  debug
3660
3776
  );
3661
3777
  if (workflowRunEnded) {
3662
- return onStepFinish(workflowRunId, "workflow-already-ended");
3778
+ return onStepFinish(workflowRunId, "workflow-already-ended", {
3779
+ condition: "workflow-already-ended"
3780
+ });
3663
3781
  }
3664
3782
  if (isLastDuplicate) {
3665
- return onStepFinish(workflowRunId, "duplicate-step");
3783
+ return onStepFinish(workflowRunId, "duplicate-step", {
3784
+ condition: "duplicate-step"
3785
+ });
3666
3786
  }
3667
3787
  const failureCheck = await handleFailure(
3668
3788
  request,
@@ -3673,14 +3793,18 @@ var serveBase = (routeFunction, telemetry2, options) => {
3673
3793
  failureFunction,
3674
3794
  env,
3675
3795
  retries,
3796
+ retryDelay,
3676
3797
  flowControl,
3677
3798
  debug
3678
3799
  );
3679
3800
  if (failureCheck.isErr()) {
3680
3801
  throw failureCheck.error;
3681
- } else if (failureCheck.value === "is-failure-callback") {
3802
+ } else if (failureCheck.value.result === "is-failure-callback") {
3682
3803
  await debug?.log("WARN", "RESPONSE_DEFAULT", "failureFunction executed");
3683
- return onStepFinish(workflowRunId, "failure-callback");
3804
+ return onStepFinish(workflowRunId, "failure-callback", {
3805
+ condition: "failure-callback",
3806
+ result: failureCheck.value.response
3807
+ });
3684
3808
  }
3685
3809
  const invokeCount = Number(request.headers.get(WORKFLOW_INVOKE_COUNT_HEADER) ?? "0");
3686
3810
  const workflowContext = new WorkflowContext({
@@ -3694,6 +3818,7 @@ var serveBase = (routeFunction, telemetry2, options) => {
3694
3818
  debug,
3695
3819
  env,
3696
3820
  retries,
3821
+ retryDelay,
3697
3822
  telemetry: telemetry2,
3698
3823
  invokeCount,
3699
3824
  flowControl
@@ -3709,7 +3834,8 @@ var serveBase = (routeFunction, telemetry2, options) => {
3709
3834
  await debug?.log("ERROR", "ERROR", { error: AUTH_FAIL_MESSAGE });
3710
3835
  return onStepFinish(
3711
3836
  isFirstInvocation ? "no-workflow-id" : workflowContext.workflowRunId,
3712
- "auth-fail"
3837
+ "auth-fail",
3838
+ { condition: "auth-fail" }
3713
3839
  );
3714
3840
  }
3715
3841
  const callReturnCheck = await handleThirdPartyCallResult({
@@ -3719,6 +3845,7 @@ var serveBase = (routeFunction, telemetry2, options) => {
3719
3845
  workflowUrl,
3720
3846
  failureUrl: workflowFailureUrl,
3721
3847
  retries,
3848
+ retryDelay,
3722
3849
  flowControl,
3723
3850
  telemetry: telemetry2,
3724
3851
  debug
@@ -3746,19 +3873,28 @@ var serveBase = (routeFunction, telemetry2, options) => {
3746
3873
  debug
3747
3874
  });
3748
3875
  if (result.isOk() && result.value instanceof WorkflowNonRetryableError) {
3749
- return onStepFinish(workflowRunId, result.value);
3876
+ return onStepFinish(workflowRunId, result.value, {
3877
+ condition: "non-retryable-error",
3878
+ result: result.value
3879
+ });
3750
3880
  }
3751
3881
  if (result.isErr()) {
3752
3882
  await debug?.log("ERROR", "ERROR", { error: result.error.message });
3753
3883
  throw result.error;
3754
3884
  }
3755
3885
  await debug?.log("INFO", "RESPONSE_WORKFLOW");
3756
- return onStepFinish(workflowContext.workflowRunId, "success");
3886
+ return onStepFinish(workflowContext.workflowRunId, "success", {
3887
+ condition: "success"
3888
+ });
3757
3889
  } else if (callReturnCheck.value === "workflow-ended") {
3758
- return onStepFinish(workflowContext.workflowRunId, "workflow-already-ended");
3890
+ return onStepFinish(workflowContext.workflowRunId, "workflow-already-ended", {
3891
+ condition: "workflow-already-ended"
3892
+ });
3759
3893
  }
3760
3894
  await debug?.log("INFO", "RESPONSE_DEFAULT");
3761
- return onStepFinish("no-workflow-id", "fromCallback");
3895
+ return onStepFinish("no-workflow-id", "fromCallback", {
3896
+ condition: "fromCallback"
3897
+ });
3762
3898
  };
3763
3899
  const safeHandler = async (request) => {
3764
3900
  try {
@@ -3773,11 +3909,17 @@ var serveBase = (routeFunction, telemetry2, options) => {
3773
3909
  Original error: '${formattedError.message}'`;
3774
3910
  console.error(errorMessage);
3775
3911
  return new Response(errorMessage, {
3776
- status: 500
3912
+ status: 500,
3913
+ headers: {
3914
+ [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
3915
+ }
3777
3916
  });
3778
3917
  }
3779
3918
  return new Response(JSON.stringify(formattedError), {
3780
- status: 500
3919
+ status: 500,
3920
+ headers: {
3921
+ [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
3922
+ }
3781
3923
  });
3782
3924
  }
3783
3925
  };
package/h3.mjs CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  SDK_TELEMETRY,
3
3
  serveBase,
4
4
  serveManyBase
5
- } from "./chunk-AC5CQCN3.mjs";
5
+ } from "./chunk-RP7G4UD5.mjs";
6
6
 
7
7
  // node_modules/defu/dist/defu.mjs
8
8
  function isPlainObject(value) {
package/hono.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Context } from 'hono';
2
- import { R as RouteFunction, n as PublicServeOptions, w as InvokableWorkflow } from './types-Dd-3bPoU.mjs';
2
+ import { R as RouteFunction, n as PublicServeOptions, x as InvokableWorkflow } from './types--R_3XZXz.mjs';
3
3
  import { Variables } from 'hono/types';
4
- import { s as serveManyBase } from './serve-many-AFwJPR3S.mjs';
4
+ import { s as serveManyBase } from './serve-many-DgDSOvQs.mjs';
5
5
  import '@upstash/qstash';
6
6
  import 'zod';
7
7
  import 'ai';
package/hono.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Context } from 'hono';
2
- import { R as RouteFunction, n as PublicServeOptions, w as InvokableWorkflow } from './types-Dd-3bPoU.js';
2
+ import { R as RouteFunction, n as PublicServeOptions, x as InvokableWorkflow } from './types--R_3XZXz.js';
3
3
  import { Variables } from 'hono/types';
4
- import { s as serveManyBase } from './serve-many-AaKSQyi7.js';
4
+ import { s as serveManyBase } from './serve-many-B3DfoTFt.js';
5
5
  import '@upstash/qstash';
6
6
  import 'zod';
7
7
  import 'ai';