Skip to content

Commit

Permalink
resolve threads
Browse files Browse the repository at this point in the history
  • Loading branch information
garyzhang99 committed May 15, 2024
1 parent 903d49d commit f88ed5d
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 59 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ the following libraries.
- [Conversation with ReAct Agent](./examples/conversation_with_react_agent)
- [Conversation in Natural Language to Query SQL](./examples/conversation_nl2sql/)
- [Conversation with RAG Agent](./examples/conversation_with_RAG_agents)
- [Conversation with SWE Agnet](./examples/swe_agent/)

- Game
- [Gomoku](./examples/game_gomoku)
Expand Down
1 change: 1 addition & 0 deletions README_ZH.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ AgentScope支持使用以下库快速部署本地模型服务。
- [与ReAct智能体对话](./examples/conversation_with_react_agent)
- [通过对话查询SQL信息](./examples/conversation_nl2sql/)
- [与RAG智能体对话](./examples/conversation_with_RAG_agents)
- [与SWE智能体对话](./examples/swe_agent/)

- 游戏
- [五子棋](./examples/game_gomoku)
Expand Down
93 changes: 37 additions & 56 deletions examples/swe_agent/main.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@
"# Example with SWE-agent\n",
"\n",
"SWE-agent(SoftWare Engineering Agent) is an agent designed for solving real world software engineering problems, such as fixing github issues.\n",
"More details can be found in their [homepage](https://swe-agent.com/) and related [github repo](https://swe-agent.com/).\n",
"More details can be found in the project's [homepage](https://swe-agent.com/) and related [github repo](https://swe-agent.com/).\n",
"\n",
"In the example here, we partially implement the SWE-agent, and provide a simple example of how to use the implemented SWE-agent to fix a bug in a python file.\n",
"You should note that currently how to enable agents with stronger programming capabilities remains an open challenge, and the performance of the paritially implemented SWE-agent is not guaranteed.\n",
"\n",
"## Prerequisites\n",
"\n",
"- Follow [READMD.md](https://github.com/modelscope/agentscope) to install AgentScope. \n",
"- Prepare a model configuration. AgentScope supports both local deployed model services (CPU or GPU) and third-party services. More details and example model configurations please refer to our [tutorial]\n",
"- Understand the ServiceFactory module and how to use it to pre-process the tool functions for LLMs. You can refer to the [ReAct agent example](../conversation_with_react_agent/main.ipynb).\n",
"- Prepare a model configuration. AgentScope supports both local deployed model services (CPU or GPU) and third-party services. More details and example model configurations please refer to our [tutorial](https://modelscope.github.io/agentscope/en/tutorial/203-model.html).\n",
"- Understand the ServiceToolkit module and how to use it to pre-process the tool functions for LLMs. You can refer to the [ReAct agent example](../conversation_with_react_agent/main.ipynb) and you should also refer to the [tutorial](https://modelscope.github.io/agentscope/en/tutorial/204-service.html) for service functions.\n",
"\n",
"\n",
"## Note\n",
"\n",
Expand All @@ -25,6 +26,22 @@
"- How to enable agents with stronger programming capabilities remains an open challenge, and the current implementations are not perfect. Please feel free to explore it yourself."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"YOUR_MODEL_CONFIGURATION_NAME = \"{YOUR_MODEL_CONFIGURATION_NAME}\"\n",
"\n",
"YOUR_MODEL_CONFIGURATION = {\n",
" \"model_type\": \"xxx\", \n",
" \"config_name\": YOUR_MODEL_CONFIGURATION_NAME\n",
" \n",
" # ...\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand All @@ -47,11 +64,8 @@
"from swe_agent import SWEAgent\n",
"\n",
"import agentscope\n",
"from agentscope.models import load_model_by_config_name\n",
"agentscope.init(\n",
" model_configs=\"xxx.json\", # fill you model config file path here\n",
")\n",
"loaded_model = load_model_by_config_name('gpt-4')\n",
"\n",
"agentscope.init(model_configs=YOUR_MODEL_CONFIGURATION)\n",
"\n",
"agent = SWEAgent(\n",
" name=\"assistant\",\n",
Expand All @@ -72,7 +86,7 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": 3,
"metadata": {},
"outputs": [
{
Expand All @@ -82,7 +96,7 @@
" 'content': 'WRITE OPERATION:\\nYou have written to \"gcd.py\" on these lines: 0:-1.\\ndef gcd(a, b):\\n if a == 0:\\n return b\\n while a != 0:\\n a, b = b, a\\n return b\\n\\ndef lcm(a, b):\\n return (a * b) // gcd(a, b)\\n\\n# testing on GCD and LCM functions\\nprint(\"GCD of 12 and 18 is:\", gcd(12, 18))\\nprint(\"LCM of 12 and 18 is:\", lcm(12, 18))\\n\\n'}"
]
},
"execution_count": 2,
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
Expand Down Expand Up @@ -121,7 +135,7 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 4,
"metadata": {},
"outputs": [
{
Expand All @@ -130,7 +144,7 @@
"text": [
"user: The file in gcd.py is not returning the correct answer, can you fix the file for me?\n",
"assistant: {\n",
" \"thought\": \"To debug the gcd.py file, first we need to read the contents of the file to understand the existing program logic.\",\n",
" \"thought\": \"First thing I'll do is read the content of gcd.py file to understand the existing logic.\",\n",
" \"action\": {\n",
" \"name\": \"read_file\",\n",
" \"arguments\": {\n",
Expand All @@ -156,42 +170,38 @@
"print(\"LCM of 12 and 18 is:\", lcm(12, 18))\n",
"\n",
"\n",
"assistant: ```json\n",
"Upon reviewing the contents of gcd.py, I can see the gcd function is incorrectly implemented. While the function starts correctly by evaluating `if a == 0: return b`, the loop structure `while a != 0: a, b = b, a` does not accurately compute the greatest common divisor (gcd). \n",
"\n",
"Instead, this loop intends to swap a and b while 'a' is not zero, but does not perform any operation that would actually calculate the gcd. In fact, without proper adjustments, this results in an infinite loop when 'a' is not zero.\n",
"\n",
"The correct implementation should be using Euclid's algorithm for calculating gcd which goes: while b is not zero, swap a, b = b, remainder of (a divided by b), when b becomes zero, 'a' is the gcd.\n",
"\n",
"I will replace the current gcd function in the file with this correct implementation.```\n",
"system: {'action': {'name': 'error'}, 'error_msg': 'Your response is not a JSON object, and cannot be parsed by `json.loads` in parse function:\\n## Your Response:\\n[YOUR RESPONSE BEGIN]\\n```json\\nUpon reviewing the contents of gcd.py, I can see the gcd function is incorrectly implemented. While the function starts correctly by evaluating `if a == 0: return b`, the loop structure `while a != 0: a, b = b, a` does not accurately compute the greatest common divisor (gcd). \\n\\nInstead, this loop intends to swap a and b while \\'a\\' is not zero, but does not perform any operation that would actually calculate the gcd. In fact, without proper adjustments, this results in an infinite loop when \\'a\\' is not zero.\\n\\nThe correct implementation should be using Euclid\\'s algorithm for calculating gcd which goes: while b is not zero, swap a, b = b, remainder of (a divided by b), when b becomes zero, \\'a\\' is the gcd.\\n\\nI will replace the current gcd function in the file with this correct implementation.```\\n[YOUR RESPONSE END]\\n\\n## Error Information:\\nThe content between ```json and ``` MUST be a JSON object.When parsing \"```json\\nUpon reviewing the contents of gcd.py, I can see the gcd function is incorrectly implemented. While the function starts correctly by evaluating `if a == 0: return b`, the loop structure `while a != 0: a, b = b, a` does not accurately compute the greatest common divisor (gcd). \\n\\nInstead, this loop intends to swap a and b while \\'a\\' is not zero, but does not perform any operation that would actually calculate the gcd. In fact, without proper adjustments, this results in an infinite loop when \\'a\\' is not zero.\\n\\nThe correct implementation should be using Euclid\\'s algorithm for calculating gcd which goes: while b is not zero, swap a, b = b, remainder of (a divided by b), when b becomes zero, \\'a\\' is the gcd.\\n\\nI will replace the current gcd function in the file with this correct implementation.```\", an error occurred: Expecting value: line 2 column 1 (char 1)\\n\\nAnalyze the reason, and re-correct your response in the correct format.'}\n",
"assistant: {\n",
" \"thought\": \"To fix the gcd function, I need to use Euclid's algorithm. The algorithm is: while b is not zero, swap a, b = b, remainder of (a divided by b), when b becomes zero, 'a' is the gcd. I will replace the current faulty gcd function in the file with this correct implementation.\",\n",
" \"thought\": \"I can see the error in the gcd calculation. The gcd calculation in the file is incorrect. The correct way to find the gcd of two numbers using the Euclidean algorithm is to continually reduce a and b by finding the remainder of a % b until b is 0, at which point a will be the gcd of the original a and b values. In the given code, instead of finding the remainder, it is incorrectly swapping the values of a and b. I'll correct this error by modifying the gcd function using the write_file command, reflecting the correct Euclidean algorithm.\",\n",
" \"action\": {\n",
" \"name\": \"write_file\",\n",
" \"arguments\": {\n",
" \"content\": \"def gcd(a, b):\\n while b != 0:\\n a, b = b, a % b\\n return a\\n\\ndef lcm(a, b):\\n return (a * b) // gcd(a, b)\\n\\n# testing on GCD and LCM functions\\nprint(\\\"GCD of 12 and 18 is:\\\", gcd(12, 18))\\nprint(\\\"LCM of 12 and 18 is:\\\", lcm(12, 18))\",\n",
" \"start_line\": 0,\n",
" \"end_line\": 15,\n",
" \"content\": \"def gcd(a, b):\\n while b != 0:\\n a, b = b, a % b\\n return a\\n\\n\\ndef lcm(a, b):\\n return (a * b) // gcd(a, b)\\n\\n\\n# testing on GCD and LCM functions\\nprint(\\\"GCD of 12 and 18 is:\\\", gcd(12, 18))\\nprint(\\\"LCM of 12 and 18 is:\\\", lcm(12, 18))\\n\",\n",
" \"file_path\": \"gcd.py\"\n",
" }\n",
" }\n",
"}\n",
"assistant: \n",
"====Observation====\n",
"WRITE OPERATION:\n",
"You have written to \"gcd.py\" on these lines: 0:-1.def gcd(a, b):\n",
"You have written to \"gcd.py\" on these lines: 0:15.def gcd(a, b):\n",
" while b != 0:\n",
" a, b = b, a % b\n",
" return a\n",
"\n",
"\n",
"def lcm(a, b):\n",
" return (a * b) // gcd(a, b)\n",
"\n",
"\n",
"# testing on GCD and LCM functions\n",
"print(\"GCD of 12 and 18 is:\", gcd(12, 18))\n",
"print(\"LCM of 12 and 18 is:\", lcm(12, 18))\n",
"\n",
"\n",
"assistant: {\n",
" \"thought\": \"Now I have fixed the gcd function, I now need to test if it's working as expected. I can do this by executing the Python file.\",\n",
" \"thought\": \"I should run the python file to see if the changes I made have fixed the gcd function.\",\n",
" \"action\": {\n",
" \"name\": \"execute_shell_command\",\n",
" \"arguments\": {\n",
Expand All @@ -204,7 +214,7 @@
"GCD of 12 and 18 is: 6\n",
"LCM of 12 and 18 is: 36\n",
"assistant: {\n",
" \"thought\": \"The code has been corrected and tested. It is now returning the correct gcd and lcm. No further actions are required.\",\n",
" \"thought\": \"The gcd.py file has been fixed and tested successfully. Therefore, no further actions are needed.\",\n",
" \"action\": {\n",
" \"name\": \"exit\",\n",
" \"arguments\": {}\n",
Expand Down Expand Up @@ -235,36 +245,7 @@
"source": [
"### Conlusion\n",
"\n",
"After a few iterations, the assistant response:\n",
"```text\n",
"\n",
"assistant: {\n",
" \"thought\": \"Now I have fixed the gcd function, I now need to test if it's working as expected. I can do this by executing the Python file.\",\n",
" \"action\": {\n",
" \"name\": \"execute_shell_command\",\n",
" \"arguments\": {\n",
" \"command\": \"python3 gcd.py\"\n",
" }\n",
" }\n",
"}\n",
"assistant: \n",
"====Observation====\n",
"GCD of 12 and 18 is: 6\n",
"LCM of 12 and 18 is: 36\n",
"assistant: {\n",
" \"thought\": \"The code has been corrected and tested. It is now returning the correct gcd and lcm. No further actions are required.\",\n",
" \"action\": {\n",
" \"name\": \"exit\",\n",
" \"arguments\": {}\n",
" }\n",
"}\n",
"assistant: \n",
"====Observation====\n",
"Current task finished, exitting.\n",
"\n",
"```\n",
"\n",
"The SWE-agent finish the job successfully, and the code is now working fine."
"After a few iterations, the SWE-agent assistant finish the job successfully, and the code is now working fine."
]
},
{
Expand Down
7 changes: 5 additions & 2 deletions examples/swe_agent/swe_agent_prompts.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ def get_system_prompt(command_prompt: str) -> str:
However, the environment does NOT support interactive session commands (e.g. vim, python), so please do not invoke them.
Your Response should always be a valid JSON string that can be parsed.
{RESPONSE_FORMAT_PROMPT}
""" # noqa
Expand All @@ -46,16 +44,20 @@ def get_system_prompt(command_prompt: str) -> str:
RESPONSE_FORMAT_PROMPT = """
## Response Format:
You should respond with a JSON object in the following format.
```json
{
"thought": "what you thought",
"action": {"name": "{command name}", "arguments": {"{argument1 name}": xxx, "{argument2 name}": xxx}}
}
```
For Example:
```json
{
"thought": "First I'll start by using ls to see what files are in the current directory. Then maybe we can look at some relevant files to see what they look like.",
"action": {"name": "execute_shell_command", "arguments": {"command": "ls -a"}}
}
```
OUTPUT the JSON format and ONLY OUTPUT the JSON format.
Your Response should always be a valid JSON string that can be parsed.
""" # noqa
Expand Down Expand Up @@ -99,6 +101,7 @@ def get_step_prompt(
NOTE THAT THIS ENVIRONMENT DOES NOT SUPPORT INTERACTIVE SESSION COMMANDS, such as "vim" or "python", or "python3". So DONOT execute them by running `execute_shell_command` with `python` command or `python3` command if the code need additional inputs.
If you want to check whether a python file is valid, you can use `exec_py_linting` to check for errors.
You should always notice your response format and respond with a JSON object in the following format.
{RESPONSE_FORMAT_PROMPT}
""" # noqa

Expand Down
2 changes: 1 addition & 1 deletion src/agentscope/service/file/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def create_file(file_path: str, content: str = "") -> ServiceResponse:
Args:
file_path (`str`):
The path where the file will be created.
The path where the file will be created.
content (`str`):
Content to write into the file.
Expand Down

0 comments on commit f88ed5d

Please sign in to comment.