Commit da54fd87 authored by Joel's avatar Joel

feat: batch run

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