draft: a MastraAgentwrites a one-line note for the payment, through the AgentOS gateway.review: the step callssuspend(). On AgentOS that becomes a hold in the Review queue; once a person approves, edits or rejects, the workflow resumes atreviewwith the decision.draftdoesn’t run again.
runWorkflow from @agentos/sdk/mastra, does the pause and resume: it keeps the workflow’s snapshot in run state, so the resume works in any process, after the container was stopped, with no database of your own.
The bundle
vendor/agentos-sdk-0.1.0.tgz, the TypeScript SDK (see SDKs: it isn’t on npm yet and ships with AgentOS). Set config.models.main to a model from your environment’s Models page, zip the folder with vendor/ in it and deploy it.
How the model is wired
Mastra agents take AI SDK models, so thewriter agent uses agentosModel(inv) from @agentos/sdk/ai-sdk: the model for the role main in config.models, served by the gateway, with the run token added to its requests while the invocation runs. That is why payments(inv) builds the agent, the workflow and the Mastra instance inside the handler, once per invocation.
Approve the payment
In a step, call Mastra’s ownsuspend(), not inv.ask(). A payload shaped like an ask (intent, items, optional actions, details, expiresIn) is asked as it is, and the step resumes with {resolvedBy, items: [{id, action, data, comment}], comment}. Any other payload becomes one item named after the step, and the step resumes with that item’s {action, data, comment} (action is "expired" when nobody decided in time).
1
Start the run
2
Decide
In the Review queue, or through the API. An
edit carries the item’s full data:3
Read the result
Good to know
- Give the
Mastrainstance anInMemoryStore. The adapter writes the saved snapshot into it on the resume; without a storagerunWorkflowthrows. - Steps before the suspension don’t run again. The workflow resumes at the suspended step, so the model call in
drafthappens once per run. - A finished workflow isn’t run twice. Once it succeeds, its result replaces the snapshot in run state, and a later invocation of the same run gets that result back. Pass
{ fresh: true }torunWorkflowto run it anew, and{ name: "..." }to give each workflow call in one handler its own checkpoint. - Run state is at most 1 MiB. A snapshot larger than that is refused before asking (
too_large).
@mastra/core 1.76.0, ai 7.0.138 and Node 24, with the conformance kit. More frameworks: Framework examples.
