UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

3,595 lines • 182 kB
import { c as normalizeOptionalLowercaseString, l as normalizeOptionalString, o as normalizeLowercaseStringOrEmpty } from "./string-coerce-1VuiLaaR.mjs";
import { t as pruneMapToMaxSize } from "./map-size-BlrH_CnE.mjs";
import { a as resolveGlobalSingleton } from "./global-singleton-0m-JziJW.mjs";
import { t as createDeferredCore } from "./deferred-D0La5CRk.mjs";
import { t as isAbortError } from "./abort-signal-QqAmLWTl.mjs";
import { t as formatErrorMessage } from "./errors-BvOkmQM5.mjs";
import { p as isDiagnosticsEnabled } from "./diagnostic-events-DT4ejwoa.mjs";
import { t as createSubsystemLogger } from "./subsystem-4NzR43uz.mjs";
import { l as resolveAgentIdFromSessionKey } from "./session-key-DY3MOX4N.mjs";
import { f as resolveSessionDispatchKind, h as parseAgentSessionKey, r as isAcpSessionKey } from "./session-key-utils-CDyBC9Gn.mjs";
import { c as resolveSessionStorePathCore } from "./paths-Bonddxfk.mjs";
import { d as resolveAgentWorkspaceDir, r as resolveAgentConfig } from "./agent-scope-config-BEk6-ThS.mjs";
import { _ as readAgentDatabaseAdmissionRefusal } from "./agent-database-admission-CRwW7FsI.mjs";
import { n as resolveGlobalDedupeCache } from "./dedupe-DKjkQntq.mjs";
import { t as normalizeChatType } from "./chat-type-qwvaeaJu.mjs";
import { t as buildConversationRef } from "./conversation-ref-BU3wU9j-.mjs";
import { u as sessionDeliveryChannel } from "./store-entry-ClyG-tia.mjs";
import { n as channelRouteDedupeKey } from "./channel-route-2bD3dZs2.mjs";
import "./message-channel-constants-B3vfipkP.mjs";
import { t as normalizeAnyChannelId } from "./registry-normalize-DKVgg-js.mjs";
import { n as normalizeMessageChannel } from "./message-channel-core-D9WI2Y8r.mjs";
import { t as _usingCtx } from "./usingCtx-BhiZp_rS.mjs";
import { o as measureDiagnosticsTimelineSpan } from "./diagnostics-timeline-Dn9nJTaj.mjs";
import { h as resolveSessionAgentId } from "./agent-scope-bJOokm5r.mjs";
import { d as withPluginRuntimeRegistryScope, o as getPluginRuntimeGatewayRequestScope } from "./gateway-request-scope-DV3FHtde.mjs";
import { d as getAgentEventLifecycleGeneration, t as assertAgentRunLifecycleGenerationCurrent } from "./agent-events-jWdQ_ESE.mjs";
import { d as sessionEntryCommitGuardOptions } from "./session-source-authority-h1UO3u0I.mjs";
import { d as normalizeVerboseLevel } from "./thinking.shared-BI1319dV.mjs";
import { t as applyMergePatch } from "./merge-patch-Lf-N96cZ.mjs";
import "./message-channel-AvA3r_Xp.mjs";
import { r as logVerbose } from "./globals-yEiTitH8.mjs";
import { n as getGlobalHookRunner, r as getGlobalPluginRegistry } from "./hook-runner-global-Cn3xHNvt.mjs";
import { l as getGroupThreadTurn } from "./group-thread-context-DLcO7Z-w.mjs";
import { a as createPluginSubagentRequesterContext, p as fireAndForgetHook, u as withClaimingHookAdmission } from "./hooks-CgZHhfMh.mjs";
import { D as setReplyPayloadMetadata, _ as isReplyPayloadStatusNotice, c as getReplyPayloadMetadata, d as isCommandReplyForDelivery, f as isFastModeAutoProgressPayload, o as copyReplyPayloadMetadata, w as readAskUserQuestionId, y as isReplyPayloadTerminalContent } from "./reply-payload-BEgsL2xJ.mjs";
import { l as normalizeTtsAutoMode, s as shouldCleanTtsDirectiveText } from "./tts-config-CX34pOp-.mjs";
import { c as isSessionWorkStartInvalidatedError, i as SessionRestartRecoveryTombstoneError } from "./work-start-error-Dh9d0ImY.mjs";
import { l as readChannelContextGatewayContextResolver } from "./admission-evidence-CcY0jAvs.mjs";
import { i as resolveCommandAuthorization } from "./command-auth-BHrKDij6.mjs";
import { o as prepareChannelParticipantObservation } from "./host-context-builder-DqHC41dw.mjs";
import { i as scopePreparedModelRuntimeLease } from "./prepared-model-runtime-generation-scope-Ck1wk1tN.mjs";
import "./thinking-7OesKvXK.mjs";
import { v as stripLegacyMediaContextFields } from "./media-facts-BIPREXi-.mjs";
import { t as collectTextContentBlocks } from "./content-blocks-DDtxq3Ff.mjs";
import { r as onSessionIdentityMutation } from "./session-lifecycle-events-CfTrpgyR.mjs";
import { t as getChannelPlugin } from "./registry-Bcrk1FVy.mjs";
import { r as resolveGroupSessionKey } from "./group-Ds6OVeC2.mjs";
import { o as conversationIdentityFromMsgContext } from "./session-accessor.sqlite-conversation-DXON_Nd3.mjs";
import { v as runExclusiveSessionLifecycleMutation } from "./session-lifecycle-admission-B5CJ-emz.mjs";
import { h as redactTranscriptMessage } from "./session-accessor.sqlite-transcript-store-D63Niwm2.mjs";
import { n as buildChannelUserTurnSender, o as preparePersistedUserTurnMessageForTranscriptWrite } from "./user-turn-transcript.metadata-DHDwAwgF.mjs";
import { r as appendTranscriptEventSync } from "./session-accessor.sqlite-transcript-write-ClP59_lJ.mjs";
import { i as GENERIC_EXTERNAL_RUN_FAILURE_TEXT, j as sanitizeUserFacingText } from "./user-facing-text-BCPDY-39.mjs";
import { c as patchSessionEntryCore, s as loadSessionEntryReadOnly } from "./session-accessor.sqlite-entry-DLa7_9ui.mjs";
import { E as prepareSessionPendingInputDedupeRecovery } from "./session-accessor-C3ljJ974.mjs";
import { i as readSessionEntryReadOnlyInWorker } from "./session-entry-read-runtime-BdnQjoL6.mjs";
import { n as isRestartRecoveryTombstone } from "./session-work-start-Bkld8CTK.mjs";
import { l as runConversationDatabaseWrite, o as resolveConversationRegistryScope } from "./conversation-registry-DcdOMU8T.mjs";
import { t as appendAssistantMessageToSessionTranscript } from "./transcript-CpqWjSbD.mjs";
import { r as normalizeExplicitSessionKey } from "./session-key-muxbzSVJ.mjs";
import { n as resolveSendPolicy } from "./send-policy-BbMAtCtM.mjs";
import { n as classifySessionStateActor } from "./session-state-events-tNQ7VRZz.mjs";
import { c as resolveEffectiveReplyRoute } from "./session-event-handoff-BkyE9Uzx.mjs";
import { t as isParentOwnedBackgroundAcpSession } from "./session-interaction-mode-CEQJGOLB.mjs";
import { c as readAcpSessionEntryAsync } from "./session-meta-CSN8P5u2.mjs";
import { q as waitForReplyBarrierSettlement } from "./reply-run-registry.state-BgHFgrrj.mjs";
import { y as RUN_STALE_TAKEOVER_MS } from "./diagnostic-run-activity-NzwvGiAW.mjs";
import { A as beginReplyOperationFinalizationWork, g as replyRunRegistry, o as forceClearReplyRunBySessionId } from "./reply-run-registry.registry-ICalZVvY.mjs";
import { t as hasInboundAudio } from "./inbound-media-D9dVgt41.mjs";
import "./reply-run-registry-1HN3_KMU.mjs";
import { d as markDiagnosticSessionProgress, n as logMessageDispatchStarted, t as logMessageDispatchCompleted } from "./diagnostic-jtgHaFVw.mjs";
import { i as resolveActiveEmbeddedRunSessionId } from "./active-run-projections-TAxZeJ_S.mjs";
import { a as isNativeCommandTurn, c as resolveCommandTurnContext, l as resolveCommandTurnTargetSessionKey } from "./command-turn-context-TJGbDzsZ.mjs";
import { r as isFinalizedInboundContext, t as finalizeInboundContext } from "./inbound-context-CRxwq3D_.mjs";
import "./lifecycle-BJGMGqxC.mjs";
import { c as findConversationTurnDeliveryByReplyTarget, d as markConversationDeliverySent, u as markConversationDeliveryReplied } from "./delivery-completion-CBsvdkT5.mjs";
import { n as createStructuredOutboundPayloadPlan } from "./payloads-k3x9706z.mjs";
import { a as resolveSendableOutboundReplyParts } from "./reply-payload-parts-XnYlwTNV.mjs";
import { i as extractShortModelName } from "./normalize-reply-B3mNRWkY.mjs";
import { g as shouldRetryReplyDispatch, h as resolveRoutedReplyDeliveryOutcome, n as bindReplyDispatcherConversationContext, o as prepareReplyPayloadForDispatcher, r as captureReplyDispatchDeliveryOutcome, s as waitForReplyDispatcherIdle, t as attachReplyDispatchUndeliveredFallback, u as ReplyDispatchDeliveryError } from "./reply-dispatcher-gTTFXVZE.mjs";
import { n as resolveAgentIdentity } from "./identity-DMes0XZ3.mjs";
import { a as toInternalMessageReceivedContext, c as toPluginInboundClaimPair, l as toPluginMessageContext, n as deriveInboundMessageHookContext, u as toPluginMessageReceivedEvent } from "./message-hook-mappers-4B6b-i9y.mjs";
import { a as hasOutboundReplyContent } from "./reply-payload-eiK8mKuN.mjs";
import { r as resolveGroupToolPolicy } from "./agent-tools.policy-B-XJsXps.mjs";
import { n as normalizeCommandBody, r as resolveTextCommand } from "./commands-registry-normalize-BUPL-PYW.mjs";
import { t as shouldHandleTextCommands } from "./commands-text-routing-CZ9Civxw.mjs";
import { a as isActiveRunSafeCommandTurn, r as findCommandByNativeName } from "./commands-registry-Dr2bNuzu.mjs";
import { t as registerReplyDispatcherSettledTask } from "./dispatch-dispatcher-BKxE1A-W.mjs";
import { C as isPluginOwnedSessionBindingRecord } from "./current-conversation-bindings.kernel-DWqaaBL6.mjs";
import { i as readConversationBindingRouteFacts } from "./conversation-binding-route-facts-cMEJL1Lo.mjs";
import { t as getSessionBindingService } from "./session-binding-service-wvWqRl2A.mjs";
import { a as resolveConversationBindingContextFromMessage } from "./acp-reset-target-j7GMtDbc.mjs";
import { n as resolveRoutedDeliveryThreadId, t as isSlackDirectRoutedThreadTurn } from "./routed-delivery-thread-Dew4dOMp.mjs";
import { a as resolveDispatchConversationBinding, n as assertPreparedConversationBindingRouteCurrent, r as readPreparedConversationBindingRouteCurrent, t as assertPreparedConversationBindingRoute } from "./session-conversation-binding-Ct7uOkBw.mjs";
import { a as withFullRuntimeReplyConfig, c as stageRemoteInboundMediaIfNeeded, d as resolveAuthorizedSessionResetCommand, f as canReplaceRestartTombstoneFromParent, l as bindPreparedReplyDispatchRuntime, o as resolveReplyPolicyConversationType, s as normalizeMessageTimestampMs, t as resolveRunTypingPolicy } from "./typing-policy-DeG6P7eA.mjs";
import { C as reserveReplyAdmissionTicket, S as REPLY_ADMISSION_TICKET, a as isReplyOperationStalledBeforeOutput, m as buildTerminalAgentRunFailureReplyPayload, r as STALLED_TURN_NOTICE_TEXT, s as isDuplicateRestartRecoverySource, t as resolveTurnCommentaryProgressOwner, y as renderPostCompactionModelFailurePayload } from "./commentary-progress-owner-DcmR1wPD.mjs";
import { a as resolveReplyOperationRunState, n as recordReplyOperationAgentTurn, t as REPLY_OPERATION_RUN_STATE } from "./reply-operation-run-state-DXeGMR72.mjs";
import { a as setChannelSourceTurnId, n as readChannelSourceTurnId, s as shouldMintChannelSourceTurnId, t as buildChannelSourceTurnId } from "./source-turn-id-CdR123OU.mjs";
import { a as isCaptionedFinalTextPayload, c as DispatchReplyOperationAbortedError, d as runWithDispatchAbortSignal, i as cleanDeferredFinalText, l as createAbortAwareDispatcher, o as mergeDeferredFinalText, r as buildCaptionedFinalTextFallback, s as shouldDeferFinalTtsText, t as finalizeDispatchAndAudit, u as isDispatchReplyOperationAbortedError } from "./dispatch-from-config.finalize-BkelvVWI.mjs";
import { n as hasTrustedMessageAuditListeners, t as emitTrustedMessageAuditEvent } from "./message-audit-events-CzlrKIaw.mjs";
import { t as createTtsDirectiveTextStreamCleaner } from "./directives-N8T4kLmk.mjs";
import { _ as recoverBlockReplySources, a as hasAskUserPayload, c as maybeApplyTtsToReplyPayload, d as shouldDeliverDespiteSourceReplySuppression, f as createBlockReplyContentKey, l as prepareReplyPayloadForSideEffects, m as createBlockReplySource, o as hasExecApprovalPayload, s as hasExecApprovalUnavailablePayload, u as requiresDurableToolResultDelivery, v as setBlockReplyDelivery } from "./dispatch-from-config.payloads-Bju_QM-B.mjs";
import { n as suppressPendingFinalDelivery } from "./dispatch-from-config.pending-final-Dmj3iCWo.mjs";
import { n as runAgentHarnessBeforeMessageWriteHook } from "./hook-helpers-DQD6Kn21.mjs";
import { S as isDispatchFinalReplySessionWriterAuthorized } from "./delivery-queue-recovery-BXQ7PAEc.mjs";
import { m as normalizeAgentPlanSteps, u as formatPlanChecklistLines } from "./streaming-DF0Ecn4m.mjs";
import { n as createInternalHookEvent, u as triggerInternalHook } from "./internal-hooks-eyE9vom5.mjs";
import { i as isAskUserPromptPending } from "./ask-user-tool-DfDCY7gI.mjs";
import { t as settleProgressVisibilityCallbackResult } from "./progress-visibility-DVUJibF4.mjs";
import { o as takeCommandSessionMetadataChanges } from "./commands-goal-D1silaAQ.mjs";
import { r as resolveReplyCompletion } from "./reply-completion-B5n1Cnxm.mjs";
import { t as createDiagnosticMessageLifecycle } from "./message-lifecycle-C7xvzKWs.mjs";
import { t as prepareTtsPreferences } from "./tts-preferences-O074cDlX.mjs";
import { a as resolveTurnModelOverride, i as createShouldEmitVerboseProgress, o as resolveVisibleRepliesPolicy, r as resolveStableMessageToolAvailability, t as resolveReplyMessageToolAvailability } from "./session-stable-reply-mode-DzEPecSf.mjs";
import { t as isRecoverableTerminalSessionStatus } from "./terminal-status-zjRF_Q7R.mjs";
import { d as resolveWorkerPlacementArchiveRestoreError, l as readSessionWorkerPlacementAsync, o as prepareSessionWorkerPlacementMutationCheckAsync } from "./session-placement-lifecycle-D16TB6AJ.mjs";
import { i as runWithReplyOperationLifecycleAdmission, n as isReplyProfilerEnabled, r as admitReplyTurn, t as createReplyTimingTracker } from "./reply-timing-tracker-BEqZ21mF.mjs";
import { n as resolveReplyTurnKind } from "./reply-turn-kind-CGA3YPu0.mjs";
import { a as loadReplyMediaPathsRuntime, i as loadPreparedModelRuntime, n as loadFastApproveRuntime, o as loadRouteReplyRuntime, r as loadGetReplyFromConfigRuntime, s as loadRuntimePlugins, t as loadAbortRuntime } from "./dispatch-from-config.runtime.js";
import { t as noteDispatchProcessedOutcome } from "./dispatch-processed-outcome-BSdYjymX.mjs";
import { i as buildPluginBindingErrorText, l as hasShownPluginBindingFallbackNotice, m as toPluginConversationBinding, o as buildPluginBindingUnavailableText, r as buildPluginBindingDeclinedText, u as markPluginBindingFallbackNoticeShown } from "./conversation-binding-e4SMpsaM.mjs";
import { a as resolveSourceReplyExpectation, n as isUnauthorizedTextSlashCommand, o as resolveSourceReplyVisibilityPolicy, s as isExplicitCommandTurnContext } from "./source-reply-delivery-mode-D_BY_QoJ.mjs";
import { n as claimPendingConversationTurnReply } from "./conversation-turns-DdfR2-dZ.mjs";
import "./user-turn-transcript-DuAfBkUt.mjs";
import { i as buildPersistedUserTurnMessage } from "./user-turn-transcript.message--uwt9Vax.mjs";
import { t as resolveOriginMessageProvider } from "./origin-routing-B3FgSjbD.mjs";
import { a as resolveReplyDeliveryAccountId, o as resolveReplyToMode, t as createReplyDeliveryContext } from "./reply-threading-ChfJS7JV.mjs";
import { t as getGatewayNativeApprovalRuntime } from "./approval-gateway-runtime-context-Dv8llXGl.mjs";
import { r as hasActiveNativeApprovalRoute } from "./approval-native-route-coordinator-CTtlRjWk.mjs";
import { r as resolveSessionModelRef } from "./session-model-ref-CS-wdkCn.mjs";
import { i as PLUGIN_COMMAND_DISPATCH, r as matchPluginCommandInvocation, t as createPluginCommandRuntime } from "./plugin-command-runtime-DOHxS-L8.mjs";
import { r as resolveCommandChannel } from "./commands-context-BWTNsJMW.mjs";
import { n as resolveCommandContextText } from "./context-text-XBr5_KXU.mjs";
import crypto from "node:crypto";
//#region src/auto-reply/reply/dispatch-session-refresh-error.ts
/** Pre-dispatch session state changed before any user-visible work began. */
var DispatchSessionRefreshRequiredError = class extends Error {
	constructor(cause) {
		super(cause.message, { cause });
		this.name = "DispatchSessionRefreshRequiredError";
	}
};
//#endregion
//#region src/auto-reply/reply/dispatch-from-config.context.ts
function shouldLetSlackRoutedThreadBypassBusyReplyOperation(params) {
	return isSlackDirectRoutedThreadTurn(params.ctx) && params.activeOperation?.routeThreadId !== void 0 && params.routeThreadId !== void 0 && String(params.activeOperation.routeThreadId) !== String(params.routeThreadId);
}
async function resolveSessionStoreLookup(ctx, cfg, assertCurrent) {
	assertCurrent?.();
	const targetSessionKey = resolveCommandTurnTargetSessionKey(ctx);
	const sessionKey = normalizeOptionalString(targetSessionKey ?? ctx.SessionKey);
	if (!sessionKey) return {};
	const agentId = resolveSessionAgentId({
		sessionKey,
		config: cfg,
		fallbackAgentId: ctx.AgentId
	});
	const target = {
		agentId,
		sessionKey,
		storePath: resolveSessionStorePathCore(cfg.session?.store, { agentId })
	};
	try {
		const entry = await readSessionEntryReadOnlyInWorker({
			...target,
			readConsistency: "latest",
			clone: false
		}, assertCurrent);
		assertCurrent?.();
		return {
			...target,
			entry,
			store: entry ? { [sessionKey]: entry } : void 0
		};
	} catch {
		assertCurrent?.();
		return target;
	}
}
async function resolveBoundAcpDispatchSessionKey(params) {
	if (resolveCommandTurnTargetSessionKey(params.ctx)) return;
	const preparedRoute = readConversationBindingRouteFacts(params.ctx);
	const bindingContext = preparedRoute?.conversation ?? resolveConversationBindingContextFromMessage({
		cfg: params.cfg,
		ctx: params.ctx
	});
	if (!bindingContext) return;
	const readCurrentBinding = () => preparedRoute ? readPreparedConversationBindingRouteCurrent(params.ctx) : getSessionBindingService().resolveByConversationAsync(bindingContext);
	const binding = await readCurrentBinding();
	assertPreparedConversationBindingRoute(params.ctx, binding);
	const targetSessionKey = normalizeOptionalString(binding?.targetSessionKey);
	if (!binding || !targetSessionKey || !isAcpSessionKey(targetSessionKey)) return;
	if (isPluginOwnedSessionBindingRecord(binding)) return;
	const { bindingId, boundAt, targetSessionKey: boundTargetSessionKey, targetKind } = binding;
	const scope = { ...binding.conversation };
	await getSessionBindingService().touchAsync(bindingId, void 0, scope);
	const currentBinding = await readCurrentBinding();
	assertPreparedConversationBindingRoute(params.ctx, currentBinding);
	if (currentBinding && (currentBinding.bindingId !== bindingId || currentBinding.boundAt !== boundAt || currentBinding.targetSessionKey !== boundTargetSessionKey || currentBinding.targetKind !== targetKind || currentBinding.conversation.channel !== scope.channel || currentBinding.conversation.accountId !== scope.accountId)) throw new DispatchSessionRefreshRequiredError(/* @__PURE__ */ new Error("conversation binding changed while recording activity"));
	const currentTargetSessionKey = normalizeOptionalString(currentBinding?.targetSessionKey);
	return currentBinding && currentTargetSessionKey && isAcpSessionKey(currentTargetSessionKey) && !isPluginOwnedSessionBindingRecord(currentBinding) ? preparedRoute ? normalizeOptionalString(params.ctx.SessionKey) : currentTargetSessionKey : void 0;
}
function resolveDispatchResetAdmission(params) {
	const { ctx, entry } = params;
	const parentSessionKey = normalizeOptionalString(ctx.ParentSessionKey);
	const commandTarget = resolveCommandTurnTargetSessionKey(ctx);
	const nativeCommandTarget = isNativeCommandTurn(ctx.CommandTurn) ? commandTarget : void 0;
	const actorType = classifySessionStateActor({ inputProvenance: ctx.InputProvenance }).actorType;
	const mayReplaceRestartTombstoneFromParent = canReplaceRestartTombstoneFromParent({
		actorType,
		entry,
		hasParentForkSource: true,
		hasPluginOwnedBinding: params.hasPluginOwnedBinding,
		inboundAccessAuthorized: ctx.InboundAccessAuthorized,
		inboundEventKind: ctx.InboundEventKind,
		nativeCommandTarget: commandTarget,
		sessionKey: params.sessionKey
	});
	let hasParentForkSource = false;
	if (mayReplaceRestartTombstoneFromParent && parentSessionKey && parentSessionKey !== params.sessionKey && params.storePath) try {
		hasParentForkSource = Boolean(loadSessionEntryReadOnly({
			agentId: params.agentId,
			storePath: params.storePath,
			sessionKey: parentSessionKey,
			readConsistency: "latest",
			clone: false
		})?.sessionId);
	} catch {
		hasParentForkSource = false;
	}
	const allowRestartTombstoneParentFork = mayReplaceRestartTombstoneFromParent && hasParentForkSource;
	let resetTriggered = false;
	if (!params.hasPluginOwnedBinding && entry?.pluginOwnerId === void 0 && ctx.InboundAccessAuthorized === true && ctx.InboundEventKind !== "room_event" && (nativeCommandTarget === void 0 || nativeCommandTarget === params.sessionKey) && actorType === "human") {
		const normalizedChatType = normalizeChatType(ctx.ChatType);
		const isGroup = normalizedChatType != null && normalizedChatType !== "direct" || Boolean(resolveGroupSessionKey(ctx));
		const { resetCommand } = resolveAuthorizedSessionResetCommand({
			agentId: params.agentId,
			cfg: params.cfg,
			commandAuthorized: ctx.CommandAuthorized,
			ctx,
			isGroup
		});
		resetTriggered = resetCommand.matchedResetTriggerLower !== void 0;
	}
	return {
		resetTriggered,
		allowRestartTombstoneParentFork,
		allowRestartTombstoneReset: resetTriggered
	};
}
//#endregion
//#region src/auto-reply/reply/dispatch-from-config.audit.ts
const completedInboundAuditReasons = /* @__PURE__ */ new Map([
	["fast_abort", "fast_abort"],
	["plugin-bound-handled", "plugin_bound_handled"],
	["plugin-bound-fallback-missing-plugin", "plugin_bound_unavailable"],
	["plugin-bound-fallback-no-handler", "plugin_bound_unavailable"],
	["plugin-bound-declined", "plugin_bound_declined"],
	["before_dispatch_handled", "before_dispatch_handled"],
	["acp_dispatch", "acp_dispatch_completed"],
	["acp_empty_prompt", "acp_dispatch_empty"],
	["active_run_injected", "active_run_injected"]
]);
const skippedInboundAuditReasons = /* @__PURE__ */ new Map([["duplicate", "duplicate"], ["reply-operation-active", "reply_operation_active"]]);
function resolveInboundMessageAuditTerminal(outcome, reason) {
	if (reason === "plugin-bound-error" || reason?.startsWith("acp_error:")) return {
		status: "failed",
		outcome: "failed",
		errorCode: "message_processing_failed",
		reasonCode: reason === "plugin-bound-error" ? "plugin_bound_error" : "acp_dispatch_failed"
	};
	if (reason === "reply_operation_aborted" || reason === "acp_aborted") return {
		status: "blocked",
		outcome: "skipped",
		reasonCode: reason === "reply_operation_aborted" ? "reply_operation_aborted" : "acp_dispatch_aborted"
	};
	if (outcome === "completed") {
		const reasonCode = completedInboundAuditReasons.get(reason);
		return {
			status: "succeeded",
			outcome: "completed",
			...reasonCode ? { reasonCode } : {}
		};
	}
	if (outcome === "skipped") {
		const reasonCode = skippedInboundAuditReasons.get(reason);
		return {
			status: "blocked",
			outcome: "skipped",
			...reasonCode ? { reasonCode } : {}
		};
	}
	return {
		status: "failed",
		outcome: "failed",
		errorCode: "message_processing_failed"
	};
}
function emitInboundMessageAuditTerminal(params) {
	const { ctx, cfg } = params;
	const occurredAt = Date.now();
	const sessionKey = normalizeOptionalString(ctx.SessionKey) ?? normalizeOptionalString(ctx.CommandTargetSessionKey);
	const actorId = normalizeOptionalString(ctx.SenderId);
	const accountId = normalizeOptionalString(ctx.AccountId);
	const conversationId = normalizeOptionalString(ctx.NativeChannelId) ?? normalizeOptionalString(ctx.OriginatingTo) ?? normalizeOptionalString(ctx.To) ?? normalizeOptionalString(ctx.From);
	const messageId = normalizeOptionalString(ctx.MessageSidFull) ?? normalizeOptionalString(ctx.MessageSid) ?? normalizeOptionalString(ctx.MessageSidFirst) ?? normalizeOptionalString(ctx.MessageSidLast);
	const terminalFields = resolveInboundMessageAuditTerminal(params.terminal.outcome, params.terminal.options?.reason);
	let agentId = normalizeOptionalString(ctx.AgentId);
	try {
		agentId = resolveSessionAgentId({
			sessionKey,
			config: cfg,
			agentId: ctx.AgentId
		});
	} catch {}
	try {
		emitTrustedMessageAuditEvent({
			occurredAt,
			kind: "message",
			action: "message.inbound.processed",
			...terminalFields,
			actorType: actorId ? "channel_sender" : "system",
			actorId: actorId ?? "gateway",
			...agentId ? { agentId } : {},
			...normalizeOptionalString(params.observedRunId) ? { runId: normalizeOptionalString(params.observedRunId) } : {},
			direction: "inbound",
			channel: normalizeLowercaseStringOrEmpty(ctx.OriginatingChannel) || normalizeLowercaseStringOrEmpty(ctx.Surface) || normalizeLowercaseStringOrEmpty(ctx.Provider) || "unknown",
			conversationKind: normalizeChatType(ctx.ChatType) ?? "unknown",
			durationMs: Math.max(0, occurredAt - params.startedAt),
			resultCount: params.counts.tool + params.counts.block + params.counts.final,
			...accountId ? { accountId } : {},
			...conversationId ? { conversationId } : {},
			...messageId ? { messageId } : {}
		});
	} catch {}
}
/**
* Captures one terminal event for the reply-processing boundary. Channel admission and
* pre-dispatch drops remain outside this boundary and need their own ingress projection.
*/
function createInboundMessageAuditTerminal(params) {
	if (!hasTrustedMessageAuditListeners()) return;
	const startedAt = Date.now();
	let notedTerminal;
	let observedRunId = normalizeOptionalString(params.replyOptions?.runId);
	let finished = false;
	const emitTerminal = (terminal, counts) => {
		if (finished) return;
		finished = true;
		emitInboundMessageAuditTerminal({
			cfg: params.cfg,
			counts,
			ctx: params.ctx,
			observedRunId,
			startedAt,
			terminal
		});
	};
	return {
		note(outcome, options) {
			notedTerminal = {
				outcome,
				...options ? { options } : {}
			};
		},
		observeRunId(runId) {
			observedRunId = normalizeOptionalString(runId) ?? observedRunId;
		},
		finishSuccess(result) {
			emitTerminal(notedTerminal ?? { outcome: "completed" }, result.counts);
		},
		finishError() {
			let counts = {
				tool: 0,
				block: 0,
				final: 0
			};
			try {
				counts = params.dispatcher.getQueuedCounts();
			} catch {}
			emitTerminal({ outcome: "error" }, counts);
		}
	};
}
//#endregion
//#region src/auto-reply/reply/dispatch-from-config.events.ts
function admittedSessionSettingsRestrictRuntime(settings) {
	return settings?.permissionMode !== void 0 && settings.permissionMode !== "full" || settings?.toolOverrides !== void 0 && Object.keys(settings.toolOverrides).length > 0;
}
function createReplyDispatchEvent(params) {
	const { shouldSendToolSummaries, ...event } = params;
	return Object.defineProperty(event, "shouldSendToolSummaries", {
		enumerable: true,
		get: shouldSendToolSummaries
	});
}
//#endregion
//#region src/auto-reply/reply/dispatch-from-config.reply-dispatch-hook.ts
function runReplyDispatchHook(state, options) {
	const { hookRunner, params } = state;
	if (!state.allowInboundHandlers || admittedSessionSettingsRestrictRuntime(params.replyOptions?.admittedSessionSettings) || !hookRunner?.hasHooks("reply_dispatch", { dispatchKind: state.dispatchKind })) return;
	const run = () => state.runWithDispatchLifecycleAdmission(async () => {
		return await runWithDispatchAbortSignal(options.isTailDispatch ? state.getDispatchAbortSignal() : state.getPreDispatchAbortSignal(), async () => {
			const shouldSendFullToolDetails = await state.shouldEmitFullVerboseProgressAsync();
			state.assertProgressCurrent();
			return hookRunner.runReplyDispatch(createReplyDispatchEvent({
				ctx: state.ctx,
				runId: params.replyOptions?.runId,
				sessionKey: state.acpDispatchSessionKey,
				toolsAllow: params.replyOptions?.toolsAllow,
				images: params.replyOptions?.images,
				inboundAudio: state.inboundAudio,
				sessionTtsAuto: state.sessionTtsAuto,
				ttsChannel: state.deliveryChannel,
				suppressUserDelivery: state.suppressHookUserDelivery,
				suppressReplyLifecycle: state.suppressHookReplyLifecycle,
				sourceReplyDeliveryMode: state.sourceReplyDeliveryMode,
				shouldRouteToOriginating: state.shouldRouteToOriginating,
				originatingChannel: state.routeReplyChannel,
				originatingTo: state.routeReplyTo,
				originatingAccountId: state.replyContextAccountId,
				originatingThreadId: state.routeReplyThreadId,
				originatingChatType: state.replyRoute.chatType,
				shouldSendToolSummaries: options.shouldSendToolSummaries,
				shouldSendToolSummariesAsync: options.shouldSendToolSummariesAsync,
				shouldSendFullToolDetails,
				shouldSendFullToolDetailsAsync: state.shouldEmitFullVerboseProgressAsync,
				sendPolicy: state.sendPolicy,
				...options.isTailDispatch ? { isTailDispatch: true } : {}
			}), withClaimingHookAdmission({
				cfg: state.cfg,
				dispatchKind: state.dispatchKind,
				dispatcher: state.dispatchHookDispatcher,
				abortSignal: state.getPreDispatchAbortSignal() ?? params.replyOptions?.abortSignal,
				onReplyStart: params.replyOptions?.onReplyStart,
				onAgentRunStart: params.replyOptions?.onAgentRunStart,
				userTurnTranscriptRecorder: params.replyOptions?.userTurnTranscriptRecorder,
				prepareAssistantTranscriptMessage: params.replyOptions?.prepareAssistantTranscriptMessage,
				recordProcessed: state.recordProcessed,
				markIdle: state.markIdle
			}, options.isTailDispatch ? void 0 : { prepare: state.assertCurrentBindingRoute }));
		}, state.trackDispatchLifecycleWork);
	});
	return options.isTailDispatch ? run() : state.traceReplyPhase("reply.reply_dispatch_hooks", run);
}
//#endregion
//#region src/auto-reply/reply/dispatch-from-config.session-metadata.ts
function createSessionMetadataChangeNotifier(onSessionMetadataChanges) {
	const notifiedKeys = /* @__PURE__ */ new Set();
	const routeState = {};
	const notifySessionMetadataChanges = (changes) => {
		if (!changes?.length) return;
		const freshChanges = changes.filter((change) => {
			const key = JSON.stringify([
				change.sessionKey,
				change.agentId ?? null,
				change.reason
			]);
			if (notifiedKeys.has(key)) return false;
			notifiedKeys.add(key);
			return true;
		});
		if (freshChanges.length === 0) return;
		routeState.sessionMetadataChangesForResult = [...routeState.sessionMetadataChangesForResult ?? [], ...freshChanges];
		onSessionMetadataChanges?.(freshChanges);
	};
	return {
		notifySessionMetadataChanges,
		routeState
	};
}
//#endregion
//#region src/auto-reply/reply/dispatch-from-config.transcript.ts
function transcriptMirrorExpectations(mirror) {
	return {
		...mirror.expectedSessionId ? { expectedSessionId: mirror.expectedSessionId } : {},
		...mirror.expectedLifecycleRevision !== void 0 ? { expectedLifecycleRevision: mirror.expectedLifecycleRevision } : {},
		...mirror.expectedWriterRunId !== void 0 ? { expectedWriterRunId: mirror.expectedWriterRunId } : {}
	};
}
async function mirrorDeliveredReplyToTranscript(params) {
	const mirror = params.metadata;
	if (!mirror || mirror.transcriptOwner) return;
	try {
		const result = await appendAssistantMessageToSessionTranscript({
			sessionKey: mirror.sessionKey,
			agentId: mirror.agentId,
			...transcriptMirrorExpectations(mirror),
			text: mirror.text,
			mediaUrls: mirror.preferText && mirror.text ? void 0 : mirror.mediaUrls,
			idempotencyKey: mirror.idempotencyKey,
			...mirror.deliveryMirror ? { deliveryMirror: mirror.deliveryMirror } : {},
			...mirror.storePath ? { storePath: mirror.storePath } : {},
			updateMode: "inline",
			config: params.cfg,
			beforeMessageWrite: runAgentHarnessBeforeMessageWriteHook
		});
		if (!result.ok) logVerbose(`dispatch-from-config: transcript mirror skipped: ${result.reason}`);
	} catch (error) {
		logVerbose(`dispatch-from-config: transcript mirror failed after delivery: ${formatErrorMessage(error)}`);
	}
}
function transcriptMirrorForDeliveredPayload(metadata, payload) {
	const sendable = resolveSendableOutboundReplyParts(payload);
	if (!sendable.text && sendable.mediaUrls.length === 0) return;
	return {
		...metadata,
		text: sendable.text,
		mediaUrls: sendable.mediaUrls.length > 0 ? sendable.mediaUrls : void 0
	};
}
function captureDeliveredTranscriptMirror(params) {
	if (!params.metadata || !params.dispatcher.appendBeforeDeliver) return () => params.metadata?.transcriptOwner ? void 0 : params.metadata;
	const metadata = params.metadata;
	let deliveredMetadata;
	let observedFinal = false;
	const { idempotencyKey, sessionKey } = metadata;
	params.dispatcher.appendBeforeDeliver((payload, info) => {
		if (info.kind !== "final") return payload;
		const payloadMetadata = getReplyPayloadMetadata(payload);
		if (payloadMetadata?.finalDeliveryCapture !== params.captureToken) return payload;
		observedFinal = true;
		const payloadMirror = payloadMetadata?.sourceReplyTranscriptMirror;
		if (payloadMirror && payloadMirror.idempotencyKey === idempotencyKey && payloadMirror.sessionKey === sessionKey) deliveredMetadata = transcriptMirrorForDeliveredPayload({
			...payloadMirror,
			...transcriptMirrorExpectations(metadata),
			storePath: metadata.storePath
		}, payload);
		else if (!payloadMirror && !metadata.transcriptOwner && (!idempotencyKey || metadata.deliveryMirror)) deliveredMetadata = transcriptMirrorForDeliveredPayload(metadata, payload);
		return payload;
	});
	return () => observedFinal ? deliveredMetadata : metadata.transcriptOwner ? void 0 : metadata;
}
//#endregion
//#region src/auto-reply/reply/dispatch-from-config.choose-route.ts
async function chooseDispatchRoute(state) {
	const { acpDispatchSessionKey, attachSourceReplyDeliveryMode, cfg, commitInboundDedupeIfClaimed, completeDispatchReplyOperation, ctx, deliveryChannel, dispatcher, getPreDispatchAbortSignal, hookRunner, isRoutedReplyDelivered, markIdle, markInboundDedupeReplayUnsafe, params, recordProcessed, replyContextAccountId, replyRoute, resolvePreparedTranscriptBinding, routeReplyChannel, routeReplyThreadId, routeReplyTo, runWithDispatchLifecycleAdmission, sendPayloadAsync, sessionAgentId, sessionKey, sessionStoreEntry, sessionTtsAuto, shouldEmitVerboseProgressAsync, shouldRouteToOriginating, traceReplyPhase, trackDispatchLifecycleWork, turnLedger } = state;
	const shouldSuppressProgressDelivery = async () => state.sendPolicyDenied || state.suppressDelivery && !await shouldDeliverVerboseProgressDespiteSourceSuppression();
	const shouldSendToolSummaries = () => params.replyOptions?.suppressToolProgressMessages !== true && state.shouldEmitVerboseProgress();
	const shouldSendToolSummariesAsync = async () => params.replyOptions?.suppressToolProgressMessages !== true && await shouldEmitVerboseProgressAsync();
	const { notifySessionMetadataChanges, routeState } = createSessionMetadataChangeNotifier(params.onSessionMetadataChanges);
	const allowsVerboseProgressDespiteSourceSuppression = () => state.suppressAutomaticSourceDelivery && state.sourceReplyDeliveryMode === "message_tool_only" && ctx.InboundEventKind !== "room_event" && !state.sendPolicyDenied;
	const shouldDeliverVerboseProgressDespiteSourceSuppression = async () => allowsVerboseProgressDespiteSourceSuppression() && await shouldSendToolSummariesAsync();
	const shouldSuppressProgressDeliverySync = () => state.sendPolicyDenied || state.suppressDelivery && !(allowsVerboseProgressDespiteSourceSuppression() && shouldSendToolSummaries());
	const shouldDeliverForcedToolProgressDespiteSourceSuppression = () => allowsVerboseProgressDespiteSourceSuppression() && params.replyOptions?.forceToolResultProgress === true;
	let finalReplyDeliveryStarted = false;
	const isSessionWriterDeliveryAuthorized = (payload) => isDispatchFinalReplySessionWriterAuthorized(payload, sessionStoreEntry.storePath, sessionKey);
	const shouldSuppressLateTextOnlyToolProgress = (payload) => finalReplyDeliveryStarted && !requiresDurableToolResultDelivery(payload);
	let pendingCommentaryProgress = null;
	const deliverCommentaryProgressMessage = async (text) => {
		if (!await shouldSendToolSummariesAsync() || await shouldSuppressProgressDelivery()) return;
		if (state.isDispatchOperationAborted()) return;
		const payload = { text: `💬 ${text}` };
		if (shouldSuppressLateTextOnlyToolProgress(payload)) return;
		state.assertProgressCurrent();
		if (shouldRouteToOriginating) await sendPayloadAsync(payload);
		else {
			markInboundDedupeReplayUnsafe();
			turnLedger.sendQueued("tool", payload);
		}
	};
	const flushPendingCommentaryProgress = async () => {
		const pending = pendingCommentaryProgress;
		pendingCommentaryProgress = null;
		const text = pending?.text.trim();
		if (!text) return;
		await deliverCommentaryProgressMessage(text);
	};
	const noteCommentaryProgress = async (payload) => {
		const itemId = payload.itemId?.trim() || void 0;
		const text = payload.progressText ?? "";
		const updatesBufferedItem = pendingCommentaryProgress !== null && (pendingCommentaryProgress.itemId !== void 0 && pendingCommentaryProgress.itemId === itemId || pendingCommentaryProgress.text.trim() === text.trim());
		if (!text.trim()) {
			if (updatesBufferedItem) pendingCommentaryProgress = null;
			return;
		}
		if (pendingCommentaryProgress && !updatesBufferedItem) await flushPendingCommentaryProgress();
		pendingCommentaryProgress = {
			itemId,
			text
		};
	};
	const shouldSuppressMessageToolOnlyTextErrorProgress = async (payload) => {
		if (state.sourceReplyDeliveryMode !== "message_tool_only" || await state.shouldEmitFullVerboseProgressAsync() || payload.isError !== true) return false;
		return !resolveSendableOutboundReplyParts(payload).hasMedia && !hasExecApprovalPayload(payload);
	};
	const captionedFinalTtsContext = {
		cfg,
		preparedTtsPreferences: state.preparedTtsPreferences,
		ttsAuto: sessionTtsAuto,
		agentId: sessionAgentId,
		channelId: deliveryChannel,
		accountId: replyRoute.accountId,
		inboundAudio: state.inboundAudio
	};
	const deferFinalTtsText = shouldDeferFinalTtsText(captionedFinalTtsContext);
	const cleanDeferredFinalDirectives = shouldCleanTtsDirectiveText(captionedFinalTtsContext);
	const blockDeliveryOutcomes = /* @__PURE__ */ new Map();
	const recordBlockOutcome = (payload, outcome) => {
		setBlockReplyDelivery(outcome, payload);
		if (getReplyPayloadMetadata(payload)?.independentDeliveryIntentId !== void 0) return;
		const key = createBlockReplyContentKey(payload);
		const outcomes = blockDeliveryOutcomes.get(key) ?? [];
		outcomes.push(outcome);
		blockDeliveryOutcomes.set(key, outcomes);
	};
	const sendTrackedBlockReply = (operation) => {
		const payload = operation.kind === "prepared" ? operation.plan.payload : operation.payload;
		const delivery = operation.kind === "prepared" ? turnLedger.sendPreparedQueued("block", operation.plan) : turnLedger.sendQueued("block", payload);
		recordBlockOutcome(payload, delivery.queued ? delivery.outcome?.then((outcome) => ({
			outcome,
			pending: delivery.hasPendingDelivery?.()
		})) ?? Promise.resolve({ outcome: "failed-deliver" }) : Promise.resolve({ outcome: "cancelled" }));
		return delivery;
	};
	const recordRoutedBlockReplyDelivery = (payload, result) => {
		if (!result) {
			recordBlockOutcome(payload, Promise.resolve({ outcome: "cancelled" }));
			return;
		}
		const outcome = resolveRoutedReplyDeliveryOutcome(result);
		recordBlockOutcome(payload, Promise.resolve({
			outcome,
			pending: result.queueCustody === "held" || result.ambiguous === true
		}));
		return outcome;
	};
	const getBlockReplyOutcome = async (payload, abortSignal) => {
		const outcomes = blockDeliveryOutcomes.get(createBlockReplyContentKey(payload));
		if (!outcomes || abortSignal?.aborted) return;
		const settled = await runWithDispatchAbortSignal(abortSignal, () => Promise.all(outcomes));
		return settled.find(({ outcome }) => outcome === "delivered") ?? settled.find(({ outcome, pending }) => pending || !shouldRetryReplyDispatch(outcome)) ?? settled[0];
	};
	const sendFinalPayload = async (inputPayload, options = {}) => {
		const abortSignal = options.abortSignal === false ? void 0 : options.abortSignal ?? state.getDispatchAbortSignal();
		const throwIfFinalDeliveryAborted = () => {
			if (abortSignal?.aborted) throw new DispatchReplyOperationAbortedError();
		};
		throwIfFinalDeliveryAborted();
		await flushPendingCommentaryProgress();
		throwIfFinalDeliveryAborted();
		const preparation = prepareReplyPayloadForDispatcher(dispatcher, "final", inputPayload);
		if (preparation.kind === "suppress") {
			await suppressPendingFinalDelivery(inputPayload, { preserveActivity: state.replyOperationRunState.heartbeat !== void 0 });
			return {
				queuedFinal: false,
				routedFinalCount: 0,
				suppressionReason: preparation.reason
			};
		}
		const payload = renderPostCompactionModelFailurePayload(preparation.payload);
		const payloadMetadata = getReplyPayloadMetadata(payload);
		const expectedWriterRunId = normalizeOptionalString(params.replyOptions?.runId);
		const expectedLifecycleRevision = sessionStoreEntry.entry?.lifecycleRevision;
		const transcriptWriterMetadata = (binding) => ({
			...binding ? { expectedSessionId: binding.sessionId } : {},
			...expectedLifecycleRevision !== void 0 ? { expectedLifecycleRevision } : {},
			...expectedWriterRunId ? { expectedWriterRunId } : {},
			storePath: binding?.storePath ?? sessionStoreEntry.storePath
		});
		const sourceReplySessionBinding = resolvePreparedTranscriptBinding(payloadMetadata?.sourceReplyTranscriptMirror?.sessionKey);
		let sourceReplyTranscriptMirror = payloadMetadata?.sourceReplyTranscriptMirror ? {
			...payloadMetadata.sourceReplyTranscriptMirror,
			...transcriptWriterMetadata(sourceReplySessionBinding)
		} : void 0;
		const hasTranscriptOwner = payloadMetadata?.assistantMessageIndex !== void 0 || payloadMetadata?.assistantTranscriptOwned === true;
		const hasVisibleFinalContent = hasOutboundReplyContent(payload, { trimText: true });
		if (hasVisibleFinalContent) {
			markInboundDedupeReplayUnsafe();
			finalReplyDeliveryStarted = true;
		}
		const shouldAttachDeferredText = deferFinalTtsText && isCaptionedFinalTextPayload(payload);
		const deferredRawText = shouldAttachDeferredText ? mergeDeferredFinalText(options.deferredTtsText ?? "", payload.text) : void 0;
		const ttsInputPayload = shouldAttachDeferredText ? copyReplyPayloadMetadata(payload, {
			...payload,
			text: deferredRawText
		}) : payload;
		const deferredVisibleText = shouldAttachDeferredText ? cleanDeferredFinalDirectives ? cleanDeferredFinalText(deferredRawText) : deferredRawText : void 0;
		let appliedTtsPayload = payload;
		if (!options.skipTts && payload.isReasoning !== true && payload.isCommentary !== true) try {
			appliedTtsPayload = await state.maybeApplyTtsWithFinalizationLease(ttsInputPayload, "final");
		} catch (error) {
			if (!shouldAttachDeferredText) throw error;
			logVerbose(`dispatch-from-config: final TTS failed: ${formatErrorMessage(error)}`);
		}
		const ttsPayload = shouldAttachDeferredText ? copyReplyPayloadMetadata(appliedTtsPayload, {
			...appliedTtsPayload,
			text: deferredVisibleText || void 0
		}) : appliedTtsPayload;
		throwIfFinalDeliveryAborted();
		let normalizedPayload;
		try {
			normalizedPayload = await state.normalizeReplyMediaPayload(ttsPayload);
		} catch (error) {
			if (!shouldAttachDeferredText || !deferredVisibleText) throw error;
			logVerbose(`dispatch-from-config: media normalization failed: ${formatErrorMessage(error)}`);
			normalizedPayload = buildCaptionedFinalTextFallback(ttsPayload);
		}
		throwIfFinalDeliveryAborted();
		const sourceRecovery = getReplyPayloadMetadata(payload)?.blockReplySources;
		let block;
		if (sourceRecovery) {
			const recovery = await runWithDispatchAbortSignal(abortSignal, () => recoverBlockReplySources(normalizedPayload, sourceRecovery));
			normalizedPayload = recovery.payload;
			block = recovery.delivery;
		} else block = await getBlockReplyOutcome(payload, abortSignal);
		throwIfFinalDeliveryAborted();
		const blockDeliveryOutcome = block?.outcome;
		const pendingBlock = block?.pending && blockDeliveryOutcome !== "delivered";
		if (blockDeliveryOutcome && (pendingBlock || !shouldRetryReplyDispatch(blockDeliveryOutcome))) {
			if (blockDeliveryOutcome === "channel-transform" || blockDeliveryOutcome === "failed-deliver" && !pendingBlock && !sourceRecovery || createBlockReplyContentKey(normalizedPayload) === createBlockReplyContentKey(payload)) return {
				blockDeliveryOutcome,
				pendingBlock,
				queuedFinal: false,
				routedFinalCount: 0
			};
			normalizedPayload = copyReplyPayloadMetadata(normalizedPayload, {
				...normalizedPayload,
				text: void 0
			});
			if (pendingBlock) await suppressPendingFinalDelivery(payload, { preserveActivity: state.replyOperationRunState.heartbeat !== void 0 });
			if (pendingBlock || sourceRecovery) {
				setReplyPayloadMetadata(normalizedPayload, { pendingFinalDeliveryCompletion: void 0 });
				sourceReplyTranscriptMirror = sourceReplyTranscriptMirror ? transcriptMirrorForDeliveredPayload(sourceReplyTranscriptMirror, normalizedPayload) : void 0;
			}
			if (!hasOutboundReplyContent(normalizedPayload, { trimText: true })) return {
				blockDeliveryOutcome,
				pendingBlock,
				queuedFinal: false,
				routedFinalCount: 0
			};
		}
		if (!isSessionWriterDeliveryAuthorized(normalizedPayload)) return {
			queuedFinal: false,
			routedFinalCount: 0,
			sessionWriterDeliveryRevoked: true
		};
		const routeFinalPayload = (finalPayload) => state.routeReplyToOriginating(finalPayload, {
			abortSignal,
			kind: "final",
			...hasTranscriptOwner ? { mirror: false } : {}
		});
		let result = await routeFinalPayload(normalizedPayload);
		if (result) {
			let routedOutcome = resolveRoutedReplyDeliveryOutcome(result);
			if (!result.ok) logVerbose(`dispatch-from-config: route-reply (final) failed: ${result.error ?? "unknown error"}`);
			const fallbackText = deferFinalTtsText && normalizedPayload.mediaUrl ? normalizeOptionalString(normalizedPayload.text) : void 0;
			if (fallbackText && shouldRetryReplyDispatch(routedOutcome)) {
				if (!isSessionWriterDeliveryAuthorized(normalizedPayload)) return {
					queuedFinal: false,
					routedFinalCount: 0,
					sessionWriterDeliveryRevoked: true
				};
				result = await routeFinalPayload(copyReplyPayloadMetadata(normalizedPayload, { text: fallbackText })) ?? result;
				routedOutcome = resolveRoutedReplyDeliveryOutcome(result);
			}
			if (isRoutedReplyDelivered(result)) await mirrorDeliveredReplyToTranscript({
				metadata: sourceReplyTranscriptMirror,
				cfg
			});
			return {
				blockDeliveryOutcome: sourceRecovery ? blockDeliveryOutcome : void 0,
				pendingBlock,
				queuedFinal: result.ok,
				routedFinalCount: isRoutedReplyDelivered(result) ? 1 : 0,
				routedOutcome,
				...result.reason === "channel_transform" ? { suppressionReason: "channel_transform" } : {}
			};
		}
		throwIfFinalDeliveryAborted();
		const transcriptMirrorSessionKey = acpDispatchSessionKey ?? sessionStoreEntry.sessionKey ?? sessionKey;
		const transcriptMirrorSourceId = normalizeOptionalString(state.messageIdForHook) ?? normalizeOptionalString(params.replyOptions?.runId);
		const transcriptMirrorSessionBinding = resolvePreparedTranscriptBinding(transcriptMirrorSessionKey);
		const transcriptMirror = sourceReplyTranscriptMirror ?? (state.normalizedCurrentSurface === "slack" && hasVisibleFinalContent && transcriptMirrorSessionKey ? transcriptMirrorForDeliveredPayload({
			sessionKey: transcriptMirrorSessionKey,
			agentId: sessionAgentId,
			...transcriptWriterMetadata(transcriptMirrorSessionBinding),
			preferText: true,
			...hasTranscriptOwner ? { transcriptOwner: true } : {},
			idempotencyKey: transcriptMirrorSourceId ? `channel-final:${transcriptMirrorSourceId}:${options.deliveryId ?? "single"}` : void 0,
			deliveryMirror: {
				kind: "channel-final",
				...transcriptMirrorSourceId ? { sourceMessageId: transcriptMirrorSourceId } : {}
			}
		}, normalizedPayload) : void 0);
		if (!isSessionWriterDeliveryAuthorized(normalizedPayload)) return {
			queuedFinal: false,
			routedFinalCount: 0,
			sessionWriterDeliveryRevoked: true
		};
		markInboundDedupeReplayUnsafe();
		const finalDeliveryCapture = transcriptMirror ? {} : void 0;
		const deliveredTranscriptMirror = transcriptMirror ? captureDeliveredTranscriptMirror({
			dispatcher,
			metadata: transcriptMirror,
			captureToken: finalDeliveryCapture
		}) : void 0;
		if (finalDeliveryCapture) setReplyPayloadMetadata(normalizedPayload, { finalDeliveryCapture });
		if (deferFinalTtsText && normalizedPayload.mediaUrl && normalizedPayload.text?.trim()) attachReplyDispatchUndeliveredFallback(normalizedPayload, buildCaptionedFinalTextFallback(normalizedPayload));
		const { queued: queuedFinal, outcome: dispatcherOutcome } = turnLedger.sendQueued("final", normalizedPayload);
		if (queuedFinal && deliveredTranscriptMirror && dispatcherOutcome) registerReplyDispatcherSettledTask(dispatcher, async () => {
			if (await dispatcherOutcome === "delivered") await mirrorDeliveredReplyToTranscript({
				metadata: deliveredTranscriptMirror(),
				cfg
			});
		});
		return {
			blockDeliveryOutcome: sourceRecovery ? blockDeliveryOutcome : void 0,
			pendingBlock,
			queuedFinal,
			routedFinalCount: 0,
			...queuedFinal && dispatcherOutcome ? { dispatcherOutcome } : {}
		};
	};
	let takeover;
	if (state.allowInboundHandlers && !admittedSessionSettingsRestrictRuntime(params.replyOptions?.admittedSessionSettings) && hookRunner?.hasHooks("before_dispatch")) {
		const beforeDispatchSessionKey = sessionStoreEntry.sessionKey ?? sessionKey;
		const pluginSubagentRequester = createPluginSubagentRequesterContext({
			sessionKey: beforeDispatchSessionKey,
			origin: {
				channel: routeReplyChannel,
				to: routeReplyTo,
				accountId: replyContextAccountId,
				threadId: routeReplyThreadId
			}
		});
		const beforeDispatchResult = await traceReplyPhase("reply.before_dispatch_hooks", () => runWithDispatchLifecycleAdmission(async () => {
			return await runWithDispatchAbortSignal(getPreDispatchAbortSignal(), () => {
				const hookContext = state.hookState.hookContext;
				const replyContext = {
					messageId: hookContext.messageId,
					sessionKey: beforeDispatchSessionKey,
					senderId: hookContext.senderId,
					replyToId: hookContext.replyToId,
					replyToIdFull: hookContext.replyToIdFull,
					replyToBody: hookContext.replyToBody,
					replyToSender: hookContext.replyToSender,
					replyToIsQuote: hookContext.replyToIsQuote
				};
				return hookRunner.runBeforeDispatch({
					...replyContext,
					content: hookContext.content,
					body: hookContext.bodyForAgent ?? hookContext.body,
					channel: hookContext.channelId,
					isGroup: hookContext.isGroup,
					timestamp: hookContext.timestamp
				}, withClaimingHookAdmission({
					...replyContext,
					channelId: hookContext.channelId,
					accountId: hookContext.accountId,
					conversationId: state.hookState.inboundClaimContext.conversationId
				}, { prepare: state.assertCurrentBindingRoute }), pluginSubagentRequester);
			}, trackDispatchLifecycleWork);
		}));
		if (beforeDispatchResult?.handled) takeover = {
			payload: { text: beforeDispatchResult.text },
			deliveryId: "before-dispatch",
			recordProcessed: () => recordProcessed("completed", { reason: "before_dispatch_handled" })
		};
	}
	if (!takeover && state.dispatchKind === "acp" && admittedSessionSettingsRestrictRuntime(params.replyOptions?.admittedSessionSettings)) {
		const error = "This session's bound runtime cannot enforce its permission or tool policy; use an embedded runtime for this restricted conversation.";
		takeover = {
			payload: {
				text: error,
				isError: true
			},
			deliveryId: "restricted-runtime-takeover",
			recordProcessed: () => state.recordProcessed("error", {
				reason: "restricted_runtime_takeover",
				error
			})
		};
	}
	if (takeover) {
		const { queuedFinal, routedFinalCount } = takeover.payload.text && !state.suppressDelivery ? await sendFinalPayload(takeover.payload, {
			abortSignal: getPreDispatchAbortSignal(),
			deliveryId: takeover.deliveryId
		}) : {
			queuedFinal: false,
			routedFinalCount: 0
		};
		const counts = dispatcher.getQueuedCounts();
		counts.final += routedFinalCount;
		takeover.recordProcessed();
		markIdle("message_completed");
		commitInboundDedupeIfClaimed();
		completeDispatchReplyOperation();
		return {
			status: "complete",
			result: attachSourceReplyDeliveryMode({
				queuedFinal,
				counts
			})
		};
	}
	const replyDispatchTakeover = await runReplyDispatchHook(state, {
		shouldSendToolSummaries,
		shouldSendToolSummariesAsync
	});
	if (replyDispatchTakeover?.handled) {
		commitInboundDedupeIfClaimed();
		completeDispatchReplyOperation();
		return {
			status: "complete",
			result: attachSourceReplyDeliveryMode({
				queuedFinal: replyDispatchTakeover.queuedFinal,
				counts: replyDispatchTakeover.counts
			})
		};
	}
	const dispatchPhase = state.activeRunSafeCommandTurn ? "command_resolution" : "dispatch";
	const dispatchAcquisition = await traceReplyPhase(`reply.admit_${dispatchPhase}`, () => state.ensureDispatchReplyOperation(dispatchPhase));
	if (dispatchAcquisition.status === "aborted") return {
		status: "complete",
		result: state.finishReplyOperationAbortedDispatch()
	};
	if (dispatchAcquisition.status === "busy") return {
		status: "complete",
		result: state.finishReplyOperationBusyDispatch({ dedupeDisposition: "release" })
	};
	return {
		status: "ready",
		state: Object.assign(state, {
			shouldSuppressProgressDelivery,
			shouldSuppressProgressDeliverySync,
			shouldSendToolSummaries,
			shouldSendToolSummariesAsync,
			notifySessionMetadataChanges,
			shouldDeliverVerboseProgressDespiteSourceSuppression,
			shouldDeliverForcedToolProgressDespiteSourceSuppression,
			shouldSuppressLateTextOnlyToolProgress,
			flushPendingCommentaryProgress,
			noteCommentaryProgress,
			shouldSuppressMessageToolOnlyTextErrorProgress,
			sendTrackedBlockReply,
			recordRoutedBlockReplyDelivery,
			sendFinalPayload,
			isSessionWriterDeliveryAuthorized,
			deferFinalTtsText,
			routeState
		})
	};
}
//#endregion
//#region src/auto-reply/reply/dispatch-from-config.acp-tail.ts
async function handleAcpDispatchTailAfterReset(state) {
	if (state.ctx.AcpDispatchTailAfterReset !== true) return;
	state.ctx.AcpDispatchTailAfterReset = false;
	const tailDispatchResult = await runReplyDispatchHook(state, {
		shouldSendToolSummaries: state.shouldSendToolSummaries,
		shouldSendToolSummariesAsync: state.shouldSendToolSummariesAsync,
		isTailDispatch: true
	});
	if (!tailDispatchResult?.handled) return;
	state.commitInboundDedupeIfClaimed();
	state.recordAgentDispatchCompleted("completed");
	state.completeDispatchReplyOperation();
	return {
		status: "complete",
		result: state.attachSourceReplyDeliveryMode({
			queuedFinal: tailDispatchResult.queuedFinal,
			counts: tailDispatchResult.counts,
			...state.routeState.sessionMetadataChangesForResult ? { sessionMetadataChanges: state.routeState.sessionMetadataChangesForResult } : {}
		})
	};
}
//#endregion
//#region src/auto-reply/reply/dispatch-from-config.block-reply.ts
function createDispatchBlockReplyHandler(state) {
	const { cleanBlockTtsDirectiveText, commentaryPayloadsEnabled, deferFinalTtsText, dispatcher, flushPendingCommentaryProgress, isDispatchOperationAborted, markInboundDedupeReplayUnsafe, markProgress, maybeApplyTtsWithFinalizationLease, normalizeReplyMediaPayload, params, reasoningPayloadsEnabled, shouldRouteToOriginating, trackDispatchLifecycleWork } = state;
	let pendingBlockSource;
	let drain;
	const dispatchBlockReply = (operation, context) => {
		const inputPayload = operation.kind === "prepared" ? operation.plan.payload : operation.payload;
		setBlockReplyDelivery(Promise.resolve({ outcome: "cancelled" }));
		if (state.replyOperationRunState.heartbeat) return Promise.resolve();
		markProgress();
		const run = async () => {
			if (isDispatchOperationAborted()) return;
			await flushPendingCommentaryProgress();
			const independentDurableBlock = context?.deliveryIntentId !== void 0;
			if (independentDurableBlock && state.suppressAcpChildUserDelivery) return;
			if (state.suppressDelivery && !shouldDeliverDespiteSourceReplySuppression(inputPayload, state)) return;
			if (inputPayload.isReasoning === true && !reasoningPayloadsEnabled || inputPayload.isCommentary === true && !commentaryPayloadsEnabled) return;
			const payload = prepareReplyPayloadForSideEffects(dispatcher, "block", inputPayload, state.progressState, markInboundDedupeReplayUnsafe);
			if (!payload) return;
			const contributesToFinalReply = !isReplyPayloadStatusNotice(payload) && !independentDurableBlock && payload.isReasoning !== true && payload.isCommentary !== true;
			if (payload.text && contributesToFinalReply) {
				const joinsBufferedTtsDirective = cleanBlockTtsDirectiveText?.hasBufferedDirectiveText() === true;
				if (state.progressState.accumulatedBlockText.length > 0) state.progressState.accumulatedBlockText += "\n";
				state.progressState.accumulatedBlockText += payload.text;
				if (state.progressState.accumulatedBlockTtsText.length > 0 && !joinsBufferedTtsDirective) state.progressState.accumulatedBlockTtsText += "\n";
				state.progressState.accumulatedBlockTtsText += payload.text;
				state.progressState.blockCount++;
			}
			let source;
			let cleanedPayload = payload;
			if (payload.text && cleanBlockTtsDirectiveText && contributesToFinalReply) {
				if (!deferFinalTtsText) source = pendingBlockSource ?? createBlockReplySource();
				const text = cleanBlockTtsDirectiveText.push(payload.text);
				const buffered = cleanBlockTtsDirectiveText.hasBufferedDirectiveText();
				source?.setComplete(!buffered);
				pendingBlockSource = buffered ? source : void 0;
				cleanedPayload = copyReplyPayloadMetadata(payload, {
					...payload,
					text: text.trim() ? text : void 0
				});
			}
			const sendPrepared = async (preparedPayload, terminal = false) => {
				let visiblePayload = preparedPayload;
				if (terminal) setBlockReplyDelivery(Promise.resolve({ outcome: "cancelled" }), visiblePayload);
				if (deferFinalTtsText && contributesToFinalReply) {
					if (!Boolean(visiblePayload.mediaUrl || visiblePayload.mediaUrls?.length || visiblePayload.presentation || visiblePayload.interactive || visiblePayload.channelData)) return;
					visiblePayload = copyReplyPayloadMetadata(visiblePayload, {
						...visiblePayload,
						text: void 0
					});
				}
				if (!hasOutboundReplyContent(visiblePayload, { trimText: true })) return;
				const payloadMetadata = getReplyPayloadMetadata(payload);
				const queuedContext = payloadMetadata?.assistantMessageIndex !== void 0 ? {
					...context,
					assistantMessageIndex: payloadMetadata.assistantMessageIndex
				} : context;
				if (isDispatchOperationAborted()) return;
				const ttsPayload = terminal || payload.isReasoning === true || payload.isCommentary === true ? visiblePayload : await maybeApplyTtsWithFinalizationLease(visiblePayload, "block");
				const normalizedPayload = await normalizeReplyMediaPayload(ttsPayload);
				let deliveryOperation = {
					kind: "raw",
					payload: normalizedPayload
				};
				if (operation.kind === "prepared") {
					const plan = createStructuredOutboundPayloadPlan([normalizedPayload])[0];
					if (!plan) return;
					deliveryOperation = {
						kind: "prepared",
						plan
					};
				}
				if (isDispatchOperationAborted()) return;
				if (shouldRouteToOriginating || independentDurableBlock && state.canRouteDurableBlockReply) {
					const result = await state.sendReplyOperationAsync(deliveryOperation, context?.abortSignal, "block", context?.deliveryIntentId);
					if (state.recordRoutedBlockReplyDelivery(normalizedPayload, result) === "delivered" && !state.suppressAutomaticSourceDelivery) await params.replyOptions?.onBlockReplyQueued?.(visiblePayload, queuedContext);
				} else {
					markInboundDedupeReplayUnsafe();
					const delivery = state.sendTrackedBlockReply(deliveryOperation);
					if (delivery.queued) {
						const pending = (delivery.outcome ?? dispatcher.waitForIdle()).then(() => void 0);
						pending.catch(() => void 0);
						state.progressState.pendingDirectBlockReplyDelivery = pending;
					}
					if (delivery.queued && !state.suppressAutomaticSourceDelivery && params.replyOptions?.onBlockReplyQueued) trackDispatchLifecycleWork((delivery.outcome ?? Promise.resolve("delivered")).then(async (outcome) => {
						if (outcome === "delivered" && !context?.abortSignal?.aborted) await params.replyOptions?.onBlockReplyQueued?.(visiblePayload, queuedContext);
					}), "delivery");
				}
			};
			const sendWithSource = (sourcePayload, terminal = false) => {
				const send = () => sendPrepared(sourcePayload, terminal);
				return source ? source.run(send) : send();
			};
			if (cleanBlockTtsDirectiveText && contributesToFinalReply && payload.text) drain = async (text) => {
				if (!text || deferFinalTtsText) {
					source?.setComplete(true);
					return;
				}
				if (isDispatchOperationAborted()) return;
				const tail = buildCaptionedFinalTextFallback(payload);
				tail.text = text;
				source?.setComplete(true);
				await sendWithSource(tail, true);
			};
			await sendWithSource(cleanedPayload);
		};
		return run();
	};
	const onBlockReply = (payload, context) => dispatchBlockReply({
		kind: "raw",
		payload
	}, context);
	const onPreparedBlockReply = (plan, context) => dispatchBlockReply({
		kind: "prepared",
		plan
	}, context);
	return {
		onBlockReply,
		onPreparedBlockReply,
		flush: async () => {
			if (!cleanBlockTtsDirectiveText?.hasBufferedDirectiveText()) return;
			const text = cleanBlockTtsDirectiveText.flush();
			const finish = drain;
			drain = void 0;
			pendingBlockSource = void 0;
			await finish?.(text);
		}
	};
}
//#endregion
//#region src/auto-reply/reply/dispatch-from-config.turn-ledger.ts
const SETTLE_QUEUED_TIMEOUT_MS = 3e4;
const RAW_REPLY_SEND_METHODS = {
	tool: "sendToolResult",
	block: "sendBlockReply",
	final: "sendFinalReply"
};
async function requireQueuedReplyDelivery(params) {
	if (!params.delivery.queued) throw new Error("queued reply delivery failed");
	const outcome = params.delivery.outcome;
	if (!outcome) {
		const receipt = await waitForReplyDispatcherIdle(params.dispatcher, params.abortSignal);
		if (params.dispatcher.supportsSettledReceipt === true && receipt?.anyVisibleDelivered !== true) throw new Error("queued reply delivery failed");
		return;
	}
	const settledOutcome = await runWithDispatchAbortSignal(params.abortSignal, () => outcome);
	if (settledOutcome !== "delivered") throw new ReplyDispatchDeliveryError(settledOutcome);
}
function createReplyTurnLedger(dispatcher) {
	const outcomes = /* @__PURE__ */ new Set();
	let pendingDelivery = false;
	let terminalDelivery = "missing";
	const mayHaveDelivered = () => outcomes.has("delivered") || outcomes.has("failed-deliver");
	const recordDelivery = (kind, payload, outcome, pending) => {
		pendingDelivery ||= pending;
		if (!hasOutboundReplyContent(payload, { trimText: true })) return;
		outcomes.add(outcome);
		if (kind === "tool" || !isReplyPayloadTerminalContent(payload)) return;
		if (outcome === "delivered" && !pending) terminalDelivery = "delivered";
		else if (terminalDelivery !== "delivered" && (pending || outcome === "failed-deliver" || outcome === "recovery-owned")) terminalDelivery = "pending";
	};
	const sendOperation = (kind, operation) => {
		const payload = operation.kind === "prepared" ? operation.plan.payload : operation.payload;
		const capture = dispatcher.supportsSettledReceipt === true ? captureReplyDispatchDeliveryOutcome(payload) : void 0;
		if (!(operation.kind === "prepared" && dispatcher.sendPreparedReply ? dispatcher.sendPreparedReply(kind, operation.plan) : dispatcher[RAW_REPLY_SEND_METHODS[kind]](payload))) return { queued: false };
		if (!capture || !capture.isTracked()) {
			recordDelivery(kind, payload, "failed-deliver", false);
			return { queued: true };
		}
		return {
			queued: true,
			outcome: capture.promise.then((settled) => {
				recordDelivery(kind, payload, settled, capture.hasPendingDelivery());
				return settled;
			}),
			hasPendingDelivery: capture.hasPendingDelivery
		};
	};
	return {
		sendQueued: (kind, payload) => sendOperation(kind, {
			kind: "raw",
			payload
		}),
		sendPreparedQueued: (kind, plan) => sendOperation(kind, {
			kind: "prepared",
			plan
		}),
		recordRoutedDelivery(kind, payload, result) {
			const outcome = resolveRoutedReplyDeliveryOutcome(result);
			recordDelivery(kind, payload, outcome, result.queueCustody === "held" || result.ambiguous === true || outcome === "recovery-owned");
		},
		async settleQueued(abortSignal) {
			if (abortSignal?.aborted) return "aborted";
			const deadline = new AbortController();
			const timer = setTimeout(() => deadline.abort(), SETTLE_QUEUED_TIMEOUT_MS);
			timer.unref?.();
			try {
				const receipt = await waitForReplyDispatcherIdle(dispatcher, abortSignal ? AbortSignal.any([abortSignal, deadline.signal]) : deadline.signal);
				if (abortSignal?.aborted) return "aborted";
				if (deadline.signal.aborted) return "timed-out";
				if (dispatcher.supportsSettledReceipt === true && receipt) for (const counts of Object.values(receipt.counts)) {
					if (counts.delivered > 0) outcomes.add("delivered");
					if (counts.failedAfterSend > 0) outcomes.add("failed-deliver");
				}
				pendingDelivery ||= receipt?.hasPendingDelivery === true;
				return "settled";
			} finally {
				clearTimeout(timer);
			}
		},
		mayHaveDelivered,
		hasObservedDelivery: () => outcomes.has("delivered"),
		canAttemptFallback: () => !mayHaveDelivered() && !pendingDelivery && !outcomes.has("recovery-owned"),
		hasPendingDelivery: () => pendingDelivery,
		resolveTerminalDelivery: () => terminalDelivery
	};
}
//#endregion
//#region src/auto-reply/reply/dispatch-from-config.execute.ts
async function executeDispatch(state) {
	const { commentaryPayloadsEnabled, ctx, deferFinalTtsText, dispatcher, failDispatchReplyOperation, flushPendingCommentaryProgress, getAgentRunTerminalOutcome, getDispatchAbortOperation, getDispatchAbortSignal, isDispatchOperationAborted, markInboundDedupeReplayUnsafe, markProgress, maybeApplyTtsWithFinalizationLease, normalizeReplyMediaPayload, notifySessionMetadataChanges, onToolResultFromReplyOptions, onReasoningStream, params, reasoningPayloadsEnabled, replyConfig, resolveToolDeliveryPayload, runWithDispatchLifecycleAdmission, sendPayloadAsync, shouldForwardProgressCallback, shouldRouteToOriginating, trackDispatchLifecycleWork, typing, waitForPendingDirectBlockReplyDelivery, wrapProgressCallback } = state;
	const replyResolver = bindPreparedReplyDispatchRuntime(params.configOverride ? void 0 : state.preparedReplyDispatchRuntime, state.replyResolver);
	let pendingContinuation = false;
	let pendingContinuationSettlement;
	const releasePendingContinuation = async () => {
		const settlement = pendingContinuationSettlement;
		pendingContinuationSettlement = void 0;
		await settlement?.settle(false);
	};
	let didDeliverVisiblePartialReply = false;
	const { onBlockReply, onPreparedBlockReply, flush: flushBlockTtsText } = createDispatchBlockReplyHandler(state);
	const flushDeferredFinalText = async () => {
		try {
			if (!state.deferFinalTtsText || params.replyOptions?.isHeartbeat === true) return;
			const deferredVisibleText = state.cleanBlockTtsDirectiveText ? cleanDeferredFinalText(state.progressState.accumulatedBlockTtsText) : state.progressState.accumulatedBlockText;
			if (!deferredVisibleText.trim()) return;
			const fallback = await state.sendFinalPayload({ text: deferredVisibleText }, {
				abortSignal: isDispatchOperationAborted() ? false : void 0,
				skipTts: true
			});
			if (fallback.queuedFinal || fallback.routedFinalCount !== 0) {
				state.progressState.accumulatedBlockText = "";
				state.progressState.accumulatedBlockTtsText = "";
				didDeliverVisiblePartialReply = true;
			}
		} catch (error) {
			logVerbose(`dispatch-from-config: deferred final text fallback failed: ${formatErrorMessage(error)}`);
		}
	};
	const forwardToolProgress = async (forward) => {
		if (isDispatchOperationAborted()) return;
		markProgress();
		await waitForPendingDirectBlockReplyDelivery(getDispatchAbortOperation()?.abortSignal);
		if (isDispatchOperationAborted()) return;
		markInboundDedupeReplayUnsafe();
		if (await shouldForwardProgressCallback({
			forwardWhenSourceDeliverySuppressed: true,
			requiresToolSummaryVisibility: true
		}) && !isDispatchOperationAborted()) {
			state.assertProgressCurrent();
			await forward();
		}
	};
	const replyResult = await runWithDispatchLifecycleAdmission(async () => {
		const resolverWork = runWithDispatchAbortSignal(getDispatchAbortSignal(), () => state.traceReplyPhase("reply.run_reply_resolver", async () => {
			const toolProgressOptions = {
				forwardWhenSourceDeliverySuppressed: true,
				requiresToolSummaryVisibility: true,
				waitForDirectBlockReplyDelivery: true
			};
			const toolLifecycleOptions = {
				...toolProgressOptions,
				allowWhenToolSummariesHidden: params.replyOptions?.allowToolLifecycleWhenProgressHidden === true
			};
			const result = await replyResolver(ctx, {
				...state.getReplyOptions(),
				preparedTtsPreferences: state.preparedTtsPreferences,
				[REPLY_OPERATION_RUN_STATE]: state.replyOperationRunState,
				sourceReplyDeliveryMode: state.sourceReplyDeliveryMode,
				sessionPromptSourceReplyDeliveryMode: state.sessionStableSourceReplyDeliveryMode,
				...state.sourceReplyDeliveryRuntimeOptions,
				mediaNormalizationOwner: state.isInternalWebchatTurn ? "gateway" : void 0,
				onPendingContinuation: (settlement) => {
					pendingContinuation = true;
					pendingContinuationSettlement ??= settlement;
				},
				onSessionMetadataChanges: notifySessionMetadataChanges,
				onSessionPrepared: state.notePreparedSession,
				onRunVerbosityResolved: (settings) => {
					state.noteRunVerbosity(settings);
					params.replyOptions?.onRunVerbosityResolved?.(settings);
				},
				onObservedReplyDelivery: state.markObservedReplyDelivery,
				typingPolicy: typing.typingPolicy,
				suppressTyping: typing.suppressTyping,
				onPartialReply: deferFinalTtsText ? void 0 : wrapProgressCallback(params.replyOptions?.onPartialReply, { onVisible: (payload) => {
					if (hasOutboundReplyContent(payload, { trimText: true })) didDeliverVisiblePartialReply = true;
				} }),
				onReasoningStream,
				streamReasoningInNonStreamModes: params.replyOptions?.streamReasoningInNonStreamModes,
				onReasoningEnd: wrapProgressCallback(params.replyOptions?.onReasoningEnd),
				onAssistantMessageStart: wrapProgressCallback(params.replyOptions?.onAssistantMessageStart),
				onQueuedFollowupSettled: async () => {
					try {
						await flushBlockTtsText();
						await waitForPendingDirectBlockReplyDelivery();
						if (dispatcher.getFailedCounts().block > 0 && state.turnLedger.canAttemptFallback()) await dispatcher.waitForIdle();
					} catch (error) {
						try {
							await params.replyOptions?.onQueuedFollowupSettled?.();
						} catch (cleanupError) {
							logVerbose(`dispatch-from-config: queued cleanup failed; preserving delivery error: ${formatErrorMessage(cleanupError)}`);
						}
						throw error;
					}
					await params.replyOptions?.onQueuedFollowupSettled?.();
				},
				onBlockReplyQueued: wrapProgressCallback(params.replyOptions?.onBlockReplyQueued),
				onToolStart: wrapProgressCallback(params.replyOptions?.onToolStart, {
					...toolLifecycleOptions,
					onForward: async () => {
						await flushPendingCommentaryProgress();
					}
				}),
				onItemEvent: state.onItemEvent,
				commentaryProgressEnabled: state.deliverStandaloneCommentaryProgress || state.canForwardSuppressedSourceItemEvents || params.replyOptions?.commentaryProgressEnabled,
				reasoningPayloadsEnabled,
				commentaryPayloadsEnabled,
				onCommandOutput: wrapProgressCallback(params.replyOptions?.onCommandOutput, toolProgressOptions),
				onCompactionStart: wrapProgressCallback(params.replyOptions?.onCompactionStart, toolLifecycleOptions),
				onCompactionEnd: wrapProgressCallback(params.replyOptions?.onCompactionEnd, toolLifecycleOptions),
				onToolResult: (payload) => {
					if (state.replyOperationRunState.heartbeat) return Promise.resolve();
					state.getDispatchReplyOperation()?.recordActivity();
					markProgress();
					const run = async () => {
						if (isDispatchOperationAborted()) return;
						await waitForPendingDirectBlockReplyDelivery(getDispatchAbortOperation()?.abortSignal);
						if (isDispatchOperationAborted()) return;
						markInboundDedupeReplayUnsafe();
						await flushPendingCommentaryProgress();
						const isFastModeAutoProgress = isFastModeAutoProgressPayload(payload);
						const isForcedToolProgress = state.shouldDeliverForcedToolProgressDespiteSourceSuppression();
						const forceToolResultProgress = params.replyOptions?.forceToolResultProgress === true;
						const allowProgressCallbacksWhenSourceDeliverySuppressed = params.replyOptions?.allowProgressCallbacksWhenSourceDeliverySuppressed === true && ctx.InboundEventKind !== "room_event";
						const durableToolResult = requiresDurableToolResultDelivery(payload);
						const requiresDurableToolResult = forceToolResultProgress && durableToolResult;
						const shouldDeliverFastModeAutoProgress = isFastModeAutoProgress && (!state.suppressAutomaticSourceDelivery && (forceToolResultProgress || await state.shouldSendToolSummariesAsync()) || isForcedToolProgress || await state.shouldDeliverVerboseProgressDespiteSourceSuppression());
						if (params.replyOptions?.suppressToolProgressMessages && !durableToolResult) return;
						const toolResultProgressCallback = (forceToolResultProgress ? !requiresDurableToolResult && (isFastModeAutoProgress || !await state.shouldEmitVerboseProgressAsync()) && await shouldForwardProgressCallback({ forwardWhenSourceDeliverySuppressed: allowProgressCallbacksWhenSourceDeliverySuppressed }) : (await state.shouldSendToolSummariesAsync() || isFastModeAutoProgress && params.replyOptions?.allowToolLifecycleWhenProgressHidden === true) && await shouldForwardProgressCallback(isFastModeAutoProgress ? { forwardWhenSourceDeliverySuppressed: allowProgressCallbacksWhenSourceDeliverySuppressed } : void 0)) ? onToolResultFromReplyOptions : void 0;
						let toolResultProgressVisible = false;
						if (isDispatchOperationAborted()) return;
						state.assertProgressCurrent();
						if (toolResultProgressCallback) toolResultProgressVisible = (await settleProgressVisibilityCallbackResult(toolResultProgressCallback(payload))).visible;
						if (isDispatchOperationAborted()) return;
						if (toolResultProgressCallback && (isFastModeAutoProgress ? toolResultProgressVisible || !shouldDeliverFastModeAutoProgress : forceToolResultProgress)) return;
						if (state.sendPolicyDenied) return;
						const bypassToolSummarySuppression = isForcedToolProgress || shouldDeliverFastModeAutoProgress;
						if (await state.shouldSuppressProgressDelivery() && !bypassToolSummarySuppression && !hasAskUserPayload(payload)) return;
						const visibleToolPayload = prepareReplyPayloadForSideEffects(dispatcher, "tool", bypassToolSummarySuppression ? payload : await resolveToolDeliveryPayload(payload), state.progressState);
						if (!visibleToolPayload) return;
						const ttsPayload = await maybeApplyTtsWithFinalizationLease(visibleToolPayload, "tool");
						const normalizedPayload = await normalizeReplyMediaPayload(ttsPayload);
						const deliveryPayload = bypassToolSummarySuppression ? normalizedPayload : await resolveToolDeliveryPayload(normalizedPayload);
						if (!deliveryPayload || isDispatchOperationAborted()) return;
						if (state.shouldSuppressLateTextOnlyToolProgress(deliveryPayload) && !bypassToolSummarySuppression) return;
						if (await state.shouldSuppressMessageToolOnlyTextErrorProgress(deliveryPayload)) return;
						if (!await state.shouldSendToolSummariesAsync() && !bypassToolSummarySuppression && !requiresDurableToolResultDelivery(deliveryPayload)) return;
						const askUserQuestionId = readAskUserQuestionId(deliveryPayload);
						if (askUserQuestionId !== void 0 && !await isAskUserPromptPending(askUserQuestionId)) return;
						if (isDispatchOperationAborted()) return;
						state.assertProgressCurrent();
						if (shouldRouteToOriginating) await sendPayloadAsync(deliveryPayload);
						else {
							const delivery = state.turnLedger.sendQueued("tool", deliveryPayload);
							if (hasAskUserPayload(deliveryPayload)) await requireQueuedReplyDelivery({
								delivery,
								dispatcher,
								abortSignal: getDispatchAbortOperation()?.abortSignal
							});
						}
					};
					return run();
				},
				onPlanUpdate: async (payload) => {
					if (isDispatchOperationAborted()) return;
					const steps = normalizeAgentPlanSteps(payload.steps);
					const normalized = {
						phase: payload.phase,
						title: payload.title,
						explanation: payload.explanation,
						...payload.explanationFormat ? { explanationFormat: payload.explanationFormat } : {},
						steps,
						source: payload.source
					};
					await forwardToolProgress(() => state.onPlanUpdateFromReplyOptions?.(normalized));
					if (isDispatchOperationAborted()) return;
					if (payload.phase !== "update" || !await state.shouldSendToolSummariesAsync()) return;
					await state.sendPlanUpdate({
						explanation: normalized.explanation,
						explanationFormat: normalized.explanationFormat,
						steps
					});
				},
				onApprovalEvent: (payload) => forwardToolProgress(() => state.onApprovalEventFromReplyOptions?.(payload)),
				onPatchSummary: (payload) => forwardToolProgress(() => state.onPatchSummaryFromReplyOptions?.(payload)),
				onBlockReply,
				onPreparedBlockReply
			}, state.preparedReplyDispatchRuntime && !params.configOverride ? void 0 : replyConfig);
			for (const reply of Array.isArray(result) ? result : result ? [result] : []) {
				const continuation = getReplyPayloadMetadata(reply)?.progressContinuation;
				if (continuation) {
					if (isDispatchOperationAborted()) continuation.close();
					else registerReplyDispatcherSettledTask(dispatcher, continuation.close);
				}
			}
			return result;
		}), trackDispatchLifecycleWork);
		try {
			return await resolverWork;
		} finally {
			await flushBlockTtsText();
		}
	}).catch(async (error) => {
		await releasePendingContinuation();
		await flushDeferredFinalText();
		const failedAgentRun = getAgentRunTerminalOutcome() === "failed";
		const adopted = state.turnAdoptionState?.adopted === true;
		if (params.replyOptions?.isHeartbeat === true || !failedAgentRun && !didDeliverVisiblePartialReply && !adopted || isDispatchOperationAborted()) throw error;
		failDispatchReplyOperation(error, "failed");
		if (!didDeliverVisiblePartialReply) return adopted && state.replyOperationRunState.replyCompletion?.expectation === "required" && state.replyOperationRunState.replyCompletion.outcome !== "blocked" && !state.suppressDelivery && !state.getObservedReplyDelivery() ? {
			text: GENERIC_EXTERNAL_RUN_FAILURE_TEXT,
			isError: true
		} : void 0;
		return buildTerminalAgentRunFailureReplyPayload({
			replyExpectation: state.replyOperationRunState.replyCompletion?.expectation ?? "required",
			visibleReplyDelivered: true
		});
	});
	try {
		if (isDispatchOperationAborted()) await flushDeferredFinalText();
		notifySessionMetadataChanges(takeCommandSessionMetadataChanges(ctx));
		const finalDispatchAcquisition = isCommandReplyForDelivery(replyResult) ? { status: "ready" } : await state.ensureDispatchReplyOperation("dispatch");
		if (finalDispatchAcquisition.status === "aborted") return {
			status: "complete",
			result: state.finishReplyOperationAbortedDispatch()
		};
		if (finalDispatchAcquisition.status === "busy") return {
			status: "complete",
			result: state.finishReplyOperationBusyDispatch({
				recordAgentDispatchCompleted: true,
				...state.routeState.sessionMetadataChangesForResult ? { sessionMetadataChanges: state.routeState.sessionMetadataChangesForResult } : {}
			})
		};
		const acpTailResult = await handleAcpDispatchTailAfterReset(state);
		if (acpTailResult) return acpTailResult;
		const nextState = Object.assign(state, {
			pendingContinuation,
			pendingContinuationSettlement,
			replyResult
		});
		pendingContinuationSettlement = void 0;
		return {
			status: "ready",
			state: nextState
		};
	} finally {
		await releasePendingContinuation();
	}
}
//#endregion
//#region src/auto-reply/reply/dispatch-from-config.lifecycle.ts
async function restoreArchivedDispatchSession(params) {
	const { ctx, entry, hasPluginOwnedBinding, sessionKey, storePath } = params;
	if (!entry || !sessionKey || !storePath || entry.archivedAt === void 0 || isRestartRecoveryTombstone(entry) || hasPluginOwnedBinding || ctx.InboundAccessAuthorized !== true || ctx.InboundEventKind === "room_event" || isNativeCommandTurn(ctx.CommandTurn) && ctx.CommandTurn?.authorized !== true || classifySessionStateActor({ inputProvenance: ctx.InputProvenance }).actorType !== "human") return entry;
	let placementContext = params.placementContext;
	if (!placementContext) try {
		placementContext = (await import("./session-worker-placement-context-CmjTGyMC.mjs")).resolveSessionWorkerPlacementContext();
	} catch {
		return entry;
	}
	const snapshotSessionId = entry.sessionId;
	const snapshotArchivedAt = entry.archivedAt;
	const canRestore = (currentEntry, prepared) => {
		if (currentEntry.sessionId !== snapshotSessionId || currentEntry.archivedAt !== snapshotArchivedAt || isRestartRecoveryTombstone(currentEntry)) return false;
		try {
			const placement = prepared ? prepared.placement : currentEntry.sessionId ? placementContext.workerSessionPlacementService?.getMany([currentEntry.sessionId]).get(currentEntry.sessionId) : void 0;
			return !resolveWorkerPlacementArchiveRestoreError({
				context: placementContext,
				key: sessionKey,
				placement
			});
		} catch {
			return false;
		}
	};
	return await runExclusiveSessionLifecycleMutation("restore", {
		scope: storePath,
		identities: [sessionKey, snapshotSessionId],
		run: async () => {
			const scope = {
				sessionKey,
				storePath
			};
			const currentEntry = loadSessionEntryReadOnly(scope);
			if (!currentEntry || !canRestore(currentEntry, { placement: await readSessionWorkerPlacementAsync({
				context: placementContext,
				sessionId: currentEntry.sessionId
			}) })) return currentEntry;
			let assertCommitAllowed;
			if (currentEntry.worktree) {
				const { restoreSessionWorktree } = await import("./session-worktree-lifecycle-CleVQGX9.mjs");
				assertCommitAllowed = await restoreSessionWorktree({
					entry: currentEntry,
					scope,
					commitGuard: await prepareSessionWorkerPlacementMutationCheckAsync({
						context: placementContext,
						sessionId: currentEntry.sessionId
					})
				});
			}
			return await patchSessionEntryCore(scope, (current) => canRestore(current) ? {
				archivedAt: void 0,
				archivedBy: void 0,
				archiveReason: void 0
			} : null, sessionEntryCommitGuardOptions(assertCommitAllowed)) ?? void 0;
		}
	});
}
function createDispatchReplyOperationCoordinator(params) {
	let dispatchReplyOperation;
	let admittedExpectedSessionId;
	let dispatchAbortOperation;
	let preDispatchAbortOperation;
	let preDispatchLifecycleAdmission;
	let removePreDispatchLifecycleAbortListener;
	let preDispatchLifecycleAbortController;
	let dispatchLifecycleAbortController;
	let preDispatchLifecycleInterrupted = false;
	let dispatchResetTriggered = false;
	let allowRestartTombstoneParentFork = false;
	let allowRestartTombstoneReset = false;
	const dispatchLifecycleWork = {
		owner: /* @__PURE__ */ new Set(),
		delivery: /* @__PURE__ */ new Set()
	};
	const trackDispatchLifecycleWork = (work, phase = "owner") => {
		if (!dispatchReplyOperation && !preDispatchLifecycleAdmission) return;
		const pending = dispatchLifecycleWork[phase];
		const settled = work.then(() => {}, () => {});
		pending.add(settled);
		settled.then(() => {
			pending.delete(settled);
		});
	};
	const waitForDispatchDelivery = async () => {
		await Promise.allSettled(Array.from(dispatchLifecycleWork.delivery));
		await waitForReplyDispatcherIdle(params.dispatcher);
	};
	const releasePreDispatchLifecycleAdmission = async (afterWorkBarrier) => {
		removePreDispatchLifecycleAbortListener?.();
		removePreDispatchLifecycleAbortListener = void 0;
		const admission = preDispatchLifecycleAdmission;
		const preDispatchAbortController = preDispatchLifecycleAbortController;
		const dispatchAbortController = dispatchLifecycleAbortController;
		preDispatchLifecycleAdmission = void 0;
		if (!admission) return;
		const pendingWork = [...dispatchLifecycleWork.owner, ...dispatchLifecycleWork.delivery];
		const clearAbortControllers = () => {
			if (preDispatchLifecycleAbortController === preDispatchAbortController) preDispatchLifecycleAbortController = void 0;
			if (dispatchLifecycleAbortController === dispatchAbortController) dispatchLifecycleAbortController = void 0;
		};
		try {
			if (afterWorkBarrier || pendingWork.length > 0) await Promise.allSettled(pendingWork);
			if (afterWorkBarrier) await waitForReplyBarrierSettlement(afterWorkBarrier(), params.dispatcher.resolveFollowupAdmissionBarrierTimeoutPolicy?.());
		} finally {
			clearAbortControllers();
			admission.release();
		}
	};
	const armPreDispatchLifecycleAbortRelease = () => {
		const abortSignal = params.replyOptions?.turnAdoptionLifecycle?.abortSignal ?? params.replyOptions?.abortSignal;
		if (!abortSignal || !preDispatchLifecycleAdmission) return;
		removePreDispatchLifecycleAbortListener?.();
		const onAbort = () => {
			releasePreDispatchLifecycleAdmission(() => waitForReplyDispatcherIdle(params.dispatcher));
		};
		abortSignal.addEventListener("abort", onAbort, { once: true });
		removePreDispatchLifecycleAbortListener = () => abortSignal.removeEventListener("abort", onAbort);
		if (abortSignal.aborted) onAbort();
	};
	const runWithDispatchLifecycleAdmission = async (run) => {
		if (dispatchReplyOperation) return await runWithReplyOperationLifecycleAdmission(dispatchReplyOperation, run);
		return preDispatchLifecycleAdmission ? await preDispatchLifecycleAdmission.run(run) : await run();
	};
	const ensureDispatchReplyOperation = async (phase, hasPluginOwnedBinding = false) => {
		if (phase === "pre_dispatch") {
			params.operationSessionStoreEntry.entry = await restoreArchivedDispatchSession({
				ctx: params.ctx,
				entry: params.operationSessionStoreEntry.entry,
				hasPluginOwnedBinding,
				placementContext: params.sessionWorkerPlacementContext,
				sessionKey: params.dispatchOperationSessionKey,
				storePath: params.operationSessionStoreEntry.storePath
			});
			({resetTriggered: dispatchResetTriggered, allowRestartTombstoneParentFork, allowRestartTombstoneReset} = resolveDispatchResetAdmission({
				agentId: params.agentId,
				cfg: params.cfg,
				ctx: params.ctx,
				entry: params.operationSessionStoreEntry.entry,
				hasPluginOwnedBinding,
				sessionKey: params.dispatchOperationSessionKey,
				storePath: params.operationSessionStoreEntry.storePath
			}));
		}
		if (phase !== "pre_dispatch" && preDispatchLifecycleInterrupted) return { status: dispatchReplyOperation ? "aborted" : "busy" };
		if (dispatchReplyOperation) return { status: "ready" };
		if (dispatchAbortOperation && !dispatchAbortOperation.result) return { status: "busy" };
		if (phase !== "pre_dispatch" && preDispatchAbortOperation?.result && preDispatchAbortOperation.result.kind !== "completed" && params.allowActiveQueueResolution !== true) {
			dispatchAbortOperation = preDispatchAbortOperation;
			return { status: "busy" };
		}
		const dispatchOperationSessionKey = params.dispatchOperationSessionKey;
		if (!dispatchOperationSessionKey) return { status: "ready" };
		const operationSessionId = dispatchAbortOperation?.sessionId ?? params.operationSessionStoreEntry.entry?.sessionId ?? crypto.randomUUID();
		const replyTurnKind = resolveReplyTurnKind(params.replyOptions);
		const activeReplyOperation = replyRunRegistry.get(dispatchOperationSessionKey);
		const activeEmbeddedSessionId = resolveActiveEmbeddedRunSessionId(dispatchOperationSessionKey);
		const allowGatewayQueueResolution = (replyTurnKind === "visible" || params.replyOptions?.internalEventExecution !== void 0) && (params.replyOptions?.turnAdoptionLifecycle !== void 0 || params.allowActiveQueueResolution === true);
		if (allowGatewayQueueResolution && (activeReplyOperation ? phase !== "pre_dispatch" && (activeReplyOperation.turnKind !== "heartbeat" || params.replyOptions?.internalEventExecution !== void 0) : activeEmbeddedSessionId === operationSessionId)) return { status: "ready" };
		if (phase !== "pre_dispatch") {
			await releasePreDispatchLifecycleAdmission(() => waitForReplyDispatcherIdle(params.dispatcher));
			if (preDispatchLifecycleInterrupted) return { status: dispatchReplyOperation ? "aborted" : "busy" };
		}
		const allowActiveResolution = (replyTurnKind === "visible" || params.replyOptions?.internalEventExecution !== void 0) && (phase === "pre_dispatch" || phase === "command_resolution");
		const allowSlackRoutedThreadBypass = phase !== "pre_dispatch" && shouldLetSlackRoutedThreadBypassBusyReplyOperation({
			activeOperation: replyRunRegistry.get(dispatchOperationSessionKey),
			ctx: params.ctx,
			routeThreadId: params.routeThreadId
		});
		const lifecycleOnlyAbortController = allowActiveResolution || allowSlackRoutedThreadBypass ? new AbortController() : void 0;
		const onLifecycleInterrupt = () => {
			preDispatchLifecycleInterrupted = true;
			lifecycleOnlyAbortController?.abort();
		};
		const admitCurrentReplyTurn = async () => {
			try {
				return await admitReplyTurn({
					assertRequestCurrent: () => {
						params.replyOptions?.operatorAuthority?.assertCurrent();
						params.replyOptions?.internalEventExecution?.assertCurrent?.();
					},
					providerReviewAcknowledgment: params.replyOptions?.providerReviewAcknowledgment,
					agentId: params.agentId,
					sessionKey: dispatchOperationSessionKey,
					resolveGatewayContext: readChannelContextGatewayContextResolver(params.ctx) ?? getPluginRuntimeGatewayRequestScope()?.resolveGatewayContext,
					sessionId: operationSessionId,
					expectedSessionId: params.replyOptions?.expectedExistingSessionId ?? params.resolveOperationExpectedSessionId(),
					expectedActiveOperations: [params.replyOptions?.expectedActiveReplyOperation, params.initialDispatchReplyOperation].filter((operation) => operation !== void 0),
					storePath: params.operationSessionStoreEntry.storePath,
					kind: replyTurnKind,
					resetTriggered: dispatchResetTriggered,
					allowRestartTombstoneParentFork,
					allowRestartTombstoneReset,
					routeThreadId: params.routeThreadId,
					originatingLeafEntryId: params.replyOptions?.turnAdoptionLifecycle?.originatingLeafEntryId,
					upstreamAbortSignal: params.replyOptions?.abortSignal,
					waitForActive: !allowActiveResolution && !allowSlackRoutedThreadBypass,
					retainLifecycleAdmissionOnActive: allowActiveResolution || allowSlackRoutedThreadBypass,
					onLifecycleInterrupt
				});
			} catch (error) {
				if (phase === "pre_dispatch" && replyTurnKind === "visible" && isSessionWorkStartInvalidatedError(error)) throw new DispatchSessionRefreshRequiredError(error);
				throw error;
			}
		};
		let admission = await admitCurrentReplyTurn();
		if (admission.status === "skipped" && admission.reason === "active-run" && replyTurnKind === "visible" && isRecoverableTerminalSessionStatus(params.operationSessionStoreEntry.entry?.status) && admission.activeOperation?.sessionId === params.operationSessionStoreEntry.entry?.sessionId && !admission.activeOperation?.terminalRecovery) {
			if (forceClearReplyRunBySessionId(admission.activeOperation?.sessionId ?? operationSessionId, /* @__PURE__ */ new Error("clearing stale terminal reply operation"))) {
				admission.lifecycleAdmission?.release();
				logVerbose(`dispatch-from-config: cleared stale active reply operation for terminal session ${dispatchOperationSessionKey}`);
				admission = await admitCurrentReplyTurn();
			}
		}
		admittedExpectedSessionId = admission.status === "owned" ? admission.operation.sessionId : admission.sessionEntry?.sessionId;
		const runState = resolveReplyOperationRunState(params.replyOptions);
		if (runState && runState.admission?.status !== "accepted") runState.admission = admission.status === "owned" ? { status: "owned" } : {
			status: "skipped",
			reason: admission.reason
		};
		if (admission.status === "skipped") {
			if (admission.reason === "active-run" && (allowActiveResolution || shouldLetSlackRoutedThreadBypassBusyReplyOperation({
				activeOperation: admission.activeOperation,
				ctx: params.ctx,
				routeThreadId: params.routeThreadId
			}))) {
				if (allowActiveResolution && !allowGatewayQueueResolution) preDispatchAbortOperation = admission.activeOperation;
				preDispatchLifecycleAdmission = admission.lifecycleAdmission;
				if (allowActiveResolution && phase === "pre_dispatch") preDispatchLifecycleAbortController = lifecycleOnlyAbortController;
				else dispatchLifecycleAbortController = lifecycleOnlyAbortController;
				armPreDispatchLifecycleAbortRelease();
				if (!allowActiveResolution) logVerbose(`dispatch-from-config: allowing Slack routed thread ${params.routeThreadId} while ${dispatchOperationSessionKey} has an active reply operation in another Slack thread`);
				return { status: "ready" };
			}
			admission.lifecycleAdmission?.release();
			dispatchAbortOperation = admission.activeOperation;
			logVerbose(`dispatch-from-config: skipped reply operation admission for ${dispatchOperationSessionKey}; reason=${admission.reason}`);
			return { status: "busy" };
		}
		if (replyTurnKind === "visible" && isRecoverableTerminalSessionStatus(params.operationSessionStoreEntry.entry?.status) && operationSessionId === params.operationSessionStoreEntry.entry?.sessionId) admission.operation.markTerminalRecovery();
		dispatchReplyOperation = admission.operation;
		dispatchReplyOperation.retainFailureUntilComplete();
		dispatchAbortOperation = admission.operation;
		params.replyOptions?.onReplyOperationOwned?.(admission.operation);
		return { status: "ready" };
	};
	let cachedOperationSignal;
	let cachedLifecycleSignal;
	let cachedUpstreamSignal;
	let cachedPreDispatchAbortSignal;
	const getPreDispatchAbortSignal = () => {
		const operationSignal = (dispatchAbortOperation ?? preDispatchAbortOperation)?.abortSignal;
		const lifecycleSignal = preDispatchLifecycleAbortController?.signal;
		const upstreamSignal = params.replyOptions?.abortSignal;
		if (cachedOperationSignal === operationSignal && cachedLifecycleSignal === lifecycleSignal && cachedUpstreamSignal === upstreamSignal) return cachedPreDispatchAbortSignal;
		const abortSignals = [
			operationSignal,
			lifecycleSignal,
			upstreamSignal
		].filter((signal) => Boolean(signal));
		cachedPreDispatchAbortSignal = abortSignals.length > 1 ? AbortSignal.any(abortSignals) : abortSignals[0];
		cachedOperationSignal = operationSignal;
		cachedLifecycleSignal = lifecycleSignal;
		cachedUpstreamSignal = upstreamSignal;
		return cachedPreDispatchAbortSignal;
	};
	const getDispatchAbortSignal = () => {
		if (dispatchReplyOperation) return dispatchReplyOperation.abortSignal;
		const lifecycleSignal = dispatchLifecycleAbortController?.signal ?? preDispatchLifecycleAbortController?.signal;
		const upstreamSignal = params.replyOptions?.abortSignal;
		return lifecycleSignal && upstreamSignal ? AbortSignal.any([lifecycleSignal, upstreamSignal]) : lifecycleSignal ?? upstreamSignal;
	};
	const getQueuedFollowupAbortSignal = () => params.replyOptions?.turnAdoptionLifecycle?.abortSignal ?? dispatchReplyOperation?.abortSignal ?? params.replyOptions?.abortSignal;
	let observedReplyDelivery = false;
	let agentRunTerminalOutcome;
	let agentRunId = params.replyOptions?.runId;
	const markObservedReplyDelivery = async () => {
		if (observedReplyDelivery) return;
		observedReplyDelivery = true;
		await params.replyOptions?.onObservedReplyDelivery?.();
	};
	const getReplyOptions = () => {
		const abortSignal = getDispatchAbortSignal();
		const expectedExistingSessionId = params.replyOptions?.expectedExistingSessionId ? dispatchReplyOperation?.sessionId ?? admittedExpectedSessionId : void 0;
		return {
			...params.replyOptions,
			...expectedExistingSessionId ? { expectedExistingSessionId } : {},
			...abortSignal ? {
				abortSignal,
				queuedFollowupAbortSignal: getQueuedFollowupAbortSignal()
			} : {},
			onAgentRunStart: (...args) => {
				agentRunTerminalOutcome = "completed";
				agentRunId = args[0];
				params.messageAuditTerminal?.observeRunId(args[0]);
				return params.replyOptions?.onAgentRunStart?.(...args);
			},
			onAgentRunTerminalOutcome: (outcome) => {
				if (outcome === "failed" || agentRunTerminalOutcome === void 0) agentRunTerminalOutcome = outcome;
				params.replyOptions?.onAgentRunTerminalOutcome?.(outcome);
			},
			...dispatchReplyOperation ? { replyOperation: dispatchReplyOperation } : {},
			...params.replyOptions?.internalEventExecution ? { onReplyOperationOwned: (operation) => {
				if (dispatchReplyOperation && dispatchReplyOperation !== operation) throw new Error("Reply dispatch already owns another operation");
				operation.abortSignal.throwIfAborted();
				params.replyOptions?.abortSignal?.throwIfAborted();
				params.replyOptions?.onReplyOperationOwned?.(operation);
				params.replyOptions?.internalEventExecution?.assertCurrent?.();
				operation.retainFailureUntilComplete();
				dispatchReplyOperation = operation;
				dispatchAbortOperation = operation;
				admittedExpectedSessionId = operation.sessionId;
				return true;
			} } : {}
		};
	};
	const completeDispatchReplyOperation = () => {
		releasePreDispatchLifecycleAdmission(() => waitForReplyDispatcherIdle(params.dispatcher));
		const operation = dispatchReplyOperation;
		if (!operation) return;
		const timeoutPolicy = params.dispatcher.resolveFollowupAdmissionBarrierTimeoutPolicy?.();
		const complete = () => {
			if (params.replyOptions?.internalEventExecution) {
				const settle = () => operation.complete();
				waitForDispatchDelivery().then(settle, settle);
			} else operation.completeWithAfterClearBarrier(waitForDispatchDelivery(), timeoutPolicy);
		};
		if (dispatchLifecycleWork.owner.size > 0) Promise.allSettled(Array.from(dispatchLifecycleWork.owner)).then(complete);
		else complete();
	};
	const failDispatchReplyOperation = (error, terminalOutcome) => {
		if (terminalOutcome === "failed") agentRunTerminalOutcome = "failed";
		dispatchReplyOperation?.freezeAbort();
		if (dispatchReplyOperation && !dispatchReplyOperation.result) dispatchReplyOperation.fail("run_failed", error);
		completeDispatchReplyOperation();
	};
	const isDispatchOperationAborted = () => getDispatchAbortSignal()?.aborted === true;
	const isPreDispatchOperationAborted = () => getPreDispatchAbortSignal()?.aborted === true;
	const throwIfDispatchOperationAborted = () => {
		if (isDispatchOperationAborted()) throw new DispatchReplyOperationAbortedError();
	};
	const turnLedger = createReplyTurnLedger(params.dispatcher);
	return {
		completeDispatchReplyOperation,
		dispatchHookDispatcher: createAbortAwareDispatcher({
			dispatcher: {
				...params.dispatcher,
				sendToolResult: (payload) => turnLedger.sendQueued("tool", payload).queued,
				sendBlockReply: (payload) => turnLedger.sendQueued("block", payload).queued,
				sendFinalReply: (payload) => turnLedger.sendQueued("final", payload).queued,
				...params.dispatcher.sendPreparedReply ? { sendPreparedReply: (kind, plan) => turnLedger.sendPreparedQueued(kind, plan).queued } : {}
			},
			isAborted: isPreDispatchOperationAborted
		}),
		turnLedger,
		ensureDispatchReplyOperation,
		failDispatchReplyOperation,
		getAgentRunId: () => agentRunId,
		getAgentRunTerminalOutcome: () => agentRunTerminalOutcome,
		getDispatchAbortOperation: () => dispatchAbortOperation,
		getDispatchAbortSignal,
		getDispatchReplyOperation: () => dispatchReplyOperation,
		getReplyOptions,
		getObservedReplyDelivery: () => observedReplyDelivery,
		getPreDispatchAbortSignal,
		isDispatchOperationAborted,
		isPreDispatchOperationAborted,
		markObservedReplyDelivery,
		releasePreDispatchLifecycleAdmission,
		runWithDispatchLifecycleAdmission,
		throwIfDispatchOperationAborted,
		trackDispatchLifecycleWork
	};
}
//#endregion
//#region src/auto-reply/reply/dispatch-from-config.timing.ts
const replyHotPathTimingLog = createSubsystemLogger("auto-reply/reply-timing");
function createReplyHotPathTimingTracker(options = {}) {
	const timing = createReplyTimingTracker({
		log: replyHotPathTimingLog,
		enabled: options.profilerEnabled === true,
		formatMessage: (params, summary, stages) => `reply hot path timings channel=${params.channel} messageId=${params.messageId ?? "unknown"} runId=${params.runId ?? "unknown"} sessionId=${params.sessionId ?? "unknown"} sessionKey=${params.sessionKey ?? "unknown"} outcome=${params.outcome} totalMs=${summary.totalMs} stages=${stages}${params.reason ? ` reason=${params.reason}` : ""}`,
		detailKeys: () => [
			"channel",
			"messageId",
			"runId",
			"sessionId",
			"sessionKey",
			"outcome",
			"reason"
		]
	});
	return {
		measure: timing.measure,
		logIfSlow(params, completion) {
			if (!options.profilerEnabled && !completion?.beforeReplyResolver) return;
			timing.logIfSlow(params);
		},
		logPreparationIfSlow(params) {
			timing.logIfSlow({
				...params,
				outcome: "milestone",
				reason: "before_reply_resolver"
			}, { repeat: true });
		}
	};
}
//#endregion
//#region src/auto-reply/reply/dispatch-from-config.gather.ts
async function gatherDispatchRequest(params, messageAuditTerminal, allowActiveQueueResolution = false, onRuntimeLease) {
	const lifecycleGeneration = getAgentEventLifecycleGeneration();
	const ctx = isFinalizedInboundContext(params.ctx) ? params.ctx : finalizeInboundContext(params.ctx);
	const turnAdoptionLifecycle = params.replyOptions?.turnAdoptionLifecycle;
	prepareChannelParticipantObservation(ctx);
	const turnAdoptionState = { adopted: false };
	const normalizedParams = {
		...params,
		ctx,
		replyOptions: {
			...params.replyOptions,
			...turnAdoptionLifecycle ? { turnAdoptionLifecycle: {
				...turnAdoptionLifecycle,
				onAdopted: async () => {
					await turnAdoptionLifecycle.onAdopted();
					turnAdoptionState.adopted = true;
				}
			} } : {}
		}
	};
	const replyOperationRunState = resolveReplyOperationRunState(normalizedParams.replyOptions) ?? {};
	let replayUnsafeActivity = false;
	const state = {
		params: normalizedParams,
		messageAuditTerminal,
		allowInboundHandlers: replyOperationRunState.heartbeat === void 0 && !params.replyOptions?.internalEventExecution,
		get inboundDedupeReplayUnsafe() {
			const admission = replyOperationRunState.admission;
			return replayUnsafeActivity || admission?.status === "accepted" && admission.mode === "steer" || admission?.status === "skipped" && admission.reason === "question-response-indeterminate";
		},
		turnAdoptionState: turnAdoptionLifecycle ? turnAdoptionState : void 0
	};
	const { cfg, dispatcher } = normalizedParams;
	bindReplyDispatcherConversationContext(dispatcher, ctx.agentText);
	const targetAgentId = resolveSessionAgentId({
		sessionKey: resolveCommandTurnTargetSessionKey(ctx) ?? ctx.SessionKey,
		config: cfg,
		fallbackAgentId: ctx.AgentId
	});
	const refusal = readAgentDatabaseAdmissionRefusal(targetAgentId);
	if (refusal) {
		const aborted = params.replyOptions?.abortSignal?.aborted === true;
		const queuedFinal = !aborted && dispatcher.sendFinalReply({
			text: `${refusal.reason}\n${refusal.repairHint}`,
			isError: true
		});
		const outcome = aborted ? "skipped" : "error";
		const reason = aborted ? "reply_operation_aborted" : refusal.code;
		noteDispatchProcessedOutcome({
			outcome,
			reason
		});
		messageAuditTerminal?.note(outcome, { reason });
		return {
			status: "complete",
			result: {
				queuedFinal,
				counts: dispatcher.getQueuedCounts()
			}
		};
	}
	const diagnosticsEnabled = isDiagnosticsEnabled(cfg);
	const channel = normalizeLowercaseStringOrEmpty(ctx.Surface ?? ctx.Provider ?? "unknown");
	const chatId = ctx.To ?? ctx.From;
	const messageId = ctx.MessageSidFull ?? ctx.MessageSid ?? ctx.MessageSidFirst ?? ctx.MessageSidLast;
	const sessionKey = normalizeOptionalString(ctx.SessionKey) ?? normalizeOptionalString(ctx.CommandTargetSessionKey);
	const startTime = diagnosticsEnabled ? Date.now() : 0;
	const canTrackSession = diagnosticsEnabled && Boolean(sessionKey);
	const assertRequestCurrent = () => params.replyOptions?.operatorAuthority?.assertCurrent();
	const initialSessionStoreEntry = await resolveSessionStoreLookup(ctx, cfg, assertRequestCurrent);
	assertRequestCurrent();
	const lifecycleSessionId = initialSessionStoreEntry.sessionKey === sessionKey ? initialSessionStoreEntry.entry?.sessionId : void 0;
	const messageLifecycle = createDiagnosticMessageLifecycle({
		enabled: diagnosticsEnabled,
		channel,
		chatId,
		messageId,
		sessionKey,
		sessionId: lifecycleSessionId,
		agentId: targetAgentId,
		source: "dispatch",
		processingReason: "message_start",
		startedAtMs: startTime,
		trackSessionState: canTrackSession
	});
	const traceAttributes = {
		surface: channel,
		hasSessionKey: Boolean(sessionKey),
		hasRunId: typeof params.replyOptions?.runId === "string"
	};
	const replyHotPathTiming = createReplyHotPathTimingTracker({ profilerEnabled: isReplyProfilerEnabled({ config: cfg }) });
	const traceReplyPhase = (name, run) => replyHotPathTiming.measure(name, () => measureDiagnosticsTimelineSpan(name, run, {
		phase: "agent-turn",
		config: cfg,
		attributes: traceAttributes
	}));
	let agentDispatchStartedAt = 0;
	const recordProcessed = (outcome, opts) => {
		noteDispatchProcessedOutcome({
			outcome,
			...opts?.reason !== void 0 ? { reason: opts.reason } : {}
		});
		messageAuditTerminal?.note(outcome, opts);
		if (diagnosticsEnabled) replyHotPathTiming.logIfSlow({
			channel,
			messageId,
			runId: params.replyOptions?.runId,
			sessionId: lifecycleSessionId,
			sessionKey,
			outcome,
			reason: opts?.reason
		}, { beforeReplyResolver: agentDispatchStartedAt === 0 });
		messageLifecycle.markProcessed(outcome, opts);
	};
	const finishReplyOperationAborted = () => {
		recordProcessed("skipped", { reason: "reply_operation_aborted" });
		return {
			status: "complete",
			result: {
				queuedFinal: false,
				counts: dispatcher.getQueuedCounts()
			}
		};
	};
	if (params.replyOptions?.abortSignal?.aborted) return finishReplyOperationAborted();
	const recordAgentDispatchStarted = () => {
		if (!diagnosticsEnabled || agentDispatchStartedAt > 0) return;
		agentDispatchStartedAt = Date.now();
		replyHotPathTiming.logPreparationIfSlow({
			channel,
			messageId,
			runId: params.replyOptions?.runId,
			sessionId: lifecycleSessionId,
			sessionKey
		});
		logMessageDispatchStarted({
			channel,
			sessionKey: acpDispatchSessionKey,
			source: "replyResolver"
		});
	};
	const recordAgentDispatchCompleted = (outcome, opts) => {
		if (!diagnosticsEnabled || agentDispatchStartedAt <= 0) return;
		logMessageDispatchCompleted({
			channel,
			sessionKey: acpDispatchSessionKey,
			source: "replyResolver",
			durationMs: Date.now() - agentDispatchStartedAt,
			outcome,
			reason: opts?.reason,
			error: opts?.error
		});
	};
	const markInboundDedupeReplayUnsafe = () => {
		replayUnsafeActivity = true;
	};
	const boundAcpDispatchSessionKey = state.allowInboundHandlers ? await resolveBoundAcpDispatchSessionKey({
		ctx,
		cfg
	}) : void 0;
	const acpDispatchSessionKey = boundAcpDispatchSessionKey ?? initialSessionStoreEntry.sessionKey ?? sessionKey;
	const sourceSessionKey = normalizeOptionalString(ctx.SessionKey);
	const dispatchOperationSessionKey = sourceSessionKey ?? initialSessionStoreEntry.sessionKey ?? sessionKey ?? acpDispatchSessionKey;
	const operationSessionStoreEntry = sourceSessionKey && initialSessionStoreEntry.sessionKey && sourceSessionKey !== initialSessionStoreEntry.sessionKey ? await resolveSessionStoreLookup({
		...ctx,
		CommandTargetSessionKey: void 0
	}, cfg, assertRequestCurrent) : initialSessionStoreEntry;
	assertRequestCurrent();
	if (params.replyOptions?.abortSignal?.aborted) return finishReplyOperationAborted();
	const initialDispatchReplyOperation = dispatchOperationSessionKey ? replyRunRegistry.get(dispatchOperationSessionKey) : void 0;
	if (params.replyOptions?.isHeartbeat === true && dispatchOperationSessionKey && initialDispatchReplyOperation) {
		noteDispatchProcessedOutcome({
			outcome: "skipped",
			reason: "reply-operation-active"
		});
		messageAuditTerminal?.note("skipped", { reason: "reply-operation-active" });
		return {
			status: "complete",
			result: {
				queuedFinal: false,
				counts: dispatcher.getQueuedCounts()
			}
		};
	}
	const markProgress = () => {
		if (!canTrackSession || !sessionKey) return;
		markDiagnosticSessionProgress({ sessionKey });
		if (acpDispatchSessionKey && acpDispatchSessionKey !== sessionKey) markDiagnosticSessionProgress({ sessionKey: acpDispatchSessionKey });
	};
	const sessionStoreEntry = boundAcpDispatchSessionKey ? await resolveSessionStoreLookup({
		...ctx,
		SessionKey: boundAcpDispatchSessionKey
	}, cfg, assertRequestCurrent) : initialSessionStoreEntry;
	assertRequestCurrent();
	if (params.replyOptions?.abortSignal?.aborted) return finishReplyOperationAborted();
	const dispatchKind = resolveSessionDispatchKind(acpDispatchSessionKey, sessionStoreEntry.entry);
	const toSessionBinding = ({ sessionKey: bindingSessionKey, entry, storePath }) => bindingSessionKey && entry?.sessionId ? {
		sessionKey: bindingSessionKey,
		sessionId: entry.sessionId,
		lifecycleRevision: entry.lifecycleRevision,
		storePath
	} : void 0;
	let preparedSessionBinding = toSessionBinding(sessionStoreEntry);
	let preparedOperationSessionBinding = toSessionBinding(operationSessionStoreEntry);
	const sessionKeysMatch = (left, right) => Boolean(left && right && normalizeExplicitSessionKey(left, ctx) === normalizeExplicitSessionKey(right, ctx));
	const notePreparedSession = (binding) => {
		if (sessionKeysMatch(binding.sessionKey, sessionStoreEntry.sessionKey)) preparedSessionBinding = binding;
		if (sessionKeysMatch(binding.sessionKey, operationSessionStoreEntry.sessionKey)) preparedOperationSessionBinding = binding;
		params.replyOptions?.onSessionPrepared?.(binding);
	};
	const resolveOperationExpectedSessionId = () => preparedOperationSessionBinding?.sessionId ?? operationSessionStoreEntry.entry?.sessionId;
	const resolvePreparedTranscriptBinding = (mirrorSessionKey) => preparedSessionBinding && sessionKeysMatch(mirrorSessionKey, preparedSessionBinding.sessionKey) ? preparedSessionBinding : void 0;
	const sessionAgentId = resolveSessionAgentId({
		sessionKey: acpDispatchSessionKey,
		config: cfg,
		fallbackAgentId: ctx.AgentId
	});
	const sessionAgentCfg = resolveAgentConfig(cfg, sessionAgentId);
	const assertProgressCurrent = () => {
		assertAgentRunLifecycleGenerationCurrent(lifecycleGeneration);
		params.replyOptions?.abortSignal?.throwIfAborted();
		replyOperationCoordinator.getDispatchAbortSignal()?.throwIfAborted();
		assertRequestCurrent();
	};
	const verboseProgress = createShouldEmitVerboseProgress({
		agentId: sessionAgentId,
		sessionKey: acpDispatchSessionKey,
		storePath: sessionStoreEntry.storePath,
		initialExplicitLevel: sessionStoreEntry.entry?.verboseLevel,
		assertCurrent: assertProgressCurrent,
		fallbackLevel: normalizeVerboseLevel(sessionStoreEntry.entry?.verboseLevel ?? sessionAgentCfg?.verboseDefault ?? cfg.agents?.defaults?.verboseDefault ?? "") ?? "off"
	});
	const replyRoute = resolveEffectiveReplyRoute({
		ctx,
		entry: sessionStoreEntry.entry
	});
	const routeThreadId = resolveRoutedDeliveryThreadId({
		ctx,
		sessionKey: acpDispatchSessionKey
	});
	const routeReplyThreadId = replyRoute.threadId ?? routeThreadId;
	const inboundAudio = hasInboundAudio(ctx);
	const sessionTtsAuto = normalizeTtsAutoMode(sessionStoreEntry.entry?.ttsAuto);
	const preparedReplyDispatchAgentId = boundAcpDispatchSessionKey ? resolveSessionAgentId({
		sessionKey,
		config: cfg,
		fallbackAgentId: ctx.AgentId
	}) : sessionAgentId;
	let preparedReplyDispatchRuntime;
	let preparedTtsPreferences;
	try {
		preparedReplyDispatchRuntime = await traceReplyPhase("reply.load_prepared_dispatch_runtime", async () => {
			const { loadPublishedGatewayReplyDispatchRuntime } = await loadPreparedModelRuntime();
			return await loadPublishedGatewayReplyDispatchRuntime({
				agentId: preparedReplyDispatchAgentId,
				demand: params.replyOptions?.isHeartbeat ? "scheduled" : "interactive",
				abortSignal: params.replyOptions?.abortSignal,
				onRuntimeLease
			});
		});
		preparedTtsPreferences = await prepareTtsPreferences();
		params.replyOptions?.abortSignal?.throwIfAborted();
		params.replyOptions?.operatorAuthority?.assertCurrent();
	} catch (error) {
		if (params.replyOptions?.abortSignal?.aborted && isAbortError(error)) return finishReplyOperationAborted();
		throw error;
	}
	const workspaceDir = preparedReplyDispatchRuntime?.workspaceDir ?? resolveAgentWorkspaceDir(cfg, sessionAgentId);
	const replyOperationCoordinator = createDispatchReplyOperationCoordinator({
		allowActiveQueueResolution,
		agentId: operationSessionStoreEntry.agentId ?? sessionAgentId,
		cfg,
		ctx,
		dispatcher,
		dispatchOperationSessionKey,
		initialDispatchReplyOperation,
		messageAuditTerminal,
		operationSessionStoreEntry,
		replyOptions: normalizedParams.replyOptions,
		resolveOperationExpectedSessionId,
		routeThreadId,
		sessionWorkerPlacementContext: normalizedParams.sessionWorkerPlacementContext
	});
	const { getPreDispatchAbortSignal } = replyOperationCoordinator;
	const pluginRegistry = preparedReplyDispatchRuntime?.inboundPluginRegistry ?? await traceReplyPhase("reply.load_runtime_plugin_registry_handle", async () => {
		const { loadAgentRuntimePluginRegistryHandle } = await traceReplyPhase("reply.load_runtime_plugins", loadRuntimePlugins);
		return loadAgentRuntimePluginRegistryHandle({
			config: cfg,
			workspaceDir,
			allowGatewaySubagentBinding: true
		});
	});
	const hookRunner = getGlobalHookRunner();
	const timestamp = typeof ctx.Timestamp === "number" && Number.isFinite(ctx.Timestamp) ? ctx.Timestamp : void 0;
	const messageIdForHook = ctx.MessageSidFull ?? ctx.MessageSid ?? ctx.MessageSidFirst ?? ctx.MessageSidLast;
	const hookCtx = { ...ctx };
	const buildHookState = (sourceCtx) => {
		const nextHookContext = deriveInboundMessageHookContext(sourceCtx, { messageId: messageIdForHook });
		const inboundClaim = toPluginInboundClaimPair(nextHookContext, {
			commandAuthorized: typeof ctx.CommandAuthorized === "boolean" ? ctx.CommandAuthorized : void 0,
			wasMentioned: typeof ctx.WasMentioned === "boolean" ? ctx.WasMentioned : void 0
		});
		return {
			hookContext: nextHookContext,
			inboundClaimContext: inboundClaim.context,
			inboundClaimEvent: inboundClaim.event
		};
	};
	const hookState = buildHookState(hookCtx);
	const { isGroup, groupId } = hookState.hookContext;
	let hookMediaPrepared = false;
	let hookMediaMetadataStaged = false;
	const prepareHookMediaMetadata = async () => {
		if (hookMediaPrepared) return;
		hookMediaPrepared = true;
		if (await traceReplyPhase("reply.stage_remote_media_for_dispatch", () => stageRemoteInboundMediaIfNeeded({
			ctx: hookCtx,
			cfg,
			agentId: sessionAgentId,
			sessionKey: acpDispatchSessionKey,
			workspaceDir,
			remoteMediaMode: "cache",
			abortSignal: getPreDispatchAbortSignal()
		}))) {
			hookMediaMetadataStaged = true;
			Object.assign(hookState, buildHookState(hookCtx));
		}
	};
	const buildMessageReceivedHookContext = () => {
		const mediaRemoteHost = normalizeOptionalString(ctx.MediaRemoteHost);
		const { hookContext } = hookState;
		const hasUnstagedRemoteMediaMetadata = Boolean(hookContext.media?.length);
		if (hookMediaMetadataStaged || !mediaRemoteHost || !hasUnstagedRemoteMediaMetadata) return hookContext;
		const messageReceivedCtx = { ...hookCtx };
		stripLegacyMediaContextFields(messageReceivedCtx);
		delete messageReceivedCtx.media;
		return {
			...buildHookState(messageReceivedCtx).hookContext,
			mediaRemoteHost,
			mediaStagingPending: true,
			originalMedia: hookContext.media?.map((entry) => ({ ...entry })),
			originalMediaPath: hookContext.mediaPath,
			originalMediaUrl: hookContext.mediaUrl,
			originalMediaType: hookContext.mediaType,
			originalMediaPaths: hookContext.mediaPaths,
			originalMediaUrls: hookContext.mediaUrls,
			originalMediaTypes: hookContext.mediaTypes
		};
	};
	return {
		status: "ready",
		state: Object.assign(state, {
			ctx,
			cfg,
			dispatcher,
			sessionKey,
			traceReplyPhase,
			recordProcessed,
			recordAgentDispatchStarted,
			recordAgentDispatchCompleted,
			markProcessing: () => messageLifecycle.markProcessing(),
			markIdle: (reason) => messageLifecycle.markIdle(reason),
			markInboundDedupeReplayUnsafe,
			acpDispatchSessionKey,
			dispatchKind,
			markProgress,
			sessionStoreEntry,
			notePreparedSession,
			resolvePreparedTranscriptBinding,
			sessionAgentId,
			dispatchOperationSessionKey,
			operationSessionStoreEntry,
			noteRunVerbosity: verboseProgress.noteRunVerbosity,
			assertProgressCurrent,
			shouldEmitVerboseProgress: verboseProgress.shouldEmit,
			shouldEmitFullVerboseProgress: verboseProgress.shouldEmitFull,
			shouldEmitVerboseProgressAsync: verboseProgress.shouldEmitAsync,
			shouldEmitFullVerboseProgressAsync: verboseProgress.shouldEmitFullAsync,
			replyRoute,
			routeReplyThreadId,
			inboundAudio,
			sessionTtsAuto,
			workspaceDir,
			preparedReplyDispatchRuntime,
			preparedTtsPreferences,
			pluginRegistry,
			replyOperationRunState,
			...replyOperationCoordinator,
			hookRunner,
			timestamp,
			messageIdForHook,
			isGroup,
			groupId,
			hookState,
			prepareHookMediaMetadata,
			buildMessageReceivedHookContext
		})
	};
}
//#endregion
//#region src/auto-reply/reply/conversation-turn-capture.ts
const CONVERSATION_TURN_REPLY_CUSTOM_TYPE = "openclaw.conversation-turn-reply";
function readPersistedReplyText(message) {
	const content = message?.content;
	return normalizeOptionalString(typeof content === "string" ? content : collectTextContentBlocks(content).join("\n"));
}
async function capturePendingConversationTurnReplyUnsafe(params) {
	if (params.ctx.InboundAccessAuthorized !== true) return false;
	const sessionKey = normalizeOptionalString(params.ctx.SessionKey);
	const messageId = normalizeOptionalString(params.ctx.MessageSidFull) ?? normalizeOptionalString(params.ctx.MessageSid) ?? normalizeOptionalString(params.ctx.MessageSidFirst) ?? normalizeOptionalString(params.ctx.MessageSidLast);
	const replyText = normalizeOptionalString(params.ctx.agentText);
	if (!sessionKey || !messageId || !replyText) return false;
	const conversation = conversationIdentityFromMsgContext({ ctx: params.ctx });
	if (!conversation) return false;
	const replyToId = normalizeOptionalString(params.ctx.ReplyToIdFull) ?? normalizeOptionalString(params.ctx.ReplyToId);
	const threadId = params.ctx.MessageThreadId == null ? void 0 : normalizeOptionalString(String(params.ctx.MessageThreadId));
	const replyTarget = {
		messageId,
		...replyToId ? { replyToId } : {},
		...threadId ? { threadId } : {}
	};
	const agentId = normalizeOptionalString(params.ctx.AgentId) ?? resolveAgentIdFromSessionKey(sessionKey);
	const scope = resolveConversationRegistryScope({
		agentId,
		config: params.cfg
	});
	const sessionEntry = loadSessionEntryReadOnly({
		...scope,
		sessionKey,
		readConsistency: "latest"
	});
	if (!sessionEntry) return false;
	const timestamp = normalizeMessageTimestampMs(params.ctx.Timestamp);
	const parentConversationRef = threadId ? conversation.parentConversationRef ?? buildConversationRef({
		channel: conversation.channel,
		accountId: conversation.accountId,
		kind: conversation.kind,
		peerId: conversation.peerId
	}) : void 0;
	const input = {
		text: replyText,
		timestamp,
		idempotencyKey: `conversation-inbound:${conversation.conversationRef}:${messageId}`,
		...params.ctx.InputProvenance ? { provenance: params.ctx.InputProvenance } : {},
		transport: {
			channel: conversation.channel,
			conversationRef: conversation.conversationRef,
			...replyTarget
		},
		sender: conversation.kind === "group" || conversation.kind === "channel" ? buildChannelUserTurnSender(params.ctx) : void 0
	};
	const claim = await claimPendingConversationTurnReply({
		agentId,
		conversationRef: conversation.conversationRef,
		...parentConversationRef ? { parentConversationRef } : {},
		sessionId: sessionEntry.sessionId,
		messageId,
		replyToId,
		threadId,
		text: replyText,
		timestamp
	});
	if (!claim) {
		if (!replyToId) return false;
		const operation = await findConversationTurnDeliveryByReplyTarget(scope, {
			conversationRef: conversation.conversationRef,
			replyToId
		}) ?? (parentConversationRef && parentConversationRef !== conversation.conversationRef ? await findConversationTurnDeliveryByReplyTarget(scope, {
			conversationRef: parentConversationRef,
			replyToId
		}) : void 0);
		if (operation?.status === "replied" && operation.reply?.messageId === messageId) return true;
		if (operation && operation.status !== "replied") await markConversationDeliverySent(scope, operation.operationId, replyToId);
		return false;
	}
	let replyCommitted = false;
	try {
		if (sessionEntry.sessionId !== claim.sessionId) throw new Error(`session changed before captured reply persistence: ${sessionKey}`);
		const prepared = preparePersistedUserTurnMessageForTranscriptWrite(buildPersistedUserTurnMessage(input), {
			agentId,
			sessionKey,
			beforeMessageWrite: runAgentHarnessBeforeMessageWriteHook
		});
		if (!prepared) throw new Error("captured conversation turn reply was blocked before persistence");
		const persistedMessage = redactTranscriptMessage(prepared, params.cfg);
		const persistedReplyText = readPersistedReplyText(persistedMessage);
		if (!persistedReplyText) throw new Error("captured conversation turn reply has no persistable text");
		await markConversationDeliveryReplied(scope, {
			operationId: claim.turnId,
			session: {
				sessionKey,
				sessionId: claim.sessionId,
				lifecycleRevision: sessionEntry.lifecycleRevision
			},
			reply: {
				...replyTarget,
				text: persistedReplyText,
				timestamp: timestamp ?? Date.now()
			}
		}, claim.assertCurrent);
		replyCommitted = true;
		return await runConversationDatabaseWrite(scope, (writeScope) => {
			claim.assertCurrent();
			const current = loadSessionEntryReadOnly({
				...writeScope,
				sessionKey,
				readConsistency: "latest"
			});
			if (current?.sessionId !== claim.sessionId || current.lifecycleRevision !== sessionEntry.lifecycleRevision) throw new Error(`session changed before captured reply persistence: ${sessionKey}`);
			const artifactId = `conversation-turn-reply-${claim.turnId}`;
			let persisted = false;
			try {
				const appendResult = appendTranscriptEventSync({
					...writeScope,
					sessionId: sessionEntry.sessionId,
					sessionKey
				}, {
					type: "custom",
					id: artifactId,
					customType: CONVERSATION_TURN_REPLY_CUSTOM_TYPE,
					appendMode: "side",
					timestamp: timestamp ?? Date.now(),
					data: {
						turnId: claim.turnId,
						conversationRef: conversation.conversationRef,
						...replyTarget,
						message: persistedMessage
					}
				});
				persisted = appendResult.ok && appendResult.value;
				if (!appendResult.ok) logVerbose(`captured conversation turn reply audit persistence failed: ${appendResult.error.code}`);
			} catch (error) {
				logVerbose(`captured conversation turn reply audit persistence failed: ${String(error)}`);
			}
			if (!persisted) logVerbose("captured conversation turn reply audit artifact was not persisted");
			claim.complete(persisted ? { transcriptArtifactId: artifactId } : void 0);
			return true;
		});
	} catch (error) {
		claim.release();
		logVerbose(`conversation turn reply capture failed: ${String(error)}`);
		return replyCommitted;
	}
}
/** Consumes a correlated channel reply before it can start a second local agent turn. */
async function capturePendingConversationTurnReply(params) {
	try {
		return await capturePendingConversationTurnReplyUnsafe(params);
	} catch (error) {
		logVerbose(`conversation turn reply capture unavailable: ${String(error)}`);
		return false;
	}
}
//#endregion
//#region src/auto-reply/reply/inbound-dedupe.ts
const DEFAULT_INBOUND_DEDUPE_TTL_MS = 12e5;
const DEFAULT_INBOUND_DEDUPE_MAX = 5e3;
/**
* Keep inbound dedupe shared across bundled chunks so the same provider
* message cannot bypass dedupe by entering through a different chunk copy.
*/
const INBOUND_DEDUPE_CACHE_KEY = Symbol.for("openclaw.inboundDedupeCache");
const INBOUND_DEDUPE_INFLIGHT_KEY = Symbol.for("openclaw.inboundDedupeClaims");
const inboundDedupeCache = resolveGlobalDedupeCache(INBOUND_DEDUPE_CACHE_KEY, {
	ttlMs: DEFAULT_INBOUND_DEDUPE_TTL_MS,
	maxSize: DEFAULT_INBOUND_DEDUPE_MAX
});
const inboundDedupeInFlight = resolveGlobalSingleton(INBOUND_DEDUPE_INFLIGHT_KEY, () => /* @__PURE__ */ new Map());
function resolveInboundDedupeSessionScope(ctx) {
	const commandTarget = resolveCommandTurnTargetSessionKey(ctx);
	if (commandTarget) return commandTarget;
	const sessionKey = normalizeOptionalString(ctx.SessionKey) || "";
	const parsed = parseAgentSessionKey(sessionKey);
	return parsed ? `agent:${parsed.agentId}` : sessionKey;
}
function buildInboundDedupeKey(ctx) {
	const provider = normalizeOptionalLowercaseString(ctx.OriginatingChannel ?? ctx.Provider ?? ctx.Surface) || "";
	const messageId = normalizeOptionalString(ctx.MessageSid);
	if (!provider || !messageId) return null;
	const peerId = ctx.OriginatingTo ?? ctx.To ?? ctx.From ?? ctx.SessionKey;
	if (!peerId) return null;
	const sessionScope = resolveInboundDedupeSessionScope(ctx);
	const accountId = normalizeOptionalString(ctx.AccountId) ?? "";
	const routeKey = channelRouteDedupeKey({
		channel: provider,
		to: peerId,
		accountId,
		threadId: ctx.MessageThreadId
	});
	return JSON.stringify([
		sessionScope,
		routeKey,
		messageId
	]);
}
function claimInboundDedupe(ctx, opts) {
	const key = buildInboundDedupeKey(ctx);
	if (!key) return { status: "invalid" };
	const duplicate = inboundDedupeCache.peek(key);
	if (inboundDedupeInFlight.has(key)) return { status: duplicate ? "duplicate" : "inflight" };
	const recovered = opts?.reclaimPendingInput?.() === true;
	if (duplicate) {
		if (!recovered) return { status: "duplicate" };
		inboundDedupeCache.delete(key);
	}
	const owner = {};
	inboundDedupeInFlight.set(key, owner);
	return {
		status: "claimed",
		commit: () => {
			if (inboundDedupeInFlight.get(key) === owner) {
				inboundDedupeCache.check(key, void 0, owner);
				inboundDedupeInFlight.delete(key);
			}
		},
		release: () => {
			if (inboundDedupeInFlight.get(key) === owner) inboundDedupeInFlight.delete(key);
			inboundDedupeCache.delete(key, owner);
		}
	};
}
function resetInboundDedupe() {
	inboundDedupeCache.clear();
	inboundDedupeInFlight.clear();
}
//#endregion
//#region src/auto-reply/reply/message-received-hooks.ts
/** Emit observation hooks once for an accepted inbound turn, independent of reply dispatch. */
function emitMessageReceivedHooks(params) {
	if (params.ctx.SuppressMessageReceivedHooks === true) return;
	const buildContext = params.buildContext ?? (() => deriveInboundMessageHookContext(params.ctx, { messageId: params.ctx.MessageSidFull ?? params.ctx.MessageSid ?? params.ctx.MessageSidFirst ?? params.ctx.MessageSidLast }));
	if (params.hookRunner?.hasHooks("message_received") === true) {
		const context = buildContext();
		fireAndForgetHook(params.hookRunner.runMessageReceived(toPluginMessageReceivedEvent(context), toPluginMessageContext(context)), "message_received plugin hook failed");
	}
	if (params.sessionKey) {
		const context = buildContext();
		fireAndForgetHook(triggerInternalHook(createInternalHookEvent("message", "received", params.sessionKey, {
			...toInternalMessageReceivedContext(context),
			timestamp: params.timestamp
		})), "message_received internal hook failed");
	}
}
//#endregion
//#region src/auto-reply/reply/dispatch-from-config.prepare-context.ts
async function prepareDispatchOperationContext(state) {
	const { acpDispatchSessionKey, buildMessageReceivedHookContext, cfg, ctx, dispatcher, hookRunner, isInternalWebchatTurn, markIdle, params, recordAgentDispatchCompleted, recordProcessed, replyRoute, sessionAgentId, sessionKey, sessionStoreEntry } = state;
	const sendBindingNotice = async (payload, mode, transcriptOwner) => {
		if (sourceReplyPolicy.suppressAutomaticSourceDelivery) return false;
		return await state.deliverBindingPayload(payload, mode, transcriptOwner);
	};
	const pluginOwnedBindingRecord = state.allowInboundHandlers ? await resolveDispatchConversationBinding(cfg, ctx) : null;
	const pluginOwnedBinding = toPluginConversationBinding(pluginOwnedBindingRecord);
	const pluginBindingSessionKey = normalizeOptionalString(pluginOwnedBindingRecord?.targetSessionKey);
	const pluginBindingTargetKind = pluginOwnedBindingRecord?.targetKind;
	const persistPluginBindingUserTurn = async () => {
		const recorder = params.replyOptions?.userTurnTranscriptRecorder;
		if (!recorder || !pluginBindingSessionKey) return;
		const targetAgentId = resolveSessionAgentId({
			sessionKey: pluginBindingSessionKey,
			config: cfg,
			fallbackAgentId: ctx.AgentId
		});
		const blockedOwner = (expectedSessionId) => ({
			agentId: targetAgentId,
			sessionKey: pluginBindingSessionKey,
			...expectedSessionId ? { expectedSessionId } : {},
			transcriptWriteBlocked: true
		});
		if (recorder.hasPersisted()) return blockedOwner();
		const assertCurrent = () => {
			state.getPreDispatchAbortSignal()?.throwIfAborted();
			params.replyOptions?.operatorAuthority?.assertCurrent();
		};
		let lastOwner;
		for (let attempt = 0; attempt < 2; attempt += 1) {
			const targetSessionStoreEntry = await resolveSessionStoreLookup({
				...ctx,
				CommandTargetSessionKey: void 0,
				SessionKey: pluginBindingSessionKey
			}, cfg, assertCurrent);
			assertCurrent();
			const targetSessionEntry = targetSessionStoreEntry.entry;
			if (!targetSessionEntry || targetSessionEntry.sessionId === lastOwner?.expectedSessionId) break;
			lastOwner = {
				agentId: targetAgentId,
				expectedSessionId: targetSessionEntry.sessionId,
				sessionKey: pluginBindingSessionKey
			};
			if (await recorder.persistApproved({
				target: {
					sessionId: targetSessionEntry.sessionId,
					sessionKey: pluginBindingSessionKey,
					sessionEntry: targetSessionEntry,
					...targetSessionStoreEntry.store ? { sessionStore: targetSessionStoreEntry.store } : {},
					storePath: targetSessionStoreEntry.storePath,
					agentId: targetAgentId,
					cwd: resolveAgentWorkspaceDir(cfg, targetAgentId),
					config: cfg
				},
				expectedSessionId: targetSessionEntry.sessionId,
				retryIfUnpersisted: true
			})) return lastOwner;
		}
		recorder.markBlocked();
		if (lastOwner) logVerbose(`plugin-bound user-turn persistence skipped after the target session changed`);
		return blockedOwner(lastOwner?.expectedSessionId);
	};
	const sendPolicy = resolveSendPolicy({
		cfg,
		entry: sessionStoreEntry.entry,
		sessionKey: sessionStoreEntry.sessionKey ?? sessionKey,
		channel: (state.shouldRouteToOriginating ? state.routeReplyChannel : void 0) ?? sessionDeliveryChannel(sessionStoreEntry.entry) ?? replyRoute.channel ?? ctx.Surface ?? ctx.Provider ?? void 0,
		chatType: sessionStoreEntry.entry?.chatType
	});
	const chatType = normalizeChatType(ctx.ChatType);
	state.replyOperationRunState.replyCompletion = resolveReplyCompletion(resolveSourceReplyExpectation({
		ctx,
		cfg,
		isHeartbeat: params.replyOptions?.isHeartbeat
	}), "empty");
	const { configuredVisibleReplies, harnessDefaultVisibleReplies } = resolveVisibleRepliesPolicy({
		cfg,
		chatType,
		ctx,
		entry: sessionStoreEntry.entry,
		sessionAgentId,
		sessionKey: acpDispatchSessionKey,
		sessionStore: sessionStoreEntry.store,
		turnModelOverride: resolveTurnModelOverride(params.replyOptions)
	});
	const effectiveVisibleReplies = configuredVisibleReplies ?? harnessDefaultVisibleReplies;
	const prefersMessageToolDelivery = params.replyOptions?.sourceReplyDeliveryMode === "message_tool_only" || ctx.InboundEventKind === "room_event" && !isInternalWebchatTurn || params.replyOptions?.sourceReplyDeliveryMode === void 0 && !isExplicitCommandTurnContext(ctx, cfg) && (configuredVisibleReplies === "message_tool" || !isInternalWebchatTurn && effectiveVisibleReplies === "message_tool");
	const groupResolution = resolveGroupSessionKey(ctx);
	const messageProvider = resolveOriginMessageProvider({
		originatingChannel: ctx.OriginatingChannel,
		provider: ctx.Provider ?? ctx.Surface
	});
	const groupPolicy = resolveGroupToolPolicy({
		config: cfg,
		sessionKey: acpDispatchSessionKey,
		messageProvider,
		groupId: groupResolution?.id,
		groupChannel: normalizeOptionalString(ctx.GroupChannel) ?? normalizeOptionalString(ctx.GroupSubject),
		groupSpace: normalizeOptionalString(ctx.GroupSpace),
		accountId: ctx.AccountId,
		senderId: normalizeOptionalString(ctx.SenderId),
		senderName: normalizeOptionalString(ctx.SenderName),
		senderUsername: normalizeOptionalString(ctx.SenderUsername),
		senderE164: normalizeOptionalString(ctx.SenderE164)
	});
	const messageToolAvailable = resolveReplyMessageToolAvailability({
		cfg,
		sessionAgentId,
		sessionKey: acpDispatchSessionKey,
		groupPolicy,
		prefersMessageToolDelivery
	});
	const sessionStableMessageToolAvailable = effectiveVisibleReplies === "message_tool" ? resolveStableMessageToolAvailability({
		cfg,
		ctx,
		sessionEntry: sessionStoreEntry.entry,
		sessionAgentId,
		sessionKey: acpDispatchSessionKey
	}) : void 0;
	const sourceReplyPolicyParams = {
		cfg,
		ctx,
		strictMessageToolOnly: ctx.InboundEventKind === "room_event" && !isInternalWebchatTurn,
		sendPolicy,
		suppressAcpChildUserDelivery: state.suppressAcpChildUserDelivery,
		explicitSuppressTyping: params.replyOptions?.suppressTyping === true,
		shouldSuppressTyping: state.shouldSuppressTyping,
		messageToolAvailable,
		sessionStableMessageToolAvailable,
		isHeartbeat: params.replyOptions?.isHeartbeat,
		requested: params.replyOptions?.sourceReplyDeliveryMode
	};
	let sourceReplyPolicy = resolveSourceReplyVisibilityPolicy({
		...sourceReplyPolicyParams,
		defaultVisibleReplies: harnessDefaultVisibleReplies
	});
	const alternateHarnessDefault = harnessDefaultVisibleReplies === "message_tool" ? "automatic" : "message_tool";
	const sourceReplyDeliveryRuntimeOptions = {
		sourceReplyDeliveryModeOrigin: resolveSourceReplyVisibilityPolicy({
			...sourceReplyPolicyParams,
			defaultVisibleReplies: alternateHarnessDefault
		}).sourceReplyDeliveryMode === sourceReplyPolicy.sourceReplyDeliveryMode ? "stable_policy" : "runtime_default",
		onSourceReplyDeliveryModeResolved: (mode) => {
			const stableMode = sourceReplyPolicy.sessionStableSourceReplyDeliveryMode;
			sourceReplyPolicy = resolveSourceReplyVisibilityPolicy({
				...sourceReplyPolicyParams,
				requested: mode
			});
			sourceReplyPolicy.sessionStableSourceReplyDeliveryMode = stableMode;
			Object.assign(state, sourceReplyPolicy, { sourceReplyPolicy });
		}
	};
	Object.assign(sourceReplyPolicy, sourceReplyDeliveryRuntimeOptions);
	const reasoningPayloadsEnabled = params.replyOptions?.reasoningPayloadsEnabled === true;
	const commentaryPayloadsEnabled = params.replyOptions?.commentaryPayloadsEnabled === true;
	const attachSourceReplyDeliveryMode = (result) => sourceReplyPolicy.sourceReplyDeliveryMode === "message_tool_only" || sourceReplyPolicy.sendPolicyDenied ? {
		...result,
		...sourceReplyPolicy.sourceReplyDeliveryMode === "message_tool_only" ? { sourceReplyDeliveryMode: sourceReplyPolicy.sourceReplyDeliveryMode } : {},
		...sourceReplyPolicy.sendPolicyDenied ? { sendPolicyDenied: true } : {}
	} : result;
	const baseDispatchResult = (queuedFinal = false) => ({
		queuedFinal,
		counts: dispatcher.getQueuedCounts()
	});
	const explicitCommandTurnCtx = isExplicitCommandTurnContext(ctx, cfg);
	const activeRunSafeCommandTurn = explicitCommandTurnCtx && isActiveRunSafeCommandTurn({
		commandTurn: resolveCommandTurnContext(ctx),
		cfg,
		provider: ctx.Provider ?? ctx.Surface
	});
	const unauthorizedTextSlashSourceReplyCtx = (chatType === "group" || chatType === "channel") && isUnauthorizedTextSlashCommand(ctx);
	const shouldDeliverPluginBindingReply = !sourceReplyPolicy.suppressAutomaticSourceDelivery || explicitCommandTurnCtx || ctx.InboundEventKind !== "room_event" && !unauthorizedTextSlashSourceReplyCtx;
	const skipDuplicate = () => {
		recordProcessed("skipped", { reason: "duplicate" });
		return {
			status: "complete",
			result: attachSourceReplyDeliveryMode(baseDispatchResult())
		};
	};
	const durableSourceTurnId = readChannelSourceTurnId(ctx) ?? (shouldMintChannelSourceTurnId(ctx.Provider ?? ctx.Surface) ? buildChannelSourceTurnId({
		provider: resolveOriginMessageProvider({
			originatingChannel: replyRoute.channel,
			provider: ctx.Provider ?? ctx.Surface
		}),
		accountId: replyRoute.accountId,
		conversationId: replyRoute.to,
		messageId: normalizeOptionalString(ctx.MessageSidFull) ?? normalizeOptionalString(ctx.MessageSid)
	}) : void 0);
	setChannelSourceTurnId(ctx, durableSourceTurnId);
	if (isDuplicateRestartRecoverySource(sessionStoreEntry.entry, durableSourceTurnId)) return skipDuplicate();
	const sourceRunId = normalizeOptionalString(ctx.MessageSid);
	const recorder = params.replyOptions?.userTurnTranscriptRecorder;
	let reclaimPendingInput;
	if (recorder?.getPendingInputMessage?.() && !recorder.hasPersisted() && sourceRunId && sessionStoreEntry.sessionKey && sessionStoreEntry.entry?.sessionId) {
		const recoveryScope = {
			agentId: sessionStoreEntry.agentId ?? sessionAgentId,
			storePath: sessionStoreEntry.storePath,
			sessionKey: sessionStoreEntry.sessionKey,
			sessionId: sessionStoreEntry.entry.sessionId
		};
		reclaimPendingInput = await prepareSessionPendingInputDedupeRecovery(recoveryScope, sourceRunId);
	}
	const claimInput = () => {
		const reclaim = reclaimPendingInput;
		return claimInboundDedupe(ctx, { reclaimPendingInput: reclaim ? () => !recorder.hasPersisted() && reclaim() : void 0 });
	};
	const inboundDedupeClaim = reclaimPendingInput && recorder?.withPendingInputCurrent ? await recorder.withPendingInputCurrent(claimInput) : claimInput();
	if (inboundDedupeClaim.status === "duplicate" || inboundDedupeClaim.status === "inflight") return skipDuplicate();
	const commitInboundDedupeIfClaimed = () => inboundDedupeClaim.commit?.();
	const releaseInboundDedupeIfClaimed = () => inboundDedupeClaim.release?.();
	const lifecycle = params.replyOptions?.turnAdoptionLifecycle;
	if (lifecycle && inboundDedupeClaim.status === "claimed") {
		const onAbandoned = lifecycle.onAbandoned;
		lifecycle.onAbandoned = () => {
			if (!state.inboundDedupeReplayUnsafe && !state.turnAdoptionState?.adopted) inboundDedupeClaim.release();
			onAbandoned?.();
		};
	}
	const finishReplyOperationBusyDispatch = (opts) => {
		state.releasePreDispatchLifecycleAdmission(() => waitForReplyDispatcherIdle(dispatcher));
		if (opts?.recordAgentDispatchCompleted) recordAgentDispatchCompleted("completed", { reason: "reply-operation-active" });
		recordProcessed("skipped", { reason: "reply-operation-active" });
		markIdle("message_completed");
		if (opts?.dedupeDisposition === "release") releaseInboundDedupeIfClaimed();
		else commitInboundDedupeIfClaimed();
		return attachSourceReplyDeliveryMode({
			...baseDispatchResult(),
			...opts?.sessionMetadataChanges ? { sessionMetadataChanges: opts.sessionMetadataChanges } : {}
		});
	};
	const finishReplyOperationAbortedDispatch = () => {
		const operation = state.getDispatchReplyOperation();
		recordReplyOperationAgentTurn([state.replyOperationRunState], operation);
		const queuedFinal = isReplyOperationStalledBeforeOutput(operation) && state.replyOperationRunState.continueStalledTurn?.() !== true ? dispatcher.sendFinalReply({
			text: STALLED_TURN_NOTICE_TEXT,
			isError: true
		}) : false;
		if (state.turnAdoptionState && !state.turnAdoptionState.adopted && !state.inboundDedupeReplayUnsafe) releaseInboundDedupeIfClaimed();
		else commitInboundDedupeIfClaimed();
		recordProcessed("skipped", { reason: "reply_operation_aborted" });
		markIdle("message_completed");
		state.completeDispatchReplyOperation();
		return attachSourceReplyDeliveryMode({
			...baseDispatchResult(queuedFinal),
			...state.turnLedger.hasObservedDelivery() ? { observedReplyDelivery: true } : {}
		});
	};
	const bindingState = {};
	const emitMessageReceivedHooks$1 = () => {
		if (!state.allowInboundHandlers) return;
		emitMessageReceivedHooks({
			ctx,
			hookRunner,
			sessionKey,
			timestamp: state.timestamp,
			buildContext: buildMessageReceivedHookContext
		});
	};
	state.markProcessing();
	if (state.allowInboundHandlers && await capturePendingConversationTurnReply({
		cfg,
		ctx
	})) {
		emitMessageReceivedHooks$1();
		commitInboundDedupeIfClaimed();
		recordProcessed("completed", { reason: "conversation-turn-reply" });
		markIdle("message_completed");
		return {
			status: "complete",
			result: attachSourceReplyDeliveryMode({
				...baseDispatchResult(),
				observedReplyDelivery: true
			})
		};
	}
	return {
		status: "ready",
		state: Object.assign(state, {
			sendBindingNotice,
			pluginOwnedBinding,
			pluginBindingSessionKey,
			pluginBindingTargetKind,
			persistPluginBindingUserTurn,
			sendPolicy,
			chatType,
			sourceReplyPolicy,
			sourceReplyDeliveryRuntimeOptions,
			...sourceReplyPolicy,
			reasoningPayloadsEnabled,
			commentaryPayloadsEnabled,
			attachSourceReplyDeliveryMode,
			explicitCommandTurnCtx,
			activeRunSafeCommandTurn,
			shouldDeliverPluginBindingReply,
			inboundDedupeClaim,
			commitInboundDedupeIfClaimed,
			finishReplyOperationBusyDispatch,
			finishReplyOperationAbortedDispatch,
			emitMessageReceivedHooks: emitMessageReceivedHooks$1,
			bindingState
		})
	};
}
//#endregion
//#region src/auto-reply/reply/routing-policy.ts
/** Resolves whether replies should route to the originating channel or current surface. */
/** Computes source-routing and typing suppression for a reply turn. */
function resolveReplyRoutingDecision(params) {
	const originatingChannel = normalizeMessageChannel(params.originatingChannel);
	const providerChannel = normalizeMessageChannel(params.provider);
	const surfaceChannel = normalizeMessageChannel(params.surface);
	const currentSurface = providerChannel ?? surfaceChannel;
	const isInternalWebchatTurn = currentSurface === "webchat" && (surfaceChannel === "webchat" || !surfaceChannel) && params.explicitDeliverRoute !== true;
	const shouldRouteToOriginating = Boolean(!params.suppressDirectUserDelivery && !isInternalWebchatTurn && params.isRoutableChannel(originatingChannel) && params.originatingTo && originatingChannel !== currentSurface);
	return {
		originatingChannel,
		currentSurface,
		isInternalWebchatTurn,
		shouldRouteToOriginating,
		shouldSuppressTyping: params.suppressDirectUserDelivery === true || shouldRouteToOriginating || originatingChannel === "webchat"
	};
}
//#endregion
//#region src/auto-reply/reply/dispatch-from-config.prepare-delivery.ts
async function prepareDispatchDelivery(state) {
	const { cfg, ctx, groupId, markInboundDedupeReplayUnsafe, replyRoute, sessionStoreEntry, turnLedger } = state;
	const assertPreparationCurrent = () => {
		state.getPreDispatchAbortSignal()?.throwIfAborted();
		state.params.replyOptions?.operatorAuthority?.assertCurrent();
	};
	const currentAcpSession = sessionStoreEntry.sessionKey ? await readAcpSessionEntryAsync({
		cfg,
		agentId: sessionStoreEntry.agentId,
		sessionKey: sessionStoreEntry.sessionKey,
		assertCurrent: assertPreparationCurrent
	}) : void 0;
	assertPreparationCurrent();
	const sessionEntryWithAcp = currentAcpSession?.entry ? {
		...currentAcpSession.entry,
		acp: currentAcpSession.acp
	} : void 0;
	const suppressAcpChildUserDelivery = isParentOwnedBackgroundAcpSession(sessionEntryWithAcp);
	const effectiveExplicitDeliverRoute = ctx.ExplicitDeliverRoute === true || replyRoute.inheritedExternalRoute === true;
	const resolveRouting = (isRoutableChannel) => resolveReplyRoutingDecision({
		provider: ctx.Provider,
		surface: ctx.Surface,
		explicitDeliverRoute: effectiveExplicitDeliverRoute,
		originatingChannel: replyRoute.channel,
		originatingTo: replyRoute.to,
		suppressDirectUserDelivery: suppressAcpChildUserDelivery,
		isRoutableChannel
	});
	const { currentSurface: normalizedCurrentSurface, isInternalWebchatTurn, shouldRouteToOriginating: hasRouteReplyCandidate } = resolveRouting(Boolean);
	const routeReplyRuntime = hasRouteReplyCandidate && !state.replyOperationRunState.heartbeat ? await loadRouteReplyRuntime() : void 0;
	const { originatingChannel: routeReplyChannel, currentSurface, shouldRouteToOriginating, shouldSuppressTyping } = resolveRouting(routeReplyRuntime?.isRoutableChannel ?? (() => false));
	const routeReplyTo = replyRoute.to;
	const canRouteDurableBlockReply = Boolean(!suppressAcpChildUserDelivery && !isInternalWebchatTurn && routeReplyChannel && routeReplyTo && routeReplyChannel === normalizedCurrentSurface);
	const deliveryChannel = shouldRouteToOriginating ? routeReplyChannel : currentSurface;
	const { preparedTtsPreferences, getDispatchReplyOperation } = state;
	const maybeApplyTtsWithFinalizationLease = async (payload, kind) => {
		const ttsContext = {
			cfg,
			channel: deliveryChannel,
			ttsAuto: state.sessionTtsAuto,
			agentId: state.sessionAgentId,
			accountId: replyRoute.accountId
		};
		const replyOperation = getDispatchReplyOperation();
		const finishFinalizationWork = replyOperation ? beginReplyOperationFinalizationWork(replyOperation, RUN_STALE_TAKEOVER_MS) : void 0;
		try {
			return await maybeApplyTtsToReplyPayload({
				...ttsContext,
				payload,
				kind,
				preparedTtsPreferences,
				inboundAudio: state.inboundAudio || state.getDispatchReplyOperation()?.acceptedSteeredInboundAudio === true
			});
		} finally {
			finishFinalizationWork?.();
			replyOperation?.recordActivity();
		}
	};
	const replyContextAccountId = routeReplyChannel ? resolveReplyDeliveryAccountId(cfg, routeReplyChannel, replyRoute.accountId) : void 0;
	let normalizeReplyMediaPaths;
	const normalizeReplyMediaPayload = async (payload) => {
		if (isInternalWebchatTurn || !resolveSendableOutboundReplyParts(payload).hasMedia) return payload;
		if (!normalizeReplyMediaPaths) {
			const { createReplyMediaPathNormalizer } = await loadReplyMediaPathsRuntime();
			normalizeReplyMediaPaths = createReplyMediaPathNormalizer({
				cfg,
				agentId: state.sessionAgentId,
				sessionKey: state.acpDispatchSessionKey,
				workspaceDir: state.workspaceDir,
				messageProvider: deliveryChannel,
				accountId: replyContextAccountId,
				groupId,
				groupChannel: ctx.GroupChannel,
				groupSpace: ctx.GroupSpace,
				requesterSenderId: ctx.SenderId,
				requesterSenderName: ctx.SenderName,
				requesterSenderUsername: ctx.SenderUsername,
				requesterSenderE164: ctx.SenderE164
			});
		}
		return await normalizeReplyMediaPaths(payload);
	};
	const routeReplyOperationToOriginating = async (operation, options) => {
		const payload = operation.kind === "prepared" ? operation.plan.payload : operation.payload;
		const durableRouteAuthorized = options?.deliveryIntentId !== void 0 && canRouteDurableBlockReply;
		const runtime = routeReplyRuntime ?? (durableRouteAuthorized ? await loadRouteReplyRuntime() : void 0);
		if (!shouldRouteToOriginating && !durableRouteAuthorized || !routeReplyChannel || !routeReplyTo || !runtime) {
			if (options?.deliveryIntentId) throw new Error("durable block reply route unavailable");
			return null;
		}
		markInboundDedupeReplayUnsafe();
		const agentRuntimeSessionKey = options?.sessionKey ?? (ctx.CommandSource === "native" ? resolveCommandTurnTargetSessionKey(ctx) ?? ctx.SessionKey : ctx.SessionKey);
		const routeParams = {
			channel: routeReplyChannel,
			to: routeReplyTo,
			agentId: state.sessionAgentId,
			sessionKey: agentRuntimeSessionKey,
			policySessionKey: options?.sessionKey ?? resolveCommandTurnTargetSessionKey(ctx) ?? ctx.SessionKey,
			policyConversationType: resolveReplyPolicyConversationType(ctx),
			accountId: replyContextAccountId,
			requesterSenderId: ctx.SenderId,
			requesterSenderName: ctx.SenderName,
			requesterSenderUsername: ctx.SenderUsername,
			requesterSenderE164: ctx.SenderE164,
			threadId: state.routeReplyThreadId,
			replyDelivery: createReplyDeliveryContext(resolveReplyToMode(cfg, routeReplyChannel, replyContextAccountId, replyRoute.chatType), replyRoute.chatType),
			cfg,
			abortSignal: options?.abortSignal,
			mirror: options?.mirror,
			isGroup: state.isGroup,
			groupId,
			replyKind: options?.kind ?? "final",
			runId: state.params.replyOptions?.runId,
			responsePrefixContext: options?.responsePrefixContext,
			deliveryIntentId: options?.deliveryIntentId
		};
		const result = operation.kind === "prepared" ? await runtime.routePreparedReply({
			...routeParams,
			plan: operation.plan
		}) : await runtime.routeReply({
			...routeParams,
			payload
		});
		turnLedger.recordRoutedDelivery(options?.kind ?? "final", payload, result);
		return result;
	};
	const routeReplyToOriginating = (payload, options) => routeReplyOperationToOriginating({
		kind: "raw",
		payload
	}, options);
	const isRoutedReplyDelivered = (result) => result.delivered && result.ambiguous !== true;
	const sendReplyOperationAsync = async (operation, abortSignal, kind = "tool", deliveryIntentId) => {
		const payload = operation.kind === "prepared" ? operation.plan.payload : operation.payload;
		if (!routeReplyRuntime && !deliveryIntentId) return null;
		const effectiveAbortSignal = abortSignal ?? state.getDispatchAbortSignal();
		if (effectiveAbortSignal?.aborted) return null;
		const result = await routeReplyOperationToOriginating(operation, {
			abortSignal: effectiveAbortSignal,
			mirror: false,
			kind,
			deliveryIntentId
		});
		if (result && !result.ok) {
			logVerbose(`dispatch-from-config: route-reply failed: ${result.error ?? "unknown error"}`);
			if (deliveryIntentId && result.queueCustody !== "held") throw new Error(result.error ?? "durable block reply delivery failed", { cause: result.cause });
		}
		if (hasAskUserPayload(payload) && !effectiveAbortSignal?.aborted && !result?.delivered) throw new Error("ask_user prompt delivery failed");
		return result;
	};
	const sendPayloadAsync = (payload) => sendReplyOperationAsync({
		kind: "raw",
		payload
	});
	const deliverBindingPayload = async (payload, mode, transcriptOwner) => {
		const bindingPayload = setReplyPayloadMetadata(copyReplyPayloadMetadata(payload, { ...payload }), { sourceReplyTranscriptMirror: transcriptOwner ? {
			sessionKey: transcriptOwner.sessionKey,
			agentId: transcriptOwner.agentId,
			...transcriptOwner.expectedSessionId ? { expectedSessionId: transcriptOwner.expectedSessionId } : {},
			...transcriptOwner.transcriptWriteBlocked ? { transcriptWriteBlocked: true } : {}
		} : void 0 });
		const result = await routeReplyToOriginating(bindingPayload, {
			kind: mode === "terminal" ? "final" : "tool",
			sessionKey: transcriptOwner?.sessionKey
		});
		if (result) {
			if (!result.ok) logVerbose(`dispatch-from-config: route-reply (plugin binding notice) failed: ${result.error ?? "unknown error"}`);
			return result.delivered || result.suppressed === true;
		}
		markInboundDedupeReplayUnsafe();
		return turnLedger.sendQueued(mode === "additive" ? "tool" : "final", bindingPayload).queued;
	};
	return Object.assign(state, {
		suppressAcpChildUserDelivery,
		normalizedCurrentSurface,
		isInternalWebchatTurn,
		routeReplyChannel,
		canRouteDurableBlockReply,
		shouldRouteToOriginating,
		shouldSuppressTyping,
		routeReplyTo,
		deliveryChannel,
		maybeApplyTtsWithFinalizationLease,
		replyContextAccountId,
		normalizeReplyMediaPayload,
		routeReplyToOriginating,
		isRoutedReplyDelivered,
		sendPayloadAsync,
		sendReplyOperationAsync,
		deliverBindingPayload
	});
}
//#endregion
//#region src/channels/plugins/exec-approval-local.ts
function shouldSuppressLocalExecApprovalPrompt(params) {
	const channel = params.channel ? normalizeAnyChannelId(params.channel) : null;
	if (!channel) return false;
	return getChannelPlugin(channel)?.outbound?.shouldSuppressLocalPayloadPrompt?.({
		cfg: params.cfg,
		accountId: params.accountId,
		payload: params.payload,
		hint: {
			kind: "approval-pending",
			approvalKind: "exec",
			nativeRouteActive: hasActiveNativeApprovalRoute(getGatewayNativeApprovalRuntime()?.routeCoordinator, {
				channel,
				accountId: params.accountId,
				approvalKind: "exec"
			})
		}
	}) ?? false;
}
//#endregion
//#region src/auto-reply/reply/dispatch-from-config.prepare-execution.ts
async function prepareDispatchExecution(state) {
	const { cfg, ctx, isDispatchOperationAborted, markInboundDedupeReplayUnsafe, markProgress, noteCommentaryProgress, params, sendPayloadAsync, sessionKey, shouldEmitVerboseProgressAsync, shouldRouteToOriginating, shouldSendToolSummariesAsync, shouldSuppressProgressDelivery, turnLedger } = state;
	if (state.suppressDelivery) logVerbose(`Delivery suppressed by ${state.deliverySuppressionReason} for session ${state.sessionStoreEntry.sessionKey ?? sessionKey ?? "unknown"} — agent will still process the message`);
	let didSendPlanStatusNotice = false;
	const sendPlanUpdate = async (payload) => {
		if (await shouldSuppressProgressDelivery() || !await shouldSendToolSummariesAsync() || didSendPlanStatusNotice || isDispatchOperationAborted()) return;
		didSendPlanStatusNotice = true;
		const explanation = payload.explanation?.replace(/\s+/g, " ").trim();
		const lines = formatPlanChecklistLines(payload.steps ?? [], {
			maxLines: payload.steps?.length ?? 0,
			maxLineChars: 120
		});
		const replyPayload = {
			text: lines.length > 0 ? lines.join("\n") : payload.explanationFormat === "plain" ? "Progress updated" : explanation || "Planning next steps.",
			isStatusNotice: true
		};
		state.assertProgressCurrent();
		if (shouldRouteToOriginating) {
			await sendPayloadAsync(replyPayload);
			return;
		}
		markInboundDedupeReplayUnsafe();
		turnLedger.sendQueued("tool", replyPayload);
	};
	const progressState = {
		accumulatedBlockText: "",
		accumulatedBlockTtsText: "",
		acceptedReplyPayload: false,
		blockCount: 0,
		channelTransformSuppressed: false,
		pendingDirectBlockReplyDelivery: Promise.resolve(),
		progressCallbackStartTail: Promise.resolve()
	};
	const cleanBlockTtsDirectiveText = shouldCleanTtsDirectiveText({
		cfg,
		preparedTtsPreferences: state.preparedTtsPreferences,
		ttsAuto: state.sessionTtsAuto,
		agentId: state.sessionAgentId,
		channelId: state.deliveryChannel,
		accountId: state.replyRoute.accountId
	}) ? createTtsDirectiveTextStreamCleaner() : void 0;
	const resolveToolDeliveryPayload = async (payload) => {
		if (shouldSuppressLocalExecApprovalPrompt({
			channel: normalizeMessageChannel(ctx.Surface ?? ctx.Provider),
			cfg,
			accountId: ctx.AccountId,
			payload
		})) return null;
		if (await shouldSendToolSummariesAsync() || hasExecApprovalPayload(payload) || hasExecApprovalUnavailablePayload(payload) || hasAskUserPayload(payload)) return payload;
		if (!resolveSendableOutboundReplyParts(payload).hasMedia) return null;
		return {
			...payload,
			text: void 0
		};
	};
	const typing = resolveRunTypingPolicy({
		requestedPolicy: params.replyOptions?.typingPolicy,
		suppressTyping: state.sourceReplyPolicy.suppressTyping,
		originatingChannel: state.routeReplyChannel,
		systemEvent: shouldRouteToOriginating
	});
	const onToolResultFromReplyOptions = params.replyOptions?.onToolResult;
	const onPlanUpdateFromReplyOptions = params.replyOptions?.onPlanUpdate;
	const onApprovalEventFromReplyOptions = params.replyOptions?.onApprovalEvent;
	const onPatchSummaryFromReplyOptions = params.replyOptions?.onPatchSummary;
	const allowSuppressedSourceProgressCallbacks = params.replyOptions?.allowProgressCallbacksWhenSourceDeliverySuppressed === true;
	const waitForPendingDirectBlockReplyDelivery = (abortSignal) => waitForReplyDispatcherIdle({ waitForIdle: () => progressState.pendingDirectBlockReplyDelivery }, abortSignal);
	const shouldForwardProgressCallback = async (options) => {
		if (params.replyOptions?.progressRequiresReply === true && state.replyOperationRunState.replyCompletion?.expectation !== "required") return false;
		if (options?.requiresToolSummaryVisibility === true && !await shouldSendToolSummariesAsync() && params.replyOptions?.suppressDefaultToolProgressMessages !== true && options.allowWhenToolSummariesHidden !== true) return false;
		return !state.suppressAutomaticSourceDelivery || allowSuppressedSourceProgressCallbacks && !state.sendPolicyDenied && options?.forwardWhenSourceDeliverySuppressed === true;
	};
	const preserveProgressCallbackStartOrder = params.replyOptions?.preserveProgressCallbackStartOrder === true;
	const wrapProgressCallback = (callback, options) => {
		if (!callback) return;
		return async (...args) => {
			const start = preserveProgressCallbackStartOrder ? createDeferredCore() : void 0;
			if (start) {
				const previousStart = progressState.progressCallbackStartTail;
				progressState.progressCallbackStartTail = start.promise;
				await previousStart;
			}
			try {
				if (isDispatchOperationAborted()) return;
				state.getDispatchReplyOperation()?.recordActivity();
				markProgress();
				if (options?.waitForDirectBlockReplyDelivery) {
					await waitForPendingDirectBlockReplyDelivery(state.getDispatchAbortOperation()?.abortSignal);
					if (isDispatchOperationAborted()) return;
				}
				if (await shouldForwardProgressCallback(options) && !isDispatchOperationAborted()) {
					if (!preserveProgressCallbackStartOrder || options?.onForward) await options?.onForward?.(...args);
					if (isDispatchOperationAborted()) return;
					state.assertProgressCurrent();
					const callbackResult = callback(...args);
					start?.resolve();
					const result = await callbackResult;
					if (result === false) return result;
					state.assertProgressCurrent();
					await options?.onVisible?.(...args);
				}
				return;
			} finally {
				start?.resolve();
			}
		};
	};
	const reasoningCallback = params.replyOptions?.onReasoningStream;
	const onReasoningStream = reasoningCallback ? wrapProgressCallback((payload) => {
		const text = sanitizeUserFacingText(payload.text, {
			conversationContext: ctx.BodyForAgent ?? ctx.Body,
			streaming: true
		});
		const visible = {
			...payload,
			text
		};
		if (!text.trim() && !resolveSendableOutboundReplyParts(visible).hasMedia) return false;
		return reasoningCallback(visible);
	}) : void 0;
	const standaloneCommentaryProgressVisible = await shouldEmitVerboseProgressAsync();
	state.assertProgressCurrent();
	const resolveVerboseProgressVisibility = () => standaloneCommentaryProgressVisible && state.shouldSendToolSummaries() && !state.shouldSuppressProgressDeliverySync();
	const { commentaryPayloadsEnabled, draftOwnsCommentaryProgress } = await resolveTurnCommentaryProgressOwner({
		commentaryPayloadsEnabled: state.commentaryPayloadsEnabled,
		options: params.replyOptions,
		resolveVerboseProgressVisibility,
		resolveVerboseProgressVisibilityAsync: async () => {
			const visible = standaloneCommentaryProgressVisible && await state.shouldSendToolSummariesAsync() && !await state.shouldSuppressProgressDelivery();
			state.assertProgressCurrent();
			return visible;
		}
	});
	state.assertProgressCurrent();
	const deliverStandaloneCommentaryProgress = standaloneCommentaryProgressVisible && !draftOwnsCommentaryProgress;
	const canForwardItemEvents = Boolean(params.replyOptions?.onItemEvent);
	const canForwardSuppressedSourceItemEvents = allowSuppressedSourceProgressCallbacks && !state.sendPolicyDenied && canForwardItemEvents;
	const shouldDeliverDurableCommentaryProgress = (payload) => deliverStandaloneCommentaryProgress && payload.kind === "preamble" && payload.suppressDurableProgress !== true;
	const forwardItemEvent = wrapProgressCallback(params.replyOptions?.onItemEvent, {
		forwardWhenSourceDeliverySuppressed: true,
		requiresToolSummaryVisibility: true,
		waitForDirectBlockReplyDelivery: true,
		onForward: (payload) => preserveProgressCallbackStartOrder && shouldDeliverDurableCommentaryProgress(payload) ? noteCommentaryProgress(payload) : void 0
	});
	const onItemEvent = deliverStandaloneCommentaryProgress || canForwardItemEvents ? async (payload) => {
		if (isDispatchOperationAborted()) return;
		if (!forwardItemEvent && deliverStandaloneCommentaryProgress) markProgress();
		if ((!forwardItemEvent || !preserveProgressCallbackStartOrder) && shouldDeliverDurableCommentaryProgress(payload)) await noteCommentaryProgress(payload);
		return await forwardItemEvent?.(payload);
	} : void 0;
	const replyResolver = params.replyResolver ?? (await state.traceReplyPhase("reply.load_reply_resolver", () => loadGetReplyFromConfigRuntime())).getReplyFromConfig;
	const runtimeReplyConfig = state.preparedReplyDispatchRuntime?.config ?? cfg;
	const replyConfig = withFullRuntimeReplyConfig(params.configOverride ? applyMergePatch(runtimeReplyConfig, params.configOverride) : runtimeReplyConfig);
	state.recordAgentDispatchStarted();
	return Object.assign(state, {
		sendPlanUpdate,
		cleanBlockTtsDirectiveText,
		resolveToolDeliveryPayload,
		typing,
		onToolResultFromReplyOptions,
		onPlanUpdateFromReplyOptions,
		onApprovalEventFromReplyOptions,
		onPatchSummaryFromReplyOptions,
		waitForPendingDirectBlockReplyDelivery,
		shouldForwardProgressCallback,
		preserveProgressCallbackStartOrder,
		wrapProgressCallback,
		onReasoningStream,
		deliverStandaloneCommentaryProgress,
		canForwardSuppressedSourceItemEvents,
		onItemEvent,
		commentaryPayloadsEnabled,
		replyResolver,
		replyConfig,
		progressState
	});
}
//#endregion
//#region src/auto-reply/reply/dispatch-from-config.plugin-binding.ts
function shouldBypassPluginOwnedBindingForCommand(ctx, cfg, replyOptions) {
	if (ctx.CommandAuthorized !== void 0 && typeof ctx.CommandAuthorized !== "boolean") return false;
	const commandTurn = resolveCommandTurnContext(ctx);
	if ((commandTurn.kind === "native" || commandTurn.kind === "text-slash") && !commandTurn.authorized) return false;
	if (isNativeCommandTurn(commandTurn) && commandTurn.authorized) return true;
	if (!(commandTurn.kind === "text-slash" && commandTurn.authorized || commandTurn.kind === "normal" && typeof ctx.CommandAuthorized === "boolean" && ctx.CommandAuthorized) || !shouldHandleTextCommands({
		cfg,
		surface: ctx.Surface ?? ctx.Provider ?? "",
		commandSource: ctx.CommandSource
	})) return false;
	const commandBody = normalizeCommandBody(commandTurn.body ?? resolveCommandContextText(ctx), { botUsername: ctx.BotUsername });
	if (!commandBody.startsWith("/")) return false;
	if (replyOptions?.[PLUGIN_COMMAND_DISPATCH]) return true;
	const channel = resolveCommandChannel(ctx);
	const match = matchPluginCommandInvocation(createPluginCommandRuntime(), commandBody, { channel });
	if (match) {
		if (replyOptions) Object.assign(replyOptions, { [PLUGIN_COMMAND_DISPATCH]: match.dispatch });
		return true;
	}
	if (!isExplicitCommandTurnContext(ctx, cfg)) return false;
	if (resolveTextCommand(commandBody)) return true;
	const provider = normalizeOptionalString(ctx.Provider ?? ctx.Surface);
	return Boolean(commandTurn.commandName && findCommandByNativeName(commandTurn.commandName, provider, { includeBundledChannelFallback: true }));
}
//#endregion
//#region src/auto-reply/reply/dispatch-from-config.prepare-operation.ts
async function prepareDispatchOperation(state) {
	const { attachSourceReplyDeliveryMode, cfg, chatType, commitInboundDedupeIfClaimed, completeDispatchReplyOperation, ctx, deliverySuppressionReason, dispatcher, emitMessageReceivedHooks, finishReplyOperationAbortedDispatch, hookRunner, isPreDispatchOperationAborted, markIdle, params, persistPluginBindingUserTurn, pluginOwnedBinding, recordProcessed, sendBindingNotice, sessionAgentId, sessionKey, sessionStoreEntry, suppressDelivery, turnLedger } = state;
	const abortRuntime = params.fastAbortResolver ? null : await loadAbortRuntime();
	const fastAbortResolver = params.fastAbortResolver ?? abortRuntime?.tryFastAbortFromMessage;
	const formatAbortReplyTextResolver = params.formatAbortReplyTextResolver ?? abortRuntime?.formatAbortReplyText;
	if (!fastAbortResolver || !formatAbortReplyTextResolver) throw new Error("abort runtime unavailable");
	const finishFastCommand = async (fast) => {
		if (pluginOwnedBinding) await getSessionBindingService().touchAsync(pluginOwnedBinding.bindingId, void 0, pluginOwnedBinding);
		emitMessageReceivedHooks();
		let queuedFinal = false;
		let routedFinalCount = 0;
		if (!suppressDelivery && fast.payload) {
			const selectedModel = resolveSessionModelRef(cfg, sessionStoreEntry.entry, sessionAgentId);
			const modelSelection = {
				...selectedModel,
				thinkLevel: sessionStoreEntry.entry?.thinkingLevel
			};
			const responsePrefixContext = {
				identityName: normalizeOptionalString(resolveAgentIdentity(cfg, sessionAgentId)?.name),
				provider: selectedModel.provider,
				model: extractShortModelName(selectedModel.model),
				modelFull: `${selectedModel.provider}/${selectedModel.model}`,
				thinkingLevel: modelSelection.thinkLevel ?? "off"
			};
			const result = await state.routeReplyToOriginating(fast.payload, { responsePrefixContext });
			if (result) {
				queuedFinal = result.ok;
				if (state.isRoutedReplyDelivered(result)) routedFinalCount += 1;
				if (!result.ok) logVerbose(`dispatch-from-config: route-reply (${fast.logKind}) failed: ${result.error ?? "unknown error"}`);
			} else {
				state.markInboundDedupeReplayUnsafe();
				params.replyOptions?.onModelSelected?.(modelSelection);
				queuedFinal = dispatcher.sendFinalReply(fast.payload);
			}
		} else if (suppressDelivery) logVerbose(`dispatch-from-config: ${fast.logKind} reply suppressed by ${deliverySuppressionReason} (session=${sessionKey ?? "unknown"})`);
		const counts = dispatcher.getQueuedCounts();
		counts.final += routedFinalCount;
		recordProcessed("completed", { reason: fast.reason });
		markIdle("message_completed");
		commitInboundDedupeIfClaimed();
		completeDispatchReplyOperation();
		return {
			status: "complete",
			result: attachSourceReplyDeliveryMode({
				queuedFinal,
				counts
			})
		};
	};
	const fastAbort = await fastAbortResolver({
		ctx,
		cfg,
		isCommandTargetCurrent: params.replyOptions?.isCommandTargetCurrent
	});
	if (fastAbort.handled) {
		if (fastAbort.aborted || (fastAbort.stoppedSubagents ?? 0) > 0) state.markInboundDedupeReplayUnsafe();
		return await finishFastCommand({
			payload: { text: formatAbortReplyTextResolver(fastAbort.stoppedSubagents, fastAbort.rejectionReason, fastAbort.failedSubagents) },
			reason: "fast_abort",
			logKind: "fast_abort"
		});
	}
	if (/^\s*\/approve(?:@[^\s]+)?(?:\s|$)/i.test(ctx.commandText)) {
		const fastApprove = await (await loadFastApproveRuntime()).tryFastApproveFromMessage({
			ctx,
			cfg,
			agentId: sessionAgentId,
			sessionKey
		});
		if (fastApprove.handled) return await finishFastCommand({
			...fastApprove.reply ? { payload: fastApprove.reply } : {},
			reason: "before_dispatch_handled",
			logKind: "fast_approve"
		});
	}
	const admissionTicket = params.replyOptions?.[REPLY_ADMISSION_TICKET];
	if (!state.activeRunSafeCommandTurn && admissionTicket && !await state.traceReplyPhase("reply.wait_admission_ticket", () => admissionTicket.wait(params.replyOptions?.abortSignal))) return {
		status: "complete",
		result: finishReplyOperationAbortedDispatch()
	};
	const assertCurrentBindingRoute = async () => {
		if (ctx.InternalTurnSource === void 0 && readConversationBindingRouteFacts(ctx)) {
			await assertPreparedConversationBindingRouteCurrent(ctx);
			if (isPreDispatchOperationAborted()) throw new DispatchReplyOperationAbortedError();
		}
	};
	await assertCurrentBindingRoute();
	const preDispatchAcquisition = await state.traceReplyPhase("reply.admit_pre_dispatch", () => state.ensureDispatchReplyOperation("pre_dispatch", Boolean(pluginOwnedBinding)));
	if (preDispatchAcquisition.status === "aborted") return {
		status: "complete",
		result: finishReplyOperationAbortedDispatch()
	};
	if (preDispatchAcquisition.status === "busy") return {
		status: "complete",
		result: state.finishReplyOperationBusyDispatch({ dedupeDisposition: "release" })
	};
	const finishPluginBindingDispatch = async (outcome) => {
		if (await turnLedger.settleQueued(state.getPreDispatchAbortSignal()) === "aborted" || isPreDispatchOperationAborted()) return {
			status: "complete",
			result: finishReplyOperationAbortedDispatch()
		};
		markIdle(outcome === "handled" ? "plugin_binding_dispatch" : `plugin_binding_${outcome}`);
		recordProcessed("completed", { reason: `plugin-bound-${outcome}` });
		commitInboundDedupeIfClaimed();
		completeDispatchReplyOperation();
		return {
			status: "complete",
			result: attachSourceReplyDeliveryMode({
				queuedFinal: false,
				counts: dispatcher.getQueuedCounts(),
				...turnLedger.hasObservedDelivery() ? { observedReplyDelivery: true } : {}
			})
		};
	};
	if (pluginOwnedBinding) {
		if (isPreDispatchOperationAborted()) return {
			status: "complete",
			result: finishReplyOperationAbortedDispatch()
		};
		await getSessionBindingService().touchAsync(pluginOwnedBinding.bindingId, void 0, pluginOwnedBinding);
		const currentBinding = await getSessionBindingService().resolveByConversationAsync(pluginOwnedBinding);
		if (currentBinding?.bindingId !== pluginOwnedBinding.bindingId || currentBinding.boundAt !== pluginOwnedBinding.boundAt || currentBinding.targetSessionKey !== state.pluginBindingSessionKey || currentBinding.targetKind !== state.pluginBindingTargetKind || currentBinding.metadata?.pluginBindingOwner !== "plugin" || currentBinding.metadata?.pluginId !== pluginOwnedBinding.pluginId || currentBinding.metadata?.pluginRoot !== pluginOwnedBinding.pluginRoot) throw new DispatchSessionRefreshRequiredError(/* @__PURE__ */ new Error("conversation binding changed while recording activity"));
		if (isPreDispatchOperationAborted()) return {
			status: "complete",
			result: finishReplyOperationAbortedDispatch()
		};
		params.replyOptions ??= {};
		if (shouldBypassPluginOwnedBindingForCommand(ctx, cfg, params.replyOptions)) logVerbose(`plugin-bound inbound command escaped plugin binding (plugin=${pluginOwnedBinding.pluginId} session=${sessionKey ?? "unknown"}); falling through to command processing`);
		else if (state.sendPolicyDenied || suppressDelivery && !state.suppressAutomaticSourceDelivery) logVerbose(`plugin-bound inbound skipped under ${deliverySuppressionReason} (plugin=${pluginOwnedBinding.pluginId} session=${sessionKey ?? "unknown"}); falling through to suppressed agent processing`);
		else {
			logVerbose(`plugin-bound inbound routed to ${pluginOwnedBinding.pluginId} conversation=${pluginOwnedBinding.conversationId}`);
			const bindingAuthorization = resolveCommandAuthorization({
				ctx,
				cfg,
				commandAuthorized: ctx.CommandAuthorized
			});
			const targetedClaimOutcome = hookRunner?.runInboundClaimForPluginOutcome ? await (async () => {
				await runWithDispatchAbortSignal(state.getPreDispatchAbortSignal(), state.prepareHookMediaMetadata, state.trackDispatchLifecycleWork);
				if (isPreDispatchOperationAborted()) throw new DispatchReplyOperationAbortedError();
				const authorizedInboundClaimEvent = {
					...state.hookState.inboundClaimEvent,
					senderIsOwner: bindingAuthorization.senderIsOwner
				};
				const claim = state.runWithDispatchLifecycleAdmission(async () => await hookRunner.runInboundClaimForPluginOutcome(pluginOwnedBinding.pluginId, authorizedInboundClaimEvent, withClaimingHookAdmission({
					...state.hookState.inboundClaimContext,
					pluginBinding: pluginOwnedBinding
				}, { prepare: assertCurrentBindingRoute })));
				state.trackDispatchLifecycleWork(claim);
				return await claim;
			})() : getGlobalPluginRegistry()?.plugins.some((plugin) => plugin.id === pluginOwnedBinding.pluginId && plugin.status === "loaded") ? { status: "no_handler" } : { status: "missing_plugin" };
			if (isPreDispatchOperationAborted()) return {
				status: "complete",
				result: finishReplyOperationAbortedDispatch()
			};
			switch (targetedClaimOutcome.status) {
				case "handled": {
					const transcriptOwner = await persistPluginBindingUserTurn();
					if (targetedClaimOutcome.result.reply && state.shouldDeliverPluginBindingReply) await state.deliverBindingPayload(targetedClaimOutcome.result.reply, "terminal", transcriptOwner);
					return await finishPluginBindingDispatch("handled");
				}
				case "missing_plugin":
				case "no_handler":
					state.bindingState.pluginFallbackReason = targetedClaimOutcome.status === "missing_plugin" ? "plugin-bound-fallback-missing-plugin" : "plugin-bound-fallback-no-handler";
					if ((chatType === "group" || chatType === "channel") && ctx.WasMentioned === false && !state.explicitCommandTurnCtx && ctx.GroupRequireMention !== false) {
						markIdle("plugin_binding_fallback_unmentioned");
						recordProcessed("completed", { reason: state.bindingState.pluginFallbackReason });
						commitInboundDedupeIfClaimed();
						completeDispatchReplyOperation();
						return {
							status: "complete",
							result: attachSourceReplyDeliveryMode({
								queuedFinal: false,
								counts: dispatcher.getQueuedCounts()
							})
						};
					}
					if (!hasShownPluginBindingFallbackNotice(pluginOwnedBinding.bindingId, pluginOwnedBinding)) {
						if (await sendBindingNotice({ text: buildPluginBindingUnavailableText(pluginOwnedBinding) }, "additive")) markPluginBindingFallbackNoticeShown(pluginOwnedBinding.bindingId, pluginOwnedBinding);
					}
					break;
				case "declined":
				case "error": {
					const transcriptOwner = await persistPluginBindingUserTurn();
					if (targetedClaimOutcome.status === "error") logVerbose(`plugin-bound inbound claim failed for ${pluginOwnedBinding.pluginId}: ${targetedClaimOutcome.error}`);
					await sendBindingNotice({ text: targetedClaimOutcome.status === "error" ? buildPluginBindingErrorText(pluginOwnedBinding) : buildPluginBindingDeclinedText(pluginOwnedBinding) }, "terminal", transcriptOwner);
					return await finishPluginBindingDispatch(targetedClaimOutcome.status);
				}
			}
		}
	}
	emitMessageReceivedHooks();
	return {
		status: "ready",
		state: Object.assign(state, { assertCurrentBindingRoute })
	};
}
//#endregion
//#region src/auto-reply/reply/reply-turn-recovery-notice.ts
const log = createSubsystemLogger("auto-reply/reply-turn-admission");
const notices = resolveGlobalSingleton(Symbol.for("openclaw.replyRestartRecoveryNotices"), () => ({ entries: /* @__PURE__ */ new Map() }), (state) => {
	state.unsubscribe?.();
	state.unsubscribe = void 0;
	state.entries.clear();
});
/** A rejected turn can report its recovery path without reopening the session. */
async function sendReplyRestartRecoveryNotice(params) {
	try {
		const currentAcpSession = await readAcpSessionEntryAsync({
			cfg: params.cfg,
			agentId: params.agentId,
			sessionKey: params.sessionKey
		});
		const entry = loadSessionEntryReadOnly({
			agentId: params.agentId,
			sessionKey: params.sessionKey,
			storePath: params.storePath,
			readConsistency: "latest"
		});
		const recovery = entry?.mainRestartRecovery;
		if (!entry || !recovery?.tombstone) return;
		if (isParentOwnedBackgroundAcpSession(currentAcpSession?.entry ? {
			...currentAcpSession.entry,
			acp: currentAcpSession.acp
		} : void 0) || resolveSendPolicy({
			cfg: params.cfg,
			entry,
			sessionKey: params.sessionKey,
			channel: params.channel,
			chatType: entry.chatType
		}) === "deny") return;
		notices.unsubscribe ??= onSessionIdentityMutation((mutation) => {
			const keys = /* @__PURE__ */ new Set([...mutation.previous.sessionKeys, ...mutation.kind === "delete" ? [] : mutation.current.sessionKeys]);
			for (const [key, notice] of notices.entries) if (notice.agentId === mutation.agentId && keys.has(notice.sessionKey)) notices.entries.delete(key);
		});
		const key = JSON.stringify([
			params.agentId,
			params.storePath,
			params.sessionKey
		]);
		const previous = notices.entries.get(key);
		if (previous?.sessionId === entry.sessionId && previous.cycleId === recovery.cycleId) return;
		notices.entries.delete(key);
		pruneMapToMaxSize(notices.entries, 1023);
		notices.entries.set(key, {
			agentId: params.agentId,
			sessionKey: params.sessionKey,
			sessionId: entry.sessionId,
			cycleId: recovery.cycleId
		});
		const hint = entry.modelSelectionLocked === true ? "Open it in WebChat and use Resume in new session." : "Use /reset or /new to start a replacement session.";
		if (!await params.deliver(`My session in this room ended during restart recovery. ${hint}`)) log.warn(`restart recovery notice delivery was not confirmed for session ${params.sessionKey}`);
	} catch (error) {
		log.warn(`failed to deliver restart recovery notice for session ${params.sessionKey}: ${String(error)}`);
	}
}
//#endregion
//#region src/auto-reply/reply/dispatch-from-config.ts
async function dispatchReplyFromConfig(params) {
	return await dispatchReplyFromConfigWithQueuePolicy(params, false);
}
/** Low-level plugin dispatch must reach queue policy before waiting on the active reply owner. */
async function dispatchLowLevelChannelReplyFromConfig(params) {
	return await dispatchReplyFromConfigWithQueuePolicy(params, !getGroupThreadTurn());
}
async function dispatchReplyFromConfigWithQueuePolicy(params, allowActiveQueueResolution) {
	const inheritedTicket = params.replyOptions?.[REPLY_ADMISSION_TICKET];
	const ticket = inheritedTicket ?? reserveReplyAdmissionTicket([params.ctx.SessionKey, params.ctx.CommandTargetSessionKey]);
	const ticketedParams = ticket ? {
		...params,
		replyOptions: {
			...params.replyOptions,
			[REPLY_ADMISSION_TICKET]: ticket
		}
	} : params;
	const messageAuditTerminal = createInboundMessageAuditTerminal(params);
	let refreshedSessionSnapshot = false;
	try {
		while (true) try {
			const result = await dispatchReplyFromConfigInner(ticketedParams, messageAuditTerminal, allowActiveQueueResolution);
			messageAuditTerminal?.finishSuccess(result);
			return result;
		} catch (error) {
			if (error instanceof DispatchSessionRefreshRequiredError && !refreshedSessionSnapshot && params.replyOptions?.abortSignal?.aborted !== true) {
				refreshedSessionSnapshot = true;
				continue;
			}
			messageAuditTerminal?.finishError();
			throw error;
		}
	} finally {
		if (!inheritedTicket) ticket?.release();
	}
}
async function dispatchReplyFromConfigInner(params, messageAuditTerminal, allowActiveQueueResolution) {
	try {
		var _usingCtx$1 = _usingCtx();
		const runtimeResources = _usingCtx$1.a(new AsyncDisposableStack());
		let runtimeLease;
		const gathered = await gatherDispatchRequest(params, messageAuditTerminal, allowActiveQueueResolution, (lease) => {
			runtimeLease = runtimeResources.use(scopePreparedModelRuntimeLease(lease));
		});
		if (gathered.status === "complete") return gathered.result;
		const execute = async () => {
			const context = await prepareDispatchOperationContext(await prepareDispatchDelivery(gathered.state));
			if (context.status === "complete") return context.result;
			const errorState = context.state;
			try {
				const operation = await prepareDispatchOperation(context.state);
				if (operation.status === "complete") return operation.result;
				const route = await chooseDispatchRoute(operation.state);
				if (route.status === "complete") return route.result;
				const executed = await executeDispatch(await prepareDispatchExecution(route.state));
				if (executed.status === "complete") return executed.result;
				return await finalizeDispatchAndAudit(executed.state);
			} catch (err) {
				const { failDispatchReplyOperation, finishReplyOperationAbortedDispatch, inboundDedupeClaim, markIdle, recordAgentDispatchCompleted, recordProcessed } = errorState;
				if (isDispatchReplyOperationAbortedError(err)) return finishReplyOperationAbortedDispatch();
				if (inboundDedupeClaim.status === "claimed") {
					if (errorState.turnAdoptionState?.adopted || errorState.inboundDedupeReplayUnsafe) inboundDedupeClaim.commit();
					else inboundDedupeClaim.release();
				}
				if (err instanceof DispatchSessionRefreshRequiredError) markIdle("session_refresh");
				else {
					recordAgentDispatchCompleted("error", { error: String(err) });
					recordProcessed("error", { error: String(err) });
					markIdle("message_error");
				}
				failDispatchReplyOperation(err);
				if (err instanceof SessionRestartRecoveryTombstoneError && params.ctx.InboundAccessAuthorized === true && params.ctx.InboundEventKind !== "room_event" && params.ctx.InternalTurnSource === void 0 && classifySessionStateActor({ inputProvenance: params.ctx.InputProvenance }).actorType === "human" && !errorState.isInternalWebchatTurn && !errorState.sendPolicyDenied && !errorState.suppressAcpChildUserDelivery && params.replyOptions?.abortSignal?.aborted !== true && errorState.dispatchOperationSessionKey && errorState.operationSessionStoreEntry.storePath) await sendReplyRestartRecoveryNotice({
					agentId: errorState.operationSessionStoreEntry.agentId ?? errorState.sessionAgentId,
					cfg: errorState.cfg,
					channel: errorState.deliveryChannel,
					sessionKey: errorState.dispatchOperationSessionKey,
					storePath: errorState.operationSessionStoreEntry.storePath,
					deliver: async (text) => {
						const payload = {
							text,
							isError: true
						};
						const routed = await errorState.routeReplyToOriginating(payload, { mirror: false });
						if (routed) return errorState.isRoutedReplyDelivered(routed);
						if (!params.dispatcher.sendFinalReply(payload)) return false;
						const receipt = await params.dispatcher.waitForIdle();
						return receipt ? receipt.counts.final.delivered > 0 : false;
					}
				});
				throw err;
			}
		};
		const runWithRegistry = () => withPluginRuntimeRegistryScope(gathered.state.pluginRegistry, execute);
		return runtimeLease ? await runtimeLease.run(runWithRegistry) : await runWithRegistry();
	} catch (_) {
		_usingCtx$1.e = _;
	} finally {
		await _usingCtx$1.d();
	}
}
//#endregion
export { emitInboundMessageAuditTerminal as a, resetInboundDedupe as i, dispatchReplyFromConfig as n, resolveBoundAcpDispatchSessionKey as o, emitMessageReceivedHooks as r, DispatchSessionRefreshRequiredError as s, dispatchLowLevelChannelReplyFromConfig as t };