@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/cloudflare.js CHANGED
@@ -39,69 +39,18 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
39
39
  var DEFAULT_CONTENT_TYPE = "application/json";
40
40
  var NO_CONCURRENCY = 1;
41
41
  var DEFAULT_RETRIES = 3;
42
- var VERSION = "v0.2.21";
42
+ var VERSION = "v0.3.0-rc";
43
43
  var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
44
44
  var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
45
45
  var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
46
46
  var TELEMETRY_HEADER_RUNTIME = "Upstash-Telemetry-Runtime";
47
- var TELEMETRY_HEADER_AGENT = "Upstash-Telemetry-Agent";
48
47
 
49
48
  // src/client/utils.ts
50
- var import_qstash = require("@upstash/qstash");
51
- var makeNotifyRequest = async (requester, eventId, eventData) => {
52
- const result = await requester.request({
53
- path: ["v2", "notify", eventId],
54
- method: "POST",
55
- body: typeof eventData === "string" ? eventData : JSON.stringify(eventData)
56
- });
57
- return result;
58
- };
59
- var makeCancelRequest = async (requester, workflowRunId) => {
60
- await requester.request({
61
- path: ["v2", "workflows", "runs", `${workflowRunId}?cancel=true`],
62
- method: "DELETE",
63
- parseResponseAsJson: false
64
- });
65
- return true;
66
- };
67
- var getSteps = async (requester, workflowRunId, messageId, debug) => {
68
- try {
69
- const steps = await requester.request({
70
- path: ["v2", "workflows", "runs", workflowRunId],
71
- parseResponseAsJson: true
72
- });
73
- if (!messageId) {
74
- await debug?.log("INFO", "ENDPOINT_START", {
75
- message: `Pulled ${steps.length} steps from QStashand returned them without filtering with messageId.`
76
- });
77
- return { steps, workflowRunEnded: false };
78
- } else {
79
- const index = steps.findIndex((item) => item.messageId === messageId);
80
- if (index === -1) {
81
- return { steps: [], workflowRunEnded: false };
82
- }
83
- const filteredSteps = steps.slice(0, index + 1);
84
- await debug?.log("INFO", "ENDPOINT_START", {
85
- message: `Pulled ${steps.length} steps from QStash and filtered them to ${filteredSteps.length} using messageId.`
86
- });
87
- return { steps: filteredSteps, workflowRunEnded: false };
88
- }
89
- } catch (error) {
90
- if (error instanceof import_qstash.QstashError && error.status === 404) {
91
- await debug?.log("WARN", "ENDPOINT_START", {
92
- message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
93
- error
94
- });
95
- return { steps: void 0, workflowRunEnded: true };
96
- } else {
97
- throw error;
98
- }
99
- }
100
- };
49
+ var import_qstash2 = require("@upstash/qstash");
101
50
 
102
51
  // src/error.ts
