/** * slides/07-sandbox-providers.js * ---------------------------------------------------------------------------- * Slide 07 -- Sandbox providers: comparison * Table of Modal / Daytona / Runloop / LangSmith. */ 'use strict'; const { helpers, layouts } = require('../../design-system'); function buildSandboxProviders(pres, theme) { const slide = pres.addSlide(); helpers.slideBase(slide, pres, theme); helpers.addHeader(slide, pres, theme, { eyebrow: 'STAGE 4', sectionNumber: 4, title: 'Sandbox-провайдеры', }); // Comparison table card const x = 0.5; const y = layouts.CONTENT_TOP; const w = 9.0; const h = 3.55; slide.addShape(pres.ShapeType.roundRect, { x: x, y: y, w: w, h: h, fill: { color: theme.palette.bg.elevated }, line: { color: theme.palette.border.subtle, width: 1 }, rectRadius: 0.08, }); // Table headers const cols = [ { label: 'Provider', w: 1.6 }, { label: 'Setup', w: 1.9 }, { label: 'Pricing model', w: 1.7 }, { label: 'Persistent state', w: 1.6 }, { label: 'Best for', w: 2.2 }, ]; const headerY = y + 0.1; let cx = x + 0.15; cols.forEach(function (c) { slide.addShape(pres.ShapeType.rect, { x: cx, y: headerY, w: c.w, h: 0.32, fill: { color: theme.palette.bg.code }, line: { color: theme.palette.border.subtle, width: 0.5 }, }); slide.addText(c.label, { x: cx + 0.05, y: headerY, w: c.w - 0.1, h: 0.32, fontFace: helpers.withFallback(theme.fonts.ui), fontSize: theme.sizes.caption, color: theme.palette.accent.tertiary, bold: true, charSpacing: 2, valign: 'middle', }); cx += c.w; }); const rows = [ ['ModalBackend', 'token_id + token_secret', 'per-second + GB-s', 'yes (volume)', 'Python-first, GPU-доступный'], ['DaytonaBackend','api_key', 'per-session', 'yes (volume)', 'default в README'], ['RunloopBackend','api_key', 'per-second', 'yes (volume)', 'dev-цикл, snapshot/restart'], ['LangSmithBackend','LANGSMITH_API_KEY', 'через LangSmith', 'через LS', 'уже платите за LangSmith'], ]; const rowH = 0.7; rows.forEach(function (row, idx) { const ry = headerY + 0.32 + idx * rowH; cx = x + 0.15; row.forEach(function (cell, cidx) { slide.addShape(pres.ShapeType.rect, { x: cx, y: ry, w: cols[cidx].w, h: rowH, fill: { color: idx % 2 === 0 ? theme.palette.bg.primary : theme.palette.bg.overlay }, line: { color: theme.palette.border.subtle, width: 0.4 }, }); slide.addText(cell, { x: cx + 0.05, y: ry, w: cols[cidx].w - 0.1, h: rowH, fontFace: helpers.withFallback(theme.fonts.code), fontSize: 9, color: theme.palette.text.primary, valign: 'middle', }); cx += cols[cidx].w; }); }); helpers.addPageNumber(slide, pres, theme, 7); helpers.addSourceLine(slide, pres, theme, { source: 'research/per-tech/openswe.md: 78-89, 139-145', }); return slide; } module.exports = { buildSandboxProviders };