UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

677 lines (676 loc) • 36.9 kB
import { o as resolveUserPath } from "./home-dir-Dc6nN6HB.mjs"; import { n as sanitizeForLog } from "./ansi-DyIsQZAA.mjs"; import "./utils-CitNzLyF.mjs"; import { t as createSubsystemLogger } from "./subsystem-4NzR43uz.mjs"; import "./session-key-DY3MOX4N.mjs"; import { s as isSubagentSessionKey } from "./session-key-utils-CDyBC9Gn.mjs"; import { r as resolveCollapsedSessionAuthPinSource } from "./auth-profile-override-provenance-Jztnei-C.mjs"; import { a as isRuntimeToolAllowed, o as isToolAllowedByPolicies } from "./tool-policy-match-BXLYReRw.mjs"; import { u as resolveOpenAIRuntimeProvider } from "./openai-routing-DNTQ-lG2.mjs"; import "./message-channel-AvA3r_Xp.mjs"; import { r as getCliSessionBinding } from "./cli-session-binding-Dx1VbkI8.mjs"; import { a as resolveAuthProfileOrder } from "./order-C69p83pK.mjs"; import { n as ensureAuthProfileStore } from "./store-runtime-DPTEKEq5.mjs"; import { t as AgentHarnessPreflightError } from "./errors-BAipjK5G.mjs"; import { n as resolveAvailableAgentHarnessPolicy } from "./availability-LCoXDLq_.mjs"; import { h as resolveSessionPinnedHarnessId } from "./agent-harness-session-key-Dx0vv6oG.mjs"; import "./model-selection-Cpoq0B2R.mjs"; import { t as isCliProvider } from "./model-selection-cli-46qX0ujd.mjs"; import { t as DEFAULT_MAX_LIVE_TOOL_RESULT_CHARS } from "./tool-result-limits-DNBSu_jg.mjs"; import { a as annotateInterSessionPromptText } from "./input-provenance-B5YZS2Do.mjs"; import { d as readSessionEntryInWorker } from "./session-entry-read-runtime-BdnQjoL6.mjs"; import { c as hasNewGeneratedMediaTaskForSessionKey, s as getGeneratedMediaTaskIdsForSessionKey } from "./media-generation-activity-Bu95TPd8.mjs"; import { n as resolveSandboxRuntimeStatus } from "./runtime-status-BBzhhE6k.mjs"; import { c as resolveCliSessionClearReason, d as shouldClearFailedCliSessionBinding } from "./cli-session-DpAF471M.mjs"; import { a as setChannelSourceTurnId, n as readChannelSourceTurnId, o as setChannelSourceTurnSameThreadRequired, r as readChannelSourceTurnSameThreadRequired } from "./source-turn-id-CdR123OU.mjs"; import { t as buildAgentRuntimeAuthPlan } from "./auth-CAKAwWQF.mjs"; import { a as isTrustedSubagentCompletionHandoffForRun, i as isSubagentAnnounceCompletionHandoff, t as hasVerifiedRequesterCompletionHandoff } from "./requester-tool-policy-BPnUlA5J.mjs"; import { t as resolveConversationCapabilityProfile } from "./conversation-capability-profile-Bzbp--xF.mjs"; import { r as messageToolOwnsVisibleReply } from "./source-reply-delivery-mode-CBzJmohC.mjs"; import { i as resolveConversationToolPolicies } from "./conversation-tool-policy-pipeline-qvZEbKgk.mjs"; import { c as resolveDelegationCapability } from "./agent-tools-Bpi7xWYy.mjs"; import { n as resolveRunEntryCliRuntime } from "./sessions-spawn-tool-B6gir6W9.mjs"; import { t as buildAgentInternalEventContext } from "./internal-events-BxRyNeVO.mjs"; import { o as resolveBootstrapWarningSignaturesSeen } from "./bootstrap-budget-y7OLz5cL.mjs"; import { g as timestampOptsFromConfig, h as injectTimestamp } from "./attempt-system-prompt-prepare-ChKsbjSh.mjs"; import { n as mergeForcedEmbeddedAttemptToolsAllow } from "./attempt-tool-construction-plan-Cf_IxbdX.mjs"; import "./selection-BmmsVs_p.mjs"; import { t as runEmbeddedAgent } from "./embedded-agent-DoEPu8ye.mjs"; import { n as resolveCliRuntimeToolsAllow } from "./tool-policy-CgqZN4xr.mjs"; import { o as resizeExecApprovalContinuationPrompt } from "./bash-tools.exec-approval-output-Do99ku-1.mjs"; import { n as resolveCliExecutionAuthProfileId, t as cliBackendAcceptsAuthProfileForwarding } from "./cli-execution-auth-Bmv6hc3N.mjs"; import { n as emitAgentAttemptRuntimeStart } from "./attempt-callbacks-n8R-aP3x.mjs"; import { s as hasCliLiveSession } from "./cli-live-session-registry-BcPd7Lg7.mjs"; import { _ as resolveFallbackRetryPrompt, f as createAcpVisibleTextAccumulator, g as resolveCompletionToolPolicy, h as resolveCommandReplyExpectation, l as buildClaudeCliFallbackContextPrelude, m as rebaseExecApprovalContinuationPromptRange, p as isClaudeCliProvider, u as claudeCliSessionTranscriptHasContent, v as sessionTranscriptHasContent } from "./session-history-DPHAu5W5.mjs"; import { t as buildCliMcpDelegationCapabilityBinding } from "./mcp-grant-context-1Tzfwjzl.mjs"; import { n as runCliAgent } from "./cli-runner-ChFRQmpq.mjs"; import { a as emitAcpLifecycleError, c as emitAcpRuntimeEvent, i as emitAcpLifecycleEnd, l as resolveAcpLifecycleEndFields, n as createAcpToolLifecycleTracker, o as emitAcpLifecycleStart, r as emitAcpAssistantDelta, s as emitAcpPromptSubmitted, t as buildAcpResult } from "./acp-lifecycle-B1endETq.mjs"; import { a as restoreCliSessionForkInStore, n as clearCliSessionInStore, t as buildCliSessionForkRunParams } from "./cli-session-store-CRxpOUwK.mjs"; import { t as withAdmittedCliCandidate } from "./run-entry-cli-BIfLGfYL.mjs"; import { n as persistCliTurnTranscript, r as resolveCliTranscriptReplyText, t as persistAcpTurnTranscript } from "./transcript-persistence-D4f9J9sD.mjs"; //#region src/agents/command/attempt-auth-selection.ts /** * An explicit session choice owns the conversation. Otherwise the profile bound * to the configured model replaces a stale automatic session choice. */ function resolveSelectedSessionAuthProfile(sessionEntry, configuredAuthProfileId) { const sessionAuthProfileId = sessionEntry?.authProfileOverride?.trim(); const sessionAuthProfileSource = resolveCollapsedSessionAuthPinSource(sessionEntry); if (sessionAuthProfileId && sessionAuthProfileSource !== "auto") return { id: sessionAuthProfileId, source: sessionAuthProfileSource }; const configured = configuredAuthProfileId?.trim(); if (configured) return { id: configured, source: "user" }; return sessionAuthProfileId ? { id: sessionAuthProfileId, source: sessionAuthProfileSource } : void 0; } function resolveHarnessAuthProfileSelection(params) { const sessionAuthProfileId = params.sessionAuthProfileId?.trim(); if (sessionAuthProfileId) { const credential = ensureAuthProfileStore(params.agentDir, { allowKeychainPrompt: false, externalCliProfileIds: [sessionAuthProfileId] }).profiles[sessionAuthProfileId]; return { authProfileId: sessionAuthProfileId, authProfileIdSource: params.sessionAuthProfileSource, authProfileProvider: credential?.provider ?? params.authProfileProvider, authProfileMode: credential?.type }; } if (!params.allowHarnessAuthProfileForwarding) return { authProfileProvider: params.authProfileProvider }; const harnessAuthProvider = buildAgentRuntimeAuthPlan({ provider: params.provider, authProfileProvider: params.authProfileProvider, config: params.config, workspaceDir: params.workspaceDir, ...params.metadataSnapshot ? { metadataSnapshot: params.metadataSnapshot } : {}, providerAuthAliasesEnabled: params.providerAuthAliasesEnabled, harnessId: params.harnessId, harnessRuntime: params.harnessRuntime, allowHarnessAuthProfileForwarding: params.allowHarnessAuthProfileForwarding }).harnessAuthProvider; if (!harnessAuthProvider) return { authProfileProvider: params.authProfileProvider }; const store = ensureAuthProfileStore(params.agentDir, { allowKeychainPrompt: false, externalCliProviderIds: [harnessAuthProvider] }); const authProfileId = resolveAuthProfileOrder({ cfg: params.config, store, provider: harnessAuthProvider })[0]; return authProfileId ? { authProfileId, authProfileIdSource: "auto", authProfileProvider: harnessAuthProvider } : { authProfileProvider: params.authProfileProvider }; } //#endregion //#region src/agents/command/attempt-execution.cli-prompt.ts /** * Builds the CLI-backend prompt, transcript prompt, and continuation body. * * Exec-approval continuations resize the approved output to the live tool-result * budget before the retry/provenance decoration the shared path already * applied to `effectivePrompt`; inter-session prompts skip the * timestamp because their provenance annotation already frames them. */ function resolveCliAttemptPrompts(params) { const continuationBody = params.promptRange ? resizeExecApprovalContinuationPrompt({ prompt: params.body, range: params.promptRange, maxOutputUtf16Units: DEFAULT_MAX_LIVE_TOOL_RESULT_CHARS }) : params.body; const effectivePrompt = params.promptRange ? annotateInterSessionPromptText(resolveFallbackRetryPrompt({ body: continuationBody, isFallbackRetry: params.isFallbackRetry, sessionHasHistory: params.sessionHasHistory, priorContextPrelude: params.priorContextPrelude }), params.inputProvenance) : params.effectivePrompt; return { continuationBody, transcriptPrompt: params.transcriptBody === void 0 || !params.transcriptPromptRange ? params.transcriptBody : resizeExecApprovalContinuationPrompt({ prompt: params.transcriptBody, range: params.transcriptPromptRange, maxOutputUtf16Units: DEFAULT_MAX_LIVE_TOOL_RESULT_CHARS }), prompt: params.inputProvenance?.kind === "inter_session" ? effectivePrompt : injectTimestamp(effectivePrompt, timestampOptsFromConfig(params.cfg)) }; } //#endregion //#region src/agents/command/attempt-sandbox-cli-admission.ts /** * Sandboxed delegated children never dispatch to host-executed CLI backends. * * A CLI backend spawns a local AI CLI on the gateway host; its native tools run * with the gateway OS user outside any configured sandbox. Spawn admission * fails closed once the resolved child model is known, but fallback candidates * and post-spawn runtime overrides can still land on a CLI backend when the * run starts, so the run seam owns the invariant: refuse the CLI candidate for * any session with spawn provenance and whose sandbox classification (the * configured sandbox mode covering this session key, or a creation-stamped * `sandbox: "required"`) claims containment. Recovery is configuration: pick an * API-backed child model, or change the agent's sandbox policy explicitly. * Direct operator-chosen CLI runs on a non-delegated, unsandboxed session stay * permitted, mirroring the cron seam guard * (`assertCronCandidateSandboxPlacement`). */ function assertSandboxedDelegatedChildNotCli(params) { if (!params.useCliExecution) return; if (!(isSubagentSessionKey(params.sessionKey) || Boolean(params.sessionEntry?.spawnedBy?.trim()))) return; const placement = resolveSandboxRuntimeStatus({ cfg: params.cfg, sessionKey: params.sessionKey, agentId: params.sessionAgentId, preparedSessionEntry: params.sessionEntry ?? null }); if (!placement.sandboxed && !placement.sandboxRequired) return; throw new AgentHarnessPreflightError(`This delegated run belongs to a sandboxed session, but resolved execution provider ${params.cliExecutionProvider} runs on the host and cannot honor the sandbox. Override agents.entries.<id>.subagents.model, agents.defaults.subagents.model, or the spawn model with an API-backed provider (and clear any pinned CLI runtime override), or change the agent's sandbox policy explicitly.`); } //#endregion //#region src/agents/command/attempt-execution.ts const log = createSubsystemLogger("agents/agent-command"); function runAgentAttempt(params) { const selectedAuthProfile = resolveSelectedSessionAuthProfile(params.sessionEntry, params.configuredAuthProfileId); const isRawModelRun = params.opts.modelRun === true || params.opts.promptMode === "none"; const isSubagentAnnounceHandoff = isSubagentAnnounceCompletionHandoff({ inputProvenance: params.opts.inputProvenance, internalEvents: params.opts.internalEvents }); const trustedSubagentCompletionHandoff = isTrustedSubagentCompletionHandoffForRun({ handoff: params.opts.trustedInternalHandoff, inputProvenance: params.opts.inputProvenance, internalEvents: params.opts.internalEvents, sessionKey: params.sessionKey, sessionId: params.sessionId, provider: params.providerOverride, model: params.modelOverride }) && hasVerifiedRequesterCompletionHandoff({ config: params.cfg, sessionKey: params.sessionKey, inputProvenance: params.opts.inputProvenance, trustedInternalHandoff: params.opts.trustedInternalHandoff, sessionId: params.sessionId, modelProvider: params.providerOverride, modelId: params.modelOverride }); const trustedSubagentAnnounceHandoff = isSubagentAnnounceHandoff && trustedSubagentCompletionHandoff; const completionRequestsMessageDelivery = trustedSubagentAnnounceHandoff && !isRawModelRun && params.opts.disableMessageTool !== true && messageToolOwnsVisibleReply(params.opts); const completionSandboxStatus = completionRequestsMessageDelivery ? resolveSandboxRuntimeStatus({ cfg: params.cfg, sessionKey: params.sessionKey, agentId: params.sessionAgentId }) : void 0; const completionCapabilityProfile = completionRequestsMessageDelivery ? resolveConversationCapabilityProfile({ config: params.cfg, sessionKey: params.sessionKey, sessionId: params.sessionId, agentId: params.sessionAgentId, senderId: params.runContext.senderId, modelProvider: params.providerOverride, modelId: params.modelOverride, sandboxToolPolicy: completionSandboxStatus?.sandboxed ? completionSandboxStatus.toolPolicy : void 0, inputProvenance: params.opts.inputProvenance, trustedInternalHandoff: params.opts.trustedInternalHandoff }) : void 0; const completionToolPolicies = completionCapabilityProfile ? resolveConversationToolPolicies({ capabilityProfile: completionCapabilityProfile, additionalProfileAllow: ["message"], additionalPolicyAllow: ["message"], additionalInheritedAllow: ["message"] }) : void 0; const completionNeedsMessageDelivery = completionCapabilityProfile?.policy.requesterPolicySource === "completion-handoff" && completionToolPolicies !== void 0 && isToolAllowedByPolicies("message", Object.values(completionToolPolicies)) && isRuntimeToolAllowed("message", params.opts.toolsAllow); const claudeCliFallbackPrelude = !isRawModelRun && params.isFallbackRetry && isClaudeCliProvider(params.originalProvider) && !isClaudeCliProvider(params.providerOverride) ? buildClaudeCliFallbackContextPrelude({ cliSessionId: getCliSessionBinding(params.sessionEntry, "claude-cli")?.sessionId }) : ""; const resolvedPrompt = resolveFallbackRetryPrompt({ body: params.body, isFallbackRetry: params.isFallbackRetry, sessionHasHistory: params.sessionHasHistory, priorContextPrelude: claudeCliFallbackPrelude }); const effectivePrompt = isRawModelRun ? resolvedPrompt : annotateInterSessionPromptText(resolvedPrompt, params.opts.inputProvenance); const embeddedExecApprovalContinuationPromptRange = rebaseExecApprovalContinuationPromptRange({ body: params.body, prompt: effectivePrompt, range: params.opts.execApprovalContinuationPromptRange }); const continuationTranscriptBody = params.opts.execApprovalContinuationPromptRange ? params.transcriptBody ?? params.body : params.transcriptBody; const continuationTranscriptPromptRange = params.opts.execApprovalContinuationTranscriptPromptRange ?? params.opts.execApprovalContinuationPromptRange; const bootstrapPromptWarningSignaturesSeen = resolveBootstrapWarningSignaturesSeen(params.sessionEntry?.systemPromptReport); const requestedAgentHarnessId = isRawModelRun ? "openclaw" : void 0; const sessionRuntimeOverride = isRawModelRun ? void 0 : params.agentHarnessRuntimeOverride; const pinnedHarnessId = isRawModelRun ? void 0 : resolveSessionPinnedHarnessId(params.sessionEntry); const { cliExecutionProvider, useCliExecution: isCliExecutionProvider } = isRawModelRun ? { cliExecutionProvider: params.providerOverride, useCliExecution: isCliProvider(params.providerOverride, params.cfg) } : resolveRunEntryCliRuntime({ config: params.cfg, provider: params.providerOverride, model: params.modelOverride, agentId: params.sessionAgentId, authProfileId: selectedAuthProfile?.id, sessionRuntimeOverride, pinnedHarnessId }); assertSandboxedDelegatedChildNotCli({ useCliExecution: isCliExecutionProvider, cliExecutionProvider, cfg: params.cfg, sessionKey: params.sessionKey, sessionAgentId: params.sessionAgentId, sessionEntry: params.sessionEntry }); const { completionRetainsRequesterTools, runtimeToolsAllow, disableTools } = resolveCompletionToolPolicy({ run: params, trustedSubagentAnnounceHandoff, isSubagentAnnounceHandoff, isRawModelRun, isCliExecutionProvider, cliExecutionProvider, completionNeedsMessageDelivery }); const cliRuntimeToolsAllow = mergeForcedEmbeddedAttemptToolsAllow(runtimeToolsAllow, { forceToolNames: params.opts.swarmCollector && params.opts.swarmOutputSchema ? ["structured_output"] : void 0 }); const toolContext = { messageChannel: params.messageChannel, messageProvider: params.opts.messageProvider ?? params.messageChannel, agentAccountId: params.runContext.accountId, groupId: params.runContext.groupId, groupChannel: params.runContext.groupChannel, groupSpace: params.runContext.groupSpace, spawnedBy: params.spawnedBy, currentChannelId: params.runContext.currentChannelId, chatId: params.runContext.chatId, channelContext: params.runContext.channelContext, currentThreadTs: params.runContext.currentThreadTs, currentInboundAudio: params.runContext.currentInboundAudio, replyToMode: params.runContext.replyToMode, senderId: params.runContext.senderId, senderIsOwner: params.opts.senderIsOwner, scheduledToolPolicy: params.opts.scheduledToolPolicy, pinnedWidgetAuthoring: params.opts.pinnedWidgetAuthoring }; if (params.fallbackRuntimeState && params.fallbackRuntimeState.originRuntime === void 0) params.fallbackRuntimeState.originRuntime = !isRawModelRun && isCliExecutionProvider ? "cli" : "embedded"; const shouldForwardImagesToEmbedded = !params.isFallbackRetry || params.fallbackRuntimeState?.originRuntime === "cli"; const allowCliAuthProfileForwarding = isCliExecutionProvider && cliBackendAcceptsAuthProfileForwarding({ provider: cliExecutionProvider, config: params.cfg, agentId: params.sessionAgentId }); const agentHarnessPolicy = isRawModelRun ? { runtime: "openclaw", runtimeSource: "model" } : sessionRuntimeOverride ? { runtime: sessionRuntimeOverride, runtimeSource: "model" } : resolveAvailableAgentHarnessPolicy({ provider: params.providerOverride, modelId: params.modelOverride, config: params.cfg, agentId: params.sessionAgentId, sessionKey: params.sessionKey ?? params.sessionId }); const harnessAuthContext = { config: params.cfg, workspaceDir: params.workspaceDir, provider: params.providerOverride, harnessId: requestedAgentHarnessId, harnessRuntime: agentHarnessPolicy.runtime, ...params.metadataSnapshot ? { metadataSnapshot: params.metadataSnapshot } : {}, providerAuthAliasesEnabled: params.pluginsEnabled, allowHarnessAuthProfileForwarding: !isCliExecutionProvider }; const harnessAuthSelection = resolveHarnessAuthProfileSelection({ ...harnessAuthContext, agentDir: params.agentDir, authProfileProvider: params.authProfileProvider, sessionAuthProfileId: selectedAuthProfile?.id, sessionAuthProfileSource: selectedAuthProfile?.source }); const runtimeAuthPlan = buildAgentRuntimeAuthPlan({ ...harnessAuthContext, authProfileProvider: harnessAuthSelection.authProfileProvider, authProfileMode: harnessAuthSelection.authProfileMode, sessionAuthProfileId: harnessAuthSelection.authProfileId }); const cliAuthNeedsSessionBinding = allowCliAuthProfileForwarding && !isRawModelRun && (!harnessAuthSelection.authProfileId || harnessAuthSelection.authProfileIdSource === "auto"); const buildCliAuthContext = () => ({ cliExecutionProvider, authProfileProvider: params.authProfileProvider, config: params.cfg, agentDir: params.agentDir, selected: harnessAuthSelection }); const authProfileId = allowCliAuthProfileForwarding && !cliAuthNeedsSessionBinding ? resolveCliExecutionAuthProfileId(buildCliAuthContext()) : runtimeAuthPlan.forwardedAuthProfileId; const embeddedAgentProvider = resolveOpenAIRuntimeProvider({ provider: params.providerOverride, harnessRuntime: agentHarnessPolicy.runtime, agentHarnessId: requestedAgentHarnessId, authProfileProvider: runtimeAuthPlan.authProfileProviderForAuth, authProfileId, config: params.cfg, workspaceDir: params.workspaceDir }); const embeddedAgentHarnessOverride = requestedAgentHarnessId ?? sessionRuntimeOverride ?? (agentHarnessPolicy.runtime === "openclaw" && agentHarnessPolicy.runtimeSource !== "implicit" ? "openclaw" : void 0); const replyExpectation = resolveCommandReplyExpectation(params); const buildCommonRunParams = () => ({ preparedRunAdmission: params.preparedRunAdmission, sessionId: params.sessionId, sessionKey: params.sessionKey, sessionTarget: params.sessionTarget, chatType: params.sessionEntry?.chatType, contextWindow: params.sessionEntry?.contextWindow, agentId: params.sessionAgentId, trigger: "user", sessionFile: params.sessionFile, workspaceDir: params.workspaceDir, cwd: params.cwd, config: params.cfg, toolOverrides: params.sessionEntry?.toolOverrides, modelHasVision: params.modelHasVision, model: params.modelOverride, modelRoutingProvenance: params.modelRoutingProvenance, thinkLevel: params.resolvedThinkLevel, fastMode: params.fastMode, fastModeStartedAtMs: params.fastModeStartedAtMs, fastModeAutoOnSeconds: params.fastModeAutoOnSeconds, timeoutMs: params.timeoutMs, runTimeoutOverrideMs: params.runTimeoutOverrideMs, runId: params.runId, lifecycleGeneration: params.lifecycleGeneration, onExecutionPhase: (info) => emitAgentAttemptRuntimeStart(info, params.onAgentEvent), lane: params.opts.lane, swarmExecutionLane: params.opts.swarmExecutionLane, extraSystemPrompt: params.opts.extraSystemPrompt, inputProvenance: params.opts.inputProvenance, skillLibraryAuthoring: params.opts.skillLibraryAuthoring, sourceReplyDeliveryMode: params.opts.sourceReplyDeliveryMode, taskSuggestionDeliveryMode: params.opts.taskSuggestionDeliveryMode, clientCaps: params.opts.clientCaps, gatewayUiCommandTarget: params.opts.gatewayUiCommandTarget, media: params.opts.media, skillsSnapshot: params.skillsSnapshot, streamParams: params.opts.streamParams, approvalReviewerDeviceId: params.opts.approvalReviewerDeviceId, bashElevated: params.opts.bashElevated, cleanupBundleMcpOnRunEnd: params.opts.cleanupBundleMcpOnRunEnd, oneShotCliRun: params.opts.oneShotCliRun, userTurnTranscriptRecorder: params.userTurnTranscriptRecorder, prepareAssistantTranscriptMessage: params.opts.prepareAssistantTranscriptMessage, contextEngineLogicalTurnLease: params.contextEngineLogicalTurnLease, onContextEngineTurnCandidate: params.onContextEngineTurnCandidate, suppressNextUserMessagePersistence: params.suppressPromptPersistenceOnRetry === true, disableTools, terminalReplyExpectation: replyExpectation, silentReplyPromptMode: params.opts.silentReplyPromptMode ?? (replyExpectation === "required" ? "none" : void 0), bootstrapPromptWarningSignaturesSeen, bootstrapPromptWarningSignature: bootstrapPromptWarningSignaturesSeen.at(-1) }); if (!isRawModelRun && isCliExecutionProvider) { const expectedLifecycleRevision = params.sessionEntry?.lifecycleRevision; return withAdmittedCliCandidate({ claim: { sessionId: params.sessionId, sessionKey: params.sessionKey ?? params.sessionId, agentId: params.sessionAgentId, runId: params.runId }, admission: { preparedRunAdmission: params.preparedRunAdmission, lifecycleGeneration: params.lifecycleGeneration, isFinalFallbackAttempt: params.isFinalFallbackAttempt, abortSignal: params.deferredLifecycle?.signal ?? params.opts.abortSignal, trigger: "user", inputProvenance: params.opts.inputProvenance }, provider: cliExecutionProvider, sessionTarget: params.sessionKey && params.storePath ? { agentId: params.sessionAgentId, sessionId: params.sessionId, sessionKey: params.sessionKey, storePath: params.storePath } : void 0, expectedLifecycleRevision, readMode: "writable", getSessionEntry: () => params.sessionEntry, classifyResult: params.classifyResult }, async ({ sessionEntry, cliSessionBinding, assertSettlementCurrent, settleResult }) => { params.sessionEntry = sessionEntry; const cliAuthProfileId = cliAuthNeedsSessionBinding ? resolveCliExecutionAuthProfileId({ ...buildCliAuthContext(), sessionBinding: cliSessionBinding }) : authProfileId; const diagnosticOwner = params.deferredLifecycle?.handoffToCli(); const cliProcessCwd = params.cwd ? resolveUserPath(params.cwd) : params.workspaceDir; const { continuationBody: cliContinuationBody, transcriptPrompt: cliTranscriptPrompt, prompt: cliPrompt } = resolveCliAttemptPrompts({ cfg: params.cfg, body: params.body, promptRange: params.opts.execApprovalContinuationPromptRange, transcriptBody: continuationTranscriptBody, transcriptPromptRange: continuationTranscriptPromptRange, isFallbackRetry: params.isFallbackRetry, sessionHasHistory: params.sessionHasHistory, priorContextPrelude: claudeCliFallbackPrelude, inputProvenance: params.opts.inputProvenance, effectivePrompt }); params.userTurnTranscriptRecorder?.replaceTextBeforePersistence?.(cliTranscriptPrompt ?? cliContinuationBody); const mutableCliSessionStore = params.sessionKey && params.sessionStore && params.storePath ? { agentId: params.sessionAgentId, sessionKey: params.sessionKey, sessionStore: params.sessionStore, storePath: params.storePath, expectedSessionId: params.sessionId, assertCommitAllowed: assertSettlementCurrent } : void 0; const clearCliBinding = async (expectedCliSessionId) => { if (!mutableCliSessionStore) return false; const cleared = await clearCliSessionInStore({ provider: cliExecutionProvider, ...expectedCliSessionId !== void 0 ? { expectedCliSessionId } : {}, ...mutableCliSessionStore }); params.sessionEntry = cleared ?? params.sessionEntry; return Boolean(cleared); }; const prepareCliSessionBinding = async () => { if (!isClaudeCliProvider(cliExecutionProvider) || !cliSessionBinding?.sessionId) return; if (hasCliLiveSession({ backendId: cliExecutionProvider, agentId: params.sessionAgentId, sessionId: params.sessionId, sessionKey: params.sessionKey }) || await claudeCliSessionTranscriptHasContent({ sessionId: cliSessionBinding.sessionId, workspaceDir: cliProcessCwd })) return; log.warn(`cli session reset: provider=${sanitizeForLog(cliExecutionProvider)} reason=transcript-missing sessionKey=${params.sessionKey ?? params.sessionId}`); await clearCliBinding(); }; const mediaTaskIdsBefore = getGeneratedMediaTaskIdsForSessionKey(params.sessionKey, params.sessionAgentId); const hasNewMediaTask = () => hasNewGeneratedMediaTaskForSessionKey(params.sessionKey, mediaTaskIdsBefore, params.sessionAgentId); await prepareCliSessionBinding(); const { internalEvents, runtimeContextFragments: supplementalContext } = params.opts; let result; try { const forkStoreParams = cliSessionBinding?.sessionId && mutableCliSessionStore ? { provider: cliExecutionProvider, expectedCliSessionId: cliSessionBinding.sessionId, ...mutableCliSessionStore, assertCommitAllowed: () => { assertSettlementCurrent(); (params.deferredLifecycle?.signal ?? params.opts.abortSignal)?.throwIfAborted(); } } : void 0; result = await runCliAgent({ ...buildCommonRunParams(), diagnosticOwner, sessionEntry: params.sessionEntry, storePath: params.storePath, persistAssistantTranscript: params.storePath !== void 0 && params.sessionStore !== void 0, prompt: cliPrompt, runtimeContextFragments: buildAgentInternalEventContext(internalEvents, supplementalContext), transcriptPrompt: cliTranscriptPrompt, modelProvider: params.providerOverride, requesterModel: { provider: params.providerOverride, model: params.modelOverride }, provider: cliExecutionProvider, trustedInternalHandoff: completionRetainsRequesterTools ? params.opts.trustedInternalHandoff : void 0, abortSignal: params.deferredLifecycle?.signal ?? params.opts.abortSignal, onExecutionStarted: params.opts.onExecutionStarted, cronCreatorCallerOrigin: params.opts.cronCreatorAuthorityCapability?.callerOrigin, requireExplicitMessageTarget: params.opts.requireExplicitMessageTarget ?? isSubagentSessionKey(params.sessionKey), cliSessionBindingFacts: params.opts.cliSessionBindingFacts, cliSessionId: cliSessionBinding?.sessionId, cliSessionBinding, forkCliSessionOnResume: cliSessionBinding?.forkNextResume === true, ...forkStoreParams ? buildCliSessionForkRunParams({ ...forkStoreParams, assertCommitAllowed: assertSettlementCurrent, abortSignal: params.deferredLifecycle?.signal ?? params.opts.abortSignal }, (entry) => { params.sessionEntry = entry; }) : {}, authProfileId: cliAuthProfileId, imagePrompt: params.body, images: params.opts.images, imageOrder: params.opts.imageOrder, ...toolContext, currentChannelId: params.runContext.currentChannelId ?? (completionNeedsMessageDelivery ? params.opts.replyTo ?? params.opts.to : void 0), toolsAllow: resolveCliRuntimeToolsAllow(cliRuntimeToolsAllow), ...buildCliMcpDelegationCapabilityBinding(resolveDelegationCapability({ fallbackActive: params.isFallbackRetry, inputProvenance: params.opts.inputProvenance, disableTools, toolsAllow: runtimeToolsAllow })), cleanupCliLiveSessionOnRunEnd: params.opts.cleanupCliLiveSessionOnRunEnd, ...forkStoreParams && cliSessionBinding?.forkNextResume !== true ? { onBeforeForkedCliSessionRetry: async (retry) => { if (hasNewMediaTask() || retry.sessionId !== cliSessionBinding?.sessionId) return false; log.warn(`CLI session stalled, arming forked recovery: provider=${sanitizeForLog(cliExecutionProvider)} sessionKey=${forkStoreParams.sessionKey}`); const armed = await restoreCliSessionForkInStore(forkStoreParams); params.sessionEntry = armed ?? params.sessionEntry; return Boolean(armed); } } : {}, ...mutableCliSessionStore ? { onBeforeFreshCliSessionRetry: async (retry) => { if (hasNewMediaTask()) return false; const currentEntry = await readSessionEntryInWorker({ agentId: params.sessionAgentId, sessionKey: mutableCliSessionStore.sessionKey, storePath: mutableCliSessionStore.storePath, readConsistency: "latest" }, assertSettlementCurrent); assertSettlementCurrent(); if (hasNewMediaTask() || getCliSessionBinding(currentEntry, cliExecutionProvider)?.sessionId !== retry.sessionId) return false; log.warn(`CLI session failed, clearing before fresh retry: provider=${sanitizeForLog(cliExecutionProvider)} sessionKey=${mutableCliSessionStore.sessionKey} reason=${sanitizeForLog(retry.reason)}`); return await clearCliBinding(retry.sessionId); } } : {} }); } catch (err) { const failedCliSessionBinding = getCliSessionBinding(params.sessionEntry, cliExecutionProvider); const failedCliSessionId = failedCliSessionBinding?.sessionId; if (isClaudeCliProvider(cliExecutionProvider) && shouldClearFailedCliSessionBinding({ error: err, binding: failedCliSessionBinding, bindingReplacedDuringRun: failedCliSessionId !== cliSessionBinding?.sessionId, hasNewGeneratedMediaTask: hasNewMediaTask() }) && failedCliSessionId && mutableCliSessionStore) { log.warn(`CLI session cleared after failed reused turn: provider=${sanitizeForLog(cliExecutionProvider)} sessionKey=${mutableCliSessionStore.sessionKey} reason=${sanitizeForLog(resolveCliSessionClearReason(err))}`); await clearCliBinding(failedCliSessionId); } throw err; } return settleResult({ result, expectedSession: params.sessionEntry, sessionStore: params.sessionStore, preserveBinding: params.preserveCliSessionBinding }); }); } const embeddedRunParams = { ...buildCommonRunParams(), sandboxSessionKey: params.sessionKey, ...toolContext, messageTo: params.opts.replyTo ?? params.opts.to, messageThreadId: params.opts.threadId, hasRepliedRef: params.runContext.hasRepliedRef, permissionMode: params.sessionEntry?.permissionMode, sessionRoot: params.sessionEntry?.sessionRoot, ...params.pluginGeneration ? { pluginGeneration: params.pluginGeneration } : {}, agentHarnessId: pinnedHarnessId, modelSelectionLocked: !isRawModelRun && params.sessionEntry?.modelSelectionLocked === true, agentHarnessRuntimeOverride: embeddedAgentHarnessOverride, agentHarnessRuntimePreparationHint: agentHarnessPolicy.runtimeSource !== "implicit" ? agentHarnessPolicy.runtime : void 0, prompt: effectivePrompt, transcriptPrompt: continuationTranscriptBody, images: shouldForwardImagesToEmbedded ? params.opts.images : void 0, imageOrder: shouldForwardImagesToEmbedded ? params.opts.imageOrder : void 0, clientTools: params.opts.clientTools, toolBindings: params.opts.toolBindings, provider: embeddedAgentProvider, requestedRouteResolution: "resolved", modelThinkingCapability: params.modelThinkingCapability, modelFallbacksOverride: params.modelFallbacksOverride, authProfileId, authProfileIdSource: authProfileId ? harnessAuthSelection.authProfileIdSource : void 0, isFinalFallbackAttempt: params.isFinalFallbackAttempt, verboseLevel: params.resolvedVerboseLevel, execSession: params.sessionEntry, execApprovalContinuationPromptRange: embeddedExecApprovalContinuationPromptRange, execApprovalContinuationTranscriptPromptRange: continuationTranscriptPromptRange, suppressLiveStreamOutput: params.opts.sessionEffects === "internal" && params.opts.deliver !== true, abortSignal: params.opts.abortSignal, bootstrapContextMode: params.opts.bootstrapContextMode, bootstrapContextRunKind: params.opts.bootstrapContextRunKind, toolsAllow: runtimeToolsAllow, runtimePluginToolGrant: params.opts.runtimePluginToolGrant, trustedInternalHandoff: trustedSubagentCompletionHandoff ? params.opts.trustedInternalHandoff : void 0, cronCreatorAuthorityCapability: params.opts.cronCreatorAuthorityCapability, internalEvents: params.opts.internalEvents, runtimeContextFragments: params.opts.runtimeContextFragments, requireExplicitMessageTarget: params.opts.requireExplicitMessageTarget, disableMessageTool: params.opts.disableMessageTool, swarmCollector: params.opts.swarmCollector, swarmOutputSchema: params.opts.swarmOutputSchema, forceRestartSafeTools: params.opts.forceRestartSafeTools, forceCodeModeTools: params.opts.forceCodeModeTools, codeModeOverride: params.opts.codeModeOverride, agentDir: params.agentDir, allowGatewaySubagentBinding: params.opts.allowGatewaySubagentBinding, allowTransientCooldownProbe: params.allowTransientCooldownProbe, modelRun: params.opts.modelRun, promptMode: params.opts.promptMode, onAgentEvent: params.onAgentEvent, deferTerminalLifecycle: params.deferTerminalLifecycle, onDeferredLifecycleOwner: params.deferredLifecycle?.adopt, onDeferredLifecycleAbort: params.deferredLifecycle?.abort, onRetryWait: params.deferredLifecycle?.beginRetryWait, assistantErrorTranscript: params.assistantErrorTranscript, authProfileFailurePolicy: params.authProfileFailurePolicy, onUserMessagePersisted: params.onUserMessagePersisted, onCompactionAccounting: params.onCompactionAccounting, onCompactionRequestBudget: params.onCompactionRequestBudget, onSuccessfulAuthProfile: params.onSuccessfulAuthProfile ? (successfulProfileId) => params.onSuccessfulAuthProfile?.({ authProfileId: successfulProfileId, authProfileIdSource: successfulProfileId ? successfulProfileId === authProfileId ? harnessAuthSelection.authProfileIdSource : "auto" : void 0 }) : void 0, onExecutionStarted: async (info) => { await params.opts.onExecutionStarted?.(); if (info?.lifecycleGeneration) params.onLifecycleGenerationChanged?.(info.lifecycleGeneration); }, onSessionIdChanged: params.opts.onSessionIdChanged }; setChannelSourceTurnId(embeddedRunParams, readChannelSourceTurnId(params.runContext)); setChannelSourceTurnSameThreadRequired(embeddedRunParams, readChannelSourceTurnSameThreadRequired(params.runContext)); return runEmbeddedAgent(embeddedRunParams); } //#endregion export { buildAcpResult, createAcpToolLifecycleTracker, createAcpVisibleTextAccumulator, emitAcpAssistantDelta, emitAcpLifecycleEnd, emitAcpLifecycleError, emitAcpLifecycleStart, emitAcpPromptSubmitted, emitAcpRuntimeEvent, persistAcpTurnTranscript, persistCliTurnTranscript, resolveAcpLifecycleEndFields, resolveCliTranscriptReplyText, runAgentAttempt, sessionTranscriptHasContent };