Documentation
¶
Overview ¶
Package server provides the HTTP server for BuildMax.
Route handling lives in the handlers sub-package:
- server/handlers — all HTTP handlers in one package, grouped by domain file: auth.go (OTP/login + JWT middleware), spaces.go, agents.go, usage.go, issues.go, workflows.go, conversations.go, tasks.go, artifacts.go, files.go, stream.go, ws.go, webhook_keys.go, inbound_webhook.go, worker.go.
This package wires handlers.NewHandler, holds server Config, and serves healthz, openapi, swagger, CORS, and request-logging middleware.
Index ¶
- Constants
- type AuthConfig
- type Config
- type ConversationConfig
- type ReadinessCheck
- type Server
- func (s *Server) Drain()
- func (s *Server) Draining() bool
- func (s *Server) Handler() http.Handler
- func (s *Server) ListenAndServe() error
- func (s *Server) Shutdown(ctx context.Context) error
- func (s *Server) StartBackground()
- func (s *Server) StopBackground(ctx context.Context)
- func (s *Server) WorkerHandler() http.Handler
- type ServicesConfig
- type ShutdownBudget
- type StorageConfig
- type StoresConfig
- type WebhookConfig
- type WorkerConfig
Constants ¶
const DefaultShutdownGrace = 25 * time.Second
DefaultShutdownGrace is the whole budget for an orderly stop when the deployment configures none.
It sits under the Kubernetes default terminationGracePeriodSeconds of 30 with room for a preStop hook, so a deployment that changed nothing still finishes its ladder before the kubelet kills it.
const RequestIDHeader = "X-Request-Id"
RequestIDHeader returns the request's correlation id to the caller, so a bug report can name the request instead of describing it.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AuthConfig ¶
type AuthConfig struct {
JWTSecret string // Required for login when UserStore is set
AllowSignup bool // Open POST /api/otp/request to self-registration; closed by default
CORSOrigin string // If set, enable CORS with this origin (e.g. "http://localhost:5173")
// PublicBaseURL is the externally reachable origin at which people open
// BuildMax. Artifact share links are rendered against it; empty refuses
// share creation rather than emitting an unreachable link.
PublicBaseURL string
QuotaService *quota.Service // Optional; when set, create chat/run enforce quota and return 429 when exceeded
DefaultQuotaTier string // Default quota tier for new users (e.g. signup); used when calling CreateUser
// Token lifetimes; zero means the default in internal/core/identity.
AccessTokenTTL time.Duration
RefreshTokenTTL time.Duration
RefreshRotationGrace time.Duration
}
AuthConfig holds auth and CORS settings plus optional quota for signup and create-chat/run.
type Config ¶
type Config struct {
Addr string // Public listen address (e.g. ":5678")
// WorkerAddr is the internal worker-control listener address (e.g.
// "127.0.0.1:5679"). Empty leaves the worker listener off, which is what a
// test that only builds the public handler wants; the server binary always
// sets it. The worker routes are registered on their own mux regardless, so
// WorkerHandler is testable without opening a second socket. See
// docs/design/worker-api-network-boundary.md.
WorkerAddr string
// WorkerTLS is the worker listener's TLS configuration. Nil serves plain
// HTTP, which is a development-only mode; production sets the server
// certificate and, for native mTLS, the client CA. The public listener has
// no TLS field because TLS terminates at the Ingress in front of it.
WorkerTLS *tls.Config
Auth AuthConfig
Stores StoresConfig
Services ServicesConfig
Storage StorageConfig
Worker WorkerConfig
Conv ConversationConfig
Webhook WebhookConfig
// Audit records sensitive actions. Nil discards them.
Audit *audit.Recorder
// Deployment describes this deployment for the admin system status.
Deployment admin.DeploymentInfo
// RedactedConfig is the operator-facing view of server.yaml. Nil means the
// admin configuration route answers 503.
RedactedConfig any
// Readiness lists the dependency probes GET /readyz runs. Empty means the
// endpoint reports ready without verifying anything, and says so by
// returning an empty check list.
Readiness []ReadinessCheck
}
Config holds server configuration. Grouped fields document what is required for auth, storage, worker, and conversation.
type ConversationConfig ¶
type ConversationConfig struct {
TitleGenerator llm.TitleGenerator
ConversationStore coreconv.Store
ConversationMessageStore coreconv.MessageStore
ConversationLLMClient llm.LLMClient
// LLMGateway serves managed inference to authenticated clients. Nil leaves
// the /llm routes answering 503.
LLMGateway *llmgateway.Service
}
ConversationConfig holds Tier 1 conversation stores and LLM wiring.
type ReadinessCheck ¶
type ReadinessCheck struct {
// Name appears in the response, so it must be safe to show an
// unauthenticated caller: "database", not a DSN.
Name string
Probe func(ctx context.Context) error
}
ReadinessCheck is one dependency the server needs before it can serve traffic. The server does not know what a database or an object store is — bootstrap supplies the probes, which keeps infrastructure detail out of this layer.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server wraps the HTTP server and runs it.
func New ¶
New builds the server. The public listener serves healthz, readyz, openapi, swagger, and every non-worker API handler; a separate worker listener serves only /api/worker/*. The two never share a mux, so the public socket cannot dispatch a worker route even under a broad Ingress rule. See docs/design/worker-api-network-boundary.md.
func (*Server) Drain ¶
func (s *Server) Drain()
Drain marks this server as going away: /readyz starts answering 503 so the load balancer stops sending it new work, and watcher streams return so they stop holding the drain open. It is idempotent and does not wait.
Requests in flight are untouched. Ending them is Shutdown's job, one rung further down.
func (*Server) ListenAndServe ¶
ListenAndServe serves until Shutdown is called, and reports nil for the orderly stop that causes.
It does not install a signal handler. Stopping this process is a sequence that reaches further than the HTTP surface — see docs/design/graceful-shutdown.md — and the layer that assembles the scheduler and the background loops is the only one that can walk it in the right order.
func (*Server) Shutdown ¶
Shutdown stops accepting connections and waits for the work in flight, bounded by ctx. It also drains, so a caller that stops the server without walking the whole ladder still takes it out of the load balancer first.
Conversation turns are waited for first and explicitly: one reached over a WebSocket lives on a hijacked connection, which http.Server.Shutdown returns without waiting for.
func (*Server) StartBackground ¶
func (s *Server) StartBackground()
StartBackground launches the background work the API surface owns.
Called by whoever runs the server rather than by New, so that building a handler — which a test does freely — never starts a goroutine.
func (*Server) StopBackground ¶
StopBackground stops that work and waits for it, bounded by ctx.
func (*Server) WorkerHandler ¶
WorkerHandler returns the worker-control HTTP handler for use in tests. It is built whether or not a worker socket is opened, so a test can prove the route boundary — a worker route answers here and 404s on Handler, and the reverse — without binding a second port.
type ServicesConfig ¶
type ServicesConfig struct {
// Plugin publishes Marketplace releases and manages catalog entries. Nil
// is a deployment with no Marketplace, which those routes report rather
// than serving an empty catalog.
Plugin *pluginsvc.Service
// Secret backs the Space Secret management routes. Nil when no KEK file is
// configured; those routes then report the feature off.
Secret *secretsvc.Service
}
ServicesConfig holds application services the handlers reach through rather than a store directly.
type ShutdownBudget ¶
type ShutdownBudget struct {
// Workers is how long in-flight runs have to stop and report. It is the
// largest share because it is the only phase that waits on another process.
Workers time.Duration
// Streams is how long watcher streams have to notice the drain and return.
// They are selecting on a closed channel, so this is generous already.
Streams time.Duration
// Requests is how long ordinary in-flight requests have to finish.
Requests time.Duration
// Background is how long the background loops have to end their current
// pass.
Background time.Duration
}
ShutdownBudget divides the grace period among the rungs of the shutdown ladder. Derived rather than configured: an operator sets one number, and the phases keep their proportions to each other automatically.
See docs/design/graceful-shutdown.md §3.
func NewShutdownBudget ¶
func NewShutdownBudget(grace time.Duration) ShutdownBudget
NewShutdownBudget splits grace into the ladder's phases. A zero or negative grace uses the default; anything under minShutdownGrace is raised to it, because a budget too small to divide is a configuration mistake rather than a request to skip the ladder.
func (ShutdownBudget) Total ¶
func (b ShutdownBudget) Total() time.Duration
Total is the sum of the phases, which is the grace period rounded down by the integer division above.
type StorageConfig ¶
type StorageConfig struct {
PersistStorage blob.PersistStorage
RunOutputStorage blob.RunOutputStorage
// ArtifactStorage holds artifact content. It is separate from
// RunOutputStorage because they are different key spaces with different
// lifetimes, not two names for one bucket.
ArtifactStorage artifactsvc.ContentStore
// MaxArtifactBytes caps one artifact. Zero uses the service default.
MaxArtifactBytes int64
// ArtifactShareTTL bounds a public share link's lifetime. Zero uses the
// service default.
WorkspacesDir string // Overrides config.WorkspacesDir() for workspace file operations
}
StorageConfig holds blob storage and workspace paths.
type StoresConfig ¶
type StoresConfig struct {
UserStore coreidentity.UserStore
LoginCodeStore coreidentity.LoginCodeStore
PasswordStore coreidentity.PasswordStore
RefreshTokenStore coreidentity.RefreshTokenStore
SpaceStore corespace.Store
WorkflowStore coreworkflow.Store
AgentStore agentdef.Store
IssueStore coreissue.Store
IssueCommentStore coreissue.CommentStore
TaskStore coretask.Store
TaskRunStore coretask.RunStore
LLMCallStore coregw.CallStore
RunOutputLister workroutes.RunOutputLister
UserWebhookKeyStore coreidentity.UserWebhookKeyStore
AuditStore coreaudit.Store
SystemGrantStore coreidentity.SystemGrantStore
SchemaStore coreschema.Store
LLMModelStore coregw.ModelStore
// ArtifactStore records durable files. Nil leaves the artifact routes
// answering 503, which is what a deployment with no database has.
ArtifactStore coreartifact.Store
// while artifacts otherwise work.
ArtifactShareStore coreartifact.ShareStore
// SecretStore is the Space Secret store. Nil disables the secret feature.
SecretStore coresecret.Store
}
StoresConfig holds entity store interfaces used by handlers.
type WebhookConfig ¶
type WebhookConfig struct {
MessagePath string // JSON path for message in body (default "message")
UserID string // CreatedBy for webhook runs (default "webhook")
}
WebhookConfig holds webhook handler options (message path and optional user ID for created runs).
type WorkerConfig ¶
type WorkerConfig struct {
// LLM tells a worker how to reach a model. Nil means direct.
LLM *workerclient.TaskRunLLM
}
WorkerConfig holds what a worker is told about models for its run. Worker authentication is not here: it is the run token the scheduler mints, verified with the deployment's JWT secret.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package access owns who a caller is and what they may do.
|
Package access owns who a caller is and what they may do. |
|
Package authtoken signs and verifies the run token a worker presents to the managed LLM gateway.
|
Package authtoken signs and verifies the run token a worker presents to the managed LLM gateway. |
|
admin
Package admin serves the deployment-scoped routes.
|
Package admin serves the deployment-scoped routes. |
|
artifact
Package artifact serves the durable files a space keeps.
|
Package artifact serves the durable files a space keeps. |
|
auditexport
Package auditexport streams the audit trail as CSV.
|
Package auditexport streams the audit trail as CSV. |
|
auth
Package auth serves the routes that establish a session.
|
Package auth serves the routes that establish a session. |
|
llmhttp
Package llmhttp presents the managed gateway over HTTP.
|
Package llmhttp presents the managed gateway over HTTP. |
|
runterminal
Package runterminal announces a task run that reached a terminal status.
|
Package runterminal announces a task run that reached a terminal status. |
|
space
Package space serves what a space owns: its membership, its agents, its webhook keys, its consumption, and its audit trail.
|
Package space serves what a space owns: its membership, its agents, its webhook keys, its consumption, and its audit trail. |
|
work
Package work serves the surface a space does its work on: issues and their comments, workflows, tasks and the runs that execute them, the conversations that start them, and the files and traces they leave behind.
|
Package work serves the surface a space does its work on: issues and their comments, workflows, tasks and the runs that execute them, the conversations that start them, and the files and traces they leave behind. |
|
worker
Package worker serves the routes a running worker calls back on.
|
Package worker serves the routes a running worker calls back on. |
|
Package scheduler provides task run scheduling.
|
Package scheduler provides task run scheduling. |
|
Package turnqueue serializes the turns of one conversation.
|
Package turnqueue serializes the turns of one conversation. |
|
Package streamhub provides task-scoped stream buffers for worker-push and client subscribe (SSE).
|
Package streamhub provides task-scoped stream buffers for worker-push and client subscribe (SSE). |