openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
202 lines (201 loc) • 9.58 kB
JavaScript
import { a as getNodeSqliteKysely, r as executeSqliteQuerySync } from "./kysely-sync-COmh4HWh.js";
import { E as tableExists } from "./openclaw-state-db-cache-C7ljO0xP.js";
import { r as withExistingOpenClawStateDatabaseReadOnly } from "./openclaw-state-db-readonly-BRgmrGHt.js";
import { s as runOpenClawStateWriteTransaction } from "./openclaw-state-db-BRTnL-D8.js";
//#region src/agents/sandbox/registry.ts
function getSandboxRegistryKysely(db) {
return getNodeSqliteKysely(db);
}
function parseRegistryEntryJson(row) {
try {
const parsed = JSON.parse(row.entry_json);
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
} catch {
return null;
}
}
function optionalPayloadString(value) {
return typeof value === "string" ? value : "";
}
function rowToContainerEntry(row) {
if (row.registry_kind !== "container") return null;
const payload = parseRegistryEntryJson(row);
if (!payload) return null;
return normalizeSandboxRegistryEntry({
...payload,
containerName: row.container_name,
sessionKey: row.session_key ?? optionalPayloadString(payload.sessionKey),
createdAtMs: row.created_at_ms ?? Number(payload.createdAtMs ?? 0),
lastUsedAtMs: row.last_used_at_ms ?? Number(payload.lastUsedAtMs ?? 0),
image: row.image ?? optionalPayloadString(payload.image),
...row.backend_id != null ? { backendId: row.backend_id } : {},
...row.runtime_label != null ? { runtimeLabel: row.runtime_label } : {},
...row.config_label_kind != null ? { configLabelKind: row.config_label_kind } : {},
...row.config_hash != null ? { configHash: row.config_hash } : {}
});
}
function rowToBrowserEntry(row) {
if (row.registry_kind !== "browser") return null;
const payload = parseRegistryEntryJson(row);
if (!payload) return null;
return {
...payload,
containerName: row.container_name,
sessionKey: row.session_key ?? optionalPayloadString(payload.sessionKey),
createdAtMs: row.created_at_ms ?? Number(payload.createdAtMs ?? 0),
lastUsedAtMs: row.last_used_at_ms ?? Number(payload.lastUsedAtMs ?? 0),
image: row.image ?? optionalPayloadString(payload.image),
cdpPort: row.cdp_port ?? Number(payload.cdpPort ?? 0),
...row.no_vnc_port != null ? { noVncPort: row.no_vnc_port } : {},
...row.config_hash != null ? { configHash: row.config_hash } : {}
};
}
function containerEntryToRow(entry, existing) {
const next = {
...entry,
backendId: entry.backendId ?? existing?.backendId,
backendTarget: entry.backendTarget ?? existing?.backendTarget,
runtimeLabel: entry.runtimeLabel ?? existing?.runtimeLabel,
createdAtMs: existing?.createdAtMs ?? entry.createdAtMs,
image: existing?.image ?? entry.image,
configLabelKind: entry.configLabelKind ?? existing?.configLabelKind,
configHash: entry.configHash ?? existing?.configHash
};
return {
registry_kind: "container",
container_name: next.containerName,
session_key: next.sessionKey,
backend_id: next.backendId ?? null,
runtime_label: next.runtimeLabel ?? null,
image: next.image,
created_at_ms: next.createdAtMs,
last_used_at_ms: next.lastUsedAtMs,
config_label_kind: next.configLabelKind ?? null,
config_hash: next.configHash ?? null,
cdp_port: null,
no_vnc_port: null,
entry_json: JSON.stringify(next),
updated_at: Date.now()
};
}
function browserEntryToRow(entry, existing) {
const next = {
...entry,
createdAtMs: existing?.createdAtMs ?? entry.createdAtMs,
image: existing?.image ?? entry.image,
configHash: entry.configHash ?? existing?.configHash
};
return {
registry_kind: "browser",
container_name: next.containerName,
session_key: next.sessionKey,
backend_id: null,
runtime_label: null,
image: next.image,
created_at_ms: next.createdAtMs,
last_used_at_ms: next.lastUsedAtMs,
config_label_kind: null,
config_hash: next.configHash ?? null,
cdp_port: next.cdpPort,
no_vnc_port: next.noVncPort ?? null,
entry_json: JSON.stringify(next),
updated_at: Date.now()
};
}
function rowToUpdate(row) {
const { registry_kind: _registryKind, container_name: _containerName, ...update } = row;
return update;
}
function readRegistryRows(kind, filter) {
return withExistingOpenClawStateDatabaseReadOnly(({ db }) => {
if (!tableExists(db, "sandbox_registry_entries")) return [];
let query = getSandboxRegistryKysely(db).selectFrom("sandbox_registry_entries").selectAll().where("registry_kind", "=", kind);
if (filter) query = query.where("session_key", "=", filter.scopeKey).where("backend_id", "=", filter.backendId);
return executeSqliteQuerySync(db, filter ? query.orderBy("last_used_at_ms", "desc").orderBy("container_name", "asc") : query.orderBy("container_name", "asc")).rows;
}) ?? [];
}
function readRegistryRow(kind, containerName) {
return withExistingOpenClawStateDatabaseReadOnly(({ db }) => {
if (!tableExists(db, "sandbox_registry_entries")) return null;
const stateDb = getSandboxRegistryKysely(db);
return executeSqliteQuerySync(db, stateDb.selectFrom("sandbox_registry_entries").selectAll().where("registry_kind", "=", kind).where("container_name", "=", containerName).limit(1)).rows[0] ?? null;
}) ?? null;
}
function insertRegistryRowIfMissing(row) {
runOpenClawStateWriteTransaction(({ db }) => {
const stateDb = getSandboxRegistryKysely(db);
executeSqliteQuerySync(db, stateDb.insertInto("sandbox_registry_entries").values(row).onConflict((conflict) => conflict.columns(["registry_kind", "container_name"]).doNothing()));
});
}
function insertRegistryRow(db, row) {
const stateDb = getSandboxRegistryKysely(db);
executeSqliteQuerySync(db, stateDb.insertInto("sandbox_registry_entries").values(row).onConflict((conflict) => conflict.columns(["registry_kind", "container_name"]).doUpdateSet(rowToUpdate(row))));
}
function readRegistryRowFromDb(db, kind, containerName) {
const stateDb = getSandboxRegistryKysely(db);
return executeSqliteQuerySync(db, stateDb.selectFrom("sandbox_registry_entries").selectAll().where("registry_kind", "=", kind).where("container_name", "=", containerName).limit(1)).rows[0] ?? null;
}
function removeRegistryRow(kind, containerName) {
runOpenClawStateWriteTransaction(({ db }) => {
const stateDb = getSandboxRegistryKysely(db);
executeSqliteQuerySync(db, stateDb.deleteFrom("sandbox_registry_entries").where("registry_kind", "=", kind).where("container_name", "=", containerName));
});
}
function normalizeSandboxRegistryEntry(entry) {
return {
...entry,
backendId: entry.backendId?.trim() || "docker",
runtimeLabel: entry.runtimeLabel?.trim() || entry.containerName,
configLabelKind: entry.configLabelKind?.trim() || "Image"
};
}
/** Reads all registered sandbox runtime containers from SQLite. */
async function readRegistry() {
return { entries: readRegistryRows("container").map((row) => rowToContainerEntry(row)).filter((entry) => entry != null).map((entry) => normalizeSandboxRegistryEntry(entry)) };
}
/** Reads one registered sandbox runtime container by container name. */
async function readRegistryEntry(containerName) {
const row = readRegistryRow("container", containerName);
const entry = row ? rowToContainerEntry(row) : null;
return entry ? normalizeSandboxRegistryEntry(entry) : null;
}
/** Reads registered runtime IDs for one backend-owned sandbox scope, newest first. */
async function readRegisteredSandboxRuntimeIds(params) {
return readRegistryRows("container", params).map((row) => rowToContainerEntry(row)).filter((entry) => entry != null).map((entry) => entry.containerName);
}
/** Inserts one sandbox runtime registry entry without replacing an existing entry. */
function insertSandboxRegistryEntryIfMissing(entry) {
insertRegistryRowIfMissing(containerEntryToRow(entry));
}
/** Creates or updates one sandbox runtime registry entry, preserving immutable creation fields. */
async function updateRegistry(entry) {
runOpenClawStateWriteTransaction(({ db }) => {
const existingRow = readRegistryRowFromDb(db, "container", entry.containerName);
insertRegistryRow(db, containerEntryToRow(entry, existingRow ? rowToContainerEntry(existingRow) : null));
});
}
/** Removes one sandbox runtime registry entry by container name. */
async function removeRegistryEntry(containerName) {
removeRegistryRow("container", containerName);
}
/** Reads all registered browser sandbox containers from SQLite. */
async function readBrowserRegistry() {
return { entries: readRegistryRows("browser").map((row) => rowToBrowserEntry(row)).filter((entry) => entry != null) };
}
/** Inserts one browser sandbox registry entry without replacing an existing entry. */
function insertSandboxBrowserRegistryEntryIfMissing(entry) {
insertRegistryRowIfMissing(browserEntryToRow(entry));
}
/** Creates or updates one browser sandbox registry entry, preserving immutable creation fields. */
async function updateBrowserRegistry(entry) {
runOpenClawStateWriteTransaction(({ db }) => {
const existingRow = readRegistryRowFromDb(db, "browser", entry.containerName);
insertRegistryRow(db, browserEntryToRow(entry, existingRow ? rowToBrowserEntry(existingRow) : null));
});
}
/** Removes one browser sandbox registry entry by container name. */
async function removeBrowserRegistryEntry(containerName) {
removeRegistryRow("browser", containerName);
}
//#endregion
export { readRegistry as a, removeRegistryEntry as c, readRegisteredSandboxRuntimeIds as i, updateBrowserRegistry as l, insertSandboxRegistryEntryIfMissing as n, readRegistryEntry as o, readBrowserRegistry as r, removeBrowserRegistryEntry as s, insertSandboxBrowserRegistryEntryIfMissing as t, updateRegistry as u };