Files
IdeA/.ideai/tickets/157/carnet.md

10 KiB
Raw Blame History

issueRef, version, updatedBy, updatedAt
issueRef version updatedBy updatedAt
#157 17
kind agent_id
agent a6c6ea12-bfc6-4bdc-8031-324102dfa34d
1786378849914

Journal d'itération (le plus récent en haut)

Itération 3 — 2026-08-10 — Régression CLI custom: doublons tool/MCP + progress potentiellement manquants avant le premier MCP

Remontée user (capture live AppImage, 2026-08-10) : sur la CLI custom, l'usage de idea_ask_agent affiche les événements tool/MCP en double (deux cartes Delegation idea_ask_agent et deux cartes Provider tool: idea_ask_agent) alors que l'attendu produit est de ne conserver qu'une première carte start et une première carte done. En parallèle, l'utilisateur suspecte que tous les messages de progression/intention ne sont pas surfacés, notamment possiblement avant le premier appel MCP (ex. "Je vais d'abord regarder la liste de tools MCP...").

Arbitrage Main + Architect

  • #157 reste le ticket principal du rendu CLI custom pour la hiérarchie visuelle et le dédoublonnage des cartes tool/MCP/delegation.
  • #171 porte la pipeline d'observabilité live (ReplyEvent::Progress -> UI) pour les progress/messages d'intention qui ne doivent pas dépendre du Final.
  • #167 reste fermé : le bug historique traité sur l'ordre events after Final n'est pas rouvert à ce stade ; si DevBackend démontre un nouveau défaut d'émission/ordering backend, il faudra alors créer un delta dédié ou rouvrir en second temps.

Hypothèse de travail pour ce cycle

  • Le backend expose déjà une part significative des progress live via la fondation #156 et le correctif OpenCode de l'itération 2.
  • Le symptôme utilisateur courant est probablement un split :
    1. problème frontend de réconciliation/rendu (dédoublonnage des cartes start/done), et/ou
    2. défaut de projection live UI de certains ReplyChunk::Progress en amont du premier appel MCP.

Cycle relancé

  • Architect consulté pour arbitrage ports/contrats/tickets.
  • Décision Git préparatoire récupérée : branche de cycle existante fix/171-conversation-observability-pipeline à privilégier, sauf preuve backend contraire.
  • DevBackend mandaté pour vérifier si les progress pré-MCP existent bien dans le flux backend actuel et si les doublons tool/MCP naissent avant ou après transport UI.
  • DevFrontend mandaté pour inspecter la logique de rendu/réconciliation des cartes progress/tool/MCP/delegation dans la custom CLI, corriger si nécessaire et préparer les tests.
  • QA passera après implémentation réelle avec preuve de commandes/tests.

Attendus de validation pour clôture

  • Pour un appel idea_ask_agent, la CLI custom n'affiche qu'une carte start et une carte done pertinentes, sans doublons parasites.
  • Les messages de progression/intention disponibles dans le flux sont visibles avant le premier MCP quand ils existent réellement côté provider/IdeA.
  • Aucun faux streaming n'est simulé pour les profils qui n'exposent pas ce niveau de granularité.

Itération 2 — 2026-08-09 — Régression profil OpenCode/GLM (pas de progress, pas de bulle MCP)

Remontée user : sur la CLI custom avec un profil OpenCode/GLM, aucun message de progress pendant le traitement de l'agent, et aucune bulle d'appel de tool MCP quand l'agent invoque un outil.

Cause racine (vérifiée en source opencode v1.17.18)

J'ai lu packages/opencode/src/cli/cmd/run.ts (sst/opencode). opencode run --format json émet chaque événement JSONL en temps réel sur stdout ({type, timestamp, sessionID, ...data}). Types émis : step_start, step_finish, text (part textuelle finalisée, pas un delta token), tool_use (seulement à part.state.status=completed|error, pas de start), reasoning, error. Le parser IdeA opencode.rs::parse_jsonl_record reconnaît déjà ces types correctement — le parser n'était pas cassé.

Les deux vraies causes :

  1. OpenCodeSession ne surchargeait pas send_with_tap (défaut domain/ports.rs:1380 ignore le tap). Son send bufferisait TOUT le stdout jusqu'à l'EOF puis parsait en bloc → le tap live (commands.rs:2301) recevait zéro event pendant le tour (silence total), tout arrivait en burst à la fin.
  2. La bulle kind:Mcp/source:IdeaLocal n'était émise que par openai_compat.rs::apply_tool_calls (où IdeA orchestre les outils). Pour OpenCode, les outils tournent dans opencode ; les tool_use étaient taggés kind:Tool générique.

Correctif livré (backend-only)

