@upstash/workflow 0.2.3 → 0.2.5-agents

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/nextjs.js CHANGED
@@ -78,6 +78,23 @@ var getSteps = async (requester, workflowRunId, messageId, debug) => {
78
78
  }
79
79
  };
80
80
 
81
+ // src/constants.ts
82
+ var WORKFLOW_ID_HEADER = "Upstash-Workflow-RunId";
83
+ var WORKFLOW_INIT_HEADER = "Upstash-Workflow-Init";
84
+ var WORKFLOW_URL_HEADER = "Upstash-Workflow-Url";
85
+ var WORKFLOW_FAILURE_HEADER = "Upstash-Workflow-Is-Failure";
86
+ var WORKFLOW_FEATURE_HEADER = "Upstash-Feature-Set";
87
+ var WORKFLOW_PROTOCOL_VERSION = "1";
88
+ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
89
+ var DEFAULT_CONTENT_TYPE = "application/json";
90
+ var NO_CONCURRENCY = 1;
91
+ var DEFAULT_RETRIES = 3;
92
+ var VERSION = "v0.2.3";
93
+ var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
94
+ var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
95
+ var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
96
+ var TELEMETRY_HEADER_RUNTIME = "Upstash-Telemetry-Runtime";
97
+
81
98
  // src/error.ts
82
99
  var import_qstash2 = require("@upstash/qstash");
