mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-01 00:05:43 +08:00
Go CLI: refactor (#16355)
This commit is contained in:
@@ -957,7 +957,7 @@ func (h *Handler) HandleNoRoute(c *gin.Context) {
|
||||
// GetLogLevel returns the current log level
|
||||
func (h *Handler) GetLogLevel(c *gin.Context) {
|
||||
level := common.GetLevel()
|
||||
success(c, gin.H{"level": level}, "")
|
||||
success(c, gin.H{"level": level}, "SUCCESS")
|
||||
}
|
||||
|
||||
// SetLogLevelRequest set log level request
|
||||
@@ -978,7 +978,7 @@ func (h *Handler) SetLogLevel(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
success(c, gin.H{"level": req.Level}, "Log level updated successfully")
|
||||
success(c, gin.H{"level": req.Level}, "SUCCESS")
|
||||
}
|
||||
|
||||
func (h *Handler) ListMessagesFromQueue(c *gin.Context) {
|
||||
|
||||
@@ -83,6 +83,9 @@ func (r *Router) Setup(engine *gin.Engine) {
|
||||
|
||||
// Configs
|
||||
protected.GET("/configs", r.handler.ListConfigs)
|
||||
// Log level
|
||||
protected.GET("/config/log", r.handler.GetLogLevel)
|
||||
protected.PUT("/config/log", r.handler.SetLogLevel)
|
||||
|
||||
// Environments
|
||||
protected.GET("/environments", r.handler.ListEnvironments)
|
||||
@@ -90,10 +93,6 @@ func (r *Router) Setup(engine *gin.Engine) {
|
||||
// Version
|
||||
protected.GET("/version", r.handler.GetVersion)
|
||||
|
||||
// Log level
|
||||
protected.GET("/log_level", r.handler.GetLogLevel)
|
||||
protected.PUT("/log_level", r.handler.SetLogLevel)
|
||||
|
||||
queue := protected.Group("/queue")
|
||||
{
|
||||
queue.GET("/", r.handler.ShowMessageQueue)
|
||||
|
||||
@@ -21,7 +21,6 @@ import (
|
||||
"crypto/tls"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
@@ -36,7 +35,6 @@ import (
|
||||
"ragflow/internal/utility"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
@@ -1456,56 +1454,6 @@ func NewAdminException(message string) *AdminException {
|
||||
}
|
||||
}
|
||||
|
||||
func formatSystemSetting(setting entity.SystemSettings) map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"data_type": setting.DataType,
|
||||
"name": setting.Name,
|
||||
"setting_type": "config",
|
||||
"value": setting.Value,
|
||||
}
|
||||
}
|
||||
|
||||
func formatSystemSettings(settings []entity.SystemSettings) []map[string]interface{} {
|
||||
result := make([]map[string]interface{}, 0, len(settings))
|
||||
for _, setting := range settings {
|
||||
result = append(result, formatSystemSetting(setting))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func validateSystemSettingValue(setting entity.SystemSettings, value string) error {
|
||||
dataType := strings.ToLower(setting.DataType)
|
||||
switch dataType {
|
||||
case "string":
|
||||
return nil
|
||||
case "integer", "int":
|
||||
if _, err := strconv.Atoi(value); err != nil {
|
||||
return NewAdminException(fmt.Sprintf("Invalid integer value for %s: %s", setting.Name, value))
|
||||
}
|
||||
case "bool", "boolean":
|
||||
if value != "true" && value != "false" {
|
||||
return NewAdminException(fmt.Sprintf("Invalid bool value for %s: expected true or false", setting.Name))
|
||||
}
|
||||
case "json":
|
||||
if !json.Valid([]byte(value)) {
|
||||
return NewAdminException(fmt.Sprintf("Invalid JSON value for %s", setting.Name))
|
||||
}
|
||||
default:
|
||||
return NewAdminException(fmt.Sprintf("Unsupported data type for %s: %s", setting.Name, setting.DataType))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func inferSystemSettingDataType(name string) string {
|
||||
if strings.HasPrefix(name, "sandbox.") {
|
||||
return "json"
|
||||
}
|
||||
if strings.HasSuffix(name, ".enabled") {
|
||||
return "bool"
|
||||
}
|
||||
return "string"
|
||||
}
|
||||
|
||||
// GetVariable get variable by name
|
||||
// Returns the exact system setting with the given name, or settings matching the
|
||||
// given name prefix when an exact setting does not exist.
|
||||
@@ -1524,7 +1472,7 @@ func (s *Service) GetVariable(varName string) ([]map[string]interface{}, error)
|
||||
return nil, NewAdminException("Can't get setting: " + varName)
|
||||
}
|
||||
}
|
||||
return formatSystemSettings(settings), nil
|
||||
return common.FormatSystemSettings(settings), nil
|
||||
}
|
||||
|
||||
// ListAllVariables list all variables
|
||||
@@ -1535,7 +1483,7 @@ func (s *Service) ListAllVariables() ([]map[string]interface{}, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return formatSystemSettings(settings), nil
|
||||
return common.FormatSystemSettings(settings), nil
|
||||
}
|
||||
|
||||
// SetVariable set variable
|
||||
@@ -1549,7 +1497,7 @@ func (s *Service) SetVariable(varName, varValue string) error {
|
||||
|
||||
if len(settings) == 1 {
|
||||
setting := &settings[0]
|
||||
if err := validateSystemSettingValue(*setting, varValue); err != nil {
|
||||
if err = common.ValidateSystemSettingValue(*setting, varValue); err != nil {
|
||||
return err
|
||||
}
|
||||
setting.Value = varValue
|
||||
@@ -1558,14 +1506,14 @@ func (s *Service) SetVariable(varName, varValue string) error {
|
||||
return NewAdminException("Can't update more than 1 setting: " + varName)
|
||||
}
|
||||
|
||||
dataType := inferSystemSettingDataType(varName)
|
||||
dataType := common.InferSystemSettingDataType(varName)
|
||||
newSetting := &entity.SystemSettings{
|
||||
Name: varName,
|
||||
Value: varValue,
|
||||
Source: "admin",
|
||||
DataType: dataType,
|
||||
}
|
||||
if err := validateSystemSettingValue(*newSetting, varValue); err != nil {
|
||||
if err = common.ValidateSystemSettingValue(*newSetting, varValue); err != nil {
|
||||
return err
|
||||
}
|
||||
return s.systemSettingsDAO.Create(newSetting)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"ragflow/internal/common"
|
||||
"ragflow/internal/entity"
|
||||
"testing"
|
||||
)
|
||||
@@ -42,7 +43,7 @@ func TestValidateSystemSettingValue(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
setting := entity.SystemSettings{Name: "test.setting", DataType: tt.dataType}
|
||||
err := validateSystemSettingValue(setting, tt.value)
|
||||
err := common.ValidateSystemSettingValue(setting, tt.value)
|
||||
if (err != nil) != tt.wantError {
|
||||
t.Fatalf("validateSystemSettingValue() error = %v, wantError %v", err, tt.wantError)
|
||||
}
|
||||
@@ -58,7 +59,7 @@ func TestInferSystemSettingDataType(t *testing.T) {
|
||||
}
|
||||
|
||||
for name, want := range tests {
|
||||
if got := inferSystemSettingDataType(name); got != want {
|
||||
if got := common.InferSystemSettingDataType(name); got != want {
|
||||
t.Fatalf("inferSystemSettingDataType(%q) = %q, want %q", name, got, want)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1073,8 +1073,8 @@ func (c *CLI) AdminSetLicenseConfigCommand(cmd *Command) (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// SetVariable updates a system variable (admin mode only).
|
||||
func (c *CLI) SetVariable(cmd *Command) (ResponseIf, error) {
|
||||
// AdminSetVariableCommand updates a system variable (admin mode only).
|
||||
func (c *CLI) AdminSetVariableCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
@@ -1171,6 +1171,39 @@ func (c *CLI) AdminSetRoleDefaultModelsCommand(cmd *Command) (ResponseIf, error)
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// AdminSetLogLevelCommand set log level (admin mode only).
|
||||
func (c *CLI) AdminSetLogLevelCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != AdminMode {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
|
||||
logLevel, ok := cmd.Params["level"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("no log level")
|
||||
}
|
||||
|
||||
payload := map[string]interface{}{
|
||||
"level": logLevel,
|
||||
}
|
||||
|
||||
resp, err := c.AdminServerClient.Request("PUT", "/admin/config/log", "admin", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to change log level: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to register user: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result SimpleResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("change log level failed: invalid JSON (%w)", err)
|
||||
}
|
||||
result.Code = 0
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// AdminResetRoleDefaultModelsCommand reset role default models (admin mode only).
|
||||
func (c *CLI) AdminResetRoleDefaultModelsCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != AdminMode || c.AdminServerClient.LoginToken == nil {
|
||||
@@ -3504,3 +3537,31 @@ func (c *CLI) AdminDeleteModelsCommand(cmd *Command) (ResponseIf, error) {
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) AdminShowLogLevelCommand(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if c.Config.CLIMode != AdminMode {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode or already login")
|
||||
}
|
||||
|
||||
resp, err := c.AdminServerClient.Request("GET", "/admin/config/log", "web", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get log level config: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to get log level config: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonDataResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("get log level config failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
@@ -396,6 +396,8 @@ func (p *Parser) parseAdminShowCommands() (*Command, error) {
|
||||
return p.parseAdminShowQuota()
|
||||
case TokenTasks:
|
||||
return p.parseAdminShowTasks()
|
||||
case TokenLog:
|
||||
return p.parseAdminShowLogCommands()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown SHOW target: %s", p.curToken.Value)
|
||||
}
|
||||
@@ -1058,6 +1060,7 @@ func (p *Parser) parseAdminCreateCommand() (*Command, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// CREATE USER 'user@example.com' 'password';
|
||||
func (p *Parser) parseAdminCreateUser() (*Command, error) {
|
||||
p.nextToken() // consume USER
|
||||
userName, err := p.parseQuotedString()
|
||||
@@ -1649,6 +1652,8 @@ func (p *Parser) parseAdminSetCommand() (*Command, error) {
|
||||
return p.parseAdminSetVariable()
|
||||
case TokenRole:
|
||||
return p.parseAdminSetRoleDefaultModel()
|
||||
case TokenLog:
|
||||
return p.parseAdminSetLog()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown SET target: %s", p.curToken.Value)
|
||||
}
|
||||
@@ -1660,7 +1665,7 @@ func (p *Parser) parseAdminSetLicense() (*Command, error) {
|
||||
if p.curToken.Type == TokenConfig {
|
||||
p.nextToken() // consume CONFIG
|
||||
// SET LICENSE CONFIG <number1> <number2>
|
||||
cmd := NewCommand("admin_set_license_config_command")
|
||||
cmd := NewCommand("admin_set_license_config")
|
||||
number1, err := p.parseNumber()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1682,7 +1687,7 @@ func (p *Parser) parseAdminSetLicense() (*Command, error) {
|
||||
}
|
||||
p.nextToken()
|
||||
|
||||
cmd := NewCommand("admin_set_license_command")
|
||||
cmd := NewCommand("admin_set_license")
|
||||
cmd.Params["license"] = license
|
||||
|
||||
// Semicolon is optional
|
||||
@@ -1706,7 +1711,7 @@ func (p *Parser) parseAdminSetVariable() (*Command, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmd := NewCommand("set_variable")
|
||||
cmd := NewCommand("admin_set_variable")
|
||||
cmd.Params["var_name"] = varName
|
||||
cmd.Params["var_value"] = varValue
|
||||
|
||||
@@ -1778,6 +1783,45 @@ func (p *Parser) parseAdminSetRoleDefaultModel() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseAdminSetLog() (*Command, error) {
|
||||
p.nextToken() // consume LOG
|
||||
|
||||
switch p.curToken.Type {
|
||||
case TokenLevel:
|
||||
return p.parseAdminSetLogLevel()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown log target: %s", p.curToken.Value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parser) parseAdminSetLogLevel() (*Command, error) {
|
||||
p.nextToken() // consume LEVEL
|
||||
|
||||
cmd := NewCommand("admin_set_log_level")
|
||||
switch p.curToken.Type {
|
||||
case TokenDebug:
|
||||
cmd.Params["level"] = "debug"
|
||||
case TokenInfo:
|
||||
cmd.Params["level"] = "info"
|
||||
case TokenWarn:
|
||||
cmd.Params["level"] = "warn"
|
||||
case TokenError:
|
||||
cmd.Params["level"] = "error"
|
||||
case TokenFatal:
|
||||
cmd.Params["level"] = "fatal"
|
||||
case TokenPanic:
|
||||
cmd.Params["level"] = "panic"
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown log level: %s", p.curToken.Value)
|
||||
}
|
||||
p.nextToken()
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseAdminResetCommand() (*Command, error) {
|
||||
p.nextToken() // consume RESET
|
||||
|
||||
@@ -2695,6 +2739,30 @@ func (p *Parser) parseAdminShowTasks() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseAdminShowLogCommands() (*Command, error) {
|
||||
p.nextToken() // consume LOG
|
||||
|
||||
switch p.curToken.Type {
|
||||
case TokenLevel:
|
||||
return p.parseAdminShowLogLevel()
|
||||
default:
|
||||
return nil, fmt.Errorf("expected LEVEL after LOG")
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parser) parseAdminShowLogLevel() (*Command, error) {
|
||||
p.nextToken() // consume LEVEL
|
||||
|
||||
cmd := NewCommand("admin_show_log_level")
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// PURGE PREVIEW ORPHAN
|
||||
// PURGE ORPHAN
|
||||
|
||||
|
||||
@@ -97,14 +97,16 @@ func (c *CLI) ExecuteAdminCommand(cmd *Command) (ResponseIf, error) {
|
||||
return c.AdminListEnvironmentsCommand(cmd)
|
||||
case "admin_show_variable":
|
||||
return c.AdminShowVariable(cmd)
|
||||
case "admin_set_license_command":
|
||||
case "admin_set_license":
|
||||
return c.AdminSetLicenseCommand(cmd)
|
||||
case "admin_set_license_config_command":
|
||||
case "admin_set_license_config":
|
||||
return c.AdminSetLicenseConfigCommand(cmd)
|
||||
case "set_variable":
|
||||
return c.SetVariable(cmd)
|
||||
case "admin_set_variable":
|
||||
return c.AdminSetVariableCommand(cmd)
|
||||
case "admin_set_role_default_model":
|
||||
return c.AdminSetRoleDefaultModelsCommand(cmd)
|
||||
case "admin_set_log_level":
|
||||
return c.AdminSetLogLevelCommand(cmd)
|
||||
case "admin_reset_role_default_model":
|
||||
return c.AdminResetRoleDefaultModelsCommand(cmd)
|
||||
case "list_user_datasets":
|
||||
@@ -260,6 +262,8 @@ func (c *CLI) ExecuteAdminCommand(cmd *Command) (ResponseIf, error) {
|
||||
return c.ShowAdminServer(cmd)
|
||||
case "show_api_server":
|
||||
return c.ShowAPIServer(cmd)
|
||||
case "admin_show_log_level":
|
||||
return c.AdminShowLogLevelCommand(cmd)
|
||||
case "admin_list_api_servers":
|
||||
return c.CommonListAPIServers(cmd)
|
||||
case "add_api_server":
|
||||
@@ -293,8 +297,8 @@ func (c *CLI) ExecuteUserCommand(cmd *Command) (ResponseIf, error) {
|
||||
// Configuration commands
|
||||
case "api_list_configs":
|
||||
return c.ListConfigs(cmd)
|
||||
case "set_log_level":
|
||||
return c.SetLogLevel(cmd)
|
||||
case "api_set_log_level":
|
||||
return c.APISetLogLevelCommand(cmd)
|
||||
case "benchmark":
|
||||
return c.RunBenchmark(cmd)
|
||||
case "api_list_datasets":
|
||||
@@ -323,14 +327,16 @@ func (c *CLI) ExecuteUserCommand(cmd *Command) (ResponseIf, error) {
|
||||
case "api_delete_api_key":
|
||||
return c.APIDeleteAPIKeyCommand(cmd)
|
||||
case "api_set_api_key":
|
||||
return c.APISetAPIKey(cmd)
|
||||
return c.APISetAPIKeyCommand(cmd)
|
||||
case "api_set_variable":
|
||||
return c.APISetVariableCommand(cmd)
|
||||
case "api_unset_api_key":
|
||||
return c.APIUnsetAPIKeyCommand(cmd)
|
||||
case "api_show_version":
|
||||
return c.APIShowVersionCommand(cmd)
|
||||
case "api_show_api_key":
|
||||
return c.APIShowAPIKeyCommand(cmd)
|
||||
case "show_current":
|
||||
case "api_show_current":
|
||||
return c.CommonShowCurrentCommand(cmd)
|
||||
case "api_list_available_providers":
|
||||
return c.CommonAvailableProvidersCommand(cmd)
|
||||
@@ -411,7 +417,7 @@ func (c *CLI) ExecuteUserCommand(cmd *Command) (ResponseIf, error) {
|
||||
return c.CommonUseAdminServerCommand(cmd)
|
||||
case "set_default_model":
|
||||
return c.SetDefaultModel(cmd)
|
||||
case "reset_default_model":
|
||||
case "api_reset_default_model":
|
||||
return c.ResetDefaultModel(cmd)
|
||||
case "api_list_default_models":
|
||||
return c.ListDefaultModels(cmd)
|
||||
@@ -460,8 +466,14 @@ func (c *CLI) ExecuteUserCommand(cmd *Command) (ResponseIf, error) {
|
||||
return c.ShowAdminServer(cmd)
|
||||
case "show_api_server":
|
||||
return c.ShowAPIServer(cmd)
|
||||
case "api_show_log_level":
|
||||
return c.APIShowLogLevelCommand(cmd)
|
||||
case "api_list_api_servers":
|
||||
return c.CommonListAPIServers(cmd)
|
||||
case "api_list_environments":
|
||||
return c.APIListEnvironmentsCommand(cmd)
|
||||
case "api_list_variables":
|
||||
return c.APIListVariablesCommand(cmd)
|
||||
case "add_api_server":
|
||||
return c.AddAPIServer(cmd)
|
||||
case "delete_api_server":
|
||||
|
||||
@@ -164,10 +164,8 @@ func (p *Parser) parseUserCommand() (*Command, error) {
|
||||
return p.parseAlterCommand()
|
||||
case TokenSet:
|
||||
return p.parseAPISetCommands()
|
||||
case TokenUnset:
|
||||
return p.parseUnsetCommand()
|
||||
case TokenReset:
|
||||
return p.parseResetCommand()
|
||||
return p.parseAPIResetCommands()
|
||||
case TokenImport:
|
||||
return p.parseImportCommand()
|
||||
case TokenInsert:
|
||||
|
||||
@@ -227,36 +227,37 @@ func GetHost(config *map[string]interface{}, serverType, address, port string) s
|
||||
return result
|
||||
}
|
||||
|
||||
func (c *CLI) SetLogLevel(cmd *Command) (ResponseIf, error) {
|
||||
func (c *CLI) APISetLogLevelCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != APIMode {
|
||||
return nil, fmt.Errorf("this command is only allowed in USER mode")
|
||||
}
|
||||
|
||||
if logLevel, ok := cmd.Params["level"].(string); ok {
|
||||
payload := map[string]interface{}{
|
||||
"level": logLevel,
|
||||
}
|
||||
|
||||
httpClient := c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer]
|
||||
resp, err := httpClient.Request("PUT", "/system/log", "admin", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to change log level: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to register user: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result SimpleResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("change log level failed: invalid JSON (%w)", err)
|
||||
}
|
||||
result.Code = 0
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
logLevel, ok := cmd.Params["level"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("no log level")
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("no log level")
|
||||
payload := map[string]interface{}{
|
||||
"level": logLevel,
|
||||
}
|
||||
|
||||
httpClient := c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer]
|
||||
resp, err := httpClient.Request("PUT", "/system/config/log", "admin", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to change log level: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to register user: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result SimpleResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("change log level failed: invalid JSON (%w)", err)
|
||||
}
|
||||
result.Code = 0
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) RegisterUser(cmd *Command) (ResponseIf, error) {
|
||||
@@ -1041,8 +1042,8 @@ func (c *CLI) APIDeleteAPIKeyCommand(cmd *Command) (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// APISetAPIKey sets the API key after validating it
|
||||
func (c *CLI) APISetAPIKey(cmd *Command) (ResponseIf, error) {
|
||||
// APISetAPIKeyCommand sets the API key after validating it
|
||||
func (c *CLI) APISetAPIKeyCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != APIMode {
|
||||
return nil, fmt.Errorf("this command is only allowed in USER mode")
|
||||
}
|
||||
@@ -1099,6 +1100,52 @@ func (c *CLI) APISetAPIKey(cmd *Command) (ResponseIf, error) {
|
||||
return &successResult, nil
|
||||
}
|
||||
|
||||
// APISetVariableCommand sets variable value
|
||||
func (c *CLI) APISetVariableCommand(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if c.Config.CLIMode != APIMode {
|
||||
return nil, fmt.Errorf("this command is only allowed in USER mode")
|
||||
}
|
||||
|
||||
if c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].APIKey == nil && c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].LoginToken == nil {
|
||||
return nil, fmt.Errorf("API key not set. Please login first")
|
||||
}
|
||||
|
||||
varName, ok := cmd.Params["var_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("var_name not provided")
|
||||
}
|
||||
varValue, ok := cmd.Params["var_value"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("var_value not provided")
|
||||
}
|
||||
|
||||
payload := map[string]interface{}{
|
||||
"var_name": varName,
|
||||
"var_value": varValue,
|
||||
}
|
||||
resp, err := c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].Request("PUT", "/system/variables", "web", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to set variable: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to set variable: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result MessageResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("set variable failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// APIShowAPIKeyCommand displays the current API key
|
||||
func (c *CLI) APIShowAPIKeyCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != APIMode {
|
||||
@@ -3360,6 +3407,99 @@ func (c *CLI) ListUserIngestionTasks(cmd *Command) (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// APIShowLogLevelCommand sets the log level for the system.
|
||||
func (c *CLI) APIShowLogLevelCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != APIMode {
|
||||
return nil, fmt.Errorf("this command is only allowed in USER mode")
|
||||
}
|
||||
|
||||
resp, err := c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].Request("GET", "/system/config/log", "web", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get log level config: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to get log level config: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonDataResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("get log level config failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
|
||||
}
|
||||
|
||||
// APIListEnvironmentsCommand lists all system environments (api mode only).
|
||||
func (c *CLI) APIListEnvironmentsCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != APIMode {
|
||||
return nil, fmt.Errorf("this command is only allowed in USER mode")
|
||||
}
|
||||
|
||||
if c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].APIKey == nil && c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].LoginToken == nil {
|
||||
return nil, fmt.Errorf("API key not set. Please login first")
|
||||
}
|
||||
|
||||
resp, err := c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].Request("GET", "/system/environments", "web", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list environments: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to list environments: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("list environments failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// APIListVariablesCommand lists all system variables (api mode only).
|
||||
func (c *CLI) APIListVariablesCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.Config.CLIMode != APIMode {
|
||||
return nil, fmt.Errorf("this command is only allowed in USER mode")
|
||||
}
|
||||
|
||||
if c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].APIKey == nil && c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].LoginToken == nil {
|
||||
return nil, fmt.Errorf("API key not set. Please login first")
|
||||
}
|
||||
|
||||
resp, err := c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].Request("GET", "/system/variables", "web", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list variables: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("failed to list variables: HTTP %d, body: %s", resp.StatusCode, string(resp.Body))
|
||||
}
|
||||
|
||||
var result CommonResponse
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("list environments failed: invalid JSON (%w)", err)
|
||||
}
|
||||
|
||||
if result.Code != 0 {
|
||||
return nil, fmt.Errorf("%s", result.Message)
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) UserStartIngestionCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].APIKey == nil && c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].LoginToken == nil {
|
||||
return nil, fmt.Errorf("API key not set. Please login first")
|
||||
|
||||
@@ -20,7 +20,7 @@ func tokenTypeDescription(t int, tok Token) string {
|
||||
func (p *Parser) parseAPILogout() (*Command, error) {
|
||||
cmd := NewCommand("api_logout")
|
||||
p.nextToken()
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -55,7 +55,7 @@ func (p *Parser) parseAPILoginUser() (*Command, error) {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -66,7 +66,7 @@ func (p *Parser) parseAPILoginUser() (*Command, error) {
|
||||
func (p *Parser) parseAPIPingServer() (*Command, error) {
|
||||
cmd := NewCommand("api_ping_server")
|
||||
p.nextToken()
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -112,7 +112,7 @@ func (p *Parser) parseAPIRegisterCommand() (*Command, error) {
|
||||
cmd.Params["password"] = password
|
||||
p.nextToken() // consume 'password'
|
||||
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -154,6 +154,10 @@ func (p *Parser) parseAPIListCommands() (*Command, error) {
|
||||
return p.parseAPIListAvailableProviders()
|
||||
case TokenAPI:
|
||||
return p.parseAPIListAPIServers()
|
||||
case TokenEnvs:
|
||||
return p.parseAPIListEnvironments()
|
||||
case TokenVars:
|
||||
return p.parseAPIListVariables()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown LIST target: %s", p.curToken.Value)
|
||||
}
|
||||
@@ -174,7 +178,7 @@ func (p *Parser) parseAPIListDatasets() (*Command, error) {
|
||||
cmd := NewCommand("api_list_datasets")
|
||||
p.nextToken() // consume DATASETS
|
||||
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -459,7 +463,7 @@ func (p *Parser) parseAPIListDefaultModels() (*Command, error) {
|
||||
return nil, fmt.Errorf("expected MODELS")
|
||||
}
|
||||
p.nextToken()
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -516,13 +520,7 @@ func (p *Parser) parseAPIShowCommands() (*Command, error) {
|
||||
case TokenKey:
|
||||
return p.parseAPIShowKey()
|
||||
case TokenCurrent:
|
||||
p.nextToken()
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return NewCommand("show_current"), nil
|
||||
return p.parseAPIShowCurrent()
|
||||
case TokenVar:
|
||||
return p.parseShowVariable()
|
||||
case TokenProvider:
|
||||
@@ -541,6 +539,8 @@ func (p *Parser) parseAPIShowCommands() (*Command, error) {
|
||||
return p.parseUserShowAdmin()
|
||||
case TokenAPI:
|
||||
return p.parseUserShowAPI()
|
||||
case TokenLog:
|
||||
return p.parseAPIShowLogCommands()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown SHOW target: %s", p.curToken.Value)
|
||||
}
|
||||
@@ -566,6 +566,16 @@ func (p *Parser) parseAPIShowKey() (*Command, error) {
|
||||
return NewCommand("api_show_api_key"), nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseAPIShowCurrent() (*Command, error) {
|
||||
p.nextToken()
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return NewCommand("api_show_current"), nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseShowVariable() (*Command, error) {
|
||||
p.nextToken() // consume VAR
|
||||
varName, err := p.parseIdentifier()
|
||||
@@ -577,7 +587,7 @@ func (p *Parser) parseShowVariable() (*Command, error) {
|
||||
cmd.Params["var_name"] = varName
|
||||
|
||||
p.nextToken()
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -792,7 +802,7 @@ func (p *Parser) parseCreateRole() (*Command, error) {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -822,7 +832,7 @@ func (p *Parser) parseCreateModelProvider() (*Command, error) {
|
||||
cmd.Params["provider_key"] = providerKey
|
||||
|
||||
p.nextToken()
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -1271,7 +1281,7 @@ func (p *Parser) parseCreateDataset() (*Command, error) {
|
||||
return nil, fmt.Errorf("expected PARSER or PIPELINE")
|
||||
}
|
||||
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -1289,7 +1299,7 @@ func (p *Parser) parseCreateChat() (*Command, error) {
|
||||
cmd.Params["chat_name"] = chatName
|
||||
|
||||
p.nextToken()
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -1436,7 +1446,7 @@ func (p *Parser) parseDropUser() (*Command, error) {
|
||||
cmd.Params["user_name"] = userName
|
||||
|
||||
p.nextToken()
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -1454,7 +1464,7 @@ func (p *Parser) parseDropRole() (*Command, error) {
|
||||
cmd.Params["role_name"] = roleName
|
||||
|
||||
p.nextToken()
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -1492,7 +1502,7 @@ func (p *Parser) parseDropDataset() (*Command, error) {
|
||||
cmd.Params["dataset_name"] = datasetName
|
||||
|
||||
p.nextToken()
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -1510,7 +1520,7 @@ func (p *Parser) parseDropChat() (*Command, error) {
|
||||
cmd.Params["chat_name"] = chatName
|
||||
|
||||
p.nextToken()
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -1907,7 +1917,7 @@ func (p *Parser) parseAPISetCommands() (*Command, error) {
|
||||
p.nextToken() // consume SET
|
||||
|
||||
if p.curToken.Type == TokenVar {
|
||||
return p.parseSetVariable()
|
||||
return p.parseAPISetVariable()
|
||||
}
|
||||
if p.curToken.Type == TokenDefault {
|
||||
return p.parseSetDefault()
|
||||
@@ -1919,31 +1929,32 @@ func (p *Parser) parseAPISetCommands() (*Command, error) {
|
||||
return p.parseSetMeta()
|
||||
}
|
||||
if p.curToken.Type == TokenLog {
|
||||
return p.parseSetLog()
|
||||
return p.parseAPISetLog()
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unknown SET target: %s", p.curToken.Value)
|
||||
}
|
||||
|
||||
func (p *Parser) parseSetVariable() (*Command, error) {
|
||||
func (p *Parser) parseAPISetVariable() (*Command, error) {
|
||||
p.nextToken() // consume VAR
|
||||
varName, err := p.parseIdentifier()
|
||||
|
||||
varName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.nextToken()
|
||||
|
||||
varValue, err := p.parseVariableValue()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.nextToken()
|
||||
|
||||
cmd := NewCommand("set_variable")
|
||||
cmd := NewCommand("api_set_variable")
|
||||
cmd.Params["var_name"] = varName
|
||||
cmd.Params["var_value"] = varValue
|
||||
|
||||
p.nextToken()
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -2030,21 +2041,21 @@ func (p *Parser) parseAPISetAPIKey() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseSetLog() (*Command, error) {
|
||||
func (p *Parser) parseAPISetLog() (*Command, error) {
|
||||
p.nextToken() // consume LOG
|
||||
|
||||
switch p.curToken.Type {
|
||||
case TokenLevel:
|
||||
return p.parseSetLogLevel()
|
||||
return p.parseAPISetLogLevel()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown log target: %s", p.curToken.Value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parser) parseSetLogLevel() (*Command, error) {
|
||||
func (p *Parser) parseAPISetLogLevel() (*Command, error) {
|
||||
p.nextToken() // consume LEVEL
|
||||
|
||||
cmd := NewCommand("set_log_level")
|
||||
cmd := NewCommand("api_set_log_level")
|
||||
switch p.curToken.Type {
|
||||
case TokenDebug:
|
||||
cmd.Params["level"] = "debug"
|
||||
@@ -2059,23 +2070,31 @@ func (p *Parser) parseSetLogLevel() (*Command, error) {
|
||||
case TokenPanic:
|
||||
cmd.Params["level"] = "panic"
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown log target: %s", p.curToken.Value)
|
||||
return nil, fmt.Errorf("unknown log level: %s", p.curToken.Value)
|
||||
}
|
||||
p.nextToken()
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseResetCommand() (*Command, error) {
|
||||
func (p *Parser) parseAPIResetCommands() (*Command, error) {
|
||||
p.nextToken() // consume RESET
|
||||
|
||||
if p.curToken.Type != TokenDefault {
|
||||
return nil, fmt.Errorf("expected DEFAULT")
|
||||
switch p.curToken.Type {
|
||||
case TokenDefault:
|
||||
return p.parseAPIResetDefaultModel()
|
||||
case TokenKey:
|
||||
return p.parseAPIResetKey()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown RESET target: %s", p.curToken.Value)
|
||||
}
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
func (p *Parser) parseAPIResetDefaultModel() (*Command, error) {
|
||||
p.nextToken() // consume DEFAULT
|
||||
|
||||
var modelType string
|
||||
switch p.curToken.Type {
|
||||
@@ -2106,13 +2125,23 @@ func (p *Parser) parseResetCommand() (*Command, error) {
|
||||
}
|
||||
p.nextToken() // pass MODEL
|
||||
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseAPIResetKey() (*Command, error) {
|
||||
p.nextToken()
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return NewCommand("api_unset_api_key"), nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseImportCommand() (*Command, error) {
|
||||
p.nextToken() // consume IMPORT
|
||||
documentPaths, err := p.parseQuotedString()
|
||||
@@ -2140,7 +2169,7 @@ func (p *Parser) parseImportCommand() (*Command, error) {
|
||||
cmd.Params["dataset_name"] = datasetName
|
||||
|
||||
p.nextToken()
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -2519,7 +2548,7 @@ func (p *Parser) parseEnableCommand() (*Command, error) {
|
||||
}
|
||||
p.nextToken()
|
||||
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -2562,7 +2591,7 @@ func (p *Parser) parseDisableCommand() (*Command, error) {
|
||||
}
|
||||
p.nextToken()
|
||||
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -3006,7 +3035,7 @@ func (p *Parser) parseASRCommand() (*Command, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -3421,7 +3450,7 @@ func (p *Parser) parseParseDataset() (*Command, error) {
|
||||
cmd.Params["method"] = method
|
||||
|
||||
p.nextToken()
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -3455,7 +3484,7 @@ func (p *Parser) parseParseDocs() (*Command, error) {
|
||||
cmd.Params["documents"] = documents
|
||||
cmd.Params["dataset_id"] = datasetID
|
||||
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -3584,10 +3613,6 @@ func (p *Parser) parseUserStatement() (*Command, error) {
|
||||
return p.parseCreateCommand()
|
||||
case TokenDrop:
|
||||
return p.parseDropCommand()
|
||||
case TokenUnset:
|
||||
return p.parseUnsetCommand()
|
||||
case TokenReset:
|
||||
return p.parseResetCommand()
|
||||
case TokenList:
|
||||
return p.parseAPIListCommands()
|
||||
case TokenParse:
|
||||
@@ -3609,21 +3634,6 @@ func (p *Parser) parseUserStatement() (*Command, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parser) parseUnsetCommand() (*Command, error) {
|
||||
p.nextToken() // consume UNSET
|
||||
|
||||
if p.curToken.Type != TokenKey {
|
||||
return nil, fmt.Errorf("expected TOKEN after UNSET")
|
||||
}
|
||||
p.nextToken()
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return NewCommand("api_unset_api_key"), nil
|
||||
}
|
||||
|
||||
// parseGetCommand parses: GET CHUNK or GET METADATA
|
||||
func (p *Parser) parseGetCommand() (*Command, error) {
|
||||
p.nextToken() // consume GET
|
||||
@@ -4061,7 +4071,7 @@ func (p *Parser) parseUserStartIngestion() (*Command, error) {
|
||||
cmd.Params["dataset_id"] = datasetID
|
||||
p.nextToken()
|
||||
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -4112,7 +4122,7 @@ func (p *Parser) parseUserStopIngestion() (*Command, error) {
|
||||
cmd.Params["tasks"] = tasks
|
||||
p.nextToken()
|
||||
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -4138,7 +4148,7 @@ func (p *Parser) parseAPIListIngestionTasks() (*Command, error) {
|
||||
cmd.Params["dataset_id"] = datasetID
|
||||
}
|
||||
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -4164,7 +4174,7 @@ func (p *Parser) parseUserRemoveTask() (*Command, error) {
|
||||
|
||||
cmd.Params["tasks"] = tasks
|
||||
|
||||
// Semicolon is optional for UNSET TOKEN
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
@@ -4201,6 +4211,30 @@ func (p *Parser) parseUserShowAPI() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseAPIShowLogCommands() (*Command, error) {
|
||||
p.nextToken() // consume LOG
|
||||
|
||||
switch p.curToken.Type {
|
||||
case TokenLevel:
|
||||
return p.parseShowLogLevel()
|
||||
default:
|
||||
return nil, fmt.Errorf("expected LEVEL after LOG")
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parser) parseShowLogLevel() (*Command, error) {
|
||||
p.nextToken() // consume LEVEL
|
||||
|
||||
cmd := NewCommand("api_show_log_level")
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseAPIListAPIServers() (*Command, error) {
|
||||
p.nextToken() // consume API
|
||||
|
||||
@@ -4221,6 +4255,32 @@ func (p *Parser) parseAPIListAPIServers() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseAPIListEnvironments() (*Command, error) {
|
||||
p.nextToken() // consume Envs
|
||||
|
||||
cmd := NewCommand("api_list_environments")
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseAPIListVariables() (*Command, error) {
|
||||
p.nextToken() // consume Variables
|
||||
|
||||
cmd := NewCommand("api_list_variables")
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseExplainCommand() (*Command, error) {
|
||||
p.nextToken() // consume EXPLAIN
|
||||
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
|
||||
75
internal/common/system.go
Normal file
75
internal/common/system.go
Normal file
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"ragflow/internal/entity"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func FormatSystemSetting(setting entity.SystemSettings) map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"data_type": setting.DataType,
|
||||
"name": setting.Name,
|
||||
"setting_type": "config",
|
||||
"value": setting.Value,
|
||||
}
|
||||
}
|
||||
|
||||
func FormatSystemSettings(settings []entity.SystemSettings) []map[string]interface{} {
|
||||
result := make([]map[string]interface{}, 0, len(settings))
|
||||
for _, setting := range settings {
|
||||
result = append(result, FormatSystemSetting(setting))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func ValidateSystemSettingValue(setting entity.SystemSettings, value string) error {
|
||||
dataType := strings.ToLower(setting.DataType)
|
||||
switch dataType {
|
||||
case "string":
|
||||
return nil
|
||||
case "integer", "int":
|
||||
if _, err := strconv.Atoi(value); err != nil {
|
||||
return fmt.Errorf("invalid integer value for %s: %s", setting.Name, value)
|
||||
}
|
||||
case "bool", "boolean":
|
||||
if value != "true" && value != "false" {
|
||||
return fmt.Errorf("invalid bool value for %s: expected true or false", setting.Name)
|
||||
}
|
||||
case "json":
|
||||
if !json.Valid([]byte(value)) {
|
||||
return fmt.Errorf("invalid JSON value for %s", setting.Name)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unsupported data type for %s: %s", setting.Name, setting.DataType)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func InferSystemSettingDataType(name string) string {
|
||||
if strings.HasPrefix(name, "sandbox.") {
|
||||
return "json"
|
||||
}
|
||||
if strings.HasSuffix(name, ".enabled") {
|
||||
return "bool"
|
||||
}
|
||||
return "string"
|
||||
}
|
||||
@@ -222,3 +222,87 @@ func (h *SystemHandler) SetLogLevel(c *gin.Context) {
|
||||
"data": gin.H{"level": req.Level},
|
||||
})
|
||||
}
|
||||
|
||||
// ListVariables handle list variables
|
||||
func (h *SystemHandler) ListVariables(c *gin.Context) {
|
||||
variables, err := h.systemService.ListAllVariables()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 500,
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": variables,
|
||||
})
|
||||
}
|
||||
|
||||
// SetVariableHTTPRequest set variable request
|
||||
type SetVariableHTTPRequest struct {
|
||||
VarName string `json:"var_name" binding:"required"`
|
||||
VarValue string `json:"var_value" binding:"required"`
|
||||
}
|
||||
|
||||
// SetVariable handle set variable
|
||||
// Python logic: update or create a system setting with the given name and value
|
||||
func (h *SystemHandler) SetVariable(c *gin.Context) {
|
||||
var req SetVariableHTTPRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 400,
|
||||
"message": "Var name is required",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if req.VarName == "" {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 400,
|
||||
"message": "Var name is required",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if req.VarValue == "" {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 400,
|
||||
"message": "Var value is required",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.systemService.SetVariable(req.VarName, req.VarValue); err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 500,
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 0,
|
||||
"message": "SUCCESS",
|
||||
})
|
||||
}
|
||||
|
||||
// ListEnvironments handle list environments
|
||||
func (h *SystemHandler) ListEnvironments(c *gin.Context) {
|
||||
environments, err := h.systemService.ListEnvironments()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 500,
|
||||
"message": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": environments,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -561,6 +561,13 @@ func (r *Router) Setup(engine *gin.Engine) {
|
||||
config.PUT("/log", r.systemHandler.SetLogLevel)
|
||||
}
|
||||
|
||||
// Variables/Settings
|
||||
system.GET("/variables", r.systemHandler.ListVariables)
|
||||
system.PUT("/variables", r.systemHandler.SetVariable)
|
||||
|
||||
// Environments
|
||||
system.GET("/environments", r.systemHandler.ListEnvironments)
|
||||
|
||||
//log := system.Group("/log")
|
||||
//{
|
||||
// // /api/v1/system/log GET
|
||||
|
||||
@@ -20,7 +20,10 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"ragflow/internal/common"
|
||||
"ragflow/internal/engine/redis"
|
||||
"ragflow/internal/entity"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -32,11 +35,15 @@ import (
|
||||
)
|
||||
|
||||
// SystemService system service
|
||||
type SystemService struct{}
|
||||
type SystemService struct {
|
||||
systemSettingsDAO *dao.SystemSettingsDAO
|
||||
}
|
||||
|
||||
// NewSystemService create system service
|
||||
func NewSystemService() *SystemService {
|
||||
return &SystemService{}
|
||||
return &SystemService{
|
||||
systemSettingsDAO: dao.NewSystemSettingsDAO(),
|
||||
}
|
||||
}
|
||||
|
||||
// ConfigResponse system configuration response
|
||||
@@ -370,3 +377,115 @@ func (s *SystemService) Healthz(ctx context.Context) (*HealthzResponse, bool) {
|
||||
}
|
||||
return result, allOK
|
||||
}
|
||||
|
||||
// ListAllVariables list all variables
|
||||
// Returns all system settings from database
|
||||
func (s *SystemService) ListAllVariables() ([]map[string]interface{}, error) {
|
||||
settings, err := s.systemSettingsDAO.GetAll()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return common.FormatSystemSettings(settings), nil
|
||||
}
|
||||
|
||||
// SetVariable set variable
|
||||
// Creates or updates a system setting
|
||||
// If the setting exists, updates it; otherwise creates a new one
|
||||
func (s *SystemService) SetVariable(varName, varValue string) error {
|
||||
settings, err := s.systemSettingsDAO.GetByName(varName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(settings) == 1 {
|
||||
setting := &settings[0]
|
||||
if err = common.ValidateSystemSettingValue(*setting, varValue); err != nil {
|
||||
return err
|
||||
}
|
||||
setting.Value = varValue
|
||||
return s.systemSettingsDAO.UpdateByName(varName, setting)
|
||||
} else if len(settings) > 1 {
|
||||
return fmt.Errorf("can't update more than 1 setting: %s", varName)
|
||||
}
|
||||
|
||||
dataType := common.InferSystemSettingDataType(varName)
|
||||
newSetting := &entity.SystemSettings{
|
||||
Name: varName,
|
||||
Value: varValue,
|
||||
Source: "admin",
|
||||
DataType: dataType,
|
||||
}
|
||||
if err = common.ValidateSystemSettingValue(*newSetting, varValue); err != nil {
|
||||
return err
|
||||
}
|
||||
return s.systemSettingsDAO.Create(newSetting)
|
||||
}
|
||||
|
||||
// Config methods
|
||||
|
||||
// ListAllConfigs list all configs
|
||||
// Returns all service configurations from the config file
|
||||
func (s *SystemService) ListAllConfigs() ([]map[string]interface{}, error) {
|
||||
result := server.GetAllConfigs()
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Environment methods
|
||||
|
||||
// ListEnvironments list all environments
|
||||
func (s *SystemService) ListEnvironments() ([]map[string]interface{}, error) {
|
||||
result := make([]map[string]interface{}, 0)
|
||||
|
||||
// DOC_ENGINE
|
||||
docEngine := os.Getenv("DOC_ENGINE")
|
||||
if docEngine == "" {
|
||||
docEngine = "elasticsearch"
|
||||
}
|
||||
result = append(result, map[string]interface{}{
|
||||
"env": "DOC_ENGINE",
|
||||
"value": docEngine,
|
||||
})
|
||||
|
||||
// DEFAULT_SUPERUSER_EMAIL
|
||||
defaultSuperuserEmail := os.Getenv("DEFAULT_SUPERUSER_EMAIL")
|
||||
if defaultSuperuserEmail == "" {
|
||||
defaultSuperuserEmail = "admin@ragflow.io"
|
||||
}
|
||||
result = append(result, map[string]interface{}{
|
||||
"env": "DEFAULT_SUPERUSER_EMAIL",
|
||||
"value": defaultSuperuserEmail,
|
||||
})
|
||||
|
||||
// DB_TYPE
|
||||
dbType := os.Getenv("DB_TYPE")
|
||||
if dbType == "" {
|
||||
dbType = "mysql"
|
||||
}
|
||||
result = append(result, map[string]interface{}{
|
||||
"env": "DB_TYPE",
|
||||
"value": dbType,
|
||||
})
|
||||
|
||||
// DEVICE
|
||||
device := os.Getenv("DEVICE")
|
||||
if device == "" {
|
||||
device = "cpu"
|
||||
}
|
||||
result = append(result, map[string]interface{}{
|
||||
"env": "DEVICE",
|
||||
"value": device,
|
||||
})
|
||||
|
||||
// STORAGE_IMPL
|
||||
storageImpl := os.Getenv("STORAGE_IMPL")
|
||||
if storageImpl == "" {
|
||||
storageImpl = "MINIO"
|
||||
}
|
||||
result = append(result, map[string]interface{}{
|
||||
"env": "STORAGE_IMPL",
|
||||
"value": storageImpl,
|
||||
})
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user