Files
ez-api/internal/api/model_registry_handler.go
RC-CHN c990fa6610 docs(swagger): fix response type annotations for swagger generation
Update DeleteMasterKey endpoint to use MapData instead of dto.DeleteResponse
and add blank references for model registry DTOs to ensure proper swagger
documentation generation.
2026-01-10 15:36:46 +08:00

127 lines
4.5 KiB
Go

package api
import (
"net/http"
"strings"
"github.com/ez-api/ez-api/internal/dto"
"github.com/ez-api/ez-api/internal/service"
"github.com/gin-gonic/gin"
)
// Blank references for swagger doc generation
var (
_ dto.ModelRegistryStatusResponse
_ dto.ModelRegistryCheckResponse
)
type ModelRegistryHandler struct {
reg *service.ModelRegistryService
}
func NewModelRegistryHandler(reg *service.ModelRegistryService) *ModelRegistryHandler {
return &ModelRegistryHandler{reg: reg}
}
// GetModelRegistryStatus godoc
// @Summary Get model registry status
// @Description Returns Redis meta and local last-good cache info for model capability registry
// @Tags admin
// @Produce json
// @Security AdminAuth
// @Success 200 {object} ResponseEnvelope{data=dto.ModelRegistryStatusResponse}
// @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/model-registry/status [get]
func (h *ModelRegistryHandler) GetStatus(c *gin.Context) {
if h == nil || h.reg == nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "model registry not configured"})
return
}
st, err := h.reg.Status(c.Request.Context())
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get model registry status", "details": err.Error()})
return
}
c.JSON(http.StatusOK, st)
}
type refreshModelRegistryRequest struct {
Ref string `json:"ref"`
}
// CheckModelRegistry godoc
// @Summary Check model registry upstream version
// @Description Checks models.dev commit SHA for a ref and indicates whether refresh is needed (does not apply changes)
// @Tags admin
// @Accept json
// @Produce json
// @Security AdminAuth
// @Param body body refreshModelRegistryRequest false "optional override ref"
// @Success 200 {object} ResponseEnvelope{data=dto.ModelRegistryCheckResponse}
// @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/model-registry/check [post]
func (h *ModelRegistryHandler) Check(c *gin.Context) {
if h == nil || h.reg == nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "model registry not configured"})
return
}
var req refreshModelRegistryRequest
_ = c.ShouldBindJSON(&req)
ref := strings.TrimSpace(req.Ref)
out, err := h.reg.Check(c.Request.Context(), ref)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to check model registry", "details": err.Error()})
return
}
c.JSON(http.StatusOK, out)
}
// RefreshModelRegistry godoc
// @Summary Refresh model registry from models.dev
// @Description Fetches models.dev, computes per-binding capabilities, and updates Redis meta:models
// @Tags admin
// @Accept json
// @Produce json
// @Security AdminAuth
// @Param body body refreshModelRegistryRequest false "optional override ref"
// @Success 200 {object} ResponseEnvelope{data=MapData}
// @Failure 400 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/model-registry/refresh [post]
func (h *ModelRegistryHandler) Refresh(c *gin.Context) {
if h == nil || h.reg == nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "model registry not configured"})
return
}
var req refreshModelRegistryRequest
_ = c.ShouldBindJSON(&req)
ref := strings.TrimSpace(req.Ref)
if err := h.reg.Refresh(c.Request.Context(), ref); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to refresh model registry", "details": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"status": "refreshed"})
}
// RollbackModelRegistry godoc
// @Summary Rollback model registry
// @Description Rollback meta:models to previous cached last-good version
// @Tags admin
// @Produce json
// @Security AdminAuth
// @Success 200 {object} ResponseEnvelope{data=MapData}
// @Failure 500 {object} ResponseEnvelope{data=MapData}
// @Router /admin/model-registry/rollback [post]
func (h *ModelRegistryHandler) Rollback(c *gin.Context) {
if h == nil || h.reg == nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "model registry not configured"})
return
}
if err := h.reg.Rollback(c.Request.Context()); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to rollback model registry", "details": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"status": "rolled_back"})
}