@@ -49,6 +49,7 @@ export class CodexAcpClient {
4949 private gatewayConfig : GatewayConfig | null ;
5050 private pendingLoginCompleted : Promise < AccountLoginCompletedNotification > | null = null ;
5151 private pendingAccountUpdated : Promise < AccountUpdatedNotification > | null = null ;
52+ private readonly sessionNotificationQueues = new Map < string , Promise < void > > ( ) ;
5253
5354
5455 constructor ( codexClient : CodexAppServerClient , codexConfig ?: JsonObject , modelProvider ?: string ) {
@@ -384,13 +385,56 @@ export class CodexAcpClient {
384385
385386 async subscribeToSessionEvents (
386387 sessionId : string ,
387- eventHandler : ( result : ServerNotification ) => void ,
388+ eventHandler : ( result : ServerNotification ) => void | Promise < void > ,
388389 approvalHandler : ApprovalHandler ,
389390 elicitationHandler : ElicitationHandler
390391 ) {
391- this . codexClient . onServerNotification ( sessionId , eventHandler ) ;
392- this . codexClient . onApprovalRequest ( sessionId , approvalHandler ) ;
393- this . codexClient . onElicitationRequest ( sessionId , elicitationHandler ) ;
392+ this . codexClient . onServerNotification ( sessionId , ( event ) => {
393+ this . enqueueSessionNotification ( sessionId , ( ) => eventHandler ( event ) ) ;
394+ } ) ;
395+ this . codexClient . onApprovalRequest ( sessionId , {
396+ handleCommandExecution : async ( params ) => {
397+ await this . waitForSessionNotifications ( sessionId ) ;
398+ return await approvalHandler . handleCommandExecution ( params ) ;
399+ } ,
400+ handleFileChange : async ( params ) => {
401+ await this . waitForSessionNotifications ( sessionId ) ;
402+ return await approvalHandler . handleFileChange ( params ) ;
403+ } ,
404+ } ) ;
405+ this . codexClient . onElicitationRequest ( sessionId , {
406+ handleElicitation : async ( params ) => {
407+ await this . waitForSessionNotifications ( sessionId ) ;
408+ return await elicitationHandler . handleElicitation ( params ) ;
409+ } ,
410+ } ) ;
411+ }
412+
413+ async waitForSessionNotifications ( sessionId : string ) : Promise < void > {
414+ while ( true ) {
415+ const queue = this . sessionNotificationQueues . get ( sessionId ) ;
416+ if ( ! queue ) return ;
417+ await queue ;
418+ }
419+ }
420+
421+ private enqueueSessionNotification ( sessionId : string , operation : ( ) => void | Promise < void > ) : void {
422+ const run = async ( ) => {
423+ try {
424+ await operation ( ) ;
425+ } catch ( error ) {
426+ logger . error ( "Error handling Codex session notification" , error ) ;
427+ }
428+ } ;
429+
430+ const previous = this . sessionNotificationQueues . get ( sessionId ) ;
431+ const next = previous ? previous . then ( run , run ) : run ( ) ;
432+ this . sessionNotificationQueues . set ( sessionId , next ) ;
433+ void next . finally ( ( ) => {
434+ if ( this . sessionNotificationQueues . get ( sessionId ) === next ) {
435+ this . sessionNotificationQueues . delete ( sessionId ) ;
436+ }
437+ } ) ;
394438 }
395439
396440 async sendPrompt (
0 commit comments