()
| 540 | await finalizeTurnStream(); |
| 541 | }, |
| 542 | async markInterrupted() { |
| 543 | // Idempotent. Mark BEFORE any await so subsequent subscriber |
| 544 | // callbacks (including the RUN_ERROR that AG-UI fires when we |
| 545 | // abort) see the flag and bail. |
| 546 | if (aborted) return; |
| 547 | aborted = true; |
| 548 | // Clear the native status; the interrupted marker (or the next turn) is |
| 549 | // the user-visible signal now. |
| 550 | if (statusMode) await clearStatus(); |
| 551 | // Native turn stream: append the interrupted marker to the partial reply |
| 552 | // and finalize it. |
| 553 | if (nativeMode) { |
| 554 | if (turnStream && turnText.length > 0 && !turnFinalised) { |
| 555 | turnStream.append(turnText + INTERRUPTED_SUFFIX); |
| 556 | } |
| 557 | await finalizeTurnStream(); |
| 558 | } |
| 559 | // Legacy per-message streams: append the marker and drain. Streams with |
| 560 | // no content yet are silently dropped (the bot never posted anything). |
| 561 | const tasks: Promise<void>[] = []; |
| 562 | for (const [id, stream] of Array.from(streams.entries())) { |
| 563 | const buf = buffers.get(id) ?? ""; |
| 564 | if (buf.length > 0) { |
| 565 | stream.append(buf + INTERRUPTED_SUFFIX); |
| 566 | tasks.push(stream.finish()); |
| 567 | } |
| 568 | streams.delete(id); |
| 569 | finalised.add(id); |
| 570 | } |
| 571 | buffers.clear(); |
| 572 | await Promise.all(tasks); |
| 573 | }, |
| 574 | }; |
| 575 | } |
no test coverage detected
searching dependent graphs…