Spaces:
Sleeping
Sleeping
import { useChat } from 'ai/react'; | |
import { toast } from 'react-hot-toast'; | |
import { useEffect, useRef } from 'react'; | |
import { ChatWithMessages } from '../types'; | |
import { convertDBMessageToAPIMessage } from '../utils/message'; | |
import { useRouter } from 'next/navigation'; | |
import { Message } from '@prisma/client'; | |
import { useSetAtom } from 'jotai'; | |
import { selectedMessageId } from '@/state/chat'; | |
const useVisionAgent = (chat: ChatWithMessages) => { | |
const { messages: dbMessages, id, mediaUrl } = chat; | |
const latestDbMessage = dbMessages[dbMessages.length - 1]; | |
// Temporary solution for now while single we have to pass mediaUrl separately outside of the messages | |
const router = useRouter(); | |
const setMessageId = useSetAtom(selectedMessageId); | |
const { | |
data = [], | |
reload, | |
append, | |
messages, | |
isLoading, | |
} = useChat({ | |
api: '/api/vision-agent', | |
onResponse(response) { | |
if (response.status !== 200) { | |
toast.error(response.statusText); | |
} | |
}, | |
onFinish: () => { | |
setMessageId(latestDbMessage.id); | |
router.refresh(); | |
}, | |
body: { | |
mediaUrl: latestDbMessage.mediaUrl, | |
chatId: id, | |
messageId: latestDbMessage.id, | |
// for some reason, the messages has to be stringified to be sent to the API | |
apiMessages: JSON.stringify(convertDBMessageToAPIMessage(dbMessages)), | |
}, | |
onError: err => { | |
err && toast.error(err.message); | |
}, | |
}); | |
/** | |
* If case this is first time user navigated with init message, we need to reload the chat for the first response | |
*/ | |
const once = useRef(true); | |
useEffect(() => { | |
const appendDbMessage = async (latestDbMessage: Message) => { | |
await append({ | |
id: latestDbMessage.id + '-user', | |
content: latestDbMessage.prompt, | |
role: 'user', | |
}); | |
}; | |
if (isLoading || latestDbMessage.response || latestDbMessage.responseBody) { | |
return; | |
} | |
if (messages.length === 0) { | |
if (once.current) { | |
once.current = false; | |
appendDbMessage(latestDbMessage); | |
} | |
return; | |
} | |
if ( | |
messages.findIndex(message => message.id.includes(latestDbMessage.id)) === | |
-1 | |
) { | |
appendDbMessage(latestDbMessage); | |
} | |
}, [latestDbMessage, messages, isLoading]); | |
const initDataIndex = data.findIndex( | |
(m: any) => | |
m.type === 'init' && m.payload?.messageId === latestDbMessage.id, | |
); | |
return { | |
data: | |
initDataIndex >= 0 | |
? (data.slice(initDataIndex + 1) as unknown as PrismaJson.MessageBody[]) | |
: [], | |
reload, | |
isLoading, | |
}; | |
}; | |
export default useVisionAgent; | |