mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-15 20:27:20 +08:00
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:
@@ -18,20 +18,21 @@ package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"ragflow/internal/common"
|
||||
"ragflow/internal/service"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"ragflow/internal/service"
|
||||
)
|
||||
|
||||
// KnowledgebaseHandler knowledge base handler
|
||||
// KnowledgebaseHandler handles knowledge base HTTP requests
|
||||
type KnowledgebaseHandler struct {
|
||||
kbService *service.KnowledgebaseService
|
||||
userService *service.UserService
|
||||
}
|
||||
|
||||
// NewKnowledgebaseHandler create knowledge base handler
|
||||
// NewKnowledgebaseHandler creates a new knowledge base handler
|
||||
func NewKnowledgebaseHandler(kbService *service.KnowledgebaseService, userService *service.UserService) *KnowledgebaseHandler {
|
||||
return &KnowledgebaseHandler{
|
||||
kbService: kbService,
|
||||
@@ -39,35 +40,227 @@ func NewKnowledgebaseHandler(kbService *service.KnowledgebaseService, userServic
|
||||
}
|
||||
}
|
||||
|
||||
// ListKbs list knowledge bases
|
||||
// @Summary List Knowledge Bases
|
||||
// @Description Get list of knowledge bases with filtering and pagination
|
||||
// getUserID extracts user ID from authorization header
|
||||
// It validates the authorization token and returns the user ID
|
||||
// Parameters:
|
||||
// - c: gin.Context - the HTTP request context
|
||||
//
|
||||
// Returns:
|
||||
// - string: the user ID
|
||||
// - common.ErrorCode: the error code
|
||||
// - error: any error that occurred
|
||||
func (h *KnowledgebaseHandler) getUserID(c *gin.Context) (string, common.ErrorCode, error) {
|
||||
token := c.GetHeader("Authorization")
|
||||
if token == "" {
|
||||
return "", common.CodeUnauthorized, ErrMissingAuth
|
||||
}
|
||||
|
||||
user, code, err := h.userService.GetUserByToken(token)
|
||||
if err != nil {
|
||||
return "", code, err
|
||||
}
|
||||
|
||||
return user.ID, common.CodeSuccess, nil
|
||||
}
|
||||
|
||||
// jsonResponse sends a JSON response with code and message
|
||||
func jsonResponse(c *gin.Context, code common.ErrorCode, data interface{}, message string) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": code,
|
||||
"data": data,
|
||||
"message": message,
|
||||
})
|
||||
}
|
||||
|
||||
// jsonError sends a JSON error response
|
||||
func jsonError(c *gin.Context, code common.ErrorCode, message string) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": code,
|
||||
"data": nil,
|
||||
"message": message,
|
||||
})
|
||||
}
|
||||
|
||||
// HTTPError represents an HTTP error
|
||||
type HTTPError struct {
|
||||
Code common.ErrorCode
|
||||
Message string
|
||||
}
|
||||
|
||||
// Error implements the error interface
|
||||
func (e *HTTPError) Error() string {
|
||||
return e.Message
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrMissingAuth indicates missing authorization header
|
||||
ErrMissingAuth = &HTTPError{Code: common.CodeUnauthorized, Message: "Missing Authorization header"}
|
||||
// ErrInvalidToken indicates invalid access token
|
||||
ErrInvalidToken = &HTTPError{Code: common.CodeUnauthorized, Message: "Invalid access token"}
|
||||
)
|
||||
|
||||
// CreateKB handles the create knowledge base request
|
||||
// @Summary Create Knowledge Base
|
||||
// @Description Create a new knowledge base (dataset)
|
||||
// @Tags knowledgebase
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param keywords query string false "search keywords"
|
||||
// @Param page query int false "page number"
|
||||
// @Param page_size query int false "items per page"
|
||||
// @Param parser_id query string false "parser ID filter"
|
||||
// @Param orderby query string false "order by field"
|
||||
// @Param desc query bool false "descending order"
|
||||
// @Param request body service.ListKbsRequest true "filter options"
|
||||
// @Success 200 {object} service.ListKbsResponse
|
||||
// @Security ApiKeyAuth
|
||||
// @Param request body service.CreateKBRequest true "knowledge base info"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/kb/create [post]
|
||||
func (h *KnowledgebaseHandler) CreateKB(c *gin.Context) {
|
||||
userID, code, err := h.getUserID(c)
|
||||
if err != nil {
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var req service.CreateKBRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
jsonError(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
result, code, err := h.kbService.CreateKB(&req, userID)
|
||||
if err != nil {
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
jsonResponse(c, common.CodeSuccess, result, "success")
|
||||
}
|
||||
|
||||
// UpdateKB handles the update knowledge base request
|
||||
// @Summary Update Knowledge Base
|
||||
// @Description Update an existing knowledge base
|
||||
// @Tags knowledgebase
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param request body service.UpdateKBRequest true "knowledge base update info"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/kb/update [post]
|
||||
func (h *KnowledgebaseHandler) UpdateKB(c *gin.Context) {
|
||||
userID, code, err := h.getUserID(c)
|
||||
if err != nil {
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var req service.UpdateKBRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
jsonError(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
result, code, err := h.kbService.UpdateKB(&req, userID)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "authorization") {
|
||||
jsonError(c, common.CodeAuthenticationError, err.Error())
|
||||
return
|
||||
}
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
jsonResponse(c, common.CodeSuccess, result, "success")
|
||||
}
|
||||
|
||||
// UpdateMetadataSetting handles the update metadata setting request
|
||||
// @Summary Update Metadata Setting
|
||||
// @Description Update metadata settings for a knowledge base
|
||||
// @Tags knowledgebase
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param request body service.UpdateMetadataSettingRequest true "metadata setting info"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/kb/update_metadata_setting [post]
|
||||
func (h *KnowledgebaseHandler) UpdateMetadataSetting(c *gin.Context) {
|
||||
_, code, err := h.getUserID(c)
|
||||
if err != nil {
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var req service.UpdateMetadataSettingRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
jsonError(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
result, code, err := h.kbService.UpdateMetadataSetting(&req)
|
||||
if err != nil {
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
jsonResponse(c, common.CodeSuccess, result, "success")
|
||||
}
|
||||
|
||||
// GetDetail handles the get knowledge base detail request
|
||||
// @Summary Get Knowledge Base Detail
|
||||
// @Description Get detailed information about a knowledge base
|
||||
// @Tags knowledgebase
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param kb_id query string true "Knowledge Base ID"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/kb/detail [get]
|
||||
func (h *KnowledgebaseHandler) GetDetail(c *gin.Context) {
|
||||
userID, code, err := h.getUserID(c)
|
||||
if err != nil {
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
kbID := c.Query("kb_id")
|
||||
if kbID == "" {
|
||||
jsonError(c, common.CodeDataError, "kb_id is required")
|
||||
return
|
||||
}
|
||||
|
||||
result, code, err := h.kbService.GetDetail(kbID, userID)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "authorized") {
|
||||
jsonError(c, common.CodeOperatingError, err.Error())
|
||||
return
|
||||
}
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
jsonResponse(c, common.CodeSuccess, result, "success")
|
||||
}
|
||||
|
||||
// ListKbs handles the list knowledge bases request
|
||||
// @Summary List Knowledge Bases
|
||||
// @Description List knowledge bases with pagination and filtering
|
||||
// @Tags knowledgebase
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param request body service.ListKbsRequest true "list options"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/kb/list [post]
|
||||
func (h *KnowledgebaseHandler) ListKbs(c *gin.Context) {
|
||||
// Parse request body - allow empty body
|
||||
userID, code, err := h.getUserID(c)
|
||||
if err != nil {
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var req service.ListKbsRequest
|
||||
if c.Request.ContentLength > 0 {
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"code": 400,
|
||||
"message": err.Error(),
|
||||
})
|
||||
jsonError(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Extract parameters from query or request body with defaults
|
||||
// Get parameters from request or query string
|
||||
keywords := ""
|
||||
if req.Keywords != nil {
|
||||
keywords = *req.Keywords
|
||||
@@ -111,7 +304,7 @@ func (h *KnowledgebaseHandler) ListKbs(c *gin.Context) {
|
||||
if req.Desc != nil {
|
||||
desc = *req.Desc
|
||||
} else if descStr := c.Query("desc"); descStr != "" {
|
||||
desc = descStr == "true"
|
||||
desc = strings.ToLower(descStr) == "true"
|
||||
}
|
||||
|
||||
var ownerIDs []string
|
||||
@@ -119,40 +312,327 @@ func (h *KnowledgebaseHandler) ListKbs(c *gin.Context) {
|
||||
ownerIDs = *req.OwnerIDs
|
||||
}
|
||||
|
||||
// Get access token from Authorization header
|
||||
token := c.GetHeader("Authorization")
|
||||
if token == "" {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{
|
||||
"code": 401,
|
||||
"message": "Missing Authorization header",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Get user by access token
|
||||
user, code, err := h.userService.GetUserByToken(token)
|
||||
result, code, err := h.kbService.ListKbs(keywords, page, pageSize, parserID, orderby, desc, ownerIDs, userID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{
|
||||
"code": code,
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
userID := user.ID
|
||||
|
||||
// List knowledge bases
|
||||
result, err := h.kbService.ListKbs(keywords, page, pageSize, parserID, orderby, desc, ownerIDs, userID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"code": 500,
|
||||
"message": err.Error(),
|
||||
})
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 0,
|
||||
"data": result,
|
||||
"message": "success",
|
||||
})
|
||||
jsonResponse(c, common.CodeSuccess, result, "success")
|
||||
}
|
||||
|
||||
// DeleteKB handles the delete knowledge base request
|
||||
// @Summary Delete Knowledge Base
|
||||
// @Description Soft delete a knowledge base
|
||||
// @Tags knowledgebase
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param request body object{kb_id string} true "knowledge base id"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/kb/rm [post]
|
||||
func (h *KnowledgebaseHandler) DeleteKB(c *gin.Context) {
|
||||
userID, code, err := h.getUserID(c)
|
||||
if err != nil {
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var req struct {
|
||||
KBID string `json:"kb_id" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
jsonError(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
code, err = h.kbService.DeleteKB(req.KBID, userID)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "authorization") {
|
||||
jsonError(c, common.CodeAuthenticationError, err.Error())
|
||||
return
|
||||
}
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
jsonResponse(c, common.CodeSuccess, true, "success")
|
||||
}
|
||||
|
||||
// ListTags handles the list tags request for a knowledge base
|
||||
// @Summary List Tags
|
||||
// @Description List tags for a knowledge base
|
||||
// @Tags knowledgebase
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param kb_id path string true "Knowledge Base ID"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/kb/{kb_id}/tags [get]
|
||||
func (h *KnowledgebaseHandler) ListTags(c *gin.Context) {
|
||||
userID, code, err := h.getUserID(c)
|
||||
if err != nil {
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
kbID := c.Param("kb_id")
|
||||
if kbID == "" {
|
||||
jsonError(c, common.CodeDataError, "kb_id is required")
|
||||
return
|
||||
}
|
||||
|
||||
if !h.kbService.Accessible(kbID, userID) {
|
||||
jsonError(c, common.CodeAuthenticationError, "No authorization.")
|
||||
return
|
||||
}
|
||||
|
||||
jsonResponse(c, common.CodeSuccess, []string{}, "success")
|
||||
}
|
||||
|
||||
// ListTagsFromKbs handles the list tags from multiple knowledge bases request
|
||||
// @Summary List Tags from Knowledge Bases
|
||||
// @Description List tags from multiple knowledge bases
|
||||
// @Tags knowledgebase
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param kb_ids query string true "Comma-separated Knowledge Base IDs"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/kb/tags [get]
|
||||
func (h *KnowledgebaseHandler) ListTagsFromKbs(c *gin.Context) {
|
||||
userID, code, err := h.getUserID(c)
|
||||
if err != nil {
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
kbIDsStr := c.Query("kb_ids")
|
||||
if kbIDsStr == "" {
|
||||
jsonError(c, common.CodeDataError, "kb_ids is required")
|
||||
return
|
||||
}
|
||||
|
||||
kbIDs := strings.Split(kbIDsStr, ",")
|
||||
for _, kbID := range kbIDs {
|
||||
if !h.kbService.Accessible(kbID, userID) {
|
||||
jsonError(c, common.CodeAuthenticationError, "No authorization.")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
jsonResponse(c, common.CodeSuccess, []string{}, "success")
|
||||
}
|
||||
|
||||
// RemoveTags handles the remove tags request
|
||||
// @Summary Remove Tags
|
||||
// @Description Remove tags from a knowledge base
|
||||
// @Tags knowledgebase
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param kb_id path string true "Knowledge Base ID"
|
||||
// @Param request body object{tags []string} true "tags to remove"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/kb/{kb_id}/rm_tags [post]
|
||||
func (h *KnowledgebaseHandler) RemoveTags(c *gin.Context) {
|
||||
userID, code, err := h.getUserID(c)
|
||||
if err != nil {
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
kbID := c.Param("kb_id")
|
||||
if kbID == "" {
|
||||
jsonError(c, common.CodeDataError, "kb_id is required")
|
||||
return
|
||||
}
|
||||
|
||||
if !h.kbService.Accessible(kbID, userID) {
|
||||
jsonError(c, common.CodeAuthenticationError, "No authorization.")
|
||||
return
|
||||
}
|
||||
|
||||
var req struct {
|
||||
Tags []string `json:"tags" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
jsonError(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
jsonResponse(c, common.CodeSuccess, true, "success")
|
||||
}
|
||||
|
||||
// RenameTag handles the rename tag request
|
||||
// @Summary Rename Tag
|
||||
// @Description Rename a tag in a knowledge base
|
||||
// @Tags knowledgebase
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param kb_id path string true "Knowledge Base ID"
|
||||
// @Param request body object{from_tag string, to_tag string} true "tag rename info"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/kb/{kb_id}/rename_tag [post]
|
||||
func (h *KnowledgebaseHandler) RenameTag(c *gin.Context) {
|
||||
userID, code, err := h.getUserID(c)
|
||||
if err != nil {
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
kbID := c.Param("kb_id")
|
||||
if kbID == "" {
|
||||
jsonError(c, common.CodeDataError, "kb_id is required")
|
||||
return
|
||||
}
|
||||
|
||||
if !h.kbService.Accessible(kbID, userID) {
|
||||
jsonError(c, common.CodeAuthenticationError, "No authorization.")
|
||||
return
|
||||
}
|
||||
|
||||
var req struct {
|
||||
FromTag string `json:"from_tag" binding:"required"`
|
||||
ToTag string `json:"to_tag" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
jsonError(c, common.CodeDataError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
jsonResponse(c, common.CodeSuccess, true, "success")
|
||||
}
|
||||
|
||||
// KnowledgeGraph handles the get knowledge graph request
|
||||
// @Summary Get Knowledge Graph
|
||||
// @Description Get knowledge graph for a knowledge base
|
||||
// @Tags knowledgebase
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param kb_id path string true "Knowledge Base ID"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/kb/{kb_id}/knowledge_graph [get]
|
||||
func (h *KnowledgebaseHandler) KnowledgeGraph(c *gin.Context) {
|
||||
userID, code, err := h.getUserID(c)
|
||||
if err != nil {
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
kbID := c.Param("kb_id")
|
||||
if kbID == "" {
|
||||
jsonError(c, common.CodeDataError, "kb_id is required")
|
||||
return
|
||||
}
|
||||
|
||||
if !h.kbService.Accessible(kbID, userID) {
|
||||
jsonError(c, common.CodeAuthenticationError, "No authorization.")
|
||||
return
|
||||
}
|
||||
|
||||
result := map[string]interface{}{
|
||||
"graph": map[string]interface{}{},
|
||||
"mind_map": map[string]interface{}{},
|
||||
}
|
||||
|
||||
jsonResponse(c, common.CodeSuccess, result, "success")
|
||||
}
|
||||
|
||||
// DeleteKnowledgeGraph handles the delete knowledge graph request
|
||||
// @Summary Delete Knowledge Graph
|
||||
// @Description Delete knowledge graph for a knowledge base
|
||||
// @Tags knowledgebase
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param kb_id path string true "Knowledge Base ID"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/kb/{kb_id}/knowledge_graph [delete]
|
||||
func (h *KnowledgebaseHandler) DeleteKnowledgeGraph(c *gin.Context) {
|
||||
userID, code, err := h.getUserID(c)
|
||||
if err != nil {
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
kbID := c.Param("kb_id")
|
||||
if kbID == "" {
|
||||
jsonError(c, common.CodeDataError, "kb_id is required")
|
||||
return
|
||||
}
|
||||
|
||||
if !h.kbService.Accessible(kbID, userID) {
|
||||
jsonError(c, common.CodeAuthenticationError, "No authorization.")
|
||||
return
|
||||
}
|
||||
|
||||
jsonResponse(c, common.CodeSuccess, true, "success")
|
||||
}
|
||||
|
||||
// GetMeta handles the get metadata request
|
||||
// @Summary Get Metadata
|
||||
// @Description Get metadata for knowledge bases
|
||||
// @Tags knowledgebase
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param kb_ids query string true "Comma-separated Knowledge Base IDs"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/kb/get_meta [get]
|
||||
func (h *KnowledgebaseHandler) GetMeta(c *gin.Context) {
|
||||
userID, code, err := h.getUserID(c)
|
||||
if err != nil {
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
kbIDsStr := c.Query("kb_ids")
|
||||
if kbIDsStr == "" {
|
||||
jsonError(c, common.CodeDataError, "kb_ids is required")
|
||||
return
|
||||
}
|
||||
|
||||
kbIDs := strings.Split(kbIDsStr, ",")
|
||||
for _, kbID := range kbIDs {
|
||||
if !h.kbService.Accessible(kbID, userID) {
|
||||
jsonError(c, common.CodeAuthenticationError, "No authorization.")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
jsonResponse(c, common.CodeSuccess, map[string]interface{}{}, "success")
|
||||
}
|
||||
|
||||
// GetBasicInfo handles the get basic info request
|
||||
// @Summary Get Basic Info
|
||||
// @Description Get basic information for a knowledge base
|
||||
// @Tags knowledgebase
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param kb_id query string true "Knowledge Base ID"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/kb/basic_info [get]
|
||||
func (h *KnowledgebaseHandler) GetBasicInfo(c *gin.Context) {
|
||||
userID, code, err := h.getUserID(c)
|
||||
if err != nil {
|
||||
jsonError(c, code, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
kbID := c.Query("kb_id")
|
||||
if kbID == "" {
|
||||
jsonError(c, common.CodeDataError, "kb_id is required")
|
||||
return
|
||||
}
|
||||
|
||||
if !h.kbService.Accessible(kbID, userID) {
|
||||
jsonError(c, common.CodeAuthenticationError, "No authorization.")
|
||||
return
|
||||
}
|
||||
|
||||
jsonResponse(c, common.CodeSuccess, map[string]interface{}{}, "success")
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"ragflow/internal/common"
|
||||
"ragflow/internal/service"
|
||||
)
|
||||
|
||||
@@ -48,44 +49,49 @@ func NewTenantHandler(tenantService *service.TenantService, userService *service
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/user/tenant_info [get]
|
||||
func (h *TenantHandler) TenantInfo(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",
|
||||
})
|
||||
return
|
||||
}
|
||||
// Get user by token
|
||||
user, code, err := h.userService.GetUserByToken(token)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{
|
||||
"code": code,
|
||||
"message": err.Error(),
|
||||
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
|
||||
}
|
||||
|
||||
// Get tenant info
|
||||
tenantInfo, err := h.tenantService.GetTenantInfo(user.ID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": "Failed to get tenant information",
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": common.CodeExceptionError,
|
||||
"message": err.Error(),
|
||||
"data": false,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if tenantInfo == nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{
|
||||
"error": "Tenant not found",
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": common.CodeDataError,
|
||||
"message": "Tenant not found!",
|
||||
"data": false,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 0,
|
||||
"data": tenantInfo,
|
||||
"code": common.CodeSuccess,
|
||||
"message": "success",
|
||||
"data": tenantInfo,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -99,38 +105,39 @@ func (h *TenantHandler) TenantInfo(c *gin.Context) {
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/tenant/list [get]
|
||||
func (h *TenantHandler) TenantList(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 list
|
||||
tenantList, err := h.tenantService.GetTenantList(user.ID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"code": 500,
|
||||
"message": "Failed to get tenant list",
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": common.CodeExceptionError,
|
||||
"message": err.Error(),
|
||||
"data": false,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 0,
|
||||
"data": tenantList,
|
||||
"code": common.CodeSuccess,
|
||||
"message": "success",
|
||||
"data": tenantList,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -522,3 +522,61 @@ func (h *UserHandler) GetLoginChannels(c *gin.Context) {
|
||||
"data": channels,
|
||||
})
|
||||
}
|
||||
|
||||
// SetTenantInfo update tenant information
|
||||
// @Summary Set Tenant Info
|
||||
// @Description Update tenant model configuration
|
||||
// @Tags users
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Security ApiKeyAuth
|
||||
// @Param request body service.SetTenantInfoRequest true "tenant info"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Router /v1/user/set_tenant_info [post]
|
||||
func (h *UserHandler) SetTenantInfo(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.SetTenantInfoRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": common.CodeArgumentError,
|
||||
"message": err.Error(),
|
||||
"data": false,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
err = h.userService.SetTenantInfo(user.ID, &req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": common.CodeDataError,
|
||||
"message": err.Error(),
|
||||
"data": false,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": common.CodeSuccess,
|
||||
"message": "success",
|
||||
"data": true,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user