Skip to content

Server Routes

GodeX runs on Bun's built-in HTTP server and exposes a small, purposeful set of routes. Three endpoints cover the full operational surface: a health check for load balancers, a model listing for client discovery, and the primary /v1/responses endpoint that accepts OpenAI-compatible requests and either returns a synchronous JSON response or streams Server-Sent Events. Every route is wired through ApplicationContext, giving handlers access to the resolver, logger, provider registrar, and session store without global singletons.

At a Glance

AspectDetail
HTTP serverBun.serve with static route map
Routes/health, /v1/models, /v1/responses
StreamingSSE via ResponseSseEncoder
Error handlingresponseRouteErrorToResponse with structured logging
Request tracingTraceRecordingContext per request

Route Map

Routes are registered in createBuiltinRoutes at src/server/server.ts:21-27. The server is started via startServer at line 29, which passes the route map to Bun.serve along with hostname, port, and an idle timeout. Unmatched paths fall through to a default fetch handler that returns a 404 JSON error.

/health

handleHealth at src/server/routes/health.ts:3-13 returns a JSON object with:

FieldTypeDescription
statusstringAlways "ok"
timestampnumberDate.now() at request time
providersstring[]Registered provider IDs
unsupported_providersstring[]Providers in config but not registered

/v1/models

handleModels at src/server/routes/models.ts:9-19 uses the ModelResolver to list configured aliases filtered to registered providers.

Response format (OpenAI-compatible):

json
{
  "object": "list",
  "data": [
    { "id": "gpt-4", "object": "model", "owned_by": "deepseek" }
  ]
}

/v1/responses Request Lifecycle

Step 1: Request Parsing

parseResponseRequest at src/server/routes/responses/request-parser.ts:13-70 validates:

CheckError CodeStatus
Valid JSON bodyserver.request.invalid_json400
Body is an objectserver.request.invalid_parameter400
No previous_response_id + conversation conflictserver.request.invalid_parameter400

Step 2: Context Creation

createResponsesContext resolves the model, loads any session chain referenced by previous_response_id, and creates a request-scoped logger with a unique requestId.

Step 3: Dispatch

dispatchResponseRequest at src/server/routes/responses/response-dispatcher.ts:7-21 branches on ctx.request.stream:

  • Sync -- calls app.responses.request(ctx) and returns Response.json().
  • Stream -- calls app.responses.stream(ctx), pipes through ResponseSseEncoder, and returns with SSE headers.

SSE Headers

sseHeaders at src/server/routes/responses/sse.ts:1-7 sets:

Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

Error Handling

responseRouteErrorToResponse at src/server/routes/responses/error-handler.ts:12-50 handles errors in priority order, records trace errors, and attaches the x-request-id header when available.

Request Logging

Each request is logged via responseRequestLogEntry at src/server/routes/responses/request-log.ts:4-25, which captures:

FieldDescription
modelClient-specified model selector
resolvedProvider + model after resolution
streamWhether streaming was requested
previous_response_idSession chain reference
storeWhether response should be persisted
input_countNumber of input items
tools_countNumber of tool definitions

Cross-References

References