- #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>
3.4 KiB
name, description, metadata
| name | description | metadata | ||
|---|---|---|---|---|
| opencode-streaming-progress-mcp-surfacing-157 | memory note opencode-streaming-progress-mcp-surfacing-157 |
|
OpenCode (CLI custom) — streaming progress & bulle MCP
Décision/fix du ticket #157 (itération 2, 2026-08-09). Profil OpenCode/GLM sur la CLI custom.
Cause racine (vérifiée en source)
opencode run --format json (v1.17.18, packages/opencode/src/cli/cmd/run.ts) émet chaque event JSONL en temps réel sur stdout. Schéma ligne : {type, timestamp, sessionID, ...data}. Types : step_start, step_finish, text (part textuelle finalisée sous .part.text, pas un delta token), tool_use (seulement à part.state.status=completed|error, pas de start ; nom outil sous .part.tool), reasoning (thinking), error.
Le parser IdeA crates/infrastructure/src/session/opencode.rs::parse_jsonl_record reconnaît déjà ces types — il n'était pas cassé. Les 2 vraies causes :
OpenCodeSessionne surchargeait passend_with_tap(défautdomain/ports.rs:1380ignore le tap) →sendbufferisait tout le stdout jusqu'à l'EOF → silence total pendant le tour, burst à la fin.- La bulle
kind:Mcp/source:IdeaLocaln'était émise que paropenai_compat.rs::apply_tool_calls. OpenCode taggait lestool_useenkind:Toolgénérique.
Fix (backend-only, commit 836137a3, branche fix/ticket157-opencode-progress-mcp-surfacing)
- Override
send_with_tapsurOpenCodeSession(pattern codex.rs/claude.rs) : stdout ligne par ligne, projection live au tap des non-terminaux, Final assemblé à la fin (jamais au tap). - Tagging MCP :
tool_usepréfixéidea_→ReplyProgress{source:IdeaLocal, kind:Mcp, stage:Completed, tool_name}(remplace la Progress Tool provider-native). - Protection replay : session continuée = premier messageID tamponné puis supprimé si un nouveau arrive.
Règles durables pour les prochains travaux
- Tout adapter
AgentSessionqui peut streamer DOIT surchargersend_with_tap(le défaut ignore le tap). Sans override, la CLI custom est muette jusqu'au Final. codex/claude/openai_compat l'ont ; OpenCode maintenant aussi. - Bulle MCP dédiée : n'existe que quand IdeA sait que l'outil est un outil MCP IdeA. Pour les profils provider-orchestrés (OpenCode/Codex/Claude), les outils tournent DANS le provider ; IdeA ne peut les tagger Mcp que heuristiquement (préfixe
idea_). Pour openai_compat (IdeA orchestre), c'est natif (IdeaLocal/Mcp). - opencode JSON est granulaire et honnête : pas de deltas de tokens ni de tool-start. Ne pas simuler de faux stream. step_start/step_finish + text(finalisé) + tool_use(completed) = le maximum exposé.
- Dette : events
reasoning(thinking) d'OpenCode ignorés par le parser (Ignored). Ticket dédié à créer si on veut afficher le thinking. - Réserve replay : session continuée à messageID unique sans replay observable → tap muet jusqu'à l'EOF (
hold_until_new_message) pour éviter un historique non rétractable. Cas frais = streaming immédiat.
Validation
cargo test -p infrastructure session::opencode = 20 passed (3 nouveaux tests streaming/mcp/replay). QA VERT, pas de régression (échecs larges mcp_server/orchestrator pré-existants sur base a3d94d4d). Vérif live user en attente (AppImage rebuild target/release/bundle/appimage/IdeA_0.3.0_amd64.AppImage). Branche non mergée dans develop en attente du live vert.