Approbation des Agents
Lorsqu’ils appellent des outils qui effectuent des opérations sensibles, comme la suppression de ressources ou l’exécution de processus longs, les Agents nécessitent parfois la même supervision humaine que celle utilisée dans les Workflows. L’approbation des Agents permet de suspendre l’appel d’un outil avant son exécution afin qu’un humain puisse l’approuver ou le refuser. Les outils peuvent également se suspendre eux-mêmes pour demander des informations supplémentaires à l’utilisateur.
Quand utiliser l’approbation des AgentsLien direct vers Quand utiliser l’approbation des Agents
- Actions destructives ou irréversibles, comme la suppression d’enregistrements, l’envoi d’e-mails ou encore le traitement de paiements.
- Opérations coûteuses, comme l’appel d’API tierces onéreuses dont vous souhaitez d’abord vérifier les arguments.
- Confirmation conditionnelle, lorsqu’un outil commence son exécution, puis constate qu’il a besoin d’une confirmation ou de données supplémentaires de l’utilisateur pour la terminer.
Démarrage rapideLien direct vers Démarrage rapide
Définissez requireApproval: true sur un outil, puis recherchez le segment tool-call-approval dans le flux afin d’approuver ou de refuser son appel :
import { Agent } from '@mastra/core/agent'
import { createTool } from '@mastra/core/tools'
import { z } from 'zod'
const deleteTool = createTool({
id: 'delete-record',
description: 'Delete a record by ID',
inputSchema: z.object({ id: z.string() }),
outputSchema: z.object({ deleted: z.boolean() }),
requireApproval: true,
execute: async ({ id }) => {
await db.delete(id)
return { deleted: true }
},
})
const agent = new Agent({
id: 'my-agent',
name: 'My Agent',
model: 'openai/gpt-5-mini',
tools: { deleteTool },
})
const stream = await agent.stream('Delete record abc-123')
for await (const chunk of stream.fullStream) {
if (chunk.type === 'tool-call-approval') {
const approved = await agent.approveToolCall({ runId: stream.runId })
for await (const c of approved.textStream) process.stdout.write(c)
}
}
L’approbation des Agents utilise des snapshots pour capturer l’état de la requête. Configurez un Provider de stockage sur votre instance Mastra, sans quoi l’erreur « snapshot not found » s’affichera.
Les snapshots des exécutions d’Agents sont des artefacts de reprise minimaux : ils contiennent uniquement les éléments nécessaires à la reprise de l’exécution suspendue et sont supprimés une fois celle-ci terminée. Utilisez le tracing pour conserver une trace de l’exécution et la mémoire pour l’historique de la conversation.
Fonctionnement de l’approbationLien direct vers Fonctionnement de l’approbation
Mastra propose deux mécanismes distincts pour interrompre les appels d’outils : l’approbation avant exécution et la suspension pendant l’exécution.
Approbation avant exécutionLien direct vers Approbation avant exécution
L’approbation avant exécution interrompt l’appel d’un outil avant l’exécution de sa fonction execute. Le LLM choisit toujours l’outil à appeler et fournit ses arguments, mais execute ne s’exécute qu’après votre approbation explicite.
Les options ci-dessous contrôlent ce comportement selon une logique OU. Si l’une d’elles vaut true, l’appel est suspendu :
| Option | Où la définir | Portée |
|---|---|---|
requireToolApproval: true | Options de stream() / generate() | Suspend tous les appels d’outils de cette requête |
requireApproval: true | Définition de createTool() | Suspend les appels de cet outil précis |
Le flux émet un segment tool-call-approval contenant toolCallId, toolName et args. Pour poursuivre, appelez approveToolCall() ou declineToolCall() avec le runId du flux :
const stream = await agent.stream("What's the weather in London?", {
requireToolApproval: true,
})
for await (const chunk of stream.fullStream) {
if (chunk.type === 'tool-call-approval') {
console.log('Tool:', chunk.payload.toolName)
console.log('Args:', chunk.payload.args)
// Approve
const approved = await agent.approveToolCall({ runId: stream.runId })
for await (const c of approved.textStream) process.stdout.write(c)
// Or decline
const declined = await agent.declineToolCall({ runId: stream.runId })
for await (const c of declined.textStream) process.stdout.write(c)
}
}
Approbation conditionnelle avec une fonctionLien direct vers Approbation conditionnelle avec une fonction
Au lieu d’un booléen, requireToolApproval accepte une fonction qui prend une décision pour chaque appel d’outil. Elle reçoit le toolName, les args transmis par le modèle, le requestContext et le workspace. Renvoyez true pour exiger l’approbation de cet appel, ou false pour l’autoriser. Vous pouvez ainsi conditionner l’approbation pendant l’exécution, par exemple uniquement pour les outils dont le nom correspond à un motif :
const stream = await agent.stream('Clean up old records', {
requireToolApproval: ({ toolName }) => /^delete_/.test(toolName),
})
Le paramètre requireApproval propre à un outil prévaut sur la fonction ci-dessus. Sa règle détermine si cet outil nécessite une approbation. Si la fonction lève une exception, l’appel exige une approbation par mesure de sécurité.
L’utilisation d’une fonction avec requireToolApproval n’est disponible que pour les appels stream() / generate() ordinaires. Les Agents durables et les Agents stockés conservent leurs options. Une fonction ne pouvant pas être sérialisée, ils n’acceptent qu’un booléen. Si vous transmettez une fonction dans ces contextes, tous les appels d’outils nécessiteront une approbation par défaut.
Lier l’approbation aux arguments exacts de l’outilLien direct vers Lier l’approbation aux arguments exacts de l’outil
Pour les outils sensibles, liez l’approbation au nom exact de l’outil et aux arguments présentés à la personne chargée de la validation. Si ces arguments changent avant l’exécution, l’outil ne doit pas s’exécuter sur la base de l’ancienne approbation.
Le segment tool-call-approval contient déjà toolName, toolCallId et args. Vous pouvez créer une empreinte de ces champs lors de l’affichage de la demande d’approbation. L’exemple ci-dessous utilise une chaîne JSON comme empreinte, mais en production, utilisez une empreinte stable du nom de l’outil et de ses arguments :
import { Agent } from '@mastra/core/agent'
// For your production usecase, build a stable hash of the tool name and args
function actionFingerprint(toolName: string, args: unknown) {
const payload = JSON.stringify({ toolName, args })
return `fingerprint-${payload}`
}
const sensitiveTools = new Set(['issue_refund', 'delete_record'])
const approvedFingerprints = new Set<string>()
export const approvalBoundAgent = new Agent({
id: 'approval-bound-agent',
name: 'Approval Bound Agent',
model: 'openai/gpt-5.6-sol',
tools: { issueRefundTool, deleteRecordTool },
hooks: {
beforeToolCall: ({ toolName, input }) => {
if (!sensitiveTools.has(toolName)) return
const fingerprint = actionFingerprint(toolName, input)
if (!approvedFingerprints.delete(fingerprint)) {
return {
proceed: false,
output: `Tool call blocked: approval did not match ${toolName} arguments.`,
}
}
},
},
})
const stream = await approvalBoundAgent.stream('Refund order ord-1042', {
requireToolApproval: ({ toolName }) => sensitiveTools.has(toolName),
})
async function consumeApprovalStream(currentStream: typeof stream) {
for await (const chunk of currentStream.fullStream) {
if (chunk.type === 'tool-call-approval') {
const { toolName, toolCallId, args } = chunk.payload
const fingerprint = actionFingerprint(toolName, args)
// Present toolName, args, and fingerprint to your approval UI.
const approved = await showApprovalDialog({ toolName, args, fingerprint })
const nextStream = approved
? await approveReviewedToolCall(currentStream.runId, toolCallId, fingerprint)
: await approvalBoundAgent.declineToolCall({ runId: currentStream.runId, toolCallId })
await consumeApprovalStream(nextStream)
}
}
}
async function approveReviewedToolCall(runId: string, toolCallId: string, fingerprint: string) {
approvedFingerprints.add(fingerprint)
return approvalBoundAgent.approveToolCall({ runId, toolCallId })
}
await consumeApprovalStream(stream)
En production, stockez l’empreinte approuvée dans un stockage durable associé à l’utilisateur, à l’exécution, à l’appel de l’outil et à la version de la politique. Le Set ci-dessus est volontairement minimal afin que la limite soit claire : l’approbation n’est consommée qu’une seule fois, et uniquement pour les mêmes arguments canoniques de l’outil que ceux qui ont été examinés.
Suspension pendant l’exécution avec suspend()Lien direct vers runtime-suspension-with-suspend
Un outil peut également s’interrompre pendant sa fonction execute en appelant suspend(). Ce mécanisme est utile lorsque l’outil commence son exécution, puis constate qu’il a besoin d’informations supplémentaires ou d’une confirmation de l’utilisateur pour la terminer.
Le flux émet un segment tool-call-suspended dont la charge utile personnalisée est définie par le suspendSchema de l’outil. Pour reprendre l’exécution, appelez resumeStream() avec des données conformes au resumeSchema de l’outil.
const weatherTool = createTool({
id: 'get-weather',
inputSchema: z.object({
location: z.string().optional(),
}),
suspendSchema: z.object({
question: z.string(),
}),
resumeSchema: z.object({
location: z.string(),
}),
execute: async ({ location }, context) => {
if (!location) {
return await context?.agent?.suspend({
question: 'Which city would you like the weather for?',
})
}
return await fetchWeather(location)
},
})
suspend() ne lève pas d’exception : effectuez un retour immédiatement après son appel (par exemple, return await suspend({ ... })). Le code situé après await suspend(...) s’exécute tout de même avant la suspension de l’outil.
Approbation des outils avec generate()Lien direct vers tool-approval-with-generate
L’approbation des outils fonctionne également avec generate() dans les cas d’usage sans streaming. Lorsqu’un outil nécessite une approbation, generate() renvoie immédiatement finishReason: 'suspended', un suspendPayload contenant les détails de l’appel de l’outil (toolCallId, toolName, args) et un runId :
const output = await agent.generate('Find user John', {
requireToolApproval: true,
})
if (output.finishReason === 'suspended') {
console.log('Tool requires approval:', output.suspendPayload.toolName)
// Approve
const result = await agent.approveToolCallGenerate({
runId: output.runId,
toolCallId: output.suspendPayload.toolCallId,
})
console.log('Final result:', result.text)
// Or decline
const result = await agent.declineToolCallGenerate({
runId: output.runId,
toolCallId: output.suspendPayload.toolCallId,
})
}
Comparaison entre stream et generateLien direct vers Comparaison entre stream et generate
| Aspect | stream() | generate() |
|---|---|---|
| Type de réponse | Segments diffusés en streaming | Réponse complète |
| Détection de l’approbation | Segment tool-call-approval | finishReason: 'suspended' |
| Méthode d’approbation | approveToolCall({ runId }) | approveToolCallGenerate({ runId, toolCallId }) |
| Méthode de refus | declineToolCall({ runId }) | declineToolCallGenerate({ runId, toolCallId }) |
| Résultat | Flux à parcourir | Objet de sortie complet |
toolCallId est facultatif pour chacune des quatre méthodes. Transmettez-le lorsque plusieurs appels d’outils peuvent être en attente, ce qui est fréquent avec les Agents superviseurs. S’il est omis, l’Agent reprend le dernier appel d’outil suspendu.
Approbation au niveau de l’outilLien direct vers Approbation au niveau de l’outil
Au lieu de suspendre chaque appel d’outil au niveau de l’Agent, vous pouvez indiquer individuellement les outils qui nécessitent une approbation. Vous bénéficiez ainsi d’un contrôle précis : seuls certains outils sont suspendus, tandis que les autres s’exécutent immédiatement.
Approbation avec requireApprovalLien direct vers approval-using-requireapproval
Définissez requireApproval: true dans la définition d’un outil. Celui-ci est suspendu avant son exécution, que requireToolApproval soit ou non défini sur l’Agent :
export const testTool = createTool({
id: 'test-tool',
description: 'Fetches weather for a location',
inputSchema: z.object({
location: z.string(),
}),
outputSchema: z.object({
weather: z.string(),
}),
resumeSchema: z.object({
approved: z.boolean(),
}),
execute: async inputData => {
const response = await fetch(`https://wttr.in/${inputData.location}?format=3`)
const weather = await response.text()
return { weather }
},
requireApproval: true,
})
Lorsque requireApproval vaut true, le flux émet des segments tool-call-approval, comme pour une approbation au niveau de l’Agent. Utilisez approveToolCall() ou declineToolCall() pour poursuivre :
const stream = await agent.stream("What's the weather in London?")
for await (const chunk of stream.fullStream) {
if (chunk.type === 'tool-call-approval') {
console.log('Approval required for:', chunk.payload.toolName)
}
}
const handleApproval = async () => {
const approvedStream = await agent.approveToolCall({ runId: stream.runId })
for await (const chunk of approvedStream.textStream) {
process.stdout.write(chunk)
}
process.stdout.write('\n')
}
Approbation avec suspend()Lien direct vers approval-using-suspend
Avec cette approche, ni l’Agent ni l’outil n’utilisent requireApproval. La fonction execute de l’outil appelle plutôt suspend() pour s’interrompre à un point précis et renvoyer à l’utilisateur des informations contextuelles ou une demande de confirmation. Cette méthode est utile lorsque l’approbation dépend de conditions rencontrées pendant l’exécution au lieu d’être systématique.
export const testToolB = createTool({
id: 'test-tool-b',
description: 'Fetches weather for a location',
inputSchema: z.object({
location: z.string(),
}),
outputSchema: z.object({
weather: z.string(),
}),
resumeSchema: z.object({
approved: z.boolean(),
}),
suspendSchema: z.object({
reason: z.string(),
}),
execute: async (inputData, context) => {
const { resumeData: { approved } = {}, suspend } = context?.agent ?? {}
if (!approved) {
return suspend?.({ reason: 'Approval required.' })
}
const response = await fetch(`https://wttr.in/${inputData.location}?format=3`)
const weather = await response.text()
return { weather }
},
})
Avec cette approche, le flux contient un segment tool-call-suspended, et le suspendPayload contient la reason définie par le suspendSchema de l’outil. Pour poursuivre, appelez resumeStream avec les données du resumeSchema et le runId :
const stream = await agent.stream("What's the weather in London?")
for await (const chunk of stream.fullStream) {
if (chunk.type === 'tool-call-suspended') {
console.log(chunk.payload.suspendPayload)
}
}
const handleResume = async () => {
const resumedStream = await agent.resumeStream({ approved: true }, { runId: stream.runId })
for await (const chunk of resumedStream.textStream) {
process.stdout.write(chunk)
}
process.stdout.write('\n')
}
Reprise automatique des outilsLien direct vers Reprise automatique des outils
Lorsque vous utilisez des outils qui appellent suspend(), vous pouvez activer la reprise automatique afin que l’Agent relance les outils suspendus en fonction du prochain message de l’utilisateur. Définissez autoResumeSuspendedTools sur true dans les options par défaut de l’Agent ou pour une requête particulière :
import { Agent } from '@mastra/core/agent'
import { Memory } from '@mastra/memory'
const agent = new Agent({
id: 'my-agent',
name: 'My Agent',
instructions: 'You are a helpful assistant',
model: 'openai/gpt-5-mini',
tools: { weatherTool },
memory: new Memory(),
defaultOptions: {
autoResumeSuspendedTools: true,
},
})
Lorsque cette option est activée, l’Agent détecte les outils suspendus dans l’historique des messages à la réception du message suivant de l’utilisateur. Il extrait les resumeData selon le resumeSchema de l’outil, puis reprend automatiquement son exécution.
L’exemple suivant présente un flux conversationnel complet :
import { createTool } from '@mastra/core/tools'
import { z } from 'zod'
const weatherTool = createTool({
id: 'weather-tool',
description: 'Fetches weather for a city',
inputSchema: z.object({
city: z.string(),
}),
outputSchema: z.object({
weather: z.string(),
}),
suspendSchema: z.object({
message: z.string(),
}),
resumeSchema: z.object({
city: z.string(),
}),
execute: async (inputData, context) => {
const { resumeData, suspend } = context?.agent ?? {}
// If no city provided, ask the user
if (!inputData.city && !resumeData?.city) {
return suspend?.({ message: 'What city do you want to know the weather for?' })
}
const city = resumeData?.city ?? inputData.city
const response = await fetch(`https://wttr.in/${city}?format=3`)
const weather = await response.text()
return { weather: `${city}: ${weather}` }
},
})
const stream = await agent.stream("What's the weather like?")
for await (const chunk of stream.fullStream) {
if (chunk.type === 'tool-call-suspended') {
console.log(chunk.payload.suspendPayload)
}
}
// User sends follow-up on the same thread
const resumedStream = await agent.stream('San Francisco')
for await (const chunk of resumedStream.textStream) {
process.stdout.write(chunk)
}
User: "What's the weather like?"
Agent: "What city do you want to know the weather for?"
User: "San Francisco"
Agent: "The weather in San Francisco is: San Francisco: ☀️ +72°F"
Le deuxième message reprend automatiquement l’outil suspendu. L’Agent extrait { city: "San Francisco" } du message de l’utilisateur et le transmet en tant que resumeData.
Conditions requisesLien direct vers Conditions requises
Pour que la reprise automatique des outils fonctionne :
- Mémoire configurée : l’Agent a besoin de la mémoire pour suivre les outils suspendus d’un message à l’autre.
- Même thread : le message de suivi doit utiliser les mêmes identifiants de thread mémoire et de ressource.
resumeSchemadéfini : l’outil doit définir unresumeSchemaafin que l’Agent sache quelle structure de données extraire du message de l’utilisateur.
Reprise manuelle ou automatiqueLien direct vers Reprise manuelle ou automatique
| Approche | Cas d’usage |
|---|---|
Manuelle (resumeStream()) | Contrôle programmatique, webhooks, clics sur des boutons, déclencheurs externes |
Automatique (autoResumeSuspendedTools) | Flux conversationnels dans lesquels les utilisateurs fournissent les données de reprise en langage naturel |
Les deux approches fonctionnent avec les mêmes définitions d’outils. La reprise automatique ne se déclenche que si l’historique des messages contient des outils suspendus et que l’utilisateur envoie un nouveau message dans le même thread.
Reprendre après un redémarrageLien direct vers Reprendre après un redémarrage
Dans les exemples ci-dessus, stream.runId est conservé entre la suspension et l’approbation. Cela fonctionne tant que le processus reste actif, mais en production, l’approbation intervient souvent plus tard, après l’actualisation d’une page, le redémarrage d’un serveur ou sur une autre instance de serveur derrière un répartiteur de charge.
Utilisez listSuspendedRuns() pour retrouver dans le stockage l’exécution en attente d’une conversation :
// In the request handler that receives the user's decision
const { runs } = await agent.listSuspendedRuns({
threadId: 'thread-123',
resourceId: 'user-456',
})
const run = runs[0]
const toolCall = run?.toolCalls[0]
if (run && toolCall) {
let stream
if (toolCall.requiresApproval) {
// Suspended by requireApproval — approve or decline the tool call
stream = await agent.approveToolCall({ runId: run.runId, toolCallId: toolCall.toolCallId })
} else {
// Suspended by suspend() — resume with the data the tool asked for
console.log('Tool asked:', toolCall.suspendPayload)
stream = await agent.resumeStream({ name: 'San Francisco' }, { runId: run.runId })
}
for await (const chunk of stream.textStream) process.stdout.write(chunk)
}
Chaque exécution renvoyée comprend les appels d’outils suspendus (toolCallId, toolName, args et requiresApproval). Les suspensions pour approbation (requiresApproval: true) sont traitées avec approveToolCall() / declineToolCall(), tandis que les suspensions basées sur suspend() contiennent leur suspendPayload et attendent un appel à resumeStream() avec les données de reprise. Vous pouvez ainsi reconstruire l’interface appropriée pour chaque flux sans conserver d’état en mémoire.
sendToolApproval() utilise automatiquement le même mécanisme de recherche fondé sur le stockage : lorsqu’aucune exécution active n’est trouvée en mémoire pour le thread, la méthode recherche l’exécution suspendue dans le stockage avant d’échouer. Si plusieurs exécutions suspendues correspondent au thread, transmettez un toolCallId pour lever l’ambiguïté.
Le même mécanisme de recherche est disponible via HTTP avec GET /agents/:agentId/suspended-runs et dans le SDK client avec agent.listSuspendedRuns(). Les interfaces d’approbation exécutées dans un navigateur peuvent ainsi retrouver directement les exécutions en attente.
Les exécutions suspendues ne survivent aux redémarrages que si votre instance Mastra est configurée avec un Provider de stockage persistant. Le stockage en mémoire par défaut perd les snapshots à l’arrêt du processus.
Approbation des outils : Agents superviseursLien direct vers Approbation des outils : Agents superviseurs
Un Agent superviseur coordonne plusieurs sous-agents au moyen de .stream() ou .generate(). Lorsqu’un sous-agent appelle un outil qui nécessite une approbation, la demande remonte la chaîne de délégation et apparaît au niveau du superviseur :
- Le superviseur délègue une tâche à un sous-agent.
- Le sous-agent appelle un outil qui définit
requireApproval: trueou utilisesuspend(). - La demande d’approbation remonte jusqu’au superviseur.
- Vous approuvez ou refusez la demande au niveau du superviseur.
- La décision redescend jusqu’au sous-agent.
Les approbations d’outils se propagent également à travers plusieurs niveaux de délégation. Si un superviseur délègue une tâche au sous-agent A, qui la délègue à son tour au sous-agent B disposant d’un outil avec requireApproval: true, la demande d’approbation apparaît tout de même au niveau du superviseur principal.
Approuver et refuser avec les Agents superviseursLien direct vers Approuver et refuser avec les Agents superviseurs
L’exemple ci-dessous crée un sous-agent doté d’un outil qui nécessite une approbation. Lorsque l’outil déclenche une demande d’approbation, celle-ci apparaît dans le flux du superviseur sous la forme d’un segment tool-call-approval :
import { Agent } from '@mastra/core/agent'
import { createTool } from '@mastra/core/tools'
import { Memory } from '@mastra/memory'
import { z } from 'zod'
const findUserTool = createTool({
id: 'find-user',
description: 'Finds user by ID in the database',
inputSchema: z.object({
userId: z.string(),
}),
outputSchema: z.object({
user: z.object({
id: z.string(),
name: z.string(),
email: z.string(),
}),
}),
requireApproval: true,
execute: async input => {
const user = await database.findUser(input.userId)
return { user }
},
})
const dataAgent = new Agent({
id: 'data-agent',
name: 'Data Agent',
description: 'Handles database queries and user data retrieval',
model: 'openai/gpt-5-mini',
tools: { findUserTool },
})
const supervisorAgent = new Agent({
id: 'supervisor',
name: 'Supervisor Agent',
instructions: `You coordinate data retrieval tasks.
Delegate to data-agent for user lookups.`,
model: 'openai/gpt-5.6-sol',
agents: { dataAgent },
memory: new Memory(),
})
const stream = await supervisorAgent.stream('Find user with ID 12345')
for await (const chunk of stream.fullStream) {
if (chunk.type === 'tool-call-approval') {
console.log('Tool requires approval:', chunk.payload.toolName)
console.log('Arguments:', chunk.payload.args)
// Approve the tool call
const resumeStream = await supervisorAgent.approveToolCall({
runId: stream.runId,
toolCallId: chunk.payload.toolCallId,
})
for await (const resumeChunk of resumeStream.textStream) {
process.stdout.write(resumeChunk)
}
// To decline instead, use:
const declineStream = await supervisorAgent.declineToolCall({
runId: stream.runId,
toolCallId: chunk.payload.toolCallId,
})
}
}
Utiliser suspend() avec les Agents superviseursLien direct vers use-suspend-in-supervisor-agents
Les outils peuvent également utiliser suspend() pour interrompre l’exécution et renvoyer des informations contextuelles à l’utilisateur. Cette approche traverse la chaîne de délégation du superviseur de la même manière que requireApproval : la suspension apparaît au niveau du superviseur.
const conditionalTool = createTool({
id: 'conditional-operation',
description: 'Performs an operation that may require confirmation',
inputSchema: z.object({
operation: z.string(),
}),
suspendSchema: z.object({
message: z.string(),
}),
resumeSchema: z.object({
confirmed: z.boolean(),
}),
execute: async (input, context) => {
const { resumeData } = context?.agent ?? {}
if (!resumeData?.confirmed) {
return context?.agent?.suspend({
message: `Confirm: ${input.operation}?`,
})
}
// Proceed with operation
return await performOperation(input.operation)
},
})
// When using this tool through a subagent in supervisor agents
for await (const chunk of stream.fullStream) {
if (chunk.type === 'tool-call-suspended') {
console.log('Tool suspended:', chunk.payload.suspendPayload.message)
// Resume with confirmation
const resumeStream = await supervisorAgent.resumeStream(
{ confirmed: true },
{ runId: stream.runId },
)
for await (const resumeChunk of resumeStream.textStream) {
process.stdout.write(resumeChunk)
}
}
}
Approbation du superviseur avec generate()Lien direct vers supervisor-approval-with-generate
La propagation de l’approbation des outils fonctionne également avec generate() dans les Agents superviseurs :
const output = await supervisorAgent.generate('Find user with ID 12345', {
maxSteps: 10,
})
if (output.finishReason === 'suspended') {
console.log('Tool requires approval:', output.suspendPayload.toolName)
// Approve
const result = await supervisorAgent.approveToolCallGenerate({
runId: output.runId,
toolCallId: output.suspendPayload.toolCallId,
})
console.log('Final result:', result.text)
}