diff --git a/packages/coding-agent/src/modes/utils/ui-helpers.ts b/packages/coding-agent/src/modes/utils/ui-helpers.ts index 906590ebd..632095fa8 100644 --- a/packages/coding-agent/src/modes/utils/ui-helpers.ts +++ b/packages/coding-agent/src/modes/utils/ui-helpers.ts @@ -209,6 +209,7 @@ export class UiHelpers { sessionContext: SessionContext, options: { updateFooter?: boolean; populateHistory?: boolean } = {}, ): void { + this.ctx.optimisticUserMessageSignature = undefined; this.ctx.pendingTools.clear(); if (options.updateFooter) { diff --git a/packages/coding-agent/test/interactive-mode-status.test.ts b/packages/coding-agent/test/interactive-mode-status.test.ts index 7de45651b..82a75cd04 100644 --- a/packages/coding-agent/test/interactive-mode-status.test.ts +++ b/packages/coding-agent/test/interactive-mode-status.test.ts @@ -1,5 +1,6 @@ import { beforeAll, describe, expect, test, vi } from "bun:test"; import { initTheme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme"; +import type { InteractiveModeContext } from "@oh-my-pi/pi-coding-agent/modes/types"; import { UiHelpers } from "@oh-my-pi/pi-coding-agent/modes/utils/ui-helpers"; import { Container } from "@oh-my-pi/pi-tui"; @@ -16,13 +17,13 @@ describe("InteractiveMode.showStatus", () => { }); test("coalesces immediately-sequential status messages", () => { - const ctx: any = { + const ctx = { chatContainer: new Container(), ui: { requestRender: vi.fn() }, isBackgrounded: false, lastStatusSpacer: undefined, lastStatusText: undefined, - }; + } as unknown as InteractiveModeContext; const helpers = new UiHelpers(ctx); helpers.showStatus("STATUS_ONE"); @@ -37,13 +38,13 @@ describe("InteractiveMode.showStatus", () => { }); test("appends a new status line if something else was added in between", () => { - const ctx: any = { + const ctx = { chatContainer: new Container(), ui: { requestRender: vi.fn() }, isBackgrounded: false, lastStatusSpacer: undefined, lastStatusText: undefined, - }; + } as unknown as InteractiveModeContext; const helpers = new UiHelpers(ctx); helpers.showStatus("STATUS_ONE"); @@ -58,4 +59,18 @@ describe("InteractiveMode.showStatus", () => { expect(ctx.chatContainer.children).toHaveLength(5); expect(renderLastLine(ctx.chatContainer)).toContain("STATUS_TWO"); }); + + test("clears stale optimistic user signatures when rebuilding transcript state", () => { + const ctx = { + chatContainer: new Container(), + pendingTools: new Map(), + ui: { requestRender: vi.fn() }, + optimisticUserMessageSignature: "hello\u00001", + } as unknown as InteractiveModeContext; + const helpers = new UiHelpers(ctx); + + helpers.renderSessionContext({ messages: [], entries: [] }); + + expect(ctx.optimisticUserMessageSignature).toBeUndefined(); + }); });