(config: RuntimeNodeServeConfig)
| 142 | } |
| 143 | |
| 144 | export async function startRuntimeNodeServe(config: RuntimeNodeServeConfig): Promise<RuntimeNodeHttpServer> { |
| 145 | const agentExecutor = createRuntimeNodeHarnessAgentExecutor() |
| 146 | const runtime = createRuntimeNodeServer({ |
| 147 | serverName: "runtime-node", |
| 148 | serverVersion: process.env.RELEASE ?? "headless", |
| 149 | checkpointStore: createRuntimeNodeCheckpointStore(config.checkpointFile ?? defaultCheckpointFile()), |
| 150 | }) |
| 151 | const bridgeRegistry = createRuntimeNodeAgentBridgeRegistry() |
| 152 | const bridgeRegistrations: Array<{ bridge: RuntimeNodeCodexAppServerBridge; unregister: () => void }> = [] |
| 153 | const cleanupRuntimeModules: Array<() => void> = [] |
| 154 | for (const bridgeConfig of config.codexAppServers ?? []) { |
| 155 | const bridge = createRuntimeNodeCodexAppServerBridge({ |
| 156 | ...bridgeConfig, |
| 157 | onNotification(method, params) { |
| 158 | notifyRuntimeNodeAgentBridgeEvent(runtime, method, params) |
| 159 | }, |
| 160 | }) |
| 161 | bridgeRegistrations.push({ bridge, unregister: registerRuntimeNodeServerProtocolAgentBridge(bridge, bridgeRegistry) }) |
| 162 | } |
| 163 | const processAdapter = createRuntimeNodeLocalProcessAdapter() |
| 164 | const ptyAdapter = createRuntimeNodeLocalPtyAdapter() |
| 165 | registerRuntimeNodeFilesModule(runtime, createRuntimeNodeLocalFilesAdapter()) |
| 166 | registerRuntimeNodeGitModule(runtime, createRuntimeNodeLocalGitAdapter()) |
| 167 | cleanupRuntimeModules.push(registerRuntimeNodeProcessModule(runtime, processAdapter)) |
| 168 | cleanupRuntimeModules.push(registerRuntimeNodePtyModule(runtime, ptyAdapter)) |
| 169 | cleanupRuntimeModules.push(registerRuntimeNodeFsWatchModule(runtime)) |
| 170 | registerRuntimeNodeAgentModule(runtime, agentExecutor, { bridgeRegistry }) |
| 171 | |
| 172 | const options: RuntimeNodeHttpServerOptions = { |
| 173 | runtime, |
| 174 | host: config.host, |
| 175 | port: config.port, |
| 176 | path: config.path, |
| 177 | token: config.token, |
| 178 | allowUnauthenticatedLoopback: config.allowUnauthenticatedLoopback, |
| 179 | } |
| 180 | const server = await serveRuntimeNodeHttp(options) |
| 181 | return { |
| 182 | ...server, |
| 183 | async close() { |
| 184 | try { |
| 185 | await Promise.all(bridgeRegistrations.map(({ bridge }) => bridge.disconnect())) |
| 186 | await Promise.all([processAdapter.killAll(), ptyAdapter.killAll()]) |
| 187 | } finally { |
| 188 | for (const cleanup of cleanupRuntimeModules.splice(0).reverse()) cleanup() |
| 189 | for (const { unregister } of bridgeRegistrations) unregister() |
| 190 | await server.close() |
| 191 | } |
| 192 | }, |
| 193 | } |
| 194 | } |
| 195 | |
| 196 | export async function startRuntimeNodeCli(args: string[] = process.argv.slice(2), env: NodeJS.ProcessEnv = process.env): Promise<RuntimeNodeHttpServer> { |
| 197 | if (args[0] !== "serve") { |
no test coverage detected