fix(ui): hide synthetic helper text in user messages
Avoid rendering tool trace/read output parts on user messages while keeping the primary prompt text visible.
This commit is contained in:
@@ -45,6 +45,15 @@ export default function MessageItem(props: MessageItemProps) {
|
||||
|
||||
const messageParts = () => props.parts
|
||||
|
||||
// User messages can temporarily include synthetic helper parts (e.g. tool traces / file reads).
|
||||
// We only want to display the primary prompt text for the user message; other synthetic text
|
||||
// parts should be hidden.
|
||||
const primaryUserTextPartId = () => {
|
||||
if (!isUser()) return null
|
||||
const firstText = messageParts().find((part) => part?.type === "text") as { id?: string } | undefined
|
||||
return typeof firstText?.id === "string" ? firstText.id : null
|
||||
}
|
||||
|
||||
const fileAttachments = () =>
|
||||
messageParts().filter((part): part is FilePart => part?.type === "file" && typeof (part as FilePart).url === "string")
|
||||
|
||||
@@ -372,6 +381,7 @@ export default function MessageItem(props: MessageItemProps) {
|
||||
messageType={props.record.role}
|
||||
instanceId={props.instanceId}
|
||||
sessionId={props.sessionId}
|
||||
primaryUserTextPartId={primaryUserTextPartId()}
|
||||
onRendered={props.onContentRendered}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -13,9 +13,12 @@ interface MessagePartProps {
|
||||
messageType?: "user" | "assistant"
|
||||
instanceId: string
|
||||
sessionId: string
|
||||
// For user messages, keep the primary prompt text visible even when synthetic (optimistic).
|
||||
// Other synthetic text parts (tool traces, read outputs, etc.) should be hidden.
|
||||
primaryUserTextPartId?: string | null
|
||||
onRendered?: () => void
|
||||
}
|
||||
export default function MessagePart(props: MessagePartProps) {
|
||||
export default function MessagePart(props: MessagePartProps) {
|
||||
|
||||
const { isDark } = useTheme()
|
||||
const { preferences } = useConfig()
|
||||
@@ -28,8 +31,19 @@ interface MessagePartProps {
|
||||
const shouldHideTextPart = () => {
|
||||
const part = props.part
|
||||
if (!part || part.type !== "text") return false
|
||||
// Keep optimistic user prompts visible; hide synthetic assistant text.
|
||||
return Boolean((part as any).synthetic) && props.messageType !== "user"
|
||||
|
||||
const isSynthetic = Boolean((part as any).synthetic)
|
||||
if (!isSynthetic) return false
|
||||
|
||||
// Keep optimistic user prompts visible; hide other synthetic user helper parts.
|
||||
if (props.messageType === "user") {
|
||||
const primaryId = props.primaryUserTextPartId
|
||||
if (!primaryId) return false
|
||||
return part.id !== primaryId
|
||||
}
|
||||
|
||||
// Hide synthetic assistant text.
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Attachment } from "../types/attachment"
|
||||
import type { Attachment, FileSource } from "../types/attachment"
|
||||
|
||||
export function resolvePastedPlaceholders(prompt: string, attachments: Attachment[] = []): string {
|
||||
if (!prompt) {
|
||||
@@ -12,7 +12,7 @@ export function resolvePastedPlaceholders(prompt: string, attachments: Attachmen
|
||||
// IMPORTANT: avoid rewriting plain `@mentions` or email addresses.
|
||||
const fileAttachmentPaths = new Set(
|
||||
attachments
|
||||
.filter((a) => a.source.type === "file")
|
||||
.filter((a): a is Attachment & { source: FileSource } => a.source.type === "file")
|
||||
.map((a) => a.source.path),
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user