darkfire514's picture
Upload 2526 files
fb4d8fe verified
import fs from "node:fs/promises";
import type { OpenClawConfig } from "../../config/config.js";
import type { SandboxContext, SandboxWorkspaceInfo } from "./types.js";
import { DEFAULT_BROWSER_EVALUATE_ENABLED } from "../../browser/constants.js";
import { defaultRuntime } from "../../runtime.js";
import { resolveUserPath } from "../../utils.js";
import { syncSkillsToWorkspace } from "../skills.js";
import { DEFAULT_AGENT_WORKSPACE_DIR } from "../workspace.js";
import { ensureSandboxBrowser } from "./browser.js";
import { resolveSandboxConfigForAgent } from "./config.js";
import { ensureSandboxContainer } from "./docker.js";
import { maybePruneSandboxes } from "./prune.js";
import { resolveSandboxRuntimeStatus } from "./runtime-status.js";
import { resolveSandboxScopeKey, resolveSandboxWorkspaceDir } from "./shared.js";
import { ensureSandboxWorkspace } from "./workspace.js";
export async function resolveSandboxContext(params: {
config?: OpenClawConfig;
sessionKey?: string;
workspaceDir?: string;
}): Promise<SandboxContext | null> {
const rawSessionKey = params.sessionKey?.trim();
if (!rawSessionKey) {
return null;
}
const runtime = resolveSandboxRuntimeStatus({
cfg: params.config,
sessionKey: rawSessionKey,
});
if (!runtime.sandboxed) {
return null;
}
const cfg = resolveSandboxConfigForAgent(params.config, runtime.agentId);
await maybePruneSandboxes(cfg);
const agentWorkspaceDir = resolveUserPath(
params.workspaceDir?.trim() || DEFAULT_AGENT_WORKSPACE_DIR,
);
const workspaceRoot = resolveUserPath(cfg.workspaceRoot);
const scopeKey = resolveSandboxScopeKey(cfg.scope, rawSessionKey);
const sandboxWorkspaceDir =
cfg.scope === "shared" ? workspaceRoot : resolveSandboxWorkspaceDir(workspaceRoot, scopeKey);
const workspaceDir = cfg.workspaceAccess === "rw" ? agentWorkspaceDir : sandboxWorkspaceDir;
if (workspaceDir === sandboxWorkspaceDir) {
await ensureSandboxWorkspace(
sandboxWorkspaceDir,
agentWorkspaceDir,
params.config?.agents?.defaults?.skipBootstrap,
);
if (cfg.workspaceAccess !== "rw") {
try {
await syncSkillsToWorkspace({
sourceWorkspaceDir: agentWorkspaceDir,
targetWorkspaceDir: sandboxWorkspaceDir,
config: params.config,
});
} catch (error) {
const message = error instanceof Error ? error.message : JSON.stringify(error);
defaultRuntime.error?.(`Sandbox skill sync failed: ${message}`);
}
}
} else {
await fs.mkdir(workspaceDir, { recursive: true });
}
const containerName = await ensureSandboxContainer({
sessionKey: rawSessionKey,
workspaceDir,
agentWorkspaceDir,
cfg,
});
const evaluateEnabled =
params.config?.browser?.evaluateEnabled ?? DEFAULT_BROWSER_EVALUATE_ENABLED;
const browser = await ensureSandboxBrowser({
scopeKey,
workspaceDir,
agentWorkspaceDir,
cfg,
evaluateEnabled,
});
return {
enabled: true,
sessionKey: rawSessionKey,
workspaceDir,
agentWorkspaceDir,
workspaceAccess: cfg.workspaceAccess,
containerName,
containerWorkdir: cfg.docker.workdir,
docker: cfg.docker,
tools: cfg.tools,
browserAllowHostControl: cfg.browser.allowHostControl,
browser: browser ?? undefined,
};
}
export async function ensureSandboxWorkspaceForSession(params: {
config?: OpenClawConfig;
sessionKey?: string;
workspaceDir?: string;
}): Promise<SandboxWorkspaceInfo | null> {
const rawSessionKey = params.sessionKey?.trim();
if (!rawSessionKey) {
return null;
}
const runtime = resolveSandboxRuntimeStatus({
cfg: params.config,
sessionKey: rawSessionKey,
});
if (!runtime.sandboxed) {
return null;
}
const cfg = resolveSandboxConfigForAgent(params.config, runtime.agentId);
const agentWorkspaceDir = resolveUserPath(
params.workspaceDir?.trim() || DEFAULT_AGENT_WORKSPACE_DIR,
);
const workspaceRoot = resolveUserPath(cfg.workspaceRoot);
const scopeKey = resolveSandboxScopeKey(cfg.scope, rawSessionKey);
const sandboxWorkspaceDir =
cfg.scope === "shared" ? workspaceRoot : resolveSandboxWorkspaceDir(workspaceRoot, scopeKey);
const workspaceDir = cfg.workspaceAccess === "rw" ? agentWorkspaceDir : sandboxWorkspaceDir;
if (workspaceDir === sandboxWorkspaceDir) {
await ensureSandboxWorkspace(
sandboxWorkspaceDir,
agentWorkspaceDir,
params.config?.agents?.defaults?.skipBootstrap,
);
if (cfg.workspaceAccess !== "rw") {
try {
await syncSkillsToWorkspace({
sourceWorkspaceDir: agentWorkspaceDir,
targetWorkspaceDir: sandboxWorkspaceDir,
config: params.config,
});
} catch (error) {
const message = error instanceof Error ? error.message : JSON.stringify(error);
defaultRuntime.error?.(`Sandbox skill sync failed: ${message}`);
}
}
} else {
await fs.mkdir(workspaceDir, { recursive: true });
}
return {
workspaceDir,
containerWorkdir: cfg.docker.workdir,
};
}