openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
281 lines (280 loc) • 13.4 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 { i as listAgentEntries } from "./agent-scope-config-DcbEhP0R.js";
import { O as parseAgentSessionKey } from "./session-key-BnWWjqNc.js";
import { t as isIncognitoSessionKey } from "./incognito-session-key-BwpD1Lwd.js";
import { n as resolveSessionStoreCompatibilityAgentId } from "./legacy.default-agent-owner-BGwEdQRe.js";
import { o as resolveSessionStorePathCore } from "./paths-CXdaYWF_.js";
import "./agent-scope-DbtJyKUL.js";
import { t as resolvePersistedSessionStoreOwner } from "./session-store-owner-CR2Ag3xK.js";
import { b as readOpenClawAgentDatabaseRegistryToken, y as listOpenClawRegisteredAgentDatabases } from "./openclaw-agent-db-maintenance-wTIy-jt-.js";
import { f as listOpenIncognitoAgentDatabases, m as readOpenIncognitoAgentDatabaseGeneration } from "./openclaw-agent-db-CWtDoRbC.js";
import "./session-accessor-YsytfDtG.js";
import { a as listSessionEntriesReadOnly, t as countSessionEntryRowsReadOnly } from "./session-accessor.sqlite-entry-CWk3jL7s.js";
import { r as resolveSqliteTargetFromSessionStorePath } from "./session-sqlite-target-Dp-kgpcT.js";
import { o as resolveDeliveryProvenCanonicalSessionKey } from "./store-entry-CzRELcpv.js";
import { m as canonicalSessionKeyMigrationRequiredError } from "./session-accessor.sqlite-transcript-state-DwF2owZS.js";
import { n as canonicalizeMainSessionAlias } from "./main-session-Br0F9dzh.js";
import { a as resolveStoredSessionKeyForAgentStore, n as resolveSessionStoreAgentId } from "./session-store-key-8xEjWSNi.js";
import { t as listSessionEntriesCore } from "./session-accessor.entry-CQ2WPpfn.js";
import { d as dedupeSessionStoreTargetsBySqliteTarget, i as resolveAgentSessionStoreTargetsSync, n as listConfiguredSessionStoreAgentIds, o as resolveAllAgentSessionStoreTargetsSync, r as listKnownSessionStoreAgentIds } from "./targets-Cknmo7YZ.js";
//#region src/config/sessions/combined-store-gateway.ts
let preparedConfiguredSessionStoreTargets;
function isStorePathTemplate(store) {
return typeof store === "string" && store.includes("{agentId}");
}
function resolveCombinedStorePath(paths, storeConfig) {
return paths.length === 1 ? expectDefined(paths[0], "store path at 0") : typeof storeConfig === "string" && storeConfig.trim() ? storeConfig.trim() : "(multiple)";
}
function resolveCombinedDatabasePath(targets, defaultAgentId, physicallyDeduped = false) {
if (physicallyDeduped && targets.length !== 1) return "(multiple)";
const paths = [...new Set(targets.map((target) => resolveSqliteTargetFromSessionStorePath(target.storePath, {
agentId: target.agentId,
defaultAgentId
}).path))];
return paths.length === 1 ? expectDefined(paths[0], "database path at 0") : "(multiple)";
}
function resolveSharedStoreRowOwner(cfg, selected, sharedStorePaths) {
const configuredPath = resolveSessionStorePathCore(cfg.session?.store, { agentId: resolveSessionStoreCompatibilityAgentId(cfg) });
if (!sharedStorePaths.has(configuredPath)) return;
const persistedOwner = resolvePersistedSessionStoreOwner(cfg);
return persistedOwner.kind === "configured" ? {
agentId: persistedOwner.agentId,
target: selected
} : void 0;
}
function loadGatewayStoreEntries(params) {
return (params.includeOpenDatabases ? listSessionEntriesCore : listSessionEntriesReadOnly)({
agentId: params.agentId,
clone: false,
projection: params.projection,
storePath: params.storePath
});
}
function mergeSessionEntryIntoCombined(params) {
const { cfg, combined, entry, agentId, canonicalKey } = params;
const existing = combined[canonicalKey];
if (existing && (canonicalKey === "global" || canonicalKey === "unknown")) return;
if (existing) throw canonicalSessionKeyMigrationRequiredError(`duplicate rows resolve to canonical session key ${canonicalKey}`);
const deliveryCanonicalKey = resolveDeliveryProvenCanonicalSessionKey(canonicalKey, entry);
if (deliveryCanonicalKey !== canonicalKey) throw canonicalSessionKeyMigrationRequiredError(`non-canonical persisted row resolves to session key ${deliveryCanonicalKey}`);
const projected = { ...entry };
if (cfg.session?.scope === "global") for (const field of ["parentSessionKey", "spawnedBy"]) {
const sessionKey = projected[field];
const parsed = sessionKey ? parseAgentSessionKey(sessionKey) : null;
if (sessionKey && parsed) projected[field] = canonicalizeMainSessionAlias({
cfg,
agentId: parsed.agentId,
sessionKey
});
}
combined[canonicalKey] = projected;
params.agentIdBySessionKey.set(canonicalKey, agentId);
}
function mergeOpenIncognitoStores(params) {
const storePaths = [];
for (const target of params.targets) {
const store = loadGatewayStoreEntries({
agentId: target.agentId,
includeOpenDatabases: true,
projection: params.projection,
storePath: target.storePath
});
let merged = false;
for (const { sessionKey, entry } of store) {
if (!isIncognitoSessionKey(sessionKey) || entry.incognito !== true) continue;
mergeSessionEntryIntoCombined({
cfg: params.cfg,
combined: params.combined,
agentIdBySessionKey: params.agentIdBySessionKey,
entry,
agentId: target.agentId,
canonicalKey: sessionKey
});
merged = true;
}
if (merged) storePaths.push(target.storePath);
}
return storePaths;
}
function filterCombinedStoreToConfiguredAgents(params) {
const isConfiguredSessionKey = (key) => {
const normalizedKey = normalizeOptionalString(key);
if (!normalizedKey) return false;
const agentId = resolveSessionStoreAgentId(params.cfg, normalizedKey);
return params.configuredAgentIds.has(normalizeAgentId(agentId));
};
for (const [key, entry] of Object.entries(params.store)) if (!(key === "global" || key === "unknown" || isConfiguredSessionKey(key) || isConfiguredSessionKey(entry.spawnedBy) || isConfiguredSessionKey(entry.parentSessionKey))) {
delete params.store[key];
params.agentIdBySessionKey.delete(key);
}
}
function resolvePreparedConfiguredSessionStoreTargets(cfg, includeIncognito) {
const registryToken = readOpenClawAgentDatabaseRegistryToken();
const incognitoGeneration = readOpenIncognitoAgentDatabaseGeneration();
const cached = preparedConfiguredSessionStoreTargets;
if (cached?.cfg === cfg && cached.registryToken === registryToken && cached.incognitoGeneration === incognitoGeneration && cached.includeIncognito === includeIncognito) return cached.resolved;
const storeConfig = cfg.session?.store;
const defaultAgentId = normalizeAgentId(resolveSessionStoreCompatibilityAgentId(cfg));
const configuredIds = listConfiguredSessionStoreAgentIds(cfg);
const configuredAgentIds = new Set(configuredIds);
const incognitoTargets = includeIncognito ? listOpenIncognitoAgentDatabases() : [];
const incognitoTargetKeys = new Set(incognitoTargets.map((target) => `${target.agentId}\0${target.storePath}`));
const diagnostics = [];
let sharedStoreRowOwner;
const candidates = dedupeSessionStoreTargetsBySqliteTarget([
...listOpenClawRegisteredAgentDatabases().map(({ agentId, path }) => ({
agentId,
storePath: path
})),
...configuredIds.map((agentId) => ({
agentId,
storePath: resolveSessionStorePathCore(storeConfig, { agentId })
})),
...incognitoTargets
], {
defaultAgentId,
onDiagnostic: (diagnostic) => diagnostics.push(diagnostic.message),
onSharedTarget: (selected, paths) => {
sharedStoreRowOwner ??= resolveSharedStoreRowOwner(cfg, selected, paths);
}
});
const durableTargets = candidates.filter((target) => !incognitoTargetKeys.has(`${target.agentId}\0${target.storePath}`));
const resolved = Object.freeze({
configuredAgentIds,
defaultAgentId,
diagnostics: Object.freeze(diagnostics),
durableStorePath: resolveCombinedDatabasePath(durableTargets, defaultAgentId, true),
durableTargets: Object.freeze(durableTargets.map((target) => Object.freeze({ ...target }))),
incognitoTargets: Object.freeze(candidates.filter((target) => incognitoTargetKeys.has(`${target.agentId}\0${target.storePath}`)).map((target) => Object.freeze({ ...target }))),
sharedStoreRowOwner,
storeConfig
});
preparedConfiguredSessionStoreTargets = {
cfg,
includeIncognito,
incognitoGeneration,
registryToken,
resolved
};
return resolved;
}
function resolveGatewaySessionStoreTargets(cfg, opts) {
const storeConfig = cfg.session?.store;
const diagnostics = [];
const requestedAgentId = typeof opts.agentId === "string" && opts.agentId.trim() ? normalizeAgentId(opts.agentId) : void 0;
if (opts.configuredAgentsOnly === true && !requestedAgentId) return resolvePreparedConfiguredSessionStoreTargets(cfg, opts.includeIncognito !== false);
const defaultAgentId = normalizeAgentId(resolveSessionStoreCompatibilityAgentId(cfg));
const incognitoTargets = opts.includeIncognito === false ? [] : listOpenIncognitoAgentDatabases().filter((target) => !requestedAgentId || target.agentId === requestedAgentId);
if (storeConfig && !isStorePathTemplate(storeConfig)) {
const ownerIds = [.../* @__PURE__ */ new Set([
...listAgentEntries(cfg).map((entry) => normalizeAgentId(entry.id)),
...listKnownSessionStoreAgentIds(cfg),
defaultAgentId,
...requestedAgentId ? [requestedAgentId] : []
])];
let sharedStoreRowOwner;
return {
defaultAgentId,
diagnostics,
durableTargets: dedupeSessionStoreTargetsBySqliteTarget(ownerIds.map((agentId) => ({
agentId,
storePath: resolveSessionStorePathCore(storeConfig, { agentId })
})), {
defaultAgentId,
onDiagnostic: (diagnostic) => diagnostics.push(diagnostic.message),
onSharedTarget: (selected, paths) => {
sharedStoreRowOwner ??= resolveSharedStoreRowOwner(cfg, selected, paths);
}
}),
incognitoTargets,
requestedAgentId,
sharedStoreRowOwner,
storeConfig
};
}
return {
defaultAgentId,
diagnostics,
durableTargets: requestedAgentId ? dedupeSessionStoreTargetsBySqliteTarget(resolveAgentSessionStoreTargetsSync(cfg, requestedAgentId), { defaultAgentId }) : resolveAllAgentSessionStoreTargetsSync(cfg),
incognitoTargets,
requestedAgentId,
storeConfig
};
}
/** Checks whether Gateway prewarm can project the selected stores within a bounded row budget. */
function canPrewarmCombinedSessionStoresForGateway(cfg, params) {
let totalRows = 0;
for (const agentId of params.agentIds) {
const resolved = resolveGatewaySessionStoreTargets(cfg, { agentId });
const projectionTargets = resolved.incognitoTargets.length === 0 ? resolved.durableTargets : dedupeSessionStoreTargetsBySqliteTarget([...resolved.durableTargets, ...resolved.incognitoTargets], { defaultAgentId: resolved.defaultAgentId });
for (const target of projectionTargets) {
totalRows += countSessionEntryRowsReadOnly(target);
if (totalRows > params.maxRows) return false;
}
}
return true;
}
/** Loads and canonicalizes session entries for gateway views across one or more agent stores. */
function loadCombinedSessionStoreForGatewayCore(cfg, opts = {}) {
const projection = opts.projection ?? "full";
const { configuredAgentIds, defaultAgentId, diagnostics, durableStorePath: preparedDurableStorePath, durableTargets, incognitoTargets, requestedAgentId, sharedStoreRowOwner, storeConfig } = resolveGatewaySessionStoreTargets(cfg, opts);
const combined = {};
const agentIdBySessionKey = /* @__PURE__ */ new Map();
for (const target of durableTargets) {
const agentId = target.agentId;
const storePath = target.storePath;
const store = loadGatewayStoreEntries({
agentId,
projection,
storePath
});
const rowAgentId = sharedStoreRowOwner?.target.storePath === storePath && sharedStoreRowOwner.target.agentId === agentId ? sharedStoreRowOwner.agentId : agentId;
for (const { sessionKey: key, entry } of store) {
const parsed = parseAgentSessionKey(key);
const canonicalKey = resolveStoredSessionKeyForAgentStore({
cfg,
agentId: parsed ? agentId : rowAgentId,
sessionKey: key
});
if (key !== canonicalKey) throw canonicalSessionKeyMigrationRequiredError(`non-canonical persisted row resolves to session key ${canonicalKey}`);
const canonicalAgentId = normalizeAgentId(parsed?.agentId ?? rowAgentId);
if (requestedAgentId && canonicalAgentId !== requestedAgentId) continue;
mergeSessionEntryIntoCombined({
cfg,
combined,
agentIdBySessionKey,
entry,
agentId: canonicalAgentId,
canonicalKey
});
}
}
const incognitoStorePaths = mergeOpenIncognitoStores({
cfg,
combined,
agentIdBySessionKey,
projection,
targets: incognitoTargets
});
if (configuredAgentIds) filterCombinedStoreToConfiguredAgents({
cfg,
configuredAgentIds,
store: combined,
agentIdBySessionKey
});
const durableStorePaths = durableTargets.map((target) => target.storePath);
const durableStorePath = preparedDurableStorePath ?? resolveCombinedDatabasePath(durableTargets, defaultAgentId);
return {
diagnostics,
durableStorePath,
durableTargets,
storePath: storeConfig && !isStorePathTemplate(storeConfig) ? incognitoStorePaths.length > 0 ? "(multiple)" : durableStorePath : resolveCombinedStorePath([...durableStorePaths, ...incognitoStorePaths], storeConfig),
store: combined,
agentIdBySessionKey
};
}
//#endregion
export { loadCombinedSessionStoreForGatewayCore as n, canPrewarmCombinedSessionStoresForGateway as t };