@@ -19,6 +19,7 @@ import type {
1919 ItemStartedNotification ,
2020 ThreadItem ,
2121 ModelReroutedNotification ,
22+ PlanDeltaNotification ,
2223 ReasoningSummaryPartAddedNotification ,
2324 ReasoningSummaryTextDeltaNotification ,
2425 ReasoningTextDeltaNotification ,
@@ -76,6 +77,7 @@ export class CodexEventHandler {
7677 private readonly activeGuardianApprovalReviews = new Set < string > ( ) ;
7778 private readonly activeImageGenerationItems = new Set < string > ( ) ;
7879 private readonly emittedImageViewItems = new Set < string > ( ) ;
80+ private readonly planDeltaTextByItemId = new Map < string , string > ( ) ;
7981 private readonly seenReasoningDeltaItemIds = new Set < string > ( ) ;
8082 private readonly terminalCommandIds = new Set < string > ( ) ;
8183 private readonly terminalCommandOutputIds = new Set < string > ( ) ;
@@ -110,6 +112,8 @@ export class CodexEventHandler {
110112 switch ( notification . method ) {
111113 case "item/agentMessage/delta" :
112114 return await this . createTextEvent ( notification . params ) ;
115+ case "item/plan/delta" :
116+ return this . createPlanDeltaEvent ( notification . params ) ;
113117 case "item/started" :
114118 return await this . createItemEvent ( notification . params ) ;
115119 case "item/completed" :
@@ -223,7 +227,6 @@ export class CodexEventHandler {
223227 case "rawResponseItem/completed" :
224228 case "rawResponse/completed" :
225229 case "thread/started" :
226- case "item/plan/delta" :
227230 case "remoteControl/status/changed" :
228231 case "app/list/updated" :
229232 case "thread/settings/updated" :
@@ -293,6 +296,15 @@ export class CodexEventHandler {
293296 return this . createAgentThoughtEvent ( event . delta , event . itemId ) ;
294297 }
295298
299+ private createPlanDeltaEvent ( event : PlanDeltaNotification ) : UpdateSessionEvent | null {
300+ if ( event . delta . length === 0 ) {
301+ return null ;
302+ }
303+ const text = this . planDeltaTextByItemId . get ( event . itemId ) ?? "" ;
304+ this . planDeltaTextByItemId . set ( event . itemId , text + event . delta ) ;
305+ return null ;
306+ }
307+
296308 private createReasoningSectionBreakEvent ( event : ReasoningSummaryPartAddedNotification ) : UpdateSessionEvent {
297309 this . seenReasoningDeltaItemIds . add ( event . itemId ) ;
298310 return this . createAgentThoughtEvent ( "\n\n" , event . itemId ) ;
@@ -389,6 +401,11 @@ export class CodexEventHandler {
389401 case "agentMessage" :
390402 this . rememberAgentMessagePhase ( event . item ) ;
391403 return null ;
404+ case "plan" : {
405+ const deltaText = this . planDeltaTextByItemId . get ( event . item . id ) ?? "" ;
406+ this . planDeltaTextByItemId . delete ( event . item . id ) ;
407+ return this . createCompletedPlanEvent ( event . item , deltaText ) ;
408+ }
392409 case "exitedReviewMode" :
393410 return this . createExitedReviewModeEvent ( event . item ) ;
394411 case "contextCompaction" :
@@ -404,7 +421,6 @@ export class CodexEventHandler {
404421 case "userMessage" :
405422 case "hookPrompt" :
406423 case "enteredReviewMode" :
407- case "plan" :
408424 return null ;
409425
410426 }
@@ -423,6 +439,25 @@ export class CodexEventHandler {
423439 return this . createAgentThoughtEvent ( text , item . id ) ;
424440 }
425441
442+ private createCompletedPlanEvent (
443+ item : ThreadItem & { type : "plan" } ,
444+ deltaText : string ,
445+ ) : UpdateSessionEvent | null {
446+ const text = item . text . length > 0 ? item . text : deltaText ;
447+ if ( text . length === 0 ) {
448+ return null ;
449+ }
450+ return this . createPlanTextEvent ( text , item . id ) ;
451+ }
452+
453+ private createPlanTextEvent ( text : string , messageId : string ) : UpdateSessionEvent {
454+ return createAgentTextMessageChunk (
455+ text ,
456+ messageId ,
457+ createCodexMessagePhaseMeta ( "final_answer" ) ,
458+ ) ;
459+ }
460+
426461 private createExitedReviewModeEvent ( item : ThreadItem & { type : "exitedReviewMode" } ) : UpdateSessionEvent | null {
427462 const text = item . review . trim ( ) ;
428463 if ( text . length === 0 ) {
0 commit comments