fix(custom-cli): cartes progress/tools visibles dès la 2e sollicitation malgré la réutilisation du progressId — la clé d'upsert borne le progressId au scope du tour au lieu d'un dédup global sur l'historique — #157 (QA verte)
This commit is contained in:
@ -1764,6 +1764,118 @@ describe("CustomAgentChatView", () => {
|
|||||||
expect(screen.getAllByTestId("chat-tool-progress")).toHaveLength(2);
|
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(
|
||||||
|
<DIProvider
|
||||||
|
gateways={{
|
||||||
|
agent: harness.agent,
|
||||||
|
system: { pickFile: vi.fn(async () => null) },
|
||||||
|
} as unknown as Gateways}
|
||||||
|
>
|
||||||
|
<CustomAgentChatView
|
||||||
|
projectId="project-1"
|
||||||
|
agentId="agent-1"
|
||||||
|
agentName="Worker"
|
||||||
|
profile={profile}
|
||||||
|
cwd="/repo"
|
||||||
|
nodeId="node-1"
|
||||||
|
sessionId="chat-session-1"
|
||||||
|
conversationId="conversation-1"
|
||||||
|
onSessionId={vi.fn()}
|
||||||
|
onConversationId={vi.fn()}
|
||||||
|
/>
|
||||||
|
</DIProvider>,
|
||||||
|
);
|
||||||
|
|
||||||
|
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 () => {
|
it("ignores a late first-turn progress chunk but still shows the real second-turn progress from the next callback", async () => {
|
||||||
const harness = createStreamingAgentHarness();
|
const harness = createStreamingAgentHarness();
|
||||||
|
|
||||||
|
|||||||
@ -325,7 +325,7 @@ function progressKey(progress: ReplyProgress): string {
|
|||||||
|
|
||||||
function progressUpsertKey(progress: ReplyProgress, scope: number): string {
|
function progressUpsertKey(progress: ReplyProgress, scope: number): string {
|
||||||
const progressId = progress.progressId?.trim();
|
const progressId = progress.progressId?.trim();
|
||||||
if (progressId) return progressId;
|
if (progressId) return `progress:${scope}:${progressId}`;
|
||||||
return `legacy:${scope}:${progressDisplayKey(progress)}`;
|
return `legacy:${scope}:${progressDisplayKey(progress)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user