From 4db264ea8ca26bb0e6eddac20604a68a627ae4bb Mon Sep 17 00:00:00 2001 From: Blomios Date: Mon, 24 Aug 2026 09:43:20 +0200 Subject: [PATCH 1/2] =?UTF-8?q?fix(custom-cli):=20cartes=20progress/tools?= =?UTF-8?q?=20visibles=20d=C3=A8s=20la=202e=20sollicitation=20malgr=C3=A9?= =?UTF-8?q?=20la=20r=C3=A9utilisation=20du=20progressId=20=E2=80=94=20la?= =?UTF-8?q?=20cl=C3=A9=20d'upsert=20borne=20le=20progressId=20au=20scope?= =?UTF-8?q?=20du=20tour=20au=20lieu=20d'un=20d=C3=A9dup=20global=20sur=20l?= =?UTF-8?q?'historique=20=E2=80=94=20#157=20(QA=20verte)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agents/CustomAgentChatView.test.tsx | 112 ++++++++++++++++++ .../features/agents/CustomAgentChatView.tsx | 2 +- 2 files changed, 113 insertions(+), 1 deletion(-) diff --git a/frontend/src/features/agents/CustomAgentChatView.test.tsx b/frontend/src/features/agents/CustomAgentChatView.test.tsx index dce09046..458e7190 100644 --- a/frontend/src/features/agents/CustomAgentChatView.test.tsx +++ b/frontend/src/features/agents/CustomAgentChatView.test.tsx @@ -1764,6 +1764,118 @@ describe("CustomAgentChatView", () => { expect(screen.getAllByTestId("chat-tool-progress")).toHaveLength(2); }); + it("keeps second-turn progress visible when the provider reuses the same progressId across turns", async () => { + const harness = createStreamingAgentHarness(); + + render( + null) }, + } as unknown as Gateways} + > + + , + ); + + await waitFor(() => + expect(harness.agent.reattachAgentChat).toHaveBeenCalledWith( + "chat-session-1", + expect.any(Function), + ), + ); + + fireEvent.change(screen.getByLabelText(/message CLI custom/), { + target: { value: "first request" }, + }); + fireEvent.click(screen.getByRole("button", { name: "Envoyer" })); + await waitFor(() => expect(harness.emitterCount()).toBe(1)); + + act(() => { + harness.emit(0, { + kind: "progress", + progress: { + progressId: "codex:item:call_1", + source: "providerNative", + kind: "tool", + stage: "started", + label: "shell", + toolName: "shell", + text: "Running first request", + }, + }); + harness.emit(0, { + kind: "progress", + progress: { + progressId: "codex:item:call_1", + source: "providerNative", + kind: "tool", + stage: "completed", + label: "shell", + toolName: "shell", + text: "Done first request", + }, + }); + harness.emit(0, { kind: "final", content: "done first request" }); + }); + await screen.findByText("done first request"); + + fireEvent.change(screen.getByLabelText(/message CLI custom/), { + target: { value: "second request" }, + }); + fireEvent.click(screen.getByRole("button", { name: "Envoyer" })); + await waitFor(() => expect(harness.emitterCount()).toBe(2)); + + act(() => { + harness.emit(1, { + kind: "progress", + progress: { + progressId: "codex:item:call_1", + source: "providerNative", + kind: "tool", + stage: "started", + label: "shell", + toolName: "shell", + text: "Running second request", + }, + }); + }); + + expect(screen.getByText("Running second request")).toBeTruthy(); + + act(() => { + harness.emit(1, { + kind: "progress", + progress: { + progressId: "codex:item:call_1", + source: "providerNative", + kind: "tool", + stage: "completed", + label: "shell", + toolName: "shell", + text: "Done second request", + }, + }); + harness.emit(1, { kind: "final", content: "done second request" }); + }); + + await screen.findByText("done second request"); + expect(screen.getByText("Done first request")).toBeTruthy(); + expect(screen.getByText("Done second request")).toBeTruthy(); + expect(screen.getAllByTestId("chat-tool-progress")).toHaveLength(2); + }); + it("ignores a late first-turn progress chunk but still shows the real second-turn progress from the next callback", async () => { const harness = createStreamingAgentHarness(); diff --git a/frontend/src/features/agents/CustomAgentChatView.tsx b/frontend/src/features/agents/CustomAgentChatView.tsx index dc80bb9d..c7a0529b 100644 --- a/frontend/src/features/agents/CustomAgentChatView.tsx +++ b/frontend/src/features/agents/CustomAgentChatView.tsx @@ -325,7 +325,7 @@ function progressKey(progress: ReplyProgress): string { function progressUpsertKey(progress: ReplyProgress, scope: number): string { const progressId = progress.progressId?.trim(); - if (progressId) return progressId; + if (progressId) return `progress:${scope}:${progressId}`; return `legacy:${scope}:${progressDisplayKey(progress)}`; } From 6b57addd4ecf66b611562d3dc65d2528a866694f Mon Sep 17 00:00:00 2001 From: Blomios Date: Mon, 24 Aug 2026 09:43:26 +0200 Subject: [PATCH 2/2] =?UTF-8?q?chore(tickets):=20synchro=20du=20store=20lo?= =?UTF-8?q?cal=20=E2=80=94=20carnet=20#157=20it=C3=A9ration=205=20(r=C3=A9?= =?UTF-8?q?gression=20progressId=20r=C3=A9utilis=C3=A9,=20QA=20verte)=20+?= =?UTF-8?q?=20reliquat=20cl=C3=B4ture=20#253?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .ideai/tickets/157/carnet.md | 40 ++++++++++++++++++++++++++++++++++-- .ideai/tickets/157/issue.md | 6 +++--- .ideai/tickets/253/carnet.md | 18 +++++++++++++--- .ideai/tickets/253/issue.md | 8 ++++---- .ideai/tickets/index.json | 8 ++++---- 5 files changed, 64 insertions(+), 16 deletions(-) diff --git a/.ideai/tickets/157/carnet.md b/.ideai/tickets/157/carnet.md index 4357fe7c..be0e2e14 100644 --- a/.ideai/tickets/157/carnet.md +++ b/.ideai/tickets/157/carnet.md @@ -1,11 +1,47 @@ --- issueRef: "#157" -version: 19 +version: 21 updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"} -updatedAt: 1786380032724 +updatedAt: 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 `progressId` identique 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 diff --git a/.ideai/tickets/157/issue.md b/.ideai/tickets/157/issue.md index e61a0d80..216437f9 100644 --- a/.ideai/tickets/157/issue.md +++ b/.ideai/tickets/157/issue.md @@ -2,7 +2,7 @@ id: "d49aaae5-0d03-43fe-a51c-2ab5e921045c" number: 157 title: "CLI custom: surface all available agent progress, MCP activity, and inter-agent delegation flow" -status: "qa" +status: "inProgress" priority: "high" sprint: null links: [{"target":"#156","kind":"dependsOn"}] @@ -11,7 +11,7 @@ attachments: [] createdBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"} updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"} createdAt: 1785965383914 -updatedAt: 1786380032724 -version: 19 +updatedAt: 1787556963342 +version: 21 --- Régression/remontée utilisateur (profil OpenCode/GLM) sur la CLI custom : aucun message de progress ne s'affiche pendant le traitement de l'agent, et aucune bulle/carte d'appel de tool MCP n'apparaît quand l'agent invoque un outil MCP. Périmètre initial (surfacer progress + activité MCP + délégations inter-agent) à valider à nouveau sur le profil OpenCode. \ No newline at end of file diff --git a/.ideai/tickets/253/carnet.md b/.ideai/tickets/253/carnet.md index b3c22ce6..9f56cceb 100644 --- a/.ideai/tickets/253/carnet.md +++ b/.ideai/tickets/253/carnet.md @@ -1,8 +1,8 @@ --- issueRef: "#253" -version: 2 -updatedBy: {"kind":"agent","agent_id":"1ff94b51-3e17-4a39-8543-7715d1ff0f80"} -updatedAt: 1787551753848 +version: 4 +updatedBy: {"kind":"agent","agent_id":"a6c6ea12-bfc6-4bdc-8031-324102dfa34d"} +updatedAt: 1787552434207 --- # Git — décision de branche (2026-08-24) @@ -12,3 +12,15 @@ updatedAt: 1787551753848 - Interdits : aucun push distant ; pas de merge/rebase vers `develop` sans l'agent Git. Fusion locale décidée par Git après QA verte. - `scripts/restart-idea-over-ssh.sh` reste non suivi — ne pas le committer. - Contexte : symptômes initiaux documentés dans le carnet #252 (section « Signalement QA » du 2026-08-24). + +# Git — commits, merge et tag de build (2026-08-24, QA verte vérifiée) + +Commits sur `fix/253-opencode-tests-parallel-flakiness` : +- `cd70a3c` test(opencode): fiabilisation de la suite en parallèle — écriture atomique des fixtures, gates par fichier au lieu de sleep, runtime dédié par test, timeout 5s — #253 (QA verte) +- `c05b671` chore(tickets): synchro du store local — carnet et statut #253 + +Merge local : **effectué** — `d9af4b5` merge(opencode) `--no-ff` dans `develop`. + +Tag de build AppImage : **`v0.33.0`** (annoté) sur le commit de merge `d9af4b5` — build sur `develop` → incrément de `y` (dernier tag `v0.32.0`). **Branche finale de build : `develop` @ `d9af4b5`.** Aucun push (branche, tag, tout reste local). + +Re-vérification indépendante par Git avant merge : 3 runs parallèles + 1 run sériel (`--test-threads=1`) de `cargo test -p infrastructure session::opencode` → 21 passed partout ; durée de la suite passée de ~1 s à ~0,06 s (suppression des `sleep` au profit de gates par fichier). Stratégie retenue (par DevBackend, validée par Git) : écriture atomique des scripts fixtures (tmp+fsync+rename), synchronisation déterministe par fichier de release au lieu de `sleep`, exécution des fixtures via `sh