openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
609 lines (608 loc) • 28.2 kB
JavaScript
import { c as resolveUserPath } from "./home-dir-BPhrG-aM.js";
import "./utils-P__uGsPB.js";
import { u as resolveAgentDir } from "./agent-scope-config-DcbEhP0R.js";
import { O as parseAgentSessionKey, f as resolveAgentIdFromSessionKey } from "./session-key-BnWWjqNc.js";
import { t as createSubsystemLogger } from "./subsystem-Dy2tqXOS.js";
import { a as normalizeOptionalAgentRuntimeId, r as isDefaultAgentRuntimeId } from "./agent-runtime-id-BpfvnoN1.js";
import { y as resolveSessionAgentIds } from "./agent-scope-DbtJyKUL.js";
import { i as isOpenAIProvider } from "./openai-routing-Ex_3E9TF.js";
import { r as logVerbose } from "./globals-CTaGxEqj.js";
import { x as runWithGatewayIndependentRootWorkContinuation } from "./gateway-work-admission-R1IpuDim.js";
import { t as resolveAgentHarnessPolicy } from "./policy-D9i1QMuw.js";
import { t as getGlobalHookRunner } from "./hook-runner-global-0kfmMG4T.js";
import { t as SessionTranscriptWriterClaimReboundError } from "./transcript-write-context-mhuh2Sos.js";
import { a as ensureAuthProfileStoreWithoutExternalProfiles, r as ensureAuthProfileStore } from "./store-F1B2duCT.js";
import { o as resolveCodexAgentHarnessNativeCompaction } from "./registry-D1_C7waJ.js";
import { a as unwrapSecretSentinelsForProviderEgress, i as unwrapModelHeaderSentinelsForProviderEgress } from "./provider-secret-egress-C-JiHB7J.js";
import "./session-accessor-YsytfDtG.js";
import { E as resolveSessionStorePathForScope, a as listSessionEntriesReadOnly, d as patchSessionEntryCore, l as loadSessionEntry, u as loadSessionEntryReadOnly } from "./session-accessor.sqlite-entry-CWk3jL7s.js";
import { n as parseSqliteSessionFileMarker, t as formatSqliteSessionFileMarker } from "./legacy-sqlite-marker-COPKCuIN.js";
import { a as projectPreparedModelProvider } from "./availability-DrQ2OOVX.js";
import { a as isCliRuntimeProvider, i as isCliRuntimeAliasForProvider } from "./model-runtime-aliases-BJ2qM8I_.js";
import { r as applySecretRefHeaderSentinels } from "./model-auth-C48_DZ-I.js";
import { t as resolvePreferredSessionKeyForSessionIdMatches } from "./session-id-resolution-BbcM7Och.js";
import { t as log$1 } from "./logger-C3TD2wdV.js";
import { r as prepareAgentRuntimeAuth, t as agentRuntimeAuthPlanMatchesTarget } from "./prepare-auth-Ci9igqt8.js";
import { s as resolveStableSessionEndTranscript } from "./session-transcript-files.fs-D0B5TSty.js";
import { n as resolveModelAsync } from "./model-qCT5QXYI.js";
import { n as resolveAgentRunSessionTarget } from "./run-session-target-Ckn1JYI3.js";
import { t as materializePreparedRuntimeModel } from "./materialize-model-DTezazoG.js";
import { c as selectAgentHarness, l as selectAgentHarnessForPreparedModelProviders, r as resolveAgentHarnessNativeToolPolicyRestricted } from "./selection-CgLPGlZh.js";
import { a as buildSessionStartHookPayload, i as buildSessionEndHookPayload, r as noteActiveSessionForShutdown, t as forgetActiveSessionForShutdown } from "./active-sessions-shutdown-tracker-NctYi_BN.js";
import { n as resolvePreparedRuntimeModelAuth, t as resolvePreparedRuntimeAuthAttempts } from "./resolve-auth-DN46qixj.js";
import { t as captureSessionPlacementCompactionSuccessorAssertion } from "./session-placement-admission-UsKSuaws.js";
import path from "node:path";
//#region src/agents/harness/compaction-recovery.ts
/** Returns whether a native harness failure reason indicates a recoverable binding issue. */
function isRecoverableNativeHarnessBindingReason(reason) {
if (typeof reason !== "string") return false;
const normalized = reason.trim().toLowerCase();
return normalized === "missing_thread_binding" || normalized === "stale_thread_binding" || normalized.includes("thread not found") || normalized.includes("no thread binding");
}
/** Returns whether a compact result failed due to a recoverable native binding issue. */
function isRecoverableNativeHarnessBindingFailure(result) {
return result?.ok === false && (isRecoverableNativeHarnessBindingReason(result.failure?.reason) || isRecoverableNativeHarnessBindingReason(result.reason));
}
//#endregion
//#region src/agents/harness/compaction.ts
/**
* Routes compaction through selected native agent harnesses when supported.
*/
const log = createSubsystemLogger("agents/harness-compaction");
function runtimePlanRequiresHostApiKey(plan) {
return plan?.modelRoute?.authRequirement === "api-key";
}
function resolveHarnessCompactIdentity(params) {
const agentIds = resolveSessionAgentIds({
sessionKey: params.sessionKey,
config: params.config,
agentId: params.agentId
});
return {
agentDir: params.agentDir ?? resolveAgentDir(params.config ?? {}, agentIds.sessionAgentId),
agentId: params.agentId ?? agentIds.sessionAgentId
};
}
function stripHarnessOwnedAuthInputs(params) {
const result = { ...params };
delete result.resolvedApiKey;
delete result.runtimeModel;
return result;
}
async function resolveHarnessCompactApiKey(params) {
const { agentDir, compactParams, initialHarness } = params;
if (!compactParams.provider?.trim() || !compactParams.model?.trim()) {
const existing = compactParams.resolvedApiKey?.trim();
return existing ? {
harness: initialHarness,
apiKey: existing
} : { harness: initialHarness };
}
const provider = compactParams.provider;
const modelId = compactParams.model;
const providedRuntimeAuthPlan = compactParams.runtimeAuthPlan ?? compactParams.runtimePlan?.auth;
const reusableRuntimeAuthPlan = providedRuntimeAuthPlan && agentRuntimeAuthPlanMatchesTarget(providedRuntimeAuthPlan, {
provider,
modelId
}) ? providedRuntimeAuthPlan : void 0;
const workspaceDir = resolveUserPath(compactParams.workspaceDir);
const preparedStores = params.preparedModelRuntime.createStores();
const callerRuntimeModel = compactParams.runtimeModel;
const fallbackResolution = (harness, runtimeModel, runtimeAuthPlan) => {
const apiKey = compactParams.resolvedApiKey?.trim() || void 0;
if (harness.authBootstrap === "harness" && !runtimeAuthPlan && apiKey) throw new Error(`Unable to prepare a route-locked native compaction attempt for ${provider}/${modelId}; refusing harness-owned ambient auth.`);
return {
harness,
...apiKey ? { apiKey } : {},
...runtimeModel ? { runtimeModel } : {},
...runtimeAuthPlan ? { runtimeAuthPlan } : {}
};
};
const selectPreparedHarness = (attempts, preparedModel) => selectAgentHarnessForPreparedModelProviders({
provider,
modelId,
modelProviders: attempts.map((attempt) => projectPreparedModelProvider({
model: preparedModel,
plan: attempt.plan,
attemptKind: attempt.kind
})),
config: compactParams.config,
agentId: parseAgentSessionKey(params.sessionKey) ? void 0 : params.agentId,
sessionKey: params.sessionKey,
agentHarnessId: params.pinnedHarnessId
});
if (reusableRuntimeAuthPlan) {
const reusableHarness = selectPreparedHarness([{
kind: "implicit",
plan: reusableRuntimeAuthPlan
}], callerRuntimeModel);
if ((reusableHarness.authBootstrap === "harness" || reusableRuntimeAuthPlan.harnessAuthProvider) && !runtimePlanRequiresHostApiKey(reusableRuntimeAuthPlan)) return fallbackResolution(reusableHarness, callerRuntimeModel, reusableRuntimeAuthPlan);
}
const resolvePreparedModel = ({ config, authProfileId: profileId, authProfileMode }) => resolveModelAsync(provider, modelId, agentDir, config, {
...preparedStores,
preparedModelRuntime: params.preparedModelRuntime,
authProfileId: profileId,
authProfileMode,
skipAgentDiscovery: true,
allowBundledStaticCatalogFallback: true,
preferBundledStaticCatalogTransport: true,
workspaceDir
});
let model = callerRuntimeModel;
if (!model) try {
model = (await resolveModelAsync(provider, modelId, agentDir, compactParams.config, {
...preparedStores,
preparedModelRuntime: params.preparedModelRuntime,
authProfileId: reusableRuntimeAuthPlan?.forwardedAuthProfileId ?? compactParams.authProfileId?.trim() ?? void 0,
workspaceDir
})).model;
} catch (error) {
log.warn(`native compaction model resolution failed for ${provider}/${modelId}: ${error instanceof Error ? error.message : String(error)}`);
return fallbackResolution(initialHarness);
}
if (!model) return fallbackResolution(initialHarness);
const runtimeAuthProfileStore = isOpenAIProvider(provider) ? ensureAuthProfileStore(agentDir, {
profileId: compactParams.authProfileId ?? reusableRuntimeAuthPlan?.forwardedAuthProfileId,
externalCliProviderIds: ["openai"],
allowKeychainPrompt: false
}) : ensureAuthProfileStoreWithoutExternalProfiles(agentDir, {
profileId: compactParams.authProfileId ?? reusableRuntimeAuthPlan?.forwardedAuthProfileId,
allowKeychainPrompt: false
});
const prepareRuntimeAuth = (harness) => prepareAgentRuntimeAuth({
provider,
modelId,
modelApi: model.api,
modelBaseUrl: model.baseUrl,
config: compactParams.config,
env: process.env,
agentDir,
workspaceDir,
authProfileStore: runtimeAuthProfileStore,
sessionAuthProfileId: compactParams.authProfileId,
sessionAuthProfileSource: compactParams.authProfileIdSource,
harnessId: harness.id,
harnessRuntime: harness.id,
harnessAuthBootstrap: harness.authBootstrap
});
let preparation;
if (reusableRuntimeAuthPlan) preparation = {
plan: reusableRuntimeAuthPlan,
attempts: [{
kind: "implicit",
plan: reusableRuntimeAuthPlan
}]
};
else try {
preparation = prepareRuntimeAuth(initialHarness);
} catch (error) {
log.warn(`native compaction auth preparation failed for ${provider}/${modelId}: ${error instanceof Error ? error.message : String(error)}`);
return fallbackResolution(initialHarness, model);
}
let harness = params.pinnedHarnessId ? initialHarness : selectPreparedHarness(preparation.attempts, model);
if (!params.pinnedHarnessId && !reusableRuntimeAuthPlan && harness.id !== initialHarness.id) {
try {
preparation = prepareRuntimeAuth(harness);
} catch (error) {
log.warn(`native compaction auth preparation failed for ${provider}/${modelId}: ${error instanceof Error ? error.message : String(error)}`);
return fallbackResolution(harness, model);
}
const confirmedHarness = selectPreparedHarness(preparation.attempts, model);
if (confirmedHarness.id !== harness.id) throw new Error(`Prepared native compaction auth routes did not converge on one agent harness for ${provider}/${modelId}.`);
harness = confirmedHarness;
}
const materializeModel = async (input) => {
const materialized = await materializePreparedRuntimeModel({
plan: input.plan,
provider,
modelId,
config: compactParams.config,
model: input.model,
forceResolve: input.forceResolve,
rejectMismatchedModel: true,
resolveModel: resolvePreparedModel
});
if (!materialized) throw new Error(`Unable to materialize ${provider}/${modelId} for native compaction.`);
return applySecretRefHeaderSentinels(materialized, compactParams.config);
};
let resolved;
try {
resolved = await resolvePreparedRuntimeAuthAttempts({
attempts: preparation.attempts,
store: runtimeAuthProfileStore,
modelId,
model,
materializeModel,
resolveAuth: async ({ attempt, model: attemptModel }) => {
if ((harness.authBootstrap === "harness" || attempt.plan.harnessAuthProvider) && !runtimePlanRequiresHostApiKey(attempt.plan)) return {
plan: attempt.plan,
auth: {}
};
const existing = attempt.plan.forwardedAuthProfileSource === "auto" && Boolean(attempt.plan.forwardedAuthProfileId || attempt.plan.forwardedAuthProfileCandidateIds?.length) ? void 0 : compactParams.resolvedApiKey?.trim();
if (existing) return {
plan: attempt.plan,
auth: { apiKey: existing }
};
const auth = await resolvePreparedRuntimeModelAuth({
plan: attempt.plan,
model: attemptModel,
cfg: compactParams.config,
store: runtimeAuthProfileStore,
agentDir,
workspaceDir,
...attempt.allowAuthProfileFallback !== void 0 ? { allowAuthProfileFallback: attempt.allowAuthProfileFallback } : {},
secretSentinels: true
});
return {
plan: auth.plan,
auth: { apiKey: auth.auth.apiKey?.trim() || void 0 }
};
},
errorMessage: `Prepared native compaction auth attempts could not be resolved for ${provider}/${modelId}.`
});
} catch (error) {
log.warn(`native compaction prepared auth resolution failed for ${provider}/${modelId}: ${error instanceof Error ? error.message : String(error)}`);
return fallbackResolution(harness, model, preparation.plan);
}
return {
harness,
apiKey: resolved.auth.apiKey,
runtimeModel: resolved.model,
runtimeAuthPlan: resolved.plan
};
}
/** Runs harness-provided compaction when the selected runtime supports it. */
async function maybeCompactAgentHarnessSession(params, options) {
const selectedRuntime = normalizeOptionalAgentRuntimeId(params.agentHarnessId);
const pinnedHarnessId = selectedRuntime && !isDefaultAgentRuntimeId(selectedRuntime) ? selectedRuntime : void 0;
if (!pinnedHarnessId && params.provider && isCliRuntimeProvider(params.provider, { config: params.config })) return;
const runtimePolicySessionKey = params.sandboxSessionKey ?? params.sessionKey;
const runtimePolicyAgentId = params.sandboxAgentId ?? (params.sandboxSessionKey && parseAgentSessionKey(params.sandboxSessionKey) ? void 0 : params.agentId);
const runtimeAuthPlan = params.runtimeAuthPlan ?? params.runtimePlan?.auth;
const modelRoute = runtimeAuthPlan?.modelRoute;
if (runtimeAuthPlan && modelRoute && (!params.provider || !params.model || !agentRuntimeAuthPlanMatchesTarget(runtimeAuthPlan, {
provider: params.provider,
modelId: params.model ?? ""
}))) throw new Error(`Prepared runtime auth route ${modelRoute.provider}/${modelRoute.modelId} does not match the compaction target ${params.provider ?? "unknown"}/${params.model ?? "unknown"}.`);
const runtime = resolveAgentHarnessPolicy({
provider: params.provider,
modelId: params.model,
config: params.config,
agentId: runtimePolicyAgentId,
sessionKey: runtimePolicySessionKey
}).runtime;
if (isCliRuntimeAliasForProvider({
runtime: pinnedHarnessId ?? runtime,
provider: params.provider,
cfg: params.config
})) return;
const harnessSelectionParams = {
provider: params.provider ?? "",
modelId: params.model,
config: params.config,
agentId: runtimePolicyAgentId,
sessionKey: runtimePolicySessionKey,
agentHarnessId: pinnedHarnessId
};
let harness = runtimeAuthPlan ? selectAgentHarnessForPreparedModelProviders({
...harnessSelectionParams,
modelProviders: [projectPreparedModelProvider({
model: params.runtimeModel,
plan: runtimeAuthPlan
})]
}) : selectAgentHarness(harnessSelectionParams);
const initialNativeCompaction = resolveCodexAgentHarnessNativeCompaction(harness);
if (options.nativeCompactionRequest === "after_context_engine" && !initialNativeCompaction) return;
if (!options.nativeCompactionRequest && !harness.compact) {
if (harness.id !== "openclaw") return {
ok: false,
compacted: false,
reason: `Agent harness "${harness.id}" does not support compaction.`,
failure: { reason: "unsupported_harness_compaction" }
};
return;
}
const compactIdentity = resolveHarnessCompactIdentity(params);
let resolvedRuntimeAuthPlan = runtimeAuthPlan;
const resolveNativeToolPolicyRestricted = (targetHarness) => resolveAgentHarnessNativeToolPolicyRestricted({
...params,
agentId: compactIdentity.agentId,
provider: params.provider ?? "",
modelId: params.model ?? ""
}, targetHarness);
const compactParams = {
...params,
agentDir: compactIdentity.agentDir,
agentId: compactIdentity.agentId,
...resolvedRuntimeAuthPlan ? {
runtimeAuthPlan: resolvedRuntimeAuthPlan,
...params.runtimePlan ? { runtimePlan: {
...params.runtimePlan,
auth: resolvedRuntimeAuthPlan
} } : {}
} : {}
};
const resolved = await resolveHarnessCompactApiKey({
agentDir: compactIdentity.agentDir,
compactParams,
initialHarness: harness,
agentId: compactIdentity.agentId,
sessionKey: runtimePolicySessionKey,
pinnedHarnessId,
preparedModelRuntime: options.preparedModelRuntime
});
harness = resolved.harness;
const nativeToolPolicyRestricted = resolveNativeToolPolicyRestricted(harness);
compactParams.nativeToolSurface = nativeToolPolicyRestricted ? "host-isolated" : "unrestricted";
resolvedRuntimeAuthPlan = resolved.runtimeAuthPlan ?? resolvedRuntimeAuthPlan;
const nativeCompaction = resolveCodexAgentHarnessNativeCompaction(harness);
if (options.nativeCompactionRequest === "after_context_engine" && !nativeCompaction) return;
if (!options.nativeCompactionRequest && !harness.compact) {
if (harness.id !== "openclaw") return {
ok: false,
compacted: false,
reason: `Agent harness "${harness.id}" does not support compaction.`,
failure: { reason: "unsupported_harness_compaction" }
};
return;
}
if (nativeToolPolicyRestricted && harness.id !== "openclaw" && harness.conversationToolPolicySupport !== "exact") throw new Error(`Agent harness ${harness.id} cannot enforce the host-isolated tool policy required for compaction`);
const harnessOwnsAuth = harness.authBootstrap === "harness" && !runtimePlanRequiresHostApiKey(resolvedRuntimeAuthPlan);
const resolvedApiKey = harnessOwnsAuth ? void 0 : resolved.apiKey;
const runtimeModel = harnessOwnsAuth && !resolvedRuntimeAuthPlan ? void 0 : resolved.runtimeModel;
const compactParamsWithResolvedAuth = resolvedRuntimeAuthPlan ? {
...compactParams,
authProfileId: resolvedRuntimeAuthPlan.forwardedAuthProfileId,
authProfileIdSource: resolvedRuntimeAuthPlan.forwardedAuthProfileSource,
runtimeAuthPlan: resolvedRuntimeAuthPlan,
...compactParams.runtimePlan ? { runtimePlan: {
...compactParams.runtimePlan,
auth: resolvedRuntimeAuthPlan
} } : {}
} : compactParams;
const handoffCompactParams = harnessOwnsAuth ? stripHarnessOwnedAuthInputs(compactParamsWithResolvedAuth) : compactParamsWithResolvedAuth;
const resolvedCompactParams = resolvedApiKey || runtimeModel ? {
...handoffCompactParams,
...resolvedApiKey ? { resolvedApiKey: unwrapSecretSentinelsForProviderEgress(resolvedApiKey, "plugin harness compaction handoff") } : {},
...runtimeModel ? { runtimeModel: unwrapModelHeaderSentinelsForProviderEgress(runtimeModel, "plugin harness compaction handoff") } : {}
} : handoffCompactParams;
if (options.nativeCompactionRequest) {
if (nativeCompaction) {
options.onNativeCompactionCapabilityUsed?.();
return nativeCompaction({
...resolvedCompactParams,
nativeCompactionRequest: options.nativeCompactionRequest
});
}
if (!harness.compact) return;
}
return harness.compact?.(resolvedCompactParams);
}
//#endregion
//#region src/agents/embedded-agent-runner/compaction-successor.ts
/** Resolve a context engine's successor without letting it cross the active store binding. */
async function resolveContextEngineCompactionSuccessor(params) {
const current = params.currentTarget;
const result = params.result.result;
const target = result?.sessionTarget;
const successorId = target?.sessionId ?? result?.sessionId;
const successorFile = result?.sessionFile;
if (target) {
if (result?.sessionId && target.sessionId && target.sessionId !== result.sessionId) throw new Error("Context-engine successor identity is inconsistent");
const resolvedTarget = await resolveAgentRunSessionTarget({
agentId: target.agentId ?? current.agentId,
config: params.config,
missingSessionKey: "resolve-existing",
sessionId: target.sessionId ?? successorId ?? current.sessionId,
sessionFile: successorFile,
sessionKey: target.sessionKey ?? current.sessionKey,
sessionTarget: {
...target,
storePath: target.storePath ?? current.storePath
}
});
assertSameSessionBinding(current, resolvedTarget, "Context-engine");
return {
sessionId: resolvedTarget.sessionId,
sessionFile: resolvedTarget.sessionKey,
sessionTarget: {
...resolvedTarget,
...target.threadId !== void 0 ? { threadId: target.threadId } : {}
}
};
}
if (successorFile) {
const marker = parseSqliteSessionFileMarker(successorFile);
if (marker && (marker.agentId !== current.agentId || successorId && marker.sessionId !== successorId)) throw new Error("Legacy context-engine successor identity is inconsistent");
const isSessionKey = successorFile.startsWith("agent:");
const keyedEntry = isSessionKey ? loadSessionEntryReadOnly({
agentId: current.agentId,
sessionKey: successorFile,
storePath: current.storePath
}) : void 0;
if (isSessionKey && (resolveAgentIdFromSessionKey(successorFile) !== current.agentId || !keyedEntry?.sessionId || successorId && keyedEntry.sessionId !== successorId)) throw new Error("Legacy context-engine successor identity is inconsistent");
const keyedSessionId = isSessionKey ? successorId ?? keyedEntry?.sessionId : void 0;
const retainedMarkerEntry = marker ? loadSessionEntryReadOnly({
agentId: marker.agentId,
sessionKey: current.sessionKey,
storePath: marker.storePath
}) : void 0;
const markerMatches = marker ? listSessionEntriesReadOnly({
agentId: marker.agentId,
storePath: marker.storePath
}).filter(({ entry }) => entry.sessionId === marker.sessionId) : [];
const preferredMarkerSessionKey = marker ? resolvePreferredSessionKeyForSessionIdMatches(markerMatches.map(({ sessionKey, entry }) => [sessionKey, entry]), marker.sessionId) : void 0;
const markerMappedToRetainedKey = markerMatches.some(({ sessionKey }) => sessionKey === current.sessionKey);
const markerSessionKey = marker ? retainedMarkerEntry?.sessionId === marker.sessionId || retainedMarkerEntry?.sessionId === current.sessionId && (markerMatches.length === 0 || markerMappedToRetainedKey) ? current.sessionKey : preferredMarkerSessionKey ?? (markerMatches.length === 0 && !retainedMarkerEntry ? current.sessionKey : void 0) : void 0;
const legacyTarget = marker ? markerSessionKey ? {
...marker,
sessionId: marker.sessionId,
sessionKey: markerSessionKey
} : void 0 : keyedSessionId ? {
...current,
sessionId: keyedSessionId,
sessionKey: successorFile
} : void 0;
if (!legacyTarget) throw new Error("Legacy context-engine successor files are unsupported; return a structured sessionTarget");
const resolvedTarget = await resolveAgentRunSessionTarget({
agentId: legacyTarget.agentId,
config: params.config,
missingSessionKey: "resolve-existing",
sessionId: legacyTarget.sessionId,
sessionKey: legacyTarget.sessionKey,
sessionTarget: legacyTarget
});
assertSameSessionBinding(current, resolvedTarget, "Legacy context-engine");
return {
sessionId: resolvedTarget.sessionId,
sessionFile: marker ? formatSqliteSessionFileMarker(resolvedTarget) : resolvedTarget.sessionKey,
sessionTarget: resolvedTarget
};
}
return {
sessionId: successorId ?? current.sessionId,
sessionFile: params.currentSessionFile,
sessionTarget: successorId ? {
...current,
sessionId: successorId
} : current
};
}
/** Accepts a declared successor under the predecessor's exact host-owned claim. */
async function acceptCompactionSuccessor(params) {
const currentTarget = { ...params.currentTarget };
const expected = { ...params.expectedEntry };
const assertPlacement = captureSessionPlacementCompactionSuccessorAssertion();
params.assertActive();
if (currentTarget.sessionId !== expected.sessionId) throw new SessionTranscriptWriterClaimReboundError();
const successor = await resolveContextEngineCompactionSuccessor({
config: params.config,
currentSessionFile: params.currentSessionFile ?? currentTarget.sessionKey,
currentTarget,
result: params.result
});
params.assertActive();
const requireExpectedEntry = (entry) => {
if (!entry || entry.sessionId !== expected.sessionId || entry.lifecycleRevision !== expected.lifecycleRevision || entry.activeWriterRunId !== expected.activeWriterRunId) throw new SessionTranscriptWriterClaimReboundError();
return entry;
};
const previousEntry = requireExpectedEntry(loadSessionEntry({
...currentTarget,
readConsistency: "latest"
}));
if (successor.sessionId === currentTarget.sessionId) return {
...successor,
entry: previousEntry
};
if (!params.result.ok || !params.result.compacted) throw new Error("Cannot accept a successor without a successful completed compaction");
const assertCommitAllowed = () => {
params.assertActive();
assertPlacement({
currentTarget,
successorSessionId: successor.sessionId
});
};
assertCommitAllowed();
let committed;
try {
await patchSessionEntryCore(currentTarget, (entry) => {
requireExpectedEntry(entry);
return { sessionId: successor.sessionId };
}, {
skipMaintenance: true,
assertCommitAllowed,
onCommitted: (entry) => {
committed = {
...successor,
entry,
previousSessionId: currentTarget.sessionId
};
params.onCommitted?.(committed);
}
});
if (!committed) throw new SessionTranscriptWriterClaimReboundError();
return committed;
} catch (error) {
if (!committed) {
params.assertActive();
throw error;
}
log$1.warn(`compaction successor committed but publication failed: ${String(error)}`);
return committed;
} finally {
if (committed && params.config) try {
emitCompactionSessionLifecycleHooks({
agentId: currentTarget.agentId,
cfg: params.config,
sessionKey: currentTarget.sessionKey,
storePath: currentTarget.storePath,
previousEntry,
nextEntry: committed.entry
});
} catch (error) {
log$1.warn(`compaction successor lifecycle notification failed: ${String(error)}`);
}
}
}
function emitCompactionSessionLifecycleHooks(params) {
const agentId = params.agentId ?? resolveAgentIdFromSessionKey(params.sessionKey);
if (params.previousEntry.sessionId) forgetActiveSessionForShutdown(params.previousEntry.sessionId);
if (params.nextEntry.sessionId && params.storePath) noteActiveSessionForShutdown({
cfg: params.cfg,
sessionKey: params.sessionKey,
sessionId: params.nextEntry.sessionId,
storePath: params.storePath,
sessionFile: params.sessionKey,
agentId
});
const hookRunner = getGlobalHookRunner();
if (!hookRunner) return;
if (hookRunner.hasHooks("session_end")) {
const storePath = agentId && params.storePath ? resolveSessionStorePathForScope({
agentId,
sessionKey: params.sessionKey,
storePath: params.storePath
}) : params.storePath;
const transcript = resolveStableSessionEndTranscript({
sessionId: params.previousEntry.sessionId,
storePath,
agentId
});
const payload = buildSessionEndHookPayload({
sessionId: params.previousEntry.sessionId,
sessionKey: params.sessionKey,
agentId,
reason: "compaction",
sessionFile: transcript.sessionFile ?? (agentId && storePath ? formatSqliteSessionFileMarker({
agentId,
sessionId: params.previousEntry.sessionId,
storePath
}) : void 0),
transcriptArchived: transcript.transcriptArchived,
nextSessionId: params.nextEntry.sessionId
});
runWithGatewayIndependentRootWorkContinuation(async () => {
await hookRunner.runSessionEnd(payload.event, payload.context);
}, "hooks:session-end").catch((error) => {
logVerbose(`session_end hook failed: ${String(error)}`);
});
}
if (hookRunner.hasHooks("session_start")) {
const payload = buildSessionStartHookPayload({
sessionId: params.nextEntry.sessionId,
sessionKey: params.sessionKey,
agentId,
resumedFrom: params.previousEntry.sessionId
});
runWithGatewayIndependentRootWorkContinuation(async () => {
await hookRunner.runSessionStart(payload.event, payload.context);
}, "hooks:session-start").catch((error) => {
logVerbose(`session_start hook failed: ${String(error)}`);
});
}
}
function assertSameSessionBinding(currentTarget, successorTarget, label) {
if (successorTarget.agentId !== currentTarget.agentId || successorTarget.sessionKey !== currentTarget.sessionKey || path.resolve(successorTarget.storePath) !== path.resolve(currentTarget.storePath)) throw new Error(`${label} successor target changed the active session binding`);
}
//#endregion
export { isRecoverableNativeHarnessBindingFailure as i, resolveContextEngineCompactionSuccessor as n, maybeCompactAgentHarnessSession as r, acceptCompactionSuccessor as t };