mirror of
https://github.com/All-Hands-AI/OpenHands.git
synced 2026-04-29 03:00:45 -04:00
Compare commits
10 Commits
fix-basic-
...
docs/updat
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c5f31b643e | ||
|
|
5730db327a | ||
|
|
24a03738a8 | ||
|
|
3a093c13b8 | ||
|
|
e367ced954 | ||
|
|
4c2c1bd8eb | ||
|
|
20b1f37fbd | ||
|
|
2bae39ef30 | ||
|
|
9f8bcf8729 | ||
|
|
137eec4dd1 |
@@ -2,8 +2,6 @@ This repository contains the code for OpenHands, an automated AI software engine
|
|||||||
(in the `openhands` directory) and React frontend (in the `frontend` directory).
|
(in the `openhands` directory) and React frontend (in the `frontend` directory).
|
||||||
|
|
||||||
## General Setup:
|
## General Setup:
|
||||||
To set up the entire repo, including frontend and backend, run `make build`.
|
|
||||||
You don't need to do this unless the user asks you to, or if you're trying to run the entire application.
|
|
||||||
|
|
||||||
IMPORTANT: Before making any changes to the codebase, ALWAYS run `make install-pre-commit-hooks` to ensure pre-commit hooks are properly installed.
|
IMPORTANT: Before making any changes to the codebase, ALWAYS run `make install-pre-commit-hooks` to ensure pre-commit hooks are properly installed.
|
||||||
|
|
||||||
@@ -21,13 +19,91 @@ then re-run the command to ensure it passes. Common issues include:
|
|||||||
- Trailing whitespace
|
- Trailing whitespace
|
||||||
- Missing newlines at end of files
|
- Missing newlines at end of files
|
||||||
|
|
||||||
|
## Testing and Debugging
|
||||||
|
|
||||||
|
### Environment Setup for Testing
|
||||||
|
- Run `make build` to install all dependencies (only necessary for running tests):
|
||||||
|
```bash
|
||||||
|
make build
|
||||||
|
```
|
||||||
|
**IMPORTANT**: When using `execute_bash` to run `make build` or similar long-running commands, set the `timeout` parameter to a high value (e.g., 600 seconds):
|
||||||
|
```
|
||||||
|
execute_bash(command="make build", timeout=600)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Docker Installation
|
||||||
|
**NOTE: Docker installation is ONLY required for running runtime tests with the Docker runtime.**
|
||||||
|
|
||||||
|
- Install Docker on Debian-based systems:
|
||||||
|
```bash
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release
|
||||||
|
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
||||||
|
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
|
||||||
|
```
|
||||||
|
- Start Docker daemon (in container environments without systemd):
|
||||||
|
```bash
|
||||||
|
sudo dockerd > /tmp/docker.log 2>&1 & sleep 5
|
||||||
|
```
|
||||||
|
- Verify Docker installation:
|
||||||
|
```bash
|
||||||
|
sudo docker run hello-world
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Development Environment Setup
|
||||||
|
- Before running `make run`, ensure netcat is installed:
|
||||||
|
```bash
|
||||||
|
sudo apt-get install -y netcat-openbsd
|
||||||
|
```
|
||||||
|
|
||||||
|
### Unit Tests
|
||||||
|
- All unit tests are in `tests/unit/test_*.py`
|
||||||
|
- To test new code, run `poetry run pytest tests/unit/test_xxx.py` where `xxx` is the appropriate file for the current functionality
|
||||||
|
- Write all tests with pytest
|
||||||
|
|
||||||
|
### Runtime Tests
|
||||||
|
- Runtime tests are in `tests/runtime/test_*.py`
|
||||||
|
- Run tests with different runtime implementations by setting the `TEST_RUNTIME` environment variable:
|
||||||
|
```bash
|
||||||
|
# Use Docker runtime (default)
|
||||||
|
DEBUG=1 poetry run pytest -vvxss tests/runtime/test_bash.py
|
||||||
|
|
||||||
|
# Use CLI runtime (more reliable in some environments)
|
||||||
|
DEBUG=1 TEST_RUNTIME=cli poetry run pytest -vvxss tests/runtime/test_bash.py
|
||||||
|
|
||||||
|
# Run a specific test
|
||||||
|
DEBUG=1 TEST_RUNTIME=cli poetry run pytest -vvxss tests/runtime/test_bash.py::test_bash_server
|
||||||
|
```
|
||||||
|
- **IMPORTANT**: Runtime tests can take a long time to run, especially when building Docker images. Set a high timeout value:
|
||||||
|
```
|
||||||
|
execute_bash(command="DEBUG=1 poetry run pytest -vvxss tests/runtime/test_bash.py", timeout=600)
|
||||||
|
```
|
||||||
|
- The `DEBUG=1` flag enables more verbose logging
|
||||||
|
- The `-vvxss` flags make the test output more verbose and stop after the first failure
|
||||||
|
|
||||||
|
### Debugging Docker Issues
|
||||||
|
- Check Docker container status:
|
||||||
|
```bash
|
||||||
|
sudo docker ps -a
|
||||||
|
```
|
||||||
|
- View Docker logs:
|
||||||
|
```bash
|
||||||
|
sudo docker logs <container_id>
|
||||||
|
```
|
||||||
|
- Check Docker daemon logs:
|
||||||
|
```bash
|
||||||
|
sudo cat /tmp/docker.log | tail -n 100
|
||||||
|
```
|
||||||
|
- Check OpenHands logs:
|
||||||
|
```bash
|
||||||
|
cat logs/openhands_*.log | grep -i error | tail -n 20
|
||||||
|
```
|
||||||
|
|
||||||
## Repository Structure
|
## Repository Structure
|
||||||
Backend:
|
Backend:
|
||||||
- Located in the `openhands` directory
|
- Located in the `openhands` directory
|
||||||
- Testing:
|
|
||||||
- All tests are in `tests/unit/test_*.py`
|
|
||||||
- To test new code, run `poetry run pytest tests/unit/test_xxx.py` where `xxx` is the appropriate file for the current functionality
|
|
||||||
- Write all tests with pytest
|
|
||||||
|
|
||||||
Frontend:
|
Frontend:
|
||||||
- Located in the `frontend` directory
|
- Located in the `frontend` directory
|
||||||
@@ -50,6 +126,13 @@ Frontend:
|
|||||||
|
|
||||||
If you are starting a pull request (PR), please follow the template in `.github/pull_request_template.md`.
|
If you are starting a pull request (PR), please follow the template in `.github/pull_request_template.md`.
|
||||||
|
|
||||||
|
## Runtime Architecture
|
||||||
|
- OpenHands uses a Docker-based runtime for secure execution of agent actions
|
||||||
|
- The runtime builds a custom Docker image based on a specified base image
|
||||||
|
- The image includes OpenHands-specific code and the runtime client
|
||||||
|
- The runtime client executes actions in the sandboxed environment and returns observations
|
||||||
|
- More details in the [runtime architecture documentation](https://docs.all-hands.dev/usage/architecture/runtime)
|
||||||
|
|
||||||
## Implementation Details
|
## Implementation Details
|
||||||
|
|
||||||
These details may or may not be useful for your current task.
|
These details may or may not be useful for your current task.
|
||||||
@@ -80,4 +163,4 @@ These details may or may not be useful for your current task.
|
|||||||
- Add the translation key to `frontend/src/i18n/declaration.ts`
|
- Add the translation key to `frontend/src/i18n/declaration.ts`
|
||||||
2. Add the setting to the backend:
|
2. Add the setting to the backend:
|
||||||
- Add the setting to the `Settings` model in `openhands/storage/data_models/settings.py`
|
- Add the setting to the `Settings` model in `openhands/storage/data_models/settings.py`
|
||||||
- Update any relevant backend code to apply the setting (e.g., in session creation)
|
- Update any relevant backend code to apply the setting (e.g., in session creation)
|
||||||
@@ -36,7 +36,6 @@ class MCPProxyManager:
|
|||||||
Initialize the MCP Proxy Manager.
|
Initialize the MCP Proxy Manager.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
name: Name of the proxy server
|
|
||||||
auth_enabled: Whether authentication is enabled
|
auth_enabled: Whether authentication is enabled
|
||||||
api_key: API key for authentication (required if auth_enabled is True)
|
api_key: API key for authentication (required if auth_enabled is True)
|
||||||
logger_level: Logging level for the FastMCP logger
|
logger_level: Logging level for the FastMCP logger
|
||||||
@@ -59,7 +58,7 @@ class MCPProxyManager:
|
|||||||
"""
|
"""
|
||||||
if len(self.config['mcpServers']) == 0:
|
if len(self.config['mcpServers']) == 0:
|
||||||
logger.info(
|
logger.info(
|
||||||
f"No MCP servers configured for FastMCP Proxy, skipping initialization."
|
'No MCP servers configured for FastMCP Proxy, skipping initialization.'
|
||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -70,7 +69,7 @@ class MCPProxyManager:
|
|||||||
api_key=self.api_key,
|
api_key=self.api_key,
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.info(f"FastMCP Proxy initialized successfully")
|
logger.info('FastMCP Proxy initialized successfully')
|
||||||
|
|
||||||
async def mount_to_app(
|
async def mount_to_app(
|
||||||
self, app: FastAPI, allow_origins: Optional[list[str]] = None
|
self, app: FastAPI, allow_origins: Optional[list[str]] = None
|
||||||
@@ -83,9 +82,7 @@ class MCPProxyManager:
|
|||||||
allow_origins: List of allowed origins for CORS
|
allow_origins: List of allowed origins for CORS
|
||||||
"""
|
"""
|
||||||
if len(self.config['mcpServers']) == 0:
|
if len(self.config['mcpServers']) == 0:
|
||||||
logger.info(
|
logger.info('No MCP servers configured for FastMCP Proxy, skipping mount.')
|
||||||
f"No MCP servers configured for FastMCP Proxy, skipping mount."
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if not self.proxy:
|
if not self.proxy:
|
||||||
@@ -101,8 +98,7 @@ class MCPProxyManager:
|
|||||||
app.routes.remove('/mcp')
|
app.routes.remove('/mcp')
|
||||||
|
|
||||||
app.mount('/', mcp_app)
|
app.mount('/', mcp_app)
|
||||||
logger.info(f"Mounted FastMCP Proxy app at /mcp")
|
logger.info('Mounted FastMCP Proxy app at /mcp')
|
||||||
|
|
||||||
|
|
||||||
async def update_and_remount(
|
async def update_and_remount(
|
||||||
self,
|
self,
|
||||||
@@ -119,13 +115,10 @@ class MCPProxyManager:
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
app: FastAPI application to mount to
|
app: FastAPI application to mount to
|
||||||
tools: List of tool configurations
|
stdio_servers: List of stdio server configurations
|
||||||
allow_origins: List of allowed origins for CORS
|
allow_origins: List of allowed origins for CORS
|
||||||
"""
|
"""
|
||||||
tools = {
|
tools = {t.name: t.model_dump() for t in stdio_servers}
|
||||||
t.name: t.model_dump()
|
|
||||||
for t in stdio_servers
|
|
||||||
}
|
|
||||||
self.config['mcpServers'] = tools
|
self.config['mcpServers'] = tools
|
||||||
|
|
||||||
del self.proxy
|
del self.proxy
|
||||||
|
|||||||
Reference in New Issue
Block a user