diff --git a/admin/client/ragflow_client.py b/admin/client/ragflow_client.py index d8038d47ce..9d9dcab814 100644 --- a/admin/client/ragflow_client.py +++ b/admin/client/ragflow_client.py @@ -1655,7 +1655,7 @@ class RAGFlowClient: if self.server_type == "admin": response = self.http_client.request("GET", "/admin/version", use_api_base=True, auth_kind="admin") else: - response = self.http_client.request("GET", "/system/version", use_api_base=False, auth_kind="admin") + response = self.http_client.request("GET", "/system/version", use_api_base=True, auth_kind="admin") res_json = response.json() if response.status_code == 200: diff --git a/api/apps/restful_apis/system_api.py b/api/apps/restful_apis/system_api.py new file mode 100644 index 0000000000..b6b4e0e56f --- /dev/null +++ b/api/apps/restful_apis/system_api.py @@ -0,0 +1,42 @@ +# +# Copyright 2026 The InfiniFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +from api.apps import login_required + +from api.utils.api_utils import get_json_result +from common.versions import get_ragflow_version + +@manager.route("/system/version", methods=["GET"]) # noqa: F821 +@login_required +def version(): + """ + Get the current version of the application. + --- + tags: + - System + security: + - ApiKeyAuth: [] + responses: + 200: + description: Version retrieved successfully. + schema: + type: object + properties: + version: + type: string + description: Version number. + """ + return get_json_result(data=get_ragflow_version()) \ No newline at end of file diff --git a/api/apps/system_app.py b/api/apps/system_app.py index 5cbda3afd8..fd10492f5b 100644 --- a/api/apps/system_app.py +++ b/api/apps/system_app.py @@ -29,7 +29,6 @@ from api.utils.api_utils import ( server_error_response, generate_confirmation_token, ) -from common.versions import get_ragflow_version from common.time_utils import current_timestamp, datetime_format from common.log_utils import get_log_levels, set_log_level from timeit import default_timer as timer @@ -39,30 +38,6 @@ from quart import jsonify from api.utils.health_utils import run_health_checks, get_oceanbase_status from common import settings - -@manager.route("/version", methods=["GET"]) # noqa: F821 -@login_required -def version(): - """ - Get the current version of the application. - --- - tags: - - System - security: - - ApiKeyAuth: [] - responses: - 200: - description: Version retrieved successfully. - schema: - type: object - properties: - version: - type: string - description: Version number. - """ - return get_json_result(data=get_ragflow_version()) - - @manager.route("/status", methods=["GET"]) # noqa: F821 @login_required def status(): diff --git a/internal/cli/user_command.go b/internal/cli/user_command.go index fb3ccaa5b7..6b9a292e97 100644 --- a/internal/cli/user_command.go +++ b/internal/cli/user_command.go @@ -69,11 +69,11 @@ func (c *RAGFlowClient) ShowServerVersion(cmd *Command) (ResponseIf, error) { if iterations > 1 { // Benchmark mode: multiple iterations - return c.HTTPClient.RequestWithIterations("GET", "/system/version", false, "web", nil, nil, iterations) + return c.HTTPClient.RequestWithIterations("GET", "/system/version", true, "web", nil, nil, iterations) } // Single mode - resp, err := c.HTTPClient.Request("GET", "/system/version", false, "web", nil, nil) + resp, err := c.HTTPClient.Request("GET", "/system/version", true, "web", nil, nil) if err != nil { return nil, fmt.Errorf("failed to show version: %w", err) } diff --git a/internal/handler/search.go b/internal/handler/search.go index 7eb17ea9bd..1bb8cb0e12 100644 --- a/internal/handler/search.go +++ b/internal/handler/search.go @@ -40,7 +40,7 @@ func NewSearchHandler(searchService *service.SearchService, userService *service } } -// ListSearchApps list search apps +// ListSearches list search apps // @Summary List Search Apps // @Description Get list of search apps for the current user with filtering, pagination and sorting // @Tags search @@ -53,8 +53,8 @@ func NewSearchHandler(searchService *service.SearchService, userService *service // @Param desc query bool false "descending order (default: true)" // @Param request body service.ListSearchAppsRequest true "filter options including owner_ids" // @Success 200 {object} service.ListSearchAppsResponse -// @Router /v1/search/list [post] -func (h *SearchHandler) ListSearchApps(c *gin.Context) { +// @Router /api/v1/searches [post] +func (h *SearchHandler) ListSearches(c *gin.Context) { user, errorCode, errorMessage := GetUser(c) if errorCode != common.CodeSuccess { jsonError(c, errorCode, errorMessage) @@ -99,7 +99,7 @@ func (h *SearchHandler) ListSearchApps(c *gin.Context) { } // List search apps with filtering - result, err := h.searchService.ListSearchApps(userID, keywords, page, pageSize, orderby, desc, req.OwnerIDs) + result, err := h.searchService.ListSearches(userID, keywords, page, pageSize, orderby, desc, req.OwnerIDs) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "code": 500, diff --git a/internal/handler/system.go b/internal/handler/system.go index c2173ff8a2..6bd14e5067 100644 --- a/internal/handler/system.go +++ b/internal/handler/system.go @@ -48,7 +48,7 @@ func (h *SystemHandler) Ping(c *gin.Context) { c.String(http.StatusOK, "pong") } -// Health health check +// Health check func (h *SystemHandler) Health(c *gin.Context) { c.JSON(200, gin.H{ "status": "ok", diff --git a/internal/router/router.go b/internal/router/router.go index 5d4b8994f5..acca8e653c 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -22,7 +22,6 @@ import ( "ragflow/internal/handler" ) -// Router router type Router struct { authHandler *handler.AuthHandler userHandler *handler.UserHandler @@ -196,6 +195,16 @@ func (r *Router) Setup(engine *gin.Engine) { // message.GET("/:memory_id/:message_id/content", r.memoryHandler.GetMessageContent) // } + chats := v1.Group("/chats") + { + chats.GET("", r.chatHandler.ListChats) + } + + searches := v1.Group("/searches") + { + searches.GET("", r.searchHandler.ListSearches) + } + file := v1.Group("/files") { file.POST("", r.fileHandler.UploadFile) @@ -220,6 +229,11 @@ func (r *Router) Setup(engine *gin.Engine) { provider.PUT("/:provider_name/instances/:instance_name/models/:model_name", r.providerHandler.EnableOrDisableModel) provider.POST("/:provider_name/instances/:instance_name/models/:model_name", r.providerHandler.ChatToModel) } + + system := v1.Group("/system") + { + system.GET("/version", r.systemHandler.GetVersion) + } } // Knowledge base routes @@ -285,7 +299,6 @@ func (r *Router) Setup(engine *gin.Engine) { // Chat routes chat := authorized.Group("/v1/dialog") { - chat.GET("/list", r.chatHandler.ListChats) chat.POST("/next", r.chatHandler.ListChatsNext) chat.POST("/set", r.chatHandler.SetDialog) chat.POST("/rm", r.chatHandler.RemoveChats) @@ -306,12 +319,6 @@ func (r *Router) Setup(engine *gin.Engine) { connector.GET("/list", r.connectorHandler.ListConnectors) } - // Search routes - search := authorized.Group("/v1/search") - { - search.POST("/list", r.searchHandler.ListSearchApps) - } - // File routes file := authorized.Group("/v1/file") { diff --git a/internal/server/config.go b/internal/server/config.go index fb9bfe432e..0c2bd03f0f 100644 --- a/internal/server/config.go +++ b/internal/server/config.go @@ -179,6 +179,7 @@ type MinioConfig struct { Password string `mapstructure:"password"` // Secret key Secure bool `mapstructure:"secure"` // Use HTTPS Verify bool `mapstructure:"verify"` // Verify SSL certificates + Region string `mapstructure:"region"` // optional Bucket string `mapstructure:"bucket"` // Default bucket (optional) PrefixPath string `mapstructure:"prefix_path"` // Path prefix (optional) } @@ -448,6 +449,9 @@ func FromEnvironments() error { // Minio minioIP := strings.ToLower(os.Getenv("MINIO_IP")) if minioIP != "" { + if globalConfig.StorageEngine.Minio == nil { + return fmt.Errorf("Minio config not found") + } _, port, err := net.SplitHostPort(globalConfig.StorageEngine.Minio.Host) if err != nil { return fmt.Errorf("Error parsing host address %s: %v\n", globalConfig.StorageEngine.Minio.Host, err) @@ -458,6 +462,9 @@ func FromEnvironments() error { minioPort := strings.ToLower(os.Getenv("MINIO_PORT")) // println(fmt.Sprintf("MINIO ip and port from env: %s:%s", minioIP, minioPort)) if minioPort != "" { + if globalConfig.StorageEngine.Minio == nil { + return fmt.Errorf("Minio config not found") + } ip, _, err := net.SplitHostPort(globalConfig.StorageEngine.Minio.Host) if err != nil { return fmt.Errorf("Error parsing host address %s: %v\n", globalConfig.StorageEngine.Minio.Host, err) @@ -465,6 +472,14 @@ func FromEnvironments() error { globalConfig.StorageEngine.Minio.Host = fmt.Sprintf("%s:%s", ip, minioPort) } + minioRegion := strings.ToLower(os.Getenv("MINIO_REGION")) + if minioRegion != "" { + if globalConfig.StorageEngine.Minio == nil { + return fmt.Errorf("Minio config not found") + } + globalConfig.StorageEngine.Minio.Region = minioRegion + } + // Language if globalConfig.Language == "" { globalConfig.Language = GetLanguage() @@ -644,6 +659,7 @@ func FromConfigFile(configPath string) error { Secure: minioConfig.GetBool("secure"), PrefixPath: minioConfig.GetString("prefix_path"), Verify: minioConfig.GetBool("verify"), + Region: minioConfig.GetString("region"), Bucket: minioConfig.GetString("bucket"), } } diff --git a/internal/service/search.go b/internal/service/search.go index aa561bb1ce..d189ed1783 100644 --- a/internal/service/search.go +++ b/internal/service/search.go @@ -53,8 +53,8 @@ type ListSearchAppsResponse struct { Total int64 `json:"total"` } -// ListSearchApps list search apps with advanced filtering (equivalent to list_search_app) -func (s *SearchService) ListSearchApps(userID string, keywords string, page, pageSize int, orderby string, desc bool, ownerIDs []string) (*ListSearchAppsResponse, error) { +// ListSearches list search apps with advanced filtering (equivalent to list_search_app) +func (s *SearchService) ListSearches(userID string, keywords string, page, pageSize int, orderby string, desc bool, ownerIDs []string) (*ListSearchAppsResponse, error) { var searches []*entity.Search var total int64 var err error diff --git a/internal/storage/minio.go b/internal/storage/minio.go index 72e6d5d0df..11a9b6f9cf 100644 --- a/internal/storage/minio.go +++ b/internal/storage/minio.go @@ -71,6 +71,7 @@ func (m *MinioStorage) connect() error { Creds: credentials.NewStaticV4(m.config.User, m.config.Password, ""), Secure: m.config.Secure, Transport: transport, + Region: m.config.Region, }) if err != nil { return fmt.Errorf("failed to connect to MinIO: %w", err) diff --git a/test/testcases/test_web_api/common.py b/test/testcases/test_web_api/common.py index b77001971d..3d82bc009b 100644 --- a/test/testcases/test_web_api/common.py +++ b/test/testcases/test_web_api/common.py @@ -35,6 +35,7 @@ MEMORY_API_URL = f"/api/{VERSION}/memories" MESSAGE_API_URL = f"/api/{VERSION}/messages" API_APP_URL = f"/{VERSION}/api" SYSTEM_APP_URL = f"/{VERSION}/system" +SYSTEM_API_URL = f"/api/{VERSION}/system" LLM_APP_URL = f"/{VERSION}/llm" PLUGIN_APP_URL = f"/{VERSION}/plugin" SEARCHES_URL = f"/api/{VERSION}/searches" @@ -113,7 +114,7 @@ def system_status(auth, params=None, *, headers=HEADERS): def system_version(auth, params=None, *, headers=HEADERS): - res = requests.get(url=f"{HOST_ADDRESS}{SYSTEM_APP_URL}/version", headers=headers, auth=auth, params=params) + res = requests.get(url=f"{HOST_ADDRESS}{SYSTEM_API_URL}/version", headers=headers, auth=auth, params=params) return res.json() diff --git a/web/src/utils/api.ts b/web/src/utils/api.ts index b36dc3c675..329834894c 100644 --- a/web/src/utils/api.ts +++ b/web/src/utils/api.ts @@ -170,7 +170,7 @@ export default { moveFile: `${restAPIv1}/files/move`, // system - getSystemVersion: `${webAPI}/system/version`, + getSystemVersion: `${restAPIv1}/system/version`, getSystemStatus: `${webAPI}/system/status`, getSystemTokenList: `${webAPI}/system/token_list`, createSystemToken: `${webAPI}/system/new_token`,