| 375 | } |
| 376 | |
| 377 | async function emitReasoning(state: State, body: string, signal?: AbortSignal): Promise<void> { |
| 378 | const msg = open(state) |
| 379 | const part = take(state, "part", "part") |
| 380 | const start = Date.now() |
| 381 | |
| 382 | feed(state, { |
| 383 | type: "message.part.updated", |
| 384 | properties: { |
| 385 | sessionID: state.id, |
| 386 | time: Date.now(), |
| 387 | part: { |
| 388 | id: part, |
| 389 | sessionID: state.id, |
| 390 | messageID: msg, |
| 391 | type: "reasoning", |
| 392 | text: "", |
| 393 | time: { |
| 394 | start, |
| 395 | }, |
| 396 | }, |
| 397 | }, |
| 398 | } as Event) |
| 399 | |
| 400 | let next = "" |
| 401 | for (const item of split(body)) { |
| 402 | if (signal?.aborted) { |
| 403 | return |
| 404 | } |
| 405 | |
| 406 | next += item |
| 407 | feed(state, { |
| 408 | type: "message.part.delta", |
| 409 | properties: { |
| 410 | sessionID: state.id, |
| 411 | messageID: msg, |
| 412 | partID: part, |
| 413 | field: "text", |
| 414 | delta: item, |
| 415 | }, |
| 416 | } as Event) |
| 417 | await wait(45, signal) |
| 418 | } |
| 419 | |
| 420 | feed(state, { |
| 421 | type: "message.part.updated", |
| 422 | properties: { |
| 423 | sessionID: state.id, |
| 424 | time: Date.now(), |
| 425 | part: { |
| 426 | id: part, |
| 427 | sessionID: state.id, |
| 428 | messageID: msg, |
| 429 | type: "reasoning", |
| 430 | text: next, |
| 431 | time: { |
| 432 | start, |
| 433 | end: Date.now(), |
| 434 | }, |