From 88a5256a1e051e50c224f75dc25e7921d82b622a Mon Sep 17 00:00:00 2001 From: Blomios Date: Mon, 27 Jul 2026 16:49:22 +0200 Subject: [PATCH] =?UTF-8?q?feat(rendezvous):=20libell=C3=A9=20explicite=20?= =?UTF-8?q?des=20notifications=20de=20fin=20de=20background=20task=20(#91)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le toast de fin de tâche de fond liée à un rendez-vous inter-agent passe de « Main -> DevBackend completed » à « Appel Main -> DevBackend terminé » (idem en échec / annulé), pour nommer explicitement l'appel plutôt qu'un état brut. Fallback générique conservé quand requester/target sont absents. Validations obtenues avant commit : tests frontend annoncés verts pour #91. Co-Authored-By: Claude Sonnet 5 --- .../projects/ProjectsView.ls7.test.tsx | 51 ++++++++++++++++++- .../src/features/projects/ProjectsView.tsx | 16 +++++- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/frontend/src/features/projects/ProjectsView.ls7.test.tsx b/frontend/src/features/projects/ProjectsView.ls7.test.tsx index 9965b22..e63cbf5 100644 --- a/frontend/src/features/projects/ProjectsView.ls7.test.tsx +++ b/frontend/src/features/projects/ProjectsView.ls7.test.tsx @@ -266,7 +266,7 @@ describe("ProjectsView — LS7 conversation viewer integration", () => { }); const toast = await screen.findByRole("button", { - name: /Main -> DevBackend completed/i, + name: /Appel Main -> DevBackend terminé/i, }); expect(within(toast).getByText("Task task-ren")).toBeTruthy(); @@ -277,10 +277,57 @@ describe("ProjectsView — LS7 conversation viewer integration", () => { ).toBeTruthy(); expect(await screen.findByText("contenu du fil ouvert")).toBeTruthy(); expect( - screen.queryByRole("button", { name: /Main -> DevBackend completed/i }), + screen.queryByRole("button", { name: /Appel Main -> DevBackend terminé/i }), ).toBeNull(); }); + it("labels rendezvous failure and cancellation toasts with explicit call attribution", async () => { + const project = new MockProjectGateway(); + const created = await project.createProject("alpha", "/p/a"); + const agent = new MockAgentGateway(); + const system = new MockSystemGateway(); + const requester = await agent.createAgent(created.id, { + name: "Main", + profileId: "codex", + }); + const target = await agent.createAgent(created.id, { + name: "DevBackend", + profileId: "codex", + }); + renderView(project, { agent, system }); + + await openProjectAndWorkTab("/p/a"); + system.emit({ + type: "backgroundTaskChanged", + projectId: created.id, + agentId: target.id, + taskId: "task-rendezvous-failed", + state: "failed", + requesterAgentId: requester.id, + targetAgentId: target.id, + }); + system.emit({ + type: "backgroundTaskChanged", + projectId: created.id, + agentId: target.id, + taskId: "task-rendezvous-cancelled", + state: "cancelled", + requesterAgentId: requester.id, + targetAgentId: target.id, + }); + + expect( + await screen.findByRole("button", { + name: /Appel Main -> DevBackend en échec/i, + }), + ).toBeTruthy(); + expect( + await screen.findByRole("button", { + name: /Appel Main -> DevBackend annulé/i, + }), + ).toBeTruthy(); + }); + it("keeps the generic background-task toast when rendezvous agent ids are absent", async () => { const project = new MockProjectGateway(); const created = await project.createProject("alpha", "/p/a"); diff --git a/frontend/src/features/projects/ProjectsView.tsx b/frontend/src/features/projects/ProjectsView.tsx index 8ac1f08..c7bace0 100644 --- a/frontend/src/features/projects/ProjectsView.tsx +++ b/frontend/src/features/projects/ProjectsView.tsx @@ -135,6 +135,20 @@ function agentLabel(agents: Agent[], agentId: string): string { ); } +function rendezvousToastStateLabel(state: string): string { + switch (state) { + case "completed": + case "delivered": + return "terminé"; + case "failed": + return "en échec"; + case "cancelled": + return "annulé"; + default: + return state; + } +} + export function ProjectsView() { const vm = useProjects(); const { @@ -274,7 +288,7 @@ export function ProjectsView() { taskId: event.taskId, state: event.state, title: labels - ? `${labels.requester} -> ${labels.target} ${event.state}` + ? `Appel ${labels.requester} -> ${labels.target} ${rendezvousToastStateLabel(event.state)}` : `Background task ${event.state}`, subtitle: labels ? `Task ${shortTaskId(event.taskId)}`