* 创建 SSE 事件解析器
(
event: Electron.IpcMainInvokeEvent,
eventChannel: string,
fullResponse: { value: string },
fullReasoning: { value: string }
)
| 196 | * 创建 SSE 事件解析器 |
| 197 | */ |
| 198 | private createStreamParser( |
| 199 | event: Electron.IpcMainInvokeEvent, |
| 200 | eventChannel: string, |
| 201 | fullResponse: { value: string }, |
| 202 | fullReasoning: { value: string } |
| 203 | ) { |
| 204 | return createParser({ |
| 205 | onEvent: (eventData) => { |
| 206 | if (eventData.data === '[DONE]') { |
| 207 | this.sendComplete(event, eventChannel, fullResponse.value, fullReasoning.value) |
| 208 | return |
| 209 | } |
| 210 | |
| 211 | try { |
| 212 | const parsed = JSON.parse(eventData.data) |
| 213 | const delta = parsed.choices?.[0]?.delta |
| 214 | const content = delta?.content |
| 215 | const reasoning_content = |
| 216 | delta?.reasoning_content || |
| 217 | delta?.reasoning || |
| 218 | parsed.reasoning_content || |
| 219 | parsed?.reasoning |
| 220 | |
| 221 | if (content) { |
| 222 | fullResponse.value += content |
| 223 | event.sender.send(eventChannel, { |
| 224 | type: 'chunk', |
| 225 | content: content |
| 226 | } as AIStreamChunk) |
| 227 | } |
| 228 | |
| 229 | if (reasoning_content) { |
| 230 | fullReasoning.value += reasoning_content |
| 231 | event.sender.send(eventChannel, { |
| 232 | type: 'reasoning_content', |
| 233 | reasoning_content: reasoning_content |
| 234 | } as AIStreamChunk) |
| 235 | } |
| 236 | } catch (e) { |
| 237 | console.warn('Failed to parse streaming data:', e) |
| 238 | } |
| 239 | } |
| 240 | }) |
| 241 | } |
| 242 | |
| 243 | /** |
| 244 | * 处理流式响应 |
no test coverage detected