From 22917bc9433b0ef8faa77ef542fb6b53755e3986 Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Fri, 25 Sep 2026 02:05:25 +0800 Subject: [PATCH] fix(agent): hide chat overlays until agent is ready --- .../agent/__tests__/dao_chat_view.test.ts | 20 +++++++++++++++++++ .../ui/webui/resources/agent/dao_chat_view.ts | 15 +++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/dao/browser/ui/webui/resources/agent/__tests__/dao_chat_view.test.ts b/src/dao/browser/ui/webui/resources/agent/__tests__/dao_chat_view.test.ts index ec5e0788..1c52f17d 100644 --- a/src/dao/browser/ui/webui/resources/agent/__tests__/dao_chat_view.test.ts +++ b/src/dao/browser/ui/webui/resources/agent/__tests__/dao_chat_view.test.ts @@ -1817,6 +1817,26 @@ describe('dao-chat-view element picker', () => { expect(screenshotButton?.nextElementSibling).toBe(sendButton); }); + it('hides the empty guide and chip row until the panel has an agent', + async () => { + const view = document.createElement('dao-chat-view') as HTMLElement & { + render: () => unknown; + }; + const before = templateText(view.render()); + expect(before).not.toContain('class="dao-empty-guide"'); + expect(before).not.toContain('class="dao-page-chip-row"'); + + const {view: mounted} = await mountChatViewWithSend(vi.fn()); + try { + const after = templateText( + (mounted as unknown as {render: () => unknown}).render()); + expect(after).toContain('class="dao-empty-guide"'); + expect(after).toContain('class="dao-page-chip-row"'); + } finally { + clearTabWatchTimer(mounted); + } + }); + it('sends only the element screenshot image attachment', async () => { const originalSend = vi.fn(async () => 'sent'); const {view, iface} = await mountChatViewWithSend(originalSend); diff --git a/src/dao/browser/ui/webui/resources/agent/dao_chat_view.ts b/src/dao/browser/ui/webui/resources/agent/dao_chat_view.ts index 346d27ef..7e96863f 100644 --- a/src/dao/browser/ui/webui/resources/agent/dao_chat_view.ts +++ b/src/dao/browser/ui/webui/resources/agent/dao_chat_view.ts @@ -313,6 +313,7 @@ export class DaoChatView extends CrLitElement { dreamReport_: {type: Object, state: true}, proactiveSuggestion_: {type: Object, state: true}, proactiveRunning_: {type: Boolean, state: true}, + agentReady_: {type: Boolean, state: true}, }; } @@ -351,6 +352,7 @@ export class DaoChatView extends CrLitElement { this.proactiveSuggestion_ = null; this.proactiveSuggestionReceivedAtMs_ = 0; this.proactiveRunning_ = false; + this.agentReady_ = false; this.restoreProactiveNeverHereKeys_(); this.restoreProactiveNotNowSnoozes_(); } @@ -389,6 +391,10 @@ export class DaoChatView extends CrLitElement { private panel_: PiChatPanel | null = null; private mounted_ = false; private mountSucceeded_ = false; + // True once pi-chat-panel has an agent. Until then the panel shows its + // "No agent set" placeholder, so Dao's overlays (empty guide, chip row) + // stay hidden instead of floating over it. + declare protected agentReady_: boolean; // Resolves once mount_() has finished (including maybeResumeLastSession_). // Awaited by submitExternalPrompt so the resume probe can't land after a // Cmd+L/Cmd+T-driven startNewSession() and re-hydrate the old conversation. @@ -645,7 +651,7 @@ export class DaoChatView extends CrLitElement { let stateClass = 'idle'; if (ratio >= 0.75) stateClass = 'hot'; else if (ratio >= 0.5) stateClass = 'warm'; - const showEmptyGuide = + const showEmptyGuide = this.agentReady_ && this.messageCount_ === 0 && !this.isStreaming_ && !this.compacting_; return html` @@ -970,6 +976,12 @@ export class DaoChatView extends CrLitElement { ${this.renderSkillPicker_()} ${this.renderUserContextModal_()} + ${this.renderPageChipRow_()}`; + } + + private renderPageChipRow_() { + if (!this.agentReady_) return nothing; + return html`