@upstash/workflow 0.2.21 → 0.2.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -0
- package/astro.d.mts +2 -2
- package/astro.d.ts +2 -2
- package/astro.js +124 -71
- package/astro.mjs +1 -1
- package/{chunk-NQDNC5P4.mjs → chunk-BON2RKOR.mjs} +93 -76
- package/cloudflare.d.mts +2 -2
- package/cloudflare.d.ts +2 -2
- package/cloudflare.js +124 -71
- package/cloudflare.mjs +1 -1
- package/express.d.mts +2 -2
- package/express.d.ts +2 -2
- package/express.js +139 -23895
- package/express.mjs +8 -23805
- package/h3.d.mts +2 -2
- package/h3.d.ts +2 -2
- package/h3.js +124 -71
- package/h3.mjs +1 -1
- package/hono.d.mts +2 -2
- package/hono.d.ts +2 -2
- package/hono.js +124 -71
- package/hono.mjs +1 -1
- package/index.d.mts +10 -2
- package/index.d.ts +10 -2
- package/index.js +128 -73
- package/index.mjs +5 -3
- package/nextjs.d.mts +2 -2
- package/nextjs.d.ts +2 -2
- package/nextjs.js +126 -72
- package/nextjs.mjs +3 -2
- package/package.json +1 -1
- package/{serve-many-CXqQP3RI.d.ts → serve-many-BXDr30rl.d.ts} +1 -1
- package/{serve-many-BNusWYgt.d.mts → serve-many-CctdYIfB.d.mts} +1 -1
- package/solidjs.d.mts +1 -1
- package/solidjs.d.ts +1 -1
- package/solidjs.js +124 -71
- package/solidjs.mjs +1 -1
- package/svelte.d.mts +2 -2
- package/svelte.d.ts +2 -2
- package/svelte.js +124 -71
- package/svelte.mjs +1 -1
- package/tanstack.d.mts +2 -2
- package/tanstack.d.ts +2 -2
- package/tanstack.js +124 -71
- package/tanstack.mjs +1 -1
- package/{types-Q3dM0UlR.d.ts → types-9nCq6bRP.d.mts} +12 -1
- package/{types-Q3dM0UlR.d.mts → types-9nCq6bRP.d.ts} +12 -1
package/solidjs.mjs
CHANGED
package/svelte.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as _sveltejs_kit from '@sveltejs/kit';
|
|
2
2
|
import { RequestHandler } from '@sveltejs/kit';
|
|
3
|
-
import { R as RouteFunction,
|
|
4
|
-
import { s as serveManyBase } from './serve-many-
|
|
3
|
+
import { R as RouteFunction, o as PublicServeOptions, z as InvokableWorkflow } from './types-9nCq6bRP.mjs';
|
|
4
|
+
import { s as serveManyBase } from './serve-many-CctdYIfB.mjs';
|
|
5
5
|
import '@upstash/qstash';
|
|
6
6
|
import 'zod';
|
|
7
7
|
import 'ai';
|
package/svelte.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as _sveltejs_kit from '@sveltejs/kit';
|
|
2
2
|
import { RequestHandler } from '@sveltejs/kit';
|
|
3
|
-
import { R as RouteFunction,
|
|
4
|
-
import { s as serveManyBase } from './serve-many-
|
|
3
|
+
import { R as RouteFunction, o as PublicServeOptions, z as InvokableWorkflow } from './types-9nCq6bRP.js';
|
|
4
|
+
import { s as serveManyBase } from './serve-many-BXDr30rl.js';
|
|
5
5
|
import '@upstash/qstash';
|
|
6
6
|
import 'zod';
|
|
7
7
|
import 'ai';
|
package/svelte.js
CHANGED
|
@@ -27,7 +27,95 @@ __export(svelte_exports, {
|
|
|
27
27
|
module.exports = __toCommonJS(svelte_exports);
|
|
28
28
|
|
|
29
29
|
// src/client/utils.ts
|
|
30
|
+
var import_qstash2 = require("@upstash/qstash");
|
|
31
|
+
|
|
32
|
+
// src/error.ts
|
|
30
33
|
var import_qstash = require("@upstash/qstash");
|
|
34
|
+
var WorkflowError = class extends import_qstash.QstashError {
|
|
35
|
+
constructor(message) {
|
|
36
|
+
super(message);
|
|
37
|
+
this.name = "WorkflowError";
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
var WorkflowAbort = class extends Error {
|
|
41
|
+
stepInfo;
|
|
42
|
+
stepName;
|
|
43
|
+
/**
|
|
44
|
+
* whether workflow is to be canceled on abort
|
|
45
|
+
*/
|
|
46
|
+
cancelWorkflow;
|
|
47
|
+
/**
|
|
48
|
+
*
|
|
49
|
+
* @param stepName name of the aborting step
|
|
50
|
+
* @param stepInfo step information
|
|
51
|
+
* @param cancelWorkflow
|
|
52
|
+
*/
|
|
53
|
+
constructor(stepName, stepInfo, cancelWorkflow = false) {
|
|
54
|
+
super(
|
|
55
|
+
`This is an Upstash Workflow error thrown after a step executes. It is expected to be raised. Make sure that you await for each step. Also, if you are using try/catch blocks, you should not wrap context.run/sleep/sleepUntil/call methods with try/catch. Aborting workflow after executing step '${stepName}'.`
|
|
56
|
+
);
|
|
57
|
+
this.name = "WorkflowAbort";
|
|
58
|
+
this.stepName = stepName;
|
|
59
|
+
this.stepInfo = stepInfo;
|
|
60
|
+
this.cancelWorkflow = cancelWorkflow;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
var WorkflowNonRetryableError = class extends WorkflowAbort {
|
|
64
|
+
/**
|
|
65
|
+
* @param message error message to be displayed
|
|
66
|
+
*/
|
|
67
|
+
constructor(message) {
|
|
68
|
+
super("fail", void 0, false);
|
|
69
|
+
this.name = "WorkflowNonRetryableError";
|
|
70
|
+
if (message) this.message = message;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
var WorkflowRetryAfterError = class extends WorkflowAbort {
|
|
74
|
+
retryAfter;
|
|
75
|
+
/**
|
|
76
|
+
* @param retryAfter time in seconds after which the workflow should be retried
|
|
77
|
+
* @param message error message to be displayed
|
|
78
|
+
*/
|
|
79
|
+
constructor(message, retryAfter) {
|
|
80
|
+
super("retry", void 0, false);
|
|
81
|
+
this.name = "WorkflowRetryAfterError";
|
|
82
|
+
this.retryAfter = retryAfter;
|
|
83
|
+
if (message) this.message = message;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
var formatWorkflowError = (error) => {
|
|
87
|
+
return error instanceof Error ? {
|
|
88
|
+
error: error.name,
|
|
89
|
+
message: error.message,
|
|
90
|
+
stack: error.stack
|
|
91
|
+
} : {
|
|
92
|
+
error: "Error",
|
|
93
|
+
message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
function getConstructorName(obj) {
|
|
97
|
+
if (obj === null || obj === void 0) {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
const ctor = obj.constructor;
|
|
101
|
+
if (!ctor || ctor.name === "Object") {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
return ctor.name;
|
|
105
|
+
}
|
|
106
|
+
function getConstructorNames(obj) {
|
|
107
|
+
const proto = Object.getPrototypeOf(obj);
|
|
108
|
+
const name = getConstructorName(proto);
|
|
109
|
+
if (name === null) {
|
|
110
|
+
return [];
|
|
111
|
+
}
|
|
112
|
+
return [name, ...getConstructorNames(proto)];
|
|
113
|
+
}
|
|
114
|
+
function isInstanceOf(v, ctor) {
|
|
115
|
+
return getConstructorNames(v).includes(ctor.name);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// src/client/utils.ts
|
|
31
119
|
var makeNotifyRequest = async (requester, eventId, eventData) => {
|
|
32
120
|
const result = await requester.request({
|
|
33
121
|
path: ["v2", "notify", eventId],
|
|
@@ -67,7 +155,7 @@ var getSteps = async (requester, workflowRunId, messageId, debug) => {
|
|
|
67
155
|
return { steps: filteredSteps, workflowRunEnded: false };
|
|
68
156
|
}
|
|
69
157
|
} catch (error) {
|
|
70
|
-
if (error
|
|
158
|
+
if (isInstanceOf(error, import_qstash2.QstashError) && error.status === 404) {
|
|
71
159
|
await debug?.log("WARN", "ENDPOINT_START", {
|
|
72
160
|
message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
|
|
73
161
|
error
|
|
@@ -92,65 +180,13 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
|
|
|
92
180
|
var DEFAULT_CONTENT_TYPE = "application/json";
|
|
93
181
|
var NO_CONCURRENCY = 1;
|
|
94
182
|
var DEFAULT_RETRIES = 3;
|
|
95
|
-
var VERSION = "v0.2.
|
|
183
|
+
var VERSION = "v0.2.22";
|
|
96
184
|
var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
|
|
97
185
|
var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
|
|
98
186
|
var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
|
|
99
187
|
var TELEMETRY_HEADER_RUNTIME = "Upstash-Telemetry-Runtime";
|
|
100
188
|
var TELEMETRY_HEADER_AGENT = "Upstash-Telemetry-Agent";
|
|
101
189
|
|
|
102
|
-
// src/error.ts
|
|
103
|
-
var import_qstash2 = require("@upstash/qstash");
|
|
104
|
-
var WorkflowError = class extends import_qstash2.QstashError {
|
|
105
|
-
constructor(message) {
|
|
106
|
-
super(message);
|
|
107
|
-
this.name = "WorkflowError";
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
var WorkflowAbort = class extends Error {
|
|
111
|
-
stepInfo;
|
|
112
|
-
stepName;
|
|
113
|
-
/**
|
|
114
|
-
* whether workflow is to be canceled on abort
|
|
115
|
-
*/
|
|
116
|
-
cancelWorkflow;
|
|
117
|
-
/**
|
|
118
|
-
*
|
|
119
|
-
* @param stepName name of the aborting step
|
|
120
|
-
* @param stepInfo step information
|
|
121
|
-
* @param cancelWorkflow
|
|
122
|
-
*/
|
|
123
|
-
constructor(stepName, stepInfo, cancelWorkflow = false) {
|
|
124
|
-
super(
|
|
125
|
-
`This is an Upstash Workflow error thrown after a step executes. It is expected to be raised. Make sure that you await for each step. Also, if you are using try/catch blocks, you should not wrap context.run/sleep/sleepUntil/call methods with try/catch. Aborting workflow after executing step '${stepName}'.`
|
|
126
|
-
);
|
|
127
|
-
this.name = "WorkflowAbort";
|
|
128
|
-
this.stepName = stepName;
|
|
129
|
-
this.stepInfo = stepInfo;
|
|
130
|
-
this.cancelWorkflow = cancelWorkflow;
|
|
131
|
-
}
|
|
132
|
-
};
|
|
133
|
-
var WorkflowNonRetryableError = class extends WorkflowAbort {
|
|
134
|
-
/**
|
|
135
|
-
* @param message error message to be displayed
|
|
136
|
-
*/
|
|
137
|
-
constructor(message) {
|
|
138
|
-
super("fail", void 0, false);
|
|
139
|
-
this.name = "WorkflowNonRetryableError";
|
|
140
|
-
if (message) this.message = message;
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
var formatWorkflowError = (error) => {
|
|
144
|
-
return error instanceof Error ? {
|
|
145
|
-
error: error.name,
|
|
146
|
-
message: error.message,
|
|
147
|
-
stack: error.stack
|
|
148
|
-
} : {
|
|
149
|
-
error: "Error",
|
|
150
|
-
message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
|
|
151
|
-
};
|
|
152
|
-
};
|
|
153
|
-
|
|
154
190
|
// src/context/auto-executor.ts
|
|
155
191
|
var import_qstash5 = require("@upstash/qstash");
|
|
156
192
|
|
|
@@ -710,17 +746,17 @@ var triggerRouteFunction = async ({
|
|
|
710
746
|
return ok("workflow-finished");
|
|
711
747
|
} catch (error) {
|
|
712
748
|
const error_ = error;
|
|
713
|
-
if (error
|
|
749
|
+
if (isInstanceOf(error, import_qstash3.QstashError) && error.status === 400) {
|
|
714
750
|
await debug?.log("WARN", "RESPONSE_WORKFLOW", {
|
|
715
751
|
message: `tried to append to a cancelled workflow. exiting without publishing.`,
|
|
716
752
|
name: error.name,
|
|
717
753
|
errorMessage: error.message
|
|
718
754
|
});
|
|
719
755
|
return ok("workflow-was-finished");
|
|
720
|
-
} else if (
|
|
721
|
-
return err(error_);
|
|
722
|
-
} else if (error_ instanceof WorkflowNonRetryableError) {
|
|
756
|
+
} else if (isInstanceOf(error_, WorkflowNonRetryableError) || isInstanceOf(error_, WorkflowRetryAfterError)) {
|
|
723
757
|
return ok(error_);
|
|
758
|
+
} else if (!isInstanceOf(error_, WorkflowAbort)) {
|
|
759
|
+
return err(error_);
|
|
724
760
|
} else if (error_.cancelWorkflow) {
|
|
725
761
|
await onCancel();
|
|
726
762
|
return ok("workflow-finished");
|
|
@@ -2027,7 +2063,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2027
2063
|
});
|
|
2028
2064
|
throw new WorkflowAbort(parallelStep.stepName, resultStep);
|
|
2029
2065
|
} catch (error) {
|
|
2030
|
-
if (error
|
|
2066
|
+
if (isInstanceOf(error, WorkflowAbort) || isInstanceOf(error, import_qstash5.QstashError) && error.status === 400) {
|
|
2031
2067
|
throw error;
|
|
2032
2068
|
}
|
|
2033
2069
|
throw new WorkflowError(
|
|
@@ -2134,7 +2170,7 @@ var validateParallelSteps = (lazySteps, stepsFromRequest) => {
|
|
|
2134
2170
|
validateStep(lazySteps[index], stepFromRequest);
|
|
2135
2171
|
}
|
|
2136
2172
|
} catch (error) {
|
|
2137
|
-
if (error
|
|
2173
|
+
if (isInstanceOf(error, WorkflowError)) {
|
|
2138
2174
|
const lazyStepNames = lazySteps.map((lazyStep) => lazyStep.stepName);
|
|
2139
2175
|
const lazyStepTypes = lazySteps.map((lazyStep) => lazyStep.stepType);
|
|
2140
2176
|
const requestStepNames = stepsFromRequest.map((step) => step.stepName);
|
|
@@ -2315,7 +2351,7 @@ var fetchWithContextCall = async (context, agentCallParams, ...params) => {
|
|
|
2315
2351
|
headers: responseHeaders
|
|
2316
2352
|
});
|
|
2317
2353
|
} catch (error) {
|
|
2318
|
-
if (error instanceof Error && error
|
|
2354
|
+
if (error instanceof Error && isInstanceOf(error, WorkflowAbort)) {
|
|
2319
2355
|
throw error;
|
|
2320
2356
|
} else {
|
|
2321
2357
|
console.error("Error in fetch implementation:", error);
|
|
@@ -2417,10 +2453,10 @@ var Agent = class {
|
|
|
2417
2453
|
});
|
|
2418
2454
|
return { text: result.text };
|
|
2419
2455
|
} catch (error) {
|
|
2420
|
-
if (error
|
|
2421
|
-
if (error.cause instanceof Error && error.cause
|
|
2456
|
+
if (isInstanceOf(error, import_ai2.ToolExecutionError)) {
|
|
2457
|
+
if (error.cause instanceof Error && isInstanceOf(error.cause, WorkflowAbort)) {
|
|
2422
2458
|
throw error.cause;
|
|
2423
|
-
} else if (error.cause
|
|
2459
|
+
} else if (isInstanceOf(error.cause, import_ai2.ToolExecutionError) && isInstanceOf(error.cause.cause, WorkflowAbort)) {
|
|
2424
2460
|
throw error.cause.cause;
|
|
2425
2461
|
} else {
|
|
2426
2462
|
throw error;
|
|
@@ -3169,7 +3205,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
3169
3205
|
try {
|
|
3170
3206
|
await routeFunction(disabledContext);
|
|
3171
3207
|
} catch (error) {
|
|
3172
|
-
if (error
|
|
3208
|
+
if (isInstanceOf(error, WorkflowAbort) && error.stepName === this.disabledMessage || isInstanceOf(error, WorkflowNonRetryableError) || isInstanceOf(error, WorkflowRetryAfterError)) {
|
|
3173
3209
|
return ok("step-found");
|
|
3174
3210
|
}
|
|
3175
3211
|
console.warn(
|
|
@@ -3422,13 +3458,24 @@ var processOptions = (options) => {
|
|
|
3422
3458
|
},
|
|
3423
3459
|
status: 489
|
|
3424
3460
|
});
|
|
3425
|
-
} else if (detailedFinishCondition?.condition === "
|
|
3426
|
-
return new Response(detailedFinishCondition.result
|
|
3427
|
-
status: 200,
|
|
3461
|
+
} else if (detailedFinishCondition?.condition === "retry-after-error") {
|
|
3462
|
+
return new Response(JSON.stringify(formatWorkflowError(detailedFinishCondition.result)), {
|
|
3428
3463
|
headers: {
|
|
3464
|
+
"Retry-After": detailedFinishCondition.result.retryAfter.toString(),
|
|
3429
3465
|
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3430
|
-
}
|
|
3466
|
+
},
|
|
3467
|
+
status: 429
|
|
3431
3468
|
});
|
|
3469
|
+
} else if (detailedFinishCondition?.condition === "failure-callback") {
|
|
3470
|
+
return new Response(
|
|
3471
|
+
JSON.stringify({ result: detailedFinishCondition.result ?? void 0 }),
|
|
3472
|
+
{
|
|
3473
|
+
status: 200,
|
|
3474
|
+
headers: {
|
|
3475
|
+
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3476
|
+
}
|
|
3477
|
+
}
|
|
3478
|
+
);
|
|
3432
3479
|
}
|
|
3433
3480
|
return new Response(JSON.stringify({ workflowRunId }), {
|
|
3434
3481
|
status: 200,
|
|
@@ -3638,12 +3685,18 @@ var serveBase = (routeFunction, telemetry2, options) => {
|
|
|
3638
3685
|
},
|
|
3639
3686
|
debug
|
|
3640
3687
|
});
|
|
3641
|
-
if (result.isOk() && result.value
|
|
3688
|
+
if (result.isOk() && isInstanceOf(result.value, WorkflowNonRetryableError)) {
|
|
3642
3689
|
return onStepFinish(workflowRunId, result.value, {
|
|
3643
3690
|
condition: "non-retryable-error",
|
|
3644
3691
|
result: result.value
|
|
3645
3692
|
});
|
|
3646
3693
|
}
|
|
3694
|
+
if (result.isOk() && isInstanceOf(result.value, WorkflowRetryAfterError)) {
|
|
3695
|
+
return onStepFinish(workflowRunId, result.value, {
|
|
3696
|
+
condition: "retry-after-error",
|
|
3697
|
+
result: result.value
|
|
3698
|
+
});
|
|
3699
|
+
}
|
|
3647
3700
|
if (result.isErr()) {
|
|
3648
3701
|
await debug?.log("ERROR", "ERROR", { error: result.error.message });
|
|
3649
3702
|
throw result.error;
|
|
@@ -3674,7 +3727,7 @@ var serveBase = (routeFunction, telemetry2, options) => {
|
|
|
3674
3727
|
const errorMessage = `Error while running onError callback: '${formattedOnErrorError.message}'.
|
|
3675
3728
|
Original error: '${formattedError.message}'`;
|
|
3676
3729
|
console.error(errorMessage);
|
|
3677
|
-
return new Response(errorMessage, {
|
|
3730
|
+
return new Response(JSON.stringify({ error: errorMessage }), {
|
|
3678
3731
|
status: 500,
|
|
3679
3732
|
headers: {
|
|
3680
3733
|
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
package/svelte.mjs
CHANGED
package/tanstack.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as RouteFunction,
|
|
2
|
-
import { s as serveManyBase } from './serve-many-
|
|
1
|
+
import { R as RouteFunction, o as PublicServeOptions, z as InvokableWorkflow } from './types-9nCq6bRP.mjs';
|
|
2
|
+
import { s as serveManyBase } from './serve-many-CctdYIfB.mjs';
|
|
3
3
|
import '@upstash/qstash';
|
|
4
4
|
import 'zod';
|
|
5
5
|
import 'ai';
|
package/tanstack.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as RouteFunction,
|
|
2
|
-
import { s as serveManyBase } from './serve-many-
|
|
1
|
+
import { R as RouteFunction, o as PublicServeOptions, z as InvokableWorkflow } from './types-9nCq6bRP.js';
|
|
2
|
+
import { s as serveManyBase } from './serve-many-BXDr30rl.js';
|
|
3
3
|
import '@upstash/qstash';
|
|
4
4
|
import 'zod';
|
|
5
5
|
import 'ai';
|
package/tanstack.js
CHANGED
|
@@ -27,7 +27,95 @@ __export(tanstack_exports, {
|
|
|
27
27
|
module.exports = __toCommonJS(tanstack_exports);
|
|
28
28
|
|
|
29
29
|
// src/client/utils.ts
|
|
30
|
+
var import_qstash2 = require("@upstash/qstash");
|
|
31
|
+
|
|
32
|
+
// src/error.ts
|
|
30
33
|
var import_qstash = require("@upstash/qstash");
|
|
34
|
+
var WorkflowError = class extends import_qstash.QstashError {
|
|
35
|
+
constructor(message) {
|
|
36
|
+
super(message);
|
|
37
|
+
this.name = "WorkflowError";
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
var WorkflowAbort = class extends Error {
|
|
41
|
+
stepInfo;
|
|
42
|
+
stepName;
|
|
43
|
+
/**
|
|
44
|
+
* whether workflow is to be canceled on abort
|
|
45
|
+
*/
|
|
46
|
+
cancelWorkflow;
|
|
47
|
+
/**
|
|
48
|
+
*
|
|
49
|
+
* @param stepName name of the aborting step
|
|
50
|
+
* @param stepInfo step information
|
|
51
|
+
* @param cancelWorkflow
|
|
52
|
+
*/
|
|
53
|
+
constructor(stepName, stepInfo, cancelWorkflow = false) {
|
|
54
|
+
super(
|
|
55
|
+
`This is an Upstash Workflow error thrown after a step executes. It is expected to be raised. Make sure that you await for each step. Also, if you are using try/catch blocks, you should not wrap context.run/sleep/sleepUntil/call methods with try/catch. Aborting workflow after executing step '${stepName}'.`
|
|
56
|
+
);
|
|
57
|
+
this.name = "WorkflowAbort";
|
|
58
|
+
this.stepName = stepName;
|
|
59
|
+
this.stepInfo = stepInfo;
|
|
60
|
+
this.cancelWorkflow = cancelWorkflow;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
var WorkflowNonRetryableError = class extends WorkflowAbort {
|
|
64
|
+
/**
|
|
65
|
+
* @param message error message to be displayed
|
|
66
|
+
*/
|
|
67
|
+
constructor(message) {
|
|
68
|
+
super("fail", void 0, false);
|
|
69
|
+
this.name = "WorkflowNonRetryableError";
|
|
70
|
+
if (message) this.message = message;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
var WorkflowRetryAfterError = class extends WorkflowAbort {
|
|
74
|
+
retryAfter;
|
|
75
|
+
/**
|
|
76
|
+
* @param retryAfter time in seconds after which the workflow should be retried
|
|
77
|
+
* @param message error message to be displayed
|
|
78
|
+
*/
|
|
79
|
+
constructor(message, retryAfter) {
|
|
80
|
+
super("retry", void 0, false);
|
|
81
|
+
this.name = "WorkflowRetryAfterError";
|
|
82
|
+
this.retryAfter = retryAfter;
|
|
83
|
+
if (message) this.message = message;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
var formatWorkflowError = (error) => {
|
|
87
|
+
return error instanceof Error ? {
|
|
88
|
+
error: error.name,
|
|
89
|
+
message: error.message,
|
|
90
|
+
stack: error.stack
|
|
91
|
+
} : {
|
|
92
|
+
error: "Error",
|
|
93
|
+
message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
function getConstructorName(obj) {
|
|
97
|
+
if (obj === null || obj === void 0) {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
const ctor = obj.constructor;
|
|
101
|
+
if (!ctor || ctor.name === "Object") {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
return ctor.name;
|
|
105
|
+
}
|
|
106
|
+
function getConstructorNames(obj) {
|
|
107
|
+
const proto = Object.getPrototypeOf(obj);
|
|
108
|
+
const name = getConstructorName(proto);
|
|
109
|
+
if (name === null) {
|
|
110
|
+
return [];
|
|
111
|
+
}
|
|
112
|
+
return [name, ...getConstructorNames(proto)];
|
|
113
|
+
}
|
|
114
|
+
function isInstanceOf(v, ctor) {
|
|
115
|
+
return getConstructorNames(v).includes(ctor.name);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// src/client/utils.ts
|
|
31
119
|
var makeNotifyRequest = async (requester, eventId, eventData) => {
|
|
32
120
|
const result = await requester.request({
|
|
33
121
|
path: ["v2", "notify", eventId],
|
|
@@ -67,7 +155,7 @@ var getSteps = async (requester, workflowRunId, messageId, debug) => {
|
|
|
67
155
|
return { steps: filteredSteps, workflowRunEnded: false };
|
|
68
156
|
}
|
|
69
157
|
} catch (error) {
|
|
70
|
-
if (error
|
|
158
|
+
if (isInstanceOf(error, import_qstash2.QstashError) && error.status === 404) {
|
|
71
159
|
await debug?.log("WARN", "ENDPOINT_START", {
|
|
72
160
|
message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
|
|
73
161
|
error
|
|
@@ -92,65 +180,13 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
|
|
|
92
180
|
var DEFAULT_CONTENT_TYPE = "application/json";
|
|
93
181
|
var NO_CONCURRENCY = 1;
|
|
94
182
|
var DEFAULT_RETRIES = 3;
|
|
95
|
-
var VERSION = "v0.2.
|
|
183
|
+
var VERSION = "v0.2.22";
|
|
96
184
|
var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
|
|
97
185
|
var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
|
|
98
186
|
var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
|
|
99
187
|
var TELEMETRY_HEADER_RUNTIME = "Upstash-Telemetry-Runtime";
|
|
100
188
|
var TELEMETRY_HEADER_AGENT = "Upstash-Telemetry-Agent";
|
|
101
189
|
|
|
102
|
-
// src/error.ts
|
|
103
|
-
var import_qstash2 = require("@upstash/qstash");
|
|
104
|
-
var WorkflowError = class extends import_qstash2.QstashError {
|
|
105
|
-
constructor(message) {
|
|
106
|
-
super(message);
|
|
107
|
-
this.name = "WorkflowError";
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
var WorkflowAbort = class extends Error {
|
|
111
|
-
stepInfo;
|
|
112
|
-
stepName;
|
|
113
|
-
/**
|
|
114
|
-
* whether workflow is to be canceled on abort
|
|
115
|
-
*/
|
|
116
|
-
cancelWorkflow;
|
|
117
|
-
/**
|
|
118
|
-
*
|
|
119
|
-
* @param stepName name of the aborting step
|
|
120
|
-
* @param stepInfo step information
|
|
121
|
-
* @param cancelWorkflow
|
|
122
|
-
*/
|
|
123
|
-
constructor(stepName, stepInfo, cancelWorkflow = false) {
|
|
124
|
-
super(
|
|
125
|
-
`This is an Upstash Workflow error thrown after a step executes. It is expected to be raised. Make sure that you await for each step. Also, if you are using try/catch blocks, you should not wrap context.run/sleep/sleepUntil/call methods with try/catch. Aborting workflow after executing step '${stepName}'.`
|
|
126
|
-
);
|
|
127
|
-
this.name = "WorkflowAbort";
|
|
128
|
-
this.stepName = stepName;
|
|
129
|
-
this.stepInfo = stepInfo;
|
|
130
|
-
this.cancelWorkflow = cancelWorkflow;
|
|
131
|
-
}
|
|
132
|
-
};
|
|
133
|
-
var WorkflowNonRetryableError = class extends WorkflowAbort {
|
|
134
|
-
/**
|
|
135
|
-
* @param message error message to be displayed
|
|
136
|
-
*/
|
|
137
|
-
constructor(message) {
|
|
138
|
-
super("fail", void 0, false);
|
|
139
|
-
this.name = "WorkflowNonRetryableError";
|
|
140
|
-
if (message) this.message = message;
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
var formatWorkflowError = (error) => {
|
|
144
|
-
return error instanceof Error ? {
|
|
145
|
-
error: error.name,
|
|
146
|
-
message: error.message,
|
|
147
|
-
stack: error.stack
|
|
148
|
-
} : {
|
|
149
|
-
error: "Error",
|
|
150
|
-
message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
|
|
151
|
-
};
|
|
152
|
-
};
|
|
153
|
-
|
|
154
190
|
// src/context/auto-executor.ts
|
|
155
191
|
var import_qstash5 = require("@upstash/qstash");
|
|
156
192
|
|
|
@@ -710,17 +746,17 @@ var triggerRouteFunction = async ({
|
|
|
710
746
|
return ok("workflow-finished");
|
|
711
747
|
} catch (error) {
|
|
712
748
|
const error_ = error;
|
|
713
|
-
if (error
|
|
749
|
+
if (isInstanceOf(error, import_qstash3.QstashError) && error.status === 400) {
|
|
714
750
|
await debug?.log("WARN", "RESPONSE_WORKFLOW", {
|
|
715
751
|
message: `tried to append to a cancelled workflow. exiting without publishing.`,
|
|
716
752
|
name: error.name,
|
|
717
753
|
errorMessage: error.message
|
|
718
754
|
});
|
|
719
755
|
return ok("workflow-was-finished");
|
|
720
|
-
} else if (
|
|
721
|
-
return err(error_);
|
|
722
|
-
} else if (error_ instanceof WorkflowNonRetryableError) {
|
|
756
|
+
} else if (isInstanceOf(error_, WorkflowNonRetryableError) || isInstanceOf(error_, WorkflowRetryAfterError)) {
|
|
723
757
|
return ok(error_);
|
|
758
|
+
} else if (!isInstanceOf(error_, WorkflowAbort)) {
|
|
759
|
+
return err(error_);
|
|
724
760
|
} else if (error_.cancelWorkflow) {
|
|
725
761
|
await onCancel();
|
|
726
762
|
return ok("workflow-finished");
|
|
@@ -2027,7 +2063,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2027
2063
|
});
|
|
2028
2064
|
throw new WorkflowAbort(parallelStep.stepName, resultStep);
|
|
2029
2065
|
} catch (error) {
|
|
2030
|
-
if (error
|
|
2066
|
+
if (isInstanceOf(error, WorkflowAbort) || isInstanceOf(error, import_qstash5.QstashError) && error.status === 400) {
|
|
2031
2067
|
throw error;
|
|
2032
2068
|
}
|
|
2033
2069
|
throw new WorkflowError(
|
|
@@ -2134,7 +2170,7 @@ var validateParallelSteps = (lazySteps, stepsFromRequest) => {
|
|
|
2134
2170
|
validateStep(lazySteps[index], stepFromRequest);
|
|
2135
2171
|
}
|
|
2136
2172
|
} catch (error) {
|
|
2137
|
-
if (error
|
|
2173
|
+
if (isInstanceOf(error, WorkflowError)) {
|
|
2138
2174
|
const lazyStepNames = lazySteps.map((lazyStep) => lazyStep.stepName);
|
|
2139
2175
|
const lazyStepTypes = lazySteps.map((lazyStep) => lazyStep.stepType);
|
|
2140
2176
|
const requestStepNames = stepsFromRequest.map((step) => step.stepName);
|
|
@@ -2315,7 +2351,7 @@ var fetchWithContextCall = async (context, agentCallParams, ...params) => {
|
|
|
2315
2351
|
headers: responseHeaders
|
|
2316
2352
|
});
|
|
2317
2353
|
} catch (error) {
|
|
2318
|
-
if (error instanceof Error && error
|
|
2354
|
+
if (error instanceof Error && isInstanceOf(error, WorkflowAbort)) {
|
|
2319
2355
|
throw error;
|
|
2320
2356
|
} else {
|
|
2321
2357
|
console.error("Error in fetch implementation:", error);
|
|
@@ -2417,10 +2453,10 @@ var Agent = class {
|
|
|
2417
2453
|
});
|
|
2418
2454
|
return { text: result.text };
|
|
2419
2455
|
} catch (error) {
|
|
2420
|
-
if (error
|
|
2421
|
-
if (error.cause instanceof Error && error.cause
|
|
2456
|
+
if (isInstanceOf(error, import_ai2.ToolExecutionError)) {
|
|
2457
|
+
if (error.cause instanceof Error && isInstanceOf(error.cause, WorkflowAbort)) {
|
|
2422
2458
|
throw error.cause;
|
|
2423
|
-
} else if (error.cause
|
|
2459
|
+
} else if (isInstanceOf(error.cause, import_ai2.ToolExecutionError) && isInstanceOf(error.cause.cause, WorkflowAbort)) {
|
|
2424
2460
|
throw error.cause.cause;
|
|
2425
2461
|
} else {
|
|
2426
2462
|
throw error;
|
|
@@ -3169,7 +3205,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
3169
3205
|
try {
|
|
3170
3206
|
await routeFunction(disabledContext);
|
|
3171
3207
|
} catch (error) {
|
|
3172
|
-
if (error
|
|
3208
|
+
if (isInstanceOf(error, WorkflowAbort) && error.stepName === this.disabledMessage || isInstanceOf(error, WorkflowNonRetryableError) || isInstanceOf(error, WorkflowRetryAfterError)) {
|
|
3173
3209
|
return ok("step-found");
|
|
3174
3210
|
}
|
|
3175
3211
|
console.warn(
|
|
@@ -3422,13 +3458,24 @@ var processOptions = (options) => {
|
|
|
3422
3458
|
},
|
|
3423
3459
|
status: 489
|
|
3424
3460
|
});
|
|
3425
|
-
} else if (detailedFinishCondition?.condition === "
|
|
3426
|
-
return new Response(detailedFinishCondition.result
|
|
3427
|
-
status: 200,
|
|
3461
|
+
} else if (detailedFinishCondition?.condition === "retry-after-error") {
|
|
3462
|
+
return new Response(JSON.stringify(formatWorkflowError(detailedFinishCondition.result)), {
|
|
3428
3463
|
headers: {
|
|
3464
|
+
"Retry-After": detailedFinishCondition.result.retryAfter.toString(),
|
|
3429
3465
|
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3430
|
-
}
|
|
3466
|
+
},
|
|
3467
|
+
status: 429
|
|
3431
3468
|
});
|
|
3469
|
+
} else if (detailedFinishCondition?.condition === "failure-callback") {
|
|
3470
|
+
return new Response(
|
|
3471
|
+
JSON.stringify({ result: detailedFinishCondition.result ?? void 0 }),
|
|
3472
|
+
{
|
|
3473
|
+
status: 200,
|
|
3474
|
+
headers: {
|
|
3475
|
+
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3476
|
+
}
|
|
3477
|
+
}
|
|
3478
|
+
);
|
|
3432
3479
|
}
|
|
3433
3480
|
return new Response(JSON.stringify({ workflowRunId }), {
|
|
3434
3481
|
status: 200,
|
|
@@ -3638,12 +3685,18 @@ var serveBase = (routeFunction, telemetry2, options) => {
|
|
|
3638
3685
|
},
|
|
3639
3686
|
debug
|
|
3640
3687
|
});
|
|
3641
|
-
if (result.isOk() && result.value
|
|
3688
|
+
if (result.isOk() && isInstanceOf(result.value, WorkflowNonRetryableError)) {
|
|
3642
3689
|
return onStepFinish(workflowRunId, result.value, {
|
|
3643
3690
|
condition: "non-retryable-error",
|
|
3644
3691
|
result: result.value
|
|
3645
3692
|
});
|
|
3646
3693
|
}
|
|
3694
|
+
if (result.isOk() && isInstanceOf(result.value, WorkflowRetryAfterError)) {
|
|
3695
|
+
return onStepFinish(workflowRunId, result.value, {
|
|
3696
|
+
condition: "retry-after-error",
|
|
3697
|
+
result: result.value
|
|
3698
|
+
});
|
|
3699
|
+
}
|
|
3647
3700
|
if (result.isErr()) {
|
|
3648
3701
|
await debug?.log("ERROR", "ERROR", { error: result.error.message });
|
|
3649
3702
|
throw result.error;
|
|
@@ -3674,7 +3727,7 @@ var serveBase = (routeFunction, telemetry2, options) => {
|
|
|
3674
3727
|
const errorMessage = `Error while running onError callback: '${formattedOnErrorError.message}'.
|
|
3675
3728
|
Original error: '${formattedError.message}'`;
|
|
3676
3729
|
console.error(errorMessage);
|
|
3677
|
-
return new Response(errorMessage, {
|
|
3730
|
+
return new Response(JSON.stringify({ error: errorMessage }), {
|
|
3678
3731
|
status: 500,
|
|
3679
3732
|
headers: {
|
|
3680
3733
|
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|