(ownerWorkspaceId: string)
| 1726 | } |
| 1727 | |
| 1728 | private async drainBashMonitorWakes(ownerWorkspaceId: string): Promise<void> { |
| 1729 | const pending = (await this.bashMonitorWakeStore.listPending(ownerWorkspaceId)).filter( |
| 1730 | (record) => |
| 1731 | !this.cancelingBashMonitorWakeKeys.has(this.bashMonitorWakeKey(ownerWorkspaceId, record.id)) |
| 1732 | ); |
| 1733 | if (pending.length === 0) return; |
| 1734 | |
| 1735 | const cfg = this.config.loadConfigOrDefault(); |
| 1736 | const entry = findWorkspaceEntry(cfg, ownerWorkspaceId); |
| 1737 | if (entry == null) { |
| 1738 | for (const record of pending) { |
| 1739 | await this.bashMonitorWakeStore.markSuperseded(ownerWorkspaceId, record.id); |
| 1740 | } |
| 1741 | return; |
| 1742 | } |
| 1743 | |
| 1744 | const ownerHasPendingQueuedPreparingOrRetry = |
| 1745 | this.hasPendingQueuedOrPreparingTurn(ownerWorkspaceId); |
| 1746 | const ownerHasSessionBackedBusyState = this.isBusyForMessage(ownerWorkspaceId); |
| 1747 | const ownerHasAiServiceStream = this.aiService.isStreaming(ownerWorkspaceId); |
| 1748 | if ( |
| 1749 | ownerHasPendingQueuedPreparingOrRetry || |
| 1750 | (ownerHasSessionBackedBusyState && !ownerHasAiServiceStream) |
| 1751 | ) { |
| 1752 | this.scheduleBashMonitorWakeDrainAfterIdle(ownerWorkspaceId); |
| 1753 | return; |
| 1754 | } |
| 1755 | |
| 1756 | if (ownerHasAiServiceStream && !ownerHasSessionBackedBusyState) { |
| 1757 | return; |
| 1758 | } |
| 1759 | |
| 1760 | const sendOptions = this.getWorkflowContinuationSendOptions(ownerWorkspaceId); |
| 1761 | if (sendOptions == null) { |
| 1762 | log.debug("Bash monitor wake has no send options; leaving pending", { ownerWorkspaceId }); |
| 1763 | return; |
| 1764 | } |
| 1765 | |
| 1766 | const prompt = buildBashMonitorWakePrompt(pending); |
| 1767 | const retryAfterIdleIfBusy = (reason: string): void => { |
| 1768 | if ( |
| 1769 | this.isBusyForMessage(ownerWorkspaceId) || |
| 1770 | this.hasPendingQueuedOrPreparingTurn(ownerWorkspaceId) |
| 1771 | ) { |
| 1772 | this.scheduleBashMonitorWakeDrainAfterIdle(ownerWorkspaceId); |
| 1773 | return; |
| 1774 | } |
| 1775 | log.debug("Bash monitor wake left pending without immediate retry", { |
| 1776 | ownerWorkspaceId, |
| 1777 | reason, |
| 1778 | }); |
| 1779 | }; |
| 1780 | const markDeliveredAfterAccepted = async ( |
| 1781 | records: readonly BashMonitorWakeRecord[] |
| 1782 | ): Promise<void> => { |
| 1783 | let hasUndeliveredMergedMatches = false; |
| 1784 | for (const record of records) { |
| 1785 | const delivered = await this.bashMonitorWakeStore.markDeliveredSnapshot( |
no test coverage detected