UNPKG

aaab

Version:

Advanced AI Agent Builder - A comprehensive framework for building AI agents with TypeScript support

482 lines (416 loc) 12.5 kB
const fs = require('fs'); // const _path = require('path'); // Unused for now const console = require('../utils/console'); class AABBDeployer { constructor() { this.deploymentStrategies = { replit: new ReplitDeployment(), docker: new DockerDeployment(), serverless: new ServerlessDeployment(), kubernetes: new KubernetesDeployment(), }; } async deploy(strategy, options = {}) { console.header('Deploying AAAB Application', `Strategy: ${strategy}`); const deployer = this.deploymentStrategies[strategy]; if (!deployer) { throw new Error(`Unknown deployment strategy: ${strategy}`); } return await deployer.deploy(options); } generateDockerfile(options = {}) { const nodeVersion = options.nodeVersion || '18-alpine'; const port = options.port || 5000; return `FROM node:${nodeVersion} # Set working directory WORKDIR /app # Install curl for health checks RUN apk add --no-cache curl # Copy package files COPY package*.json ./ # Install dependencies RUN npm ci --only=production && npm cache clean --force # Copy application code COPY . . # Create agents directory RUN mkdir -p agents # Create non-root user for security RUN addgroup -g 1001 -S nodejs && \\ adduser -S aaab -u 1001 # Change ownership of the app directory RUN chown -R aaab:nodejs /app USER aaab # Expose port EXPOSE ${port} # Health check HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\ CMD curl -f http://localhost:${port}/health || exit 1 # Start application CMD ["npm", "start"] `; } generatePackageJson(options = {}) { const port = options.port || 5000; return { name: options.appName || 'aaab-app', version: '1.0.0', description: 'AAAB Agent Application', main: 'bin/aaab.js', scripts: { start: `node bin/aaab.js serve --port ${port}`, serve: `node bin/aaab.js serve --port ${port}`, dev: `node bin/aaab.js serve --port ${port} --watch`, test: 'echo "No tests specified" && exit 0', }, dependencies: { 'ajv': '^8.17.1', 'ajv-formats': '^3.0.1', 'chalk': '^4.1.2', 'chokidar': '^4.0.3', 'commander': '^14.0.0', 'cors': '^2.8.5', 'express': '^5.1.0', 'express-rate-limit': '^8.0.1', 'helmet': '^8.1.0', 'morgan': '^1.10.1', 'openai': '^4.28.0', '@google/generative-ai': '^0.21.0', 'jsonwebtoken': '^9.0.2', 'bcryptjs': '^2.4.3', 'dotenv': '^16.4.1', }, engines: { node: '>=18.0.0', }, }; } generateK8sManifest(options = {}) { const appName = options.appName || 'aaab-app'; const image = options.image || 'aaab:latest'; const replicas = options.replicas || 2; const port = options.port || 5000; return `apiVersion: apps/v1 kind: Deployment metadata: name: ${appName} labels: app: ${appName} spec: replicas: ${replicas} selector: matchLabels: app: ${appName} template: metadata: labels: app: ${appName} spec: containers: - name: ${appName} image: ${image} ports: - containerPort: ${port} env: - name: NODE_ENV value: "production" - name: PORT value: "${port}" - name: AAAB_ENCRYPTION_KEY valueFrom: secretKeyRef: name: ${appName}-secrets key: encryption-key - name: OPENAI_API_KEY valueFrom: secretKeyRef: name: ${appName}-secrets key: openai-api-key resources: requests: memory: "128Mi" cpu: "100m" limits: memory: "512Mi" cpu: "500m" livenessProbe: httpGet: path: /health port: ${port} initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /health port: ${port} initialDelaySeconds: 5 periodSeconds: 5 --- apiVersion: v1 kind: Service metadata: name: ${appName}-service spec: selector: app: ${appName} ports: - protocol: TCP port: 80 targetPort: ${port} type: LoadBalancer --- apiVersion: v1 kind: Secret metadata: name: ${appName}-secrets type: Opaque data: encryption-key: <base64-encoded-encryption-key> openai-api-key: <base64-encoded-openai-key> `; } generateServerlessConfig(options = {}) { const functionName = options.functionName || 'aaab-function'; const runtime = options.runtime || 'nodejs18.x'; return { service: functionName, provider: { name: 'aws', runtime: runtime, environment: { NODE_ENV: 'production', AAAB_ENCRYPTION_KEY: '${env:AAAB_ENCRYPTION_KEY}', OPENAI_API_KEY: '${env:OPENAI_API_KEY}', }, iam: { role: { statements: [ { Effect: 'Allow', Action: [ 'logs:CreateLogGroup', 'logs:CreateLogStream', 'logs:PutLogEvents', ], Resource: 'arn:aws:logs:*:*:*', }, ], }, }, }, functions: { app: { handler: 'serverless.handler', events: [ { http: { path: '/{proxy+}', method: 'ANY', cors: true, }, }, ], environment: { AAAB_ENCRYPTION_KEY: '${env:AAAB_ENCRYPTION_KEY}', OPENAI_API_KEY: '${env:OPENAI_API_KEY}', }, }, }, }; } generateRailwayConfig(_options = {}) { return { build: { builder: 'nixpacks', }, deploy: { startCommand: 'npm start', healthcheckPath: '/health', healthcheckTimeout: 300, restartPolicyType: 'ON_FAILURE', restartPolicyMaxRetries: 10, }, }; } generateVercelConfig(_options = {}) { return { version: 2, builds: [ { src: 'bin/aaab.js', use: '@vercel/node', }, ], routes: [ { src: '/(.*)', dest: '/bin/aaab.js', }, ], env: { NODE_ENV: 'production', }, }; } } class ReplitDeployment { async deploy(_options) { console.section('Replit Deployment'); // Generate Replit-specific files const replitConfig = { run: 'npm start', language: 'nodejs', entrypoint: 'bin/aaab.js', }; fs.writeFileSync('.replit', Object.entries(replitConfig) .map(([key, value]) => `${key} = "${value}"`) .join('\n')); // Generate replit.nix for dependencies const replitNix = `{ pkgs }: { deps = [ pkgs.nodejs-18_x pkgs.nodePackages.npm ]; }`; fs.writeFileSync('replit.nix', replitNix); console.success('Generated .replit configuration'); console.success('Generated replit.nix for dependencies'); console.info('Ready for Replit deployment'); console.info('Click the "Deploy" button in Replit to go live!'); return { status: 'ready', platform: 'replit' }; } } class DockerDeployment { async deploy(options) { console.section('Docker Deployment'); const deployer = new AABBDeployer(); const dockerfile = deployer.generateDockerfile(options); const packageJson = deployer.generatePackageJson(options); fs.writeFileSync('Dockerfile', dockerfile); console.success('Generated Dockerfile'); // Update package.json with proper scripts if (fs.existsSync('package.json')) { const existingPackage = JSON.parse(fs.readFileSync('package.json', 'utf8')); existingPackage.scripts = { ...existingPackage.scripts, ...packageJson.scripts }; fs.writeFileSync('package.json', JSON.stringify(existingPackage, null, 2)); console.success('Updated package.json with deployment scripts'); } else { fs.writeFileSync('package.json', JSON.stringify(packageJson, null, 2)); console.success('Generated package.json'); } // Generate docker-compose.yml const dockerCompose = `version: '3.8' services: aaab: build: . ports: - "${options.port || 5000}:${options.port || 5000}" environment: - NODE_ENV=production - PORT=${options.port || 5000} - AAAB_ENCRYPTION_KEY=${process.env.AAAB_ENCRYPTION_KEY || 'your-encryption-key'} - OPENAI_API_KEY=${process.env.OPENAI_API_KEY || ''} volumes: - ./agents:/app/agents:ro restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:${options.port || 5000}/health"] interval: 30s timeout: 10s retries: 3 start_period: 40s `; fs.writeFileSync('docker-compose.yml', dockerCompose); console.success('Generated docker-compose.yml'); // Generate .dockerignore const dockerignore = `node_modules npm-debug.log .git .gitignore README.md .env .aaab-secrets *.log .DS_Store `; fs.writeFileSync('.dockerignore', dockerignore); console.success('Generated .dockerignore'); console.info('Build and run with:'); console.info('• docker build -t aaab .'); console.info('• docker run -p 5000:5000 -e OPENAI_API_KEY=your-key aaab'); console.info('Or use: docker-compose up'); return { status: 'ready', platform: 'docker' }; } } class ServerlessDeployment { async deploy(options) { console.section('Serverless Deployment'); const deployer = new AABBDeployer(); const config = deployer.generateServerlessConfig(options); fs.writeFileSync('serverless.yml', JSON.stringify(config, null, 2)); console.success('Generated serverless.yml'); // Generate serverless handler const handler = `const serverless = require('serverless-http'); const AABBServer = require('./lib/server/express-server'); const server = new AABBServer({ port: process.env.PORT || 5000, enableAuth: false, // Disable auth for serverless cors: { origin: '*', credentials: false } }); module.exports.handler = serverless(server.app); `; fs.writeFileSync('serverless.js', handler); console.success('Generated serverless handler'); // Generate package.json for serverless const serverlessPackage = { name: 'aaab-serverless', version: '1.0.0', main: 'serverless.js', dependencies: { 'serverless-http': '^3.2.0', }, }; fs.writeFileSync('serverless-package.json', JSON.stringify(serverlessPackage, null, 2)); console.success('Generated serverless-package.json'); console.info('Deploy with:'); console.info('• npm install -g serverless'); console.info('• serverless deploy'); return { status: 'ready', platform: 'serverless' }; } } class KubernetesDeployment { async deploy(options) { console.section('Kubernetes Deployment'); const deployer = new AABBDeployer(); const manifest = deployer.generateK8sManifest(options); fs.writeFileSync('k8s-manifest.yml', manifest); console.success('Generated Kubernetes manifest'); // Generate deployment script const deployScript = `#!/bin/bash # AAAB Kubernetes Deployment Script echo "Building Docker image..." docker build -t ${options.image || 'aaab:latest'} . echo "Creating Kubernetes secrets..." kubectl create secret generic ${options.appName || 'aaab-app'}-secrets \\ --from-literal=encryption-key="${process.env.AAAB_ENCRYPTION_KEY || 'your-key'}" \\ --from-literal=openai-api-key="${process.env.OPENAI_API_KEY || ''}" \\ --dry-run=client -o yaml | kubectl apply -f - echo "Deploying to Kubernetes..." kubectl apply -f k8s-manifest.yml echo "Checking deployment status..." kubectl get pods -l app=${options.appName || 'aaab-app'} echo "Deployment complete!" `; fs.writeFileSync('deploy-k8s.sh', deployScript); fs.chmodSync('deploy-k8s.sh', '755'); console.success('Generated deploy-k8s.sh script'); console.info('Deploy with:'); console.info('• chmod +x deploy-k8s.sh'); console.info('• ./deploy-k8s.sh'); console.info('Or manually: kubectl apply -f k8s-manifest.yml'); return { status: 'ready', platform: 'kubernetes' }; } } module.exports = AABBDeployer;