openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
358 lines (357 loc) • 13.7 kB
JavaScript
import "./src-vebZIeLe.js";
import { t as expectDefined } from "./expect-CyE8FADM.js";
import { l as normalizeOptionalString } from "./string-coerce-CIXf7egm.js";
import { n as normalizeAgentId } from "./agent-id-CeT3w4ap.js";
import { o as listAgentIds } from "./agent-scope-config-DcbEhP0R.js";
import { E as normalizeSessionKeyPreservingOpaquePeerIds, O as parseAgentSessionKey } from "./session-key-BnWWjqNc.js";
import "./agent-scope-DbtJyKUL.js";
import { t as ErrorCodes } from "./gateway-error-details-w0nAGBBp.js";
import { d as errorShape } from "./error-codes-Bo8q2D1o.js";
import { i as resolveSessionStoreKey, n as resolveSessionStoreAgentId } from "./session-store-key-8xEjWSNi.js";
import { n as loadCombinedSessionStoreForGatewayCore } from "./combined-store-gateway-DGm4nZAJ.js";
import { r as controlUiSessionSlug } from "./share-DPKiewIx.js";
import { n as SHORT_SESSION_ID_RE, t as SESSION_UUID_SUFFIX_RE } from "./src-DqwLld49.js";
import { n as resolveSessionIdMatchSelection } from "./session-id-resolution-BbcM7Och.js";
import { n as hasOperatorBoundary } from "./operator-role-policy-wsr1DeJv.js";
import { c as buildSessionListRowMetadataContext, t as filterAndSortSessionEntries, u as resolveGatewaySessionDisplayName } from "./session-utils-list-B0k8KJn5.js";
import { n as resolveRequestedSessionAgentId } from "./session-request-agent-CCRSEGCB.js";
import { f as resolveGatewaySessionStoreTargetWithStore, l as resolveDeletedAgentIdFromSessionKey } from "./session-utils-store-CInT2loy.js";
import "./session-utils-Cai0_C6U.js";
import { t as parseSessionLabel } from "./session-label-DSD-L6TD.js";
import { i as prepareSessionSharing } from "./session-sharing-B7MI8hNo.js";
//#region src/gateway/sessions-resolve.ts
function resolveSessionVisibilityFilterOptions(p) {
return {
includeGlobal: p.includeGlobal === true,
includeUnknown: p.includeUnknown === true,
spawnedBy: p.spawnedBy,
agentId: p.agentId
};
}
function noSessionFoundResult(params) {
if (params.p.allowMissing) return {
ok: true,
missing: true
};
return {
ok: false,
error: errorShape(ErrorCodes.INVALID_REQUEST, params.message)
};
}
/** Rejects sessions whose owning agent no longer exists in config (#65524). */
function validateSessionAgentExists(cfg, key, entry, options) {
const deletedAgentId = resolveDeletedAgentIdFromSessionKey(cfg, key, entry, options);
if (deletedAgentId === null) return null;
return {
ok: false,
error: errorShape(ErrorCodes.INVALID_REQUEST, `Agent "${deletedAgentId}" no longer exists in configuration`)
};
}
function isResolvedSessionKeyVisible(params) {
if (typeof params.p.spawnedBy !== "string" || params.p.spawnedBy.trim().length === 0) return true;
return filterAndSortSessionEntries({
cfg: params.cfg,
store: params.store,
now: Date.now(),
opts: resolveSessionVisibilityFilterOptions(params.p)
}).some(([key]) => key === params.key);
}
function findVisibleSessionIdMatches(params) {
return filterAndSortSessionEntries({
cfg: params.cfg,
store: params.store,
now: Date.now(),
opts: resolveSessionVisibilityFilterOptions(params.p)
}).filter(([key, entry]) => (params.entryFilter?.(key, entry) ?? true) && (entry?.sessionId === params.sessionId || key === params.sessionId));
}
function normalizeShortSessionId(shortId) {
return SHORT_SESSION_ID_RE.test(shortId) ? shortId.toLowerCase() : null;
}
function sessionResolveCandidate(key, entry, agentId) {
const displayName = resolveGatewaySessionDisplayName(key, entry);
return {
key,
agentId: normalizeAgentId(agentId),
...displayName ? { displayName } : {},
...entry.boardFace ? { boardFace: entry.boardFace } : {}
};
}
function findVisibleShortIdMatches(params) {
const now = Date.now();
return filterAndSortSessionEntries({
cfg: params.cfg,
store: params.store,
now,
opts: {
...resolveSessionVisibilityFilterOptions(params.p),
archived: "all"
}
}).flatMap(([key, entry]) => {
if (params.entryFilter && !params.entryFilter(key, entry)) return [];
const parsed = parseAgentSessionKey(key);
const uuid = parsed?.rest.match(SESSION_UUID_SUFFIX_RE)?.[1];
if (!parsed || !uuid?.toLowerCase().replaceAll("-", "").startsWith(params.shortId)) return [];
if (resolveDeletedAgentIdFromSessionKey(params.cfg, key, entry) !== null) return [];
return [sessionResolveCandidate(key, entry, parsed.agentId)];
});
}
async function resolveSessionKeyFromResolveParams(params) {
const { cfg, client, p } = params;
const { entryFilter } = prepareSessionSharing({
client,
cfg
});
const key = normalizeOptionalString(p.key) ?? "";
const hasKey = key.length > 0;
const sessionId = normalizeOptionalString(p.sessionId) ?? "";
const hasSessionId = sessionId.length > 0;
const hasLabel = (normalizeOptionalString(p.label) ?? "").length > 0;
const rawShortId = normalizeOptionalString(p.shortId) ?? "";
const hasShortId = rawShortId.length > 0;
const hasReference = p.reference !== void 0;
if (p.slugHint !== void 0 && !hasShortId) return {
ok: false,
error: errorShape(ErrorCodes.INVALID_REQUEST, "slugHint requires shortId")
};
const selectionCount = [
hasKey,
hasSessionId,
hasLabel,
hasShortId,
hasReference
].filter(Boolean).length;
if (selectionCount > 1) return {
ok: false,
error: errorShape(ErrorCodes.INVALID_REQUEST, "Provide either key, sessionId, label, shortId, or reference (not multiple)")
};
if (selectionCount === 0) return {
ok: false,
error: errorShape(ErrorCodes.INVALID_REQUEST, "Either key, sessionId, label, shortId, or reference is required")
};
if (p.reference) {
const referenceKey = normalizeSessionKeyPreservingOpaquePeerIds(p.reference.key);
const parsed = parseAgentSessionKey(referenceKey);
const exactKey = !p.agentId || !parsed || parsed.agentId === normalizeAgentId(p.agentId) ? resolveSessionStoreKey({
cfg,
sessionKey: referenceKey,
storeAgentId: p.agentId
}) : referenceKey;
const { store, agentIdBySessionKey } = loadCombinedSessionStoreForGatewayCore(cfg, {
agentId: p.agentId,
configuredAgentsOnly: true,
projection: "list"
});
const entries = filterAndSortSessionEntries({
cfg,
store,
entryFilter,
now: Date.now(),
opts: {
...resolveSessionVisibilityFilterOptions(p),
archived: "all"
}
}).filter(([candidateKey, entry]) => resolveDeletedAgentIdFromSessionKey(cfg, candidateKey, entry) === null);
const candidate = ([candidateKey, entry]) => sessionResolveCandidate(candidateKey, entry, expectDefined(agentIdBySessionKey.get(candidateKey), "reference session agent"));
const exact = entries.find(([candidateKey]) => normalizeSessionKeyPreservingOpaquePeerIds(candidateKey) === exactKey);
if (exact) return {
ok: true,
...candidate(exact)
};
const slug = normalizeOptionalString(p.reference.slug);
const matches = slug ? entries.filter(([candidateKey, entry]) => SESSION_UUID_SUFFIX_RE.test(parseAgentSessionKey(candidateKey)?.rest ?? "") && controlUiSessionSlug(resolveGatewaySessionDisplayName(candidateKey, entry)) === slug).slice(0, 10).map(candidate) : [];
if (matches.length > 1) return {
ok: true,
ambiguous: true,
candidates: matches
};
const selected = matches[0];
return selected ? {
ok: true,
...selected
} : noSessionFoundResult({
p,
message: `No session found: ${p.reference.key}`
});
}
if (hasKey) {
const requestedAgent = resolveRequestedSessionAgentId(cfg, key, p.agentId);
if (!requestedAgent.ok) return requestedAgent;
const target = resolveGatewaySessionStoreTargetWithStore({
cfg,
key,
clone: false,
...requestedAgent.agentId ? { agentId: requestedAgent.agentId } : {}
});
const store = target.store;
const entry = store[target.canonicalKey];
if (entry) {
if (hasOperatorBoundary(client, cfg) && entryFilter?.(target.canonicalKey, entry) === false || !isResolvedSessionKeyVisible({
cfg,
p,
store,
key: target.canonicalKey
})) return noSessionFoundResult({
p,
message: `No session found: ${key}`
});
const agentCheck = validateSessionAgentExists(cfg, target.canonicalKey, entry, { acpMetadataSessionKey: target.canonicalKey });
if (agentCheck) return agentCheck;
return {
ok: true,
key: target.canonicalKey,
agentId: requestedAgent.agentId
};
}
return noSessionFoundResult({
p,
message: `No session found: ${key}`
});
}
if (hasSessionId) {
if (!p.agentId) {
const ownerTaggedMatches = /* @__PURE__ */ new Map();
for (const agentId of listAgentIds(cfg)) {
const agentMatches = findVisibleSessionIdMatches({
cfg,
store: loadCombinedSessionStoreForGatewayCore(cfg, { agentId }).store,
p: {
...p,
agentId
},
sessionId,
entryFilter
});
const agentSelection = resolveSessionIdMatchSelection(agentMatches, sessionId);
if (agentSelection.kind === "ambiguous") return {
ok: false,
error: errorShape(ErrorCodes.INVALID_REQUEST, `Multiple sessions found for sessionId: ${sessionId} (${agentSelection.sessionKeys.join(", ")})`)
};
if (agentSelection.kind === "selected") {
const entry = agentMatches.find(([matchKey]) => matchKey === agentSelection.sessionKey)?.[1];
const owner = resolveRequestedSessionAgentId(cfg, agentSelection.sessionKey, agentId);
if (entry && owner.ok) ownerTaggedMatches.set(`${owner.agentId}\0${agentSelection.sessionKey}`, {
agentId: owner.agentId,
entry,
key: agentSelection.sessionKey
});
}
}
if (ownerTaggedMatches.size > 1) return {
ok: false,
error: errorShape(ErrorCodes.INVALID_REQUEST, `Multiple sessions found for sessionId: ${sessionId} (${[...ownerTaggedMatches.values()].map((match) => `${match.agentId}:${match.key}`).join(", ")})`)
};
const ownerTaggedMatch = ownerTaggedMatches.values().next().value;
if (ownerTaggedMatch) return validateSessionAgentExists(cfg, ownerTaggedMatch.key, ownerTaggedMatch.entry) ?? {
ok: true,
key: ownerTaggedMatch.key,
agentId: ownerTaggedMatch.agentId
};
}
const { store } = loadCombinedSessionStoreForGatewayCore(cfg, { agentId: p.agentId });
const matches = findVisibleSessionIdMatches({
cfg,
store,
p,
sessionId,
entryFilter
});
const selection = resolveSessionIdMatchSelection(matches, sessionId);
if (selection.kind === "none") return noSessionFoundResult({
p,
message: `No session found: ${sessionId}`
});
if (selection.kind === "ambiguous") return {
ok: false,
error: errorShape(ErrorCodes.INVALID_REQUEST, `Multiple sessions found for sessionId: ${sessionId} (${selection.sessionKeys.join(", ")})`)
};
const selectedEntry = matches.find(([matchKey]) => matchKey === selection.sessionKey)?.[1];
let selectedAgentId = parseAgentSessionKey(selection.sessionKey)?.agentId ?? p.agentId;
if (!selectedAgentId) {
const resolvedOwner = resolveRequestedSessionAgentId(cfg, selection.sessionKey);
if (!resolvedOwner.ok) return resolvedOwner;
selectedAgentId = resolvedOwner.agentId;
}
const agentCheckSessionId = validateSessionAgentExists(cfg, selection.sessionKey, selectedEntry);
if (agentCheckSessionId) return agentCheckSessionId;
return {
ok: true,
key: selection.sessionKey,
agentId: selectedAgentId
};
}
if (hasShortId) {
const shortId = normalizeShortSessionId(rawShortId);
if (!shortId) return {
ok: false,
error: errorShape(ErrorCodes.INVALID_REQUEST, "shortId must be 8-32 hexadecimal characters")
};
const { store } = loadCombinedSessionStoreForGatewayCore(cfg, {
agentId: p.agentId,
projection: "list"
});
const matches = findVisibleShortIdMatches({
cfg,
store,
p,
shortId,
entryFilter
});
const slugHint = normalizeOptionalString(p.slugHint);
const slugMatches = slugHint ? matches.filter((candidate) => controlUiSessionSlug(candidate.displayName) === slugHint) : [];
const narrowed = slugMatches.length > 0 ? slugMatches : matches;
if (narrowed.length === 0) return noSessionFoundResult({
p,
message: `No session found: ${shortId}`
});
if (narrowed.length > 1) return {
ok: true,
ambiguous: true,
candidates: narrowed.slice(0, 10)
};
return {
ok: true,
...expectDefined(narrowed[0], "short session match at 0")
};
}
const parsedLabel = parseSessionLabel(p.label);
if (!parsedLabel.ok) return {
ok: false,
error: errorShape(ErrorCodes.INVALID_REQUEST, parsedLabel.error)
};
const { store } = loadCombinedSessionStoreForGatewayCore(cfg, { agentId: p.agentId });
const now = Date.now();
let rowContext;
const matches = filterAndSortSessionEntries({
cfg,
...entryFilter ? { entryFilter } : {},
store,
now,
getRowContext: () => rowContext ??= buildSessionListRowMetadataContext({ now }),
opts: {
...resolveSessionVisibilityFilterOptions(p),
label: parsedLabel.label,
limit: 2
}
});
if (matches.length === 0) return noSessionFoundResult({
p,
message: `No session found with label: ${parsedLabel.label}`
});
if (matches.length > 1) {
const keys = matches.map(([matchKey]) => matchKey).join(", ");
return {
ok: false,
error: errorShape(ErrorCodes.INVALID_REQUEST, `Multiple sessions found with label: ${parsedLabel.label} (${keys})`)
};
}
const [labelKey, labelEntry] = expectDefined(matches[0], "label session match at 0");
const agentCheckLabel = validateSessionAgentExists(cfg, labelKey, labelEntry);
if (agentCheckLabel) return agentCheckLabel;
return {
ok: true,
key: labelKey,
agentId: normalizeAgentId(parseAgentSessionKey(labelKey)?.agentId ?? p.agentId ?? resolveSessionStoreAgentId(cfg, labelKey))
};
}
//#endregion
export { resolveSessionKeyFromResolveParams as t };