Exécuter des candidats concurrents
Essayez plusieurs candidats avec une validation, des budgets et une intégration explicites.
Mettre des candidats en concurrence
Section intitulée « Mettre des candidats en concurrence »Utilisez speculate() pour lancer plusieurs candidats sur une même tâche et valider explicitement chaque résultat. Les candidats ont des branches et des sandboxes séparées ; un gagnant est choisi uniquement si votre vérification l’accepte.
Référence API : SpeculationOptions.
Pour un scénario complet opposant Codex à Claude Code, voir la recette Mettre des agents en concurrence.
Valider le comportement réel
Section intitulée « Valider le comportement réel »validate reçoit la key du candidat, le result de son dispatch et sa sandbox, encore ouverte. Lancez-y vos tests et renvoyez true seulement s’ils passent : un agent qui affirme avoir réussi ne prouve rien.
Passez signal à chaque commande. Il se déclenche quand un autre candidat gagne ou que la course s’arrête.
Le commit du gagnant est le HEAD lu après le retour de validate. Un commit créé pendant la validation fait partie du gagnant ; les modifications non commitées, non. Un agent de revue lancé dans validate ne doit donc pas commiter : voir Laisser un agent de revue trancher.
Lire le résultat
Section intitulée « Lire le résultat »Référence API : SpeculationResult.
Examinez les résultats des candidats avant de choisir ce que vous souhaitez conserver.
Référence API : SpeculativeCandidateResult et SpeculationResult.
Budget et nettoyage
Section intitulée « Budget et nettoyage »- Limite de tentativesChaque démarrage de candidat consomme une des
budget.attempts. Une fois atteinte, aucun nouveau candidat ne démarre ; ceux en cours terminent. - Limite de tokensUne fois
budget.usageatteint, tous les candidats en cours sont annulés. - GagnantLes candidats en cours sont annulés et ceux en attente sont ignorés.
Les tokens consommés dans validate, par exemple par un agent de revue, ne comptent pas dans budget. Les candidats en cours peuvent dépasser la limite de tokens avant que leur usage soit remonté. Budgets explique comment les limites sont mesurées.
Chaque sandbox est libérée à la fin de son candidat. Si elle ne se ferme pas dans le délai cleanupMs, le candidat indique cleanup: "pending", avec son resourceId dans une course durable. Une course durable dont un nettoyage reste en attente reste possédée : appelez recoverSpeculation() avant le prochain speculate().
Ce qui est conservé
Section intitulée « Ce qui est conservé »Les branches des candidats restent toujours dans votre dépôt, gagnant comme perdants.
Un worktree n’est supprimé que s’il est propre. Un worktree contenant des fichiers non commités, non suivis ou ignorés, comme node_modules, reste sous .outpost/workspaces, et son chemin figure dans le retainedDirectory du candidat. Le worktree d’un candidat en échec est conservé lui aussi, et les courses durables conservent le worktree de chaque candidat. Rétention et nettoyage montre comment les supprimer.
Vérifier l’intégration avant de fusionner
Section intitulée « Vérifier l’intégration avant de fusionner »result.integration indique si le gagnant se fusionne dans le HEAD de votre checkout, calculé avec git merge-tree sans toucher à vos fichiers ni à l’index.
Référence API : SpeculationIntegration.
Votre checkout peut changer après la course. Vérifiez à nouveau juste avant de fusionner :
Passez winner.branch et winner.commit. Une branche déplacée depuis la validation donne blocked. La vérification ne fusionne jamais : lancez git merge vous-même.
Reprendre après un arrêt brutal
Section intitulée « Reprendre après un arrêt brutal »Passez durability à speculate(). Tentatives, usage, sorties et ressources allouées sont enregistrés via un transport, et une course terminée est renvoyée sans être relancée.
Changez version quand vous modifiez les agents ou validate. Une course enregistrée dont les briefs, le budget, le fournisseur ou la version diffèrent est refusée : relancez-la sous un nouveau runId.
Une course durable exige un fournisseur capable de retrouver et d’arrêter ses sandboxes après un arrêt brutal. Docker et Podman dans leur mode monté par défaut en sont capables ; les autres fournisseurs sont refusés, sauf si vous implémentez la récupération.
Récupérer après un arrêt brutal
Section intitulée « Récupérer après un arrêt brutal »Une course interrompue par un arrêt brutal reste détenue par son coordinateur, le processus qui a lancé speculate(). Libérez-la avant de la rejouer.
Un candidat interrompu repart comme une nouvelle tentative, sur …/<key>/2, depuis le commit d’origine. Son ancienne branche et son ancien worktree figurent dans result.previousAttempts. Les candidats validés avant le arrêt brutal gardent leur issue.
Reprendre après un quota
Section intitulée « Reprendre après un quota »Une course durable terminée avec le statut quota n’est pas définitive. Rappeler speculate() avec la même durability relance uniquement les candidats arrêtés par une limite d’usage ou de débit, comme nouvelles tentatives. result.quota.resetAt donne l’heure de réinitialisation quand l’agent la communique ; Pauses sur quota explique comment l’attendre.
speculate()ne fusionne jamais, ne pousse rien et n’ouvre aucune pull request.- Une intégration
cleann’est pas un verrou : toute modification ultérieure de votre checkout la rend obsolète. cleanupMsborne l’attente, pas le fournisseur : une sandboxpendingpeut encore tourner jusqu’à sa réconciliation.- La récupération reprend la course, pas un processus d’agent interrompu. Un candidat rejoué peut répéter des effets externes.
- Une course durable a besoin de ses worktrees sur disque : un transport distant enregistre l’état, pas le checkout.
- Les résultats durables doivent contenir des valeurs JSON, et un arrêt brutal en cours d’exécution rend l’usage incomplet : ajoutez
budget.attemptsaux limites de tokens.
API : speculate · SpeculationOptions · SpeculationResult · SpeculativeCandidateResult · SpeculativeValidation · checkSpeculationIntegration · SpeculationDurability · recoverSpeculation.