fix(tui): clear pinned output on message_end to prevent duplicate display
The pinned "Latest Output" zone was only cleared at agent_end, but during flows with form elicitation (e.g. discuss-phase), there is a gap between message_end and agent_end where the agent waits for user input. During this gap, the same content was visible in both the chat history and the pinned zone. Clear the pinned zone at message_end when the assistant message is finalized in the chat container.
This commit is contained in:
parent
65c42ba6dc
commit
b488961609
2 changed files with 59 additions and 0 deletions
|
|
@ -386,6 +386,56 @@ test("chat-controller clears pinned zone when the agent turn ends", async () =>
|
|||
assert.equal(host.pinnedMessageContainer.children.length, 0, "pinned zone should clear on agent_end");
|
||||
});
|
||||
|
||||
test("chat-controller clears pinned zone when assistant message ends", async () => {
|
||||
(globalThis as any)[Symbol.for("@gsd/pi-coding-agent:theme")] = {
|
||||
fg: (_key: string, text: string) => text,
|
||||
bg: (_key: string, text: string) => text,
|
||||
bold: (text: string) => text,
|
||||
italic: (text: string) => text,
|
||||
truncate: (text: string) => text,
|
||||
};
|
||||
|
||||
const host = createHost();
|
||||
const toolCall = {
|
||||
type: "toolCall",
|
||||
id: "tool-msg-end-1",
|
||||
name: "exec_command",
|
||||
arguments: { cmd: "echo hi" },
|
||||
};
|
||||
|
||||
await handleAgentEvent(host, { type: "message_start", message: makeAssistant([]) } as any);
|
||||
|
||||
host.getMarkdownThemeWithSettings = () => ({});
|
||||
const msgContent = [{ type: "text", text: "Summary after tools." }, toolCall];
|
||||
await handleAgentEvent(
|
||||
host,
|
||||
{
|
||||
type: "message_update",
|
||||
message: makeAssistant(msgContent),
|
||||
assistantMessageEvent: {
|
||||
type: "toolcall_end",
|
||||
contentIndex: 1,
|
||||
toolCall: {
|
||||
...toolCall,
|
||||
externalResult: {
|
||||
content: [{ type: "text", text: "ok" }],
|
||||
details: {},
|
||||
isError: false,
|
||||
},
|
||||
},
|
||||
partial: makeAssistant(msgContent),
|
||||
},
|
||||
} as any,
|
||||
);
|
||||
|
||||
assert.ok(host.pinnedMessageContainer.children.length > 0, "pinned zone should be populated during streaming");
|
||||
|
||||
// End the assistant message (e.g. before form elicitation) — pinned zone should clear
|
||||
await handleAgentEvent(host, { type: "message_end", message: makeAssistant(msgContent) } as any);
|
||||
|
||||
assert.equal(host.pinnedMessageContainer.children.length, 0, "pinned zone should clear on message_end to prevent duplicate display");
|
||||
});
|
||||
|
||||
test("chat-controller does not pin when there are no tool calls", async () => {
|
||||
(globalThis as any)[Symbol.for("@gsd/pi-coding-agent:theme")] = {
|
||||
fg: (_key: string, text: string) => text,
|
||||
|
|
|
|||
|
|
@ -380,6 +380,15 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
|
|||
}
|
||||
host.streamingComponent = undefined;
|
||||
host.streamingMessage = undefined;
|
||||
// Clear pinned output once the message is finalized in the chat
|
||||
// container — prevents duplicate display when the agent continues
|
||||
// (e.g. form elicitation) after the assistant message ends.
|
||||
if (pinnedBorder) pinnedBorder.stopSpinner();
|
||||
host.pinnedMessageContainer.clear();
|
||||
lastPinnedText = "";
|
||||
hasToolsInTurn = false;
|
||||
pinnedBorder = undefined;
|
||||
pinnedTextComponent = undefined;
|
||||
host.footer.invalidate();
|
||||
}
|
||||
host.ui.requestRender();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue