Initial commit: LlamaLink Go rewrite
Complete rewrite from Python/FastAPI to Go/Gin: - Go backend: auth (API keys + bcrypt), llama.cpp subprocess manager, hot-swap multi-model, rate limiting, quota system, webhooks - Vue 3 SPA admin panel (src/) with Tailwind CSS - Deployment: Docker multi-stage, docker-compose, nginx, systemd - GORM/SQLite models: ApiKey, Model, UsageLog, Quota, Webhook - REST API: /api/v1/admin/* (keys, models, chat, usage, health) - Embedded frontend via go:embed (build output at web/dist/) Removed legacy Python artifacts (app/, tests/, pyproject.toml, etc.)
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/llamalink/llamalink/internal/api/handlers"
|
||||
"github.com/llamalink/llamalink/internal/api/middleware"
|
||||
"github.com/llamalink/llamalink/internal/auth"
|
||||
"github.com/llamalink/llamalink/internal/config"
|
||||
"github.com/llamalink/llamalink/internal/llama"
|
||||
"github.com/llamalink/llamalink/internal/quota"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func New(cfg *config.Config, db *gorm.DB, llamaManager *llama.Manager) *gin.Engine {
|
||||
if cfg.LlamalinkEnv == "production" {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
}
|
||||
|
||||
r := gin.New()
|
||||
r.Use(gin.Recovery())
|
||||
r.Use(gin.Logger())
|
||||
|
||||
// Initialize services
|
||||
authService := auth.NewService(db)
|
||||
quotaSvc := quota.NewService(db)
|
||||
webhookSvc := quota.NewWebhookService(db)
|
||||
proxy := llama.NewProxy(llamaManager)
|
||||
|
||||
// Initialize handlers
|
||||
healthHandler := handlers.NewHealthHandler(db, llamaManager)
|
||||
chatHandler := handlers.NewChatHandler(proxy, authService, quotaSvc, webhookSvc)
|
||||
keysHandler := handlers.NewKeysHandler(authService)
|
||||
modelsHandler := handlers.NewModelsHandler(llamaManager)
|
||||
usageHandler := handlers.NewUsageHandler(db, quotaSvc)
|
||||
|
||||
// Health endpoints (public)
|
||||
r.GET("/health", healthHandler.Health)
|
||||
r.GET("/ready", healthHandler.Ready)
|
||||
|
||||
// API v1 group
|
||||
v1 := r.Group("/v1")
|
||||
|
||||
// Chat completions (requires API key auth + chat scope)
|
||||
chat := v1.Group("/chat")
|
||||
chat.Use(middleware.APIKeyAuth(authService))
|
||||
chat.POST("/completions", chatHandler.ChatCompletions)
|
||||
|
||||
// Keys management (admin only)
|
||||
keys := v1.Group("/keys")
|
||||
keys.Use(middleware.APIKeyAuth(authService))
|
||||
keys.Use(middleware.AdminOnly())
|
||||
keys.GET("", keysHandler.ListKeys)
|
||||
keys.POST("", keysHandler.CreateKey)
|
||||
keys.DELETE("/:id", keysHandler.RevokeKey)
|
||||
|
||||
// Models management
|
||||
models := v1.Group("/models")
|
||||
models.Use(middleware.APIKeyAuth(authService))
|
||||
models.GET("", modelsHandler.ListModels)
|
||||
models.POST("", modelsHandler.CreateModel)
|
||||
models.GET("/active", modelsHandler.GetActiveModel)
|
||||
models.GET("/:name", modelsHandler.GetActiveModel) // alias for compatibility
|
||||
|
||||
// Model load (admin only)
|
||||
modelLoad := v1.Group("/models")
|
||||
modelLoad.Use(middleware.APIKeyAuth(authService))
|
||||
modelLoad.Use(middleware.AdminOnly())
|
||||
modelLoad.POST("/:name/load", modelsHandler.LoadModel)
|
||||
|
||||
// Usage (requires API key auth)
|
||||
usage := v1.Group("/usage")
|
||||
usage.Use(middleware.APIKeyAuth(authService))
|
||||
usage.GET("", usageHandler.GetCurrentKeyUsage)
|
||||
usage.GET("/:key_id", usageHandler.GetUsage)
|
||||
|
||||
return r
|
||||
}
|
||||
Reference in New Issue
Block a user