16 KiB
issueRef, version, updatedBy, updatedAt
| issueRef | version | updatedBy | updatedAt | ||||
|---|---|---|---|---|---|---|---|
| #157 | 21 |
|
1787556963342 |
Journal d'itération (le plus récent en haut)
Itération 5 — 2026-08-24 — Réouverture ciblée sur régression 2e sollicitation / progressId réutilisé entre tours
Nouveau signal utilisateur
Dans la custom CLI, à partir de la seconde sollicitation sur une même conversation, les messages progress et l'activité tools ne s'affichent plus comme une nouvelle activité de tour.
Repro QA validée
QA a trouvé une repro automatisée fiable dans frontend/src/features/agents/CustomAgentChatView.test.tsx.
- scénario minimal: 2 requêtes successives dans la même conversation
- le provider réémet un
progressIdidentique entre les 2 tours (ex.codex:item:call_1) - résultat actuel: la carte du 2e tour remplace/écrase celle du 1er au lieu de créer une nouvelle activité
Preuve rouge actuelle
Commande QA:
cd /home/anthony/Documents/Projects/IdeA/frontend && npm test -- --run src/features/agents/CustomAgentChatView.test.tsx -t "keeps second-turn progress visible when the provider reuses the same progressId across turns"
Verdict actuel: ROUGE.
Hypothèse active
Le point suspect principal est le dédoublonnage global par progressId dans CustomAgentChatView.tsx, alors que l'identité visuelle attendue doit rester bornée au tour/callback courant et non à tout l'historique de conversation.
Cycle relancé
- UX: valider l'attendu visuel/fonctionnel sur la conservation des cartes de tours successifs.
- Architect: cadrer la règle d'identité/dédoublonnage côté surface.
- Git: décider de la branche locale de correction.
- DevFrontend: implémenter le fix avec le test QA rouge comme garde-fou.
- QA: rejouer la repro puis la suite ciblée; si rouge, reboucler.
Itération 4 — 2026-08-10 — Correctif livré, QA verte ciblée, merge local sur develop, attente de validation AppImage live
Diagnostic final du cycle
Le problème utilisateur n'était pas uniquement frontend.
- Backend Codex : un
agent_messaged'intention avantidea_ask_agentpouvait être traité comme faux candidatFinalet ne pas être projeté live. De plus, le parser/session Codex émettait à la fois unProgresscanonique et unToolActivityde compatibilité pour certains événements tool/MCP (conversation.item.added/conversation.item.done), ce qui créait déjà une duplication en amont de l'UI. - Frontend custom CLI : la réconciliation des cartes de progress ne dédupliquait pas au niveau de l'entité visuelle métier. Le même
idea_ask_agentpouvait donc produire deux cartes distinctes (Provider toolpuisDélégation) au lieu d'une seule cartestartet d'une seule cartedone.
Correctifs réalisés
Backend (#171 transverse, impact direct sur #157)
- Reclassification d'un
agent_messagepré-MCP enAnnouncementdès qu'un événement ultérieur prouve que le tour continue, au lieu de l'avaler comme candidatFinal. - Suppression de l'émission doublon
ToolActivityquand unReplyEvent::Progresscanonique existe déjà pour l'événement Codex/MCP concerné. - Fichiers:
crates/infrastructure/src/session/codex.rs,crates/infrastructure/src/session/mod.rs.
Frontend (#157)
- Déduplication par entité visuelle métier: même délégation/tool + même bucket
startedoucompleted= une seule carte. idea_ask_agent/idea_ask_agentstoujours rendus comme délégation, même si le provider les remonte commeproviderNative/tool.- Le
Finalne crée pas une deuxième cartedone; il termine simplement l'état en cours quand approprié. - Fichiers:
frontend/src/features/agents/CustomAgentChatView.tsx,frontend/src/features/agents/CustomAgentChatView.test.tsx.
Preuves de test / QA
QA a rejoué et validé les commandes suivantes:
CARGO_HOME=/tmp/idea-cargo-home cargo test -p infrastructure codex -- --nocapture→ 41 passedCARGO_HOME=/tmp/idea-cargo-home cargo test -p app-tauri --test chat_bridge -- --nocapture→ 25 passedcd frontend && npx vitest run src/features/agents/CustomAgentChatView.test.tsx→ 26 passed testscd frontend && npx vitest run→ 1133 passed testscd frontend && ./node_modules/.bin/tsc --noEmit --pretty false→ exit 0
Verdict QA: vert sur le scope tickets #157 + #171.
Git / intégration locale
- Commit backend:
d6306bb5—fix(codex): intention pré-MCP reclassée en Announcement + doublon ToolActivity supprimé (#157 #171) - Commit frontend:
9fe87a86—fix(cli): déduplication métier des cartes progress + délégations rendues une fois (#157 #171) - Commit miroir tickets:
1beeed8c—chore(tickets): sync miroir #157 #171 — QA verte ciblée (AppImage en attente) - Merge local vers
develop:fa613674—merge(codex/cli): cycle #157 #171 — dedup cartes tool/MCP + intention pré-MCP live
Réserve explicite avant fermeture définitive
- Pas encore de preuve E2E/AppImage live sur le binaire utilisateur final.
- Un rouge Rust global subsiste mais est préexistant et hors scope:
crates/infrastructure/tests/mcp_server.rs:777attend 37 tools alors que le catalogue en expose 38 (idea_context_updateen plus).
Statut décidé
- Ticket laissé en QA et non fermé, dans l'attente d'une validation live AppImage par l'utilisateur.
- Si le live confirme: le ticket pourra être fermé sans nouveau cycle de correction.
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 duFinal. - #167 reste fermé : le bug historique traité sur l'ordre
events after Finaln'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 :
- problème frontend de réconciliation/rendu (dédoublonnage des cartes
start/done), et/ou - défaut de projection live UI de certains
ReplyChunk::Progressen amont du premier appel MCP.
- problème frontend de réconciliation/rendu (dédoublonnage des cartes
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 cartestartet une cartedonepertinentes, 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 :
OpenCodeSessionne surchargeait passend_with_tap(défautdomain/ports.rs:1380ignore le tap). Sonsendbufferisait 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.- La bulle
kind:Mcp/source:IdeaLocaln'était émise que paropenai_compat.rs::apply_tool_calls(où IdeA orchestre les outils). Pour OpenCode, les outils tournent dans opencode ; lestool_useétaient taggéskind:Toolgé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_tapoverride (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_usepré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_service39 hangs/spawn) reproduisent à l'identique sur la basea3d94d4d→ 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. reasoningnon mappé (dette) : opencode émet des eventsreasoning(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 dansdevelopen attente de vérif live verte (Git ferait le fast-forward ensuite). - Frontend : aucun changement requis (
CustomAgentChatView/ProgressBubblegè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éeAgent A -> Agent Bavec 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
startedrunningdoneerror
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ècheFrom -> 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.