// Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: MIT import { FastForward } from "lucide-react"; import { useCallback, useRef, useState } from "react"; import { Button } from "~/components/ui/button"; import { Card, CardDescription, CardHeader, CardTitle, } from "~/components/ui/card"; import { fastForwardReplay } from "~/core/api"; import type { Option } from "~/core/messages"; import { useReplay } from "~/core/replay"; import { sendMessage, useStore } from "~/core/store"; import { cn } from "~/lib/utils"; import { ConversationStarter } from "./conversation-starter"; import { InputBox } from "./input-box"; import { MessageListView } from "./message-list-view"; import { RainbowText } from "./rainbow-text"; export function MessagesBlock({ className }: { className?: string }) { const messageCount = useStore((state) => state.messageIds.length); const responding = useStore((state) => state.responding); const { isReplay } = useReplay(); const abortControllerRef = useRef(null); const [feedback, setFeedback] = useState<{ option: Option } | null>(null); const handleSend = useCallback( async (message: string, options?: { interruptFeedback?: string }) => { const abortController = new AbortController(); abortControllerRef.current = abortController; try { await sendMessage( message, { interruptFeedback: options?.interruptFeedback ?? feedback?.option.value, }, { abortSignal: abortController.signal, }, ); } catch {} }, [feedback], ); const handleCancel = useCallback(() => { console.info("cancel"); abortControllerRef.current?.abort(); abortControllerRef.current = null; }, []); const handleFeedback = useCallback( (feedback: { option: Option }) => { setFeedback(feedback); }, [setFeedback], ); const handleRemoveFeedback = useCallback(() => { setFeedback(null); }, [setFeedback]); const [fastForwarding, setFastForwarding] = useState(false); const handleFastForwardReplay = useCallback(() => { setFastForwarding(!fastForwarding); fastForwardReplay(!fastForwarding); }, [fastForwarding]); return (
{!isReplay ? (
{!responding && messageCount === 0 && ( )}
) : (
Replay Mode DeerFlow is now replaying the conversation...
{responding && ( )}
)}
); }