UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

1,411 lines • 62.1 kB
import { t as sleep } from "./sleep-dMoNLoKC.mjs";
import { r as resolveStateDir } from "./state-dir-CYkBUd_G.mjs";
import { t as formatErrorMessage } from "./errors-BvOkmQM5.mjs";
import { E as createDiagnosticTraceContextFromActiveScope, J as hasInternalDiagnosticEventListeners, O as freezeDiagnosticTraceContext, P as runWithDiagnosticTraceContext, c as emitTrustedDiagnosticEventWithPrivateData, s as emitTrustedDiagnosticEvent, t as areDiagnosticsEnabledForProcess, w as createChildDiagnosticTraceContext } from "./diagnostic-events-DT4ejwoa.mjs";
import { t as createSubsystemLogger } from "./subsystem-4NzR43uz.mjs";
import { t as SessionTranscriptWriterClaimReboundError } from "./session-transcript-writer-claim-error-eP-_sDN9.mjs";
import "./session-key-DY3MOX4N.mjs";
import { h as parseAgentSessionKey } from "./session-key-utils-CDyBC9Gn.mjs";
import { c as resolveSessionStorePathCore } from "./paths-Bonddxfk.mjs";
import { r as cloneEnvWithPlatformSemantics } from "./config-env-vars-BzUE_dOh.mjs";
import { r as resolvePersistedSessionStoreOwnerForTarget } from "./session-store-owner-DZX-SiyK.mjs";
import { h as resolveSessionAgentId } from "./agent-scope-bJOokm5r.mjs";
import { C as withAgentRunLifecycleGeneration, r as captureAgentRunLifecycleGeneration, t as assertAgentRunLifecycleGenerationCurrent } from "./agent-events-jWdQ_ESE.mjs";
import { n as recordAgentCleanupFailure } from "./run-cleanup-timeout-CHdeH1f3.mjs";
import { n as recordModelFallbackStop } from "./model-fallback-stop-BXDxJQSp.mjs";
import { n as markAuthProfileSuccess } from "./profiles-6K3k_v-S.mjs";
import { i as runWithCliHistoryWriter, n as getCliHistoryWriter } from "./cli-history-boundary-CK2yr7Tm.mjs";
import { c as getOwnedSessionTranscriptWriterFence, h as withSessionTranscriptWriteAssertion, r as captureOwnedTranscriptWriteAssertion } from "./transcript-write-context-DwwjCPCE.mjs";
import { c as isSignalTimeoutReason, l as isTimeoutError, s as isFailoverError } from "./error-Cmm-AuUb.mjs";
import { l as isAgentRunDirectAbortReason } from "./run-termination-5c-0T0hN.mjs";
import { n as getGlobalHookRunner } from "./hook-runner-global-Cn3xHNvt.mjs";
import { a as isSilentReplyPayloadText, r as SILENT_REPLY_TOKEN } from "./tokens-Ljy0DfNV.mjs";
import { D as setReplyPayloadMetadata } from "./reply-payload-BEgsL2xJ.mjs";
import { g as readRunOperatorAuthority, r as bindOperatorModelExecution } from "./admitted-run-context-D0yzk2io.mjs";
import { n as externalCliDiscoveryForProviderAuth } from "./external-cli-discovery-C550HCjn.mjs";
import { o as loadAuthProfileStoreForRuntime } from "./store-runtime-DPTEKEq5.mjs";
import { n as markAuthProfileFailure } from "./usage-CJIu7a1i.mjs";
import { a as resolveCliBackendConfig } from "./cli-backends-CMl10xFW.mjs";
import "./auth-profiles-DpzfW6rH.mjs";
import { l as resolveSessionEntry, n as loadExactSessionEntryCandidates } from "./session-accessor.sqlite-exact-read-HBi2gDDN.mjs";
import { c as patchSessionEntryCore } from "./session-accessor.sqlite-entry-DLa7_9ui.mjs";
import "./session-accessor-C3ljJ974.mjs";
import { i as resolveSessionTranscriptDatabasePath } from "./session-accessor.transcript-target-DdAdqCJ1.mjs";
import { n as appendExactAssistantMessageToSessionTranscript } from "./transcript-CpqWjSbD.mjs";
import { r as coerceToFailoverError } from "./failover-error-JM6M2oyF.mjs";
import { a as resolveRetryAfterMs } from "./retry-evidence-CCU7EGiH.mjs";
import { d as shouldClearFailedCliSessionBinding, f as shouldClearInterruptedCliSessionBinding } from "./cli-session-DpAF471M.mjs";
import { n as diagnosticErrorFailureKind, r as diagnosticErrorMessage, t as diagnosticErrorCategory } from "./diagnostic-error-metadata-Dt79CD6m.mjs";
import { n as runAgentHarnessBeforeMessageWriteHook } from "./hook-helpers-DQD6Kn21.mjs";
import { n as prepareCronRootSessionGeneration } from "./session-delivery-generation-B8Iv03w1.mjs";
import { i as resolveReplyExpectation } from "./reply-completion-B5n1Cnxm.mjs";
import { i as buildGenericCliContextEngineHostSupport } from "./host-compat-DWLjZN89.mjs";
import { n as bootstrapHarnessContextEngine, o as runHarnessContextEngineMaintenance, r as finalizeHarnessContextEngineTurn } from "./context-engine-lifecycle-DA8PeUIj.mjs";
import { n as buildAgentHookContextIdentityFields, t as buildAgentHookContextChannelFields } from "./hook-agent-context-vC-cM68i.mjs";
import { t as isHeartbeatLifecycleRunKind } from "./bootstrap-mode-HvSedbJl.mjs";
import { b as resolveSourceReplyDelivery, y as resolveExplicitFinalSourceReplyDeliveryEvidence } from "./delivery-evidence-DfR9-cfA.mjs";
import { n as hasCompletionMessageSessionSpawn, t as hasAcceptedSessionSpawn } from "./accepted-session-spawn-B717Q0Hs.mjs";
import { t as SessionManager } from "./session-manager-BpvVpTVC.mjs";
import { n as withSessionManagerWrite } from "./session-manager-write-admission-DQneVl5b.mjs";
import { n as runAgentEndSideEffects, t as awaitAgentEndSideEffects } from "./agent-end-side-effects-Cc9DHY-6.mjs";
import { t as buildAgentHookContext } from "./hook-context-DTNlPqW5.mjs";
import { a as runAgentHarnessLlmInputHook, o as runAgentHarnessLlmOutputHook } from "./lifecycle-hook-helpers-BOCYz9r1.mjs";
import { r as buildUsageWithNoCost, t as buildAssistantMessage } from "./stream-message-shared-CYuIJ_XF.mjs";
import { t as projectAgentHarnessTranscriptMessageForDisplay } from "./transcript-visibility-sRYXACld.mjs";
import { n as runBeforeAgentRunGate, t as buildAgentRunBlockedUserMessage } from "./before-agent-run-0bHKoKHh.mjs";
import { t as subscribeAgentCommentaryDiagnostics } from "./commentary-diagnostics-BwHmk2ql.mjs";
import { n as buildHandledBeforeAgentReplyPayloads, r as runBeforeAgentReplyForTurn, t as resolveAuthProfileFailureReason } from "./auth-profile-failure-policy-BEoYDPdF.mjs";
import { n as mergeAttemptToolMediaPayloads } from "./tool-media-payloads-Cu1p8tPb.mjs";
import { t as buildEmbeddedRunPayloads } from "./payloads-CmhbJUtd.mjs";
import { a as resolveCliRuntimeOwnerFingerprint, i as resolveCliRuntimeArtifactFingerprint } from "./cli-auth-epoch-CZKGJiXj.mjs";
import { n as cliBackendLog, r as formatCliBackendOutputDigest } from "./log-_KnmVvHo.mjs";
import { u as hashCliReseedPrompt } from "./cli-session-history.claude-CSoMwCfp.mjs";
import { t as acceptsCliLiveSession, u as createCliFailoverError, w as runCliCleanup } from "./cli-live-session-registry-BcPd7Lg7.mjs";
import { n as runCliRecovery, t as resolveCliSessionId } from "./cli-run-recovery-DpfvheRb.mjs";
import { i as cliAssistantItemId, n as getCliMessagingDeliveryEvidence, r as projectCliMessagingDeliveryEvidence, t as attachCliMessagingDeliveryEvidence } from "./delivery-evidence-hMWnlfMU.mjs";
import { c as CliAuthProfilePreparationError, i as loadCliSessionHistoryMessages, r as loadCliSessionContextEngineMessages, s as buildAgentHookConversationMessages, u as claudeCliSessionTranscriptHasContent } from "./session-history-DPHAu5W5.mjs";
//#region src/agents/cli-runner/before-agent-reply.ts
async function runCliBeforeAgentReply(params, assertCurrent) {
	const hookStartedAt = Date.now();
	const hookResult = params.isolatedCompletion || params.controlOperation ? void 0 : await runBeforeAgentReplyForTurn({
		runId: params.runId,
		trigger: params.trigger,
		assertCurrent,
		event: { cleanedBody: params.prompt },
		context: {
			runId: params.runId,
			jobId: params.jobId,
			agentId: params.agentId,
			sessionKey: params.sessionKey,
			sessionId: params.sessionId,
			workspaceDir: params.workspaceDir,
			trigger: params.trigger,
			...buildAgentHookContextChannelFields(params),
			...buildAgentHookContextIdentityFields({
				trigger: params.trigger,
				senderId: params.senderId,
				chatId: params.chatId,
				channelContext: params.channelContext
			})
		},
		onDispatch: () => params.onExecutionPhase?.({
			phase: "before_agent_reply",
			provider: params.provider,
			model: params.model ?? ""
		}),
		onDeclined: () => params.onExecutionPhase?.({
			phase: "runtime_plugins",
			provider: params.provider,
			model: params.model ?? ""
		})
	});
	if (hookResult?.handled) {
		const finalText = hookResult.reply?.text ?? "NO_REPLY";
		const sessionBindingDisabled = resolveCliBackendConfig(params.provider, params.config, { agentId: params.agentId })?.config.sessionMode === "none";
		cliBackendLog.info(`cli synthetic turn: provider=${params.provider} model=<synthetic> requestedModel=${params.model ?? ""} durationMs=${Date.now() - hookStartedAt} ${formatCliBackendOutputDigest(finalText)}`);
		return {
			payloads: buildHandledBeforeAgentReplyPayloads(hookResult.reply),
			meta: {
				durationMs: Date.now() - hookStartedAt,
				agentMeta: {
					sessionId: "",
					provider: params.modelProvider ?? params.provider,
					model: params.model ?? "",
					...sessionBindingDisabled ? { clearCliSessionBinding: true } : {}
				},
				finalAssistantVisibleText: finalText,
				finalAssistantRawText: finalText
			}
		};
	}
}
//#endregion
//#region src/agents/cli-runner/cli-run-settlement.ts
const log$2 = createSubsystemLogger("agents/cli-runner");
/** Formats the visible terminal reason for an interrupted turn that retained partial output. */
function formatCliTerminalInterruption(interruption) {
	return `CLI turn ${interruption.reason} after partial output`;
}
/** Marks the history reseed this native session received, so imports can strip it. */
function buildCliReseedReceipt(params) {
	const { runParams, output } = params;
	if (!params.usedHistoryPrompt || !isClaudeCliBackend(runParams.provider) || output.finalPromptText === void 0 || !params.userTurnHandled || !runParams.sessionId) return;
	return {
		version: 1,
		promptHash: hashCliReseedPrompt(output.finalPromptText),
		localSessionId: runParams.sessionId,
		userTurnDisposition: runParams.userTurnTranscriptRecorder?.hasPersisted() ? "persisted" : "omitted"
	};
}
/** Native continuity for a returned session, keyed to this run's auth and prompt facts. */
function buildCliSessionBinding(context, sessionId, output, reseedReceipt) {
	return {
		sessionId,
		...context.effectiveAuthProfileId ? { authProfileId: context.effectiveAuthProfileId } : {},
		...output.resumeCheckpointId ? { resumeCheckpointId: output.resumeCheckpointId } : {},
		...context.authEpoch ? { authEpoch: context.authEpoch } : {},
		authEpochVersion: context.authEpochVersion,
		...context.extraSystemPromptHash ? { extraSystemPromptHash: context.extraSystemPromptHash } : {},
		...context.messageToolPolicyHash ? { messageToolPolicyHash: context.messageToolPolicyHash } : {},
		...context.promptToolNamesHash ? { promptToolNamesHash: context.promptToolNamesHash } : {},
		...context.cwdHash ? { cwdHash: context.cwdHash } : {},
		...context.preparedBackend.mcpConfigHash ? { mcpConfigHash: context.preparedBackend.mcpConfigHash } : {},
		...context.preparedBackend.mcpResumeHash ? { mcpResumeHash: context.preparedBackend.mcpResumeHash } : {},
		...reseedReceipt ? { reseedReceipt } : {},
		...context.transcriptCursor && !output.terminalInterruption ? { transcriptCursor: {
			...context.transcriptCursor,
			userEntryId: context.params.userTurnTranscriptRecorder?.getAdmissionReceipt()?.entryId
		} } : {}
	};
}
async function settleCliAuthProfile(params) {
	try {
		if (params.terminal.outcome === "success") {
			await markAuthProfileSuccess({
				store: params.store,
				profileId: params.profileId,
				provider: params.provider,
				agentDir: params.agentDir
			});
			return;
		}
		const error = params.terminal.error;
		const reason = resolveAuthProfileFailureReason({
			failoverReason: isFailoverError(error) ? error.reason : null,
			providerStarted: isFailoverError(error) && error.reason === "timeout" ? error.cliTimeout?.observedActivity : void 0
		});
		if (reason) await markAuthProfileFailure({
			store: params.store,
			profileId: params.profileId,
			reason,
			cfg: params.terminal.config,
			agentDir: params.agentDir,
			runId: params.terminal.runId,
			modelId: params.terminal.modelId,
			retryAfterMs: resolveRetryAfterMs(formatErrorMessage(error), Date.now(), error)
		});
	} catch (error) {
		log$2.warn(`CLI auth-profile ${params.terminal.outcome} settlement failed: ${formatErrorMessage(error)}`);
	}
}
function isClaudeCliBackend(provider) {
	return provider.trim().toLowerCase() === "claude-cli";
}
async function assertCliRuntimeBinding(context) {
	if (!context.runtimeArtifactFingerprint) return;
	const currentArtifact = await resolveCliRuntimeArtifactFingerprint({
		provider: context.params.provider,
		config: context.params.config ?? context.contextEngineConfig,
		agentId: context.params.agentId,
		runtimeArtifactId: context.backendResolved.id
	});
	if (currentArtifact !== context.runtimeArtifactFingerprint) throw new Error("CLI executable/package artifact changed during successful inference");
	if (!context.runtimeOwnerFingerprint) return;
	if (await resolveCliRuntimeOwnerFingerprint({
		provider: context.params.provider,
		config: context.params.config ?? context.contextEngineConfig,
		...context.agentDir ? { agentDir: context.agentDir } : {},
		agentId: context.params.agentId,
		runtimeOwnerId: context.backendResolved.id,
		...context.effectiveAuthProfileId ? { authProfileId: context.effectiveAuthProfileId } : {},
		...context.authBindingSkipsLocalCredential ? { skipLocalCredential: true } : {},
		runtimeArtifactFingerprint: currentArtifact
	}) !== context.runtimeOwnerFingerprint) throw new Error("CLI runtime owner changed during successful inference");
}
async function settleCliPreparationError(error, params) {
	try {
		params.assertCurrent?.();
		if (!(error instanceof CliAuthProfilePreparationError)) return;
		await settleCliAuthProfile({
			store: loadAuthProfileStoreForRuntime(error.agentDir, { externalCli: externalCliDiscoveryForProviderAuth({
				cfg: params.config,
				provider: error.provider,
				profileId: error.profileId
			}) }),
			profileId: error.profileId,
			provider: error.provider,
			agentDir: error.agentDir,
			terminal: {
				outcome: "failure",
				error,
				config: params.config,
				runId: params.runId,
				modelId: params.model
			}
		});
	} finally {
		const reportCleanupError = (cleanupError) => {
			recordAgentCleanupFailure();
			log$2.warn(`bundle-mcp preparation cleanup failed: ${formatErrorMessage(cleanupError)}`);
		};
		try {
			await retireCliRunMcpRuntime(params, reportCleanupError);
		} catch (cleanupError) {
			reportCleanupError(cleanupError);
		}
	}
}
async function retireCliRunMcpRuntime(params, onError) {
	if (params.cleanupBundleMcpOnRunEnd !== true) return;
	const { retireSessionMcpRuntime } = await import("./agent-bundle-mcp-tools-R7J54QFa.mjs");
	await runCliCleanup(params, "cli-bundle-mcp-retire", async () => {
		await retireSessionMcpRuntime({
			sessionId: params.sessionId,
			reason: "cli-run-end",
			preserveActiveLeases: true,
			onError
		});
	});
}
async function settlePreparedCliRun(params) {
	const { context, diagnosticLifecycle, run } = params;
	const runParams = context.params;
	let outcome;
	try {
		outcome = { result: await run() };
	} catch (error) {
		outcome = { error };
	}
	let cleanupError;
	const recordCleanupError = (error) => {
		recordAgentCleanupFailure();
		cleanupError ??= error instanceof Error ? error : new Error(formatErrorMessage(error));
	};
	if (runParams.cleanupCliLiveSessionOnRunEnd === true) try {
		const { closeCliLiveSession } = await import("./cli-live-session-registry-C-1uboSD.mjs");
		await closeCliLiveSession(context, "restart");
	} catch (error) {
		recordCleanupError(error);
	}
	try {
		await retireCliRunMcpRuntime(runParams, recordCleanupError);
	} catch (error) {
		recordCleanupError(error);
	}
	if (cleanupError) {
		if ("error" in outcome || outcome.result.didSendViaMessagingTool === true) log$2.warn(`cli run cleanup failed after completion: ${formatErrorMessage(cleanupError)}`);
		else diagnosticLifecycle?.setPhase("cleanup");
	}
	runParams.assertCurrent?.();
	if (context.effectiveAuthProfileId && context.authProfileStore) {
		const profileId = context.effectiveAuthProfileId;
		const authProfileStore = context.authProfileStore;
		const terminal = "error" in outcome ? {
			outcome: "failure",
			error: outcome.error,
			config: runParams.config,
			runId: runParams.runId,
			modelId: context.modelId
		} : outcome.result.meta.executionTrace?.attempts?.at(-1)?.result === "success" ? { outcome: "success" } : void 0;
		if (terminal) await settleCliAuthProfile({
			store: authProfileStore,
			profileId,
			provider: authProfileStore.profiles[profileId]?.provider ?? runParams.provider,
			agentDir: context.agentDir,
			terminal
		});
	}
	if ("error" in outcome) throw outcome.error instanceof Error ? outcome.error : new Error(formatErrorMessage(outcome.error));
	if (cleanupError && outcome.result.didSendViaMessagingTool !== true) throw cleanupError;
	return outcome.result;
}
function resolveCliSourceReplyMirror(params) {
	const { evidence, modelId, runParams } = params;
	const payloads = buildEmbeddedRunPayloads({
		assistantTexts: [],
		lastAssistant: void 0,
		sessionKey: runParams.sessionKey ?? "",
		provider: runParams.provider,
		model: modelId,
		didSendViaMessagingTool: evidence.didSendViaMessagingTool,
		didDeliverSourceReplyViaMessageTool: evidence.didDeliverSourceReplyViaMessageTool,
		messagingToolSentTargets: evidence.messagingToolSentTargets,
		messagingToolSourceReplyPayloads: evidence.messagingToolSourceReplyPayloads,
		sourceReplyDeliveryMode: runParams.sourceReplyDeliveryMode,
		agentId: runParams.agentId,
		runId: runParams.runId
	});
	return {
		payloads,
		delivered: payloads.length > 0 || runParams.sourceReplyDeliveryMode === "message_tool_only" && evidence.didDeliverSourceReplyViaMessageTool === true,
		visibleText: payloads.map((payload) => payload.text?.trim() ?? "").filter(Boolean).join("\n\n") || void 0
	};
}
function buildCliExecutionMetadata(context, attempt) {
	return {
		executionTrace: {
			winnerProvider: context.params.provider,
			winnerModel: context.modelId,
			attempts: [{
				provider: context.params.provider,
				model: context.modelId,
				...attempt
			}],
			fallbackUsed: false,
			runner: "cli"
		},
		requestShaping: {
			...context.params.thinkLevel ? { thinking: context.params.thinkLevel } : {},
			...context.effectiveAuthProfileId ? { authMode: "auth-profile" } : {}
		}
	};
}
function buildBlockedCliRunResult(params) {
	const { context, message, preparedContextAgentMeta, sessionBindingDisabled } = params;
	const runParams = context.params;
	return {
		payloads: [{
			text: message,
			isError: true
		}],
		meta: {
			durationMs: Date.now() - context.started,
			finalAssistantVisibleText: message,
			finalAssistantRawText: message,
			livenessState: "blocked",
			error: {
				kind: "hook_block",
				message
			},
			systemPromptReport: context.systemPromptReport,
			...buildCliExecutionMetadata(context, {
				result: "error",
				reason: "before_agent_run blocked the run"
			}),
			completion: {
				finishReason: "blocked",
				stopReason: "blocked",
				refusal: true
			},
			agentMeta: {
				sessionId: runParams.sessionId ?? "",
				provider: runParams.modelProvider ?? runParams.provider,
				model: context.modelId,
				...preparedContextAgentMeta,
				...sessionBindingDisabled ? { clearCliSessionBinding: true } : {}
			}
		}
	};
}
function buildCliDeliveredFailure(params) {
	const { context, error, evidence, preparedContextAgentMeta, reusableCliSessionId, sessionBindingDisabled } = params;
	const runParams = context.params;
	const message = formatErrorMessage(error);
	const { payloads } = resolveCliSourceReplyMirror({
		evidence,
		runParams,
		modelId: context.modelId
	});
	const visiblePayloads = payloads.length > 0 ? payloads : resolveExplicitFinalSourceReplyDeliveryEvidence(evidence) === false ? [{
		text: "The reply stopped after sending progress. Please try again.",
		isError: true
	}] : void 0;
	return {
		...visiblePayloads ? { payloads: visiblePayloads } : {},
		meta: {
			durationMs: Date.now() - context.started,
			systemPromptReport: context.systemPromptReport,
			stopReason: "error",
			...buildCliExecutionMetadata(context, {
				result: "error",
				reason: message
			}),
			completion: {
				finishReason: "error",
				stopReason: "error",
				refusal: false
			},
			agentMeta: {
				sessionId: "",
				provider: runParams.modelProvider ?? runParams.provider,
				model: context.modelId,
				...preparedContextAgentMeta,
				...sessionBindingDisabled || shouldClearFailedCliSessionBinding({
					error,
					binding: reusableCliSessionId ? { sessionId: reusableCliSessionId } : void 0,
					bindingReplacedDuringRun: params.bindingReplacedDuringRun
				}) ? { clearCliSessionBinding: true } : {}
			}
		},
		...projectCliMessagingDeliveryEvidence(evidence),
		didSendViaMessagingTool: true
	};
}
function buildCliRunResult(params) {
	const { assistantTranscriptOwned, assistantTranscriptIdempotencyKey, bindingFlushOk, context, effectiveCliSessionId, output, preparedContextAgentMeta, sessionBindingDisabled, usedHistoryPrompt, userTurnHandled } = params;
	const runParams = context.params;
	const text = output.text?.trim();
	const rawText = output.rawText?.trim();
	const sourceReplyMirror = resolveCliSourceReplyMirror({
		evidence: output,
		runParams,
		modelId: context.modelId
	});
	const finalAssistantVisibleText = sourceReplyMirror.delivered ? sourceReplyMirror.visibleText : text;
	const payloads = sourceReplyMirror.payloads.length > 0 ? sourceReplyMirror.payloads : sourceReplyMirror.delivered ? void 0 : text ? (output.textParts ?? [text]).map((partText, assistantMessageIndex) => assistantTranscriptOwned || output.textParts ? setReplyPayloadMetadata({ text: partText }, {
		...output.textParts ? { assistantMessageIndex } : {},
		...assistantTranscriptOwned ? { assistantTranscriptOwned: true } : {},
		...assistantTranscriptIdempotencyKey ? { assistantTranscriptIdempotencyKey } : {}
	}) : { text: partText }) : resolveReplyExpectation(runParams) === "optional" ? [{ text: SILENT_REPLY_TOKEN }] : void 0;
	const payloadsWithToolMedia = mergeAttemptToolMediaPayloads({
		payloads,
		toolMediaUrls: output.toolMediaUrls,
		toolAudioAsVoice: output.toolAudioAsVoice,
		toolTrustedLocalMedia: output.toolTrustedLocalMedia,
		sourceReplyDeliveryMode: runParams.sourceReplyDeliveryMode
	});
	const unflushed = !sessionBindingDisabled && effectiveCliSessionId && bindingFlushOk === false;
	const terminalInterruption = output.terminalInterruption;
	const cliSessionBindingCleared = sessionBindingDisabled || unflushed || shouldClearInterruptedCliSessionBinding({
		interrupted: terminalInterruption !== void 0,
		bindingReplacedDuringRun: effectiveCliSessionId !== resolveCliSessionId(context.reusableCliSession)
	});
	const persistedCliSessionId = cliSessionBindingCleared ? void 0 : effectiveCliSessionId;
	const createdReseedReceipt = persistedCliSessionId ? buildCliReseedReceipt({
		runParams,
		output,
		usedHistoryPrompt,
		userTurnHandled
	}) : void 0;
	const preservedReseedReceipt = runParams.cliSessionBinding && persistedCliSessionId === runParams.cliSessionBinding.sessionId ? runParams.cliSessionBinding.reseedReceipt : void 0;
	const reseedReceipt = createdReseedReceipt ?? preservedReseedReceipt;
	const agentSessionId = terminalInterruption || unflushed ? "" : sessionBindingDisabled ? runParams.sessionId ?? "" : effectiveCliSessionId ?? runParams.sessionId ?? "";
	const yielded = output.yielded === true;
	const stopReason = terminalInterruption?.reason ?? (yielded ? "end_turn" : "completed");
	if (!terminalInterruption) runParams.onSuccessfulAuthBinding?.({
		...context.effectiveAuthProfileId ? { authProfileId: context.effectiveAuthProfileId } : {},
		...context.authBindingFingerprint ? { authFingerprint: context.authBindingFingerprint } : {},
		...!context.authBindingFingerprint && context.runtimeOwnerFingerprint ? {
			runtimeOwnerFingerprint: context.runtimeOwnerFingerprint,
			runtimeOwnerKind: "cli-runtime",
			runtimeOwnerId: context.backendResolved.id
		} : {},
		...context.runtimeArtifactFingerprint ? {
			runtimeArtifactFingerprint: context.runtimeArtifactFingerprint,
			runtimeArtifactId: context.backendResolved.id
		} : {},
		...context.authBindingSkipsLocalCredential ? { skipLocalCredential: true } : {}
	});
	return {
		payloads: payloadsWithToolMedia,
		meta: {
			durationMs: Date.now() - context.started,
			...output.finalPromptText ? { finalPromptText: output.finalPromptText } : {},
			...finalAssistantVisibleText ? { finalAssistantVisibleText } : {},
			...rawText ? { finalAssistantRawText: rawText } : {},
			systemPromptReport: context.systemPromptReport,
			...terminalInterruption ? {
				aborted: true,
				providerStarted: true,
				stopReason,
				...terminalInterruption.reason === "timeout" ? { timeoutPhase: "provider" } : {}
			} : yielded ? {
				yielded: true,
				livenessState: "paused",
				stopReason
			} : {},
			...output.yieldAcknowledgment ? { yieldAcknowledgment: output.yieldAcknowledgment } : {},
			...buildCliExecutionMetadata(context, {
				result: terminalInterruption?.reason ?? "success",
				...terminalInterruption ? { reason: formatCliTerminalInterruption(terminalInterruption) } : {}
			}),
			completion: {
				finishReason: terminalInterruption?.reason ?? (yielded ? "end_turn" : "stop"),
				stopReason,
				refusal: false
			},
			...output.toolSummary ? { toolSummary: output.toolSummary } : {},
			agentMeta: {
				sessionId: agentSessionId,
				provider: runParams.modelProvider ?? runParams.provider,
				model: context.modelId,
				...preparedContextAgentMeta,
				usage: output.usage,
				...output.usage ? { lastCallUsage: output.usage } : {},
				...output.diagnosticUsage ? { diagnosticUsage: output.diagnosticUsage } : {},
				...persistedCliSessionId ? { cliSessionBinding: buildCliSessionBinding(context, persistedCliSessionId, output, reseedReceipt) } : {},
				...cliSessionBindingCleared ? { clearCliSessionBinding: true } : {}
			}
		},
		...projectCliMessagingDeliveryEvidence(output),
		...output.acceptedSessionSpawns?.length ? { acceptedSessionSpawns: output.acceptedSessionSpawns } : {}
	};
}
//#endregion
//#region src/agents/cli-runner/cli-run-transcript.ts
const log$1 = createSubsystemLogger("agents/cli-runner");
function buildCliHookUserMessage(prompt) {
	return {
		role: "user",
		content: prompt,
		timestamp: Date.now()
	};
}
/** Interrupted turns persist as aborted so replayed history never treats partial text as complete. */
function resolveCliAssistantStopReason(output) {
	return output.terminalInterruption ? "aborted" : "stop";
}
function buildCliHookAssistantMessage(params) {
	return {
		role: "assistant",
		content: [{
			type: "text",
			text: params.text
		}],
		api: "responses",
		provider: params.provider,
		model: params.model,
		...params.usage ? { usage: params.usage } : {},
		stopReason: params.stopReason,
		timestamp: Date.now()
	};
}
function isAgentMessage(value) {
	return Boolean(value && typeof value === "object" && "role" in value);
}
async function runCliAgentEndHook(params, hookParams) {
	if (!params.messageChannel && !params.messageProvider) {
		await awaitAgentEndSideEffects(hookParams);
		return;
	}
	runAgentEndSideEffects(hookParams);
}
async function persistApprovedCliUserTurnTranscript(params) {
	const recorder = params.userTurnTranscriptRecorder;
	const reusingPersistedTurn = params.suppressNextUserMessagePersistence === true;
	if (!recorder || reusingPersistedTurn && !recorder.hasPersisted()) return recorder?.isBlocked() === true;
	const persisted = await recorder.persistApproved({ cwd: params.cwd ?? params.workspaceDir });
	if (!persisted && !recorder.hasPersisted() && await recorder.resolveMessage()) recorder.markBlocked();
	if (persisted && !reusingPersistedTurn) try {
		const notification = params.onUserMessagePersisted?.(persisted.message);
		if (notification) Promise.resolve(notification).catch((error) => {
			log$1.warn(`CLI user turn persistence notification failed: ${formatErrorMessage(error)}`);
		});
	} catch (error) {
		log$1.warn(`CLI user turn persistence notification failed: ${formatErrorMessage(error)}`);
	}
	return persisted !== void 0 || recorder.hasPersisted() || recorder.isBlocked();
}
async function persistCliAssistantTranscript(params) {
	const { runParams } = params;
	if (runParams.currentInboundEventKind === "room_event" || !params.text) {
		const admission = runParams.userTurnTranscriptRecorder?.getAdmissionReceipt();
		return {
			owned: runParams.currentInboundEventKind === "room_event",
			...admission ? { terminalAnchor: admission } : {}
		};
	}
	if (!runParams.persistAssistantTranscript || !runParams.sessionKey) return { owned: false };
	try {
		const idempotencyKey = cliAssistantItemId(runParams.runId);
		const result = await appendExactAssistantMessageToSessionTranscript({
			sessionKey: runParams.sessionKey,
			agentId: runParams.agentId,
			expectedSessionId: runParams.sessionId,
			...runParams.expectedLifecycleRevision !== void 0 ? { expectedLifecycleRevision: runParams.expectedLifecycleRevision } : {},
			...runParams.expectedWriterRunId !== void 0 ? { expectedWriterRunId: runParams.expectedWriterRunId } : {},
			storePath: runParams.storePath,
			idempotencyKey,
			runId: runParams.runId,
			config: runParams.config,
			beforeMessageWrite: (write) => {
				const message = runAgentHarnessBeforeMessageWriteHook({
					...write,
					message: projectAgentHarnessTranscriptMessageForDisplay({
						hidden: false,
						inputProvenance: runParams.inputProvenance,
						message: write.message
					}),
					prepareAssistantTranscriptMessage: runParams.prepareAssistantTranscriptMessage
				});
				return message ? projectAgentHarnessTranscriptMessageForDisplay({
					hidden: false,
					inputProvenance: runParams.inputProvenance,
					message
				}) : null;
			},
			message: {
				...buildAssistantMessage({
					model: {
						api: "cli",
						provider: runParams.provider,
						id: params.modelId
					},
					content: [{
						type: "text",
						text: params.text
					}],
					stopReason: params.stopReason,
					usage: buildUsageWithNoCost({
						input: params.usage?.input,
						output: params.usage?.output,
						cacheRead: params.usage?.cacheRead,
						cacheWrite: params.usage?.cacheWrite,
						totalTokens: params.usage?.total
					})
				}),
				...params.yielded && params.stopReason === "stop" ? { openclawStreamFallback: {
					replacementText: params.text,
					source: "segment",
					itemId: runParams.runId
				} } : {}
			}
		});
		if (!result.ok) {
			log$1.warn(`CLI assistant transcript persistence skipped: ${result.reason}`);
			return { owned: result.code === "blocked" || result.code === "session-rebound" };
		}
		return {
			owned: true,
			idempotencyKey,
			...result.anchor ? { terminalAnchor: result.anchor } : {}
		};
	} catch (error) {
		log$1.warn(`CLI assistant transcript persistence failed: ${formatErrorMessage(error)}`);
		return { owned: false };
	}
}
async function notifyCliUserMessagePersisted(params, message, context) {
	try {
		await Promise.resolve(params.onUserMessagePersisted?.(message));
	} catch (err) {
		log$1.warn(`${context} notification failed: ${formatErrorMessage(err)}`);
	}
}
function captureCliBlockFallbackWrite(target, expectedEntry) {
	const identity = { ...target };
	const env = cloneEnvWithPlatformSemantics(process.env);
	env.OPENCLAW_STATE_DIR = resolveStateDir(env);
	const readScope = {
		...identity,
		env
	};
	const assertOwnedWrite = captureOwnedTranscriptWriteAssertion(identity);
	const fence = getOwnedSessionTranscriptWriterFence({
		sessionKey: identity.sessionKey,
		sessionTarget: identity
	});
	const { normalizedKey } = resolveSessionEntry(readScope, { readOnly: true });
	let source;
	const captured = loadExactSessionEntryCandidates({
		...readScope,
		sessionKeys: [normalizedKey],
		readOnly: true,
		onReadSource: (readSource) => {
			source = {
				agentId: readSource.agentId,
				path: readSource.path
			};
		}
	})[0]?.entry;
	if (!source || !captured || captured.sessionId !== identity.sessionId) throw new SessionTranscriptWriterClaimReboundError();
	const readSource = source;
	const { lifecycleRevision, activeWriterRunId } = expectedEntry;
	const cliWriter = getCliHistoryWriter({
		...identity,
		storePath: readSource.path
	});
	const assertCurrent = () => {
		assertOwnedWrite();
		cliWriter?.assertCurrent();
		const current = loadExactSessionEntryCandidates({
			...readScope,
			sessionKeys: [normalizedKey],
			readOnly: true,
			onReadSource: (currentSource) => {
				if (currentSource.agentId !== readSource.agentId || currentSource.path !== readSource.path) throw new SessionTranscriptWriterClaimReboundError();
			}
		})[0]?.entry;
		if (!current || current.sessionId !== identity.sessionId || current.lifecycleRevision !== lifecycleRevision || current.activeWriterRunId !== activeWriterRunId || fence?.expectedLifecycleRevision !== void 0 && current.lifecycleRevision !== fence.expectedLifecycleRevision || fence?.expectedWriterRunId !== void 0 && current.activeWriterRunId !== fence.expectedWriterRunId) throw new SessionTranscriptWriterClaimReboundError();
	};
	return {
		readScope,
		assertCurrent
	};
}
async function persistCliRunBlock(params, block) {
	const redactedUserMessage = buildAgentRunBlockedUserMessage(params.runId, {
		message: block.message,
		blockedBy: block.pluginId
	});
	try {
		const persisted = await params.userTurnTranscriptRecorder?.persistBlocked(redactedUserMessage);
		if (persisted) {
			await notifyCliUserMessagePersisted(params, persisted.message, "before_agent_run block user-turn persistence");
			return;
		}
	} catch (err) {
		log$1.warn(`before_agent_run block: failed to persist canonical CLI user message: ${formatErrorMessage(err)}`);
	}
	try {
		const sessionManager = params.sessionManager;
		if (!sessionManager) {
			const sessionKey = params.sessionKey?.trim() || params.sessionId;
			const targetAgentId = params.sessionTarget?.agentId;
			const targetStorePath = params.sessionTarget?.storePath;
			const targetStoreOwner = resolvePersistedSessionStoreOwnerForTarget({
				config: params.config ?? {},
				sessionKey,
				storePath: targetStorePath
			});
			const agentId = (targetAgentId && targetStorePath && !parseAgentSessionKey(sessionKey)?.agentId && targetStoreOwner.kind === "none" ? targetAgentId : void 0) ?? resolveSessionAgentId({
				agentId: targetAgentId ?? params.agentId,
				config: params.config,
				sessionKey
			});
			const sessionTarget = { ...params.sessionTarget ?? {
				agentId,
				sessionId: params.sessionId,
				sessionKey,
				storePath: params.storePath ?? resolveSessionStorePathCore(params.config?.session?.store, { agentId })
			} };
			const persistedEntry = await patchSessionEntryCore(sessionTarget, (entry, patchContext) => {
				if (patchContext.existingEntry && entry.sessionId !== sessionTarget.sessionId) return null;
				return {
					sessionId: sessionTarget.sessionId,
					updatedAt: Date.now()
				};
			}, {
				fallbackEntry: params.sessionEntry ? void 0 : {
					sessionId: sessionTarget.sessionId,
					updatedAt: Date.now()
				},
				skipMaintenance: true
			});
			if (persistedEntry?.sessionId !== sessionTarget.sessionId) return;
			const write = captureCliBlockFallbackWrite(sessionTarget, persistedEntry);
			const { restoreSessionColdTranscript } = await import("./session-cold-storage-L7zFwmx1.mjs");
			await restoreSessionColdTranscript(write.readScope, write.assertCurrent);
			await withSessionTranscriptWriteAssertion(write.readScope, write.assertCurrent, async () => {
				const manager = await SessionManager.openAsync(write.readScope);
				write.assertCurrent();
				await manager.appendMessageAsync(redactedUserMessage);
			});
			return;
		}
		const target = sessionManager.getSessionTarget();
		const assertOwnedWrite = target ? captureOwnedTranscriptWriteAssertion(target) : void 0;
		const cliWriter = target ? getCliHistoryWriter({
			...target,
			storePath: resolveSessionTranscriptDatabasePath(target)
		}) : void 0;
		const assertCurrent = () => {
			assertOwnedWrite?.();
			cliWriter?.assertCurrent();
		};
		const append = () => withSessionManagerWrite(sessionManager, async () => {
			assertCurrent();
			await sessionManager.appendMessageAsync(redactedUserMessage);
		});
		await (target ? withSessionTranscriptWriteAssertion(target, assertCurrent, append) : append());
	} catch (err) {
		log$1.warn(`before_agent_run block: failed to persist redacted CLI user message: ${formatErrorMessage(err)}`);
	}
}
async function finalizeCliContextEngineTurn(params) {
	const { context } = params;
	if (!context.contextEngine) return;
	const { params: runParams } = context;
	const admission = runParams.userTurnTranscriptRecorder?.getAdmissionReceipt();
	if (runParams.onContextEngineTurnCandidate) {
		if (admission && params.terminalAnchor) runParams.onContextEngineTurnCandidate({
			boundary: {
				admission,
				terminal: params.terminalAnchor
			},
			sessionIdUsed: runParams.sessionId,
			sessionKey: runParams.sessionKey,
			sessionTarget: runParams.sessionTarget,
			promptError: false,
			aborted: params.output.terminalInterruption !== void 0 || runParams.abortSignal?.aborted === true,
			yieldAborted: false,
			isHeartbeat: isHeartbeatLifecycleRunKind(runParams.bootstrapContextRunKind),
			runtimeContext: {
				provider: runParams.modelProvider ?? runParams.provider,
				modelId: context.modelId,
				modelContextWindow: runParams.modelContextWindow,
				tokenBudget: context.contextWindowInfo?.tokens
			}
		});
	} else {
		const prePromptMessages = params.historyMessages.filter(isAgentMessage);
		const turnMessages = [];
		if (context.contextEngineTurnPrompt) turnMessages.push(buildCliHookUserMessage(context.contextEngineTurnPrompt));
		if (params.assistantText) turnMessages.push(buildCliHookAssistantMessage({
			text: params.assistantText,
			provider: runParams.provider,
			model: context.modelId,
			usage: params.output.usage,
			stopReason: resolveCliAssistantStopReason(params.output)
		}));
		const contextEngineHostSupport = buildGenericCliContextEngineHostSupport({ backendId: context.backendResolved.id });
		await finalizeHarnessContextEngineTurn({
			contextEngine: context.contextEngine,
			promptError: false,
			aborted: params.output.terminalInterruption !== void 0 || runParams.abortSignal?.aborted === true,
			yieldAborted: false,
			sessionIdUsed: runParams.sessionId,
			sessionKey: runParams.sessionKey,
			sessionTarget: runParams.sessionTarget,
			sessionFile: runParams.sessionFile,
			isHeartbeat: isHeartbeatLifecycleRunKind(runParams.bootstrapContextRunKind),
			messagesSnapshot: [...prePromptMessages, ...turnMessages],
			prePromptMessageCount: prePromptMessages.length,
			sessionManager: runParams.sessionManager,
			config: context.contextEngineConfig,
			contextEngineHostSupport,
			providerId: runParams.provider,
			modelId: context.modelId,
			runMaintenance: async (maintenanceParams) => await runHarnessContextEngineMaintenance({
				...maintenanceParams,
				onDeferredMaintenance: context.deferContextEngineDisposalUntil,
				withSessionManagerRewriteLock: async (operation) => await operation()
			}),
			warn: (message) => log$1.warn(message)
		});
	}
}
//#endregion
//#region src/agents/cli-runner/run-diagnostics.ts
/** Trusted run hierarchy for Claude Code CLI-backed agent turns. */
function diagnosticBase(params, trace) {
	const channel = params.messageChannel ?? params.messageProvider;
	const trigger = params.isolatedCompletionPurpose ?? params.trigger;
	return {
		runId: params.runId,
		...params.agentId ? { agentId: params.agentId } : {},
		sessionId: params.sessionId,
		...params.sessionKey ? { sessionKey: params.sessionKey } : {},
		provider: params.modelProvider ?? "anthropic",
		...params.model ? { model: params.model } : {},
		...trigger ? { trigger } : {},
		...channel ? { channel } : {},
		trace
	};
}
function resultRunOutcome(result) {
	if (result.meta.livenessState === "blocked") return "blocked";
	if (result.meta.aborted === true) return "aborted";
	if (result.meta.error) return "error";
	return "completed";
}
function errorHarnessOutcome(error, abortSignal) {
	const failureKind = diagnosticErrorFailureKind(error);
	if (failureKind === "timeout") return "timed_out";
	if (failureKind === "aborted" || abortSignal?.aborted) return abortSignal?.aborted && isSignalTimeoutReason(abortSignal.reason) ? "timed_out" : "aborted";
	if (isTimeoutError(error)) return "timed_out";
	return "error";
}
/**
* Wraps one OpenClaw Claude CLI turn in synthetic harness/run boundaries.
* The child run scope makes every real Claude CLI model call nest beneath it.
*/
async function runClaudeCliAgentTurnWithDiagnostics(params, run) {
	const harnessTrace = freezeDiagnosticTraceContext(createDiagnosticTraceContextFromActiveScope());
	const runTrace = freezeDiagnosticTraceContext(createChildDiagnosticTraceContext(harnessTrace));
	const harnessBase = {
		...diagnosticBase(params, harnessTrace),
		harnessId: "claude-cli"
	};
	const runBase = diagnosticBase(params, runTrace);
	const startedAt = Date.now();
	let phase = "prepare";
	let unsubscribeCommentary;
	const lifecycle = {
		setPhase: (nextPhase) => {
			phase = nextPhase;
		},
		setExecutionContext: ({ agentId, config }) => {
			if (agentId) {
				harnessBase.agentId = agentId;
				runBase.agentId = agentId;
			}
			unsubscribeCommentary?.();
			unsubscribeCommentary = subscribeAgentCommentaryDiagnostics(config, harnessBase);
		}
	};
	emitTrustedDiagnosticEvent({
		type: "harness.run.started",
		...harnessBase
	});
	emitTrustedDiagnosticEvent({
		type: "run.started",
		...runBase
	});
	try {
		const result = await runWithDiagnosticTraceContext(runTrace, () => run(lifecycle));
		const runOutcome = resultRunOutcome(result);
		const resultErrorMessage = result.meta.error?.message;
		const runErrorMessage = runOutcome === "error" ? resultErrorMessage : void 0;
		emitTrustedDiagnosticEventWithPrivateData({
			type: "run.completed",
			...runBase,
			durationMs: Date.now() - startedAt,
			outcome: runOutcome,
			...runOutcome === "blocked" ? { blockedBy: "before_agent_run" } : {},
			...runOutcome === "error" && result.meta.error ? { errorCategory: result.meta.error.kind } : {}
		}, runErrorMessage ? { errorMessage: runErrorMessage } : void 0);
		emitTrustedDiagnosticEventWithPrivateData({
			type: "harness.run.completed",
			...harnessBase,
			durationMs: Date.now() - startedAt,
			outcome: result.meta.timeoutPhase !== void 0 ? "timed_out" : runOutcome === "blocked" ? "error" : runOutcome,
			...typeof result.meta.yielded === "boolean" ? { yieldDetected: result.meta.yielded } : {}
		}, resultErrorMessage && (runOutcome === "error" || runOutcome === "blocked") ? { errorMessage: resultErrorMessage } : void 0);
		return result.diagnosticTrace ? result : {
			...result,
			diagnosticTrace: harnessTrace
		};
	} catch (error) {
		const errorMessage = diagnosticErrorMessage(error);
		const harnessOutcome = errorHarnessOutcome(error, params.abortSignal);
		emitTrustedDiagnosticEventWithPrivateData({
			type: "run.completed",
			...runBase,
			durationMs: Date.now() - startedAt,
			outcome: harnessOutcome === "error" ? "error" : "aborted",
			...harnessOutcome === "error" ? { errorCategory: diagnosticErrorCategory(error) } : {}
		}, errorMessage ? { errorMessage } : void 0);
		if (harnessOutcome === "error") emitTrustedDiagnosticEventWithPrivateData({
			type: "harness.run.error",
			...harnessBase,
			durationMs: Date.now() - startedAt,
			phase,
			errorCategory: diagnosticErrorCategory(error)
		}, errorMessage ? { errorMessage } : void 0);
		else emitTrustedDiagnosticEvent({
			type: "harness.run.completed",
			...harnessBase,
			durationMs: Date.now() - startedAt,
			outcome: harnessOutcome
		});
		throw error;
	} finally {
		unsubscribeCommentary?.();
	}
}
//#endregion
//#region src/agents/cli-runner.ts
const log = createSubsystemLogger("agents/cli-runner");
/** Checks whether a Claude CLI session binding has reached its transcript file. */
async function isCliBindingFlushed(sessionId, provider, workspaceDir, options) {
	if (!provider || !isClaudeCliBackend(provider)) return true;
	if (!sessionId) return false;
	if (options?.skipTranscriptProbe) return true;
	for (const delayMs of [
		0,
		50,
		150
	]) {
		if (delayMs > 0) await sleep(delayMs);
		if (await claudeCliSessionTranscriptHasContent({
			sessionId,
			workspaceDir
		})) return true;
	}
	return false;
}
function runCliAgent(paramsInput) {
	const lifecycleGeneration = paramsInput.lifecycleGeneration ?? captureAgentRunLifecycleGeneration(paramsInput.runId);
	const params = {
		...paramsInput,
		lifecycleGeneration
	};
	return withAgentRunLifecycleGeneration(lifecycleGeneration, () => isClaudeCliBackend(params.provider) && areDiagnosticsEnabledForProcess() && hasInternalDiagnosticEventListeners() ? runClaudeCliAgentTurnWithDiagnostics(params, (diagnosticLifecycle) => runCliAgentInternal(params, diagnosticLifecycle)) : runCliAgentInternal(params));
}
async function runCliAgentInternal(params, diagnosticLifecycle) {
	assertAgentRunLifecycleGenerationCurrent(params.lifecycleGeneration);
	await params.onExecutionStarted?.();
	assertAgentRunLifecycleGenerationCurrent(params.lifecycleGeneration);
	params.abortSignal?.throwIfAborted();
	params.assertCurrent?.();
	let modelExecution;
	const assertCallerCurrent = params.assertCurrent;
	const generationAbortController = new AbortController();
	let generation;
	try {
		const target = params.sessionTarget;
		generation = target && !params.sessionManager && !params.isolatedCompletion ? await prepareCronRootSessionGeneration({
			...target,
			sessionKey: params.sessionKey ?? target.sessionKey,
			sessionId: params.sessionId,
			lifecycleRevision: params.expectedLifecycleRevision ?? params.sessionEntry?.lifecycleRevision
		}, (reason) => generationAbortController.abort(reason)) : void 0;
		const hookResult = await runCliBeforeAgentReply(params, generation?.assertCurrent);
		if (hookResult) return hookResult;
		modelExecution = bindOperatorModelExecution(readRunOperatorAuthority(params), params.requesterModel, params.mapOperatorAuthorizationError);
		const abortSignals = [
			params.abortSignal,
			modelExecution?.signal,
			generation ? generationAbortController.signal : void 0
		].filter((signal) => signal !== void 0);
		const runParams = modelExecution || generation ? {
			...params,
			abortSignal: abortSignals.length > 1 ? AbortSignal.any(abortSignals) : abortSignals[0],
			assertCurrent: () => {
				assertCallerCurrent?.();
				modelExecution?.assertCurrent();
				generation?.assertCurrent();
			}
		} : params;
		const { prepareCliRunContext } = await import("./prepare.runtime.js");
		let context;
		try {
			context = await prepareCliRunContext(runParams);
		} catch (error) {
			await settleCliPreparationError(error, runParams);
			throw error;
		}
		diagnosticLifecycle?.setExecutionContext(context.params);
		const result = await settlePreparedCliRun({
			context,
			diagnosticLifecycle,
			run: async () => await runPreparedCliAgent(context, diagnosticLifecycle)
		});
		modelExecution?.assertCurrent();
		return result;
	} finally {
		generation?.release();
		modelExecution?.release();
	}
}
async function runPreparedCliAgent(context, diagnosticLifecycle) {
	const run = () => runPreparedCliAgentOwned(context, diagnosticLifecycle);
	return await runWithCliHistoryWriter(context.cliHistoryWriter, run);
}
async function runPreparedCliAgentOwned(context, diagnosticLifecycle) {
	let executePreparedCliRun;
	const { params } = context;
	const cliFailoverContext = {
		provider: params.provider,
		model: context.modelId,
		sessionId: params.sessionId,
		lane: params.lane
	};
	const sessionBindingDisabled = context.preparedBackend.backend.sessionMode === "none";
	const resultContext = {
		context,
		preparedContextAgentMeta: isClaudeCliBackend(params.provider) && context.contextWindowInfo ? {
			contextTokens: context.contextWindowInfo.tokens,
			contextTokensSource: "resolved"
		} : {},
		sessionBindingDisabled
	};
	const isolatedCompletion = params.isolatedCompletion === true;
	const controlOperation = params.controlOperation !== void 0;
	const turnSideEffectsDisabled = isolatedCompletion || controlOperation;
	const hookRunner = turnSideEffectsDisabled ? void 0 : getGlobalHookRunner();
	const hasLlmInputHooks = hookRunner?.hasHooks("llm_input") === true;
	const hasLlmOutputHooks = hookRunner?.hasHooks("llm_output") === true;
	const hasAgentEndHooks = hookRunner?.hasHooks("agent_end") === true;
	const hasBeforeAgentRunHooks = hookRunner?.hasHooks("before_agent_run") === true;
	const needsHookHistory = hasLlmInputHooks || hasAgentEndHooks || hasBeforeAgentRunHooks;
	let historyMessages = [];
	const promptForHooks = context.promptForHooks ?? params.prompt;
	const contextWindowFields = () => ({
		...context.contextWindowInfo?.tokens ? { contextTokenBudget: context.contextWindowInfo.tokens } : {},
		...context.contextWindowInfo?.source ? { contextWindowSource: context.contextWindowInfo.source } : {},
		...context.contextWindowInfo?.referenceTokens ? { contextWindowReferenceTokens: context.contextWindowInfo.referenceTokens } : {}
	});
	const hookContext = {
		runId: params.runId,
		jobId: params.jobId,
		agentId: params.agentId,
		sessionKey: params.sessionKey,
		sessionId: params.sessionId,
		workspaceDir: params.workspaceDir,
		trigger: params.trigger,
		...params.config ? { config: params.config } : {},
		...contextWindowFields(),
		...buildAgentHookContextChannelFields(params),
		...buildAgentHookContextIdentityFields({
			trigger: params.trigger,
			senderId: params.senderId,
			chatId: params.chatId,
			channelContext: params.channelContext
		})
	};
	const buildAgentEndMessages = (lastAssistant) => buildAgentHookConversationMessages({
		historyMessages,
		currentTurnMessages: [buildCliHookUserMessage(promptForHooks), ...lastAssistant ? [lastAssistant] : []]
	});
	const finishAgentEndHook = (messages, error) => runCliAgentEndHook(params, {
		event: {
			messages,
			success: error === void 0,
			...error !== void 0 ? { error } : {},
			durationMs: Date.now() - context.started
		},
		ctx: hookContext,
		hookRunner
	});
	const finishFailedAgentEndHook = (error) => finishAgentEndHook(buildAgentEndMessages(), formatErrorMessage(error));
	const finishBlockedRun = async (message, pluginId) => {
		await persistCliRunBlock(params, {
			message,
			pluginId
		});
		await finishAgentEndHook(buildAgentHookConversationMessages({
			historyMessages,
			currentTurnMessages: [buildCliHookUserMessage(message)]
		}), message);
		return buildBlockedCliRunResult({
			...resultContext,
			message
		});
	};
	let deliveredMessagingSideEffect = false;
	let userTurnHandled = false;
	const persistStoppedFirstCliSession = async (error, output, cliSessionIdToUse) => {
		const sessionId = output.sessionId;
		if (!params.persistStoppedFirstCliSession || !output.terminalInterruption || !sessionId || cliSessionIdToUse || resolveCliSessionId(context.reusableCliSession) || sessionBindingDisabled || !isAgentRunDirectAbortReason(error) || !isClaudeCliBackend(params.provider) || !await isCliBindingFlushed(sessionId, params.provider, context.cwd ?? context.workspaceDir)) return;
		try {
			const reseedReceipt = buildCliReseedReceipt({
				runParams: params,
				output,
				usedHistoryPrompt: context.openClawHistoryPrompt !== void 0,
				userTurnHandled
			});
			await params.persistStoppedFirstCliSession(buildCliSessionBinding(context, sessionId, output, reseedReceipt));
		} catch (persistError) {
			log.warn(`CLI run ${params.runId} could not keep its stopped first session: ${formatErrorMessage(persistError)}`);
		}
	};
	const executeCliAttempt = async (cliSessionIdToUse, options) => {
		const timeoutMs = options?.timeoutMs ?? params.timeoutMs;
		const forkCliSessionOnResume = options?.forkCliSessionOnResume ?? context.params.forkCliSessionOnResume;
		const cliSessionResumeAt = cliSessionIdToUse && forkCliSessionOnResume ? options?.resumeAt ?? context.params.cliSessionResumeAt ?? context.params.cliSessionBinding?.resumeCheckpointId : void 0;
		const persistCliSessionForkSuccessor = options?.onForkSuccessorPersisted && context.params.persistCliSessionForkSuccessor ? async (sessionId) => {
			await context.params.persistCliSessionForkSuccessor?.(sessionId);
			options.onForkSuccessorPersisted?.(sessionId);
		} : context.params.persistCliSessionForkSuccessor;
		const attemptContext = timeoutMs === params.timeoutMs && forkCliSessionOnResume === context.params.forkCliSessionOnResume && cliSessionResumeAt === context.params.cliSessionResumeAt && persistCliSessionForkSuccessor === context.params.persistCliSessionForkSuccessor ? context : {
			...context,
			params: {
				...context.params,
				timeoutMs,
				forkCliSessionOnResume,
				cliSessionResumeAt,
				persistCliSessionForkSuccessor
			}
		};
		diagnosticLifecycle?.setPhase("send");
		const output = await executePreparedCliRun(attemptContext, cliSessionIdToUse, diagnosticLifecycle ? { onPhase: diagnosticLifecycle.setPhase } : void 0);
		try {
			params.assertCurrent?.();
		} catch (error) {
			await persistStoppedFirstCliSession(error, output, cliSessionIdToUse);
			throw error;
		}
		diagnosticLifecycle?.setPhase("resolve");
		const sourceReplyMirror = resolveCliSourceReplyMirror({
			evidence: output,
			runParams: params,
			modelId: context.modelId
		});
		const assistantText = sourceReplyMirror.delivered ? sourceReplyMirror.visibleText ?? "" : output.text.trim();
		if ((!output.text.trim() || isSilentReplyPayloadText(output.text)) && resolveSourceReplyDelivery(output) === "missing" && !output.toolMediaUrls?.length && !output.yielded && !hasCompletionMessageSessionSpawn(output.acceptedSessionSpawns) && !output.terminalInterruption && resolveReplyExpectation(params) === "required" && !(isolatedCompletion && params.outputTextPolicy === "strict-visible")) {
			const process = output.diagnostics?.process;
			if (process) {
				const diagnostics = [
					`backend=${process.backendId}`,
					`reason=${process.processReason}`,
					`exitCode=${process.exitCode ?? "null"}`,
					`exitSignal=${process.exitSignal ?? "null"}`,
					`durationMs=${process.durationMs}`,
					`stdoutBytes=${process.stdoutBytes}`,
					`stdoutHash=${process.stdoutHash}`,
					`stderrBytes=${process.stderrBytes}`,
					`stderrHash=${process.stderrHash}`,
					`useResume=${process.useResume ? "true" : "false"}`
				].join(" ");
				cliBackendLog.warn(`cli empty response diagnostics: ${diagnostics}`);
			}
			const error = createCliFailoverError("CLI backend returned an empty response.", "empty_response", cliFailoverContext);
			if ((output.toolSummary?.calls ?? 0) > 0 || hasAcceptedSessionSpawn(output.acceptedSessionSpawns)) recordModelFallbackStop(error);
			throw attachCliMessagingDeliveryEvidence(error, output);
		}
		const assistantTexts = assistantText ? [assistantText] : [];
		const lastAssistant = assistantText.length > 0 ? buildCliHookAssistantMessage({
			text: assistantText,
			provider: params.provider,
			model: context.modelId,
			usage: output.usage,
			stopReason: resolveCliAssistantStopReason(output)
		}) : void 0;
		if (assistantText.length > 0 && hasLlmOutputHooks) runAgentHarnessLlmOutputHook({
			event: {
				runId: params.runId,
				sessionId: params.sessionId,
				provider: params.provider,
				model: context.modelId,
				...contextWindowFields(),
				resolvedRef: `${params.provider}/${context.modelId}`,
				assistantTexts,
				...lastAssistant ? { lastAssistant } : {},
				...output.usage ? { usage: output.usage } : {}
			},
			ctx: hookContext,
			hookRunner
		});
		return {
			output,
			assistantText,
			lastAssistant,
			sourceReplyWasDelivered: sourceReplyMirror.delivered,
			usedHistoryPrompt: cliSessionIdToUse === void 0 && context.openClawHistoryPrompt !== void 0
		};
	};
	const executeRun = async () => {
		({executePreparedCliRun} = await import("./execute.runtime.js"));
		historyMessages = needsHookHistory ? await loadCliSessionHistoryMessages(params) : [];
		const llmInputEvent = {
			runId: params.runId,
			sessionId: params.sessionId,
			provider: params.provider,
			model: context.modelId,
			systemPrompt: context.systemPrompt,
			prompt: promptForHooks,
			historyMessages,
			imagesCount: params.images?.length ?? 0
		};
		if (turnSideEffectsDisabled) {
			const reusableCliSessionId = isolatedCompletion ? void 0 : resolveCliSessionId(context.reusableCliSession);
			if (!isolatedCompletion && !reusableCliSessionId) throw new Error(`CLI backend ${context.backendResolved.id} cannot ${params.controlOperation} without a reusable native session.`);
			const { output, usedHistoryPrompt } = await executeCliAttempt(reusableCliSessionId);
			return buildCliRunResult({
				...resultContext,
				output,
				...!isolatedCompletion ? { effectiveCliSessionId: reusableCliSessionId } : {},
				bindingFlushOk: true,
				assistantTranscriptOwned: false,
				usedHistoryPrompt,
				userTurnHandled
			});
		}
		await bootstrapHarnessContextEngine({
			admittedRunContext: params.admittedRunContext,
			hadSessionFile: context.hadSessionFile,
			contextEngine: context.contextEngine,
			sessionId: params.sessionId,
			sessionKey: params.sessionKey,
			sessionTarget: params.sessionTarget,
			sessionFile: params.sessionFile,
			sessionManager: params.sessionManager,
			transcriptReadFence: params.sessionManager ? void 0 : params.userTurnTranscriptRecorder?.getAdmissionReceipt(),
			config: context.contextEngineConfig,
			contextEngineHostSupport: buildGenericCliContextEngineHostSupport({ backendId: context.backendResolved.id }),
			providerId: params.provider,
			modelId: context.modelId,
			warn: (message) => log.warn(message)
		});
		const contextEngineHistoryMessages = context.contextEngine ? await loadCliSessionContextEngineMessages(params) : [];
		const finishCliAttempt = async (result, fallbackCliSessionId) => {
			const { output, assistantText, lastAssistant, sourceReplyWasDelivered, usedHistoryPrompt } = result;
			try {
				const terminalInterruption = output.terminalInterruption;
				if (!terminalInterruption) await assertCliRuntimeBinding(context);
				const effectiveCliSessionId = output.sessionId ?? fallbackCliSessionId;
				const assistantTranscript = await persistCliAssistantTranscript({
					runParams: params,
					text: sourceReplyWasDelivered ? "" : assistantText,
					modelId: context.modelId,
					usage: output.usage,
					stopReason: resolveCliAssistantStopReason(output),
					yielded: output.yielded
				});
				await finalizeCliContextEngineTurn({
					context,
					historyMessages: context.contextEngine ? contextEngineHistoryMessages : historyMessages,
					assistantText,
					terminalAnchor: assistantTranscript.terminalAnchor,
					output
				});
				const bindingFlushOk = sessionBindingDisabled ? true : await isCliBindingFlushed(effectiveCliSessionId, params.provider, context.cwd ?? context.workspaceDir, { skipTranscriptProbe: acceptsCliLiveSession(context) });
				const interruptionError = terminalInterruption ? formatCliTerminalInterruption(terminalInterruption) : void 0;
				await finishAgentEndHook(buildAgentEndMessages(lastAssistant), interruptionError);
				return buildCliRunResult({
					...resultContext,
					output,
					effectiveCliSessionId,
					bindingFlushOk,
					assistantTranscriptOwned: assistantTranscript.owned,
					assistantTranscriptIdempotencyKey: assistantTranscript.idempotencyKey,
					usedHistoryPrompt,
					userTurnHandled
				});
			} catch (error) {
				throw attachCliMessagingDeliveryEvidence(error, output);
			}
		};
		const finishDeliveredFailure = async (error, bindingReplacedDuringRun) => {
			const evidence = getCliMessagingDeliveryEvidence(error);
			if (!evidence) return;
			await finishFailedAgentEndHook(error);
			deliveredMessagingSideEffect = true;
			return buildCliDeliveredFailure({
				...resultContext,
				error,
				evidence,
				reusableCliSessionId: resolveCliSessionId(context.reusableCliSession),
				bindingReplacedDuringRun
			});
		};
		const block = await runBeforeAgentRunGate(hookRunner, {
			prompt: promptForHooks,
			systemPrompt: context.systemPrompt,
			messages: buildAgentHookConversationMessages({
				historyMessages,
				currentTurnMessages: []
			}),
			channelId: hookContext.channelId,
			accountId: params.agentAccountId,
			senderId: params.senderId ?? void 0,
			senderIsOwner: params.senderIsOwner
		}, buildAgentHookContext(hookContext));
		if (block) return finishBlockedRun(block.message, block.blockedBy);
		userTurnHandled = await persistApprovedCliUserTurnTranscript(params);
		runAgentHarnessLlmInputHook({
			event: llmInputEvent,
			ctx: hookContext,
			hookRunner
		});
		return await runCliRecovery({
			context,
			executeAttempt: executeCliAttempt,
			finishAttempt: finishCliAttempt,
			finishDeliveredFailure,
			onTerminalFailure: finishFailedAgentEndHook
		});
	};
	let outcome;
	try {
		outcome = { result: await executeRun() };
	} catch (error) {
		outcome = { error };
	}
	let cleanupError;
	try {
		await runCliCleanup(params, "cli-backend-release", async () => {
			await context.preparedBackend.cleanup?.();
		});
	} catch (error) {
		cleanupError = error;
	}
	params.assertCurrent?.();
	if (cleanupError) {
		recordAgentCleanupFailure();
		if (!deliveredMessagingSideEffect) {
			if ("error" in outcome) log.warn(`CLI run also failed before backend cleanup: ${formatErrorMessage(outcome.error)}`);
			diagnosticLifecycle?.setPhase("cleanup");
			throw cleanupError;
		}
		log.warn(`CLI backend cleanup failed after confirmed message delivery: ${formatErrorMessage(cleanupError)}`);
	}
	if ("error" in outcome) throw coerceToFailoverError(outcome.error, cliFailoverContext) ?? outcome.error;
	if (!outcome.result) throw new Error("CLI run completed without a result");
	return outcome.result;
}
//#endregion
export { runCliAgent as n, runPreparedCliAgent as r, isCliBindingFlushed as t };