@@ -338,6 +338,7 @@ export async function deliverAgentCommandResult(params: {
338338 opts : AgentCommandOpts ;
339339 outboundSession : OutboundSessionContext | undefined ;
340340 sessionEntry : SessionEntry | undefined ;
341+ resolveFreshSessionEntryForDelivery ?: ( ) => Promise < SessionEntry | undefined > ;
341342 result : RunResult ;
342343 payloads : RunResult [ "payloads" ] ;
343344} ) : Promise < AgentCommandDeliveryResult > {
@@ -349,76 +350,144 @@ export async function deliverAgentCommandResult(params: {
349350 const turnSourceTo = opts . runContext ?. currentChannelId ?? opts . to ;
350351 const turnSourceAccountId = opts . runContext ?. accountId ?? opts . accountId ;
351352 const turnSourceThreadId = opts . runContext ?. currentThreadTs ?? opts . threadId ;
352- const deliveryPlan = resolveAgentDeliveryPlan ( {
353- sessionEntry,
354- requestedChannel : opts . replyChannel ?? opts . channel ,
355- explicitTo : opts . replyTo ?? opts . to ,
356- explicitThreadId : opts . threadId ,
357- accountId : opts . replyAccountId ?? opts . accountId ,
358- wantsDelivery : deliver ,
359- turnSourceChannel,
360- turnSourceTo,
361- turnSourceAccountId,
362- turnSourceThreadId,
363- } ) ;
364- let deliveryChannel = deliveryPlan . resolvedChannel ;
365353 const explicitChannelHint = ( opts . replyChannel ?? opts . channel ) ?. trim ( ) ;
366- if ( deliver && isInternalMessageChannel ( deliveryChannel ) && ! explicitChannelHint ) {
367- try {
368- const selection = await resolveMessageChannelSelection ( { cfg } ) ;
369- deliveryChannel = selection . channel ;
370- } catch {
371- // Keep the internal channel marker; error handling below reports the failure.
354+ const resolveDeliveryRouting = async ( candidateSessionEntry : SessionEntry | undefined ) => {
355+ const deliveryPlan = resolveAgentDeliveryPlan ( {
356+ sessionEntry : candidateSessionEntry ,
357+ requestedChannel : opts . replyChannel ?? opts . channel ,
358+ explicitTo : opts . replyTo ?? opts . to ,
359+ explicitThreadId : opts . threadId ,
360+ accountId : opts . replyAccountId ?? opts . accountId ,
361+ wantsDelivery : deliver ,
362+ turnSourceChannel,
363+ turnSourceTo,
364+ turnSourceAccountId,
365+ turnSourceThreadId,
366+ } ) ;
367+ let deliveryChannel = deliveryPlan . resolvedChannel ;
368+ if ( deliver && isInternalMessageChannel ( deliveryChannel ) && ! explicitChannelHint ) {
369+ try {
370+ const selection = await resolveMessageChannelSelection ( { cfg } ) ;
371+ deliveryChannel = selection . channel ;
372+ } catch {
373+ // Keep the internal channel marker; error handling below reports the failure.
374+ }
372375 }
373- }
374- const effectiveDeliveryPlan =
375- deliveryChannel === deliveryPlan . resolvedChannel
376- ? deliveryPlan
377- : {
378- ...deliveryPlan ,
379- resolvedChannel : deliveryChannel ,
380- } ;
381- // Channel docking: delivery channels are resolved via plugin registry.
382- const deliveryPlugin =
383- deliver && ! isInternalMessageChannel ( deliveryChannel )
384- ? getChannelPlugin ( normalizeChannelId ( deliveryChannel ) ?? deliveryChannel )
385- : undefined ;
386-
387- const isDeliveryChannelKnown =
388- isInternalMessageChannel ( deliveryChannel ) || Boolean ( deliveryPlugin ) ;
376+ const effectiveDeliveryPlan =
377+ deliveryChannel === deliveryPlan . resolvedChannel
378+ ? deliveryPlan
379+ : {
380+ ...deliveryPlan ,
381+ resolvedChannel : deliveryChannel ,
382+ } ;
383+ // Channel docking: delivery channels are resolved via plugin registry.
384+ const deliveryPlugin =
385+ deliver && ! isInternalMessageChannel ( deliveryChannel )
386+ ? getChannelPlugin ( normalizeChannelId ( deliveryChannel ) ?? deliveryChannel )
387+ : undefined ;
388+ const isDeliveryChannelKnown =
389+ isInternalMessageChannel ( deliveryChannel ) || Boolean ( deliveryPlugin ) ;
390+ const targetMode =
391+ opts . deliveryTargetMode ??
392+ effectiveDeliveryPlan . deliveryTargetMode ??
393+ ( opts . to ? "explicit" : "implicit" ) ;
394+ const resolvedAccountId = effectiveDeliveryPlan . resolvedAccountId ;
395+ const resolved =
396+ deliver && isDeliveryChannelKnown && deliveryChannel
397+ ? resolveAgentOutboundTarget ( {
398+ cfg,
399+ plan : effectiveDeliveryPlan ,
400+ targetMode,
401+ validateExplicitTarget : true ,
402+ } )
403+ : {
404+ resolvedTarget : null ,
405+ resolvedTo : effectiveDeliveryPlan . resolvedTo ,
406+ targetMode,
407+ } ;
408+ const resolvedThreadId = deliveryPlan . resolvedThreadId ?? opts . threadId ;
409+ const replyTransport =
410+ deliveryPlugin ?. threading ?. resolveReplyTransport ?.( {
411+ cfg,
412+ accountId : resolvedAccountId ,
413+ threadId : resolvedThreadId ,
414+ } ) ?? null ;
415+ return {
416+ deliveryPlan,
417+ deliveryChannel,
418+ effectiveDeliveryPlan,
419+ deliveryPlugin,
420+ isDeliveryChannelKnown,
421+ targetMode,
422+ resolvedAccountId,
423+ resolved,
424+ resolvedTarget : resolved . resolvedTarget ,
425+ deliveryTarget : resolved . resolvedTo ,
426+ resolvedThreadId,
427+ resolvedReplyToId : replyTransport ?. replyToId ?? undefined ,
428+ resolvedThreadTarget :
429+ replyTransport && Object . hasOwn ( replyTransport , "threadId" )
430+ ? ( replyTransport . threadId ?? null )
431+ : ( resolvedThreadId ?? null ) ,
432+ } ;
433+ } ;
434+ const deliveryRoutingFailureReason = (
435+ route : Awaited < ReturnType < typeof resolveDeliveryRouting > > ,
436+ ) : string | undefined => {
437+ if ( ! deliver ) {
438+ return undefined ;
439+ }
440+ if ( isInternalMessageChannel ( route . deliveryChannel ) ) {
441+ return "channel_resolved_to_internal" ;
442+ }
443+ if ( ! route . isDeliveryChannelKnown ) {
444+ return "unknown_channel" ;
445+ }
446+ if ( route . resolvedTarget && ! route . resolvedTarget . ok ) {
447+ return "invalid_delivery_target" ;
448+ }
449+ if ( ! route . deliveryTarget ) {
450+ return "no_delivery_target" ;
451+ }
452+ return undefined ;
453+ } ;
454+ const isRetryableFreshSessionRoutingFailure = (
455+ route : Awaited < ReturnType < typeof resolveDeliveryRouting > > ,
456+ ) : boolean => {
457+ const reason = deliveryRoutingFailureReason ( route ) ;
458+ if ( ! reason ) {
459+ return false ;
460+ }
461+ if ( reason === "unknown_channel" ) {
462+ return false ;
463+ }
464+ return true ;
465+ } ;
389466
390- const targetMode =
391- opts . deliveryTargetMode ??
392- effectiveDeliveryPlan . deliveryTargetMode ??
393- ( opts . to ? "explicit" : "implicit" ) ;
394- const resolvedAccountId = effectiveDeliveryPlan . resolvedAccountId ;
395- const resolved =
396- deliver && isDeliveryChannelKnown && deliveryChannel
397- ? resolveAgentOutboundTarget ( {
398- cfg,
399- plan : effectiveDeliveryPlan ,
400- targetMode,
401- validateExplicitTarget : true ,
402- } )
403- : {
404- resolvedTarget : null ,
405- resolvedTo : effectiveDeliveryPlan . resolvedTo ,
406- targetMode,
407- } ;
408- const resolvedTarget = resolved . resolvedTarget ;
409- const deliveryTarget = resolved . resolvedTo ;
410- const resolvedThreadId = deliveryPlan . resolvedThreadId ?? opts . threadId ;
411- const replyTransport =
412- deliveryPlugin ?. threading ?. resolveReplyTransport ?.( {
413- cfg,
414- accountId : resolvedAccountId ,
415- threadId : resolvedThreadId ,
416- } ) ?? null ;
417- const resolvedReplyToId = replyTransport ?. replyToId ?? undefined ;
418- const resolvedThreadTarget =
419- replyTransport && Object . hasOwn ( replyTransport , "threadId" )
420- ? ( replyTransport . threadId ?? null )
421- : ( resolvedThreadId ?? null ) ;
467+ let deliveryRouting = await resolveDeliveryRouting ( sessionEntry ) ;
468+ if ( isRetryableFreshSessionRoutingFailure ( deliveryRouting ) ) {
469+ const freshSessionEntry = await params . resolveFreshSessionEntryForDelivery ?.( ) ;
470+ if ( freshSessionEntry && freshSessionEntry !== sessionEntry ) {
471+ const freshRouting = await resolveDeliveryRouting ( freshSessionEntry ) ;
472+ if ( ! deliveryRoutingFailureReason ( freshRouting ) ) {
473+ if ( ! opts . json ) {
474+ runtime . log (
475+ `[delivery] refreshed session routing before final delivery (session=${ effectiveSessionKey ?? "unknown" } channel=${ freshRouting . deliveryChannel } )` ,
476+ ) ;
477+ }
478+ deliveryRouting = freshRouting ;
479+ }
480+ }
481+ }
482+ const {
483+ deliveryChannel,
484+ isDeliveryChannelKnown,
485+ resolvedAccountId,
486+ resolvedTarget,
487+ deliveryTarget,
488+ resolvedReplyToId,
489+ resolvedThreadTarget,
490+ } = deliveryRouting ;
422491
423492 let deliveryLoggedError = false ;
424493 const logDeliveryError = ( err : unknown ) => {
0 commit comments