diff --git a/.gitignore b/.gitignore index 16fd3222b..310629bfa 100644 --- a/.gitignore +++ b/.gitignore @@ -203,3 +203,8 @@ backup .hypothesis + + +# Added by cargo + +/target diff --git a/admin/build_cli_release.sh b/admin/build_cli_release.sh index c9fd6d9d9..d9025ff18 100755 --- a/admin/build_cli_release.sh +++ b/admin/build_cli_release.sh @@ -21,7 +21,7 @@ cp pyproject.toml release/$PROJECT_NAME/pyproject.toml cp README.md release/$PROJECT_NAME/README.md mkdir release/$PROJECT_NAME/$SOURCE_DIR/$PACKAGE_DIR -p -cp admin_client.py release/$PROJECT_NAME/$SOURCE_DIR/$PACKAGE_DIR/admin_client.py +cp ragflow_cli.py release/$PROJECT_NAME/$SOURCE_DIR/$PACKAGE_DIR/ragflow_cli.py if [ -d "release/$PROJECT_NAME/$SOURCE_DIR" ]; then echo "✅ source dir: release/$PROJECT_NAME/$SOURCE_DIR" diff --git a/admin/client/pyproject.toml b/admin/client/pyproject.toml index de6bf7bc3..3e35d86c1 100644 --- a/admin/client/pyproject.toml +++ b/admin/client/pyproject.toml @@ -21,4 +21,4 @@ test = [ ] [project.scripts] -ragflow-cli = "admin_client:main" +ragflow-cli = "ragflow_cli:main" diff --git a/admin/client/admin_client.py b/admin/client/ragflow_cli.py similarity index 76% rename from admin/client/admin_client.py rename to admin/client/ragflow_cli.py index 79284a53f..a8e50caea 100644 --- a/admin/client/admin_client.py +++ b/admin/client/ragflow_cli.py @@ -64,6 +64,11 @@ sql_command: list_services | generate_key | list_keys | drop_key + | list_user_datasets + | list_user_agents + | list_user_chats + | list_user_model_providers + | list_user_default_models // meta command definition meta_command: "\\" meta_command_name [meta_args] @@ -114,6 +119,11 @@ ENVS: "ENVS"i KEY: "KEY"i KEYS: "KEYS"i GENERATE: "GENERATE"i +MODEL: "MODEL"i +MODELS: "MODELS"i +PROVIDERS: "PROVIDERS"i +DEFAULT: "DEFAULT"i +CHATS: "CHATS"i list_services: LIST SERVICES ";" show_service: SHOW SERVICE NUMBER ";" @@ -142,20 +152,26 @@ revoke_permission: REVOKE action_list ON identifier FROM ROLE identifier ";" alter_user_role: ALTER USER quoted_string SET ROLE identifier ";" show_user_permission: SHOW USER PERMISSION quoted_string ";" +show_version: SHOW VERSION ";" + grant_admin: GRANT ADMIN quoted_string ";" revoke_admin: REVOKE ADMIN quoted_string ";" +generate_key: GENERATE KEY FOR USER quoted_string ";" +list_keys: LIST KEYS OF quoted_string ";" +drop_key: DROP KEY quoted_string OF quoted_string ";" + set_variable: SET VAR identifier identifier ";" show_variable: SHOW VAR identifier ";" list_variables: LIST VARS ";" list_configs: LIST CONFIGS ";" list_environments: LIST ENVS ";" -generate_key: GENERATE KEY FOR USER quoted_string ";" -list_keys: LIST KEYS OF quoted_string ";" -drop_key: DROP KEY quoted_string OF quoted_string ";" - -show_version: SHOW VERSION ";" +list_user_datasets: LIST DATASETS ";" +list_user_agents: LIST AGENTS ";" +list_user_chats: LIST CHATS ";" +list_user_model_providers: LIST MODEL PROVIDERS ";" +list_user_default_models: LIST DEFAULT MODELS ";" action_list: identifier ("," identifier)* @@ -172,7 +188,7 @@ NUMBER: /[0-9]+/ """ -class AdminTransformer(Transformer): +class RAGFlowCLITransformer(Transformer): def start(self, items): return items[0] @@ -289,6 +305,19 @@ class AdminTransformer(Transformer): user_name = items[2] return {"type": "revoke_admin", "user_name": user_name} + def generate_key(self, items): + user_name = items[4] + return {"type": "generate_key", "user_name": user_name} + + def list_keys(self, items): + user_name = items[3] + return {"type": "list_keys", "user_name": user_name} + + def drop_key(self, items): + key = items[2] + user_name = items[4] + return {"type": "drop_key", "key": key, "user_name": user_name} + def set_variable(self, items): var_name = items[2] var_value = items[3] @@ -307,18 +336,20 @@ class AdminTransformer(Transformer): def list_environments(self, items): return {"type": "list_environments"} - def generate_key(self, items): - user_name = items[4] - return {"type": "generate_key", "user_name": user_name} + def list_user_datasets(self, items): + return {"type": "list_user_datasets"} - def list_keys(self, items): - user_name = items[3] - return {"type": "list_keys", "user_name": user_name} + def list_user_agents(self, items): + return {"type": "list_user_agents"} - def drop_key(self, items): - key = items[2] - user_name = items[4] - return {"type": "drop_key", "key": key, "user_name": user_name} + def list_user_chats(self, items): + return {"type": "list_user_chats"} + + def list_user_model_providers(self, items): + return {"type": "list_user_model_providers"} + + def list_user_default_models(self, items): + return {"type": "list_user_default_models"} def action_list(self, items): return items @@ -397,21 +428,22 @@ Meta Commands: print(help_text) -class AdminCLI(Cmd): +class RAGFlowCLI(Cmd): def __init__(self): super().__init__() - self.parser = Lark(GRAMMAR, start="start", parser="lalr", transformer=AdminTransformer()) + self.parser = Lark(GRAMMAR, start="start", parser="lalr", transformer=RAGFlowCLITransformer()) self.command_history = [] self.is_interactive = False - self.admin_account = "admin@ragflow.io" - self.admin_password: str = "admin" + self.account = "admin@ragflow.io" + self.account_password: str = "admin" self.session = requests.Session() self.access_token: str = "" self.host: str = "" self.port: int = 0 + self.mode: str = "admin" intro = r"""Type "\h" for help.""" - prompt = "admin> " + prompt = "ragflow> " def onecmd(self, command: str) -> bool: try: @@ -454,11 +486,21 @@ class AdminCLI(Cmd): except Exception as e: return {"type": "error", "message": f"Parse error: {str(e)}"} - def verify_admin(self, arguments: dict, single_command: bool): + def verify_auth(self, arguments: dict, single_command: bool): self.host = arguments["host"] self.port = arguments["port"] - print("Attempt to access server for admin login") - url = f"http://{self.host}:{self.port}/api/v1/admin/login" + # Determine mode and username + self.mode = arguments.get("type", "admin") + username = arguments.get("username", "admin@ragflow.io") + self.account = username + + # Set login endpoint based on mode + if self.mode == "admin": + url = f"http://{self.host}:{self.port}/api/v1/admin/login" + print("Attempt to access server for admin login") + else: # user mode + url = f"http://{self.host}:{self.port}/v1/user/login" + print("Attempt to access server for user login") attempt_count = 3 if single_command: @@ -471,17 +513,19 @@ class AdminCLI(Cmd): return False if single_command: - admin_passwd = arguments["password"] + account_passwd = arguments["password"] else: - admin_passwd = getpass.getpass(f"password for {self.admin_account}: ").strip() + account_passwd = getpass.getpass(f"password for {self.account}: ").strip() try: - self.admin_password = encrypt(admin_passwd) - response = self.session.post(url, json={"email": self.admin_account, "password": self.admin_password}) + self.account_password = encrypt(account_passwd) + response = self.session.post(url, json={"email": self.account, "password": self.account_password}) if response.status_code == 200: res_json = response.json() error_code = res_json.get("code", -1) if error_code == 0: - self.session.headers.update({"Content-Type": "application/json", "Authorization": response.headers["Authorization"], "User-Agent": "RAGFlow-CLI/0.23.1"}) + self.session.headers.update( + {"Content-Type": "application/json", "Authorization": response.headers["Authorization"], + "User-Agent": "RAGFlow-CLI/0.23.1"}) print("Authentication successful.") return True else: @@ -492,7 +536,7 @@ class AdminCLI(Cmd): print(f"Bad response,status: {response.status_code}, password is wrong") except Exception as e: print(str(e)) - print("Can't access server for admin login (connection failed)") + print("Can't access server for login (connection failed)") def _format_service_detail_table(self, data): if isinstance(data, list): @@ -568,11 +612,11 @@ class AdminCLI(Cmd): def run_interactive(self): self.is_interactive = True - print("RAGFlow Admin command line interface - Type '\\?' for help, '\\q' to quit") + print("RAGFlow command line interface - Type '\\?' for help, '\\q' to quit") while True: try: - command = input("admin> ").strip() + command = input("ragflow> ").strip() if not command: continue @@ -597,20 +641,42 @@ class AdminCLI(Cmd): self.execute_command(result) def parse_connection_args(self, args: List[str]) -> Dict[str, Any]: - parser = argparse.ArgumentParser(description="Admin CLI Client", add_help=False) - parser.add_argument("-h", "--host", default="localhost", help="Admin service host") - parser.add_argument("-p", "--port", type=int, default=9381, help="Admin service port") + parser = argparse.ArgumentParser(description="RAGFlow CLI Client", add_help=False) + parser.add_argument("-h", "--host", default="localhost", help="Admin or RAGFlow service host") + parser.add_argument("-p", "--port", type=int, default=9381, help="Admin or RAGFlow service port") parser.add_argument("-w", "--password", default="admin", type=str, help="Superuser password") + parser.add_argument("-t", "--type", default="admin", type=str, help="CLI mode, admin or user") + parser.add_argument("-u", "--username", default=None, + help="Username (email). In admin mode defaults to admin@ragflow.io, in user mode required.") parser.add_argument("command", nargs="?", help="Single command") try: parsed_args, remaining_args = parser.parse_known_args(args) + # Determine username based on mode + username = parsed_args.username + if parsed_args.type == "admin": + if username is None: + username = "admin@ragflow.io" + else: # user mode + if username is None: + print("Error: username (-u) is required in user mode") + return {"error": "Username required"} + if remaining_args: command = remaining_args[0] - return {"host": parsed_args.host, "port": parsed_args.port, "password": parsed_args.password, "command": command} + return { + "host": parsed_args.host, + "port": parsed_args.port, + "password": parsed_args.password, + "type": parsed_args.type, + "username": username, + "command": command + } else: return { "host": parsed_args.host, "port": parsed_args.port, + "type": parsed_args.type, + "username": username, } except SystemExit: return {"error": "Invalid connection arguments"} @@ -681,6 +747,12 @@ class AdminCLI(Cmd): self._grant_admin(command_dict) case "revoke_admin": self._revoke_admin(command_dict) + case "generate_key": + self._generate_key(command_dict) + case "list_keys": + self._list_keys(command_dict) + case "drop_key": + self._drop_key(command_dict) case "set_variable": self._set_variable(command_dict) case "show_variable": @@ -691,19 +763,24 @@ class AdminCLI(Cmd): self._list_configs(command_dict) case "list_environments": self._list_environments(command_dict) - case "generate_key": - self._generate_key(command_dict) - case "list_keys": - self._list_keys(command_dict) - case "drop_key": - self._drop_key(command_dict) + case "list_user_datasets": + self._list_user_datasets(command_dict) + case "list_user_agents": + self._list_user_agents(command_dict) + case "list_user_chats": + self._list_user_chats(command_dict) + case "list_user_model_providers": + self._list_user_model_providers(command_dict) + case "list_user_default_models": + self._list_user_default_models(command_dict) case "meta": self._handle_meta_command(command_dict) case _: print(f"Command '{command_type}' would be executed with API") def _handle_list_services(self, command): - print("Listing all services") + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") url = f"http://{self.host}:{self.port}/api/v1/admin/services" response = self.session.get(url) @@ -714,8 +791,10 @@ class AdminCLI(Cmd): print(f"Fail to get all services, code: {res_json['code']}, message: {res_json['message']}") def _handle_show_service(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + service_id: int = command["number"] - print(f"Showing service: {service_id}") url = f"http://{self.host}:{self.port}/api/v1/admin/services/{service_id}" response = self.session.get(url) @@ -735,19 +814,29 @@ class AdminCLI(Cmd): print(f"Fail to show service, code: {res_json['code']}, message: {res_json['message']}") def _handle_restart_service(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + service_id: int = command["number"] print(f"Restart service {service_id}") def _handle_shutdown_service(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + service_id: int = command["number"] print(f"Shutdown service {service_id}") def _handle_startup_service(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + service_id: int = command["number"] print(f"Startup service {service_id}") def _handle_list_users(self, command): - print("Listing all users") + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") url = f"http://{self.host}:{self.port}/api/v1/admin/users" response = self.session.get(url) @@ -758,6 +847,9 @@ class AdminCLI(Cmd): print(f"Fail to get all users, code: {res_json['code']}, message: {res_json['message']}") def _handle_show_user(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + username_tree: Tree = command["user_name"] user_name: str = username_tree.children[0].strip("'\"") print(f"Showing user: {user_name}") @@ -765,13 +857,16 @@ class AdminCLI(Cmd): response = self.session.get(url) res_json = response.json() if response.status_code == 200: - table_data = res_json["data"] + table_data = res_json["data"][0] table_data.pop("avatar") self._print_table_simple(table_data) else: print(f"Fail to get user {user_name}, code: {res_json['code']}, message: {res_json['message']}") def _handle_drop_user(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + username_tree: Tree = command["user_name"] user_name: str = username_tree.children[0].strip("'\"") print(f"Drop user: {user_name}") @@ -784,6 +879,9 @@ class AdminCLI(Cmd): print(f"Fail to drop user, code: {res_json['code']}, message: {res_json['message']}") def _handle_alter_user(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + user_name_tree: Tree = command["user_name"] user_name: str = user_name_tree.children[0].strip("'\"") password_tree: Tree = command["password"] @@ -798,6 +896,9 @@ class AdminCLI(Cmd): print(f"Fail to alter password, code: {res_json['code']}, message: {res_json['message']}") def _handle_create_user(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + user_name_tree: Tree = command["user_name"] user_name: str = user_name_tree.children[0].strip("'\"") password_tree: Tree = command["password"] @@ -813,6 +914,9 @@ class AdminCLI(Cmd): print(f"Fail to create user {user_name}, code: {res_json['code']}, message: {res_json['message']}") def _handle_activate_user(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + user_name_tree: Tree = command["user_name"] user_name: str = user_name_tree.children[0].strip("'\"") activate_tree: Tree = command["activate_status"] @@ -830,6 +934,9 @@ class AdminCLI(Cmd): print(f"Unknown activate status: {activate_status}.") def _grant_admin(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + user_name_tree: Tree = command["user_name"] user_name: str = user_name_tree.children[0].strip("'\"") url = f"http://{self.host}:{self.port}/api/v1/admin/users/{user_name}/admin" @@ -840,9 +947,13 @@ class AdminCLI(Cmd): if response.status_code == 200: print(res_json["message"]) else: - print(f"Fail to grant {user_name} admin authorization, code: {res_json['code']}, message: {res_json['message']}") + print( + f"Fail to grant {user_name} admin authorization, code: {res_json['code']}, message: {res_json['message']}") def _revoke_admin(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + user_name_tree: Tree = command["user_name"] user_name: str = user_name_tree.children[0].strip("'\"") url = f"http://{self.host}:{self.port}/api/v1/admin/users/{user_name}/admin" @@ -853,228 +964,8 @@ class AdminCLI(Cmd): if response.status_code == 200: print(res_json["message"]) else: - print(f"Fail to revoke {user_name} admin authorization, code: {res_json['code']}, message: {res_json['message']}") - - def _set_variable(self, command): - var_name_tree: Tree = command["var_name"] - var_name = var_name_tree.children[0].strip("'\"") - var_value_tree: Tree = command["var_value"] - var_value = var_value_tree.children[0].strip("'\"") - url = f"http://{self.host}:{self.port}/api/v1/admin/variables" - response = self.session.put(url, json={"var_name": var_name, "var_value": var_value}) - res_json = response.json() - if response.status_code == 200: - print(res_json["message"]) - else: - print(f"Fail to set variable {var_name} to {var_value}, code: {res_json['code']}, message: {res_json['message']}") - - def _show_variable(self, command): - var_name_tree: Tree = command["var_name"] - var_name = var_name_tree.children[0].strip("'\"") - url = f"http://{self.host}:{self.port}/api/v1/admin/variables" - response = self.session.get(url, json={"var_name": var_name}) - res_json = response.json() - if response.status_code == 200: - self._print_table_simple(res_json["data"]) - else: - print(f"Fail to get variable {var_name}, code: {res_json['code']}, message: {res_json['message']}") - - def _list_variables(self, command): - url = f"http://{self.host}:{self.port}/api/v1/admin/variables" - response = self.session.get(url) - res_json = response.json() - if response.status_code == 200: - self._print_table_simple(res_json["data"]) - else: - print(f"Fail to list variables, code: {res_json['code']}, message: {res_json['message']}") - - def _list_configs(self, command): - url = f"http://{self.host}:{self.port}/api/v1/admin/configs" - response = self.session.get(url) - res_json = response.json() - if response.status_code == 200: - self._print_table_simple(res_json["data"]) - else: - print(f"Fail to list variables, code: {res_json['code']}, message: {res_json['message']}") - - def _list_environments(self, command): - url = f"http://{self.host}:{self.port}/api/v1/admin/environments" - response = self.session.get(url) - res_json = response.json() - if response.status_code == 200: - self._print_table_simple(res_json["data"]) - else: - print(f"Fail to list variables, code: {res_json['code']}, message: {res_json['message']}") - - def _handle_list_datasets(self, command): - username_tree: Tree = command["user_name"] - user_name: str = username_tree.children[0].strip("'\"") - print(f"Listing all datasets of user: {user_name}") - url = f"http://{self.host}:{self.port}/api/v1/admin/users/{user_name}/datasets" - response = self.session.get(url) - res_json = response.json() - if response.status_code == 200: - table_data = res_json["data"] - for t in table_data: - t.pop("avatar") - self._print_table_simple(table_data) - else: - print(f"Fail to get all datasets of {user_name}, code: {res_json['code']}, message: {res_json['message']}") - - def _handle_list_agents(self, command): - username_tree: Tree = command["user_name"] - user_name: str = username_tree.children[0].strip("'\"") - print(f"Listing all agents of user: {user_name}") - url = f"http://{self.host}:{self.port}/api/v1/admin/users/{user_name}/agents" - response = self.session.get(url) - res_json = response.json() - if response.status_code == 200: - table_data = res_json["data"] - for t in table_data: - t.pop("avatar") - self._print_table_simple(table_data) - else: - print(f"Fail to get all agents of {user_name}, code: {res_json['code']}, message: {res_json['message']}") - - def _create_role(self, command): - role_name_tree: Tree = command["role_name"] - role_name: str = role_name_tree.children[0].strip("'\"") - desc_str: str = "" - if "description" in command: - desc_tree: Tree = command["description"] - desc_str = desc_tree.children[0].strip("'\"") - - print(f"create role name: {role_name}, description: {desc_str}") - url = f"http://{self.host}:{self.port}/api/v1/admin/roles" - response = self.session.post(url, json={"role_name": role_name, "description": desc_str}) - res_json = response.json() - if response.status_code == 200: - self._print_table_simple(res_json["data"]) - else: - print(f"Fail to create role {role_name}, code: {res_json['code']}, message: {res_json['message']}") - - def _drop_role(self, command): - role_name_tree: Tree = command["role_name"] - role_name: str = role_name_tree.children[0].strip("'\"") - print(f"drop role name: {role_name}") - url = f"http://{self.host}:{self.port}/api/v1/admin/roles/{role_name}" - response = self.session.delete(url) - res_json = response.json() - if response.status_code == 200: - self._print_table_simple(res_json["data"]) - else: - print(f"Fail to drop role {role_name}, code: {res_json['code']}, message: {res_json['message']}") - - def _alter_role(self, command): - role_name_tree: Tree = command["role_name"] - role_name: str = role_name_tree.children[0].strip("'\"") - desc_tree: Tree = command["description"] - desc_str: str = desc_tree.children[0].strip("'\"") - - print(f"alter role name: {role_name}, description: {desc_str}") - url = f"http://{self.host}:{self.port}/api/v1/admin/roles/{role_name}" - response = self.session.put(url, json={"description": desc_str}) - res_json = response.json() - if response.status_code == 200: - self._print_table_simple(res_json["data"]) - else: - print(f"Fail to update role {role_name} with description: {desc_str}, code: {res_json['code']}, message: {res_json['message']}") - - def _list_roles(self, command): - print("Listing all roles") - url = f"http://{self.host}:{self.port}/api/v1/admin/roles" - response = self.session.get(url) - res_json = response.json() - if response.status_code == 200: - self._print_table_simple(res_json["data"]) - else: - print(f"Fail to list roles, code: {res_json['code']}, message: {res_json['message']}") - - def _show_role(self, command): - role_name_tree: Tree = command["role_name"] - role_name: str = role_name_tree.children[0].strip("'\"") - print(f"show role: {role_name}") - url = f"http://{self.host}:{self.port}/api/v1/admin/roles/{role_name}/permission" - response = self.session.get(url) - res_json = response.json() - if response.status_code == 200: - self._print_table_simple(res_json["data"]) - else: - print(f"Fail to list roles, code: {res_json['code']}, message: {res_json['message']}") - - def _grant_permission(self, command): - role_name_tree: Tree = command["role_name"] - role_name_str: str = role_name_tree.children[0].strip("'\"") - resource_tree: Tree = command["resource"] - resource_str: str = resource_tree.children[0].strip("'\"") - action_tree_list: list = command["actions"] - actions: list = [] - for action_tree in action_tree_list: - action_str: str = action_tree.children[0].strip("'\"") - actions.append(action_str) - print(f"grant role_name: {role_name_str}, resource: {resource_str}, actions: {actions}") - url = f"http://{self.host}:{self.port}/api/v1/admin/roles/{role_name_str}/permission" - response = self.session.post(url, json={"actions": actions, "resource": resource_str}) - res_json = response.json() - if response.status_code == 200: - self._print_table_simple(res_json["data"]) - else: - print(f"Fail to grant role {role_name_str} with {actions} on {resource_str}, code: {res_json['code']}, message: {res_json['message']}") - - def _revoke_permission(self, command): - role_name_tree: Tree = command["role_name"] - role_name_str: str = role_name_tree.children[0].strip("'\"") - resource_tree: Tree = command["resource"] - resource_str: str = resource_tree.children[0].strip("'\"") - action_tree_list: list = command["actions"] - actions: list = [] - for action_tree in action_tree_list: - action_str: str = action_tree.children[0].strip("'\"") - actions.append(action_str) - print(f"revoke role_name: {role_name_str}, resource: {resource_str}, actions: {actions}") - url = f"http://{self.host}:{self.port}/api/v1/admin/roles/{role_name_str}/permission" - response = self.session.delete(url, json={"actions": actions, "resource": resource_str}) - res_json = response.json() - if response.status_code == 200: - self._print_table_simple(res_json["data"]) - else: - print(f"Fail to revoke role {role_name_str} with {actions} on {resource_str}, code: {res_json['code']}, message: {res_json['message']}") - - def _alter_user_role(self, command): - role_name_tree: Tree = command["role_name"] - role_name_str: str = role_name_tree.children[0].strip("'\"") - user_name_tree: Tree = command["user_name"] - user_name_str: str = user_name_tree.children[0].strip("'\"") - print(f"alter_user_role user_name: {user_name_str}, role_name: {role_name_str}") - url = f"http://{self.host}:{self.port}/api/v1/admin/users/{user_name_str}/role" - response = self.session.put(url, json={"role_name": role_name_str}) - res_json = response.json() - if response.status_code == 200: - self._print_table_simple(res_json["data"]) - else: - print(f"Fail to alter user: {user_name_str} to role {role_name_str}, code: {res_json['code']}, message: {res_json['message']}") - - def _show_user_permission(self, command): - user_name_tree: Tree = command["user_name"] - user_name_str: str = user_name_tree.children[0].strip("'\"") - print(f"show_user_permission user_name: {user_name_str}") - url = f"http://{self.host}:{self.port}/api/v1/admin/users/{user_name_str}/permission" - response = self.session.get(url) - res_json = response.json() - if response.status_code == 200: - self._print_table_simple(res_json["data"]) - else: - print(f"Fail to show user: {user_name_str} permission, code: {res_json['code']}, message: {res_json['message']}") - - def _show_version(self, command): - print("show_version") - url = f"http://{self.host}:{self.port}/api/v1/admin/version" - response = self.session.get(url) - res_json = response.json() - if response.status_code == 200: - self._print_table_simple(res_json["data"]) - else: - print(f"Fail to show version, code: {res_json['code']}, message: {res_json['message']}") + print( + f"Fail to revoke {user_name} admin authorization, code: {res_json['code']}, message: {res_json['message']}") def _generate_key(self, command: dict[str, Any]) -> None: username_tree: Tree = command["user_name"] @@ -1086,7 +977,8 @@ class AdminCLI(Cmd): if response.status_code == 200: self._print_table_simple(res_json["data"]) else: - print(f"Failed to generate key for user {user_name}, code: {res_json['code']}, message: {res_json['message']}") + print( + f"Failed to generate key for user {user_name}, code: {res_json['code']}, message: {res_json['message']}") def _list_keys(self, command: dict[str, Any]) -> None: username_tree: Tree = command["user_name"] @@ -1116,6 +1008,361 @@ class AdminCLI(Cmd): else: print(f"Failed to drop key for user {user_name}, code: {res_json['code']}, message: {res_json['message']}") + def _set_variable(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + + var_name_tree: Tree = command["var_name"] + var_name = var_name_tree.children[0].strip("'\"") + var_value_tree: Tree = command["var_value"] + var_value = var_value_tree.children[0].strip("'\"") + url = f"http://{self.host}:{self.port}/api/v1/admin/variables" + response = self.session.put(url, json={"var_name": var_name, "var_value": var_value}) + res_json = response.json() + if response.status_code == 200: + print(res_json["message"]) + else: + print( + f"Fail to set variable {var_name} to {var_value}, code: {res_json['code']}, message: {res_json['message']}") + + def _show_variable(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + + var_name_tree: Tree = command["var_name"] + var_name = var_name_tree.children[0].strip("'\"") + url = f"http://{self.host}:{self.port}/api/v1/admin/variables" + response = self.session.get(url, json={"var_name": var_name}) + res_json = response.json() + if response.status_code == 200: + self._print_table_simple(res_json["data"]) + else: + print(f"Fail to get variable {var_name}, code: {res_json['code']}, message: {res_json['message']}") + + def _list_variables(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + + url = f"http://{self.host}:{self.port}/api/v1/admin/variables" + response = self.session.get(url) + res_json = response.json() + if response.status_code == 200: + self._print_table_simple(res_json["data"]) + else: + print(f"Fail to list variables, code: {res_json['code']}, message: {res_json['message']}") + + def _list_configs(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + + url = f"http://{self.host}:{self.port}/api/v1/admin/configs" + response = self.session.get(url) + res_json = response.json() + if response.status_code == 200: + self._print_table_simple(res_json["data"]) + else: + print(f"Fail to list variables, code: {res_json['code']}, message: {res_json['message']}") + + def _list_environments(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + + url = f"http://{self.host}:{self.port}/api/v1/admin/environments" + response = self.session.get(url) + res_json = response.json() + if response.status_code == 200: + self._print_table_simple(res_json["data"]) + else: + print(f"Fail to list variables, code: {res_json['code']}, message: {res_json['message']}") + + def _handle_list_datasets(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + + username_tree: Tree = command["user_name"] + user_name: str = username_tree.children[0].strip("'\"") + print(f"Listing all datasets of user: {user_name}") + url = f"http://{self.host}:{self.port}/api/v1/admin/users/{user_name}/datasets" + response = self.session.get(url) + res_json = response.json() + if response.status_code == 200: + table_data = res_json["data"] + for t in table_data: + t.pop("avatar") + self._print_table_simple(table_data) + else: + print(f"Fail to get all datasets of {user_name}, code: {res_json['code']}, message: {res_json['message']}") + + def _handle_list_agents(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + + username_tree: Tree = command["user_name"] + user_name: str = username_tree.children[0].strip("'\"") + print(f"Listing all agents of user: {user_name}") + url = f"http://{self.host}:{self.port}/api/v1/admin/users/{user_name}/agents" + response = self.session.get(url) + res_json = response.json() + if response.status_code == 200: + table_data = res_json["data"] + for t in table_data: + t.pop("avatar") + self._print_table_simple(table_data) + else: + print(f"Fail to get all agents of {user_name}, code: {res_json['code']}, message: {res_json['message']}") + + def _create_role(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + + role_name_tree: Tree = command["role_name"] + role_name: str = role_name_tree.children[0].strip("'\"") + desc_str: str = "" + if "description" in command: + desc_tree: Tree = command["description"] + desc_str = desc_tree.children[0].strip("'\"") + + print(f"create role name: {role_name}, description: {desc_str}") + url = f"http://{self.host}:{self.port}/api/v1/admin/roles" + response = self.session.post(url, json={"role_name": role_name, "description": desc_str}) + res_json = response.json() + if response.status_code == 200: + self._print_table_simple(res_json["data"]) + else: + print(f"Fail to create role {role_name}, code: {res_json['code']}, message: {res_json['message']}") + + def _drop_role(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + + role_name_tree: Tree = command["role_name"] + role_name: str = role_name_tree.children[0].strip("'\"") + print(f"drop role name: {role_name}") + url = f"http://{self.host}:{self.port}/api/v1/admin/roles/{role_name}" + response = self.session.delete(url) + res_json = response.json() + if response.status_code == 200: + self._print_table_simple(res_json["data"]) + else: + print(f"Fail to drop role {role_name}, code: {res_json['code']}, message: {res_json['message']}") + + def _alter_role(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + + role_name_tree: Tree = command["role_name"] + role_name: str = role_name_tree.children[0].strip("'\"") + desc_tree: Tree = command["description"] + desc_str: str = desc_tree.children[0].strip("'\"") + + print(f"alter role name: {role_name}, description: {desc_str}") + url = f"http://{self.host}:{self.port}/api/v1/admin/roles/{role_name}" + response = self.session.put(url, json={"description": desc_str}) + res_json = response.json() + if response.status_code == 200: + self._print_table_simple(res_json["data"]) + else: + print( + f"Fail to update role {role_name} with description: {desc_str}, code: {res_json['code']}, message: {res_json['message']}") + + def _list_roles(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + + url = f"http://{self.host}:{self.port}/api/v1/admin/roles" + response = self.session.get(url) + res_json = response.json() + if response.status_code == 200: + self._print_table_simple(res_json["data"]) + else: + print(f"Fail to list roles, code: {res_json['code']}, message: {res_json['message']}") + + def _show_role(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + + role_name_tree: Tree = command["role_name"] + role_name: str = role_name_tree.children[0].strip("'\"") + print(f"show role: {role_name}") + url = f"http://{self.host}:{self.port}/api/v1/admin/roles/{role_name}/permission" + response = self.session.get(url) + res_json = response.json() + if response.status_code == 200: + self._print_table_simple(res_json["data"]) + else: + print(f"Fail to list roles, code: {res_json['code']}, message: {res_json['message']}") + + def _grant_permission(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + + role_name_tree: Tree = command["role_name"] + role_name_str: str = role_name_tree.children[0].strip("'\"") + resource_tree: Tree = command["resource"] + resource_str: str = resource_tree.children[0].strip("'\"") + action_tree_list: list = command["actions"] + actions: list = [] + for action_tree in action_tree_list: + action_str: str = action_tree.children[0].strip("'\"") + actions.append(action_str) + print(f"grant role_name: {role_name_str}, resource: {resource_str}, actions: {actions}") + url = f"http://{self.host}:{self.port}/api/v1/admin/roles/{role_name_str}/permission" + response = self.session.post(url, json={"actions": actions, "resource": resource_str}) + res_json = response.json() + if response.status_code == 200: + self._print_table_simple(res_json["data"]) + else: + print( + f"Fail to grant role {role_name_str} with {actions} on {resource_str}, code: {res_json['code']}, message: {res_json['message']}") + + def _revoke_permission(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + + role_name_tree: Tree = command["role_name"] + role_name_str: str = role_name_tree.children[0].strip("'\"") + resource_tree: Tree = command["resource"] + resource_str: str = resource_tree.children[0].strip("'\"") + action_tree_list: list = command["actions"] + actions: list = [] + for action_tree in action_tree_list: + action_str: str = action_tree.children[0].strip("'\"") + actions.append(action_str) + print(f"revoke role_name: {role_name_str}, resource: {resource_str}, actions: {actions}") + url = f"http://{self.host}:{self.port}/api/v1/admin/roles/{role_name_str}/permission" + response = self.session.delete(url, json={"actions": actions, "resource": resource_str}) + res_json = response.json() + if response.status_code == 200: + self._print_table_simple(res_json["data"]) + else: + print( + f"Fail to revoke role {role_name_str} with {actions} on {resource_str}, code: {res_json['code']}, message: {res_json['message']}") + + def _alter_user_role(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + + role_name_tree: Tree = command["role_name"] + role_name_str: str = role_name_tree.children[0].strip("'\"") + user_name_tree: Tree = command["user_name"] + user_name_str: str = user_name_tree.children[0].strip("'\"") + print(f"alter_user_role user_name: {user_name_str}, role_name: {role_name_str}") + url = f"http://{self.host}:{self.port}/api/v1/admin/users/{user_name_str}/role" + response = self.session.put(url, json={"role_name": role_name_str}) + res_json = response.json() + if response.status_code == 200: + self._print_table_simple(res_json["data"]) + else: + print( + f"Fail to alter user: {user_name_str} to role {role_name_str}, code: {res_json['code']}, message: {res_json['message']}") + + def _show_user_permission(self, command): + if self.mode != "admin": + print("This command is only allowed in ADMIN mode") + + user_name_tree: Tree = command["user_name"] + user_name_str: str = user_name_tree.children[0].strip("'\"") + print(f"show_user_permission user_name: {user_name_str}") + url = f"http://{self.host}:{self.port}/api/v1/admin/users/{user_name_str}/permission" + response = self.session.get(url) + res_json = response.json() + if response.status_code == 200: + self._print_table_simple(res_json["data"]) + else: + print( + f"Fail to show user: {user_name_str} permission, code: {res_json['code']}, message: {res_json['message']}") + + def _show_version(self, command): + if self.mode == "admin": + url = f"http://{self.host}:{self.port}/api/v1/admin/version" + else: + url = f"http://{self.host}:{self.port}/v1/system/version" + + response = self.session.get(url) + res_json = response.json() + if response.status_code == 200: + if self.mode == "admin": + self._print_table_simple(res_json["data"]) + else: + self._print_table_simple({"version": res_json["data"]}) + else: + print(f"Fail to show version, code: {res_json['code']}, message: {res_json['message']}") + + def _list_user_datasets(self, command): + if self.mode != "user": + print("This command is only allowed in USER mode") + + url = f"http://{self.host}:{self.port}/v1/kb/list" + response = self.session.post(url) + res_json = response.json() + if response.status_code == 200: + self._print_table_simple(res_json["data"]) + else: + print(f"Fail to list datasets, code: {res_json['code']}, message: {res_json['message']}") + + def _list_user_agents(self, command): + if self.mode != "user": + print("This command is only allowed in USER mode") + + url = f"http://{self.host}:{self.port}/v1/canvas/list" + response = self.session.get(url) + res_json = response.json() + if response.status_code == 200: + self._print_table_simple(res_json["data"]) + else: + print(f"Fail to list datasets, code: {res_json['code']}, message: {res_json['message']}") + + def _list_user_chats(self, command): + if self.mode != "user": + print("This command is only allowed in USER mode") + + url = f"http://{self.host}:{self.port}/v1/dialog/next" + response = self.session.get(url) + res_json = response.json() + if response.status_code == 200: + self._print_table_simple(res_json["data"]) + else: + print(f"Fail to list datasets, code: {res_json['code']}, message: {res_json['message']}") + + def _list_user_model_providers(self, command): + if self.mode != "user": + print("This command is only allowed in USER mode") + + url = f"http://{self.host}:{self.port}/v1/llm/my_llms" + response = self.session.get(url) + res_json = response.json() + if response.status_code == 200: + new_input = [] + for key, value in res_json["data"].items(): + new_input.append({"model provider": key, "models": value}) + self._print_table_simple(new_input) + + def _list_user_default_models(self, command): + if self.mode != "user": + print("This command is only allowed in USER mode") + + url = f"http://{self.host}:{self.port}/v1/user/tenant_info" + response = self.session.get(url) + res_json = response.json() + if response.status_code == 200: + new_input = [] + for key, value in res_json["data"].items(): + if key == "asr_id" and value != "": + new_input.append({"model_category": "ASR", "model_name": value}) + elif key == "embd_id" and value != "": + new_input.append({"model_category": "Embedding", "model_name": value}) + elif key == "llm_id" and value != "": + new_input.append({"model_category": "LLM", "model_name": value}) + elif key == "rerank_id" and value != "": + new_input.append({"model_category": "Reranker", "model_name": value}) + elif key == "tts_id" and value != "": + new_input.append({"model_category": "TTS", "model_name": value}) + elif key == "img2txt_id" and value != "": + new_input.append({"model_category": "VLM", "model_name": value}) + else: + continue + self._print_table_simple(new_input) + def _handle_meta_command(self, command): meta_command = command["command"] args = command.get("args", []) @@ -1131,7 +1378,7 @@ class AdminCLI(Cmd): def main(): import sys - cli = AdminCLI() + cli = RAGFlowCLI() args = cli.parse_connection_args(sys.argv) if "error" in args: @@ -1142,18 +1389,18 @@ def main(): if "password" not in args: print("Error: password is missing") return - if cli.verify_admin(args, single_command=True): + if cli.verify_auth(args, single_command=True): command: str = args["command"] # print(f"Run single command: {command}") cli.run_single_command(command) else: - if cli.verify_admin(args, single_command=False): + if cli.verify_auth(args, single_command=False): print(r""" - ____ ___ ______________ ___ __ _ - / __ \/ | / ____/ ____/ /___ _ __ / | ____/ /___ ___ (_)___ - / /_/ / /| |/ / __/ /_ / / __ \ | /| / / / /| |/ __ / __ `__ \/ / __ \ - / _, _/ ___ / /_/ / __/ / / /_/ / |/ |/ / / ___ / /_/ / / / / / / / / / / - /_/ |_/_/ |_\____/_/ /_/\____/|__/|__/ /_/ |_\__,_/_/ /_/ /_/_/_/ /_/ + ____ ___ ______________ ________ ____ + / __ \/ | / ____/ ____/ /___ _ __ / ____/ / / _/ + / /_/ / /| |/ / __/ /_ / / __ \ | /| / / / / / / / / + / _, _/ ___ / /_/ / __/ / / /_/ / |/ |/ / / /___/ /____/ / + /_/ |_/_/ |_\____/_/ /_/\____/|__/|__/ \____/_____/___/ """) cli.cmdloop() diff --git a/api/utils/crypt.py b/api/utils/crypt.py index 174ca3568..d81cf7c6a 100644 --- a/api/utils/crypt.py +++ b/api/utils/crypt.py @@ -24,7 +24,7 @@ from common.file_utils import get_project_base_directory def crypt(line): """ - decrypt(crypt(input_string)) == base64(input_string), which frontend and admin_client use. + decrypt(crypt(input_string)) == base64(input_string), which frontend and ragflow_cli use. """ file_path = os.path.join(get_project_base_directory(), "conf", "public.pem") rsa_key = RSA.importKey(open(file_path).read(), "Welcome") diff --git a/docs/guides/admin/admin_cli.md b/docs/guides/admin/ragflow_cli.md similarity index 94% rename from docs/guides/admin/admin_cli.md rename to docs/guides/admin/ragflow_cli.md index fed8a6264..73db779a9 100644 --- a/docs/guides/admin/admin_cli.md +++ b/docs/guides/admin/ragflow_cli.md @@ -5,11 +5,11 @@ sidebar_custom_props: { categoryIcon: LucideSquareTerminal } --- -# Admin CLI +# RAGFlow CLI -The RAGFlow Admin CLI is a command-line-based system administration tool that offers administrators an efficient and flexible method for system interaction and control. Operating on a client-server architecture, it communicates in real-time with the Admin Service, receiving administrator commands and dynamically returning execution results. +The RAGFlow CLI is a command-line-based system administration tool that offers administrators an efficient and flexible method for system interaction and control. Operating on a client-server architecture, it communicates in real-time with the Admin Service, receiving administrator commands and dynamically returning execution results. -## Using the Admin CLI +## Using the RAGFlow CLI 1. Ensure the Admin Service is running. @@ -169,7 +169,7 @@ Commands are case-insensitive and must be terminated with a semicolon(;). - List all available services. ``` -admin> list services; +ragflow> list services; command: list services; Listing all services +-------------------------------------------------------------------------------------------+-----------+----+---------------+-------+----------------+---------+ @@ -190,7 +190,7 @@ Listing all services - Show ragflow_server. ``` -admin> show service 0; +ragflow> show service 0; command: show service 0; Showing service: 0 Service ragflow_0 is alive. Detail: @@ -200,7 +200,7 @@ Confirm elapsed: 26.0 ms. - Show mysql. ``` -admin> show service 1; +ragflow> show service 1; command: show service 1; Showing service: 1 Service mysql is alive. Detail: @@ -216,7 +216,7 @@ Service mysql is alive. Detail: - Show minio. ``` -admin> show service 2; +ragflow> show service 2; command: show service 2; Showing service: 2 Service minio is alive. Detail: @@ -226,7 +226,7 @@ Confirm elapsed: 2.1 ms. - Show elasticsearch. ``` -admin> show service 3; +ragflow> show service 3; command: show service 3; Showing service: 3 Service elasticsearch is alive. Detail: @@ -240,7 +240,7 @@ Service elasticsearch is alive. Detail: - Show infinity. ``` -admin> show service 4; +ragflow> show service 4; command: show service 4; Showing service: 4 Fail to show service, code: 500, message: Infinity is not in use. @@ -249,7 +249,7 @@ Fail to show service, code: 500, message: Infinity is not in use. - Show redis. ``` -admin> show service 5; +ragflow> show service 5; command: show service 5; Showing service: 5 Service redis is alive. Detail: @@ -264,7 +264,7 @@ Service redis is alive. Detail: - Show RAGFlow version ``` -admin> show version; +ragflow> show version; +-----------------------+ | version | +-----------------------+ @@ -277,7 +277,7 @@ admin> show version; - List all user. ``` -admin> list users; +ragflow> list users; command: list users; Listing all users +-------------------------------+----------------------+-----------+----------+ @@ -293,7 +293,7 @@ Listing all users - Show specified user. ``` -admin> show user "admin@ragflow.io"; +ragflow> show user "admin@ragflow.io"; command: show user "admin@ragflow.io"; Showing user: admin@ragflow.io +-------------------------------+------------------+-----------+--------------+------------------+--------------+----------+-----------------+---------------+--------+-------------------------------+ @@ -308,7 +308,7 @@ Showing user: admin@ragflow.io - Create new user. ``` -admin> create user "example@ragflow.io" "psw"; +ragflow> create user "example@ragflow.io" "psw"; command: create user "example@ragflow.io" "psw"; Create user: example@ragflow.io, password: psw, role: user +----------------------------------+--------------------+----------------------------------+--------------+---------------+----------+ @@ -323,7 +323,7 @@ Create user: example@ragflow.io, password: psw, role: user - Alter user password. ``` -admin> alter user password "example@ragflow.io" "newpsw"; +ragflow> alter user password "example@ragflow.io" "newpsw"; command: alter user password "example@ragflow.io" "newpsw"; Alter user: example@ragflow.io, password: newpsw Password updated successfully! @@ -334,7 +334,7 @@ Password updated successfully! - Alter user active, turn off. ``` -admin> alter user active "example@ragflow.io" off; +ragflow> alter user active "example@ragflow.io" off; command: alter user active "example@ragflow.io" off; Alter user example@ragflow.io activate status, turn off. Turn off user activate status successfully! @@ -345,7 +345,7 @@ Turn off user activate status successfully! - Drop user. ``` -admin> Drop user "example@ragflow.io"; +ragflow> Drop user "example@ragflow.io"; command: Drop user "example@ragflow.io"; Drop user: example@ragflow.io Successfully deleted user. Details: @@ -403,7 +403,7 @@ API key deleted successfully - List the specified user's dataset. ``` -admin> list datasets of "lynn_inf@hotmail.com"; +ragflow> list datasets of "lynn_inf@hotmail.com"; command: list datasets of "lynn_inf@hotmail.com"; Listing all datasets of user: lynn_inf@hotmail.com +-----------+-------------------------------+---------+----------+---------------+------------+--------+-----------+-------------------------------+ @@ -419,7 +419,7 @@ Listing all datasets of user: lynn_inf@hotmail.com - List the specified user's agents. ``` -admin> list agents of "lynn_inf@hotmail.com"; +ragflow> list agents of "lynn_inf@hotmail.com"; command: list agents of "lynn_inf@hotmail.com"; Listing all agents of user: lynn_inf@hotmail.com +-----------------+-------------+------------+-----------------+ @@ -434,7 +434,7 @@ Listing all agents of user: lynn_inf@hotmail.com - Display the current RAGFlow version. ``` -admin> show version; +ragflow> show version; show_version +-----------------------+ | version | @@ -448,7 +448,7 @@ show_version - Grant administrator privileges to the specified user. ``` -admin> grant admin "anakin.skywalker@ragflow.io"; +ragflow> grant admin "anakin.skywalker@ragflow.io"; Grant successfully! ``` @@ -457,7 +457,7 @@ Grant successfully! - Revoke administrator privileges from the specified user. ``` -admin> revoke admin "anakin.skywalker@ragflow.io"; +ragflow> revoke admin "anakin.skywalker@ragflow.io"; Revoke successfully! ``` @@ -466,7 +466,7 @@ Revoke successfully! - List all system settings. ``` -admin> list vars; +ragflow> list vars; +-----------+---------------------+--------------+-----------+ | data_type | name | source | value | +-----------+---------------------+--------------+-----------+ @@ -488,7 +488,7 @@ admin> list vars; - Display the content of a specific system configuration/setting by its name or name prefix. ``` -admin> show var mail.server; +ragflow> show var mail.server; +-----------+-------------+--------------+-----------+ | data_type | name | source | value | +-----------+-------------+--------------+-----------+ @@ -501,7 +501,7 @@ admin> show var mail.server; - Set the value for a specified configuration item. ``` -admin> set var mail.server 127.0.0.1; +ragflow> set var mail.server 127.0.0.1; Set variable successfully ``` @@ -511,7 +511,7 @@ Set variable successfully - List all system configurations. ``` -admin> list configs; +ragflow> list configs; +-------------------------------------------------------------------------------------------+-----------+----+---------------+-------+----------------+ | extra | host | id | name | port | service_type | +-------------------------------------------------------------------------------------------+-----------+----+---------------+-------+----------------+ @@ -530,7 +530,7 @@ admin> list configs; - List all system environments which can accessed by Admin service. ``` -admin> list envs; +ragflow> list envs; +-------------------------+------------------+ | env | value | +-------------------------+------------------+ @@ -548,7 +548,7 @@ admin> list envs; - Show help information. ``` -admin> \help +ragflow> \help command: \help Commands: @@ -589,7 +589,7 @@ Meta Commands: - Exit ``` -admin> \q +ragflow> \q command: \q Goodbye! ``` diff --git a/web/src/pages/agent/hooks/use-add-node.ts b/web/src/pages/agent/hooks/use-add-node.ts index d5cceef63..257307cf4 100644 --- a/web/src/pages/agent/hooks/use-add-node.ts +++ b/web/src/pages/agent/hooks/use-add-node.ts @@ -32,6 +32,7 @@ import { initialLoopValues, initialMessageValues, initialNoteValues, + initialPDFGeneratorValues, initialParserValues, initialPubMedValues, initialRetrievalValues, @@ -48,7 +49,6 @@ import { initialVariableAssignerValues, initialWaitingDialogueValues, initialWenCaiValues, - initialPDFGeneratorValues, initialWikipediaValues, initialYahooFinanceValues, } from '../constant';