// Package main is the entry point for the LLM Gateway / Proxy service. // // @title LLM Gateway API // @version 1.0 // @description OpenAI-compatible and Anthropic-compatible LLM proxy/gateway with Bifrost mapping. // @termsOfService http://swagger.io/terms/ // // @contact.name optoant // @contact.email admin@optoant.local // // @license.name MIT // @license.url https://opensource.org/licenses/MIT // // @host localhost:8000 // @BasePath / // // @securityDefinitions.apikey BearerAuth // @in header // @name Authorization package main import ( "fmt" "log" "net/url" "os" "path/filepath" "github.com/gofiber/fiber/v3" "github.com/joho/godotenv" "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" gormlogger "gorm.io/gorm/logger" "optoant/config" "optoant/handlers" "optoant/internal/logger" "optoant/models" ) func main() { // Load .env file if present (silently ignore if missing) _ = godotenv.Load() cfg := config.Load() // Logger verbosity from LOG_LEVEL env (debug, info, warn) logger.SetLevel(cfg.LogLevel) // ------------------------------------------------------------------ // Database setup (GORM — PostgreSQL or SQLite based on DB_MODE) // ------------------------------------------------------------------ var db *gorm.DB if cfg.PostgresDSN != "" || cfg.DBMode == "sqlite" { var dialector gorm.Dialector dbEngine := "postgres" switch cfg.DBMode { case "sqlite": dsn := cfg.DBPath if dsn == "" { dsn = "data/gateway.db" } if err := os.MkdirAll(filepath.Dir(dsn), 0755); err != nil { log.Printf("⚠️ Failed to create DB directory: %v", err) } dialector = sqlite.Open(dsn) dbEngine = "sqlite" default: dsn := cfg.PostgresDSN if cfg.DBTimezone != "" { dsn = appendQueryParam(dsn, "timezone", cfg.DBTimezone) } dialector = postgres.Open(dsn) } var err error db, err = gorm.Open(dialector, &gorm.Config{ Logger: gormlogger.Default.LogMode(gormlogger.Warn), }) if err != nil { log.Printf("⚠️ DB connection failed (continuing without DB): %v", err) db = nil } else { if err := db.AutoMigrate(&models.RequestLog{}); err != nil { log.Printf("⚠️ AutoMigrate failed: %v", err) } else { log.Printf("✅ Database connected and migrated (%s)", dbEngine) } } } else { log.Println("ℹ️ No POSTGRES_DSN/DATABASE_DSN set — running without database logging") } // ------------------------------------------------------------------ // Fiber v3 application // ------------------------------------------------------------------ app := fiber.New(fiber.Config{ AppName: "LLM Gateway v1.0", ServerHeader: "optoant-gateway", }) // ------------------------------------------------------------------ // Swagger UI at /swagger/* — Fiber v3 native, no v2 dependency // Swagger UI is loaded from CDN; spec is served from /swagger/swagger.json // ------------------------------------------------------------------ app.Get("/swagger/swagger.json", func(c fiber.Ctx) error { return c.SendFile("./docs/swagger.json") }) app.Get("/swagger", func(c fiber.Ctx) error { return c.Redirect().To("/swagger/") }) app.Get("/swagger/*", func(c fiber.Ctx) error { html := `