Files
IdeA/.ideai/tickets/157/carnet.md
Blomios 47bc2c4fb6 chore(tickets): sync miroir #157 (backend live vert, rouvert pour delta frontend) + #155 (rouvert inProgress)
- #157: status closed→inProgress ; description régressée au cas profil OpenCode/GLM
  (aucun progress ni bulle MCP pendant le tour) ; carnet itération 2 (cause racine
  send_with_tap + tagging MCP, correctif livré au commit 836137a3, QA backend vert
  puis validé en live sur AppImage).
- #155: status qa→inProgress (collage clipboard custom CLI toujours KO au runtime,
  requalifié fichier/image via le pipeline d'attachments existant).
- mémoire: note projet opencode-streaming-progress-mcp-surfacing-157 + index.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-10 09:30:39 +02:00

7.6 KiB
Raw Blame History

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

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

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). Les autres outils restent ProviderNative/Tool.
  • 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.