malepati/custom_template_working
0
1/* This script starts the FastAPI and Next.js servers, setting up user configuration if necessary. It reads environment variables to configure API keys and other settings, ensuring that the user configuration file is created if it doesn't exist. The script also handles the starting of both servers and keeps the Node.js process alive until one of the servers exits. */2 3import { join, dirname } from "path";4import { fileURLToPath } from "url";5import { spawn } from "child_process";6import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";7 8const __filename = fileURLToPath(import.meta.url);9const __dirname = dirname(__filename);10 11const fastapiDir = join(__dirname, "servers/fastapi");12const nextjsDir = join(__dirname, "servers/nextjs");13 14const args = process.argv.slice(2);15const hasDevArg = args.includes("--dev") || args.includes("-d");16const isDev = hasDevArg;17const canChangeKeys = process.env.CAN_CHANGE_KEYS !== "false";18 19const fastapiPort = 8000;20const nextjsPort = 3000;21const appmcpPort = 8001;22 23const userConfigPath = join(process.env.APP_DATA_DIRECTORY, "userConfig.json");24const userDataDir = dirname(userConfigPath);25 26// Create user_data directory if it doesn't exist27if (!existsSync(userDataDir)) {28 mkdirSync(userDataDir, { recursive: true });29}30 31// Setup node_modules for development32const setupNodeModules = () => {33 return new Promise((resolve, reject) => {34 console.log("Setting up node_modules for Next.js...");35 const npmProcess = spawn("npm", ["install"], {36 cwd: nextjsDir,37 stdio: "inherit",38 env: process.env,39 });40 41 npmProcess.on("error", (err) => {42 console.error("npm install failed:", err);43 reject(err);44 });45 46 npmProcess.on("exit", (code) => {47 if (code === 0) {48 console.log("npm install completed successfully");49 resolve();50 } else {51 console.error(`npm install failed with exit code: ${code}`);52 reject(new Error(`npm install failed with exit code: ${code}`));53 }54 });55 });56};57 58process.env.USER_CONFIG_PATH = userConfigPath;59 60//? UserConfig is only setup if API Keys can be changed61const setupUserConfigFromEnv = () => {62 let existingConfig = {};63 64 if (existsSync(userConfigPath)) {65 existingConfig = JSON.parse(readFileSync(userConfigPath, "utf8"));66 }67 68 if (!["ollama", "openai", "google"].includes(existingConfig.LLM)) {69 existingConfig.LLM = undefined;70 }71 72 const userConfig = {73 LLM: process.env.LLM || existingConfig.LLM,74 OPENAI_API_KEY: process.env.OPENAI_API_KEY || existingConfig.OPENAI_API_KEY,75 OPENAI_MODEL: process.env.OPENAI_MODEL || existingConfig.OPENAI_MODEL,76 GOOGLE_API_KEY: process.env.GOOGLE_API_KEY || existingConfig.GOOGLE_API_KEY,77 GOOGLE_MODEL: process.env.GOOGLE_MODEL || existingConfig.GOOGLE_MODEL,78 OLLAMA_URL: process.env.OLLAMA_URL || existingConfig.OLLAMA_URL,79 OLLAMA_MODEL: process.env.OLLAMA_MODEL || existingConfig.OLLAMA_MODEL,80 ANTHROPIC_API_KEY:81 process.env.ANTHROPIC_API_KEY || existingConfig.ANTHROPIC_API_KEY,82 ANTHROPIC_MODEL:83 process.env.ANTHROPIC_MODEL || existingConfig.ANTHROPIC_MODEL,84 CUSTOM_LLM_URL: process.env.CUSTOM_LLM_URL || existingConfig.CUSTOM_LLM_URL,85 CUSTOM_LLM_API_KEY:86 process.env.CUSTOM_LLM_API_KEY || existingConfig.CUSTOM_LLM_API_KEY,87 CUSTOM_MODEL: process.env.CUSTOM_MODEL || existingConfig.CUSTOM_MODEL,88 PEXELS_API_KEY: process.env.PEXELS_API_KEY || existingConfig.PEXELS_API_KEY,89 PIXABAY_API_KEY:90 process.env.PIXABAY_API_KEY || existingConfig.PIXABAY_API_KEY,91 IMAGE_PROVIDER: process.env.IMAGE_PROVIDER || existingConfig.IMAGE_PROVIDER,92 TOOL_CALLS: process.env.TOOL_CALLS || existingConfig.TOOL_CALLS,93 DISABLE_THINKING:94 process.env.DISABLE_THINKING || existingConfig.DISABLE_THINKING,95 EXTENDED_REASONING:96 process.env.EXTENDED_REASONING || existingConfig.EXTENDED_REASONING,97 WEB_GROUNDING: process.env.WEB_GROUNDING || existingConfig.WEB_GROUNDING,98 USE_CUSTOM_URL: process.env.USE_CUSTOM_URL || existingConfig.USE_CUSTOM_URL,99 };100 101 writeFileSync(userConfigPath, JSON.stringify(userConfig));102};103 104const startServers = async () => {105 const fastApiArgs = [106 "server.py",107 "--port",108 fastapiPort.toString(),109 ];110 111 if (isDev) {112 fastApiArgs.push("--reload");113 }114 115 const fastApiProcess = spawn(116 "python",117 fastApiArgs,118 {119 cwd: fastapiDir,120 stdio: "inherit",121 env: process.env,122 }123 );124 125 fastApiProcess.on("error", (err) => {126 console.error("FastAPI process failed to start:", err);127 });128 129 const appmcpProcess = spawn(130 "python",131 ["mcp_server.py", "--port", appmcpPort.toString()],132 {133 cwd: fastapiDir,134 stdio: "ignore",135 env: process.env,136 }137 );138 139 appmcpProcess.on("error", (err) => {140 console.error("App MCP process failed to start:", err);141 });142 143 const nextjsProcess = spawn(144 "npm",145 [146 "run",147 isDev ? "dev" : "start",148 "--",149 "-H",150 "127.0.0.1",151 "-p",152 nextjsPort.toString(),153 ],154 {155 cwd: nextjsDir,156 stdio: "inherit",157 env: process.env,158 }159 );160 161 nextjsProcess.on("error", (err) => {162 console.error("Next.js process failed to start:", err);163 });164 165 const ollamaProcess = spawn("ollama", ["serve"], {166 cwd: "/",167 stdio: "inherit",168 env: process.env,169 });170 171 ollamaProcess.on("error", (err) => {172 console.error("Ollama process failed to start:", err);173 });174 175 // Keep the Node process alive until both servers exit176 const exitCode = await Promise.race([177 new Promise((resolve) => fastApiProcess.on("exit", resolve)),178 new Promise((resolve) => nextjsProcess.on("exit", resolve)),179 new Promise((resolve) => ollamaProcess.on("exit", resolve)),180 ]);181 182 console.log(`One of the processes exited. Exit code: ${exitCode}`);183 process.exit(exitCode);184};185 186// Start nginx service187const startNginx = () => {188 const nginxProcess = spawn("service", ["nginx", "start"], {189 stdio: "inherit",190 env: process.env,191 });192 193 nginxProcess.on("error", (err) => {194 console.error("Nginx process failed to start:", err);195 });196 197 nginxProcess.on("exit", (code) => {198 if (code === 0) {199 console.log("Nginx started successfully");200 } else {201 console.error(`Nginx failed to start with exit code: ${code}`);202 }203 });204};205 206const main = async () => {207 if (isDev) {208 await setupNodeModules();209 }210 211 if (canChangeKeys) {212 setupUserConfigFromEnv();213 }214 215 startServers();216 startNginx();217};218 219main();220 