(
ownerWorkspaceId: string,
handleId: string
)
| 5761 | } |
| 5762 | |
| 5763 | async interruptWorkspaceTurn( |
| 5764 | ownerWorkspaceId: string, |
| 5765 | handleId: string |
| 5766 | ): Promise<Result<{ workspaceId: string }, string>> { |
| 5767 | let workspaceId: string | undefined; |
| 5768 | let shouldClearQueuedPrompt = false; |
| 5769 | let shouldStopStream = false; |
| 5770 | let interruptedRecord: WorkspaceTurnTaskHandleRecord | undefined; |
| 5771 | |
| 5772 | const result = await this.workspaceTurnSettlementLocks.withLock(handleId, async () => { |
| 5773 | const record = await this.taskHandleStore.getWorkspaceTurn(ownerWorkspaceId, handleId); |
| 5774 | if (record == null) { |
| 5775 | return Err("Workspace turn not found or out of scope"); |
| 5776 | } |
| 5777 | if (record.status === "completed" || record.status === "error") { |
| 5778 | return Err(`Workspace turn is already ${record.status} and cannot be interrupted.`); |
| 5779 | } |
| 5780 | |
| 5781 | workspaceId = record.workspaceId; |
| 5782 | shouldClearQueuedPrompt = |
| 5783 | record.status === "queued" && |
| 5784 | this.workspaceService.hasQueuedWorkspaceTurn(record.workspaceId, record.handleId); |
| 5785 | shouldStopStream = record.status !== "queued"; |
| 5786 | |
| 5787 | const next: WorkspaceTurnTaskHandleRecord = { |
| 5788 | ...record, |
| 5789 | status: "interrupted", |
| 5790 | updatedAt: getIsoNow(), |
| 5791 | }; |
| 5792 | await this.taskHandleStore.upsertWorkspaceTurn(next); |
| 5793 | interruptedRecord = next; |
| 5794 | |
| 5795 | const active = this.activeWorkspaceTurnHandleByWorkspaceId.get(record.workspaceId); |
| 5796 | if ( |
| 5797 | active?.handleId === record.handleId && |
| 5798 | active.ownerWorkspaceId === record.ownerWorkspaceId |
| 5799 | ) { |
| 5800 | this.activeWorkspaceTurnHandleByWorkspaceId.delete(record.workspaceId); |
| 5801 | } |
| 5802 | this.settleWorkspaceTurnWaiters(record.handleId, { |
| 5803 | status: "error", |
| 5804 | error: new Error("Workspace turn interrupted"), |
| 5805 | }); |
| 5806 | this.markTaskForegroundRelevant(record.handleId); |
| 5807 | return Ok({ workspaceId: record.workspaceId }); |
| 5808 | }); |
| 5809 | |
| 5810 | if (!result.success) { |
| 5811 | return result; |
| 5812 | } |
| 5813 | |
| 5814 | if (shouldClearQueuedPrompt && workspaceId != null) { |
| 5815 | const clearQueueResult = this.workspaceService.clearQueue(workspaceId, { |
| 5816 | cancelReason: "Workspace turn interrupted", |
| 5817 | }); |
| 5818 | if (!clearQueueResult.success) { |
| 5819 | return Err(`Failed to clear queued workspace turn: ${clearQueueResult.error}`); |
| 5820 | } |
no test coverage detected