openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
119 lines (118 loc) • 8.42 kB
JavaScript
import { l as normalizeOptionalString } from "./string-coerce-CIXf7egm.js";
import { O as parseAgentSessionKey } from "./session-key-BnWWjqNc.js";
import { a as normalizeOptionalAgentRuntimeId } from "./agent-runtime-id-BpfvnoN1.js";
//#region src/sessions/agent-harness-session-key.ts
const AGENT_HARNESS_SESSION_KEY_PREFIX = "harness:";
const AGENT_HARNESS_SESSION_KEY_RESERVED_MESSAGE = "Session key namespace is reserved for agent harness-owned sessions.";
const AGENT_HARNESS_SESSION_ID_LOCKED_MESSAGE = "Agent harness-owned session identity is locked and cannot be replaced or shared.";
const AGENT_HARNESS_MODEL_RUN_FORBIDDEN_MESSAGE = "Agent harness-owned sessions cannot be used for one-shot model runs.";
const MODEL_SELECTION_LOCK_REMOVAL_MESSAGE = "Model-selection-locked sessions cannot be removed, unlocked, or reassigned.";
function resolveAgentHarnessSessionKeyRest(sessionKey) {
const trimmed = sessionKey.trim().toLowerCase();
return parseAgentSessionKey(trimmed)?.rest ?? trimmed;
}
function resolveAgentHarnessSessionKeyOwner(sessionKey) {
const rest = resolveAgentHarnessSessionKeyRest(sessionKey);
if (!rest.startsWith(AGENT_HARNESS_SESSION_KEY_PREFIX)) return;
const ownerSegment = rest.slice(8).split(":", 1)[0];
return normalizeOptionalAgentRuntimeId(ownerSegment);
}
/** Agent harnesses own this namespace; public session APIs must not create rows in it. */
function isAgentHarnessSessionKey(sessionKey) {
return resolveAgentHarnessSessionKeyRest(sessionKey).startsWith(AGENT_HARNESS_SESSION_KEY_PREFIX);
}
function resolveMissingAgentHarnessSessionError(sessionKey, entry) {
return entry === void 0 && isAgentHarnessSessionKey(sessionKey) ? AGENT_HARNESS_SESSION_KEY_RESERVED_MESSAGE : void 0;
}
/** Missing reserved keys fail closed; pre-feature unlocked collisions stay ordinary. */
function resolveAgentHarnessSessionContextError(sessionKey, entry) {
if (!isAgentHarnessSessionKey(sessionKey)) return;
return entry ? resolveAgentHarnessSessionStoreEntryError(sessionKey, entry) : AGENT_HARNESS_SESSION_KEY_RESERVED_MESSAGE;
}
/** Trusted creation must bind the namespace owner to the persisted harness owner. */
function isAgentHarnessSessionKeyOwnedBy(sessionKey, agentHarnessId) {
const normalizedHarnessId = normalizeOptionalAgentRuntimeId(agentHarnessId);
return Boolean(normalizedHarnessId && normalizedHarnessId === resolveAgentHarnessSessionKeyOwner(sessionKey));
}
/** A trusted plugin owner outranks the harness observed during its last turn. */
function resolveSessionPinnedHarnessId(entry) {
return entry?.modelSelectionLocked === true && !normalizeOptionalString(entry.pluginOwnerId) ? normalizeOptionalAgentRuntimeId(entry.agentHarnessId) : void 0;
}
function sessionLockOwnerMatches(previous, next) {
const previousPluginOwner = normalizeOptionalString(previous.pluginOwnerId);
const nextPluginOwner = normalizeOptionalString(next.pluginOwnerId);
if (previousPluginOwner || nextPluginOwner) return previousPluginOwner === nextPluginOwner;
const previousOwner = normalizeOptionalString(previous.agentHarnessId)?.toLowerCase();
const nextOwner = normalizeOptionalString(next.agentHarnessId)?.toLowerCase();
return previousOwner === nextOwner && normalizeOptionalAgentRuntimeId(previousOwner) === normalizeOptionalAgentRuntimeId(nextOwner);
}
function hasEquivalentRelocatedLockedEntry(params) {
if (isAgentHarnessSessionKey(params.previousKey)) return false;
const sessionId = normalizeOptionalString(params.previousEntry.sessionId);
if (!sessionId) return false;
return Object.entries(params.store).some(([sessionKey, entry]) => sessionKey !== params.previousKey && entry.modelSelectionLocked === true && entry.sessionId === sessionId && sessionLockOwnerMatches(params.previousEntry, entry));
}
/** Preserves durable harness ownership across whole-store compatibility projections. */
function resolveAgentHarnessSessionStoreTransitionError(params) {
for (const [sessionKey, previousEntry] of params.before ?? []) {
const nextEntry = params.store[sessionKey];
if (nextEntry?.modelSelectionLocked === true && sessionLockOwnerMatches(previousEntry, nextEntry)) {
if (nextEntry.sessionId !== previousEntry.sessionId) return AGENT_HARNESS_SESSION_ID_LOCKED_MESSAGE;
continue;
}
const allowedRemoval = params.allowedRemovals?.get(sessionKey);
if (nextEntry === void 0 && allowedRemoval !== void 0 && JSON.stringify(previousEntry) === JSON.stringify(allowedRemoval)) continue;
if (nextEntry === void 0 && hasEquivalentRelocatedLockedEntry({
previousKey: sessionKey,
previousEntry,
store: params.store
})) continue;
return MODEL_SELECTION_LOCK_REMOVAL_MESSAGE;
}
}
/** True when a reserved-looking row carries the durable harness lock added with this feature. */
function isAgentHarnessSessionStoreEntryProtected(sessionKey, entry) {
return isAgentHarnessSessionKey(sessionKey) && entry.modelSelectionLocked === true;
}
/** Validates durable harness locks and prevents transcript identity aliases. */
function resolveAgentHarnessSessionStoreError(store) {
const lockedSessionIds = /* @__PURE__ */ new Map();
for (const [sessionKey, entry] of Object.entries(store)) {
const entryError = resolveAgentHarnessSessionStoreEntryError(sessionKey, entry);
if (entryError) return entryError;
if (!isValidAgentHarnessSessionStoreEntry(sessionKey, entry)) continue;
const sessionId = normalizeOptionalString(entry.sessionId);
if (!sessionId || lockedSessionIds.has(sessionId)) return AGENT_HARNESS_SESSION_ID_LOCKED_MESSAGE;
lockedSessionIds.set(sessionId, sessionKey);
}
for (const [sessionKey, entry] of Object.entries(store)) {
const sessionId = normalizeOptionalString(entry.sessionId);
const lockedOwner = sessionId ? lockedSessionIds.get(sessionId) : void 0;
if (lockedOwner && lockedOwner !== sessionKey) return AGENT_HARNESS_SESSION_ID_LOCKED_MESSAGE;
}
}
/** Rejects caller-selected transcript identities that would rotate a durable harness lock. */
function resolveAgentHarnessSessionIdMismatchError(entry, requestedSessionId) {
if (!entry || !resolveSessionPinnedHarnessId(entry)) return;
const requested = normalizeOptionalString(requestedSessionId);
if (!requested) return;
return requested === normalizeOptionalString(entry.sessionId) ? void 0 : AGENT_HARNESS_SESSION_ID_LOCKED_MESSAGE;
}
/** Locked rows require durable identity; reserved rows must also match the key owner. */
function resolveAgentHarnessSessionStoreEntryError(sessionKey, entry) {
if (entry.modelSelectionLocked !== true) return;
const reservedKey = isAgentHarnessSessionKey(sessionKey);
if (normalizeOptionalString(entry.pluginOwnerId)) return reservedKey ? AGENT_HARNESS_SESSION_KEY_RESERVED_MESSAGE : void 0;
const rawHarnessId = normalizeOptionalString(entry.agentHarnessId)?.toLowerCase();
const hasCanonicalHarnessOwner = Boolean(rawHarnessId) && rawHarnessId === normalizeOptionalAgentRuntimeId(rawHarnessId);
if (!normalizeOptionalString(entry.sessionId) && (reservedKey || entry.agentHarnessId !== void 0)) return AGENT_HARNESS_SESSION_ID_LOCKED_MESSAGE;
if (reservedKey) return hasCanonicalHarnessOwner && isAgentHarnessSessionKeyOwnedBy(sessionKey, entry.agentHarnessId) ? void 0 : AGENT_HARNESS_SESSION_KEY_RESERVED_MESSAGE;
if (entry.agentHarnessId === void 0) return;
if (!hasCanonicalHarnessOwner) return AGENT_HARNESS_SESSION_ID_LOCKED_MESSAGE;
}
/** True for any valid durable harness lock, including supported ordinary-key rows. */
function isValidAgentHarnessSessionStoreEntry(sessionKey, entry) {
return entry.modelSelectionLocked === true && (isAgentHarnessSessionKey(sessionKey) || resolveSessionPinnedHarnessId(entry) !== void 0) && resolveAgentHarnessSessionStoreEntryError(sessionKey, entry) === void 0;
}
//#endregion
export { isAgentHarnessSessionKey as a, isValidAgentHarnessSessionStoreEntry as c, resolveAgentHarnessSessionStoreEntryError as d, resolveAgentHarnessSessionStoreError as f, resolveSessionPinnedHarnessId as h, MODEL_SELECTION_LOCK_REMOVAL_MESSAGE as i, resolveAgentHarnessSessionContextError as l, resolveMissingAgentHarnessSessionError as m, AGENT_HARNESS_SESSION_ID_LOCKED_MESSAGE as n, isAgentHarnessSessionKeyOwnedBy as o, resolveAgentHarnessSessionStoreTransitionError as p, AGENT_HARNESS_SESSION_KEY_RESERVED_MESSAGE as r, isAgentHarnessSessionStoreEntryProtected as s, AGENT_HARNESS_MODEL_RUN_FORBIDDEN_MESSAGE as t, resolveAgentHarnessSessionIdMismatchError as u };