import type { ModalClient } from 'modal'; import { isIsolatedRuntimeSchedulerSchema } from './runtime-scheduler-topology'; import { STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS, validatePlaySandboxRuntimeLimits, type PlaySandboxRuntimeLimits, } from './sandbox-runtime-limits'; export const MODAL_RUNNER_APP_NAME = 'deepline-play-runner'; export const MODAL_RUNNER_IMAGE = 'node:20-bookworm-slim'; export const MODAL_RUNNER_WORKDIR = '/root/deepline'; // Modal bills one physical core as two vCPUs. This matches the standard // Deepline one-vCPU / one-GiB sandbox. export const MODAL_SANDBOX_CPU_CORES = 0.5; export const MODAL_SANDBOX_MEMORY_MIB = 1024; export type ModalRequiredConfig = { client: ModalClient; appName: string; image: string; workdir: string; outboundCidrAllowlist: string[] | null; limits: PlaySandboxRuntimeLimits; }; export type ModalClientConfig = Omit< ModalRequiredConfig, 'outboundCidrAllowlist' | 'limits' >; function requiredEnv( env: NodeJS.ProcessEnv, name: 'MODAL_TOKEN_ID' | 'MODAL_TOKEN_SECRET', ): string { const value = env[name]?.trim(); if (!value) throw new Error(`Missing required Modal configuration: ${name}.`); return value; } function cidrAllowlist(raw: string | null | undefined): string[] | null { const values = (raw ?? '') .split(',') .map((value) => value.trim()) .filter(Boolean) .filter((value) => !value.includes(':')); return values.length > 0 ? values : null; } export function resolveModalSandboxNetworkPolicy(input: { runtimeSchedulerSchema: string | null | undefined; env?: NodeJS.ProcessEnv; }): { outboundCidrAllowlist: string[] | null } { const env = input.env ?? process.env; const outboundCidrAllowlist = cidrAllowlist( env.DEEPLINE_DAYTONA_NETWORK_ALLOW_LIST, ); if ( !outboundCidrAllowlist && env.NODE_ENV === 'production' && !isIsolatedRuntimeSchedulerSchema(input.runtimeSchedulerSchema) ) { throw new Error( 'DEEPLINE_DAYTONA_NETWORK_ALLOW_LIST is required for the Modal capacity fallback in production. Refusing to run customer code with unrestricted outbound network access.', ); } return { outboundCidrAllowlist }; } export async function loadModalRequiredConfig(input: { env?: NodeJS.ProcessEnv; runtimeSchedulerSchema?: string | null; limits?: PlaySandboxRuntimeLimits | null; }): Promise { const env = input.env ?? process.env; const clientConfig = await loadModalClientConfig({ env }); const { outboundCidrAllowlist } = resolveModalSandboxNetworkPolicy({ env, runtimeSchedulerSchema: input.runtimeSchedulerSchema, }); return { ...clientConfig, outboundCidrAllowlist, limits: validatePlaySandboxRuntimeLimits( input.limits ?? { ...STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS }, ), }; } export async function loadModalClientConfig( input: { env?: NodeJS.ProcessEnv } = {}, ): Promise { const env = input.env ?? process.env; const tokenId = requiredEnv(env, 'MODAL_TOKEN_ID'); const tokenSecret = requiredEnv(env, 'MODAL_TOKEN_SECRET'); const { ModalClient } = await import('modal'); return { client: new ModalClient({ tokenId, tokenSecret }), appName: env.DEEPLINE_MODAL_RUNNER_APP_NAME?.trim() || MODAL_RUNNER_APP_NAME, image: env.DEEPLINE_MODAL_RUNNER_IMAGE?.trim() || MODAL_RUNNER_IMAGE, workdir: env.DEEPLINE_MODAL_RUNNER_WORKDIR?.trim() || MODAL_RUNNER_WORKDIR, }; }