(options: ServerOptions)
| 57 | * Express + WS, and loads adapters (Web always, IM adapters if configured). |
| 58 | */ |
| 59 | export async function startServer(options: ServerOptions): Promise<void> { |
| 60 | const { |
| 61 | rootDir, |
| 62 | host = process.env.HOST || "127.0.0.1", |
| 63 | port = Number(process.env.PORT) || 26313, |
| 64 | runtimeMode = process.env.SKILLPACK_RUNTIME_MODE === "embedded" |
| 65 | ? "embedded" |
| 66 | : "standalone", |
| 67 | } = options; |
| 68 | |
| 69 | // --------------------------------------------------------------------------- |
| 70 | // Read runtime configuration: data/config.json first, env vars override |
| 71 | // --------------------------------------------------------------------------- |
| 72 | |
| 73 | const dataConfig = configManager.load(rootDir); |
| 74 | const apiKey = dataConfig.apiKey || ""; |
| 75 | const provider = dataConfig.provider || "openai"; |
| 76 | const canonicalRootDir = canonicalizeDir(rootDir); |
| 77 | const packConfig = loadPackConfig(canonicalRootDir); |
| 78 | const baseUrl = dataConfig.baseUrl?.trim() || undefined; |
| 79 | |
| 80 | const modelId = |
| 81 | dataConfig.modelId?.trim() || |
| 82 | (SUPPORTED_PROVIDERS[provider]?.defaultModelId ?? SUPPORTED_PROVIDERS.openai.defaultModelId); |
| 83 | const apiProtocol = dataConfig.apiProtocol; |
| 84 | const reasoning = dataConfig.reasoning; |
| 85 | |
| 86 | // --------------------------------------------------------------------------- |
| 87 | // Create Express app & HTTP server |
| 88 | // --------------------------------------------------------------------------- |
| 89 | |
| 90 | // Resolve web directory: prefer rootDir/web, fallback to package-distributed web/ |
| 91 | const packageRoot = path.resolve(__dirname, ".."); |
| 92 | const webDir = fs.existsSync(path.join(rootDir, "web")) |
| 93 | ? path.join(rootDir, "web") |
| 94 | : path.join(packageRoot, "web"); |
| 95 | |
| 96 | const app = express(); |
| 97 | app.use(express.json()); |
| 98 | app.use(express.static(webDir)); |
| 99 | |
| 100 | const server = createServer(app); |
| 101 | app.get("/api/health", (_req, res) => { |
| 102 | const address = server.address(); |
| 103 | const actualPort = typeof address === "string" ? port : (address?.port ?? port); |
| 104 | res.json({ |
| 105 | status: "ok", |
| 106 | dir: canonicalRootDir, |
| 107 | name: packConfig.name, |
| 108 | version: packConfig.version, |
| 109 | port: actualPort, |
| 110 | pid: process.pid, |
| 111 | }); |
| 112 | }); |
| 113 | |
| 114 | const lifecycle = new Lifecycle(server); |
| 115 | |
| 116 | // --------------------------------------------------------------------------- |
no test coverage detected