Human-in-the-loop für Mastra
Menschliche Entscheidungen für Mastra-Agenten und -Workflows.
Dein Mastra-Agent stoppt, bevor ein riskantes Tool läuft. Dein Nutzer gibt es auf dem Handy frei.
Was Mastra mitbringt
suspend() und run.resume()
Ein Workflow-Schritt kann pausieren; dein Code ruft später run.resume() auf. Ein Agenten-Tool kann requireApproval setzen, wodurch der Lauf vor der Tool-Ausführung pausiert. Für Wartezeiten über die Prozesslaufzeit hinaus brauchst du persistenten Mastra-Speicher und die gespeicherte Lauf-ID. Prüfe resumeData, bevor damit etwas ausgeführt werden darf.
const approval = createStep({
id: "approval",
inputSchema: z.object({}),
outputSchema: z.object({ approved: z.boolean() }),
resumeSchema: z.object({ approved: z.boolean() }),
execute: async ({ suspend, resumeData }) => {
if (!resumeData) return await suspend({})
return { approved: resumeData.approved }
},
})Wo es nicht weitergeht
- Ein pausierter Schritt bleibt still. Der Speicher weiß, dass der Lauf wartet; ein Mensch erfährt es nicht.
- Irgendetwas muss run.resume() aufrufen. Du baust die Route, die die Antwort empfängt und die passende runId findet.
- Der Snapshot enthält den Workflow-Zustand. Er dokumentiert nicht, wer freigegeben oder was die Person gesehen hat.
Die Lösung
Pushary holt die Antwort deines Nutzers ein.
Mastra kann einen Lauf vor der Tool-Ausführung pausieren, benachrichtigt aber niemanden. Pushary schickt jeden pausierten Aufruf auf das Handy deines Nutzers und genehmigt oder verwirft ihn in Mastra.
issueRefund setzt Mastras eigenes requireApproval. Der Lauf pausiert deshalb vor der Ausführung. resolvePusharyApprovals fragt deinen Nutzer und genehmigt oder verwirft den Aufruf in Mastra. Bei Ablehnung oder keiner rechtzeitigen Antwort wird die Erstattung nie ausgeführt. Deckt eine deiner Pushary-Regeln die Erstattung ab, antwortet die Regel zuerst.
npm install @pushary/mastra @mastra/core zodimport { createTool } from "@mastra/core/tools"
import { resolvePusharyApprovals } from "@pushary/mastra"
import { z } from "zod"
export const issueRefund = createTool({
id: "issue-refund",
description: "Refund an order",
inputSchema: z.object({ orderId: z.string(), amount: z.number().positive() }),
requireApproval: true,
execute: async (input) => refundOrder(input),
})
const output = await agent.generate("Refund order 1234", {
memory: { thread: conversation.id, resource: user.id },
})
if (output.finishReason === "suspended") {
// Your user taps Approve or Deny. No answer means declined.
const outcome = await resolvePusharyApprovals({ externalId: user.id }, { agent, resourceId: user.id })
await handlePendingRuns(outcome.pending)
}Nutze im Workflow den Freigabeschritt
pusharyApprovalStep erstellt die Anfrage, pausiert den Workflow und kehrt sofort zurück. Pushary schickt die Antwort als signierten Webhook an deine Callback-URL. Deine Route prüft sie und ruft run.resume() auf. Ein späterer Schritt prüft approved, bevor die riskante Aktion läuft.
import { createWorkflow } from "@mastra/core/workflows"
import { pusharyApprovalStep, pusharyApprovalStepInputSchema, pusharyAnswerSchema } from "@pushary/mastra"
const config = { apiKey: process.env.PUSHARY_API_KEY! }
const review = pusharyApprovalStep(config, { callbackUrl, externalId: user.id })
const workflow = createWorkflow({
id: "customer-review",
inputSchema: pusharyApprovalStepInputSchema,
outputSchema: pusharyAnswerSchema,
}).then(review).commit()So funktioniert es
Von der Installation zur ersten Antwort
Verbinde deinen Nutzer einmal. Sichere den riskanten Schritt mit einer Freigabe ab. Pushary schickt die Frage, wartet auf die Antwort und speichert sie.
- 01
Adapter installieren
Führe npm install @pushary/mastra @mastra/core zod aus und speichere deinen API-Schlüssel in PUSHARY_API_KEY. Richte für spätere Antworten persistenten Speicher für Mastra ein.
- 02
Nutzer einmal verbinden
connect() liefert einen Link. Zeige ihn in deinem Produkt an. Dein Nutzer öffnet ihn mit der kostenlosen Pushary-App auf seinem Handy. Kein Konto, keine Zahlung.
- 03
Das riskante Tool mit einer Freigabe absichern
Setze requireApproval: true am Tool. Ergänze in einem Workflow pusharyApprovalStep. Für eine einfache Frage, die das Modell nach eigenem Ermessen stellen darf, ergänzt du createPusharyAskTool.
- 04
Auf die Antwort reagieren
resolvePusharyApprovals genehmigt oder verwirft den pausierten Aufruf und setzt den Lauf fort. Im Workflow ruft deine Callback-Route run.resume() auf. Bei Nein, Ablauf oder fehlender Antwort läuft die Aktion nie.
Eine Frage kann ein Ja oder Nein verlangen, eine Auswahl aus einer Liste oder eine Texteingabe. Jede Antwort wird gespeichert.
Vor der Veröffentlichung
Stolperfallen bei Mastra
- Ein Frage-Tool erzwingt keine Freigabe
- createPusharyAskTool ist ein Tool, dessen Aufruf das Modell selbst wählt. Es erzwingt keine Freigabe vor einem anderen Tool. Auch ein Prompt mit „erst fragen“ tut das nicht. Setze requireApproval direkt am riskanten Tool.
- Du brauchst eine Zuordnung von correlationId zu runId
- Die Antwort erreicht deinen Webhook mit Bezug zur Anfrage, nicht zu deinem Workflow. Speichere die Zuordnung beim Pausieren. Sonst hast du eine Antwort, weißt aber nicht, zu welchem pausierten Lauf sie gehört.
- Beim ersten Durchlauf ist resumeData undefined
- Die execute-Funktion des Schritts läuft einmal zum Pausieren und erneut zum Fortsetzen. Vergisst du den undefined-Fall beim ersten Durchlauf, löst sie einen Fehler aus, bevor sie überhaupt pausiert.
Der Partner-Tarif
Dein Agent fragt deine Nutzer, nicht nur dich
Stelle deinen Nutzern deinen Agenten bereit. Jeder gibt dessen riskante Aktionen vom eigenen Handy aus frei, unter deiner Marke.
Deine Nutzer brauchen kein Pushary-Konto und zahlen nichts an uns.
Deine Nutzer antworten auf ihren eigenen Handys
Verbinde jeden Nutzer einmal über einen Link. Er installiert die kostenlose Pushary-App und antwortet vom Sperrbildschirm aus, ohne eigenes Konto.
Keine Antwort heißt Nein
Führe die Aktion nur nach einer ausdrücklichen Freigabe aus. Eine wartende, abgelaufene oder abgebrochene Anfrage zählt nie als Ja. Pushary behält jede Anfrage, damit dein Code sie nach einem Neustart wieder aufnehmen kann.
Erreicht sie auf dem Handy
Die App kommt zuerst, denn nur sie zeigt „Genehmigen“ und „Ablehnen“ auf dem Sperrbildschirm. Browser-Benachrichtigungen folgen danach. Du musst kein Zustellsystem bauen.
Jede Antwort gespeichert
Zu jeder Antwort wird gespeichert, wer wann geantwortet hat. Du kannst sie durchsuchen und exportieren. Mit einer Callback-URL geht jede Antwort außerdem als signierter Webhook an deinen Server.
FAQ
Fragen und Antworten
Gibt es ein Mastra-Paket für Pushary?
Sollte ich das Tool oder den Workflow-Schritt verwenden?
Was passiert, wenn niemand antwortet?
Kann jeder meiner Endnutzer auf seinem eigenen Handy freigeben?
Übersteht die Wartezeit einen Neustart oder ein Deployment?
Wann sollte ich suspend() statt eines blockierenden Frage-Tools verwenden?
Lass deinen Mastra-Agenten fragen, bevor er handelt.
Verbinde einen Nutzer einmal, frage mit einem Aufruf und führe die Aktion nur bei einem Ja aus. Jede Antwort wird gespeichert.
Start freePartner-Tarif, $99 im Monat. Deine Nutzer brauchen kein Pushary-Konto und zahlen nichts an uns.