





















@@ -338,6 +338,7 @@ export async function deliverAgentCommandResult(params: {
338338opts: AgentCommandOpts;
339339outboundSession: OutboundSessionContext | undefined;
340340sessionEntry: SessionEntry | undefined;
341+resolveFreshSessionEntryForDelivery?: () => Promise<SessionEntry | undefined>;
341342result: RunResult;
342343payloads: RunResult["payloads"];
343344}): Promise<AgentCommandDeliveryResult> {
@@ -349,76 +350,144 @@ export async function deliverAgentCommandResult(params: {
349350const turnSourceTo = opts.runContext?.currentChannelId ?? opts.to;
350351const turnSourceAccountId = opts.runContext?.accountId ?? opts.accountId;
351352const 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;
365353const 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+};
389466390-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;
422491423492let deliveryLoggedError = false;
424493const logDeliveryError = (err: unknown) => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。