mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-08-03 17:01:15 +08:00
fix: hide blank assistant message bubbles
This commit is contained in:
parent
74766d8880
commit
465e043563
@ -8,6 +8,8 @@ type Props = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function AssistantMessage({ content, isStreaming }: Props) {
|
export function AssistantMessage({ content, isStreaming }: Props) {
|
||||||
|
if (!content.trim()) return null
|
||||||
|
|
||||||
const documentLayout = shouldUseDocumentLayout(content)
|
const documentLayout = shouldUseDocumentLayout(content)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -95,6 +95,41 @@ describe('MessageList nested tool calls', () => {
|
|||||||
expect(container.textContent).toContain('Agent')
|
expect(container.textContent).toContain('Agent')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('does not render blank assistant bubbles for whitespace-only text', () => {
|
||||||
|
const messages: UIMessage[] = [
|
||||||
|
{
|
||||||
|
id: 'assistant-empty',
|
||||||
|
type: 'assistant_text',
|
||||||
|
content: '\n\n ',
|
||||||
|
timestamp: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'tool-bash',
|
||||||
|
type: 'tool_use',
|
||||||
|
toolName: 'Bash',
|
||||||
|
toolUseId: 'bash-1',
|
||||||
|
input: { command: 'pwd' },
|
||||||
|
timestamp: 2,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const { renderItems } = buildRenderModel(messages)
|
||||||
|
expect(renderItems).toHaveLength(1)
|
||||||
|
expect(renderItems[0]).toMatchObject({ kind: 'tool_group' })
|
||||||
|
|
||||||
|
useChatStore.setState({
|
||||||
|
sessions: {
|
||||||
|
[ACTIVE_TAB]: makeSessionState({
|
||||||
|
messages,
|
||||||
|
streamingText: '\n ',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const { container } = render(<MessageList />)
|
||||||
|
expect(container.querySelectorAll('[data-message-shell="assistant"]')).toHaveLength(0)
|
||||||
|
})
|
||||||
|
|
||||||
it('keeps root tool runs split when nested child tool calls appear between them', () => {
|
it('keeps root tool runs split when nested child tool calls appear between them', () => {
|
||||||
const messages: UIMessage[] = [
|
const messages: UIMessage[] = [
|
||||||
{
|
{
|
||||||
|
|||||||
@ -90,6 +90,10 @@ export function buildRenderModel(messages: UIMessage[]): RenderModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const msg of messages) {
|
for (const msg of messages) {
|
||||||
|
if (msg.type === 'assistant_text' && !msg.content.trim()) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if (msg.type === 'tool_result' && toolUseIds.has(msg.toolUseId)) {
|
if (msg.type === 'tool_result' && toolUseIds.has(msg.toolUseId)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -495,7 +499,7 @@ export function MessageList({ sessionId, compact = false }: MessageListProps = {
|
|||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|
||||||
{streamingText && (
|
{streamingText.trim() && (
|
||||||
<AssistantMessage content={streamingText} isStreaming={chatState === 'streaming'} />
|
<AssistantMessage content={streamingText} isStreaming={chatState === 'streaming'} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@ -184,6 +184,35 @@ describe('chatStore history mapping', () => {
|
|||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('skips whitespace-only assistant transcript messages', () => {
|
||||||
|
const messages: MessageEntry[] = [
|
||||||
|
{
|
||||||
|
id: 'assistant-empty',
|
||||||
|
type: 'assistant',
|
||||||
|
timestamp: '2026-04-06T00:00:00.000Z',
|
||||||
|
model: 'opus',
|
||||||
|
content: '\n\n ',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'assistant-real',
|
||||||
|
type: 'assistant',
|
||||||
|
timestamp: '2026-04-06T00:00:01.000Z',
|
||||||
|
model: 'opus',
|
||||||
|
content: '可见回复',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const mapped = mapHistoryMessagesToUiMessages(messages)
|
||||||
|
|
||||||
|
expect(mapped).toMatchObject([
|
||||||
|
{
|
||||||
|
id: 'assistant-real',
|
||||||
|
type: 'assistant_text',
|
||||||
|
content: '可见回复',
|
||||||
|
},
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
it('surfaces teammate prompt content when mapping member transcript history', () => {
|
it('surfaces teammate prompt content when mapping member transcript history', () => {
|
||||||
const messages: MessageEntry[] = [
|
const messages: MessageEntry[] = [
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1080,6 +1080,7 @@ export function mapHistoryMessagesToUiMessages(
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (msg.type === 'assistant' && typeof msg.content === 'string') {
|
if (msg.type === 'assistant' && typeof msg.content === 'string') {
|
||||||
|
if (!msg.content.trim()) continue
|
||||||
uiMessages.push({ id: msg.id || nextId(), type: 'assistant_text', content: msg.content, timestamp, model: msg.model })
|
uiMessages.push({ id: msg.id || nextId(), type: 'assistant_text', content: msg.content, timestamp, model: msg.model })
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user