/ src / lib / agent-sandbox-defaults.ts
agent-sandbox-defaults.ts
 1  import type { Agent } from '@/types'
 2  import {
 3    DEFAULT_SANDBOX_BROWSER_AUTOSTART_TIMEOUT_MS,
 4    DEFAULT_SANDBOX_BROWSER_CDP_PORT,
 5    DEFAULT_SANDBOX_BROWSER_ENABLE_NOVNC,
 6    DEFAULT_SANDBOX_BROWSER_HEADLESS,
 7    DEFAULT_SANDBOX_BROWSER_IMAGE,
 8    DEFAULT_SANDBOX_BROWSER_MOUNT_UPLOADS,
 9    DEFAULT_SANDBOX_BROWSER_NETWORK,
10    DEFAULT_SANDBOX_BROWSER_NOVNC_PORT,
11    DEFAULT_SANDBOX_BROWSER_PREFIX,
12    DEFAULT_SANDBOX_BROWSER_VNC_PORT,
13    DEFAULT_SANDBOX_CONTAINER_PREFIX,
14    DEFAULT_SANDBOX_IMAGE,
15    DEFAULT_SANDBOX_PRUNE_IDLE_HOURS,
16    DEFAULT_SANDBOX_PRUNE_MAX_AGE_DAYS,
17    DEFAULT_SANDBOX_WORKDIR,
18  } from '@/lib/sandbox-defaults'
19  
20  export type AgentSandboxConfig = NonNullable<Agent['sandboxConfig']>
21  
22  export const DEFAULT_AGENT_SANDBOX_CONFIG: AgentSandboxConfig = {
23    enabled: true,
24    mode: 'all',
25    scope: 'session',
26    workspaceAccess: 'rw',
27    image: DEFAULT_SANDBOX_IMAGE,
28    network: 'bridge',
29    memoryMb: 512,
30    cpus: 1,
31    readonlyRoot: false,
32    workdir: DEFAULT_SANDBOX_WORKDIR,
33    containerPrefix: DEFAULT_SANDBOX_CONTAINER_PREFIX,
34    pidsLimit: 256,
35    browser: {
36      enabled: true,
37      image: DEFAULT_SANDBOX_BROWSER_IMAGE,
38      containerPrefix: DEFAULT_SANDBOX_BROWSER_PREFIX,
39      network: DEFAULT_SANDBOX_BROWSER_NETWORK,
40      cdpPort: DEFAULT_SANDBOX_BROWSER_CDP_PORT,
41      vncPort: DEFAULT_SANDBOX_BROWSER_VNC_PORT,
42      noVncPort: DEFAULT_SANDBOX_BROWSER_NOVNC_PORT,
43      headless: DEFAULT_SANDBOX_BROWSER_HEADLESS,
44      enableNoVnc: DEFAULT_SANDBOX_BROWSER_ENABLE_NOVNC,
45      mountUploads: DEFAULT_SANDBOX_BROWSER_MOUNT_UPLOADS,
46      autoStartTimeoutMs: DEFAULT_SANDBOX_BROWSER_AUTOSTART_TIMEOUT_MS,
47    },
48    prune: {
49      idleHours: DEFAULT_SANDBOX_PRUNE_IDLE_HOURS,
50      maxAgeDays: DEFAULT_SANDBOX_PRUNE_MAX_AGE_DAYS,
51    },
52  }
53  
54  function asRecord(value: unknown): Record<string, unknown> | null {
55    if (!value || typeof value !== 'object' || Array.isArray(value)) return null
56    return value as Record<string, unknown>
57  }
58  
59  export function normalizeAgentSandboxConfig(config: Agent['sandboxConfig'] | unknown): AgentSandboxConfig {
60    const input = asRecord(config)
61    const hasBrowser = Boolean(input && Object.prototype.hasOwnProperty.call(input, 'browser'))
62    const hasPrune = Boolean(input && Object.prototype.hasOwnProperty.call(input, 'prune'))
63    const browserInput = hasBrowser
64      ? (input?.browser === null ? null : asRecord(input?.browser))
65      : undefined
66    const pruneInput = hasPrune
67      ? (input?.prune === null ? null : asRecord(input?.prune))
68      : undefined
69  
70    return {
71      ...DEFAULT_AGENT_SANDBOX_CONFIG,
72      ...(input ?? {}),
73      enabled: typeof input?.enabled === 'boolean' ? input.enabled : DEFAULT_AGENT_SANDBOX_CONFIG.enabled,
74      browser: browserInput === undefined
75        ? DEFAULT_AGENT_SANDBOX_CONFIG.browser
76        : browserInput === null
77        ? null
78        : {
79            ...DEFAULT_AGENT_SANDBOX_CONFIG.browser,
80            ...(browserInput ?? {}),
81          },
82      prune: pruneInput === undefined
83        ? DEFAULT_AGENT_SANDBOX_CONFIG.prune
84        : pruneInput === null
85        ? null
86        : {
87            ...DEFAULT_AGENT_SANDBOX_CONFIG.prune,
88            ...(pruneInput ?? {}),
89          },
90    }
91  }