@upstash/workflow 0.2.10 → 0.2.12

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/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as RouteFunction, W as WorkflowServeOptions, E as ExclusiveValidationOptions, T as Telemetry, S as StepType, a as RawStep, N as NotifyResponse, b as Waiter, c as Step } from './types-CYhDXnf8.js';
2
- export { A as AsyncStepFunction, C as CallResponse, r as CallSettings, D as Duration, l as FailureFunctionPayload, F as FinishCondition, H as HeaderParams, t as InvokableWorkflow, s as InvokeStepResponse, I as InvokeWorkflowRequest, L as LazyInvokeStepParams, u as LogLevel, p as NotifyStepResponse, P as ParallelCallState, k as PublicServeOptions, m as RequiredExceptFields, j as StepFunction, h as StepTypes, i as SyncStepFunction, q as WaitEventOptions, n as WaitRequest, o as WaitStepResponse, f as WorkflowClient, e as WorkflowContext, w as WorkflowLogger, v as WorkflowLoggerOptions, g as WorkflowReceiver, d as WorkflowTool } from './types-CYhDXnf8.js';
1
+ import { R as RouteFunction, W as WorkflowServeOptions, E as ExclusiveValidationOptions, T as Telemetry, S as StepType, a as RawStep, N as NotifyResponse, b as Waiter, c as Step } from './types-D1W0VOpy.js';
2
+ export { A as AsyncStepFunction, C as CallResponse, r as CallSettings, D as Duration, l as FailureFunctionPayload, F as FinishCondition, H as HeaderParams, t as InvokableWorkflow, s as InvokeStepResponse, I as InvokeWorkflowRequest, L as LazyInvokeStepParams, u as LogLevel, p as NotifyStepResponse, P as ParallelCallState, k as PublicServeOptions, m as RequiredExceptFields, j as StepFunction, h as StepTypes, i as SyncStepFunction, q as WaitEventOptions, n as WaitRequest, o as WaitStepResponse, f as WorkflowClient, e as WorkflowContext, w as WorkflowLogger, v as WorkflowLoggerOptions, g as WorkflowReceiver, d as WorkflowTool } from './types-D1W0VOpy.js';
3
3
  import { HTTPMethods, State, FlowControl, Client as Client$1, QstashError } from '@upstash/qstash';
4
4
  import 'zod';
5
5
  import 'ai';
