import { MessagePrimitive, useAssistantState } from '@assistant-ui/react' import { useHappyChatContext } from '@/components/AssistantChat/context' import type { HappyChatMessageMetadata } from '@/lib/assistant-runtime' import { MessageStatusIndicator } from '@/components/AssistantChat/messages/MessageStatusIndicator' import { MessageAttachments } from '@/components/AssistantChat/messages/MessageAttachments' import { UserBubbleContent, getUserBubbleClassName, shouldShowMessageStatus } from '@/components/AssistantChat/messages/user-bubble' import { CliOutputBlock } from '@/components/CliOutputBlock' import { getConversationMessageAnchorId } from '@/chat/outline' import { MessageActions } from '@/components/AssistantChat/messages/MessageActions' export function HappyUserMessage() { const ctx = useHappyChatContext() const role = useAssistantState(({ message }) => message.role) const messageId = useAssistantState(({ message }) => message.id) const text = useAssistantState(({ message }) => { if (message.role !== 'user') return '' return message.content.find((part) => part.type === 'text')?.text ?? '' }) const status = useAssistantState(({ message }) => { if (message.role !== 'user') return undefined const custom = message.metadata.custom as Partial | undefined return custom?.status }) const localId = useAssistantState(({ message }) => { if (message.role !== 'user') return null const custom = message.metadata.custom as Partial | undefined return custom?.localId ?? null }) const attachments = useAssistantState(({ message }) => { if (message.role !== 'user') return undefined const custom = message.metadata.custom as Partial | undefined return custom?.attachments }) const isCliOutput = useAssistantState(({ message }) => { const custom = message.metadata.custom as Partial | undefined return custom?.kind === 'cli-output' }) const cliText = useAssistantState(({ message }) => { const custom = message.metadata.custom as Partial | undefined if (custom?.kind !== 'cli-output') return '' return message.content.find((part) => part.type === 'text')?.text ?? '' }) if (role !== 'user') return null const canRetry = status === 'failed' && typeof localId === 'string' && Boolean(ctx.onRetryMessage) const onRetry = canRetry ? () => ctx.onRetryMessage!(localId) : undefined const showStatus = shouldShowMessageStatus(status) if (isCliOutput) { return (
) } const hasText = text.length > 0 const hasAttachments = attachments && attachments.length > 0 return (
{hasText ? : null} {hasAttachments ? : null}
{showStatus && (
{showStatus ? : null}
)}
) }