feat(core): implement SandboxManager interface and config schema (#21774)

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
Gal Zahavi
2026-03-11 14:42:50 -07:00
committed by GitHub
parent 926dddf0bf
commit e3b3b71c14
15 changed files with 1074 additions and 214 deletions
+41 -4
View File
@@ -8,6 +8,7 @@ import * as fs from 'node:fs';
import * as path from 'node:path';
import { inspect } from 'node:util';
import process from 'node:process';
import { z } from 'zod';
import {
AuthType,
createContentGenerator,
@@ -96,7 +97,6 @@ import type {
import { ModelAvailabilityService } from '../availability/modelAvailabilityService.js';
import { ModelRouterService } from '../routing/modelRouterService.js';
import { OutputFormat } from '../output/types.js';
//import { type AgentLoopContext } from './agent-loop-context.js';
import {
ModelConfigService,
type ModelConfig,
@@ -451,10 +451,36 @@ export enum AuthProviderType {
}
export interface SandboxConfig {
command: 'docker' | 'podman' | 'sandbox-exec' | 'runsc' | 'lxc';
image: string;
enabled: boolean;
allowedPaths?: string[];
networkAccess?: boolean;
command?: 'docker' | 'podman' | 'sandbox-exec' | 'runsc' | 'lxc';
image?: string;
}
export const ConfigSchema = z.object({
sandbox: z
.object({
enabled: z.boolean().default(false),
allowedPaths: z.array(z.string()).default([]),
networkAccess: z.boolean().default(false),
command: z
.enum(['docker', 'podman', 'sandbox-exec', 'runsc', 'lxc'])
.optional(),
image: z.string().optional(),
})
.superRefine((data, ctx) => {
if (data.enabled && !data.command) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'Sandbox command is required when sandbox is enabled',
path: ['command'],
});
}
})
.optional(),
});
/**
* Callbacks for checking MCP server enablement status.
* These callbacks are provided by the CLI package to bridge
@@ -956,7 +982,6 @@ export class Config implements McpContext, AgentLoopContext {
this.truncateToolOutputThreshold =
params.truncateToolOutputThreshold ??
DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD;
// // TODO(joshualitt): Re-evaluate the todo tool for 3 family.
this.useWriteTodos = isPreviewModel(this.model)
? false
: (params.useWriteTodos ?? true);
@@ -1617,6 +1642,18 @@ export class Config implements McpContext, AgentLoopContext {
return this.sandbox;
}
getSandboxEnabled(): boolean {
return this.sandbox?.enabled ?? false;
}
getSandboxAllowedPaths(): string[] {
return this.sandbox?.allowedPaths ?? [];
}
getSandboxNetworkAccess(): boolean {
return this.sandbox?.networkAccess ?? false;
}
isRestrictiveSandbox(): boolean {
const sandboxConfig = this.getSandbox();
const seatbeltProfile = process.env['SEATBELT_PROFILE'];