feat: Added LLM factory initialization functionality and knowledge base related API interfaces (#13472)

### What problem does this PR solve?

feat: Added LLM factory initialization functionality and knowledge base
related API interfaces

refactor(dao): Refactored the TenantLLMDAO query method
feat(handler): Implemented knowledge base related API endpoints
feat(service): Added LLM API key setting functionality
feat(model): Extended the knowledge base model definition
feat(config): Added default user LLM configuration

### Type of change

- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
chanx
2026-03-09 15:52:14 +08:00
committed by GitHub
parent d0465ba909
commit 25ace613b0
20 changed files with 2446 additions and 340 deletions

View File

@ -21,6 +21,7 @@ import (
"github.com/gin-gonic/gin"
"ragflow/internal/common"
"ragflow/internal/dao"
"ragflow/internal/service"
)
@ -60,50 +61,112 @@ func NewLLMHandler(llmService *service.LLMService, userService *service.UserServ
// @Success 200 {object} map[string]interface{}
// @Router /v1/llm/my_llms [get]
func (h *LLMHandler) GetMyLLMs(c *gin.Context) {
// Extract token from request
token := c.GetHeader("Authorization")
if token == "" {
c.JSON(http.StatusUnauthorized, gin.H{
"code": 401,
"message": "Missing Authorization header",
c.JSON(http.StatusOK, gin.H{
"code": common.CodeUnauthorized,
"message": "Unauthorized!",
"data": false,
})
return
}
// Get user by token
user, code, err := h.userService.GetUserByToken(token)
if err != nil {
c.JSON(http.StatusUnauthorized, gin.H{
c.JSON(http.StatusOK, gin.H{
"code": code,
"message": err.Error(),
"data": false,
})
return
}
// Get tenant ID from user
tenantID := user.ID
if tenantID == "" {
c.JSON(http.StatusBadRequest, gin.H{
"error": "User has no tenant ID",
})
return
}
// Parse include_details query parameter
includeDetailsStr := c.DefaultQuery("include_details", "false")
includeDetails := includeDetailsStr == "true"
// Get LLMs for tenant
llms, err := h.llmService.GetMyLLMs(tenantID, includeDetails)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "Failed to get LLMs",
c.JSON(http.StatusOK, gin.H{
"code": common.CodeExceptionError,
"message": err.Error(),
"data": false,
})
return
}
c.JSON(http.StatusOK, gin.H{
"data": llms,
"code": common.CodeSuccess,
"message": "success",
"data": llms,
})
}
// SetAPIKey set API key for a LLM factory
// @Summary Set API Key
// @Description Set API key for a LLM factory and test connectivity
// @Tags llm
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param request body service.SetAPIKeyRequest true "API Key configuration"
// @Success 200 {object} map[string]interface{}
// @Router /v1/llm/set_api_key [post]
func (h *LLMHandler) SetAPIKey(c *gin.Context) {
token := c.GetHeader("Authorization")
if token == "" {
c.JSON(http.StatusOK, gin.H{
"code": common.CodeUnauthorized,
"message": "Unauthorized!",
"data": false,
})
return
}
user, code, err := h.userService.GetUserByToken(token)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"code": code,
"message": err.Error(),
"data": false,
})
return
}
var req service.SetAPIKeyRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusOK, gin.H{
"code": common.CodeArgumentError,
"message": "Invalid request: " + err.Error(),
"data": false,
})
return
}
tenantID := user.ID
result, err := h.llmService.SetAPIKey(tenantID, &req)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"code": common.CodeDataError,
"message": err.Error(),
"data": false,
})
return
}
if req.Verify {
c.JSON(http.StatusOK, gin.H{
"code": common.CodeSuccess,
"message": "success",
"data": result,
})
return
}
c.JSON(http.StatusOK, gin.H{
"code": common.CodeSuccess,
"message": "success",
"data": true,
})
}
@ -198,52 +261,43 @@ func (h *LLMHandler) Factories(c *gin.Context) {
// @Success 200 {object} map[string][]service.LLMListItem
// @Router /v1/llm/list [get]
func (h *LLMHandler) ListApp(c *gin.Context) {
// Extract token from request
token := c.GetHeader("Authorization")
if token == "" {
c.JSON(http.StatusUnauthorized, gin.H{
"code": 401,
"message": "Missing Authorization header",
c.JSON(http.StatusOK, gin.H{
"code": common.CodeUnauthorized,
"message": "Unauthorized!",
"data": false,
})
return
}
// Get user by token
user, code, err := h.userService.GetUserByToken(token)
if err != nil {
c.JSON(http.StatusUnauthorized, gin.H{
c.JSON(http.StatusOK, gin.H{
"code": code,
"message": err.Error(),
"data": false,
})
return
}
// Get tenant ID from user
tenantID := user.ID
if tenantID == "" {
c.JSON(http.StatusBadRequest, gin.H{
"code": 400,
"message": "User has no tenant ID",
})
return
}
// Parse model_type query parameter
modelType := c.Query("model_type")
// Get LLM list
llms, err := h.llmService.ListLLMs(tenantID, modelType)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"code": 500,
c.JSON(http.StatusOK, gin.H{
"code": common.CodeExceptionError,
"message": err.Error(),
"data": false,
})
return
}
c.JSON(http.StatusOK, gin.H{
"code": 0,
"data": llms,
"code": common.CodeSuccess,
"message": "success",
"data": llms,
})
}