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:
@@ -352,4 +352,22 @@ describe("layoutStream", () => {
|
|||||||
expect(footerOwners(layout)).toEqual([assistant.id]);
|
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([]);
|
||||||
|
},
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -150,6 +150,8 @@ function shouldRenderCompletedFooter(input: {
|
|||||||
belowItem: StreamItem | null;
|
belowItem: StreamItem | null;
|
||||||
agentStatus: string;
|
agentStatus: string;
|
||||||
auxiliaryTurnFooter: TurnFooterHost | null;
|
auxiliaryTurnFooter: TurnFooterHost | null;
|
||||||
|
boundaryIndex: number | null;
|
||||||
|
boundaryBelowItem: StreamItem | null;
|
||||||
}): boolean {
|
}): boolean {
|
||||||
if (
|
if (
|
||||||
input.item.kind !== "assistant_message" ||
|
input.item.kind !== "assistant_message" ||
|
||||||
@@ -179,6 +181,17 @@ function shouldRenderCompletedFooter(input: {
|
|||||||
items: input.items,
|
items: input.items,
|
||||||
startIndex: input.index,
|
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({
|
const assistantIndex = findLatestAssistantIndexInTurn({
|
||||||
strategy: input.strategy,
|
strategy: input.strategy,
|
||||||
items: input.items,
|
items: input.items,
|
||||||
@@ -265,6 +278,8 @@ function layoutSegment(input: LayoutSegmentInput): StreamLayoutItem[] {
|
|||||||
belowItem,
|
belowItem,
|
||||||
agentStatus: input.agentStatus,
|
agentStatus: input.agentStatus,
|
||||||
auxiliaryTurnFooter: input.auxiliaryTurnFooter,
|
auxiliaryTurnFooter: input.auxiliaryTurnFooter,
|
||||||
|
boundaryIndex: input.boundaryIndex,
|
||||||
|
boundaryBelowItem: input.boundaryBelowItem,
|
||||||
})
|
})
|
||||||
? createTurnFooterHost({
|
? createTurnFooterHost({
|
||||||
item,
|
item,
|
||||||
|
|||||||
Reference in New Issue
Block a user