UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

95 lines (94 loc) 4.48 kB
import { r as resolveRealpathOrAbsolute } from "./boundary-path-DMNeww4q.js"; import { i as isMigrationArchiveArtifactName } from "./artifacts-DMDO9PHy.js"; import { t as runTasksWithConcurrency } from "./run-with-concurrency-Dtu208ef.js"; import { n as listDurableSqliteTargetPathsForSessionStorePath } from "./session-sqlite-target-Dp-kgpcT.js"; import fs from "node:fs"; import path from "node:path"; //#region src/config/sessions/disk-budget-files.ts const SESSIONS_DIR_STAT_CONCURRENCY = 8; async function readSessionsDirFiles(sessionsDir) { const tasks = (await fs.promises.readdir(sessionsDir, { withFileTypes: true }).catch(() => [])).filter((dirent) => dirent.isFile() && !isMigrationArchiveArtifactName(dirent.name)).map((dirent) => async () => { const filePath = path.join(sessionsDir, dirent.name); const stat = await fs.promises.stat(filePath).catch(() => null); if (!stat?.isFile()) return null; return { path: filePath, canonicalPath: resolveRealpathOrAbsolute(filePath), name: dirent.name, size: stat.size, mtimeMs: stat.mtimeMs }; }); const { results } = await runTasksWithConcurrency({ tasks, limit: SESSIONS_DIR_STAT_CONCURRENCY }); return results.filter((file) => Boolean(file)); } async function readSqliteDatabaseFiles(databasePaths) { const files = []; for (const databasePath of databasePaths) for (const filePath of [databasePath, `${databasePath}-wal`]) { const stat = await fs.promises.stat(filePath).catch(() => null); if (!stat?.isFile()) continue; files.push({ path: filePath, canonicalPath: resolveRealpathOrAbsolute(filePath), name: path.basename(filePath), size: stat.size, mtimeMs: stat.mtimeMs }); } return files; } /** Measures current physical session artifacts plus the agent SQLite main file and WAL. */ async function readSessionPhysicalDiskUsage(storePath) { const sessionsDirFiles = await readSessionsDirFiles(path.dirname(storePath)); const promptBlobFiles = await readSessionPromptBlobFiles(path.dirname(storePath)); const databaseFiles = await readSqliteDatabaseFiles(listDurableSqliteTargetPathsForSessionStorePath(storePath)); const databaseMainPaths = new Set(databaseFiles.filter((file) => !file.path.endsWith("-wal")).map((file) => file.canonicalPath)); const databaseWalPaths = new Set(databaseFiles.filter((file) => file.path.endsWith("-wal")).map((file) => file.canonicalPath)); const uniqueFiles = /* @__PURE__ */ new Map(); for (const file of [ ...sessionsDirFiles, ...promptBlobFiles, ...databaseFiles ]) uniqueFiles.set(file.canonicalPath, file); const databaseMainBytes = [...databaseMainPaths].reduce((sum, databasePath) => sum + (uniqueFiles.get(databasePath)?.size ?? 0), 0); const databaseWalBytes = [...databaseWalPaths].reduce((sum, databasePath) => sum + (uniqueFiles.get(databasePath)?.size ?? 0), 0); const totalBytes = [...uniqueFiles.values()].reduce((sum, file) => sum + file.size, 0); return { databaseMainBytes, databaseWalBytes, sessionFilesBytes: totalBytes - databaseMainBytes - databaseWalBytes, totalBytes }; } async function readSessionPromptBlobFiles(sessionsDir) { const root = path.join(sessionsDir, "skills-prompts", "sha256"); const prefixEntries = await fs.promises.readdir(root, { withFileTypes: true }).catch(() => []); const files = []; for (const prefixEntry of prefixEntries) { if (!prefixEntry.isDirectory() || !/^[a-f0-9]{2}$/u.test(prefixEntry.name)) continue; const prefixDir = path.join(root, prefixEntry.name); const blobEntries = await fs.promises.readdir(prefixDir, { withFileTypes: true }).catch(() => []); for (const blobEntry of blobEntries) { if (!blobEntry.isFile() || !/^[a-f0-9]{64}\.txt$/u.test(blobEntry.name) && !isSessionPromptBlobTempArtifactName(blobEntry.name)) continue; const filePath = path.join(prefixDir, blobEntry.name); const stat = await fs.promises.stat(filePath).catch(() => null); if (!stat?.isFile()) continue; files.push({ path: filePath, canonicalPath: resolveRealpathOrAbsolute(filePath), name: blobEntry.name, size: stat.size, mtimeMs: stat.mtimeMs }); } } return files; } function isSessionPromptBlobTempArtifactName(name) { return /^[a-f0-9]{64}\.txt\.(?:\d+\.)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.tmp$/u.test(name); } //#endregion export { readSessionsDirFiles as i, readSessionPhysicalDiskUsage as n, readSessionPromptBlobFiles as r, isSessionPromptBlobTempArtifactName as t };