'use client' import type { FC } from 'react' import type { InputValueTypes, TextGenerationRunControl, TextGenerationTranslate } from './types' import type { InstalledApp } from '@/models/explore' import type { VisionFile } from '@/types/app' import { cn } from '@langgenius/dify-ui/cn' import { toast } from '@langgenius/dify-ui/toast' import { useBoolean } from 'ahooks' import { useCallback, useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import Loading from '@/app/components/base/loading' import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' import { useSearchParams } from '@/next/navigation' import { useTextGenerationAppState } from './hooks/use-text-generation-app-state' import { useTextGenerationBatch } from './hooks/use-text-generation-batch' import TextGenerationResultPanel from './text-generation-result-panel' import TextGenerationSidebar from './text-generation-sidebar' type IMainProps = { isInstalledApp?: boolean installedAppInfo?: InstalledApp isWorkflow?: boolean } const TextGeneration: FC = ({ isInstalledApp = false, isWorkflow = false }) => { const { t } = useTranslation() const translateBatchKey: TextGenerationTranslate = useCallback( (selector, options) => { return t(selector, options) }, [t], ) const media = useBreakpoints() const isPC = media === MediaType.pc const searchParams = useSearchParams() const mode = searchParams.get('mode') || 'create' const [currentTab, setCurrentTab] = useState( ['create', 'batch'].includes(mode) ? mode : 'create', ) const [inputs, setInputs] = useState>({}) const inputsRef = useRef(inputs) const [completionFiles, setCompletionFiles] = useState([]) const [runControl, setRunControl] = useState(null) const [controlSend, setControlSend] = useState(0) const [controlStopResponding, setControlStopResponding] = useState(0) const [resultExisted, setResultExisted] = useState(false) const [isShowResultPanel, { setTrue: showResultPanelState, setFalse: hideResultPanel }] = useBoolean(false) const notify = useCallback( ({ type, message }: { type: 'error' | 'info' | 'success' | 'warning'; message: string }) => { toast(message, { type }) }, [], ) const updateInputs = useCallback((newInputs: Record) => { setInputs(newInputs) inputsRef.current = newInputs }, []) const { accessMode, appId, appSourceType, customConfig, handleRemoveSavedMessage, handleSaveMessage, moreLikeThisConfig, promptConfig, savedMessages, siteInfo, systemFeatures, textToSpeechConfig, visionConfig, } = useTextGenerationAppState({ isInstalledApp, isWorkflow, }) const { allFailedTaskList, allSuccessTaskList, allTaskList, allTasksRun, controlRetry, exportRes, handleCompleted, handleRetryAllFailedTask, handleRunBatch: runBatchExecution, isCallBatchAPI, noPendingTask, resetBatchExecution, setIsCallBatchAPI, showTaskList, } = useTextGenerationBatch({ promptConfig, notify, t: translateBatchKey, }) useEffect(() => { if (isCallBatchAPI) setRunControl(null) }, [isCallBatchAPI]) const showResultPanel = useCallback(() => { setTimeout(() => { showResultPanelState() }, 0) }, [showResultPanelState]) const handleRunStart = useCallback(() => { setResultExisted(true) }, []) const handleRunOnce = useCallback(() => { setIsCallBatchAPI(false) setControlSend(Date.now()) resetBatchExecution() showResultPanel() }, [resetBatchExecution, setIsCallBatchAPI, showResultPanel]) const handleRunBatch = useCallback( (data: string[][]) => { runBatchExecution(data, { onStart: () => { setControlSend(Date.now()) setControlStopResponding(Date.now()) showResultPanel() }, }) }, [runBatchExecution, showResultPanel], ) if (!appId || !siteInfo || !promptConfig) { return (
) } return (
) } export default TextGeneration