fix(app): hide turn actions during active tool calls

Tool rows can arrive before a running turn resumes text. Treat those rows as part of the active turn so copy/fork actions wait until the turn closes.
This commit is contained in:
Mohamed Boudra
2026-06-29 22:14:34 +02:00
parent cf2fccd01d
commit 86775c18f3
2 changed files with 33 additions and 0 deletions

View File

@@ -352,4 +352,22 @@ describe("layoutStream", () => {
expect(footerOwners(layout)).toEqual([assistant.id]);
},
);
it.each(["web", "android"] as const)(
"does not render a completed footer before tool rows while the turn is running on %s",
(platform) => {
const assistant = assistantMessage("a1", 2);
const tool = toolCall("tool-1", 3);
const layout = layoutFor({
platform,
agentStatus: "running",
tail: [userMessage("u1", 1), assistant, tool],
timingIds: [assistant.id],
});
expect(layout.auxiliaryTurnFooter).toBeNull();
expect(findLayoutItem(layout, assistant.id).completedFooter).toBeNull();
expect(footerOwners(layout)).toEqual([]);
},
);
});

View File

@@ -150,6 +150,8 @@ function shouldRenderCompletedFooter(input: {
belowItem: StreamItem | null;
agentStatus: string;
auxiliaryTurnFooter: TurnFooterHost | null;
boundaryIndex: number | null;
boundaryBelowItem: StreamItem | null;
}): boolean {
if (
input.item.kind !== "assistant_message" ||
@@ -179,6 +181,17 @@ function shouldRenderCompletedFooter(input: {
items: input.items,
startIndex: input.index,
});
const belowTurnItem = getSegmentNeighbor({
strategy: input.strategy,
items: input.items,
index: turnEndIndex,
relation: "below",
boundaryIndex: input.boundaryIndex,
boundaryItem: input.boundaryBelowItem,
});
if (input.agentStatus === "running" && belowTurnItem?.kind !== "user_message") {
return false;
}
const assistantIndex = findLatestAssistantIndexInTurn({
strategy: input.strategy,
items: input.items,
@@ -265,6 +278,8 @@ function layoutSegment(input: LayoutSegmentInput): StreamLayoutItem[] {
belowItem,
agentStatus: input.agentStatus,
auxiliaryTurnFooter: input.auxiliaryTurnFooter,
boundaryIndex: input.boundaryIndex,
boundaryBelowItem: input.boundaryBelowItem,
})
? createTurnFooterHost({
item,