@upstash/workflow 0.2.22-rc → 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-CAQSUCHB.mjs → chunk-BON2RKOR.mjs} +93 -41
- 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 +126 -72
- package/express.mjs +3 -2
- 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/README.md
CHANGED
|
@@ -83,6 +83,15 @@ waiting for an event or get the workflows waiting for an event:
|
|
|
83
83
|
import { Client } from "@upstash/workflow";
|
|
84
84
|
const client = new Client({ token: "<QSTASH_TOKEN>" });
|
|
85
85
|
|
|
86
|
+
// trigger a workflow
|
|
87
|
+
const { workflowRunId } = await client.trigger({
|
|
88
|
+
url: "https://workflow-endpoint.com",
|
|
89
|
+
body: "hello there!", // Optional body
|
|
90
|
+
headers: { ... }, // Optional headers
|
|
91
|
+
workflowRunId: "my-workflow", // Optional workflow run ID
|
|
92
|
+
retries: 3 // Optional retries for the initial request
|
|
93
|
+
});
|
|
94
|
+
|
|
86
95
|
// cancel workflow:
|
|
87
96
|
await client.cancel({ workflowRunId: "<WORKFLOW_RUN_ID>" });
|
|
88
97
|
|
|
@@ -98,6 +107,36 @@ const result = await client.getWaiters({
|
|
|
98
107
|
});
|
|
99
108
|
```
|
|
100
109
|
|
|
110
|
+
## Telemetry
|
|
111
|
+
|
|
112
|
+
This sdk sends anonymous telemetry headers to help us improve your experience.
|
|
113
|
+
We collect the following:
|
|
114
|
+
|
|
115
|
+
- SDK version
|
|
116
|
+
- Platform (Cloudflare, AWS or Vercel)
|
|
117
|
+
- Runtime version (node@18.x)
|
|
118
|
+
|
|
119
|
+
You can opt out by setting `disableTelemetry: true` when triggering the workflow and in the serve options:
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
// client
|
|
123
|
+
const client = new Client(/***/);
|
|
124
|
+
await client.trigger({
|
|
125
|
+
// ...
|
|
126
|
+
disableTelemetry: true,
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// workflow endpoint
|
|
130
|
+
export const { POST } = serve(
|
|
131
|
+
async (context) => {
|
|
132
|
+
// ...
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
disableTelemetry: true,
|
|
136
|
+
}
|
|
137
|
+
);
|
|
138
|
+
```
|
|
139
|
+
|
|
101
140
|
## Contributing
|
|
102
141
|
|
|
103
142
|
### Setup
|
package/astro.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { APIContext, APIRoute } from 'astro';
|
|
2
|
-
import {
|
|
3
|
-
import { s as serveManyBase } from './serve-many-
|
|
2
|
+
import { h as WorkflowContext, o as PublicServeOptions, z as InvokableWorkflow } from './types-9nCq6bRP.mjs';
|
|
3
|
+
import { s as serveManyBase } from './serve-many-CctdYIfB.mjs';
|
|
4
4
|
import '@upstash/qstash';
|
|
5
5
|
import 'zod';
|
|
6
6
|
import 'ai';
|
package/astro.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { APIContext, APIRoute } from 'astro';
|
|
2
|
-
import {
|
|
3
|
-
import { s as serveManyBase } from './serve-many-
|
|
2
|
+
import { h as WorkflowContext, o as PublicServeOptions, z as InvokableWorkflow } from './types-9nCq6bRP.js';
|
|
3
|
+
import { s as serveManyBase } from './serve-many-BXDr30rl.js';
|
|
4
4
|
import '@upstash/qstash';
|
|
5
5
|
import 'zod';
|
|
6
6
|
import 'ai';
|
package/astro.js
CHANGED
|
@@ -27,7 +27,95 @@ __export(astro_exports, {
|
|
|
27
27
|
module.exports = __toCommonJS(astro_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/astro.mjs
CHANGED
|
@@ -1,23 +1,3 @@
|
|
|
1
|
-
// src/constants.ts
|
|
2
|
-
var WORKFLOW_ID_HEADER = "Upstash-Workflow-RunId";
|
|
3
|
-
var WORKFLOW_INIT_HEADER = "Upstash-Workflow-Init";
|
|
4
|
-
var WORKFLOW_URL_HEADER = "Upstash-Workflow-Url";
|
|
5
|
-
var WORKFLOW_FAILURE_HEADER = "Upstash-Workflow-Is-Failure";
|
|
6
|
-
var WORKFLOW_FEATURE_HEADER = "Upstash-Feature-Set";
|
|
7
|
-
var WORKFLOW_INVOKE_COUNT_HEADER = "Upstash-Workflow-Invoke-Count";
|
|
8
|
-
var WORKFLOW_LABEL_HEADER = "Upstash-Label";
|
|
9
|
-
var WORKFLOW_PROTOCOL_VERSION = "1";
|
|
10
|
-
var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
|
|
11
|
-
var DEFAULT_CONTENT_TYPE = "application/json";
|
|
12
|
-
var NO_CONCURRENCY = 1;
|
|
13
|
-
var DEFAULT_RETRIES = 3;
|
|
14
|
-
var VERSION = "v0.2.21";
|
|
15
|
-
var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
|
|
16
|
-
var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
|
|
17
|
-
var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
|
|
18
|
-
var TELEMETRY_HEADER_RUNTIME = "Upstash-Telemetry-Runtime";
|
|
19
|
-
var TELEMETRY_HEADER_AGENT = "Upstash-Telemetry-Agent";
|
|
20
|
-
|
|
21
1
|
// src/error.ts
|
|
22
2
|
import { QstashError } from "@upstash/qstash";
|
|
23
3
|
var WorkflowError = class extends QstashError {
|
|
@@ -59,6 +39,19 @@ var WorkflowNonRetryableError = class extends WorkflowAbort {
|
|
|
59
39
|
if (message) this.message = message;
|
|
60
40
|
}
|
|
61
41
|
};
|
|
42
|
+
var WorkflowRetryAfterError = class extends WorkflowAbort {
|
|
43
|
+
retryAfter;
|
|
44
|
+
/**
|
|
45
|
+
* @param retryAfter time in seconds after which the workflow should be retried
|
|
46
|
+
* @param message error message to be displayed
|
|
47
|
+
*/
|
|
48
|
+
constructor(message, retryAfter) {
|
|
49
|
+
super("retry", void 0, false);
|
|
50
|
+
this.name = "WorkflowRetryAfterError";
|
|
51
|
+
this.retryAfter = retryAfter;
|
|
52
|
+
if (message) this.message = message;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
62
55
|
var formatWorkflowError = (error) => {
|
|
63
56
|
return error instanceof Error ? {
|
|
64
57
|
error: error.name,
|
|
@@ -69,6 +62,47 @@ var formatWorkflowError = (error) => {
|
|
|
69
62
|
message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
|
|
70
63
|
};
|
|
71
64
|
};
|
|
65
|
+
function getConstructorName(obj) {
|
|
66
|
+
if (obj === null || obj === void 0) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const ctor = obj.constructor;
|
|
70
|
+
if (!ctor || ctor.name === "Object") {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
return ctor.name;
|
|
74
|
+
}
|
|
75
|
+
function getConstructorNames(obj) {
|
|
76
|
+
const proto = Object.getPrototypeOf(obj);
|
|
77
|
+
const name = getConstructorName(proto);
|
|
78
|
+
if (name === null) {
|
|
79
|
+
return [];
|
|
80
|
+
}
|
|
81
|
+
return [name, ...getConstructorNames(proto)];
|
|
82
|
+
}
|
|
83
|
+
function isInstanceOf(v, ctor) {
|
|
84
|
+
return getConstructorNames(v).includes(ctor.name);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// src/constants.ts
|
|
88
|
+
var WORKFLOW_ID_HEADER = "Upstash-Workflow-RunId";
|
|
89
|
+
var WORKFLOW_INIT_HEADER = "Upstash-Workflow-Init";
|
|
90
|
+
var WORKFLOW_URL_HEADER = "Upstash-Workflow-Url";
|
|
91
|
+
var WORKFLOW_FAILURE_HEADER = "Upstash-Workflow-Is-Failure";
|
|
92
|
+
var WORKFLOW_FEATURE_HEADER = "Upstash-Feature-Set";
|
|
93
|
+
var WORKFLOW_INVOKE_COUNT_HEADER = "Upstash-Workflow-Invoke-Count";
|
|
94
|
+
var WORKFLOW_LABEL_HEADER = "Upstash-Label";
|
|
95
|
+
var WORKFLOW_PROTOCOL_VERSION = "1";
|
|
96
|
+
var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
|
|
97
|
+
var DEFAULT_CONTENT_TYPE = "application/json";
|
|
98
|
+
var NO_CONCURRENCY = 1;
|
|
99
|
+
var DEFAULT_RETRIES = 3;
|
|
100
|
+
var VERSION = "v0.2.22";
|
|
101
|
+
var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
|
|
102
|
+
var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
|
|
103
|
+
var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
|
|
104
|
+
var TELEMETRY_HEADER_RUNTIME = "Upstash-Telemetry-Runtime";
|
|
105
|
+
var TELEMETRY_HEADER_AGENT = "Upstash-Telemetry-Agent";
|
|
72
106
|
|
|
73
107
|
// src/types.ts
|
|
74
108
|
var StepTypes = [
|
|
@@ -131,7 +165,7 @@ var fetchWithContextCall = async (context, agentCallParams, ...params) => {
|
|
|
131
165
|
headers: responseHeaders
|
|
132
166
|
});
|
|
133
167
|
} catch (error) {
|
|
134
|
-
if (error instanceof Error && error
|
|
168
|
+
if (error instanceof Error && isInstanceOf(error, WorkflowAbort)) {
|
|
135
169
|
throw error;
|
|
136
170
|
} else {
|
|
137
171
|
console.error("Error in fetch implementation:", error);
|
|
@@ -342,7 +376,7 @@ var getSteps = async (requester, workflowRunId, messageId, debug) => {
|
|
|
342
376
|
return { steps: filteredSteps, workflowRunEnded: false };
|
|
343
377
|
}
|
|
344
378
|
} catch (error) {
|
|
345
|
-
if (error
|
|
379
|
+
if (isInstanceOf(error, QstashError2) && error.status === 404) {
|
|
346
380
|
await debug?.log("WARN", "ENDPOINT_START", {
|
|
347
381
|
message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
|
|
348
382
|
error
|
|
@@ -895,17 +929,17 @@ var triggerRouteFunction = async ({
|
|
|
895
929
|
return ok("workflow-finished");
|
|
896
930
|
} catch (error) {
|
|
897
931
|
const error_ = error;
|
|
898
|
-
if (error
|
|
932
|
+
if (isInstanceOf(error, QstashError3) && error.status === 400) {
|
|
899
933
|
await debug?.log("WARN", "RESPONSE_WORKFLOW", {
|
|
900
934
|
message: `tried to append to a cancelled workflow. exiting without publishing.`,
|
|
901
935
|
name: error.name,
|
|
902
936
|
errorMessage: error.message
|
|
903
937
|
});
|
|
904
938
|
return ok("workflow-was-finished");
|
|
905
|
-
} else if (
|
|
906
|
-
return err(error_);
|
|
907
|
-
} else if (error_ instanceof WorkflowNonRetryableError) {
|
|
939
|
+
} else if (isInstanceOf(error_, WorkflowNonRetryableError) || isInstanceOf(error_, WorkflowRetryAfterError)) {
|
|
908
940
|
return ok(error_);
|
|
941
|
+
} else if (!isInstanceOf(error_, WorkflowAbort)) {
|
|
942
|
+
return err(error_);
|
|
909
943
|
} else if (error_.cancelWorkflow) {
|
|
910
944
|
await onCancel();
|
|
911
945
|
return ok("workflow-finished");
|
|
@@ -2198,7 +2232,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2198
2232
|
});
|
|
2199
2233
|
throw new WorkflowAbort(parallelStep.stepName, resultStep);
|
|
2200
2234
|
} catch (error) {
|
|
2201
|
-
if (error
|
|
2235
|
+
if (isInstanceOf(error, WorkflowAbort) || isInstanceOf(error, QstashError5) && error.status === 400) {
|
|
2202
2236
|
throw error;
|
|
2203
2237
|
}
|
|
2204
2238
|
throw new WorkflowError(
|
|
@@ -2305,7 +2339,7 @@ var validateParallelSteps = (lazySteps, stepsFromRequest) => {
|
|
|
2305
2339
|
validateStep(lazySteps[index], stepFromRequest);
|
|
2306
2340
|
}
|
|
2307
2341
|
} catch (error) {
|
|
2308
|
-
if (error
|
|
2342
|
+
if (isInstanceOf(error, WorkflowError)) {
|
|
2309
2343
|
const lazyStepNames = lazySteps.map((lazyStep) => lazyStep.stepName);
|
|
2310
2344
|
const lazyStepTypes = lazySteps.map((lazyStep) => lazyStep.stepType);
|
|
2311
2345
|
const requestStepNames = stepsFromRequest.map((step) => step.stepName);
|
|
@@ -2504,10 +2538,10 @@ var Agent = class {
|
|
|
2504
2538
|
});
|
|
2505
2539
|
return { text: result.text };
|
|
2506
2540
|
} catch (error) {
|
|
2507
|
-
if (error
|
|
2508
|
-
if (error.cause instanceof Error && error.cause
|
|
2541
|
+
if (isInstanceOf(error, ToolExecutionError)) {
|
|
2542
|
+
if (error.cause instanceof Error && isInstanceOf(error.cause, WorkflowAbort)) {
|
|
2509
2543
|
throw error.cause;
|
|
2510
|
-
} else if (error.cause
|
|
2544
|
+
} else if (isInstanceOf(error.cause, ToolExecutionError) && isInstanceOf(error.cause.cause, WorkflowAbort)) {
|
|
2511
2545
|
throw error.cause.cause;
|
|
2512
2546
|
} else {
|
|
2513
2547
|
throw error;
|
|
@@ -3181,7 +3215,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
3181
3215
|
try {
|
|
3182
3216
|
await routeFunction(disabledContext);
|
|
3183
3217
|
} catch (error) {
|
|
3184
|
-
if (error
|
|
3218
|
+
if (isInstanceOf(error, WorkflowAbort) && error.stepName === this.disabledMessage || isInstanceOf(error, WorkflowNonRetryableError) || isInstanceOf(error, WorkflowRetryAfterError)) {
|
|
3185
3219
|
return ok("step-found");
|
|
3186
3220
|
}
|
|
3187
3221
|
console.warn(
|
|
@@ -3434,13 +3468,24 @@ var processOptions = (options) => {
|
|
|
3434
3468
|
},
|
|
3435
3469
|
status: 489
|
|
3436
3470
|
});
|
|
3437
|
-
} else if (detailedFinishCondition?.condition === "
|
|
3438
|
-
return new Response(detailedFinishCondition.result
|
|
3439
|
-
status: 200,
|
|
3471
|
+
} else if (detailedFinishCondition?.condition === "retry-after-error") {
|
|
3472
|
+
return new Response(JSON.stringify(formatWorkflowError(detailedFinishCondition.result)), {
|
|
3440
3473
|
headers: {
|
|
3474
|
+
"Retry-After": detailedFinishCondition.result.retryAfter.toString(),
|
|
3441
3475
|
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3442
|
-
}
|
|
3476
|
+
},
|
|
3477
|
+
status: 429
|
|
3443
3478
|
});
|
|
3479
|
+
} else if (detailedFinishCondition?.condition === "failure-callback") {
|
|
3480
|
+
return new Response(
|
|
3481
|
+
JSON.stringify({ result: detailedFinishCondition.result ?? void 0 }),
|
|
3482
|
+
{
|
|
3483
|
+
status: 200,
|
|
3484
|
+
headers: {
|
|
3485
|
+
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3486
|
+
}
|
|
3487
|
+
}
|
|
3488
|
+
);
|
|
3444
3489
|
}
|
|
3445
3490
|
return new Response(JSON.stringify({ workflowRunId }), {
|
|
3446
3491
|
status: 200,
|
|
@@ -3650,12 +3695,18 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
3650
3695
|
},
|
|
3651
3696
|
debug
|
|
3652
3697
|
});
|
|
3653
|
-
if (result.isOk() && result.value
|
|
3698
|
+
if (result.isOk() && isInstanceOf(result.value, WorkflowNonRetryableError)) {
|
|
3654
3699
|
return onStepFinish(workflowRunId, result.value, {
|
|
3655
3700
|
condition: "non-retryable-error",
|
|
3656
3701
|
result: result.value
|
|
3657
3702
|
});
|
|
3658
3703
|
}
|
|
3704
|
+
if (result.isOk() && isInstanceOf(result.value, WorkflowRetryAfterError)) {
|
|
3705
|
+
return onStepFinish(workflowRunId, result.value, {
|
|
3706
|
+
condition: "retry-after-error",
|
|
3707
|
+
result: result.value
|
|
3708
|
+
});
|
|
3709
|
+
}
|
|
3659
3710
|
if (result.isErr()) {
|
|
3660
3711
|
await debug?.log("ERROR", "ERROR", { error: result.error.message });
|
|
3661
3712
|
throw result.error;
|
|
@@ -3686,7 +3737,7 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
3686
3737
|
const errorMessage = `Error while running onError callback: '${formattedOnErrorError.message}'.
|
|
3687
3738
|
Original error: '${formattedError.message}'`;
|
|
3688
3739
|
console.error(errorMessage);
|
|
3689
|
-
return new Response(errorMessage, {
|
|
3740
|
+
return new Response(JSON.stringify({ error: errorMessage }), {
|
|
3690
3741
|
status: 500,
|
|
3691
3742
|
headers: {
|
|
3692
3743
|
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
@@ -3715,13 +3766,14 @@ var serve = (routeFunction, options) => {
|
|
|
3715
3766
|
};
|
|
3716
3767
|
|
|
3717
3768
|
export {
|
|
3769
|
+
WorkflowError,
|
|
3770
|
+
WorkflowAbort,
|
|
3771
|
+
WorkflowNonRetryableError,
|
|
3772
|
+
WorkflowRetryAfterError,
|
|
3718
3773
|
makeNotifyRequest,
|
|
3719
3774
|
makeGetWaitersRequest,
|
|
3720
3775
|
WORKFLOW_LABEL_HEADER,
|
|
3721
3776
|
SDK_TELEMETRY,
|
|
3722
|
-
WorkflowError,
|
|
3723
|
-
WorkflowAbort,
|
|
3724
|
-
WorkflowNonRetryableError,
|
|
3725
3777
|
getWorkflowRunId,
|
|
3726
3778
|
StepTypes,
|
|
3727
3779
|
triggerFirstInvocation,
|
package/cloudflare.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/cloudflare.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';
|