UNPKG

@adonis-agora/agent

Version:

Governed, durable-backed AI agent (chat + tool-calling + governance) for AdonisJS — part of the Agora ecosystem.

142 lines • 5.85 kB
/** * Finding the sandbox kit at runtime, the way an app's `@vite()` finds its assets: the Vite plugin * running in this process (dev), the descriptor it wrote (dev, Vite in another process), or the * production manifest (`genui-sandbox-kit.json` and the assets it names). And turning what is found * into what the sandbox definition tells the model and what `GET <agent>/config` tells the browser. */ import { existsSync, readFileSync, statSync } from 'node:fs'; import { join, resolve } from 'node:path'; import { sandboxKitManifestKeys } from './plugin.js'; function readJson(path) { try { return JSON.parse(readFileSync(path, 'utf8')); } catch { return undefined; } } function isDescriptor(value) { return (typeof value === 'object' && value !== null && value.version === 2 && Array.isArray(value.components) && typeof value.assets === 'object'); } /** Find the kit (re-read when the files change — dev rewrites them). */ export function sandboxKitDiscovery(options) { const production = options.production ?? process.env.NODE_ENV === 'production'; const cache = new Map(); const cached = (path) => { if (!existsSync(path)) return undefined; const mtime = statSync(path).mtimeMs; const hit = cache.get(path); if (hit !== undefined && hit.mtime === mtime) return hit.value; const value = readJson(path); cache.set(path, { mtime, value }); return value; }; const mtimeOf = (path) => { try { return statSync(path).mtimeMs; } catch { return 0; } }; /** The build's descriptor, and when it was written. */ const fromManifest = () => { if (options.manifest === undefined) return null; const manifest = cached(resolve(options.root, options.manifest.file)); const file = manifest?.[sandboxKitManifestKeys(options.name).descriptor]?.file; if (file === undefined) return null; const path = join(resolve(options.root, options.manifest.outDir), file); const value = cached(path); return isDescriptor(value) ? { value, mtime: mtimeOf(path) } : null; }; /** The dev server's descriptor file, and when it was written. */ const fromDevFile = () => { if (options.descriptor === undefined) return null; const path = resolve(options.root, options.descriptor); const value = cached(path); return isDescriptor(value) ? { value, mtime: mtimeOf(path) } : null; }; const find = () => { // A dev server in this process is current by definition. const live = options.plugin?.()?.descriptor(); if (live !== undefined && live !== null) return live; const built = fromManifest(); if (production) return built?.value ?? fromDevFile()?.value ?? null; // Outside production, a dev descriptor left over from an earlier `vite dev` must not shadow a // newer build (or the other way round): the one written last wins. const dev = fromDevFile(); if (dev === null || built === null) return dev?.value ?? built?.value ?? null; return dev.mtime >= built.mtime ? dev.value : built.value; }; return { ...(options.name !== undefined ? { name: options.name } : {}), descriptor() { const found = find(); if (found === null || (options.kitUrl === undefined && options.cssUrl === undefined && options.tailwindUrl === undefined)) return found; const assets = { ...found.assets }; if (options.kitUrl !== undefined) assets.kit = { url: options.kitUrl }; if (options.cssUrl !== undefined) assets.css = { url: options.cssUrl }; if (options.tailwindUrl !== undefined) assets.tailwind = { url: options.tailwindUrl, ...(found.assets.tailwind?.css !== undefined ? { css: found.assets.tailwind.css } : {}), }; return { ...found, ...(options.kitUrl !== undefined ? { jsx: true } : {}), assets }; }, }; } /** * `sandbox: { kit: true }` (or `true`) as the definition and the browser need it: docs and theme * names from the discovery, asset urls for the client. What was asked for but not found is left out * of what the browser is told (and of what the model is told), so a missing build degrades to the * plain sandbox. */ export function resolveSandboxServer(sandbox, discovery) { const given = sandbox === true ? {} : sandbox; const kitAsked = given.kit === true; const docs = () => { const found = discovery.descriptor(); return found === null ? undefined : found; }; const themeOn = given.theme !== false; const define = { ...given, ...(kitAsked ? { kit: docs } : {}), ...(themeOn && typeof given.theme !== 'object' ? { theme: { vars: () => docs()?.theme?.vars } } : {}), }; return { define, client() { const kitOn = given.kit !== undefined && given.kit !== false; const assets = kitOn ? discovery.descriptor()?.assets : undefined; return { theme: themeOn, ...(assets !== undefined && discovery.name !== undefined ? { name: discovery.name } : {}), ...(assets?.kit ? { kit: assets.kit } : {}), ...(assets?.css ? { css: assets.css } : {}), ...(assets?.tailwind ? { tailwind: assets.tailwind } : {}), }; }, }; } //# sourceMappingURL=discover.js.map