@upstash/workflow 0.2.11 → 0.2.13
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/astro.d.mts +2 -2
- package/astro.d.ts +2 -2
- package/astro.js +1264 -1071
- package/astro.mjs +1 -1
- package/{chunk-WQAJ2RSZ.mjs → chunk-XVNSBBDC.mjs} +897 -702
- package/cloudflare.d.mts +2 -2
- package/cloudflare.d.ts +2 -2
- package/cloudflare.js +1264 -1071
- package/cloudflare.mjs +1 -1
- package/express.d.mts +2 -2
- package/express.d.ts +2 -2
- package/express.js +1267 -1074
- package/express.mjs +1 -1
- package/h3.d.mts +2 -2
- package/h3.d.ts +2 -2
- package/h3.js +1264 -1071
- package/h3.mjs +1 -1
- package/hono.d.mts +2 -2
- package/hono.d.ts +2 -2
- package/hono.js +1265 -1072
- package/hono.mjs +2 -2
- package/index.d.mts +16 -6
- package/index.d.ts +16 -6
- package/index.js +1238 -1038
- package/index.mjs +10 -3
- package/nextjs.d.mts +2 -2
- package/nextjs.d.ts +2 -2
- package/nextjs.js +1264 -1071
- package/nextjs.mjs +1 -1
- package/package.json +1 -1
- package/{serve-many-Fuovl7gl.d.mts → serve-many-BF71QZHQ.d.mts} +1 -1
- package/{serve-many-DNnLsDIp.d.ts → serve-many-BMlN2PAB.d.ts} +1 -1
- package/solidjs.d.mts +1 -1
- package/solidjs.d.ts +1 -1
- package/solidjs.js +1235 -1042
- package/solidjs.mjs +1 -1
- package/svelte.d.mts +2 -2
- package/svelte.d.ts +2 -2
- package/svelte.js +1264 -1071
- package/svelte.mjs +1 -1
- package/{types-DS9q8FyV.d.ts → types-C1WIgVLA.d.mts} +110 -82
- package/{types-DS9q8FyV.d.mts → types-C1WIgVLA.d.ts} +110 -82
|
@@ -42,11 +42,12 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
|
|
|
42
42
|
var DEFAULT_CONTENT_TYPE = "application/json";
|
|
43
43
|
var NO_CONCURRENCY = 1;
|
|
44
44
|
var DEFAULT_RETRIES = 3;
|
|
45
|
-
var VERSION = "v0.2.
|
|
45
|
+
var VERSION = "v0.2.13";
|
|
46
46
|
var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
|
|
47
47
|
var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
|
|
48
48
|
var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
|
|
49
49
|
var TELEMETRY_HEADER_RUNTIME = "Upstash-Telemetry-Runtime";
|
|
50
|
+
var TELEMETRY_HEADER_AGENT = "Upstash-Telemetry-Agent";
|
|
50
51
|
|
|
51
52
|
// src/error.ts
|
|
52
53
|
import { QstashError } from "@upstash/qstash";
|
|
@@ -85,7 +86,7 @@ var formatWorkflowError = (error) => {
|
|
|
85
86
|
message: error.message
|
|
86
87
|
} : {
|
|
87
88
|
error: "Error",
|
|
88
|
-
message:
|
|
89
|
+
message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
|
|
89
90
|
};
|
|
90
91
|
};
|
|
91
92
|
|
|
@@ -101,6 +102,271 @@ var StepTypes = [
|
|
|
101
102
|
"Invoke"
|
|
102
103
|
];
|
|
103
104
|
|
|
105
|
+
// src/agents/adapters.ts
|
|
106
|
+
import { tool } from "ai";
|
|
107
|
+
|
|
108
|
+
// src/agents/constants.ts
|
|
109
|
+
var AGENT_NAME_HEADER = "upstash-agent-name";
|
|
110
|
+
var MANAGER_AGENT_PROMPT = `You are an agent orchestrating other AI Agents.
|
|
111
|
+
|
|
112
|
+
These other agents have tools available to them.
|
|
113
|
+
|
|
114
|
+
Given a prompt, utilize these agents to address requests.
|
|
115
|
+
|
|
116
|
+
Don't always call all the agents provided to you at the same time. You can call one and use it's response to call another.
|
|
117
|
+
|
|
118
|
+
Avoid calling the same agent twice in one turn. Instead, prefer to call it once but provide everything
|
|
119
|
+
you need from that agent.
|
|
120
|
+
`;
|
|
121
|
+
|
|
122
|
+
// src/agents/adapters.ts
|
|
123
|
+
var fetchWithContextCall = async (context, agentCallParams, ...params) => {
|
|
124
|
+
const [input, init] = params;
|
|
125
|
+
try {
|
|
126
|
+
const headers = init?.headers ? Object.fromEntries(new Headers(init.headers).entries()) : {};
|
|
127
|
+
const body = init?.body ? JSON.parse(init.body) : void 0;
|
|
128
|
+
const agentName = headers[AGENT_NAME_HEADER];
|
|
129
|
+
const stepName = agentName ? `Call Agent ${agentName}` : "Call Agent";
|
|
130
|
+
const responseInfo = await context.call(stepName, {
|
|
131
|
+
url: input.toString(),
|
|
132
|
+
method: init?.method,
|
|
133
|
+
headers,
|
|
134
|
+
body,
|
|
135
|
+
timeout: agentCallParams?.timeout,
|
|
136
|
+
retries: agentCallParams?.retries,
|
|
137
|
+
flowControl: agentCallParams?.flowControl
|
|
138
|
+
});
|
|
139
|
+
const responseHeaders = new Headers(
|
|
140
|
+
Object.entries(responseInfo.header).reduce(
|
|
141
|
+
(acc, [key, values]) => {
|
|
142
|
+
acc[key] = values.join(", ");
|
|
143
|
+
return acc;
|
|
144
|
+
},
|
|
145
|
+
{}
|
|
146
|
+
)
|
|
147
|
+
);
|
|
148
|
+
return new Response(JSON.stringify(responseInfo.body), {
|
|
149
|
+
status: responseInfo.status,
|
|
150
|
+
headers: responseHeaders
|
|
151
|
+
});
|
|
152
|
+
} catch (error) {
|
|
153
|
+
if (error instanceof Error && error.name === "WorkflowAbort") {
|
|
154
|
+
throw error;
|
|
155
|
+
} else {
|
|
156
|
+
console.error("Error in fetch implementation:", error);
|
|
157
|
+
throw error;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
var createWorkflowModel = ({
|
|
162
|
+
context,
|
|
163
|
+
provider,
|
|
164
|
+
providerParams,
|
|
165
|
+
agentCallParams
|
|
166
|
+
}) => {
|
|
167
|
+
return provider({
|
|
168
|
+
fetch: (...params) => fetchWithContextCall(context, agentCallParams, ...params),
|
|
169
|
+
...providerParams
|
|
170
|
+
});
|
|
171
|
+
};
|
|
172
|
+
var wrapTools = ({
|
|
173
|
+
context,
|
|
174
|
+
tools
|
|
175
|
+
}) => {
|
|
176
|
+
return Object.fromEntries(
|
|
177
|
+
Object.entries(tools).map((toolInfo) => {
|
|
178
|
+
const [toolName, tool3] = toolInfo;
|
|
179
|
+
const executeAsStep = "executeAsStep" in tool3 ? tool3.executeAsStep : true;
|
|
180
|
+
const aiSDKTool = convertToAISDKTool(tool3);
|
|
181
|
+
const execute = aiSDKTool.execute;
|
|
182
|
+
if (execute && executeAsStep) {
|
|
183
|
+
const wrappedExecute = (...params) => {
|
|
184
|
+
return context.run(`Run tool ${toolName}`, () => execute(...params));
|
|
185
|
+
};
|
|
186
|
+
aiSDKTool.execute = wrappedExecute;
|
|
187
|
+
}
|
|
188
|
+
return [toolName, aiSDKTool];
|
|
189
|
+
})
|
|
190
|
+
);
|
|
191
|
+
};
|
|
192
|
+
var convertToAISDKTool = (tool3) => {
|
|
193
|
+
const isLangchainTool = "invoke" in tool3;
|
|
194
|
+
return isLangchainTool ? convertLangchainTool(tool3) : tool3;
|
|
195
|
+
};
|
|
196
|
+
var convertLangchainTool = (langchainTool) => {
|
|
197
|
+
return tool({
|
|
198
|
+
description: langchainTool.description,
|
|
199
|
+
parameters: langchainTool.schema,
|
|
200
|
+
execute: async (...param) => langchainTool.invoke(...param)
|
|
201
|
+
});
|
|
202
|
+
};
|
|
203
|
+
var WorkflowTool = class {
|
|
204
|
+
/**
|
|
205
|
+
* description of the tool
|
|
206
|
+
*/
|
|
207
|
+
description;
|
|
208
|
+
/**
|
|
209
|
+
* schema of the tool
|
|
210
|
+
*/
|
|
211
|
+
schema;
|
|
212
|
+
/**
|
|
213
|
+
* function to invoke the tool
|
|
214
|
+
*/
|
|
215
|
+
invoke;
|
|
216
|
+
/**
|
|
217
|
+
* whether the invoke method of the tool is to be wrapped with `context.run`
|
|
218
|
+
*/
|
|
219
|
+
executeAsStep;
|
|
220
|
+
/**
|
|
221
|
+
*
|
|
222
|
+
* @param description description of the tool
|
|
223
|
+
* @param schema schema of the tool
|
|
224
|
+
* @param invoke function to invoke the tool
|
|
225
|
+
* @param executeAsStep whether the invoke method of the tool is to be wrapped with `context.run`
|
|
226
|
+
*/
|
|
227
|
+
constructor(params) {
|
|
228
|
+
this.description = params.description;
|
|
229
|
+
this.schema = params.schema;
|
|
230
|
+
this.invoke = params.invoke;
|
|
231
|
+
this.executeAsStep = params.executeAsStep ?? true;
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
// src/serve/serve-many.ts
|
|
236
|
+
var getWorkflowId = (url) => {
|
|
237
|
+
const components = url.split("/");
|
|
238
|
+
const lastComponent = components[components.length - 1];
|
|
239
|
+
return lastComponent.split("?")[0];
|
|
240
|
+
};
|
|
241
|
+
var serveManyBase = ({
|
|
242
|
+
workflows,
|
|
243
|
+
getUrl,
|
|
244
|
+
serveMethod,
|
|
245
|
+
options
|
|
246
|
+
}) => {
|
|
247
|
+
const workflowIds = [];
|
|
248
|
+
const workflowMap = Object.fromEntries(
|
|
249
|
+
Object.entries(workflows).map((workflow) => {
|
|
250
|
+
const workflowId = workflow[0];
|
|
251
|
+
if (workflowIds.includes(workflowId)) {
|
|
252
|
+
throw new WorkflowError(
|
|
253
|
+
`Duplicate workflow name found: '${workflowId}'. Please set different workflow names in serveMany.`
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
if (workflowId.includes("/")) {
|
|
257
|
+
throw new WorkflowError(
|
|
258
|
+
`Invalid workflow name found: '${workflowId}'. Workflow name cannot contain '/'.`
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
workflowIds.push(workflowId);
|
|
262
|
+
workflow[1].workflowId = workflowId;
|
|
263
|
+
workflow[1].options = {
|
|
264
|
+
...options,
|
|
265
|
+
...workflow[1].options
|
|
266
|
+
};
|
|
267
|
+
const params = [workflow[1].routeFunction, workflow[1].options];
|
|
268
|
+
const handler = serveMethod(...params);
|
|
269
|
+
return [workflowId, handler];
|
|
270
|
+
})
|
|
271
|
+
);
|
|
272
|
+
return {
|
|
273
|
+
handler: async (...params) => {
|
|
274
|
+
const url = getUrl(...params);
|
|
275
|
+
const pickedWorkflowId = getWorkflowId(url);
|
|
276
|
+
if (!pickedWorkflowId) {
|
|
277
|
+
return new Response(
|
|
278
|
+
`Unexpected request in serveMany. workflowId not set. Please update the URL of your request.`,
|
|
279
|
+
{
|
|
280
|
+
status: 404
|
|
281
|
+
}
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
const workflow = workflowMap[pickedWorkflowId];
|
|
285
|
+
if (!workflow) {
|
|
286
|
+
return new Response(
|
|
287
|
+
`No workflows in serveMany found for '${pickedWorkflowId}'. Please update the URL of your request.`,
|
|
288
|
+
{
|
|
289
|
+
status: 404
|
|
290
|
+
}
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
return await workflow(...params);
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
};
|
|
297
|
+
var getNewUrlFromWorkflowId = (url, workflowId) => {
|
|
298
|
+
if (!workflowId) {
|
|
299
|
+
throw new WorkflowError("You can only call workflow which has a workflowId");
|
|
300
|
+
}
|
|
301
|
+
return url.replace(/[^/]+$/, workflowId);
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
// src/context/auto-executor.ts
|
|
305
|
+
import { QstashError as QstashError5 } from "@upstash/qstash";
|
|
306
|
+
|
|
307
|
+
// src/qstash/headers.ts
|
|
308
|
+
import { QstashError as QstashError4 } from "@upstash/qstash";
|
|
309
|
+
|
|
310
|
+
// src/client/utils.ts
|
|
311
|
+
import { QstashError as QstashError2 } from "@upstash/qstash";
|
|
312
|
+
var makeNotifyRequest = async (requester, eventId, eventData) => {
|
|
313
|
+
const result = await requester.request({
|
|
314
|
+
path: ["v2", "notify", eventId],
|
|
315
|
+
method: "POST",
|
|
316
|
+
body: typeof eventData === "string" ? eventData : JSON.stringify(eventData)
|
|
317
|
+
});
|
|
318
|
+
return result;
|
|
319
|
+
};
|
|
320
|
+
var makeGetWaitersRequest = async (requester, eventId) => {
|
|
321
|
+
const result = await requester.request({
|
|
322
|
+
path: ["v2", "waiters", eventId],
|
|
323
|
+
method: "GET"
|
|
324
|
+
});
|
|
325
|
+
return result;
|
|
326
|
+
};
|
|
327
|
+
var makeCancelRequest = async (requester, workflowRunId) => {
|
|
328
|
+
await requester.request({
|
|
329
|
+
path: ["v2", "workflows", "runs", `${workflowRunId}?cancel=true`],
|
|
330
|
+
method: "DELETE",
|
|
331
|
+
parseResponseAsJson: false
|
|
332
|
+
});
|
|
333
|
+
return true;
|
|
334
|
+
};
|
|
335
|
+
var getSteps = async (requester, workflowRunId, messageId, debug) => {
|
|
336
|
+
try {
|
|
337
|
+
const steps = await requester.request({
|
|
338
|
+
path: ["v2", "workflows", "runs", workflowRunId],
|
|
339
|
+
parseResponseAsJson: true
|
|
340
|
+
});
|
|
341
|
+
if (!messageId) {
|
|
342
|
+
await debug?.log("INFO", "ENDPOINT_START", {
|
|
343
|
+
message: `Pulled ${steps.length} steps from QStashand returned them without filtering with messageId.`
|
|
344
|
+
});
|
|
345
|
+
return { steps, workflowRunEnded: false };
|
|
346
|
+
} else {
|
|
347
|
+
const index = steps.findIndex((item) => item.messageId === messageId);
|
|
348
|
+
if (index === -1) {
|
|
349
|
+
return { steps: [], workflowRunEnded: false };
|
|
350
|
+
}
|
|
351
|
+
const filteredSteps = steps.slice(0, index + 1);
|
|
352
|
+
await debug?.log("INFO", "ENDPOINT_START", {
|
|
353
|
+
message: `Pulled ${steps.length} steps from QStash and filtered them to ${filteredSteps.length} using messageId.`
|
|
354
|
+
});
|
|
355
|
+
return { steps: filteredSteps, workflowRunEnded: false };
|
|
356
|
+
}
|
|
357
|
+
} catch (error) {
|
|
358
|
+
if (error instanceof QstashError2 && error.status === 404) {
|
|
359
|
+
await debug?.log("WARN", "ENDPOINT_START", {
|
|
360
|
+
message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
|
|
361
|
+
error
|
|
362
|
+
});
|
|
363
|
+
return { steps: void 0, workflowRunEnded: true };
|
|
364
|
+
} else {
|
|
365
|
+
throw error;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
|
|
104
370
|
// src/utils.ts
|
|
105
371
|
var NANOID_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
|
|
106
372
|
var NANOID_LENGTH = 21;
|
|
@@ -543,85 +809,27 @@ var fromThrowable = Result.fromThrowable;
|
|
|
543
809
|
|
|
544
810
|
// src/workflow-requests.ts
|
|
545
811
|
import { QstashError as QstashError3 } from "@upstash/qstash";
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
method: "DELETE",
|
|
568
|
-
parseResponseAsJson: false
|
|
569
|
-
});
|
|
570
|
-
return true;
|
|
571
|
-
};
|
|
572
|
-
var getSteps = async (requester, workflowRunId, messageId, debug) => {
|
|
573
|
-
try {
|
|
574
|
-
const steps = await requester.request({
|
|
575
|
-
path: ["v2", "workflows", "runs", workflowRunId],
|
|
576
|
-
parseResponseAsJson: true
|
|
577
|
-
});
|
|
578
|
-
if (!messageId) {
|
|
579
|
-
await debug?.log("INFO", "ENDPOINT_START", {
|
|
580
|
-
message: `Pulled ${steps.length} steps from QStashand returned them without filtering with messageId.`
|
|
581
|
-
});
|
|
582
|
-
return { steps, workflowRunEnded: false };
|
|
583
|
-
} else {
|
|
584
|
-
const index = steps.findIndex((item) => item.messageId === messageId);
|
|
585
|
-
if (index === -1) {
|
|
586
|
-
return { steps: [], workflowRunEnded: false };
|
|
587
|
-
}
|
|
588
|
-
const filteredSteps = steps.slice(0, index + 1);
|
|
589
|
-
await debug?.log("INFO", "ENDPOINT_START", {
|
|
590
|
-
message: `Pulled ${steps.length} steps from QStash and filtered them to ${filteredSteps.length} using messageId.`
|
|
591
|
-
});
|
|
592
|
-
return { steps: filteredSteps, workflowRunEnded: false };
|
|
593
|
-
}
|
|
594
|
-
} catch (error) {
|
|
595
|
-
if (error instanceof QstashError2 && error.status === 404) {
|
|
596
|
-
await debug?.log("WARN", "ENDPOINT_START", {
|
|
597
|
-
message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
|
|
598
|
-
error
|
|
599
|
-
});
|
|
600
|
-
return { steps: void 0, workflowRunEnded: true };
|
|
601
|
-
} else {
|
|
602
|
-
throw error;
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
};
|
|
606
|
-
|
|
607
|
-
// src/workflow-requests.ts
|
|
608
|
-
var triggerFirstInvocation = async ({
|
|
609
|
-
workflowContext,
|
|
610
|
-
useJSONContent,
|
|
611
|
-
telemetry,
|
|
612
|
-
debug,
|
|
613
|
-
invokeCount
|
|
614
|
-
}) => {
|
|
615
|
-
const { headers } = getHeaders({
|
|
616
|
-
initHeaderValue: "true",
|
|
617
|
-
workflowRunId: workflowContext.workflowRunId,
|
|
618
|
-
workflowUrl: workflowContext.url,
|
|
619
|
-
userHeaders: workflowContext.headers,
|
|
620
|
-
failureUrl: workflowContext.failureUrl,
|
|
621
|
-
retries: workflowContext.retries,
|
|
622
|
-
telemetry,
|
|
623
|
-
invokeCount,
|
|
624
|
-
flowControl: workflowContext.flowControl
|
|
812
|
+
var triggerFirstInvocation = async ({
|
|
813
|
+
workflowContext,
|
|
814
|
+
useJSONContent,
|
|
815
|
+
telemetry,
|
|
816
|
+
debug,
|
|
817
|
+
invokeCount,
|
|
818
|
+
delay
|
|
819
|
+
}) => {
|
|
820
|
+
const { headers } = getHeaders({
|
|
821
|
+
initHeaderValue: "true",
|
|
822
|
+
workflowConfig: {
|
|
823
|
+
workflowRunId: workflowContext.workflowRunId,
|
|
824
|
+
workflowUrl: workflowContext.url,
|
|
825
|
+
failureUrl: workflowContext.failureUrl,
|
|
826
|
+
retries: workflowContext.retries,
|
|
827
|
+
telemetry,
|
|
828
|
+
flowControl: workflowContext.flowControl,
|
|
829
|
+
useJSONContent: useJSONContent ?? false
|
|
830
|
+
},
|
|
831
|
+
invokeCount: invokeCount ?? 0,
|
|
832
|
+
userHeaders: workflowContext.headers
|
|
625
833
|
});
|
|
626
834
|
if (workflowContext.headers.get("content-type")) {
|
|
627
835
|
headers["content-type"] = workflowContext.headers.get("content-type");
|
|
@@ -635,7 +843,8 @@ var triggerFirstInvocation = async ({
|
|
|
635
843
|
headers,
|
|
636
844
|
method: "POST",
|
|
637
845
|
body,
|
|
638
|
-
url: workflowContext.url
|
|
846
|
+
url: workflowContext.url,
|
|
847
|
+
delay
|
|
639
848
|
});
|
|
640
849
|
if (result.deduplicated) {
|
|
641
850
|
await debug?.log("WARN", "SUBMIT_FIRST_INVOCATION", {
|
|
@@ -791,14 +1000,16 @@ ${atob(callbackMessage.body ?? "")}`
|
|
|
791
1000
|
const userHeaders = recreateUserHeaders(request.headers);
|
|
792
1001
|
const { headers: requestHeaders } = getHeaders({
|
|
793
1002
|
initHeaderValue: "false",
|
|
794
|
-
|
|
795
|
-
|
|
1003
|
+
workflowConfig: {
|
|
1004
|
+
workflowRunId,
|
|
1005
|
+
workflowUrl,
|
|
1006
|
+
failureUrl,
|
|
1007
|
+
retries,
|
|
1008
|
+
telemetry,
|
|
1009
|
+
flowControl
|
|
1010
|
+
},
|
|
796
1011
|
userHeaders,
|
|
797
|
-
|
|
798
|
-
retries,
|
|
799
|
-
telemetry,
|
|
800
|
-
invokeCount: Number(invokeCount),
|
|
801
|
-
flowControl
|
|
1012
|
+
invokeCount: Number(invokeCount)
|
|
802
1013
|
});
|
|
803
1014
|
const callResponse = {
|
|
804
1015
|
status: callbackMessage.status,
|
|
@@ -844,154 +1055,6 @@ var getTelemetryHeaders = (telemetry) => {
|
|
|
844
1055
|
[TELEMETRY_HEADER_RUNTIME]: telemetry.runtime ?? "unknown"
|
|
845
1056
|
};
|
|
846
1057
|
};
|
|
847
|
-
var getHeaders = ({
|
|
848
|
-
initHeaderValue,
|
|
849
|
-
workflowRunId,
|
|
850
|
-
workflowUrl,
|
|
851
|
-
userHeaders,
|
|
852
|
-
failureUrl,
|
|
853
|
-
retries,
|
|
854
|
-
step,
|
|
855
|
-
callRetries,
|
|
856
|
-
callTimeout,
|
|
857
|
-
telemetry,
|
|
858
|
-
invokeCount,
|
|
859
|
-
flowControl,
|
|
860
|
-
callFlowControl
|
|
861
|
-
}) => {
|
|
862
|
-
const callHeaders = new Headers(step?.callHeaders);
|
|
863
|
-
const contentType = (callHeaders.get("content-type") ? callHeaders.get("content-type") : userHeaders?.get("Content-Type") ? userHeaders.get("Content-Type") : void 0) ?? DEFAULT_CONTENT_TYPE;
|
|
864
|
-
const baseHeaders = {
|
|
865
|
-
[WORKFLOW_INIT_HEADER]: initHeaderValue,
|
|
866
|
-
[WORKFLOW_ID_HEADER]: workflowRunId,
|
|
867
|
-
[WORKFLOW_URL_HEADER]: workflowUrl,
|
|
868
|
-
[WORKFLOW_FEATURE_HEADER]: "LazyFetch,InitialBody",
|
|
869
|
-
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION,
|
|
870
|
-
"content-type": contentType,
|
|
871
|
-
...telemetry ? getTelemetryHeaders(telemetry) : {}
|
|
872
|
-
};
|
|
873
|
-
if (invokeCount !== void 0 && !step?.callUrl) {
|
|
874
|
-
baseHeaders[`Upstash-Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`] = invokeCount.toString();
|
|
875
|
-
}
|
|
876
|
-
if (!step?.callUrl) {
|
|
877
|
-
baseHeaders[`Upstash-Forward-${WORKFLOW_PROTOCOL_VERSION_HEADER}`] = WORKFLOW_PROTOCOL_VERSION;
|
|
878
|
-
}
|
|
879
|
-
if (callTimeout) {
|
|
880
|
-
baseHeaders[`Upstash-Timeout`] = callTimeout.toString();
|
|
881
|
-
}
|
|
882
|
-
if (failureUrl) {
|
|
883
|
-
baseHeaders[`Upstash-Failure-Callback-Forward-${WORKFLOW_FAILURE_HEADER}`] = "true";
|
|
884
|
-
baseHeaders[`Upstash-Failure-Callback-Forward-Upstash-Workflow-Failure-Callback`] = "true";
|
|
885
|
-
baseHeaders["Upstash-Failure-Callback-Workflow-Runid"] = workflowRunId;
|
|
886
|
-
baseHeaders["Upstash-Failure-Callback-Workflow-Init"] = "false";
|
|
887
|
-
baseHeaders["Upstash-Failure-Callback-Workflow-Url"] = workflowUrl;
|
|
888
|
-
baseHeaders["Upstash-Failure-Callback-Workflow-Calltype"] = "failureCall";
|
|
889
|
-
if (retries !== void 0) {
|
|
890
|
-
baseHeaders["Upstash-Failure-Callback-Retries"] = retries.toString();
|
|
891
|
-
}
|
|
892
|
-
if (flowControl) {
|
|
893
|
-
const { flowControlKey, flowControlValue } = prepareFlowControl(flowControl);
|
|
894
|
-
baseHeaders["Upstash-Failure-Callback-Flow-Control-Key"] = flowControlKey;
|
|
895
|
-
baseHeaders["Upstash-Failure-Callback-Flow-Control-Value"] = flowControlValue;
|
|
896
|
-
}
|
|
897
|
-
if (!step?.callUrl) {
|
|
898
|
-
baseHeaders["Upstash-Failure-Callback"] = failureUrl;
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
if (step?.callUrl) {
|
|
902
|
-
baseHeaders["Upstash-Retries"] = callRetries?.toString() ?? "0";
|
|
903
|
-
baseHeaders[WORKFLOW_FEATURE_HEADER] = "WF_NoDelete,InitialBody";
|
|
904
|
-
if (retries !== void 0) {
|
|
905
|
-
baseHeaders["Upstash-Callback-Retries"] = retries.toString();
|
|
906
|
-
baseHeaders["Upstash-Failure-Callback-Retries"] = retries.toString();
|
|
907
|
-
}
|
|
908
|
-
if (callFlowControl) {
|
|
909
|
-
const { flowControlKey, flowControlValue } = prepareFlowControl(callFlowControl);
|
|
910
|
-
baseHeaders["Upstash-Flow-Control-Key"] = flowControlKey;
|
|
911
|
-
baseHeaders["Upstash-Flow-Control-Value"] = flowControlValue;
|
|
912
|
-
}
|
|
913
|
-
if (flowControl) {
|
|
914
|
-
const { flowControlKey, flowControlValue } = prepareFlowControl(flowControl);
|
|
915
|
-
baseHeaders["Upstash-Callback-Flow-Control-Key"] = flowControlKey;
|
|
916
|
-
baseHeaders["Upstash-Callback-Flow-Control-Value"] = flowControlValue;
|
|
917
|
-
}
|
|
918
|
-
} else {
|
|
919
|
-
if (flowControl) {
|
|
920
|
-
const { flowControlKey, flowControlValue } = prepareFlowControl(flowControl);
|
|
921
|
-
baseHeaders["Upstash-Flow-Control-Key"] = flowControlKey;
|
|
922
|
-
baseHeaders["Upstash-Flow-Control-Value"] = flowControlValue;
|
|
923
|
-
}
|
|
924
|
-
if (retries !== void 0) {
|
|
925
|
-
baseHeaders["Upstash-Retries"] = retries.toString();
|
|
926
|
-
baseHeaders["Upstash-Failure-Callback-Retries"] = retries.toString();
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
if (userHeaders) {
|
|
930
|
-
for (const header of userHeaders.keys()) {
|
|
931
|
-
if (step?.callHeaders) {
|
|
932
|
-
baseHeaders[`Upstash-Callback-Forward-${header}`] = userHeaders.get(header);
|
|
933
|
-
} else {
|
|
934
|
-
baseHeaders[`Upstash-Forward-${header}`] = userHeaders.get(header);
|
|
935
|
-
}
|
|
936
|
-
baseHeaders[`Upstash-Failure-Callback-Forward-${header}`] = userHeaders.get(header);
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
if (step?.callHeaders) {
|
|
940
|
-
const forwardedHeaders = Object.fromEntries(
|
|
941
|
-
Object.entries(step.callHeaders).map(([header, value]) => [
|
|
942
|
-
`Upstash-Forward-${header}`,
|
|
943
|
-
value
|
|
944
|
-
])
|
|
945
|
-
);
|
|
946
|
-
return {
|
|
947
|
-
headers: {
|
|
948
|
-
...baseHeaders,
|
|
949
|
-
...forwardedHeaders,
|
|
950
|
-
"Upstash-Callback": workflowUrl,
|
|
951
|
-
"Upstash-Callback-Workflow-RunId": workflowRunId,
|
|
952
|
-
"Upstash-Callback-Workflow-CallType": "fromCallback",
|
|
953
|
-
"Upstash-Callback-Workflow-Init": "false",
|
|
954
|
-
"Upstash-Callback-Workflow-Url": workflowUrl,
|
|
955
|
-
"Upstash-Callback-Feature-Set": "LazyFetch,InitialBody",
|
|
956
|
-
"Upstash-Callback-Forward-Upstash-Workflow-Callback": "true",
|
|
957
|
-
"Upstash-Callback-Forward-Upstash-Workflow-StepId": step.stepId.toString(),
|
|
958
|
-
"Upstash-Callback-Forward-Upstash-Workflow-StepName": step.stepName,
|
|
959
|
-
"Upstash-Callback-Forward-Upstash-Workflow-StepType": step.stepType,
|
|
960
|
-
"Upstash-Callback-Forward-Upstash-Workflow-Concurrent": step.concurrent.toString(),
|
|
961
|
-
"Upstash-Callback-Forward-Upstash-Workflow-ContentType": contentType,
|
|
962
|
-
[`Upstash-Callback-Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`]: (invokeCount ?? 0).toString(),
|
|
963
|
-
"Upstash-Workflow-CallType": "toCallback"
|
|
964
|
-
}
|
|
965
|
-
};
|
|
966
|
-
}
|
|
967
|
-
if (step?.waitEventId) {
|
|
968
|
-
return {
|
|
969
|
-
headers: {
|
|
970
|
-
...baseHeaders,
|
|
971
|
-
"Upstash-Workflow-CallType": "step"
|
|
972
|
-
},
|
|
973
|
-
timeoutHeaders: {
|
|
974
|
-
// to include user headers:
|
|
975
|
-
...Object.fromEntries(
|
|
976
|
-
Object.entries(baseHeaders).map(([header, value]) => [header, [value]])
|
|
977
|
-
),
|
|
978
|
-
// to include telemetry headers:
|
|
979
|
-
...telemetry ? Object.fromEntries(
|
|
980
|
-
Object.entries(getTelemetryHeaders(telemetry)).map(([header, value]) => [
|
|
981
|
-
header,
|
|
982
|
-
[value]
|
|
983
|
-
])
|
|
984
|
-
) : {},
|
|
985
|
-
// note: using WORKFLOW_ID_HEADER doesn't work, because Runid -> RunId:
|
|
986
|
-
"Upstash-Workflow-Runid": [workflowRunId],
|
|
987
|
-
[WORKFLOW_INIT_HEADER]: ["false"],
|
|
988
|
-
[WORKFLOW_URL_HEADER]: [workflowUrl],
|
|
989
|
-
"Upstash-Workflow-CallType": ["step"]
|
|
990
|
-
}
|
|
991
|
-
};
|
|
992
|
-
}
|
|
993
|
-
return { headers: baseHeaders };
|
|
994
|
-
};
|
|
995
1058
|
var verifyRequest = async (body, signature, verifier) => {
|
|
996
1059
|
if (!verifier) {
|
|
997
1060
|
return;
|
|
@@ -1017,278 +1080,6 @@ If you want to disable QStash Verification, you should clear env variables QSTAS
|
|
|
1017
1080
|
);
|
|
1018
1081
|
}
|
|
1019
1082
|
};
|
|
1020
|
-
var prepareFlowControl = (flowControl) => {
|
|
1021
|
-
const parallelism = flowControl.parallelism?.toString();
|
|
1022
|
-
const rate = flowControl.ratePerSecond?.toString();
|
|
1023
|
-
const controlValue = [
|
|
1024
|
-
parallelism ? `parallelism=${parallelism}` : void 0,
|
|
1025
|
-
rate ? `rate=${rate}` : void 0
|
|
1026
|
-
].filter(Boolean);
|
|
1027
|
-
if (controlValue.length === 0) {
|
|
1028
|
-
throw new QstashError3("Provide at least one of parallelism or ratePerSecond for flowControl");
|
|
1029
|
-
}
|
|
1030
|
-
return {
|
|
1031
|
-
flowControlKey: flowControl.key,
|
|
1032
|
-
flowControlValue: controlValue.join(", ")
|
|
1033
|
-
};
|
|
1034
|
-
};
|
|
1035
|
-
|
|
1036
|
-
// src/serve/serve-many.ts
|
|
1037
|
-
var getWorkflowId = (url) => {
|
|
1038
|
-
const components = url.split("/");
|
|
1039
|
-
const lastComponent = components[components.length - 1];
|
|
1040
|
-
return lastComponent.split("?")[0];
|
|
1041
|
-
};
|
|
1042
|
-
var serveManyBase = ({
|
|
1043
|
-
workflows,
|
|
1044
|
-
getUrl,
|
|
1045
|
-
serveMethod,
|
|
1046
|
-
options
|
|
1047
|
-
}) => {
|
|
1048
|
-
const workflowIds = [];
|
|
1049
|
-
const workflowMap = Object.fromEntries(
|
|
1050
|
-
Object.entries(workflows).map((workflow) => {
|
|
1051
|
-
const workflowId = workflow[0];
|
|
1052
|
-
if (workflowIds.includes(workflowId)) {
|
|
1053
|
-
throw new WorkflowError(
|
|
1054
|
-
`Duplicate workflow name found: '${workflowId}'. Please set different workflow names in serveMany.`
|
|
1055
|
-
);
|
|
1056
|
-
}
|
|
1057
|
-
if (workflowId.includes("/")) {
|
|
1058
|
-
throw new WorkflowError(
|
|
1059
|
-
`Invalid workflow name found: '${workflowId}'. Workflow name cannot contain '/'.`
|
|
1060
|
-
);
|
|
1061
|
-
}
|
|
1062
|
-
workflowIds.push(workflowId);
|
|
1063
|
-
workflow[1].workflowId = workflowId;
|
|
1064
|
-
workflow[1].options = {
|
|
1065
|
-
...options,
|
|
1066
|
-
...workflow[1].options
|
|
1067
|
-
};
|
|
1068
|
-
const params = [workflow[1].routeFunction, workflow[1].options];
|
|
1069
|
-
const handler = serveMethod(...params);
|
|
1070
|
-
return [workflowId, handler];
|
|
1071
|
-
})
|
|
1072
|
-
);
|
|
1073
|
-
return {
|
|
1074
|
-
handler: async (...params) => {
|
|
1075
|
-
const url = getUrl(...params);
|
|
1076
|
-
const pickedWorkflowId = getWorkflowId(url);
|
|
1077
|
-
if (!pickedWorkflowId) {
|
|
1078
|
-
return new Response(
|
|
1079
|
-
`Unexpected request in serveMany. workflowId not set. Please update the URL of your request.`,
|
|
1080
|
-
{
|
|
1081
|
-
status: 404
|
|
1082
|
-
}
|
|
1083
|
-
);
|
|
1084
|
-
}
|
|
1085
|
-
const workflow = workflowMap[pickedWorkflowId];
|
|
1086
|
-
if (!workflow) {
|
|
1087
|
-
return new Response(
|
|
1088
|
-
`No workflows in serveMany found for '${pickedWorkflowId}'. Please update the URL of your request.`,
|
|
1089
|
-
{
|
|
1090
|
-
status: 404
|
|
1091
|
-
}
|
|
1092
|
-
);
|
|
1093
|
-
}
|
|
1094
|
-
return await workflow(...params);
|
|
1095
|
-
}
|
|
1096
|
-
};
|
|
1097
|
-
};
|
|
1098
|
-
var invokeWorkflow = async ({
|
|
1099
|
-
settings,
|
|
1100
|
-
invokeStep,
|
|
1101
|
-
context,
|
|
1102
|
-
invokeCount,
|
|
1103
|
-
telemetry
|
|
1104
|
-
}) => {
|
|
1105
|
-
const {
|
|
1106
|
-
body,
|
|
1107
|
-
workflow,
|
|
1108
|
-
headers = {},
|
|
1109
|
-
workflowRunId = getWorkflowRunId(),
|
|
1110
|
-
retries,
|
|
1111
|
-
flowControl
|
|
1112
|
-
} = settings;
|
|
1113
|
-
const { workflowId } = workflow;
|
|
1114
|
-
const {
|
|
1115
|
-
retries: workflowRetries,
|
|
1116
|
-
failureFunction,
|
|
1117
|
-
failureUrl,
|
|
1118
|
-
useJSONContent,
|
|
1119
|
-
flowControl: workflowFlowControl
|
|
1120
|
-
} = workflow.options;
|
|
1121
|
-
if (!workflowId) {
|
|
1122
|
-
throw new WorkflowError("You can only invoke workflow which has a workflowId");
|
|
1123
|
-
}
|
|
1124
|
-
const { headers: invokerHeaders } = getHeaders({
|
|
1125
|
-
initHeaderValue: "false",
|
|
1126
|
-
workflowRunId: context.workflowRunId,
|
|
1127
|
-
workflowUrl: context.url,
|
|
1128
|
-
userHeaders: context.headers,
|
|
1129
|
-
failureUrl: context.failureUrl,
|
|
1130
|
-
retries: context.retries,
|
|
1131
|
-
telemetry,
|
|
1132
|
-
invokeCount,
|
|
1133
|
-
flowControl: context.flowControl
|
|
1134
|
-
});
|
|
1135
|
-
invokerHeaders["Upstash-Workflow-Runid"] = context.workflowRunId;
|
|
1136
|
-
const newUrl = context.url.replace(/[^/]+$/, workflowId);
|
|
1137
|
-
const { headers: triggerHeaders } = getHeaders({
|
|
1138
|
-
initHeaderValue: "true",
|
|
1139
|
-
workflowRunId,
|
|
1140
|
-
workflowUrl: newUrl,
|
|
1141
|
-
userHeaders: new Headers(headers),
|
|
1142
|
-
retries: retries ?? workflowRetries,
|
|
1143
|
-
telemetry,
|
|
1144
|
-
failureUrl: failureFunction ? newUrl : failureUrl,
|
|
1145
|
-
invokeCount: invokeCount + 1,
|
|
1146
|
-
flowControl: flowControl ?? workflowFlowControl
|
|
1147
|
-
});
|
|
1148
|
-
triggerHeaders["Upstash-Workflow-Invoke"] = "true";
|
|
1149
|
-
if (useJSONContent) {
|
|
1150
|
-
triggerHeaders["content-type"] = "application/json";
|
|
1151
|
-
}
|
|
1152
|
-
const request = {
|
|
1153
|
-
body: JSON.stringify(body),
|
|
1154
|
-
headers: Object.fromEntries(
|
|
1155
|
-
Object.entries(invokerHeaders).map((pairs) => [pairs[0], [pairs[1]]])
|
|
1156
|
-
),
|
|
1157
|
-
workflowRunId: context.workflowRunId,
|
|
1158
|
-
workflowUrl: context.url,
|
|
1159
|
-
step: invokeStep
|
|
1160
|
-
};
|
|
1161
|
-
await context.qstashClient.publish({
|
|
1162
|
-
headers: triggerHeaders,
|
|
1163
|
-
method: "POST",
|
|
1164
|
-
body: JSON.stringify(request),
|
|
1165
|
-
url: newUrl
|
|
1166
|
-
});
|
|
1167
|
-
};
|
|
1168
|
-
|
|
1169
|
-
// src/agents/adapters.ts
|
|
1170
|
-
import { createOpenAI } from "@ai-sdk/openai";
|
|
1171
|
-
import { tool } from "ai";
|
|
1172
|
-
|
|
1173
|
-
// src/agents/constants.ts
|
|
1174
|
-
var AGENT_NAME_HEADER = "upstash-agent-name";
|
|
1175
|
-
var MANAGER_AGENT_PROMPT = `You are an agent orchestrating other AI Agents.
|
|
1176
|
-
|
|
1177
|
-
These other agents have tools available to them.
|
|
1178
|
-
|
|
1179
|
-
Given a prompt, utilize these agents to address requests.
|
|
1180
|
-
|
|
1181
|
-
Don't always call all the agents provided to you at the same time. You can call one and use it's response to call another.
|
|
1182
|
-
|
|
1183
|
-
Avoid calling the same agent twice in one turn. Instead, prefer to call it once but provide everything
|
|
1184
|
-
you need from that agent.
|
|
1185
|
-
`;
|
|
1186
|
-
|
|
1187
|
-
// src/agents/adapters.ts
|
|
1188
|
-
var createWorkflowOpenAI = (context, config) => {
|
|
1189
|
-
const { baseURL, apiKey } = config ?? {};
|
|
1190
|
-
return createOpenAI({
|
|
1191
|
-
baseURL,
|
|
1192
|
-
apiKey,
|
|
1193
|
-
compatibility: "strict",
|
|
1194
|
-
fetch: async (input, init) => {
|
|
1195
|
-
try {
|
|
1196
|
-
const headers = init?.headers ? Object.fromEntries(new Headers(init.headers).entries()) : {};
|
|
1197
|
-
const body = init?.body ? JSON.parse(init.body) : void 0;
|
|
1198
|
-
const agentName = headers[AGENT_NAME_HEADER];
|
|
1199
|
-
const stepName = agentName ? `Call Agent ${agentName}` : "Call Agent";
|
|
1200
|
-
const responseInfo = await context.call(stepName, {
|
|
1201
|
-
url: input.toString(),
|
|
1202
|
-
method: init?.method,
|
|
1203
|
-
headers,
|
|
1204
|
-
body
|
|
1205
|
-
});
|
|
1206
|
-
const responseHeaders = new Headers(
|
|
1207
|
-
Object.entries(responseInfo.header).reduce(
|
|
1208
|
-
(acc, [key, values]) => {
|
|
1209
|
-
acc[key] = values.join(", ");
|
|
1210
|
-
return acc;
|
|
1211
|
-
},
|
|
1212
|
-
{}
|
|
1213
|
-
)
|
|
1214
|
-
);
|
|
1215
|
-
return new Response(JSON.stringify(responseInfo.body), {
|
|
1216
|
-
status: responseInfo.status,
|
|
1217
|
-
headers: responseHeaders
|
|
1218
|
-
});
|
|
1219
|
-
} catch (error) {
|
|
1220
|
-
if (error instanceof Error && error.name === "WorkflowAbort") {
|
|
1221
|
-
throw error;
|
|
1222
|
-
} else {
|
|
1223
|
-
console.error("Error in fetch implementation:", error);
|
|
1224
|
-
throw error;
|
|
1225
|
-
}
|
|
1226
|
-
}
|
|
1227
|
-
}
|
|
1228
|
-
});
|
|
1229
|
-
};
|
|
1230
|
-
var wrapTools = ({
|
|
1231
|
-
context,
|
|
1232
|
-
tools
|
|
1233
|
-
}) => {
|
|
1234
|
-
return Object.fromEntries(
|
|
1235
|
-
Object.entries(tools).map((toolInfo) => {
|
|
1236
|
-
const [toolName, tool3] = toolInfo;
|
|
1237
|
-
const executeAsStep = "executeAsStep" in tool3 ? tool3.executeAsStep : true;
|
|
1238
|
-
const aiSDKTool = convertToAISDKTool(tool3);
|
|
1239
|
-
const execute = aiSDKTool.execute;
|
|
1240
|
-
if (execute && executeAsStep) {
|
|
1241
|
-
const wrappedExecute = (...params) => {
|
|
1242
|
-
return context.run(`Run tool ${toolName}`, () => execute(...params));
|
|
1243
|
-
};
|
|
1244
|
-
aiSDKTool.execute = wrappedExecute;
|
|
1245
|
-
}
|
|
1246
|
-
return [toolName, aiSDKTool];
|
|
1247
|
-
})
|
|
1248
|
-
);
|
|
1249
|
-
};
|
|
1250
|
-
var convertToAISDKTool = (tool3) => {
|
|
1251
|
-
const isLangchainTool = "invoke" in tool3;
|
|
1252
|
-
return isLangchainTool ? convertLangchainTool(tool3) : tool3;
|
|
1253
|
-
};
|
|
1254
|
-
var convertLangchainTool = (langchainTool) => {
|
|
1255
|
-
return tool({
|
|
1256
|
-
description: langchainTool.description,
|
|
1257
|
-
parameters: langchainTool.schema,
|
|
1258
|
-
execute: async (...param) => langchainTool.invoke(...param)
|
|
1259
|
-
});
|
|
1260
|
-
};
|
|
1261
|
-
var WorkflowTool = class {
|
|
1262
|
-
/**
|
|
1263
|
-
* description of the tool
|
|
1264
|
-
*/
|
|
1265
|
-
description;
|
|
1266
|
-
/**
|
|
1267
|
-
* schema of the tool
|
|
1268
|
-
*/
|
|
1269
|
-
schema;
|
|
1270
|
-
/**
|
|
1271
|
-
* function to invoke the tool
|
|
1272
|
-
*/
|
|
1273
|
-
invoke;
|
|
1274
|
-
/**
|
|
1275
|
-
* whether the invoke method of the tool is to be wrapped with `context.run`
|
|
1276
|
-
*/
|
|
1277
|
-
executeAsStep;
|
|
1278
|
-
/**
|
|
1279
|
-
*
|
|
1280
|
-
* @param description description of the tool
|
|
1281
|
-
* @param schema schema of the tool
|
|
1282
|
-
* @param invoke function to invoke the tool
|
|
1283
|
-
* @param executeAsStep whether the invoke method of the tool is to be wrapped with `context.run`
|
|
1284
|
-
*/
|
|
1285
|
-
constructor(params) {
|
|
1286
|
-
this.description = params.description;
|
|
1287
|
-
this.schema = params.schema;
|
|
1288
|
-
this.invoke = params.invoke;
|
|
1289
|
-
this.executeAsStep = params.executeAsStep ?? true;
|
|
1290
|
-
}
|
|
1291
|
-
};
|
|
1292
1083
|
|
|
1293
1084
|
// src/context/steps.ts
|
|
1294
1085
|
var BaseLazyStep = class _BaseLazyStep {
|
|
@@ -1299,6 +1090,11 @@ var BaseLazyStep = class _BaseLazyStep {
|
|
|
1299
1090
|
"A workflow step name cannot be undefined or an empty string. Please provide a name for your workflow step."
|
|
1300
1091
|
);
|
|
1301
1092
|
}
|
|
1093
|
+
if (typeof stepName !== "string") {
|
|
1094
|
+
console.warn(
|
|
1095
|
+
"Workflow Warning: A workflow step name must be a string. In a future release, this will throw an error."
|
|
1096
|
+
);
|
|
1097
|
+
}
|
|
1302
1098
|
this.stepName = stepName;
|
|
1303
1099
|
}
|
|
1304
1100
|
/**
|
|
@@ -1348,6 +1144,40 @@ var BaseLazyStep = class _BaseLazyStep {
|
|
|
1348
1144
|
return stepOut;
|
|
1349
1145
|
}
|
|
1350
1146
|
}
|
|
1147
|
+
getBody({ step }) {
|
|
1148
|
+
step.out = JSON.stringify(step.out);
|
|
1149
|
+
return JSON.stringify(step);
|
|
1150
|
+
}
|
|
1151
|
+
getHeaders({ context, telemetry, invokeCount, step }) {
|
|
1152
|
+
return getHeaders({
|
|
1153
|
+
initHeaderValue: "false",
|
|
1154
|
+
workflowConfig: {
|
|
1155
|
+
workflowRunId: context.workflowRunId,
|
|
1156
|
+
workflowUrl: context.url,
|
|
1157
|
+
failureUrl: context.failureUrl,
|
|
1158
|
+
retries: context.retries,
|
|
1159
|
+
useJSONContent: false,
|
|
1160
|
+
telemetry,
|
|
1161
|
+
flowControl: context.flowControl
|
|
1162
|
+
},
|
|
1163
|
+
userHeaders: context.headers,
|
|
1164
|
+
invokeCount,
|
|
1165
|
+
stepInfo: {
|
|
1166
|
+
step,
|
|
1167
|
+
lazyStep: this
|
|
1168
|
+
}
|
|
1169
|
+
});
|
|
1170
|
+
}
|
|
1171
|
+
async submitStep({ context, body, headers }) {
|
|
1172
|
+
return await context.qstashClient.batch([
|
|
1173
|
+
{
|
|
1174
|
+
body,
|
|
1175
|
+
headers,
|
|
1176
|
+
method: "POST",
|
|
1177
|
+
url: context.url
|
|
1178
|
+
}
|
|
1179
|
+
]);
|
|
1180
|
+
}
|
|
1351
1181
|
};
|
|
1352
1182
|
var LazyFunctionStep = class extends BaseLazyStep {
|
|
1353
1183
|
stepFunction;
|
|
@@ -1407,6 +1237,17 @@ var LazySleepStep = class extends BaseLazyStep {
|
|
|
1407
1237
|
concurrent
|
|
1408
1238
|
});
|
|
1409
1239
|
}
|
|
1240
|
+
async submitStep({ context, body, headers, isParallel }) {
|
|
1241
|
+
return await context.qstashClient.batch([
|
|
1242
|
+
{
|
|
1243
|
+
body,
|
|
1244
|
+
headers,
|
|
1245
|
+
method: "POST",
|
|
1246
|
+
url: context.url,
|
|
1247
|
+
delay: isParallel ? void 0 : this.sleep
|
|
1248
|
+
}
|
|
1249
|
+
]);
|
|
1250
|
+
}
|
|
1410
1251
|
};
|
|
1411
1252
|
var LazySleepUntilStep = class extends BaseLazyStep {
|
|
1412
1253
|
sleepUntil;
|
|
@@ -1438,6 +1279,17 @@ var LazySleepUntilStep = class extends BaseLazyStep {
|
|
|
1438
1279
|
safeParseOut() {
|
|
1439
1280
|
return void 0;
|
|
1440
1281
|
}
|
|
1282
|
+
async submitStep({ context, body, headers, isParallel }) {
|
|
1283
|
+
return await context.qstashClient.batch([
|
|
1284
|
+
{
|
|
1285
|
+
body,
|
|
1286
|
+
headers,
|
|
1287
|
+
method: "POST",
|
|
1288
|
+
url: context.url,
|
|
1289
|
+
notBefore: isParallel ? void 0 : this.sleepUntil
|
|
1290
|
+
}
|
|
1291
|
+
]);
|
|
1292
|
+
}
|
|
1441
1293
|
};
|
|
1442
1294
|
var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
|
|
1443
1295
|
url;
|
|
@@ -1521,6 +1373,58 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
|
|
|
1521
1373
|
}
|
|
1522
1374
|
return false;
|
|
1523
1375
|
};
|
|
1376
|
+
getBody({ step }) {
|
|
1377
|
+
if (!step.callUrl) {
|
|
1378
|
+
throw new WorkflowError("Incompatible step received in LazyCallStep.getBody");
|
|
1379
|
+
}
|
|
1380
|
+
return JSON.stringify(step.callBody);
|
|
1381
|
+
}
|
|
1382
|
+
getHeaders({ context, telemetry, invokeCount, step }) {
|
|
1383
|
+
const { headers, contentType } = super.getHeaders({ context, telemetry, invokeCount, step });
|
|
1384
|
+
headers["Upstash-Retries"] = this.retries.toString();
|
|
1385
|
+
headers[WORKFLOW_FEATURE_HEADER] = "WF_NoDelete,InitialBody";
|
|
1386
|
+
if (this.flowControl) {
|
|
1387
|
+
const { flowControlKey, flowControlValue } = prepareFlowControl(this.flowControl);
|
|
1388
|
+
headers["Upstash-Flow-Control-Key"] = flowControlKey;
|
|
1389
|
+
headers["Upstash-Flow-Control-Value"] = flowControlValue;
|
|
1390
|
+
}
|
|
1391
|
+
if (this.timeout) {
|
|
1392
|
+
headers["Upstash-Timeout"] = this.timeout.toString();
|
|
1393
|
+
}
|
|
1394
|
+
const forwardedHeaders = Object.fromEntries(
|
|
1395
|
+
Object.entries(this.headers).map(([header, value]) => [`Upstash-Forward-${header}`, value])
|
|
1396
|
+
);
|
|
1397
|
+
return {
|
|
1398
|
+
headers: {
|
|
1399
|
+
...headers,
|
|
1400
|
+
...forwardedHeaders,
|
|
1401
|
+
"Upstash-Callback": context.url,
|
|
1402
|
+
"Upstash-Callback-Workflow-RunId": context.workflowRunId,
|
|
1403
|
+
"Upstash-Callback-Workflow-CallType": "fromCallback",
|
|
1404
|
+
"Upstash-Callback-Workflow-Init": "false",
|
|
1405
|
+
"Upstash-Callback-Workflow-Url": context.url,
|
|
1406
|
+
"Upstash-Callback-Feature-Set": "LazyFetch,InitialBody",
|
|
1407
|
+
"Upstash-Callback-Forward-Upstash-Workflow-Callback": "true",
|
|
1408
|
+
"Upstash-Callback-Forward-Upstash-Workflow-StepId": step.stepId.toString(),
|
|
1409
|
+
"Upstash-Callback-Forward-Upstash-Workflow-StepName": this.stepName,
|
|
1410
|
+
"Upstash-Callback-Forward-Upstash-Workflow-StepType": this.stepType,
|
|
1411
|
+
"Upstash-Callback-Forward-Upstash-Workflow-Concurrent": step.concurrent.toString(),
|
|
1412
|
+
"Upstash-Callback-Forward-Upstash-Workflow-ContentType": contentType,
|
|
1413
|
+
"Upstash-Workflow-CallType": "toCallback"
|
|
1414
|
+
},
|
|
1415
|
+
contentType
|
|
1416
|
+
};
|
|
1417
|
+
}
|
|
1418
|
+
async submitStep({ context, headers }) {
|
|
1419
|
+
return await context.qstashClient.batch([
|
|
1420
|
+
{
|
|
1421
|
+
headers,
|
|
1422
|
+
body: JSON.stringify(this.body),
|
|
1423
|
+
method: this.method,
|
|
1424
|
+
url: this.url
|
|
1425
|
+
}
|
|
1426
|
+
]);
|
|
1427
|
+
}
|
|
1524
1428
|
};
|
|
1525
1429
|
var LazyWaitForEventStep = class extends BaseLazyStep {
|
|
1526
1430
|
eventId;
|
|
@@ -1560,6 +1464,57 @@ var LazyWaitForEventStep = class extends BaseLazyStep {
|
|
|
1560
1464
|
eventData: BaseLazyStep.tryParsing(result.eventData)
|
|
1561
1465
|
};
|
|
1562
1466
|
}
|
|
1467
|
+
getHeaders({ context, telemetry, invokeCount, step }) {
|
|
1468
|
+
const headers = super.getHeaders({ context, telemetry, invokeCount, step });
|
|
1469
|
+
headers.headers["Upstash-Workflow-CallType"] = "step";
|
|
1470
|
+
return headers;
|
|
1471
|
+
}
|
|
1472
|
+
getBody({ context, step, headers, telemetry }) {
|
|
1473
|
+
if (!step.waitEventId) {
|
|
1474
|
+
throw new WorkflowError("Incompatible step received in LazyWaitForEventStep.getBody");
|
|
1475
|
+
}
|
|
1476
|
+
const timeoutHeaders = {
|
|
1477
|
+
// to include user headers:
|
|
1478
|
+
...Object.fromEntries(Object.entries(headers).map(([header, value]) => [header, [value]])),
|
|
1479
|
+
// to include telemetry headers:
|
|
1480
|
+
...telemetry ? Object.fromEntries(
|
|
1481
|
+
Object.entries(getTelemetryHeaders(telemetry)).map(([header, value]) => [
|
|
1482
|
+
header,
|
|
1483
|
+
[value]
|
|
1484
|
+
])
|
|
1485
|
+
) : {},
|
|
1486
|
+
// note: using WORKFLOW_ID_HEADER doesn't work, because Runid -> RunId:
|
|
1487
|
+
"Upstash-Workflow-Runid": [context.workflowRunId],
|
|
1488
|
+
[WORKFLOW_INIT_HEADER]: ["false"],
|
|
1489
|
+
[WORKFLOW_URL_HEADER]: [context.url],
|
|
1490
|
+
"Upstash-Workflow-CallType": ["step"]
|
|
1491
|
+
};
|
|
1492
|
+
const waitBody = {
|
|
1493
|
+
url: context.url,
|
|
1494
|
+
timeout: step.timeout,
|
|
1495
|
+
timeoutBody: void 0,
|
|
1496
|
+
timeoutUrl: context.url,
|
|
1497
|
+
timeoutHeaders,
|
|
1498
|
+
step: {
|
|
1499
|
+
stepId: step.stepId,
|
|
1500
|
+
stepType: "Wait",
|
|
1501
|
+
stepName: step.stepName,
|
|
1502
|
+
concurrent: step.concurrent,
|
|
1503
|
+
targetStep: step.targetStep
|
|
1504
|
+
}
|
|
1505
|
+
};
|
|
1506
|
+
return JSON.stringify(waitBody);
|
|
1507
|
+
}
|
|
1508
|
+
async submitStep({ context, body, headers }) {
|
|
1509
|
+
const result = await context.qstashClient.http.request({
|
|
1510
|
+
path: ["v2", "wait", this.eventId],
|
|
1511
|
+
body,
|
|
1512
|
+
headers,
|
|
1513
|
+
method: "POST",
|
|
1514
|
+
parseResponseAsJson: false
|
|
1515
|
+
});
|
|
1516
|
+
return [result];
|
|
1517
|
+
}
|
|
1563
1518
|
};
|
|
1564
1519
|
var LazyNotifyStep = class extends LazyFunctionStep {
|
|
1565
1520
|
stepType = "Notify";
|
|
@@ -1585,6 +1540,10 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1585
1540
|
stepType = "Invoke";
|
|
1586
1541
|
params;
|
|
1587
1542
|
allowUndefinedOut = false;
|
|
1543
|
+
/**
|
|
1544
|
+
* workflow id of the invoked workflow
|
|
1545
|
+
*/
|
|
1546
|
+
workflowId;
|
|
1588
1547
|
constructor(stepName, {
|
|
1589
1548
|
workflow,
|
|
1590
1549
|
body,
|
|
@@ -1602,6 +1561,11 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1602
1561
|
retries,
|
|
1603
1562
|
flowControl
|
|
1604
1563
|
};
|
|
1564
|
+
const { workflowId } = workflow;
|
|
1565
|
+
if (!workflowId) {
|
|
1566
|
+
throw new WorkflowError("You can only invoke workflow which has a workflowId");
|
|
1567
|
+
}
|
|
1568
|
+
this.workflowId = workflowId;
|
|
1605
1569
|
}
|
|
1606
1570
|
getPlanStep(concurrent, targetStep) {
|
|
1607
1571
|
return {
|
|
@@ -1631,10 +1595,348 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1631
1595
|
body: BaseLazyStep.tryParsing(result.body)
|
|
1632
1596
|
};
|
|
1633
1597
|
}
|
|
1598
|
+
getBody({ context, step, telemetry, invokeCount }) {
|
|
1599
|
+
const { headers: invokerHeaders } = getHeaders({
|
|
1600
|
+
initHeaderValue: "false",
|
|
1601
|
+
workflowConfig: {
|
|
1602
|
+
workflowRunId: context.workflowRunId,
|
|
1603
|
+
workflowUrl: context.url,
|
|
1604
|
+
failureUrl: context.failureUrl,
|
|
1605
|
+
retries: context.retries,
|
|
1606
|
+
telemetry,
|
|
1607
|
+
flowControl: context.flowControl,
|
|
1608
|
+
useJSONContent: false
|
|
1609
|
+
},
|
|
1610
|
+
userHeaders: context.headers,
|
|
1611
|
+
invokeCount
|
|
1612
|
+
});
|
|
1613
|
+
invokerHeaders["Upstash-Workflow-Runid"] = context.workflowRunId;
|
|
1614
|
+
const request = {
|
|
1615
|
+
body: JSON.stringify(this.params.body),
|
|
1616
|
+
headers: Object.fromEntries(
|
|
1617
|
+
Object.entries(invokerHeaders).map((pairs) => [pairs[0], [pairs[1]]])
|
|
1618
|
+
),
|
|
1619
|
+
workflowRunId: context.workflowRunId,
|
|
1620
|
+
workflowUrl: context.url,
|
|
1621
|
+
step
|
|
1622
|
+
};
|
|
1623
|
+
return JSON.stringify(request);
|
|
1624
|
+
}
|
|
1625
|
+
getHeaders({ context, telemetry, invokeCount }) {
|
|
1626
|
+
const {
|
|
1627
|
+
workflow,
|
|
1628
|
+
headers = {},
|
|
1629
|
+
workflowRunId = getWorkflowRunId(),
|
|
1630
|
+
retries,
|
|
1631
|
+
flowControl
|
|
1632
|
+
} = this.params;
|
|
1633
|
+
const newUrl = context.url.replace(/[^/]+$/, this.workflowId);
|
|
1634
|
+
const {
|
|
1635
|
+
retries: workflowRetries,
|
|
1636
|
+
failureFunction,
|
|
1637
|
+
failureUrl,
|
|
1638
|
+
useJSONContent,
|
|
1639
|
+
flowControl: workflowFlowControl
|
|
1640
|
+
} = workflow.options;
|
|
1641
|
+
const { headers: triggerHeaders, contentType } = getHeaders({
|
|
1642
|
+
initHeaderValue: "true",
|
|
1643
|
+
workflowConfig: {
|
|
1644
|
+
workflowRunId,
|
|
1645
|
+
workflowUrl: newUrl,
|
|
1646
|
+
retries: retries ?? workflowRetries,
|
|
1647
|
+
telemetry,
|
|
1648
|
+
failureUrl: failureFunction ? newUrl : failureUrl,
|
|
1649
|
+
flowControl: flowControl ?? workflowFlowControl,
|
|
1650
|
+
useJSONContent: useJSONContent ?? false
|
|
1651
|
+
},
|
|
1652
|
+
invokeCount: invokeCount + 1,
|
|
1653
|
+
userHeaders: new Headers(headers)
|
|
1654
|
+
});
|
|
1655
|
+
triggerHeaders["Upstash-Workflow-Invoke"] = "true";
|
|
1656
|
+
return { headers: triggerHeaders, contentType };
|
|
1657
|
+
}
|
|
1658
|
+
async submitStep({ context, body, headers }) {
|
|
1659
|
+
const newUrl = context.url.replace(/[^/]+$/, this.workflowId);
|
|
1660
|
+
const result = await context.qstashClient.publish({
|
|
1661
|
+
headers,
|
|
1662
|
+
method: "POST",
|
|
1663
|
+
body,
|
|
1664
|
+
url: newUrl
|
|
1665
|
+
});
|
|
1666
|
+
return [result];
|
|
1667
|
+
}
|
|
1668
|
+
};
|
|
1669
|
+
|
|
1670
|
+
// src/qstash/headers.ts
|
|
1671
|
+
var WorkflowHeaders = class {
|
|
1672
|
+
userHeaders;
|
|
1673
|
+
workflowConfig;
|
|
1674
|
+
invokeCount;
|
|
1675
|
+
initHeaderValue;
|
|
1676
|
+
stepInfo;
|
|
1677
|
+
headers;
|
|
1678
|
+
constructor({
|
|
1679
|
+
userHeaders,
|
|
1680
|
+
workflowConfig,
|
|
1681
|
+
invokeCount,
|
|
1682
|
+
initHeaderValue,
|
|
1683
|
+
stepInfo
|
|
1684
|
+
}) {
|
|
1685
|
+
this.userHeaders = userHeaders;
|
|
1686
|
+
this.workflowConfig = workflowConfig;
|
|
1687
|
+
this.invokeCount = invokeCount;
|
|
1688
|
+
this.initHeaderValue = initHeaderValue;
|
|
1689
|
+
this.stepInfo = stepInfo;
|
|
1690
|
+
this.headers = {
|
|
1691
|
+
rawHeaders: {},
|
|
1692
|
+
workflowHeaders: {},
|
|
1693
|
+
failureHeaders: {}
|
|
1694
|
+
};
|
|
1695
|
+
}
|
|
1696
|
+
getHeaders() {
|
|
1697
|
+
this.addBaseHeaders();
|
|
1698
|
+
this.addRetries();
|
|
1699
|
+
this.addFlowControl();
|
|
1700
|
+
this.addUserHeaders();
|
|
1701
|
+
this.addInvokeCount();
|
|
1702
|
+
this.addFailureUrl();
|
|
1703
|
+
const contentType = this.addContentType();
|
|
1704
|
+
return this.prefixHeaders(contentType);
|
|
1705
|
+
}
|
|
1706
|
+
addBaseHeaders() {
|
|
1707
|
+
this.headers.rawHeaders = {
|
|
1708
|
+
...this.headers.rawHeaders,
|
|
1709
|
+
[WORKFLOW_INIT_HEADER]: this.initHeaderValue,
|
|
1710
|
+
[WORKFLOW_ID_HEADER]: this.workflowConfig.workflowRunId,
|
|
1711
|
+
[WORKFLOW_URL_HEADER]: this.workflowConfig.workflowUrl,
|
|
1712
|
+
[WORKFLOW_FEATURE_HEADER]: "LazyFetch,InitialBody",
|
|
1713
|
+
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION,
|
|
1714
|
+
...this.workflowConfig.telemetry ? getTelemetryHeaders(this.workflowConfig.telemetry) : {},
|
|
1715
|
+
...this.workflowConfig.telemetry && this.stepInfo?.lazyStep instanceof LazyCallStep && this.stepInfo.lazyStep.headers[AGENT_NAME_HEADER] ? { [TELEMETRY_HEADER_AGENT]: "true" } : {}
|
|
1716
|
+
};
|
|
1717
|
+
if (this.stepInfo?.lazyStep.stepType !== "Call") {
|
|
1718
|
+
this.headers.rawHeaders[`Upstash-Forward-${WORKFLOW_PROTOCOL_VERSION_HEADER}`] = WORKFLOW_PROTOCOL_VERSION;
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1721
|
+
addInvokeCount() {
|
|
1722
|
+
if (this.invokeCount === void 0 || this.invokeCount === 0) {
|
|
1723
|
+
return;
|
|
1724
|
+
}
|
|
1725
|
+
const invokeCount = this.invokeCount.toString();
|
|
1726
|
+
this.headers.workflowHeaders[`Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`] = invokeCount;
|
|
1727
|
+
if (this.workflowConfig.failureUrl) {
|
|
1728
|
+
this.headers.failureHeaders[`Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`] = invokeCount;
|
|
1729
|
+
}
|
|
1730
|
+
if (this.stepInfo?.lazyStep instanceof LazyCallStep) {
|
|
1731
|
+
this.headers.rawHeaders[`Upstash-Forward-${WORKFLOW_INVOKE_COUNT_HEADER}`] = invokeCount;
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1734
|
+
addRetries() {
|
|
1735
|
+
if (this.workflowConfig.retries === void 0 || this.workflowConfig.retries === DEFAULT_RETRIES) {
|
|
1736
|
+
return;
|
|
1737
|
+
}
|
|
1738
|
+
const retries = this.workflowConfig.retries.toString();
|
|
1739
|
+
this.headers.workflowHeaders["Retries"] = retries;
|
|
1740
|
+
if (this.workflowConfig.failureUrl) {
|
|
1741
|
+
this.headers.failureHeaders["Retries"] = retries;
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
addFlowControl() {
|
|
1745
|
+
if (!this.workflowConfig.flowControl) {
|
|
1746
|
+
return;
|
|
1747
|
+
}
|
|
1748
|
+
const { flowControlKey, flowControlValue } = prepareFlowControl(
|
|
1749
|
+
this.workflowConfig.flowControl
|
|
1750
|
+
);
|
|
1751
|
+
this.headers.workflowHeaders["Flow-Control-Key"] = flowControlKey;
|
|
1752
|
+
this.headers.workflowHeaders["Flow-Control-Value"] = flowControlValue;
|
|
1753
|
+
if (this.workflowConfig.failureUrl) {
|
|
1754
|
+
this.headers.failureHeaders["Flow-Control-Key"] = flowControlKey;
|
|
1755
|
+
this.headers.failureHeaders["Flow-Control-Value"] = flowControlValue;
|
|
1756
|
+
}
|
|
1757
|
+
}
|
|
1758
|
+
addUserHeaders() {
|
|
1759
|
+
for (const [key, value] of this.userHeaders.entries()) {
|
|
1760
|
+
const forwardKey = `Forward-${key}`;
|
|
1761
|
+
this.headers.workflowHeaders[forwardKey] = value;
|
|
1762
|
+
if (this.workflowConfig.failureUrl) {
|
|
1763
|
+
this.headers.failureHeaders[forwardKey] = value;
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
addFailureUrl() {
|
|
1768
|
+
if (!this.workflowConfig.failureUrl) {
|
|
1769
|
+
return;
|
|
1770
|
+
}
|
|
1771
|
+
this.headers.workflowHeaders["Failure-Callback"] = this.workflowConfig.failureUrl;
|
|
1772
|
+
this.headers.failureHeaders[`Forward-${WORKFLOW_FAILURE_HEADER}`] = "true";
|
|
1773
|
+
this.headers.failureHeaders[`Forward-Upstash-Workflow-Failure-Callback`] = "true";
|
|
1774
|
+
this.headers.failureHeaders["Workflow-Runid"] = this.workflowConfig.workflowRunId;
|
|
1775
|
+
this.headers.failureHeaders["Workflow-Init"] = "false";
|
|
1776
|
+
this.headers.failureHeaders["Workflow-Url"] = this.workflowConfig.workflowUrl;
|
|
1777
|
+
this.headers.failureHeaders["Workflow-Calltype"] = "failureCall";
|
|
1778
|
+
this.headers.failureHeaders["Feature-Set"] = "LazyFetch,InitialBody";
|
|
1779
|
+
if (this.workflowConfig.retries !== void 0 && this.workflowConfig.retries !== DEFAULT_RETRIES) {
|
|
1780
|
+
this.headers.failureHeaders["Retries"] = this.workflowConfig.retries.toString();
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1783
|
+
addContentType() {
|
|
1784
|
+
if (this.workflowConfig.useJSONContent) {
|
|
1785
|
+
this.headers.rawHeaders["content-type"] = "application/json";
|
|
1786
|
+
return "application/json";
|
|
1787
|
+
}
|
|
1788
|
+
const callHeaders = new Headers(
|
|
1789
|
+
this.stepInfo?.lazyStep instanceof LazyCallStep ? this.stepInfo.lazyStep.headers : {}
|
|
1790
|
+
);
|
|
1791
|
+
const contentType = (callHeaders.get("content-type") ? callHeaders.get("content-type") : this.userHeaders?.get("Content-Type") ? this.userHeaders.get("Content-Type") : void 0) ?? DEFAULT_CONTENT_TYPE;
|
|
1792
|
+
this.headers.rawHeaders["content-type"] = contentType;
|
|
1793
|
+
return contentType;
|
|
1794
|
+
}
|
|
1795
|
+
prefixHeaders(contentType) {
|
|
1796
|
+
const { rawHeaders, workflowHeaders, failureHeaders } = this.headers;
|
|
1797
|
+
const isCall = this.stepInfo?.lazyStep.stepType === "Call";
|
|
1798
|
+
return {
|
|
1799
|
+
headers: {
|
|
1800
|
+
...rawHeaders,
|
|
1801
|
+
...addPrefixToHeaders(workflowHeaders, isCall ? "Upstash-Callback-" : "Upstash-"),
|
|
1802
|
+
...addPrefixToHeaders(failureHeaders, "Upstash-Failure-Callback-"),
|
|
1803
|
+
...isCall ? addPrefixToHeaders(failureHeaders, "Upstash-Callback-Failure-Callback-") : {}
|
|
1804
|
+
},
|
|
1805
|
+
contentType
|
|
1806
|
+
};
|
|
1807
|
+
}
|
|
1808
|
+
};
|
|
1809
|
+
function addPrefixToHeaders(headers, prefix) {
|
|
1810
|
+
const prefixedHeaders = {};
|
|
1811
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
1812
|
+
prefixedHeaders[`${prefix}${key}`] = value;
|
|
1813
|
+
}
|
|
1814
|
+
return prefixedHeaders;
|
|
1815
|
+
}
|
|
1816
|
+
var prepareFlowControl = (flowControl) => {
|
|
1817
|
+
const parallelism = flowControl.parallelism?.toString();
|
|
1818
|
+
const rate = (flowControl.rate ?? flowControl.ratePerSecond)?.toString();
|
|
1819
|
+
const period = typeof flowControl.period === "number" ? `${flowControl.period}s` : flowControl.period;
|
|
1820
|
+
const controlValue = [
|
|
1821
|
+
parallelism ? `parallelism=${parallelism}` : void 0,
|
|
1822
|
+
rate ? `rate=${rate}` : void 0,
|
|
1823
|
+
period ? `period=${period}` : void 0
|
|
1824
|
+
].filter(Boolean);
|
|
1825
|
+
if (controlValue.length === 0) {
|
|
1826
|
+
throw new QstashError4("Provide at least one of parallelism or ratePerSecond for flowControl");
|
|
1827
|
+
}
|
|
1828
|
+
return {
|
|
1829
|
+
flowControlKey: flowControl.key,
|
|
1830
|
+
flowControlValue: controlValue.join(", ")
|
|
1831
|
+
};
|
|
1832
|
+
};
|
|
1833
|
+
var getHeaders = (params) => {
|
|
1834
|
+
const workflowHeaders = new WorkflowHeaders(params);
|
|
1835
|
+
return workflowHeaders.getHeaders();
|
|
1836
|
+
};
|
|
1837
|
+
|
|
1838
|
+
// src/qstash/submit-steps.ts
|
|
1839
|
+
var submitParallelSteps = async ({
|
|
1840
|
+
context,
|
|
1841
|
+
steps,
|
|
1842
|
+
initialStepCount,
|
|
1843
|
+
invokeCount,
|
|
1844
|
+
telemetry,
|
|
1845
|
+
debug
|
|
1846
|
+
}) => {
|
|
1847
|
+
const planSteps = steps.map(
|
|
1848
|
+
(step, index) => step.getPlanStep(steps.length, initialStepCount + index)
|
|
1849
|
+
);
|
|
1850
|
+
await debug?.log("SUBMIT", "SUBMIT_STEP", {
|
|
1851
|
+
length: planSteps.length,
|
|
1852
|
+
steps: planSteps
|
|
1853
|
+
});
|
|
1854
|
+
const result = await context.qstashClient.batch(
|
|
1855
|
+
planSteps.map((planStep) => {
|
|
1856
|
+
const { headers } = getHeaders({
|
|
1857
|
+
initHeaderValue: "false",
|
|
1858
|
+
workflowConfig: {
|
|
1859
|
+
workflowRunId: context.workflowRunId,
|
|
1860
|
+
workflowUrl: context.url,
|
|
1861
|
+
failureUrl: context.failureUrl,
|
|
1862
|
+
retries: context.retries,
|
|
1863
|
+
flowControl: context.flowControl,
|
|
1864
|
+
telemetry
|
|
1865
|
+
},
|
|
1866
|
+
userHeaders: context.headers,
|
|
1867
|
+
invokeCount
|
|
1868
|
+
});
|
|
1869
|
+
return {
|
|
1870
|
+
headers,
|
|
1871
|
+
method: "POST",
|
|
1872
|
+
url: context.url,
|
|
1873
|
+
body: JSON.stringify(planStep),
|
|
1874
|
+
notBefore: planStep.sleepUntil,
|
|
1875
|
+
delay: planStep.sleepFor
|
|
1876
|
+
};
|
|
1877
|
+
})
|
|
1878
|
+
);
|
|
1879
|
+
await debug?.log("INFO", "SUBMIT_STEP", {
|
|
1880
|
+
messageIds: result.map((message) => {
|
|
1881
|
+
return {
|
|
1882
|
+
message: message.messageId
|
|
1883
|
+
};
|
|
1884
|
+
})
|
|
1885
|
+
});
|
|
1886
|
+
throw new WorkflowAbort(planSteps[0].stepName, planSteps[0]);
|
|
1887
|
+
};
|
|
1888
|
+
var submitSingleStep = async ({
|
|
1889
|
+
context,
|
|
1890
|
+
lazyStep,
|
|
1891
|
+
stepId,
|
|
1892
|
+
invokeCount,
|
|
1893
|
+
concurrency,
|
|
1894
|
+
telemetry,
|
|
1895
|
+
debug
|
|
1896
|
+
}) => {
|
|
1897
|
+
const resultStep = await lazyStep.getResultStep(concurrency, stepId);
|
|
1898
|
+
await debug?.log("INFO", "RUN_SINGLE", {
|
|
1899
|
+
fromRequest: false,
|
|
1900
|
+
step: resultStep,
|
|
1901
|
+
stepCount: stepId
|
|
1902
|
+
});
|
|
1903
|
+
const { headers } = lazyStep.getHeaders({
|
|
1904
|
+
context,
|
|
1905
|
+
step: resultStep,
|
|
1906
|
+
invokeCount,
|
|
1907
|
+
telemetry
|
|
1908
|
+
});
|
|
1909
|
+
const body = lazyStep.getBody({
|
|
1910
|
+
context,
|
|
1911
|
+
step: resultStep,
|
|
1912
|
+
headers,
|
|
1913
|
+
invokeCount,
|
|
1914
|
+
telemetry
|
|
1915
|
+
});
|
|
1916
|
+
await debug?.log("SUBMIT", "SUBMIT_STEP", {
|
|
1917
|
+
length: 1,
|
|
1918
|
+
steps: [resultStep]
|
|
1919
|
+
});
|
|
1920
|
+
const submitResult = await lazyStep.submitStep({
|
|
1921
|
+
context,
|
|
1922
|
+
body,
|
|
1923
|
+
headers,
|
|
1924
|
+
isParallel: concurrency !== NO_CONCURRENCY,
|
|
1925
|
+
invokeCount,
|
|
1926
|
+
step: resultStep,
|
|
1927
|
+
telemetry
|
|
1928
|
+
});
|
|
1929
|
+
await debug?.log("INFO", "SUBMIT_STEP", {
|
|
1930
|
+
messageIds: submitResult.map((message) => {
|
|
1931
|
+
return {
|
|
1932
|
+
message: message.messageId
|
|
1933
|
+
};
|
|
1934
|
+
})
|
|
1935
|
+
});
|
|
1936
|
+
return resultStep;
|
|
1634
1937
|
};
|
|
1635
1938
|
|
|
1636
1939
|
// src/context/auto-executor.ts
|
|
1637
|
-
import { QstashError as QstashError4 } from "@upstash/qstash";
|
|
1638
1940
|
var AutoExecutor = class _AutoExecutor {
|
|
1639
1941
|
context;
|
|
1640
1942
|
promises = /* @__PURE__ */ new WeakMap();
|
|
@@ -1738,14 +2040,16 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1738
2040
|
});
|
|
1739
2041
|
return lazyStep.parseOut(step.out);
|
|
1740
2042
|
}
|
|
1741
|
-
const resultStep = await
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
2043
|
+
const resultStep = await submitSingleStep({
|
|
2044
|
+
context: this.context,
|
|
2045
|
+
lazyStep,
|
|
2046
|
+
stepId: this.stepCount,
|
|
2047
|
+
invokeCount: this.invokeCount,
|
|
2048
|
+
concurrency: 1,
|
|
2049
|
+
telemetry: this.telemetry,
|
|
2050
|
+
debug: this.debug
|
|
1746
2051
|
});
|
|
1747
|
-
|
|
1748
|
-
return resultStep.out;
|
|
2052
|
+
throw new WorkflowAbort(lazyStep.stepName, resultStep);
|
|
1749
2053
|
}
|
|
1750
2054
|
/**
|
|
1751
2055
|
* Runs steps in parallel.
|
|
@@ -1773,10 +2077,14 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1773
2077
|
});
|
|
1774
2078
|
switch (parallelCallState) {
|
|
1775
2079
|
case "first": {
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
2080
|
+
await submitParallelSteps({
|
|
2081
|
+
context: this.context,
|
|
2082
|
+
steps: parallelSteps,
|
|
2083
|
+
initialStepCount,
|
|
2084
|
+
invokeCount: this.invokeCount,
|
|
2085
|
+
telemetry: this.telemetry,
|
|
2086
|
+
debug: this.debug
|
|
2087
|
+
});
|
|
1780
2088
|
break;
|
|
1781
2089
|
}
|
|
1782
2090
|
case "partial": {
|
|
@@ -1790,13 +2098,18 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1790
2098
|
validateStep(parallelSteps[stepIndex], planStep);
|
|
1791
2099
|
try {
|
|
1792
2100
|
const parallelStep = parallelSteps[stepIndex];
|
|
1793
|
-
const resultStep = await
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
2101
|
+
const resultStep = await submitSingleStep({
|
|
2102
|
+
context: this.context,
|
|
2103
|
+
lazyStep: parallelStep,
|
|
2104
|
+
stepId: planStep.targetStep,
|
|
2105
|
+
invokeCount: this.invokeCount,
|
|
2106
|
+
concurrency: parallelSteps.length,
|
|
2107
|
+
telemetry: this.telemetry,
|
|
2108
|
+
debug: this.debug
|
|
2109
|
+
});
|
|
2110
|
+
throw new WorkflowAbort(parallelStep.stepName, resultStep);
|
|
1798
2111
|
} catch (error) {
|
|
1799
|
-
if (error instanceof WorkflowAbort || error instanceof
|
|
2112
|
+
if (error instanceof WorkflowAbort || error instanceof QstashError5 && error.status === 400) {
|
|
1800
2113
|
throw error;
|
|
1801
2114
|
}
|
|
1802
2115
|
throw new WorkflowError(
|
|
@@ -1852,128 +2165,6 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1852
2165
|
return "discard";
|
|
1853
2166
|
}
|
|
1854
2167
|
}
|
|
1855
|
-
/**
|
|
1856
|
-
* sends the steps to QStash as batch
|
|
1857
|
-
*
|
|
1858
|
-
* @param steps steps to send
|
|
1859
|
-
*/
|
|
1860
|
-
async submitStepsToQStash(steps, lazySteps) {
|
|
1861
|
-
if (steps.length === 0) {
|
|
1862
|
-
throw new WorkflowError(
|
|
1863
|
-
`Unable to submit steps to QStash. Provided list is empty. Current step: ${this.stepCount}`
|
|
1864
|
-
);
|
|
1865
|
-
}
|
|
1866
|
-
await this.debug?.log("SUBMIT", "SUBMIT_STEP", {
|
|
1867
|
-
length: steps.length,
|
|
1868
|
-
steps
|
|
1869
|
-
});
|
|
1870
|
-
if (steps[0].waitEventId && steps.length === 1) {
|
|
1871
|
-
const waitStep = steps[0];
|
|
1872
|
-
const { headers, timeoutHeaders } = getHeaders({
|
|
1873
|
-
initHeaderValue: "false",
|
|
1874
|
-
workflowRunId: this.context.workflowRunId,
|
|
1875
|
-
workflowUrl: this.context.url,
|
|
1876
|
-
userHeaders: this.context.headers,
|
|
1877
|
-
step: waitStep,
|
|
1878
|
-
failureUrl: this.context.failureUrl,
|
|
1879
|
-
retries: this.context.retries,
|
|
1880
|
-
telemetry: this.telemetry,
|
|
1881
|
-
invokeCount: this.invokeCount,
|
|
1882
|
-
flowControl: this.context.flowControl
|
|
1883
|
-
});
|
|
1884
|
-
const waitBody = {
|
|
1885
|
-
url: this.context.url,
|
|
1886
|
-
timeout: waitStep.timeout,
|
|
1887
|
-
timeoutBody: void 0,
|
|
1888
|
-
timeoutUrl: this.context.url,
|
|
1889
|
-
timeoutHeaders,
|
|
1890
|
-
step: {
|
|
1891
|
-
stepId: waitStep.stepId,
|
|
1892
|
-
stepType: "Wait",
|
|
1893
|
-
stepName: waitStep.stepName,
|
|
1894
|
-
concurrent: waitStep.concurrent,
|
|
1895
|
-
targetStep: waitStep.targetStep
|
|
1896
|
-
}
|
|
1897
|
-
};
|
|
1898
|
-
await this.context.qstashClient.http.request({
|
|
1899
|
-
path: ["v2", "wait", waitStep.waitEventId],
|
|
1900
|
-
body: JSON.stringify(waitBody),
|
|
1901
|
-
headers,
|
|
1902
|
-
method: "POST",
|
|
1903
|
-
parseResponseAsJson: false
|
|
1904
|
-
});
|
|
1905
|
-
throw new WorkflowAbort(waitStep.stepName, waitStep);
|
|
1906
|
-
}
|
|
1907
|
-
if (steps.length === 1 && lazySteps[0] instanceof LazyInvokeStep) {
|
|
1908
|
-
const invokeStep = steps[0];
|
|
1909
|
-
const lazyInvokeStep = lazySteps[0];
|
|
1910
|
-
await invokeWorkflow({
|
|
1911
|
-
settings: lazyInvokeStep.params,
|
|
1912
|
-
invokeStep,
|
|
1913
|
-
context: this.context,
|
|
1914
|
-
invokeCount: this.invokeCount,
|
|
1915
|
-
telemetry: this.telemetry
|
|
1916
|
-
});
|
|
1917
|
-
throw new WorkflowAbort(invokeStep.stepName, invokeStep);
|
|
1918
|
-
}
|
|
1919
|
-
const result = await this.context.qstashClient.batch(
|
|
1920
|
-
steps.map((singleStep, index) => {
|
|
1921
|
-
const lazyStep = lazySteps[index];
|
|
1922
|
-
const { headers } = getHeaders({
|
|
1923
|
-
initHeaderValue: "false",
|
|
1924
|
-
workflowRunId: this.context.workflowRunId,
|
|
1925
|
-
workflowUrl: this.context.url,
|
|
1926
|
-
userHeaders: this.context.headers,
|
|
1927
|
-
step: singleStep,
|
|
1928
|
-
failureUrl: this.context.failureUrl,
|
|
1929
|
-
retries: this.context.retries,
|
|
1930
|
-
callRetries: lazyStep instanceof LazyCallStep ? lazyStep.retries : void 0,
|
|
1931
|
-
callTimeout: lazyStep instanceof LazyCallStep ? lazyStep.timeout : void 0,
|
|
1932
|
-
telemetry: this.telemetry,
|
|
1933
|
-
invokeCount: this.invokeCount,
|
|
1934
|
-
flowControl: this.context.flowControl,
|
|
1935
|
-
callFlowControl: lazyStep instanceof LazyCallStep ? lazyStep.flowControl : void 0
|
|
1936
|
-
});
|
|
1937
|
-
const willWait = singleStep.concurrent === NO_CONCURRENCY || singleStep.stepId === 0;
|
|
1938
|
-
singleStep.out = JSON.stringify(singleStep.out);
|
|
1939
|
-
return singleStep.callUrl && lazyStep instanceof LazyCallStep ? (
|
|
1940
|
-
// if the step is a third party call, we call the third party
|
|
1941
|
-
// url (singleStep.callUrl) and pass information about the workflow
|
|
1942
|
-
// in the headers (handled in getHeaders). QStash makes the request
|
|
1943
|
-
// to callUrl and returns the result to Workflow endpoint.
|
|
1944
|
-
// handleThirdPartyCallResult method sends the result of the third
|
|
1945
|
-
// party call to QStash.
|
|
1946
|
-
{
|
|
1947
|
-
headers,
|
|
1948
|
-
method: singleStep.callMethod,
|
|
1949
|
-
body: JSON.stringify(singleStep.callBody),
|
|
1950
|
-
url: singleStep.callUrl
|
|
1951
|
-
}
|
|
1952
|
-
) : (
|
|
1953
|
-
// if the step is not a third party call, we use workflow
|
|
1954
|
-
// endpoint (context.url) as URL when calling QStash. QStash
|
|
1955
|
-
// calls us back with the updated steps list.
|
|
1956
|
-
{
|
|
1957
|
-
headers,
|
|
1958
|
-
method: "POST",
|
|
1959
|
-
body: JSON.stringify(singleStep),
|
|
1960
|
-
url: this.context.url,
|
|
1961
|
-
notBefore: willWait ? singleStep.sleepUntil : void 0,
|
|
1962
|
-
delay: willWait ? singleStep.sleepFor : void 0
|
|
1963
|
-
}
|
|
1964
|
-
);
|
|
1965
|
-
})
|
|
1966
|
-
);
|
|
1967
|
-
const _result = result;
|
|
1968
|
-
await this.debug?.log("INFO", "SUBMIT_STEP", {
|
|
1969
|
-
messageIds: _result.map((message) => {
|
|
1970
|
-
return {
|
|
1971
|
-
message: message.messageId
|
|
1972
|
-
};
|
|
1973
|
-
})
|
|
1974
|
-
});
|
|
1975
|
-
throw new WorkflowAbort(steps[0].stepName, steps[0]);
|
|
1976
|
-
}
|
|
1977
2168
|
/**
|
|
1978
2169
|
* Get the promise by executing the lazt steps list. If there is a single
|
|
1979
2170
|
* step, we call `runSingle`. Otherwise `runParallel` is called.
|
|
@@ -2169,6 +2360,9 @@ var WorkflowApi = class extends BaseWorkflowApi {
|
|
|
2169
2360
|
}
|
|
2170
2361
|
};
|
|
2171
2362
|
|
|
2363
|
+
// src/agents/index.ts
|
|
2364
|
+
import { createOpenAI } from "@ai-sdk/openai";
|
|
2365
|
+
|
|
2172
2366
|
// src/agents/agent.ts
|
|
2173
2367
|
import { z } from "zod";
|
|
2174
2368
|
import { generateText, tool as tool2, ToolExecutionError } from "ai";
|
|
@@ -2373,10 +2567,16 @@ var WorkflowAgents = class {
|
|
|
2373
2567
|
*/
|
|
2374
2568
|
openai(...params) {
|
|
2375
2569
|
const [model, settings] = params;
|
|
2376
|
-
const { baseURL, apiKey, ...otherSettings } = settings ?? {};
|
|
2377
|
-
const
|
|
2378
|
-
|
|
2570
|
+
const { baseURL, apiKey, callSettings, ...otherSettings } = settings ?? {};
|
|
2571
|
+
const openaiModel = this.AISDKModel({
|
|
2572
|
+
context: this.context,
|
|
2573
|
+
provider: createOpenAI,
|
|
2574
|
+
providerParams: { baseURL, apiKey, compatibility: "strict" },
|
|
2575
|
+
agentCallParams: callSettings
|
|
2576
|
+
});
|
|
2577
|
+
return openaiModel(model, otherSettings);
|
|
2379
2578
|
}
|
|
2579
|
+
AISDKModel = createWorkflowModel;
|
|
2380
2580
|
};
|
|
2381
2581
|
|
|
2382
2582
|
// src/context/context.ts
|
|
@@ -2600,60 +2800,42 @@ var WorkflowContext = class {
|
|
|
2600
2800
|
}
|
|
2601
2801
|
await this.addStep(new LazySleepUntilStep(stepName, time));
|
|
2602
2802
|
}
|
|
2603
|
-
/**
|
|
2604
|
-
* Makes a third party call through QStash in order to make a
|
|
2605
|
-
* network call without consuming any runtime.
|
|
2606
|
-
*
|
|
2607
|
-
* ```ts
|
|
2608
|
-
* const { status, body } = await context.call<string>(
|
|
2609
|
-
* "post call step",
|
|
2610
|
-
* {
|
|
2611
|
-
* url: "https://www.some-endpoint.com/api",
|
|
2612
|
-
* method: "POST",
|
|
2613
|
-
* body: "my-payload"
|
|
2614
|
-
* }
|
|
2615
|
-
* );
|
|
2616
|
-
* ```
|
|
2617
|
-
*
|
|
2618
|
-
* tries to parse the result of the request as JSON. If it's
|
|
2619
|
-
* not a JSON which can be parsed, simply returns the response
|
|
2620
|
-
* body as it is.
|
|
2621
|
-
*
|
|
2622
|
-
* @param stepName
|
|
2623
|
-
* @param url url to call
|
|
2624
|
-
* @param method call method. "GET" by default.
|
|
2625
|
-
* @param body call body
|
|
2626
|
-
* @param headers call headers
|
|
2627
|
-
* @param retries number of call retries. 0 by default
|
|
2628
|
-
* @param timeout max duration to wait for the endpoint to respond. in seconds.
|
|
2629
|
-
* @returns call result as {
|
|
2630
|
-
* status: number;
|
|
2631
|
-
* body: unknown;
|
|
2632
|
-
* header: Record<string, string[]>
|
|
2633
|
-
* }
|
|
2634
|
-
*/
|
|
2635
2803
|
async call(stepName, settings) {
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2804
|
+
let callStep;
|
|
2805
|
+
if ("workflow" in settings) {
|
|
2806
|
+
const url = getNewUrlFromWorkflowId(this.url, settings.workflow.workflowId);
|
|
2807
|
+
callStep = new LazyCallStep(
|
|
2808
|
+
stepName,
|
|
2809
|
+
url,
|
|
2810
|
+
"POST",
|
|
2811
|
+
settings.body,
|
|
2812
|
+
settings.headers || {},
|
|
2813
|
+
settings.retries || 0,
|
|
2814
|
+
settings.timeout,
|
|
2815
|
+
settings.flowControl ?? settings.workflow.options.flowControl
|
|
2816
|
+
);
|
|
2817
|
+
} else {
|
|
2818
|
+
const {
|
|
2819
|
+
url,
|
|
2820
|
+
method = "GET",
|
|
2821
|
+
body,
|
|
2822
|
+
headers = {},
|
|
2823
|
+
retries = 0,
|
|
2824
|
+
timeout,
|
|
2825
|
+
flowControl
|
|
2826
|
+
} = settings;
|
|
2827
|
+
callStep = new LazyCallStep(
|
|
2647
2828
|
stepName,
|
|
2648
2829
|
url,
|
|
2649
2830
|
method,
|
|
2650
|
-
|
|
2831
|
+
body,
|
|
2651
2832
|
headers,
|
|
2652
2833
|
retries,
|
|
2653
2834
|
timeout,
|
|
2654
2835
|
flowControl
|
|
2655
|
-
)
|
|
2656
|
-
|
|
2836
|
+
);
|
|
2837
|
+
}
|
|
2838
|
+
return await this.addStep(callStep);
|
|
2657
2839
|
}
|
|
2658
2840
|
/**
|
|
2659
2841
|
* Pauses workflow execution until a specific event occurs or a timeout is reached.
|
|
@@ -3099,6 +3281,7 @@ var processOptions = (options) => {
|
|
|
3099
3281
|
retries: DEFAULT_RETRIES,
|
|
3100
3282
|
useJSONContent: false,
|
|
3101
3283
|
disableTelemetry: false,
|
|
3284
|
+
onError: console.error,
|
|
3102
3285
|
...options
|
|
3103
3286
|
};
|
|
3104
3287
|
};
|
|
@@ -3148,7 +3331,8 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
3148
3331
|
retries,
|
|
3149
3332
|
useJSONContent,
|
|
3150
3333
|
disableTelemetry,
|
|
3151
|
-
flowControl
|
|
3334
|
+
flowControl,
|
|
3335
|
+
onError
|
|
3152
3336
|
} = processOptions(options);
|
|
3153
3337
|
telemetry = disableTelemetry ? void 0 : telemetry;
|
|
3154
3338
|
const debug = WorkflowLogger.getLogger(verbose);
|
|
@@ -3277,8 +3461,19 @@ var serveBase = (routeFunction, telemetry, options) => {
|
|
|
3277
3461
|
try {
|
|
3278
3462
|
return await handler(request);
|
|
3279
3463
|
} catch (error) {
|
|
3280
|
-
|
|
3281
|
-
|
|
3464
|
+
const formattedError = formatWorkflowError(error);
|
|
3465
|
+
try {
|
|
3466
|
+
onError?.(error);
|
|
3467
|
+
} catch (onErrorError) {
|
|
3468
|
+
const formattedOnErrorError = formatWorkflowError(onErrorError);
|
|
3469
|
+
const errorMessage = `Error while running onError callback: '${formattedOnErrorError.message}'.
|
|
3470
|
+
Original error: '${formattedError.message}'`;
|
|
3471
|
+
console.error(errorMessage);
|
|
3472
|
+
return new Response(errorMessage, {
|
|
3473
|
+
status: 500
|
|
3474
|
+
});
|
|
3475
|
+
}
|
|
3476
|
+
return new Response(JSON.stringify(formattedError), {
|
|
3282
3477
|
status: 500
|
|
3283
3478
|
});
|
|
3284
3479
|
}
|
|
@@ -3308,8 +3503,8 @@ export {
|
|
|
3308
3503
|
getWorkflowRunId,
|
|
3309
3504
|
StepTypes,
|
|
3310
3505
|
triggerFirstInvocation,
|
|
3311
|
-
serveManyBase,
|
|
3312
3506
|
WorkflowTool,
|
|
3507
|
+
serveManyBase,
|
|
3313
3508
|
WorkflowContext,
|
|
3314
3509
|
WorkflowLogger,
|
|
3315
3510
|
serveBase,
|