尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

在 Temporal 上运行 Mastra 工作流:@mastra/temporal 集成指南

在 Temporal 上运行 Mastra 工作流:@mastra/temporal 集成指南 在 Temporal 上运行 Mastra 工作流mastra/temporal 集成指南【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra本指南聚焦 Mastra 开源仓库中的mastra/temporal包workflows/temporal讲解如何让标准 Mastra Workflow 以「接近原生写法」的 API 运行在 Temporal 这一持久化执行durable execution平台上。读完本文你将掌握 Temporal 开发环境的搭建、Worker 插件的接入方式、工作流定义与运行 API以及该集成在源码层面「编译转换」的实现原理。注意该包仍处于实验阶段README 明确标注 “under active development and is not ready for production use yet”生产环境请谨慎评估。为什么需要 Temporal 作为 Mastra 的工作流引擎Mastra 的核心工作流引擎mastra/core中的Workflow/Run负责步骤编排、状态管理与执行图构建但默认执行进程是内存态的——进程重启后运行状态即丢失。Temporal 提供了事件溯源event sourcing驱动的持久化执行模型工作流执行状态被持久化到 Temporal Server具备自动重试、定时器、活动Activity分发与长期运行long-running workflow等能力。mastra/temporal的目标见 README 首句是Run Mastra workflows on Temporal with a workflow authoring API that stays close to standard Mastra workflows.即保持与标准 Mastra 工作流几乎一致的编写体验同时把执行底座切换到 Temporal。开发者依然使用 Mastra 的createWorkflow/createStep链式 API 编写流程剩下的「如何让 Temporal Worker 识别并执行这些工作流」由集成层完成。安装与运行环境要求npm install mastra/temporal从 package.json 可以确认以下运行时前提项要求Node.js 22.13.0engines字段mastra/corepeer 依赖1.50.0-0 2.0.0-0zodpeer 依赖^3.25.0 \|\| ^4.0.0输入/输出 Schema 校验内部依赖temporalio/worker、temporalio/client、temporalio/workflow、temporalio/activity、temporalio/plugin均^1.22.0以及babel/*、rollup用于编译转换导出入口主入口mastra/temporal与子路径mastra/temporal/worker包名关键词为mastra、temporal、workflows、durable-execution许可证为 Apache-2.0。启动本地 Temporal 开发环境仓库为本地开发提供了开箱即用的 Docker Compose 配置docker-compose.yaml。其内容如下name: mastra-temporal-dev services: temporal: image: temporalio/auto-setup:latest container_name: mastra-temporal-server ports: - 7233:7233 - 8080:8080 environment: - TEMPORAL_ADDRESS0.0.0.0:7233 - TEMPORAL_UI_PORT8080启动方式docker compose -f workflows/temporal/docker-compose.yaml up -d启动后localhost:7233gRPC 前端地址Worker 的NativeConnection与 Client 均连接到此端口localhost:8080Temporal Web UI可观察工作流执行历史、重试与定时器状态。temporalio/auto-setup:latest镜像会在首次启动时自动完成 Schema 初始化Auto Setup因此无需手动执行迁移命令。用 MastraPlugin 接入 Temporal WorkerREADME 给出的核心用法是把MastraPlugin作为 Temporal Worker 的插件注入见 README 的 Usage 示例对应源码 worker.ts 与 plugin.tsimport { NativeConnection, Worker } from temporalio/worker; import { MastraPlugin } from mastra/temporal/worker; const connection await NativeConnection.connect({ address: localhost:7233, }); const plugin new MastraPlugin(import.meta.resolve(./mastra/index.ts)); const worker await Worker.create({ connection, namespace: default, taskQueue: mastra, plugins: [plugin], }); await worker.run();关键点逐条拆解NativeConnection.connect({ address: localhost:7233 })建立到 Temporal Server 的原生 gRPC 连接地址需与 docker-compose.yaml 暴露的端口一致。new MastraPlugin(import.meta.resolve(./mastra/index.ts))插件构造函数接收你的 Mastra 应用入口文件。import.meta.resolve()将模块说明符解析为file:URLMastraPlugin内部会将其转换为文件系统路径见 plugin.ts 中entryFile.startsWith(file:/)的处理。入口文件即导出Mastra实例的文件仓库集成测试使用了形如new Mastra({ workflows: { complexWorkflow } })的入口见 index.ts。Worker.create({ ... plugins: [plugin] })Temporal 官方Worker会在启动时调用每个WorkerPlugin的configureWorker方法。MastraPlugin.configureWorkerplugin.ts会把编译产物自动合并进 Worker 选项workflowsPath指向生成的工作流模块activities合并进 Worker 的活动注册表。taskQueue: mastra任务队列名必须与后续调用init()/createWorkflow()时传入的taskQueue保持一致否则工作流无法被该 Worker 接收。Worker.create阶段无需手动调用预构建——MastraPlugin实现了惰性预构建首次configureWorker时若发现尚未构建会触发#prebuildplugin.ts。构建产物默认缓存在项目根目录的node_modules/.mastra下包含workflow.mjs、activities.mjs与activity-bindings.json三个文件常量定义见 plugin.ts。工作流编写与标准 Mastra 保持一致的链式 API通过 init() 绑定 Temporal 参数workflow.ts 暴露了init()工厂它是定义 Temporal 工作流的推荐入口。仓库集成测试的用法如下temporal.tsimport { init } from mastra/temporal; export const { createStep, createWorkflow } init({ client: undefined as never, // 真实场景传入 temporalio/client 的 Client 实例 taskQueue: mastra, });TemporalWorkflowParams支持三个字段workflow.ts参数类型说明clientClienttemporalio/client的 Client用于workflow.start()启动与结果获取taskQueuestring任务队列名须与 Worker 配置一致startToCloseTimeoutstring可选工作流从开始到结束的整体超时默认1 minute见 workflow.tsinit()返回{ createWorkflow, createStep }其中createStep直接透传mastra/core/workflows的标准实现createWorkflow则返回TemporalWorkflow实例workflow.ts。定义工作流TemporalWorkflow继承自mastra/core的Workflow因此标准 Mastra 的链式编排方法.then()、.parallel()、.sleep()、.commit()全部可用。仓库集成测试提供了一个覆盖多种编排原语的示例complex-workflow.tsimport { z } from zod; import { createWorkflow } from ../temporal; import { innerWorkflow } from ./inner-workflow; import { step1, step2, step3, step4 } from ./steps; export const complexWorkflow createWorkflow({ id: complex-workflow, inputSchema: z.object({ input: z.string() }), outputSchema: z.object({ result: z.string() }), }) .then(step1) .then(innerWorkflow) // 支持嵌套子工作流 .parallel([step2, step3]) .sleep(1000) // 持久化定时器 .then(step4) .commit();这段代码印证了嵌套工作流.then(innerWorkflow)可以编排另一个工作流Temporal 会将其作为子工作流执行并行步骤.parallel([step2, step3])在 Temporal 中对应并行 Activity 调度持久化定时器.sleep(1000)基于 Temporal 的 Timer 实现即使 Worker 崩溃重启定时器状态也不会丢失——这是相对默认内存引擎的关键差异。需要强调的是源码转换层对id有严格要求Temporal workflow types must be static so the loader can deterministically map a source workflow to the runtime export name used by the worker见 workflows.ts 的注释与实现。也就是说id必须是静态字符串字面量或不含表达式的模板字符串动态计算的 id 会在构建时报错Workflow id must be a static string。运行与取消TemporalRun调用createWorkflow(...)后得到的TemporalWorkflow通过createRun()创建TemporalRunworkflow.ts。TemporalRunrun.ts继承自mastra/core/workflows的Run支持三种运行方式1. 同步等待结果start()const run await workflow.createRun({ runId: my-run, resourceId: res-1 }); const result await run.start({ inputData: { input: hello } });start()内部调用this.client.workflow.start()以runId作为 Temporal 的workflowId把{ inputData, initialState, requestContext, runId, resourceId, outputOptions, tracingOptions, perStep }打包为单个入参后等待handle.result()run.ts。返回值是标准的WorkflowResult成功时status: success并携带result失败时status: failed并携带error。2. 异步提交startAsync()const { runId } await run.startAsync({ inputData: { input: hello } });仅提交执行并立即返回{ runId }适合无需同步等待的场景run.ts。无论哪种方式输入、初始状态与请求上下文都会先经过_validateInput/_validateInitialState/_validateRequestContext校验这与标准 Mastra Run 的行为一致。3. 取消cancel()await run.cancel();先通过this.client.workflow.getHandle(this.runId).cancel()向 Temporal 发送取消请求再调用父类Run.cancel()run.ts。底层原理Babel Rollup 的「编译转换」管线MastraPlugin之所以能让你用接近原生的写法编写工作流是因为它在构建期完成了一次「源码到 Temporal 可执行模块」的转换。整条管线从 plugin.ts 的#bundleMastra与#prebuild可见主要由两个 Transform 组成transformsbuildTemporalWorkflowModuletransforms/workflows.ts把打包后的 Mastra 入口源码解析为 AST将createWorkflow(...)调用改写为 Temporal Workflow 的静态导出每个工作流一个导出名并把temporal-workflow-runtime.mjstransforms/temporal-workflow-runtime.mjs中的运行时辅助函数内联进产物。处理过程中会用到pruneUnusedTopLevelBindings等剪枝手段剔除工作流执行不需要的顶层绑定。buildTemporalActivitiesModuletransforms/activities.ts收集所有createStep调用为每个 step 生成一个 Temporal Activity 导出并返回activityBindings——一个把stepId映射到导出名的清单plugin.ts 会将其写为activity-bindings.json。编译期使用babel/parserbabel/types做 AST 操作、babel/generator生成代码、rollup完成打包这些依赖均列在 package.json 的dependencies中。运行时MastraPlugin.getTemporalWorkerOptions读取绑定文件为每个 stepId 生成一个动态加载 Activity 模块的代理函数plugin.ts从而把 Mastra 步骤桥接为 Temporal Activity。单元测试对转换结果的验证transforms 目录下的测试 用快照fixture固定了转换输出transforms/fixtures/workflow/weather-workflow 存放工作流转换的input.mjs/output.js对照transforms/fixtures/activities/weather-workflow 存放 Activity 转换的对照测试入口workflows.test.ts、activities.test.ts与temporal-workflow-runtime.test.ts分别校验两个 Transform 及运行时辅助函数的正确性。如果想深入调试转换逻辑这是最直接的切入点。完整可运行的最小示例综合以上内容一个「本地 Temporal Mastra 工作流」的最小闭环如下1. 启动 Temporal Serverdocker compose -f workflows/temporal/docker-compose.yaml up -d2. 定义 Mastra 应用入口mastra/index.tsimport { Mastra } from mastra/core/mastra; import { createWorkflow } from ./workflows; import { myStep } from ./steps; export const myWorkflow createWorkflow({ id: my-workflow, inputSchema: z.object({ prompt: z.string() }), outputSchema: z.object({ answer: z.string() }), }) .then(myStep) .commit(); export const mastra new Mastra({ workflows: { myWorkflow }, });其中createWorkflow来自init({ client, taskQueue: mastra })的返回。3. 启动 Workerimport { NativeConnection, Worker } from temporalio/worker; import { MastraPlugin } from mastra/temporal/worker; const connection await NativeConnection.connect({ address: localhost:7233 }); const worker await Worker.create({ connection, namespace: default, taskQueue: mastra, plugins: [new MastraPlugin(import.meta.resolve(./mastra/index.ts))], }); await worker.run();4. 从应用侧触发工作流import { Client } from temporalio/client; import { init } from mastra/temporal; const client new Client({ connection: { address: localhost:7233 } }); const { createWorkflow } init({ client, taskQueue: mastra }); const workflow createWorkflow({ id: my-workflow, inputSchema, outputSchema }) .then(myStep) .commit(); const run await workflow.createRun(); const result await run.start({ inputData: { prompt: hello } }); console.log(result); // { status: success, result: { answer: ... }, ... }运行后可在http://localhost:8080的 Temporal Web UI 中观察工作流执行历史。版本、变更记录与边界说明当前版本为0.4.5-alpha.3见 package.json版本号仍带-alpha后缀且 README 明确声明为实验性包接口可能随版本演进发生变化。完整版本历史与依赖升级记录见 workflows/temporal/CHANGELOG.md。包采用 ESMtype: module同时通过require/import双导出提供 CJS/ESM 产物见 package.json 的exports字段但在import.meta.resolve()的使用上天然面向 ESM 场景。转换器要求工作流id为静态字符串startToCloseTimeout默认1 minute长耗时工作流建议显式调大例如30 minutes。测试命令单元测试pnpm --filter mastra/temporal test:unit集成测试pnpm --filter mastra/temporal test:integration对应src/index.test.ts需要可用的 Temporal Server。总结mastra/temporal的价值在于把 Mastra 的编排体验与 Temporal 的持久化执行能力解耦编写侧复用标准createWorkflow/createStep链式 API接入侧由一个MastraPlugin在构建期完成 Babel Rollup 的源码转换将工作流编译为 Temporal Workflow 模块、将步骤编译为 Activity并在运行时通过TemporalRun统一封装启动、异步提交与取消。对于需要长期运行、强重试保障与执行历史可审计的 Mastra 工作流场景这是一个值得持续跟踪的实验性方向在使用前请务必确认其 alpha 阶段的状态与当前仓库版本的 API 形态。【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表