33800 Docs

← Retour

Proposition : Fix pipeline create_static + Intelligence des agents

Status : IMPLEMENTEE

Analyse de l'incident

L'utilisateur a demande "une page web avec formulaire de contact" (site statique, noir et blanc 90s, nom "test-2026").

Ce qui s'est passe

  1. Briefing OK — le systeme a pose les questions (nom, sections, style), l'utilisateur a repondu
  2. Briefing re-demande — apres "go", le routing a relance un briefing au lieu d'executer le pipeline directement. Cause probable : le message enrichi PROJET: ... a ete re-interprete par l'Interpreter comme un nouveau projet → needs_briefing=true a nouveau
  3. User re-repond aux memes questions — frustrant
  4. Pipeline create_static lance — step 1 = storage-dev tente de creer un bucket Supabase
  5. storage-dev echoue — l'appel connectorFetch('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
  6. L'agent n'a pas dit "c'est un probleme d'auth que je ne peux pas resoudre" — il a boucle au lieu d'admettre la defaillance

3 bugs identifies

# 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

Solutions proposees

Fix 1 : Briefing pas re-demande (Director)

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 });

Fix 2 : Storage API auth (ToolsClient)

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 :

Recommandation : Option (A) — plus simple, pas de modif de connectors-api, et le pattern exec + curl est deja maitrise par les autres agents.

Fix 3 : Agent abort-on-repeated-failure

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;
  }
}

Fix 4 (bonus) : Lecon apprise auto-stockee

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(() => {});
}

Ordre d'implementation

  1. Fix 1 (briefing skipBriefing) — 5 min, 1 fichier
  2. Fix 3 (abort-on-repeated-failure) — 10 min, 1 fichier
  3. Fix 2 (storage-dev prompt → exec+curl) — 10 min, 1 fichier (registry.ts prompt)
  4. Fix 4 (auto-lesson on failure) — 5 min, 1 fichier

Total : ~30 min, commit + push + CI/CD deploy.


Test de validation

Apres deploiement :

  1. Demander "page web avec formulaire de contact"
  2. Briefing = 1 seul tour de questions (pas re-demande)
  3. Pipeline execute → storage-dev cree le bucket via curl
  4. Si erreur → l'agent s'arrete apres 2 tentatives avec message clair
  5. Lecon stockee automatiquement en cas d'echec