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

109 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
issueRef: "#157"
version: 16
updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"}
updatedAt: 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.