mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-14 17:08:31 +08:00
Go: refactor CLI (#15728)
### What problem does this PR solve? ``` RAGFlow(user)> add api server 'ccc' host '127.0.0.1:9980'; SUCCESS RAGFlow(user)> list api server; +------------+---------------+-----------------+---------+-------------+---------------+ | api_server | api_server_ip | api_server_port | auth | user_name | user_password | +------------+---------------+-----------------+---------+-------------+---------------+ | ccc | 127.0.0.1 | 9980 | no auth | | | | default | 127.0.0.1 | 9384 | login | aaa@aaa.com | *** | +------------+---------------+-----------------+---------+-------------+---------------+ RAGFlow(user)> delete api server 'ccc'; SUCCESS RAGFlow(user)> list api server; +------------+---------------+-----------------+---------+ | api_server | api_server_ip | api_server_port | auth | +------------+---------------+-----------------+---------+ | default | 127.0.0.1 | 9384 | no auth | +------------+---------------+-----------------+---------+ RAGFlow(user)> show admin server; +--------------+-------+ | field | value | +--------------+-------+ | admin_server | N/A | +--------------+-------+ RAGFlow(user)> add admin server host '127.0.0.1:9880'; SUCCESS RAGFlow(user)> show admin server; +-------------------+-----------+ | field | value | +-------------------+-----------+ | admin_server_ip | 127.0.0.1 | | admin_server_port | 9880 | | auth | no auth | +-------------------+-----------+ RAGFlow(user)> delete admin server; SUCCESS RAGFlow(user)> show admin server; +--------------+-------+ | field | value | +--------------+-------+ | admin_server | N/A | +--------------+-------+ RAGFlow(user)> show current +-----------------+-------------+ | field | value | +-----------------+-------------+ | api_server_port | 9384 | | user_name | aaa@aaa.com | | user_password | *** | | mode | api | | verbose | false | | api_server | default | | api_server_ip | 127.0.0.1 | | auth | login | | output | table | | interactive | true | +-----------------+-------------+ ``` ### Type of change - [x] Refactoring --------- Signed-off-by: Jin Hai <haijin.chn@gmail.com>
This commit is contained in:
@@ -26,57 +26,109 @@ import (
|
||||
"ragflow/internal/cli"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Parse command line arguments (skip program name)
|
||||
args, err := cli.ParseConnectionArgs(os.Args[1:])
|
||||
func newMain() {
|
||||
parseArgs, err := cli.ParseArgs(os.Args[1:])
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
os.Exit(1)
|
||||
return
|
||||
}
|
||||
|
||||
// Initialize logger with appropriate level
|
||||
if parseArgs.ShowHelp {
|
||||
cli.PrintUsage()
|
||||
return
|
||||
}
|
||||
|
||||
//parseArgs.Print()
|
||||
logLevel := "warn" // Default to warn (quiet mode)
|
||||
if args.Verbose {
|
||||
if parseArgs.Verbose {
|
||||
logLevel = "info"
|
||||
}
|
||||
|
||||
if err = common.Init(logLevel, ""); err != nil {
|
||||
fmt.Printf("Warning: Failed to initialize logger: %v\n", err)
|
||||
}
|
||||
|
||||
// Show help and exit
|
||||
if args.ShowHelp {
|
||||
cli.PrintUsage()
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// Create CLI instance with parsed arguments
|
||||
cliApp, err := cli.NewCLIWithArgs(args)
|
||||
client, err := cli.NewCLIWithConfig(parseArgs)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to create CLI: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Handle interrupt signal
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
||||
go func() {
|
||||
<-sigChan
|
||||
cliApp.Cleanup()
|
||||
client.Cleanup()
|
||||
os.Exit(0)
|
||||
}()
|
||||
|
||||
// Check if we have a single command to execute
|
||||
if args.Command != nil {
|
||||
// Single command mode
|
||||
if err = cliApp.RunSingleCommand(args.Command); err != nil {
|
||||
if parseArgs.Command != nil {
|
||||
if err = client.RunSingleCommand(parseArgs.Command); err != nil {
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
} else {
|
||||
// Interactive mode
|
||||
if err = cliApp.Run(); err != nil {
|
||||
if err = client.NewRun(); err != nil {
|
||||
fmt.Printf("CLI error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
newMain()
|
||||
//// Parse command line arguments (skip program name)
|
||||
//args, err := cli.ParseConnectionArgs(os.Args[1:])
|
||||
//if err != nil {
|
||||
// fmt.Printf("Error: %v\n", err)
|
||||
// os.Exit(1)
|
||||
//}
|
||||
//
|
||||
//// Initialize logger with appropriate level
|
||||
//logLevel := "warn" // Default to warn (quiet mode)
|
||||
//if args.Verbose {
|
||||
// logLevel = "info"
|
||||
//}
|
||||
//if err = common.Init(logLevel); err != nil {
|
||||
// fmt.Printf("Warning: Failed to initialize logger: %v\n", err)
|
||||
//}
|
||||
//
|
||||
//// Show help and exit
|
||||
//if args.ShowHelp {
|
||||
// cli.PrintUsage()
|
||||
// os.Exit(0)
|
||||
//}
|
||||
//
|
||||
//// Create CLI instance with parsed arguments
|
||||
//cliApp, err := cli.NewCLIWithArgs(args)
|
||||
//if err != nil {
|
||||
// fmt.Printf("Failed to create CLI: %v\n", err)
|
||||
// os.Exit(1)
|
||||
//}
|
||||
//
|
||||
//// Handle interrupt signal
|
||||
//sigChan := make(chan os.Signal, 1)
|
||||
//signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
||||
//go func() {
|
||||
// <-sigChan
|
||||
// cliApp.Cleanup()
|
||||
// os.Exit(0)
|
||||
//}()
|
||||
//
|
||||
//// Check if we have a single command to execute
|
||||
//if args.Command != nil {
|
||||
// // Single command mode
|
||||
// if err = cliApp.RunSingleCommand(args.Command); err != nil {
|
||||
// fmt.Printf("Error: %v\n", err)
|
||||
// os.Exit(1)
|
||||
// }
|
||||
//} else {
|
||||
// // Interactive mode
|
||||
// if err = cliApp.Run(); err != nil {
|
||||
// fmt.Printf("CLI error: %v\n", err)
|
||||
// os.Exit(1)
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ func (r *Router) Setup(engine *gin.Engine) {
|
||||
protected.Use(r.handler.AuthMiddleware())
|
||||
{
|
||||
|
||||
protected.GET("/logout", r.handler.Logout)
|
||||
protected.POST("/logout", r.handler.Logout)
|
||||
// Auth
|
||||
protected.GET("/auth", r.handler.AuthCheck)
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
|
||||
// PingServer pings the server to check if it's alive
|
||||
// Returns benchmark result map if iterations > 1, otherwise prints status
|
||||
func (c *RAGFlowClient) PingAdmin(cmd *Command) (ResponseIf, error) {
|
||||
func (c *CLI) PingAdmin(cmd *Command) (ResponseIf, error) {
|
||||
// Get iterations from command params (for benchmark)
|
||||
iterations := 1
|
||||
if val, ok := cmd.Params["iterations"].(int); ok && val > 1 {
|
||||
@@ -33,11 +33,11 @@ func (c *RAGFlowClient) PingAdmin(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if iterations > 1 {
|
||||
// Benchmark mode: multiple iterations
|
||||
return c.HTTPClient.RequestWithIterations("GET", "/admin/ping", "web", nil, nil, iterations)
|
||||
return c.AdminServerClient.RequestWithIterations("GET", "/admin/ping", "web", nil, nil, iterations)
|
||||
}
|
||||
|
||||
// Single mode
|
||||
resp, err := c.HTTPClient.Request("GET", "/admin/ping", "web", nil, nil)
|
||||
resp, err := c.AdminServerClient.Request("GET", "/admin/ping", "web", nil, nil)
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
fmt.Println("Server is down")
|
||||
@@ -58,7 +58,7 @@ func (c *RAGFlowClient) PingAdmin(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
// Show admin version to show RAGFlow admin version
|
||||
// Returns benchmark result map if iterations > 1, otherwise prints status
|
||||
func (c *RAGFlowClient) ShowAdminVersion(cmd *Command) (ResponseIf, error) {
|
||||
func (c *CLI) ShowAdminVersion(cmd *Command) (ResponseIf, error) {
|
||||
// Get iterations from command params (for benchmark)
|
||||
iterations := 1
|
||||
if val, ok := cmd.Params["iterations"].(int); ok && val > 1 {
|
||||
@@ -67,11 +67,11 @@ func (c *RAGFlowClient) ShowAdminVersion(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if iterations > 1 {
|
||||
// Benchmark mode: multiple iterations
|
||||
return c.HTTPClient.RequestWithIterations("GET", "/admin/version", "web", nil, nil, iterations)
|
||||
return c.AdminServerClient.RequestWithIterations("GET", "/admin/version", "web", nil, nil, iterations)
|
||||
}
|
||||
|
||||
// Single mode
|
||||
resp, err := c.HTTPClient.Request("GET", "/admin/version", "web", nil, nil)
|
||||
resp, err := c.AdminServerClient.Request("GET", "/admin/version", "web", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to show admin version: %w", err)
|
||||
}
|
||||
@@ -93,9 +93,9 @@ func (c *RAGFlowClient) ShowAdminVersion(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
// ListRoles to list roles (admin mode only)
|
||||
func (c *RAGFlowClient) ListRoles(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) ListRoles(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")
|
||||
}
|
||||
|
||||
// Check for benchmark iterations
|
||||
@@ -106,10 +106,10 @@ func (c *RAGFlowClient) ListRoles(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if iterations > 1 {
|
||||
// Benchmark mode - return raw result for benchmark stats
|
||||
return c.HTTPClient.RequestWithIterations("GET", "/admin/roles", "admin", nil, nil, iterations)
|
||||
return c.AdminServerClient.RequestWithIterations("GET", "/admin/roles", "admin", nil, nil, iterations)
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", "/admin/roles", "admin", nil, nil)
|
||||
resp, err := c.AdminServerClient.Request("GET", "/admin/roles", "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list roles: %w", err)
|
||||
}
|
||||
@@ -136,9 +136,9 @@ func (c *RAGFlowClient) ListRoles(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
// ShowRole to show role (admin mode only)
|
||||
func (c *RAGFlowClient) ShowRole(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) ShowRole(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")
|
||||
}
|
||||
|
||||
roleName := cmd.Params["role_name"].(string)
|
||||
@@ -153,10 +153,10 @@ func (c *RAGFlowClient) ShowRole(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if iterations > 1 {
|
||||
// Benchmark mode - return raw result for benchmark stats
|
||||
return c.HTTPClient.RequestWithIterations("GET", endPoint, "admin", nil, nil, iterations)
|
||||
return c.AdminServerClient.RequestWithIterations("GET", endPoint, "admin", nil, nil, iterations)
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", endPoint, "admin", nil, nil)
|
||||
resp, err := c.AdminServerClient.Request("GET", endPoint, "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to show role: %w", err)
|
||||
}
|
||||
@@ -179,9 +179,9 @@ func (c *RAGFlowClient) ShowRole(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
// CreateRole creates a new role (admin mode only)
|
||||
func (c *RAGFlowClient) CreateRole(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) CreateRole(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")
|
||||
}
|
||||
|
||||
roleName, ok := cmd.Params["role_name"].(string)
|
||||
@@ -197,7 +197,7 @@ func (c *RAGFlowClient) CreateRole(cmd *Command) (ResponseIf, error) {
|
||||
payload["description"] = description
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("POST", "/admin/roles", "admin", nil, payload)
|
||||
resp, err := c.AdminServerClient.Request("POST", "/admin/roles", "admin", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create role: %w", err)
|
||||
}
|
||||
@@ -220,9 +220,9 @@ func (c *RAGFlowClient) CreateRole(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
// DropRole deletes the role (admin mode only)
|
||||
func (c *RAGFlowClient) DropRole(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) DropRole(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")
|
||||
}
|
||||
|
||||
roleName, ok := cmd.Params["role_name"].(string)
|
||||
@@ -230,7 +230,7 @@ func (c *RAGFlowClient) DropRole(cmd *Command) (ResponseIf, error) {
|
||||
return nil, fmt.Errorf("role_name not provided")
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("DELETE", fmt.Sprintf("/admin/roles/%s", roleName), "admin", nil, nil)
|
||||
resp, err := c.AdminServerClient.Request("DELETE", fmt.Sprintf("/admin/roles/%s", roleName), "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to drop role: %w", err)
|
||||
}
|
||||
@@ -253,9 +253,9 @@ func (c *RAGFlowClient) DropRole(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
// AlterRole alters the role rights (admin mode only)
|
||||
func (c *RAGFlowClient) AlterRole(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) AlterRole(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")
|
||||
}
|
||||
|
||||
roleName, ok := cmd.Params["role_name"].(string)
|
||||
@@ -271,7 +271,7 @@ func (c *RAGFlowClient) AlterRole(cmd *Command) (ResponseIf, error) {
|
||||
payload["description"] = description
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("PUT", fmt.Sprintf("/admin/roles/%s", roleName), "admin", nil, payload)
|
||||
resp, err := c.AdminServerClient.Request("PUT", fmt.Sprintf("/admin/roles/%s", roleName), "admin", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to alter role: %w", err)
|
||||
}
|
||||
@@ -294,9 +294,9 @@ func (c *RAGFlowClient) AlterRole(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
// GrantAdmin grants admin privileges to a user (admin mode only)
|
||||
func (c *RAGFlowClient) GrantAdmin(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) GrantAdmin(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")
|
||||
}
|
||||
|
||||
userName, ok := cmd.Params["user_name"].(string)
|
||||
@@ -304,7 +304,7 @@ func (c *RAGFlowClient) GrantAdmin(cmd *Command) (ResponseIf, error) {
|
||||
return nil, fmt.Errorf("user_name not provided")
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("PUT", fmt.Sprintf("/admin/users/%s/admin", userName), "admin", nil, nil)
|
||||
resp, err := c.AdminServerClient.Request("PUT", fmt.Sprintf("/admin/users/%s/admin", userName), "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to grant admin: %w", err)
|
||||
}
|
||||
@@ -327,9 +327,9 @@ func (c *RAGFlowClient) GrantAdmin(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
// RevokeAdmin revokes admin privileges from a user (admin mode only)
|
||||
func (c *RAGFlowClient) RevokeAdmin(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) RevokeAdmin(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")
|
||||
}
|
||||
|
||||
userName, ok := cmd.Params["user_name"].(string)
|
||||
@@ -337,7 +337,7 @@ func (c *RAGFlowClient) RevokeAdmin(cmd *Command) (ResponseIf, error) {
|
||||
return nil, fmt.Errorf("user_name not provided")
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("DELETE", fmt.Sprintf("/admin/users/%s/admin", userName), "admin", nil, nil)
|
||||
resp, err := c.AdminServerClient.Request("DELETE", fmt.Sprintf("/admin/users/%s/admin", userName), "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to revoke admin: %w", err)
|
||||
}
|
||||
@@ -360,9 +360,9 @@ func (c *RAGFlowClient) RevokeAdmin(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
// CreateUser creates a new user (admin mode only)
|
||||
func (c *RAGFlowClient) CreateUser(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) CreateUser(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")
|
||||
}
|
||||
|
||||
userName, ok := cmd.Params["user_name"].(string)
|
||||
@@ -387,7 +387,7 @@ func (c *RAGFlowClient) CreateUser(cmd *Command) (ResponseIf, error) {
|
||||
"role": "user",
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("POST", "/admin/users", "admin", nil, payload)
|
||||
resp, err := c.AdminServerClient.Request("POST", "/admin/users", "admin", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create user: %w", err)
|
||||
}
|
||||
@@ -410,9 +410,9 @@ func (c *RAGFlowClient) CreateUser(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
// ActivateUser activates or deactivates a user (admin mode only)
|
||||
func (c *RAGFlowClient) ActivateUser(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) ActivateUser(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")
|
||||
}
|
||||
|
||||
userName, ok := cmd.Params["user_name"].(string)
|
||||
@@ -434,7 +434,7 @@ func (c *RAGFlowClient) ActivateUser(cmd *Command) (ResponseIf, error) {
|
||||
"activate_status": activateStatus,
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("PUT", fmt.Sprintf("/admin/users/%s/activate", userName), "admin", nil, payload)
|
||||
resp, err := c.AdminServerClient.Request("PUT", fmt.Sprintf("/admin/users/%s/activate", userName), "admin", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to update user status: %w", err)
|
||||
}
|
||||
@@ -457,9 +457,9 @@ func (c *RAGFlowClient) ActivateUser(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
// AlterUserPassword changes a user's password (admin mode only)
|
||||
func (c *RAGFlowClient) AlterUserPassword(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) AlterUserPassword(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")
|
||||
}
|
||||
|
||||
userName, ok := cmd.Params["user_name"].(string)
|
||||
@@ -482,7 +482,7 @@ func (c *RAGFlowClient) AlterUserPassword(cmd *Command) (ResponseIf, error) {
|
||||
"new_password": encryptedPassword,
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("PUT", fmt.Sprintf("/admin/users/%s/password", userName), "admin", nil, payload)
|
||||
resp, err := c.AdminServerClient.Request("PUT", fmt.Sprintf("/admin/users/%s/password", userName), "admin", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to change user password: %w", err)
|
||||
}
|
||||
@@ -511,9 +511,9 @@ type listServicesResponse struct {
|
||||
}
|
||||
|
||||
// ListServices lists all services (admin mode only)
|
||||
func (c *RAGFlowClient) ListServices(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) ListServices(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")
|
||||
}
|
||||
|
||||
// Check for benchmark iterations
|
||||
@@ -524,10 +524,10 @@ func (c *RAGFlowClient) ListServices(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if iterations > 1 {
|
||||
// Benchmark mode - return raw result for benchmark stats
|
||||
return c.HTTPClient.RequestWithIterations("GET", "/admin/services", "admin", nil, nil, iterations)
|
||||
return c.AdminServerClient.RequestWithIterations("GET", "/admin/services", "admin", nil, nil, iterations)
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", "/admin/services", "admin", nil, nil)
|
||||
resp, err := c.AdminServerClient.Request("GET", "/admin/services", "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list services: %w", err)
|
||||
}
|
||||
@@ -554,9 +554,9 @@ func (c *RAGFlowClient) ListServices(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
// Show service show service (admin mode only)
|
||||
func (c *RAGFlowClient) ShowService(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) ShowService(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")
|
||||
}
|
||||
|
||||
serviceIndex := cmd.Params["number"].(int)
|
||||
@@ -571,10 +571,10 @@ func (c *RAGFlowClient) ShowService(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if iterations > 1 {
|
||||
// Benchmark mode - return raw result for benchmark stats
|
||||
return c.HTTPClient.RequestWithIterations("GET", endPoint, "admin", nil, nil, iterations)
|
||||
return c.AdminServerClient.RequestWithIterations("GET", endPoint, "admin", nil, nil, iterations)
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", endPoint, "admin", nil, nil)
|
||||
resp, err := c.AdminServerClient.Request("GET", endPoint, "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to show service: %w", err)
|
||||
}
|
||||
@@ -610,9 +610,9 @@ func normalizeVariableRows(rows []map[string]interface{}) {
|
||||
}
|
||||
|
||||
// ListVariables lists all system variables (admin mode only).
|
||||
func (c *RAGFlowClient) ListVariables(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) ListVariables(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")
|
||||
}
|
||||
|
||||
iterations := 1
|
||||
@@ -621,10 +621,10 @@ func (c *RAGFlowClient) ListVariables(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
if iterations > 1 {
|
||||
return c.HTTPClient.RequestWithIterations("GET", "/admin/variables", "admin", nil, nil, iterations)
|
||||
return c.AdminServerClient.RequestWithIterations("GET", "/admin/variables", "admin", nil, nil, iterations)
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", "/admin/variables", "admin", nil, nil)
|
||||
resp, err := c.AdminServerClient.Request("GET", "/admin/variables", "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list variables: %w", err)
|
||||
}
|
||||
@@ -648,9 +648,9 @@ func (c *RAGFlowClient) ListVariables(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
// ShowVariable shows system variables by exact name or name prefix (admin mode only).
|
||||
func (c *RAGFlowClient) ShowVariable(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) ShowVariable(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")
|
||||
}
|
||||
|
||||
varName, ok := cmd.Params["var_name"].(string)
|
||||
@@ -665,10 +665,10 @@ func (c *RAGFlowClient) ShowVariable(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
payload := map[string]interface{}{"var_name": varName}
|
||||
if iterations > 1 {
|
||||
return c.HTTPClient.RequestWithIterations("GET", "/admin/variables", "admin", nil, payload, iterations)
|
||||
return c.AdminServerClient.RequestWithIterations("GET", "/admin/variables", "admin", nil, payload, iterations)
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", "/admin/variables", "admin", nil, payload)
|
||||
resp, err := c.AdminServerClient.Request("GET", "/admin/variables", "admin", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to show variable: %w", err)
|
||||
}
|
||||
@@ -692,9 +692,9 @@ func (c *RAGFlowClient) ShowVariable(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
// SetVariable updates a system variable (admin mode only).
|
||||
func (c *RAGFlowClient) SetVariable(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) SetVariable(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")
|
||||
}
|
||||
|
||||
varName, ok := cmd.Params["var_name"].(string)
|
||||
@@ -710,7 +710,7 @@ func (c *RAGFlowClient) SetVariable(cmd *Command) (ResponseIf, error) {
|
||||
"var_name": varName,
|
||||
"var_value": varValue,
|
||||
}
|
||||
resp, err := c.HTTPClient.Request("PUT", "/admin/variables", "admin", nil, payload)
|
||||
resp, err := c.AdminServerClient.Request("PUT", "/admin/variables", "admin", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to set variable: %w", err)
|
||||
}
|
||||
@@ -734,9 +734,9 @@ func (c *RAGFlowClient) SetVariable(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
// ListUsers lists all users (admin mode only)
|
||||
// Returns (result_map, error) - result_map is non-nil for benchmark mode
|
||||
func (c *RAGFlowClient) ListUsers(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) ListUsers(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")
|
||||
}
|
||||
|
||||
// Check for benchmark iterations
|
||||
@@ -747,10 +747,10 @@ func (c *RAGFlowClient) ListUsers(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if iterations > 1 {
|
||||
// Benchmark mode - return raw result for benchmark stats
|
||||
return c.HTTPClient.RequestWithIterations("GET", "/admin/users", "admin", nil, nil, iterations)
|
||||
return c.AdminServerClient.RequestWithIterations("GET", "/admin/users", "admin", nil, nil, iterations)
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", "/admin/users", "admin", nil, nil)
|
||||
resp, err := c.AdminServerClient.Request("GET", "/admin/users", "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list users: %w", err)
|
||||
}
|
||||
@@ -777,9 +777,9 @@ func (c *RAGFlowClient) ListUsers(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
// DropUser deletes a user (admin mode only)
|
||||
func (c *RAGFlowClient) DropUser(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) DropUser(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")
|
||||
}
|
||||
|
||||
userName, ok := cmd.Params["user_name"].(string)
|
||||
@@ -787,7 +787,7 @@ func (c *RAGFlowClient) DropUser(cmd *Command) (ResponseIf, error) {
|
||||
return nil, fmt.Errorf("user_name not provided")
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("DELETE", fmt.Sprintf("/admin/users/%s", userName), "admin", nil, nil)
|
||||
resp, err := c.AdminServerClient.Request("DELETE", fmt.Sprintf("/admin/users/%s", userName), "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to drop user: %w", err)
|
||||
}
|
||||
@@ -810,9 +810,9 @@ func (c *RAGFlowClient) DropUser(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
// Show user show user (admin mode only)
|
||||
func (c *RAGFlowClient) ShowUser(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) ShowUser(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")
|
||||
}
|
||||
|
||||
userName, ok := cmd.Params["user_name"].(string)
|
||||
@@ -820,7 +820,7 @@ func (c *RAGFlowClient) ShowUser(cmd *Command) (ResponseIf, error) {
|
||||
return nil, fmt.Errorf("user_name not provided")
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", fmt.Sprintf("/admin/users/%s", userName), "admin", nil, nil)
|
||||
resp, err := c.AdminServerClient.Request("GET", fmt.Sprintf("/admin/users/%s", userName), "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to show user: %w", err)
|
||||
}
|
||||
@@ -844,9 +844,9 @@ func (c *RAGFlowClient) ShowUser(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
// ListUserDatasets lists datasets for a specific user (admin mode)
|
||||
// Returns (result_map, error) - result_map is non-nil for benchmark mode
|
||||
func (c *RAGFlowClient) ListUserDatasets(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) ListUserDatasets(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")
|
||||
}
|
||||
|
||||
userName, ok := cmd.Params["user_name"].(string)
|
||||
@@ -862,10 +862,10 @@ func (c *RAGFlowClient) ListUserDatasets(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if iterations > 1 {
|
||||
// Benchmark mode - return raw result for benchmark stats
|
||||
return c.HTTPClient.RequestWithIterations("GET", fmt.Sprintf("/admin/users/%s/datasets", userName), "admin", nil, nil, iterations)
|
||||
return c.AdminServerClient.RequestWithIterations("GET", fmt.Sprintf("/admin/users/%s/datasets", userName), "admin", nil, nil, iterations)
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", fmt.Sprintf("/admin/users/%s/datasets", userName), "admin", nil, nil)
|
||||
resp, err := c.AdminServerClient.Request("GET", fmt.Sprintf("/admin/users/%s/datasets", userName), "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list datasets: %w", err)
|
||||
}
|
||||
@@ -899,9 +899,9 @@ func (c *RAGFlowClient) ListUserDatasets(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
// ListAgents lists agents for a specific user (admin mode)
|
||||
// Returns (result_map, error) - result_map is non-nil for benchmark mode
|
||||
func (c *RAGFlowClient) ListAgents(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) ListAgents(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")
|
||||
}
|
||||
|
||||
userName, ok := cmd.Params["user_name"].(string)
|
||||
@@ -917,10 +917,10 @@ func (c *RAGFlowClient) ListAgents(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if iterations > 1 {
|
||||
// Benchmark mode - return raw result for benchmark stats
|
||||
return c.HTTPClient.RequestWithIterations("GET", fmt.Sprintf("/admin/users/%s/agents", userName), "admin", nil, nil, iterations)
|
||||
return c.AdminServerClient.RequestWithIterations("GET", fmt.Sprintf("/admin/users/%s/agents", userName), "admin", nil, nil, iterations)
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", fmt.Sprintf("/admin/users/%s/agents", userName), "admin", nil, nil)
|
||||
resp, err := c.AdminServerClient.Request("GET", fmt.Sprintf("/admin/users/%s/agents", userName), "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list agents: %w", err)
|
||||
}
|
||||
@@ -953,9 +953,9 @@ func (c *RAGFlowClient) ListAgents(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
// GrantPermission grants permission to a role (admin mode only)
|
||||
func (c *RAGFlowClient) GrantPermission(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) GrantPermission(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")
|
||||
}
|
||||
|
||||
userName, ok := cmd.Params["user_name"].(string)
|
||||
@@ -963,7 +963,7 @@ func (c *RAGFlowClient) GrantPermission(cmd *Command) (ResponseIf, error) {
|
||||
return nil, fmt.Errorf("user_name not provided")
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", fmt.Sprintf("/admin/users/%s/keys", userName), "admin", nil, nil)
|
||||
resp, err := c.AdminServerClient.Request("GET", fmt.Sprintf("/admin/users/%s/keys", userName), "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list tokens: %w", err)
|
||||
}
|
||||
@@ -991,9 +991,9 @@ func (c *RAGFlowClient) GrantPermission(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
// RevokePermission revokes permission from a role (admin mode only)
|
||||
func (c *RAGFlowClient) RevokePermission(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) RevokePermission(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")
|
||||
}
|
||||
|
||||
roleName, ok := cmd.Params["role_name"].(string)
|
||||
@@ -1023,7 +1023,7 @@ func (c *RAGFlowClient) RevokePermission(cmd *Command) (ResponseIf, error) {
|
||||
"actions": actions,
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("DELETE", fmt.Sprintf("/admin/roles/%s/permission", roleName), "admin", nil, payload)
|
||||
resp, err := c.AdminServerClient.Request("DELETE", fmt.Sprintf("/admin/roles/%s/permission", roleName), "admin", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to revoke permission: %w", err)
|
||||
}
|
||||
@@ -1051,9 +1051,9 @@ func (c *RAGFlowClient) RevokePermission(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
// AlterUserRole alters user's role (admin mode only)
|
||||
func (c *RAGFlowClient) AlterUserRole(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) AlterUserRole(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")
|
||||
}
|
||||
|
||||
userName, ok := cmd.Params["user_name"].(string)
|
||||
@@ -1070,7 +1070,7 @@ func (c *RAGFlowClient) AlterUserRole(cmd *Command) (ResponseIf, error) {
|
||||
"role_name": roleName,
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("PUT", fmt.Sprintf("/admin/users/%s/role", userName), "admin", nil, payload)
|
||||
resp, err := c.AdminServerClient.Request("PUT", fmt.Sprintf("/admin/users/%s/role", userName), "admin", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to alter user role: %w", err)
|
||||
}
|
||||
@@ -1098,9 +1098,9 @@ func (c *RAGFlowClient) AlterUserRole(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
// ShowUserPermission shows user's permissions (admin mode only)
|
||||
func (c *RAGFlowClient) ShowUserPermission(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) ShowUserPermission(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")
|
||||
}
|
||||
|
||||
userName, ok := cmd.Params["user_name"].(string)
|
||||
@@ -1108,7 +1108,7 @@ func (c *RAGFlowClient) ShowUserPermission(cmd *Command) (ResponseIf, error) {
|
||||
return nil, fmt.Errorf("user_name not provided")
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", fmt.Sprintf("/admin/users/%s/permission", userName), "admin", nil, nil)
|
||||
resp, err := c.AdminServerClient.Request("GET", fmt.Sprintf("/admin/users/%s/permission", userName), "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to show user permission: %w", err)
|
||||
}
|
||||
@@ -1136,9 +1136,9 @@ func (c *RAGFlowClient) ShowUserPermission(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
// GenerateAdminToken generates an API token for a user (admin mode only)
|
||||
func (c *RAGFlowClient) GenerateAdminToken(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) GenerateAdminToken(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")
|
||||
}
|
||||
|
||||
userName, ok := cmd.Params["user_name"].(string)
|
||||
@@ -1146,7 +1146,7 @@ func (c *RAGFlowClient) GenerateAdminToken(cmd *Command) (ResponseIf, error) {
|
||||
return nil, fmt.Errorf("user_name not provided")
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("POST", fmt.Sprintf("/admin/users/%s/keys", userName), "admin", nil, nil)
|
||||
resp, err := c.AdminServerClient.Request("POST", fmt.Sprintf("/admin/users/%s/keys", userName), "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate token: %w", err)
|
||||
}
|
||||
@@ -1173,9 +1173,9 @@ func (c *RAGFlowClient) GenerateAdminToken(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
// ListAdminTokens lists all API tokens for a user (admin mode only)
|
||||
func (c *RAGFlowClient) ListAdminTokens(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) ListAdminTokens(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")
|
||||
}
|
||||
|
||||
userName, ok := cmd.Params["user_name"].(string)
|
||||
@@ -1183,7 +1183,7 @@ func (c *RAGFlowClient) ListAdminTokens(cmd *Command) (ResponseIf, error) {
|
||||
return nil, fmt.Errorf("user_name not provided")
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", fmt.Sprintf("/admin/users/%s/keys", userName), "admin", nil, nil)
|
||||
resp, err := c.AdminServerClient.Request("GET", fmt.Sprintf("/admin/users/%s/keys", userName), "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list tokens: %w", err)
|
||||
}
|
||||
@@ -1215,9 +1215,9 @@ func (c *RAGFlowClient) ListAdminTokens(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
// DropToken drops an API token for a user (admin mode only)
|
||||
func (c *RAGFlowClient) DropAdminToken(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) DropAdminToken(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")
|
||||
}
|
||||
|
||||
userName, ok := cmd.Params["user_name"].(string)
|
||||
@@ -1233,7 +1233,7 @@ func (c *RAGFlowClient) DropAdminToken(cmd *Command) (ResponseIf, error) {
|
||||
// URL encode the token to handle special characters
|
||||
encodedToken := url.QueryEscape(token)
|
||||
|
||||
resp, err := c.HTTPClient.Request("DELETE", fmt.Sprintf("/admin/users/%s/keys/%s", userName, encodedToken), "admin", nil, nil)
|
||||
resp, err := c.AdminServerClient.Request("DELETE", fmt.Sprintf("/admin/users/%s/keys/%s", userName, encodedToken), "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to drop token: %w", err)
|
||||
}
|
||||
@@ -1255,12 +1255,12 @@ func (c *RAGFlowClient) DropAdminToken(cmd *Command) (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *RAGFlowClient) ListAdminTasks(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) ListAdminTasks(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")
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", "/admin/tasks", "admin", nil, nil)
|
||||
resp, err := c.AdminServerClient.Request("GET", "/admin/tasks", "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to drop token: %w", err)
|
||||
}
|
||||
@@ -1282,11 +1282,11 @@ func (c *RAGFlowClient) ListAdminTasks(cmd *Command) (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *RAGFlowClient) ListAdminIngestors(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) ListAdminIngestors(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")
|
||||
}
|
||||
resp, err := c.HTTPClient.Request("GET", "/admin/ingestors", "admin", nil, nil)
|
||||
resp, err := c.AdminServerClient.Request("GET", "/admin/ingestors", "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list ingestors: %w", err)
|
||||
}
|
||||
@@ -1307,12 +1307,12 @@ func (c *RAGFlowClient) ListAdminIngestors(cmd *Command) (ResponseIf, error) {
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
func (c *RAGFlowClient) ListAdminIngestionTasks(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) ListAdminIngestionTasks(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")
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", "/admin/ingestion/tasks", "admin", nil, nil)
|
||||
resp, err := c.AdminServerClient.Request("GET", "/admin/ingestion/tasks", "admin", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list admin tasks: %w", err)
|
||||
}
|
||||
@@ -1334,9 +1334,9 @@ func (c *RAGFlowClient) ListAdminIngestionTasks(cmd *Command) (ResponseIf, error
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *RAGFlowClient) AdminStartIngestionCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) AdminStartIngestionCommand(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")
|
||||
}
|
||||
|
||||
fileURI, ok := cmd.Params["uri"].(string)
|
||||
@@ -1348,7 +1348,7 @@ func (c *RAGFlowClient) AdminStartIngestionCommand(cmd *Command) (ResponseIf, er
|
||||
"from": "CLI",
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("POST", "/admin/ingestion", "admin", nil, payload)
|
||||
resp, err := c.AdminServerClient.Request("POST", "/admin/ingestion", "admin", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to ingest file: %w", err)
|
||||
}
|
||||
@@ -1370,9 +1370,9 @@ func (c *RAGFlowClient) AdminStartIngestionCommand(cmd *Command) (ResponseIf, er
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *RAGFlowClient) AdminStopIngestionCommand(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) AdminStopIngestionCommand(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")
|
||||
}
|
||||
|
||||
taskID, ok := cmd.Params["task_id"].(string)
|
||||
@@ -1384,7 +1384,7 @@ func (c *RAGFlowClient) AdminStopIngestionCommand(cmd *Command) (ResponseIf, err
|
||||
"from": "CLI",
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("DELETE", "/admin/ingestion", "admin", nil, payload)
|
||||
resp, err := c.AdminServerClient.Request("DELETE", "/admin/ingestion", "admin", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to ingest file: %w", err)
|
||||
}
|
||||
@@ -1406,9 +1406,9 @@ func (c *RAGFlowClient) AdminStopIngestionCommand(cmd *Command) (ResponseIf, err
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *RAGFlowClient) AdminShutdownIngestor(cmd *Command) (ResponseIf, error) {
|
||||
if c.ServerType != "admin" {
|
||||
return nil, fmt.Errorf("this command is only allowed in ADMIN mode")
|
||||
func (c *CLI) AdminShutdownIngestor(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")
|
||||
}
|
||||
|
||||
ingestorName, ok := cmd.Params["ingestor_name"].(string)
|
||||
@@ -1419,7 +1419,7 @@ func (c *RAGFlowClient) AdminShutdownIngestor(cmd *Command) (ResponseIf, error)
|
||||
"ingestor_name": ingestorName,
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("DELETE", "/admin/ingestors", "admin", nil, payload)
|
||||
resp, err := c.AdminServerClient.Request("DELETE", "/admin/ingestors", "admin", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to shutdown ingestor: %w", err)
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@ func (p *Parser) parseAdminLoginUser() (*Command, error) {
|
||||
cmd := NewCommand("login_user")
|
||||
|
||||
p.nextToken() // consume LOGIN
|
||||
if p.curToken.Type != TokenUser {
|
||||
return nil, fmt.Errorf("expected USER after LOGIN")
|
||||
if p.curToken.Type != TokenAdmin {
|
||||
return nil, fmt.Errorf("expected ADMIN after LOGIN")
|
||||
}
|
||||
|
||||
p.nextToken()
|
||||
@@ -196,6 +196,8 @@ func (p *Parser) parseAdminListCommand() (*Command, error) {
|
||||
return p.parseAdminListIngestors()
|
||||
case TokenIngestion:
|
||||
return p.parseAdminListIngestionTasks()
|
||||
case TokenAPI:
|
||||
return p.parseListApiCommand()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown LIST target: %s", p.curToken.Value)
|
||||
}
|
||||
@@ -418,15 +420,12 @@ func (p *Parser) parseAdminShowCommand() (*Command, error) {
|
||||
return NewCommand("show_token"), nil
|
||||
case TokenCurrent:
|
||||
p.nextToken()
|
||||
if p.curToken.Type != TokenUser {
|
||||
return nil, fmt.Errorf("expected USER after CURRENT")
|
||||
}
|
||||
p.nextToken()
|
||||
|
||||
// Semicolon is optional for SHOW TOKEN
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return NewCommand("show_current_user"), nil
|
||||
return NewCommand("show_current"), nil
|
||||
case TokenUser:
|
||||
return p.parseShowUser()
|
||||
case TokenRole:
|
||||
@@ -439,6 +438,10 @@ func (p *Parser) parseAdminShowCommand() (*Command, error) {
|
||||
return p.parseShowProvider()
|
||||
case TokenModel:
|
||||
return p.parseShowModel()
|
||||
case TokenAdmin:
|
||||
return p.parseUserShowAdmin()
|
||||
case TokenAPI:
|
||||
return p.parseUserShowAPI()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown SHOW target: %s", p.curToken.Value)
|
||||
}
|
||||
@@ -1377,7 +1380,7 @@ func (p *Parser) parseAdminImportCommand() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseAdminSearchCommand() (*Command, error) {
|
||||
func (p *Parser) parseAdminRetrieveCommand() (*Command, error) {
|
||||
p.nextToken() // consume SEARCH
|
||||
question, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
@@ -1533,8 +1536,8 @@ func (p *Parser) parseAdminUserStatement() (*Command, error) {
|
||||
return p.parseParseCommand()
|
||||
case TokenImport:
|
||||
return p.parseImportCommand()
|
||||
case TokenSearch:
|
||||
return p.parseSearchCommand()
|
||||
case TokenRetrieve:
|
||||
return p.parseRetrieveCommand()
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid user statement: %s", p.curToken.Value)
|
||||
}
|
||||
@@ -1637,6 +1640,40 @@ func (p *Parser) parseAdminRestartCommand() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseAdminAddCommand() (*Command, error) {
|
||||
p.nextToken() // consume ADD
|
||||
switch p.curToken.Type {
|
||||
case TokenAPI:
|
||||
return p.parseAddAPIServer()
|
||||
case TokenAdmin:
|
||||
return p.parseAddAdminServer()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown ADD target: %s", p.curToken.Value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parser) parseAdminDeleteCommand() (*Command, error) {
|
||||
p.nextToken() // consume DELETE
|
||||
switch p.curToken.Type {
|
||||
case TokenAPI:
|
||||
return p.parseDeleteAPIServer()
|
||||
case TokenAdmin:
|
||||
return p.parseDeleteAdminServer()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown ADD target: %s", p.curToken.Value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parser) parseAdminSaveCommand() (*Command, error) {
|
||||
p.nextToken() // consume SAVE
|
||||
switch p.curToken.Type {
|
||||
case TokenConfig:
|
||||
return p.parseSaveConfig()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown ADD target: %s", p.curToken.Value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parser) parseStartIngestion() (*Command, error) {
|
||||
p.nextToken() // consume Start
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ type BenchmarkResult struct {
|
||||
}
|
||||
|
||||
// RunBenchmark runs a benchmark with the given concurrency and iterations
|
||||
func (c *RAGFlowClient) RunBenchmark(cmd *Command) (ResponseIf, error) {
|
||||
func (c *CLI) RunBenchmark(cmd *Command) (ResponseIf, error) {
|
||||
concurrency, ok := cmd.Params["concurrency"].(int)
|
||||
if !ok {
|
||||
concurrency = 1
|
||||
@@ -64,7 +64,7 @@ func (c *RAGFlowClient) RunBenchmark(cmd *Command) (ResponseIf, error) {
|
||||
}
|
||||
|
||||
// runBenchmarkSingle runs benchmark with single concurrency (sequential execution)
|
||||
func (c *RAGFlowClient) runBenchmarkSingle(iterations int, nestedCmd *Command) (*BenchmarkResponse, error) {
|
||||
func (c *CLI) runBenchmarkSingle(iterations int, nestedCmd *Command) (*BenchmarkResponse, error) {
|
||||
commandType := nestedCmd.Type
|
||||
|
||||
// For search_on_datasets, convert dataset names to IDs first
|
||||
@@ -144,7 +144,7 @@ func (c *RAGFlowClient) runBenchmarkSingle(iterations int, nestedCmd *Command) (
|
||||
}
|
||||
|
||||
// runBenchmarkConcurrent runs benchmark with multiple concurrent workers
|
||||
func (c *RAGFlowClient) runBenchmarkConcurrent(concurrency, iterations int, nestedCmd *Command) (*BenchmarkResponse, error) {
|
||||
func (c *CLI) runBenchmarkConcurrent(concurrency, iterations int, nestedCmd *Command) (*BenchmarkResponse, error) {
|
||||
results := make([]map[string]interface{}, concurrency)
|
||||
var wg sync.WaitGroup
|
||||
|
||||
@@ -173,8 +173,13 @@ func (c *RAGFlowClient) runBenchmarkConcurrent(concurrency, iterations int, nest
|
||||
defer wg.Done()
|
||||
|
||||
// Create a new client for each goroutine to avoid race conditions
|
||||
workerClient := NewRAGFlowClient(c.ServerType)
|
||||
workerClient.HTTPClient = c.HTTPClient // Share the same HTTP client config
|
||||
workerClient, err := NewCLIWithConfig(nil)
|
||||
if err != nil {
|
||||
fmt.Printf("fail to create worker client: %s", err)
|
||||
return
|
||||
}
|
||||
workerClient.AdminServerClient = c.AdminServerClient
|
||||
workerClient.APIServerClientMap = c.APIServerClientMap
|
||||
|
||||
// Execute benchmark silently (no output)
|
||||
responseList := workerClient.executeBenchmarkSilent(nestedCmd, iterations)
|
||||
@@ -218,21 +223,23 @@ func (c *RAGFlowClient) runBenchmarkConcurrent(concurrency, iterations int, nest
|
||||
}
|
||||
|
||||
// executeBenchmarkSilent executes a command for benchmark without printing output
|
||||
func (c *RAGFlowClient) executeBenchmarkSilent(cmd *Command, iterations int) []*Response {
|
||||
func (c *CLI) executeBenchmarkSilent(cmd *Command, iterations int) []*Response {
|
||||
responseList := make([]*Response, 0, iterations)
|
||||
|
||||
httpClient := c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer]
|
||||
|
||||
for i := 0; i < iterations; i++ {
|
||||
var resp *Response
|
||||
var err error
|
||||
|
||||
switch cmd.Type {
|
||||
case "ping":
|
||||
resp, err = c.HTTPClient.Request("GET", "/system/ping", "web", nil, nil)
|
||||
resp, err = httpClient.Request("GET", "/system/ping", "web", nil, nil)
|
||||
case "list_user_datasets":
|
||||
resp, err = c.HTTPClient.Request("POST", "/kb/list", "web", nil, nil)
|
||||
resp, err = httpClient.Request("POST", "/kb/list", "web", nil, nil)
|
||||
case "list_datasets":
|
||||
userName, _ := cmd.Params["user_name"].(string)
|
||||
resp, err = c.HTTPClient.Request("GET", fmt.Sprintf("/admin/users/%s/datasets", userName), "admin", nil, nil)
|
||||
resp, err = httpClient.Request("GET", fmt.Sprintf("/admin/users/%s/datasets", userName), "admin", nil, nil)
|
||||
case "search_on_datasets":
|
||||
question, _ := cmd.Params["question"].(string)
|
||||
datasetIDs, _ := cmd.Params["dataset_ids"].([]string)
|
||||
@@ -242,7 +249,7 @@ func (c *RAGFlowClient) executeBenchmarkSilent(cmd *Command, iterations int) []*
|
||||
"similarity_threshold": 0.2,
|
||||
"vector_similarity_weight": 0.3,
|
||||
}
|
||||
resp, err = c.HTTPClient.Request("POST", "/datasets/search", "web", nil, payload)
|
||||
resp, err = httpClient.Request("POST", "/datasets/search", "web", nil, payload)
|
||||
default:
|
||||
// For other commands, we would need to add specific handling
|
||||
// For now, mark as failed
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
304
internal/cli/cli_http.go
Normal file
304
internal/cli/cli_http.go
Normal file
@@ -0,0 +1,304 @@
|
||||
//
|
||||
// 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 cli
|
||||
|
||||
import "fmt"
|
||||
|
||||
// ExecuteCommand executes a parsed command
|
||||
// Returns benchmark result map for commands that support it (e.g., ping_server with iterations > 1)
|
||||
func (c *CLI) ExecuteCommand(cmd *Command) (ResponseIf, error) {
|
||||
switch c.Config.CLIMode {
|
||||
case APIMode:
|
||||
// Interactive mode: execute command with user privileges
|
||||
return c.ExecuteUserCommand(cmd)
|
||||
case AdminMode:
|
||||
// Admin mode: execute command with admin privileges
|
||||
return c.ExecuteAdminCommand(cmd)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid server type: %s", c.Config.CLIMode)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CLI) ExecuteAdminCommand(cmd *Command) (ResponseIf, error) {
|
||||
switch cmd.Type {
|
||||
case "login_user":
|
||||
return c.LoginUserByCommand(cmd)
|
||||
case "logout":
|
||||
return c.Logout()
|
||||
case "ping":
|
||||
return c.PingByCommand(cmd)
|
||||
case "benchmark":
|
||||
return c.RunBenchmark(cmd)
|
||||
case "list_users":
|
||||
return c.ListUsers(cmd)
|
||||
case "list_services":
|
||||
return c.ListServices(cmd)
|
||||
case "grant_admin":
|
||||
return c.GrantAdmin(cmd)
|
||||
case "revoke_admin":
|
||||
return c.RevokeAdmin(cmd)
|
||||
case "create_user":
|
||||
return c.CreateUser(cmd)
|
||||
case "activate_user":
|
||||
return c.ActivateUser(cmd)
|
||||
case "alter_user":
|
||||
return c.AlterUserPassword(cmd)
|
||||
case "drop_user":
|
||||
return c.DropUser(cmd)
|
||||
case "show_service":
|
||||
return c.ShowService(cmd)
|
||||
case "show_version":
|
||||
return c.ShowAdminVersion(cmd)
|
||||
case "show_current":
|
||||
return c.ShowCommonCurrent(cmd)
|
||||
case "show_user":
|
||||
return c.ShowUser(cmd)
|
||||
case "list_variables":
|
||||
return c.ListVariables(cmd)
|
||||
case "show_variable":
|
||||
return c.ShowVariable(cmd)
|
||||
case "set_variable":
|
||||
return c.SetVariable(cmd)
|
||||
case "list_user_datasets":
|
||||
return c.ListUserDatasets(cmd)
|
||||
case "list_agents":
|
||||
return c.ListAgents(cmd)
|
||||
case "generate_token":
|
||||
return c.GenerateAdminToken(cmd)
|
||||
case "list_tokens":
|
||||
return c.ListAdminTokens(cmd)
|
||||
case "drop_token":
|
||||
return c.DropAdminToken(cmd)
|
||||
case "list_available_providers":
|
||||
return c.ListAvailableProviders(cmd)
|
||||
case "show_provider":
|
||||
return c.ShowProvider(cmd)
|
||||
case "list_provider_models":
|
||||
return c.ListModels(cmd)
|
||||
case "list_supported_models":
|
||||
return c.ListSupportedModels(cmd)
|
||||
case "list_instance_models":
|
||||
return c.ListInstanceModels(cmd)
|
||||
case "show_provider_model":
|
||||
return c.ShowProviderModel(cmd)
|
||||
case "show_model":
|
||||
return c.ShowModel(cmd)
|
||||
case "list_all_models":
|
||||
return c.ListAllModels(cmd)
|
||||
case "list_admin_tasks":
|
||||
return c.ListAdminTasks(cmd)
|
||||
case "admin_list_ingestors":
|
||||
return c.ListAdminIngestors(cmd)
|
||||
case "admin_start_ingestion_command":
|
||||
return c.AdminStartIngestionCommand(cmd)
|
||||
case "admin_stop_ingestion_command":
|
||||
return c.AdminStopIngestionCommand(cmd)
|
||||
case "admin_shutdown_ingestor_command":
|
||||
return c.AdminShutdownIngestor(cmd)
|
||||
case "list_admin_ingestion_tasks":
|
||||
return c.ListAdminIngestionTasks(cmd)
|
||||
case "show_admin_server":
|
||||
return c.ShowAdminServer(cmd)
|
||||
case "show_api_server":
|
||||
return c.ShowAPIServer(cmd)
|
||||
case "list_api_server":
|
||||
return c.ListAPIServer(cmd)
|
||||
case "add_api_server":
|
||||
return c.AddAPIServer(cmd)
|
||||
case "delete_api_server":
|
||||
return c.DeleteAPIServer(cmd)
|
||||
case "add_admin_server":
|
||||
return nil, fmt.Errorf("cannot add admin server in admin mode")
|
||||
case "delete_admin_server":
|
||||
return nil, fmt.Errorf("cannot delete admin server in admin mode")
|
||||
case "save_config_command":
|
||||
return c.SaveServerConfig(cmd)
|
||||
// TODO: Implement other commands
|
||||
default:
|
||||
return nil, fmt.Errorf("command '%s' would be executed with API", cmd.Type)
|
||||
}
|
||||
}
|
||||
func (c *CLI) ExecuteUserCommand(cmd *Command) (ResponseIf, error) {
|
||||
switch cmd.Type {
|
||||
case "register_user":
|
||||
return c.RegisterUser(cmd)
|
||||
case "login_user":
|
||||
return c.LoginUserByCommand(cmd)
|
||||
case "logout":
|
||||
return c.Logout()
|
||||
case "ping":
|
||||
return c.PingByCommand(cmd)
|
||||
// Configuration commands
|
||||
case "list_configs":
|
||||
return c.ListConfigs(cmd)
|
||||
case "set_log_level":
|
||||
return c.SetLogLevel(cmd)
|
||||
case "benchmark":
|
||||
return c.RunBenchmark(cmd)
|
||||
case "list_datasets":
|
||||
return c.ListDatasets(cmd)
|
||||
case "list_dataset_documents":
|
||||
return c.ListDatasetDocumentUserCommand(cmd)
|
||||
case "search_on_datasets":
|
||||
return c.SearchOnDatasets(cmd)
|
||||
case "search_help":
|
||||
printSearchHelp()
|
||||
return nil, nil
|
||||
case "create_token":
|
||||
return c.CreateToken(cmd)
|
||||
case "list_tokens":
|
||||
return c.ListTokens(cmd)
|
||||
case "drop_token":
|
||||
return c.DropToken(cmd)
|
||||
case "set_token":
|
||||
return c.SetToken(cmd)
|
||||
case "show_token":
|
||||
return c.ShowToken(cmd)
|
||||
case "unset_token":
|
||||
return c.UnsetToken(cmd)
|
||||
case "show_version":
|
||||
return c.ShowServerVersion(cmd)
|
||||
case "show_current":
|
||||
return c.ShowCommonCurrent(cmd)
|
||||
case "list_available_providers":
|
||||
return c.ListAvailableProviders(cmd)
|
||||
case "show_provider":
|
||||
return c.ShowProvider(cmd)
|
||||
case "list_provider_models":
|
||||
return c.ListModels(cmd)
|
||||
case "list_supported_models":
|
||||
return c.ListSupportedModels(cmd)
|
||||
case "list_instance_models":
|
||||
return c.ListInstanceModels(cmd)
|
||||
case "show_provider_model":
|
||||
return c.ShowProviderModel(cmd)
|
||||
case "show_model":
|
||||
return c.ShowModel(cmd)
|
||||
case "list_all_models":
|
||||
return c.ListAllModels(cmd)
|
||||
// Provider commands
|
||||
case "add_provider":
|
||||
return c.AddProvider(cmd)
|
||||
case "list_providers":
|
||||
return c.ListProviders(cmd)
|
||||
case "delete_provider":
|
||||
return c.DeleteProvider(cmd)
|
||||
// Provider instance commands
|
||||
case "create_provider_instance":
|
||||
return c.CreateProviderInstance(cmd)
|
||||
case "list_provider_instances":
|
||||
return c.ListProviderInstances(cmd)
|
||||
case "show_provider_instance":
|
||||
return c.ShowProviderInstance(cmd)
|
||||
case "show_instance_balance":
|
||||
return c.ShowInstanceBalance(cmd)
|
||||
case "alter_provider_instance":
|
||||
return c.AlterProviderInstance(cmd)
|
||||
case "drop_provider_instance":
|
||||
return c.DropProviderInstance(cmd)
|
||||
case "drop_instance_model":
|
||||
return c.DropInstanceModel(cmd)
|
||||
case "enable_model":
|
||||
return c.EnableOrDisableModel(cmd, "enable")
|
||||
case "disable_model":
|
||||
return c.EnableOrDisableModel(cmd, "disable")
|
||||
case "add_custom_model":
|
||||
return c.AddCustomModel(cmd)
|
||||
case "chat_to_model":
|
||||
return c.ChatToModel(cmd)
|
||||
case "think_chat_to_model":
|
||||
return c.ChatToModel(cmd)
|
||||
case "embed_user_text":
|
||||
return c.EmbedUserText(cmd)
|
||||
case "rarank_user_document":
|
||||
return c.RerankUserDocument(cmd)
|
||||
case "tts_user_command":
|
||||
return c.TTSUserCommand(cmd)
|
||||
case "asr_user_command":
|
||||
return c.ASRUserCommand(cmd)
|
||||
case "ocr_user_command":
|
||||
return c.OCRUserCommand(cmd)
|
||||
case "parse_file_user_command":
|
||||
return c.ParseFileUserCommand(cmd)
|
||||
case "check_provider_connection":
|
||||
return c.CheckProviderConnection(cmd)
|
||||
case "check_provider_with_key":
|
||||
return c.CheckProviderWithKey(cmd)
|
||||
case "use_model":
|
||||
return c.UseModel(cmd)
|
||||
case "set_default_model":
|
||||
return c.SetDefaultModel(cmd)
|
||||
case "reset_default_model":
|
||||
return c.ResetDefaultModel(cmd)
|
||||
case "list_user_default_models":
|
||||
return c.ListDefaultModels(cmd)
|
||||
case "list_tasks_user_command":
|
||||
return c.ListTasksUserCommand(cmd)
|
||||
case "show_task_user_command":
|
||||
return c.ShowTaskUserCommand(cmd)
|
||||
case "create_chunk_store":
|
||||
return c.CreateChunkStore(cmd)
|
||||
case "drop_chunk_store":
|
||||
return c.DropChunkStore(cmd)
|
||||
case "create_metadata_store":
|
||||
return c.CreateMetadataStore(cmd)
|
||||
case "drop_metadata_store":
|
||||
return c.DropMetadataStore(cmd)
|
||||
case "insert_chunks_from_file":
|
||||
return c.InsertChunksFromFile(cmd)
|
||||
case "insert_metadata_from_file":
|
||||
return c.InsertMetadataFromFile(cmd)
|
||||
case "update_chunk":
|
||||
return c.UpdateChunk(cmd)
|
||||
case "get_chunk":
|
||||
return c.GetChunk(cmd)
|
||||
case "set_meta":
|
||||
return c.SetMeta(cmd)
|
||||
case "delete_meta":
|
||||
return c.DeleteMeta(cmd)
|
||||
case "rm_tags":
|
||||
return c.RmTags(cmd)
|
||||
case "remove_chunks":
|
||||
return c.RemoveChunks(cmd)
|
||||
case "get_metadata":
|
||||
return c.GetMetadata(cmd)
|
||||
case "parse_documents_user_command":
|
||||
return c.ParseDocumentsUserCommand(cmd)
|
||||
case "show_admin_server":
|
||||
return c.ShowAdminServer(cmd)
|
||||
case "show_api_server":
|
||||
return c.ShowAPIServer(cmd)
|
||||
case "list_api_server":
|
||||
return c.ListAPIServer(cmd)
|
||||
case "add_api_server":
|
||||
return c.AddAPIServer(cmd)
|
||||
case "delete_api_server":
|
||||
return c.DeleteAPIServer(cmd)
|
||||
case "add_admin_server":
|
||||
return c.AddAdminServer(cmd)
|
||||
case "delete_admin_server":
|
||||
return c.DeleteAdminServer(cmd)
|
||||
case "save_config_command":
|
||||
return c.SaveServerConfig(cmd)
|
||||
// ContextEngine commands
|
||||
case "context_engine_command":
|
||||
return nil, c.executeFilesystem(cmd.Params["command"].(string))
|
||||
default:
|
||||
return nil, fmt.Errorf("command '%s' would be executed with API", cmd.Type)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -84,9 +84,9 @@ func (a *httpClientAdapter) Request(method, path string, authKind string, header
|
||||
// Auto-detect auth kind based on available tokens
|
||||
// If authKind is "auto" or empty, determine based on token availability
|
||||
if authKind == "auto" || authKind == "" {
|
||||
if a.client.useAPIToken && a.client.APIToken != "" {
|
||||
if a.client.useAPIToken && a.client.APIToken != nil {
|
||||
authKind = "api"
|
||||
} else if a.client.LoginToken != "" {
|
||||
} else if a.client.LoginToken != nil {
|
||||
authKind = "web"
|
||||
} else {
|
||||
authKind = "web" // default
|
||||
@@ -108,261 +108,6 @@ func (a *httpClientAdapter) UploadMultipart(path string, contentType string, bod
|
||||
return a.client.UploadMultipart(path, contentType, body)
|
||||
}
|
||||
|
||||
// ExecuteCommand executes a parsed command
|
||||
// Returns benchmark result map for commands that support it (e.g., ping_server with iterations > 1)
|
||||
func (c *RAGFlowClient) ExecuteCommand(cmd *Command) (ResponseIf, error) {
|
||||
switch c.ServerType {
|
||||
case "admin":
|
||||
// Admin mode: execute command with admin privileges
|
||||
return c.ExecuteAdminCommand(cmd)
|
||||
case "user":
|
||||
// User mode: execute command with user privileges
|
||||
return c.ExecuteUserCommand(cmd)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid server type: %s", c.ServerType)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *RAGFlowClient) ExecuteAdminCommand(cmd *Command) (ResponseIf, error) {
|
||||
switch cmd.Type {
|
||||
case "login_user":
|
||||
return nil, c.LoginUser(cmd)
|
||||
case "logout":
|
||||
return c.Logout()
|
||||
case "ping":
|
||||
return c.PingAdmin(cmd)
|
||||
case "benchmark":
|
||||
return c.RunBenchmark(cmd)
|
||||
case "list_users":
|
||||
return c.ListUsers(cmd)
|
||||
case "list_services":
|
||||
return c.ListServices(cmd)
|
||||
case "grant_admin":
|
||||
return c.GrantAdmin(cmd)
|
||||
case "revoke_admin":
|
||||
return c.RevokeAdmin(cmd)
|
||||
case "create_user":
|
||||
return c.CreateUser(cmd)
|
||||
case "activate_user":
|
||||
return c.ActivateUser(cmd)
|
||||
case "alter_user":
|
||||
return c.AlterUserPassword(cmd)
|
||||
case "drop_user":
|
||||
return c.DropUser(cmd)
|
||||
case "show_service":
|
||||
return c.ShowService(cmd)
|
||||
case "show_version":
|
||||
return c.ShowAdminVersion(cmd)
|
||||
case "show_user":
|
||||
return c.ShowUser(cmd)
|
||||
case "list_variables":
|
||||
return c.ListVariables(cmd)
|
||||
case "show_variable":
|
||||
return c.ShowVariable(cmd)
|
||||
case "set_variable":
|
||||
return c.SetVariable(cmd)
|
||||
case "list_user_datasets":
|
||||
return c.ListUserDatasets(cmd)
|
||||
case "list_agents":
|
||||
return c.ListAgents(cmd)
|
||||
case "generate_token":
|
||||
return c.GenerateAdminToken(cmd)
|
||||
case "list_tokens":
|
||||
return c.ListAdminTokens(cmd)
|
||||
case "drop_token":
|
||||
return c.DropAdminToken(cmd)
|
||||
case "list_available_providers":
|
||||
return c.ListAvailableProviders(cmd)
|
||||
case "show_provider":
|
||||
return c.ShowProvider(cmd)
|
||||
case "list_provider_models":
|
||||
return c.ListModels(cmd)
|
||||
case "list_supported_models":
|
||||
return c.ListSupportedModels(cmd)
|
||||
case "list_instance_models":
|
||||
return c.ListInstanceModels(cmd)
|
||||
case "show_provider_model":
|
||||
return c.ShowProviderModel(cmd)
|
||||
case "list_all_models":
|
||||
return c.ListAllModels(cmd)
|
||||
case "show_model":
|
||||
return c.ShowModel(cmd)
|
||||
case "list_admin_tasks":
|
||||
return c.ListAdminTasks(cmd)
|
||||
case "admin_list_ingestors":
|
||||
return c.ListAdminIngestors(cmd)
|
||||
case "admin_start_ingestion_command":
|
||||
return c.AdminStartIngestionCommand(cmd)
|
||||
case "admin_stop_ingestion_command":
|
||||
return c.AdminStopIngestionCommand(cmd)
|
||||
case "admin_shutdown_ingestor_command":
|
||||
return c.AdminShutdownIngestor(cmd)
|
||||
case "list_admin_ingestion_tasks":
|
||||
return c.ListAdminIngestionTasks(cmd)
|
||||
// TODO: Implement other commands
|
||||
default:
|
||||
return nil, fmt.Errorf("command '%s' would be executed with API", cmd.Type)
|
||||
}
|
||||
}
|
||||
func (c *RAGFlowClient) ExecuteUserCommand(cmd *Command) (ResponseIf, error) {
|
||||
switch cmd.Type {
|
||||
case "register_user":
|
||||
return c.RegisterUser(cmd)
|
||||
case "login_user":
|
||||
return nil, c.LoginUser(cmd)
|
||||
case "logout":
|
||||
return c.Logout()
|
||||
case "ping":
|
||||
return c.PingServer(cmd)
|
||||
// Configuration commands
|
||||
case "list_configs":
|
||||
return c.ListConfigs(cmd)
|
||||
case "set_log_level":
|
||||
return c.SetLogLevel(cmd)
|
||||
case "benchmark":
|
||||
return c.RunBenchmark(cmd)
|
||||
case "list_datasets":
|
||||
return c.ListDatasets(cmd)
|
||||
case "list_dataset_documents":
|
||||
return c.ListDatasetDocumentUserCommand(cmd)
|
||||
case "search_on_datasets":
|
||||
return c.SearchOnDatasets(cmd)
|
||||
case "search_help":
|
||||
printSearchHelp()
|
||||
return nil, nil
|
||||
case "create_token":
|
||||
return c.CreateToken(cmd)
|
||||
case "list_tokens":
|
||||
return c.ListTokens(cmd)
|
||||
case "drop_token":
|
||||
return c.DropToken(cmd)
|
||||
case "set_token":
|
||||
return c.SetToken(cmd)
|
||||
case "show_token":
|
||||
return c.ShowToken(cmd)
|
||||
case "unset_token":
|
||||
return c.UnsetToken(cmd)
|
||||
case "show_version":
|
||||
return c.ShowServerVersion(cmd)
|
||||
case "list_available_providers":
|
||||
return c.ListAvailableProviders(cmd)
|
||||
case "show_provider":
|
||||
return c.ShowProvider(cmd)
|
||||
case "list_provider_models":
|
||||
return c.ListModels(cmd)
|
||||
case "list_supported_models":
|
||||
return c.ListSupportedModels(cmd)
|
||||
case "list_instance_models":
|
||||
return c.ListInstanceModels(cmd)
|
||||
case "show_provider_model":
|
||||
return c.ShowProviderModel(cmd)
|
||||
case "list_all_models":
|
||||
return c.ListAllModels(cmd)
|
||||
case "show_model":
|
||||
return c.ShowModel(cmd)
|
||||
// Provider commands
|
||||
case "add_provider":
|
||||
return c.AddProvider(cmd)
|
||||
case "list_providers":
|
||||
return c.ListProviders(cmd)
|
||||
case "delete_provider":
|
||||
return c.DeleteProvider(cmd)
|
||||
// Provider instance commands
|
||||
case "create_provider_instance":
|
||||
return c.CreateProviderInstance(cmd)
|
||||
case "list_provider_instances":
|
||||
return c.ListProviderInstances(cmd)
|
||||
case "show_provider_instance":
|
||||
return c.ShowProviderInstance(cmd)
|
||||
case "show_instance_balance":
|
||||
return c.ShowInstanceBalance(cmd)
|
||||
case "alter_provider_instance":
|
||||
return c.AlterProviderInstance(cmd)
|
||||
case "drop_provider_instance":
|
||||
return c.DropProviderInstance(cmd)
|
||||
case "drop_instance_model":
|
||||
return c.DropInstanceModel(cmd)
|
||||
case "enable_model":
|
||||
return c.EnableOrDisableModel(cmd, "enable")
|
||||
case "disable_model":
|
||||
return c.EnableOrDisableModel(cmd, "disable")
|
||||
case "add_custom_model":
|
||||
return c.AddCustomModel(cmd)
|
||||
case "chat_to_model":
|
||||
return c.ChatToModel(cmd)
|
||||
case "think_chat_to_model":
|
||||
return c.ChatToModel(cmd)
|
||||
case "embed_user_text":
|
||||
return c.EmbedUserText(cmd)
|
||||
case "rarank_user_document":
|
||||
return c.RerankUserDocument(cmd)
|
||||
case "tts_user_command":
|
||||
return c.TTSUserCommand(cmd)
|
||||
case "asr_user_command":
|
||||
return c.ASRUserCommand(cmd)
|
||||
case "ocr_user_command":
|
||||
return c.OCRUserCommand(cmd)
|
||||
case "parse_file_user_command":
|
||||
return c.ParseFileUserCommand(cmd)
|
||||
case "check_provider_connection":
|
||||
return c.CheckProviderConnection(cmd)
|
||||
case "check_provider_with_key":
|
||||
return c.CheckProviderWithKey(cmd)
|
||||
case "use_model":
|
||||
return c.UseModel(cmd)
|
||||
case "show_current_model":
|
||||
return c.ShowCurrentModel(cmd)
|
||||
case "set_default_model":
|
||||
return c.SetDefaultModel(cmd)
|
||||
case "reset_default_model":
|
||||
return c.ResetDefaultModel(cmd)
|
||||
case "list_user_default_models":
|
||||
return c.ListDefaultModels(cmd)
|
||||
case "list_tasks_user_command":
|
||||
return c.ListTasksUserCommand(cmd)
|
||||
case "show_task_user_command":
|
||||
return c.ShowTaskUserCommand(cmd)
|
||||
case "create_chunk_store":
|
||||
return c.CreateChunkStore(cmd)
|
||||
case "drop_chunk_store":
|
||||
return c.DropChunkStore(cmd)
|
||||
case "create_metadata_store":
|
||||
return c.CreateMetadataStore(cmd)
|
||||
case "drop_metadata_store":
|
||||
return c.DropMetadataStore(cmd)
|
||||
case "insert_chunks_from_file":
|
||||
return c.InsertChunksFromFile(cmd)
|
||||
case "insert_metadata_from_file":
|
||||
return c.InsertMetadataFromFile(cmd)
|
||||
case "update_chunk":
|
||||
return c.UpdateChunk(cmd)
|
||||
case "get_chunk":
|
||||
return c.GetChunk(cmd)
|
||||
case "set_meta":
|
||||
return c.SetMeta(cmd)
|
||||
case "delete_meta":
|
||||
return c.DeleteMeta(cmd)
|
||||
case "rm_tags":
|
||||
return c.RmTags(cmd)
|
||||
case "remove_chunks":
|
||||
return c.RemoveChunks(cmd)
|
||||
case "get_metadata":
|
||||
return c.GetMetadata(cmd)
|
||||
case "parse_documents_user_command":
|
||||
return c.ParseDocumentsUserCommand(cmd)
|
||||
// ContextEngine commands
|
||||
case "ce_ls":
|
||||
return c.CEList(cmd)
|
||||
case "ce_cat":
|
||||
return c.CECat(cmd)
|
||||
case "ce_search":
|
||||
return c.CESearch(cmd)
|
||||
// TODO: Implement other commands
|
||||
default:
|
||||
return nil, fmt.Errorf("command '%s' would be executed with API", cmd.Type)
|
||||
}
|
||||
}
|
||||
|
||||
// ShowCurrentUser shows the current logged-in user information
|
||||
// TODO: Implement showing current user information when API is available
|
||||
func (c *RAGFlowClient) ShowCurrentUser(cmd *Command) (map[string]interface{}, error) {
|
||||
|
||||
@@ -18,126 +18,50 @@ package cli
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
// LoginUserInteractive performs interactive login with username and password
|
||||
func (c *RAGFlowClient) LoginUserInteractive(username, password string) error {
|
||||
// First, ping the server to check if it's available
|
||||
// For admin mode, use /admin/ping with useAPIBase=true
|
||||
// For user mode, use /system/ping with useAPIBase=false
|
||||
var pingPath string
|
||||
if c.ServerType == "admin" {
|
||||
pingPath = "/admin/ping"
|
||||
} else {
|
||||
pingPath = "/system/ping"
|
||||
func (c *CLI) LoginUserByCommand(cmd *Command) (ResponseIf, error) {
|
||||
email, ok := cmd.Params["email"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("email not provided")
|
||||
}
|
||||
password, ok := cmd.Params["password"].(string)
|
||||
if !ok {
|
||||
password = ""
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", pingPath, "web", nil, nil)
|
||||
err := c.LoginUserInteractive(email, password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result SimpleResponse
|
||||
result.Code = 0
|
||||
result.SetOutputFormat(c.outputFormat)
|
||||
result.Message = "Login successful"
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// LoginUserInteractive performs interactive login with username and password
|
||||
func (c *CLI) LoginUserInteractive(email, password string) error {
|
||||
// First, ping the server to check if it's available
|
||||
_, err := c.PingServer(1)
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
fmt.Println("Can't access server for login (connection failed)")
|
||||
return err
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
fmt.Println("Server is down")
|
||||
return fmt.Errorf("server is down")
|
||||
}
|
||||
|
||||
// Check response - admin returns JSON with message "pong", user returns plain "pong"
|
||||
resJSON, err := resp.JSON()
|
||||
if err == nil {
|
||||
// Admin mode returns {"code":0,"message":"pong"}
|
||||
if msg, ok := resJSON["message"].(string); !ok || msg != "pong" {
|
||||
fmt.Println("Server is down")
|
||||
return fmt.Errorf("server is down")
|
||||
}
|
||||
} else {
|
||||
// User mode returns plain "pong"
|
||||
if string(resp.Body) != "pong" {
|
||||
fmt.Println("Server is down")
|
||||
return fmt.Errorf("server is down")
|
||||
}
|
||||
}
|
||||
|
||||
// If password is not provided, prompt for it
|
||||
if password == "" {
|
||||
fmt.Printf("password for %s: ", username)
|
||||
var err error
|
||||
password, err = ReadPassword()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read password: %w", err)
|
||||
}
|
||||
password = strings.TrimSpace(password)
|
||||
}
|
||||
|
||||
// Login
|
||||
token, err := c.loginUser(username, password)
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
fmt.Println("Can't access server for login (connection failed)")
|
||||
return err
|
||||
}
|
||||
|
||||
c.HTTPClient.LoginToken = token
|
||||
fmt.Printf("Login user %s successfully\n", username)
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoginUser performs user login
|
||||
func (c *RAGFlowClient) LoginUser(cmd *Command) error {
|
||||
// First, ping the server to check if it's available
|
||||
// For admin mode, use /admin/ping with useAPIBase=true
|
||||
// For user mode, use /system/ping with useAPIBase=false
|
||||
var pingPath string
|
||||
if c.ServerType == "admin" {
|
||||
pingPath = "/admin/ping"
|
||||
} else {
|
||||
pingPath = "/system/ping"
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", pingPath, "web", nil, nil)
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
fmt.Println("Can't access server for login (connection failed)")
|
||||
return err
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
fmt.Println("Server is down")
|
||||
return fmt.Errorf("server is down")
|
||||
}
|
||||
|
||||
// Check response - admin returns JSON with message "pong", user returns plain "pong"
|
||||
resJSON, err := resp.JSON()
|
||||
if err == nil {
|
||||
// Admin mode returns {"code":0,"message":"pong"}
|
||||
if msg, ok := resJSON["message"].(string); !ok || msg != "pong" {
|
||||
fmt.Println("Server is down")
|
||||
return fmt.Errorf("server is down")
|
||||
}
|
||||
} else {
|
||||
// User mode returns plain "pong"
|
||||
if string(resp.Body) != "pong" {
|
||||
fmt.Println("Server is down")
|
||||
return fmt.Errorf("server is down")
|
||||
}
|
||||
}
|
||||
|
||||
email, ok := cmd.Params["email"].(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("email not provided")
|
||||
}
|
||||
|
||||
password, ok := cmd.Params["password"].(string)
|
||||
if !ok {
|
||||
// Get password from user input (hidden)
|
||||
fmt.Printf("password for %s: ", email)
|
||||
password, err = ReadPassword()
|
||||
if err != nil {
|
||||
@@ -154,13 +78,87 @@ func (c *RAGFlowClient) LoginUser(cmd *Command) error {
|
||||
return err
|
||||
}
|
||||
|
||||
c.HTTPClient.LoginToken = token
|
||||
fmt.Printf("Login user %s successfully\n", email)
|
||||
|
||||
switch c.Config.CLIMode {
|
||||
case AdminMode:
|
||||
c.AdminServerClient.LoginToken = &token
|
||||
c.Config.AdminClientConfig.AdminName = &email
|
||||
c.Config.AdminClientConfig.AdminPassword = &password
|
||||
case APIMode:
|
||||
c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].LoginToken = &token
|
||||
c.Config.APIClientConfig.APIServerMap[c.Config.APIClientConfig.CurrentAPIServer].UserName = &email
|
||||
c.Config.APIClientConfig.APIServerMap[c.Config.APIClientConfig.CurrentAPIServer].UserPassword = &password
|
||||
default:
|
||||
return fmt.Errorf("invalid server type")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *CLI) PingByCommand(cmd *Command) (ResponseIf, error) {
|
||||
iterations := 1
|
||||
if iterationsParam, ok := cmd.Params["iterations"]; ok {
|
||||
iterations = int(iterationsParam.(float64))
|
||||
}
|
||||
return c.PingServer(iterations)
|
||||
}
|
||||
|
||||
func (c *CLI) PingServer(iterations int) (ResponseIf, error) {
|
||||
var pingPath string
|
||||
var resp *Response
|
||||
var err error
|
||||
switch c.Config.CLIMode {
|
||||
case AdminMode:
|
||||
pingPath = "/admin/ping"
|
||||
if iterations > 1 {
|
||||
return c.AdminServerClient.RequestWithIterations("GET", pingPath, "web", nil, nil, iterations)
|
||||
}
|
||||
resp, err = c.AdminServerClient.Request("GET", pingPath, "web", nil, nil)
|
||||
case APIMode:
|
||||
pingPath = "/system/ping"
|
||||
if iterations > 1 {
|
||||
return c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].RequestWithIterations("GET", pingPath, "web", nil, nil, iterations)
|
||||
}
|
||||
resp, err = c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].Request("GET", pingPath, "web", nil, nil)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid server type")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
fmt.Println("Can't access server for login (connection failed)")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
fmt.Println("Server is down")
|
||||
return nil, fmt.Errorf("server is down")
|
||||
}
|
||||
|
||||
var result SimpleResponse
|
||||
switch c.Config.CLIMode {
|
||||
case AdminMode:
|
||||
if err = json.Unmarshal(resp.Body, &result); err != nil {
|
||||
return nil, fmt.Errorf("list users failed: invalid JSON (%w)", err)
|
||||
}
|
||||
case APIMode:
|
||||
if string(resp.Body) == "pong" {
|
||||
result.Code = 0
|
||||
result.Message = "Pong"
|
||||
} else {
|
||||
result.Code = 1
|
||||
result.Message = "Ping failed"
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid server type")
|
||||
}
|
||||
|
||||
result.Duration = resp.Duration
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// loginUser performs the actual login request
|
||||
func (c *RAGFlowClient) loginUser(email, password string) (string, error) {
|
||||
func (c *CLI) loginUser(email, password string) (string, error) {
|
||||
// Encrypt password using scrypt (same as Python implementation)
|
||||
encryptedPassword, err := EncryptPassword(password)
|
||||
if err != nil {
|
||||
@@ -172,14 +170,16 @@ func (c *RAGFlowClient) loginUser(email, password string) (string, error) {
|
||||
"password": encryptedPassword,
|
||||
}
|
||||
|
||||
var path string
|
||||
if c.ServerType == "admin" {
|
||||
path = "/admin/login"
|
||||
} else {
|
||||
path = "/auth/login"
|
||||
var resp *Response
|
||||
switch c.Config.CLIMode {
|
||||
case AdminMode:
|
||||
resp, err = c.AdminServerClient.Request("POST", "/admin/login", "", nil, payload)
|
||||
case APIMode:
|
||||
resp, err = c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].Request("POST", "/auth/login", "", nil, payload)
|
||||
default:
|
||||
return "", fmt.Errorf("invalid server type")
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("POST", path, "", nil, payload)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -201,19 +201,25 @@ func (c *RAGFlowClient) loginUser(email, password string) (string, error) {
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func (c *RAGFlowClient) Logout() (ResponseIf, error) {
|
||||
if c.HTTPClient.LoginToken == "" {
|
||||
return nil, fmt.Errorf("not logged in")
|
||||
func (c *CLI) Logout() (ResponseIf, error) {
|
||||
|
||||
var resp *Response
|
||||
var err error
|
||||
switch c.Config.CLIMode {
|
||||
case AdminMode:
|
||||
if c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("not logged in")
|
||||
}
|
||||
resp, err = c.AdminServerClient.Request("POST", "/admin/logout", "web", nil, nil)
|
||||
case APIMode:
|
||||
if c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].LoginToken == nil {
|
||||
return nil, fmt.Errorf("not logged in")
|
||||
}
|
||||
resp, err = c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].Request("POST", "/auth/logout", "web", nil, nil)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid server type")
|
||||
}
|
||||
|
||||
var path string
|
||||
if c.ServerType == "admin" {
|
||||
path = "/admin/logout"
|
||||
} else {
|
||||
path = "/auth/logout"
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("POST", path, "web", nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -227,19 +233,35 @@ func (c *RAGFlowClient) Logout() (ResponseIf, error) {
|
||||
return nil, fmt.Errorf("login failed: %s", result.Message)
|
||||
}
|
||||
|
||||
switch c.Config.CLIMode {
|
||||
case AdminMode:
|
||||
c.AdminServerClient.LoginToken = nil
|
||||
c.Config.AdminClientConfig.AdminName = nil
|
||||
c.Config.AdminClientConfig.AdminPassword = nil
|
||||
case APIMode:
|
||||
c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].LoginToken = nil
|
||||
c.Config.APIClientConfig.APIServerMap[c.Config.APIClientConfig.CurrentAPIServer].UserName = nil
|
||||
c.Config.APIClientConfig.APIServerMap[c.Config.APIClientConfig.CurrentAPIServer].UserPassword = nil
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid server type")
|
||||
}
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *RAGFlowClient) ListAvailableProviders(cmd *Command) (ResponseIf, error) {
|
||||
func (c *CLI) ListAvailableProviders(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
var endPoint string
|
||||
if c.ServerType == "admin" {
|
||||
endPoint = fmt.Sprintf("/admin/providers?available=true")
|
||||
} else {
|
||||
endPoint = fmt.Sprintf("/providers?available=true")
|
||||
var resp *Response
|
||||
var err error
|
||||
switch c.Config.CLIMode {
|
||||
case AdminMode:
|
||||
resp, err = c.AdminServerClient.Request("GET", "/admin/providers?available=true", "web", nil, nil)
|
||||
case APIMode:
|
||||
resp, err = c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].Request("GET", "/providers?available=true", "web", nil, nil)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid server type")
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", endPoint, "web", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list providers: %w", err)
|
||||
}
|
||||
@@ -260,20 +282,26 @@ func (c *RAGFlowClient) ListAvailableProviders(cmd *Command) (ResponseIf, error)
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *RAGFlowClient) ShowProvider(cmd *Command) (ResponseIf, error) {
|
||||
func (c *CLI) ShowProvider(cmd *Command) (ResponseIf, error) {
|
||||
providerName, ok := cmd.Params["provider_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("provider_name not provided")
|
||||
}
|
||||
|
||||
var resp *Response
|
||||
var err error
|
||||
var endPoint string
|
||||
if c.ServerType == "admin" {
|
||||
switch c.Config.CLIMode {
|
||||
case AdminMode:
|
||||
endPoint = fmt.Sprintf("/admin/providers/%s", providerName)
|
||||
} else {
|
||||
resp, err = c.AdminServerClient.Request("GET", endPoint, "web", nil, nil)
|
||||
case APIMode:
|
||||
endPoint = fmt.Sprintf("/providers/%s", providerName)
|
||||
resp, err = c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].Request("GET", endPoint, "web", nil, nil)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid server type")
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", endPoint, "web", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to show provider: %w", err)
|
||||
}
|
||||
@@ -294,21 +322,27 @@ func (c *RAGFlowClient) ShowProvider(cmd *Command) (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *RAGFlowClient) ListModels(cmd *Command) (ResponseIf, error) {
|
||||
func (c *CLI) ListModels(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
providerName, ok := cmd.Params["provider_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("provider_name not provided")
|
||||
}
|
||||
|
||||
var resp *Response
|
||||
var err error
|
||||
var endPoint string
|
||||
if c.ServerType == "admin" {
|
||||
switch c.Config.CLIMode {
|
||||
case AdminMode:
|
||||
endPoint = fmt.Sprintf("/admin/providers/%s/models", providerName)
|
||||
} else {
|
||||
resp, err = c.AdminServerClient.Request("GET", endPoint, "web", nil, nil)
|
||||
case APIMode:
|
||||
endPoint = fmt.Sprintf("/providers/%s/models", providerName)
|
||||
resp, err = c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].Request("GET", endPoint, "web", nil, nil)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid server type")
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", endPoint, "web", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list models: %w", err)
|
||||
}
|
||||
@@ -329,7 +363,7 @@ func (c *RAGFlowClient) ListModels(cmd *Command) (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *RAGFlowClient) ListSupportedModels(cmd *Command) (ResponseIf, error) {
|
||||
func (c *CLI) ListSupportedModels(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
providerName, ok := cmd.Params["provider_name"].(string)
|
||||
if !ok {
|
||||
@@ -340,14 +374,20 @@ func (c *RAGFlowClient) ListSupportedModels(cmd *Command) (ResponseIf, error) {
|
||||
return nil, fmt.Errorf("instance_name not provided")
|
||||
}
|
||||
|
||||
var resp *Response
|
||||
var err error
|
||||
var endPoint string
|
||||
if c.ServerType == "admin" {
|
||||
switch c.Config.CLIMode {
|
||||
case AdminMode:
|
||||
endPoint = fmt.Sprintf("/admin/providers/%s/instances/%s/models?supported=true", providerName, instanceName)
|
||||
} else {
|
||||
resp, err = c.AdminServerClient.Request("GET", endPoint, "web", nil, nil)
|
||||
case APIMode:
|
||||
endPoint = fmt.Sprintf("/providers/%s/instances/%s/models?supported=true", providerName, instanceName)
|
||||
resp, err = c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].Request("GET", endPoint, "web", nil, nil)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid server type")
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", endPoint, "web", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list models: %w", err)
|
||||
}
|
||||
@@ -368,7 +408,7 @@ func (c *RAGFlowClient) ListSupportedModels(cmd *Command) (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *RAGFlowClient) ShowProviderModel(cmd *Command) (ResponseIf, error) {
|
||||
func (c *CLI) ShowProviderModel(cmd *Command) (ResponseIf, error) {
|
||||
providerName, ok := cmd.Params["provider_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("provider_name not provided")
|
||||
@@ -378,14 +418,19 @@ func (c *RAGFlowClient) ShowProviderModel(cmd *Command) (ResponseIf, error) {
|
||||
return nil, fmt.Errorf("model_name not provided")
|
||||
}
|
||||
|
||||
var resp *Response
|
||||
var err error
|
||||
var endPoint string
|
||||
if c.ServerType == "admin" {
|
||||
switch c.Config.CLIMode {
|
||||
case AdminMode:
|
||||
endPoint = fmt.Sprintf("/admin/providers/%s/models/%s", providerName, modelName)
|
||||
} else {
|
||||
resp, err = c.AdminServerClient.Request("GET", endPoint, "web", nil, nil)
|
||||
case APIMode:
|
||||
endPoint = fmt.Sprintf("/providers/%s/models/%s", providerName, modelName)
|
||||
resp, err = c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].Request("GET", endPoint, "web", nil, nil)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid server type")
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", endPoint, "web", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to show model: %w", err)
|
||||
}
|
||||
@@ -406,7 +451,7 @@ func (c *RAGFlowClient) ShowProviderModel(cmd *Command) (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *RAGFlowClient) SetDefaultModel(cmd *Command) (ResponseIf, error) {
|
||||
func (c *CLI) SetDefaultModel(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
modelType, ok := cmd.Params["model_type"].(string)
|
||||
if !ok {
|
||||
@@ -434,7 +479,17 @@ func (c *RAGFlowClient) SetDefaultModel(cmd *Command) (ResponseIf, error) {
|
||||
"model_name": modelName,
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("PATCH", "/models", "web", nil, payload)
|
||||
var resp *Response
|
||||
var err error
|
||||
switch c.Config.CLIMode {
|
||||
case AdminMode:
|
||||
resp, err = c.AdminServerClient.Request("PATCH", "/admin/models", "web", nil, payload)
|
||||
case APIMode:
|
||||
resp, err = c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].Request("PATCH", "/models", "web", nil, payload)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid server type")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to set default model: %w", err)
|
||||
}
|
||||
@@ -455,7 +510,7 @@ func (c *RAGFlowClient) SetDefaultModel(cmd *Command) (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *RAGFlowClient) ResetDefaultModel(cmd *Command) (ResponseIf, error) {
|
||||
func (c *CLI) ResetDefaultModel(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
modelType, ok := cmd.Params["model_type"].(string)
|
||||
if !ok {
|
||||
@@ -466,7 +521,17 @@ func (c *RAGFlowClient) ResetDefaultModel(cmd *Command) (ResponseIf, error) {
|
||||
"model_type": modelType,
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("PATCH", "/models", "web", nil, payload)
|
||||
var resp *Response
|
||||
var err error
|
||||
switch c.Config.CLIMode {
|
||||
case AdminMode:
|
||||
resp, err = c.AdminServerClient.Request("PATCH", "/admin/models", "web", nil, payload)
|
||||
case APIMode:
|
||||
resp, err = c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].Request("PATCH", "/models", "web", nil, payload)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid server type")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to reset default model: %w", err)
|
||||
}
|
||||
@@ -487,8 +552,19 @@ func (c *RAGFlowClient) ResetDefaultModel(cmd *Command) (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *RAGFlowClient) ListDefaultModels(cmd *Command) (ResponseIf, error) {
|
||||
resp, err := c.HTTPClient.Request("GET", "/models", "web", nil, nil)
|
||||
func (c *CLI) ListDefaultModels(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
var resp *Response
|
||||
var err error
|
||||
switch c.Config.CLIMode {
|
||||
case AdminMode:
|
||||
resp, err = c.AdminServerClient.Request("GET", "/admin/models", "web", nil, nil)
|
||||
case APIMode:
|
||||
resp, err = c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].Request("GET", "/models", "web", nil, nil)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid server type")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list default models: %w", err)
|
||||
}
|
||||
@@ -509,7 +585,308 @@ func (c *RAGFlowClient) ListDefaultModels(cmd *Command) (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *RAGFlowClient) ListAllModels(cmd *Command) (ResponseIf, error) {
|
||||
func (c *CLI) ShowCommonCurrent(cmd *Command) (ResponseIf, error) {
|
||||
var result *CommonDataResponse
|
||||
|
||||
switch c.Config.CLIMode {
|
||||
case AdminMode:
|
||||
response, err := c.GetAdminServerInfo()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to show current: %w", err)
|
||||
}
|
||||
result = response.(*CommonDataResponse)
|
||||
|
||||
case APIMode:
|
||||
response, err := c.GetAPIServerInfo(c.Config.APIClientConfig.CurrentAPIServer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = response.(*CommonDataResponse)
|
||||
|
||||
if c.CurrentModel != nil {
|
||||
if result.Data == nil {
|
||||
result.Data = make(map[string]interface{})
|
||||
}
|
||||
result.Data["model_provider"] = c.CurrentModel.Provider
|
||||
result.Data["model_instance"] = c.CurrentModel.Instance
|
||||
result.Data["model_model"] = c.CurrentModel.Model
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid server type")
|
||||
}
|
||||
|
||||
if result == nil {
|
||||
result = &CommonDataResponse{}
|
||||
if result.Data == nil {
|
||||
result.Data = make(map[string]interface{})
|
||||
}
|
||||
}
|
||||
|
||||
result.Data["mode"] = c.Config.CLIMode
|
||||
result.Data["output"] = c.Config.OutputFormat
|
||||
result.Data["interactive"] = c.Config.Interactive
|
||||
result.Data["verbose"] = c.Config.Verbose
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) ShowAdminServer(cmd *Command) (ResponseIf, error) {
|
||||
return c.GetAdminServerInfo()
|
||||
}
|
||||
|
||||
func (c *CLI) ShowAPIServer(cmd *Command) (ResponseIf, error) {
|
||||
apiServerName, ok := cmd.Params["api_server_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("api_server_name not provided")
|
||||
}
|
||||
result, err := c.GetAPIServerInfo(apiServerName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) ListAPIServer(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
var result CommonResponse
|
||||
result.Data = make([]map[string]interface{}, 0)
|
||||
|
||||
for serverName, apiServerConfig := range c.Config.APIClientConfig.APIServerMap {
|
||||
element := map[string]interface{}{
|
||||
"api_server": serverName,
|
||||
}
|
||||
element["api_server_ip"] = apiServerConfig.IP
|
||||
element["api_server_port"] = apiServerConfig.Port
|
||||
if apiServerConfig.UserName != nil {
|
||||
element["user_name"] = *apiServerConfig.UserName
|
||||
}
|
||||
if apiServerConfig.UserPassword != nil {
|
||||
element["user_password"] = strings.Repeat("*", len(*apiServerConfig.UserPassword))
|
||||
}
|
||||
if c.APIServerClientMap[serverName].LoginToken != nil {
|
||||
element["auth"] = "login"
|
||||
} else if apiServerConfig.ApiToken != nil {
|
||||
element["auth"] = "api token"
|
||||
} else {
|
||||
element["auth"] = "no auth"
|
||||
}
|
||||
result.Data = append(result.Data, element)
|
||||
}
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) AddAPIServer(cmd *Command) (ResponseIf, error) {
|
||||
apiServerName, ok := cmd.Params["server_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("server name not provided")
|
||||
}
|
||||
if c.Config.APIClientConfig.APIServerMap[apiServerName] != nil {
|
||||
return nil, fmt.Errorf("api server already exists")
|
||||
}
|
||||
|
||||
apiServerIP, ok := cmd.Params["server_ip"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("server ip not provided")
|
||||
}
|
||||
apiServerPort, ok := cmd.Params["server_port"].(int)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("server port not provided")
|
||||
}
|
||||
apiServerToken, ok := cmd.Params["server_token"].(string)
|
||||
if !ok {
|
||||
apiServerToken = ""
|
||||
}
|
||||
|
||||
if c.Config.APIClientConfig.APIServerMap == nil {
|
||||
c.Config.APIClientConfig.APIServerMap = make(map[string]*APIServerConfig)
|
||||
}
|
||||
|
||||
c.Config.APIClientConfig.APIServerMap[apiServerName] = &APIServerConfig{
|
||||
Name: apiServerName,
|
||||
IP: apiServerIP,
|
||||
Port: apiServerPort,
|
||||
}
|
||||
c.Config.APIClientConfig.APIServerMap[apiServerName].IP = apiServerIP
|
||||
c.Config.APIClientConfig.APIServerMap[apiServerName].Port = apiServerPort
|
||||
if apiServerToken != "" {
|
||||
c.Config.APIClientConfig.APIServerMap[apiServerName].ApiToken = &apiServerToken
|
||||
}
|
||||
|
||||
transport := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}
|
||||
|
||||
if c.APIServerClientMap == nil {
|
||||
c.APIServerClientMap = make(map[string]*HTTPClient)
|
||||
}
|
||||
|
||||
if c.APIServerClientMap[apiServerName] != nil {
|
||||
return nil, fmt.Errorf("api server: %s already exists", apiServerName)
|
||||
}
|
||||
|
||||
c.APIServerClientMap[apiServerName] = &HTTPClient{
|
||||
Host: apiServerIP,
|
||||
Port: apiServerPort,
|
||||
APIVersion: "v1",
|
||||
ConnectTimeout: 5 * time.Second,
|
||||
ReadTimeout: 60 * time.Second,
|
||||
VerifySSL: false,
|
||||
client: &http.Client{
|
||||
Transport: transport,
|
||||
Timeout: 300 * time.Second,
|
||||
},
|
||||
}
|
||||
|
||||
var result SimpleResponse
|
||||
result.Code = 0
|
||||
result.Message = "api server deleted successfully"
|
||||
result.Duration = 0
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) DeleteAPIServer(cmd *Command) (ResponseIf, error) {
|
||||
apiServerName, ok := cmd.Params["server_name"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("server name not provided")
|
||||
}
|
||||
if apiServerName == c.Config.APIClientConfig.CurrentAPIServer {
|
||||
return nil, fmt.Errorf("cannot delete current api server")
|
||||
}
|
||||
delete(c.Config.APIClientConfig.APIServerMap, apiServerName)
|
||||
delete(c.APIServerClientMap, apiServerName)
|
||||
var result SimpleResponse
|
||||
result.Code = 0
|
||||
result.Message = "api server deleted successfully"
|
||||
result.Duration = 0
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) AddAdminServer(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if c.AdminServerClient != nil && c.AdminServerClient.LoginToken != nil {
|
||||
return nil, fmt.Errorf("admin server already login, please logout")
|
||||
}
|
||||
|
||||
adminServerIP, ok := cmd.Params["server_ip"].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("server ip not provided")
|
||||
}
|
||||
adminServerPort, ok := cmd.Params["server_port"].(int)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("server port not provided")
|
||||
}
|
||||
|
||||
if c.Config.AdminClientConfig == nil {
|
||||
c.Config.AdminClientConfig = &AdminModeConfig{}
|
||||
}
|
||||
|
||||
if adminServerIP != "" {
|
||||
c.Config.AdminClientConfig.AdminHost = adminServerIP
|
||||
}
|
||||
if adminServerPort != 0 {
|
||||
c.Config.AdminClientConfig.AdminPort = adminServerPort
|
||||
}
|
||||
|
||||
var result SimpleResponse
|
||||
result.Code = 0
|
||||
result.Message = "admin server added successfully"
|
||||
result.Duration = 0
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) DeleteAdminServer(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
if c.AdminServerClient != nil && c.AdminServerClient.LoginToken != nil {
|
||||
return nil, fmt.Errorf("admin server already login, please logout")
|
||||
}
|
||||
|
||||
if c.Config.AdminClientConfig == nil {
|
||||
return nil, fmt.Errorf("admin server not set")
|
||||
}
|
||||
|
||||
c.Config.AdminClientConfig = nil
|
||||
|
||||
var result SimpleResponse
|
||||
result.Code = 0
|
||||
result.Message = "admin server deleted successfully"
|
||||
result.Duration = 0
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) SaveServerConfig(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
switch c.Config.CLIMode {
|
||||
case AdminMode:
|
||||
if c.AdminServerClient.LoginToken == nil {
|
||||
return nil, fmt.Errorf("admin server isn't already login")
|
||||
}
|
||||
case APIMode:
|
||||
if c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].APIToken == nil && c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].LoginToken == nil {
|
||||
return nil, fmt.Errorf("API token not set. Please login first")
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid server type")
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *CLI) GetAdminServerInfo() (ResponseIf, error) {
|
||||
var result CommonDataResponse
|
||||
result.Data = make(map[string]interface{})
|
||||
|
||||
if c.Config.AdminClientConfig == nil {
|
||||
result.Data["admin_server"] = "N/A"
|
||||
} else {
|
||||
result.Data["admin_server_ip"] = c.Config.AdminClientConfig.AdminHost
|
||||
result.Data["admin_server_port"] = c.Config.AdminClientConfig.AdminPort
|
||||
if c.Config.AdminClientConfig.AdminName != nil {
|
||||
result.Data["admin_name"] = *c.Config.AdminClientConfig.AdminName
|
||||
}
|
||||
if c.Config.AdminClientConfig.AdminPassword != nil {
|
||||
result.Data["admin_password"] = strings.Repeat("*", len(*c.Config.AdminClientConfig.AdminPassword))
|
||||
}
|
||||
if c.AdminServerClient == nil || c.AdminServerClient.LoginToken == nil {
|
||||
result.Data["auth"] = "no auth"
|
||||
} else {
|
||||
result.Data["auth"] = "login"
|
||||
}
|
||||
}
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) GetAPIServerInfo(serverName string) (ResponseIf, error) {
|
||||
var result CommonDataResponse
|
||||
result.Data = make(map[string]interface{})
|
||||
|
||||
if c.Config.APIClientConfig.APIServerMap == nil || c.Config.APIClientConfig.APIServerMap[serverName] == nil {
|
||||
result.Data["api_server"] = "N/A"
|
||||
} else {
|
||||
result.Data["api_server"] = serverName
|
||||
apiServerConfig := c.Config.APIClientConfig.APIServerMap[serverName]
|
||||
result.Data["api_server_ip"] = apiServerConfig.IP
|
||||
result.Data["api_server_port"] = apiServerConfig.Port
|
||||
if apiServerConfig.UserName != nil {
|
||||
result.Data["user_name"] = *apiServerConfig.UserName
|
||||
}
|
||||
|
||||
if apiServerConfig.UserPassword != nil {
|
||||
result.Data["user_password"] = strings.Repeat("*", len(*apiServerConfig.UserPassword))
|
||||
}
|
||||
if c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer].LoginToken != nil {
|
||||
result.Data["auth"] = "login"
|
||||
} else if apiServerConfig.ApiToken != nil {
|
||||
result.Data["auth"] = "api token"
|
||||
} else {
|
||||
result.Data["auth"] = "no auth"
|
||||
}
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *CLI) ListAllModels(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
page, ok := cmd.Params["page"].(int)
|
||||
if !ok {
|
||||
@@ -526,7 +903,17 @@ func (c *RAGFlowClient) ListAllModels(cmd *Command) (ResponseIf, error) {
|
||||
"page_size": pageSize,
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", "/all-models", "web", nil, payload)
|
||||
var httpClient *HTTPClient
|
||||
switch c.Config.CLIMode {
|
||||
case AdminMode:
|
||||
httpClient = c.AdminServerClient
|
||||
case APIMode:
|
||||
httpClient = c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer]
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid server type")
|
||||
}
|
||||
|
||||
resp, err := httpClient.Request("GET", "/all-models", "web", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list all models: %w", err)
|
||||
}
|
||||
@@ -547,7 +934,7 @@ func (c *RAGFlowClient) ListAllModels(cmd *Command) (ResponseIf, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *RAGFlowClient) ShowModel(cmd *Command) (ResponseIf, error) {
|
||||
func (c *CLI) ShowModel(cmd *Command) (ResponseIf, error) {
|
||||
|
||||
modelName, ok := cmd.Params["model_name"].(string)
|
||||
if !ok {
|
||||
@@ -558,7 +945,17 @@ func (c *RAGFlowClient) ShowModel(cmd *Command) (ResponseIf, error) {
|
||||
"model_name": modelName,
|
||||
}
|
||||
|
||||
resp, err := c.HTTPClient.Request("GET", "/all-models", "web", nil, payload)
|
||||
var httpClient *HTTPClient
|
||||
switch c.Config.CLIMode {
|
||||
case AdminMode:
|
||||
httpClient = c.AdminServerClient
|
||||
case APIMode:
|
||||
httpClient = c.APIServerClientMap[c.Config.APIClientConfig.CurrentAPIServer]
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid server type")
|
||||
}
|
||||
|
||||
resp, err := httpClient.Request("GET", "/all-models", "web", nil, payload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to show model: %w", err)
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ type HTTPClient struct {
|
||||
Host string
|
||||
Port int
|
||||
APIVersion string
|
||||
APIToken string
|
||||
LoginToken string
|
||||
APIToken *string
|
||||
LoginToken *string
|
||||
ConnectTimeout time.Duration
|
||||
ReadTimeout time.Duration
|
||||
VerifySSL bool
|
||||
@@ -84,15 +84,15 @@ func (c *HTTPClient) Headers(authKind string, extra map[string]string) map[strin
|
||||
|
||||
switch authKind {
|
||||
case "api":
|
||||
if c.APIToken != "" {
|
||||
headers["Authorization"] = fmt.Sprintf("Bearer %s", c.APIToken)
|
||||
} else if c.LoginToken != "" {
|
||||
if c.APIToken != nil {
|
||||
headers["Authorization"] = fmt.Sprintf("Bearer %s", *c.APIToken)
|
||||
} else if c.LoginToken != nil {
|
||||
// Fallback to login token for API requests (user mode)
|
||||
headers["Authorization"] = fmt.Sprintf("Bearer %s", c.LoginToken)
|
||||
headers["Authorization"] = fmt.Sprintf("Bearer %s", *c.LoginToken)
|
||||
}
|
||||
case "web", "admin":
|
||||
if c.LoginToken != "" {
|
||||
headers["Authorization"] = c.LoginToken
|
||||
if c.LoginToken != nil {
|
||||
headers["Authorization"] = *c.LoginToken
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,6 +121,10 @@ func (r *Response) JSON() (map[string]interface{}, error) {
|
||||
|
||||
// Request makes an HTTP request
|
||||
func (c *HTTPClient) Request(method, path string, authKind string, headers map[string]string, jsonBody map[string]interface{}) (*Response, error) {
|
||||
if c == nil {
|
||||
return nil, fmt.Errorf("HTTP Client is nil")
|
||||
}
|
||||
|
||||
url := c.BuildURL(path)
|
||||
mergedHeaders := c.Headers(authKind, headers)
|
||||
|
||||
@@ -282,10 +286,10 @@ func (c *HTTPClient) UploadMultipart(path string, contentType string, body io.Re
|
||||
|
||||
// Set headers
|
||||
req.Header.Set("Content-Type", contentType)
|
||||
if c.APIToken != "" {
|
||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", c.APIToken))
|
||||
} else if c.LoginToken != "" {
|
||||
req.Header.Set("Authorization", c.LoginToken)
|
||||
if c.APIToken != nil {
|
||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", *c.APIToken))
|
||||
} else if c.LoginToken != nil {
|
||||
req.Header.Set("Authorization", *c.LoginToken)
|
||||
}
|
||||
|
||||
resp, err := c.client.Do(req)
|
||||
|
||||
@@ -221,8 +221,14 @@ func (l *Lexer) lookupIdent(ident string) Token {
|
||||
return Token{Type: TokenActive, Value: ident}
|
||||
case "ADMIN":
|
||||
return Token{Type: TokenAdmin, Value: ident}
|
||||
case "SERVER":
|
||||
return Token{Type: TokenServer, Value: ident}
|
||||
case "API":
|
||||
return Token{Type: TokenAPI, Value: ident}
|
||||
case "ADD":
|
||||
return Token{Type: TokenAdd, Value: ident}
|
||||
case "HOST":
|
||||
return Token{Type: TokenHost, Value: ident}
|
||||
case "DELETE":
|
||||
return Token{Type: TokenDelete, Value: ident}
|
||||
case "PASSWORD":
|
||||
@@ -273,6 +279,8 @@ func (l *Lexer) lookupIdent(ident string) Token {
|
||||
return Token{Type: TokenVars, Value: ident}
|
||||
case "CONFIGS":
|
||||
return Token{Type: TokenConfigs, Value: ident}
|
||||
case "CONFIG":
|
||||
return Token{Type: TokenConfig, Value: ident}
|
||||
case "ENVS":
|
||||
return Token{Type: TokenEnvs, Value: ident}
|
||||
case "KEY":
|
||||
@@ -349,6 +357,8 @@ func (l *Lexer) lookupIdent(ident string) Token {
|
||||
return Token{Type: TokenGet, Value: ident}
|
||||
case "SEARCH":
|
||||
return Token{Type: TokenSearch, Value: ident}
|
||||
case "RETRIEVE":
|
||||
return Token{Type: TokenRetrieve, Value: ident}
|
||||
case "CURRENT":
|
||||
return Token{Type: TokenCurrent, Value: ident}
|
||||
case "VISION":
|
||||
|
||||
@@ -28,12 +28,13 @@ type Parser struct {
|
||||
lexer *Lexer
|
||||
curToken Token
|
||||
peekToken Token
|
||||
original string
|
||||
}
|
||||
|
||||
// NewParser creates a new parser
|
||||
func NewParser(input string) *Parser {
|
||||
l := NewLexer(input)
|
||||
p := &Parser{lexer: l}
|
||||
p := &Parser{lexer: l, original: input}
|
||||
// Read two tokens to initialize curToken and peekToken
|
||||
p.nextToken()
|
||||
p.nextToken()
|
||||
@@ -46,7 +47,7 @@ func (p *Parser) nextToken() {
|
||||
}
|
||||
|
||||
// Parse parses the input and returns a Command
|
||||
func (p *Parser) Parse(adminCommand bool) (*Command, error) {
|
||||
func (p *Parser) Parse(cliMode CommandLineMode) (*Command, error) {
|
||||
if p.curToken.Type == TokenEOF {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -56,13 +57,7 @@ func (p *Parser) Parse(adminCommand bool) (*Command, error) {
|
||||
return p.parseMetaCommand()
|
||||
}
|
||||
|
||||
// Check for ContextEngine commands (ls, cat, search)
|
||||
// Note: These are now handled in parseUserCommand to support both SQL-style and CE-style syntax
|
||||
// if p.curToken.Type == TokenIdentifier && isCECommand(p.curToken.Value) {
|
||||
// return p.parseCECommand()
|
||||
// }
|
||||
|
||||
return p.parseCommand(adminCommand)
|
||||
return p.parseCommand(cliMode)
|
||||
}
|
||||
|
||||
func (p *Parser) parseMetaCommand() (*Command, error) {
|
||||
@@ -115,8 +110,8 @@ func (p *Parser) parseAdminCommand() (*Command, error) {
|
||||
return p.parseAdminGenerateCommand()
|
||||
case TokenImport:
|
||||
return p.parseAdminImportCommand()
|
||||
case TokenSearch:
|
||||
return p.parseAdminSearchCommand()
|
||||
case TokenRetrieve:
|
||||
return p.parseAdminRetrieveCommand()
|
||||
case TokenParse:
|
||||
return p.parseAdminParseCommand()
|
||||
case TokenBenchmark:
|
||||
@@ -133,6 +128,12 @@ func (p *Parser) parseAdminCommand() (*Command, error) {
|
||||
return p.parseStartIngestion()
|
||||
case TokenStop:
|
||||
return p.parseStopIngestion()
|
||||
case TokenAdd:
|
||||
return p.parseAdminAddCommand()
|
||||
case TokenDelete:
|
||||
return p.parseAdminDeleteCommand()
|
||||
case TokenSave:
|
||||
return p.parseAdminSaveCommand()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown command: %s", p.curToken.Value)
|
||||
}
|
||||
@@ -177,8 +178,8 @@ func (p *Parser) parseUserCommand() (*Command, error) {
|
||||
return p.parseImportCommand()
|
||||
case TokenInsert:
|
||||
return p.parseInsertCommand()
|
||||
case TokenSearch:
|
||||
return p.parseSearchCommand()
|
||||
case TokenRetrieve:
|
||||
return p.parseRetrieveCommand()
|
||||
case TokenParse:
|
||||
return p.parseParseCommand()
|
||||
case TokenBenchmark:
|
||||
@@ -213,10 +214,8 @@ func (p *Parser) parseUserCommand() (*Command, error) {
|
||||
return p.parseOCRCommand()
|
||||
case TokenCheck:
|
||||
return p.parseCheckCommand()
|
||||
case TokenLS:
|
||||
return p.parseCEListCommand()
|
||||
case TokenCat:
|
||||
return p.parseCECatCommand()
|
||||
case TokenSave:
|
||||
return p.parseUserSaveCommand()
|
||||
case TokenUse:
|
||||
return p.parseUseCommand()
|
||||
case TokenUpdate:
|
||||
@@ -226,21 +225,27 @@ func (p *Parser) parseUserCommand() (*Command, error) {
|
||||
case TokenGet:
|
||||
return p.parseGetCommand()
|
||||
|
||||
case TokenLS, TokenCat, TokenSearch:
|
||||
// For context engine
|
||||
return p.parseContextEngineCommand()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown command: %s", p.curToken.Value)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parser) parseCommand(adminCommand bool) (*Command, error) {
|
||||
func (p *Parser) parseCommand(cliMode CommandLineMode) (*Command, error) {
|
||||
if p.curToken.Type != TokenIdentifier && !isKeyword(p.curToken.Type) {
|
||||
return nil, fmt.Errorf("expected command, got %s", p.curToken.Value)
|
||||
}
|
||||
|
||||
if adminCommand {
|
||||
switch cliMode {
|
||||
case AdminMode:
|
||||
return p.parseAdminCommand()
|
||||
case APIMode:
|
||||
return p.parseUserCommand()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown mode: %s", cliMode)
|
||||
}
|
||||
|
||||
return p.parseUserCommand()
|
||||
}
|
||||
|
||||
func (p *Parser) expectPeek(tokenType int) error {
|
||||
@@ -385,20 +390,13 @@ func tokenTypeToString(t int) string {
|
||||
return fmt.Sprintf("token(%d)", t)
|
||||
}
|
||||
|
||||
// parseCECommand parses ContextEngine commands (ls, search)
|
||||
func (p *Parser) parseCECommand() (*Command, error) {
|
||||
cmdName := strings.ToUpper(p.curToken.Value)
|
||||
func (p *Parser) parseContextEngineCommand() (*Command, error) {
|
||||
p.nextToken() // consume COMMAND
|
||||
|
||||
switch cmdName {
|
||||
case "LS", "LIST":
|
||||
return p.parseCEListCommand()
|
||||
case "CAT":
|
||||
return p.parseCECatCommand()
|
||||
case "SEARCH":
|
||||
return p.parseCESearchCommand()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown ContextEngine command: %s", cmdName)
|
||||
}
|
||||
cmd := NewCommand("context_engine_command")
|
||||
cmd.Params["command"] = p.original
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// parseCEListCommand parses the ls command
|
||||
|
||||
@@ -42,7 +42,10 @@ const (
|
||||
TokenAlter
|
||||
TokenActive
|
||||
TokenAdmin
|
||||
TokenServer
|
||||
TokenAPI
|
||||
TokenAdd
|
||||
TokenHost
|
||||
TokenDelete
|
||||
TokenPassword
|
||||
TokenDataset
|
||||
@@ -68,6 +71,7 @@ const (
|
||||
TokenVar
|
||||
TokenVars
|
||||
TokenConfigs
|
||||
TokenConfig
|
||||
TokenEnvs
|
||||
TokenKey
|
||||
TokenKeys
|
||||
@@ -96,6 +100,7 @@ const (
|
||||
TokenParser
|
||||
TokenPipeline
|
||||
TokenSearch
|
||||
TokenRetrieve
|
||||
TokenCurrent
|
||||
TokenVision
|
||||
TokenEmbedding
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -174,6 +174,8 @@ func (p *Parser) parseListCommand() (*Command, error) {
|
||||
return p.parseListFiles()
|
||||
case TokenQuotedString:
|
||||
return p.parseListQuotedStringCommand()
|
||||
case TokenAPI:
|
||||
return p.parseListApiCommand()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown LIST target: %s", p.curToken.Value)
|
||||
}
|
||||
@@ -432,23 +434,13 @@ func (p *Parser) parseShowCommand() (*Command, error) {
|
||||
return NewCommand("show_token"), nil
|
||||
case TokenCurrent:
|
||||
p.nextToken()
|
||||
if p.curToken.Type == TokenUser {
|
||||
|
||||
// Semicolon is optional for SHOW TOKEN
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
// Semicolon is optional for SHOW CURRENT USER
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return NewCommand("show_current_user"), nil
|
||||
} else if p.curToken.Type == TokenModel {
|
||||
p.nextToken()
|
||||
// Semicolon is optional for SHOW CURRENT MODEL
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return NewCommand("show_current_model"), nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("expected USER or MODEL after CURRENT")
|
||||
return NewCommand("show_current"), nil
|
||||
case TokenUser:
|
||||
return p.parseShowUser()
|
||||
case TokenRole:
|
||||
@@ -469,6 +461,10 @@ func (p *Parser) parseShowCommand() (*Command, error) {
|
||||
return p.parseShowTask()
|
||||
case TokenQuotedString:
|
||||
return p.parseShowQuotedStringCommand()
|
||||
case TokenAdmin:
|
||||
return p.parseUserShowAdmin()
|
||||
case TokenAPI:
|
||||
return p.parseUserShowAPI()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown SHOW target: %s", p.curToken.Value)
|
||||
}
|
||||
@@ -666,6 +662,10 @@ func (p *Parser) parseAddCommand() (*Command, error) {
|
||||
return p.parseAddProvider()
|
||||
case TokenModel:
|
||||
return p.parseAddModel()
|
||||
case TokenAPI:
|
||||
return p.parseAddAPIServer()
|
||||
case TokenAdmin:
|
||||
return p.parseAddAdminServer()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown ADD target: %s", p.curToken.Value)
|
||||
}
|
||||
@@ -1089,6 +1089,180 @@ A:
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// syntax: add admin server host '127.0.0.1:9333' user 'ccc' password 'ppp'
|
||||
func (p *Parser) parseAddAdminServer() (*Command, error) {
|
||||
p.nextToken() // consume ADMIN
|
||||
|
||||
if p.curToken.Type != TokenServer {
|
||||
return nil, fmt.Errorf("expected server name")
|
||||
}
|
||||
p.nextToken() // consume SERVER
|
||||
|
||||
if p.curToken.Type != TokenHost {
|
||||
return nil, fmt.Errorf("expected HOST")
|
||||
}
|
||||
p.nextToken()
|
||||
|
||||
host, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.nextToken()
|
||||
|
||||
ip, port, err := parseHostPort(host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmd := NewCommand("add_admin_server")
|
||||
cmd.Params["server_ip"] = ip
|
||||
cmd.Params["server_port"] = port
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// syntax: add api server 'abc' host '127.0.0.1:9333' token 'xxx' user 'ccc' password 'ppp'
|
||||
func (p *Parser) parseAddAPIServer() (*Command, error) {
|
||||
p.nextToken() // consume API
|
||||
|
||||
if p.curToken.Type != TokenServer {
|
||||
return nil, fmt.Errorf("expected server name")
|
||||
}
|
||||
p.nextToken() // consume SERVER
|
||||
|
||||
serverName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.nextToken() // consume model name
|
||||
|
||||
if p.curToken.Type != TokenHost {
|
||||
return nil, fmt.Errorf("expected TO")
|
||||
}
|
||||
p.nextToken()
|
||||
|
||||
host, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.nextToken()
|
||||
|
||||
ip, port, err := parseHostPort(host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var token string
|
||||
|
||||
optionsLoop:
|
||||
for {
|
||||
switch p.curToken.Type {
|
||||
case TokenToken:
|
||||
p.nextToken()
|
||||
token, err = p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case TokenSemicolon:
|
||||
p.nextToken()
|
||||
break optionsLoop // done
|
||||
default:
|
||||
// No more options to process
|
||||
break optionsLoop
|
||||
}
|
||||
}
|
||||
|
||||
cmd := NewCommand("add_api_server")
|
||||
cmd.Params["server_name"] = serverName
|
||||
cmd.Params["server_ip"] = ip
|
||||
cmd.Params["server_port"] = port
|
||||
if token != "" {
|
||||
cmd.Params["server_token"] = token
|
||||
}
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// syntax: delete api server 'abc'
|
||||
func (p *Parser) parseDeleteAPIServer() (*Command, error) {
|
||||
p.nextToken() // consume API
|
||||
|
||||
if p.curToken.Type != TokenServer {
|
||||
return nil, fmt.Errorf("expected server name")
|
||||
}
|
||||
p.nextToken() // consume SERVER
|
||||
|
||||
serverName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.nextToken() // consume model name
|
||||
|
||||
cmd := NewCommand("delete_api_server")
|
||||
cmd.Params["server_name"] = serverName
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// syntax: delete admin server 'abc'
|
||||
func (p *Parser) parseDeleteAdminServer() (*Command, error) {
|
||||
p.nextToken() // consume ADMIN
|
||||
|
||||
if p.curToken.Type != TokenServer {
|
||||
return nil, fmt.Errorf("expected server name")
|
||||
}
|
||||
p.nextToken() // consume SERVER
|
||||
|
||||
cmd := NewCommand("delete_admin_server")
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseUserSaveCommand() (*Command, error) {
|
||||
p.nextToken() // consume SAVE
|
||||
switch p.curToken.Type {
|
||||
case TokenConfig:
|
||||
return p.parseSaveConfig()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown ADD target: %s", p.curToken.Value)
|
||||
}
|
||||
}
|
||||
|
||||
// syntax: save config as 'path'
|
||||
func (p *Parser) parseSaveConfig() (*Command, error) {
|
||||
p.nextToken() // consume CONFIG
|
||||
|
||||
if p.curToken.Type != TokenAs {
|
||||
return nil, fmt.Errorf("expected AS after CONFIG")
|
||||
}
|
||||
p.nextToken() // consume AS
|
||||
|
||||
path, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmd := NewCommand("save_config_command")
|
||||
cmd.Params["path"] = path
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseCreateDataset() (*Command, error) {
|
||||
p.nextToken() // consume DATASET
|
||||
datasetName, err := p.parseQuotedString()
|
||||
@@ -1196,6 +1370,10 @@ func (p *Parser) parseDeleteCommand() (*Command, error) {
|
||||
return p.parseDeleteProvider()
|
||||
case TokenMetadata:
|
||||
return p.parseDeleteMeta()
|
||||
case TokenAdmin:
|
||||
return p.parseDeleteAdminServer()
|
||||
case TokenAPI:
|
||||
return p.parseDeleteAPIServer()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown DELETE target: %s", p.curToken.Value)
|
||||
}
|
||||
@@ -2403,7 +2581,7 @@ func (p *Parser) parseInsertMetadataFromFile() (*Command, error) {
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseSearchCommand() (*Command, error) {
|
||||
func (p *Parser) parseRetrieveCommand() (*Command, error) {
|
||||
p.nextToken() // consume SEARCH
|
||||
|
||||
// Handle help flag: -h / --help. The lexer tokenizes each leading
|
||||
@@ -3668,8 +3846,8 @@ func (p *Parser) parseUserStatement() (*Command, error) {
|
||||
return p.parseImportCommand()
|
||||
case TokenInsert:
|
||||
return p.parseInsertCommand()
|
||||
case TokenSearch:
|
||||
return p.parseSearchCommand()
|
||||
case TokenRetrieve:
|
||||
return p.parseRetrieveCommand()
|
||||
case TokenGet:
|
||||
return p.parseGetCommand()
|
||||
case TokenUpdate:
|
||||
@@ -4172,3 +4350,75 @@ func (p *Parser) parseRemoveChunk() (*Command, error) {
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// parseShowTask parses SHOW ADMIN SERVER
|
||||
func (p *Parser) parseUserShowAdmin() (*Command, error) {
|
||||
p.nextToken() // consume ADMIN
|
||||
|
||||
var cmd *Command
|
||||
switch p.curToken.Type {
|
||||
case TokenServer:
|
||||
p.nextToken()
|
||||
cmd = NewCommand("show_admin_server")
|
||||
default:
|
||||
return nil, fmt.Errorf("expected SERVER after ADMIN")
|
||||
}
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
// parseShowTask parses SHOW API SERVER <server_name>
|
||||
func (p *Parser) parseUserShowAPI() (*Command, error) {
|
||||
p.nextToken() // consume API
|
||||
|
||||
var cmd *Command
|
||||
switch p.curToken.Type {
|
||||
case TokenServer:
|
||||
p.nextToken()
|
||||
cmd = NewCommand("show_api_server")
|
||||
|
||||
serverName, err := p.parseQuotedString()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("expected dataset_name: %w", err)
|
||||
}
|
||||
cmd.Params["api_server_name"] = serverName
|
||||
p.nextToken()
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("expected SERVER after API")
|
||||
}
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseListApiCommand() (*Command, error) {
|
||||
p.nextToken() // consume API
|
||||
|
||||
var cmd *Command
|
||||
switch p.curToken.Type {
|
||||
case TokenServer:
|
||||
p.nextToken()
|
||||
|
||||
cmd = NewCommand("list_api_server")
|
||||
p.nextToken()
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("expected SERVER after API")
|
||||
}
|
||||
|
||||
// Semicolon is optional
|
||||
if p.curToken.Type == TokenSemicolon {
|
||||
p.nextToken()
|
||||
}
|
||||
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
@@ -164,7 +164,8 @@ export default {
|
||||
version: 'Versione',
|
||||
skillVersion: 'Versione',
|
||||
skillVersionPlaceholder: 'es. 1.0.0',
|
||||
versionFormatHelp: 'La versione deve essere in formato semver (es. 1.0.0)',
|
||||
versionFormatHelp:
|
||||
'La versione deve essere in formato semver (es. 1.0.0)',
|
||||
versionRequired: 'La versione è richiesta',
|
||||
selectFilesOrFolder: 'Seleziona file o cartella',
|
||||
uploadDescription:
|
||||
@@ -208,9 +209,12 @@ export default {
|
||||
'Skill non valida: "name" deve essere minuscolo e URL-safe (solo lettere, numeri, trattini).',
|
||||
invalid_version:
|
||||
'Skill non valida: "version" deve essere un semver valido (es. 1.0.0).',
|
||||
invalid_metadata: 'Skill non valida: i metadati contengono campi non validi.',
|
||||
invalid_file_type: 'Skill non valida: sono ammessi solo file basati su testo.',
|
||||
invalid_path: 'Skill non valida: il percorso del file contiene caratteri non validi.',
|
||||
invalid_metadata:
|
||||
'Skill non valida: i metadati contengono campi non validi.',
|
||||
invalid_file_type:
|
||||
'Skill non valida: sono ammessi solo file basati su testo.',
|
||||
invalid_path:
|
||||
'Skill non valida: il percorso del file contiene caratteri non validi.',
|
||||
file_too_large:
|
||||
'Skill non valida: la dimensione del singolo file supera il limite di 5MB.',
|
||||
total_size_exceeded:
|
||||
@@ -236,7 +240,8 @@ export default {
|
||||
accessToken: 'Token di accesso',
|
||||
githubTokenHelp:
|
||||
'Per repository privati o limiti di frequenza più alti (5000 richieste/ora)',
|
||||
giteeTokenHelp: 'Per repository privati o limiti di frequenza più alti (2000 richieste/ora)',
|
||||
giteeTokenHelp:
|
||||
'Per repository privati o limiti di frequenza più alti (2000 richieste/ora)',
|
||||
rateLimitInfo: 'Info limite di frequenza',
|
||||
githubRateLimit:
|
||||
'Repository pubblici: 60 richieste/ora per IP. Usa il token per 5000 richieste/ora.',
|
||||
@@ -255,7 +260,7 @@ export default {
|
||||
similarityThreshold: 'Soglia di similarità',
|
||||
topK: 'Top K risultati',
|
||||
indexFields: 'Campi indice',
|
||||
indexFieldsDesc: 'Seleziona quali campi includere nell\'indice di ricerca',
|
||||
indexFieldsDesc: "Seleziona quali campi includere nell'indice di ricerca",
|
||||
fieldName: 'Nome',
|
||||
fieldNameDesc: 'Nome skill',
|
||||
fieldTags: 'Tag',
|
||||
@@ -324,7 +329,7 @@ Procedural Memory: skill apprese, abitudini e procedure automatizzate.`,
|
||||
forget: 'Dimentica',
|
||||
forgetMessageTip: 'Sei sicuro di voler dimenticare?',
|
||||
messageDescription:
|
||||
'L\'estrazione della memoria è configurata con i prompt e la temperatura dalle impostazioni avanzate.',
|
||||
"L'estrazione della memoria è configurata con i prompt e la temperatura dalle impostazioni avanzate.",
|
||||
copied: 'Copiato!',
|
||||
contentEmbed: 'Embedding contenuto',
|
||||
content: 'Contenuto',
|
||||
@@ -381,15 +386,17 @@ Esempio: un messaggio di 1 KB con embedding a 1024 dimensioni usa ~9 KB. Il limi
|
||||
fields: 'campi',
|
||||
selectFiles: 'Selezionati {{count}} file',
|
||||
type: 'Tipo',
|
||||
fieldNameInvalid: 'Il nome del campo può contenere solo lettere o underscore.',
|
||||
fieldNameInvalid:
|
||||
'Il nome del campo può contenere solo lettere o underscore.',
|
||||
builtIn: 'Integrato',
|
||||
generation: 'Generazione',
|
||||
toMetadataSetting: 'Impostazioni generazione',
|
||||
toMetadataSettingTip: 'Imposta i metadati automatici nella Configurazione.',
|
||||
toMetadataSettingTip:
|
||||
'Imposta i metadati automatici nella Configurazione.',
|
||||
descriptionTip:
|
||||
'Fornisci descrizioni o esempi per guidare l\'LLM nell\'estrazione dei valori per questo campo. Se lasciato vuoto, si baserà sul nome del campo.',
|
||||
"Fornisci descrizioni o esempi per guidare l'LLM nell'estrazione dei valori per questo campo. Se lasciato vuoto, si baserà sul nome del campo.",
|
||||
restrictDefinedValuesTip:
|
||||
'Modalità Enum: limita l\'estrazione dell\'LLM ai soli valori preimpostati. Definisci i valori qui sotto.',
|
||||
"Modalità Enum: limita l'estrazione dell'LLM ai soli valori preimpostati. Definisci i valori qui sotto.",
|
||||
valueExists:
|
||||
'Il valore esiste già. Conferma per unire i duplicati e combinare tutti i file associati.',
|
||||
fieldNameExists:
|
||||
@@ -400,7 +407,8 @@ Esempio: un messaggio di 1 KB con embedding a 1024 dimensioni usa ~9 KB. Il limi
|
||||
'Il nome del campo esiste già. Conferma per unire i duplicati.',
|
||||
fieldExists: 'Il campo esiste già.',
|
||||
fieldSetting: 'Impostazioni campo',
|
||||
changesAffectNewParses: 'Le modifiche riguardano solo le nuove analisi.',
|
||||
changesAffectNewParses:
|
||||
'Le modifiche riguardano solo le nuove analisi.',
|
||||
restrictDefinedValues: 'Limita ai valori definiti',
|
||||
metadataGenerationSettings: 'Impostazioni generazione metadati',
|
||||
manageMetadata: 'Gestisci metadati',
|
||||
@@ -426,7 +434,8 @@ Esempio: un messaggio di 1 KB con embedding a 1024 dimensioni usa ~9 KB. Il limi
|
||||
deleteSettingValueWarn: `Questo valore sarà eliminato; i metadati esistenti non saranno interessati.`,
|
||||
},
|
||||
redoAll: 'Cancella i chunk esistenti',
|
||||
applyAutoMetadataSettings: 'Applica le impostazioni globali dei metadati automatici',
|
||||
applyAutoMetadataSettings:
|
||||
'Applica le impostazioni globali dei metadati automatici',
|
||||
parseFileTip: 'Sei sicuro di voler analizzare?',
|
||||
parseFile: 'Analizza file',
|
||||
emptyMetadata: 'Nessun metadato',
|
||||
@@ -553,7 +562,7 @@ Esempio: un messaggio di 1 KB con embedding a 1024 dimensioni usa ~9 KB. Il limi
|
||||
changeSpecificCategory: 'Cambia categoria specifica',
|
||||
uploadTitle: 'Trascina e rilascia il tuo file qui per caricarlo',
|
||||
uploadDescription:
|
||||
'Supporta caricamento singolo o multiplo. Per un RAGFlow distribuito localmente: il limite di dimensione totale dei file per caricamento è 1GB, con un limite batch di 32 file. Non c\'è limite al numero totale di file per account. Per cloud.ragflow.io, il limite di dimensione totale dei file per caricamento è 10MB, con ogni file non superiore a 10MB e un massimo di 128 file per account.',
|
||||
"Supporta caricamento singolo o multiplo. Per un RAGFlow distribuito localmente: il limite di dimensione totale dei file per caricamento è 1GB, con un limite batch di 32 file. Non c'è limite al numero totale di file per account. Per cloud.ragflow.io, il limite di dimensione totale dei file per caricamento è 10MB, con ogni file non superiore a 10MB e un massimo di 128 file per account.",
|
||||
chunk: 'Chunk',
|
||||
bulk: 'Multiplo',
|
||||
cancel: 'Annulla',
|
||||
@@ -609,7 +618,8 @@ Esempio: un messaggio di 1 KB con embedding a 1024 dimensioni usa ~9 KB. Il limi
|
||||
randomSeedTip:
|
||||
'Il seme è il punto di partenza per un algoritmo pseudo-casuale che garantisce la riproducibilità dello stesso output in esecuzioni diverse.',
|
||||
datasetDescription: 'Descrivi il tuo dataset',
|
||||
overlappedPercentTip: 'La percentuale di sovrapposizione tra due chunk adiacenti',
|
||||
overlappedPercentTip:
|
||||
'La percentuale di sovrapposizione tra due chunk adiacenti',
|
||||
globalIndexModelTip:
|
||||
'Usato per generare grafi della conoscenza, RAPTOR, metadati automatici, parole chiave automatiche e domande automatiche. Le prestazioni del modello influenzeranno la qualità della generazione.',
|
||||
globalIndexModel: 'Modello di indicizzazione',
|
||||
@@ -622,22 +632,24 @@ Esempio: un messaggio di 1 KB con embedding a 1024 dimensioni usa ~9 KB. Il limi
|
||||
mineruOptions: 'Opzioni MinerU',
|
||||
mineruParseMethod: 'Metodo di analisi',
|
||||
mineruParseMethodTip:
|
||||
'Metodo per l\'analisi del PDF: auto (rilevamento automatico), txt (estrazione testo), ocr (riconoscimento ottico dei caratteri)',
|
||||
"Metodo per l'analisi del PDF: auto (rilevamento automatico), txt (estrazione testo), ocr (riconoscimento ottico dei caratteri)",
|
||||
mineruFormulaEnable: 'Riconoscimento formule',
|
||||
mineruFormulaEnableTip:
|
||||
'Abilita il riconoscimento delle formule. Nota: questo potrebbe non funzionare correttamente per documenti cirillici.',
|
||||
mineruTableEnable: 'Riconoscimento tabelle',
|
||||
mineruTableEnableTip: 'Abilita il riconoscimento e l\'estrazione delle tabelle.',
|
||||
mineruTableEnableTip:
|
||||
"Abilita il riconoscimento e l'estrazione delle tabelle.",
|
||||
paddleocrOptions: 'Opzioni PaddleOCR',
|
||||
paddleocrApiUrl: 'URL API di PaddleOCR',
|
||||
paddleocrApiUrlTip: 'L\'URL dell\'endpoint API del servizio PaddleOCR',
|
||||
paddleocrApiUrlTip: "L'URL dell'endpoint API del servizio PaddleOCR",
|
||||
paddleocrApiUrlPlaceholder:
|
||||
'es. https://paddleocr-server.com/layout-parsing',
|
||||
paddleocrAccessToken: 'Token di accesso AI Studio',
|
||||
paddleocrAccessTokenTip: 'Token di accesso per l\'API PaddleOCR (opzionale)',
|
||||
paddleocrAccessTokenTip:
|
||||
"Token di accesso per l'API PaddleOCR (opzionale)",
|
||||
paddleocrAccessTokenPlaceholder: 'Il tuo token AI Studio (opzionale)',
|
||||
paddleocrAlgorithm: 'Algoritmo PaddleOCR',
|
||||
paddleocrAlgorithmTip: 'Algoritmo da usare per l\'analisi PaddleOCR',
|
||||
paddleocrAlgorithmTip: "Algoritmo da usare per l'analisi PaddleOCR",
|
||||
paddleocrSelectAlgorithm: 'Seleziona algoritmo',
|
||||
paddleocrModelNamePlaceholder: 'es. paddleocr-from-env-1',
|
||||
overlappedPercent: 'Percentuale di sovrapposizione(%)',
|
||||
@@ -652,7 +664,8 @@ Esempio: un messaggio di 1 KB con embedding a 1024 dimensioni usa ~9 KB. Il limi
|
||||
baseInfo: 'Base',
|
||||
globalIndex: 'Indice globale',
|
||||
dataSource: 'Fonte dati',
|
||||
linkSourceSetTip: 'Gestisci il collegamento della fonte dati con questo dataset',
|
||||
linkSourceSetTip:
|
||||
'Gestisci il collegamento della fonte dati con questo dataset',
|
||||
linkDataSource: 'Collega fonte dati',
|
||||
tocExtraction: 'PageIndex',
|
||||
tocExtractionTip:
|
||||
@@ -672,7 +685,8 @@ Esempio: un messaggio di 1 KB con embedding a 1024 dimensioni usa ~9 KB. Il limi
|
||||
setDefaultTip: '',
|
||||
setDefault: 'Imposta come predefinito',
|
||||
editLinkDataPipeline: 'Modifica ingestion pipeline',
|
||||
linkPipelineSetTip: 'Gestisci il collegamento della ingestion pipeline con questo dataset',
|
||||
linkPipelineSetTip:
|
||||
'Gestisci il collegamento della ingestion pipeline con questo dataset',
|
||||
default: 'Predefinito',
|
||||
dataPipeline: 'Cambia o configura la ingestion pipeline.',
|
||||
linkDataPipeline: 'Collega ingestion pipeline',
|
||||
@@ -688,7 +702,7 @@ Esempio: un messaggio di 1 KB con embedding a 1024 dimensioni usa ~9 KB. Il limi
|
||||
'Aggiorna la configurazione del tuo dataset qui, in particolare il LLM e i prompt.',
|
||||
name: 'Nome dataset',
|
||||
photo: 'Foto dataset',
|
||||
photoTip: 'Puoi caricare un\'immagine fino a 4 MB.',
|
||||
photoTip: "Puoi caricare un'immagine fino a 4 MB.",
|
||||
description: 'Descrizione',
|
||||
language: 'Lingua documento',
|
||||
languageMessage: 'Inserisci la tua lingua!',
|
||||
@@ -696,7 +710,8 @@ Esempio: un messaggio di 1 KB con embedding a 1024 dimensioni usa ~9 KB. Il limi
|
||||
permissions: 'Permessi',
|
||||
embeddingModel: 'Modello di embedding',
|
||||
chunkTokenNumber: 'Dimensione chunk raccomandata',
|
||||
chunkTokenNumberMessage: 'Il numero di token per chunk per il testo è richiesto',
|
||||
chunkTokenNumberMessage:
|
||||
'Il numero di token per chunk per il testo è richiesto',
|
||||
embeddingModelTip:
|
||||
'Il modello di embedding predefinito usato dal dataset. Una volta che il dataset contiene chunk, quando si cambia il modello di embedding il sistema estrae casualmente alcuni chunk per una verifica di compatibilità, li ricodifica con il nuovo modello di embedding e calcola la similarità coseno tra i vettori nuovi e quelli vecchi. Il cambio è consentito solo se la similarità media del campione è ≥ 0.9. In caso contrario, è necessario eliminare tutti i chunk nel dataset prima di poterlo modificare.',
|
||||
permissionsTip:
|
||||
@@ -846,13 +861,14 @@ Esempio: un messaggio di 1 KB con embedding a 1024 dimensioni usa ~9 KB. Il limi
|
||||
'RAPTOR può essere usato per attività di question-answering multi-hop. Naviga alla pagina File, clicca Genera > RAPTOR per abilitarlo. Vedi https://ragflow.io/docs/dev/enable_raptor per i dettagli.',
|
||||
prompt: 'Prompt',
|
||||
promptTip:
|
||||
'Usa il prompt di sistema per descrivere il compito per l\'LLM, specificare come dovrebbe rispondere e delineare altri requisiti vari. Il prompt di sistema è spesso usato insieme a chiavi (variabili), che servono come vari input di dati per l\'LLM. Usa una barra `/` o il pulsante (x) per mostrare le chiavi da usare.',
|
||||
"Usa il prompt di sistema per descrivere il compito per l'LLM, specificare come dovrebbe rispondere e delineare altri requisiti vari. Il prompt di sistema è spesso usato insieme a chiavi (variabili), che servono come vari input di dati per l'LLM. Usa una barra `/` o il pulsante (x) per mostrare le chiavi da usare.",
|
||||
promptMessage: 'Il prompt è richiesto',
|
||||
promptText: `Per favore riassumi i seguenti paragrafi. Fai attenzione ai numeri, non inventare cose. Paragrafi come segue:
|
||||
{cluster_content}
|
||||
Quanto sopra è il contenuto che devi riassumere.`,
|
||||
maxToken: 'Token massimi',
|
||||
maxTokenTip: 'Il numero massimo di token per chunk di riepilogo generato.',
|
||||
maxTokenTip:
|
||||
'Il numero massimo di token per chunk di riepilogo generato.',
|
||||
maxTokenMessage: 'Token massimi richiesti',
|
||||
threshold: 'Soglia',
|
||||
thresholdTip:
|
||||
@@ -902,12 +918,12 @@ Questa funzionalità di auto-tagging migliora il recupero aggiungendo un ulterio
|
||||
NER: Usa spaCy NER e l'estrazione di parole chiave basata su regole per estrarre entità e relazioni. Non è necessario un LLM per l'estrazione stessa, rendendola veloce ed efficiente nelle risorse.`,
|
||||
graphRagBatchChunkTokenSize: 'Dimensione token chunk batch',
|
||||
graphRagBatchChunkTokenSizeTip:
|
||||
'Il limite di token per ogni batch di chunk inviati all\'LLM per l\'estrazione di entità e relazioni del grafo della conoscenza. Non applicato a NER.',
|
||||
"Il limite di token per ogni batch di chunk inviati all'LLM per l'estrazione di entità e relazioni del grafo della conoscenza. Non applicato a NER.",
|
||||
resolution: 'Risoluzione entità',
|
||||
resolutionTip: `Un interruttore di deduplicazione entità. Quando abilitato, l'LLM combinerà entità simili - es. '2025' e 'l'anno 2025', o 'IT' e 'Information Technology' - per costruire un grafo più accurato`,
|
||||
community: 'Report comunità',
|
||||
communityTip:
|
||||
'In un grafo della conoscenza, una comunità è un cluster di entità collegate da relazioni. Puoi far generare all\'LLM un abstract per ogni comunità, noto come report comunità. Vedi qui per maggiori informazioni: https://www.microsoft.com/en-us/research/blog/graphrag-improving-global-search-via-dynamic-community-selection/',
|
||||
"In un grafo della conoscenza, una comunità è un cluster di entità collegate da relazioni. Puoi far generare all'LLM un abstract per ogni comunità, noto come report comunità. Vedi qui per maggiori informazioni: https://www.microsoft.com/en-us/research/blog/graphrag-improving-global-search-via-dynamic-community-selection/",
|
||||
theDocumentBeingParsedCannotBeDeleted:
|
||||
'Il documento in fase di analisi non può essere eliminato',
|
||||
lastWeek: 'dalla settimana scorsa',
|
||||
@@ -933,7 +949,8 @@ Questa funzionalità di auto-tagging migliora il recupero aggiungendo un ulterio
|
||||
disabled: 'Disabilitato',
|
||||
keyword: 'Parola chiave',
|
||||
image: 'Immagine',
|
||||
imageUploaderTitle: 'Carica una nuova immagine per aggiornare questo chunk immagine',
|
||||
imageUploaderTitle:
|
||||
'Carica una nuova immagine per aggiornare questo chunk immagine',
|
||||
function: 'Funzione',
|
||||
chunkMessage: 'Inserisci un valore!',
|
||||
full: 'Testo completo',
|
||||
@@ -1005,7 +1022,7 @@ Questa funzionalità di auto-tagging migliora il recupero aggiungendo un ulterio
|
||||
- **Considera sempre** l'intera cronologia della conversazione.`,
|
||||
systemMessage: 'Inserisci!',
|
||||
systemTip:
|
||||
'I tuoi prompt o istruzioni per l\'LLM, inclusi ma non limitati al suo ruolo, la lunghezza desiderata, il tono e la lingua delle sue risposte. Se il tuo modello ha supporto nativo per il ragionamento, puoi aggiungere //no_thinking al prompt per fermare il ragionamento.',
|
||||
"I tuoi prompt o istruzioni per l'LLM, inclusi ma non limitati al suo ruolo, la lunghezza desiderata, il tono e la lingua delle sue risposte. Se il tuo modello ha supporto nativo per il ragionamento, puoi aggiungere //no_thinking al prompt per fermare il ragionamento.",
|
||||
topN: 'Top N',
|
||||
topNTip: `Non tutti i chunk con punteggio di similarità sopra la 'soglia di similarità' saranno inviati all'LLM. Questo seleziona 'Top N' chunk da quelli recuperati.`,
|
||||
variable: 'Variabile',
|
||||
@@ -1070,7 +1087,7 @@ Questa funzionalità di auto-tagging migliora il recupero aggiungendo un ulterio
|
||||
embedModalTitle: 'Incorpora nella pagina web',
|
||||
published: 'Pubblicato',
|
||||
publishedTooltip:
|
||||
'Usa la versione pubblicata per questo embed. Quando abilitato, l\'URL generato include release=true.',
|
||||
"Usa la versione pubblicata per questo embed. Quando abilitato, l'URL generato include release=true.",
|
||||
embedType: 'Tipo di embed',
|
||||
fullscreenChat: 'Chat a schermo intero (iframe tradizionale)',
|
||||
floatingWidget: 'Widget fluttuante (stile Intercom)',
|
||||
@@ -1104,7 +1121,7 @@ Questa funzionalità di auto-tagging migliora il recupero aggiungendo un ulterio
|
||||
'Questo ottimizza le query utente usando il contesto in una conversazione multi-round. Quando abilitato, consumerà token LLM aggiuntivi.',
|
||||
howUseId: "Come usare l'ID chat?",
|
||||
description: "Descrizione dell'assistente",
|
||||
descriptionPlaceholder: "Sono un assistente chat.",
|
||||
descriptionPlaceholder: 'Sono un assistente chat.',
|
||||
useKnowledgeGraph: 'Usa grafo della conoscenza',
|
||||
useKnowledgeGraphTip:
|
||||
'Se usare il/i grafo/i della conoscenza nel/i dataset specificato/i durante il recupero per il question answering multi-hop. Quando abilitato, ciò comporterebbe ricerche iterative attraverso chunk di entità, relazioni e report di comunità, aumentando notevolmente il tempo di recupero.',
|
||||
@@ -1127,7 +1144,7 @@ Questa funzionalità di auto-tagging migliora il recupero aggiungendo un ulterio
|
||||
createChat: 'Crea chat',
|
||||
metadata: 'Metadati',
|
||||
metadataTip:
|
||||
'Il filtraggio dei metadati è il processo di utilizzo degli attributi dei metadati (come tag, categorie o permessi di accesso) per affinare e controllare il recupero delle informazioni rilevanti all\'interno di un sistema.',
|
||||
"Il filtraggio dei metadati è il processo di utilizzo degli attributi dei metadati (come tag, categorie o permessi di accesso) per affinare e controllare il recupero delle informazioni rilevanti all'interno di un sistema.",
|
||||
conditions: 'Condizioni',
|
||||
metadataKeys: 'Elementi filtrabili',
|
||||
addCondition: 'Aggiungi condizione',
|
||||
@@ -1153,7 +1170,7 @@ Questa funzionalità di auto-tagging migliora il recupero aggiungendo un ulterio
|
||||
'Permette a questo modello di chiamare strumenti quando il tipo di modello selezionato supporta le chiamate a strumenti.',
|
||||
deleteModel: 'Elimina modello',
|
||||
bedrockCredentialsHint:
|
||||
'Suggerimento: lascia Access Key / Secret Key vuoti per usare l\'autenticazione AWS IAM.',
|
||||
"Suggerimento: lascia Access Key / Secret Key vuoti per usare l'autenticazione AWS IAM.",
|
||||
awsAuthModeAccessKeySecret: 'Access Key',
|
||||
awsAuthModeIamRole: 'IAM Role',
|
||||
awsAuthModeAssumeRole: 'Assume Role',
|
||||
@@ -1162,10 +1179,11 @@ Questa funzionalità di auto-tagging migliora il recupero aggiungendo un ulterio
|
||||
awsRoleArn: 'AWS Role ARN',
|
||||
awsRoleArnMessage: 'Inserisci AWS Role ARN',
|
||||
awsAssumeRoleTip:
|
||||
'Se selezioni questa modalità, l\'istanza Amazon EC2 assumerà il suo ruolo esistente per accedere ai servizi AWS. Non sono richieste credenziali aggiuntive.',
|
||||
"Se selezioni questa modalità, l'istanza Amazon EC2 assumerà il suo ruolo esistente per accedere ai servizi AWS. Non sono richieste credenziali aggiuntive.",
|
||||
modelEmptyTip:
|
||||
'Nessun modello disponibile. <br>Aggiungi modelli dal pannello a destra.',
|
||||
sourceEmptyTip: 'Nessuna fonte dati aggiunta. Selezionane una qui sotto per connetterti.',
|
||||
sourceEmptyTip:
|
||||
'Nessuna fonte dati aggiunta. Selezionane una qui sotto per connetterti.',
|
||||
seconds: 'secondi',
|
||||
minutes: 'minuti',
|
||||
edit: 'Modifica',
|
||||
@@ -1177,9 +1195,9 @@ Questa funzionalità di auto-tagging migliora il recupero aggiungendo un ulterio
|
||||
connectorNameTip: 'Un nome descrittivo per il connettore',
|
||||
syncDeletedFiles: 'Sincronizza file eliminati',
|
||||
confluenceIsCloudTip:
|
||||
'Spunta se questa è un\'istanza Confluence Cloud, deseleziona per Confluence Server/Data Center',
|
||||
"Spunta se questa è un'istanza Confluence Cloud, deseleziona per Confluence Server/Data Center",
|
||||
confluenceWikiBaseUrlTip:
|
||||
'L\'URL base della tua istanza Confluence (es. https://your-domain.atlassian.net/wiki)',
|
||||
"L'URL base della tua istanza Confluence (es. https://your-domain.atlassian.net/wiki)",
|
||||
confluenceSpaceKeyTip:
|
||||
'Opzionale: specifica una chiave spazio per limitare la sincronizzazione a uno spazio specifico. Lascia vuoto per sincronizzare tutti gli spazi accessibili. Per più spazi, separa con virgole (es. DEV,DOCS,HR)',
|
||||
s3PrefixTip: `Specifica il percorso della cartella all'interno del tuo bucket S3 da cui recuperare i file.
|
||||
@@ -1215,7 +1233,8 @@ Esempio: Virtual Hosted Style`,
|
||||
'Sincronizza pagine e database da Notion per il recupero della conoscenza.',
|
||||
google_driveDescription:
|
||||
'Connetti il tuo Google Drive tramite OAuth e sincronizza cartelle o drive specifici.',
|
||||
gmailDescription: 'Connetti il tuo Gmail tramite OAuth per sincronizzare le email.',
|
||||
gmailDescription:
|
||||
'Connetti il tuo Gmail tramite OAuth per sincronizzare le email.',
|
||||
webdavDescription: 'Connettiti a server WebDAV per sincronizzare i file.',
|
||||
webdavRemotePathTip:
|
||||
'Opzionale: specifica un percorso cartella sul server WebDAV (es. /Documents). Lascia vuoto per sincronizzare dalla radice.',
|
||||
@@ -1238,31 +1257,34 @@ Esempio: Virtual Hosted Style`,
|
||||
teamsDescription:
|
||||
'Connetti Microsoft Teams tramite Microsoft Graph per sincronizzare post e risposte dei canali.',
|
||||
teamsTenantIdTip:
|
||||
'ID tenant Azure AD. Richiede un\'app con permessi applicativi Team.ReadBasic.All e ChannelMessage.Read.All (consenso admin).',
|
||||
"ID tenant Azure AD. Richiede un'app con permessi applicativi Team.ReadBasic.All e ChannelMessage.Read.All (consenso admin).",
|
||||
slackDescription:
|
||||
'Connetti il tuo workspace Slack per sincronizzare messaggi e thread dei canali.',
|
||||
slackBotTokenTip:
|
||||
'Token OAuth utente bot Slack (inizia con xoxb-). L\'app necessita degli scope channels:read, channels:history e users:read.',
|
||||
"Token OAuth utente bot Slack (inizia con xoxb-). L'app necessita degli scope channels:read, channels:history e users:read.",
|
||||
slackChannelsTip:
|
||||
'Opzionale: nomi dei canali da sincronizzare (es. general). Lascia vuoto per sincronizzare tutti i canali accessibili.',
|
||||
sharepointDescription:
|
||||
'Connetti un sito SharePoint tramite Microsoft Graph per sincronizzare le sue librerie documenti.',
|
||||
sharepointSiteUrlTip:
|
||||
'URL completo del sito SharePoint da indicizzare, es. https://contoso.sharepoint.com/sites/MySite. Richiede un\'app Azure AD con permessi applicativi Sites.Read.All e Files.Read.All (consenso admin).',
|
||||
bitbucketDescription: 'Connetti Bitbucket per sincronizzare il contenuto delle PR.',
|
||||
"URL completo del sito SharePoint da indicizzare, es. https://contoso.sharepoint.com/sites/MySite. Richiede un'app Azure AD con permessi applicativi Sites.Read.All e Files.Read.All (consenso admin).",
|
||||
bitbucketDescription:
|
||||
'Connetti Bitbucket per sincronizzare il contenuto delle PR.',
|
||||
bitbucketTopWorkspaceTip:
|
||||
'Il workspace Bitbucket da indicizzare (es. "atlassian" da https://bitbucket.org/atlassian/workspace ).',
|
||||
bitbucketRepositorySlugsTip:
|
||||
'Slug dei repository separati da virgola. Es. repo-one,repo-two',
|
||||
bitbucketProjectsTip: 'Chiavi progetto separate da virgola. Es. PROJ1,PROJ2',
|
||||
bitbucketProjectsTip:
|
||||
'Chiavi progetto separate da virgola. Es. PROJ1,PROJ2',
|
||||
bitbucketWorkspaceTip:
|
||||
'Questo connettore indicizzerà tutti i repository nel workspace.',
|
||||
boxDescription: 'Connetti il tuo drive Box per sincronizzare file e cartelle.',
|
||||
boxDescription:
|
||||
'Connetti il tuo drive Box per sincronizzare file e cartelle.',
|
||||
|
||||
githubDescription:
|
||||
'Connetti GitHub per sincronizzare pull request e issue per il recupero.',
|
||||
airtableDescription:
|
||||
'Connettiti ad Airtable e sincronizza i file da una tabella specificata all\'interno di un workspace designato.',
|
||||
"Connettiti ad Airtable e sincronizza i file da una tabella specificata all'interno di un workspace designato.",
|
||||
dingtalkAITableDescription:
|
||||
'Connettiti a Dingtalk AI Table e sincronizza i record da una tabella specificata.',
|
||||
gitlabDescription:
|
||||
@@ -1276,30 +1298,33 @@ Esempio: Virtual Hosted Style`,
|
||||
moodleDescription:
|
||||
'Connettiti al tuo LMS Moodle per sincronizzare contenuti dei corsi, forum e risorse.',
|
||||
moodleUrlTip:
|
||||
'L\'URL base della tua istanza Moodle (es. https://moodle.university.edu). Non includere /webservice o /login.',
|
||||
"L'URL base della tua istanza Moodle (es. https://moodle.university.edu). Non includere /webservice o /login.",
|
||||
moodleTokenTip:
|
||||
'Genera un token di servizio web in Moodle: vai a Amministrazione del sito → Server → Servizi web → Gestisci token. L\'utente deve essere iscritto ai corsi che vuoi sincronizzare.',
|
||||
"Genera un token di servizio web in Moodle: vai a Amministrazione del sito → Server → Servizi web → Gestisci token. L'utente deve essere iscritto ai corsi che vuoi sincronizzare.",
|
||||
seafileDescription:
|
||||
'Connettiti al tuo server SeaFile per sincronizzare file e documenti dalle tue librerie.',
|
||||
seafileUrlTip:
|
||||
'L\'URL completo del tuo server SeaFile incluso il protocollo. Esempio: https://seafile.example.com - Non includere una barra finale o alcun percorso dopo il dominio.',
|
||||
"L'URL completo del tuo server SeaFile incluso il protocollo. Esempio: https://seafile.example.com - Non includere una barra finale o alcun percorso dopo il dominio.",
|
||||
seafileAccountScopeTip:
|
||||
'Sincronizza tutte le librerie visibili al token API account qui sotto.',
|
||||
seafileTokenPanelHeading: 'Fornisci uno di questi metodi di autenticazione:',
|
||||
seafileTokenPanelAccountBullet: '- concede accesso a tutte le tue librerie.',
|
||||
seafileTokenPanelHeading:
|
||||
'Fornisci uno di questi metodi di autenticazione:',
|
||||
seafileTokenPanelAccountBullet:
|
||||
'- concede accesso a tutte le tue librerie.',
|
||||
seafileTokenPanelLibraryBullet:
|
||||
'— limitato a una singola libreria (più sicuro).',
|
||||
seafileValidationAccountTokenRequired:
|
||||
'Il token API account è richiesto per l\'ambito Intero account',
|
||||
"Il token API account è richiesto per l'ambito Intero account",
|
||||
seafileValidationTokenRequired:
|
||||
'Fornisci un token API account o un token libreria',
|
||||
seafileValidationLibraryIdRequired: 'L\'ID libreria è richiesto',
|
||||
seafileValidationDirectoryPathRequired: 'Il percorso directory è richiesto',
|
||||
seafileValidationLibraryIdRequired: "L'ID libreria è richiesto",
|
||||
seafileValidationDirectoryPathRequired:
|
||||
'Il percorso directory è richiesto',
|
||||
seafileSyncScopeTip:
|
||||
'Controlla cosa viene sincronizzato: ' +
|
||||
'(1) Intero account - Sincronizza tutte le librerie a cui il tuo token ha accesso. Richiede un token API account. ' +
|
||||
'(2) Singola libreria - Sincronizza tutti i file all\'interno di una libreria specifica. Richiede l\'ID libreria e un token API account o un token API libreria. ' +
|
||||
'(3) Directory specifica - Sincronizza solo i file all\'interno di una cartella specifica dentro una libreria. Richiede l\'ID libreria, il percorso della cartella all\'interno di quella libreria, e un token API account o un token API libreria.',
|
||||
"(2) Singola libreria - Sincronizza tutti i file all'interno di una libreria specifica. Richiede l'ID libreria e un token API account o un token API libreria. " +
|
||||
"(3) Directory specifica - Sincronizza solo i file all'interno di una cartella specifica dentro una libreria. Richiede l'ID libreria, il percorso della cartella all'interno di quella libreria, e un token API account o un token API libreria.",
|
||||
seafileTokenTip:
|
||||
'Il tuo token API SeaFile a livello di account. ' +
|
||||
'Concede accesso a tutte le librerie visibili al tuo account. ' +
|
||||
@@ -1309,16 +1334,16 @@ Esempio: Virtual Hosted Style`,
|
||||
'Un token API limitato a una libreria che concede accesso solo a una libreria specifica. ' +
|
||||
'Può essere usato al posto del token API account per gli ambiti di sincronizzazione "Singola libreria" e "Directory specifica".',
|
||||
seafileRepoIdTip:
|
||||
'L\'identificatore univoco (UUID) della libreria SeaFile che vuoi sincronizzare. ' +
|
||||
'Puoi trovarlo nella barra degli indirizzi del browser quando apri la libreria nell\'interfaccia web SeaFile. ' +
|
||||
"L'identificatore univoco (UUID) della libreria SeaFile che vuoi sincronizzare. " +
|
||||
"Puoi trovarlo nella barra degli indirizzi del browser quando apri la libreria nell'interfaccia web SeaFile. " +
|
||||
'Esempio: 7a9e1b3c-4d5f-6a7b-8c9d-0e1f2a3b4c5d. ' +
|
||||
'Richiesto quando l\'ambito di sincronizzazione è "Singola libreria" o "Directory specifica".',
|
||||
seafileSyncPathTip:
|
||||
'Il percorso assoluto della cartella da sincronizzare all\'interno della libreria specificata dall\'ID libreria sopra. ' +
|
||||
"Il percorso assoluto della cartella da sincronizzare all'interno della libreria specificata dall'ID libreria sopra. " +
|
||||
'Deve iniziare con una barra in avanti. ' +
|
||||
'Tutti i file e le sottocartelle sotto questo percorso saranno inclusi ricorsivamente. ' +
|
||||
'Esempio: /Documents/Reports. ' +
|
||||
'Importante: la cartella deve esistere all\'interno della libreria specificata. ' +
|
||||
"Importante: la cartella deve esistere all'interno della libreria specificata. " +
|
||||
'I percorsi al di fuori della libreria non sono supportati. ' +
|
||||
'Usato solo quando l\'ambito di sincronizzazione è "Directory specifica".',
|
||||
seafileIncludeSharedTip:
|
||||
@@ -1337,8 +1362,7 @@ Esempio: Virtual Hosted Style`,
|
||||
'Opzionale: limita la sincronizzazione a una singola chiave progetto (es. ENG).',
|
||||
jiraJqlTip:
|
||||
'Filtro JQL opzionale. Lascia vuoto per affidarti ai filtri progetto/tempo.',
|
||||
jiraBatchSizeTip:
|
||||
'Numero massimo di issue richieste da Jira per batch.',
|
||||
jiraBatchSizeTip: 'Numero massimo di issue richieste da Jira per batch.',
|
||||
jiraCommentsTip:
|
||||
'Includi i commenti Jira nel documento markdown generato.',
|
||||
jiraAttachmentsTip:
|
||||
@@ -1346,12 +1370,12 @@ Esempio: Virtual Hosted Style`,
|
||||
jiraAttachmentSizeTip:
|
||||
'Gli allegati più grandi di questo numero di byte saranno saltati.',
|
||||
jiraLabelsTip:
|
||||
'Etichette che dovrebbero essere saltate durante l\'indicizzazione (separate da virgola).',
|
||||
"Etichette che dovrebbero essere saltate durante l'indicizzazione (separate da virgola).",
|
||||
jiraBlacklistTip:
|
||||
'I commenti la cui email autore corrisponde a queste voci saranno ignorati.',
|
||||
jiraScopedTokenTip:
|
||||
'Abilita questo quando usi token Atlassian limitati (api.atlassian.com).',
|
||||
jiraEmailTip: 'Email associata all\'account/token API Jira.',
|
||||
jiraEmailTip: "Email associata all'account/token API Jira.",
|
||||
jiraTokenTip:
|
||||
'Token API generato da https://id.atlassian.com/manage-profile/security/api-tokens.',
|
||||
jiraPasswordTip:
|
||||
@@ -1367,7 +1391,7 @@ Esempio: Virtual Hosted Style`,
|
||||
mysqlIdColumnTip:
|
||||
'Colonna da usare come ID documento univoco. Se non specificata, sarà usato un hash del contenuto.',
|
||||
mysqlTimestampColumnTip:
|
||||
'Colonna datetime/timestamp per la sincronizzazione incrementale. Saranno recuperate solo le righe modificate dopo l\'ultima sincronizzazione.',
|
||||
"Colonna datetime/timestamp per la sincronizzazione incrementale. Saranno recuperate solo le righe modificate dopo l'ultima sincronizzazione.",
|
||||
postgresqlDescription:
|
||||
'Connettiti al database PostgreSQL per sincronizzare i dati dalle tabelle usando query SQL.',
|
||||
postgresqlQueryTip:
|
||||
@@ -1379,23 +1403,23 @@ Esempio: Virtual Hosted Style`,
|
||||
postgresqlIdColumnTip:
|
||||
'Colonna da usare come ID documento univoco. Se non specificata, sarà usato un hash del contenuto.',
|
||||
postgresqlTimestampColumnTip:
|
||||
'Colonna datetime/timestamp per la sincronizzazione incrementale. Saranno recuperate solo le righe modificate dopo l\'ultima sincronizzazione.',
|
||||
"Colonna datetime/timestamp per la sincronizzazione incrementale. Saranno recuperate solo le righe modificate dopo l'ultima sincronizzazione.",
|
||||
rest_apiDescription:
|
||||
'Connetti qualsiasi endpoint REST API come fonte dati usando un connettore flessibile guidato dalla configurazione.',
|
||||
onedriveDescription:
|
||||
'Connetti OneDrive o OneDrive for Business per indicizzare file e cartelle tramite query delta Microsoft Graph.',
|
||||
onedriveTenantIdTip:
|
||||
'ID tenant Azure Active Directory (Directory ID) dell\'organizzazione Microsoft 365.',
|
||||
"ID tenant Azure Active Directory (Directory ID) dell'organizzazione Microsoft 365.",
|
||||
onedriveClientIdTip:
|
||||
'ID applicazione (client) della registrazione app Azure AD con permesso Files.Read.All.',
|
||||
onedriveClientSecretTip:
|
||||
'Valore del client secret generato nella registrazione app Azure AD.',
|
||||
onedriveFolderPathTip:
|
||||
'Percorso sotto-cartella opzionale per limitare l\'indicizzazione (es. /Documents/Reports). Lascia vuoto per indicizzare l\'intero drive.',
|
||||
"Percorso sotto-cartella opzionale per limitare l'indicizzazione (es. /Documents/Reports). Lascia vuoto per indicizzare l'intero drive.",
|
||||
outlookDescription:
|
||||
'Connetti le caselle Outlook / Microsoft 365 e indicizza i messaggi tramite query delta Microsoft Graph.',
|
||||
outlookTenantIdTip:
|
||||
'ID tenant Azure Active Directory (Directory ID) dell\'organizzazione Microsoft 365.',
|
||||
"ID tenant Azure Active Directory (Directory ID) dell'organizzazione Microsoft 365.",
|
||||
outlookClientIdTip:
|
||||
'ID applicazione (client) della registrazione app Azure AD con permesso Mail.Read.',
|
||||
outlookClientSecretTip:
|
||||
@@ -1405,13 +1429,13 @@ Esempio: Virtual Hosted Style`,
|
||||
outlookUserIdsTip:
|
||||
'UPN o object ID separati da virgola delle caselle da sincronizzare. Lascia vuoto per sincronizzare ogni casella nel tenant (richiede User.Read.All).',
|
||||
salesforceDescription:
|
||||
'Connetti un\'org Salesforce e indicizza i record CRM (Account, Contatti, Opportunità, Casi, articoli Knowledge) tramite SOQL con sincronizzazione incrementale.',
|
||||
"Connetti un'org Salesforce e indicizza i record CRM (Account, Contatti, Opportunità, Casi, articoli Knowledge) tramite SOQL con sincronizzazione incrementale.",
|
||||
salesforceInstanceUrlTip:
|
||||
'URL org Salesforce, es. https://your-domain.my.salesforce.com (senza barra finale).',
|
||||
salesforceClientIdTip:
|
||||
'Consumer Key di una Connected App con Client Credentials Flow abilitato e lo scope api.',
|
||||
salesforceClientSecretTip:
|
||||
'Consumer Secret della Connected App usata per l\'autenticazione client-credentials.',
|
||||
"Consumer Secret della Connected App usata per l'autenticazione client-credentials.",
|
||||
salesforceObjectsTip:
|
||||
'Nomi API SObject separati da virgola da indicizzare. Predefinito Account, Contact, Opportunity, Case, Knowledge__kav.',
|
||||
salesforceApiVersionTip:
|
||||
@@ -1421,27 +1445,27 @@ Esempio: Virtual Hosted Style`,
|
||||
azureBlobAuthModeTip:
|
||||
'Scegli il metodo di autenticazione. Account Key e Connection String richiedono container_name; SAS Token richiede container_url + sas_token.',
|
||||
azureBlobAccountNameTip:
|
||||
'Nome account di storage Azure (es. mystorageaccount). Richiesto per l\'autenticazione account-key.',
|
||||
"Nome account di storage Azure (es. mystorageaccount). Richiesto per l'autenticazione account-key.",
|
||||
azureBlobAccountKeyTip:
|
||||
'Chiave di accesso account di storage (codificata Base64). Richiesta per l\'autenticazione account-key.',
|
||||
"Chiave di accesso account di storage (codificata Base64). Richiesta per l'autenticazione account-key.",
|
||||
azureBlobConnectionStringTip:
|
||||
'Stringa di connessione Azure Storage completa (DefaultEndpointsProtocol=https;AccountName=...;...). Richiesta per l\'autenticazione connection-string.',
|
||||
"Stringa di connessione Azure Storage completa (DefaultEndpointsProtocol=https;AccountName=...;...). Richiesta per l'autenticazione connection-string.",
|
||||
azureBlobContainerUrlTip:
|
||||
'URL HTTPS completo del container (es. https://account.blob.core.windows.net/container). Richiesto per l\'autenticazione SAS-token.',
|
||||
"URL HTTPS completo del container (es. https://account.blob.core.windows.net/container). Richiesto per l'autenticazione SAS-token.",
|
||||
azureBlobSasTokenTip:
|
||||
'Stringa di query SAS (senza il "?" iniziale). Richiesta per l\'autenticazione SAS-token.',
|
||||
azureBlobContainerNameTip:
|
||||
'Nome del container da indicizzare. Richiesto per l\'autenticazione account-key e connection-string.',
|
||||
"Nome del container da indicizzare. Richiesto per l'autenticazione account-key e connection-string.",
|
||||
azureBlobPrefixTip:
|
||||
'Prefisso nome blob opzionale per limitare l\'indicizzazione a una cartella virtuale (es. documents/reports/). Lascia vuoto per indicizzare l\'intero container.',
|
||||
"Prefisso nome blob opzionale per limitare l'indicizzazione a una cartella virtuale (es. documents/reports/). Lascia vuoto per indicizzare l'intero container.",
|
||||
restApiQueryParamsTip:
|
||||
'Coppie Chiave=valore (una per riga) inviate come parametri di query URL. Usa questo invece di incorporare i parametri nell\'URL.',
|
||||
"Coppie Chiave=valore (una per riga) inviate come parametri di query URL. Usa questo invece di incorporare i parametri nell'URL.",
|
||||
restApiHeadersTip:
|
||||
'Oggetto JSON opzionale di header HTTP aggiuntivi da inviare con ogni richiesta.',
|
||||
restApiItemsPathTip:
|
||||
'Nome del campo o JSONPath all\'array di elementi nella risposta. Lascia vuoto per il rilevamento automatico (prova "items", "results", "data", ecc.).',
|
||||
restApiIdFieldTip:
|
||||
'Percorso del campo all\'interno di ogni elemento usato per costruire un ID documento stabile. Lascia vuoto per generare automaticamente dall\'hash del contenuto.',
|
||||
"Percorso del campo all'interno di ogni elemento usato per costruire un ID documento stabile. Lascia vuoto per generare automaticamente dall'hash del contenuto.",
|
||||
restApiContentFieldsTip:
|
||||
'Elenco separato da virgola di campi degli elementi da concatenare nel contenuto del documento.',
|
||||
restApiMetadataFieldsTip:
|
||||
@@ -1449,11 +1473,11 @@ Esempio: Virtual Hosted Style`,
|
||||
restApiNextCursorPathTip:
|
||||
'Espressione JSONPath che si risolve nel cursore della pagina successiva nella risposta API.',
|
||||
restApiPollTimestampFieldTip:
|
||||
'Percorso del campo in ogni elemento che rappresenta l\'ora dell\'ultimo aggiornamento, usato per la sincronizzazione incrementale.',
|
||||
"Percorso del campo in ogni elemento che rappresenta l'ora dell'ultimo aggiornamento, usato per la sincronizzazione incrementale.",
|
||||
restApiRequestBodyTip:
|
||||
'Body JSON opzionale da inviare per le richieste POST. Usato insieme ai parametri di query e alla paginazione.',
|
||||
restApiRequestDelayTip:
|
||||
'Ritardo in secondi tra richieste di pagina consecutive. Aiuta a evitare il rate limiting dall\'API. Imposta a 0 per disabilitare.',
|
||||
"Ritardo in secondi tra richieste di pagina consecutive. Aiuta a evitare il rate limiting dall'API. Imposta a 0 per disabilitare.",
|
||||
restApiValidationApiKeyRequired:
|
||||
'La chiave API è richiesta quando il tipo di autenticazione è API Key (Header).',
|
||||
restApiValidationApiKeyHeaderNameRequired:
|
||||
@@ -1506,7 +1530,8 @@ Esempio: Virtual Hosted Style`,
|
||||
timezoneMessage: 'Inserisci il tuo fuso orario!',
|
||||
timezonePlaceholder: 'seleziona il tuo fuso orario',
|
||||
email: 'Email',
|
||||
emailDescription: "Una volta registrata, l'email non può essere cambiata.",
|
||||
emailDescription:
|
||||
"Una volta registrata, l'email non può essere cambiata.",
|
||||
currentPassword: 'Password attuale',
|
||||
currentPasswordMessage: 'Inserisci la tua password!',
|
||||
newPassword: 'Nuova password',
|
||||
@@ -1535,7 +1560,8 @@ Esempio: Virtual Hosted Style`,
|
||||
'Per utenti cinesi, non è necessario compilare o usare https://dashscope.aliyuncs.com/compatible-mode/v1. Per utenti internazionali, usa https://dashscope-intl.aliyuncs.com/compatible-mode/v1',
|
||||
siliconBaseUrlTip:
|
||||
'Per utenti cinesi, non è necessario compilare o usare https://api.siliconflow.cn/v1. Per utenti internazionali, usa https://api.siliconflow.com/v1',
|
||||
tongyiBaseUrlPlaceholder: '(Solo utenti internazionali, vedi suggerimento)',
|
||||
tongyiBaseUrlPlaceholder:
|
||||
'(Solo utenti internazionali, vedi suggerimento)',
|
||||
minimaxBaseUrlTip:
|
||||
'Solo utenti internazionali: usa https://api.minimax.io/v1',
|
||||
minimaxBaseUrlPlaceholder:
|
||||
@@ -1549,7 +1575,7 @@ Esempio: Virtual Hosted Style`,
|
||||
'Il modello di embedding predefinito per ogni nuovo dataset creato. Se non riesci a trovare un modello di embedding dal menu a discesa, controlla se stai usando la versione slim di RAGFlow (che non include modelli di embedding) o controlla https://ragflow.io/docs/dev/supported_models per vedere se il tuo fornitore di modelli supporta questo modello.',
|
||||
img2txtModel: 'VLM',
|
||||
img2txtModelTip:
|
||||
'Il VLM predefinito per ogni nuovo dataset creato. Descrive un\'immagine o un video. Se non riesci a trovare un modello dal menu a discesa, controlla https://ragflow.io/docs/dev/supported_models per vedere se il tuo fornitore di modelli supporta questo modello.',
|
||||
"Il VLM predefinito per ogni nuovo dataset creato. Descrive un'immagine o un video. Se non riesci a trovare un modello dal menu a discesa, controlla https://ragflow.io/docs/dev/supported_models per vedere se il tuo fornitore di modelli supporta questo modello.",
|
||||
sequence2txtModel: 'ASR',
|
||||
sequence2txtModelTip:
|
||||
'Il modello ASR predefinito per ogni nuovo dataset creato. Usa questo modello per tradurre le voci in testo corrispondente.',
|
||||
@@ -1564,7 +1590,7 @@ Esempio: Virtual Hosted Style`,
|
||||
editLlmTitle: 'Modifica modello {{name}}',
|
||||
editModel: 'Modifica modello',
|
||||
instanceName: 'Nome istanza',
|
||||
instanceNameMessage: 'Inserisci il nome dell\'istanza!',
|
||||
instanceNameMessage: "Inserisci il nome dell'istanza!",
|
||||
instanceNameTip:
|
||||
'Un nome univoco per identificare questa istanza del fornitore sotto la stessa factory.',
|
||||
modelName: 'Nome modello',
|
||||
@@ -1585,7 +1611,7 @@ Esempio: Virtual Hosted Style`,
|
||||
selectAlgorithm: 'Seleziona algoritmo',
|
||||
modelNamePlaceholder: 'Ad esempio: paddleocr-from-env-1',
|
||||
modelNameRequired: 'Il nome del modello è obbligatorio',
|
||||
apiUrlRequired: 'L\'URL API di PaddleOCR è obbligatorio',
|
||||
apiUrlRequired: "L'URL API di PaddleOCR è obbligatorio",
|
||||
},
|
||||
vision: 'Supporta Vision?',
|
||||
ollamaLink: 'Come integrare {{name}}',
|
||||
@@ -1593,7 +1619,7 @@ Esempio: Virtual Hosted Style`,
|
||||
TencentCloudLink: 'Come usare TencentCloud ASR',
|
||||
volcModelNameMessage: 'Inserisci il nome del tuo modello!',
|
||||
addEndpointID: 'ID Modello',
|
||||
endpointIDMessage: 'Inserisci l\'ID del tuo modello',
|
||||
endpointIDMessage: "Inserisci l'ID del tuo modello",
|
||||
addArkApiKey: 'VOLC ARK_API_KEY',
|
||||
ArkApiKeyMessage: 'Inserisci la tua ARK_API_KEY',
|
||||
bedrockModelNameMessage: 'Inserisci il nome del tuo modello!',
|
||||
@@ -1656,8 +1682,7 @@ Esempio: Virtual Hosted Style`,
|
||||
yiyanAKMessage: 'Inserisci la tua API KEY',
|
||||
addyiyanSK: 'yiyan Secret KEY',
|
||||
yiyanSKMessage: 'Inserisci la tua Secret KEY',
|
||||
FishAudioModelNameMessage:
|
||||
'Dai un nome al tuo modello di sintesi vocale',
|
||||
FishAudioModelNameMessage: 'Dai un nome al tuo modello di sintesi vocale',
|
||||
addFishAudioAK: 'Fish Audio API KEY',
|
||||
addFishAudioAKMessage: 'Inserisci la tua API KEY',
|
||||
addFishAudioRefID: 'FishAudio Reference ID',
|
||||
@@ -1694,21 +1719,22 @@ Esempio: Virtual Hosted Style`,
|
||||
configuration: 'Configurazione',
|
||||
langfuseDescription:
|
||||
'Tracce, valutazioni, gestione dei prompt e metriche per il debug e il miglioramento della tua applicazione LLM.',
|
||||
viewLangfuseSDocumentation: "Visualizza la documentazione di Langfuse",
|
||||
viewLangfuseSDocumentation: 'Visualizza la documentazione di Langfuse',
|
||||
view: 'Visualizza',
|
||||
modelsToBeAddedTooltip:
|
||||
'Se il tuo fornitore di modelli non è elencato ma dichiara di essere "OpenAI-compatible", seleziona la scheda OpenAI-API-compatible per aggiungere i modelli pertinenti. ',
|
||||
mcp: 'MCP',
|
||||
mineru: {
|
||||
modelNameRequired: 'Il nome del modello è obbligatorio',
|
||||
apiServerRequired: 'La configurazione del MinerU API Server è richiesta',
|
||||
apiServerRequired:
|
||||
'La configurazione del MinerU API Server è richiesta',
|
||||
serverUrlBackendLimit:
|
||||
'L\'indirizzo URL del MinerU Server è disponibile solo per il backend client HTTP',
|
||||
"L'indirizzo URL del MinerU Server è disponibile solo per il backend client HTTP",
|
||||
apiserver: 'Configurazione MinerU API Server',
|
||||
outputDir: 'Percorso directory di output MinerU',
|
||||
backend: 'Tipo di backend di elaborazione MinerU',
|
||||
serverUrl: 'Indirizzo URL MinerU Server',
|
||||
deleteOutput: 'Elimina i file di output dopo l\'elaborazione',
|
||||
deleteOutput: "Elimina i file di output dopo l'elaborazione",
|
||||
selectBackend: 'Seleziona backend di elaborazione',
|
||||
backendOptions: {
|
||||
pipeline: 'Elaborazione pipeline standard',
|
||||
@@ -1787,7 +1813,7 @@ Esempio: Virtual Hosted Style`,
|
||||
directory: 'Directory',
|
||||
uploadTitle: 'Trascina e rilascia il tuo file qui per caricarlo',
|
||||
uploadDescription:
|
||||
'Supporta caricamento singolo o multiplo. Per un RAGFlow distribuito localmente: il limite di dimensione totale dei file per caricamento è 1GB, con un limite batch di 32 file. Non c\'è limite al numero totale di file per account. Per cloud.ragflow.io, il limite di dimensione totale dei file per caricamento è 10MB, con ogni file non superiore a 10MB e un massimo di 128 file per account.',
|
||||
"Supporta caricamento singolo o multiplo. Per un RAGFlow distribuito localmente: il limite di dimensione totale dei file per caricamento è 1GB, con un limite batch di 32 file. Non c'è limite al numero totale di file per account. Per cloud.ragflow.io, il limite di dimensione totale dei file per caricamento è 10MB, con ogni file non superiore a 10MB e un massimo di 128 file per account.",
|
||||
local: 'Caricamenti locali',
|
||||
s3: 'Caricamenti S3',
|
||||
preview: 'Anteprima',
|
||||
@@ -1813,7 +1839,7 @@ Esempio: Virtual Hosted Style`,
|
||||
removeTagAriaLabel: 'Rimuovi {{tag}}',
|
||||
includeHeadingContent: 'Separa contenuto intestazione padre',
|
||||
includeHeadingContentTip:
|
||||
'Quando abilitato, i chunk includono solo il loro percorso di intestazione e contenuto; il contenuto immediatamente successivo a un\'intestazione padre è mantenuto come chunk separato.',
|
||||
"Quando abilitato, i chunk includono solo il loro percorso di intestazione e contenuto; il contenuto immediatamente successivo a un'intestazione padre è mantenuto come chunk separato.",
|
||||
rootAsHeading: 'Imposta il primo chunk come contesto globale',
|
||||
rootAsHeadingTip:
|
||||
'Tratta la prima divisione come intestazione globale per mantenere un contesto coerente nella gerarchia del documento. Ideale per i curriculum dove la prima sezione identifica il soggetto.',
|
||||
@@ -1826,7 +1852,7 @@ Ideale per: documenti con contenuto fluente e contestualmente connesso — come
|
||||
'Rileva e analizza i layout di pagina multi-colonna per preservare il corretto ordine di lettura. Attiva questo per PDF o documenti con layout a due colonne o stile giornale.',
|
||||
removeToc: 'Rimuovi indice originale',
|
||||
removeTocTip:
|
||||
'Rimuove l\'indice incluso nel PDF originale, così non viene analizzato come contenuto regolare o suddiviso per il recupero.',
|
||||
"Rimuove l'indice incluso nel PDF originale, così non viene analizzato come contenuto regolare o suddiviso per il recupero.",
|
||||
removeHeaderFooter: 'Rimuovi intestazione e piè di pagina',
|
||||
autoPlay: 'Riproduzione automatica audio',
|
||||
downloadFileTypeTip: 'Il tipo di file da scaricare',
|
||||
@@ -1888,11 +1914,10 @@ Ideale per: documenti con contenuto fluente e contestualmente connesso — come
|
||||
split: 'Dividi',
|
||||
script: 'Script',
|
||||
iterationItemDescription:
|
||||
'Rappresenta l\'elemento corrente nell\'iterazione, che può essere referenziato e manipolato nei passaggi successivi.',
|
||||
"Rappresenta l'elemento corrente nell'iterazione, che può essere referenziato e manipolato nei passaggi successivi.",
|
||||
guidingQuestion: 'Domanda guida',
|
||||
onFailure: 'In caso di fallimento',
|
||||
userPromptDefaultValue:
|
||||
'Questo è l\'ordine che devi inviare all\'agente.',
|
||||
userPromptDefaultValue: "Questo è l'ordine che devi inviare all'agente.",
|
||||
search: 'Cerca',
|
||||
communication: 'Comunicazione',
|
||||
developer: 'Sviluppatore',
|
||||
@@ -1935,7 +1960,8 @@ Ideale per: documenti con contenuto fluente e contestualmente connesso — come
|
||||
multimodalModels: 'Modelli multimodali',
|
||||
textOnlyModels: 'Modelli solo testo',
|
||||
allModels: 'Tutti i modelli',
|
||||
codeExecDescription: 'Scrivi la tua logica Python o Javascript personalizzata.',
|
||||
codeExecDescription:
|
||||
'Scrivi la tua logica Python o Javascript personalizzata.',
|
||||
stringTransformDescription:
|
||||
'Modifica il contenuto del testo. Attualmente supporta: divisione o concatenazione del testo.',
|
||||
foundation: 'Fondamenti',
|
||||
@@ -1961,7 +1987,7 @@ Ideale per: documenti con contenuto fluente e contestualmente connesso — come
|
||||
addMessage: 'Aggiungi messaggio',
|
||||
loop: 'Ciclo',
|
||||
loopDescription:
|
||||
'Il ciclo è il limite massimo del numero di cicli del componente corrente; quando il numero di cicli supera il valore del ciclo, significa che il componente non può completare l\'attività corrente, per favore ri-ottimizza l\'agente',
|
||||
"Il ciclo è il limite massimo del numero di cicli del componente corrente; quando il numero di cicli supera il valore del ciclo, significa che il componente non può completare l'attività corrente, per favore ri-ottimizza l'agente",
|
||||
exitLoop: 'Esci dal ciclo',
|
||||
exitLoopDescription: `Equivalente a "break". Questo nodo non ha elementi di configurazione. Quando il corpo del ciclo raggiunge questo nodo, il ciclo termina.`,
|
||||
loopVariables: 'Variabili ciclo',
|
||||
@@ -2016,7 +2042,7 @@ Ideale per: documenti con contenuto fluente e contestualmente connesso — come
|
||||
'Un componente che cerca da duckduckgo.com, permettendo di specificare il numero di risultati di ricerca usando TopN. Integra i dataset esistenti.',
|
||||
searXNG: 'SearXNG',
|
||||
searXNGDescription:
|
||||
'Un componente che cerca tramite l\'URL dell\'istanza SearXNG fornita. Specifica TopN e l\'URL dell\'istanza.',
|
||||
"Un componente che cerca tramite l'URL dell'istanza SearXNG fornita. Specifica TopN e l'URL dell'istanza.",
|
||||
docGenerator: 'Generatore Documenti',
|
||||
docGeneratorDescription: `Genera un file da contenuto Markdown.`,
|
||||
browser: 'Browser',
|
||||
@@ -2045,7 +2071,7 @@ Ideale per: documenti con contenuto fluente e contestualmente connesso — come
|
||||
news: 'Notizie',
|
||||
messageHistoryWindowSize: 'Dimensione finestra messaggi',
|
||||
messageHistoryWindowSizeTip:
|
||||
'La dimensione della finestra della cronologia conversazione visibile all\'LLM. Più grande è meglio, ma fai attenzione al limite massimo di token dell\'LLM.',
|
||||
"La dimensione della finestra della cronologia conversazione visibile all'LLM. Più grande è meglio, ma fai attenzione al limite massimo di token dell'LLM.",
|
||||
wikipedia: 'Wikipedia',
|
||||
pubMed: 'PubMed',
|
||||
pubMedDescription:
|
||||
@@ -2097,7 +2123,7 @@ Ideale per: documenti con contenuto fluente e contestualmente connesso — come
|
||||
fieldtranslate: 'Traduzione di settore',
|
||||
},
|
||||
baiduDomainOptions: {
|
||||
it: 'Tecnologia dell\'informazione',
|
||||
it: "Tecnologia dell'informazione",
|
||||
finance: 'Finanza ed economia',
|
||||
machinery: 'Produzione meccanica',
|
||||
senimed: 'Biomedicina',
|
||||
@@ -2142,7 +2168,7 @@ Ideale per: documenti con contenuto fluente e contestualmente connesso — come
|
||||
},
|
||||
qWeather: 'QWeather',
|
||||
qWeatherDescription:
|
||||
'Un componente che recupera informazioni meteorologiche, come temperatura e qualità dell\'aria, da https://www.qweather.com/.',
|
||||
"Un componente che recupera informazioni meteorologiche, come temperatura e qualità dell'aria, da https://www.qweather.com/.",
|
||||
lang: 'Lingua',
|
||||
type: 'Tipo',
|
||||
webApiKey: 'Web API key',
|
||||
@@ -2184,7 +2210,7 @@ Ideale per: documenti con contenuto fluente e contestualmente connesso — come
|
||||
qWeatherTypeOptions: {
|
||||
weather: 'Previsioni meteo',
|
||||
indices: 'Indice vita meteo',
|
||||
airquality: 'Qualità dell\'aria',
|
||||
airquality: "Qualità dell'aria",
|
||||
},
|
||||
qWeatherUserTypeOptions: {
|
||||
free: 'Abbonato gratuito',
|
||||
@@ -2239,7 +2265,7 @@ Ideale per: documenti con contenuto fluente e contestualmente connesso — come
|
||||
wenCai: 'WenCai',
|
||||
queryType: 'Tipo di query',
|
||||
wenCaiDescription:
|
||||
'Un componente che ottiene informazioni finanziarie, inclusi prezzi delle azioni e notizie sui finanziamenti, da un\'ampia gamma di siti web finanziari.',
|
||||
"Un componente che ottiene informazioni finanziarie, inclusi prezzi delle azioni e notizie sui finanziamenti, da un'ampia gamma di siti web finanziari.",
|
||||
wenCaiQueryTypeOptions: {
|
||||
stock: 'azione',
|
||||
zhishu: 'indice',
|
||||
@@ -2365,7 +2391,7 @@ Ideale per: documenti con contenuto fluente e contestualmente connesso — come
|
||||
testRun: 'Test esecuzione',
|
||||
template: 'Template',
|
||||
templateDescription:
|
||||
'Un componente che formatta l\'output di altri componenti. 1. Supporta template Jinja2, prima converte l\'input in un oggetto e poi renderizza il template, 2. Mantiene contemporaneamente il metodo originale di sostituzione stringhe {parameter}',
|
||||
"Un componente che formatta l'output di altri componenti. 1. Supporta template Jinja2, prima converte l'input in un oggetto e poi renderizza il template, 2. Mantiene contemporaneamente il metodo originale di sostituzione stringhe {parameter}",
|
||||
emailComponent: 'Email',
|
||||
emailDescription: "Invia un'email a un indirizzo specificato.",
|
||||
smtpServer: 'Host SMTP',
|
||||
@@ -2378,11 +2404,11 @@ Ideale per: documenti con contenuto fluente e contestualmente connesso — come
|
||||
ccEmail: 'Email CC',
|
||||
emailSubject: 'Oggetto',
|
||||
emailContent: 'Contenuto',
|
||||
smtpServerRequired: 'Inserisci l\'indirizzo del server SMTP',
|
||||
senderEmailRequired: 'Inserisci l\'email del mittente',
|
||||
smtpServerRequired: "Inserisci l'indirizzo del server SMTP",
|
||||
senderEmailRequired: "Inserisci l'email del mittente",
|
||||
authCodeRequired: 'Inserisci il codice di autorizzazione',
|
||||
toEmailRequired: 'Inserisci l\'email del destinatario',
|
||||
emailContentRequired: 'Inserisci il contenuto dell\'email',
|
||||
toEmailRequired: "Inserisci l'email del destinatario",
|
||||
emailContentRequired: "Inserisci il contenuto dell'email",
|
||||
emailSentSuccess: 'Email inviata con successo',
|
||||
emailSentFailed: 'Invio email fallito',
|
||||
dynamicParameters: 'Parametri dinamici',
|
||||
@@ -2462,14 +2488,15 @@ Questo delimitatore è usato per dividere il testo di input in diversi pezzi di
|
||||
},
|
||||
prompt: 'Prompt',
|
||||
promptTip:
|
||||
'Usa il prompt di sistema per descrivere il compito per l\'LLM, specificare come dovrebbe rispondere e delineare altri requisiti vari. Il prompt di sistema è spesso usato insieme a chiavi (variabili), che servono come vari input di dati per l\'LLM. Usa una barra `/` o il pulsante (x) per mostrare le chiavi da usare.',
|
||||
"Usa il prompt di sistema per descrivere il compito per l'LLM, specificare come dovrebbe rispondere e delineare altri requisiti vari. Il prompt di sistema è spesso usato insieme a chiavi (variabili), che servono come vari input di dati per l'LLM. Usa una barra `/` o il pulsante (x) per mostrare le chiavi da usare.",
|
||||
promptMessage: 'Il prompt è richiesto',
|
||||
infor: 'Esecuzione informativa',
|
||||
knowledgeBasesTip:
|
||||
'Seleziona i dataset da associare a questo assistente chat, o scegli variabili contenenti ID di dataset qui sotto.',
|
||||
knowledgeBaseVars: 'Variabili dataset',
|
||||
code: 'Codice',
|
||||
codeDescription: 'Permette agli sviluppatori di scrivere logica Python personalizzata.',
|
||||
codeDescription:
|
||||
'Permette agli sviluppatori di scrivere logica Python personalizzata.',
|
||||
dataOperations: 'Operazioni dati',
|
||||
dataOperationsDescription: 'Esegui varie operazioni su un oggetto Data.',
|
||||
listOperations: 'Operazioni lista',
|
||||
@@ -2485,7 +2512,7 @@ Questo processo aggrega variabili da più rami in una singola variabile per otte
|
||||
openingSwitch: 'Interruttore apertura',
|
||||
openingCopy: 'Saluto di apertura',
|
||||
openingSwitchTip:
|
||||
'I tuoi utenti vedranno questo messaggio di benvenuto all\'inizio.',
|
||||
"I tuoi utenti vedranno questo messaggio di benvenuto all'inizio.",
|
||||
modeTip: 'La modalità definisce come viene avviato il workflow.',
|
||||
mode: 'Modalità',
|
||||
conversational: 'Conversazionale',
|
||||
@@ -2508,7 +2535,8 @@ Questo processo aggrega variabili da più rami in una singola variabile per otte
|
||||
userFillUpDescription: `Mette in pausa il workflow e attende il messaggio dell'utente prima di continuare.`,
|
||||
codeExec: 'Codice',
|
||||
tavilySearch: 'Ricerca Tavily',
|
||||
tavilySearchDescription: 'Risultati di ricerca tramite il servizio Tavily.',
|
||||
tavilySearchDescription:
|
||||
'Risultati di ricerca tramite il servizio Tavily.',
|
||||
tavilyExtract: 'Estrazione Tavily',
|
||||
tavilyExtractDescription: 'Tavily Extract',
|
||||
log: 'Log',
|
||||
@@ -2529,10 +2557,10 @@ Questo processo aggrega variabili da più rami in una singola variabile per otte
|
||||
|
||||
logTimeline: {
|
||||
begin: 'Pronto a iniziare',
|
||||
agent: 'L\'agente sta pensando',
|
||||
agent: "L'agente sta pensando",
|
||||
userFillUp: 'In attesa di te',
|
||||
retrieval: 'Consultazione della conoscenza',
|
||||
message: 'L\'agente dice',
|
||||
message: "L'agente dice",
|
||||
awaitResponse: 'In attesa di te',
|
||||
switch: 'Scelta del percorso migliore',
|
||||
iteration: 'Elaborazione batch',
|
||||
@@ -2547,7 +2575,7 @@ Questo processo aggrega variabili da più rami in una singola variabile per otte
|
||||
googleScholar: 'Ricerca accademica',
|
||||
gitHub: 'Ricerca su GitHub',
|
||||
email: 'Invio email',
|
||||
httpRequest: 'Chiamata a un\'API',
|
||||
httpRequest: "Chiamata a un'API",
|
||||
wenCai: 'Interrogazione dati finanziari',
|
||||
},
|
||||
goto: 'Ramo di fallimento',
|
||||
@@ -2559,7 +2587,7 @@ Questo processo aggrega variabili da più rami in una singola variabile per otte
|
||||
release: 'Pubblica',
|
||||
production: 'Produzione',
|
||||
productionTooltip:
|
||||
'Questa versione è pubblicata in produzione. Accedivi tramite l\'API o la pagina incorporata.',
|
||||
"Questa versione è pubblicata in produzione. Accedivi tramite l'API o la pagina incorporata.",
|
||||
confirmPublish: 'Conferma pubblicazione',
|
||||
publishIngestionPipeline:
|
||||
'Stai per pubblicare questa ingestion pipeline.',
|
||||
@@ -2574,7 +2602,7 @@ Questo processo aggrega variabili da più rami in una singola variabile per otte
|
||||
chooseAgentType: 'Scegli il tipo di agente',
|
||||
parser: 'Parser',
|
||||
parserDescription:
|
||||
'Estrae testo grezzo e struttura dai file per l\'elaborazione a valle.',
|
||||
"Estrae testo grezzo e struttura dai file per l'elaborazione a valle.",
|
||||
tokenizer: 'Indicizzatore',
|
||||
tokenizerRequired: 'Aggiungi prima il nodo Indicizzatore',
|
||||
tokenizerDescription:
|
||||
@@ -2620,7 +2648,7 @@ L'Indicizzatore memorizzerà il contenuto nelle corrispondenti strutture dati pe
|
||||
tableResultType: 'Tipo risultato tabella',
|
||||
markdownImageResponseType: 'Tipo risposta immagine Markdown',
|
||||
systemPromptPlaceholder:
|
||||
'Inserisci il prompt di sistema per l\'analisi dell\'immagine, se vuoto sarà usato il valore predefinito del sistema',
|
||||
"Inserisci il prompt di sistema per l'analisi dell'immagine, se vuoto sarà usato il valore predefinito del sistema",
|
||||
exportJson: 'Esporta JSON',
|
||||
viewResult: 'Visualizza risultato',
|
||||
running: 'In esecuzione',
|
||||
@@ -2748,7 +2776,7 @@ Le informazioni strutturate importanti possono includere: nomi, date, luoghi, ev
|
||||
response: 'Risposta',
|
||||
executionMode: 'Modalità di esecuzione',
|
||||
executionModeTip:
|
||||
'Risposta accettata: il sistema restituisce un riconoscimento immediatamente dopo che la richiesta è validata, mentre il workflow continua a eseguire in modo asincrono in background. /Risposta finale: il sistema restituisce una risposta solo dopo che l\'esecuzione del workflow è completata.',
|
||||
"Risposta accettata: il sistema restituisce un riconoscimento immediatamente dopo che la richiesta è validata, mentre il workflow continua a eseguire in modo asincrono in background. /Risposta finale: il sistema restituisce una risposta solo dopo che l'esecuzione del workflow è completata.",
|
||||
authMethods: 'Metodi di autenticazione',
|
||||
authType: 'Tipo di autenticazione',
|
||||
limit: 'Limite di frequenza richieste',
|
||||
@@ -2989,10 +3017,10 @@ Le informazioni strutturate importanti possono includere: nomi, date, luoghi, ev
|
||||
|
||||
sandboxSettingsPage: {
|
||||
description:
|
||||
'Configura il tuo provider sandbox per l\'esecuzione del codice. La sandbox è usata dal componente Codice negli agenti.',
|
||||
"Configura il tuo provider sandbox per l'esecuzione del codice. La sandbox è usata dal componente Codice negli agenti.",
|
||||
providerSelection: 'Selezione provider',
|
||||
providerSelectionDescription:
|
||||
'Scegli un provider sandbox per l\'esecuzione del codice',
|
||||
"Scegli un provider sandbox per l'esecuzione del codice",
|
||||
|
||||
namedProviderConfiguration: 'Configurazione {{name}}',
|
||||
namedProviderConfigurationDescription:
|
||||
|
||||
Reference in New Issue
Block a user