// Package buildinfo exposes stamped build metadata and the shared ops /healthz JSON. package buildinfo import ( "encoding/json" "net/http" "time" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" ) // Populated at link time via -ldflags -X. var ( Date = "unknown" Commit = "dev" Branch = "unknown" ) // Hardcoded service identity for autodiscovery / status dashboard. const ( Name = "l-ai-agent-kaya" Description = "Tasks board agent Kaya: @kaya mention replies via core RunAgent" ) // Tags is the controlled vocabulary for this service (see l-ai-docs services/healthz.md). var Tags = []string{"agent", "tasks", "llm"} var startedAt = time.Now() func init() { promauto.NewGaugeVec( prometheus.GaugeOpts{ Name: "build_info", Help: "Build metadata for this process (always 1).", }, []string{"name", "commit", "branch", "date"}, ).With(prometheus.Labels{ "name": Name, "commit": Commit, "branch": Branch, "date": Date, }).Set(1) } // Build is the nested build object in /healthz. type Build struct { Date string `json:"date"` Commit string `json:"commit"` Branch string `json:"branch"` } // Response is the shared /healthz JSON contract. type Response struct { Status string `json:"status"` Name string `json:"name"` Description string `json:"description"` Tags []string `json:"tags"` UptimeSeconds int64 `json:"uptime_seconds"` Build Build `json:"build"` } // Snapshot returns the current health payload with status "ok". func Snapshot() Response { tags := make([]string, len(Tags)) copy(tags, Tags) return Response{ Status: "ok", Name: Name, Description: Description, Tags: tags, UptimeSeconds: int64(time.Since(startedAt).Seconds()), Build: Build{ Date: Date, Commit: Commit, Branch: Branch, }, } } // Handler serves GET/HEAD /healthz as application/json (always 200 while process is up). func Handler() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet && r.Method != http.MethodHead { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } writeJSON(w, http.StatusOK, Snapshot()) }) } func writeJSON(w http.ResponseWriter, code int, body Response) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(code) _ = json.NewEncoder(w).Encode(body) }