feat(sandbox): support agent-specific sandbox config override

Changes to defaultSandboxConfig():
- Add optional agentId parameter
- Load routing.agents[agentId].sandbox if available
- Prefer agent-specific settings over global agent.sandbox

Update callers in resolveSandboxContext() and
ensureSandboxWorkspaceForSession() to extract agentId
from sessionKey and pass it to defaultSandboxConfig().

This enables per-agent sandbox modes (e.g., main: off, family: all).
This commit is contained in:
sheeek
2026-01-07 11:58:12 +01:00
parent cc9fdfe562
commit 1e3caf07d4

View File

@@ -226,16 +226,26 @@ function resolveSandboxScopeKey(scope: SandboxScope, sessionKey: string) {
return `agent:${agentId}`;
}
function defaultSandboxConfig(cfg?: ClawdbotConfig): SandboxConfig {
function defaultSandboxConfig(cfg?: ClawdbotConfig, agentId?: string): SandboxConfig {
const agent = cfg?.agent?.sandbox;
// Agent-specific sandbox config overrides global
let agentSandbox: typeof agent | undefined;
if (agentId && cfg?.routing?.agents) {
const agentConfig = cfg.routing.agents[agentId];
if (agentConfig && typeof agentConfig === "object") {
agentSandbox = agentConfig.sandbox;
}
}
return {
mode: agent?.mode ?? "off",
mode: agentSandbox?.mode ?? agent?.mode ?? "off",
scope: resolveSandboxScope({
scope: agent?.scope,
perSession: agent?.perSession,
scope: agentSandbox?.scope ?? agent?.scope,
perSession: agentSandbox?.perSession ?? agent?.perSession,
}),
workspaceAccess: agent?.workspaceAccess ?? "none",
workspaceRoot: agent?.workspaceRoot ?? DEFAULT_SANDBOX_WORKSPACE_ROOT,
workspaceAccess: agentSandbox?.workspaceAccess ?? agent?.workspaceAccess ?? "none",
workspaceRoot: agentSandbox?.workspaceRoot ?? agent?.workspaceRoot ?? DEFAULT_SANDBOX_WORKSPACE_ROOT,
docker: {
image: agent?.docker?.image ?? DEFAULT_SANDBOX_IMAGE,
containerPrefix:
@@ -924,7 +934,8 @@ export async function resolveSandboxContext(params: {
}): Promise<SandboxContext | null> {
const rawSessionKey = params.sessionKey?.trim();
if (!rawSessionKey) return null;
const cfg = defaultSandboxConfig(params.config);
const agentId = resolveAgentIdFromSessionKey(rawSessionKey);
const cfg = defaultSandboxConfig(params.config, agentId);
const mainKey = params.config?.session?.mainKey?.trim() || "main";
if (!shouldSandboxSession(cfg, rawSessionKey, mainKey)) return null;
@@ -986,7 +997,8 @@ export async function ensureSandboxWorkspaceForSession(params: {
}): Promise<SandboxWorkspaceInfo | null> {
const rawSessionKey = params.sessionKey?.trim();
if (!rawSessionKey) return null;
const cfg = defaultSandboxConfig(params.config);
const agentId = resolveAgentIdFromSessionKey(rawSessionKey);
const cfg = defaultSandboxConfig(params.config, agentId);
const mainKey = params.config?.session?.mainKey?.trim() || "main";
if (!shouldSandboxSession(cfg, rawSessionKey, mainKey)) return null;