From a4bc2186fd3b1f2fc724a3713d7f4af6e855f3c4 Mon Sep 17 00:00:00 2001 From: wenhao Date: Thu, 22 Feb 2024 14:51:03 +0800 Subject: [PATCH 01/14] fix minor example bug --- docs/sphinx_doc/source/tutorial/103-example.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sphinx_doc/source/tutorial/103-example.md b/docs/sphinx_doc/source/tutorial/103-example.md index 068b42ab7..08ead7cf5 100644 --- a/docs/sphinx_doc/source/tutorial/103-example.md +++ b/docs/sphinx_doc/source/tutorial/103-example.md @@ -52,7 +52,7 @@ from agentscope.agents import DialogAgent, UserAgent agentscope.init(model_configs="./openai_model_configs.json") # Create a dialog agent and a user agent -dialogAgent = DialogAgent(name="assistant", model_config_name="gpt-4") +dialogAgent = DialogAgent(name="assistant", model_config_name="gpt-4", sys_prompt="You are a helpful ai assistant") userAgent = UserAgent() ``` From b9f381d23a13e981fd0873b6adc4871a58ebd01e Mon Sep 17 00:00:00 2001 From: wenhao Date: Thu, 22 Feb 2024 16:52:19 +0800 Subject: [PATCH 02/14] fix single typo --- docs/sphinx_doc/source/tutorial/201-agent.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sphinx_doc/source/tutorial/201-agent.md b/docs/sphinx_doc/source/tutorial/201-agent.md index f4d513e53..76b6400b6 100644 --- a/docs/sphinx_doc/source/tutorial/201-agent.md +++ b/docs/sphinx_doc/source/tutorial/201-agent.md @@ -2,7 +2,7 @@ # Customizing Your Own Agent -This tutorial helps you to understand the `Agent` in mode depth and navigate through the process of crafting your own custom agent with AgentScope. We start by introducing the fundamental abstraction called `AgentBase`, which serves as the base class to maintain the general behaviors of all agents. Then, we will go through the *AgentPool*, an ensemble of pre-built, specialized agents, each designed with a specific purpose in mind. Finally, we will demonstrate how to customize your own agent, ensuring it fits the needs of your project. +This tutorial helps you to understand the `Agent` in more depth and navigate through the process of crafting your own custom agent with AgentScope. We start by introducing the fundamental abstraction called `AgentBase`, which serves as the base class to maintain the general behaviors of all agents. Then, we will go through the *AgentPool*, an ensemble of pre-built, specialized agents, each designed with a specific purpose in mind. Finally, we will demonstrate how to customize your own agent, ensuring it fits the needs of your project. ## Understanding `AgentBase` From e88ffad9155fa5e14ef7406cebd33ed980080709 Mon Sep 17 00:00:00 2001 From: wenhao Date: Thu, 22 Feb 2024 17:31:18 +0800 Subject: [PATCH 03/14] fix single typo in 105-logging.md --- docs/sphinx_doc/source/tutorial/105-logging.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/sphinx_doc/source/tutorial/105-logging.md b/docs/sphinx_doc/source/tutorial/105-logging.md index dd6cbbc56..913fc92cc 100644 --- a/docs/sphinx_doc/source/tutorial/105-logging.md +++ b/docs/sphinx_doc/source/tutorial/105-logging.md @@ -79,8 +79,7 @@ agentscope.web.init( ) ``` -By this way, you can see all the running instances and projects in `http://127. -0.0.1:5000` as follows: +By this way, you can see all the running instances and projects in `http://127.0.0.1:5000` as follows: ![webui](https://img.alicdn.com/imgextra/i3/O1CN01kpHFkn1HpeYEkn60I_!!6000000000807-0-tps-3104-1849.jpg) From 4e5c79db6bbafe0ca299ab493ca6ed27f75b1058 Mon Sep 17 00:00:00 2001 From: garyzhang99 Date: Fri, 12 Apr 2024 15:38:00 +0800 Subject: [PATCH 04/14] adding more service functions --- src/agentscope/service/__init__.py | 6 ++ .../service/execute_code/exec_shell.py | 57 ++++++++++++++++++ src/agentscope/service/file/common.py | 59 +++++++++++++++++++ 3 files changed, 122 insertions(+) create mode 100644 src/agentscope/service/execute_code/exec_shell.py diff --git a/src/agentscope/service/__init__.py b/src/agentscope/service/__init__.py index 50e9e89a6..d9eb55bb1 100644 --- a/src/agentscope/service/__init__.py +++ b/src/agentscope/service/__init__.py @@ -3,6 +3,7 @@ from loguru import logger from .execute_code.exec_python import execute_python_code +from .execute_code.exec_shell import execute_shell_command from .file.common import ( create_file, delete_file, @@ -10,6 +11,8 @@ create_directory, delete_directory, move_directory, + show_directory, + get_current_directory, ) from .file.text import read_text_file, write_text_file from .file.json import read_json_file, write_json_file @@ -35,12 +38,15 @@ def get_help() -> None: __all__ = [ "execute_python_code", + "execute_shell_command", "create_file", "delete_file", "move_file", "create_directory", "delete_directory", "move_directory", + "show_directory", + "get_current_directory", "read_text_file", "write_text_file", "read_json_file", diff --git a/src/agentscope/service/execute_code/exec_shell.py b/src/agentscope/service/execute_code/exec_shell.py new file mode 100644 index 000000000..aa01c97a5 --- /dev/null +++ b/src/agentscope/service/execute_code/exec_shell.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +"""Service to execute shell commands.""" +import subprocess +from agentscope.service.service_status import ServiceExecStatus +from agentscope.service.service_response import ServiceResponse + + +def execute_shell_command(command: str) -> ServiceResponse: + """ + Executes a given shell command(using subprocess) and returns the execution + result as a string. + + Args: + command (str): The shell command to execute. + + Returns: + ServiceResponse: Contains either the output from the shell command as a + string if sucessful, or an error message include the error type. + + Note: + Use any bash/shell commands you want (e.g. find, grep, cat, ls, cd), + but note that : + 1. interactive session commands (e.g. python, vim) are NOT supported, + so please do not invoke them. + 2. be VERY CAREFUL when using commands that will + change/edit the files current directory (e.g. rm, sed). + ... + """ + try: + result = subprocess.run( + command, + shell=True, + check=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + ) + return ServiceResponse( + status=ServiceExecStatus.SUCCESS, + content=result.stdout.strip() if result.stdout else "Success.", + ) + except subprocess.CalledProcessError as e: + error_message = ( + e.stderr.strip() + if e.stderr + else "An error occurred \ + while executing the command." + ) + return ServiceResponse( + status=ServiceExecStatus.ERROR, + content=error_message, + ) + except Exception as e: + return ServiceResponse( + status=ServiceExecStatus.ERROR, + content=str(e), + ) diff --git a/src/agentscope/service/file/common.py b/src/agentscope/service/file/common.py index 82ec9eed9..4c37c061f 100644 --- a/src/agentscope/service/file/common.py +++ b/src/agentscope/service/file/common.py @@ -2,6 +2,7 @@ """ Common operators for file and directory. """ import os import shutil +from typing import List from agentscope.utils.common import write_file from agentscope.service.service_response import ServiceResponse @@ -201,3 +202,61 @@ def move_directory( status=ServiceExecStatus.ERROR, content=error_message, ) + + +def show_directory(directory_path: str) -> ServiceResponse: + """ + Show/List the contents of a directory. i.e. ls -a + + Args: + directory_path (`str`): + The path of the directory to show. + + Returns: + `ServiceResponse`: The results contain a list of direcotry contents, + or an error message if any, including the error type. + """ + if not os.path.exists(directory_path): + return ServiceResponse( + status=ServiceExecStatus.ERROR, + content="FileNotFoundError: The directory does not exist.", + ) + if not os.path.isdir(directory_path): + return ServiceResponse( + status=ServiceExecStatus.ERROR, + content="FileNotFoundError: The path is not a directory", + ) + try: + ls_result: List[str] = os.listdir(directory_path) + return ServiceResponse( + status=ServiceExecStatus.SUCCESS, + content=f"The listdir results are: {ls_result}", + ) + except Exception as e: + error_message = f"{e.__class__.__name__}: {e}" + return ServiceResponse( + status=ServiceExecStatus.ERROR, + content=error_message, + ) + + +def get_current_directory() -> ServiceResponse: + """ + Get the current working directory path. + + Returns: + `ServiceResponse`: The current working directory path, or an error + message if any, including the error type. + """ + try: + cwd = os.getcwd() + return ServiceResponse( + status=ServiceExecStatus.SUCCESS, + content=cwd, + ) + except Exception as e: + error_message = f"{e.__class__.__name__}: {e}" + return ServiceResponse( + status=ServiceExecStatus.ERROR, + content=error_message, + ) From cc82278b708c06b3b38dcf0996a7b6ac36271442 Mon Sep 17 00:00:00 2001 From: garyzhang99 Date: Fri, 12 Apr 2024 15:47:28 +0800 Subject: [PATCH 05/14] dir test --- tests/operate_file_test.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/operate_file_test.py b/tests/operate_file_test.py index 7c1b5a2e9..514e7a004 100644 --- a/tests/operate_file_test.py +++ b/tests/operate_file_test.py @@ -15,6 +15,8 @@ write_text_file, read_json_file, write_json_file, + show_directory, + get_current_directory, ) from agentscope.service.service_status import ServiceExecStatus @@ -62,12 +64,19 @@ def test_file(self) -> None: def test_dir(self) -> None: """Execute dir test.""" + + is_success = get_current_directory().status + self.assertEqual(is_success, ServiceExecStatus.SUCCESS) + is_success = create_directory(self.dir_name).status self.assertEqual(is_success, ServiceExecStatus.SUCCESS) is_success = move_directory(self.dir_name, self.moved_dir_name).status self.assertEqual(is_success, ServiceExecStatus.SUCCESS) + is_success = show_directory(self.moved_dir_name).status + self.assertEqual(is_success, ServiceExecStatus.SUCCESS) + is_success = delete_directory(self.moved_dir_name).status self.assertEqual(is_success, ServiceExecStatus.SUCCESS) From 48b7a7d1b652bd53177994666cd5e74a8bd4caf4 Mon Sep 17 00:00:00 2001 From: garyzhang99 Date: Fri, 12 Apr 2024 17:35:55 +0800 Subject: [PATCH 06/14] init shell command test --- tests/execute_shell_command_test.py | 60 +++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 tests/execute_shell_command_test.py diff --git a/tests/execute_shell_command_test.py b/tests/execute_shell_command_test.py new file mode 100644 index 000000000..7581792ff --- /dev/null +++ b/tests/execute_shell_command_test.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +""" Python code execution test.""" +import unittest +import sys + +from agentscope.service import execute_shell_command +from agentscope.service import ServiceExecStatus + + +class ExecuteShellCommandTest(unittest.TestCase): + """ + Python code execution test. + """ + + def setUp(self) -> None: + """Init for ExecuteShellCommandTest.""" + + # Basic expression + self.arg0 = "touch tmp_a.text" + + self.arg1 = "echo 'Helloworld' >> tmp_a.txt" + + self.args2 = "cat tmp_a.txt" + + self.args3 = "rm tmp_a.txt" + + def test(self) -> None: + """test command""" + result = execute_shell_command( + command=self.arg0, + ) + assert result.status == ServiceExecStatus.SUCCESS + assert result.content == "Success." + + result = execute_shell_command( + command=self.arg1, + ) + assert result.status == ServiceExecStatus.SUCCESS + assert result.content == "Success." + + result = execute_shell_command( + command=self.arg2, + ) + assert result.status == ServiceExecStatus.SUCCESS + assert result.content == "helloworld" + + result = execute_shell_command( + command=self.arg3, + ) + assert result.status == ServiceExecStatus.SUCCESS + assert result.content == "Success." + + result = execute_shell_command( + command=self.arg3, + ) + assert result.status == ServiceExecStatus.ERROR + + +if __name__ == "__main__": + unittest.main() From 84df79f883fb1f1761b6a693ca3df68acbf5eb8f Mon Sep 17 00:00:00 2001 From: garyzhang99 Date: Fri, 12 Apr 2024 17:48:05 +0800 Subject: [PATCH 07/14] init shell command test --- tests/execute_shell_command_test.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/execute_shell_command_test.py b/tests/execute_shell_command_test.py index 7581792ff..5b2b8e310 100644 --- a/tests/execute_shell_command_test.py +++ b/tests/execute_shell_command_test.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- """ Python code execution test.""" import unittest -import sys from agentscope.service import execute_shell_command from agentscope.service import ServiceExecStatus From faa99e69492c8d7aa536d3dc588405aa4f5d9bb3 Mon Sep 17 00:00:00 2001 From: garyzhang99 Date: Thu, 18 Apr 2024 11:20:03 +0800 Subject: [PATCH 08/14] exec shell --- src/agentscope/service/execute_code/exec_shell.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/agentscope/service/execute_code/exec_shell.py b/src/agentscope/service/execute_code/exec_shell.py index aa01c97a5..194762c6e 100644 --- a/src/agentscope/service/execute_code/exec_shell.py +++ b/src/agentscope/service/execute_code/exec_shell.py @@ -18,10 +18,11 @@ def execute_shell_command(command: str) -> ServiceResponse: string if sucessful, or an error message include the error type. Note: - Use any bash/shell commands you want (e.g. find, grep, cat, ls, cd), + Use any bash/shell commands you want (e.g. find, grep, cat, ls), but note that : - 1. interactive session commands (e.g. python, vim) are NOT supported, - so please do not invoke them. + 1. interactive session commands (e.g. python, vim) or commands that + change current state (e.g. cd that change the current directory) + are NOT supported yet, so please do not invoke them. 2. be VERY CAREFUL when using commands that will change/edit the files current directory (e.g. rm, sed). ... From 88d0cd06a7d43d40a4d91f5d5bca05d27fe7d624 Mon Sep 17 00:00:00 2001 From: garyzhang99 Date: Thu, 18 Apr 2024 16:00:42 +0800 Subject: [PATCH 09/14] precomit --- src/agentscope/service/execute_code/exec_shell.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/agentscope/service/execute_code/exec_shell.py b/src/agentscope/service/execute_code/exec_shell.py index 194762c6e..ef0f282f3 100644 --- a/src/agentscope/service/execute_code/exec_shell.py +++ b/src/agentscope/service/execute_code/exec_shell.py @@ -20,7 +20,7 @@ def execute_shell_command(command: str) -> ServiceResponse: Note: Use any bash/shell commands you want (e.g. find, grep, cat, ls), but note that : - 1. interactive session commands (e.g. python, vim) or commands that + 1. interactive session commands (e.g. python, vim) or commands that change current state (e.g. cd that change the current directory) are NOT supported yet, so please do not invoke them. 2. be VERY CAREFUL when using commands that will From 2d7fe0b7f285f7f9d2ba97e4257eae91abee6430 Mon Sep 17 00:00:00 2001 From: garyzhang99 Date: Mon, 22 Apr 2024 14:18:30 +0800 Subject: [PATCH 10/14] fix typo in tests --- tests/execute_shell_command_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/execute_shell_command_test.py b/tests/execute_shell_command_test.py index 5b2b8e310..bf281a648 100644 --- a/tests/execute_shell_command_test.py +++ b/tests/execute_shell_command_test.py @@ -19,9 +19,9 @@ def setUp(self) -> None: self.arg1 = "echo 'Helloworld' >> tmp_a.txt" - self.args2 = "cat tmp_a.txt" + self.arg2 = "cat tmp_a.txt" - self.args3 = "rm tmp_a.txt" + self.arg3 = "rm tmp_a.txt" def test(self) -> None: """test command""" From cd38a4f4bf8d752b0a87405b09e8813330cb72f0 Mon Sep 17 00:00:00 2001 From: garyzhang99 Date: Mon, 22 Apr 2024 14:29:40 +0800 Subject: [PATCH 11/14] fix typo in tests --- tests/execute_shell_command_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/execute_shell_command_test.py b/tests/execute_shell_command_test.py index bf281a648..ae7fda6b2 100644 --- a/tests/execute_shell_command_test.py +++ b/tests/execute_shell_command_test.py @@ -41,7 +41,7 @@ def test(self) -> None: command=self.arg2, ) assert result.status == ServiceExecStatus.SUCCESS - assert result.content == "helloworld" + assert result.content == "Helloworld" result = execute_shell_command( command=self.arg3, From b5a3123fd079d480c3e9840906bc2e156594f358 Mon Sep 17 00:00:00 2001 From: garyzhang99 Date: Mon, 22 Apr 2024 15:01:50 +0800 Subject: [PATCH 12/14] skip shell command tasks on windows --- tests/execute_shell_command_test.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/execute_shell_command_test.py b/tests/execute_shell_command_test.py index ae7fda6b2..206e3bcba 100644 --- a/tests/execute_shell_command_test.py +++ b/tests/execute_shell_command_test.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- """ Python code execution test.""" import unittest +import platform from agentscope.service import execute_shell_command from agentscope.service import ServiceExecStatus @@ -24,7 +25,9 @@ def setUp(self) -> None: self.arg3 = "rm tmp_a.txt" def test(self) -> None: - """test command""" + """test command, skip on windows""" + if platform.system() == "Windows": + return result = execute_shell_command( command=self.arg0, ) From 4813913270d6b3b7e6ec898f6d347c06879b5f89 Mon Sep 17 00:00:00 2001 From: garyzhang99 Date: Tue, 23 Apr 2024 16:06:07 +0800 Subject: [PATCH 13/14] resolve comments --- src/agentscope/service/__init__.py | 4 ++-- tests/operate_file_test.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/agentscope/service/__init__.py b/src/agentscope/service/__init__.py index 877091996..b52023514 100644 --- a/src/agentscope/service/__init__.py +++ b/src/agentscope/service/__init__.py @@ -11,7 +11,7 @@ create_directory, delete_directory, move_directory, - show_directory, + list_directory_content, get_current_directory, ) from .file.text import read_text_file, write_text_file @@ -50,7 +50,7 @@ def get_help() -> None: "create_directory", "delete_directory", "move_directory", - "show_directory", + "list_directory_content", "get_current_directory", "read_text_file", "write_text_file", diff --git a/tests/operate_file_test.py b/tests/operate_file_test.py index 514e7a004..c0c663867 100644 --- a/tests/operate_file_test.py +++ b/tests/operate_file_test.py @@ -15,7 +15,7 @@ write_text_file, read_json_file, write_json_file, - show_directory, + list_directory_content, get_current_directory, ) from agentscope.service.service_status import ServiceExecStatus @@ -74,7 +74,7 @@ def test_dir(self) -> None: is_success = move_directory(self.dir_name, self.moved_dir_name).status self.assertEqual(is_success, ServiceExecStatus.SUCCESS) - is_success = show_directory(self.moved_dir_name).status + is_success = list_directory_content(self.moved_dir_name).status self.assertEqual(is_success, ServiceExecStatus.SUCCESS) is_success = delete_directory(self.moved_dir_name).status From 7878005ac4b471680e47dcdf0e8ac46b4b1d99a5 Mon Sep 17 00:00:00 2001 From: garyzhang99 Date: Tue, 23 Apr 2024 16:06:49 +0800 Subject: [PATCH 14/14] resolve comments --- src/agentscope/service/execute_code/exec_shell.py | 3 +-- src/agentscope/service/file/common.py | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/agentscope/service/execute_code/exec_shell.py b/src/agentscope/service/execute_code/exec_shell.py index ef0f282f3..ffde21b9d 100644 --- a/src/agentscope/service/execute_code/exec_shell.py +++ b/src/agentscope/service/execute_code/exec_shell.py @@ -7,8 +7,7 @@ def execute_shell_command(command: str) -> ServiceResponse: """ - Executes a given shell command(using subprocess) and returns the execution - result as a string. + Executes a given shell command. Args: command (str): The shell command to execute. diff --git a/src/agentscope/service/file/common.py b/src/agentscope/service/file/common.py index 4c37c061f..adeb5a0ad 100644 --- a/src/agentscope/service/file/common.py +++ b/src/agentscope/service/file/common.py @@ -204,9 +204,9 @@ def move_directory( ) -def show_directory(directory_path: str) -> ServiceResponse: +def list_directory_content(directory_path: str) -> ServiceResponse: """ - Show/List the contents of a directory. i.e. ls -a + List the contents of a directory. i.e. ls -a Args: directory_path (`str`): @@ -230,7 +230,7 @@ def show_directory(directory_path: str) -> ServiceResponse: ls_result: List[str] = os.listdir(directory_path) return ServiceResponse( status=ServiceExecStatus.SUCCESS, - content=f"The listdir results are: {ls_result}", + content=ls_result, ) except Exception as e: error_message = f"{e.__class__.__name__}: {e}"