Branche fix/ticket157-opencode-progress-mcp-surfacing, commit 836137a3 (base develop a3d94d4d). Fichier unique : crates/infrastructure/src/session/opencode.rs (+408/−69).

  • send_with_tap override (pattern codex.rs/claude.rs) : lecture stdout ligne par ligne, projection live au tap des events non-terminaux (Progress/TextDelta/ToolActivity/Heartbeat), Final assemblé à la fin (jamais envoyé au tap). send() sans tap reste batch (inchangé).
  • Tagging MCP : tool_use préfixé idea_ → ReplyProgress{source:IdeaLocal, kind:Mcp, stage:Completed, tool_name} (remplace la Progress Tool provider-native, pas de double card).
  • Protection replay : sur session continuée (--session), le premier messageID est tamponné puis supprimé si un nouveau messageID arrive (évite de projeter l'historique rejoué).

Tests & QA

  • 3 nouveaux tests : parse_jsonl_turn_tags_idea_tools_as_mcp_progress, send_with_tap_emits_progress_live_before_final_and_tags_idea_tool_as_mcp, send_with_tap_does_not_replay_previous_message_into_live_stream.
  • cargo test -p infrastructure session::opencode → 20 passed. cargo check -p infrastructure -p application → OK. cargo fmt --check → OK.
  • QA verdict VERT : ciblé conforme au contrat, pas de régression. Les échecs larges (mcp_server tools_list... 38 vs 37 ; orchestrator_service 39 hangs/spawn) reproduisent à l'identique sur la base a3d94d4d → pré-existants, hors périmètre du fix.

Restes / points pour les prochaines itérations

  • Réserve replay (tradeoff UX) : sur une session continuée avec un seul messageID et aucun replay observable, le tap peut rester muet jusqu'à l'EOF (hold_until_new_message) pour éviter d'afficher un historique non rétractable. Cas frais = streaming immédiat. À retravailler si la reprise de session devient prioritaire.
  • reasoning non mappé (dette) : opencode émet des events reasoning (thinking) que le parser ignore (Ignored). Hors périmètre de ce fix ; ticket dédié à créer si on veut afficher le thinking OpenCode.
  • Granularité honnête : opencode JSON ne donne ni deltas de tokens ni tool-start — seulement step_start/step_finish + text(finalisé) + tool_use(completed). Le fix reste honnête (pas de faux stream simulé), conforme aux critères d'acceptation sur profils pauvres.
  • Vérif live en attente : build AppImage lancé (artefact target/release/bundle/appimage/IdeA_0.3.0_amd64.AppImage). Le user doit remplacer l'AppImage installée + relancer IdeA pour valider en live (⚠️ relance = tue l'orchestrateur courant). Branche non mergée dans develop en attente de vérif live verte (Git ferait le fast-forward ensuite).
  • Frontend : aucun changement requis (CustomAgentChatView/ProgressBubble gèrent déjà Progress{Tool|Mcp} + délégations). Si le rendu live révèle un souci visuel (spinner qui ne s'arrête pas — cf. description initiale du ticket), ce sera un delta frontend ciblé.

Objectif

Améliorer la CLI custom / chat agent pour afficher un maximum de progress intermédiaires réellement disponibles au lieu d'un silence jusqu'au Final, avec une UX différenciée pour :

  • les messages/progress agent généraux
  • les appels MCP / outils
  • les délégations inter-agent

Dépendance

  • Dépend explicitement de #156, qui doit fournir le contrat d'événements canonique multi-profils.

Attentes produit

  • Afficher les événements intermédiaires au fil de l'eau quand ils existent.
  • Montrer clairement quel agent parle à quel agent.
  • Afficher un extrait court de la demande déléguée.
  • Rendre les appels MCP/outils visuellement distincts du reste du flux.
  • Fonctionner avec un maximum de profils IA, avec dégradation élégante quand un profil n'expose pas grand-chose.

Périmètre UI/UX attendu

Types visuels

  • AgentMessage : message/progress principal d'un agent.
  • Delegation : carte dédiée Agent A -> Agent B avec extrait court de la demande.
  • ToolCall : carte secondaire/indentée pour les appels d'outil.
  • MCPEvent : variante spécifique pour les appels MCP/méthodes MCP, distincte visuellement.

États

  • started
  • running
  • done
  • error

Hiérarchie visuelle

  • Les délégations et appels MCP ne doivent pas se confondre avec un simple texte agent.
  • Les appels MCP/outils doivent être lisibles mais plus discrets que le message principal.
  • Prévoir la lecture d'une conversation longue sans transformer l'écran en log brut.

Recommandations UX initiales (retour UX intégré)

  • Delegation : carte avec flèche From -> To, extrait de demande tronqué (~80 chars), accès au détail sur expansion/hover.
  • ToolCall : carte indentée avec badge outil, état spinner/check/error, args résumés/tronqués.
  • MCPEvent : bordure latérale/coloration dédiée par serveur ou type de méthode.
  • Timeline verticale légère pour relier visuellement les sous-événements au message/agent source.
  • Les événements très courts doivent être lissés/batchés pour éviter le clignotement.

Anti-bruit / garde-fous

  • Ne pas afficher comme texte brut tous les micro-événements sans hiérarchie.
  • Seuil temporel ou batching pour les événements trop fugitifs.
  • Possibilité de collapse/groupement pour tool calls répétitifs.
  • Limitation du nombre d'événements visibles avant expansion.
  • Si un profil n'expose aucun delta ni événement intermédiaire, afficher au minimum l'état occupé/vivant sans simuler un faux stream.

Critères d'acceptation

  • Sur les profils riches, l'utilisateur voit les progress/events apparaître avant le Final.
  • Sur les profils pauvres, l'UI reste honnête et utile (busy/progression minimale) sans faux "thinking".
  • Les appels MCP apparaissent au fil de l'eau, pas seulement après le Final, si l'information est disponible côté IdeA.
  • Les délégations inter-agent sont lisibles : on comprend qui parle à qui et à propos de quoi.
  • La vue reste stable et lisible sur conversation longue.