import fs from "node:fs"; import path from "node:path"; import {
DEFAULT_SANDBOX_BROWSER_IMAGE,
DEFAULT_SANDBOX_COMMON_IMAGE,
DEFAULT_SANDBOX_IMAGE,
resolveSandboxScope,
} from "../agents/sandbox.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { runCommandWithTimeout, runExec } from "../process/exec.js"; import type { RuntimeEnv } from "../runtime.js"; import { note } from "../terminal/note.js"; import type { DoctorPrompter } from "./doctor-prompter.js";
type SandboxScriptInfo = {
scriptPath: string;
cwd: string;
};
function resolveSandboxScript(scriptRel: string): SandboxScriptInfo | null { const candidates = new Set<string>();
candidates.add(process.cwd()); const argv1 = process.argv[1]; if (argv1) { const normalized = path.resolve(argv1);
candidates.add(path.resolve(path.dirname(normalized), ".."));
candidates.add(path.resolve(path.dirname(normalized)));
}
for (const root of candidates) { const scriptPath = path.join(root, scriptRel); if (fs.existsSync(scriptPath)) { return { scriptPath, cwd: root };
}
}
returnnull;
}
async function runSandboxScript(scriptRel: string, runtime: RuntimeEnv): Promise<boolean> { const script = resolveSandboxScript(scriptRel); if (!script) {
note(`Unable to locate ${scriptRel}. Run it from the repo root.`, "Sandbox"); returnfalse;
}
const buildHint = params.buildScript
? `Build it with ${params.buildScript}.`
: "Build or pull it first.";
note(`Sandbox ${params.kind} image missing: ${params.image}. ${buildHint}`, "Sandbox");
let built = false; if (params.buildScript) { const build = await prompter.confirmRuntimeRepair({
message: `Build ${params.kind} sandbox image now?`,
initialValue: true,
}); if (build) {
built = await runSandboxScript(params.buildScript, runtime);
}
}
if (built) { return;
}
}
export async function maybeRepairSandboxImages(
cfg: OpenClawConfig,
runtime: RuntimeEnv,
prompter: DoctorPrompter,
): Promise<OpenClawConfig> { const sandbox = cfg.agents?.defaults?.sandbox; const mode = sandbox?.mode ?? "off"; if (!sandbox || mode === "off") { return cfg;
} const backend = resolveSandboxBackend(cfg); if (backend !== "docker") { if (sandbox.browser?.enabled) {
note(
`Sandbox backend "${backend}" selected. Docker browser health checks are skipped; browser sandbox currently requires the docker backend.`, "Sandbox",
);
} return cfg;
}
const dockerAvailable = await isDockerAvailable(); if (!dockerAvailable) { const lines = [
`Sandbox mode is enabled (mode: "${mode}") but Docker is not available.`, "Docker is required for sandbox mode to function.", "Isolated sessions (cron jobs, sub-agents) will fail without Docker.", "", "Options:", "- Install Docker and restart the gateway", "- Disable sandbox mode: openclaw config set agents.defaults.sandbox.mode off",
];
note(lines.join("\n"), "Sandbox"); return cfg;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.