({
pageId,
page,
messages,
currentPath,
record,
getConfigs,
getConfigsWithOverride
}: UseChatStreamingOptions)
| 35 | } |
| 36 | |
| 37 | export function useChatStreaming({ |
| 38 | pageId, |
| 39 | page, |
| 40 | messages, |
| 41 | currentPath, |
| 42 | record, |
| 43 | getConfigs, |
| 44 | getConfigsWithOverride |
| 45 | }: UseChatStreamingOptions): UseChatStreamingResult { |
| 46 | const startStreaming = useCallback( |
| 47 | async ( |
| 48 | parentMessageId: string, |
| 49 | pathMessages: ChatMessage[], |
| 50 | llmConfig: LLMConfig, |
| 51 | modelConfig: ModelConfig | undefined |
| 52 | ) => { |
| 53 | // 1. 创建空的 assistant 消息 |
| 54 | const assistantMessage = await messagesService.addMessage(pageId, { |
| 55 | role: 'assistant', |
| 56 | content: '', |
| 57 | parentMessageId, |
| 58 | branchIndex: messagesService.getNextBranchIndex( |
| 59 | messagesService.getMessages(pageId), |
| 60 | parentMessageId |
| 61 | ), |
| 62 | modelId: llmConfig.id, |
| 63 | modelConfigId: modelConfig?.id |
| 64 | }) |
| 65 | |
| 66 | // 2. 开始 streaming |
| 67 | const aiService = createAIService(llmConfig, modelConfig) |
| 68 | streamingManager.start(pageId, assistantMessage.id, aiService) |
| 69 | |
| 70 | try { |
| 71 | await aiService.sendMessage(pathMessages, { |
| 72 | onChunk: (chunk) => { |
| 73 | const current = streamingManager.get(assistantMessage.id) |
| 74 | streamingManager.update( |
| 75 | assistantMessage.id, |
| 76 | (current?.content ?? '') + chunk, |
| 77 | current?.reasoning |
| 78 | ) |
| 79 | }, |
| 80 | onReasoning: (reasoning) => { |
| 81 | const current = streamingManager.get(assistantMessage.id) |
| 82 | streamingManager.update( |
| 83 | assistantMessage.id, |
| 84 | current?.content ?? '', |
| 85 | (current?.reasoning ?? '') + reasoning |
| 86 | ) |
| 87 | }, |
| 88 | onComplete: async () => { |
| 89 | const result = streamingManager.finish(assistantMessage.id) |
| 90 | if (result) { |
| 91 | await messagesService.updateMessage(pageId, assistantMessage.id, { |
| 92 | content: result.content, |
| 93 | reasoning_content: result.reasoning |
| 94 | }) |
no test coverage detected