@upstash/workflow 0.2.22-rc → 0.3.0-rc

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/nextjs.js CHANGED
@@ -30,7 +30,95 @@ __export(nextjs_exports, {
30
30
  module.exports = __toCommonJS(nextjs_exports);
31
31
 
32
32
  // src/client/utils.ts
33
+ var import_qstash2 = require("@upstash/qstash");
34
+
35
+ // src/error.ts
33
36
  var import_qstash = require("@upstash/qstash");
37
+ var WorkflowError = class extends import_qstash.QstashError {
38
+ constructor(message) {
39
+ super(message);
40
+ this.name = "WorkflowError";
41
+ }
42
+ };
43
+ var WorkflowAbort = class extends Error {
44
+ stepInfo;
45
+ stepName;
46
+ /**
47
+ * whether workflow is to be canceled on abort
48
+ */
49
+ cancelWorkflow;
50
+ /**
51
+ *
52
+ * @param stepName name of the aborting step
53
+ * @param stepInfo step information
54
+ * @param cancelWorkflow
55
+ */
56
+ constructor(stepName, stepInfo, cancelWorkflow = false) {
57
+ super(
58
+ `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}'.`
59
+ );
60
+ this.name = "WorkflowAbort";
61
+ this.stepName = stepName;
62
+ this.stepInfo = stepInfo;
63
+ this.cancelWorkflow = cancelWorkflow;
64
+ }
65
+ };
66
+ var WorkflowNonRetryableError = class extends WorkflowAbort {
67
+ /**
68
+ * @param message error message to be displayed
69
+ */
70
+ constructor(message) {
71
+ super("fail", void 0, false);
72
+ this.name = "WorkflowNonRetryableError";
73
+ if (message) this.message = message;
74
+ }
75
+ };
76
+ var WorkflowRetryAfterError = class extends WorkflowAbort {
77
+ retryAfter;
78
+ /**
79
+ * @param retryAfter time in seconds after which the workflow should be retried
80
+ * @param message error message to be displayed
81
+ */
82
+ constructor(message, retryAfter) {
83
+ super("retry", void 0, false);
84
+ this.name = "WorkflowRetryAfterError";
85
+ this.retryAfter = retryAfter;
86
+ if (message) this.message = message;
87
+ }
88
+ };
89
+ var formatWorkflowError = (error) => {
90
+ return error instanceof Error ? {
91
+ error: error.name,
92
+ message: error.message,
93
+ stack: error.stack
94
+ } : {
95
+ error: "Error",
96
+ message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
97
+ };
98
+ };
99
+ function getConstructorName(obj) {
100
+ if (obj === null || obj === void 0) {
101
+ return null;
102
+ }
103
+ const ctor = obj.constructor;
104
+ if (!ctor || ctor.name === "Object") {
105
+ return null;
106
+ }
107
+ return ctor.name;
108
+ }
109
+ function getConstructorNames(obj) {
110
+ const proto = Object.getPrototypeOf(obj);
111
+ const name = getConstructorName(proto);
112
+ if (name === null) {
113
+ return [];
114
+ }
115
+ return [name, ...getConstructorNames(proto)];
116
+ }
117
+ function isInstanceOf(v, ctor) {
118
+ return getConstructorNames(v).includes(ctor.name);
119
+ }
120
+
121
+ // src/client/utils.ts
34
122
  var makeNotifyRequest = async (requester, eventId, eventData) => {
35
123
  const result = await requester.request({
36
124
  path: ["v2", "notify", eventId],
@@ -70,7 +158,7 @@ var getSteps = async (requester, workflowRunId, messageId, debug) => {
70
158
  return { steps: filteredSteps, workflowRunEnded: false };
71
159
  }
72
160
  } catch (error) {
73
- if (error instanceof import_qstash.QstashError && error.status === 404) {
161
+ if (isInstanceOf(error, import_qstash2.QstashError) && error.status === 404) {
74
162
  await debug?.log("WARN", "ENDPOINT_START", {
75
163
  message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
76
164
  error
@@ -95,64 +183,11 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
95
183
  var DEFAULT_CONTENT_TYPE = "application/json";
96
184
  var NO_CONCURRENCY = 1;
97
185
  var DEFAULT_RETRIES = 3;
98
- var VERSION = "v0.2.21";
186
+ var VERSION = "v0.3.0-rc";
99
187
  var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
100
188
  var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
101
189
  var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
102
190
  var TELEMETRY_HEADER_RUNTIME = "Upstash-Telemetry-Runtime";
103
- var TELEMETRY_HEADER_AGENT = "Upstash-Telemetry-Agent";
104
-
105
- // src/error.ts
106
- var import_qstash2 = require("@upstash/qstash");
107
- var WorkflowError = class extends import_qstash2.QstashError {
108
- constructor(message) {
109
- super(message);
110
- this.name = "WorkflowError";
111
- }
112
- };
113
- var WorkflowAbort = class extends Error {
114
- stepInfo;
115
- stepName;
116
- /**
117
- * whether workflow is to be canceled on abort
118
- */
119
- cancelWorkflow;
120
- /**
121
- *
122
- * @param stepName name of the aborting step
123
- * @param stepInfo step information
124
- * @param cancelWorkflow
125
- */
126
- constructor(stepName, stepInfo, cancelWorkflow = false) {
127
- super(
128
- `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}'.`
129
- );
130
- this.name = "WorkflowAbort";
131
- this.stepName = stepName;
132
- this.stepInfo = stepInfo;
133
- this.cancelWorkflow = cancelWorkflow;
134
- }
135
- };
136
- var WorkflowNonRetryableError = class extends WorkflowAbort {
137
- /**
138
- * @param message error message to be displayed
139
- */
140
- constructor(message) {
141
- super("fail", void 0, false);
142
- this.name = "WorkflowNonRetryableError";
143
- if (message) this.message = message;
144
- }
145
- };
146
- var formatWorkflowError = (error) => {
147
- return error instanceof Error ? {
148
- error: error.name,
149
- message: error.message,
150
- stack: error.stack
151
- } : {
152
- error: "Error",
153
- message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
154
- };
155
- };
156
191
 
157
192
  // src/context/auto-executor.ts
158
193
  var import_qstash5 = require("@upstash/qstash");
@@ -525,9 +560,9 @@ var Ok = class {
525
560
  }
526
561
  safeUnwrap() {
527
562
  const value = this.value;
528
- return function* () {
563
+ return (function* () {
529
564
  return value;
530
- }();
565
+ })();
531
566
  }
532
567
  _unsafeUnwrap(_) {
533
568
  return this.value;
@@ -586,10 +621,10 @@ var Err = class {
586
621
  }
587
622
  safeUnwrap() {
588
623
  const error = this.error;
589
- return function* () {
624
+ return (function* () {
590
625
  yield err(error);
591
626
  throw new Error("Do not use this generator out of `safeTry`");
592
- }();
627
+ })();
593
628
  }
594
629
  _unsafeUnwrap(config) {
595
630
  throw createNeverThrowError("Called `_unsafeUnwrap` on an Err", this, config);
@@ -713,17 +748,17 @@ var triggerRouteFunction = async ({
713
748
  return ok("workflow-finished");
714
749
  } catch (error) {
715
750
  const error_ = error;
716
- if (error instanceof import_qstash3.QstashError && error.status === 400) {
751
+ if (isInstanceOf(error, import_qstash3.QstashError) && error.status === 400) {
717
752
  await debug?.log("WARN", "RESPONSE_WORKFLOW", {
718
753
  message: `tried to append to a cancelled workflow. exiting without publishing.`,
719
754
  name: error.name,
720
755
  errorMessage: error.message
721
756
  });
722
757
  return ok("workflow-was-finished");
723
- } else if (!(error_ instanceof WorkflowAbort)) {
724
- return err(error_);
725
- } else if (error_ instanceof WorkflowNonRetryableError) {
758
+ } else if (isInstanceOf(error_, WorkflowNonRetryableError) || isInstanceOf(error_, WorkflowRetryAfterError)) {
726
759
  return ok(error_);
760
+ } else if (!isInstanceOf(error_, WorkflowAbort)) {
761
+ return err(error_);
727
762
  } else if (error_.cancelWorkflow) {
728
763
  await onCancel();
729
764
  return ok("workflow-finished");
@@ -1556,20 +1591,6 @@ var LazyInvokeStep = class extends BaseLazyStep {
1556
1591
  }
1557
1592
  };
1558
1593
 
1559
- // src/agents/constants.ts
1560
- var AGENT_NAME_HEADER = "upstash-agent-name";
1561
- var MANAGER_AGENT_PROMPT = `You are an agent orchestrating other AI Agents.
1562
-
1563
- These other agents have tools available to them.
1564
-
1565
- Given a prompt, utilize these agents to address requests.
1566
-
1567
- 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.
1568
-
1569
- Avoid calling the same agent twice in one turn. Instead, prefer to call it once but provide everything
1570
- you need from that agent.
1571
- `;
1572
-
1573
1594
  // src/qstash/headers.ts
1574
1595
  var WorkflowHeaders = class {
1575
1596
  userHeaders;
@@ -1618,8 +1639,7 @@ var WorkflowHeaders = class {
1618
1639
  [WORKFLOW_URL_HEADER]: this.workflowConfig.workflowUrl,
1619
1640
  [WORKFLOW_FEATURE_HEADER]: "LazyFetch,InitialBody,WF_DetectTrigger" + (this.keepTriggerConfig ? ",WF_TriggerOnConfig" : ""),
1620
1641
  [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION,
1621
- ...this.workflowConfig.telemetry ? getTelemetryHeaders(this.workflowConfig.telemetry) : {},
1622
- ...this.workflowConfig.telemetry && this.stepInfo?.lazyStep instanceof LazyCallStep && this.stepInfo.lazyStep.headers[AGENT_NAME_HEADER] ? { [TELEMETRY_HEADER_AGENT]: "true" } : {}
1642
+ ...this.workflowConfig.telemetry ? getTelemetryHeaders(this.workflowConfig.telemetry) : {}
1623
1643
  };
1624
1644
  if (this.stepInfo?.lazyStep.stepType !== "Call") {
1625
1645
  this.headers.rawHeaders[`Upstash-Forward-${WORKFLOW_PROTOCOL_VERSION_HEADER}`] = WORKFLOW_PROTOCOL_VERSION;
@@ -2030,7 +2050,7 @@ var AutoExecutor = class _AutoExecutor {
2030
2050
  });
2031
2051
  throw new WorkflowAbort(parallelStep.stepName, resultStep);
2032
2052
  } catch (error) {
2033
- if (error instanceof WorkflowAbort || error instanceof import_qstash5.QstashError && error.status === 400) {
2053
+ if (isInstanceOf(error, WorkflowAbort) || isInstanceOf(error, import_qstash5.QstashError) && error.status === 400) {
2034
2054
  throw error;
2035
2055
  }
2036
2056
  throw new WorkflowError(
@@ -2137,7 +2157,7 @@ var validateParallelSteps = (lazySteps, stepsFromRequest) => {
2137
2157
  validateStep(lazySteps[index], stepFromRequest);
2138
2158
  }
2139
2159
  } catch (error) {
2140
- if (error instanceof WorkflowError) {
2160
+ if (isInstanceOf(error, WorkflowError)) {
2141
2161
  const lazyStepNames = lazySteps.map((lazyStep) => lazyStep.stepName);
2142
2162
  const lazyStepTypes = lazySteps.map((lazyStep) => lazyStep.stepType);
2143
2163
  const requestStepNames = stepsFromRequest.map((step) => step.stepName);
@@ -2282,309 +2302,6 @@ var WorkflowApi = class extends BaseWorkflowApi {
2282
2302
  }
2283
2303
  };
2284
2304
 
2285
- // src/agents/index.ts
2286
- var import_openai2 = require("@ai-sdk/openai");
2287
-
2288
- // src/agents/adapters.ts
2289
- var import_ai = require("ai");
2290
- var fetchWithContextCall = async (context, agentCallParams, ...params) => {
2291
- const [input, init] = params;
2292
- try {
2293
- const headers = init?.headers ? Object.fromEntries(new Headers(init.headers).entries()) : {};
2294
- const body = init?.body ? JSON.parse(init.body) : void 0;
2295
- const agentName = headers[AGENT_NAME_HEADER];
2296
- const stepName = agentName ? `Call Agent ${agentName}` : "Call Agent";
2297
- const responseInfo = await context.call(stepName, {
2298
- url: input.toString(),
2299
- method: init?.method,
2300
- headers,
2301
- body,
2302
- timeout: agentCallParams?.timeout,
2303
- retries: agentCallParams?.retries,
2304
- retryDelay: agentCallParams?.retryDelay,
2305
- flowControl: agentCallParams?.flowControl
2306
- });
2307
- const responseHeaders = new Headers(
2308
- Object.entries(responseInfo.header).reduce(
2309
- (acc, [key, values]) => {
2310
- acc[key] = values.join(", ");
2311
- return acc;
2312
- },
2313
- {}
2314
- )
2315
- );
2316
- return new Response(JSON.stringify(responseInfo.body), {
2317
- status: responseInfo.status,
2318
- headers: responseHeaders
2319
- });
2320
- } catch (error) {
2321
- if (error instanceof Error && error.name === "WorkflowAbort") {
2322
- throw error;
2323
- } else {
2324
- console.error("Error in fetch implementation:", error);
2325
- throw error;
2326
- }
2327
- }
2328
- };
2329
- var createWorkflowModel = ({
2330
- context,
2331
- provider,
2332
- providerParams,
2333
- agentCallParams
2334
- }) => {
2335
- return provider({
2336
- fetch: (...params) => fetchWithContextCall(context, agentCallParams, ...params),
2337
- ...providerParams
2338
- });
2339
- };
2340
- var wrapTools = ({
2341
- context,
2342
- tools
2343
- }) => {
2344
- return Object.fromEntries(
2345
- Object.entries(tools).map((toolInfo) => {
2346
- const [toolName, tool3] = toolInfo;
2347
- const executeAsStep = "executeAsStep" in tool3 ? tool3.executeAsStep : true;
2348
- const aiSDKTool = convertToAISDKTool(tool3);
2349
- const execute = aiSDKTool.execute;
2350
- if (execute && executeAsStep) {
2351
- const wrappedExecute = (...params) => {
2352
- return context.run(`Run tool ${toolName}`, () => execute(...params));
2353
- };
2354
- aiSDKTool.execute = wrappedExecute;
2355
- }
2356
- return [toolName, aiSDKTool];
2357
- })
2358
- );
2359
- };
2360
- var convertToAISDKTool = (tool3) => {
2361
- const isLangchainTool = "invoke" in tool3;
2362
- return isLangchainTool ? convertLangchainTool(tool3) : tool3;
2363
- };
2364
- var convertLangchainTool = (langchainTool) => {
2365
- return (0, import_ai.tool)({
2366
- description: langchainTool.description,
2367
- parameters: langchainTool.schema,
2368
- execute: async (...param) => langchainTool.invoke(...param)
2369
- });
2370
- };
2371
-
2372
- // src/agents/agent.ts
2373
- var import_zod = require("zod");
2374
- var import_ai2 = require("ai");
2375
-
2376
- // src/serve/utils.ts
2377
- var isDisabledWorkflowContext = (context) => {
2378
- return "disabled" in context;
2379
- };
2380
-
2381
- // src/agents/agent.ts
2382
- var Agent = class {
2383
- name;
2384
- tools;
2385
- maxSteps;
2386
- background;
2387
- model;
2388
- temparature;
2389
- context;
2390
- constructor({ tools, maxSteps, background, name, model, temparature = 0.1 }, context) {
2391
- this.name = name;
2392
- this.tools = tools ?? {};
2393
- this.maxSteps = maxSteps;
2394
- this.background = background;
2395
- this.model = model;
2396
- this.temparature = temparature;
2397
- this.context = context;
2398
- }
2399
- /**
2400
- * Trigger the agent by passing a prompt
2401
- *
2402
- * @param prompt task to assign to the agent
2403
- * @returns Response as `{ text: string }`
2404
- */
2405
- async call({ prompt }) {
2406
- try {
2407
- if (isDisabledWorkflowContext(this.context)) {
2408
- await this.context.sleep("abort", 0);
2409
- }
2410
- const result = await (0, import_ai2.generateText)({
2411
- model: this.model,
2412
- tools: this.tools,
2413
- maxSteps: this.maxSteps,
2414
- system: this.background,
2415
- prompt,
2416
- headers: {
2417
- [AGENT_NAME_HEADER]: this.name
2418
- },
2419
- temperature: this.temparature
2420
- });
2421
- return { text: result.text };
2422
- } catch (error) {
2423
- if (error instanceof import_ai2.ToolExecutionError) {
2424
- if (error.cause instanceof Error && error.cause.name === "WorkflowAbort") {
2425
- throw error.cause;
2426
- } else if (error.cause instanceof import_ai2.ToolExecutionError && error.cause.cause instanceof Error && error.cause.cause.name === "WorkflowAbort") {
2427
- throw error.cause.cause;
2428
- } else {
2429
- throw error;
2430
- }
2431
- } else {
2432
- throw error;
2433
- }
2434
- }
2435
- }
2436
- /**
2437
- * Convert the agent to a tool which can be used by other agents.
2438
- *
2439
- * @returns the agent as a tool
2440
- */
2441
- asTool() {
2442
- const toolDescriptions = Object.values(this.tools).map((tool3) => tool3.description).join("\n");
2443
- return (0, import_ai2.tool)({
2444
- parameters: import_zod.z.object({ prompt: import_zod.z.string() }),
2445
- execute: async ({ prompt }) => {
2446
- return await this.call({ prompt });
2447
- },
2448
- description: `An AI Agent with the following background: ${this.background}Has access to the following tools: ${toolDescriptions}`
2449
- });
2450
- }
2451
- };
2452
- var ManagerAgent = class extends Agent {
2453
- agents;
2454
- /**
2455
- * A manager agent which coordinates agents available to it to achieve a
2456
- * given task
2457
- *
2458
- * @param name Name of the agent
2459
- * @param background Background of the agent. If not passed, default will be used.
2460
- * @param model LLM model to use
2461
- * @param agents: List of agents available to the agent
2462
- * @param maxSteps number of times the manager agent can call the LLM at most.
2463
- * If the agent abruptly stops execution after calling other agents, you may
2464
- * need to increase maxSteps
2465
- */
2466
- constructor({
2467
- agents,
2468
- background = MANAGER_AGENT_PROMPT,
2469
- model,
2470
- maxSteps,
2471
- name = "manager llm"
2472
- }, context) {
2473
- super(
2474
- {
2475
- background,
2476
- maxSteps,
2477
- tools: Object.fromEntries(agents.map((agent) => [agent.name, agent.asTool()])),
2478
- name,
2479
- model
2480
- },
2481
- context
2482
- );
2483
- this.agents = agents;
2484
- }
2485
- };
2486
-
2487
- // src/agents/task.ts
2488
- var Task = class {
2489
- context;
2490
- taskParameters;
2491
- constructor({
2492
- context,
2493
- taskParameters
2494
- }) {
2495
- this.context = context;
2496
- this.taskParameters = taskParameters;
2497
- }
2498
- /**
2499
- * Run the agents to complete the task
2500
- *
2501
- * @returns Result of the task as { text: string }
2502
- */
2503
- async run() {
2504
- const { prompt, ...otherParams } = this.taskParameters;
2505
- if ("agent" in otherParams) {
2506
- const agent = otherParams.agent;
2507
- const result = await agent.call({
2508
- prompt
2509
- });
2510
- return { text: result.text };
2511
- } else {
2512
- const { agents, maxSteps, model, background } = otherParams;
2513
- const managerAgent = new ManagerAgent(
2514
- {
2515
- model,
2516
- maxSteps,
2517
- agents,
2518
- name: "Manager LLM",
2519
- background
2520
- },
2521
- this.context
2522
- );
2523
- const result = await managerAgent.call({ prompt });
2524
- return { text: result.text };
2525
- }
2526
- }
2527
- };
2528
-
2529
- // src/agents/index.ts
2530
- var WorkflowAgents = class {
2531
- context;
2532
- constructor({ context }) {
2533
- this.context = context;
2534
- }
2535
- /**
2536
- * Defines an agent
2537
- *
2538
- * ```ts
2539
- * const researcherAgent = context.agents.agent({
2540
- * model,
2541
- * name: 'academic',
2542
- * maxSteps: 2,
2543
- * tools: {
2544
- * wikiTool: new WikipediaQueryRun({
2545
- * topKResults: 1,
2546
- * maxDocContentLength: 500,
2547
- * })
2548
- * },
2549
- * background:
2550
- * 'You are researcher agent with access to Wikipedia. ' +
2551
- * 'Utilize Wikipedia as much as possible for correct information',
2552
- * });
2553
- * ```
2554
- *
2555
- * @param params agent parameters
2556
- * @returns
2557
- */
2558
- agent(params) {
2559
- const wrappedTools = wrapTools({ context: this.context, tools: params.tools });
2560
- return new Agent(
2561
- {
2562
- ...params,
2563
- tools: wrappedTools
2564
- },
2565
- this.context
2566
- );
2567
- }
2568
- task(taskParameters) {
2569
- return new Task({ context: this.context, taskParameters });
2570
- }
2571
- /**
2572
- * creates an openai model for agents
2573
- */
2574
- openai(...params) {
2575
- const [model, settings] = params;
2576
- const { baseURL, apiKey, callSettings, ...otherSettings } = settings ?? {};
2577
- const openaiModel = this.AISDKModel({
2578
- context: this.context,
2579
- provider: import_openai2.createOpenAI,
2580
- providerParams: { baseURL, apiKey, compatibility: "strict" },
2581
- agentCallParams: callSettings
2582
- });
2583
- return openaiModel(model, otherSettings);
2584
- }
2585
- AISDKModel = createWorkflowModel;
2586
- };
2587
-
2588
2305
  // src/serve/serve-many.ts
2589
2306
  var getWorkflowId = (url) => {
2590
2307
  const components = url.split("/");
@@ -2893,7 +2610,7 @@ var WorkflowContext = class {
2893
2610
  * @returns result of the step function
2894
2611
  */
2895
2612
  async run(stepName, stepFunction) {
2896
- const wrappedStepFunction = () => this.executor.wrapStep(stepName, stepFunction);
2613
+ const wrappedStepFunction = (() => this.executor.wrapStep(stepName, stepFunction));
2897
2614
  return await this.addStep(new LazyFunctionStep(stepName, wrappedStepFunction));
2898
2615
  }
2899
2616
  /**
@@ -3064,11 +2781,6 @@ var WorkflowContext = class {
3064
2781
  context: this
3065
2782
  });
3066
2783
  }
3067
- get agents() {
3068
- return new WorkflowAgents({
3069
- context: this
3070
- });
3071
- }
3072
2784
  };
3073
2785
 
3074
2786
  // src/logger.ts
@@ -3172,7 +2884,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
3172
2884
  try {
3173
2885
  await routeFunction(disabledContext);
3174
2886
  } catch (error) {
3175
- if (error instanceof WorkflowAbort && error.stepName === this.disabledMessage || error instanceof WorkflowNonRetryableError) {
2887
+ if (isInstanceOf(error, WorkflowAbort) && error.stepName === this.disabledMessage || isInstanceOf(error, WorkflowNonRetryableError) || isInstanceOf(error, WorkflowRetryAfterError)) {
3176
2888
  return ok("step-found");
3177
2889
  }
3178
2890
  console.warn(
@@ -3425,13 +3137,24 @@ var processOptions = (options) => {
3425
3137
  },
3426
3138
  status: 489
3427
3139
  });
3428
- } else if (detailedFinishCondition?.condition === "failure-callback") {
3429
- return new Response(detailedFinishCondition.result ?? void 0, {
3430
- status: 200,
3140
+ } else if (detailedFinishCondition?.condition === "retry-after-error") {
3141
+ return new Response(JSON.stringify(formatWorkflowError(detailedFinishCondition.result)), {
3431
3142
  headers: {
3143
+ "Retry-After": detailedFinishCondition.result.retryAfter.toString(),
3432
3144
  [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
3433
- }
3145
+ },
3146
+ status: 429
3434
3147
  });
3148
+ } else if (detailedFinishCondition?.condition === "failure-callback") {
3149
+ return new Response(
3150
+ JSON.stringify({ result: detailedFinishCondition.result ?? void 0 }),
3151
+ {
3152
+ status: 200,
3153
+ headers: {
3154
+ [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
3155
+ }
3156
+ }
3157
+ );
3435
3158
  }
3436
3159
  return new Response(JSON.stringify({ workflowRunId }), {
3437
3160
  status: 200,
@@ -3641,12 +3364,18 @@ var serveBase = (routeFunction, telemetry, options) => {
3641
3364
  },
3642
3365
  debug
3643
3366
  });
3644
- if (result.isOk() && result.value instanceof WorkflowNonRetryableError) {
3367
+ if (result.isOk() && isInstanceOf(result.value, WorkflowNonRetryableError)) {
3645
3368
  return onStepFinish(workflowRunId, result.value, {
3646
3369
  condition: "non-retryable-error",
3647
3370
  result: result.value
3648
3371
  });
3649
3372
  }
3373
+ if (result.isOk() && isInstanceOf(result.value, WorkflowRetryAfterError)) {
3374
+ return onStepFinish(workflowRunId, result.value, {
3375
+ condition: "retry-after-error",
3376
+ result: result.value
3377
+ });
3378
+ }
3650
3379
  if (result.isErr()) {
3651
3380
  await debug?.log("ERROR", "ERROR", { error: result.error.message });
3652
3381
  throw result.error;
@@ -3677,7 +3406,7 @@ var serveBase = (routeFunction, telemetry, options) => {
3677
3406
  const errorMessage = `Error while running onError callback: '${formattedOnErrorError.message}'.
3678
3407
  Original error: '${formattedError.message}'`;
3679
3408
  console.error(errorMessage);
3680
- return new Response(errorMessage, {
3409
+ return new Response(JSON.stringify({ error: errorMessage }), {
3681
3410
  status: 500,
3682
3411
  headers: {
3683
3412
  [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
@@ -3759,7 +3488,8 @@ var servePagesRouter = (routeFunction, options) => {
3759
3488
  for (const [key, value] of response.headers.entries()) {
3760
3489
  res.setHeader(key, value);
3761
3490
  }
3762
- res.status(response.status).json(await response.json());
3491
+ const responseData = await response.json();
3492
+ res.status(response.status).json(responseData);
3763
3493
  };
3764
3494
  return {
3765
3495
  handler
package/nextjs.mjs CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  SDK_TELEMETRY,
3
3
  serveBase,
4
4
  serveManyBase
5
- } from "./chunk-CAQSUCHB.mjs";
5
+ } from "./chunk-AGYYZKP7.mjs";
6
6
 
7
7
  // platforms/nextjs.ts
8
8
  var appTelemetry = {
@@ -68,7 +68,8 @@ var servePagesRouter = (routeFunction, options) => {
68
68
  for (const [key, value] of response.headers.entries()) {
69
69
  res.setHeader(key, value);
70
70
  }
71
- res.status(response.status).json(await response.json());
71
+ const responseData = await response.json();
72
+ res.status(response.status).json(responseData);
72
73
  };
73
74
  return {
74
75
  handler