@@ -1593,6 +1593,7 @@ describe("runPreparedReply media-only handling", () => {
|
1593 | 1593 | it("queues active room events as followups instead of steering fake prompts", async () => { |
1594 | 1594 | const queueSettings = await import("./queue/settings-runtime.js"); |
1595 | 1595 | const piRuntime = await import("../../agents/pi-embedded.runtime.js"); |
| 1596 | +const abortController = new AbortController(); |
1596 | 1597 | vi.mocked(queueSettings.resolveQueueSettings).mockReturnValueOnce({ |
1597 | 1598 | mode: "steer", |
1598 | 1599 | debounceMs: 500, |
@@ -1610,6 +1611,7 @@ describe("runPreparedReply media-only handling", () => {
|
1610 | 1611 | |
1611 | 1612 | await runPreparedReply( |
1612 | 1613 | baseParams({ |
| 1614 | +opts: { abortSignal: abortController.signal }, |
1613 | 1615 | ctx: { |
1614 | 1616 | Body: "ambient", |
1615 | 1617 | RawBody: "ambient", |
@@ -1638,9 +1640,58 @@ describe("runPreparedReply media-only handling", () => {
|
1638 | 1640 | expect(call.resolvedQueue.mode).toBe("steer"); |
1639 | 1641 | expect(call.followupRun.prompt).toBe("[OpenClaw room event]"); |
1640 | 1642 | expect(call.followupRun.currentInboundEventKind).toBe("room_event"); |
| 1643 | +expect(call.followupRun.abortSignal).toBe(abortController.signal); |
1641 | 1644 | expect(call.followupRun.currentInboundContext?.text).toContain("Current event:"); |
1642 | 1645 | }); |
1643 | 1646 | |
| 1647 | +it("detaches queued user requests from superseded source abort signals", async () => { |
| 1648 | +const queueSettings = await import("./queue/settings-runtime.js"); |
| 1649 | +const piRuntime = await import("../../agents/pi-embedded.runtime.js"); |
| 1650 | +const abortController = new AbortController(); |
| 1651 | +vi.mocked(queueSettings.resolveQueueSettings).mockReturnValueOnce({ |
| 1652 | +mode: "collect", |
| 1653 | +debounceMs: 500, |
| 1654 | +cap: 20, |
| 1655 | +dropPolicy: "summarize", |
| 1656 | +}); |
| 1657 | +vi.mocked(piRuntime.resolveActiveEmbeddedRunSessionId) |
| 1658 | +.mockReturnValueOnce("active-session") |
| 1659 | +.mockReturnValueOnce("active-session"); |
| 1660 | +vi.mocked(piRuntime.isEmbeddedPiRunActive).mockReturnValueOnce(true); |
| 1661 | +vi.mocked(piRuntime.isEmbeddedPiRunStreaming).mockReturnValueOnce(true); |
| 1662 | +vi.mocked(buildInboundUserContextPrefix).mockReturnValueOnce("user request context"); |
| 1663 | + |
| 1664 | +await runPreparedReply( |
| 1665 | +baseParams({ |
| 1666 | +opts: { abortSignal: abortController.signal }, |
| 1667 | +ctx: { |
| 1668 | +Body: "@bot keep this", |
| 1669 | +RawBody: "@bot keep this", |
| 1670 | +CommandBody: "@bot keep this", |
| 1671 | +Provider: "telegram", |
| 1672 | +Surface: "telegram", |
| 1673 | +ChatType: "group", |
| 1674 | +}, |
| 1675 | +sessionCtx: { |
| 1676 | +Body: "@bot keep this", |
| 1677 | +BodyStripped: "@bot keep this", |
| 1678 | +Provider: "telegram", |
| 1679 | +Surface: "telegram", |
| 1680 | +ChatType: "group", |
| 1681 | +InboundEventKind: "user_request", |
| 1682 | +MessageSid: "994", |
| 1683 | +SenderName: "Alice", |
| 1684 | +}, |
| 1685 | +}), |
| 1686 | +); |
| 1687 | + |
| 1688 | +const call = requireLastRunReplyAgentCall(); |
| 1689 | +expect(call.shouldFollowup).toBe(true); |
| 1690 | +expect(call.isActive).toBe(true); |
| 1691 | +expect(call.followupRun.currentInboundEventKind).toBe("user_request"); |
| 1692 | +expect(call.followupRun.abortSignal).toBeUndefined(); |
| 1693 | +}); |
| 1694 | + |
1644 | 1695 | it("queues active room events instead of interrupting active user requests", async () => { |
1645 | 1696 | const queueSettings = await import("./queue/settings-runtime.js"); |
1646 | 1697 | const piRuntime = await import("../../agents/pi-embedded.runtime.js"); |
|