openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
1,144 lines • 55 kB
JavaScript
import { t as sanitizeForLog } from "./ansi-DrXAcdMD.js";
import { a as asOptionalRecord } from "./record-coerce-DItp3I4t.js";
import { c as normalizeOptionalLowercaseString } from "./string-coerce-CIXf7egm.js";
import { r as truncateUtf16Safe } from "./utf16-slice-D_ngcYKd.js";
import { c as resolveUserPath } from "./home-dir-BPhrG-aM.js";
import { p as redactSensitiveText } from "./redact-BtvPPfTi.js";
import "./utils-P__uGsPB.js";
import { T as isSubagentSessionKey } from "./session-key-BnWWjqNc.js";
import { o as emitTrustedDiagnosticEvent } from "./diagnostic-events-Cwe92uV3.js";
import { t as createSubsystemLogger } from "./subsystem-Dy2tqXOS.js";
import { a as isToolAllowedByPolicies, i as isRuntimeToolAllowed } from "./tool-policy-match-TnFxBs5z.js";
import { A as resolveCollapsedSessionAuthPinSource } from "./agent-scope-DbtJyKUL.js";
import { u as resolveOpenAIRuntimeProvider } from "./openai-routing-Ex_3E9TF.js";
import { i as emitAgentEvent, r as emitAgentAuditEvent } from "./agent-events-CoxiItUi.js";
import "./message-channel-BQrhwUEA.js";
import { r as ensureAuthProfileStore } from "./store-F1B2duCT.js";
import { a as resolveAuthProfileOrder } from "./order-CC2RBzI5.js";
import { i as annotateInterSessionPromptText } from "./input-provenance-DiG-Cwnd.js";
import { f as preparePersistedUserTurnMessageForTranscriptWrite, i as buildPersistedUserTurnMessage } from "./user-turn-transcript.message-LcwHBB2I.js";
import { F as persistSessionTranscriptTurn } from "./session-accessor-YsytfDtG.js";
import { i as buildUsageWithNoCost } from "./stream-message-shared-Cyrn1UHN.js";
import { l as loadSessionEntry } from "./session-accessor.sqlite-entry-CWk3jL7s.js";
import { h as resolveSessionPinnedHarnessId } from "./agent-harness-session-key-BOz3yx0-.js";
import { n as getCliSessionBinding } from "./cli-session-binding-Aa6nlDa8.js";
import { t as DEFAULT_MAX_LIVE_TOOL_RESULT_CHARS } from "./tool-result-limits-CFk9DkYv.js";
import { n as resolveAvailableAgentHarnessPolicy } from "./availability-DrQ2OOVX.js";
import { i as resolveCliBackendConfig } from "./cli-backends-Bs_a4MW0.js";
import { s as resolveCliRuntimeExecutionProvider } from "./model-runtime-aliases-BJ2qM8I_.js";
import { s as isCliProvider } from "./model-selection-di2kjKCB.js";
import { r as formatAcpErrorChain } from "./errors-CY1OFR4J.js";
import "./errors-Bnilofa2.js";
import "./manager.turn-timeout-DfQgYwqb.js";
import { i as buildAgentRunTerminalOutcomeFromLifecycleEvent, o as classifyAgentRunTerminalOutcome } from "./agent-run-terminal-outcome-CigeY75d.js";
import { l as createAgentRunSupersededAbortError, m as resolveAgentRunAbortLifecycleFields } from "./run-termination-jabvTOp5.js";
import { a as hasNewGeneratedMediaTaskForSessionKey, r as getGeneratedMediaTaskIdsForSessionKey } from "./task-status-access-C6caarxH.js";
import { n as normalizeReplyPayload } from "./normalize-reply-C1iRjnEc.js";
import { n as resolveSandboxRuntimeStatus } from "./runtime-status-6c8Jb1Kg.js";
import { K as injectTimestamp, q as timestampOptsFromConfig } from "./builtin-openclaw-B_H1oNzF.js";
import { n as runAgentHarnessBeforeMessageWriteHook } from "./hook-helpers-3JS9XC0_.js";
import { l as shouldClearFailedCliSessionBinding, o as resolveCliSessionClearReason } from "./cli-session-pAa_-y_N.js";
import { o as messageToolOwnsVisibleReply } from "./local-model-lean-B52ThaBJ.js";
import { i as isTrustedSubagentCompletionHandoffForRun, r as isSubagentAnnounceCompletionHandoff, t as hasVerifiedRequesterCompletionHandoff } from "./requester-tool-policy-QJhnbudW.js";
import { t as resolveConversationCapabilityProfile } from "./conversation-capability-profile-B6PkMXFD.js";
import { o as resolveBootstrapWarningSignaturesSeen } from "./bootstrap-budget-7_XA_4pm.js";
import { t as buildAgentRuntimeAuthPlan } from "./auth-D2bx7kf3.js";
import "./user-turn-transcript-DDGwFDzp.js";
import { t as AGENT_LANE_SUBAGENT } from "./lanes-CI0_P-yC.js";
import { r as resolveConversationToolPolicies } from "./conversation-tool-policy-pipeline-BzM9yFTb.js";
import { r as resolveDelegationCapability } from "./agent-tools-By64BZu5.js";
import "./selection-CgLPGlZh.js";
import { a as setChannelSourceTurnSameThreadRequired, i as setChannelSourceTurnId, n as readChannelSourceTurnId, r as readChannelSourceTurnSameThreadRequired } from "./source-turn-id-6iBUXSKV.js";
import { a as withLocalSessionPlacementTurnSettlement } from "./session-placement-admission-UsKSuaws.js";
import { t as runEmbeddedAgent } from "./embedded-agent-D9hkv0XX.js";
import { t as resolveCliRuntimeToolsAllow } from "./tool-policy-CErHvAIq.js";
import { a as resizeExecApprovalContinuationPrompt } from "./bash-tools.exec-approval-output-D40DdETx.js";
import { n as cliBackendAcceptsAuthProfileForwarding, r as resolveCliExecutionAuthProfileId } from "./cli-execution-auth-BmnnNTfm.js";
import "./run-context-_oIzfa6T.js";
import { s as hasCliLiveSession } from "./cli-live-session-registry-BHTgbpiF.js";
import { l as buildClaudeCliFallbackContextPrelude, p as resolveFallbackRetryPrompt, u as claudeCliSessionTranscriptHasContent } from "./session-history-BiQCfTGK.js";
import { t as buildCliMcpDelegationCapabilityBinding } from "./mcp-grant-context-REH4fXZ7.js";
import { n as runCliAgent } from "./cli-runner-dxvZUkQb.js";
import { t as resolveAcpToolTerminalOutcome } from "./tool-status-CyYVXMyT.js";
import { n as persistCliSessionBindingResult, t as clearCliSessionInStore } from "./cli-session-store-C8XIYI19.js";
import { t as appendGitCoauthorContext } from "./git-coauthor-attribution-CsDxBk6r.js";
import { a as restoreCliSessionForkInStore, r as persistCliSessionForkSuccessorInStore, t as consumeCliSessionForkInStore } from "./session-store-CQm3CjzN.js";
//#region src/agents/command/attempt-execution.ts
const log = createSubsystemLogger("agents/agent-command");
function rebaseExecApprovalContinuationPromptRange(params) {
if (!params.range) return;
if (!params.prompt.endsWith(params.body)) throw new Error("exec approval continuation prompt range could not be rebased");
const offset = params.prompt.length - params.body.length;
return {
start: offset + params.range.start,
end: offset + params.range.end
};
}
const ACP_TRANSCRIPT_USAGE = {
input: 0,
output: 0,
cacheRead: 0,
cacheWrite: 0,
totalTokens: 0,
cost: {
input: 0,
output: 0,
cacheRead: 0,
cacheWrite: 0,
total: 0
}
};
const CLI_TRANSCRIPT_UNAVAILABLE_USAGE = {
input: 0,
output: 0,
cacheRead: 0,
cacheWrite: 0,
total: 0,
contextUsage: { state: "unavailable" }
};
function resolveCliTranscriptUsage(usage) {
if (!usage) return CLI_TRANSCRIPT_UNAVAILABLE_USAGE;
if (usage.contextUsage) return usage;
const promptTokens = (usage.input ?? 0) + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
return {
...usage,
contextUsage: promptTokens > 0 ? {
state: "available",
promptTokens,
totalTokens: promptTokens + (usage.output ?? 0)
} : { state: "unavailable" }
};
}
function shouldSuppressEmbeddedLiveStreamOutput(params) {
return params.opts.sessionEffects === "internal" && params.opts.deliver !== true;
}
function resolveProfileAuthFromStore(params) {
const profileId = params.profileId?.trim();
if (!profileId) return {};
const credential = ensureAuthProfileStore(params.agentDir, {
allowKeychainPrompt: false,
externalCliProfileIds: [profileId]
}).profiles[profileId];
return {
provider: credential?.provider,
mode: credential?.type
};
}
function resolveHarnessAuthProfileSelection(params) {
const sessionAuthProfileId = params.sessionAuthProfileId?.trim();
if (sessionAuthProfileId) {
const profileAuth = resolveProfileAuthFromStore({
agentDir: params.agentDir,
profileId: sessionAuthProfileId
});
return {
authProfileId: sessionAuthProfileId,
authProfileIdSource: params.sessionAuthProfileSource,
authProfileProvider: profileAuth.provider ?? params.authProfileProvider,
authProfileMode: profileAuth.mode
};
}
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 };
}
function resolveTranscriptUsage(usage) {
if (!usage) return ACP_TRANSCRIPT_USAGE;
const resolved = buildUsageWithNoCost({
input: usage.input,
output: usage.output,
cacheRead: usage.cacheRead,
cacheWrite: usage.cacheWrite,
totalTokens: usage.total
});
return usage.contextUsage ? {
...resolved,
contextUsage: usage.contextUsage
} : resolved;
}
async function persistTextTurnTranscript(params) {
const promptText = params.transcriptBody ?? params.body;
const replyText = params.skipAssistantTurn === true ? "" : params.finalText;
const userMessage = params.userMessage ?? await params.userTurnTranscriptRecorder?.resolveMessage() ?? (promptText ? {
role: "user",
content: promptText,
timestamp: Date.now()
} : void 0);
if (!userMessage && !replyText) return {
kind: "persisted",
sessionEntry: params.sessionEntry
};
const messages = [];
if (userMessage) messages.push({
message: userMessage,
idempotencyLookup: "scan",
prepareMessageAfterIdempotencyCheck: (message) => preparePersistedUserTurnMessageForTranscriptWrite(message, {
agentId: params.sessionAgentId,
sessionKey: params.sessionKey,
beforeMessageWrite: runAgentHarnessBeforeMessageWriteHook
})
});
if (replyText) {
const prepareAssistantTranscriptMessage = params.prepareAssistantTranscriptMessage;
messages.push({
idempotencyLookup: "scan-assistant",
message: {
role: "assistant",
...params.assistantIdempotencyKey ? { idempotencyKey: params.assistantIdempotencyKey } : {},
content: [{
type: "text",
text: replyText
}],
api: params.assistant.api,
provider: params.assistant.provider,
model: params.assistant.model,
usage: resolveTranscriptUsage(params.assistant.usage),
stopReason: params.assistant.stopReason,
timestamp: Date.now()
},
...prepareAssistantTranscriptMessage ? { prepareMessageAfterIdempotencyCheck: (message) => prepareAssistantTranscriptMessage(message, replyText) } : {}
});
}
const turn = await persistSessionTranscriptTurn({
sessionId: params.sessionId,
sessionKey: params.sessionKey,
sessionFile: params.sessionFile,
sessionEntry: params.sessionEntry,
sessionStore: params.sessionStore,
storePath: params.storePath,
agentId: params.sessionAgentId,
threadId: params.threadId
}, {
config: params.config,
cwd: params.sessionCwd,
messages,
publishWhen: "always",
touchSessionEntry: true,
updateMode: "file-only",
expectedSessionId: params.expectedSessionId ?? (params.sessionStore && params.storePath ? params.sessionId : void 0)
});
if (turn.rejectedReason === "session-rebound") return {
kind: "session-rebound",
sessionEntry: void 0
};
const persistedUser = turn.messages.find((entry) => asOptionalRecord(entry.message)?.role === "user");
if (persistedUser) params.userTurnTranscriptRecorder?.markRuntimePersisted(persistedUser.message, persistedUser.anchor, { appended: persistedUser.appended });
const assistantTranscript = turn.messages.find((entry) => asOptionalRecord(entry.message)?.role === "assistant");
return {
kind: "persisted",
sessionEntry: turn.sessionEntry,
...assistantTranscript ? { assistantTranscript } : {}
};
}
function resolveCliTranscriptReplyText(result) {
const visibleText = result.meta.finalAssistantVisibleText?.trim();
if (visibleText) return visibleText;
return (result.payloads ?? []).filter((payload) => !payload.isError && !payload.isReasoning).map((payload) => payload.text?.trim() ?? "").filter(Boolean).join("\n\n");
}
function isClaudeCliProvider(provider) {
return provider.trim().toLowerCase() === "claude-cli";
}
async function persistAcpTurnTranscript(params) {
const outcome = classifyAgentRunTerminalOutcome(params.terminalOutcome);
return await persistTextTurnTranscript({
...params,
...params.userInput ? { userMessage: buildPersistedUserTurnMessage(params.userInput) } : {},
assistant: {
api: "openai-responses",
provider: "openclaw",
model: "acp-runtime",
stopReason: outcome === "success" ? "stop" : outcome === "failure" ? "error" : "aborted"
}
});
}
async function persistCliTurnTranscript(params) {
const { result, skipUserTurn: requestedSkipUserTurn, ...transcript } = params;
const replyText = resolveCliTranscriptReplyText(result);
const provider = result.meta.agentMeta?.provider?.trim() ?? "cli";
const model = result.meta.agentMeta?.model?.trim() ?? "default";
const skipUserTurn = requestedSkipUserTurn === true;
return await persistTextTurnTranscript({
...transcript,
body: skipUserTurn ? "" : transcript.body,
transcriptBody: skipUserTurn ? void 0 : transcript.transcriptBody,
userMessage: skipUserTurn ? void 0 : transcript.userMessage,
finalText: replyText,
assistant: {
api: "cli",
provider,
model,
stopReason: "stop",
usage: resolveCliTranscriptUsage(result.meta.agentMeta?.lastCallUsage)
}
});
}
function runAgentAttempt(params) {
const onRuntimeActivity = (info) => {
if (info.phase === "assistant_output_started" || info.phase === "tool_execution_started") params.onAgentEvent({
stream: "lifecycle",
data: { phase: "start" }
});
};
const sessionAuthProfileId = params.sessionEntry?.authProfileOverride?.trim();
const sessionAuthProfileSource = resolveCollapsedSessionAuthPinSource(params.sessionEntry);
const selectedAuthProfile = sessionAuthProfileId && sessionAuthProfileSource !== "auto" ? {
id: sessionAuthProfileId,
source: sessionAuthProfileSource
} : params.configuredAuthProfileId?.trim() ? {
id: params.configuredAuthProfileId.trim(),
source: "user"
} : sessionAuthProfileId ? {
id: sessionAuthProfileId,
source: sessionAuthProfileSource
} : void 0;
const isRawModelRun = params.opts.modelRun === true || params.opts.promptMode === "none";
const isSubagentLane = params.opts.lane === AGENT_LANE_SUBAGENT;
const isSubagentAnnounceHandoff = isSubagentAnnounceCompletionHandoff({
inputProvenance: params.opts.inputProvenance,
internalEvents: params.opts.internalEvents
});
const trustedSubagentAnnounceHandoff = isSubagentAnnounceHandoff && 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 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 bootstrapPromptWarningSignature = bootstrapPromptWarningSignaturesSeen[bootstrapPromptWarningSignaturesSeen.length - 1];
const requestedAgentHarnessId = isRawModelRun ? "openclaw" : void 0;
const sessionRuntimeOverride = isRawModelRun ? void 0 : params.agentHarnessRuntimeOverride;
const pinnedHarnessId = isRawModelRun ? void 0 : resolveSessionPinnedHarnessId(params.sessionEntry);
const sessionCliRuntime = sessionRuntimeOverride && !(pinnedHarnessId !== void 0 && sessionRuntimeOverride === pinnedHarnessId) && isCliProvider(sessionRuntimeOverride, params.cfg) ? sessionRuntimeOverride : void 0;
const configuredCliRuntime = !isRawModelRun && !sessionRuntimeOverride ? resolveCliRuntimeExecutionProvider({
provider: params.providerOverride,
cfg: params.cfg,
agentId: params.sessionAgentId,
modelId: params.modelOverride,
authProfileId: selectedAuthProfile?.id
}) : void 0;
const cliExecutionProvider = isRawModelRun ? params.providerOverride : sessionCliRuntime ?? configuredCliRuntime ?? params.providerOverride;
const isCliExecutionProvider = sessionRuntimeOverride ? sessionCliRuntime !== void 0 : isCliProvider(cliExecutionProvider, params.cfg);
const completionRetainsRequesterTools = trustedSubagentAnnounceHandoff && !isRawModelRun && !isCliExecutionProvider && (!messageToolOwnsVisibleReply(params.opts) || completionNeedsMessageDelivery);
const runtimeToolsAllow = isSubagentAnnounceHandoff ? completionRetainsRequesterTools ? params.opts.toolsAllow : completionNeedsMessageDelivery ? ["message"] : void 0 : params.opts.toolsAllow;
const disableTools = params.opts.modelRun === true || isSubagentAnnounceHandoff && !completionRetainsRequesterTools && !completionNeedsMessageDelivery;
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 harnessAuthSelection = resolveHarnessAuthProfileSelection({
config: params.cfg,
agentDir: params.agentDir,
workspaceDir: params.workspaceDir,
provider: params.providerOverride,
authProfileProvider: params.authProfileProvider,
sessionAuthProfileId: selectedAuthProfile?.id,
sessionAuthProfileSource: selectedAuthProfile?.source,
harnessId: requestedAgentHarnessId,
harnessRuntime: agentHarnessPolicy.runtime,
...params.metadataSnapshot ? { metadataSnapshot: params.metadataSnapshot } : {},
providerAuthAliasesEnabled: params.pluginsEnabled,
allowHarnessAuthProfileForwarding: !isCliExecutionProvider
});
const runtimeAuthPlan = buildAgentRuntimeAuthPlan({
provider: params.providerOverride,
authProfileProvider: harnessAuthSelection.authProfileProvider,
authProfileMode: harnessAuthSelection.authProfileMode,
sessionAuthProfileId: harnessAuthSelection.authProfileId,
config: params.cfg,
workspaceDir: params.workspaceDir,
...params.metadataSnapshot ? { metadataSnapshot: params.metadataSnapshot } : {},
providerAuthAliasesEnabled: params.pluginsEnabled,
harnessId: requestedAgentHarnessId,
harnessRuntime: agentHarnessPolicy.runtime,
allowHarnessAuthProfileForwarding: !isCliExecutionProvider
});
const cliAuthProfileId = allowCliAuthProfileForwarding ? resolveCliExecutionAuthProfileId({
cliExecutionProvider,
authProfileProvider: params.authProfileProvider,
config: params.cfg,
agentDir: params.agentDir,
selected: harnessAuthSelection
}) : void 0;
const authProfileId = allowCliAuthProfileForwarding ? cliAuthProfileId : 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);
if (!isRawModelRun && isCliExecutionProvider) {
const expectedLifecycleRevision = params.sessionEntry?.lifecycleRevision;
return withLocalSessionPlacementTurnSettlement({
sessionId: params.sessionId,
sessionKey: params.sessionKey ?? params.sessionId,
agentId: params.sessionAgentId,
runId: params.runId
}, async (assertSettlementCurrent) => {
if (params.sessionKey && params.storePath) {
params.sessionEntry = loadSessionEntry({
sessionKey: params.sessionKey,
storePath: params.storePath,
readConsistency: "latest"
});
if (params.sessionEntry?.sessionId !== params.sessionId || params.sessionEntry.lifecycleRevision !== expectedLifecycleRevision) throw createAgentRunSupersededAbortError();
}
const diagnosticOwner = params.deferredLifecycle?.handoffToCli();
const cliSessionBinding = getCliSessionBinding(params.sessionEntry, cliExecutionProvider);
const cliProcessCwd = params.cwd ? resolveUserPath(params.cwd) : params.workspaceDir;
const cliContinuationBody = params.opts.execApprovalContinuationPromptRange ? resizeExecApprovalContinuationPrompt({
prompt: params.body,
range: params.opts.execApprovalContinuationPromptRange,
maxOutputUtf16Units: DEFAULT_MAX_LIVE_TOOL_RESULT_CHARS
}) : params.body;
const cliResolvedPrompt = params.opts.execApprovalContinuationPromptRange ? resolveFallbackRetryPrompt({
body: cliContinuationBody,
isFallbackRetry: params.isFallbackRetry,
sessionHasHistory: params.sessionHasHistory,
priorContextPrelude: claudeCliFallbackPrelude
}) : resolvedPrompt;
const cliEffectivePrompt = params.opts.execApprovalContinuationPromptRange ? annotateInterSessionPromptText(cliResolvedPrompt, params.opts.inputProvenance) : effectivePrompt;
const cliTranscriptPrompt = continuationTranscriptBody === void 0 || !continuationTranscriptPromptRange ? continuationTranscriptBody : resizeExecApprovalContinuationPrompt({
prompt: continuationTranscriptBody,
range: continuationTranscriptPromptRange,
maxOutputUtf16Units: DEFAULT_MAX_LIVE_TOOL_RESULT_CHARS
});
params.userTurnTranscriptRecorder?.replaceTextBeforePersistence?.(cliTranscriptPrompt ?? cliContinuationBody);
const cliPrompt = params.opts.inputProvenance?.kind === "inter_session" ? cliEffectivePrompt : injectTimestamp(cliEffectivePrompt, timestampOptsFromConfig(params.cfg));
const cliModelPrompt = appendGitCoauthorContext(cliPrompt, params.opts.gitCoauthorAttribution);
const cliPersistencePrompt = params.opts.gitCoauthorAttribution ? cliTranscriptPrompt ?? cliPrompt : cliTranscriptPrompt;
const mutableCliSessionStore = params.sessionKey && params.sessionStore && params.storePath ? {
sessionKey: params.sessionKey,
sessionStore: params.sessionStore,
storePath: params.storePath,
expectedSessionId: params.sessionId,
assertCommitAllowed: assertSettlementCurrent
} : void 0;
const resolveReusableCliSessionBinding = async () => {
const hasManagedClaudeLiveSession = Boolean(isClaudeCliProvider(cliExecutionProvider) && cliSessionBinding?.sessionId && hasCliLiveSession({
backendId: cliExecutionProvider,
agentAccountId: params.runContext.accountId,
agentId: params.sessionAgentId,
authProfileId: cliSessionBinding.authProfileId,
sessionId: params.sessionId,
sessionKey: params.sessionKey
}));
if (!isClaudeCliProvider(cliExecutionProvider) || !cliSessionBinding?.sessionId || hasManagedClaudeLiveSession || await claudeCliSessionTranscriptHasContent({
sessionId: cliSessionBinding.sessionId,
workspaceDir: cliProcessCwd
})) return cliSessionBinding;
log.warn(`cli session reset: provider=${sanitizeForLog(cliExecutionProvider)} reason=transcript-missing sessionKey=${params.sessionKey ?? params.sessionId}`);
if (mutableCliSessionStore) params.sessionEntry = await clearCliSessionInStore({
provider: cliExecutionProvider,
...mutableCliSessionStore
}) ?? params.sessionEntry;
return cliSessionBinding;
};
const mediaTaskIdsBefore = getGeneratedMediaTaskIdsForSessionKey(params.sessionKey);
const runCliWithSession = async (nextCliSessionId, activeCliSessionBinding = cliSessionBinding) => {
const forkCliSessionOnResume = activeCliSessionBinding?.forkNextResume === true;
const resolvedCliBackend = resolveCliBackendConfig(cliExecutionProvider, params.cfg, { agentId: params.sessionAgentId });
const supportsCliSessionFork = Boolean(resolvedCliBackend?.config.forkArg);
if (forkCliSessionOnResume && !supportsCliSessionFork) throw new Error(`CLI backend "${cliExecutionProvider}" does not support session forks`);
const forkStoreParams = supportsCliSessionFork && nextCliSessionId && mutableCliSessionStore ? {
provider: cliExecutionProvider,
expectedCliSessionId: nextCliSessionId,
...mutableCliSessionStore,
assertCommitAllowed: () => {
assertSettlementCurrent();
(params.deferredLifecycle?.signal ?? params.opts.abortSignal)?.throwIfAborted();
}
} : void 0;
return await runCliAgent({
preparedRunAdmission: params.preparedRunAdmission,
diagnosticOwner,
sessionId: params.sessionId,
sessionKey: params.sessionKey,
sessionTarget: params.sessionTarget,
sessionEntry: params.sessionEntry,
chatType: params.sessionEntry?.chatType,
contextWindow: params.sessionEntry?.contextWindow,
agentId: params.sessionAgentId,
trigger: "user",
sessionFile: params.sessionFile,
storePath: params.storePath,
persistAssistantTranscript: params.storePath !== void 0 && params.sessionStore !== void 0,
workspaceDir: params.workspaceDir,
cwd: params.cwd,
config: params.cfg,
prompt: cliModelPrompt,
transcriptPrompt: cliPersistencePrompt,
modelProvider: params.providerOverride,
modelHasVision: params.modelHasVision,
provider: cliExecutionProvider,
model: params.modelOverride,
modelRoutingProvenance: params.modelRoutingProvenance,
thinkLevel: params.resolvedThinkLevel,
timeoutMs: params.timeoutMs,
runTimeoutOverrideMs: params.runTimeoutOverrideMs,
runId: params.runId,
lifecycleGeneration: params.lifecycleGeneration,
abortSignal: params.deferredLifecycle?.signal ?? params.opts.abortSignal,
onExecutionStarted: params.opts.onExecutionStarted,
onExecutionPhase: onRuntimeActivity,
lane: params.opts.lane,
extraSystemPrompt: params.opts.extraSystemPrompt,
inputProvenance: params.opts.inputProvenance,
skillLibraryAuthoring: params.opts.skillLibraryAuthoring,
cronCreatorCallerOrigin: params.opts.cronCreatorAuthorityCapability?.callerOrigin,
sourceReplyDeliveryMode: params.opts.sourceReplyDeliveryMode,
requireExplicitMessageTarget: params.opts.requireExplicitMessageTarget ?? isSubagentSessionKey(params.sessionKey),
cliSessionBindingFacts: params.opts.cliSessionBindingFacts,
cliSessionId: nextCliSessionId,
cliSessionBinding: nextCliSessionId === activeCliSessionBinding?.sessionId ? activeCliSessionBinding : void 0,
forkCliSessionOnResume,
...forkStoreParams ? {
claimCliSessionFork: async () => {
const claimed = await consumeCliSessionForkInStore(forkStoreParams);
if (claimed) params.sessionEntry = claimed;
return Boolean(claimed);
},
restoreCliSessionFork: async () => {
const restored = await restoreCliSessionForkInStore(forkStoreParams);
if (restored) params.sessionEntry = restored;
},
persistCliSessionForkSuccessor: async (successorCliSessionId) => {
const persisted = await persistCliSessionForkSuccessorInStore({
...forkStoreParams,
successorCliSessionId
});
if (!persisted) throw new Error("CLI session fork successor could not be persisted");
params.sessionEntry = persisted;
}
} : {},
authProfileId,
bootstrapPromptWarningSignaturesSeen,
bootstrapPromptWarningSignature,
imagePrompt: params.body,
images: params.opts.images,
imageOrder: params.opts.imageOrder,
media: params.opts.media,
skillsSnapshot: params.skillsSnapshot,
messageChannel: params.messageChannel,
streamParams: params.opts.streamParams,
messageProvider: params.opts.messageProvider ?? params.messageChannel,
currentChannelId: params.runContext.currentChannelId ?? (completionNeedsMessageDelivery ? params.opts.replyTo ?? params.opts.to : void 0),
chatId: params.runContext.chatId,
channelContext: params.runContext.channelContext,
currentThreadTs: params.runContext.currentThreadTs,
currentInboundAudio: params.runContext.currentInboundAudio,
approvalReviewerDeviceId: params.opts.approvalReviewerDeviceId,
agentAccountId: params.runContext.accountId,
senderId: params.runContext.senderId,
senderIsOwner: params.opts.senderIsOwner,
bashElevated: params.opts.bashElevated,
groupId: params.runContext.groupId,
groupChannel: params.runContext.groupChannel,
groupSpace: params.runContext.groupSpace,
spawnedBy: params.spawnedBy,
toolsAllow: resolveCliRuntimeToolsAllow(runtimeToolsAllow, params.opts.toolsAllowIsDefault),
...buildCliMcpDelegationCapabilityBinding(resolveDelegationCapability({
fallbackActive: params.isFallbackRetry,
inputProvenance: params.opts.inputProvenance,
disableTools,
toolsAllow: runtimeToolsAllow
})),
scheduledToolPolicy: params.opts.scheduledToolPolicy,
cleanupBundleMcpOnRunEnd: params.opts.cleanupBundleMcpOnRunEnd,
cleanupCliLiveSessionOnRunEnd: params.opts.cleanupCliLiveSessionOnRunEnd,
oneShotCliRun: params.opts.oneShotCliRun,
userTurnTranscriptRecorder: params.userTurnTranscriptRecorder,
contextEngineLogicalTurnLease: params.contextEngineLogicalTurnLease,
onContextEngineTurnCandidate: params.onContextEngineTurnCandidate,
suppressNextUserMessagePersistence: params.suppressPromptPersistenceOnRetry === true,
disableTools,
allowEmptyAssistantReplyAsSilent: isSubagentLane || isSubagentAnnounceHandoff,
...forkStoreParams && !forkCliSessionOnResume ? { onBeforeForkedCliSessionRetry: async (retry) => {
if (hasNewGeneratedMediaTaskForSessionKey(params.sessionKey, mediaTaskIdsBefore) || retry.sessionId !== activeCliSessionBinding?.sessionId) return false;
log.warn(`CLI session stalled, arming forked recovery: provider=${sanitizeForLog(cliExecutionProvider)} sessionKey=${forkStoreParams.sessionKey}`);
const armed = await restoreCliSessionForkInStore(forkStoreParams);
if (armed) params.sessionEntry = armed;
return Boolean(armed);
} } : {},
...mutableCliSessionStore ? { onBeforeFreshCliSessionRetry: async (retry) => {
if (hasNewGeneratedMediaTaskForSessionKey(params.sessionKey, mediaTaskIdsBefore) || getCliSessionBinding(loadSessionEntry({
sessionKey: mutableCliSessionStore.sessionKey,
storePath: mutableCliSessionStore.storePath,
readConsistency: "latest"
}), 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)}`);
const cleared = await clearCliSessionInStore({
provider: cliExecutionProvider,
expectedCliSessionId: retry.sessionId,
...mutableCliSessionStore
});
if (!cleared) return false;
params.sessionEntry = cleared;
return true;
} } : {}
});
};
const activeCliSessionBinding = await resolveReusableCliSessionBinding();
let result;
try {
result = await runCliWithSession(activeCliSessionBinding?.sessionId, activeCliSessionBinding);
} catch (err) {
const failedCliSessionBinding = getCliSessionBinding(params.sessionEntry, cliExecutionProvider);
const failedCliSessionId = failedCliSessionBinding?.sessionId;
if (isClaudeCliProvider(cliExecutionProvider) && shouldClearFailedCliSessionBinding({
error: err,
binding: failedCliSessionBinding,
hasNewGeneratedMediaTask: hasNewGeneratedMediaTaskForSessionKey(params.sessionKey, mediaTaskIdsBefore)
}) && failedCliSessionId && mutableCliSessionStore) {
log.warn(`CLI session cleared after failed reused turn: provider=${sanitizeForLog(cliExecutionProvider)} sessionKey=${mutableCliSessionStore.sessionKey} reason=${sanitizeForLog(resolveCliSessionClearReason(err))}`);
params.sessionEntry = await clearCliSessionInStore({
provider: cliExecutionProvider,
expectedCliSessionId: failedCliSessionId,
...mutableCliSessionStore
}) ?? params.sessionEntry;
}
throw err;
}
const classification = params.classifyResult?.(result);
if (!params.preserveCliSessionBinding && (!classification || result.meta.agentMeta?.clearCliSessionBinding === true)) return await persistCliSessionBindingResult({
provider: cliExecutionProvider,
result,
sessionKey: params.sessionKey,
storePath: params.storePath,
sessionStore: params.sessionStore,
expectedSession: params.sessionEntry,
assertSettlementCurrent,
abortSignal: params.deferredLifecycle?.signal ?? params.opts.abortSignal
});
return result;
}, {
lifecycleGeneration: params.lifecycleGeneration,
abortSignal: params.deferredLifecycle?.signal ?? params.opts.abortSignal,
trigger: "user",
inputProvenance: params.opts.inputProvenance
});
}
const embeddedModelPrompt = appendGitCoauthorContext(effectivePrompt, params.opts.gitCoauthorAttribution);
const embeddedPersistencePrompt = params.opts.gitCoauthorAttribution ? continuationTranscriptBody ?? effectivePrompt : continuationTranscriptBody;
const embeddedRunParams = {
preparedRunAdmission: params.preparedRunAdmission,
sessionId: params.sessionId,
sessionKey: params.sessionKey,
chatType: params.sessionEntry?.chatType,
contextWindow: params.sessionEntry?.contextWindow,
sessionTarget: params.sessionTarget,
sandboxSessionKey: params.sessionKey,
agentId: params.sessionAgentId,
trigger: "user",
terminalReplyExpectation: isSubagentLane ? "optional" : void 0,
messageChannel: params.messageChannel,
messageProvider: params.opts.messageProvider ?? params.messageChannel,
agentAccountId: params.runContext.accountId,
messageTo: params.opts.replyTo ?? params.opts.to,
messageThreadId: params.opts.threadId,
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,
hasRepliedRef: params.runContext.hasRepliedRef,
senderId: params.runContext.senderId,
senderIsOwner: params.opts.senderIsOwner,
sessionFile: params.sessionFile,
workspaceDir: params.workspaceDir,
cwd: params.cwd,
permissionMode: params.sessionEntry?.permissionMode,
toolOverrides: params.sessionEntry?.toolOverrides,
sessionRoot: params.sessionEntry?.sessionRoot,
config: params.cfg,
...params.pluginGeneration ? { pluginGeneration: params.pluginGeneration } : {},
agentHarnessId: pinnedHarnessId,
modelSelectionLocked: !isRawModelRun && params.sessionEntry?.modelSelectionLocked === true,
agentHarnessRuntimeOverride: embeddedAgentHarnessOverride,
agentHarnessRuntimePreparationHint: agentHarnessPolicy.runtimeSource !== "implicit" ? agentHarnessPolicy.runtime : void 0,
skillsSnapshot: params.skillsSnapshot,
prompt: embeddedModelPrompt,
transcriptPrompt: embeddedPersistencePrompt,
images: shouldForwardImagesToEmbedded ? params.opts.images : void 0,
imageOrder: shouldForwardImagesToEmbedded ? params.opts.imageOrder : void 0,
media: params.opts.media,
clientTools: params.opts.clientTools,
provider: embeddedAgentProvider,
model: params.modelOverride,
modelRoutingProvenance: params.modelRoutingProvenance,
modelHasVision: params.modelHasVision,
modelThinkingCapability: params.modelThinkingCapability,
modelFallbacksOverride: params.modelFallbacksOverride,
authProfileId,
authProfileIdSource: authProfileId ? harnessAuthSelection.authProfileIdSource : void 0,
thinkLevel: params.resolvedThinkLevel,
fastMode: params.fastMode,
fastModeStartedAtMs: params.fastModeStartedAtMs,
fastModeAutoOnSeconds: params.fastModeAutoOnSeconds,
isFinalFallbackAttempt: params.isFinalFallbackAttempt,
verboseLevel: params.resolvedVerboseLevel,
bashElevated: params.opts.bashElevated,
execApprovalContinuationPromptRange: embeddedExecApprovalContinuationPromptRange,
execApprovalContinuationTranscriptPromptRange: continuationTranscriptPromptRange,
approvalReviewerDeviceId: params.opts.approvalReviewerDeviceId,
timeoutMs: params.timeoutMs,
runTimeoutOverrideMs: params.runTimeoutOverrideMs,
runId: params.runId,
lifecycleGeneration: params.lifecycleGeneration,
lane: params.opts.lane,
suppressLiveStreamOutput: shouldSuppressEmbeddedLiveStreamOutput(params),
abortSignal: params.opts.abortSignal,
extraSystemPrompt: params.opts.extraSystemPrompt,
bootstrapContextMode: params.opts.bootstrapContextMode,
bootstrapContextRunKind: params.opts.bootstrapContextRunKind,
toolsAllow: runtimeToolsAllow,
runtimePluginToolGrant: params.opts.runtimePluginToolGrant,
trustedInternalHandoff: trustedSubagentAnnounceHandoff ? params.opts.trustedInternalHandoff : void 0,
scheduledToolPolicy: params.opts.scheduledToolPolicy,
cronCreatorAuthorityCapability: params.opts.cronCreatorAuthorityCapability,
skillLibraryAuthoring: params.opts.skillLibraryAuthoring,
internalEvents: params.opts.internalEvents,
inputProvenance: params.opts.inputProvenance,
sourceReplyDeliveryMode: params.opts.sourceReplyDeliveryMode,
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,
streamParams: params.opts.streamParams,
agentDir: params.agentDir,
allowGatewaySubagentBinding: params.opts.allowGatewaySubagentBinding,
allowTransientCooldownProbe: params.allowTransientCooldownProbe,
cleanupBundleMcpOnRunEnd: params.opts.cleanupBundleMcpOnRunEnd,
oneShotCliRun: params.opts.oneShotCliRun,
modelRun: params.opts.modelRun,
promptMode: params.opts.promptMode,
disableTools,
allowEmptyAssistantReplyAsSilent: isSubagentLane || isSubagentAnnounceHandoff,
onAgentEvent: params.onAgentEvent,
onExecutionPhase: onRuntimeActivity,
deferTerminalLifecycle: params.deferTerminalLifecycle,
onDeferredLifecycleOwner: params.deferredLifecycle?.adopt,
onDeferredLifecycleAbort: params.deferredLifecycle?.abort,
suppressNextUserMessagePersistence: params.suppressPromptPersistenceOnRetry === true,
userTurnTranscriptRecorder: params.userTurnTranscriptRecorder,
contextEngineLogicalTurnLease: params.contextEngineLogicalTurnLease,
onContextEngineTurnCandidate: params.onContextEngineTurnCandidate,
onUserMessagePersisted: params.onUserMessagePersisted,
onCompactionAccounting: params.onCompactionAccounting,
onSuccessfulAuthProfile: params.onSuccessfulAuthProfile ? (successfulProfileId) => params.onSuccessfulAuthProfile?.({
authProfileId: successfulProfileId,
authProfileIdSource: successfulProfileId ? successfulProfileId === authProfileId ? harnessAuthSelection.authProfileIdSource : "auto" : void 0
}) : void 0,
onExecutionStarted: (info) => {
params.opts.onExecutionStarted?.();
if (info?.lifecycleGeneration) params.onLifecycleGenerationChanged?.(info.lifecycleGeneration);
},
onSessionIdChanged: params.opts.onSessionIdChanged,
bootstrapPromptWarningSignaturesSeen,
bootstrapPromptWarningSignature
};
setChannelSourceTurnId(embeddedRunParams, readChannelSourceTurnId(params.runContext));
setChannelSourceTurnSameThreadRequired(embeddedRunParams, readChannelSourceTurnSameThreadRequired(params.runContext));
return runEmbeddedAgent(embeddedRunParams);
}
function buildAcpResult(params) {
const normalizedFinalPayload = normalizeReplyPayload({ text: params.payloadText });
const payloads = normalizedFinalPayload ? [normalizedFinalPayload] : [];
const abortFields = resolveAgentRunAbortLifecycleFields(params.abortSignal);
const resultCancelled = params.resultStatus === "cancelled";
return {
payloads,
meta: {
durationMs: Date.now() - params.startedAt,
aborted: abortFields.aborted ?? resultCancelled,
stopReason: abortFields.stopReason ?? (resultCancelled ? "stop" : params.stopReason),
...params.terminalReply ? { terminalReply: params.terminalReply } : {}
}
};
}
function emitAcpLifecycleStart(params) {
(params.auditOnly ? emitAgentAuditEvent : emitAgentEvent)({
runId: params.runId,
...params.sessionKey ? { sessionKey: params.sessionKey } : {},
...params.agentId ? { agentId: params.agentId } : {},
...params.lifecycleGeneration ? { lifecycleGeneration: params.lifecycleGeneration } : {},
stream: "lifecycle",
data: {
phase: "start",
...params.completionSource ? { completionSource: params.completionSource } : {},
startedAt: params.startedAt
}
});
}
const ACP_PROXY_ENV_KEYS = [
"HTTP_PROXY",
"HTTPS_PROXY",
"ALL_PROXY",
"http_proxy",
"https_proxy",
"all_proxy"
];
const MAX_TRACKED_ACP_TOOLS = 4096;
function createAcpToolLifecycleTracker() {
return {
active: /* @__PURE__ */ new Map(),
terminalToolCallIds: /* @__PURE__ */ new Set(),
saturated: false
};
}
function acpAuditToolName(kind) {
switch (kind) {
case "read":
case "edit":
case "delete":
case "move":
case "search":
case "execute":
case "fetch":
case "switch_mode":
case "think":
case "other": return `acp_${kind}`;
default: return "acp_tool";
}
}
function resolveAcpToolTerminalReason(signal, stopReason, error, resultStatus) {
const abortFields = resolveAgentRunAbortLifecycleFields(signal);
if (abortFields.aborted) return abortFields.stopReason === "timeout" ? "timed_out" : "cancelled";
const normalizedStopReason = normalizeOptionalLowercaseString(stopReason);
if (normalizedStopReason === "timeout") return "timed_out";
if (resultStatus === "cancelled") return "cancelled";
if (error instanceof Error && error.detailCode === "TURN_TIMEOUT") return "timed_out";
if (normalizedStopReason === "cancel" || normalizedStopReason === "cancelled" || normalizedStopReason === "manual-cancel") return "cancelled";
return "failed";
}
function resolveAcpLifecycleEndFields(signal, stopReason, resultStatus) {
const abortFields = resolveAgentRunAbortLifecycleFields(signal);
if (abortFields.aborted) return abortFields;
const terminalReason = resolveAcpToolTerminalReason(void 0, stopReason, void 0, resultStatus);
if (terminalReason === "timed_out") return {
aborted: true,
stopReason: "timeout",
status: "timed_out"
};
if (terminalReason === "cancelled") return {
aborted: true,
stopReason: "stop",
status: "cancelled"
};
return {};
}
function emitAcpToolExecutionEvent(params) {
const { event } = params;
const now = Date.now();
const toolCallId = event.toolCallId?.trim() ? event.toolCallId : void 0;
const activeTool = toolCallId ? params.toolTracker.active.get(toolCallId) : void 0;
const terminalOutcome = resolveAcpToolTerminalOutcome(event.status);
const toolName = acpAuditToolName(event.kind);
if (toolCallId && !activeTool) {
if (params.toolTracker.terminalToolCallIds.has(toolCallId)) return;
const trackedIdentities = params.toolTracker.active.size + params.toolTracker.terminalToolCallIds.size;
if (params.toolTracker.saturated || trackedIdentities >= MAX_TRACKED_ACP_TOOLS) {
params.toolTracker.saturated = true;
return;
}
}
if (!activeTool && (toolCallId !== void 0 || toolCallId === void 0 && terminalOutcome !== void 0)) {
emitTrustedDiagnosticEvent({
type: "tool.execution.started",
runId: params.runId,
...params.sessionKey ? { sessionKey: params.sessionKey } : {},
...params.agentId ? { agentId: params.agentId } : {},
...toolCallId ? { toolCallId } : {},
toolName,
toolSource: "core",
toolOwner: "acp"
});
if (toolCallId) params.toolTracker.active.set(toolCallId, {
runId: params.runId,
...params.sessionKey ? { sessionKey: params.sessionKey } : {},
...params.agentId ? { agentId: params.agentId } : {},
toolCallId,
toolName,
startedAt: now
});
}
if (!terminalOutcome) return;
const terminalReason = resolveAcpToolTerminalReason(params.abortSignal, void 0, void 0, terminalOutcome === "cancelled" ? "cancelled" : void 0);
const durationMs = Math.max(0, now - (activeTool?.startedAt ?? now));
emitTrustedDiagnosticEvent(terminalOutcome === "completed" ? {
type: "tool.execution.completed",
runId: params.runId,
...params.sessionKey ? { sessionKey: params.sessionKey } : {},
...params.agentId ? { agentId: params.agentId } : {},
...toolCallId ? { toolCallId } : {},
toolName: activeTool?.toolName ?? toolName,
toolSource: "core",
toolOwner: "acp",
durationMs
} : {
type: "tool.execution.error",
runId: params.runId,
...params.sessionKey ? { sessionKey: params.sessionKey } : {},
...params.agentId ? { agentId: params.agentId } : {},
...toolCallId ? { toolCallId } : {},
toolName: activeTool?.toolName ?? toolName,
toolSource: "core",
toolOwner: "acp",
durationMs,
errorCategory: terminalReason === "cancelled" ? "aborted" : "acp_tool",
terminalReason
});
if (toolCallId) {
params.toolTracker.active.delete(toolCallId);
params.toolTracker.terminalToolCallIds.add(toolCallId);
}
}
function finalizeAcpToolsForRun(toolTracker, runId, terminalReason) {
const now = Date.now();
for (const activeTool of toolTracker.active.values()) emitTrustedDiagnosticEvent({
type: "tool.execution.error",
runId,
...activeTool.sessionKey ? { sessionKey: activeTool.sessionKey } : {},
...activeTool.agentId ? { agentId: activeTool.agentId } : {},
toolName: activeTool.toolName,
toolSource: "core",
toolOwner: "acp",
toolCallId: activeTool.toolCallId,
durationMs: Math.max(0, now - activeTool.startedAt),
errorCategory: terminalReason === "cancelled" ? "aborted" : "acp_tool_incomplete",
terminalReason
});
toolTracker.active.clear();
toolTracker.terminalToolCallIds.clear();
toolTracker.saturated = false;
}
function resolvePresentProxyEnvKeys(env = process.env) {
return ACP_PROXY_ENV_KEYS.filter((key) => {
const value = env[key];
return typeof value === "string" && value.trim().length > 0;
});
}
function sanitizeAcpDiagnosticText(value) {
return truncateUtf16Safe(redactSensitiveText(value).replace(/\s+/g, " ").trim(), 240);
}
function acpRuntimeEventDiagnostics(event) {
if (event.type === "status") return {
eventType: event.type,
text: sanitizeAcpDiagnosticText(event.text),
...event.tag ? { tag: event.tag } : {}
};
if (event.type === "tool_call") return {
eventType: event.type,
text: sanitizeAcpDiagnosticText(event.text),
...event.tag ? { tag: event.tag } : {},
...event.status ? { status: sanitizeAcpDiagnosticText(event.status) } : {},
...event.title ? { title: sanitizeAcpDiagnosticText(event.title) } : {},
...event.toolCallId ? { toolCallId: sanitizeAcpDiagnosticText(event.toolCallId) } : {}
};
if (event.type === "error") return {
eventType: event.type,
message: sanitizeAcpDiagnosticText(event.message),
...event.code ? { code: sanitizeAcpDiagnosticText(event.code) } : {},
...typeof event.retryable === "boolean" ? { retryable: event.retryable } : {}
};
if (event.type === "done") return {
eventType: event.type,
...event.status ? { status: event.status } : {},
...event.stopReason ? { stopReason: sanitizeAcpDiagnosticText(event.stopReason) } : {}
};
return {
eventType: event.type,
stream: event.stream ?? "output"
};
}
function emitAcpPromptSubmitted(params) {
emitAgentEvent({
runId: params.runId,
stream: "acp",
...params.sessionKey ? { sessionKey: params.sessionKey } : {},
data: {
phase: "prompt_submitted",
at: params.at,
proxyEnvKeys: resolvePresentProxyEnvKeys()
}
});
}
function emitAcpRuntimeEvent(params) {
if (params.event.type === "tool_call") emitAcpToolExecutionEvent({
runId: params.runId,
toolTracker: params.toolTracker,
...params.sessionKey ? { sessionKey: params.sessionKey } : {},
...params.agentId ? { agentId: params.agentId } : {},
...params.abortSignal ? { abortSignal: params.abortSignal } : {},
event: params.event
});
if (!params.auditOnly) emitAgentEvent({
runId: params.runId,
stream: "acp",
...params.sessionKey ? { sessionKey: params.sessionKey } : {},
...params.agentId ? { agentId: params.agentId } : {},
data: {
phase: "runtime_event",
...acpRuntimeEventDiagnostics(params.event)
}
});
}
function emitAcpTerminalLifecycle(params, terminal) {
const data = {
...terminal,
executionSettled: true,
...params.completionSource ? { completionSource: params.completionSource } : {}
};
(params.auditOnly ? emitAgentAuditEvent : emitAgentEvent)({
runId: params.runId,
...params.sessionKey ? { sessionKey: params.sessionKey } : {},
...params.agentId ? { agentId: params.agentId } : {},
...params.lifecycleGeneration ? { lifecycleGeneration: params.lifecycleGeneration } : {},
stream: "lifecycle",
data
});
return buildAgentRunTerminalOutcomeFromLifecycleEvent({
phase: terminal.phase,
data,
endedAt: terminal.endedAt
});
}
function emitAcpLifecycleEnd(params) {
finalizeAcpToolsForRun(params.toolTracker, params.runId, params.endFields.stopReason === "timeout" ? "timed_out" : params.endFields.aborted ? "cancelled" : "failed");
return emitAcpTerminalLifecycle(params, {
phase: "end",
endedAt: Date.now(),
...params.endFields,
...params.terminalReply ? { terminalReply: params.terminalReply } : {}
});
}
function emitAcpLifecycleError(params) {
const terminalReason = resolveAcpToolTerminalReason(params.abortSignal, void 0, params.error);
finalizeAcpToolsForRun(params.toolTracker, params.runId, terminalReason);
const lifecycleFields = params.terminalOutcome === "blocked" ? { livenessState: "blocked" } : terminalReason === "timed_out" ? {
aborted: true,
stopReason: "timeout",
status: "timed_out"
} : resolveAgentRunAbortLifecycleFields(params.abortSignal);
return emitAcpTerminalLifecycle(params, {
phase: "error",
...!params.auditOnly ? { error: formatAcpErrorChain(params.error) } : {},
endedAt: Date.now(),
...lifecycleFields
});
}
function emitAcpAssistantDelta(params) {
emitAgentEvent({
runId: params.runId,
stream: "assistant",
data: {
text: params.text,
delta: params.delta
}
});
}
//#endregion
export { emitAcpLifecycleError as a, emitAcpRuntimeEvent as c, resolveAcpLifecycleEndFields as d, resolveCliTranscriptReplyText as f, emitAcpLifecycleEnd as i, persistAcpTurnTranscript as l, createAcpToolLifecycleTracker as n, emitAcpLifecycleStart as o, runAgentAttempt as p, emitAcpAssistantDelta as r, emitAcpPromptSubmitted as s, buildAcpResult as t, persistCliTurnTranscript as u };