Commit da54fd87 authored by Joel's avatar Joel

feat: batch run

parent e673a5b1
......@@ -85,7 +85,7 @@ const ConfigSence: FC<IConfigSenceProps> = ({
</div>
<Button
type="primary"
className='w-[80px] !h-8 !p-0'
className='!h-8 !pl-3 !pr-4'
onClick={onSend}
disabled={!query || query === ''}
>
......
......@@ -25,6 +25,24 @@ import type { InstalledApp } from '@/models/explore'
import { appDefaultIconBackground } from '@/config'
import Toast from '@/app/components/base/toast'
const PARALLEL_LIMIT = 5
enum TaskStatus {
pending = 'pending',
running = 'running',
completed = 'completed',
}
type TaskParam = {
inputs: Record<string, any>
query: string
}
type Task = {
id: number
status: TaskStatus
params: TaskParam
}
export type IMainProps = {
isInstalledApp?: boolean
installedAppInfo?: InstalledApp
......@@ -43,7 +61,7 @@ const TextGeneration: FC<IMainProps> = ({
const isMobile = media === MediaType.mobile
const [currTab, setCurrTab] = useState<string>('batch')
const [isBatch, setIsBatch] = useState(false)
const [inputs, setInputs] = useState<Record<string, any>>({})
const [query, setQuery] = useState('') // run once query content
const [appId, setAppId] = useState<string>('')
......@@ -51,41 +69,59 @@ const TextGeneration: FC<IMainProps> = ({
const [promptConfig, setPromptConfig] = useState<PromptConfig | null>(null)
const [moreLikeThisConfig, setMoreLikeThisConfig] = useState<MoreLikeThisConfig | null>(null)
// save message
const [savedMessages, setSavedMessages] = useState<SavedMessage[]>([])
const fetchSavedMessage = async () => {
const res: any = await doFetchSavedMessage(isInstalledApp, installedAppInfo?.id)
setSavedMessages(res.data)
}
useEffect(() => {
fetchSavedMessage()
}, [])
const handleSaveMessage = async (messageId: string) => {
await saveMessage(messageId, isInstalledApp, installedAppInfo?.id)
notify({ type: 'success', message: t('common.api.saved') })
fetchSavedMessage()
}
const handleRemoveSavedMessage = async (messageId: string) => {
await removeMessage(messageId, isInstalledApp, installedAppInfo?.id)
notify({ type: 'success', message: t('common.api.remove') })
fetchSavedMessage()
}
const logError = (message: string) => {
notify({ type: 'error', message })
}
// send message task
const [controlSend, setControlSend] = useState(0)
const handleSend = () => {
setIsBatch(false)
setControlSend(Date.now())
}
const handleRunBatch = () => {
setControlSend(Date.now())
const [allTaskList, setAllTaskList] = useState<Task[]>([])
// const pendingTaskList = allTaskList.filter(task => task.status === TaskStatus.pending)
const runningTaskList = allTaskList.filter(task => task.status === TaskStatus.running)
const completedTaskList = allTaskList.filter(task => task.status === TaskStatus.completed)
const showTaskList = [...runningTaskList, ...completedTaskList]
const handleRunBatch = (data: string[][]) => {
setIsBatch(true)
const allTaskList: Task[] = data.map((item, i) => {
const inputs: Record<string, string> = {}
item.slice(0, -1).forEach((input, index) => {
inputs[promptConfig?.prompt_variables[index].key as string] = input
})
return {
id: 1,
status: i + 1 < PARALLEL_LIMIT ? TaskStatus.running : TaskStatus.pending,
params: {
inputs,
query: item[item.length - 1],
},
}
})
setAllTaskList(allTaskList)
}
// TODO: finished add pending tasks.
const fetchInitData = () => {
return Promise.all([isInstalledApp
? {
......@@ -130,7 +166,27 @@ const TextGeneration: FC<IMainProps> = ({
hideResSidebar()
}, resRef)
const renderRes = (
const renderRes = (task?: Task) => (<Res
key={task?.id}
isBatch={isBatch}
isPC={isPC}
isMobile={isMobile}
isInstalledApp={!!isInstalledApp}
installedAppInfo={installedAppInfo}
promptConfig={promptConfig}
moreLikeThisEnabled={!!moreLikeThisConfig?.enabled}
inputs={isBatch ? (task as Task).params.inputs : inputs}
query={isBatch ? (task as Task).params.query : query}
controlSend={isBatch ? 0 : controlSend}
onShowRes={showResSidebar}
handleSaveMessage={handleSaveMessage}
/>)
const renderBatchRes = () => {
return (showTaskList.map(task => renderRes(task)))
}
const renderResWrap = (
<div
ref={resRef}
className={
......@@ -157,20 +213,7 @@ const TextGeneration: FC<IMainProps> = ({
</div>
<div className='grow overflow-y-auto'>
<Res
isBatch={currTab === 'batch'}
isPC={isPC}
isMobile={isMobile}
isInstalledApp={!!isInstalledApp}
installedAppInfo={installedAppInfo}
promptConfig={promptConfig}
moreLikeThisEnabled={!!moreLikeThisConfig?.enabled}
inputs={inputs}
query={query}
controlSend={controlSend}
onShowRes={showResSidebar}
handleSaveMessage={handleSaveMessage}
/>
{!isBatch ? renderRes() : renderBatchRes()}
</div>
</>
</div>
......@@ -287,7 +330,7 @@ const TextGeneration: FC<IMainProps> = ({
{/* Result */}
{isPC && (
<div className='grow h-full'>
{renderRes}
{renderResWrap}
</div>
)}
......@@ -298,7 +341,7 @@ const TextGeneration: FC<IMainProps> = ({
background: 'rgba(35, 56, 118, 0.2)',
}}
>
{renderRes}
{renderResWrap}
</div>
)}
</div>
......
......@@ -23,7 +23,7 @@ export type IResultProps = {
moreLikeThisEnabled: boolean
inputs: Record<string, any>
query: string
controlSend: number
controlSend?: number
onShowRes: () => void
handleSaveMessage: (messageId: string) => void
}
......@@ -62,6 +62,10 @@ const Result: FC<IResultProps> = ({
}
const checkCanSend = () => {
// batch will check outer
if (isBatch)
return true
const prompt_variables = promptConfig?.prompt_variables
if (!prompt_variables || prompt_variables?.length === 0)
return true
......@@ -133,41 +137,57 @@ const Result: FC<IResultProps> = ({
},
}, isInstalledApp, installedAppInfo?.id)
}
// run once
useEffect(() => {
if (controlSend)
handleSend()
}, [controlSend])
// run batch
useEffect(() => {
if (isBatch)
handleSend()
}, [isBatch])
const renderTextGenerationRes = () => (
<TextGenerationRes
className='mt-3'
content={completionRes}
messageId={messageId}
isInWebApp
moreLikeThis={moreLikeThisEnabled}
onFeedback={handleFeedback}
feedback={feedback}
onSave={handleSaveMessage}
isMobile={isMobile}
isInstalledApp={isInstalledApp}
installedAppId={installedAppInfo?.id}
isLoading={isBatch ? (!completionRes && isResponsing) : false}
/>
)
return (
<div className={cn((isBatch && !isNoData) ? 'h-52' : 'h-full')}>
{(isResponsing && !completionRes)
? (
<div className='flex h-full w-full justify-center items-center'>
<Loading type='area' />
</div>)
: (
<>
{isNoData
? <NoData />
: (
<TextGenerationRes
className='mt-3'
content={completionRes}
messageId={messageId}
isInWebApp
moreLikeThis={moreLikeThisEnabled}
onFeedback={handleFeedback}
feedback={feedback}
onSave={handleSaveMessage}
isMobile={isMobile}
isInstalledApp={isInstalledApp}
installedAppId={installedAppInfo?.id}
/>
)
}
</>
)}
<div className={cn((isBatch && !isNoData) ? '' : 'h-full')}>
{!isBatch && (
(isResponsing && !completionRes)
? (
<div className='flex h-full w-full justify-center items-center'>
<Loading type='area' />
</div>)
: (
<>
{isNoData
? <NoData />
: renderTextGenerationRes()
}
</>
)
)}
{isBatch && (
<div className='mt-2'>
{renderTextGenerationRes()}
</div>
)}
</div>
)
}
......
......@@ -11,7 +11,7 @@ import Button from '@/app/components/base/button'
export type IRunBatchProps = {
vars: { name: string }[]
onSend: () => void
onSend: (data: string[][]) => void
}
const RunBatch: FC<IRunBatchProps> = ({
......@@ -24,9 +24,13 @@ const RunBatch: FC<IRunBatchProps> = ({
const [isParsed, setIsParsed] = React.useState(false)
const handleParsed = (data: string[][]) => {
setCsvData(data)
console.log(data)
// console.log(data)
setIsParsed(true)
}
const handleSend = () => {
onSend(csvData.slice(1))
}
return (
<div className='pt-4'>
<CSVReader onParsed={handleParsed} />
......@@ -36,7 +40,7 @@ const RunBatch: FC<IRunBatchProps> = ({
<Button
type="primary"
className='mt-4 !h-8 !pl-3 !pr-4'
onClick={onSend}
onClick={handleSend}
disabled={!isParsed}
>
<PlayIcon className="shrink-0 w-4 h-4 mr-1" aria-hidden="true" />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment