(record: WorkspaceTurnTaskHandleRecord)
| 6576 | } |
| 6577 | |
| 6578 | private async isLiveWorkspaceTurn(record: WorkspaceTurnTaskHandleRecord): Promise<boolean> { |
| 6579 | const active = this.activeWorkspaceTurnHandleByWorkspaceId.get(record.workspaceId); |
| 6580 | const hasRuntimeActivity = |
| 6581 | this.aiService.isStreaming(record.workspaceId) || |
| 6582 | this.workspaceService.hasPendingQueuedOrPreparingTurn(record.workspaceId); |
| 6583 | if (hasRuntimeActivity) { |
| 6584 | return true; |
| 6585 | } |
| 6586 | |
| 6587 | const isActiveHandle = |
| 6588 | active?.handleId === record.handleId && active.ownerWorkspaceId === record.ownerWorkspaceId; |
| 6589 | if (!isActiveHandle) { |
| 6590 | return false; |
| 6591 | } |
| 6592 | |
| 6593 | if ((record.deferredMessageIds?.length ?? 0) === 0) { |
| 6594 | return true; |
| 6595 | } |
| 6596 | |
| 6597 | // A deferred workspace-turn stream-end was waiting for background work. Once there is no |
| 6598 | // live stream/queued retry and no active descendant/workflow/nested turn left, the in-memory |
| 6599 | // handle is stale and should be recovered from the deferred history instead of blocking forever. |
| 6600 | return await this.hasActiveWorkspaceTurnDeferredBlockers(record); |
| 6601 | } |
| 6602 | |
| 6603 | private async settleStaleWorkspaceTurn(record: WorkspaceTurnTaskHandleRecord): Promise<void> { |
| 6604 | if (record.status !== "queued" && record.status !== "starting" && record.status !== "running") { |
no test coverage detected