feat(chat): hide agent replies from chat, keep them on thread cards#32
Merged
Conversation
Hides a message only when authorType is agent AND its authorId matches a real session agent — nil-author system notices and human messages stay visible.
Agent replies now surface only on the super-thread surfaces (inline AgentTaskCard and the agent thread drawer). Header grouping and the empty state derive from the visible sequence; auto-scroll stays keyed on the raw message count so an arriving reply still scrolls its card into view.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Agent task replies used to show up twice: once as a chat bubble and again as the reply text in the inline super-thread card under the @mention that spawned them. The chat now shows only the card — agent replies live exclusively on the thread surfaces (inline
AgentTaskCardand the agent thread drawer), while human messages and system notices ("Workspace is still starting", queue-full, etc.) stay in chat.This is display-only: agent messages are still persisted and broadcast (they feed
buildChatHistoryfor agent context continuity); they're just filtered out of the rendered list. A message is hidden only when it's agent-typed and its author matches a real session agent — system notices are posted with a nil author UUID, so they fall through the filter and remain visible. The predicate lives in a pure module (message-visibility.ts) with a colocated Vitest-style spec, following therepo.test.tsconvention (type-checked now, runs once a test runner is wired).Header grouping and the empty state derive from the visible sequence, so no phantom gaps appear where bubbles were removed. Auto-scroll deliberately stays keyed on the raw message count: an arriving (hidden) reply still scrolls the freshly-updated task card into view.
Notes
claude -ppath,finishAgentcan attachexpandableContentto agent messages, which the hidden bubble would have rendered. The Pi path (default, and sole harness going forward) always posts replies withexpandableContent: nil, so nothing is lost there.Test plan
npx tsc --noEmitandnpm run lintclean (one pre-existing warning in an untouched file).src/components/chat/message-visibility.test.tscovers: human messages always visible, session-agent replies hidden, nil-author system notices visible, agent-typed messages from non-session agents visible (defensive), empty agent set hides nothing, and order-preserving non-mutating filtering.Post-Deploy Monitoring & Validation
No additional operational monitoring required — frontend display-only change; no backend, persistence, or WebSocket behavior touched. Validation: in any active session, @mention an agent and confirm the reply renders in the task card but not as a bubble, and that operational notices still appear in chat. Rollback is reverting this PR.
🤖 Generated with Claude Code