@@ -454,6 +454,41 @@ export function createAppShellChatActions(deps: {
454454 } ;
455455 try {
456456 const messageId = crypto . randomUUID ( ) ;
457+ async function submitIntoSession ( sessionId : string , messageId : string ) {
458+ if ( exactTurn ) armTurnActive ( sessionId , messageId ) ;
459+ const attachmentItems =
460+ pending && pending . length > 0
461+ ? toComposerIngestItems ( pending )
462+ : undefined ;
463+ const retainedAttachments =
464+ pending && pending . length > 0
465+ ? retainedAttachmentRefs ( pending )
466+ : undefined ;
467+ const sendCommand = {
468+ text,
469+ ...( options . displayText ? { displayText : options . displayText } : { } ) ,
470+ ...copiedArray ( 'attachmentItems' , attachmentItems ) ,
471+ ...( retainedAttachments && retainedAttachments . length > 0
472+ ? { retainedAttachments }
473+ : { } ) ,
474+ ...copiedArray ( 'directoryReferences' , directoryReferences ) ,
475+ ...copiedArray ( 'quotes' , quotes ) ,
476+ ...copiedArray ( 'workspaceFileReferences' , options . workspaceFileReferences ) ,
477+ } ;
478+ return submitAndProject ( {
479+ sessionId,
480+ messageId,
481+ placement : 'current_turn' ,
482+ command : {
483+ ...sendCommand ,
484+ ...( options . turnOrchestration ? { turnOrchestration : options . turnOrchestration } : { } ) ,
485+ } ,
486+ ...( options . displayText ? { displayText : options . displayText } : { } ) ,
487+ ...copiedArray ( 'quotes' , quotes ) ,
488+ exactTurn,
489+ isSurfaceVisible : ( ) => activeIdRef . current === sessionId ,
490+ } ) ;
491+ }
457492 if ( ! initialSessionId ) {
458493 if ( ! initialNewTaskTarget ) return false ;
459494 if ( pending && pending . length > 0 ) preflightAttachmentItems ( pending , uiLocale ) ;
@@ -502,47 +537,15 @@ export function createAppShellChatActions(deps: {
502537 await discardUnsentSession ( ) ;
503538 return false ;
504539 }
505- if ( exactTurn ) armTurnActive ( session . id , messageId ) ;
506- const attachmentItems =
507- pending && pending . length > 0
508- ? toComposerIngestItems ( pending )
509- : undefined ;
510- const retainedAttachments =
511- pending && pending . length > 0
512- ? retainedAttachmentRefs ( pending )
513- : undefined ;
514- const sendCommand = {
515- text,
516- ...( options . displayText ? { displayText : options . displayText } : { } ) ,
517- ...copiedArray ( 'attachmentItems' , attachmentItems ) ,
518- ...( retainedAttachments && retainedAttachments . length > 0
519- ? { retainedAttachments }
520- : { } ) ,
521- ...copiedArray ( 'directoryReferences' , directoryReferences ) ,
522- ...copiedArray ( 'quotes' , quotes ) ,
523- ...copiedArray ( 'workspaceFileReferences' , options . workspaceFileReferences ) ,
524- } ;
525- const submitted = await submitAndProject ( {
526- sessionId : session . id ,
527- messageId,
528- placement : 'current_turn' ,
529- command : {
530- ...sendCommand ,
531- ...( options . turnOrchestration
532- ? { turnOrchestration : options . turnOrchestration }
533- : { } ) ,
534- } ,
535- ...( options . displayText ? { displayText : options . displayText } : { } ) ,
536- ...copiedArray ( 'quotes' , quotes ) ,
537- exactTurn,
538- isSurfaceVisible : ( ) => activeIdRef . current === session . id ,
539- } ) ;
540+ const submitted = await submitIntoSession ( session . id , messageId ) ;
540541 if ( submitted . kind === 'refused' ) {
541542 await discardUnsentSession ( ) ;
542543 return false ;
543544 }
544545 unsentSessionId = undefined ;
545- options . onSessionResolved ?.( session . id ) ;
546+ // The callback fires only when this send's first message projected;
547+ // an unreconciled first message stays unreported.
548+ if ( submitted . kind === 'projected' ) options . onSessionResolved ?.( session . id ) ;
546549 await refreshSessions ( ) ;
547550 return true ;
548551 }
@@ -577,42 +580,9 @@ export function createAppShellChatActions(deps: {
577580 inlineReferences : [ ] ,
578581 } ,
579582 ) ;
580- if ( exactTurn ) armTurnActive ( sessionId , messageId ) ;
581- const attachmentItems =
582- pending && pending . length > 0
583- ? toComposerIngestItems ( pending )
584- : undefined ;
585- const retainedAttachments =
586- pending && pending . length > 0
587- ? retainedAttachmentRefs ( pending )
588- : undefined ;
589- const sendCommand = {
590- text,
591- ...( options . displayText ? { displayText : options . displayText } : { } ) ,
592- ...copiedArray ( 'attachmentItems' , attachmentItems ) ,
593- ...( retainedAttachments && retainedAttachments . length > 0
594- ? { retainedAttachments }
595- : { } ) ,
596- ...copiedArray ( 'directoryReferences' , directoryReferences ) ,
597- ...copiedArray ( 'quotes' , quotes ) ,
598- ...copiedArray ( 'workspaceFileReferences' , options . workspaceFileReferences ) ,
599- } ;
600- const submitted = await submitAndProject ( {
601- sessionId,
602- messageId,
603- placement : 'current_turn' ,
604- command : {
605- ...sendCommand ,
606- ...( options . turnOrchestration ? { turnOrchestration : options . turnOrchestration } : { } ) ,
607- } ,
608- ...( options . displayText ? { displayText : options . displayText } : { } ) ,
609- ...copiedArray ( 'quotes' , quotes ) ,
610- exactTurn,
611- isSurfaceVisible : ( ) => activeIdRef . current === sessionId ,
612- } ) ;
583+ const submitted = await submitIntoSession ( sessionId , messageId ) ;
613584 if ( submitted . kind === 'refused' ) return false ;
614- if ( submitted . kind === 'unreconciled' ) return true ;
615- options . onSessionResolved ?.( sessionId ) ;
585+ // An existing-Session send never reports a resolved Session.
616586 return true ;
617587 } catch ( error ) {
618588 // Capture ownership before cleanup clears the optimistic Session. A
0 commit comments