@@ -375,22 +375,34 @@ class APIServer {
375375 }
376376 } ) ;
377377
378- // Find a connected and ready client
379- const readyClient = this . findReadyClient ( ) ;
380- if ( ! readyClient ) {
381- throw new Error ( 'No DevTools client is connected and ready. Please ensure a DevTools client is connected to the evaluation server.' ) ;
382- }
378+ // Find a client with existing tabs (not the dummy client)
379+ const baseClientId = this . findClientWithTabs ( ) ;
380+
381+ // Open a new tab for this request
382+ logger . info ( 'Opening new tab for responses request' , { baseClientId } ) ;
383+ const tabResult = await this . evaluationServer . openTab ( baseClientId , {
384+ url : 'about:blank' ,
385+ background : false
386+ } ) ;
387+
388+ logger . info ( 'Tab opened successfully' , {
389+ tabId : tabResult . tabId ,
390+ compositeClientId : tabResult . compositeClientId
391+ } ) ;
392+
393+ // Wait for the new tab's DevTools to connect
394+ const tabClient = await this . waitForClientConnection ( tabResult . compositeClientId ) ;
383395
384396 // Create a dynamic evaluation for this request
385397 const evaluation = this . createDynamicEvaluationNested ( requestBody . input , nestedModelConfig ) ;
386398
387- // Execute the evaluation on the DevTools client
388- logger . info ( 'Executing evaluation on DevTools client ' , {
389- clientId : readyClient . clientId ,
399+ // Execute the evaluation on the new tab's DevTools client
400+ logger . info ( 'Executing evaluation on new tab ' , {
401+ compositeClientId : tabResult . compositeClientId ,
390402 evaluationId : evaluation . id
391403 } ) ;
392404
393- const result = await this . evaluationServer . executeEvaluation ( readyClient , evaluation ) ;
405+ const result = await this . evaluationServer . executeEvaluation ( tabClient , evaluation ) ;
394406
395407 // Debug: log the result structure
396408 logger . debug ( 'executeEvaluation result:' , result ) ;
@@ -465,6 +477,54 @@ class APIServer {
465477 return null ;
466478 }
467479
480+ /**
481+ * Find a client that has existing tabs (not the dummy client)
482+ * @returns {string } Base client ID
483+ */
484+ findClientWithTabs ( ) {
485+ const clients = this . evaluationServer . getClientManager ( ) . getAllClients ( ) ;
486+
487+ for ( const client of clients ) {
488+ const tabs = this . evaluationServer . getClientManager ( ) . getClientTabs ( client . id ) ;
489+ if ( tabs . length > 0 ) {
490+ logger . info ( 'Found client with tabs' , { clientId : client . id , tabCount : tabs . length } ) ;
491+ return client . id ;
492+ }
493+ }
494+
495+ throw new Error ( 'No client with existing tabs found. Please ensure at least one DevTools client with a tab is connected.' ) ;
496+ }
497+
498+ /**
499+ * Wait for a client connection to be established and ready
500+ * @param {string } compositeClientId - Composite client ID (baseClientId:tabId)
501+ * @param {number } maxWaitMs - Maximum time to wait in milliseconds
502+ * @returns {Promise<Object> } Connection object
503+ */
504+ async waitForClientConnection ( compositeClientId , maxWaitMs = 10000 ) {
505+ const startTime = Date . now ( ) ;
506+ const pollInterval = 500 ; // Check every 500ms
507+
508+ logger . info ( 'Waiting for client connection' , { compositeClientId, maxWaitMs } ) ;
509+
510+ while ( Date . now ( ) - startTime < maxWaitMs ) {
511+ const connection = this . evaluationServer . connectedClients . get ( compositeClientId ) ;
512+
513+ if ( connection && connection . ready ) {
514+ logger . info ( 'Client connection established and ready' , {
515+ compositeClientId,
516+ waitedMs : Date . now ( ) - startTime
517+ } ) ;
518+ return connection ;
519+ }
520+
521+ // Wait before next check
522+ await new Promise ( resolve => setTimeout ( resolve , pollInterval ) ) ;
523+ }
524+
525+ throw new Error ( `Timeout waiting for client connection: ${ compositeClientId } . Tab may not have connected to eval-server.` ) ;
526+ }
527+
468528 /**
469529 * Create a dynamic evaluation object with nested model configuration
470530 * @param {string } input - Input message for the evaluation
0 commit comments