83
100
  var WorkflowError = class extends import_qstash2.QstashError {
@@ -715,18 +732,6 @@ var Err = class {
715
732
  };
716
733
  var fromThrowable = Result.fromThrowable;
717
734
 
718
- // src/constants.ts
719
- var WORKFLOW_ID_HEADER = "Upstash-Workflow-RunId";
720
- var WORKFLOW_INIT_HEADER = "Upstash-Workflow-Init";
721
- var WORKFLOW_URL_HEADER = "Upstash-Workflow-Url";
722
- var WORKFLOW_FAILURE_HEADER = "Upstash-Workflow-Is-Failure";
723
- var WORKFLOW_FEATURE_HEADER = "Upstash-Feature-Set";
724
- var WORKFLOW_PROTOCOL_VERSION = "1";
725
- var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
726
- var DEFAULT_CONTENT_TYPE = "application/json";
727
- var NO_CONCURRENCY = 1;
728
- var DEFAULT_RETRIES = 3;
729
-
730
735
  // src/types.ts
731
736
  var StepTypes = [
732
737
  "Initial",
@@ -740,16 +745,21 @@ var StepTypes = [
740
745
 
741
746
  // src/workflow-requests.ts
742
747
  var import_qstash3 = require("@upstash/qstash");
743
- var triggerFirstInvocation = async (workflowContext, retries, useJSONContent, debug) => {
744
- const { headers } = getHeaders(
745
- "true",
746
- workflowContext.workflowRunId,
747
- workflowContext.url,
748
- workflowContext.headers,
749
- void 0,
750
- workflowContext.failureUrl,
751
- retries
752
- );
748
+ var triggerFirstInvocation = async ({
749
+ workflowContext,
750
+ useJSONContent,
751
+ telemetry,
752
+ debug
753
+ }) => {
754
+ const { headers } = getHeaders({
755
+ initHeaderValue: "true",
756
+ workflowRunId: workflowContext.workflowRunId,
757
+ workflowUrl: workflowContext.url,
758
+ userHeaders: workflowContext.headers,
759
+ failureUrl: workflowContext.failureUrl,
760
+ retries: workflowContext.retries,
761
+ telemetry
762
+ });
753
763
  if (useJSONContent) {
754
764
  headers["content-type"] = "application/json";
755
765
  }
@@ -855,7 +865,16 @@ var recreateUserHeaders = (headers) => {
855
865
  }
856
866
  return filteredHeaders;
857
867
  };
858
- var handleThirdPartyCallResult = async (request, requestPayload, client, workflowUrl, failureUrl, retries, debug) => {
868
+ var handleThirdPartyCallResult = async ({
869
+ request,
870
+ requestPayload,
871
+ client,
872
+ workflowUrl,
873
+ failureUrl,
874
+ retries,
875
+ telemetry,
876
+ debug
877
+ }) => {
859
878
  try {
860
879
  if (request.headers.get("Upstash-Workflow-Callback")) {
861
880
  let callbackPayload;
@@ -914,15 +933,15 @@ ${atob(callbackMessage.body ?? "")}`
914
933
  );
915
934
  }
916
935
  const userHeaders = recreateUserHeaders(request.headers);
917
- const { headers: requestHeaders } = getHeaders(
918
- "false",
936
+ const { headers: requestHeaders } = getHeaders({
937
+ initHeaderValue: "false",
919
938
  workflowRunId,
920
939
  workflowUrl,
921
940
  userHeaders,
922
- void 0,
923
941
  failureUrl,
924
- retries
925
- );
942
+ retries,
943
+ telemetry
944
+ });
926
945
  const callResponse = {
927
946
  status: callbackMessage.status,
928
947
  body: atob(callbackMessage.body ?? ""),
@@ -960,12 +979,31 @@ ${atob(callbackMessage.body ?? "")}`
960
979
  );
961
980
  }
962
981
  };
963
- var getHeaders = (initHeaderValue, workflowRunId, workflowUrl, userHeaders, step, failureUrl, retries, callRetries, callTimeout) => {
982
+ var getTelemetryHeaders = (telemetry) => {
983
+ return {
984
+ [TELEMETRY_HEADER_SDK]: telemetry.sdk,
985
+ [TELEMETRY_HEADER_FRAMEWORK]: telemetry.framework,
986
+ [TELEMETRY_HEADER_RUNTIME]: telemetry.runtime ?? "unknown"
987
+ };
988
+ };
989
+ var getHeaders = ({
990
+ initHeaderValue,
991
+ workflowRunId,
992
+ workflowUrl,
993
+ userHeaders,
994
+ failureUrl,
995
+ retries,
996
+ step,
997
+ callRetries,
998
+ callTimeout,
999
+ telemetry
1000
+ }) => {
964
1001
  const baseHeaders = {
965
1002
  [WORKFLOW_INIT_HEADER]: initHeaderValue,
966
1003
  [WORKFLOW_ID_HEADER]: workflowRunId,
967
1004
  [WORKFLOW_URL_HEADER]: workflowUrl,
968
- [WORKFLOW_FEATURE_HEADER]: "LazyFetch,InitialBody"
1005
+ [WORKFLOW_FEATURE_HEADER]: "LazyFetch,InitialBody",
1006
+ ...telemetry ? getTelemetryHeaders(telemetry) : {}
969
1007
  };
970
1008
  if (!step?.callUrl) {
971
1009
  baseHeaders[`Upstash-Forward-${WORKFLOW_PROTOCOL_VERSION_HEADER}`] = WORKFLOW_PROTOCOL_VERSION;
@@ -1039,6 +1077,13 @@ var getHeaders = (initHeaderValue, workflowRunId, workflowUrl, userHeaders, step
1039
1077
  ...Object.fromEntries(
1040
1078
  Object.entries(baseHeaders).map(([header, value]) => [header, [value]])
1041
1079
  ),
1080
+ // to include telemetry headers:
1081
+ ...telemetry ? Object.fromEntries(
1082
+ Object.entries(getTelemetryHeaders(telemetry)).map(([header, value]) => [
1083
+ header,
1084
+ [value]
1085
+ ])
1086
+ ) : {},
1042
1087
  // note: using WORKFLOW_ID_HEADER doesn't work, because Runid -> RunId:
1043
1088
  "Upstash-Workflow-Runid": [workflowRunId],
1044
1089
  [WORKFLOW_INIT_HEADER]: ["false"],
@@ -1077,6 +1122,7 @@ If you want to disable QStash Verification, you should clear env variables QSTAS
1077
1122
  };
1078
1123
 
1079
1124
  // src/context/auto-executor.ts
1125
+ var import_qstash4 = require("@upstash/qstash");
1080
1126
  var AutoExecutor = class _AutoExecutor {
1081
1127
  context;
1082
1128
  promises = /* @__PURE__ */ new WeakMap();
@@ -1085,13 +1131,15 @@ var AutoExecutor = class _AutoExecutor {
1085
1131
  nonPlanStepCount;
1086
1132
  steps;
1087
1133
  indexInCurrentList = 0;
1134
+ telemetry;
1088
1135
  stepCount = 0;
1089
1136
  planStepCount = 0;
1090
1137
  executingStep = false;
1091
- constructor(context, steps, debug) {
1138
+ constructor(context, steps, telemetry, debug) {
1092
1139
  this.context = context;
1093
- this.debug = debug;
1094
1140
  this.steps = steps;
1141
+ this.telemetry = telemetry;
1142
+ this.debug = debug;
1095
1143
  this.nonPlanStepCount = this.steps.filter((step) => !step.targetStep).length;
1096
1144
  }
1097
1145
  /**
@@ -1234,7 +1282,7 @@ var AutoExecutor = class _AutoExecutor {
1234
1282
  );
1235
1283
  await this.submitStepsToQStash([resultStep], [parallelStep]);
1236
1284
  } catch (error) {
1237
- if (error instanceof WorkflowAbort) {
1285
+ if (error instanceof WorkflowAbort || error instanceof import_qstash4.QstashError && error.status === 400) {
1238
1286
  throw error;
1239
1287
  }
1240
1288
  throw new WorkflowError(
@@ -1305,15 +1353,16 @@ var AutoExecutor = class _AutoExecutor {
1305
1353
  });
1306
1354
  if (steps[0].waitEventId && steps.length === 1) {
1307
1355
  const waitStep = steps[0];
1308
- const { headers, timeoutHeaders } = getHeaders(
1309
- "false",
1310
- this.context.workflowRunId,
1311
- this.context.url,
1312
- this.context.headers,
1313
- waitStep,
1314
- this.context.failureUrl,
1315
- this.context.retries
1316
- );
1356
+ const { headers, timeoutHeaders } = getHeaders({
1357
+ initHeaderValue: "false",
1358
+ workflowRunId: this.context.workflowRunId,
1359
+ workflowUrl: this.context.url,
1360
+ userHeaders: this.context.headers,
1361
+ step: waitStep,
1362
+ failureUrl: this.context.failureUrl,
1363
+ retries: this.context.retries,
1364
+ telemetry: this.telemetry
1365
+ });
1317
1366
  const waitBody = {
1318
1367
  url: this.context.url,
1319
1368
  timeout: waitStep.timeout,
@@ -1340,17 +1389,18 @@ var AutoExecutor = class _AutoExecutor {
1340
1389
  const result = await this.context.qstashClient.batchJSON(
1341
1390
  steps.map((singleStep, index) => {
1342
1391
  const lazyStep = lazySteps[index];
1343
- const { headers } = getHeaders(
1344
- "false",
1345
- this.context.workflowRunId,
1346
- this.context.url,
1347
- this.context.headers,
1348
- singleStep,
1349
- this.context.failureUrl,
1350
- this.context.retries,
1351
- lazyStep instanceof LazyCallStep ? lazyStep.retries : void 0,
1352
- lazyStep instanceof LazyCallStep ? lazyStep.timeout : void 0
1353
- );
1392
+ const { headers } = getHeaders({
1393
+ initHeaderValue: "false",
1394
+ workflowRunId: this.context.workflowRunId,
1395
+ workflowUrl: this.context.url,
1396
+ userHeaders: this.context.headers,
1397
+ step: singleStep,
1398
+ failureUrl: this.context.failureUrl,
1399
+ retries: this.context.retries,
1400
+ callRetries: lazyStep instanceof LazyCallStep ? lazyStep.retries : void 0,
1401
+ callTimeout: lazyStep instanceof LazyCallStep ? lazyStep.timeout : void 0,
1402
+ telemetry: this.telemetry
1403
+ });
1354
1404
  const willWait = singleStep.concurrent === NO_CONCURRENCY || singleStep.stepId === 0;
1355
1405
  singleStep.out = JSON.stringify(singleStep.out);
1356
1406
  return singleStep.callUrl ? (
@@ -1463,7 +1513,7 @@ var sortSteps = (steps) => {
1463
1513
  };
1464
1514
 
1465
1515
  // src/context/api/anthropic.ts
1466
- var import_qstash4 = require("@upstash/qstash");
1516
+ var import_qstash5 = require("@upstash/qstash");
1467
1517
 
1468
1518
  // src/context/provider.ts
1469
1519
  var getProviderInfo = (api) => {
@@ -1527,7 +1577,7 @@ var AnthropicAPI = class extends BaseWorkflowApi {
1527
1577
  return await this.callApi(stepName, {
1528
1578
  api: {
1529
1579
  name: "llm",
1530
- provider: (0, import_qstash4.anthropic)({ token })
1580
+ provider: (0, import_qstash5.anthropic)({ token })
1531
1581
  },
1532
1582
  ...parameters
1533
1583
  });
@@ -1535,14 +1585,14 @@ var AnthropicAPI = class extends BaseWorkflowApi {
1535
1585
  };
1536
1586
 
1537
1587
  // src/context/api/openai.ts
1538
- var import_qstash5 = require("@upstash/qstash");
1588
+ var import_qstash6 = require("@upstash/qstash");
1539
1589
  var OpenAIAPI = class extends BaseWorkflowApi {
1540
1590
  async call(stepName, settings) {
1541
1591
  const { token, organization, operation, ...parameters } = settings;
1542
1592
  return await this.callApi(stepName, {
1543
1593
  api: {
1544
1594
  name: "llm",
1545
- provider: (0, import_qstash5.openai)({ token, organization })
1595
+ provider: (0, import_qstash6.openai)({ token, organization })
1546
1596
  },
1547
1597
  ...parameters
1548
1598
  });
@@ -1550,14 +1600,14 @@ var OpenAIAPI = class extends BaseWorkflowApi {
1550
1600
  };
1551
1601
 
1552
1602
  // src/context/api/resend.ts
1553
- var import_qstash6 = require("@upstash/qstash");
1603
+ var import_qstash7 = require("@upstash/qstash");
1554
1604
  var ResendAPI = class extends BaseWorkflowApi {
1555
1605
  async call(stepName, settings) {
1556
1606
  const { token, batch = false, ...parameters } = settings;
1557
1607
  return await this.callApi(stepName, {
1558
1608
  api: {
1559
1609
  name: "email",
1560
- provider: (0, import_qstash6.resend)({ token, batch })
1610
+ provider: (0, import_qstash7.resend)({ token, batch })
1561
1611
  },
1562
1612
  ...parameters
1563
1613
  });
@@ -1583,6 +1633,216 @@ var WorkflowApi = class extends BaseWorkflowApi {
1583
1633
  }
1584
1634
  };
1585
1635
 
1636
+ // src/agents/adapters.ts
1637
+ var import_openai2 = require("@ai-sdk/openai");
1638
+ var import_ai = require("ai");
1639
+ var AGENT_NAME_HEADER = "upstash-agent-name";
1640
+ var createWorkflowOpenAI = (context) => {
1641
+ return (0, import_openai2.createOpenAI)({
1642
+ compatibility: "strict",
1643
+ fetch: async (input, init) => {
1644
+ try {
1645
+ const headers = init?.headers ? Object.fromEntries(new Headers(init.headers).entries()) : {};
1646
+ const body = init?.body ? JSON.parse(init.body) : void 0;
1647
+ const agentName = headers[AGENT_NAME_HEADER];
1648
+ const stepName = agentName ? `Call Agent ${agentName}` : "Call Agent";
1649
+ const responseInfo = await context.call(stepName, {
1650
+ url: input.toString(),
1651
+ method: init?.method,
1652
+ headers,
1653
+ body
1654
+ });
1655
+ const responseHeaders = new Headers(
1656
+ Object.entries(responseInfo.header).reduce(
1657
+ (acc, [key, values]) => {
1658
+ acc[key] = values.join(", ");
1659
+ return acc;
1660
+ },
1661
+ {}
1662
+ )
1663
+ );
1664
+ return new Response(JSON.stringify(responseInfo.body), {
1665
+ status: responseInfo.status,
1666
+ headers: responseHeaders
1667
+ });
1668
+ } catch (error) {
1669
+ if (error instanceof Error && error.name === "WorkflowAbort") {
1670
+ throw error;
1671
+ } else {
1672
+ console.error("Error in fetch implementation:", error);
1673
+ throw error;
1674
+ }
1675
+ }
1676
+ }
1677
+ });
1678
+ };
1679
+ var wrapTools = ({
1680
+ context,
1681
+ tools
1682
+ }) => {
1683
+ return Object.fromEntries(
1684
+ Object.entries(tools).map((toolInfo) => {
1685
+ const [toolName, tool3] = toolInfo;
1686
+ const aiSDKTool = convertToAISDKTool(tool3);
1687
+ const execute = aiSDKTool.execute;
1688
+ if (execute) {
1689
+ const wrappedExecute = (...params) => {
1690
+ return context.run(`Run tool ${toolName}`, () => execute(...params));
1691
+ };
1692
+ aiSDKTool.execute = wrappedExecute;
1693
+ }
1694
+ return [toolName, aiSDKTool];
1695
+ })
1696
+ );
1697
+ };
1698
+ var convertToAISDKTool = (tool3) => {
1699
+ const isLangchainTool = "invoke" in tool3;
1700
+ return isLangchainTool ? convertLangchainTool(tool3) : tool3;
1701
+ };
1702
+ var convertLangchainTool = (langchainTool) => {
1703
+ return (0, import_ai.tool)({
1704
+ description: langchainTool.description,
1705
+ parameters: langchainTool.schema,
1706
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1707
+ execute: async (param) => langchainTool.invoke(param)
1708
+ });
1709
+ };
1710
+
1711
+ // src/agents/agent.ts
1712
+ var import_zod = require("zod");
1713
+ var import_ai2 = require("ai");
1714
+ var Agent = class {
1715
+ name;
1716
+ tools;
1717
+ maxSteps;
1718
+ background;
1719
+ model;
1720
+ constructor({ tools, maxSteps, background, name, model }) {
1721
+ this.name = name;
1722
+ this.tools = tools ?? {};
1723
+ this.maxSteps = maxSteps;
1724
+ this.background = background;
1725
+ this.model = model;
1726
+ }
1727
+ async call({ prompt }) {
1728
+ try {
1729
+ return await (0, import_ai2.generateText)({
1730
+ model: this.model,
1731
+ tools: this.tools,
1732
+ maxSteps: this.maxSteps,
1733
+ system: this.background,
1734
+ prompt,
1735
+ headers: {
1736
+ [AGENT_NAME_HEADER]: this.name
1737
+ }
1738
+ });
1739
+ } catch (error) {
1740
+ if (error instanceof import_ai2.ToolExecutionError) {
1741
+ if (error.cause instanceof Error && error.cause.name === "WorkflowAbort") {
1742
+ throw error.cause;
1743
+ } else if (error.cause instanceof import_ai2.ToolExecutionError && error.cause.cause instanceof Error && error.cause.cause.name === "WorkflowAbort") {
1744
+ throw error.cause.cause;
1745
+ } else {
1746
+ throw error;
1747
+ }
1748
+ } else {
1749
+ throw error;
1750
+ }
1751
+ }
1752
+ }
1753
+ asTool() {
1754
+ const toolDescriptions = Object.values(this.tools).map((tool3) => tool3.description).join("\n");
1755
+ return (0, import_ai2.tool)({
1756
+ parameters: import_zod.z.object({ prompt: import_zod.z.string() }),
1757
+ execute: async ({ prompt }) => {
1758
+ return await this.call({ prompt });
1759
+ },
1760
+ description: `An AI Agent with the following background: ${this.background}Has access to the following tools: ${toolDescriptions}`
1761
+ });
1762
+ }
1763
+ };
1764
+ var MANAGER_AGENT_PROMPT = `You are an AI agent who orchestrates other AI Agents.
1765
+ These other agents have tools available to them.
1766
+ Given a prompt, utilize these agents to address requests.
1767
+ 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.
1768
+ `;
1769
+ var ManagerAgent = class extends Agent {
1770
+ agents;
1771
+ constructor({
1772
+ maxSteps,
1773
+ background = MANAGER_AGENT_PROMPT,
1774
+ agents,
1775
+ model,
1776
+ name = "manager llm"
1777
+ }) {
1778
+ super({
1779
+ background,
1780
+ maxSteps,
1781
+ tools: Object.fromEntries(agents.map((agent) => [agent.name, agent.asTool()])),
1782
+ name,
1783
+ model
1784
+ });
1785
+ this.agents = agents;
1786
+ }
1787
+ };
1788
+
1789
+ // src/agents/task.ts
1790
+ var Task = class {
1791
+ context;
1792
+ taskParameters;
1793
+ constructor({
1794
+ context,
1795
+ taskParameters
1796
+ }) {
1797
+ this.context = context;
1798
+ this.taskParameters = taskParameters;
1799
+ }
1800
+ async run() {
1801
+ const { prompt, ...otherParams } = this.taskParameters;
1802
+ const safePrompt = await this.context.run("Get Prompt", () => prompt);
1803
+ if ("agent" in otherParams) {
1804
+ const agent = otherParams.agent;
1805
+ const result = await agent.call({
1806
+ prompt: safePrompt
1807
+ });
1808
+ return { text: result.text };
1809
+ } else {
1810
+ const { agents, maxSteps, model, background } = otherParams;
1811
+ const managerAgent = new ManagerAgent({
1812
+ model,
1813
+ maxSteps,
1814
+ agents,
1815
+ name: "Manager LLM",
1816
+ background
1817
+ });
1818
+ const result = await managerAgent.call({ prompt: safePrompt });
1819
+ return { text: result.text };
1820
+ }
1821
+ }
1822
+ };
1823
+
1824
+ // src/agents/index.ts
1825
+ var WorkflowAgents = class {
1826
+ context;
1827
+ constructor({ context }) {
1828
+ this.context = context;
1829
+ }
1830
+ agent(params) {
1831
+ const wrappedTools = wrapTools({ context: this.context, tools: params.tools });
1832
+ return new Agent({
1833
+ ...params,
1834
+ tools: wrappedTools
1835
+ });
1836
+ }
1837
+ task(taskParameters) {
1838
+ return new Task({ context: this.context, taskParameters });
1839
+ }
1840
+ openai(...params) {
1841
+ const openai2 = createWorkflowOpenAI(this.context);
1842
+ return openai2(...params);
1843
+ }
1844
+ };
1845
+
1586
1846
  // src/context/context.ts
1587
1847
  var WorkflowContext = class {
1588
1848
  executor;
@@ -1715,7 +1975,8 @@ var WorkflowContext = class {
1715
1975
  debug,
1716
1976
  initialPayload,
1717
1977
  env,
1718
- retries
1978
+ retries,
1979
+ telemetry
1719
1980
  }) {
1720
1981
  this.qstashClient = qstashClient;
1721
1982
  this.workflowRunId = workflowRunId;
@@ -1726,7 +1987,7 @@ var WorkflowContext = class {
1726
1987
  this.requestPayload = initialPayload;
1727
1988
  this.env = env ?? {};
1728
1989
  this.retries = retries ?? DEFAULT_RETRIES;
1729
- this.executor = new AutoExecutor(this, this.steps, debug);
1990
+ this.executor = new AutoExecutor(this, this.steps, telemetry, debug);
1730
1991
  }
1731
1992
  /**
1732
1993
  * Executes a workflow step
@@ -1967,6 +2228,11 @@ var WorkflowContext = class {
1967
2228
  context: this
1968
2229
  });
1969
2230
  }
2231
+ get agents() {
2232
+ return new WorkflowAgents({
2233
+ context: this
2234
+ });
2235
+ }
1970
2236
  };
1971
2237
 
1972
2238
  // src/logger.ts
@@ -2044,7 +2310,7 @@ function decodeBase64(base64) {
2044
2310
  }
2045
2311
 
2046
2312
  // src/serve/authorization.ts
2047
- var import_qstash7 = require("@upstash/qstash");
2313
+ var import_qstash8 = require("@upstash/qstash");
2048
2314
  var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowContext {
2049
2315
  static disabledMessage = "disabled-qstash-worklfow-run";
2050
2316
  /**
@@ -2075,7 +2341,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
2075
2341
  */
2076
2342
  static async tryAuthentication(routeFunction, context) {
2077
2343
  const disabledContext = new _DisabledWorkflowContext({
2078
- qstashClient: new import_qstash7.Client({
2344
+ qstashClient: new import_qstash8.Client({
2079
2345
  baseUrl: "disabled-client",
2080
2346
  token: "disabled-client"
2081
2347
  }),
@@ -2171,6 +2437,7 @@ var checkIfLastOneIsDuplicate = async (steps, debug) => {
2171
2437
  if (step.stepId === lastStepId && step.targetStep === lastTargetStepId) {
2172
2438
  const message = `Upstash Workflow: The step '${step.stepName}' with id '${step.stepId}' has run twice during workflow execution. Rest of the workflow will continue running as usual.`;
2173
2439
  await debug?.log("WARN", "RESPONSE_DEFAULT", message);
2440
+ console.log(steps);
2174
2441
  console.warn(message);
2175
2442
  return true;
2176
2443
  }
@@ -2239,7 +2506,7 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
2239
2506
  };
2240
2507
  }
2241
2508
  };
2242
- var handleFailure = async (request, requestPayload, qstashClient, initialPayloadParser, routeFunction, failureFunction, debug) => {
2509
+ var handleFailure = async (request, requestPayload, qstashClient, initialPayloadParser, routeFunction, failureFunction, env, retries, debug) => {
2243
2510
  if (request.headers.get(WORKFLOW_FAILURE_HEADER) !== "true") {
2244
2511
  return ok("not-failure-callback");
2245
2512
  }
@@ -2264,7 +2531,11 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
2264
2531
  steps: [],
2265
2532
  url,
2266
2533
  failureUrl: url,
2267
- debug
2534
+ debug,
2535
+ env,
2536
+ retries,
2537
+ telemetry: void 0
2538
+ // not going to make requests in authentication check
2268
2539
  });
2269
2540
  const authCheck = await DisabledWorkflowContext.tryAuthentication(
2270
2541
  routeFunction,
@@ -2289,15 +2560,15 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
2289
2560
  };
2290
2561
 
2291
2562
  // src/serve/options.ts
2292
- var import_qstash8 = require("@upstash/qstash");
2293
2563
  var import_qstash9 = require("@upstash/qstash");
2564
+ var import_qstash10 = require("@upstash/qstash");
2294
2565
  var processOptions = (options) => {
2295
2566
  const environment = options?.env ?? (typeof process === "undefined" ? {} : process.env);
2296
2567
  const receiverEnvironmentVariablesSet = Boolean(
2297
2568
  environment.QSTASH_CURRENT_SIGNING_KEY && environment.QSTASH_NEXT_SIGNING_KEY
2298
2569
  );
2299
2570
  return {
2300
- qstashClient: new import_qstash9.Client({
2571
+ qstashClient: new import_qstash10.Client({
2301
2572
  baseUrl: environment.QSTASH_URL,
2302
2573
  token: environment.QSTASH_TOKEN
2303
2574
  }),
@@ -2331,7 +2602,7 @@ var processOptions = (options) => {
2331
2602
  throw error;
2332
2603
  }
2333
2604
  },
2334
- receiver: receiverEnvironmentVariablesSet ? new import_qstash8.Receiver({
2605
+ receiver: receiverEnvironmentVariablesSet ? new import_qstash9.Receiver({
2335
2606
  currentSigningKey: environment.QSTASH_CURRENT_SIGNING_KEY,
2336
2607
  nextSigningKey: environment.QSTASH_NEXT_SIGNING_KEY
2337
2608
  }) : void 0,
@@ -2339,6 +2610,7 @@ var processOptions = (options) => {
2339
2610
  env: environment,
2340
2611
  retries: DEFAULT_RETRIES,
2341
2612
  useJSONContent: false,
2613
+ disableTelemetry: false,
2342
2614
  ...options
2343
2615
  };
2344
2616
  };
@@ -2373,7 +2645,7 @@ var determineUrls = async (request, url, baseUrl, failureFunction, failureUrl, d
2373
2645
  var AUTH_FAIL_MESSAGE = `Failed to authenticate Workflow request. If this is unexpected, see the caveat https://upstash.com/docs/workflow/basics/caveats#avoid-non-deterministic-code-outside-context-run`;
2374
2646
 
2375
2647
  // src/serve/index.ts
2376
- var serveBase = (routeFunction, options) => {
2648
+ var serveBase = (routeFunction, telemetry, options) => {
2377
2649
  const {
2378
2650
  qstashClient,
2379
2651
  onStepFinish,
@@ -2386,8 +2658,10 @@ var serveBase = (routeFunction, options) => {
2386
2658
  baseUrl,
2387
2659
  env,
2388
2660
  retries,
2389
- useJSONContent
2661
+ useJSONContent,
2662
+ disableTelemetry
2390
2663
  } = processOptions(options);
2664
+ telemetry = disableTelemetry ? void 0 : telemetry;
2391
2665
  const debug = WorkflowLogger.getLogger(verbose);
2392
2666
  const handler = async (request) => {
2393
2667
  await debug?.log("INFO", "ENDPOINT_START");
@@ -2423,7 +2697,10 @@ var serveBase = (routeFunction, options) => {
2423
2697
  qstashClient,
2424
2698
  initialPayloadParser,
2425
2699
  routeFunction,
2426
- failureFunction
2700
+ failureFunction,
2701
+ env,
2702
+ retries,
2703
+ debug
2427
2704
  );
2428
2705
  if (failureCheck.isErr()) {
2429
2706
  throw failureCheck.error;
@@ -2441,7 +2718,8 @@ var serveBase = (routeFunction, options) => {
2441
2718
  failureUrl: workflowFailureUrl,
2442
2719
  debug,
2443
2720
  env,
2444
- retries
2721
+ retries,
2722
+ telemetry
2445
2723
  });
2446
2724
  const authCheck = await DisabledWorkflowContext.tryAuthentication(
2447
2725
  routeFunction,
@@ -2457,22 +2735,23 @@ var serveBase = (routeFunction, options) => {
2457
2735
  "auth-fail"
2458
2736
  );
2459
2737
  }
2460
- const callReturnCheck = await handleThirdPartyCallResult(
2738
+ const callReturnCheck = await handleThirdPartyCallResult({
2461
2739
  request,
2462
- rawInitialPayload,
2463
- qstashClient,
2740
+ requestPayload: rawInitialPayload,
2741
+ client: qstashClient,
2464
2742
  workflowUrl,
2465
- workflowFailureUrl,
2743
+ failureUrl: workflowFailureUrl,
2466
2744
  retries,
2745
+ telemetry,
2467
2746
  debug
2468
- );
2747
+ });
2469
2748
  if (callReturnCheck.isErr()) {
2470
2749
  await debug?.log("ERROR", "SUBMIT_THIRD_PARTY_RESULT", {
2471
2750
  error: callReturnCheck.error.message
2472
2751
  });
2473
2752
  throw callReturnCheck.error;
2474
2753
  } else if (callReturnCheck.value === "continue-workflow") {
2475
- const result = isFirstInvocation ? await triggerFirstInvocation(workflowContext, retries, useJSONContent, debug) : await triggerRouteFunction({
2754
+ const result = isFirstInvocation ? await triggerFirstInvocation({ workflowContext, useJSONContent, telemetry, debug }) : await triggerRouteFunction({
2476
2755
  onStep: async () => routeFunction(workflowContext),
2477
2756
  onCleanup: async () => {
2478
2757
  await triggerWorkflowDelete(workflowContext, debug);
@@ -2511,6 +2790,11 @@ var serveBase = (routeFunction, options) => {
2511
2790
  var serve = (routeFunction, options) => {
2512
2791
  const { handler: serveHandler } = serveBase(
2513
2792
  routeFunction,
2793
+ {
2794
+ sdk: SDK_TELEMETRY,
2795
+ framework: "nextjs",
2796
+ runtime: `node@${process.version}`
2797
+ },
2514
2798
  options
2515
2799
  );
2516
2800
  return {
@@ -2520,7 +2804,15 @@ var serve = (routeFunction, options) => {
2520
2804
  };
2521
2805
  };
2522
2806
  var servePagesRouter = (routeFunction, options) => {
2523
- const { handler: serveHandler } = serveBase(routeFunction, options);
2807
+ const { handler: serveHandler } = serveBase(
2808
+ routeFunction,
2809
+ {
2810
+ sdk: SDK_TELEMETRY,
2811
+ framework: "nextjs-pages",
2812
+ runtime: process.versions.bun ? `bun@${process.versions.bun}/node@${process.version}` : `node@${process.version}`
2813
+ },
2814
+ options
2815
+ );
2524
2816
  const handler = async (request_, res) => {
2525
2817
  if (request_.method?.toUpperCase() !== "POST") {
2526
2818
  res.status(405).json("Only POST requests are allowed in worklfows");