Skip to content

Commit 07b2475

Browse files
committed
update README.md and app
1 parent 9549612 commit 07b2475

22 files changed

+156
-644
lines changed

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,15 @@ api_key = "sk-..." # Replace with your actual API key
6262
```
6363

6464
## Quick Start
65-
One line for run OpenManus:
65+
One line for run OpenManus:
6666

6767
```bash
6868
python main.py
6969
```
7070

7171
Then input your idea via terminal!
7272

73-
## How to contribute
73+
## How to contribute
7474
We welcome any friendly suggestions and helpful contributions! Just create issues or submit pull requests.
7575

7676
Or contact @mannaandpoem via 📧email: [email protected]
@@ -84,6 +84,6 @@ Or contact @mannaandpoem via 📧email: [email protected]
8484

8585
## Acknowledgement
8686

87-
Thanks to [broswer use](https://github.com/browser-use/browser-use) for providing basic support for this project!
87+
Thanks to [anthropic-computer-use](https://github.com/anthropics/anthropic-quickstarts/tree/main/computer-use-demo) and [broswer-use](https://github.com/browser-use/browser-use) for providing basic support for this project!
8888

8989
OpenManus is built by contributors from MetaGPT. Huge thanks to this agent community!

app/agent/manus.py

+7-9
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
1-
from pydantic import Field, model_validator
1+
from pydantic import Field
22

3-
from app.agent.planning import PlanningAgent
43
from app.agent.toolcall_en import ToolCallAgent
5-
from app.tool import ToolCollection, Bash, Terminate
6-
from app.tool.planning import PlanningTool
4+
from app.prompt.manus import NEXT_STEP_PROMPT, SYSTEM_PROMPT
5+
from app.tool import Terminate, ToolCollection
76
from app.tool.browser_use_tool import BrowserUseTool
7+
from app.tool.file_saver import FileSaver
88
from app.tool.google_search import GoogleSearch
99
from app.tool.python_execute import PythonExecute
10-
from app.tool.file_saver import FileSaver
11-
12-
from app.prompt.manus import SYSTEM_PROMPT, NEXT_STEP_PROMPT
1310

1411

1512
class Manus(ToolCallAgent):
@@ -22,7 +19,9 @@ class Manus(ToolCallAgent):
2219
"""
2320

2421
name: str = "Manus"
25-
description: str = "A versatile agent that can solve various tasks using multiple tools"
22+
description: str = (
23+
"A versatile agent that can solve various tasks using multiple tools"
24+
)
2625

2726
system_prompt: str = SYSTEM_PROMPT
2827
next_step_prompt: str = NEXT_STEP_PROMPT
@@ -33,4 +32,3 @@ class Manus(ToolCallAgent):
3332
PythonExecute(), GoogleSearch(), BrowserUseTool(), FileSaver(), Terminate()
3433
)
3534
)
36-

app/agent/planning.py

+1-27
Original file line numberDiff line numberDiff line change
@@ -5,37 +5,11 @@
55

66
from app.agent.toolcall import ToolCallAgent
77
from app.logger import logger
8+
from app.prompt.planning import NEXT_STEP_PROMPT, PLANNING_SYSTEM_PROMPT
89
from app.schema import Message, ToolCall
910
from app.tool import PlanningTool, Terminate, ToolCollection
1011

1112

12-
PLANNING_SYSTEM_PROMPT = """
13-
You are an expert Planning Agent tasked with solving complex problems by creating and managing structured plans.
14-
Your job is:
15-
1. Analyze requests to understand the task scope
16-
2. Create clear, actionable plans with the `planning` tool
17-
3. Execute steps using available tools as needed
18-
4. Track progress and adapt plans dynamically
19-
5. Use `finish` to conclude when the task is complete
20-
21-
Available tools will vary by task but may include:
22-
- `planning`: Create, update, and track plans (commands: create, update, mark_step, etc.)
23-
- `finish`: End the task when complete
24-
25-
Break tasks into logical, sequential steps. Think about dependencies and verification methods.
26-
"""
27-
28-
NEXT_STEP_PROMPT = """
29-
Based on the current state, what's your next step?
30-
Consider:
31-
1. Do you need to create or refine a plan?
32-
2. Are you ready to execute a specific step?
33-
3. Have you completed the task?
34-
35-
Provide reasoning, then select the appropriate tool or action.
36-
"""
37-
38-
3913
class PlanningAgent(ToolCallAgent):
4014
"""
4115
An agent that creates and manages plans to solve tasks.

app/agent/toolcall_en.py

+22-11
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from app.schema import AgentState, Message, ToolCall
1010
from app.tool import CreateChatCompletion, Terminate, ToolCollection
1111

12+
1213
TOOL_CALL_REQUIRED = "Tool calls required but none provided"
1314

1415

@@ -40,23 +41,31 @@ async def think(self) -> bool:
4041
# Get response with tool options
4142
response = await self.llm.ask_tool(
4243
messages=self.messages,
43-
system_msgs=[Message.system_message(self.system_prompt)] if self.system_prompt else None,
44+
system_msgs=[Message.system_message(self.system_prompt)]
45+
if self.system_prompt
46+
else None,
4447
tools=self.available_tools.to_params(),
4548
tool_choice=self.tool_choices,
4649
)
4750
self.tool_calls = response.tool_calls
4851

4952
# Log response info in a more engaging way
5053
logger.info(f"✨ AI's thoughts: {response.content}")
51-
logger.info(f"🛠️ AI selected {len(response.tool_calls) if response.tool_calls else 0} tools to use")
54+
logger.info(
55+
f"🛠️ AI selected {len(response.tool_calls) if response.tool_calls else 0} tools to use"
56+
)
5257
if response.tool_calls:
53-
logger.info(f"🧰 Tools being prepared: {[call.function.name for call in response.tool_calls]}")
58+
logger.info(
59+
f"🧰 Tools being prepared: {[call.function.name for call in response.tool_calls]}"
60+
)
5461

5562
try:
5663
# Handle different tool_choices modes
5764
if self.tool_choices == "none":
5865
if response.tool_calls:
59-
logger.warning("🤔 Hmm, AI tried to use tools when they weren't available!")
66+
logger.warning(
67+
"🤔 Hmm, AI tried to use tools when they weren't available!"
68+
)
6069
if response.content:
6170
self.memory.add_message(Message.assistant_message(response.content))
6271
return True
@@ -82,9 +91,11 @@ async def think(self) -> bool:
8291
return bool(self.tool_calls)
8392
except Exception as e:
8493
logger.error(f"🚨 Oops! The AI's thinking process hit a snag: {e}")
85-
self.memory.add_message(Message.assistant_message(
86-
f"Error encountered while processing: {str(e)}"
87-
))
94+
self.memory.add_message(
95+
Message.assistant_message(
96+
f"Error encountered while processing: {str(e)}"
97+
)
98+
)
8899
return False
89100

90101
async def act(self) -> str:
@@ -94,9 +105,7 @@ async def act(self) -> str:
94105
raise ValueError(TOOL_CALL_REQUIRED)
95106

96107
# Return last message content if no tool calls
97-
return (
98-
self.messages[-1].content or "No content or commands to execute"
99-
)
108+
return self.messages[-1].content or "No content or commands to execute"
100109

101110
results = []
102111
for command in self.tool_calls:
@@ -144,7 +153,9 @@ async def execute_tool(self, command: ToolCall) -> str:
144153
return observation
145154
except json.JSONDecodeError:
146155
error_msg = f"Error parsing arguments for {name}: Invalid JSON format"
147-
logger.error(f"📝 Oops! The arguments for '{name}' don't make sense - invalid JSON")
156+
logger.error(
157+
f"📝 Oops! The arguments for '{name}' don't make sense - invalid JSON"
158+
)
148159
return f"Error: {error_msg}"
149160
except Exception as e:
150161
error_msg = f"Error executing tool {name}: {str(e)}"

app/agent/toolcall_zh.py

+16-9
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from app.schema import AgentState, Message, ToolCall
1010
from app.tool import CreateChatCompletion, Terminate, ToolCollection
1111

12+
1213
TOOL_CALL_REQUIRED = "Tool calls required but none provided"
1314

1415

@@ -40,17 +41,23 @@ async def think(self) -> bool:
4041
# Get response with tool options
4142
response = await self.llm.ask_tool(
4243
messages=self.messages,
43-
system_msgs=[Message.system_message(self.system_prompt)] if self.system_prompt else None,
44+
system_msgs=[Message.system_message(self.system_prompt)]
45+
if self.system_prompt
46+
else None,
4447
tools=self.available_tools.to_params(),
4548
tool_choice=self.tool_choices,
4649
)
4750
self.tool_calls = response.tool_calls
4851

4952
# Log response info in a more engaging way
5053
logger.info(f"✨ AI的思考过程:{response.content}")
51-
logger.info(f"🛠️ AI选择了 {len(response.tool_calls) if response.tool_calls else 0} 个工具来解决问题")
54+
logger.info(
55+
f"🛠️ AI选择了 {len(response.tool_calls) if response.tool_calls else 0} 个工具来解决问题"
56+
)
5257
if response.tool_calls:
53-
logger.info(f"🧰 准备使用的工具箱:{[call.function.name for call in response.tool_calls]}")
58+
logger.info(
59+
f"🧰 准备使用的工具箱:{[call.function.name for call in response.tool_calls]}"
60+
)
5461

5562
try:
5663
# Handle different tool_choices modes
@@ -82,9 +89,11 @@ async def think(self) -> bool:
8289
return bool(self.tool_calls)
8390
except Exception as e:
8491
logger.error(f"🚨 糟糕!AI思考时遇到了一点小问题:{e}")
85-
self.memory.add_message(Message.assistant_message(
86-
f"Error encountered while processing: {str(e)}"
87-
))
92+
self.memory.add_message(
93+
Message.assistant_message(
94+
f"Error encountered while processing: {str(e)}"
95+
)
96+
)
8897
return False
8998

9099
async def act(self) -> str:
@@ -94,9 +103,7 @@ async def act(self) -> str:
94103
raise ValueError(TOOL_CALL_REQUIRED)
95104

96105
# Return last message content if no tool calls
97-
return (
98-
self.messages[-1].content or "No content or commands to execute"
99-
)
106+
return self.messages[-1].content or "No content or commands to execute"
100107

101108
results = []
102109
for command in self.tool_calls:

app/config.py

+1-15
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import threading
22
import tomllib
33
from pathlib import Path
4-
from typing import Dict, Optional
4+
from typing import Dict
55

66
from pydantic import BaseModel, Field
77

@@ -23,14 +23,8 @@ class LLMSettings(BaseModel):
2323
temperature: float = Field(1.0, description="Sampling temperature")
2424

2525

26-
class ScreenshotSettings(BaseModel):
27-
api_key: Optional[str] = Field(None, description="Screenshot API key")
28-
base_url: Optional[str] = Field(None, description="Screenshot service URL")
29-
30-
3126
class AppConfig(BaseModel):
3227
llm: Dict[str, LLMSettings]
33-
screenshot: Optional[ScreenshotSettings] = None
3428

3529

3630
class Config:
@@ -94,16 +88,8 @@ def _load_initial_config(self):
9488
}
9589
}
9690

97-
# Add screenshot config if present
98-
if screenshot_config := raw_config.get("screenshot"):
99-
config_dict["screenshot"] = screenshot_config
100-
10191
self._config = AppConfig(**config_dict)
10292

103-
@property
104-
def screenshot(self) -> Optional[ScreenshotSettings]:
105-
return self._config.screenshot
106-
10793
@property
10894
def llm(self) -> Dict[str, LLMSettings]:
10995
return self._config.llm

app/exceptions.py

-7
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,3 @@ class ToolError(Exception):
33

44
def __init__(self, message):
55
self.message = message
6-
7-
8-
class BrowserException(Exception):
9-
"""Base exception for browser-related errors."""
10-
11-
def __init__(self, message):
12-
super().__init__(message)

app/logger.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def define_log_level(print_level="INFO", logfile_level="DEBUG", name: str = None
2222

2323
_logger.remove()
2424
_logger.add(sys.stderr, level=print_level)
25-
_logger.add(PROJECT_ROOT / f"logs/{log_name}.txt", level=logfile_level)
25+
_logger.add(PROJECT_ROOT / f"logs/{log_name}.log", level=logfile_level)
2626
return _logger
2727

2828

app/loop.py

-21
This file was deleted.

app/prompt/manus.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@
1111
GoogleSearch: Perform web information retrieval
1212
1313
Based on user needs, proactively select the most appropriate tool or combination of tools. For complex tasks, you can break down the problem and use different tools step by step to solve it. After using each tool, clearly explain the execution results and suggest the next steps.
14-
"""
14+
"""

app/prompt/planning.py

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
PLANNING_SYSTEM_PROMPT = """
2+
You are an expert Planning Agent tasked with solving complex problems by creating and managing structured plans.
3+
Your job is:
4+
1. Analyze requests to understand the task scope
5+
2. Create clear, actionable plans with the `planning` tool
6+
3. Execute steps using available tools as needed
7+
4. Track progress and adapt plans dynamically
8+
5. Use `finish` to conclude when the task is complete
9+
10+
Available tools will vary by task but may include:
11+
- `planning`: Create, update, and track plans (commands: create, update, mark_step, etc.)
12+
- `finish`: End the task when complete
13+
14+
Break tasks into logical, sequential steps. Think about dependencies and verification methods.
15+
"""
16+
17+
NEXT_STEP_PROMPT = """
18+
Based on the current state, what's your next step?
19+
Consider:
20+
1. Do you need to create or refine a plan?
21+
2. Are you ready to execute a specific step?
22+
3. Have you completed the task?
23+
24+
Provide reasoning, then select the appropriate tool or action.
25+
"""

0 commit comments

Comments
 (0)