openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
172 lines (171 loc) • 6.38 kB
JavaScript
import { t as sanitizeForLog } from "./ansi-DrXAcdMD.js";
import { t as hasErrnoCode } from "./errno-CkbDOfLk.js";
import { r as isPathInside } from "./path-guards-Cp-mGr3-.js";
import { n as normalizeAgentId } from "./agent-id-CeT3w4ap.js";
import { w as resolveStateDir } from "./paths-D2sRr1a_.js";
import "./session-key-BnWWjqNc.js";
import { s as isSessionArchiveArtifactName } from "./artifacts-DMDO9PHy.js";
import { c as createOpenClawAgentDatabasePathMatcher, f as unregisterOpenClawAgentDatabase, l as isPersistentOpenClawAgentDatabasePath, y as listOpenClawRegisteredAgentDatabases } from "./openclaw-agent-db-maintenance-wTIy-jt-.js";
import { n as resolveAgentSessionDirsFromAgentsDirSync } from "./session-dirs-SATsXf4g.js";
import fs from "node:fs";
import path from "node:path";
//#region src/infra/state-migrations.media-persistence-targets.ts
function listDefaultAgentDatabaseTargets(env, failure) {
const agentsDir = path.join(resolveStateDir(env), "agents");
try {
return resolveAgentSessionDirsFromAgentsDirSync(agentsDir).map((sessionsDir) => {
const agentDir = path.dirname(sessionsDir);
return {
agentId: normalizeAgentId(path.basename(agentDir)),
path: path.join(agentDir, "agent", "openclaw-agent.sqlite"),
source: "disk"
};
});
} catch (error) {
failure(agentsDir, `Could not enumerate agent databases under ${agentsDir}: ${String(error)}`);
return [];
}
}
/** Discover maintenance targets without mutating the registry or creating stores. */
function discoverAgentDatabaseMigrationTargets(params) {
const warnings = [];
const externalWarnings = [];
const failures = [];
const registryRemovals = [];
const failure = (pathname, reason) => {
warnings.push(reason);
failures.push({
path: pathname,
reason
});
};
const discard = (candidate, change) => {
if (candidate.source === "registry") registryRemovals.push({
agentId: candidate.agentId,
path: candidate.path,
change
});
};
const candidates = [
...params.configuredAgentDatabaseTargets.map((target) => ({
agentId: target.agentId,
path: target.path,
source: "configured"
})),
...params.registeredAgentDatabases.map((entry) => ({
agentId: entry.agentId,
path: entry.path,
source: "registry"
})),
...listDefaultAgentDatabaseTargets(params.env, failure)
];
const activeStateDir = resolveStateDir(params.env);
let activeStateDirRealPath;
try {
activeStateDirRealPath = fs.realpathSync.native(activeStateDir);
} catch (error) {
if (!hasErrnoCode(error, "ENOENT")) failure(activeStateDir, `Could not resolve active state directory ${activeStateDir}: ${String(error)}`);
}
const configuredPathMatcher = createOpenClawAgentDatabasePathMatcher();
const targets = [];
const seenRealPaths = /* @__PURE__ */ new Set();
for (const candidate of candidates) {
const pathname = candidate.path;
if (!isPersistentOpenClawAgentDatabasePath(pathname, params.env)) {
discard(candidate, `Removed archived or transient agent database registry entry ${pathname}.`);
continue;
}
let realPath;
try {
realPath = fs.realpathSync.native(pathname);
} catch (error) {
if (!hasErrnoCode(error, "ENOENT")) failure(pathname, `Could not resolve agent database ${pathname}: ${String(error)}`);
}
const isConfiguredPath = realPath !== void 0 && params.configuredAgentDatabaseTargets.some((configuredTarget) => {
if (normalizeAgentId(configuredTarget.agentId) !== normalizeAgentId(candidate.agentId)) return false;
try {
return configuredPathMatcher(pathname, configuredTarget.path);
} catch {
return false;
}
});
const isInsideActiveStateDir = Boolean(realPath && activeStateDirRealPath && (realPath === activeStateDirRealPath || isPathInside(activeStateDirRealPath, realPath)));
if (realPath && !isInsideActiveStateDir && !isConfiguredPath) {
discard(candidate);
const warning = `Skipped foreign agent database ${sanitizeForLog(pathname)}; it is outside the active state directory and is not a configured session store.`;
warnings.push(warning);
externalWarnings.push(warning);
continue;
}
let stat;
try {
stat = fs.statSync(pathname);
} catch (error) {
if (!hasErrnoCode(error, "ENOENT")) {
failure(pathname, `Could not inspect ${candidate.source === "registry" ? "registered " : ""}agent database ${pathname}: ${String(error)}`);
continue;
}
}
if (!stat?.isFile()) {
discard(candidate, `Removed missing agent database registry entry ${pathname}.`);
if (candidate.source === "registry") warnings.push(`Skipped missing registered agent database ${pathname}.`);
continue;
}
if (!realPath) {
discard(candidate);
warnings.push(`Skipped agent database ${pathname}; its filesystem boundary is unresolved.`);
continue;
}
if (seenRealPaths.has(realPath)) continue;
seenRealPaths.add(realPath);
targets.push({
...candidate,
path: pathname,
realPath
});
}
return {
targets,
registryRemovals,
warnings,
externalWarnings,
failures
};
}
/** Migration alone owns cleanup of stale registry entries discovered above. */
function resolveAgentDatabaseMigrationTargets(params) {
let registeredAgentDatabases = [];
try {
registeredAgentDatabases = listOpenClawRegisteredAgentDatabases({
env: params.env,
includeIncompatibleSchemaVersions: true
});
} catch (error) {
params.warnings.push(`Failed enumerating registered agent databases for state migration: ${String(error)}`);
}
const discovery = discoverAgentDatabaseMigrationTargets({
...params,
registeredAgentDatabases
});
for (const removed of discovery.registryRemovals) {
unregisterOpenClawAgentDatabase({
...removed,
env: params.env
});
if (removed.change) params.changes.push(removed.change);
}
params.warnings.push(...discovery.warnings);
return discovery.targets;
}
function listTranscriptArchives(directory) {
let entries;
try {
entries = fs.readdirSync(directory, { withFileTypes: true });
} catch (error) {
if (hasErrnoCode(error, "ENOENT")) return [];
throw error;
}
return entries.filter((entry) => entry.isFile() && entry.name.includes(".jsonl.") && isSessionArchiveArtifactName(entry.name)).map((entry) => path.join(directory, entry.name));
}
//#endregion
export { listTranscriptArchives as n, resolveAgentDatabaseMigrationTargets as r, discoverAgentDatabaseMigrationTargets as t };