Go CLI: Fix show model and list models (#16380)

### What problem does this PR solve?

```
RAGFlow(api/default)> show model 'WiseDiag-Z1 Think';

RAGFlow(api/default)> list models;

RAGFlow(admin)> show model 'WiseDiag-Z1 Think';

RAGFlow(admin)> list models;
```

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)

Signed-off-by: Jin Hai <haijin.chn@gmail.com>
This commit is contained in:
Jin Hai
2026-06-26 15:36:01 +08:00
committed by GitHub
parent 0de8f3e127
commit 2667995b25
9 changed files with 154 additions and 139 deletions

View File

@@ -876,48 +876,6 @@ func (h *Handler) DeleteModels(c *gin.Context) {
success(c, result, "Model deleted successfully")
}
func (h *Handler) ListAllModels(c *gin.Context) {
// List models
models, err := h.service.ListAllModels()
if err != nil {
errorResponse(c, err.Error(), 500)
return
}
success(c, models, "")
}
func (h *Handler) ShowModel(c *gin.Context) {
encodedModelName := c.Param("model_name")
if encodedModelName == "" {
c.JSON(http.StatusBadRequest, gin.H{
"code": 400,
"message": "Encoded model name is empty",
})
return
}
decodedModelName, err := common.DecodeFromBase64(encodedModelName)
if err != nil {
errorResponse(c, err.Error(), 400)
return
}
if decodedModelName == "" {
errorResponse(c, "Decoded model name is empty", 400)
return
}
// Get model
model, err := h.service.GetModelByModelName(decodedModelName)
if err != nil {
errorResponse(c, err.Error(), 500)
return
}
success(c, model, "")
}
// GetSystemFingerprint handle get system fingerprint
func (h *Handler) GetSystemFingerprint(c *gin.Context) {
fingerprint, err := h.service.GetSystemFingerprint()

View File

@@ -343,24 +343,6 @@ func (s *Service) DeleteModels(userID, providerName, instanceName string, models
}, nil
}
// ListAllModels list all models
func (s *Service) ListAllModels() ([]map[string]interface{}, error) {
return []map[string]interface{}{
{
"command": "list_all_models",
"error": "'list all models' is implemented in enterprise edition",
},
}, nil
}
func (s *Service) GetModelByModelName(modelName string) (map[string]interface{}, error) {
return map[string]interface{}{
"command": "get_model_by_model_name",
"model_name": modelName,
"error": "'get model by model name' is implemented in enterprise edition",
}, nil
}
func (s *Service) GetSystemFingerprint() (map[string]interface{}, error) {
result := map[string]interface{}{
"command": "get_system_fingerprint",

View File

@@ -1294,3 +1294,60 @@ func (h *Handler) Reports(c *gin.Context) {
responseWithCode(c, message, http.StatusOK, errCode)
}
func (h *Handler) ListAllModels(c *gin.Context) {
page := 0
if v := c.Query("page"); v != "" {
if p, err := strconv.Atoi(v); err == nil && p > 0 {
page = p
}
}
pageSize := 0
if v := c.Query("page_size"); v != "" {
if ps, err := strconv.Atoi(v); err == nil && ps > 0 {
pageSize = ps
}
}
// List models
models, err := h.service.ListAllModels(page, pageSize)
if err != nil {
errorResponse(c, err.Error(), 500)
return
}
success(c, models, "")
}
func (h *Handler) ShowModel(c *gin.Context) {
encodedModelName := c.Param("model_name")
if encodedModelName == "" {
c.JSON(http.StatusBadRequest, gin.H{
"code": 400,
"message": "Encoded model name is empty",
})
return
}
decodedModelName, err := common.DecodeFromBase64(encodedModelName)
if err != nil {
errorResponse(c, err.Error(), 400)
return
}
if decodedModelName == "" {
errorResponse(c, "Decoded model name is empty", 400)
return
}
// Get model
model, err := h.service.GetModelByModelName(decodedModelName)
if err != nil {
errorResponse(c, err.Error(), 500)
return
}
success(c, model, "")
}

View File

@@ -31,6 +31,7 @@ import (
"ragflow/internal/engine/elasticsearch"
"ragflow/internal/engine/redis"
"ragflow/internal/entity"
modelModule "ragflow/internal/entity/models"
"ragflow/internal/server"
"ragflow/internal/utility"
"regexp"
@@ -1762,3 +1763,19 @@ func (s *Service) addTenantForAdmin(userID, nickname string) error {
return dao.DB.Create(userTenant).Error
}
// ListAllModels list all models
func (s *Service) ListAllModels(pageIndex, pageSize int) ([]map[string]interface{}, error) {
models, err := dao.GetModelProviderManager().ListAllModels()
if err != nil {
return nil, err
}
if pageSize > 0 && pageIndex >= 0 && pageIndex*pageSize < len(models) {
return models[pageIndex*pageSize : (pageIndex+1)*pageSize], nil
}
return models, nil
}
func (s *Service) GetModelByModelName(modelName string) (*modelModule.Model, error) {
return dao.GetModelProviderManager().GetModelByNameOrAlias(modelName), nil
}

View File

@@ -132,7 +132,7 @@ func (c *CLI) ExecuteAdminCommand(cmd *Command) (ResponseIf, error) {
case "admin_list_provider_instances":
return c.CommonListProviderInstances(cmd)
case "admin_show_model":
return c.CommonShowModel(cmd)
return c.CommonShowModelCommand(cmd)
case "admin_list_providers":
return c.AdminListProvidersCommand(cmd)
case "admin_list_all_models":
@@ -358,10 +358,8 @@ func (c *CLI) ExecuteUserCommand(cmd *Command) (ResponseIf, error) {
return c.CommonListInstanceModelsSyncCommand(cmd)
case "api_list_provider_instance_tasks":
return c.APIListModelInstanceTasksCommand(cmd)
case "show_provider_model":
return c.CommonShowProviderModelCommand(cmd)
case "show_model":
return c.CommonShowModel(cmd)
case "api_show_model":
return c.CommonShowModelCommand(cmd)
case "list_all_models":
return c.ListAllModels(cmd)
// Provider commands

View File

@@ -1432,7 +1432,7 @@ func (c *CLI) ListAllModels(cmd *Command) (ResponseIf, error) {
return &result, nil
}
func (c *CLI) CommonShowModel(cmd *Command) (ResponseIf, error) {
func (c *CLI) CommonShowModelCommand(cmd *Command) (ResponseIf, error) {
modelName, ok := cmd.Params["model_name"].(string)
if !ok {

View File

@@ -526,7 +526,7 @@ func (p *Parser) parseAPIShowCommands() (*Command, error) {
case TokenProvider:
return p.parseAPIShowProviderCommands()
case TokenModel:
return p.parseShowModel()
return p.parseAPIShowModel()
case TokenTask:
return p.parseShowTask()
case TokenQuotedString:
@@ -590,8 +590,9 @@ func (p *Parser) parseAPIShowVariable() (*Command, error) {
return cmd, nil
}
func (p *Parser) parseShowModel() (*Command, error) {
p.nextToken() // consume model
// SHOW MODEL 'model_name'
func (p *Parser) parseAPIShowModel() (*Command, error) {
p.nextToken() // consume MODEL
modelName, err := p.parseQuotedString()
if err != nil {
@@ -599,30 +600,11 @@ func (p *Parser) parseShowModel() (*Command, error) {
}
p.nextToken() // consume model_name
if p.curToken.Type != TokenFrom {
// SHOW MODEL 'model_name'
if p.curToken.Type == TokenSemicolon {
p.nextToken()
}
cmd := NewCommand("show_model")
cmd.Params["model_name"] = modelName
return cmd, nil
}
p.nextToken() // consume from
cmd := NewCommand("show_provider_model")
cmd.Params["model_name"] = modelName
providerName, err := p.parseQuotedString()
if err != nil {
return nil, fmt.Errorf("expected provider name: %w", err)
}
cmd.Params["provider_name"] = providerName
p.nextToken() // consume provider name
// Semicolon is optional
if p.curToken.Type == TokenSemicolon {
p.nextToken()
}
cmd := NewCommand("api_show_model")
cmd.Params["model_name"] = modelName
return cmd, nil
}

View File

@@ -20,6 +20,7 @@ import (
"net/http"
"ragflow/internal/common"
"ragflow/internal/service"
"strconv"
"github.com/gin-gonic/gin"
)
@@ -36,63 +37,82 @@ func NewModelHandler(modelProviderService *service.ModelProviderService) *ModelH
}
}
type ShowModelRequest struct {
ModelName *string `json:"model_name"`
Page int `json:"page"`
PageSize int `json:"page_size"`
}
func (h *ModelHandler) ListAllModels(c *gin.Context) {
var req ShowModelRequest
if err := c.ShouldBindJSON(&req); err != nil {
println("JSON bind error: %v (type: %T)", err, err)
page := 0
if v := c.Query("page"); v != "" {
if p, err := strconv.Atoi(v); err == nil && p > 0 {
page = p
}
}
pageSize := 0
if v := c.Query("page_size"); v != "" {
if ps, err := strconv.Atoi(v); err == nil && ps > 0 {
pageSize = ps
}
}
// list tenant models
models, err := h.modelProviderService.ListAllModels(page, pageSize)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"code": common.CodeBadRequest,
"code": common.CodeDataError,
"message": err.Error(),
"data": nil,
})
return
}
if req.ModelName == nil {
// list models
page := req.Page
pageSize := req.PageSize
// list tenant models
models, err := h.modelProviderService.ListAllModels(page, pageSize)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"code": common.CodeDataError,
"message": err.Error(),
"data": nil,
})
return
}
c.JSON(http.StatusOK, gin.H{
"code": 0,
"message": "success",
"data": models,
})
} else {
// show model
model, err := h.modelProviderService.ShowModel(*req.ModelName)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"code": common.CodeDataError,
"message": err.Error(),
"data": nil,
})
return
}
c.JSON(http.StatusOK, gin.H{
"code": 0,
"message": "success",
"data": model,
})
}
c.JSON(http.StatusOK, gin.H{
"code": 0,
"message": "success",
"data": models,
})
return
}
func (h *ModelHandler) ShowModel(c *gin.Context) {
encodedModelName := c.Param("model_name")
if encodedModelName == "" {
c.JSON(http.StatusOK, gin.H{
"code": 400,
"message": "Encoded model name is empty",
})
return
}
decodedModelName, err := common.DecodeFromBase64(encodedModelName)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"code": 400,
"message": err.Error(),
})
return
}
if decodedModelName == "" {
c.JSON(http.StatusOK, gin.H{
"code": 400,
"message": "Decoded model name is empty",
})
return
}
// Get model
model, err := h.modelProviderService.ShowModel(decodedModelName)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"code": common.CodeDataError,
"message": err.Error(),
"data": nil,
})
return
}
c.JSON(http.StatusOK, gin.H{
"code": common.CodeSuccess,
"message": "success",
"data": model,
})
}

View File

@@ -501,6 +501,7 @@ func (r *Router) Setup(engine *gin.Engine) {
allModels := v1.Group("/all-models")
{
allModels.GET("", r.modelHandler.ListAllModels)
allModels.GET("/:model_name", r.modelHandler.ShowModel)
}
// Agent routes