103
- var import_qstash2 = require("@upstash/qstash");
104
- var WorkflowError = class extends import_qstash2.QstashError {
52
+ var import_qstash = require("@upstash/qstash");
53
+ var WorkflowError = class extends import_qstash.QstashError {
105
54
  constructor(message) {
106
55
  super(message);
107
56
  this.name = "WorkflowError";
@@ -140,6 +89,19 @@ var WorkflowNonRetryableError = class extends WorkflowAbort {
140
89
  if (message) this.message = message;
141
90
  }
142
91
  };
92
+ var WorkflowRetryAfterError = class extends WorkflowAbort {
93
+ retryAfter;
94
+ /**
95
+ * @param retryAfter time in seconds after which the workflow should be retried
96
+ * @param message error message to be displayed
97
+ */
98
+ constructor(message, retryAfter) {
99
+ super("retry", void 0, false);
100
+ this.name = "WorkflowRetryAfterError";
101
+ this.retryAfter = retryAfter;
102
+ if (message) this.message = message;
103
+ }
104
+ };
143
105
  var formatWorkflowError = (error) => {
144
106
  return error instanceof Error ? {
145
107
  error: error.name,
@@ -150,6 +112,79 @@ var formatWorkflowError = (error) => {
150
112
  message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
151
113
  };
152
114
  };
115
+ function getConstructorName(obj) {
116
+ if (obj === null || obj === void 0) {
117
+ return null;
118
+ }
119
+ const ctor = obj.constructor;
120
+ if (!ctor || ctor.name === "Object") {
121
+ return null;
122
+ }
123
+ return ctor.name;
124
+ }
125
+ function getConstructorNames(obj) {
126
+ const proto = Object.getPrototypeOf(obj);
127
+ const name = getConstructorName(proto);
128
+ if (name === null) {
129
+ return [];
130
+ }
131
+ return [name, ...getConstructorNames(proto)];
132
+ }
133
+ function isInstanceOf(v, ctor) {
134
+ return getConstructorNames(v).includes(ctor.name);
135
+ }
136
+
137
+ // src/client/utils.ts
138
+ var makeNotifyRequest = async (requester, eventId, eventData) => {
139
+ const result = await requester.request({
140
+ path: ["v2", "notify", eventId],
141
+ method: "POST",
142
+ body: typeof eventData === "string" ? eventData : JSON.stringify(eventData)
143
+ });
144
+ return result;
145
+ };
146
+ var makeCancelRequest = async (requester, workflowRunId) => {
147
+ await requester.request({
148
+ path: ["v2", "workflows", "runs", `${workflowRunId}?cancel=true`],
149
+ method: "DELETE",
150
+ parseResponseAsJson: false
151
+ });
152
+ return true;
153
+ };
154
+ var getSteps = async (requester, workflowRunId, messageId, debug) => {
155
+ try {
156
+ const steps = await requester.request({
157
+ path: ["v2", "workflows", "runs", workflowRunId],
158
+ parseResponseAsJson: true
159
+ });
160
+ if (!messageId) {
161
+ await debug?.log("INFO", "ENDPOINT_START", {
162
+ message: `Pulled ${steps.length} steps from QStashand returned them without filtering with messageId.`
163
+ });
164
+ return { steps, workflowRunEnded: false };
165
+ } else {
166
+ const index = steps.findIndex((item) => item.messageId === messageId);
167
+ if (index === -1) {
168
+ return { steps: [], workflowRunEnded: false };
169
+ }
170
+ const filteredSteps = steps.slice(0, index + 1);
171
+ await debug?.log("INFO", "ENDPOINT_START", {
172
+ message: `Pulled ${steps.length} steps from QStash and filtered them to ${filteredSteps.length} using messageId.`
173
+ });
174
+ return { steps: filteredSteps, workflowRunEnded: false };
175
+ }
176
+ } catch (error) {
177
+ if (isInstanceOf(error, import_qstash2.QstashError) && error.status === 404) {
178
+ await debug?.log("WARN", "ENDPOINT_START", {
179
+ message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
180
+ error
181
+ });
182
+ return { steps: void 0, workflowRunEnded: true };
183
+ } else {
184
+ throw error;
185
+ }
186
+ }
187
+ };
153
188
 
154
189
  // src/context/auto-executor.ts
155
190
  var import_qstash5 = require("@upstash/qstash");
@@ -522,9 +557,9 @@ var Ok = class {
522
557
  }
523
558
  safeUnwrap() {
524
559
  const value = this.value;
525
- return function* () {
560
+ return (function* () {
526
561
  return value;
527
- }();
562
+ })();
528
563
  }
529
564
  _unsafeUnwrap(_) {
530
565
  return this.value;
@@ -583,10 +618,10 @@ var Err = class {
583
618
  }
584
619
  safeUnwrap() {
585
620
  const error = this.error;
586
- return function* () {
621
+ return (function* () {
587
622
  yield err(error);
588
623
  throw new Error("Do not use this generator out of `safeTry`");
589
- }();
624
+ })();
590
625
  }
591
626
  _unsafeUnwrap(config) {
592
627
  throw createNeverThrowError("Called `_unsafeUnwrap` on an Err", this, config);
@@ -710,17 +745,17 @@ var triggerRouteFunction = async ({
710
745
  return ok("workflow-finished");
711
746
  } catch (error) {
712
747
  const error_ = error;
713
- if (error instanceof import_qstash3.QstashError && error.status === 400) {
748
+ if (isInstanceOf(error, import_qstash3.QstashError) && error.status === 400) {
714
749
  await debug?.log("WARN", "RESPONSE_WORKFLOW", {
715
750
  message: `tried to append to a cancelled workflow. exiting without publishing.`,
716
751
  name: error.name,
717
752
  errorMessage: error.message
718
753
  });
719
754
  return ok("workflow-was-finished");
720
- } else if (!(error_ instanceof WorkflowAbort)) {
721
- return err(error_);
722
- } else if (error_ instanceof WorkflowNonRetryableError) {
755
+ } else if (isInstanceOf(error_, WorkflowNonRetryableError) || isInstanceOf(error_, WorkflowRetryAfterError)) {
723
756
  return ok(error_);
757
+ } else if (!isInstanceOf(error_, WorkflowAbort)) {
758
+ return err(error_);
724
759
  } else if (error_.cancelWorkflow) {
725
760
  await onCancel();
726
761
  return ok("workflow-finished");
@@ -1553,20 +1588,6 @@ var LazyInvokeStep = class extends BaseLazyStep {
1553
1588
  }
1554
1589
  };
1555
1590
 
1556
- // src/agents/constants.ts
1557
- var AGENT_NAME_HEADER = "upstash-agent-name";
1558
- var MANAGER_AGENT_PROMPT = `You are an agent orchestrating other AI Agents.
1559
-
1560
- These other agents have tools available to them.
1561
-
1562
- Given a prompt, utilize these agents to address requests.
1563
-
1564
- 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.
1565
-
1566
- Avoid calling the same agent twice in one turn. Instead, prefer to call it once but provide everything
1567
- you need from that agent.
1568
- `;
1569
-
1570
1591
  // src/qstash/headers.ts
1571
1592
  var WorkflowHeaders = class {
1572
1593
  userHeaders;
@@ -1615,8 +1636,7 @@ var WorkflowHeaders = class {
1615
1636
  [WORKFLOW_URL_HEADER]: this.workflowConfig.workflowUrl,
1616
1637
  [WORKFLOW_FEATURE_HEADER]: "LazyFetch,InitialBody,WF_DetectTrigger" + (this.keepTriggerConfig ? ",WF_TriggerOnConfig" : ""),
1617
1638
  [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION,
1618
- ...this.workflowConfig.telemetry ? getTelemetryHeaders(this.workflowConfig.telemetry) : {},
1619
- ...this.workflowConfig.telemetry && this.stepInfo?.lazyStep instanceof LazyCallStep && this.stepInfo.lazyStep.headers[AGENT_NAME_HEADER] ? { [TELEMETRY_HEADER_AGENT]: "true" } : {}
1639
+ ...this.workflowConfig.telemetry ? getTelemetryHeaders(this.workflowConfig.telemetry) : {}
1620
1640
  };
1621
1641
  if (this.stepInfo?.lazyStep.stepType !== "Call") {
1622
1642
  this.headers.rawHeaders[`Upstash-Forward-${WORKFLOW_PROTOCOL_VERSION_HEADER}`] = WORKFLOW_PROTOCOL_VERSION;
@@ -2027,7 +2047,7 @@ var AutoExecutor = class _AutoExecutor {
2027
2047
  });
2028
2048
  throw new WorkflowAbort(parallelStep.stepName, resultStep);
2029
2049
  } catch (error) {
2030
- if (error instanceof WorkflowAbort || error instanceof import_qstash5.QstashError && error.status === 400) {
2050
+ if (isInstanceOf(error, WorkflowAbort) || isInstanceOf(error, import_qstash5.QstashError) && error.status === 400) {
2031
2051
  throw error;
2032
2052
  }
2033
2053
  throw new WorkflowError(
@@ -2134,7 +2154,7 @@ var validateParallelSteps = (lazySteps, stepsFromRequest) => {
2134
2154
  validateStep(lazySteps[index], stepFromRequest);
2135
2155
  }
2136
2156
  } catch (error) {
2137
- if (error instanceof WorkflowError) {
2157
+ if (isInstanceOf(error, WorkflowError)) {
2138
2158
  const lazyStepNames = lazySteps.map((lazyStep) => lazyStep.stepName);
2139
2159
  const lazyStepTypes = lazySteps.map((lazyStep) => lazyStep.stepType);
2140
2160
  const requestStepNames = stepsFromRequest.map((step) => step.stepName);
@@ -2279,309 +2299,6 @@ var WorkflowApi = class extends BaseWorkflowApi {
2279
2299
  }
2280
2300
  };
2281
2301
 
2282
- // src/agents/index.ts
2283
- var import_openai2 = require("@ai-sdk/openai");
2284
-
2285
- // src/agents/adapters.ts
2286
- var import_ai = require("ai");
2287
- var fetchWithContextCall = async (context, agentCallParams, ...params) => {
2288
- const [input, init] = params;
2289
- try {
2290
- const headers = init?.headers ? Object.fromEntries(new Headers(init.headers).entries()) : {};
2291
- const body = init?.body ? JSON.parse(init.body) : void 0;
2292
- const agentName = headers[AGENT_NAME_HEADER];
2293
- const stepName = agentName ? `Call Agent ${agentName}` : "Call Agent";
2294
- const responseInfo = await context.call(stepName, {
2295
- url: input.toString(),
2296
- method: init?.method,
2297
- headers,
2298
- body,
2299
- timeout: agentCallParams?.timeout,
2300
- retries: agentCallParams?.retries,
2301
- retryDelay: agentCallParams?.retryDelay,
2302
- flowControl: agentCallParams?.flowControl
2303
- });
2304
- const responseHeaders = new Headers(
2305
- Object.entries(responseInfo.header).reduce(
2306
- (acc, [key, values]) => {
2307
- acc[key] = values.join(", ");
2308
- return acc;
2309
- },
2310
- {}
2311
- )
2312
- );
2313
- return new Response(JSON.stringify(responseInfo.body), {
2314
- status: responseInfo.status,
2315
- headers: responseHeaders
2316
- });
2317
- } catch (error) {
2318
- if (error instanceof Error && error.name === "WorkflowAbort") {
2319
- throw error;
2320
- } else {
2321
- console.error("Error in fetch implementation:", error);
2322
- throw error;
2323
- }
2324
- }
2325
- };
2326
- var createWorkflowModel = ({
2327
- context,
2328
- provider,
2329
- providerParams,
2330
- agentCallParams
2331
- }) => {
2332
- return provider({
2333
- fetch: (...params) => fetchWithContextCall(context, agentCallParams, ...params),
2334
- ...providerParams
2335
- });
2336
- };
2337
- var wrapTools = ({
2338
- context,
2339
- tools
2340
- }) => {
2341
- return Object.fromEntries(
2342
- Object.entries(tools).map((toolInfo) => {
2343
- const [toolName, tool3] = toolInfo;
2344
- const executeAsStep = "executeAsStep" in tool3 ? tool3.executeAsStep : true;
2345
- const aiSDKTool = convertToAISDKTool(tool3);
2346
- const execute = aiSDKTool.execute;
2347
- if (execute && executeAsStep) {
2348
- const wrappedExecute = (...params) => {
2349
- return context.run(`Run tool ${toolName}`, () => execute(...params));
2350
- };
2351
- aiSDKTool.execute = wrappedExecute;
2352
- }
2353
- return [toolName, aiSDKTool];
2354
- })
2355
- );
2356
- };
2357
- var convertToAISDKTool = (tool3) => {
2358
- const isLangchainTool = "invoke" in tool3;
2359
- return isLangchainTool ? convertLangchainTool(tool3) : tool3;
2360
- };
2361
- var convertLangchainTool = (langchainTool) => {
2362
- return (0, import_ai.tool)({
2363
- description: langchainTool.description,
2364
- parameters: langchainTool.schema,
2365
- execute: async (...param) => langchainTool.invoke(...param)
2366
- });
2367
- };
2368
-
2369
- // src/agents/agent.ts
2370
- var import_zod = require("zod");
2371
- var import_ai2 = require("ai");
2372
-
2373
- // src/serve/utils.ts
2374
- var isDisabledWorkflowContext = (context) => {
2375
- return "disabled" in context;
2376
- };
2377
-
2378
- // src/agents/agent.ts
2379
- var Agent = class {
2380
- name;
2381
- tools;
2382
- maxSteps;
2383
- background;
2384
- model;
2385
- temparature;
2386
- context;
2387
- constructor({ tools, maxSteps, background, name, model, temparature = 0.1 }, context) {
2388
- this.name = name;
2389
- this.tools = tools ?? {};
2390
- this.maxSteps = maxSteps;
2391
- this.background = background;
2392
- this.model = model;
2393
- this.temparature = temparature;
2394
- this.context = context;
2395
- }
2396
- /**
2397
- * Trigger the agent by passing a prompt
2398
- *
2399
- * @param prompt task to assign to the agent
2400
- * @returns Response as `{ text: string }`
2401
- */
2402
- async call({ prompt }) {
2403
- try {
2404
- if (isDisabledWorkflowContext(this.context)) {
2405
- await this.context.sleep("abort", 0);
2406
- }
2407
- const result = await (0, import_ai2.generateText)({
2408
- model: this.model,
2409
- tools: this.tools,
2410
- maxSteps: this.maxSteps,
2411
- system: this.background,
2412
- prompt,
2413
- headers: {
2414
- [AGENT_NAME_HEADER]: this.name
2415
- },
2416
- temperature: this.temparature
2417
- });
2418
- return { text: result.text };
2419
- } catch (error) {
2420
- if (error instanceof import_ai2.ToolExecutionError) {
2421
- if (error.cause instanceof Error && error.cause.name === "WorkflowAbort") {
2422
- throw error.cause;
2423
- } else if (error.cause instanceof import_ai2.ToolExecutionError && error.cause.cause instanceof Error && error.cause.cause.name === "WorkflowAbort") {
2424
- throw error.cause.cause;
2425
- } else {
2426
- throw error;
2427
- }
2428
- } else {
2429
- throw error;
2430
- }
2431
- }
2432
- }
2433
- /**
2434
- * Convert the agent to a tool which can be used by other agents.
2435
- *
2436
- * @returns the agent as a tool
2437
- */
2438
- asTool() {
2439
- const toolDescriptions = Object.values(this.tools).map((tool3) => tool3.description).join("\n");
2440
- return (0, import_ai2.tool)({
2441
- parameters: import_zod.z.object({ prompt: import_zod.z.string() }),
2442
- execute: async ({ prompt }) => {
2443
- return await this.call({ prompt });
2444
- },
2445
- description: `An AI Agent with the following background: ${this.background}Has access to the following tools: ${toolDescriptions}`
2446
- });
2447
- }
2448
- };
2449
- var ManagerAgent = class extends Agent {
2450
- agents;
2451
- /**
2452
- * A manager agent which coordinates agents available to it to achieve a
2453
- * given task
2454
- *
2455
- * @param name Name of the agent
2456
- * @param background Background of the agent. If not passed, default will be used.
2457
- * @param model LLM model to use
2458
- * @param agents: List of agents available to the agent
2459
- * @param maxSteps number of times the manager agent can call the LLM at most.
2460
- * If the agent abruptly stops execution after calling other agents, you may
2461
- * need to increase maxSteps
2462
- */
2463
- constructor({
2464
- agents,
2465
- background = MANAGER_AGENT_PROMPT,
2466
- model,
2467
- maxSteps,
2468
- name = "manager llm"
2469
- }, context) {
2470
- super(
2471
- {
2472
- background,
2473
- maxSteps,
2474
- tools: Object.fromEntries(agents.map((agent) => [agent.name, agent.asTool()])),
2475
- name,
2476
- model
2477
- },
2478
- context
2479
- );
2480
- this.agents = agents;
2481
- }
2482
- };
2483
-
2484
- // src/agents/task.ts
2485
- var Task = class {
2486
- context;
2487
- taskParameters;
2488
- constructor({
2489
- context,
2490
- taskParameters
2491
- }) {
2492
- this.context = context;
2493
- this.taskParameters = taskParameters;
2494
- }
2495
- /**
2496
- * Run the agents to complete the task
2497
- *
2498
- * @returns Result of the task as { text: string }
2499
- */
2500
- async run() {
2501
- const { prompt, ...otherParams } = this.taskParameters;
2502
- if ("agent" in otherParams) {
2503
- const agent = otherParams.agent;
2504
- const result = await agent.call({
2505
- prompt
2506
- });
2507
- return { text: result.text };
2508
- } else {
2509
- const { agents, maxSteps, model, background } = otherParams;
2510
- const managerAgent = new ManagerAgent(
2511
- {
2512
- model,
2513
- maxSteps,
2514
- agents,
2515
- name: "Manager LLM",
2516
- background
2517
- },
2518
- this.context
2519
- );
2520
- const result = await managerAgent.call({ prompt });
2521
- return { text: result.text };
2522
- }
2523
- }
2524
- };
2525
-
2526
- // src/agents/index.ts
2527
- var WorkflowAgents = class {
2528
- context;
2529
- constructor({ context }) {
2530
- this.context = context;
2531
- }
2532
- /**
2533
- * Defines an agent
2534
- *
2535
- * ```ts
2536
- * const researcherAgent = context.agents.agent({
2537
- * model,
2538
- * name: 'academic',
2539
- * maxSteps: 2,
2540
- * tools: {
2541
- * wikiTool: new WikipediaQueryRun({
2542
- * topKResults: 1,
2543
- * maxDocContentLength: 500,
2544
- * })
2545
- * },
2546
- * background:
2547
- * 'You are researcher agent with access to Wikipedia. ' +
2548
- * 'Utilize Wikipedia as much as possible for correct information',
2549
- * });
2550
- * ```
2551
- *
2552
- * @param params agent parameters
2553
- * @returns
2554
- */
2555
- agent(params) {
2556
- const wrappedTools = wrapTools({ context: this.context, tools: params.tools });
2557
- return new Agent(
2558
- {
2559
- ...params,
2560
- tools: wrappedTools
2561
- },
2562
- this.context
2563
- );
2564
- }
2565
- task(taskParameters) {
2566
- return new Task({ context: this.context, taskParameters });
2567
- }
2568
- /**
2569
- * creates an openai model for agents
2570
- */
2571
- openai(...params) {
2572
- const [model, settings] = params;
2573
- const { baseURL, apiKey, callSettings, ...otherSettings } = settings ?? {};
2574
- const openaiModel = this.AISDKModel({
2575
- context: this.context,
2576
- provider: import_openai2.createOpenAI,
2577
- providerParams: { baseURL, apiKey, compatibility: "strict" },
2578
- agentCallParams: callSettings
2579
- });
2580
- return openaiModel(model, otherSettings);
2581
- }
2582
- AISDKModel = createWorkflowModel;
2583
- };
2584
-
2585
2302
  // src/serve/serve-many.ts
2586
2303
  var getWorkflowId = (url) => {
2587
2304
  const components = url.split("/");
@@ -2890,7 +2607,7 @@ var WorkflowContext = class {
2890
2607
  * @returns result of the step function
2891
2608
  */
2892
2609
  async run(stepName, stepFunction) {
2893
- const wrappedStepFunction = () => this.executor.wrapStep(stepName, stepFunction);
2610
+ const wrappedStepFunction = (() => this.executor.wrapStep(stepName, stepFunction));
2894
2611
  return await this.addStep(new LazyFunctionStep(stepName, wrappedStepFunction));
2895
2612
  }
2896
2613
  /**
@@ -3061,11 +2778,6 @@ var WorkflowContext = class {
3061
2778
  context: this
3062
2779
  });
3063
2780
  }
3064
- get agents() {
3065
- return new WorkflowAgents({
3066
- context: this
3067
- });
3068
- }
3069
2781
  };
3070
2782
 
3071
2783
  // src/logger.ts
@@ -3169,7 +2881,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
3169
2881
  try {
3170
2882
  await routeFunction(disabledContext);
3171
2883
  } catch (error) {
3172
- if (error instanceof WorkflowAbort && error.stepName === this.disabledMessage || error instanceof WorkflowNonRetryableError) {
2884
+ if (isInstanceOf(error, WorkflowAbort) && error.stepName === this.disabledMessage || isInstanceOf(error, WorkflowNonRetryableError) || isInstanceOf(error, WorkflowRetryAfterError)) {
3173
2885
  return ok("step-found");
3174
2886
  }
3175
2887
  console.warn(
@@ -3422,13 +3134,24 @@ var processOptions = (options) => {
3422
3134
  },
3423
3135
  status: 489
3424
3136
  });
3425
- } else if (detailedFinishCondition?.condition === "failure-callback") {
3426
- return new Response(detailedFinishCondition.result ?? void 0, {
3427
- status: 200,
3137
+ } else if (detailedFinishCondition?.condition === "retry-after-error") {
3138
+ return new Response(JSON.stringify(formatWorkflowError(detailedFinishCondition.result)), {
3428
3139
  headers: {
3140
+ "Retry-After": detailedFinishCondition.result.retryAfter.toString(),
3429
3141
  [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
3430
- }
3142
+ },
3143
+ status: 429
3431
3144
  });
3145
+ } else if (detailedFinishCondition?.condition === "failure-callback") {
3146
+ return new Response(
3147
+ JSON.stringify({ result: detailedFinishCondition.result ?? void 0 }),
3148
+ {
3149
+ status: 200,
3150
+ headers: {
3151
+ [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
3152
+ }
3153
+ }
3154
+ );
3432
3155
  }
3433
3156
  return new Response(JSON.stringify({ workflowRunId }), {
3434
3157
  status: 200,
@@ -3638,12 +3361,18 @@ var serveBase = (routeFunction, telemetry2, options) => {
3638
3361
  },
3639
3362
  debug
3640
3363
  });
3641
- if (result.isOk() && result.value instanceof WorkflowNonRetryableError) {
3364
+ if (result.isOk() && isInstanceOf(result.value, WorkflowNonRetryableError)) {
3642
3365
  return onStepFinish(workflowRunId, result.value, {
3643
3366
  condition: "non-retryable-error",
3644
3367
  result: result.value
3645
3368
  });
3646
3369
  }
3370
+ if (result.isOk() && isInstanceOf(result.value, WorkflowRetryAfterError)) {
3371
+ return onStepFinish(workflowRunId, result.value, {
3372
+ condition: "retry-after-error",
3373
+ result: result.value
3374
+ });
3375
+ }
3647
3376
  if (result.isErr()) {
3648
3377
  await debug?.log("ERROR", "ERROR", { error: result.error.message });
3649
3378
  throw result.error;
@@ -3674,7 +3403,7 @@ var serveBase = (routeFunction, telemetry2, options) => {
3674
3403
  const errorMessage = `Error while running onError callback: '${formattedOnErrorError.message}'.
3675
3404
  Original error: '${formattedError.message}'`;
3676
3405
  console.error(errorMessage);
3677
- return new Response(errorMessage, {
3406
+ return new Response(JSON.stringify({ error: errorMessage }), {
3678
3407
  status: 500,
3679
3408
  headers: {
3680
3409
  [WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
package/cloudflare.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/cloudflare.ts
8
8
  var getArgs = (args) => {
package/express.d.mts CHANGED
@@ -1,14 +1,12 @@
1
1
  import * as express_serve_static_core from 'express-serve-static-core';
2
- import { R as RouteFunction, W as WorkflowServeOptions, y as InvokableWorkflow } from './types-Q3dM0UlR.mjs';
2
+ import { R as RouteFunction, W as WorkflowServeOptions, y as InvokableWorkflow } from './types-DESkn7K9.mjs';
3
3
  import { Router } from 'express';
4
- import { s as serveManyBase } from './serve-many-BNusWYgt.mjs';
4
+ import { s as serveManyBase } from './serve-many-DEwKPF6H.mjs';
5
5
  import '@upstash/qstash';
6
6
  import 'zod';
7
- import 'ai';
8
- import '@ai-sdk/openai';
9
7
 
10
8
  declare function serve<TInitialPayload = unknown, TResult = unknown>(routeFunction: RouteFunction<TInitialPayload, TResult>, options?: Omit<WorkflowServeOptions<globalThis.Response, TInitialPayload>, "onStepFinish">): Router;
11
- declare const createWorkflow: <TInitialPayload, TResult>(routeFunction: RouteFunction<TInitialPayload, TResult>, options?: Omit<WorkflowServeOptions<Response, TInitialPayload>, "onStepFinish"> | undefined) => InvokableWorkflow<TInitialPayload, TResult>;
9
+ declare const createWorkflow: <TInitialPayload, TResult>(...params: Parameters<typeof serve<TInitialPayload, TResult>>) => InvokableWorkflow<TInitialPayload, TResult>;
12
10
  declare const serveMany: (workflows: Parameters<typeof serveManyBase>[0]["workflows"], options?: Parameters<typeof serveManyBase>[0]["options"]) => express_serve_static_core.Router;
13
11
 
14
12
  export { createWorkflow, serve, serveMany };