@@ -130,6 +130,42 @@ export class SolutionWorkflowOrchestrator {
130130
131131 // Set up the resolver function
132132 this . state . resolvePendingInteraction = this . createInteractionResolver ( ) ;
133+
134+ // Register onDrain handler to trigger cleanup when queue empties
135+ // This catches cases where the queue drains naturally without resolver calls
136+ this . queueManager . onDrain ( ( ) => {
137+ this . handleQueueDrained ( ) ;
138+ } ) ;
139+ }
140+
141+ /**
142+ * Handle queue drain event - check if cleanup should happen
143+ * Called automatically when the queue becomes empty
144+ */
145+ private handleQueueDrained ( ) : void {
146+ this . logger . debug ( "Queue drained, checking cleanup conditions" , {
147+ workflowRunCompleted : this . workflowRunCompleted ,
148+ pendingInteractionsSize : this . pendingInteractions . size ,
149+ isWaitingForUserInteraction : this . state . data . isWaitingForUserInteraction ,
150+ isFetchingSolution : this . state . data . isFetchingSolution ,
151+ } ) ;
152+
153+ // Check all cleanup conditions
154+ const allComplete =
155+ this . pendingInteractions . size === 0 &&
156+ ! this . state . data . isWaitingForUserInteraction &&
157+ this . queueManager ! . getQueueLength ( ) === 0 ;
158+
159+ if ( allComplete && this . workflowRunCompleted && this . state . data . isFetchingSolution ) {
160+ this . logger . info ( "Queue drained and all conditions met - triggering cleanup" ) ;
161+ this . finalCleanup ( ) ;
162+ } else {
163+ this . logger . debug ( "Queue drained but not all conditions met for cleanup" , {
164+ allComplete,
165+ workflowRunCompleted : this . workflowRunCompleted ,
166+ isFetchingSolution : this . state . data . isFetchingSolution ,
167+ } ) ;
168+ }
133169 }
134170
135171 /**
0 commit comments