(config: ServerConfig, deps: ServerDependencies)
| 398 | `session binding refreshed: generation=${binding.wrapperGeneration ?? 'none'} connectionId=${binding.wrapperConnectionId ?? 'none'}` |
| 399 | ); |
| 400 | if (state.isConnected) { |
| 401 | await deps.closeConnection(); |
| 402 | } |
| 403 | deps.resetLifecycle(); |
| 404 | if (feedPolicy === 'restart') { |
| 405 | await notifySessionBound(deps, feedPolicy); |
| 406 | } |
| 407 | } |
| 408 | return null; |
| 409 | } |
| 410 | |
| 411 | // --------------------------------------------------------------------------- |
| 412 | // Route Handlers |
| 413 | // --------------------------------------------------------------------------- |
| 414 | |
| 415 | function createHealthHandler( |
| 416 | config: ServerConfig, |
| 417 | state: WrapperState, |
| 418 | toolCgroupHealth?: () => ToolCgroupHealth | null |
| 419 | ) { |
| 420 | return (): Response => { |
| 421 | const toolCgroup = toolCgroupHealth?.() ?? null; |
| 422 | return jsonResponse({ |
| 423 | healthy: true, |
| 424 | state: state.isActive ? 'active' : 'idle', |
| 425 | version: config.version, |
| 426 | sessionId: config.sessionId, |
| 427 | ...(config.wrapperInstanceId ? { wrapperInstanceId: config.wrapperInstanceId } : {}), |
| 428 | ...(config.wrapperInstanceGeneration !== undefined |
| 429 | ? { wrapperInstanceGeneration: config.wrapperInstanceGeneration } |
| 430 | : {}), |
| 431 | pendingMessages: state.pendingMessageIds.length, |
| 432 | ...(toolCgroup ? { toolCgroup } : {}), |
| 433 | }); |
| 434 | }; |
| 435 | } |
| 436 | |
| 437 | function createStatusHandler(state: WrapperState) { |
| 438 | return (): Response => { |
| 439 | return jsonResponse(state.getStatus()); |
| 440 | }; |
| 441 | } |
| 442 | |
| 443 | /** |
| 444 | * When a kilo client call fails because the server process itself is gone, |
| 445 | * proactively restart the runtime so the next attempt hits a live server |
| 446 | * instead of repeating the same connection failure. Fire-and-forget from the |
| 447 | * caller's perspective — the restart can take as long as a full kilo server |
| 448 | * startup, and the failing HTTP response should not wait on it. `restartKiloRuntime` |
| 449 | * is responsible for deduping concurrent calls into a single in-flight restart. |
| 450 | */ |
| 451 | function restartRuntimeIfServerUnreachable( |
| 452 | error: unknown, |
| 453 | deps: ServerDependencies, |
| 454 | logContext: string |
| 455 | ): void { |
| 456 | if (!isKiloServerUnreachableError(error)) return; |
| 457 | logToFile(`${logContext}: kilo server appears unreachable, restarting runtime`); |
no test coverage detected