Status : IMPLEMENTEE
L'utilisateur a demande "une page web avec formulaire de contact" (site statique, noir et blanc 90s, nom "test-2026").
PROJET: ... a ete re-interprete par l'Interpreter comme un nouveau projet → needs_briefing=true a nouveaucreate_static lance — step 1 = storage-dev tente de creer un bucket SupabaseconnectorFetch('supabase', ...) echoue car le connector Supabase via connectors-api retourne 401 (auth header manquant cote Supabase Storage API). L'agent a galere 8 iterations (3.5 min) avant de fail| # | Bug | Cause racine | Impact |
|---|---|---|---|
| 1 | Briefing re-demande | Le message enrichi PROJET: ... passe dans handleMessage → re-route par Interpreter → needs_briefing=true |
Double questionnaire |
| 2 | storage-dev 401 | Les appels Storage API via connectors-api necessitent un Authorization: Bearer <service_role_key> que connectorFetch ne passe pas correctement au Supabase Storage endpoint |
Pipeline casse |
| 3 | Agent boucle au lieu d'admettre | Aucune instruction dans le prompt agent pour detecter les erreurs repetitives et abandonner avec un message clair | 8 iterations pour rien |
Fichier : director/index.ts methode handleMessage
Le probleme : quand l'utilisateur confirme "go", handleBriefingMessage appelle this.handleMessage(enrichedPrompt) — et ce message enrichi est re-route par l'Interpreter qui peut a nouveau mettre needs_briefing=true.
Fix : ajouter un flag skipBriefing a handleMessage pour court-circuiter le check briefing quand on vient d'un briefing confirme.
async handleMessage(
message: string,
onEvent?: DirectorEventCallback,
opts?: { skipBriefing?: boolean }
): Promise<Objective> {
// ...
if (routing.needs_briefing && routing.pipeline && PIPELINES[routing.pipeline] && !opts?.skipBriefing) {
// Start briefing
}
}
Et dans handleBriefingMessage quand user confirme :
return this.handleMessage(enrichedPrompt, onEvent, { skipBriefing: true });
Fichier : tools/client.ts
Le probleme : connectorFetch envoie la requete au connector Supabase, mais le connector Supabase de connectors-api utilise l'anon key. L'API Storage Supabase necessite le service_role key pour creer des buckets.
Options :
storage-dev peut appeler curl directement sur Supabase Storage API depuis prod-portainer via exec. Plus fiable car controle total des headers. Modifier le prompt de storage-dev pour lui dire d'utiliser exec + curl au lieu des tools storage dedies.Authorization: Bearer <service_role_key> dans les appels storage. Necessite d'ajouter la service_role_key dans les env vars.Recommandation : Option (A) — plus simple, pas de modif de connectors-api, et le pattern exec + curl est deja maitrise par les autres agents.
Fichier : agent-runner/index.ts
Le probleme : quand un tool retourne la meme erreur 2-3 fois de suite, l'agent continue a boucler car le LLM essaie d'autres approches sans succes.
Fix : detecter les erreurs repetitives et forcer l'arret avec un message explicatif.
// Dans la boucle while du run()
// Tracker les erreurs consecutives
let consecutiveErrors = 0;
let lastErrorMsg = '';
// Apres chaque tool_result
if (resultStr.startsWith('Tool error:')) {
if (resultStr === lastErrorMsg) {
consecutiveErrors++;
if (consecutiveErrors >= 2) {
// Force stop — meme erreur 3 fois
emit('error', { message: `Arret: erreur repetee 3 fois: ${resultStr.slice(0, 200)}` });
return {
success: false,
output: `Je n'arrive pas a completer cette tache. Erreur repetee: ${resultStr.slice(0, 500)}`,
// ...
error: 'Repeated tool error — auto-stopped',
};
}
} else {
consecutiveErrors = 0;
lastErrorMsg = resultStr;
}
}
Quand un agent fail, stocker automatiquement une "lecon" dans agents.lessons pour que les futurs agents evitent le meme piege. C'est le systeme de lessons qui existe deja dans fetchRelevantLessons.
// Dans Director, apres un objective fail
if (!result.success && result.error) {
this.db.createLesson({
user_id: this.userCtx.userId,
category: routing.agent,
lesson: `Echec sur "${message.slice(0,100)}": ${result.error}. ${result.output.slice(0,200)}`,
}).catch(() => {});
}
Total : ~30 min, commit + push + CI/CD deploy.
Apres deploiement :