UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

166 lines (165 loc) • 7.62 kB
import { c as isRecord } from "./record-coerce-TIsquoVR.mjs"; import { i as getNodeSqliteKysely, n as executeSqliteQuerySync } from "./kysely-sync-BMSZn9yz.mjs"; import { i as tableExists } from "./openclaw-state-db-schema-helpers-DsjDX6BL.mjs"; //#region src/agents/sandbox/registry.kernel.ts function rowToUpdate(row) { const { registry_kind: _registryKind, container_name: _containerName, ...update } = row; return update; } function insertSandboxRegistryRowInDatabase(db, row) { executeSqliteQuerySync(db, getNodeSqliteKysely(db).insertInto("sandbox_registry_entries").values(row).onConflict((conflict) => conflict.columns(["registry_kind", "container_name"]).doUpdateSet(rowToUpdate(row)))); } function assertSandboxRegistryReservationCurrent(current, expected) { if (!current || current.runtimeState === "removing" || current.runtimeState === "removing-pending" || current.backendId !== expected.backendId || current.sessionKey !== expected.sessionKey) throw new Error("Sandbox runtime was removed or is being removed; retry after sandbox recreate completes."); } function removeContainerRegistryRowInDatabase(db, containerName) { executeSqliteQuerySync(db, getNodeSqliteKysely(db).deleteFrom("sandbox_registry_entries").where("registry_kind", "=", "container").where("container_name", "=", containerName)); } function writeSandboxRegistryInDatabase(db, write) { if (write.operation === "remove") { if (write.preserveRemovalIntent) { const row = readSandboxRegistryRowInDatabase(db, "container", write.containerName); const current = row ? rowToContainerEntry(row) : null; if (current?.runtimeState === "removing" || current?.runtimeState === "removing-pending") return; } removeContainerRegistryRowInDatabase(db, write.containerName); return; } const { entry } = write; const row = readSandboxRegistryRowInDatabase(db, "container", entry.containerName); const existing = row ? rowToContainerEntry(row) : null; if (write.operation === "update") { if (entry.runtimeState === "pending" && existing?.runtimeState !== void 0) assertSandboxRegistryReservationCurrent(existing, entry); insertSandboxRegistryRowInDatabase(db, containerEntryToRow(entry, existing)); return; } assertSandboxRegistryReservationCurrent(existing, entry); if (write.retired) removeContainerRegistryRowInDatabase(db, entry.containerName); else insertSandboxRegistryRowInDatabase(db, containerEntryToRow({ ...entry, runtimeState: "ready" }, { ...existing, image: existing.runtimeState === "pending" ? entry.image : existing.image })); } 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, runtimeState: entry.runtimeState ?? existing?.runtimeState, workspaceDir: existing?.workspaceDir ?? entry.workspaceDir }; 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, workspaceDir: entry.workspaceDir ?? existing?.workspaceDir }; 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 insertSandboxRegistryRowIfMissingInDatabase(db, row) { executeSqliteQuerySync(db, getNodeSqliteKysely(db).insertInto("sandbox_registry_entries").values(row).onConflict((conflict) => conflict.columns(["registry_kind", "container_name"]).doNothing())); } function parseRegistryEntryJson(row) { try { const parsed = JSON.parse(row.entry_json); return isRecord(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 normalizeSandboxRegistryEntry(entry) { return { ...entry, backendId: entry.backendId?.trim() || "docker", runtimeLabel: entry.runtimeLabel?.trim() || entry.containerName, configLabelKind: entry.configLabelKind?.trim() || "Image" }; } function readSandboxRegistryEntryInDatabase(db, containerName) { if (!tableExists(db, "sandbox_registry_entries")) return null; const row = readSandboxRegistryRowInDatabase(db, "container", containerName); return row ? rowToContainerEntry(row) : null; } function readSandboxRegistryRowInDatabase(db, kind, containerName) { return executeSqliteQuerySync(db, getNodeSqliteKysely(db).selectFrom("sandbox_registry_entries").selectAll().where("registry_kind", "=", kind).where("container_name", "=", containerName).limit(1)).rows[0] ?? null; } //#endregion export { insertSandboxRegistryRowInDatabase as a, rowToBrowserEntry as c, insertSandboxRegistryRowIfMissingInDatabase as i, rowToContainerEntry as l, browserEntryToRow as n, readSandboxRegistryEntryInDatabase as o, containerEntryToRow as r, readSandboxRegistryRowInDatabase as s, assertSandboxRegistryReservationCurrent as t, writeSandboxRegistryInDatabase as u };