import { memo } from 'react' import type { UserInteraction as UserInteractionData } from '../../../types' import { InteractionWrapper } from './InteractionWrapper' import { ChoiceInteraction } from './ChoiceInteraction' import { BrowserTakeoverInteraction } from './BrowserTakeoverInteraction' import { SlideFormInteraction } from './SlideFormInteraction' export { InteractionWrapper } from './InteractionWrapper' export { InteractionButtons } from './InteractionButtons' export { ChoiceInteraction } from './ChoiceInteraction' export { BrowserTakeoverInteraction } from './BrowserTakeoverInteraction' export { SlideFormInteraction } from './SlideFormInteraction' interface UserInteractionProps { userInteraction: UserInteractionData disabled?: boolean isLatest?: boolean onSendMessage?: (content: string) => void } /** * 用户交互主入口组件 * 根据 userInteraction.type 分发到对应的交互子组件 */ export const UserInteractionWidget = memo( ({ userInteraction, disabled, isLatest, onSendMessage }: UserInteractionProps) => { const { type, content, choice_options, questions, browser_type, expected_user_action, take_over_type, messageTime, } = userInteraction as UserInteractionData & { messageTime?: string } let inner: React.ReactNode = null // 浏览器接管交互:与 Remix 一致,优先根据 expected_user_action 判断 if ( expected_user_action === 'take_over_web_browser' || type === 'browser_takeover' || type === 'browser_use_takeover' ) { if (take_over_type !== 'reback') { inner = ( ) } } else if (choice_options?.length) { inner = ( ) } else if (questions?.length) { inner = ( ) } // 有文本内容或有交互子组件时才渲染 if (!inner && !content?.trim()) return null return ( {inner} ) }, )