@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/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
|
|
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,65 +183,13 @@ 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.
|
|
186
|
+
var VERSION = "v0.2.22";
|
|
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
191
|
var TELEMETRY_HEADER_AGENT = "Upstash-Telemetry-Agent";
|
|
104
192
|
|
|
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
|
-
|
|
157
193
|
// src/context/auto-executor.ts
|
|
158
194
|
var import_qstash5 = require("@upstash/qstash");
|
|
159
195
|
|
|
@@ -713,17 +749,17 @@ var triggerRouteFunction = async ({
|
|
|
713
749
|
return ok("workflow-finished");
|
|
714
750
|
} catch (error) {
|
|
715
751
|
const error_ = error;
|
|
716
|
-
if (error
|
|
752
|
+
if (isInstanceOf(error, import_qstash3.QstashError) && error.status === 400) {
|
|
717
753
|
await debug?.log("WARN", "RESPONSE_WORKFLOW", {
|
|
718
754
|
message: `tried to append to a cancelled workflow. exiting without publishing.`,
|
|
719
755
|
name: error.name,
|
|
720
756
|
errorMessage: error.message
|
|
721
757
|
});
|
|
722
758
|
return ok("workflow-was-finished");
|
|
723
|
-
} else if (
|
|
724
|
-
return err(error_);
|
|
725
|
-
} else if (error_ instanceof WorkflowNonRetryableError) {
|
|
759
|
+
} else if (isInstanceOf(error_, WorkflowNonRetryableError) || isInstanceOf(error_, WorkflowRetryAfterError)) {
|
|
726
760
|
return ok(error_);
|
|
761
|
+
} else if (!isInstanceOf(error_, WorkflowAbort)) {
|
|
762
|
+
return err(error_);
|
|
727
763
|
} else if (error_.cancelWorkflow) {
|
|
728
764
|
await onCancel();
|
|
729
765
|
return ok("workflow-finished");
|
|
@@ -2030,7 +2066,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2030
2066
|
});
|
|
2031
2067
|
throw new WorkflowAbort(parallelStep.stepName, resultStep);
|
|
2032
2068
|
} catch (error) {
|
|
2033
|
-
if (error
|
|
2069
|
+
if (isInstanceOf(error, WorkflowAbort) || isInstanceOf(error, import_qstash5.QstashError) && error.status === 400) {
|
|
2034
2070
|
throw error;
|
|
2035
2071
|
}
|
|
2036
2072
|
throw new WorkflowError(
|
|
@@ -2137,7 +2173,7 @@ var validateParallelSteps = (lazySteps, stepsFromRequest) => {
|
|
|
2137
2173
|
validateStep(lazySteps[index], stepFromRequest);
|
|
2138
2174
|
}
|
|
2139
2175
|
} catch (error) {
|
|
2140
|
-
if (error
|
|
2176
|
+
if (isInstanceOf(error, WorkflowError)) {
|
|
2141
2177
|
const lazyStepNames = lazySteps.map((lazyStep) => lazyStep.stepName);
|
|
2142
2178
|
const lazyStepTypes = lazySteps.map((lazyStep) => lazyStep.stepType);
|
|
2143
2179
|
const requestStepNames = stepsFromRequest.map((step) => step.stepName);
|
|
@@ -2318,7 +2354,7 @@ var fetchWithContextCall = async (context, agentCallParams, ...params) => {
|
|
|
2318
2354
|
headers: responseHeaders
|
|
2319
2355
|
});
|
|
2320
2356
|
} catch (error) {
|
|
2321
|
-
if (error instanceof Error && error
|
|
2357
|
+
if (error instanceof Error && isInstanceOf(error, WorkflowAbort)) {
|
|
2322
2358
|
throw error;
|
|
2323
2359
|
} else {
|
|
2324
2360
|
console.error("Error in fetch implementation:", error);
|
|
@@ -2420,10 +2456,10 @@ var Agent = class {
|
|
|
2420
2456
|
});
|
|
2421
2457
|
return { text: result.text };
|
|
2422
2458
|
} catch (error) {
|
|
2423
|
-
if (error
|
|
2424
|
-
if (error.cause instanceof Error && error.cause
|
|
2459
|
+
if (isInstanceOf(error, import_ai2.ToolExecutionError)) {
|
|
2460
|
+
if (error.cause instanceof Error && isInstanceOf(error.cause, WorkflowAbort)) {
|
|
2425
2461
|
throw error.cause;
|
|
2426
|
-
} else if (error.cause
|
|
2462
|
+
} else if (isInstanceOf(error.cause, import_ai2.ToolExecutionError) && isInstanceOf(error.cause.cause, WorkflowAbort)) {
|
|
2427
2463
|
throw error.cause.cause;
|
|
2428
2464
|
} else {
|
|
2429
2465
|
throw error;
|
|
@@ -3172,7 +3208,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
3172
3208
|
try {
|
|
3173
3209
|
await routeFunction(disabledContext);
|
|
3174
3210
|
} catch (error) {
|
|
3175
|
-
if (error
|
|
3211
|
+
if (isInstanceOf(error, WorkflowAbort) && error.stepName === this.disabledMessage || isInstanceOf(error, WorkflowNonRetryableError) || isInstanceOf(error, WorkflowRetryAfterError)) {
|
|
3176
3212
|
return ok("step-found");
|
|
3177
3213
|
}
|
|
3178
3214
|
console.warn(
|
|
@@ -3425,13 +3461,24 @@ var processOptions = (options) => {
|
|
|
3425
3461
|
},
|
|
3426
3462
|
status: 489
|
|
3427
3463
|
});
|
|
3428
|
-
} else if (detailedFinishCondition?.condition === "
|
|
3429
|
-
return new Response(detailedFinishCondition.result
|
|
3430
|
-
status: 200,
|
|
3464
|
+
} else if (detailedFinishCondition?.condition === "retry-after-error") {
|
|
3465
|
+
return new Response(JSON.stringify(formatWorkflowError(detailedFinishCondition.result)), {
|
|
3431
3466
|
headers: {
|
|
3467
|
+
"Retry-After": detailedFinishCondition.result.retryAfter.toString(),
|
|
3432
3468
|
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3433
|
-
}
|
|
3469
|
+
},
|
|
3470
|
+
status: 429
|
|
3434
3471
|
});
|
|
3472
|
+
} else if (detailedFinishCondition?.condition === "failure-callback") {
|
|
3473
|
+
return new Response(
|
|
3474
|
+
JSON.stringify({ result: detailedFinishCondition.result ?? void 0 }),
|
|
3475
|
+
{
|
|
3476
|
+
status: 200,
|
|
3477
|
+
headers: {
|
|
3478
|
+
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3479
|
+
}
|
|
3480
|
+
}
|
|
3481
|
+
);
|
|
3435
3482
|
}
|
|
3436
3483
|
return new Response(JSON.stringify({ workflowRunId }), {
|
|
3437
3484
|
status: 200,
|
|
@@ -3641,12 +3688,18 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
3641
3688
|
},
|
|
3642
3689
|
debug
|
|
3643
3690
|
});
|
|
3644
|
-
if (result.isOk() && result.value
|
|
3691
|
+
if (result.isOk() && isInstanceOf(result.value, WorkflowNonRetryableError)) {
|
|
3645
3692
|
return onStepFinish(workflowRunId, result.value, {
|
|
3646
3693
|
condition: "non-retryable-error",
|
|
3647
3694
|
result: result.value
|
|
3648
3695
|
});
|
|
3649
3696
|
}
|
|
3697
|
+
if (result.isOk() && isInstanceOf(result.value, WorkflowRetryAfterError)) {
|
|
3698
|
+
return onStepFinish(workflowRunId, result.value, {
|
|
3699
|
+
condition: "retry-after-error",
|
|
3700
|
+
result: result.value
|
|
3701
|
+
});
|
|
3702
|
+
}
|
|
3650
3703
|
if (result.isErr()) {
|
|
3651
3704
|
await debug?.log("ERROR", "ERROR", { error: result.error.message });
|
|
3652
3705
|
throw result.error;
|
|
@@ -3677,7 +3730,7 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
3677
3730
|
const errorMessage = `Error while running onError callback: '${formattedOnErrorError.message}'.
|
|
3678
3731
|
Original error: '${formattedError.message}'`;
|
|
3679
3732
|
console.error(errorMessage);
|
|
3680
|
-
return new Response(errorMessage, {
|
|
3733
|
+
return new Response(JSON.stringify({ error: errorMessage }), {
|
|
3681
3734
|
status: 500,
|
|
3682
3735
|
headers: {
|
|
3683
3736
|
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
@@ -3759,7 +3812,8 @@ var servePagesRouter = (routeFunction, options) => {
|
|
|
3759
3812
|
for (const [key, value] of response.headers.entries()) {
|
|
3760
3813
|
res.setHeader(key, value);
|
|
3761
3814
|
}
|
|
3762
|
-
|
|
3815
|
+
const responseData = await response.json();
|
|
3816
|
+
res.status(response.status).json(responseData);
|
|
3763
3817
|
};
|
|
3764
3818
|
return {
|
|
3765
3819
|
handler
|
package/nextjs.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
SDK_TELEMETRY,
|
|
3
3
|
serveBase,
|
|
4
4
|
serveManyBase
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-BON2RKOR.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
|
-
|
|
71
|
+
const responseData = await response.json();
|
|
72
|
+
res.status(response.status).json(responseData);
|
|
72
73
|
};
|
|
73
74
|
return {
|
|
74
75
|
handler
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@upstash/workflow","version":"v0.2.
|
|
1
|
+
{"name":"@upstash/workflow","version":"v0.2.22","description":"Durable, Reliable and Performant Serverless Functions","main":"./index.js","module":"./index.mjs","types":"./index.d.ts","files":["./*"],"exports":{".":{"import":"./index.mjs","require":"./index.js"},"./dist/nextjs":{"import":"./nextjs.mjs","require":"./nextjs.js"},"./nextjs":{"import":"./nextjs.mjs","require":"./nextjs.js"},"./h3":{"import":"./h3.mjs","require":"./h3.js"},"./svelte":{"import":"./svelte.mjs","require":"./svelte.js"},"./solidjs":{"import":"./solidjs.mjs","require":"./solidjs.js"},"./workflow":{"import":"./workflow.mjs","require":"./workflow.js"},"./hono":{"import":"./hono.mjs","require":"./hono.js"},"./cloudflare":{"import":"./cloudflare.mjs","require":"./cloudflare.js"},"./astro":{"import":"./astro.mjs","require":"./astro.js"},"./express":{"import":"./express.mjs","require":"./express.js"},"./tanstack":{"import":"./tanstack.mjs","require":"./tanstack.js"}},"scripts":{"build":"tsup && cp README.md ./dist/ && cp package.json ./dist/ && cp LICENSE ./dist/","test":"bun test src","fmt":"prettier --write .","lint":"tsc && eslint \"{src,platforms}/**/*.{js,ts,tsx}\" --quiet --fix","check-exports":"bun run build && cd dist && attw -P"},"repository":{"type":"git","url":"git+https://github.com/upstash/workflow-ts.git"},"keywords":["upstash","qstash","workflow","serverless"],"author":"Cahid Arda Oz","license":"MIT","bugs":{"url":"https://github.com/upstash/workflow-ts/issues"},"homepage":"https://github.com/upstash/workflow-ts#readme","devDependencies":{"@ai-sdk/anthropic":"^1.1.15","@commitlint/cli":"^19.5.0","@commitlint/config-conventional":"^19.5.0","@eslint/js":"^9.11.1","@solidjs/start":"^1.0.8","@sveltejs/kit":"^2.6.1","@tanstack/react-start":"^1.132.48","@types/bun":"^1.1.10","@types/express":"^5.0.3","astro":"^4.16.7","eslint":"^9.11.1","eslint-plugin-unicorn":"^55.0.0","express":"^5.1.0","globals":"^15.10.0","h3":"^1.12.0","hono":"^4.6.20","husky":"^9.1.6","next":"^14.2.14","prettier":"3.3.3","tsup":"^8.3.0","typescript":"^5.7.2","typescript-eslint":"^8.18.0"},"dependencies":{"@ai-sdk/openai":"^1.2.1","@upstash/qstash":"^2.8.2","ai":"^4.1.54","zod":"^3.24.1"},"directories":{"example":"examples"}}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { o as PublicServeOptions, R as RouteFunction, z as InvokableWorkflow } from './types-9nCq6bRP.js';
|
|
2
2
|
|
|
3
3
|
type OmitOptionsInServeMany<TOptions> = Omit<TOptions, "env" | "url" | "schema" | "initialPayloadParser">;
|
|
4
4
|
declare const serveManyBase: <THandler extends (...params: any[]) => any, TOptions extends OmitOptionsInServeMany<PublicServeOptions> = OmitOptionsInServeMany<PublicServeOptions>, TServeParams extends [routeFunction: RouteFunction<any, any>, options: TOptions] = [routeFunction: RouteFunction<any, any>, options: TOptions]>({ workflows, getUrl, serveMethod, options, }: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { o as PublicServeOptions, R as RouteFunction, z as InvokableWorkflow } from './types-9nCq6bRP.mjs';
|
|
2
2
|
|
|
3
3
|
type OmitOptionsInServeMany<TOptions> = Omit<TOptions, "env" | "url" | "schema" | "initialPayloadParser">;
|
|
4
4
|
declare const serveManyBase: <THandler extends (...params: any[]) => any, TOptions extends OmitOptionsInServeMany<PublicServeOptions> = OmitOptionsInServeMany<PublicServeOptions>, TServeParams extends [routeFunction: RouteFunction<any, any>, options: TOptions] = [routeFunction: RouteFunction<any, any>, options: TOptions]>({ workflows, getUrl, serveMethod, options, }: {
|
package/solidjs.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { APIEvent } from '@solidjs/start/server';
|
|
2
|
-
import { R as RouteFunction,
|
|
2
|
+
import { R as RouteFunction, o as PublicServeOptions } from './types-9nCq6bRP.mjs';
|
|
3
3
|
import '@upstash/qstash';
|
|
4
4
|
import 'zod';
|
|
5
5
|
import 'ai';
|
package/solidjs.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { APIEvent } from '@solidjs/start/server';
|
|
2
|
-
import { R as RouteFunction,
|
|
2
|
+
import { R as RouteFunction, o as PublicServeOptions } from './types-9nCq6bRP.js';
|
|
3
3
|
import '@upstash/qstash';
|
|
4
4
|
import 'zod';
|
|
5
5
|
import 'ai';
|
package/solidjs.js
CHANGED
|
@@ -25,7 +25,95 @@ __export(solidjs_exports, {
|
|
|
25
25
|
module.exports = __toCommonJS(solidjs_exports);
|
|
26
26
|
|
|
27
27
|
// src/client/utils.ts
|
|
28
|
+
var import_qstash2 = require("@upstash/qstash");
|
|
29
|
+
|
|
30
|
+
// src/error.ts
|
|
28
31
|
var import_qstash = require("@upstash/qstash");
|
|
32
|
+
var WorkflowError = class extends import_qstash.QstashError {
|
|
33
|
+
constructor(message) {
|
|
34
|
+
super(message);
|
|
35
|
+
this.name = "WorkflowError";
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
var WorkflowAbort = class extends Error {
|
|
39
|
+
stepInfo;
|
|
40
|
+
stepName;
|
|
41
|
+
/**
|
|
42
|
+
* whether workflow is to be canceled on abort
|
|
43
|
+
*/
|
|
44
|
+
cancelWorkflow;
|
|
45
|
+
/**
|
|
46
|
+
*
|
|
47
|
+
* @param stepName name of the aborting step
|
|
48
|
+
* @param stepInfo step information
|
|
49
|
+
* @param cancelWorkflow
|
|
50
|
+
*/
|
|
51
|
+
constructor(stepName, stepInfo, cancelWorkflow = false) {
|
|
52
|
+
super(
|
|
53
|
+
`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}'.`
|
|
54
|
+
);
|
|
55
|
+
this.name = "WorkflowAbort";
|
|
56
|
+
this.stepName = stepName;
|
|
57
|
+
this.stepInfo = stepInfo;
|
|
58
|
+
this.cancelWorkflow = cancelWorkflow;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
var WorkflowNonRetryableError = class extends WorkflowAbort {
|
|
62
|
+
/**
|
|
63
|
+
* @param message error message to be displayed
|
|
64
|
+
*/
|
|
65
|
+
constructor(message) {
|
|
66
|
+
super("fail", void 0, false);
|
|
67
|
+
this.name = "WorkflowNonRetryableError";
|
|
68
|
+
if (message) this.message = message;
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
var WorkflowRetryAfterError = class extends WorkflowAbort {
|
|
72
|
+
retryAfter;
|
|
73
|
+
/**
|
|
74
|
+
* @param retryAfter time in seconds after which the workflow should be retried
|
|
75
|
+
* @param message error message to be displayed
|
|
76
|
+
*/
|
|
77
|
+
constructor(message, retryAfter) {
|
|
78
|
+
super("retry", void 0, false);
|
|
79
|
+
this.name = "WorkflowRetryAfterError";
|
|
80
|
+
this.retryAfter = retryAfter;
|
|
81
|
+
if (message) this.message = message;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
var formatWorkflowError = (error) => {
|
|
85
|
+
return error instanceof Error ? {
|
|
86
|
+
error: error.name,
|
|
87
|
+
message: error.message,
|
|
88
|
+
stack: error.stack
|
|
89
|
+
} : {
|
|
90
|
+
error: "Error",
|
|
91
|
+
message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
function getConstructorName(obj) {
|
|
95
|
+
if (obj === null || obj === void 0) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
const ctor = obj.constructor;
|
|
99
|
+
if (!ctor || ctor.name === "Object") {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
return ctor.name;
|
|
103
|
+
}
|
|
104
|
+
function getConstructorNames(obj) {
|
|
105
|
+
const proto = Object.getPrototypeOf(obj);
|
|
106
|
+
const name = getConstructorName(proto);
|
|
107
|
+
if (name === null) {
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
return [name, ...getConstructorNames(proto)];
|
|
111
|
+
}
|
|
112
|
+
function isInstanceOf(v, ctor) {
|
|
113
|
+
return getConstructorNames(v).includes(ctor.name);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// src/client/utils.ts
|
|
29
117
|
var makeNotifyRequest = async (requester, eventId, eventData) => {
|
|
30
118
|
const result = await requester.request({
|
|
31
119
|
path: ["v2", "notify", eventId],
|
|
@@ -65,7 +153,7 @@ var getSteps = async (requester, workflowRunId, messageId, debug) => {
|
|
|
65
153
|
return { steps: filteredSteps, workflowRunEnded: false };
|
|
66
154
|
}
|
|
67
155
|
} catch (error) {
|
|
68
|
-
if (error
|
|
156
|
+
if (isInstanceOf(error, import_qstash2.QstashError) && error.status === 404) {
|
|
69
157
|
await debug?.log("WARN", "ENDPOINT_START", {
|
|
70
158
|
message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
|
|
71
159
|
error
|
|
@@ -90,65 +178,13 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
|
|
|
90
178
|
var DEFAULT_CONTENT_TYPE = "application/json";
|
|
91
179
|
var NO_CONCURRENCY = 1;
|
|
92
180
|
var DEFAULT_RETRIES = 3;
|
|
93
|
-
var VERSION = "v0.2.
|
|
181
|
+
var VERSION = "v0.2.22";
|
|
94
182
|
var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
|
|
95
183
|
var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
|
|
96
184
|
var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
|
|
97
185
|
var TELEMETRY_HEADER_RUNTIME = "Upstash-Telemetry-Runtime";
|
|
98
186
|
var TELEMETRY_HEADER_AGENT = "Upstash-Telemetry-Agent";
|
|
99
187
|
|
|
100
|
-
// src/error.ts
|
|
101
|
-
var import_qstash2 = require("@upstash/qstash");
|
|
102
|
-
var WorkflowError = class extends import_qstash2.QstashError {
|
|
103
|
-
constructor(message) {
|
|
104
|
-
super(message);
|
|
105
|
-
this.name = "WorkflowError";
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
var WorkflowAbort = class extends Error {
|
|
109
|
-
stepInfo;
|
|
110
|
-
stepName;
|
|
111
|
-
/**
|
|
112
|
-
* whether workflow is to be canceled on abort
|
|
113
|
-
*/
|
|
114
|
-
cancelWorkflow;
|
|
115
|
-
/**
|
|
116
|
-
*
|
|
117
|
-
* @param stepName name of the aborting step
|
|
118
|
-
* @param stepInfo step information
|
|
119
|
-
* @param cancelWorkflow
|
|
120
|
-
*/
|
|
121
|
-
constructor(stepName, stepInfo, cancelWorkflow = false) {
|
|
122
|
-
super(
|
|
123
|
-
`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}'.`
|
|
124
|
-
);
|
|
125
|
-
this.name = "WorkflowAbort";
|
|
126
|
-
this.stepName = stepName;
|
|
127
|
-
this.stepInfo = stepInfo;
|
|
128
|
-
this.cancelWorkflow = cancelWorkflow;
|
|
129
|
-
}
|
|
130
|
-
};
|
|
131
|
-
var WorkflowNonRetryableError = class extends WorkflowAbort {
|
|
132
|
-
/**
|
|
133
|
-
* @param message error message to be displayed
|
|
134
|
-
*/
|
|
135
|
-
constructor(message) {
|
|
136
|
-
super("fail", void 0, false);
|
|
137
|
-
this.name = "WorkflowNonRetryableError";
|
|
138
|
-
if (message) this.message = message;
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
var formatWorkflowError = (error) => {
|
|
142
|
-
return error instanceof Error ? {
|
|
143
|
-
error: error.name,
|
|
144
|
-
message: error.message,
|
|
145
|
-
stack: error.stack
|
|
146
|
-
} : {
|
|
147
|
-
error: "Error",
|
|
148
|
-
message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
|
|
149
|
-
};
|
|
150
|
-
};
|
|
151
|
-
|
|
152
188
|
// src/context/auto-executor.ts
|
|
153
189
|
var import_qstash5 = require("@upstash/qstash");
|
|
154
190
|
|
|
@@ -708,17 +744,17 @@ var triggerRouteFunction = async ({
|
|
|
708
744
|
return ok("workflow-finished");
|
|
709
745
|
} catch (error) {
|
|
710
746
|
const error_ = error;
|
|
711
|
-
if (error
|
|
747
|
+
if (isInstanceOf(error, import_qstash3.QstashError) && error.status === 400) {
|
|
712
748
|
await debug?.log("WARN", "RESPONSE_WORKFLOW", {
|
|
713
749
|
message: `tried to append to a cancelled workflow. exiting without publishing.`,
|
|
714
750
|
name: error.name,
|
|
715
751
|
errorMessage: error.message
|
|
716
752
|
});
|
|
717
753
|
return ok("workflow-was-finished");
|
|
718
|
-
} else if (
|
|
719
|
-
return err(error_);
|
|
720
|
-
} else if (error_ instanceof WorkflowNonRetryableError) {
|
|
754
|
+
} else if (isInstanceOf(error_, WorkflowNonRetryableError) || isInstanceOf(error_, WorkflowRetryAfterError)) {
|
|
721
755
|
return ok(error_);
|
|
756
|
+
} else if (!isInstanceOf(error_, WorkflowAbort)) {
|
|
757
|
+
return err(error_);
|
|
722
758
|
} else if (error_.cancelWorkflow) {
|
|
723
759
|
await onCancel();
|
|
724
760
|
return ok("workflow-finished");
|
|
@@ -2025,7 +2061,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2025
2061
|
});
|
|
2026
2062
|
throw new WorkflowAbort(parallelStep.stepName, resultStep);
|
|
2027
2063
|
} catch (error) {
|
|
2028
|
-
if (error
|
|
2064
|
+
if (isInstanceOf(error, WorkflowAbort) || isInstanceOf(error, import_qstash5.QstashError) && error.status === 400) {
|
|
2029
2065
|
throw error;
|
|
2030
2066
|
}
|
|
2031
2067
|
throw new WorkflowError(
|
|
@@ -2132,7 +2168,7 @@ var validateParallelSteps = (lazySteps, stepsFromRequest) => {
|
|
|
2132
2168
|
validateStep(lazySteps[index], stepFromRequest);
|
|
2133
2169
|
}
|
|
2134
2170
|
} catch (error) {
|
|
2135
|
-
if (error
|
|
2171
|
+
if (isInstanceOf(error, WorkflowError)) {
|
|
2136
2172
|
const lazyStepNames = lazySteps.map((lazyStep) => lazyStep.stepName);
|
|
2137
2173
|
const lazyStepTypes = lazySteps.map((lazyStep) => lazyStep.stepType);
|
|
2138
2174
|
const requestStepNames = stepsFromRequest.map((step) => step.stepName);
|
|
@@ -2313,7 +2349,7 @@ var fetchWithContextCall = async (context, agentCallParams, ...params) => {
|
|
|
2313
2349
|
headers: responseHeaders
|
|
2314
2350
|
});
|
|
2315
2351
|
} catch (error) {
|
|
2316
|
-
if (error instanceof Error && error
|
|
2352
|
+
if (error instanceof Error && isInstanceOf(error, WorkflowAbort)) {
|
|
2317
2353
|
throw error;
|
|
2318
2354
|
} else {
|
|
2319
2355
|
console.error("Error in fetch implementation:", error);
|
|
@@ -2415,10 +2451,10 @@ var Agent = class {
|
|
|
2415
2451
|
});
|
|
2416
2452
|
return { text: result.text };
|
|
2417
2453
|
} catch (error) {
|
|
2418
|
-
if (error
|
|
2419
|
-
if (error.cause instanceof Error && error.cause
|
|
2454
|
+
if (isInstanceOf(error, import_ai2.ToolExecutionError)) {
|
|
2455
|
+
if (error.cause instanceof Error && isInstanceOf(error.cause, WorkflowAbort)) {
|
|
2420
2456
|
throw error.cause;
|
|
2421
|
-
} else if (error.cause
|
|
2457
|
+
} else if (isInstanceOf(error.cause, import_ai2.ToolExecutionError) && isInstanceOf(error.cause.cause, WorkflowAbort)) {
|
|
2422
2458
|
throw error.cause.cause;
|
|
2423
2459
|
} else {
|
|
2424
2460
|
throw error;
|
|
@@ -3100,7 +3136,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
3100
3136
|
try {
|
|
3101
3137
|
await routeFunction(disabledContext);
|
|
3102
3138
|
} catch (error) {
|
|
3103
|
-
if (error
|
|
3139
|
+
if (isInstanceOf(error, WorkflowAbort) && error.stepName === this.disabledMessage || isInstanceOf(error, WorkflowNonRetryableError) || isInstanceOf(error, WorkflowRetryAfterError)) {
|
|
3104
3140
|
return ok("step-found");
|
|
3105
3141
|
}
|
|
3106
3142
|
console.warn(
|
|
@@ -3353,13 +3389,24 @@ var processOptions = (options) => {
|
|
|
3353
3389
|
},
|
|
3354
3390
|
status: 489
|
|
3355
3391
|
});
|
|
3356
|
-
} else if (detailedFinishCondition?.condition === "
|
|
3357
|
-
return new Response(detailedFinishCondition.result
|
|
3358
|
-
status: 200,
|
|
3392
|
+
} else if (detailedFinishCondition?.condition === "retry-after-error") {
|
|
3393
|
+
return new Response(JSON.stringify(formatWorkflowError(detailedFinishCondition.result)), {
|
|
3359
3394
|
headers: {
|
|
3395
|
+
"Retry-After": detailedFinishCondition.result.retryAfter.toString(),
|
|
3360
3396
|
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3361
|
-
}
|
|
3397
|
+
},
|
|
3398
|
+
status: 429
|
|
3362
3399
|
});
|
|
3400
|
+
} else if (detailedFinishCondition?.condition === "failure-callback") {
|
|
3401
|
+
return new Response(
|
|
3402
|
+
JSON.stringify({ result: detailedFinishCondition.result ?? void 0 }),
|
|
3403
|
+
{
|
|
3404
|
+
status: 200,
|
|
3405
|
+
headers: {
|
|
3406
|
+
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3407
|
+
}
|
|
3408
|
+
}
|
|
3409
|
+
);
|
|
3363
3410
|
}
|
|
3364
3411
|
return new Response(JSON.stringify({ workflowRunId }), {
|
|
3365
3412
|
status: 200,
|
|
@@ -3569,12 +3616,18 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
3569
3616
|
},
|
|
3570
3617
|
debug
|
|
3571
3618
|
});
|
|
3572
|
-
if (result.isOk() && result.value
|
|
3619
|
+
if (result.isOk() && isInstanceOf(result.value, WorkflowNonRetryableError)) {
|
|
3573
3620
|
return onStepFinish(workflowRunId, result.value, {
|
|
3574
3621
|
condition: "non-retryable-error",
|
|
3575
3622
|
result: result.value
|
|
3576
3623
|
});
|
|
3577
3624
|
}
|
|
3625
|
+
if (result.isOk() && isInstanceOf(result.value, WorkflowRetryAfterError)) {
|
|
3626
|
+
return onStepFinish(workflowRunId, result.value, {
|
|
3627
|
+
condition: "retry-after-error",
|
|
3628
|
+
result: result.value
|
|
3629
|
+
});
|
|
3630
|
+
}
|
|
3578
3631
|
if (result.isErr()) {
|
|
3579
3632
|
await debug?.log("ERROR", "ERROR", { error: result.error.message });
|
|
3580
3633
|
throw result.error;
|
|
@@ -3605,7 +3658,7 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
3605
3658
|
const errorMessage = `Error while running onError callback: '${formattedOnErrorError.message}'.
|
|
3606
3659
|
Original error: '${formattedError.message}'`;
|
|
3607
3660
|
console.error(errorMessage);
|
|
3608
|
-
return new Response(errorMessage, {
|
|
3661
|
+
return new Response(JSON.stringify({ error: errorMessage }), {
|
|
3609
3662
|
status: 500,
|
|
3610
3663
|
headers: {
|
|
3611
3664
|
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|