Changeset 0.33.0 (#207)

Co-authored-by: Jeffrey Smith <jasafpro@gmail.com>
Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
This commit is contained in:
2026-03-19 21:37:32 +00:00
committed by xcaliber
parent b1266b0d7c
commit ed3e9363f2
42 changed files with 2527 additions and 129 deletions

View File

@@ -1,7 +1,9 @@
package main
import (
"bytes"
"context"
_ "embed"
"encoding/json"
"fmt"
"log"
@@ -12,6 +14,7 @@ import (
"time"
"github.com/gin-gonic/gin"
"github.com/prometheus/client_golang/prometheus/promhttp"
"chat-switchboard/auth"
"chat-switchboard/compaction"
@@ -24,6 +27,8 @@ import (
"chat-switchboard/sandbox"
"chat-switchboard/handlers"
"chat-switchboard/health"
"chat-switchboard/logging"
"chat-switchboard/metrics"
"chat-switchboard/knowledge"
"chat-switchboard/memory"
"chat-switchboard/middleware"
@@ -43,6 +48,14 @@ import (
"chat-switchboard/workspace"
)
// v0.33.0: Embedded OpenAPI spec and Swagger UI for /api/docs.
//
//go:embed static/openapi.yaml
var openapiSpec []byte
//go:embed static/swagger.html
var swaggerHTML []byte
func main() {
// ── Subcommand dispatch ──────────────────
// Usage: switchboard vault rekey
@@ -58,6 +71,10 @@ func main() {
// ── Server startup ──────────────────────
cfg := config.Load()
// v0.33.0: Structured logging — must be first so all subsequent
// log output goes through slog.
logging.Init(cfg.LogFormat, cfg.LogLevel)
// Register LLM providers
providers.Init()
@@ -129,6 +146,9 @@ func main() {
healthAccum = health.NewAccumulator(healthStore)
defer healthAccum.Stop()
// v0.33.0: Start Prometheus DB pool collector
metrics.StartDBCollector(database.DB, 15*time.Second)
// Auto-disable: deactivate providers that are "down" for N consecutive
// hourly windows. Configured via PROVIDER_AUTO_DISABLE_THRESHOLD env var.
// Default: 3 (3 consecutive "down" hours triggers deactivation). Set to 0 to disable.
@@ -390,7 +410,11 @@ func main() {
log.Printf(" 🔗 Pre-completion filter chain: %d filters", filterChain.Len())
r := gin.Default()
r := gin.New()
r.Use(middleware.RequestID())
r.Use(middleware.Prometheus())
r.Use(middleware.Logger())
r.Use(middleware.Recovery())
userCache := middleware.NewUserStatusCache()
r.Use(middleware.CORS(cfg))
@@ -478,6 +502,19 @@ func main() {
c.JSON(200, gin.H{"status": "ok"})
})
// v0.33.0: Prometheus metrics endpoint (no auth — Prometheus scrapes directly)
base.GET("/metrics", gin.WrapH(promhttp.Handler()))
// v0.33.0: OpenAPI spec + Swagger UI (no auth — documentation)
base.GET("/api/docs", func(c *gin.Context) {
c.Data(http.StatusOK, "text/html; charset=utf-8", swaggerHTML)
})
base.GET("/api/docs/openapi.yaml", func(c *gin.Context) {
// Replace ${VERSION} placeholder with actual version from VERSION file
patched := bytes.Replace(openapiSpec, []byte("${VERSION}"), []byte(Version), 1)
c.Data(http.StatusOK, "application/yaml", patched)
})
// WebSocket endpoint
base.GET("/ws", middleware.WsAuth(cfg, stores.Users, userCache, ticketAdapter), hub.HandleWebSocket)
@@ -1207,6 +1244,10 @@ func main() {
admin.PUT("/extensions/:id/secrets", extSecH.SetSecrets)
admin.DELETE("/extensions/:id/secrets", extSecH.DeleteSecrets)
// Admin Dashboard (v0.33.0)
dashAdm := handlers.NewDashboardAdminHandler(stores, healthStore, hub)
admin.GET("/dashboard", dashAdm.GetDashboard)
// Provider Health (admin — v0.22.0)
healthAdm := handlers.NewHealthAdminHandler(healthStore, stores)
admin.GET("/providers/health", healthAdm.GetAllProviderHealth)