// Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: MIT import { MagicWandIcon } from "@radix-ui/react-icons"; import { AnimatePresence, motion } from "framer-motion"; import { ArrowUp, Lightbulb, X } from "lucide-react"; import { useTranslations } from "next-intl"; import { useCallback, useRef, useState } from "react"; import { Detective } from "~/components/deer-flow/icons/detective"; import MessageInput, { type MessageInputRef, } from "~/components/deer-flow/message-input"; import { ReportStyleDialog } from "~/components/deer-flow/report-style-dialog"; import { Tooltip } from "~/components/deer-flow/tooltip"; import { BorderBeam } from "~/components/magicui/border-beam"; import { Button } from "~/components/ui/button"; import { enhancePrompt } from "~/core/api"; import { useConfig } from "~/core/api/hooks"; import type { Option, Resource } from "~/core/messages"; import { setEnableDeepThinking, setEnableBackgroundInvestigation, useSettingsStore, } from "~/core/store"; import { cn } from "~/lib/utils"; export function InputBox({ className, responding, feedback, onSend, onCancel, onRemoveFeedback, }: { className?: string; size?: "large" | "normal"; responding?: boolean; feedback?: { option: Option } | null; onSend?: ( message: string, options?: { interruptFeedback?: string; resources?: Array; }, ) => void; onCancel?: () => void; onRemoveFeedback?: () => void; }) { const t = useTranslations("chat.inputBox"); const tCommon = useTranslations("common"); const enableDeepThinking = useSettingsStore( (state) => state.general.enableDeepThinking, ); const backgroundInvestigation = useSettingsStore( (state) => state.general.enableBackgroundInvestigation, ); const { config, loading } = useConfig(); const reportStyle = useSettingsStore((state) => state.general.reportStyle); const containerRef = useRef(null); const inputRef = useRef(null); const feedbackRef = useRef(null); // Enhancement state const [isEnhancing, setIsEnhancing] = useState(false); const [isEnhanceAnimating, setIsEnhanceAnimating] = useState(false); const [currentPrompt, setCurrentPrompt] = useState(""); const handleSendMessage = useCallback( (message: string, resources: Array) => { if (responding) { onCancel?.(); } else { if (message.trim() === "") { return; } if (onSend) { onSend(message, { interruptFeedback: feedback?.option.value, resources, }); onRemoveFeedback?.(); // Clear enhancement animation after sending setIsEnhanceAnimating(false); } } }, [responding, onCancel, onSend, feedback, onRemoveFeedback], ); const handleEnhancePrompt = useCallback(async () => { if (currentPrompt.trim() === "" || isEnhancing) { return; } setIsEnhancing(true); setIsEnhanceAnimating(true); try { const enhancedPrompt = await enhancePrompt({ prompt: currentPrompt, report_style: reportStyle.toUpperCase(), }); // Add a small delay for better UX await new Promise((resolve) => setTimeout(resolve, 500)); // Update the input with the enhanced prompt with animation if (inputRef.current) { inputRef.current.setContent(enhancedPrompt); setCurrentPrompt(enhancedPrompt); } // Keep animation for a bit longer to show the effect setTimeout(() => { setIsEnhanceAnimating(false); }, 1000); } catch (error) { console.error("Failed to enhance prompt:", error); setIsEnhanceAnimating(false); // Could add toast notification here } finally { setIsEnhancing(false); } }, [currentPrompt, isEnhancing, reportStyle]); return (
{feedback && (
{feedback.option.text}
)} {isEnhanceAnimating && (
{/* Sparkle effect overlay */} {/* Floating sparkles */} {[...Array(6)].map((_, i) => ( ))}
)}
{config?.models?.reasoning && config.models.reasoning.length > 0 && (

{t("deepThinkingTooltip.title", { status: enableDeepThinking ? t("on") : t("off"), })}

{t("deepThinkingTooltip.description", { model: config.models.reasoning[0] ?? "", })}

} > )}

{t("investigationTooltip.title", { status: backgroundInvestigation ? t("on") : t("off"), })}

{t("investigationTooltip.description")}

} >
{isEnhancing && ( <> )} ); }