| import type { Message } from 'ai'; |
| import { useCallback, useState } from 'react'; |
| import { StreamingMessageParser } from '~/lib/runtime/message-parser'; |
| import { workbenchStore } from '~/lib/stores/workbench'; |
| import { createScopedLogger } from '~/utils/logger'; |
|
|
| const logger = createScopedLogger('useMessageParser'); |
|
|
| const messageParser = new StreamingMessageParser({ |
| callbacks: { |
| onArtifactOpen: (data) => { |
| logger.trace('onArtifactOpen', data); |
|
|
| workbenchStore.showWorkbench.set(true); |
| workbenchStore.addArtifact(data); |
| }, |
| onArtifactClose: (data) => { |
| logger.trace('onArtifactClose'); |
|
|
| workbenchStore.updateArtifact(data, { closed: true }); |
| }, |
| onActionOpen: (data) => { |
| logger.trace('onActionOpen', data.action); |
|
|
| |
| if (data.action.type === 'file') { |
| workbenchStore.addAction(data); |
| } |
| }, |
| onActionClose: (data) => { |
| logger.trace('onActionClose', data.action); |
|
|
| if (data.action.type !== 'file') { |
| workbenchStore.addAction(data); |
| } |
|
|
| workbenchStore.runAction(data); |
| }, |
| onActionStream: (data) => { |
| logger.trace('onActionStream', data.action); |
| workbenchStore.runAction(data, true); |
| }, |
| }, |
| }); |
| const extractTextContent = (message: Message) => |
| Array.isArray(message.content) |
| ? (message.content.find((item) => item.type === 'text')?.text as string) || '' |
| : message.content; |
|
|
| export function useMessageParser() { |
| const [parsedMessages, setParsedMessages] = useState<{ [key: number]: string }>({}); |
|
|
| const parseMessages = useCallback((messages: Message[], isLoading: boolean) => { |
| let reset = false; |
|
|
| if (import.meta.env.DEV && !isLoading) { |
| reset = true; |
| messageParser.reset(); |
| } |
|
|
| for (const [index, message] of messages.entries()) { |
| if (message.role === 'assistant' || message.role === 'user') { |
| const newParsedContent = messageParser.parse(message.id, extractTextContent(message)); |
| setParsedMessages((prevParsed) => ({ |
| ...prevParsed, |
| [index]: !reset ? (prevParsed[index] || '') + newParsedContent : newParsedContent, |
| })); |
| } |
| } |
| }, []); |
|
|
| return { parsedMessages, parseMessages }; |
| } |
|
|