import type { ChannelId } from "../../channels/plugins/types.js"; import { DEFAULT_CHAT_CHANNEL } from "../../channels/registry.js"; import type { ClawdbotConfig } from "../../config/config.js"; import { loadSessionStore, resolveAgentMainSessionKey, resolveStorePath, } from "../../config/sessions.js"; import { resolveMessageChannelSelection } from "../../infra/outbound/channel-selection.js"; import type { OutboundChannel } from "../../infra/outbound/targets.js"; import { resolveOutboundTarget, resolveSessionDeliveryTarget, } from "../../infra/outbound/targets.js"; export async function resolveDeliveryTarget( cfg: ClawdbotConfig, agentId: string, jobPayload: { channel?: "last" | ChannelId; to?: string; }, ): Promise<{ channel: Exclude; to?: string; accountId?: string; mode: "explicit" | "implicit"; error?: Error; }> { const requestedChannel = typeof jobPayload.channel === "string" ? jobPayload.channel : "last"; const explicitTo = typeof jobPayload.to === "string" ? jobPayload.to : undefined; const sessionCfg = cfg.session; const mainSessionKey = resolveAgentMainSessionKey({ cfg, agentId }); const storePath = resolveStorePath(sessionCfg?.store, { agentId }); const store = loadSessionStore(storePath); const main = store[mainSessionKey]; const preliminary = resolveSessionDeliveryTarget({ entry: main, requestedChannel, explicitTo, allowMismatchedLastTo: true, }); let fallbackChannel: Exclude | undefined; if (!preliminary.channel) { try { const selection = await resolveMessageChannelSelection({ cfg }); fallbackChannel = selection.channel; } catch { fallbackChannel = preliminary.lastChannel ?? DEFAULT_CHAT_CHANNEL; } } const resolved = fallbackChannel ? resolveSessionDeliveryTarget({ entry: main, requestedChannel, explicitTo, fallbackChannel, allowMismatchedLastTo: true, mode: preliminary.mode, }) : preliminary; const channel = resolved.channel ?? fallbackChannel ?? DEFAULT_CHAT_CHANNEL; const mode = resolved.mode as "explicit" | "implicit"; const toCandidate = resolved.to; if (!toCandidate) { return { channel, to: undefined, accountId: resolved.accountId, mode }; } const docked = resolveOutboundTarget({ channel, to: toCandidate, cfg, accountId: resolved.accountId, mode, }); return { channel, to: docked.ok ? docked.to : undefined, accountId: resolved.accountId, mode, error: docked.ok ? undefined : docked.error, }; }