@@ -154,7 +154,11 @@ type WaitEventGroup = {
154
154
  type AsOptional<TType> = TType | {
155
155
  [P in keyof TType]?: never;
156
156
  };
157
- type StepLog = BaseStepLog & AsOptional<CallUrlGroup> & AsOptional<CallResponseStatusGroup> & AsOptional<InvokedWorkflowGroup> & AsOptional<WaitEventGroup>;
157
+ type StepLog = BaseStepLog & AsOptional<CallUrlGroup> & AsOptional<CallResponseStatusGroup> & AsOptional<InvokedWorkflowGroup> & AsOptional<{
158
+ sleepFor: number;
159
+ }> & AsOptional<{
160
+ sleepUntil: number;
161
+ }> & AsOptional<WaitEventGroup>;
158
162
  type StepLogGroup = {
159
163
  /**
160
164
  * Log which belongs to a single step
@@ -179,7 +183,7 @@ type StepLogGroup = {
179
183
  */
180
184
  steps: {
181
185
  messageId: string;
182
- state: "STEP_PROGRESS" | "STEP_RETRY" | "STEP_FAILED";
186
+ state: "STEP_PROGRESS" | "STEP_RETRY" | "STEP_FAILED" | "STEP_CANCELED";
183
187
  }[];
184
188
  /**
185
189
  * Log which belongs to the next step
@@ -251,6 +255,32 @@ type WorkflowRunLog = {
251
255
  *
252
256
  */
253
257
  steps: StepLogGroup[];
258
+ /**
259
+ * If the workflow returned a response, the stringified state of this
260
+ * response will be available in the workflowRunResponse field.
261
+ *
262
+ * To restore it to its original format, use JSON.parse.
263
+ */
264
+ workflowRunResponse?: string;
265
+ /**
266
+ * Information on the invoker workflow run, if any
267
+ */
268
+ invoker?: {
269
+ /**
270
+ * run id of the invoker workflow
271
+ */
272
+ workflowRunId: string;
273
+ /**
274
+ * URL of the invoker workflow
275
+ */
276
+ workflowUrl: string;
277
+ /**
278
+ * Time when the invoker workflow run was created
279
+ *
280
+ * in unix milliseconds format
281
+ */
282
+ workflowRunCreatedAt: number;
283
+ };
254
284
  };
255
285
  type WorkflowRunLogs = {
256
286
  cursor: string;
package/index.js CHANGED
@@ -146,7 +146,7 @@ var formatWorkflowError = (error) => {
146
146
  message: error.message
147
147
  } : {
148
148
  error: "Error",
149
- message: "An error occured while executing workflow."
149
+ message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
150
150
  };
151
151
  };
152
152
 
@@ -163,22 +163,21 @@ function getWorkflowRunId(id) {
163
163
  return `wfr_${id ?? nanoid()}`;
164
164
  }
165
165
  function decodeBase64(base64) {
166
+ const binString = atob(base64);
166
167
  try {
167
- const binString = atob(base64);
168
168
  const intArray = Uint8Array.from(binString, (m) => m.codePointAt(0));
169
169
  return new TextDecoder().decode(intArray);
170
170
  } catch (error) {
171
171
  console.warn(
172
172
  `Upstash Qstash: Failed while decoding base64 "${base64}". Decoding with atob and returning it instead. ${error}`
173
173
  );
174
- return atob(base64);
174
+ return binString;
175
175
  }
176
176
  }
177
177
 
178
178
  // src/context/steps.ts
179
- var BaseLazyStep = class {
179
+ var BaseLazyStep = class _BaseLazyStep {
180
180
  stepName;
181
- // will be set in the subclasses
182
181
  constructor(stepName) {
183
182
  if (!stepName) {
184
183
  throw new WorkflowError(
@@ -187,10 +186,58 @@ var BaseLazyStep = class {
187
186
  }
188
187
  this.stepName = stepName;
189
188
  }
189
+ /**
190
+ * parse the out field of a step result.
191
+ *
192
+ * will be called when returning the steps to the context from auto executor
193
+ *
194
+ * @param out field of the step
195
+ * @returns parsed out field
196
+ */
197
+ parseOut(out) {
198
+ if (out === void 0) {
199
+ if (this.allowUndefinedOut) {
200
+ return void 0;
201
+ } else {
202
+ throw new WorkflowError(
203
+ `Error while parsing output of ${this.stepType} step. Expected a string, but got: undefined`
204
+ );
205
+ }
206
+ }
207
+ if (typeof out === "object") {
208
+ if (this.stepType !== "Wait") {
209
+ console.warn(
210
+ `Error while parsing ${this.stepType} step output. Expected a string, but got object. Please reach out to Upstash Support.`
211
+ );
212
+ return out;
213
+ }
214
+ return {
215
+ ...out,
216
+ eventData: _BaseLazyStep.tryParsing(out.eventData)
217
+ };
218
+ }
219
+ if (typeof out !== "string") {
220
+ throw new WorkflowError(
221
+ `Error while parsing output of ${this.stepType} step. Expected a string or undefined, but got: ${typeof out}`
222
+ );
223
+ }
224
+ return this.safeParseOut(out);
225
+ }
226
+ safeParseOut(out) {
227
+ return _BaseLazyStep.tryParsing(out);
228
+ }
229
+ static tryParsing(stepOut) {
230
+ try {
231
+ return JSON.parse(stepOut);
232
+ } catch {
233
+ return stepOut;
234
+ }
235
+ }
190
236
  };
191
237
  var LazyFunctionStep = class extends BaseLazyStep {
192
238
  stepFunction;
193
239
  stepType = "Run";
240
+ allowUndefinedOut = true;
194
241
  constructor(stepName, stepFunction) {
195
242
  super(stepName);
196
243
  this.stepFunction = stepFunction;
@@ -221,6 +268,7 @@ var LazyFunctionStep = class extends BaseLazyStep {
221
268
  var LazySleepStep = class extends BaseLazyStep {
222
269
  sleep;
223
270
  stepType = "SleepFor";
271
+ allowUndefinedOut = true;
224
272
  constructor(stepName, sleep) {
225
273
  super(stepName);
226
274
  this.sleep = sleep;
@@ -248,6 +296,7 @@ var LazySleepStep = class extends BaseLazyStep {
248
296
  var LazySleepUntilStep = class extends BaseLazyStep {
249
297
  sleepUntil;
250
298
  stepType = "SleepUntil";
299
+ allowUndefinedOut = true;
251
300
  constructor(stepName, sleepUntil) {
252
301
  super(stepName);
253
302
  this.sleepUntil = sleepUntil;
@@ -271,8 +320,11 @@ var LazySleepUntilStep = class extends BaseLazyStep {
271
320
  concurrent
272
321
  });
273
322
  }
323
+ safeParseOut() {
324
+ return void 0;
325
+ }
274
326
  };
275
- var LazyCallStep = class extends BaseLazyStep {
327
+ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
276
328
  url;
277
329
  method;
278
330
  body;
@@ -281,6 +333,7 @@ var LazyCallStep = class extends BaseLazyStep {
281
333
  timeout;
282
334
  flowControl;
283
335
  stepType = "Call";
336
+ allowUndefinedOut = false;
284
337
  constructor(stepName, url, method, body, headers, retries, timeout, flowControl) {
285
338
  super(stepName);
286
339
  this.url = url;
@@ -312,11 +365,53 @@ var LazyCallStep = class extends BaseLazyStep {
312
365
  callHeaders: this.headers
313
366
  });
314
367
  }
368
+ safeParseOut(out) {
369
+ const { header, status, body } = JSON.parse(out);
370
+ const responseHeaders = new Headers(header);
371
+ if (_LazyCallStep.isText(responseHeaders.get("content-type"))) {
372
+ const bytes = new Uint8Array(out.length);
373
+ for (let i = 0; i < out.length; i++) {
374
+ bytes[i] = out.charCodeAt(i);
375
+ }
376
+ const processedResult = new TextDecoder().decode(bytes);
377
+ const newBody = JSON.parse(processedResult).body;
378
+ return {
379
+ status,
380
+ header,
381
+ body: BaseLazyStep.tryParsing(newBody)
382
+ };
383
+ } else {
384
+ return { header, status, body };
385
+ }
386
+ }
387
+ static applicationHeaders = /* @__PURE__ */ new Set([
388
+ "application/json",
389
+ "application/xml",
390
+ "application/javascript",
391
+ "application/x-www-form-urlencoded",
392
+ "application/xhtml+xml",
393
+ "application/ld+json",
394
+ "application/rss+xml",
395
+ "application/atom+xml"
396
+ ]);
397
+ static isText = (contentTypeHeader) => {
398
+ if (!contentTypeHeader) {
399
+ return false;
400
+ }
401
+ if (_LazyCallStep.applicationHeaders.has(contentTypeHeader)) {
402
+ return true;
403
+ }
404
+ if (contentTypeHeader.startsWith("text/")) {
405
+ return true;
406
+ }
407
+ return false;
408
+ };
315
409
  };
316
410
  var LazyWaitForEventStep = class extends BaseLazyStep {
317
411
  eventId;
318
412
  timeout;
319
413
  stepType = "Wait";
414
+ allowUndefinedOut = false;
320
415
  constructor(stepName, eventId, timeout) {
321
416
  super(stepName);
322
417
  this.eventId = eventId;
@@ -343,6 +438,13 @@ var LazyWaitForEventStep = class extends BaseLazyStep {
343
438
  concurrent
344
439
  });
345
440
  }
441
+ safeParseOut(out) {
442
+ const result = JSON.parse(out);
443
+ return {
444
+ ...result,
445
+ eventData: BaseLazyStep.tryParsing(result.eventData)
446
+ };
447
+ }
346
448
  };
347
449
  var LazyNotifyStep = class extends LazyFunctionStep {
348
450
  stepType = "Notify";
@@ -356,10 +458,18 @@ var LazyNotifyStep = class extends LazyFunctionStep {
356
458
  };
357
459
  });
358
460
  }
461
+ safeParseOut(out) {
462
+ const result = JSON.parse(out);
463
+ return {
464
+ ...result,
465
+ eventData: BaseLazyStep.tryParsing(result.eventData)
466
+ };
467
+ }
359
468
  };
360
469
  var LazyInvokeStep = class extends BaseLazyStep {
361
470
  stepType = "Invoke";
362
471
  params;
472
+ allowUndefinedOut = false;
363
473
  constructor(stepName, {
364
474
  workflow,
365
475
  body,
@@ -399,6 +509,13 @@ var LazyInvokeStep = class extends BaseLazyStep {
399
509
  concurrent
400
510
  });
401
511
  }
512
+ safeParseOut(out) {
513
+ const result = JSON.parse(out);
514
+ return {
515
+ ...result,
516
+ body: BaseLazyStep.tryParsing(result.body)
517
+ };
518
+ }
402
519
  };
403
520
 
404
521
  // node_modules/neverthrow/dist/index.es.js
@@ -1084,7 +1201,8 @@ var getHeaders = ({
1084
1201
  flowControl,
1085
1202
  callFlowControl
1086
1203
  }) => {
1087
- const contentType = (userHeaders ? userHeaders.get("Content-Type") : void 0) ?? DEFAULT_CONTENT_TYPE;
1204
+ const callHeaders = new Headers(step?.callHeaders);
1205
+ const contentType = (callHeaders.get("content-type") ? callHeaders.get("content-type") : userHeaders?.get("Content-Type") ? userHeaders.get("Content-Type") : void 0) ?? DEFAULT_CONTENT_TYPE;
1088
1206
  const baseHeaders = {
1089
1207
  [WORKFLOW_INIT_HEADER]: initHeaderValue,
1090
1208
  [WORKFLOW_ID_HEADER]: workflowRunId,
@@ -1434,7 +1552,7 @@ var AutoExecutor = class _AutoExecutor {
1434
1552
  step,
1435
1553
  stepCount: this.stepCount
1436
1554
  });
1437
- return step.out;
1555
+ return lazyStep.parseOut(step.out);
1438
1556
  }
1439
1557
  const resultStep = await lazyStep.getResultStep(NO_CONCURRENCY, this.stepCount);
1440
1558
  await this.debug?.log("INFO", "RUN_SINGLE", {
@@ -1509,7 +1627,9 @@ var AutoExecutor = class _AutoExecutor {
1509
1627
  case "last": {
1510
1628
  const parallelResultSteps = sortedSteps.filter((step) => step.stepId >= initialStepCount).slice(0, parallelSteps.length);
1511
1629
  validateParallelSteps(parallelSteps, parallelResultSteps);
1512
- return parallelResultSteps.map((step) => step.out);
1630
+ return parallelResultSteps.map(
1631
+ (step, index) => parallelSteps[index].parseOut(step.out)
1632
+ );
1513
1633
  }
1514
1634
  }
1515
1635
  const fillValue = void 0;
@@ -1612,7 +1732,7 @@ var AutoExecutor = class _AutoExecutor {
1612
1732
  });
1613
1733
  throw new WorkflowAbort(invokeStep.stepName, invokeStep);
1614
1734
  }
1615
- const result = await this.context.qstashClient.batchJSON(
1735
+ const result = await this.context.qstashClient.batch(
1616
1736
  steps.map((singleStep, index) => {
1617
1737
  const lazyStep = lazySteps[index];
1618
1738
  const { headers } = getHeaders({
@@ -1642,7 +1762,7 @@ var AutoExecutor = class _AutoExecutor {
1642
1762
  {
1643
1763
  headers,
1644
1764
  method: singleStep.callMethod,
1645
- body: singleStep.callBody,
1765
+ body: JSON.stringify(singleStep.callBody),
1646
1766
  url: singleStep.callUrl
1647
1767
  }
1648
1768
  ) : (
@@ -1652,7 +1772,7 @@ var AutoExecutor = class _AutoExecutor {
1652
1772
  {
1653
1773
  headers,
1654
1774
  method: "POST",
1655
- body: singleStep,
1775
+ body: JSON.stringify(singleStep),
1656
1776
  url: this.context.url,
1657
1777
  notBefore: willWait ? singleStep.sleepUntil : void 0,
1658
1778
  delay: willWait ? singleStep.sleepFor : void 0
@@ -1660,8 +1780,9 @@ var AutoExecutor = class _AutoExecutor {
1660
1780
  );
1661
1781
  })
1662
1782
  );
1783
+ const _result = result;
1663
1784
  await this.debug?.log("INFO", "SUBMIT_STEP", {
1664
- messageIds: result.map((message) => {
1785
+ messageIds: _result.map((message) => {
1665
1786
  return {
1666
1787
  message: message.messageId
1667
1788
  };
@@ -1864,6 +1985,9 @@ var WorkflowApi = class extends BaseWorkflowApi {
1864
1985
  }
1865
1986
  };
1866
1987
 
1988
+ // src/agents/index.ts
1989
+ var import_openai3 = require("@ai-sdk/openai");
1990
+
1867
1991
  // src/agents/adapters.ts
1868
1992
  var import_openai2 = require("@ai-sdk/openai");
1869
1993
  var import_ai = require("ai");
@@ -1883,46 +2007,49 @@ you need from that agent.
1883
2007
  `;
1884
2008
 
1885
2009
  // src/agents/adapters.ts
1886
- var createWorkflowOpenAI = (context, config) => {
1887
- const { baseURL, apiKey } = config ?? {};
1888
- return (0, import_openai2.createOpenAI)({
1889
- baseURL,
1890
- apiKey,
1891
- compatibility: "strict",
1892
- fetch: async (input, init) => {
1893
- try {
1894
- const headers = init?.headers ? Object.fromEntries(new Headers(init.headers).entries()) : {};
1895
- const body = init?.body ? JSON.parse(init.body) : void 0;
1896
- const agentName = headers[AGENT_NAME_HEADER];
1897
- const stepName = agentName ? `Call Agent ${agentName}` : "Call Agent";
1898
- const responseInfo = await context.call(stepName, {
1899
- url: input.toString(),
1900
- method: init?.method,
1901
- headers,
1902
- body
1903
- });
1904
- const responseHeaders = new Headers(
1905
- Object.entries(responseInfo.header).reduce(
1906
- (acc, [key, values]) => {
1907
- acc[key] = values.join(", ");
1908
- return acc;
1909
- },
1910
- {}
1911
- )
1912
- );
1913
- return new Response(JSON.stringify(responseInfo.body), {
1914
- status: responseInfo.status,
1915
- headers: responseHeaders
1916
- });
1917
- } catch (error) {
1918
- if (error instanceof Error && error.name === "WorkflowAbort") {
1919
- throw error;
1920
- } else {
1921
- console.error("Error in fetch implementation:", error);
1922
- throw error;
1923
- }
1924
- }
2010
+ var fetchWithContextCall = async (context, ...params) => {
2011
+ const [input, init] = params;
2012
+ try {
2013
+ const headers = init?.headers ? Object.fromEntries(new Headers(init.headers).entries()) : {};
2014
+ const body = init?.body ? JSON.parse(init.body) : void 0;
2015
+ const agentName = headers[AGENT_NAME_HEADER];
2016
+ const stepName = agentName ? `Call Agent ${agentName}` : "Call Agent";
2017
+ const responseInfo = await context.call(stepName, {
2018
+ url: input.toString(),
2019
+ method: init?.method,
2020
+ headers,
2021
+ body
2022
+ });
2023
+ const responseHeaders = new Headers(
2024
+ Object.entries(responseInfo.header).reduce(
2025
+ (acc, [key, values]) => {
2026
+ acc[key] = values.join(", ");
2027
+ return acc;
2028
+ },
2029
+ {}
2030
+ )
2031
+ );
2032
+ return new Response(JSON.stringify(responseInfo.body), {
2033
+ status: responseInfo.status,
2034
+ headers: responseHeaders
2035
+ });
2036
+ } catch (error) {
2037
+ if (error instanceof Error && error.name === "WorkflowAbort") {
2038
+ throw error;
2039
+ } else {
2040
+ console.error("Error in fetch implementation:", error);
2041
+ throw error;
1925
2042
  }
2043
+ }
2044
+ };
2045
+ var createWorkflowModel = ({
2046
+ context,
2047
+ provider,
2048
+ providerParams
2049
+ }) => {
2050
+ return provider({
2051
+ fetch: (...params) => fetchWithContextCall(context, ...params),
2052
+ ...providerParams
1926
2053
  });
1927
2054
  };
1928
2055
  var wrapTools = ({
@@ -2193,9 +2320,14 @@ var WorkflowAgents = class {
2193
2320
  openai(...params) {
2194
2321
  const [model, settings] = params;
2195
2322
  const { baseURL, apiKey, ...otherSettings } = settings ?? {};
2196
- const openai2 = createWorkflowOpenAI(this.context, { baseURL, apiKey });
2197
- return openai2(model, otherSettings);
2323
+ const openaiModel = this.AISDKModel({
2324
+ context: this.context,
2325
+ provider: import_openai3.createOpenAI,
2326
+ providerParams: { baseURL, apiKey, compatibility: "strict" }
2327
+ });
2328
+ return openaiModel(model, otherSettings);
2198
2329
  }
2330
+ AISDKModel = createWorkflowModel;
2199
2331
  };
2200
2332
 
2201
2333
  // src/context/context.ts
@@ -2381,7 +2513,7 @@ var WorkflowContext = class {
2381
2513
  */
2382
2514
  async run(stepName, stepFunction) {
2383
2515
  const wrappedStepFunction = () => this.executor.wrapStep(stepName, stepFunction);
2384
- return this.addStep(new LazyFunctionStep(stepName, wrappedStepFunction));
2516
+ return await this.addStep(new LazyFunctionStep(stepName, wrappedStepFunction));
2385
2517
  }
2386
2518
  /**
2387
2519
  * Stops the execution for the duration provided.
@@ -2452,43 +2584,27 @@ var WorkflowContext = class {
2452
2584
  * }
2453
2585
  */
2454
2586
  async call(stepName, settings) {
2455
- const { url, method = "GET", body, headers = {}, retries = 0, timeout, flowControl } = settings;
2456
- const result = await this.addStep(
2587
+ const {
2588
+ url,
2589
+ method = "GET",
2590
+ body: requestBody,
2591
+ headers = {},
2592
+ retries = 0,
2593
+ timeout,
2594
+ flowControl
2595
+ } = settings;
2596
+ return await this.addStep(
2457
2597
  new LazyCallStep(
2458
2598
  stepName,
2459
2599
  url,
2460
2600
  method,
2461
- body,
2601
+ requestBody,
2462
2602
  headers,
2463
2603
  retries,
2464
2604
  timeout,
2465
2605
  flowControl
2466
2606
  )
2467
2607
  );
2468
- if (typeof result === "string") {
2469
- try {
2470
- const body2 = JSON.parse(result);
2471
- return {
2472
- status: 200,
2473
- header: {},
2474
- body: body2
2475
- };
2476
- } catch {
2477
- return {
2478
- status: 200,
2479
- header: {},
2480
- body: result
2481
- };
2482
- }
2483
- }
2484
- try {
2485
- return {
2486
- ...result,
2487
- body: JSON.parse(result.body)
2488
- };
2489
- } catch {
2490
- return result;
2491
- }
2492
2608
  }
2493
2609
  /**
2494
2610
  * Pauses workflow execution until a specific event occurs or a timeout is reached.
@@ -2527,15 +2643,7 @@ var WorkflowContext = class {
2527
2643
  async waitForEvent(stepName, eventId, options = {}) {
2528
2644
  const { timeout = "7d" } = options;
2529
2645
  const timeoutStr = typeof timeout === "string" ? timeout : `${timeout}s`;
2530
- const result = await this.addStep(new LazyWaitForEventStep(stepName, eventId, timeoutStr));
2531
- try {
2532
- return {
2533
- ...result,
2534
- eventData: JSON.parse(result.eventData)
2535
- };
2536
- } catch {
2537
- return result;
2538
- }
2646
+ return await this.addStep(new LazyWaitForEventStep(stepName, eventId, timeoutStr));
2539
2647
  }
2540
2648
  /**
2541
2649
  * Notify workflow runs waiting for an event
@@ -2559,24 +2667,12 @@ var WorkflowContext = class {
2559
2667
  * @returns notify response which has event id, event data and list of waiters which were notified
2560
2668
  */
2561
2669
  async notify(stepName, eventId, eventData) {
2562
- const result = await this.addStep(
2670
+ return await this.addStep(
2563
2671
  new LazyNotifyStep(stepName, eventId, eventData, this.qstashClient.http)
2564
2672
  );
2565
- try {
2566
- return {
2567
- ...result,
2568
- eventData: JSON.parse(result.eventData)
2569
- };
2570
- } catch {
2571
- return result;
2572
- }
2573
2673
  }
2574
2674
  async invoke(stepName, settings) {
2575
- const result = await this.addStep(new LazyInvokeStep(stepName, settings));
2576
- return {
2577
- ...result,
2578
- body: result.body ? JSON.parse(result.body) : void 0
2579
- };
2675
+ return await this.addStep(new LazyInvokeStep(stepName, settings));
2580
2676
  }
2581
2677
  /**
2582
2678
  * Cancel the current workflow run
@@ -2735,10 +2831,6 @@ var processRawSteps = (rawSteps) => {
2735
2831
  const stepsToDecode = encodedSteps.filter((step) => step.callType === "step");
2736
2832
  const otherSteps = stepsToDecode.map((rawStep) => {
2737
2833
  const step = JSON.parse(decodeBase64(rawStep.body));
2738
- try {
2739
- step.out = JSON.parse(step.out);
2740
- } catch {
2741
- }
2742
2834
  if (step.waitEventId) {
2743
2835
  const newOut = {
2744
2836
  eventData: step.out ? decodeBase64(step.out) : void 0,
@@ -2958,6 +3050,7 @@ var processOptions = (options) => {
2958
3050
  retries: DEFAULT_RETRIES,
2959
3051
  useJSONContent: false,
2960
3052
  disableTelemetry: false,
3053
+ onError: console.error,
2961
3054
  ...options
2962
3055
  };
2963
3056
  };
@@ -3007,7 +3100,8 @@ var serveBase = (routeFunction, telemetry, options) => {
3007
3100
  retries,
3008
3101
  useJSONContent,
3009
3102
  disableTelemetry,
3010
- flowControl
3103
+ flowControl,
3104
+ onError
3011
3105
  } = processOptions(options);
3012
3106
  telemetry = disableTelemetry ? void 0 : telemetry;
3013
3107
  const debug = WorkflowLogger.getLogger(verbose);
@@ -3136,8 +3230,19 @@ var serveBase = (routeFunction, telemetry, options) => {
3136
3230
  try {
3137
3231
  return await handler(request);
3138
3232
  } catch (error) {
3139
- console.error(error);
3140
- return new Response(JSON.stringify(formatWorkflowError(error)), {
3233
+ const formattedError = formatWorkflowError(error);
3234
+ try {
3235
+ onError?.(error);
3236
+ } catch (onErrorError) {
3237
+ const formattedOnErrorError = formatWorkflowError(onErrorError);
3238
+ const errorMessage = `Error while running onError callback: '${formattedOnErrorError.message}'.
3239
+ Original error: '${formattedError.message}'`;
3240
+ console.error(errorMessage);
3241
+ return new Response(errorMessage, {
3242
+ status: 500
3243
+ });
3244
+ }
3245
+ return new Response(JSON.stringify(formattedError), {
3141
3246
  status: 500
3142
3247
  });
3143
3248
  }
package/index.mjs CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  makeNotifyRequest,
11
11
  serve,
12
12
  triggerFirstInvocation
13
- } from "./chunk-GFNR743S.mjs";
13
+ } from "./chunk-4GTHIL7S.mjs";
14
14
 
15
15
  // src/client/index.ts
16
16
  import { Client as QStashClient } from "@upstash/qstash";
package/nextjs.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next';
2
- import { R as RouteFunction, k as PublicServeOptions, t as InvokableWorkflow } from './types-CYhDXnf8.mjs';
3
- import { s as serveManyBase } from './serve-many-BVDpPsF-.mjs';
2
+ import { R as RouteFunction, k as PublicServeOptions, t as InvokableWorkflow } from './types-D1W0VOpy.mjs';
3
+ import { s as serveManyBase } from './serve-many-DLguU9iR.mjs';
4
4
  import '@upstash/qstash';
5
5
  import 'zod';
6
6
  import 'ai';
package/nextjs.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next';
2
- import { R as RouteFunction, k as PublicServeOptions, t as InvokableWorkflow } from './types-CYhDXnf8.js';
3
- import { s as serveManyBase } from './serve-many-e4zufyXN.js';
2
+ import { R as RouteFunction, k as PublicServeOptions, t as InvokableWorkflow } from './types-D1W0VOpy.js';
3
+ import { s as serveManyBase } from './serve-many-BdMq5rFX.js';
4
4
  import '@upstash/qstash';
5
5
  import 'zod';
6
6
  import 'ai';