@mastra/inngest 0.10.5 → 0.10.6-alpha.0

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/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { randomUUID } from 'crypto';
2
2
  import { subscribe } from '@inngest/realtime';
3
- import { Agent, Tool } from '@mastra/core';
4
3
  import { RuntimeContext } from '@mastra/core/di';
4
+ import { Tool } from '@mastra/core/tools';
5
5
  import { Run, Workflow, DefaultExecutionEngine } from '@mastra/core/workflows';
6
6
  import { EMITTER_SYMBOL } from '@mastra/core/workflows/_constants';
7
7
  import { serve as serve$1 } from 'inngest/hono';
@@ -43,7 +43,7 @@ var InngestRun = class extends Run {
43
43
  }
44
44
  async getRunOutput(eventId) {
45
45
  let runs = await this.getRuns(eventId);
46
- while (runs?.[0]?.status !== "Completed") {
46
+ while (runs?.[0]?.status !== "Completed" || runs?.[0]?.event_id !== eventId) {
47
47
  await new Promise((resolve) => setTimeout(resolve, 1e3));
48
48
  runs = await this.getRuns(eventId);
49
49
  if (runs?.[0]?.status === "Failed" || runs?.[0]?.status === "Cancelled") {
@@ -52,6 +52,12 @@ var InngestRun = class extends Run {
52
52
  }
53
53
  return runs?.[0];
54
54
  }
55
+ async sendEvent(event, data) {
56
+ await this.inngest.send({
57
+ name: `user-event-${event}`,
58
+ data
59
+ });
60
+ }
55
61
  async start({
56
62
  inputData
57
63
  }) {
@@ -89,6 +95,17 @@ var InngestRun = class extends Run {
89
95
  return result;
90
96
  }
91
97
  async resume(params) {
98
+ const p = this._resume(params).then((result) => {
99
+ if (result.status !== "suspended") {
100
+ this.closeStreamAction?.().catch(() => {
101
+ });
102
+ }
103
+ return result;
104
+ });
105
+ this.executionResults = p;
106
+ return p;
107
+ }
108
+ async _resume(params) {
92
109
  const steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
93
110
  (step) => typeof step === "string" ? step : step?.id
94
111
  );
@@ -122,25 +139,60 @@ var InngestRun = class extends Run {
122
139
  }
123
140
  return result;
124
141
  }
125
- watch(cb) {
142
+ watch(cb, type = "watch") {
143
+ let active = true;
126
144
  const streamPromise = subscribe(
127
145
  {
128
146
  channel: `workflow:${this.workflowId}:${this.runId}`,
129
- topics: ["watch"],
147
+ topics: [type],
130
148
  app: this.inngest
131
149
  },
132
150
  (message) => {
133
- cb(message.data);
151
+ if (active) {
152
+ cb(message.data);
153
+ }
134
154
  }
135
155
  );
136
156
  return () => {
137
- streamPromise.then((stream) => {
138
- stream.cancel();
157
+ active = false;
158
+ streamPromise.then(async (stream) => {
159
+ return stream.cancel();
139
160
  }).catch((err) => {
140
161
  console.error(err);
141
162
  });
142
163
  };
143
164
  }
165
+ stream({ inputData, runtimeContext } = {}) {
166
+ const { readable, writable } = new TransformStream();
167
+ const writer = writable.getWriter();
168
+ const unwatch = this.watch(async (event) => {
169
+ try {
170
+ await writer.write(event);
171
+ } catch {
172
+ }
173
+ }, "watch-v2");
174
+ this.closeStreamAction = async () => {
175
+ unwatch();
176
+ try {
177
+ await writer.close();
178
+ } catch (err) {
179
+ console.error("Error closing stream:", err);
180
+ } finally {
181
+ writer.releaseLock();
182
+ }
183
+ };
184
+ this.executionResults = this.start({ inputData, runtimeContext }).then((result) => {
185
+ if (result.status !== "suspended") {
186
+ this.closeStreamAction?.().catch(() => {
187
+ });
188
+ }
189
+ return result;
190
+ });
191
+ return {
192
+ stream: readable,
193
+ getWorkflowState: () => this.executionResults
194
+ };
195
+ }
144
196
  };
145
197
  var InngestWorkflow = class _InngestWorkflow extends Workflow {
146
198
  #mastra;
@@ -248,12 +300,18 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
248
300
  try {
249
301
  await publish({
250
302
  channel: `workflow:${this.id}:${runId}`,
251
- topic: "watch",
303
+ topic: event2,
252
304
  data
253
305
  });
254
306
  } catch (err) {
255
307
  this.logger.error("Error emitting event: " + (err?.stack ?? err?.message ?? err));
256
308
  }
309
+ },
310
+ on: (_event, _callback) => {
311
+ },
312
+ off: (_event, _callback) => {
313
+ },
314
+ once: (_event, _callback) => {
257
315
  }
258
316
  };
259
317
  const engine = new InngestExecutionEngine(this.#mastra, step, attempt);
@@ -291,8 +349,14 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
291
349
  return [this.getFunction(), ...this.getNestedFunctions(this.executionGraph.steps)];
292
350
  }
293
351
  };
352
+ function isAgent(params) {
353
+ return params?.component === "AGENT";
354
+ }
355
+ function isTool(params) {
356
+ return params instanceof Tool;
357
+ }
294
358
  function createStep(params) {
295
- if (params instanceof Agent) {
359
+ if (isAgent(params)) {
296
360
  return {
297
361
  id: params.name,
298
362
  // @ts-ignore
@@ -357,7 +421,7 @@ function createStep(params) {
357
421
  }
358
422
  };
359
423
  }
360
- if (params instanceof Tool) {
424
+ if (isTool(params)) {
361
425
  if (!params.inputSchema || !params.outputSchema) {
362
426
  throw new Error("Tool must have input and output schemas defined");
363
427
  }
@@ -423,6 +487,18 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
423
487
  this.inngestStep = inngestStep;
424
488
  this.inngestAttempts = inngestAttempts;
425
489
  }
490
+ async execute(params) {
491
+ await params.emitter.emit("watch-v2", {
492
+ type: "start",
493
+ payload: { runId: params.runId }
494
+ });
495
+ const result = await super.execute(params);
496
+ await params.emitter.emit("watch-v2", {
497
+ type: "finish",
498
+ payload: { runId: params.runId }
499
+ });
500
+ return result;
501
+ }
426
502
  async fmtReturnValue(executionSpan, emitter, stepResults, lastOutput, error) {
427
503
  const base = {
428
504
  status: lastOutput.status,
@@ -506,6 +582,16 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
506
582
  async executeSleep({ id, duration }) {
507
583
  await this.inngestStep.sleep(id, duration);
508
584
  }
585
+ async executeWaitForEvent({ event, timeout }) {
586
+ const eventData = await this.inngestStep.waitForEvent(`user-event-${event}`, {
587
+ event: `user-event-${event}`,
588
+ timeout: timeout ?? 5e3
589
+ });
590
+ if (eventData === null) {
591
+ throw "Timeout waiting for event";
592
+ }
593
+ return eventData?.data;
594
+ }
509
595
  async executeStep({
510
596
  step,
511
597
  stepResults,
@@ -515,9 +601,10 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
515
601
  emitter,
516
602
  runtimeContext
517
603
  }) {
518
- await this.inngestStep.run(
604
+ const startedAt = await this.inngestStep.run(
519
605
  `workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
520
606
  async () => {
607
+ const startedAt2 = Date.now();
521
608
  await emitter.emit("watch", {
522
609
  type: "watch",
523
610
  payload: {
@@ -539,6 +626,13 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
539
626
  },
540
627
  eventTimestamp: Date.now()
541
628
  });
629
+ await emitter.emit("watch-v2", {
630
+ type: "step-start",
631
+ payload: {
632
+ id: step.id
633
+ }
634
+ });
635
+ return startedAt2;
542
636
  }
543
637
  );
544
638
  if (step instanceof InngestWorkflow) {
@@ -599,6 +693,13 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
599
693
  },
600
694
  eventTimestamp: Date.now()
601
695
  });
696
+ await emitter.emit("watch-v2", {
697
+ type: "step-result",
698
+ payload: {
699
+ id: step.id,
700
+ status: "failed"
701
+ }
702
+ });
602
703
  return { executionContext, result: { status: "failed", error: result?.error } };
603
704
  } else if (result.status === "suspended") {
604
705
  const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
@@ -625,6 +726,12 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
625
726
  },
626
727
  eventTimestamp: Date.now()
627
728
  });
729
+ await emitter.emit("watch-v2", {
730
+ type: "step-suspended",
731
+ payload: {
732
+ id: step.id
733
+ }
734
+ });
628
735
  return {
629
736
  executionContext,
630
737
  result: {
@@ -675,6 +782,13 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
675
782
  },
676
783
  eventTimestamp: Date.now()
677
784
  });
785
+ await emitter.emit("watch-v2", {
786
+ type: "step-finish",
787
+ payload: {
788
+ id: step.id,
789
+ metadata: {}
790
+ }
791
+ });
678
792
  return { executionContext, result: { status: "success", output: result?.result } };
679
793
  }
680
794
  );
@@ -714,12 +828,37 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
714
828
  step: this.inngestStep
715
829
  }
716
830
  });
717
- execResults = { status: "success", output: result };
831
+ const endedAt = Date.now();
832
+ execResults = {
833
+ status: "success",
834
+ output: result,
835
+ startedAt,
836
+ endedAt,
837
+ payload: prevOutput,
838
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
839
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
840
+ };
718
841
  } catch (e) {
719
- execResults = { status: "failed", error: e instanceof Error ? e.message : String(e) };
842
+ execResults = {
843
+ status: "failed",
844
+ payload: prevOutput,
845
+ error: e instanceof Error ? e.message : String(e),
846
+ endedAt: Date.now(),
847
+ startedAt,
848
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
849
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
850
+ };
720
851
  }
721
852
  if (suspended) {
722
- execResults = { status: "suspended", payload: suspended.payload };
853
+ execResults = {
854
+ status: "suspended",
855
+ suspendedPayload: suspended.payload,
856
+ payload: prevOutput,
857
+ suspendedAt: Date.now(),
858
+ startedAt,
859
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
860
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
861
+ };
723
862
  }
724
863
  if (execResults.status === "failed") {
725
864
  if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
@@ -731,18 +870,43 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
731
870
  payload: {
732
871
  currentStep: {
733
872
  id: step.id,
734
- status: execResults.status,
735
- output: execResults.output
873
+ ...execResults
736
874
  },
737
875
  workflowState: {
738
876
  status: "running",
739
- steps: stepResults,
877
+ steps: { ...stepResults, [step.id]: execResults },
740
878
  result: null,
741
879
  error: null
742
880
  }
743
881
  },
744
882
  eventTimestamp: Date.now()
745
883
  });
884
+ if (execResults.status === "suspended") {
885
+ await emitter.emit("watch-v2", {
886
+ type: "step-suspended",
887
+ payload: {
888
+ id: step.id,
889
+ status: execResults.status,
890
+ output: execResults.status === "success" ? execResults?.output : void 0
891
+ }
892
+ });
893
+ } else {
894
+ await emitter.emit("watch-v2", {
895
+ type: "step-result",
896
+ payload: {
897
+ id: step.id,
898
+ status: execResults.status,
899
+ output: execResults.status === "success" ? execResults?.output : void 0
900
+ }
901
+ });
902
+ await emitter.emit("watch-v2", {
903
+ type: "step-finish",
904
+ payload: {
905
+ id: step.id,
906
+ metadata: {}
907
+ }
908
+ });
909
+ }
746
910
  return { result: execResults, executionContext, stepResults };
747
911
  });
748
912
  Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
@@ -860,7 +1024,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
860
1024
  if (hasFailed) {
861
1025
  execResults = { status: "failed", error: hasFailed.result.error };
862
1026
  } else if (hasSuspended) {
863
- execResults = { status: "suspended", payload: hasSuspended.result.payload };
1027
+ execResults = { status: "suspended", payload: hasSuspended.result.suspendPayload };
864
1028
  } else {
865
1029
  execResults = {
866
1030
  status: "success",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/inngest",
3
- "version": "0.10.5",
3
+ "version": "0.10.6-alpha.0",
4
4
  "description": "Mastra Inngest integration",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -38,9 +38,9 @@
38
38
  "typescript": "^5.8.3",
39
39
  "vitest": "^2.1.9",
40
40
  "@internal/lint": "0.0.13",
41
- "@mastra/core": "0.10.6",
42
- "@mastra/libsql": "0.10.3",
43
- "@mastra/deployer": "0.10.6"
41
+ "@mastra/core": "0.10.7-alpha.0",
42
+ "@mastra/libsql": "0.10.4-alpha.0",
43
+ "@mastra/deployer": "0.10.7-alpha.0"
44
44
  },
45
45
  "peerDependencies": {
46
46
  "@mastra/core": "^0.10.2-alpha.0"