mirror of
https://github.com/n8n-io/n8n.git
synced 2026-05-12 16:10:30 +02:00
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> Co-authored-by: Michael Drury <michael.drury@n8n.io> Co-authored-by: Arvin A <51036481+DeveloperTheExplorer@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Arvin Ansari <arvin.ansari@n8n.io> Co-authored-by: bjorger <50590409+bjorger@users.noreply.github.com> Co-authored-by: Eugene <eugene@n8n.io> Co-authored-by: Michael Drury <me@michaeldrury.co.uk> Co-authored-by: Robin Braumann <robin.braumann@n8n.io> Co-authored-by: Rob Hough <robhough180@gmail.com>
92 lines
3.2 KiB
JavaScript
92 lines
3.2 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Pre-bundles @n8n/agents (Tool SDK) + zod into a single CJS string consumed
|
|
* by the V8 isolate at runtime (see src/modules/agents/runtime/agent-secure-runtime.ts).
|
|
*
|
|
* Running this at build time means:
|
|
* - No esbuild on the hot path at first-request
|
|
* - No esbuild native binary needed in the Docker image at runtime
|
|
*
|
|
* Output: packages/cli/dist/agent-library-bundle.js
|
|
*/
|
|
import * as esbuild from 'esbuild';
|
|
import { createRequire } from 'module';
|
|
import path from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
import { writeFileSync, mkdirSync } from 'fs';
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const CLI_ROOT = path.resolve(__dirname, '..');
|
|
const OUTPUT_FILE = path.resolve(CLI_ROOT, 'dist', 'agent-library-bundle.js');
|
|
|
|
export async function buildAgentLibraryBundle({ silent = false } = {}) {
|
|
// Resolve @n8n/agents from the cli package so we get the workspace-linked
|
|
// copy regardless of where this script is invoked from.
|
|
const requireFromCli = createRequire(path.join(CLI_ROOT, 'package.json'));
|
|
const toSlash = (p) => p.replace(/\\/g, '/');
|
|
const agentsPath = toSlash(requireFromCli.resolve('@n8n/agents'));
|
|
const agentsSrcDir = agentsPath.replace(/dist\/index\.js$/, 'dist/');
|
|
|
|
// Import only the Tool builder (needed for describe() + handler execution)
|
|
// rather than the full barrel — the runtime pulls in MCP SDK, AI provider
|
|
// SDKs, database drivers, etc., none of which are usable inside the isolate.
|
|
const shim = `
|
|
const { Tool } = require('${agentsSrcDir}sdk/tool');
|
|
const zod = require('zod');
|
|
|
|
globalThis.__modules = {
|
|
'@n8n/agents': { Tool },
|
|
'zod': zod,
|
|
};
|
|
`;
|
|
|
|
const result = await esbuild.build({
|
|
stdin: { contents: shim, loader: 'js', resolveDir: CLI_ROOT },
|
|
bundle: true,
|
|
format: 'cjs',
|
|
target: 'es2022',
|
|
platform: 'node',
|
|
write: false,
|
|
treeShaking: true,
|
|
// The shim only pulls in `sdk/tool` (+ zod), which is pure JS with no
|
|
// Node built-in or native deps — esbuild currently externalises nothing.
|
|
// `node:*` stays as a safety net so that if some future transitive dep
|
|
// picks up a `node:<builtin>` import, esbuild marks it external rather
|
|
// than trying to bundle a built-in (which would blow up inside the
|
|
// isolate, which has no Node globals anyway).
|
|
external: ['node:*'],
|
|
define: {
|
|
'process.env.NODE_ENV': '"production"',
|
|
},
|
|
});
|
|
|
|
if (result.errors.length > 0) {
|
|
throw new Error(
|
|
`Failed to bundle agent library: ${result.errors.map((e) => e.text).join('\n')}`,
|
|
);
|
|
}
|
|
|
|
const bundle = result.outputFiles[0].text;
|
|
mkdirSync(path.dirname(OUTPUT_FILE), { recursive: true });
|
|
writeFileSync(OUTPUT_FILE, bundle, 'utf8');
|
|
|
|
if (!silent) {
|
|
const sizeKB = (bundle.length / 1024).toFixed(1);
|
|
const sizeMB = (bundle.length / (1024 * 1024)).toFixed(2);
|
|
console.log(
|
|
`[bundle-agent-library] Wrote ${path.relative(CLI_ROOT, OUTPUT_FILE)} — ${sizeKB} KB (${sizeMB} MB)`,
|
|
);
|
|
}
|
|
|
|
return OUTPUT_FILE;
|
|
}
|
|
|
|
// Allow running as a standalone script: `node scripts/bundle-agent-library.mjs`
|
|
const isMain = process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
if (isMain) {
|
|
buildAgentLibraryBundle().catch((e) => {
|
|
console.error(e);
|
|
process.exit(1);
|
|
});
|
|
}
|