@mastra/inngest 0.10.4 → 0.10.5-alpha.1
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/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +24 -0
- package/dist/_tsup-dts-rollup.d.cts +41 -18
- package/dist/_tsup-dts-rollup.d.ts +41 -18
- package/dist/index.cjs +143 -19
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +144 -21
- package/package.json +12 -12
- package/src/index.test.ts +180 -1
- package/src/index.ts +270 -53
package/dist/index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { randomUUID } from 'crypto';
|
|
2
2
|
import { subscribe } from '@inngest/realtime';
|
|
3
|
+
import { Agent, Tool } from '@mastra/core';
|
|
3
4
|
import { RuntimeContext } from '@mastra/core/di';
|
|
4
|
-
import { Run, Workflow,
|
|
5
|
+
import { Run, Workflow, DefaultExecutionEngine } from '@mastra/core/workflows';
|
|
5
6
|
import { EMITTER_SYMBOL } from '@mastra/core/workflows/_constants';
|
|
6
7
|
import { serve as serve$1 } from 'inngest/hono';
|
|
8
|
+
import { z } from 'zod';
|
|
7
9
|
|
|
8
10
|
// src/index.ts
|
|
9
11
|
function serve({ mastra, inngest }) {
|
|
@@ -161,11 +163,32 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
161
163
|
const storage = this.#mastra?.getStorage();
|
|
162
164
|
if (!storage) {
|
|
163
165
|
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
164
|
-
return null;
|
|
166
|
+
return this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null;
|
|
165
167
|
}
|
|
166
168
|
const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
|
|
167
169
|
return run ?? (this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null);
|
|
168
170
|
}
|
|
171
|
+
async getWorkflowRunExecutionResult(runId) {
|
|
172
|
+
const storage = this.#mastra?.getStorage();
|
|
173
|
+
if (!storage) {
|
|
174
|
+
this.logger.debug("Cannot get workflow run execution result. Mastra storage is not initialized");
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
|
|
178
|
+
if (!run?.snapshot) {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
if (typeof run.snapshot === "string") {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
status: run.snapshot.status,
|
|
186
|
+
result: run.snapshot.result,
|
|
187
|
+
error: run.snapshot.error,
|
|
188
|
+
payload: run.snapshot.context?.input,
|
|
189
|
+
steps: run.snapshot.context
|
|
190
|
+
};
|
|
191
|
+
}
|
|
169
192
|
__registerMastra(mastra) {
|
|
170
193
|
this.#mastra = mastra;
|
|
171
194
|
this.executionEngine.__registerMastra(mastra);
|
|
@@ -268,31 +291,128 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
268
291
|
return [this.getFunction(), ...this.getNestedFunctions(this.executionGraph.steps)];
|
|
269
292
|
}
|
|
270
293
|
};
|
|
271
|
-
function
|
|
272
|
-
|
|
273
|
-
{
|
|
274
|
-
id:
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
294
|
+
function createStep(params) {
|
|
295
|
+
if (params instanceof Agent) {
|
|
296
|
+
return {
|
|
297
|
+
id: params.name,
|
|
298
|
+
// @ts-ignore
|
|
299
|
+
inputSchema: z.object({
|
|
300
|
+
prompt: z.string()
|
|
301
|
+
// resourceId: z.string().optional(),
|
|
302
|
+
// threadId: z.string().optional(),
|
|
303
|
+
}),
|
|
304
|
+
// @ts-ignore
|
|
305
|
+
outputSchema: z.object({
|
|
306
|
+
text: z.string()
|
|
307
|
+
}),
|
|
308
|
+
execute: async ({ inputData, [EMITTER_SYMBOL]: emitter, runtimeContext }) => {
|
|
309
|
+
let streamPromise = {};
|
|
310
|
+
streamPromise.promise = new Promise((resolve, reject) => {
|
|
311
|
+
streamPromise.resolve = resolve;
|
|
312
|
+
streamPromise.reject = reject;
|
|
313
|
+
});
|
|
314
|
+
const toolData = {
|
|
315
|
+
name: params.name,
|
|
316
|
+
args: inputData
|
|
317
|
+
};
|
|
318
|
+
await emitter.emit("watch-v2", {
|
|
319
|
+
type: "tool-call-streaming-start",
|
|
320
|
+
...toolData
|
|
321
|
+
});
|
|
322
|
+
const { fullStream } = await params.stream(inputData.prompt, {
|
|
323
|
+
// resourceId: inputData.resourceId,
|
|
324
|
+
// threadId: inputData.threadId,
|
|
325
|
+
runtimeContext,
|
|
326
|
+
onFinish: (result) => {
|
|
327
|
+
streamPromise.resolve(result.text);
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
for await (const chunk of fullStream) {
|
|
331
|
+
switch (chunk.type) {
|
|
332
|
+
case "text-delta":
|
|
333
|
+
await emitter.emit("watch-v2", {
|
|
334
|
+
type: "tool-call-delta",
|
|
335
|
+
...toolData,
|
|
336
|
+
argsTextDelta: chunk.textDelta
|
|
337
|
+
});
|
|
338
|
+
break;
|
|
339
|
+
case "step-start":
|
|
340
|
+
case "step-finish":
|
|
341
|
+
case "finish":
|
|
342
|
+
break;
|
|
343
|
+
case "tool-call":
|
|
344
|
+
case "tool-result":
|
|
345
|
+
case "tool-call-streaming-start":
|
|
346
|
+
case "tool-call-delta":
|
|
347
|
+
case "source":
|
|
348
|
+
case "file":
|
|
349
|
+
default:
|
|
350
|
+
await emitter.emit("watch-v2", chunk);
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
return {
|
|
355
|
+
text: await streamPromise.promise
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
if (params instanceof Tool) {
|
|
361
|
+
if (!params.inputSchema || !params.outputSchema) {
|
|
362
|
+
throw new Error("Tool must have input and output schemas defined");
|
|
363
|
+
}
|
|
364
|
+
return {
|
|
365
|
+
// TODO: tool probably should have strong id type
|
|
366
|
+
// @ts-ignore
|
|
367
|
+
id: params.id,
|
|
368
|
+
inputSchema: params.inputSchema,
|
|
369
|
+
outputSchema: params.outputSchema,
|
|
370
|
+
execute: async ({ inputData, mastra, runtimeContext }) => {
|
|
371
|
+
return params.execute({
|
|
372
|
+
context: inputData,
|
|
373
|
+
mastra,
|
|
374
|
+
runtimeContext
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
return {
|
|
380
|
+
id: params.id,
|
|
381
|
+
description: params.description,
|
|
382
|
+
inputSchema: params.inputSchema,
|
|
383
|
+
outputSchema: params.outputSchema,
|
|
384
|
+
resumeSchema: params.resumeSchema,
|
|
385
|
+
suspendSchema: params.suspendSchema,
|
|
386
|
+
execute: params.execute
|
|
387
|
+
};
|
|
285
388
|
}
|
|
286
389
|
function init(inngest) {
|
|
287
390
|
return {
|
|
288
391
|
createWorkflow(params) {
|
|
289
392
|
return new InngestWorkflow(params, inngest);
|
|
290
393
|
},
|
|
291
|
-
createStep
|
|
292
|
-
|
|
394
|
+
createStep,
|
|
395
|
+
cloneStep(step, opts) {
|
|
396
|
+
return {
|
|
397
|
+
id: opts.id,
|
|
398
|
+
description: step.description,
|
|
399
|
+
inputSchema: step.inputSchema,
|
|
400
|
+
outputSchema: step.outputSchema,
|
|
401
|
+
execute: step.execute
|
|
402
|
+
};
|
|
293
403
|
},
|
|
294
|
-
|
|
295
|
-
|
|
404
|
+
cloneWorkflow(workflow, opts) {
|
|
405
|
+
const wf = new Workflow({
|
|
406
|
+
id: opts.id,
|
|
407
|
+
inputSchema: workflow.inputSchema,
|
|
408
|
+
outputSchema: workflow.outputSchema,
|
|
409
|
+
steps: workflow.stepDefs,
|
|
410
|
+
mastra: workflow.mastra
|
|
411
|
+
});
|
|
412
|
+
wf.setStepFlow(workflow.stepGraph);
|
|
413
|
+
wf.commit();
|
|
414
|
+
return wf;
|
|
415
|
+
}
|
|
296
416
|
};
|
|
297
417
|
}
|
|
298
418
|
var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
@@ -383,6 +503,9 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
383
503
|
runtimeContext
|
|
384
504
|
});
|
|
385
505
|
}
|
|
506
|
+
async executeSleep({ id, duration }) {
|
|
507
|
+
await this.inngestStep.sleep(id, duration);
|
|
508
|
+
}
|
|
386
509
|
async executeStep({
|
|
387
510
|
step,
|
|
388
511
|
stepResults,
|
|
@@ -753,4 +876,4 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
753
876
|
}
|
|
754
877
|
};
|
|
755
878
|
|
|
756
|
-
export { InngestExecutionEngine, InngestRun, InngestWorkflow, init, serve };
|
|
879
|
+
export { InngestExecutionEngine, InngestRun, InngestWorkflow, createStep, init, serve };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/inngest",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.5-alpha.1",
|
|
4
4
|
"description": "Mastra Inngest integration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -20,27 +20,27 @@
|
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@inngest/realtime": "^0.3.1",
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
23
|
+
"@opentelemetry/api": "^1.9.0",
|
|
24
|
+
"inngest": "^3.39.1",
|
|
25
|
+
"zod": "^3.25.57"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@ai-sdk/openai": "^1.3.22",
|
|
29
|
-
"@hono/node-server": "^1.14.
|
|
29
|
+
"@hono/node-server": "^1.14.4",
|
|
30
30
|
"@microsoft/api-extractor": "^7.52.8",
|
|
31
|
-
"@types/node": "^20.
|
|
32
|
-
"ai": "^4.3.
|
|
31
|
+
"@types/node": "^20.19.0",
|
|
32
|
+
"ai": "^4.3.16",
|
|
33
33
|
"eslint": "^9.28.0",
|
|
34
34
|
"execa": "^9.6.0",
|
|
35
35
|
"get-port": "7.1.0",
|
|
36
|
-
"hono": "^4.7.
|
|
36
|
+
"hono": "^4.7.11",
|
|
37
37
|
"tsup": "^8.5.0",
|
|
38
|
-
"typescript": "^5.8.
|
|
38
|
+
"typescript": "^5.8.3",
|
|
39
39
|
"vitest": "^2.1.9",
|
|
40
40
|
"@internal/lint": "0.0.12",
|
|
41
|
-
"@mastra/
|
|
42
|
-
"@mastra/
|
|
43
|
-
"@mastra/libsql": "0.10.
|
|
41
|
+
"@mastra/core": "0.10.6-alpha.1",
|
|
42
|
+
"@mastra/deployer": "0.10.6-alpha.1",
|
|
43
|
+
"@mastra/libsql": "0.10.3-alpha.0"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"@mastra/core": "^0.10.2-alpha.0"
|
package/src/index.test.ts
CHANGED
|
@@ -259,6 +259,186 @@ describe('MastraInngestWorkflow', () => {
|
|
|
259
259
|
|
|
260
260
|
srv.close();
|
|
261
261
|
});
|
|
262
|
+
|
|
263
|
+
it('should execute a a sleep step', async ctx => {
|
|
264
|
+
const inngest = new Inngest({
|
|
265
|
+
id: 'mastra',
|
|
266
|
+
baseUrl: `http://localhost:${(ctx as any).inngestPort}`,
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
const { createWorkflow, createStep } = init(inngest);
|
|
270
|
+
|
|
271
|
+
const execute = vi.fn<any>().mockResolvedValue({ result: 'success' });
|
|
272
|
+
const step1 = createStep({
|
|
273
|
+
id: 'step1',
|
|
274
|
+
execute,
|
|
275
|
+
inputSchema: z.object({}),
|
|
276
|
+
outputSchema: z.object({ result: z.string() }),
|
|
277
|
+
});
|
|
278
|
+
const step2 = createStep({
|
|
279
|
+
id: 'step2',
|
|
280
|
+
execute: async ({ inputData }) => {
|
|
281
|
+
return { result: 'slept successfully: ' + inputData.result };
|
|
282
|
+
},
|
|
283
|
+
inputSchema: z.object({ result: z.string() }),
|
|
284
|
+
outputSchema: z.object({ result: z.string() }),
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
const workflow = createWorkflow({
|
|
288
|
+
id: 'test-workflow',
|
|
289
|
+
inputSchema: z.object({}),
|
|
290
|
+
outputSchema: z.object({
|
|
291
|
+
result: z.string(),
|
|
292
|
+
}),
|
|
293
|
+
steps: [step1],
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
workflow.then(step1).sleep(1000).then(step2).commit();
|
|
297
|
+
|
|
298
|
+
const mastra = new Mastra({
|
|
299
|
+
storage: new DefaultStorage({
|
|
300
|
+
url: ':memory:',
|
|
301
|
+
}),
|
|
302
|
+
workflows: {
|
|
303
|
+
'test-workflow': workflow,
|
|
304
|
+
},
|
|
305
|
+
server: {
|
|
306
|
+
apiRoutes: [
|
|
307
|
+
{
|
|
308
|
+
path: '/inngest/api',
|
|
309
|
+
method: 'ALL',
|
|
310
|
+
createHandler: async ({ mastra }) => inngestServe({ mastra, inngest }),
|
|
311
|
+
},
|
|
312
|
+
],
|
|
313
|
+
},
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
const app = await createHonoServer(mastra);
|
|
317
|
+
|
|
318
|
+
const srv = serve({
|
|
319
|
+
fetch: app.fetch,
|
|
320
|
+
port: (ctx as any).handlerPort,
|
|
321
|
+
});
|
|
322
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
323
|
+
|
|
324
|
+
const run = workflow.createRun();
|
|
325
|
+
const startTime = Date.now();
|
|
326
|
+
const result = await run.start({ inputData: {} });
|
|
327
|
+
const endTime = Date.now();
|
|
328
|
+
|
|
329
|
+
expect(execute).toHaveBeenCalled();
|
|
330
|
+
expect(result.steps['step1']).toEqual({
|
|
331
|
+
status: 'success',
|
|
332
|
+
output: { result: 'success' },
|
|
333
|
+
// payload: {},
|
|
334
|
+
// startedAt: expect.any(Number),
|
|
335
|
+
// endedAt: expect.any(Number),
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
expect(result.steps['step2']).toEqual({
|
|
339
|
+
status: 'success',
|
|
340
|
+
output: { result: 'slept successfully: success' },
|
|
341
|
+
// payload: { result: 'success' },
|
|
342
|
+
// startedAt: expect.any(Number),
|
|
343
|
+
// endedAt: expect.any(Number),
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
expect(endTime - startTime).toBeGreaterThan(1000);
|
|
347
|
+
|
|
348
|
+
srv.close();
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
it('should execute a a sleep until step', async ctx => {
|
|
352
|
+
const inngest = new Inngest({
|
|
353
|
+
id: 'mastra',
|
|
354
|
+
baseUrl: `http://localhost:${(ctx as any).inngestPort}`,
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
const { createWorkflow, createStep } = init(inngest);
|
|
358
|
+
|
|
359
|
+
const execute = vi.fn<any>().mockResolvedValue({ result: 'success' });
|
|
360
|
+
const step1 = createStep({
|
|
361
|
+
id: 'step1',
|
|
362
|
+
execute,
|
|
363
|
+
inputSchema: z.object({}),
|
|
364
|
+
outputSchema: z.object({ result: z.string() }),
|
|
365
|
+
});
|
|
366
|
+
const step2 = createStep({
|
|
367
|
+
id: 'step2',
|
|
368
|
+
execute: async ({ inputData }) => {
|
|
369
|
+
return { result: 'slept successfully: ' + inputData.result };
|
|
370
|
+
},
|
|
371
|
+
inputSchema: z.object({ result: z.string() }),
|
|
372
|
+
outputSchema: z.object({ result: z.string() }),
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
const workflow = createWorkflow({
|
|
376
|
+
id: 'test-workflow',
|
|
377
|
+
inputSchema: z.object({}),
|
|
378
|
+
outputSchema: z.object({
|
|
379
|
+
result: z.string(),
|
|
380
|
+
}),
|
|
381
|
+
steps: [step1],
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
workflow
|
|
385
|
+
.then(step1)
|
|
386
|
+
.sleepUntil(new Date(Date.now() + 1000))
|
|
387
|
+
.then(step2)
|
|
388
|
+
.commit();
|
|
389
|
+
|
|
390
|
+
const mastra = new Mastra({
|
|
391
|
+
storage: new DefaultStorage({
|
|
392
|
+
url: ':memory:',
|
|
393
|
+
}),
|
|
394
|
+
workflows: {
|
|
395
|
+
'test-workflow': workflow,
|
|
396
|
+
},
|
|
397
|
+
server: {
|
|
398
|
+
apiRoutes: [
|
|
399
|
+
{
|
|
400
|
+
path: '/inngest/api',
|
|
401
|
+
method: 'ALL',
|
|
402
|
+
createHandler: async ({ mastra }) => inngestServe({ mastra, inngest }),
|
|
403
|
+
},
|
|
404
|
+
],
|
|
405
|
+
},
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
const app = await createHonoServer(mastra);
|
|
409
|
+
|
|
410
|
+
const srv = serve({
|
|
411
|
+
fetch: app.fetch,
|
|
412
|
+
port: (ctx as any).handlerPort,
|
|
413
|
+
});
|
|
414
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
415
|
+
|
|
416
|
+
const run = workflow.createRun();
|
|
417
|
+
const startTime = Date.now();
|
|
418
|
+
const result = await run.start({ inputData: {} });
|
|
419
|
+
const endTime = Date.now();
|
|
420
|
+
|
|
421
|
+
expect(execute).toHaveBeenCalled();
|
|
422
|
+
expect(result.steps['step1']).toEqual({
|
|
423
|
+
status: 'success',
|
|
424
|
+
output: { result: 'success' },
|
|
425
|
+
// payload: {},
|
|
426
|
+
// startedAt: expect.any(Number),
|
|
427
|
+
// endedAt: expect.any(Number),
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
expect(result.steps['step2']).toEqual({
|
|
431
|
+
status: 'success',
|
|
432
|
+
output: { result: 'slept successfully: success' },
|
|
433
|
+
// payload: { result: 'success' },
|
|
434
|
+
// startedAt: expect.any(Number),
|
|
435
|
+
// endedAt: expect.any(Number),
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
expect(endTime - startTime).toBeGreaterThan(1000);
|
|
439
|
+
|
|
440
|
+
srv.close();
|
|
441
|
+
});
|
|
262
442
|
});
|
|
263
443
|
|
|
264
444
|
describe('Variable Resolution', () => {
|
|
@@ -4781,7 +4961,6 @@ describe('MastraInngestWorkflow', () => {
|
|
|
4781
4961
|
|
|
4782
4962
|
const app = await createHonoServer(mastra);
|
|
4783
4963
|
app.use('*', async (ctx, next) => {
|
|
4784
|
-
'middleware', ctx.req.method, ctx.req.url;
|
|
4785
4964
|
await next();
|
|
4786
4965
|
});
|
|
4787
4966
|
|