Compare commits

..

3 Commits

Author SHA1 Message Date
openhands
1385d92447 refactor: Set git_dir during clone_or_init_repo and remove cwd params 2025-04-25 20:02:05 +00:00
openhands
74f5b24144 refactor: Simplify GitHandler to always use async functions 2025-04-25 19:44:46 +00:00
openhands
e8d51a0878 feat: Make git functions in runtime/base.py async 2025-04-25 19:42:13 +00:00
1717 changed files with 86163 additions and 153187 deletions

View File

@@ -1,19 +0,0 @@
// For format details, see: https://aka.ms/devcontainer.json
{
"name": "Python 3",
// Documentation for this image:
// - https://github.com/devcontainers/templates/tree/main/src/python
// - https://github.com/microsoft/vscode-remote-try-python
// - https://hub.docker.com/r/microsoft/devcontainers-python
"image": "mcr.microsoft.com/devcontainers/python:1-3.12-bullseye",
"features": {
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {},
"ghcr.io/devcontainers-extra/features/poetry:2": {},
"ghcr.io/devcontainers/features/node:1": {},
},
"postCreateCommand": ".devcontainer/setup.sh",
"runArgs": ["--add-host=host.docker.internal:host-gateway"],
"containerEnv": {
"DOCKER_HOST_ADDR": "host.docker.internal"
},
}

View File

@@ -1,11 +0,0 @@
#!/bin/bash
# Mark the current repository as safe for Git to prevent "dubious ownership" errors,
# which can occur in containerized environments when directory ownership doesn't match the current user.
git config --global --add safe.directory "$(realpath .)"
# Install `nc`
sudo apt update && sudo apt install netcat -y
# Do common setup tasks
source .openhands/setup.sh

View File

@@ -1,23 +1,5 @@
# NodeJS
frontend/node_modules
# Configuration (except pyproject.toml)
*.ini
*.toml
!pyproject.toml
*.yml
# Documentation (except README.md)
*.md
!README.md
# Hidden files and directories
.*
__pycache__
# Unneded files and directories
/dev_config/
/docs/
/evaluation/
/tests/
CITATION.cff
config.toml
.envrc
.env
.git

View File

@@ -1,5 +0,0 @@
[*]
# force *nix line endings so files don't look modified in container run from Windows clone
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true

6
.gitattributes vendored
View File

@@ -1,7 +1 @@
*.ipynb linguist-vendored
# force *nix line endings so files don't look modified in container run from Windows clone
* text eol=lf
# Git incorrectly thinks some media is text
*.png -text
*.mp4 -text

19
.github/.codecov.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
codecov:
notify:
wait_for_ci: true
# our project is large, so 6 builds are typically uploaded. this waits till 5/6
# See https://docs.codecov.com/docs/notifications#section-preventing-notifications-until-after-n-builds
after_n_builds: 5
coverage:
status:
patch:
default:
threshold: 100% # allow patch coverage to be lower than project coverage by any amount
project:
default:
threshold: 5% # allow project coverage to drop at most 5%
comment: false
github_checks:
annotations: false

12
.github/CODEOWNERS vendored
View File

@@ -1,12 +0,0 @@
# CODEOWNERS file for OpenHands repository
# See https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
# Frontend code owners
/frontend/ @amanape
/openhands-ui/ @amanape
# Evaluation code owners
/evaluation/ @xingyaoww @neubig
# Documentation code owners
/docs/ @mamoodi

View File

@@ -33,7 +33,6 @@ body:
- Docker command in README
- GitHub resolver
- Development workflow
- CLI
- app.all-hands.dev
- Other
default: 0
@@ -45,13 +44,6 @@ body:
description: What version of OpenHands are you using?
placeholder: ex. 0.9.8, main, etc.
- type: input
id: model-name
attributes:
label: Model Name
description: What model are you using?
placeholder: ex. gpt-4o, claude-3-5-sonnet, openrouter/deepseek-r1, etc.
- type: dropdown
id: os
attributes:

View File

@@ -13,9 +13,6 @@ updates:
browsergym:
patterns:
- "browsergym*"
mcp-packages:
patterns:
- "mcp"
security-all:
applies-to: "security-updates"
patterns:
@@ -72,9 +69,3 @@ updates:
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "docker"
directories:
- "containers/*"
schedule:
interval: "weekly"

View File

@@ -1,12 +1,12 @@
- [ ] This change is worth documenting at https://docs.all-hands.dev/
- [ ] Include this change in the Release Notes. If checked, you **must** provide an **end-user friendly** description for your change below
**End-user friendly description of the problem this fixes or functionality this introduces.**
**End-user friendly description of the problem this fixes or functionality that this introduces.**
---
**Summarize what the PR does, explaining any non-trivial design decisions.**
**Give a summary of what the PR does, explaining any non-trivial design decisions.**
---
**Link of any specific issues this addresses:**
**Link of any specific issues this addresses.**

View File

@@ -2,9 +2,10 @@
import os
import re
import sys
from typing import Set, Tuple
def find_version_references(directory: str) -> tuple[set[str], set[str]]:
def find_version_references(directory: str) -> Tuple[Set[str], Set[str]]:
openhands_versions = set()
runtime_versions = set()

View File

@@ -1,71 +0,0 @@
#!/bin/bash
set -euxo pipefail
# This script updates the PR description with commands to run the PR locally
# It adds both Docker and uvx commands
# Get the branch name for the PR
BRANCH_NAME=$(gh pr view "$PR_NUMBER" --json headRefName --jq .headRefName)
# Define the Docker command
DOCKER_RUN_COMMAND="docker run -it --rm \
-p 3000:3000 \
-v /var/run/docker.sock:/var/run/docker.sock \
--add-host host.docker.internal:host-gateway \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:${SHORT_SHA}-nikolaik \
--name openhands-app-${SHORT_SHA} \
docker.all-hands.dev/all-hands-ai/openhands:${SHORT_SHA}"
# Define the uvx command
UVX_RUN_COMMAND="uvx --python 3.12 --from git+https://github.com/All-Hands-AI/OpenHands@${BRANCH_NAME} openhands"
# Get the current PR body
PR_BODY=$(gh pr view "$PR_NUMBER" --json body --jq .body)
# Prepare the new PR body with both commands
if echo "$PR_BODY" | grep -q "To run this PR locally, use the following command:"; then
# For existing PR descriptions, use a more robust approach
# Split the PR body at the "To run this PR locally" section and replace everything after it
BEFORE_SECTION=$(echo "$PR_BODY" | sed '/To run this PR locally, use the following command:/,$d')
NEW_PR_BODY=$(cat <<EOF
${BEFORE_SECTION}
To run this PR locally, use the following command:
GUI with Docker:
\`\`\`
${DOCKER_RUN_COMMAND}
\`\`\`
CLI with uvx:
\`\`\`
${UVX_RUN_COMMAND}
\`\`\`
EOF
)
else
# For new PR descriptions: use heredoc safely without indentation
NEW_PR_BODY=$(cat <<EOF
$PR_BODY
---
To run this PR locally, use the following command:
GUI with Docker:
\`\`\`
${DOCKER_RUN_COMMAND}
\`\`\`
CLI with uvx:
\`\`\`
${UVX_RUN_COMMAND}
\`\`\`
EOF
)
fi
# Update the PR description
echo "Updating PR description with Docker and uvx commands"
gh pr edit "$PR_NUMBER" --body "$NEW_PR_BODY"

72
.github/workflows/deploy-docs.yml vendored Normal file
View File

@@ -0,0 +1,72 @@
# Workflow that builds and deploys the documentation website
name: Deploy Docs to GitHub Pages
# * Always run on "main"
# * Run on PRs that target the "main" branch and have changes in the "docs" folder or this workflow
on:
push:
branches:
- main
pull_request:
paths:
- 'docs/**'
- '.github/workflows/deploy-docs.yml'
branches:
- main
# If triggered by a PR, it will be in the same group. However, each commit on main will be in its own unique group
concurrency:
group: ${{ github.workflow }}-${{ (github.head_ref && github.ref) || github.run_id }}
cancel-in-progress: true
jobs:
# Build the documentation website
build:
if: github.repository == 'All-Hands-AI/OpenHands'
name: Build Docusaurus
runs-on: blacksmith-4vcpu-ubuntu-2204
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: useblacksmith/setup-node@v5
with:
node-version: 18
cache: npm
cache-dependency-path: docs/package-lock.json
- name: Set up Python
uses: useblacksmith/setup-python@v6
with:
python-version: '3.12'
- name: Install dependencies
run: cd docs && npm ci
- name: Build website
run: cd docs && npm run build
- name: Upload Build Artifact
if: github.ref == 'refs/heads/main'
uses: actions/upload-pages-artifact@v3
with:
path: docs/build
# Deploy the documentation website
deploy:
if: github.ref == 'refs/heads/main' && github.repository == 'All-Hands-AI/OpenHands'
name: Deploy to GitHub Pages
runs-on: blacksmith-4vcpu-ubuntu-2204
# This job only runs on "main" so only run one of these jobs at a time
# otherwise it will fail if one is already running
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
needs: build
# Grant GITHUB_TOKEN the permissions required to make a Pages deployment
permissions:
pages: write # to deploy to Pages
id-token: write # to verify the deployment originates from an appropriate source
# Deploy to the github-pages environment
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4

View File

@@ -1,227 +0,0 @@
name: End-to-End Tests
on:
pull_request:
types: [opened, synchronize, reopened, labeled]
branches:
- main
- develop
workflow_dispatch:
jobs:
e2e-tests:
if: contains(github.event.pull_request.labels.*.name, 'end-to-end') || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
timeout-minutes: 60
env:
GITHUB_REPO_NAME: ${{ github.repository }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install poetry via pipx
uses: abatilo/actions-poetry@v4
with:
poetry-version: 2.1.3
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'poetry'
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-0 libnotify4 libnss3 libxss1 libxtst6 xauth xvfb libgbm1 libasound2t64 netcat-openbsd
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
cache-dependency-path: 'frontend/package-lock.json'
- name: Setup environment for end-to-end tests
run: |
# Create test results directory
mkdir -p test-results
# Create downloads directory for OpenHands (use a directory in the home folder)
mkdir -p $HOME/downloads
sudo chown -R $USER:$USER $HOME/downloads
sudo chmod -R 755 $HOME/downloads
- name: Build OpenHands
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
LLM_MODEL: ${{ secrets.LLM_MODEL || 'gpt-4o' }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY || 'test-key' }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
INSTALL_DOCKER: 1
RUNTIME: docker
FRONTEND_PORT: 12000
FRONTEND_HOST: 0.0.0.0
BACKEND_HOST: 0.0.0.0
BACKEND_PORT: 3000
ENABLE_BROWSER: true
INSTALL_PLAYWRIGHT: 1
run: |
# Fix poetry.lock file if needed
echo "Fixing poetry.lock file if needed..."
poetry lock
# Build OpenHands using make build
echo "Running make build..."
make build
# Install Chromium Headless Shell for Playwright (needed for pytest-playwright)
echo "Installing Chromium Headless Shell for Playwright..."
poetry run playwright install chromium-headless-shell
# Verify Playwright browsers are installed (for e2e tests only)
echo "Verifying Playwright browsers installation for e2e tests..."
BROWSER_CHECK=$(poetry run python tests/e2e/check_playwright.py 2>/dev/null)
if [ "$BROWSER_CHECK" != "chromium_found" ]; then
echo "ERROR: Chromium browser not found or not working for e2e tests"
echo "$BROWSER_CHECK"
exit 1
else
echo "Playwright browsers are properly installed for e2e tests."
fi
# Docker runtime will handle workspace directory creation
# Start the application using make run with custom parameters and reduced logging
echo "Starting OpenHands using make run..."
# Set environment variables to reduce logging verbosity
export PYTHONUNBUFFERED=1
export LOG_LEVEL=WARNING
export UVICORN_LOG_LEVEL=warning
export OPENHANDS_LOG_LEVEL=WARNING
FRONTEND_PORT=12000 FRONTEND_HOST=0.0.0.0 BACKEND_HOST=0.0.0.0 make run > /tmp/openhands-e2e-test.log 2>&1 &
# Store the PID of the make run process
MAKE_PID=$!
echo "OpenHands started with PID: $MAKE_PID"
# Wait for the application to start
echo "Waiting for OpenHands to start..."
max_attempts=15
attempt=1
while [ $attempt -le $max_attempts ]; do
echo "Checking if OpenHands is running (attempt $attempt of $max_attempts)..."
# Check if the process is still running
if ! ps -p $MAKE_PID > /dev/null; then
echo "ERROR: OpenHands process has terminated unexpectedly"
echo "Last 50 lines of the log:"
tail -n 50 /tmp/openhands-e2e-test.log
exit 1
fi
# Check if frontend port is open
if nc -z localhost 12000; then
# Verify we can get HTML content
if curl -s http://localhost:12000 | grep -q "<html"; then
echo "SUCCESS: OpenHands is running and serving HTML content on port 12000"
break
else
echo "Port 12000 is open but not serving HTML content yet"
fi
else
echo "Frontend port 12000 is not open yet"
fi
# Show log output on each attempt
echo "Recent log output:"
tail -n 20 /tmp/openhands-e2e-test.log
# Wait before next attempt
echo "Waiting 10 seconds before next check..."
sleep 10
attempt=$((attempt + 1))
# Exit if we've reached the maximum number of attempts
if [ $attempt -gt $max_attempts ]; then
echo "ERROR: OpenHands failed to start after $max_attempts attempts"
echo "Last 50 lines of the log:"
tail -n 50 /tmp/openhands-e2e-test.log
exit 1
fi
done
# Final verification that the app is running
if ! nc -z localhost 12000 || ! curl -s http://localhost:12000 | grep -q "<html"; then
echo "ERROR: OpenHands is not running properly on port 12000"
echo "Last 50 lines of the log:"
tail -n 50 /tmp/openhands-e2e-test.log
exit 1
fi
# Print success message
echo "OpenHands is running successfully on port 12000"
- name: Run end-to-end tests
env:
GITHUB_TOKEN: ${{ secrets.E2E_TEST_GITHUB_TOKEN }}
LLM_MODEL: ${{ secrets.LLM_MODEL || 'gpt-4o' }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY || 'test-key' }}
LLM_BASE_URL: ${{ secrets.LLM_BASE_URL }}
run: |
# Check if the application is running
if ! nc -z localhost 12000; then
echo "ERROR: OpenHands is not running on port 12000"
echo "Last 50 lines of the log:"
tail -n 50 /tmp/openhands-e2e-test.log
exit 1
fi
# Run the tests with detailed output
cd tests/e2e
poetry run python -m pytest \
test_settings.py::test_github_token_configuration \
test_conversation.py::test_conversation_start \
test_browsing_catchphrase.py::test_browsing_catchphrase \
-v --no-header --capture=no --timeout=900
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: tests/e2e/test-results/
retention-days: 30
- name: Upload OpenHands logs
if: always()
uses: actions/upload-artifact@v4
with:
name: openhands-logs
path: |
/tmp/openhands-e2e-test.log
/tmp/openhands-e2e-build.log
/tmp/openhands-backend.log
/tmp/openhands-frontend.log
/tmp/backend-health-check.log
/tmp/frontend-check.log
/tmp/vite-config.log
/tmp/makefile-contents.log
retention-days: 30
- name: Cleanup
if: always()
run: |
# Stop OpenHands processes
echo "Stopping OpenHands processes..."
pkill -f "python -m openhands.server" || true
pkill -f "npm run dev" || true
pkill -f "make run" || true
# Print process status for debugging
echo "Checking if any OpenHands processes are still running:"
ps aux | grep -E "openhands|npm run dev" || true

View File

@@ -9,8 +9,8 @@ on:
- main
pull_request:
paths:
- "frontend/**"
- ".github/workflows/fe-unit-tests.yml"
- 'frontend/**'
- '.github/workflows/fe-unit-tests.yml'
# If triggered by a PR, it will be in the same group. However, each commit on main will be in its own unique group
concurrency:
@@ -24,7 +24,7 @@ jobs:
runs-on: blacksmith-4vcpu-ubuntu-2204
strategy:
matrix:
node-version: [22]
node-version: [20, 22]
fail-fast: true
steps:
- name: Checkout
@@ -38,7 +38,11 @@ jobs:
run: npm ci
- name: Run TypeScript compilation
working-directory: ./frontend
run: npm run build
run: npm run make-i18n && tsc
- name: Run tests and collect coverage
working-directory: ./frontend
run: npm run test:coverage
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -40,8 +40,7 @@ jobs:
# Only build nikolaik on PRs, otherwise build both nikolaik and ubuntu.
if [[ "$GITHUB_EVENT_NAME" == "pull_request" ]]; then
json=$(jq -n -c '[
{ image: "nikolaik/python-nodejs:python3.12-nodejs22", tag: "nikolaik" },
{ image: "ubuntu:24.04", tag: "ubuntu" }
{ image: "nikolaik/python-nodejs:python3.12-nodejs22", tag: "nikolaik" }
]')
else
json=$(jq -n -c '[
@@ -55,10 +54,12 @@ jobs:
ghcr_build_app:
name: Build App Image
runs-on: blacksmith-4vcpu-ubuntu-2204
if: "!(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/ext-v'))"
permissions:
contents: read
packages: write
outputs:
# Since this job uses outputs it cannot use matrix
hash_from_app_image: ${{ steps.get_hash_in_app_image.outputs.hash_from_app_image }}
steps:
- name: Checkout
uses: actions/checkout@v4
@@ -84,12 +85,24 @@ jobs:
if: "!github.event.pull_request.head.repo.fork"
run: |
./containers/build.sh -i openhands -o ${{ env.REPO_OWNER }} --push
- name: Build app image
if: "github.event.pull_request.head.repo.fork"
run: |
./containers/build.sh -i openhands -o ${{ env.REPO_OWNER }} --load
- name: Get hash in App Image
id: get_hash_in_app_image
run: |
# Run the build script in the app image
docker run -e SANDBOX_USER_ID=0 -v /var/run/docker.sock:/var/run/docker.sock ghcr.io/${{ env.REPO_OWNER }}/openhands:${{ env.RELEVANT_SHA }} /bin/bash -c "mkdir -p containers/runtime; python3 openhands/runtime/utils/runtime_build.py --base_image ${{ env.BASE_IMAGE_FOR_HASH_EQUIVALENCE_TEST }} --build_folder containers/runtime --force_rebuild" 2>&1 | tee docker-outputs.txt
# Get the hash from the build script
hash_from_app_image=$(cat docker-outputs.txt | grep "Hash for docker build directory" | awk -F "): " '{print $2}' | uniq | head -n1)
echo "hash_from_app_image=$hash_from_app_image" >> $GITHUB_OUTPUT
echo "Hash from app image: $hash_from_app_image"
# Builds the runtime Docker images
ghcr_build_runtime:
name: Build Image
runs-on: blacksmith-8vcpu-ubuntu-2204
if: "!(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/ext-v'))"
runs-on: blacksmith-4vcpu-ubuntu-2204
permissions:
contents: read
packages: write
@@ -115,13 +128,22 @@ jobs:
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
- name: Install poetry via pipx
run: pipx install poetry
- name: Set up Python
uses: useblacksmith/setup-python@v6
with:
python-version: '3.12'
cache: poetry
- name: Cache Poetry dependencies
uses: useblacksmith/cache@v5
with:
path: |
~/.cache/pypoetry
~/.virtualenvs
key: ${{ runner.os }}-poetry-${{ hashFiles('**/poetry.lock') }}
# This is the one that saves the cache, the others set 'lookup-only: true'
restore-keys: |
${{ runner.os }}-poetry-
- name: Install poetry via pipx
run: pipx install poetry
- name: Install Python dependencies using Poetry
run: make install-python-dependencies POETRY_GROUP=main INSTALL_PLAYWRIGHT=0
- name: Create source distribution and Dockerfile
@@ -166,6 +188,61 @@ jobs:
name: runtime-src-${{ matrix.base_image.tag }}
path: containers/runtime
verify_hash_equivalence_in_runtime_and_app:
name: Verify Hash Equivalence in Runtime and Docker images
runs-on: blacksmith-4vcpu-ubuntu-2204
needs: [ghcr_build_runtime, ghcr_build_app]
strategy:
fail-fast: false
matrix:
base_image: ['nikolaik']
env:
BASE_IMAGE_FOR_HASH_EQUIVALENCE_TEST: nikolaik/python-nodejs:python3.12-nodejs22
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Cache Poetry dependencies
uses: useblacksmith/cache@v5
with:
path: |
~/.cache/pypoetry
~/.virtualenvs
key: ${{ runner.os }}-poetry-${{ hashFiles('**/poetry.lock') }}
lookup-only: true
restore-keys: |
${{ runner.os }}-poetry-
- name: Set up Python
uses: useblacksmith/setup-python@v6
with:
python-version: '3.12'
- name: Install poetry via pipx
run: pipx install poetry
- name: Install Python dependencies using Poetry
run: make install-python-dependencies POETRY_GROUP=main INSTALL_PLAYWRIGHT=0
- name: Get hash in App Image
run: |
echo "Hash from app image: ${{ needs.ghcr_build_app.outputs.hash_from_app_image }}"
echo "hash_from_app_image=${{ needs.ghcr_build_app.outputs.hash_from_app_image }}" >> $GITHUB_ENV
- name: Get hash using code (development mode)
run: |
mkdir -p containers/runtime
poetry run python3 openhands/runtime/utils/runtime_build.py --base_image ${{ env.BASE_IMAGE_FOR_HASH_EQUIVALENCE_TEST }} --build_folder containers/runtime --force_rebuild > output.txt 2>&1
hash_from_code=$(cat output.txt | grep "Hash for docker build directory" | awk -F "): " '{print $2}' | uniq | head -n1)
echo "hash_from_code=$hash_from_code" >> $GITHUB_ENV
- name: Compare hashes
run: |
echo "Hash from App Image: ${{ env.hash_from_app_image }}"
echo "Hash from Code: ${{ env.hash_from_code }}"
if [ "${{ env.hash_from_app_image }}" = "${{ env.hash_from_code }}" ]; then
echo "Hashes match!"
else
echo "Hashes do not match!"
exit 1
fi
# Run unit tests with the Docker runtime Docker images as root
test_runtime_root:
name: RT Unit Tests (Root)
@@ -197,17 +274,25 @@ jobs:
load: true
tags: ghcr.io/${{ env.REPO_OWNER }}/runtime:${{ env.RELEVANT_SHA }}-${{ matrix.base_image.tag }}
context: containers/runtime
- name: Install poetry via pipx
run: pipx install poetry
- name: Cache Poetry dependencies
uses: useblacksmith/cache@v5
with:
path: |
~/.cache/pypoetry
~/.virtualenvs
key: ${{ runner.os }}-poetry-${{ hashFiles('**/poetry.lock') }}
lookup-only: true
restore-keys: |
${{ runner.os }}-poetry-
- name: Set up Python
uses: useblacksmith/setup-python@v6
with:
python-version: '3.12'
cache: poetry
- name: Install poetry via pipx
run: pipx install poetry
- name: Install Python dependencies using Poetry
run: make install-python-dependencies INSTALL_PLAYWRIGHT=0
run: make install-python-dependencies POETRY_GROUP=main,test,runtime INSTALL_PLAYWRIGHT=0
- name: Run docker runtime tests
shell: bash
run: |
# We install pytest-xdist in order to run tests across CPUs
poetry run pip install pytest-xdist
@@ -225,9 +310,11 @@ jobs:
SANDBOX_RUNTIME_CONTAINER_IMAGE=$image_name \
TEST_IN_CI=true \
RUN_AS_OPENHANDS=false \
poetry run pytest -n 7 -raRs --reruns 2 --reruns-delay 5 -s ./tests/runtime --ignore=tests/runtime/test_browsergym_envs.py --durations=10
poetry run pytest -n 7 -raRs --reruns 2 --reruns-delay 5 --cov=openhands --cov-report=xml -s ./tests/runtime --ignore=tests/runtime/test_browsergym_envs.py --durations=10
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
env:
DEBUG: "1"
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
# Run unit tests with the Docker runtime Docker images as openhands user
test_runtime_oh:
@@ -259,17 +346,25 @@ jobs:
load: true
tags: ghcr.io/${{ env.REPO_OWNER }}/runtime:${{ env.RELEVANT_SHA }}-${{ matrix.base_image.tag }}
context: containers/runtime
- name: Install poetry via pipx
run: pipx install poetry
- name: Cache Poetry dependencies
uses: useblacksmith/cache@v5
with:
path: |
~/.cache/pypoetry
~/.virtualenvs
key: ${{ runner.os }}-poetry-${{ hashFiles('**/poetry.lock') }}
lookup-only: true
restore-keys: |
${{ runner.os }}-poetry-
- name: Set up Python
uses: useblacksmith/setup-python@v6
with:
python-version: '3.12'
cache: poetry
- name: Install poetry via pipx
run: pipx install poetry
- name: Install Python dependencies using Poetry
run: make install-python-dependencies POETRY_GROUP=main,test,runtime INSTALL_PLAYWRIGHT=0
- name: Run runtime tests
shell: bash
run: |
# We install pytest-xdist in order to run tests across CPUs
poetry run pip install pytest-xdist
@@ -284,9 +379,11 @@ jobs:
SANDBOX_RUNTIME_CONTAINER_IMAGE=$image_name \
TEST_IN_CI=true \
RUN_AS_OPENHANDS=true \
poetry run pytest -n 7 -raRs --reruns 2 --reruns-delay 5 -s ./tests/runtime --ignore=tests/runtime/test_browsergym_envs.py --durations=10
poetry run pytest -n 7 -raRs --reruns 2 --reruns-delay 5 --cov=openhands --cov-report=xml -s ./tests/runtime --ignore=tests/runtime/test_browsergym_envs.py --durations=10
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
env:
DEBUG: "1"
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
# The two following jobs (named identically) are to check whether all the runtime tests have passed as the
# "All Runtime Tests Passed" is a required job for PRs to merge
@@ -296,7 +393,7 @@ jobs:
name: All Runtime Tests Passed
if: ${{ !cancelled() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }}
runs-on: blacksmith-4vcpu-ubuntu-2204
needs: [test_runtime_root, test_runtime_oh]
needs: [test_runtime_root, test_runtime_oh, verify_hash_equivalence_in_runtime_and_app]
steps:
- name: All tests passed
run: echo "All runtime tests have passed successfully!"
@@ -305,7 +402,7 @@ jobs:
name: All Runtime Tests Passed
if: ${{ cancelled() || contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}
runs-on: blacksmith-4vcpu-ubuntu-2204
needs: [test_runtime_root, test_runtime_oh]
needs: [test_runtime_root, test_runtime_oh, verify_hash_equivalence_in_runtime_and_app]
steps:
- name: Some tests failed
run: |
@@ -330,7 +427,30 @@ jobs:
PR_NUMBER: ${{ github.event.pull_request.number }}
REPO: ${{ github.repository }}
SHORT_SHA: ${{ steps.short_sha.outputs.SHORT_SHA }}
shell: bash
run: |
echo "Updating PR description with Docker and uvx commands"
bash ${GITHUB_WORKSPACE}/.github/scripts/update_pr_description.sh
echo "updating PR description"
DOCKER_RUN_COMMAND="docker run -it --rm \
-p 3000:3000 \
-v /var/run/docker.sock:/var/run/docker.sock \
--add-host host.docker.internal:host-gateway \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:$SHORT_SHA-nikolaik \
--name openhands-app-$SHORT_SHA \
docker.all-hands.dev/all-hands-ai/openhands:$SHORT_SHA"
PR_BODY=$(gh pr view $PR_NUMBER --json body --jq .body)
if echo "$PR_BODY" | grep -q "To run this PR locally, use the following command:"; then
UPDATED_PR_BODY=$(echo "${PR_BODY}" | sed -E "s|docker run -it --rm.*|$DOCKER_RUN_COMMAND|")
else
UPDATED_PR_BODY="${PR_BODY}
---
To run this PR locally, use the following command:
\`\`\`
$DOCKER_RUN_COMMAND
\`\`\`"
fi
echo "updated body: $UPDATED_PR_BODY"
gh pr edit $PR_NUMBER --body "$UPDATED_PR_BODY"

View File

@@ -54,7 +54,7 @@ jobs:
Hi! I started running the integration tests on your PR. You will receive a comment with the results shortly.
- name: Install Python dependencies using Poetry
run: poetry install --with dev,test,runtime,evaluation
run: poetry install --without evaluation
- name: Configure config.toml for testing with Haiku
env:
@@ -179,8 +179,8 @@ jobs:
id: create_comment
uses: KeisukeYamashita/create-comment@v1
with:
# if triggered by PR, use PR number, otherwise use 9745 as fallback issue number for manual triggers
number: ${{ github.event_name == 'pull_request' && github.event.pull_request.number || 9745 }}
# if triggered by PR, use PR number, otherwise use 5318 as fallback issue number for manual triggers
number: ${{ github.event_name == 'pull_request' && github.event.pull_request.number || 5318 }}
unique: false
comment: |
Trigger by: ${{ github.event_name == 'pull_request' && format('Pull Request (integration-test label on PR #{0})', github.event.pull_request.number) || (github.event_name == 'workflow_dispatch' && format('Manual Trigger: {0}', github.event.inputs.reason)) || 'Nightly Scheduled Run' }}

View File

@@ -21,20 +21,14 @@ jobs:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Install Node.js 22
- name: Install Node.js 20
uses: useblacksmith/setup-node@v5
with:
node-version: 22
node-version: 20
- name: Install frontend dependencies
run: |
cd frontend
npm install --frozen-lockfile
- name: Generate i18n and route types
run: |
cd frontend
npm run make-i18n
npx react-router typegen || true
- name: Fix frontend lint issues
run: |
cd frontend
@@ -51,7 +45,7 @@ jobs:
git config --local user.email "openhands@all-hands.dev"
git config --local user.name "OpenHands Bot"
git add -A
git commit -m "🤖 Auto-fix frontend linting issues" --no-verify
git commit -m "🤖 Auto-fix frontend linting issues"
git push
# Python lint fixes
@@ -74,13 +68,13 @@ jobs:
uses: useblacksmith/setup-python@v6
with:
python-version: 3.12
cache: "pip"
cache: 'pip'
- name: Install pre-commit
run: pip install pre-commit==3.7.0
- name: Fix python lint issues
run: |
# Run all pre-commit hooks and continue even if they modify files (exit code 1)
pre-commit run --config ./dev_config/python/.pre-commit-config.yaml --all-files || true
pre-commit run --config ./dev_config/python/.pre-commit-config.yaml --files openhands/**/* evaluation/**/* tests/**/* || true
# Commit and push changes if any
- name: Check for changes
@@ -93,5 +87,5 @@ jobs:
git config --local user.email "openhands@all-hands.dev"
git config --local user.name "OpenHands Bot"
git add -A
git commit -m "🤖 Auto-fix Python linting issues" --no-verify
git commit -m "🤖 Auto-fix Python linting issues"
git push

View File

@@ -7,7 +7,7 @@ name: Lint
on:
push:
branches:
- main
- main
pull_request:
# If triggered by a PR, it will be in the same group. However, each commit on main will be in its own unique group
@@ -22,20 +22,19 @@ jobs:
runs-on: blacksmith-4vcpu-ubuntu-2204
steps:
- uses: actions/checkout@v4
- name: Install Node.js 22
- name: Install Node.js 20
uses: useblacksmith/setup-node@v5
with:
node-version: 22
node-version: 20
- name: Install dependencies
run: |
cd frontend
npm install --frozen-lockfile
- name: Lint, TypeScript compilation, and translation checks
- name: Lint and TypeScript compilation
run: |
cd frontend
npm run lint
npm run make-i18n && tsc
npm run check-translation-completeness
# Run lint on the python code
lint-python:
@@ -49,11 +48,11 @@ jobs:
uses: useblacksmith/setup-python@v6
with:
python-version: 3.12
cache: "pip"
cache: 'pip'
- name: Install pre-commit
run: pip install pre-commit==3.7.0
- name: Run pre-commit hooks
run: pre-commit run --all-files --show-diff-on-failure --config ./dev_config/python/.pre-commit-config.yaml
run: pre-commit run --files openhands/**/* evaluation/**/* tests/**/* --show-diff-on-failure --config ./dev_config/python/.pre-commit-config.yaml
# Check version consistency across documentation
check-version-consistency:

View File

@@ -1,108 +0,0 @@
name: Publish OpenHands UI Package
# * Always run on "main"
# * Run on PRs that have changes in the "openhands-ui" folder or this workflow
on:
push:
branches:
- main
paths:
- "openhands-ui/**"
- ".github/workflows/npm-publish-ui.yml"
# If triggered by a PR, it will be in the same group. However, each commit on main will be in its own unique group
concurrency:
group: npm-publish-ui
cancel-in-progress: false
jobs:
check-version:
name: Check if version has changed
runs-on: blacksmith-4vcpu-ubuntu-2204
defaults:
run:
shell: bash
outputs:
should-publish: ${{ steps.version-check.outputs.should-publish }}
current-version: ${{ steps.version-check.outputs.current-version }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 2 # Need previous commit to compare
- name: Check if version changed
id: version-check
run: |
# Get current version from package.json
CURRENT_VERSION=$(jq -r .version openhands-ui/package.json)
echo "current-version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
# Check if package.json version changed in this commit
if git diff HEAD~1 HEAD --name-only | grep -q "openhands-ui/package.json"; then
# Check if the version field specifically changed
if git diff HEAD~1 HEAD openhands-ui/package.json | grep -q '"version"'; then
echo "Version changed in package.json, will publish"
echo "should-publish=true" >> $GITHUB_OUTPUT
else
echo "package.json changed but version did not change, skipping publish"
echo "should-publish=false" >> $GITHUB_OUTPUT
fi
else
echo "package.json did not change, skipping publish"
echo "should-publish=false" >> $GITHUB_OUTPUT
fi
publish:
name: Publish to npm
runs-on: blacksmith-4vcpu-ubuntu-2204
needs: check-version
if: needs.check-version.outputs.should-publish == 'true'
defaults:
run:
shell: bash
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version-file: "openhands-ui/.bun-version"
- name: Install dependencies
working-directory: ./openhands-ui
run: bun install --frozen-lockfile
- name: Build package
working-directory: ./openhands-ui
run: bun run build
- name: Check if package already exists on npm
id: npm-check
working-directory: ./openhands-ui
run: |
PACKAGE_NAME=$(jq -r .name package.json)
VERSION="${{ needs.check-version.outputs.current-version }}"
# Check if this version already exists on npm
if npm view "$PACKAGE_NAME@$VERSION" version 2>/dev/null; then
echo "Version $VERSION already exists on npm, skipping publish"
echo "already-exists=true" >> $GITHUB_OUTPUT
else
echo "Version $VERSION does not exist on npm, proceeding with publish"
echo "already-exists=false" >> $GITHUB_OUTPUT
fi
- name: Setup npm authentication
if: steps.npm-check.outputs.already-exists == 'false'
run: |
echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ~/.npmrc
- name: Publish to npm
if: steps.npm-check.outputs.already-exists == 'false'
working-directory: ./openhands-ui
run: |
# The prepublishOnly script will run automatically and build the package
npm publish
echo "✅ Successfully published @openhands/ui@${{ needs.check-version.outputs.current-version }} to npm"

View File

@@ -24,7 +24,7 @@ on:
LLM_MODEL:
required: false
type: string
default: "anthropic/claude-sonnet-4-20250514"
default: "anthropic/claude-3-5-sonnet-20241022"
LLM_API_VERSION:
required: false
type: string
@@ -34,10 +34,6 @@ on:
type: string
default: ""
description: "Custom sandbox env"
runner:
required: false
type: string
default: "ubuntu-latest"
secrets:
LLM_MODEL:
required: false
@@ -83,7 +79,7 @@ jobs:
(github.event.review.author_association == 'OWNER' || github.event.review.author_association == 'COLLABORATOR' || github.event.review.author_association == 'MEMBER')
)
)
runs-on: "${{ inputs.runner || 'ubuntu-latest' }}"
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
@@ -92,9 +88,6 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Upgrade pip
run: |
python -m pip install --upgrade pip
- name: Get latest versions and create requirements.txt
run: |
@@ -232,11 +225,11 @@ jobs:
// Perform package installation
if (isExperimentalLabel || isIssueCommentExperimental || isReviewCommentExperimental) {
console.log("Installing experimental OpenHands...");
await exec.exec("python -m pip install --upgrade pip");
await exec.exec("pip install git+https://github.com/all-hands-ai/openhands.git");
} else {
console.log("Installing from requirements.txt...");
await exec.exec("python -m pip install --upgrade pip");
await exec.exec("pip install -r /tmp/requirements.txt");
}

View File

@@ -1,85 +0,0 @@
# Workflow that runs python tests
name: Run Python Tests
# The jobs in this workflow are required, so they must run at all times
# * Always run on "main"
# * Always run on PRs
on:
push:
branches:
- main
pull_request:
# If triggered by a PR, it will be in the same group. However, each commit on main will be in its own unique group
concurrency:
group: ${{ github.workflow }}-${{ (github.head_ref && github.ref) || github.run_id }}
cancel-in-progress: true
jobs:
# Run python tests on Linux
test-on-linux:
name: Python Tests on Linux
runs-on: blacksmith-4vcpu-ubuntu-2204
env:
INSTALL_DOCKER: '0' # Set to '0' to skip Docker installation
strategy:
matrix:
python-version: ['3.12']
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
- name: Install tmux
run: sudo apt-get update && sudo apt-get install -y tmux
- name: Setup Node.js
uses: useblacksmith/setup-node@v5
with:
node-version: '22.x'
- name: Install poetry via pipx
run: pipx install poetry
- name: Set up Python
uses: useblacksmith/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
cache: 'poetry'
- name: Install Python dependencies using Poetry
run: poetry install --with dev,test,runtime
- name: Build Environment
run: make build
- name: Run Unit Tests
run: PYTHONPATH=".:$PYTHONPATH" poetry run pytest --forked -n auto -svv ./tests/unit
- name: Run Runtime Tests with CLIRuntime
run: PYTHONPATH=".:$PYTHONPATH" TEST_RUNTIME=cli poetry run pytest -svv tests/runtime/test_bash.py
# Run specific Windows python tests
test-on-windows:
name: Python Tests on Windows
runs-on: windows-latest
strategy:
matrix:
python-version: ['3.12']
steps:
- uses: actions/checkout@v4
- name: Install pipx
run: pip install pipx
- name: Install poetry via pipx
run: pipx install poetry
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'poetry'
- name: Install Python dependencies using Poetry
run: poetry install --with dev,test,runtime
- name: Run Windows unit tests
run: poetry run pytest -svv tests/unit/runtime/utils/test_windows_bash.py
env:
PYTHONPATH: ".;$env:PYTHONPATH"
DEBUG: "1"
- name: Run Windows runtime tests with LocalRuntime
run: $env:TEST_RUNTIME="local"; poetry run pytest -svv tests/runtime/test_bash.py
env:
PYTHONPATH: ".;$env:PYTHONPATH"
TEST_RUNTIME: local
DEBUG: "1"

55
.github/workflows/py-unit-tests.yml vendored Normal file
View File

@@ -0,0 +1,55 @@
# Workflow that runs python unit tests
name: Run Python Unit Tests
# The jobs in this workflow are required, so they must run at all times
# * Always run on "main"
# * Always run on PRs
on:
push:
branches:
- main
pull_request:
# If triggered by a PR, it will be in the same group. However, each commit on main will be in its own unique group
concurrency:
group: ${{ github.workflow }}-${{ (github.head_ref && github.ref) || github.run_id }}
cancel-in-progress: true
jobs:
# Run python unit tests on Linux
test-on-linux:
name: Python Unit Tests on Linux
runs-on: blacksmith-4vcpu-ubuntu-2204
env:
INSTALL_DOCKER: '0' # Set to '0' to skip Docker installation
strategy:
matrix:
python-version: ['3.12']
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
- name: Install tmux
run: sudo apt-get update && sudo apt-get install -y tmux
- name: Setup Node.js
uses: useblacksmith/setup-node@v5
with:
node-version: '22.x'
- name: Install poetry via pipx
run: pipx install poetry
- name: Set up Python
uses: useblacksmith/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
cache: 'poetry'
- name: Install Python dependencies using Poetry
run: poetry install --without evaluation
- name: Build Environment
run: make build
- name: Run Tests
run: poetry run pytest --forked -n auto --cov=openhands --cov-report=xml -svv ./tests/unit
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -1,135 +1,54 @@
# Run evaluation on a PR, after releases, or manually
# Run evaluation on a PR
name: Run Eval
# Runs when a PR is labeled with one of the "run-eval-" labels, after releases, or manually triggered
# Runs when a PR is labeled with one of the "run-eval-" labels
on:
pull_request:
types: [labeled]
release:
types: [published]
workflow_dispatch:
inputs:
branch:
description: 'Branch to evaluate'
required: true
default: 'main'
eval_instances:
description: 'Number of evaluation instances'
required: true
default: '50'
type: choice
options:
- '1'
- '2'
- '50'
- '100'
reason:
description: 'Reason for manual trigger'
required: false
default: ''
env:
# Environment variable for the master GitHub issue number where all evaluation results will be commented
# This should be set to the issue number where you want all evaluation results to be posted
MASTER_EVAL_ISSUE_NUMBER: ${{ vars.MASTER_EVAL_ISSUE_NUMBER || '0' }}
jobs:
trigger-job:
name: Trigger remote eval job
if: ${{ (github.event_name == 'pull_request' && (github.event.label.name == 'run-eval-1' || github.event.label.name == 'run-eval-2' || github.event.label.name == 'run-eval-50' || github.event.label.name == 'run-eval-100')) || github.event_name == 'release' || github.event_name == 'workflow_dispatch' }}
if: ${{ github.event.label.name == 'run-eval-xs' || github.event.label.name == 'run-eval-s' || github.event.label.name == 'run-eval-m' }}
runs-on: blacksmith-4vcpu-ubuntu-2204
steps:
- name: Checkout branch
- name: Checkout PR branch
uses: actions/checkout@v4
with:
ref: ${{ github.event_name == 'pull_request' && github.head_ref || (github.event_name == 'workflow_dispatch' && github.event.inputs.branch) || github.ref }}
ref: ${{ github.head_ref }}
- name: Set evaluation parameters
id: eval_params
- name: Trigger remote job
env:
PR_BRANCH: ${{ github.head_ref }}
run: |
REPO_URL="https://github.com/${{ github.repository }}"
echo "Repository URL: $REPO_URL"
echo "PR Branch: $PR_BRANCH"
# Determine branch based on trigger type
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
EVAL_BRANCH="${{ github.head_ref }}"
echo "PR Branch: $EVAL_BRANCH"
elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
EVAL_BRANCH="${{ github.event.inputs.branch }}"
echo "Manual Branch: $EVAL_BRANCH"
else
# For release events, use the tag name or main branch
EVAL_BRANCH="${{ github.ref_name }}"
echo "Release Branch/Tag: $EVAL_BRANCH"
fi
# Determine evaluation instances based on trigger type
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
if [[ "${{ github.event.label.name }}" == "run-eval-1" ]]; then
EVAL_INSTANCES="1"
elif [[ "${{ github.event.label.name }}" == "run-eval-2" ]]; then
EVAL_INSTANCES="2"
elif [[ "${{ github.event.label.name }}" == "run-eval-50" ]]; then
EVAL_INSTANCES="50"
elif [[ "${{ github.event.label.name }}" == "run-eval-100" ]]; then
EVAL_INSTANCES="100"
fi
elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
EVAL_INSTANCES="${{ github.event.inputs.eval_instances }}"
else
# For release events, default to 50 instances
EVAL_INSTANCES="50"
fi
echo "Evaluation instances: $EVAL_INSTANCES"
echo "repo_url=$REPO_URL" >> $GITHUB_OUTPUT
echo "eval_branch=$EVAL_BRANCH" >> $GITHUB_OUTPUT
echo "eval_instances=$EVAL_INSTANCES" >> $GITHUB_OUTPUT
- name: Trigger remote job
run: |
# Determine PR number for the remote evaluation system
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
PR_NUMBER="${{ github.event.pull_request.number }}"
else
# For non-PR triggers, use the master issue number as PR number
PR_NUMBER="${{ env.MASTER_EVAL_ISSUE_NUMBER }}"
if [[ "${{ github.event.label.name }}" == "run-eval-xs" ]]; then
EVAL_INSTANCES="1"
elif [[ "${{ github.event.label.name }}" == "run-eval-s" ]]; then
EVAL_INSTANCES="5"
elif [[ "${{ github.event.label.name }}" == "run-eval-m" ]]; then
EVAL_INSTANCES="30"
fi
curl -X POST \
-H "Authorization: Bearer ${{ secrets.PAT_TOKEN }}" \
-H "Accept: application/vnd.github+json" \
-d "{\"ref\": \"main\", \"inputs\": {\"github-repo\": \"${{ steps.eval_params.outputs.repo_url }}\", \"github-branch\": \"${{ steps.eval_params.outputs.eval_branch }}\", \"pr-number\": \"${PR_NUMBER}\", \"eval-instances\": \"${{ steps.eval_params.outputs.eval_instances }}\"}}" \
-d "{\"ref\": \"main\", \"inputs\": {\"github-repo\": \"${REPO_URL}\", \"github-branch\": \"${PR_BRANCH}\", \"pr-number\": \"${{ github.event.pull_request.number }}\", \"eval-instances\": \"${EVAL_INSTANCES}\"}}" \
https://api.github.com/repos/All-Hands-AI/evaluation/actions/workflows/create-branch.yml/dispatches
# Send Slack message
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
TRIGGER_URL="https://github.com/${{ github.repository }}/pull/${{ github.event.pull_request.number }}"
slack_text="PR $TRIGGER_URL has triggered evaluation on ${{ steps.eval_params.outputs.eval_instances }} instances..."
elif [[ "${{ github.event_name }}" == "release" ]]; then
TRIGGER_URL="https://github.com/${{ github.repository }}/releases/tag/${{ github.ref_name }}"
slack_text="Release $TRIGGER_URL has triggered evaluation on ${{ steps.eval_params.outputs.eval_instances }} instances..."
else
TRIGGER_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
slack_text="Manual trigger (${{ github.event.inputs.reason || 'No reason provided' }}) has triggered evaluation on ${{ steps.eval_params.outputs.eval_instances }} instances for branch ${{ steps.eval_params.outputs.eval_branch }}..."
fi
PR_URL="https://github.com/${{ github.repository }}/pull/${{ github.event.pull_request.number }}"
slack_text="PR $PR_URL has triggered evaluation on $EVAL_INSTANCES instances..."
curl -X POST -H 'Content-type: application/json' --data '{"text":"'"$slack_text"'"}' \
https://hooks.slack.com/services/${{ secrets.SLACK_TOKEN }}
- name: Comment on issue/PR
- name: Comment on PR
uses: KeisukeYamashita/create-comment@v1
with:
# For PR triggers, comment on the PR. For other triggers, comment on the master issue
number: ${{ github.event_name == 'pull_request' && github.event.pull_request.number || env.MASTER_EVAL_ISSUE_NUMBER }}
unique: false
comment: |
**Evaluation Triggered**
**Trigger:** ${{ github.event_name == 'pull_request' && format('Pull Request #{0}', github.event.pull_request.number) || (github.event_name == 'release' && 'Release') || format('Manual Trigger: {0}', github.event.inputs.reason || 'No reason provided') }}
**Branch:** ${{ steps.eval_params.outputs.eval_branch }}
**Instances:** ${{ steps.eval_params.outputs.eval_instances }}
**Commit:** ${{ github.sha }}
Running evaluation on the specified branch. Once eval is done, the results will be posted here.
Running evaluation on the PR. Once eval is done, the results will be posted.

View File

@@ -12,11 +12,11 @@ jobs:
steps:
- uses: actions/stale@v9
with:
stale-issue-message: 'This issue is stale because it has been open for 40 days with no activity. Remove the stale label or leave a comment, otherwise it will be closed in 10 days.'
stale-pr-message: 'This PR is stale because it has been open for 40 days with no activity. Remove the stale label or leave a comment, otherwise it will be closed in 10 days.'
days-before-stale: 40
exempt-issue-labels: 'roadmap'
close-issue-message: 'This issue was automatically closed due to 50 days of inactivity. We do this to help keep the issues somewhat manageable and focus on active issues.'
close-pr-message: 'This PR was closed because it had no activity for 50 days. If you feel this was closed in error, and you would like to continue the PR, please resubmit or let us know.'
days-before-close: 10
stale-issue-message: 'This issue is stale because it has been open for 30 days with no activity. Remove stale label or comment or this will be closed in 7 days.'
stale-pr-message: 'This PR is stale because it has been open for 30 days with no activity. Remove stale label or comment or this will be closed in 7 days.'
days-before-stale: 30
exempt-issue-labels: 'tracked'
close-issue-message: 'This issue was closed because it has been stalled for over 30 days with no activity.'
close-pr-message: 'This PR was closed because it has been stalled for over 30 days with no activity.'
days-before-close: 7
operations-per-run: 150

View File

@@ -1,34 +0,0 @@
name: Run UI Component Build
# * Always run on "main"
# * Run on PRs that have changes in the "openhands-ui" folder or this workflow
on:
push:
branches:
- main
pull_request:
paths:
- 'openhands-ui/**'
- '.github/workflows/ui-build.yml'
# If triggered by a PR, it will be in the same group. However, each commit on main will be in its own unique group
concurrency:
group: ${{ github.workflow }}-${{ (github.head_ref && github.ref) || github.run_id }}
cancel-in-progress: true
jobs:
ui-build:
name: Build openhands-ui
runs-on: blacksmith-4vcpu-ubuntu-2204
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
with:
bun-version-file: "openhands-ui/.bun-version"
- name: Install dependencies
working-directory: ./openhands-ui
run: bun install --frozen-lockfile
- name: Build package
working-directory: ./openhands-ui
run: bun run build

View File

@@ -1,156 +0,0 @@
# Workflow that validates the VSCode extension builds correctly
name: VSCode Extension CI
# * Always run on "main"
# * Run on PRs that have changes in the VSCode extension folder or this workflow
# * Run on tags that start with "ext-v"
on:
push:
branches:
- main
tags:
- 'ext-v*'
pull_request:
paths:
- 'openhands/integrations/vscode/**'
- 'build_vscode.py'
- '.github/workflows/vscode-extension-build.yml'
# If triggered by a PR, it will be in the same group. However, each commit on main will be in its own unique group
concurrency:
group: ${{ github.workflow }}-${{ (github.head_ref && github.ref) || github.run_id }}
cancel-in-progress: true
jobs:
# Validate VSCode extension builds correctly
validate-vscode-extension:
name: Validate VSCode Extension Build
runs-on: blacksmith-4vcpu-ubuntu-2204
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Node.js
uses: useblacksmith/setup-node@v5
with:
node-version: '22'
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install VSCode extension dependencies
working-directory: ./openhands/integrations/vscode
run: npm ci
- name: Build VSCode extension via build_vscode.py
run: python build_vscode.py
env:
# Ensure we don't skip the build
SKIP_VSCODE_BUILD: ""
- name: Validate .vsix file
run: |
# Verify the .vsix was created and is valid
if [ -f "openhands/integrations/vscode/openhands-vscode-0.0.1.vsix" ]; then
echo "✅ VSCode extension built successfully"
ls -la openhands/integrations/vscode/openhands-vscode-0.0.1.vsix
# Basic validation that the .vsix is a valid zip file
echo "🔍 Validating .vsix structure..."
file openhands/integrations/vscode/openhands-vscode-0.0.1.vsix
unzip -t openhands/integrations/vscode/openhands-vscode-0.0.1.vsix
echo "✅ VSCode extension validation passed"
else
echo "❌ VSCode extension build failed - .vsix not found"
exit 1
fi
- name: Upload VSCode extension artifact
uses: actions/upload-artifact@v4
with:
name: vscode-extension
path: openhands/integrations/vscode/openhands-vscode-0.0.1.vsix
retention-days: 7
- name: Comment on PR with artifact link
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const path = require('path');
// Get file size for display
const vsixPath = 'openhands/integrations/vscode/openhands-vscode-0.0.1.vsix';
const stats = fs.statSync(vsixPath);
const fileSizeKB = Math.round(stats.size / 1024);
const comment = `## 🔧 VSCode Extension Built Successfully!
The VSCode extension has been built and is ready for testing.
**📦 Download**: [openhands-vscode-0.0.1.vsix](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) (${fileSizeKB} KB)
**🚀 To install**:
1. Download the artifact from the workflow run above
2. In VSCode: \`Ctrl+Shift+P\` → "Extensions: Install from VSIX..."
3. Select the downloaded \`.vsix\` file
**✅ Tested with**: Node.js 22
**🔍 Validation**: File structure and integrity verified
---
*Built from commit ${{ github.sha }}*`;
// Check if we already commented on this PR and delete it
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const botComment = comments.find(comment =>
comment.user.login === 'github-actions[bot]' &&
comment.body.includes('VSCode Extension Built Successfully')
);
if (botComment) {
await github.rest.issues.deleteComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
});
}
// Create a new comment
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: comment
});
release:
name: Create GitHub Release
runs-on: blacksmith-4vcpu-ubuntu-2204
needs: validate-vscode-extension
if: startsWith(github.ref, 'refs/tags/ext-v')
steps:
- name: Download .vsix artifact
uses: actions/download-artifact@v4
with:
name: vscode-extension
path: ./
- name: Create Release
uses: ncipollo/release-action@v1.16.0
with:
artifacts: "*.vsix"
token: ${{ secrets.GITHUB_TOKEN }}
draft: true
allowUpdates: true

View File

@@ -1,50 +0,0 @@
name: Welcome Good First Issue
on:
issues:
types: [labeled]
permissions:
issues: write
jobs:
comment-on-good-first-issue:
if: github.event.label.name == 'good first issue'
runs-on: ubuntu-latest
steps:
- name: Check if welcome comment already exists
id: check_comment
uses: actions/github-script@v7
with:
result-encoding: string
script: |
const issueNumber = context.issue.number;
const comments = await github.rest.issues.listComments({
...context.repo,
issue_number: issueNumber
});
const alreadyCommented = comments.data.some(
(comment) =>
comment.body.includes('<!-- auto-comment:good-first-issue -->')
);
return alreadyCommented ? 'true' : 'false';
- name: Leave welcome comment
if: steps.check_comment.outputs.result == 'false'
uses: actions/github-script@v7
with:
script: |
const repoUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}`;
await github.rest.issues.createComment({
...context.repo,
issue_number: context.issue.number,
body: "🙌 **Hey there, future contributor!** 🙌\n\n" +
"This issue has been labeled as **good first issue**, which means it's a great place to get started with the OpenHands project.\n\n" +
"If you're interested in working on it, feel free to! No need to ask for permission.\n\n" +
"Be sure to check out our [development setup guide](" + repoUrl + "/blob/main/Development.md) to get your environment set up, and follow our [contribution guidelines](" + repoUrl + "/blob/main/CONTRIBUTING.md) when you're ready to submit a fix.\n\n" +
"🙌 Happy hacking! 🙌\n\n" +
"<!-- auto-comment:good-first-issue -->"
});

26
.gitignore vendored
View File

@@ -161,29 +161,8 @@ cython_debug/
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
.idea/
# VS Code: Ignore all but certain files that specify repo-specific settings.
# https://stackoverflow.com/questions/32964920/should-i-commit-the-vscode-folder-to-source-control
.vscode/**/*
!.vscode/extensions.json
!.vscode/settings.json
!.vscode/tasks.json
# VS Code extensions/forks:
.vscode/
.cursorignore
.rooignore
.clineignore
.windsurfignore
.cursorrules
.roorules
.clinerules
.windsurfrules
.cursor/rules
.roo/rules
.cline/rules
.windsurf/rules
.repomix
repomix-output.txt
# evaluation
evaluation/evaluation_outputs
@@ -254,6 +233,3 @@ containers/runtime/Dockerfile
containers/runtime/project.tar.gz
containers/runtime/code
**/node_modules/
# test results
test-results

View File

@@ -1,33 +0,0 @@
---
name: documentation
type: knowledge
version: 1.0.0
agent: CodeActAgent
triggers:
- documentation
- docs
- document
---
# Documentation Guidelines
All documentation must be grounded in fact, so you must not make anything up without proper evidence. When you have finished writing documentation, convey to the user what reference source, including web pages, source code, or other sources of documentation you referenced when writing each new fact in the documentation. If you cannot reference a source for anything do not include it in the pull request.
## Best Practices for Documentation
1. **Be Factual**: Only include information that can be verified from reliable sources.
2. **Cite Sources**: Always reference the source of information (code, web pages, official documentation).
3. **Be Clear and Concise**: Use simple language and avoid unnecessary jargon.
4. **Use Examples**: Include practical examples to illustrate concepts.
5. **Structure Properly**: Use headings, lists, and code blocks to organize information.
6. **Keep Updated**: Ensure documentation reflects the current state of the code or system.
## Documentation Process
1. Research and gather information from reliable sources
2. Draft documentation based on verified facts
3. Review for accuracy and completeness
4. Include references for all factual statements
5. Submit only when all information is properly sourced
Remember: If you cannot verify a piece of information, it's better to exclude it than to include potentially incorrect information.

View File

@@ -121,7 +121,7 @@ A specialized prompt that enhances OpenHands with domain-specific knowledge, rep
A central repository of available microagents and their configurations.
#### Public Microagent
A general-purpose microagent available to all OpenHands users, triggered by specific keywords. Located in `microagents/`.
A general-purpose microagent available to all OpenHands users, triggered by specific keywords.
#### Repository Microagent
A type of microagent that provides repository-specific context and guidelines, stored in the `.openhands/microagents/` directory.

View File

@@ -1,3 +1,8 @@
---
name: repo
type: repo
agent: CodeActAgent
---
This repository contains the code for OpenHands, an automated AI software engineer. It has a Python backend
(in the `openhands` directory) and React frontend (in the `frontend` directory).
@@ -5,21 +10,12 @@ This repository contains the code for OpenHands, an automated AI software engine
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.
## Running OpenHands with OpenHands:
To run the full application to debug issues:
```bash
export INSTALL_DOCKER=0
export RUNTIME=local
make build && make run FRONTEND_PORT=12000 FRONTEND_HOST=0.0.0.0 BACKEND_HOST=0.0.0.0 &> /tmp/openhands-log.txt &
```
IMPORTANT: Before making any changes to the codebase, ALWAYS run `make install-pre-commit-hooks` to ensure pre-commit hooks are properly installed.
Before pushing any changes, you MUST ensure that any lint errors or simple test errors have been fixed.
* If you've made changes to the backend, you should run `pre-commit run --config ./dev_config/python/.pre-commit-config.yaml` (this will run on staged files).
* If you've made changes to the backend, you should run `pre-commit run --all-files --config ./dev_config/python/.pre-commit-config.yaml`
* If you've made changes to the frontend, you should run `cd frontend && npm run lint:fix && npm run build ; cd ..`
* If you've made changes to the VSCode extension, you should run `cd openhands/integrations/vscode && npm run lint:fix && npm run compile ; cd ../../..`
The pre-commit hooks MUST pass successfully before pushing any changes to the repository. This is a mandatory requirement to maintain code quality and consistency.
@@ -30,12 +26,6 @@ then re-run the command to ensure it passes. Common issues include:
- Trailing whitespace
- Missing newlines at end of files
## Git Best Practices
- Prefer specific `git add <filename>` instead of `git add .` to avoid accidentally staging unintended files
- Be especially careful with `git reset --hard` after staging files, as it will remove accidentally staged files
- When remote has new changes, use `git fetch upstream && git rebase upstream/<branch>` on the same branch
## Repository Structure
Backend:
- Located in the `openhands` directory
@@ -59,63 +49,16 @@ Frontend:
- Available variables: VITE_BACKEND_HOST, VITE_USE_TLS, VITE_INSECURE_SKIP_VERIFY, VITE_FRONTEND_PORT
- Internationalization:
- Generate i18n declaration file: `npm run make-i18n`
- Data Fetching & Cache Management:
- We use TanStack Query (fka React Query) for data fetching and cache management
- Data Access Layer: API client methods are located in `frontend/src/api` and should never be called directly from UI components - they must always be wrapped with TanStack Query
- Custom hooks are located in `frontend/src/hooks/query/` and `frontend/src/hooks/mutation/`
- Query hooks should follow the pattern use[Resource] (e.g., `useConversationMicroagents`)
- Mutation hooks should follow the pattern use[Action] (e.g., `useDeleteConversation`)
- Architecture rule: UI components → TanStack Query hooks → Data Access Layer (`frontend/src/api`) → API endpoints
VSCode Extension:
- Located in the `openhands/integrations/vscode` directory
- Setup: Run `npm install` in the extension directory
- Linting:
- Run linting with fixes: `npm run lint:fix`
- Check only: `npm run lint`
- Type checking: `npm run typecheck`
- Building:
- Compile TypeScript: `npm run compile`
- Package extension: `npm run package-vsix`
- Testing:
- Run tests: `npm run test`
- Development Best Practices:
- Use `vscode.window.createOutputChannel()` for debug logging instead of `showErrorMessage()` popups
- Pre-commit process runs both frontend and backend checks when committing extension changes
## Template for Github Pull Request
If you are starting a pull request (PR), please follow the template in `.github/pull_request_template.md`.
If you need to add labels when opening a PR, check the existing labels defined on that repository and select from existing ones. Do not invent your own labels.
## Implementation Details
These details may or may not be useful for your current task.
### Microagents
Microagents are specialized prompts that enhance OpenHands with domain-specific knowledge and task-specific workflows. They are Markdown files that can include frontmatter for configuration.
#### Types:
- **Public Microagents**: Located in `microagents/`, available to all users
- **Repository Microagents**: Located in `.openhands/microagents/`, specific to this repository
#### Loading Behavior:
- **Without frontmatter**: Always loaded into LLM context
- **With triggers in frontmatter**: Only loaded when user's message matches the specified trigger keywords
#### Structure:
```yaml
---
triggers:
- keyword1
- keyword2
---
# Microagent Content
Your specialized knowledge and instructions here...
```
### Frontend
#### Action Handling:
@@ -128,109 +71,3 @@ Your specialized knowledge and instructions here...
- Actions with `thought` property are displayed in the UI based on their action type:
- Regular actions (like "run", "edit") display the thought as a separate message
- Special actions (like "think") are displayed as collapsible elements only
#### Adding User Settings:
- To add a new user setting to OpenHands, follow these steps:
1. Add the setting to the frontend:
- Add the setting to the `Settings` type in `frontend/src/types/settings.ts`
- Add the setting to the `ApiSettings` type in the same file
- Add the setting with an appropriate default value to `DEFAULT_SETTINGS` in `frontend/src/services/settings.ts`
- Update the `useSettings` hook in `frontend/src/hooks/query/use-settings.ts` to map the API response
- Update the `useSaveSettings` hook in `frontend/src/hooks/mutation/use-save-settings.ts` to include the setting in API requests
- Add UI components (like toggle switches) in the appropriate settings screen (e.g., `frontend/src/routes/app-settings.tsx`)
- Add i18n translations for the setting name and any tooltips in `frontend/src/i18n/translation.json`
- Add the translation key to `frontend/src/i18n/declaration.ts`
2. Add the setting to the backend:
- 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)
#### Settings UI Patterns:
There are two main patterns for saving settings in the OpenHands frontend:
**Pattern 1: Entity-based Resources (Immediate Save)**
- Used for: API Keys, Secrets, MCP Servers
- Behavior: Changes are saved immediately when user performs actions (add/edit/delete)
- Implementation:
- No "Save Changes" button
- No local state management or `isDirty` tracking
- Uses dedicated mutation hooks for each operation (e.g., `use-add-mcp-server.ts`, `use-delete-mcp-server.ts`)
- Each mutation triggers immediate API call with query invalidation for UI updates
- Example: MCP settings, API Keys & Secrets tabs
- Benefits: Simpler UX, no risk of losing changes, consistent with modern web app patterns
**Pattern 2: Form-based Settings (Manual Save)**
- Used for: Application settings, LLM configuration
- Behavior: Changes are accumulated locally and saved when user clicks "Save Changes"
- Implementation:
- Has "Save Changes" button that becomes enabled when changes are detected
- Uses local state management with `isDirty` tracking
- Uses `useSaveSettings` hook to save all changes at once
- Example: LLM tab, Application tab
- Benefits: Allows bulk changes, explicit save action, can validate all fields before saving
**When to use each pattern:**
- Use Pattern 1 (Immediate Save) for entity management where each item is independent
- Use Pattern 2 (Manual Save) for configuration forms where settings are interdependent or need validation
### Adding New LLM Models
To add a new LLM model to OpenHands, you need to update multiple files across both frontend and backend:
#### Model Configuration Procedure:
1. **Frontend Model Arrays** (`frontend/src/utils/verified-models.ts`):
- Add the model to `VERIFIED_MODELS` array (main list of all verified models)
- Add to provider-specific arrays based on the model's provider:
- `VERIFIED_OPENAI_MODELS` for OpenAI models
- `VERIFIED_ANTHROPIC_MODELS` for Anthropic models
- `VERIFIED_MISTRAL_MODELS` for Mistral models
- `VERIFIED_OPENHANDS_MODELS` for models available through OpenHands provider
2. **Backend CLI Integration** (`openhands/cli/utils.py`):
- Add the model to the appropriate `VERIFIED_*_MODELS` arrays
- This ensures the model appears in CLI model selection
3. **Backend Model List** (`openhands/utils/llm.py`):
- **CRITICAL**: Add the model to the `openhands_models` list (lines 57-66) if using OpenHands provider
- This is required for the model to appear in the frontend model selector
- Format: `'openhands/model-name'` (e.g., `'openhands/o3'`)
4. **Backend LLM Configuration** (`openhands/llm/llm.py`):
- Add to feature-specific arrays based on model capabilities:
- `FUNCTION_CALLING_SUPPORTED_MODELS` if the model supports function calling
- `REASONING_EFFORT_SUPPORTED_MODELS` if the model supports reasoning effort parameters
- `CACHE_PROMPT_SUPPORTED_MODELS` if the model supports prompt caching
- `MODELS_WITHOUT_STOP_WORDS` if the model doesn't support stop words
5. **Validation**:
- Run backend linting: `pre-commit run --config ./dev_config/python/.pre-commit-config.yaml`
- Run frontend linting: `cd frontend && npm run lint:fix`
- Run frontend build: `cd frontend && npm run build`
#### Model Verification Arrays:
- **VERIFIED_MODELS**: Main array of all verified models shown in the UI
- **VERIFIED_OPENAI_MODELS**: OpenAI models (LiteLLM doesn't return provider prefix)
- **VERIFIED_ANTHROPIC_MODELS**: Anthropic models (LiteLLM doesn't return provider prefix)
- **VERIFIED_MISTRAL_MODELS**: Mistral models (LiteLLM doesn't return provider prefix)
- **VERIFIED_OPENHANDS_MODELS**: Models available through OpenHands managed provider
#### Model Feature Support Arrays:
- **FUNCTION_CALLING_SUPPORTED_MODELS**: Models that support structured function calling
- **REASONING_EFFORT_SUPPORTED_MODELS**: Models that support reasoning effort parameters (like o1, o3)
- **CACHE_PROMPT_SUPPORTED_MODELS**: Models that support prompt caching for efficiency
- **MODELS_WITHOUT_STOP_WORDS**: Models that don't support stop word parameters
#### Frontend Model Integration:
- Models are automatically available in the model selector UI once added to verified arrays
- The `extractModelAndProvider` utility automatically detects provider from model arrays
- Provider-specific models are grouped and prioritized in the UI selection
#### CLI Model Integration:
- Models appear in CLI provider selection based on the verified arrays
- The `organize_models_and_providers` function groups models by provider
- Default model selection prioritizes verified models for each provider

View File

@@ -1,175 +0,0 @@
#!/bin/bash
echo "Running OpenHands pre-commit hook..."
echo "This hook runs selective linting based on changed files."
# Store the exit code to return at the end
# This allows us to be additive to existing pre-commit hooks
EXIT_CODE=0
# Get the list of staged files
STAGED_FILES=$(git diff --cached --name-only)
# Check if any files match specific patterns
has_frontend_changes=false
has_backend_changes=false
has_vscode_changes=false
# Check each file individually to avoid issues with grep
for file in $STAGED_FILES; do
if [[ $file == frontend/* ]]; then
has_frontend_changes=true
elif [[ $file == openhands/* || $file == evaluation/* || $file == tests/* ]]; then
has_backend_changes=true
# Check for VSCode extension changes (subset of backend changes)
if [[ $file == openhands/integrations/vscode/* ]]; then
has_vscode_changes=true
fi
fi
done
echo "Analyzing changes..."
echo "- Frontend changes: $has_frontend_changes"
echo "- Backend changes: $has_backend_changes"
echo "- VSCode extension changes: $has_vscode_changes"
# Run frontend linting if needed
if [ "$has_frontend_changes" = true ]; then
# Check if we're in a CI environment or if frontend dependencies are missing
if [ -n "$CI" ] || ! command -v react-router &> /dev/null || ! command -v vitest &> /dev/null; then
echo "Skipping frontend checks (CI environment or missing dependencies detected)."
echo "WARNING: Frontend files have changed but frontend checks are being skipped."
echo "Please run 'make lint-frontend' manually before submitting your PR."
else
echo "Running frontend linting..."
make lint-frontend
if [ $? -ne 0 ]; then
echo "Frontend linting failed. Please fix the issues before committing."
EXIT_CODE=1
else
echo "Frontend linting checks passed!"
fi
# Run additional frontend checks
if [ -d "frontend" ]; then
echo "Running additional frontend checks..."
cd frontend || exit 1
# Run build
echo "Running npm build..."
npm run build
if [ $? -ne 0 ]; then
echo "Frontend build failed. Please fix the issues before committing."
EXIT_CODE=1
fi
# Run tests
echo "Running npm test..."
npm test
if [ $? -ne 0 ]; then
echo "Frontend tests failed. Please fix the failing tests before committing."
EXIT_CODE=1
fi
cd ..
fi
fi
else
echo "Skipping frontend checks (no frontend changes detected)."
fi
# Run backend linting if needed
if [ "$has_backend_changes" = true ]; then
echo "Running backend linting..."
make lint-backend
if [ $? -ne 0 ]; then
echo "Backend linting failed. Please fix the issues before committing."
EXIT_CODE=1
else
echo "Backend linting checks passed!"
fi
else
echo "Skipping backend checks (no backend changes detected)."
fi
# Run VSCode extension checks if needed
if [ "$has_vscode_changes" = true ]; then
# Check if we're in a CI environment
if [ -n "$CI" ]; then
echo "Skipping VSCode extension checks (CI environment detected)."
echo "WARNING: VSCode extension files have changed but checks are being skipped."
echo "Please run VSCode extension checks manually before submitting your PR."
else
echo "Running VSCode extension checks..."
if [ -d "openhands/integrations/vscode" ]; then
cd openhands/integrations/vscode || exit 1
echo "Running npm lint:fix..."
npm run lint:fix
if [ $? -ne 0 ]; then
echo "VSCode extension linting failed. Please fix the issues before committing."
EXIT_CODE=1
else
echo "VSCode extension linting passed!"
fi
echo "Running npm typecheck..."
npm run typecheck
if [ $? -ne 0 ]; then
echo "VSCode extension type checking failed. Please fix the issues before committing."
EXIT_CODE=1
else
echo "VSCode extension type checking passed!"
fi
echo "Running npm compile..."
npm run compile
if [ $? -ne 0 ]; then
echo "VSCode extension compilation failed. Please fix the issues before committing."
EXIT_CODE=1
else
echo "VSCode extension compilation passed!"
fi
cd ../../..
fi
fi
else
echo "Skipping VSCode extension checks (no VSCode extension changes detected)."
fi
# If no specific code changes detected, run basic checks
if [ "$has_frontend_changes" = false ] && [ "$has_backend_changes" = false ]; then
echo "No specific code changes detected. Running basic checks..."
if [ -n "$STAGED_FILES" ]; then
# Run only basic pre-commit hooks for non-code files
poetry run pre-commit run --files $(echo "$STAGED_FILES" | tr '\n' ' ') --hook-stage commit --config ./dev_config/python/.pre-commit-config.yaml
if [ $? -ne 0 ]; then
echo "Basic checks failed. Please fix the issues before committing."
EXIT_CODE=1
else
echo "Basic checks passed!"
fi
else
echo "No files changed. Skipping basic checks."
fi
fi
# Run any existing pre-commit hooks that might have been installed by the user
# This makes our hook additive rather than replacing existing hooks
if [ -f ".git/hooks/pre-commit.local" ]; then
echo "Running existing pre-commit hooks..."
bash .git/hooks/pre-commit.local
if [ $? -ne 0 ]; then
echo "Existing pre-commit hooks failed."
EXIT_CODE=1
fi
fi
if [ $EXIT_CODE -eq 0 ]; then
echo "All pre-commit checks passed!"
else
echo "Some pre-commit checks failed. Please fix the issues before committing."
fi
exit $EXIT_CODE

View File

@@ -2,12 +2,4 @@
echo "Setting up the environment..."
# Install pre-commit package
python -m pip install pre-commit
# Install pre-commit hooks if .git directory exists
if [ -d ".git" ]; then
echo "Installing pre-commit hooks..."
pre-commit install
make install-pre-commit-hooks
fi

View File

@@ -1,6 +0,0 @@
{
// force *nix line endings so files don't look modified in container run from Windows clone
"files.eol": "\n",
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": true,
}

View File

@@ -121,7 +121,7 @@ These Slack and Discord etiquette guidelines are designed to foster an inclusive
- Use threads for specific discussions to keep channels organized and easier to follow.
- Tag others only when their input is critical or urgent, and use @here, @channel or @everyone sparingly to minimize disruptions.
- Be patient, as open-source contributors and maintainers often have other commitments and may need time to respond.
- Post questions or discussions in the most relevant channel (e.g., for [slack - #general](https://openhands-ai.slack.com/archives/C06P5NCGSFP) for general topics, [slack - #questions](https://openhands-ai.slack.com/archives/C06U8UTKSAD) for queries/questions, [discord - #general](https://discord.com/channels/1222935860639563850/1222935861386018885)).
- Post questions or discussions in the most relevant channel (e.g., for [slack - #general](https://app.slack.com/client/T06P212QSEA/C06P5NCGSFP) for general topics, [slack - #questions](https://openhands-ai.slack.com/archives/C06U8UTKSAD) for queries/questions, [discord - #general](https://discord.com/channels/1222935860639563850/1222935861386018885)).
- When asking for help or raising issues, include necessary details like links, screenshots, or clear explanations to provide context.
- Keep discussions in public channels whenever possible to allow others to benefit from the conversation, unless the matter is sensitive or private.
- Always adhere to [our standards](https://github.com/All-Hands-AI/OpenHands/blob/main/CODE_OF_CONDUCT.md#our-standards) to ensure a welcoming and collaborative environment.

View File

@@ -20,7 +20,7 @@ We have a separate doc [Development.md](https://github.com/All-Hands-AI/OpenHand
There are many ways that you can contribute:
1. **Download and use** OpenHands, and send [issues](https://github.com/All-Hands-AI/OpenHands/issues) when you encounter something that isn't working or a feature that you'd like to see.
2. **Send feedback** after each session by [clicking the thumbs-up thumbs-down buttons](https://docs.all-hands.dev/usage/feedback), so we can see where things are working and failing, and also build an open dataset for training code agents.
2. **Send feedback** after each session by [clicking the thumbs-up thumbs-down buttons](https://docs.all-hands.dev/modules/usage/feedback), so we can see where things are working and failing, and also build an open dataset for training code agents.
3. **Improve the Codebase** by sending [PRs](#sending-pull-requests-to-openhands) (see details below). In particular, we have some [good first issues](https://github.com/All-Hands-AI/OpenHands/labels/good%20first%20issue) that may be ones to start on.
## What Can I Build?
@@ -31,7 +31,7 @@ We're always looking to improve the look and feel of the application. If you've
for something that's bugging you, feel free to open up a PR that changes the [`./frontend`](./frontend) directory.
If you're looking to make a bigger change, add a new UI element, or significantly alter the style
of the application, please open an issue first, or better, join the #eng-ui-ux channel in our Slack
of the application, please open an issue first, or better, join the #frontend channel in our Slack
to gather consensus from our design team first.
#### Improving the agent

View File

@@ -1,10 +1,8 @@
# Development Guide
This guide is for people working on OpenHands and editing the source code.
If you wish to contribute your changes, check out the
[CONTRIBUTING.md](https://github.com/All-Hands-AI/OpenHands/blob/main/CONTRIBUTING.md)
on how to clone and setup the project initially before moving on. Otherwise,
you can clone the OpenHands project directly.
If you wish to contribute your changes, check out the [CONTRIBUTING.md](https://github.com/All-Hands-AI/OpenHands/blob/main/CONTRIBUTING.md) on how to clone and setup the project initially before moving on.
Otherwise, you can clone the OpenHands project directly.
## Start the Server for Development
@@ -16,26 +14,14 @@ you can clone the OpenHands project directly.
- [NodeJS](https://nodejs.org/en/download/package-manager) >= 22.x
- [Poetry](https://python-poetry.org/docs/#installing-with-the-official-installer) >= 1.8
- OS-specific dependencies:
- Ubuntu: build-essential => `sudo apt-get install build-essential python3.12-dev`
- Ubuntu: build-essential => `sudo apt-get install build-essential`
- WSL: netcat => `sudo apt-get install netcat`
Make sure you have all these dependencies installed before moving on to `make build`.
#### Dev container
There is a [dev container](https://containers.dev/) available which provides a
pre-configured environment with all the necessary dependencies installed if you
are using a [supported editor or tool](https://containers.dev/supporting). For
example, if you are using Visual Studio Code (VS Code) with the
[Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)
extension installed, you can open the project in a dev container by using the
_Dev Container: Reopen in Container_ command from the Command Palette
(Ctrl+Shift+P).
#### Develop without sudo access
If you want to develop without system admin/sudo access to upgrade/install `Python` and/or `NodeJS`, you can use
`conda` or `mamba` to manage the packages for you:
If you want to develop without system admin/sudo access to upgrade/install `Python` and/or `NodeJs`, you can use `conda` or `mamba` to manage the packages for you:
```bash
# Download and install Mamba (a faster version of conda)
@@ -50,8 +36,7 @@ mamba install conda-forge::poetry
### 2. Build and Setup The Environment
Begin by building the project which includes setting up the environment and installing dependencies. This step ensures
that OpenHands is ready to run on your system:
Begin by building the project which includes setting up the environment and installing dependencies. This step ensures that OpenHands is ready to run on your system:
```bash
make build
@@ -60,6 +45,8 @@ make build
### 3. Configuring the Language Model
OpenHands supports a diverse array of Language Models (LMs) through the powerful [litellm](https://docs.litellm.ai) library.
By default, we've chosen Claude Sonnet 3.5 as our go-to model, but the world is your oyster! You can unleash the
potential of any other LM that piques your interest.
To configure the LM of your choice, run:
@@ -67,16 +54,13 @@ To configure the LM of your choice, run:
make setup-config
```
This command will prompt you to enter the LLM API key, model name, and other variables ensuring that OpenHands is
tailored to your specific needs. Note that the model name will apply only when you run headless. If you use the UI,
please set the model in the UI.
This command will prompt you to enter the LLM API key, model name, and other variables ensuring that OpenHands is tailored to your specific needs. Note that the model name will apply only when you run headless. If you use the UI, please set the model in the UI.
Note: If you have previously run OpenHands using the docker command, you may have already set some environment
variables in your terminal. The final configurations are set from highest to lowest priority:
Note: If you have previously run OpenHands using the docker command, you may have already set some environmental variables in your terminal. The final configurations are set from highest to lowest priority:
Environment variables > config.toml variables > default variables
**Note on Alternative Models:**
See [our documentation](https://docs.all-hands.dev/usage/llms) for recommended models.
See [our documentation](https://docs.all-hands.dev/modules/usage/llms) for recommended models.
### 4. Running the application
@@ -90,42 +74,17 @@ make run
#### Option B: Individual Server Startup
- **Start the Backend Server:** If you prefer, you can start the backend server independently to focus on
backend-related tasks or configurations.
- **Start the Backend Server:** If you prefer, you can start the backend server independently to focus on backend-related tasks or configurations.
```bash
make start-backend
```
- **Start the Frontend Server:** Similarly, you can start the frontend server on its own to work on frontend-related
components or interface enhancements.
- **Start the Frontend Server:** Similarly, you can start the frontend server on its own to work on frontend-related components or interface enhancements.
```bash
make start-frontend
```
### 5. Running OpenHands with OpenHands
You can use OpenHands to develop and improve OpenHands itself! This is a powerful way to leverage AI assistance for contributing to the project.
#### Quick Start
1. **Build and run OpenHands:**
```bash
export INSTALL_DOCKER=0
export RUNTIME=local
make build && make run
```
2. **Access the interface:**
- Local development: http://localhost:3001
- Remote/cloud environments: Use the appropriate external URL
3. **Configure for external access (if needed):**
```bash
# For external access (e.g., cloud environments)
make run FRONTEND_PORT=12000 FRONTEND_HOST=0.0.0.0 BACKEND_HOST=0.0.0.0
```
### 6. LLM Debugging
If you encounter any issues with the Language Model (LM) or you're simply curious, export DEBUG=1 in the environment and restart the backend.
@@ -154,12 +113,12 @@ poetry run pytest ./tests/unit/test_*.py
1. Add your dependency in `pyproject.toml` or use `poetry add xxx`.
2. Update the poetry.lock file via `poetry lock --no-update`.
### 10. Use existing Docker image
### 9. Use existing Docker image
To reduce build time (e.g., if no changes were made to the client-runtime component), you can use an existing Docker
container image by setting the SANDBOX_RUNTIME_CONTAINER_IMAGE environment variable to the desired Docker image.
To reduce build time (e.g., if no changes were made to the client-runtime component), you can use an existing Docker container image by
setting the SANDBOX_RUNTIME_CONTAINER_IMAGE environment variable to the desired Docker image.
Example: `export SANDBOX_RUNTIME_CONTAINER_IMAGE=ghcr.io/all-hands-ai/runtime:0.54-nikolaik`
Example: `export SANDBOX_RUNTIME_CONTAINER_IMAGE=ghcr.io/all-hands-ai/runtime:0.34-nikolaik`
## Develop inside Docker container

View File

@@ -3,12 +3,17 @@ These are the procedures and guidelines on how issues are triaged in this repo b
## General
* All issues must be tagged with **enhancement**, **bug** or **troubleshooting/help**.
* Issues may be tagged with what it relates to (**agent quality**, **resolver**, **CLI**, etc.).
* Issues may be tagged with what it relates to (**agent quality**, **frontend**, **resolver**, etc.).
## Severity
* **Low**: Minor issues or affecting single user.
* **Medium**: Affecting multiple users.
* **High**: High visibility issues or affecting many users.
* **Critical**: Affecting all users or potential security issues.
## Effort
* Issues may be estimated with effort required (**small effort**, **medium effort**, **large effort**).
## Difficulty
* Issues with low implementation difficulty may be tagged with **good first issue**.

View File

@@ -3,16 +3,14 @@ SHELL=/usr/bin/env bash
# Variables
BACKEND_HOST ?= "127.0.0.1"
BACKEND_PORT ?= 3000
BACKEND_PORT = 3000
BACKEND_HOST_PORT = "$(BACKEND_HOST):$(BACKEND_PORT)"
FRONTEND_HOST ?= "127.0.0.1"
FRONTEND_PORT ?= 3001
FRONTEND_PORT = 3001
DEFAULT_WORKSPACE_DIR = "./workspace"
DEFAULT_MODEL = "gpt-4o"
CONFIG_FILE = config.toml
PRE_COMMIT_CONFIG_PATH = "./dev_config/python/.pre-commit-config.yaml"
PYTHON_VERSION = 3.12
KIND_CLUSTER_NAME = "local-hands"
# ANSI color codes
GREEN=$(shell tput -Txterm setaf 2)
@@ -152,7 +150,7 @@ install-python-dependencies:
echo "Installing only POETRY_GROUP=${POETRY_GROUP}"; \
poetry install --only $${POETRY_GROUP}; \
else \
poetry install --with dev,test,runtime; \
poetry install; \
fi
@if [ "${INSTALL_PLAYWRIGHT}" != "false" ] && [ "${INSTALL_PLAYWRIGHT}" != "0" ]; then \
if [ -f "/etc/manjaro-release" ]; then \
@@ -174,7 +172,7 @@ install-python-dependencies:
fi
@echo "$(GREEN)Python dependencies installed successfully.$(RESET)"
install-frontend-dependencies: check-npm check-nodejs
install-frontend-dependencies:
@echo "$(YELLOW)Setting up frontend environment...$(RESET)"
@echo "$(YELLOW)Detect Node.js version...$(RESET)"
@cd frontend && node ./scripts/detect-node-version.js
@@ -182,17 +180,17 @@ install-frontend-dependencies: check-npm check-nodejs
@cd frontend && npm install
@echo "$(GREEN)Frontend dependencies installed successfully.$(RESET)"
install-pre-commit-hooks: check-python check-poetry install-python-dependencies
install-pre-commit-hooks:
@echo "$(YELLOW)Installing pre-commit hooks...$(RESET)"
@git config --unset-all core.hooksPath || true
@poetry run pre-commit install --config $(PRE_COMMIT_CONFIG_PATH)
@echo "$(GREEN)Pre-commit hooks installed successfully.$(RESET)"
lint-backend: install-pre-commit-hooks
lint-backend:
@echo "$(YELLOW)Running linters...$(RESET)"
@poetry run pre-commit run --all-files --show-diff-on-failure --config $(PRE_COMMIT_CONFIG_PATH)
@poetry run pre-commit run --files openhands/**/* evaluation/**/* tests/**/* --show-diff-on-failure --config $(PRE_COMMIT_CONFIG_PATH)
lint-frontend: install-frontend-dependencies
lint-frontend:
@echo "$(YELLOW)Running linters for frontend...$(RESET)"
@cd frontend && npm run lint
@@ -200,40 +198,6 @@ lint:
@$(MAKE) -s lint-frontend
@$(MAKE) -s lint-backend
kind:
@echo "$(YELLOW)Checking if kind is installed...$(RESET)"
@if ! command -v kind > /dev/null; then \
echo "$(RED)kind is not installed. Please install kind with `brew install kind` to continue$(RESET)"; \
exit 1; \
else \
echo "$(BLUE)kind $(shell kind version) is already installed.$(RESET)"; \
fi
@echo "$(YELLOW)Checking if kind cluster '$(KIND_CLUSTER_NAME)' already exists...$(RESET)"
@if kind get clusters | grep -q "^$(KIND_CLUSTER_NAME)$$"; then \
echo "$(BLUE)Kind cluster '$(KIND_CLUSTER_NAME)' already exists.$(RESET)"; \
kubectl config use-context kind-$(KIND_CLUSTER_NAME); \
else \
echo "$(YELLOW)Creating kind cluster '$(KIND_CLUSTER_NAME)'...$(RESET)"; \
kind create cluster --name $(KIND_CLUSTER_NAME) --config kind/cluster.yaml; \
fi
@echo "$(YELLOW)Checking if mirrord is installed...$(RESET)"
@if ! command -v mirrord > /dev/null; then \
echo "$(RED)mirrord is not installed. Please install mirrord with `brew install metalbear-co/mirrord/mirrord` to continue$(RESET)"; \
exit 1; \
else \
echo "$(BLUE)mirrord $(shell mirrord --version) is already installed.$(RESET)"; \
fi
@echo "$(YELLOW)Installing k8s mirrord resources...$(RESET)"
@kubectl apply -f kind/manifests
@echo "$(GREEN)Mirrord resources installed successfully.$(RESET)"
@echo "$(YELLOW)Waiting for Mirrord pod to be ready.$(RESET)"
@sleep 5
@kubectl wait --for=condition=Available deployment/ubuntu-dev
@echo "$(YELLOW)Waiting for Nginx to be ready.$(RESET)"
@kubectl -n ingress-nginx wait --for=condition=Available deployment/ingress-nginx-controller
@echo "$(YELLOW)Running make run inside of mirrord.$(RESET)"
@mirrord exec --target deployment/ubuntu-dev -- make run
test-frontend:
@echo "$(YELLOW)Running tests for frontend...$(RESET)"
@cd frontend && npm run test
@@ -324,15 +288,6 @@ setup-config-prompts:
@read -p "Enter your LLM base URL [mostly used for local LLMs, leave blank if not needed - example: http://localhost:5001/v1/]: " llm_base_url; \
if [[ ! -z "$$llm_base_url" ]]; then echo "base_url=\"$$llm_base_url\"" >> $(CONFIG_FILE).tmp; fi
setup-config-basic:
@printf '%s\n' \
'[core]' \
'workspace_base="./workspace"' \
> config.toml
@echo "$(GREEN)config.toml created.$(RESET)"
openhands-cloud-run:
@$(MAKE) run BACKEND_HOST="0.0.0.0" BACKEND_PORT="12000" FRONTEND_HOST="0.0.0.0" FRONTEND_PORT="12001"
# Develop in container
docker-dev:
@@ -367,5 +322,5 @@ help:
@echo " $(GREEN)help$(RESET) - Display this help message, providing information on available targets."
# Phony targets
.PHONY: build check-dependencies check-system check-python check-npm check-nodejs check-docker check-poetry install-python-dependencies install-frontend-dependencies install-pre-commit-hooks lint-backend lint-frontend lint test-frontend test build-frontend start-backend start-frontend _run_setup run run-wsl setup-config setup-config-prompts setup-config-basic openhands-cloud-run docker-dev docker-run clean help
.PHONY: kind
.PHONY: build check-dependencies check-python check-npm check-docker check-poetry install-python-dependencies install-frontend-dependencies install-pre-commit-hooks lint start-backend start-frontend run run-wsl setup-config setup-config-prompts help
.PHONY: docker-dev docker-run

111
README.md
View File

@@ -9,26 +9,16 @@
<div align="center">
<a href="https://github.com/All-Hands-AI/OpenHands/graphs/contributors"><img src="https://img.shields.io/github/contributors/All-Hands-AI/OpenHands?style=for-the-badge&color=blue" alt="Contributors"></a>
<a href="https://github.com/All-Hands-AI/OpenHands/stargazers"><img src="https://img.shields.io/github/stars/All-Hands-AI/OpenHands?style=for-the-badge&color=blue" alt="Stargazers"></a>
<a href="https://codecov.io/github/All-Hands-AI/OpenHands?branch=main"><img alt="CodeCov" src="https://img.shields.io/codecov/c/github/All-Hands-AI/OpenHands?style=for-the-badge&color=blue"></a>
<a href="https://github.com/All-Hands-AI/OpenHands/blob/main/LICENSE"><img src="https://img.shields.io/github/license/All-Hands-AI/OpenHands?style=for-the-badge&color=blue" alt="MIT License"></a>
<br/>
<a href="https://join.slack.com/t/openhands-ai/shared_invite/zt-3847of6xi-xuYJIPa6YIPg4ElbDWbtSA"><img src="https://img.shields.io/badge/Slack-Join%20Us-red?logo=slack&logoColor=white&style=for-the-badge" alt="Join our Slack community"></a>
<a href="https://join.slack.com/t/openhands-ai/shared_invite/zt-2ngejmfw6-9gW4APWOC9XUp1n~SiQ6iw"><img src="https://img.shields.io/badge/Slack-Join%20Us-red?logo=slack&logoColor=white&style=for-the-badge" alt="Join our Slack community"></a>
<a href="https://discord.gg/ESHStjSjD4"><img src="https://img.shields.io/badge/Discord-Join%20Us-purple?logo=discord&logoColor=white&style=for-the-badge" alt="Join our Discord community"></a>
<a href="https://github.com/All-Hands-AI/OpenHands/blob/main/CREDITS.md"><img src="https://img.shields.io/badge/Project-Credits-blue?style=for-the-badge&color=FFE165&logo=github&logoColor=white" alt="Credits"></a>
<br/>
<a href="https://docs.all-hands.dev/usage/getting-started"><img src="https://img.shields.io/badge/Documentation-000?logo=googledocs&logoColor=FFE165&style=for-the-badge" alt="Check out the documentation"></a>
<a href="https://docs.all-hands.dev/modules/usage/getting-started"><img src="https://img.shields.io/badge/Documentation-000?logo=googledocs&logoColor=FFE165&style=for-the-badge" alt="Check out the documentation"></a>
<a href="https://arxiv.org/abs/2407.16741"><img src="https://img.shields.io/badge/Paper%20on%20Arxiv-000?logoColor=FFE165&logo=arxiv&style=for-the-badge" alt="Paper on Arxiv"></a>
<a href="https://docs.google.com/spreadsheets/d/1wOUdFCMyY6Nt0AIqF705KN4JKOWgeI4wUGUP60krXXs/edit?gid=0#gid=0"><img src="https://img.shields.io/badge/Benchmark%20score-000?logoColor=FFE165&logo=huggingface&style=for-the-badge" alt="Evaluation Benchmark Score"></a>
<!-- Keep these links. Translations will automatically update with the README. -->
<a href="https://www.readme-i18n.com/All-Hands-AI/OpenHands?lang=de">Deutsch</a> |
<a href="https://www.readme-i18n.com/All-Hands-AI/OpenHands?lang=es">Español</a> |
<a href="https://www.readme-i18n.com/All-Hands-AI/OpenHands?lang=fr">français</a> |
<a href="https://www.readme-i18n.com/All-Hands-AI/OpenHands?lang=ja">日本語</a> |
<a href="https://www.readme-i18n.com/All-Hands-AI/OpenHands?lang=ko">한국어</a> |
<a href="https://www.readme-i18n.com/All-Hands-AI/OpenHands?lang=pt">Português</a> |
<a href="https://www.readme-i18n.com/All-Hands-AI/OpenHands?lang=ru">Русский</a> |
<a href="https://www.readme-i18n.com/All-Hands-AI/OpenHands?lang=zh">中文</a>
<hr>
</div>
@@ -48,92 +38,64 @@ Learn more at [docs.all-hands.dev](https://docs.all-hands.dev), or [sign up for
## ☁️ OpenHands Cloud
The easiest way to get started with OpenHands is on [OpenHands Cloud](https://app.all-hands.dev),
which comes with $20 in free credits for new users.
which comes with $50 in free credits for new users.
## 💻 Running OpenHands Locally
### Option 1: CLI Launcher (Recommended)
OpenHands can also run on your local system using Docker.
See the [Running OpenHands](https://docs.all-hands.dev/modules/usage/installation) guide for
system requirements and more information.
The easiest way to run OpenHands locally is using the CLI launcher with [uv](https://docs.astral.sh/uv/). This provides better isolation from your current project's virtual environment and is required for OpenHands' default MCP servers.
> [!WARNING]
> On a public network? See our [Hardened Docker Installation Guide](https://docs.all-hands.dev/modules/usage/runtimes/docker#hardened-docker-installation)
> to secure your deployment by restricting network binding and implementing additional security measures.
**Install uv** (if you haven't already):
See the [uv installation guide](https://docs.astral.sh/uv/getting-started/installation/) for the latest installation instructions for your platform.
**Launch OpenHands**:
```bash
# Launch the GUI server
uvx --python 3.12 --from openhands-ai openhands serve
# Or launch the CLI
uvx --python 3.12 --from openhands-ai openhands
```
You'll find OpenHands running at [http://localhost:3000](http://localhost:3000) (for GUI mode)!
### Option 2: Docker
<details>
<summary>Click to expand Docker command</summary>
You can also run OpenHands directly with Docker:
```bash
docker pull docker.all-hands.dev/all-hands-ai/runtime:0.54-nikolaik
docker pull docker.all-hands.dev/all-hands-ai/runtime:0.34-nikolaik
docker run -it --rm --pull=always \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.54-nikolaik \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.34-nikolaik \
-e LOG_ALL_EVENTS=true \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ~/.openhands:/.openhands \
-v ~/.openhands-state:/.openhands-state \
-p 3000:3000 \
--add-host host.docker.internal:host-gateway \
--name openhands-app \
docker.all-hands.dev/all-hands-ai/openhands:0.54
docker.all-hands.dev/all-hands-ai/openhands:0.34
```
</details>
> **Note**: If you used OpenHands before version 0.44, you may want to run `mv ~/.openhands-state ~/.openhands` to migrate your conversation history to the new location.
> [!WARNING]
> On a public network? See our [Hardened Docker Installation Guide](https://docs.all-hands.dev/usage/runtimes/docker#hardened-docker-installation)
> to secure your deployment by restricting network binding and implementing additional security measures.
### Getting Started
You'll find OpenHands running at [http://localhost:3000](http://localhost:3000)!
When you open the application, you'll be asked to choose an LLM provider and add an API key.
[Anthropic's Claude Sonnet 4](https://www.anthropic.com/api) (`anthropic/claude-sonnet-4-20250514`)
works best, but you have [many options](https://docs.all-hands.dev/usage/llms).
See the [Running OpenHands](https://docs.all-hands.dev/usage/installation) guide for
system requirements and more information.
[Anthropic's Claude 3.5 Sonnet](https://www.anthropic.com/api) (`anthropic/claude-3-5-sonnet-20241022`)
works best, but you have [many options](https://docs.all-hands.dev/modules/usage/llms).
## 💡 Other ways to run OpenHands
> [!WARNING]
> [!CAUTION]
> OpenHands is meant to be run by a single user on their local workstation.
> It is not appropriate for multi-tenant deployments where multiple users share the same instance. There is no built-in authentication, isolation, or scalability.
>
> If you're interested in running OpenHands in a multi-tenant environment, check out the source-available, commercially-licensed
> [OpenHands Cloud Helm Chart](https://github.com/all-Hands-AI/OpenHands-cloud)
> If you're interested in running OpenHands in a multi-tenant environment, please
> [get in touch with us](https://docs.google.com/forms/d/e/1FAIpQLSet3VbGaz8z32gW9Wm-Grl4jpt5WgMXPgJ4EDPVmCETCBpJtQ/viewform)
> for advanced deployment options.
You can [connect OpenHands to your local filesystem](https://docs.all-hands.dev/usage/runtimes/docker#connecting-to-your-filesystem),
interact with it via a [friendly CLI](https://docs.all-hands.dev/usage/how-to/cli-mode),
run OpenHands in a scriptable [headless mode](https://docs.all-hands.dev/usage/how-to/headless-mode),
or run it on tagged issues with [a github action](https://docs.all-hands.dev/usage/how-to/github-action).
You can also [connect OpenHands to your local filesystem](https://docs.all-hands.dev/modules/usage/runtimes/docker#connecting-to-your-filesystem),
run OpenHands in a scriptable [headless mode](https://docs.all-hands.dev/modules/usage/how-to/headless-mode),
interact with it via a [friendly CLI](https://docs.all-hands.dev/modules/usage/how-to/cli-mode),
or run it on tagged issues with [a github action](https://docs.all-hands.dev/modules/usage/how-to/github-action).
Visit [Running OpenHands](https://docs.all-hands.dev/usage/installation) for more information and setup instructions.
Visit [Running OpenHands](https://docs.all-hands.dev/modules/usage/installation) for more information and setup instructions.
If you want to modify the OpenHands source code, check out [Development.md](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md).
Having issues? The [Troubleshooting Guide](https://docs.all-hands.dev/usage/troubleshooting) can help.
Having issues? The [Troubleshooting Guide](https://docs.all-hands.dev/modules/usage/troubleshooting) can help.
## 📖 Documentation
<a href="https://deepwiki.com/All-Hands-AI/OpenHands"><img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki" title="Autogenerated Documentation by DeepWiki"></a>
To learn more about the project, and for tips on using OpenHands,
check out our [documentation](https://docs.all-hands.dev/usage/getting-started).
check out our [documentation](https://docs.all-hands.dev/modules/usage/getting-started).
There you'll find resources on how to use different LLM providers,
troubleshooting resources, and advanced configuration options.
@@ -143,7 +105,7 @@ troubleshooting resources, and advanced configuration options.
OpenHands is a community-driven project, and we welcome contributions from everyone. We do most of our communication
through Slack, so this is the best place to start, but we also are happy to have you contact us on Discord or Github:
- [Join our Slack workspace](https://join.slack.com/t/openhands-ai/shared_invite/zt-3847of6xi-xuYJIPa6YIPg4ElbDWbtSA) - Here we talk about research, architecture, and future development.
- [Join our Slack workspace](https://join.slack.com/t/openhands-ai/shared_invite/zt-2ngejmfw6-9gW4APWOC9XUp1n~SiQ6iw) - Here we talk about research, architecture, and future development.
- [Join our Discord server](https://discord.gg/ESHStjSjD4) - This is a community-run server for general discussion, questions, and feedback.
- [Read or post Github Issues](https://github.com/All-Hands-AI/OpenHands/issues) - Check out the issues we're working on, or add your own ideas.
@@ -172,12 +134,13 @@ For a list of open source projects and licenses used in OpenHands, please see ou
## 📚 Cite
```
@inproceedings{
wang2025openhands,
title={OpenHands: An Open Platform for {AI} Software Developers as Generalist Agents},
author={Xingyao Wang and Boxuan Li and Yufan Song and Frank F. Xu and Xiangru Tang and Mingchen Zhuge and Jiayi Pan and Yueqi Song and Bowen Li and Jaskirat Singh and Hoang H. Tran and Fuqiang Li and Ren Ma and Mingzhang Zheng and Bill Qian and Yanjun Shao and Niklas Muennighoff and Yizhe Zhang and Binyuan Hui and Junyang Lin and Robert Brennan and Hao Peng and Heng Ji and Graham Neubig},
booktitle={The Thirteenth International Conference on Learning Representations},
year={2025},
url={https://openreview.net/forum?id=OJd3ayDDoF}
@misc{openhands,
title={{OpenHands: An Open Platform for AI Software Developers as Generalist Agents}},
author={Xingyao Wang and Boxuan Li and Yufan Song and Frank F. Xu and Xiangru Tang and Mingchen Zhuge and Jiayi Pan and Yueqi Song and Bowen Li and Jaskirat Singh and Hoang H. Tran and Fuqiang Li and Ren Ma and Mingzhang Zheng and Bill Qian and Yanjun Shao and Niklas Muennighoff and Yizhe Zhang and Binyuan Hui and Junyang Lin and Robert Brennan and Hao Peng and Heng Ji and Graham Neubig},
year={2024},
eprint={2407.16741},
archivePrefix={arXiv},
primaryClass={cs.SE},
url={https://arxiv.org/abs/2407.16741},
}
```

View File

@@ -1,148 +0,0 @@
<a name="readme-top"></a>
<div align="center">
<img src="./docs/static/img/logo.png" alt="Logo" width="200">
<h1 align="center">OpenHands: 少写代码,多做事</h1>
</div>
<div align="center">
<a href="https://github.com/All-Hands-AI/OpenHands/graphs/contributors"><img src="https://img.shields.io/github/contributors/All-Hands-AI/OpenHands?style=for-the-badge&color=blue" alt="Contributors"></a>
<a href="https://github.com/All-Hands-AI/OpenHands/stargazers"><img src="https://img.shields.io/github/stars/All-Hands-AI/OpenHands?style=for-the-badge&color=blue" alt="Stargazers"></a>
<a href="https://github.com/All-Hands-AI/OpenHands/blob/main/LICENSE"><img src="https://img.shields.io/github/license/All-Hands-AI/OpenHands?style=for-the-badge&color=blue" alt="MIT License"></a>
<br/>
<a href="https://join.slack.com/t/openhands-ai/shared_invite/zt-3847of6xi-xuYJIPa6YIPg4ElbDWbtSA"><img src="https://img.shields.io/badge/Slack-Join%20Us-red?logo=slack&logoColor=white&style=for-the-badge" alt="加入我们的Slack社区"></a>
<a href="https://discord.gg/ESHStjSjD4"><img src="https://img.shields.io/badge/Discord-Join%20Us-purple?logo=discord&logoColor=white&style=for-the-badge" alt="加入我们的Discord社区"></a>
<a href="https://github.com/All-Hands-AI/OpenHands/blob/main/CREDITS.md"><img src="https://img.shields.io/badge/Project-Credits-blue?style=for-the-badge&color=FFE165&logo=github&logoColor=white" alt="致谢"></a>
<br/>
<a href="https://docs.all-hands.dev/usage/getting-started"><img src="https://img.shields.io/badge/Documentation-000?logo=googledocs&logoColor=FFE165&style=for-the-badge" alt="查看文档"></a>
<a href="https://arxiv.org/abs/2407.16741"><img src="https://img.shields.io/badge/Paper%20on%20Arxiv-000?logoColor=FFE165&logo=arxiv&style=for-the-badge" alt="Arxiv论文"></a>
<a href="https://docs.google.com/spreadsheets/d/1wOUdFCMyY6Nt0AIqF705KN4JKOWgeI4wUGUP60krXXs/edit?gid=0#gid=0"><img src="https://img.shields.io/badge/Benchmark%20score-000?logoColor=FFE165&logo=huggingface&style=for-the-badge" alt="评估基准分数"></a>
<hr>
</div>
欢迎使用OpenHands前身为OpenDevin这是一个由AI驱动的软件开发代理平台。
OpenHands代理可以完成人类开发者能做的任何事情修改代码、运行命令、浏览网页、调用API甚至从StackOverflow复制代码片段。
在[docs.all-hands.dev](https://docs.all-hands.dev)了解更多信息,或[注册OpenHands Cloud](https://app.all-hands.dev)开始使用。
> [!IMPORTANT]
> 在工作中使用OpenHands我们很想与您交流填写
> [这份简短表格](https://docs.google.com/forms/d/e/1FAIpQLSet3VbGaz8z32gW9Wm-Grl4jpt5WgMXPgJ4EDPVmCETCBpJtQ/viewform)
> 加入我们的设计合作伙伴计划,您将获得商业功能的早期访问权限,并有机会对我们的产品路线图提供意见。
![应用截图](./docs/static/img/screenshot.png)
## ☁️ OpenHands Cloud
开始使用OpenHands的最简单方式是在[OpenHands Cloud](https://app.all-hands.dev)上,
新用户可获得$50的免费额度。
## 💻 在本地运行OpenHands
OpenHands也可以使用Docker在本地系统上运行。
查看[运行OpenHands](https://docs.all-hands.dev/usage/installation)指南了解
系统要求和更多信息。
> [!WARNING]
> 在公共网络上?请参阅我们的[强化Docker安装指南](https://docs.all-hands.dev/usage/runtimes/docker#hardened-docker-installation)
> 通过限制网络绑定和实施其他安全措施来保护您的部署。
```bash
docker pull docker.all-hands.dev/all-hands-ai/runtime:0.54-nikolaik
docker run -it --rm --pull=always \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.54-nikolaik \
-e LOG_ALL_EVENTS=true \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ~/.openhands:/.openhands \
-p 3000:3000 \
--add-host host.docker.internal:host-gateway \
--name openhands-app \
docker.all-hands.dev/all-hands-ai/openhands:0.54
```
> **注意**: 如果您在0.44版本之前使用过OpenHands您可能需要运行 `mv ~/.openhands-state ~/.openhands` 来将对话历史迁移到新位置。
您将在[http://localhost:3000](http://localhost:3000)找到运行中的OpenHands
打开应用程序时您将被要求选择一个LLM提供商并添加API密钥。
[Anthropic的Claude Sonnet 4](https://www.anthropic.com/api)`anthropic/claude-sonnet-4-20250514`
效果最佳,但您还有[许多选择](https://docs.all-hands.dev/usage/llms)。
## 💡 运行OpenHands的其他方式
> [!CAUTION]
> OpenHands旨在由单个用户在其本地工作站上运行。
> 它不适合多租户部署,即多个用户共享同一实例。没有内置的身份验证、隔离或可扩展性。
>
> 如果您有兴趣在多租户环境中运行OpenHands
> [与我们联系](https://docs.google.com/forms/d/e/1FAIpQLSet3VbGaz8z32gW9Wm-Grl4jpt5WgMXPgJ4EDPVmCETCBpJtQ/viewform)
> 了解高级部署选项。
您还可以[将OpenHands连接到本地文件系统](https://docs.all-hands.dev/usage/runtimes/docker#connecting-to-your-filesystem)
以可编程的[无头模式](https://docs.all-hands.dev/usage/how-to/headless-mode)运行OpenHands
通过[友好的CLI](https://docs.all-hands.dev/usage/how-to/cli-mode)与其交互,
或使用[GitHub Action](https://docs.all-hands.dev/usage/how-to/github-action)在标记的问题上运行它。
访问[运行OpenHands](https://docs.all-hands.dev/usage/installation)获取更多信息和设置说明。
如果您想修改OpenHands源代码请查看[Development.md](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md)。
遇到问题?[故障排除指南](https://docs.all-hands.dev/usage/troubleshooting)可以提供帮助。
## 📖 文档
<a href="https://deepwiki.com/All-Hands-AI/OpenHands"><img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki" title="DeepWiki自动生成文档"></a>
要了解有关项目的更多信息以及使用OpenHands的技巧
请查看我们的[文档](https://docs.all-hands.dev/usage/getting-started)。
在那里您将找到有关如何使用不同LLM提供商、
故障排除资源和高级配置选项的资源。
## 🤝 如何加入社区
OpenHands是一个社区驱动的项目我们欢迎每个人的贡献。我们大部分沟通
通过Slack进行因此这是开始的最佳场所但我们也很乐意您通过Discord或Github与我们联系
- [加入我们的Slack工作空间](https://join.slack.com/t/openhands-ai/shared_invite/zt-3847of6xi-xuYJIPa6YIPg4ElbDWbtSA) - 这里我们讨论研究、架构和未来发展。
- [加入我们的Discord服务器](https://discord.gg/ESHStjSjD4) - 这是一个社区运营的服务器,用于一般讨论、问题和反馈。
- [阅读或发布Github问题](https://github.com/All-Hands-AI/OpenHands/issues) - 查看我们正在处理的问题,或添加您自己的想法。
在[COMMUNITY.md](./COMMUNITY.md)中了解更多关于社区的信息,或在[CONTRIBUTING.md](./CONTRIBUTING.md)中找到有关贡献的详细信息。
## 📈 进展
在[这里](https://github.com/orgs/All-Hands-AI/projects/1)查看OpenHands月度路线图每月月底在维护者会议上更新
<p align="center">
<a href="https://star-history.com/#All-Hands-AI/OpenHands&Date">
<img src="https://api.star-history.com/svg?repos=All-Hands-AI/OpenHands&type=Date" width="500" alt="Star History Chart">
</a>
</p>
## 📜 许可证
根据MIT许可证分发。有关更多信息请参阅[`LICENSE`](./LICENSE)。
## 🙏 致谢
OpenHands由大量贡献者构建每一份贡献都备受感谢我们还借鉴了其他开源项目对他们的工作深表感谢。
有关OpenHands中使用的开源项目和许可证列表请参阅我们的[CREDITS.md](./CREDITS.md)文件。
## 📚 引用
```
@misc{openhands,
title={{OpenHands: An Open Platform for AI Software Developers as Generalist Agents}},
author={Xingyao Wang and Boxuan Li and Yufan Song and Frank F. Xu and Xiangru Tang and Mingchen Zhuge and Jiayi Pan and Yueqi Song and Bowen Li and Jaskirat Singh and Hoang H. Tran and Fuqiang Li and Ren Ma and Mingzhang Zheng and Bill Qian and Yanjun Shao and Niklas Muennighoff and Yizhe Zhang and Binyuan Hui and Junyang Lin and Robert Brennan and Hao Peng and Heng Ji and Graham Neubig},
year={2024},
eprint={2407.16741},
archivePrefix={arXiv},
primaryClass={cs.SE},
url={https://arxiv.org/abs/2407.16741},
}
```

View File

@@ -1,60 +0,0 @@
<a name="readme-top"></a>
<div align="center">
<img src="./docs/static/img/logo.png" alt="Logo" width="200">
<h1 align="center">OpenHands: コードを減らして、もっと作ろう</h1>
</div>
<div align="center">
<a href="https://github.com/All-Hands-AI/OpenHands/graphs/contributors"><img src="https://img.shields.io/github/contributors/All-Hands-AI/OpenHands?style=for-the-badge&color=blue" alt="Contributors"></a>
<a href="https://github.com/All-Hands-AI/OpenHands/stargazers"><img src="https://img.shields.io/github/stars/All-Hands-AI/OpenHands?style=for-the-badge&color=blue" alt="Stargazers"></a>
<a href="https://github.com/All-Hands-AI/OpenHands/blob/main/LICENSE"><img src="https://img.shields.io/github/license/All-Hands-AI/OpenHands?style=for-the-badge&color=blue" alt="MIT License"></a>
<br/>
<a href="https://join.slack.com/t/openhands-ai/shared_invite/zt-3847of6xi-xuYJIPa6YIPg4ElbDWbtSA"><img src="https://img.shields.io/badge/Slack-Join%20Us-red?logo=slack&logoColor=white&style=for-the-badge" alt="Slackコミュニティに参加"></a>
<a href="https://discord.gg/ESHStjSjD4"><img src="https://img.shields.io/badge/Discord-Join%20Us-purple?logo=discord&logoColor=white&style=for-the-badge" alt="Discordコミュニティに参加"></a>
<a href="https://github.com/All-Hands-AI/OpenHands/blob/main/CREDITS.md"><img src="https://img.shields.io/badge/Project-Credits-blue?style=for-the-badge&color=FFE165&logo=github&logoColor=white" alt="クレジット"></a>
<br/>
<a href="https://docs.all-hands.dev/usage/getting-started"><img src="https://img.shields.io/badge/Documentation-000?logo=googledocs&logoColor=FFE165&style=for-the-badge" alt="ドキュメントを見る"></a>
<a href="https://arxiv.org/abs/2407.16741"><img src="https://img.shields.io/badge/Paper%20on%20Arxiv-000?logoColor=FFE165&logo=arxiv&style=for-the-badge" alt="Arxiv論文"></a>
<a href="https://docs.google.com/spreadsheets/d/1wOUdFCMyY6Nt0AIqF705KN4JKOWgeI4wUGUP60krXXs/edit?gid=0#gid=0"><img src="https://img.shields.io/badge/Benchmark%20score-000?logoColor=FFE165&logo=huggingface&style=for-the-badge" alt="評価ベンチマークスコア"></a>
<hr>
</div>
OpenHands旧OpenDevinへようこそ。これはAIが駆動するソフトウェア開発エージェントのプラットフォームです。
OpenHandsのエージェントは人間の開発者ができることは何でもこなします。コードを修正し、コマンドを実行し、ウェブを閲覧し、APIを呼び出し、StackOverflowからコードスニペットをコピーすることさえできます。
詳細は[docs.all-hands.dev](https://docs.all-hands.dev)をご覧いただくか、[OpenHands Cloud](https://app.all-hands.dev)に登録して始めましょう。
> [!IMPORTANT]
> 仕事でOpenHandsを使っていますかぜひお話を聞かせてください。[こちらの短いフォーム](https://docs.google.com/forms/d/e/1FAIpQLSet3VbGaz8z32gW9Wm-Grl4jpt5WgMXPgJ4EDPVmCETCBpJtQ/viewform)にご記入いただき、Design Partnerプログラムにご参加ください。商用機能の早期アクセスや製品ロードマップへのフィードバックの機会を提供します。
![アプリのスクリーンショット](./docs/static/img/screenshot.png)
## ☁️ OpenHands Cloud
OpenHandsを始める最も簡単な方法は[OpenHands Cloud](https://app.all-hands.dev)を利用することです。新規ユーザーには50ドル分の無料クレジットが付与されます。
## 💻 OpenHandsをローカルで実行する
OpenHandsはDockerを利用してローカル環境でも実行できます。システム要件や詳細については[Running OpenHands](https://docs.all-hands.dev/usage/installation)ガイドをご覧ください。
> [!WARNING]
> 公共ネットワークで実行していますか?[Hardened Docker Installation Guide](https://docs.all-hands.dev/usage/runtimes/docker#hardened-docker-installation)を参照して、ネットワークバインディングの制限や追加のセキュリティ対策を実施してください。
```bash
docker pull docker.all-hands.dev/all-hands-ai/runtime:0.54-nikolaik
docker run -it --rm --pull=always \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.54-nikolaik \
-e LOG_ALL_EVENTS=true \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ~/.openhands:/.openhands \
-p 3000:3000 \
--add-host host.docker.internal:host-gateway \
--name openhands-app \
docker.all-hands.dev/all-hands-ai/openhands:0.54
```
**注**: バージョン0.44以前のOpenHandsを使用していた場合は、会話履歴を移行するために `mv ~/.openhands-state ~/.openhands` を実行してください。
OpenHandsは[http://localhost:3000](http://localhost:3000)で起動します!

View File

@@ -1,113 +0,0 @@
import os
import pathlib
import subprocess
# This script is intended to be run by Poetry during the build process.
# Define the expected name of the .vsix file based on the extension's package.json
# This should match the name and version in openhands-vscode/package.json
EXTENSION_NAME = 'openhands-vscode'
EXTENSION_VERSION = '0.0.1'
VSIX_FILENAME = f'{EXTENSION_NAME}-{EXTENSION_VERSION}.vsix'
# Paths
ROOT_DIR = pathlib.Path(__file__).parent.resolve()
VSCODE_EXTENSION_DIR = ROOT_DIR / 'openhands' / 'integrations' / 'vscode'
def check_node_version():
"""Check if Node.js version is sufficient for building the extension."""
try:
result = subprocess.run(
['node', '--version'], capture_output=True, text=True, check=True
)
version_str = result.stdout.strip()
# Extract major version number (e.g., "v12.22.9" -> 12)
major_version = int(version_str.lstrip('v').split('.')[0])
return major_version >= 18 # Align with frontend actual usage (18.20.1)
except (subprocess.CalledProcessError, FileNotFoundError, ValueError):
return False
def build_vscode_extension():
"""Builds the VS Code extension."""
vsix_path = VSCODE_EXTENSION_DIR / VSIX_FILENAME
# Check if VSCode extension build is disabled via environment variable
if os.environ.get('SKIP_VSCODE_BUILD', '').lower() in ('1', 'true', 'yes'):
print('--- Skipping VS Code extension build (SKIP_VSCODE_BUILD is set) ---')
if vsix_path.exists():
print(f'--- Using existing VS Code extension: {vsix_path} ---')
else:
print('--- No pre-built VS Code extension found ---')
return
# Check Node.js version - if insufficient, use pre-built extension as fallback
if not check_node_version():
print('--- Warning: Node.js version < 18 detected or Node.js not found ---')
print('--- Skipping VS Code extension build (requires Node.js >= 18) ---')
print('--- Using pre-built extension if available ---')
if not vsix_path.exists():
print('--- Warning: No pre-built VS Code extension found ---')
print('--- VS Code extension will not be available ---')
else:
print(f'--- Using pre-built VS Code extension: {vsix_path} ---')
return
print(f'--- Building VS Code extension in {VSCODE_EXTENSION_DIR} ---')
try:
# Ensure npm dependencies are installed
print('--- Running npm install for VS Code extension ---')
subprocess.run(
['npm', 'install'],
cwd=VSCODE_EXTENSION_DIR,
check=True,
shell=os.name == 'nt',
)
# Package the extension
print(f'--- Packaging VS Code extension ({VSIX_FILENAME}) ---')
subprocess.run(
['npm', 'run', 'package-vsix'],
cwd=VSCODE_EXTENSION_DIR,
check=True,
shell=os.name == 'nt',
)
# Verify the generated .vsix file exists
if not vsix_path.exists():
raise FileNotFoundError(
f'VS Code extension package not found after build: {vsix_path}'
)
print(f'--- VS Code extension built successfully: {vsix_path} ---')
except subprocess.CalledProcessError as e:
print(f'--- Warning: Failed to build VS Code extension: {e} ---')
print('--- Continuing without building extension ---')
if not vsix_path.exists():
print('--- Warning: No pre-built VS Code extension found ---')
print('--- VS Code extension will not be available ---')
def build(setup_kwargs):
"""This function is called by Poetry during the build process.
`setup_kwargs` is a dictionary that will be passed to `setuptools.setup()`.
"""
print('--- Running custom Poetry build script (build_vscode.py) ---')
# Build the VS Code extension and place the .vsix file
build_vscode_extension()
# Poetry will handle including files based on pyproject.toml `include` patterns.
# Ensure openhands/integrations/vscode/*.vsix is included there.
print('--- Custom Poetry build script (build_vscode.py) finished ---')
if __name__ == '__main__':
print('Running build_vscode.py directly for testing VS Code extension packaging...')
build_vscode_extension()
print('Direct execution of build_vscode.py finished.')

View File

@@ -10,7 +10,18 @@
# General core configurations
##############################################################################
[core]
# API keys and configuration for core services
# API key for E2B
#e2b_api_key = ""
# API key for Modal
#modal_api_token_id = ""
#modal_api_token_secret = ""
# API key for Daytona
#daytona_api_key = ""
# Daytona Target
#daytona_target = ""
# Base path for the workspace
#workspace_base = "./workspace"
@@ -18,6 +29,9 @@
# Cache directory path
#cache_dir = "/tmp/cache"
# Reasoning effort for o1 models (low, medium, high, or not set)
#reasoning_effort = "medium"
# Debugging enabled
#debug = false
@@ -46,14 +60,11 @@
# Maximum file size for uploads, in megabytes
#file_uploads_max_file_size_mb = 0
# Enable the browser environment
#enable_browser = true
# Maximum budget per task, 0.0 means no limit
#max_budget_per_task = 0.0
# Maximum number of iterations
#max_iterations = 500
#max_iterations = 250
# Path to mount the workspace in the sandbox
#workspace_mount_path_in_sandbox = "/workspace"
@@ -116,9 +127,6 @@ api_key = ""
# API version
#api_version = ""
# Reasoning effort for OpenAI o-series models (low, medium, high, or not set)
#reasoning_effort = "medium"
# Cost per input token
#input_cost_per_token = 0.0
@@ -193,27 +201,6 @@ model = "gpt-4o"
#native_tool_calling = None
# Safety settings for models that support them (e.g., Mistral AI, Gemini)
# Example for Mistral AI:
# safety_settings = [
# { "category" = "hate", "threshold" = "low" },
# { "category" = "harassment", "threshold" = "low" },
# { "category" = "sexual", "threshold" = "low" },
# { "category" = "dangerous", "threshold" = "low" }
# ]
#
# Example for Gemini:
# safety_settings = [
# { "category" = "HARM_CATEGORY_HARASSMENT", "threshold" = "BLOCK_NONE" },
# { "category" = "HARM_CATEGORY_HATE_SPEECH", "threshold" = "BLOCK_NONE" },
# { "category" = "HARM_CATEGORY_SEXUALLY_EXPLICIT", "threshold" = "BLOCK_NONE" },
# { "category" = "HARM_CATEGORY_DANGEROUS_CONTENT", "threshold" = "BLOCK_NONE" }
# ]
#safety_settings = []
[llm.draft_editor]
# The number of times llm_editor tries to fix an error when editing.
correct_num = 5
[llm.gpt4o-mini]
api_key = ""
@@ -229,7 +216,6 @@ model = "gpt-4o"
[agent]
# Whether the browsing tool is enabled
# Note: when this is set to true, enable_browser in the core config must also be true
enable_browsing = true
# Whether the LLM draft editor is enabled
@@ -264,19 +250,11 @@ enable_finish = true
# length limit
enable_history_truncation = true
# Whether the condensation request tool is enabled
enable_condensation_request = false
[agent.RepoExplorerAgent]
# Example: use a cheaper model for RepoExplorerAgent to reduce cost, especially
# useful when an agent doesn't demand high quality but uses a lot of tokens
llm_config = 'gpt3'
[agent.CustomAgent]
# Example: use a custom agent from a different package
# This will be automatically be registered as a new agent named "CustomAgent"
classpath = "my_package.my_module.MyCustomAgent"
#################################### Sandbox ###################################
# Configuration for the sandbox
##############################################################################
@@ -335,25 +313,9 @@ classpath = "my_package.my_module.MyCustomAgent"
# Enable GPU support in the runtime
#enable_gpu = false
# When there are multiple cards, you can specify the GPU by ID
#cuda_visible_devices = ''
# Additional Docker runtime kwargs
#docker_runtime_kwargs = {}
# Specific port to use for VSCode. If not set, a random port will be chosen.
# Useful when deploying OpenHands in a remote machine where you need to expose a specific port.
#vscode_port = 41234
# Volume mounts in the format 'host_path:container_path[:mode]'
# e.g. '/my/host/dir:/workspace:rw'
# Multiple mounts can be specified using commas
# e.g. '/path1:/workspace/path1,/path2:/workspace/path2:ro'
# Configure volumes under the [sandbox] section:
# [sandbox]
# volumes = "/my/host/dir:/workspace:rw,/path2:/workspace/path2:ro"
#################################### Security ###################################
# Configuration for security features
##############################################################################
@@ -429,53 +391,9 @@ type = "noop"
#[llm.condenser]
#model = "gpt-4o"
#temperature = 0.1
#max_input_tokens = 1024
#max_tokens = 1024
#################################### Eval ####################################
# Configuration for the evaluation, please refer to the specific evaluation
# plugin for the available options
##############################################################################
########################### Kubernetes #######################################
# Kubernetes configuration when using the Kubernetes runtime
##############################################################################
[kubernetes]
# The Kubernetes namespace to use for OpenHands resources
#namespace = "default"
# Domain for ingress resources
#ingress_domain = "localhost"
# Size of the persistent volume claim
#pvc_storage_size = "2Gi"
# Storage class for persistent volume claims
#pvc_storage_class = "standard"
# CPU request for runtime pods
#resource_cpu_request = "1"
# Memory request for runtime pods
#resource_memory_request = "1Gi"
# Memory limit for runtime pods
#resource_memory_limit = "2Gi"
# Optional name of image pull secret for private registries
#image_pull_secret = ""
# Optional name of TLS secret for ingress
#ingress_tls_secret = ""
# Optional node selector key for pod scheduling
#node_selector_key = ""
# Optional node selector value for pod scheduling
#node_selector_val = ""
# Optional YAML string defining pod tolerations
#tolerations_yaml = ""
# Run the runtime sandbox container in privileged mode for use with docker-in-docker
#privileged = false

View File

@@ -1,16 +1,16 @@
ARG OPENHANDS_BUILD_VERSION=dev
FROM node:24.3.0-bookworm-slim AS frontend-builder
FROM node:21.7.2-bookworm-slim AS frontend-builder
WORKDIR /app
COPY frontend/package.json frontend/package-lock.json ./
COPY ./frontend/package.json frontend/package-lock.json ./
RUN npm install -g npm@10.5.1
RUN npm ci
COPY frontend ./
COPY ./frontend ./
RUN npm run build
FROM python:3.12.10-slim AS base
FROM base AS backend-builder
FROM python:3.12.3-slim AS backend-builder
WORKDIR /app
ENV PYTHONPATH='/app'
@@ -21,19 +21,18 @@ ENV POETRY_NO_INTERACTION=1 \
POETRY_CACHE_DIR=/tmp/poetry_cache
RUN apt-get update -y \
&& apt-get install -y curl make git build-essential jq gettext \
&& python3 -m pip install poetry --break-system-packages
&& apt-get install -y curl make git build-essential \
&& python3 -m pip install poetry==1.8.2 --break-system-packages
COPY pyproject.toml poetry.lock ./
COPY ./pyproject.toml ./poetry.lock ./
RUN touch README.md
RUN export POETRY_CACHE_DIR && poetry install --no-root && rm -rf $POETRY_CACHE_DIR
RUN export POETRY_CACHE_DIR && poetry install --without evaluation --no-root && rm -rf $POETRY_CACHE_DIR
FROM base AS openhands-app
FROM python:3.12.3-slim AS openhands-app
WORKDIR /app
# re-declare for this section
ARG OPENHANDS_BUILD_VERSION
ARG OPENHANDS_BUILD_VERSION #re-declare for this section
ENV RUN_AS_OPENHANDS=true
# A random number--we need this to be different from the user's UID on the host machine
@@ -44,8 +43,7 @@ ENV WORKSPACE_BASE=/opt/workspace_base
ENV OPENHANDS_BUILD_VERSION=$OPENHANDS_BUILD_VERSION
ENV SANDBOX_USER_ID=0
ENV FILE_STORE=local
ENV FILE_STORE_PATH=/.openhands
ENV INIT_GIT_IN_EMPTY_WORKSPACE=1
ENV FILE_STORE_PATH=/.openhands-state
RUN mkdir -p $FILE_STORE_PATH
RUN mkdir -p $WORKSPACE_BASE
@@ -58,8 +56,8 @@ RUN sed -i 's/^UID_MIN.*/UID_MIN 499/' /etc/login.defs
# Default is 60000, but we've seen up to 200000
RUN sed -i 's/^UID_MAX.*/UID_MAX 1000000/' /etc/login.defs
RUN groupadd --gid $OPENHANDS_USER_ID app
RUN useradd -l -m -u $OPENHANDS_USER_ID --gid $OPENHANDS_USER_ID -s /bin/bash openhands && \
RUN groupadd app
RUN useradd -l -m -u $OPENHANDS_USER_ID -s /bin/bash openhands && \
usermod -aG app openhands && \
usermod -aG sudo openhands && \
echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
@@ -72,11 +70,17 @@ ENV VIRTUAL_ENV=/app/.venv \
PYTHONPATH='/app'
COPY --chown=openhands:app --chmod=770 --from=backend-builder ${VIRTUAL_ENV} ${VIRTUAL_ENV}
RUN playwright install --with-deps chromium
COPY --chown=openhands:app --chmod=770 ./microagents ./microagents
COPY --chown=openhands:app --chmod=770 ./openhands ./openhands
COPY --chown=openhands:app --chmod=777 ./openhands/runtime/plugins ./openhands/runtime/plugins
COPY --chown=openhands:app pyproject.toml poetry.lock README.md MANIFEST.in LICENSE ./
COPY --chown=openhands:app --chmod=770 ./openhands/agenthub ./openhands/agenthub
COPY --chown=openhands:app ./pyproject.toml ./pyproject.toml
COPY --chown=openhands:app ./poetry.lock ./poetry.lock
COPY --chown=openhands:app ./README.md ./README.md
COPY --chown=openhands:app ./MANIFEST.in ./MANIFEST.in
COPY --chown=openhands:app ./LICENSE ./LICENSE
# This is run as "openhands" user, and will create __pycache__ with openhands:openhands ownership
RUN python openhands/core/download.py # No-op to download assets

View File

@@ -23,21 +23,13 @@ if [ -z "$WORKSPACE_MOUNT_PATH" ]; then
unset WORKSPACE_BASE
fi
if [[ "$INSTALL_THIRD_PARTY_RUNTIMES" == "true" ]]; then
echo "Downloading and installing third_party_runtimes..."
echo "Warning: Third-party runtimes are provided as-is, not actively supported and may be removed in future releases."
if pip install 'openhands-ai[third_party_runtimes]' -qqq 2> >(tee /dev/stderr); then
echo "third_party_runtimes installed successfully."
else
echo "Failed to install third_party_runtimes." >&2
exit 1
fi
fi
if [[ "$SANDBOX_USER_ID" -eq 0 ]]; then
echo "Running OpenHands as root"
export RUN_AS_OPENHANDS=false
mkdir -p /root/.cache/ms-playwright/
if [ -d "/home/openhands/.cache/ms-playwright/" ]; then
mv /home/openhands/.cache/ms-playwright/ /root/.cache/
fi
"$@"
else
echo "Setting up enduser with id $SANDBOX_USER_ID"
@@ -66,6 +58,10 @@ else
fi
mkdir -p /home/enduser/.cache/huggingface/hub/
mkdir -p /home/enduser/.cache/ms-playwright/
if [ -d "/home/openhands/.cache/ms-playwright/" ]; then
mv /home/openhands/.cache/ms-playwright/ /home/enduser/.cache/
fi
usermod -aG $DOCKER_SOCKET_GID enduser
echo "Running as enduser"

View File

@@ -10,9 +10,8 @@ services:
environment:
- BACKEND_HOST=${BACKEND_HOST:-"0.0.0.0"}
- SANDBOX_API_HOSTNAME=host.docker.internal
- DOCKER_HOST_ADDR=host.docker.internal
#
- SANDBOX_RUNTIME_CONTAINER_IMAGE=${SANDBOX_RUNTIME_CONTAINER_IMAGE:-ghcr.io/all-hands-ai/runtime:0.54-nikolaik}
- SANDBOX_RUNTIME_CONTAINER_IMAGE=${SANDBOX_RUNTIME_CONTAINER_IMAGE:-ghcr.io/all-hands-ai/runtime:0.34-nikolaik}
- SANDBOX_USER_ID=${SANDBOX_USER_ID:-1234}
- WORKSPACE_MOUNT_PATH=${WORKSPACE_BASE:-$PWD/workspace}
ports:

View File

@@ -1,4 +1,4 @@
FROM ubuntu:24.04
FROM ubuntu:22.04
# install basic packages
RUN apt-get update && apt-get install -y \

View File

@@ -1,47 +1,43 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
rev: v4.5.0
hooks:
- id: trailing-whitespace
exclude: ^(docs/|modules/|python/|openhands-ui/|third_party/)
exclude: docs/modules/python
- id: end-of-file-fixer
exclude: ^(docs/|modules/|python/|openhands-ui/|third_party/)
exclude: docs/modules/python
- id: check-yaml
args: ["--allow-multiple-documents"]
- id: debug-statements
- repo: https://github.com/tox-dev/pyproject-fmt
rev: v2.5.1
rev: 1.7.0
hooks:
- id: pyproject-fmt
- repo: https://github.com/abravalheri/validate-pyproject
rev: v0.24.1
rev: v0.16
hooks:
- id: validate-pyproject
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.11.8
rev: v0.4.1
hooks:
# Run the linter.
- id: ruff
entry: ruff check --config dev_config/python/ruff.toml
types_or: [python, pyi, jupyter]
args: [--fix, --unsafe-fixes]
exclude: third_party/
args: [--fix]
# Run the formatter.
- id: ruff-format
entry: ruff format --config dev_config/python/ruff.toml
types_or: [python, pyi, jupyter]
exclude: third_party/
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.15.0
rev: v1.9.0
hooks:
- id: mypy
additional_dependencies:
[types-requests, types-setuptools, types-pyyaml, types-toml, types-docker, types-Markdown, pydantic, lxml]
# To see gaps add `--html-report mypy-report/`
[types-requests, types-setuptools, types-pyyaml, types-toml]
entry: mypy --config-file dev_config/python/mypy.ini openhands/
always_run: true
pass_filenames: false

View File

@@ -7,9 +7,3 @@ warn_unreachable = True
warn_redundant_casts = True
no_implicit_optional = True
strict_optional = True
# Exclude third-party runtime directory from type checking
exclude = third_party/
[mypy-openhands.memory.condenser.impl.*]
disable_error_code = override

View File

@@ -1,6 +1,3 @@
# Exclude third-party runtime directory from linting
exclude = ["third_party/"]
[lint]
select = [
"E",
@@ -10,9 +7,6 @@ select = [
"Q",
"B",
"ASYNC",
"UP006", # Use `list` instead of `List` for annotations
"UP007", # Use `X | Y` instead of `Union[X, Y]`
"UP008", # Use `X | None` instead of `Optional[X]`
]
ignore = [
@@ -23,12 +17,6 @@ ignore = [
"B010",
"B904",
"B018",
# Temporarily ignore ASYNC rules until they can be properly fixed in a separate PR
"ASYNC110",
"ASYNC220",
"ASYNC221",
"ASYNC230",
"ASYNC251",
]
[lint.flake8-quotes]

View File

@@ -7,8 +7,8 @@ services:
image: openhands:latest
container_name: openhands-app-${DATE:-}
environment:
- SANDBOX_RUNTIME_CONTAINER_IMAGE=${SANDBOX_RUNTIME_CONTAINER_IMAGE:-docker.all-hands.dev/all-hands-ai/runtime:0.54-nikolaik}
#- SANDBOX_USER_ID=${SANDBOX_USER_ID:-1234} # enable this only if you want a specific non-root sandbox user but you will have to manually adjust permissions of ~/.openhands for this user
- SANDBOX_RUNTIME_CONTAINER_IMAGE=${SANDBOX_RUNTIME_CONTAINER_IMAGE:-docker.all-hands.dev/all-hands-ai/runtime:0.34-nikolaik}
#- SANDBOX_USER_ID=${SANDBOX_USER_ID:-1234} # enable this only if you want a specific non-root sandbox user but you will have to manually adjust permissions of openhands-state for this user
- WORKSPACE_MOUNT_PATH=${WORKSPACE_BASE:-$PWD/workspace}
ports:
- "3000:3000"
@@ -16,7 +16,7 @@ services:
- "host.docker.internal:host-gateway"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ~/.openhands:/.openhands
- ~/.openhands-state:/.openhands-state
- ${WORKSPACE_BASE:-$PWD/workspace}:/opt/workspace_base
pull_policy: build
stdin_open: true

21
docs/.gitignore vendored Normal file
View File

@@ -0,0 +1,21 @@
# Dependencies
/node_modules
# Production
/build
/static/swagger-ui
# Generated files
.docusaurus
.cache-loader
# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

View File

@@ -54,9 +54,9 @@ docker run -it \
When adding a note or warning, use the built-in note and warning syntax.
Example:
<Note>
:::note
This section is for advanced users only.
</Note>
:::
### Referring to UI Elements

View File

@@ -1,17 +1,60 @@
# Setup
# OpenHands Documentation
```
npm install -g mint
This website is built using [Docusaurus](https://docusaurus.io/).
When published, the content will be published at https://docs.all-hands.dev/.
### Installation
```bash
$ cd docs
$ yarn
```
or
### Local Development
```
yarn global add mint
$ yarn start # for the default English version
```
# Preview
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
Alternatively, you can pass a `--locale` argument to render a specific language in dev mode as in:
```
mint dev
$ yarn start --locale pt-BR # for the Brazilian Portuguese version
$ yarn start --locale fr # for the French version
$ yarn start --locale zh-Hans # for the Chinese Han (simplified variant) version
```
### Build
```
$ yarn build
```
This command generates static content into the `build` directory and can be served using any static contents hosting service.
It compiles all languages.
### Deployment
Open a new pull request and - when it is merged - the [deploy-docs](.github/workflows/deploy-docs.yml) GH action will take care of everything else.
## Automatic Translations
Translations can be automatically updated when the original English content changes, this is done by the script [`translation_updater.py`](./translation_updater.py).
From the root of the repository, you can run the following:
```bash
$ export ANTHROPIC_API_KEY=<your_api_key>
$ poetry run python docs/translation_updater.py
# ...
# Change detected in docs/modules/usage/getting-started.mdx
# translating... docs/modules/usage/getting-started.mdx pt-BR
# translation done
# ...
```
This process uses `claude-3-7-sonnet-20250219` as base model and each language consumes at least ~30k input tokens and ~35k output tokens.

View File

@@ -1,17 +0,0 @@
# セットアップ
```
npm install -g mint
```
または
```
yarn global add mint
```
# プレビュー
```
mint dev
```

3
docs/babel.config.js Normal file
View File

@@ -0,0 +1,3 @@
module.exports = {
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
};

View File

@@ -1,230 +0,0 @@
{
"$schema": "https://mintlify.com/docs.json",
"theme": "mint",
"name": "All Hands Docs",
"colors": {
"primary": "#99873c",
"light": "#ffe165",
"dark": "#ffe165"
},
"background": {
"color": {
"light": "#f7f3ee",
"dark": "#0B0D0E"
}
},
"appearance": {
"default": "light"
},
"favicon": "/logo-square.png",
"navigation": {
"tabs": [
{
"tab": "Docs",
"pages": [
"index",
"usage/installation",
"usage/getting-started",
"usage/key-features",
"usage/faqs",
{
"group": "OpenHands Cloud",
"pages": [
"usage/cloud/openhands-cloud",
{
"group": "Integrations",
"pages": [
"usage/cloud/bitbucket-installation",
"usage/cloud/github-installation",
"usage/cloud/gitlab-installation",
"usage/cloud/slack-installation",
{
"group": "Project Management Tools",
"pages": [
"usage/cloud/project-management/overview",
"usage/cloud/project-management/jira-integration",
"usage/cloud/project-management/jira-dc-integration",
"usage/cloud/project-management/linear-integration"
]
}
]
},
"usage/cloud/cloud-ui",
"usage/cloud/cloud-api"
]
},
{
"group": "Run OpenHands on Your Own",
"pages": [
"usage/local-setup",
"usage/how-to/gui-mode",
"usage/how-to/cli-mode",
"usage/how-to/headless-mode",
"usage/how-to/github-action",
{
"group": "Advanced Configuration",
"pages": [
{
"group": "LLM Configuration",
"pages": [
"usage/llms/llms",
{
"group": "Providers",
"pages": [
"usage/llms/openhands-llms",
"usage/llms/azure-llms",
"usage/llms/google-llms",
"usage/llms/groq",
"usage/llms/local-llms",
"usage/llms/litellm-proxy",
"usage/llms/moonshot",
"usage/llms/openai-llms",
"usage/llms/openrouter"
]
}
]
},
{
"group": "Runtime Configuration",
"pages": [
"usage/runtimes/overview",
{
"group": "Providers",
"pages": [
"usage/runtimes/docker",
"usage/runtimes/remote",
"usage/runtimes/local",
{
"group": "Third-Party Providers",
"pages": [
"usage/runtimes/modal",
"usage/runtimes/daytona",
"usage/runtimes/runloop",
"usage/runtimes/e2b"
]
}
]
}
]
},
"usage/configuration-options",
"usage/how-to/custom-sandbox-guide",
"usage/search-engine-setup",
"usage/mcp"
]
}
]
},
{
"group": "Customizations & Settings",
"pages": [
"usage/common-settings",
"usage/prompting/repository",
{
"group": "Microagents",
"pages": [
"usage/prompting/microagents-overview",
"usage/prompting/microagents-repo",
"usage/prompting/microagents-keyword",
"usage/prompting/microagents-org",
"usage/prompting/microagents-public"
]
}
]
},
{
"group": "Tips and Tricks",
"pages": [
"usage/prompting/prompting-best-practices"
]
},
{
"group": "Troubleshooting & Feedback",
"pages": [
"usage/troubleshooting/troubleshooting",
"usage/feedback"
]
},
{
"group": "OpenHands Developers",
"pages": [
"usage/how-to/development-overview",
{
"group": "Architecture",
"pages": [
"usage/architecture/backend",
"usage/architecture/runtime"
]
},
"usage/how-to/debugging",
"usage/how-to/evaluation-harness",
"usage/how-to/websocket-connection"
]
}
]
},
{
"tab": "Success Stories",
"pages": [
"success-stories/index"
]
},
{
"tab": "API Reference",
"openapi": "/openapi.json"
}
],
"global": {
"anchors": [
{
"anchor": "Company",
"href": "https://www.all-hands.dev/",
"icon": "house"
},
{
"anchor": "Blog",
"href": "https://www.all-hands.dev/blog",
"icon": "newspaper"
},
{
"anchor": "OpenHands Cloud",
"href": "https://app.all-hands.dev",
"icon": "cloud"
}
]
}
},
"logo": {
"light": "/logo/light.svg",
"dark": "/logo/dark.svg"
},
"navbar": {
"links": [
],
"primary": {
"type": "github",
"href": "https://github.com/All-Hands-AI/OpenHands"
}
},
"footer": {
"socials": {
"slack": "https://join.slack.com/t/openhands-ai/shared_invite/zt-3847of6xi-xuYJIPa6YIPg4ElbDWbtSA",
"github": "https://github.com/All-Hands-AI/OpenHands",
"discord": "https://discord.gg/ESHStjSjD4"
}
},
"contextual": {
"options": [
"copy",
"view",
"chatgpt",
"claude"
]
},
"redirects": [
{
"source": "/modules/:slug*",
"destination": "/:slug*"
}
]
}

107
docs/docusaurus.config.ts Normal file
View File

@@ -0,0 +1,107 @@
import type * as Preset from '@docusaurus/preset-classic';
import type { Config } from '@docusaurus/types';
import { themes as prismThemes } from 'prism-react-renderer';
const config: Config = {
title: 'OpenHands',
tagline: 'Code Less, Make More',
favicon: 'img/logo-square.png',
// Set the production url of your site here
url: 'https://docs.all-hands.dev',
baseUrl: '/',
// GitHub pages deployment config.
organizationName: 'All-Hands-AI',
projectName: 'OpenHands',
trailingSlash: false,
onBrokenLinks: 'throw',
onBrokenMarkdownLinks: 'warn',
// Even if you don't use internationalization, you can use this field to set
// useful metadata like html lang. For example, if your site is Chinese, you
// may want to replace "en" with "zh-Hans".
i18n: {
defaultLocale: 'en',
locales: ['en', 'fr', 'zh-Hans', 'ja', 'pt-BR'],
localeConfigs: {
en: {
htmlLang: 'en-GB',
},
},
},
markdown: {
mermaid: true,
},
themes: ['@docusaurus/theme-mermaid'],
plugins: [],
presets: [
[
'classic',
{
docs: {
path: 'modules',
routeBasePath: 'modules',
sidebarPath: './sidebars.ts',
exclude: [
// '**/_*.{js,jsx,ts,tsx,md,mdx}',
// '**/_*/**',
'**/*.test.{js,jsx,ts,tsx}',
'**/__tests__/**',
],
},
blog: {
showReadingTime: true,
},
theme: {
customCss: './src/css/custom.css',
},
} satisfies Preset.Options,
],
],
themeConfig: {
image: 'img/docusaurus.png',
navbar: {
title: 'OpenHands',
logo: {
alt: 'OpenHands',
src: 'img/logo.png',
},
items: [
{
type: 'docSidebar',
sidebarId: 'docsSidebar',
position: 'left',
label: 'User Guides',
},
{
href: 'https://docs.all-hands.dev/swagger-ui/', // FIXME: this should be a relative path, but docusarus steals the click
label: 'API',
position: 'left',
},
{
type: 'localeDropdown',
position: 'left',
},
{
href: 'https://all-hands.dev',
label: 'Company',
position: 'right',
},
{
href: 'https://github.com/All-Hands-AI/OpenHands',
label: 'GitHub',
position: 'right',
},
],
},
prism: {
theme: prismThemes.oneLight,
darkTheme: prismThemes.oneDark,
},
} satisfies Preset.ThemeConfig,
};
export default config;

View File

@@ -1,19 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.06145 23.1079C5.26816 22.3769 -3.39077 20.6274 1.4173 5.06384C9.6344 6.09939 16.9728 14.0644 9.06145 23.1079Z" fill="url(#paint0_linear_17557_2021)"/>
<path d="M8.91928 23.0939C5.27642 21.2223 0.78371 4.20891 17.0071 0C20.7569 7.19341 19.6212 16.5452 8.91928 23.0939Z" fill="url(#paint1_linear_17557_2021)"/>
<path d="M8.91388 23.0788C8.73534 19.8817 10.1585 9.08525 23.5699 13.1107C23.1812 20.1229 18.984 26.4182 8.91388 23.0788Z" fill="url(#paint2_linear_17557_2021)"/>
<defs>
<linearGradient id="paint0_linear_17557_2021" x1="3.77557" y1="5.91571" x2="5.23185" y2="21.5589" gradientUnits="userSpaceOnUse">
<stop stop-color="#18E299"/>
<stop offset="1" stop-color="#15803D"/>
</linearGradient>
<linearGradient id="paint1_linear_17557_2021" x1="12.1711" y1="-0.718425" x2="10.1897" y2="22.9832" gradientUnits="userSpaceOnUse">
<stop stop-color="#16A34A"/>
<stop offset="1" stop-color="#4ADE80"/>
</linearGradient>
<linearGradient id="paint2_linear_17557_2021" x1="23.1327" y1="15.353" x2="9.33841" y2="18.5196" gradientUnits="userSpaceOnUse">
<stop stop-color="#4ADE80"/>
<stop offset="1" stop-color="#0D9373"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

102
docs/generate-swagger-ui.js Normal file
View File

@@ -0,0 +1,102 @@
const fs = require('fs');
const path = require('path');
const swaggerUiDist = require('swagger-ui-dist');
/**
* This script manually sets up Swagger UI for the Docusaurus documentation.
*
* Why we need this approach:
* 1. Docusaurus doesn't have a built-in way to integrate Swagger UI
* 2. We need to copy the necessary files from swagger-ui-dist to our static directory
* 3. We need to create a custom index.html file that points to our OpenAPI spec
* 4. This approach allows us to customize the Swagger UI to match our documentation style
*/
// Get the absolute path to the swagger-ui-dist package
const swaggerUiDistPath = swaggerUiDist.getAbsoluteFSPath();
// Create the target directory if it doesn't exist
const targetDir = path.join(__dirname, 'static', 'swagger-ui');
if (!fs.existsSync(targetDir)) {
fs.mkdirSync(targetDir, { recursive: true });
}
// Copy all files from swagger-ui-dist to our target directory
const files = fs.readdirSync(swaggerUiDistPath);
files.forEach(file => {
const sourcePath = path.join(swaggerUiDistPath, file);
const targetPath = path.join(targetDir, file);
// Skip directories and non-essential files
if (fs.statSync(sourcePath).isDirectory() ||
file === 'package.json' ||
file === 'README.md' ||
file.endsWith('.map')) {
return;
}
fs.copyFileSync(sourcePath, targetPath);
});
// Create a custom index.html file that points to our OpenAPI spec
const indexHtml = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>OpenHands API Documentation</title>
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" />
<link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
<style>
html {
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
margin: 0;
background: #fafafa;
}
</style>
</head>
<body>
<div id="swagger-ui"></div>
<script src="./swagger-ui-bundle.js" charset="UTF-8"> </script>
<script src="./swagger-ui-standalone-preset.js" charset="UTF-8"> </script>
<script>
window.onload = function() {
// Begin Swagger UI call region
const ui = SwaggerUIBundle({
url: "/openapi.json",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
});
// End Swagger UI call region
window.ui = ui;
};
</script>
</body>
</html>
`;
fs.writeFileSync(path.join(targetDir, 'index.html'), indexHtml);
console.log('Swagger UI files generated successfully in static/swagger-ui/');

427
docs/i18n/fr/code.json Normal file
View File

@@ -0,0 +1,427 @@
{
"footer.title": {
"message": "OpenHands"
},
"footer.docs": {
"message": "Documents"
},
"footer.community": {
"message": "Communauté"
},
"footer.copyright": {
"message": "© {year} OpenHands"
},
"faq.title": {
"message": "Questions Fréquemment Posées",
"description": "FAQ Title"
},
"faq.description": {
"message": "Questions Fréquemment Posées"
},
"faq.section.title.1": {
"message": "Qu'est-ce qu'OpenHands ?",
"description": "First Section Title"
},
"faq.section.highlight": {
"message": "OpenHands",
"description": "Highlight Text"
},
"faq.section.description.1": {
"message": "est un ingénieur logiciel autonome qui peut résoudre des tâches d'ingénierie logicielle et de navigation web à tout moment. Il peut exécuter des requêtes en sciences des données, telles que \"Trouver le nombre de demandes de pull à l'repository OpenHands dans les derniers mois\", et des tâches d'ingénierie logicielle, comme \"Veuillez ajouter des tests à ce fichier et vérifier si tous les tests passent. Si ce n'est pas le cas, réparez le fichier.\"",
"description": "Description for OpenHands"
},
"faq.section.description.2": {
"message": "De plus, OpenHands est une plateforme et communauté pour les développeurs d'agents qui souhaitent tester et évaluer de nouveaux agents.",
"description": "Further Description for OpenHands"
},
"faq.section.title.2": {
"message": "Support",
"description": "Support Section Title"
},
"faq.section.support.answer": {
"message": "Si vous rencontrez un problème que d'autres utilisateurs peuvent également avoir, merci de le signaler sur {githubLink}. Si vous avez des difficultés à l'installation ou des questions générales, rejoignez-vous sur {discordLink} ou {slackLink}.",
"description": "Support Answer"
},
"faq.section.title.3": {
"message": "Comment résoudre un problème sur GitHub avec OpenHands ?",
"description": "GitHub Issue Section Title"
},
"faq.section.github.steps.intro": {
"message": "Pour résoudre un problème sur GitHub en utilisant OpenHands, envoyez une commande à OpenHands demandant qu'il suit des étapes comme les suivantes :",
"description": "GitHub Steps Introduction"
},
"faq.section.github.step1": {
"message": "Lisez l'issue https://github.com/All-Hands-AI/OpenHands/issues/1611",
"description": "GitHub Step 1"
},
"faq.section.github.step2": {
"message": "Cloner le dépôt et vérifier une nouvelle branche",
"description": "GitHub Step 2"
},
"faq.section.github.step3": {
"message": "Sur la base des instructions dans la description de l'issue, modifiez les fichiers pour résoudre le problème",
"description": "GitHub Step 3"
},
"faq.section.github.step4": {
"message": "Pousser le résultat à GitHub en utilisant la variable d'environnement GITHUB_TOKEN",
"description": "GitHub Step 4"
},
"faq.section.github.step5": {
"message": "Dites-moi le lien que je dois utiliser pour envoyer une demande de pull",
"description": "GitHub Step 5"
},
"faq.section.github.steps.preRun": {
"message": "Avant de lancer OpenHands, vous pouvez faire :",
"description": "GitHub Steps Pre-Run"
},
"faq.section.github.steps.tokenInfo": {
"message": "où XXX est un jeton GitHub que vous avez créé et qui a les autorisations pour pousser dans le dépôt OpenHands. Si vous n'avez pas d'autorisations de modification du dépôt OpenHands, vous devrez peut-être changer cela en :",
"description": "GitHub Steps Token Info"
},
"faq.section.github.steps.usernameInfo": {
"message": "où USERNAME est votre nom GitHub.",
"description": "GitHub Steps Username Info"
},
"faq.section.title.4": {
"message": "Comment OpenHands est-il différent de Devin ?",
"description": "Devin Section Title"
},
"faq.section.openhands.linkText": {
"message": "Devin",
"description": "Devin Link Text"
},
"faq.section.openhands.description": {
"message": "est un produit commercial par Cognition Inc., qui a servi d'inspiration initiale pour OpenHands. Les deux visent à bien faire le travail d'ingénierie logicielle, mais vous pouvez télécharger, utiliser et modifier OpenHands, tandis que Devin peut être utilisé uniquement via le site de Cognition. De plus, OpenHands a évolué au-delà de l'inspiration initiale, et est maintenant un écosystème communautaire pour le développement d'agents en général, et nous serions ravis de vous voir rejoindre et",
"description": "Devin Description"
},
"faq.section.openhands.contribute": {
"message": "contribuer",
"description": "Contribute Link"
},
"faq.section.title.5": {
"message": "Comment OpenHands est-il différent de ChatGPT ?",
"description": "ChatGPT Section Title"
},
"faq.section.chatgpt.description": {
"message": "ChatGPT vous pouvez accéder en ligne, il ne se connecte pas aux fichiers locaux et ses capacités d'exécution du code sont limitées. Alors qu'il peut écrire du code, mais c'est difficile à tester ou à exécuter.",
"description": "ChatGPT Description"
},
"homepage.description": {
"message": "Génération d'code AI pour l'ingénierie logicielle.",
"description": "The homepage description"
},
"homepage.getStarted": {
"message": "Commencer"
},
"welcome.message": {
"message": "Bienvenue à OpenHands, un système d'IA autonome ingénieur logiciel capable d'exécuter des tâches d'ingénierie complexes et de collaborer activement avec les utilisateurs sur les projets de développement logiciel."
},
"theme.ErrorPageContent.title": {
"message": "Cette page a planté.",
"description": "The title of the fallback page when the page crashed"
},
"theme.BackToTopButton.buttonAriaLabel": {
"message": "Retourner en haut de la page",
"description": "The ARIA label for the back to top button"
},
"theme.blog.archive.title": {
"message": "Archives",
"description": "The page & hero title of the blog archive page"
},
"theme.blog.archive.description": {
"message": "Archives",
"description": "The page & hero description of the blog archive page"
},
"theme.blog.paginator.navAriaLabel": {
"message": "Pagination des listes d'articles du blog",
"description": "The ARIA label for the blog pagination"
},
"theme.blog.paginator.newerEntries": {
"message": "Nouvelles entrées",
"description": "The label used to navigate to the newer blog posts page (previous page)"
},
"theme.blog.paginator.olderEntries": {
"message": "Anciennes entrées",
"description": "The label used to navigate to the older blog posts page (next page)"
},
"theme.blog.post.paginator.navAriaLabel": {
"message": "Pagination des articles du blog",
"description": "The ARIA label for the blog posts pagination"
},
"theme.blog.post.paginator.newerPost": {
"message": "Article plus récent",
"description": "The blog post button label to navigate to the newer/previous post"
},
"theme.blog.post.paginator.olderPost": {
"message": "Article plus ancien",
"description": "The blog post button label to navigate to the older/next post"
},
"theme.blog.post.plurals": {
"message": "Un article|{count} articles",
"description": "Pluralized label for \"{count} posts\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)"
},
"theme.blog.tagTitle": {
"message": "{nPosts} tags avec « {tagName} »",
"description": "The title of the page for a blog tag"
},
"theme.tags.tagsPageLink": {
"message": "Voir tous les tags",
"description": "The label of the link targeting the tag list page"
},
"theme.colorToggle.ariaLabel": {
"message": "Basculer entre le mode sombre et clair (actuellement {mode})",
"description": "The ARIA label for the navbar color mode toggle"
},
"theme.colorToggle.ariaLabel.mode.dark": {
"message": "mode sombre",
"description": "The name for the dark color mode"
},
"theme.colorToggle.ariaLabel.mode.light": {
"message": "mode clair",
"description": "The name for the light color mode"
},
"theme.docs.breadcrumbs.navAriaLabel": {
"message": "Bouton de navigation des liens de la page",
"description": "The ARIA label for the breadcrumbs"
},
"theme.docs.DocCard.categoryDescription.plurals": {
"message": "1 élément|{count} éléments",
"description": "The default description for a category card in the generated index about how many items this category includes"
},
"theme.docs.paginator.navAriaLabel": {
"message": "Pages de documentation",
"description": "The ARIA label for the docs pagination"
},
"theme.docs.paginator.previous": {
"message": "Précédent",
"description": "The label used to navigate to the previous doc"
},
"theme.docs.paginator.next": {
"message": "Suivant",
"description": "The label used to navigate to the next doc"
},
"theme.docs.tagDocListPageTitle.nDocsTagged": {
"message": "Un document tagué|{count} documents tagués",
"description": "Pluralized label for \"{count} docs tagged\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)"
},
"theme.docs.tagDocListPageTitle": {
"message": "{nDocsTagged} avec \"{tagName}\"",
"description": "The title of the page for a docs tag"
},
"theme.docs.versionBadge.label": {
"message": "Version: {versionLabel}"
},
"theme.docs.versions.unreleasedVersionLabel": {
"message": "Ceci est la documentation de la prochaine version {versionLabel} de {siteTitle}.",
"description": "The label used to tell the user that he's browsing an unreleased doc version"
},
"theme.docs.versions.unmaintainedVersionLabel": {
"message": "Ceci est la documentation de {siteTitle} {versionLabel}, qui n'est plus activement maintenue.",
"description": "The label used to tell the user that he's browsing an unmaintained doc version"
},
"theme.docs.versions.latestVersionSuggestionLabel": {
"message": "Pour une documentation à jour, consultez la {latestVersionLink} ({versionLabel}).",
"description": "The label used to tell the user to check the latest version"
},
"theme.docs.versions.latestVersionLinkLabel": {
"message": "dernière version",
"description": "The label used for the latest version suggestion link label"
},
"theme.common.editThisPage": {
"message": "Éditer cette page",
"description": "The link label to edit the current page"
},
"theme.common.headingLinkTitle": {
"message": "Lien direct vers {heading}",
"description": "Title for link to heading"
},
"theme.lastUpdated.atDate": {
"message": " le {date}",
"description": "The words used to describe on which date a page has been last updated"
},
"theme.lastUpdated.byUser": {
"message": " par {user}",
"description": "The words used to describe by who the page has been last updated"
},
"theme.lastUpdated.lastUpdatedAtBy": {
"message": "Dernière mise à jour{atDate}{byUser}",
"description": "The sentence used to display when a page has been last updated, and by who"
},
"theme.navbar.mobileVersionsDropdown.label": {
"message": "Versions",
"description": "The label for the navbar versions dropdown on mobile view"
},
"theme.NotFound.title": {
"message": "Page introuvable",
"description": "The title of the 404 page"
},
"theme.tags.tagsListLabel": {
"message": "Tags :",
"description": "The label alongside a tag list"
},
"theme.admonition.caution": {
"message": "prudence",
"description": "The default label used for the Caution admonition (:::caution)"
},
"theme.admonition.danger": {
"message": "danger",
"description": "The default label used for the Danger admonition (:::danger)"
},
"theme.admonition.info": {
"message": "information",
"description": "The default label used for the Info admonition (:::info)"
},
"theme.admonition.note": {
"message": "remarque",
"description": "The default label used for the Note admonition (:::note)"
},
"theme.admonition.tip": {
"message": "astuce",
"description": "The default label used for the Tip admonition (:::tip)"
},
"theme.admonition.warning": {
"message": "prudence",
"description": "The default label used for the Warning admonition (:::warning)"
},
"theme.AnnouncementBar.closeButtonAriaLabel": {
"message": "Fermer",
"description": "The ARIA label for close button of announcement bar"
},
"theme.blog.sidebar.navAriaLabel": {
"message": "Navigation vers les articles récents du blog",
"description": "The ARIA label for recent posts in the blog sidebar"
},
"theme.CodeBlock.copied": {
"message": "Copié",
"description": "The copied button label on code blocks"
},
"theme.CodeBlock.copyButtonAriaLabel": {
"message": "Copier le code",
"description": "The ARIA label for copy code blocks button"
},
"theme.CodeBlock.copy": {
"message": "Copier",
"description": "The copy button label on code blocks"
},
"theme.CodeBlock.wordWrapToggle": {
"message": "Activer/désactiver le retour à la ligne",
"description": "The title attribute for toggle word wrapping button of code block lines"
},
"theme.DocSidebarItem.expandCategoryAriaLabel": {
"message": "Développer la catégorie '{label}' de la barre latérale",
"description": "The ARIA label to expand the sidebar category"
},
"theme.DocSidebarItem.collapseCategoryAriaLabel": {
"message": "Réduire la catégorie '{label}' de la barre latérale",
"description": "The ARIA label to collapse the sidebar category"
},
"theme.NavBar.navAriaLabel": {
"message": "Main",
"description": "The ARIA label for the main navigation"
},
"theme.navbar.mobileLanguageDropdown.label": {
"message": "Langues",
"description": "The label for the mobile language switcher dropdown"
},
"theme.NotFound.p1": {
"message": "Nous n'avons pas trouvé ce que vous recherchez.",
"description": "The first paragraph of the 404 page"
},
"theme.NotFound.p2": {
"message": "Veuillez contacter le propriétaire du site qui vous a lié à l'URL d'origine et leur faire savoir que leur lien est cassé.",
"description": "The 2nd paragraph of the 404 page"
},
"theme.TOCCollapsible.toggleButtonLabel": {
"message": "Sur cette page",
"description": "The label used by the button on the collapsible TOC component"
},
"theme.blog.post.readMore": {
"message": "Lire plus",
"description": "The label used in blog post item excerpts to link to full blog posts"
},
"theme.blog.post.readMoreLabel": {
"message": "En savoir plus sur {title}",
"description": "The ARIA label for the link to full blog posts from excerpts"
},
"theme.blog.post.readingTime.plurals": {
"message": "Une minute de lecture|{readingTime} minutes de lecture",
"description": "Pluralized label for \"{readingTime} min read\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)"
},
"theme.docs.breadcrumbs.home": {
"message": "Page d'accueil",
"description": "The ARIA label for the home page in the breadcrumbs"
},
"theme.docs.sidebar.collapseButtonTitle": {
"message": "Réduire le menu latéral",
"description": "The title attribute for collapse button of doc sidebar"
},
"theme.docs.sidebar.collapseButtonAriaLabel": {
"message": "Réduire le menu latérale",
"description": "The title attribute for collapse button of doc sidebar"
},
"theme.docs.sidebar.navAriaLabel": {
"message": "Barre de navigation latérale des docs",
"description": "The ARIA label for the sidebar navigation"
},
"theme.docs.sidebar.closeSidebarButtonAriaLabel": {
"message": "Fermer la barre de navigation",
"description": "The ARIA label for close button of mobile sidebar"
},
"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": {
"message": "← Retour au menu principal",
"description": "The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"
},
"theme.docs.sidebar.toggleSidebarButtonAriaLabel": {
"message": "Ouvrir/fermer la barre de navigation",
"description": "The ARIA label for hamburger menu button of mobile navigation"
},
"theme.docs.sidebar.expandButtonTitle": {
"message": "Déplier le menu latéral",
"description": "The ARIA label and title attribute for expand button of doc sidebar"
},
"theme.docs.sidebar.expandButtonAriaLabel": {
"message": "Déployer le menu latérale",
"description": "The ARIA label and title attribute for expand button of doc sidebar"
},
"theme.ErrorPageContent.tryAgain": {
"message": "Réessayer",
"description": "The label of the button to try again rendering when the React error boundary captures an error"
},
"theme.common.skipToMainContent": {
"message": "Aller directement au contenu principal",
"description": "The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation"
},
"theme.tags.tagsPageTitle": {
"message": "Tags",
"description": "The title of the tag list page"
},
"theme.unlistedContent.title": {
"message": "Page non répertoriée",
"description": "The unlisted content banner title"
},
"theme.unlistedContent.message": {
"message": "Cette page n'est pas répertoriée. Les moteurs de recherche ne l'indexeront pas, et seuls les utilisateurs ayant un lien direct peuvent y accéder.",
"description": "The unlisted content banner message"
},
"Use AI to tackle the toil in your backlog. Our agents have all the same tools as a human developer: they can modify code, run commands, browse the web, call APIs, and yes-even copy code snippets from StackOverflow.": {
"message": "Utilisez l'IA pour gérer les tâches répétitives de votre backlog. Nos agents disposent des mêmes outils qu'un développeur humain : ils peuvent modifier du code, exécuter des commandes, naviguer sur le web, appeler des API et même copier des extraits de code depuis StackOverflow."
},
"Get started with OpenHands.": {
"message": "Commencer avec OpenHands"
},
"Most Popular Links": {
"message": "Liens Populaires"
},
"Customizing OpenHands to a repository": {
"message": "Personnaliser OpenHands pour un dépôt"
},
"Integrating OpenHands with Github": {
"message": "Intégrer OpenHands avec Github"
},
"Recommended models to use": {
"message": "Modèles recommandés"
},
"Connecting OpenHands to your filesystem": {
"message": "Connecter OpenHands à votre système de fichiers"
}
}

View File

@@ -0,0 +1,14 @@
{
"title": {
"message": "Blog",
"description": "The title for the blog used in SEO"
},
"description": {
"message": "Blog",
"description": "The description for the blog used in SEO"
},
"sidebar.title": {
"message": "Articles récents",
"description": "The label for the left sidebar"
}
}

View File

@@ -0,0 +1,210 @@
{
"version.label": {
"message": "Next",
"description": "The label for version current"
},
"sidebar.docsSidebar.category.🤖 Backends LLM": {
"message": "🤖 Backends LLM",
"description": "The label for category 🤖 Backends LLM in sidebar docsSidebar"
},
"sidebar.docsSidebar.category.🚧 Dépannage": {
"message": "🚧 Dépannage",
"description": "The label for category 🚧 Dépannage in sidebar docsSidebar"
},
"sidebar.apiSidebar.category.Backend": {
"message": "Backend",
"description": "The label for category Backend in sidebar apiSidebar"
},
"sidebar.docsSidebar.category.User Guides": {
"message": "Guides d'Utilisateur",
"description": "The label for category User Guides in sidebar docsSidebar"
},
"sidebar.docsSidebar.category.Running OpenHands": {
"message": "Exécution d'OpenHands",
"description": "The label for category Running OpenHands in sidebar docsSidebar"
},
"sidebar.docsSidebar.category.Prompting": {
"message": "Prompting",
"description": "The label for category Prompting in sidebar docsSidebar"
},
"sidebar.docsSidebar.category.Architecture": {
"message": "Architecture",
"description": "The label for category Architecture in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Running OpenHands": {
"message": "Exécution d'OpenHands",
"description": "The label for document Running OpenHands in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Getting Started": {
"message": "Commencer",
"description": "The label for document Getting Started in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Key Features": {
"message": "Fonctionnalités Clés",
"description": "The label for document Key Features in sidebar docsSidebar"
},
"sidebar.docsSidebar.category.Customization": {
"message": "Personnalisation",
"description": "The label for category Customization in sidebar docsSidebar"
},
"sidebar.docsSidebar.category.Usage Methods": {
"message": "Méthodes d'Utilisation",
"description": "The label for category Usage Methods in sidebar docsSidebar"
},
"sidebar.docsSidebar.category.Advanced Configuration": {
"message": "Configuration Avancée",
"description": "The label for category Advanced Configuration in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Troubleshooting": {
"message": "Dépannage",
"description": "The label for document Troubleshooting in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Feedback": {
"message": "Retour d'Information",
"description": "The label for document Feedback in sidebar docsSidebar"
},
"sidebar.docsSidebar.category.For OpenHands Developers": {
"message": "Pour les Développeurs OpenHands",
"description": "The label for category For OpenHands Developers in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.About": {
"message": "À Propos",
"description": "The label for document About in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Best Practices": {
"message": "Meilleures Pratiques",
"description": "The label for document Best Practices in sidebar docsSidebar"
},
"sidebar.docsSidebar.category.Microagents": {
"message": "Micro-agents",
"description": "The label for category Microagents in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Overview": {
"message": "Aperçu",
"description": "The label for document Overview in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Repository": {
"message": "Dépôt",
"description": "The label for document Repository in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Public": {
"message": "Public",
"description": "The label for document Public in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Repository Customization": {
"message": "Personnalisation du Dépôt",
"description": "The label for document Repository Customization in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.GUI Mode": {
"message": "Mode GUI",
"description": "The label for document GUI Mode in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.CLI Mode": {
"message": "Mode CLI",
"description": "The label for document CLI Mode in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Headless Mode": {
"message": "Mode Sans Interface",
"description": "The label for document Headless Mode in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Github Action": {
"message": "Action GitHub",
"description": "The label for document Github Action in sidebar docsSidebar"
},
"sidebar.docsSidebar.category.Cloud": {
"message": "Cloud",
"description": "The label for category Cloud in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Openhands Cloud": {
"message": "OpenHands Cloud",
"description": "The label for document Openhands Cloud in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Cloud GitHub Resolver": {
"message": "Résolveur GitHub Cloud",
"description": "The label for document Cloud GitHub Resolver in sidebar docsSidebar"
},
"sidebar.docsSidebar.category.LLM Configuration": {
"message": "Configuration LLM",
"description": "The label for category LLM Configuration in sidebar docsSidebar"
},
"sidebar.docsSidebar.category.Providers": {
"message": "Fournisseurs",
"description": "The label for category Providers in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Azure": {
"message": "Azure",
"description": "The label for document Azure in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Google": {
"message": "Google",
"description": "The label for document Google in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Groq": {
"message": "Groq",
"description": "The label for document Groq in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.LiteLLM Proxy": {
"message": "Proxy LiteLLM",
"description": "The label for document LiteLLM Proxy in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.OpenAI": {
"message": "OpenAI",
"description": "The label for document OpenAI in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.OpenRouter": {
"message": "OpenRouter",
"description": "The label for document OpenRouter in sidebar docsSidebar"
},
"sidebar.docsSidebar.category.Runtime Configuration": {
"message": "Configuration d'Exécution",
"description": "The label for category Runtime Configuration in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Docker Runtime": {
"message": "Environnement Docker",
"description": "The label for document Docker Runtime in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Remote Runtime": {
"message": "Environnement Distant",
"description": "The label for document Remote Runtime in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Modal Runtime": {
"message": "Environnement Modal",
"description": "The label for document Modal Runtime in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Daytona Runtime": {
"message": "Environnement Daytona",
"description": "The label for document Daytona Runtime in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Local Runtime": {
"message": "Environnement Local",
"description": "The label for document Local Runtime in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Configuration Options": {
"message": "Options de Configuration",
"description": "The label for document Configuration Options in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Custom Sandbox": {
"message": "Bac à Sable Personnalisé",
"description": "The label for document Custom Sandbox in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Development Overview": {
"message": "Aperçu du Développement",
"description": "The label for document Development Overview in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Backend": {
"message": "Backend",
"description": "The label for document Backend in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Runtime": {
"message": "Environnement d'Exécution",
"description": "The label for document Runtime in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Debugging": {
"message": "Débogage",
"description": "The label for document Debugging in sidebar docsSidebar"
},
"sidebar.docsSidebar.doc.Evaluation": {
"message": "Évaluation",
"description": "The label for document Evaluation in sidebar docsSidebar"
}
}

View File

@@ -0,0 +1,5 @@
# Documentation Python
La documentation apparaîtra ici après le déploiement.

View File

@@ -0,0 +1,5 @@
{
"items": ["python/python"],
"label": "Backend",
"type": "categorie"
}

View File

@@ -0,0 +1,28 @@
# À propos d'OpenHands
## Stratégie de recherche
La réplication complète d'applications de niveau production avec des LLM est une entreprise complexe. Notre stratégie implique :
1. **Recherche technique fondamentale :** Se concentrer sur la recherche fondamentale pour comprendre et améliorer les aspects techniques de la génération et de la gestion du code
2. **Capacités spécialisées :** Améliorer l'efficacité des composants de base grâce à la curation des données, aux méthodes d'entraînement, et plus encore
3. **Planification des tâches :** Développer des capacités pour la détection des bugs, la gestion des bases de code et l'optimisation
4. **Évaluation :** Établir des métriques d'évaluation complètes pour mieux comprendre et améliorer nos modèles
## Agent par défaut
Notre Agent par défaut est actuellement le [CodeActAgent](agents), qui est capable de générer du code et de gérer des fichiers.
## Construit avec
OpenHands est construit en utilisant une combinaison de frameworks et de bibliothèques puissants, fournissant une base solide pour son développement. Voici les principales technologies utilisées dans le projet :
![FastAPI](https://img.shields.io/badge/FastAPI-black?style=for-the-badge) ![uvicorn](https://img.shields.io/badge/uvicorn-black?style=for-the-badge) ![LiteLLM](https://img.shields.io/badge/LiteLLM-black?style=for-the-badge) ![Docker](https://img.shields.io/badge/Docker-black?style=for-the-badge) ![Ruff](https://img.shields.io/badge/Ruff-black?style=for-the-badge) ![MyPy](https://img.shields.io/badge/MyPy-black?style=for-the-badge) ![LlamaIndex](https://img.shields.io/badge/LlamaIndex-black?style=for-the-badge) ![React](https://img.shields.io/badge/React-black?style=for-the-badge)
Veuillez noter que la sélection de ces technologies est en cours et que des technologies supplémentaires peuvent être ajoutées ou des technologies existantes peuvent être supprimées à mesure que le projet évolue. Nous nous efforçons d'adopter les outils les plus appropriés et les plus efficaces pour améliorer les capacités d'OpenHands.
## Licence
Distribué sous la [Licence](https://github.com/All-Hands-AI/OpenHands/blob/main/LICENSE) MIT.

View File

@@ -0,0 +1,25 @@
# 🧠 Agent Principal et Capacités
## CodeActAgent
### Description
Cet agent implémente l'idée de CodeAct ([article](https://arxiv.org/abs/2402.01030), [tweet](https://twitter.com/xingyaow_/status/1754556835703751087)) qui consolide les **act**ions des agents LLM dans un espace d'action de **code** unifié à la fois pour la _simplicité_ et la _performance_.
L'idée conceptuelle est illustrée ci-dessous. À chaque tour, l'agent peut :
1. **Converser** : Communiquer avec les humains en langage naturel pour demander des clarifications, des confirmations, etc.
2. **CodeAct** : Choisir d'effectuer la tâche en exécutant du code
- Exécuter n'importe quelle commande Linux `bash` valide
- Exécuter n'importe quel code `Python` valide avec [un interpréteur Python interactif](https://ipython.org/). Ceci est simulé via une commande `bash`, voir le système de plugin ci-dessous pour plus de détails.
![image](https://github.com/All-Hands-AI/OpenHands/assets/38853559/92b622e3-72ad-4a61-8f41-8c040b6d5fb3)
### Démo
https://github.com/All-Hands-AI/OpenHands/assets/38853559/f592a192-e86c-4f48-ad31-d69282d5f6ac
_Exemple de CodeActAgent avec `gpt-4-turbo-2024-04-09` effectuant une tâche de science des données (régression linéaire)_.

View File

@@ -0,0 +1,50 @@
---
sidebar_position: 4
---
# 🏛️ Aperçu de l'Architecture Système
Voici un aperçu de haut niveau de l'architecture du système. Le système est divisé en deux composants principaux : le frontend et le backend. Le frontend est responsable de la gestion des interactions avec l'utilisateur et de l'affichage des résultats. Le backend est responsable de la gestion de la logique métier et de l'exécution des agents.
![system_architecture.svg](/img/system_architecture.svg)
Cet aperçu est simplifié pour montrer les principaux composants et leurs interactions. Pour une vue plus détaillée de l'architecture du backend, consultez la section [Architecture du Backend](#backend-architecture-fr).
# Architecture du Backend {#backend-architecture-fr}
_**Avertissement**: L'architecture du backend est en cours de développement et est sujette à modifications. Le schéma suivant montre l'architecture actuelle du backend basée sur le commit indiqué dans le pied de page du schéma._
![backend_architecture.svg](/img/backend_architecture.svg)
<details>
<summary>Mise à jour de ce Schéma</summary>
<div>
La génération du schéma d'architecture du backend est partiellement automatisée.
Le schéma est généré à partir des annotations de type dans le code en utilisant l'outil py2puml.
Le schéma est ensuite revu manuellement, ajusté et exporté en PNG et SVG.
## Prérequis
- Un environnement Python dans lequel openhands est exécutable
(selon les instructions du fichier README.md à la racine du dépôt)
- [py2puml](https://github.com/lucsorel/py2puml) installé
## Étapes
1. Générez automatiquement le schéma en exécutant la commande suivante depuis la racine du dépôt :
`py2puml openhands openhands > docs/architecture/backend_architecture.puml`
2. Ouvrez le fichier généré dans un éditeur PlantUML, par exemple Visual Studio Code avec l'extension PlantUML ou [PlantText](https://www.planttext.com/)
3. Révisez le PUML généré et apportez toutes les modifications nécessaires au schéma (ajoutez les parties manquantes, corrigez les erreurs, améliorez l'agencement).
_py2puml crée le schéma à partir des annotations de type dans le code, donc les annotations de type manquantes ou incorrectes peuvent entraîner un schéma incomplet ou incorrect._
4. Examinez la différence entre le nouveau schéma et le précédent et vérifiez manuellement si les modifications sont correctes.
_Assurez-vous de ne pas supprimer les parties ajoutées manuellement au schéma par le passé et qui sont toujours pertinentes._
5. Ajoutez le hash du commit qui a été utilisé pour générer le schéma dans le pied de page du schéma.
6. Exporte le schéma sous forme de fichiers PNG et SVG et remplacez les schémas existants dans le répertoire `docs/architecture`. Cela peut être fait avec (par exemple [PlantText](https://www.planttext.com/))
</div>
</details>

View File

@@ -0,0 +1,54 @@
# 🏛️ Architecture du Système
<div style={{ textAlign: 'center' }}>
<img src="https://github.com/All-Hands-AI/OpenHands/assets/16201837/97d747e3-29d8-4ccb-8d34-6ad1adb17f38" alt="OpenHands System Architecture Diagram Jul 4 2024" />
<p><em>Diagramme de l'Architecture du Système OpenHands (4 juillet 2024)</em></p>
</div>
Ceci est une vue d'ensemble de haut niveau de l'architecture du système. Le système est divisé en deux composants principaux : le frontend et le backend. Le frontend est responsable de la gestion des interactions utilisateur et de l'affichage des résultats. Le backend est responsable de la gestion de la logique métier et de l'exécution des agents.
# Architecture du Frontend {#frontend-architecture-fr}
![system_architecture.svg](/img/system_architecture.svg)
Cette vue d'ensemble est simplifiée pour montrer les principaux composants et leurs interactions. Pour une vue plus détaillée de l'architecture du backend, voir la section Architecture du Backend ci-dessous.
# Architecture du Backend {#backend-architecture-fr}
_**Avertissement** : L'architecture du backend est en cours de développement et est sujette à changement. Le diagramme suivant montre l'architecture actuelle du backend basée sur le commit indiqué dans le pied de page du diagramme._
![backend_architecture.svg](/img/backend_architecture.svg)
<details>
<summary>Mise à jour de ce Diagramme</summary>
<div>
La génération du diagramme d'architecture du backend est partiellement automatisée.
Le diagramme est généré à partir des indications de type dans le code en utilisant l'outil py2puml. Le diagramme est ensuite manuellement revu, ajusté et exporté en PNG et SVG.
## Prérequis
- Environnement python fonctionnel dans lequel openhands est exécutable
(selon les instructions du fichier README.md à la racine du dépôt)
- [py2puml](https://github.com/lucsorel/py2puml) installé
## Étapes
1. Générer automatiquement le diagramme en exécutant la commande suivante depuis la racine du dépôt :
`py2puml openhands openhands > docs/architecture/backend_architecture.puml`
2. Ouvrir le fichier généré dans un éditeur PlantUML, par ex. Visual Studio Code avec l'extension PlantUML ou [PlantText](https://www.planttext.com/)
3. Revoir le PUML généré et effectuer tous les ajustements nécessaires au diagramme (ajouter les parties manquantes, corriger les erreurs, améliorer le positionnement).
_py2puml crée le diagramme en se basant sur les indications de type dans le code, donc des indications manquantes ou incorrectes peuvent entraîner un diagramme incomplet ou incorrect._
4. Revoir la différence entre le nouveau diagramme et le précédent et vérifier manuellement si les changements sont corrects.
_S'assurer de ne pas supprimer des parties qui ont été ajoutées manuellement au diagramme par le passé et qui sont toujours pertinentes._
5. Ajouter le hash du commit qui a été utilisé pour générer le diagramme dans le pied de page du diagramme.
6. Exporter le diagramme sous forme de fichiers PNG et SVG et remplacer les diagrammes existants dans le répertoire `docs/architecture`. Cela peut être fait avec (par ex. [PlantText](https://www.planttext.com/))
</div>
</details>

View File

@@ -0,0 +1,138 @@
# 📦 Runtime Docker
Le Runtime Docker d'OpenHands est le composant principal qui permet l'exécution sécurisée et flexible des actions des agents d'IA.
Il crée un environnement en bac à sable (sandbox) en utilisant Docker, où du code arbitraire peut être exécuté en toute sécurité sans risquer le système hôte.
## Pourquoi avons-nous besoin d'un runtime en bac à sable ?
OpenHands doit exécuter du code arbitraire dans un environnement sécurisé et isolé pour plusieurs raisons :
1. Sécurité : L'exécution de code non fiable peut poser des risques importants pour le système hôte. Un environnement en bac à sable empêche le code malveillant d'accéder ou de modifier les ressources du système hôte
2. Cohérence : Un environnement en bac à sable garantit que l'exécution du code est cohérente sur différentes machines et configurations, éliminant les problèmes du type "ça fonctionne sur ma machine"
3. Contrôle des ressources : Le bac à sable permet un meilleur contrôle de l'allocation et de l'utilisation des ressources, empêchant les processus incontrôlés d'affecter le système hôte
4. Isolation : Différents projets ou utilisateurs peuvent travailler dans des environnements isolés sans interférer les uns avec les autres ou avec le système hôte
5. Reproductibilité : Les environnements en bac à sable facilitent la reproduction des bugs et des problèmes, car l'environnement d'exécution est cohérent et contrôlable
## Comment fonctionne le Runtime ?
Le système Runtime d'OpenHands utilise une architecture client-serveur implémentée avec des conteneurs Docker. Voici un aperçu de son fonctionnement :
```mermaid
graph TD
A[Image Docker personnalisée fournie par l'utilisateur] --> B[Backend OpenHands]
B -->|Construit| C[Image OH Runtime]
C -->|Lance| D[Exécuteur d'actions]
D -->|Initialise| E[Navigateur]
D -->|Initialise| F[Shell Bash]
D -->|Initialise| G[Plugins]
G -->|Initialise| L[Serveur Jupyter]
B -->|Génère| H[Agent]
B -->|Génère| I[EventStream]
I <--->|Exécute l'action pour
obtenir l'observation
via l'API REST
| D
H -->|Génère l'action| I
I -->|Obtient l'observation| H
subgraph "Conteneur Docker"
D
E
F
G
L
end
```
1. Entrée utilisateur : L'utilisateur fournit une image Docker de base personnalisée
2. Construction de l'image : OpenHands construit une nouvelle image Docker (l'"image OH runtime") basée sur l'image fournie par l'utilisateur. Cette nouvelle image inclut le code spécifique à OpenHands, principalement le "client runtime"
3. Lancement du conteneur : Lorsqu'OpenHands démarre, il lance un conteneur Docker en utilisant l'image OH runtime
4. Initialisation du serveur d'exécution des actions : Le serveur d'exécution des actions initialise un `ActionExecutor` à l'intérieur du conteneur, mettant en place les composants nécessaires comme un shell bash et chargeant les plugins spécifiés
5. Communication : Le backend OpenHands (`openhands/runtime/impl/eventstream/eventstream_runtime.py`) communique avec le serveur d'exécution des actions via une API RESTful, envoyant des actions et recevant des observations
6. Exécution des actions : Le client runtime reçoit les actions du backend, les exécute dans l'environnement en bac à sable et renvoie les observations
7. Retour des observations : Le serveur d'exécution des actions renvoie les résultats d'exécution au backend OpenHands sous forme d'observations
Le rôle du client :
- Il agit comme un intermédiaire entre le backend OpenHands et l'environnement en bac à sable
- Il exécute différents types d'actions (commandes shell, opérations sur les fichiers, code Python, etc.) en toute sécurité dans le conteneur
- Il gère l'état de l'environnement en bac à sable, y compris le répertoire de travail courant et les plugins chargés
- Il formate et renvoie les observations au backend, assurant une interface cohérente pour le traitement des résultats
## Comment OpenHands construit et maintient les images OH Runtime
L'approche d'OpenHands pour la construction et la gestion des images runtime assure l'efficacité, la cohérence et la flexibilité dans la création et la maintenance des images Docker pour les environnements de production et de développement.
Consultez le [code pertinent](https://github.com/All-Hands-AI/OpenHands/blob/main/openhands/runtime/utils/runtime_build.py) si vous souhaitez plus de détails.
### Système de balises d'images
OpenHands utilise un système à trois balises pour ses images runtime afin d'équilibrer la reproductibilité et la flexibilité.
Les balises peuvent être dans l'un des 2 formats suivants :
- **Balise versionnée** : `oh_v{openhands_version}_{base_image}` (ex : `oh_v0.9.9_nikolaik_s_python-nodejs_t_python3.12-nodejs22`)
- **Balise de verrouillage** : `oh_v{openhands_version}_{16_digit_lock_hash}` (ex : `oh_v0.9.9_1234567890abcdef`)
- **Balise source** : `oh_v{openhands_version}_{16_digit_lock_hash}_{16_digit_source_hash}`
(ex : `oh_v0.9.9_1234567890abcdef_1234567890abcdef`)
#### Balise source - La plus spécifique
Il s'agit des 16 premiers chiffres du MD5 du hash du répertoire pour le répertoire source. Cela donne un hash
uniquement pour la source d'openhands
#### Balise de verrouillage
Ce hash est construit à partir des 16 premiers chiffres du MD5 de :
- Le nom de l'image de base sur laquelle l'image a été construite (ex : `nikolaik/python-nodejs:python3.12-nodejs22`)
- Le contenu du `pyproject.toml` inclus dans l'image.
- Le contenu du `poetry.lock` inclus dans l'image.
Cela donne effectivement un hash pour les dépendances d'Openhands indépendamment du code source.
#### Balise versionnée - La plus générique
Cette balise est une concaténation de la version d'openhands et du nom de l'image de base (transformé pour s'adapter au standard des balises).
#### Processus de construction
Lors de la génération d'une image...
- **Pas de reconstruction** : OpenHands vérifie d'abord si une image avec la même **balise source la plus spécifique** existe. S'il existe une telle image,
aucune construction n'est effectuée - l'image existante est utilisée.
- **Reconstruction la plus rapide** : OpenHands vérifie ensuite si une image avec la **balise de verrouillage générique** existe. S'il existe une telle image,
OpenHands construit une nouvelle image basée sur celle-ci, en contournant toutes les étapes d'installation (comme `poetry install` et
`apt-get`) sauf une opération finale pour copier le code source actuel. La nouvelle image est balisée avec une
balise **source** uniquement.
- **Reconstruction correcte** : Si ni une balise **source** ni une balise **de verrouillage** n'existe, une image sera construite sur la base de l'image avec la balise **versionnée**.
Dans l'image avec la balise versionnée, la plupart des dépendances devraient déjà être installées, ce qui permet de gagner du temps.
- **Reconstruction la plus lente** : Si les trois balises n'existent pas, une toute nouvelle image est construite à partir de
l'image de base (ce qui est une opération plus lente). Cette nouvelle image est balisée avec toutes les balises **source**, **de verrouillage** et **versionnée**.
Cette approche de balisage permet à OpenHands de gérer efficacement les environnements de développement et de production.
1. Un code source et un Dockerfile identiques produisent toujours la même image (via des balises basées sur des hashs)
2. Le système peut reconstruire rapidement les images lorsque des changements mineurs se produisent (en s'appuyant sur des images compatibles récentes)
3. La balise **de verrouillage** (ex : `runtime:oh_v0.9.3_1234567890abcdef`) pointe toujours vers la dernière version pour une combinaison particulière d'image de base, de dépendances et de version d'OpenHands
## Système de plugins du Runtime
Le Runtime d'OpenHands prend en charge un système de plugins qui permet d'étendre les fonctionnalités et de personnaliser l'environnement d'exécution. Les plugins sont initialisés lorsque le client runtime démarre.
Consultez [un exemple de plugin Jupyter ici](https://github.com/All-Hands-AI/OpenHands/blob/ecf4aed28b0cf7c18d4d8ff554883ba182fc6bdd/openhands/runtime/plugins/jupyter/__init__.py#L21-L55) si vous souhaitez implémenter votre propre plugin.
*Plus de détails sur le système de plugins sont encore en construction - les contributions sont les bienvenues !*
Aspects clés du système de plugins :
1. Définition des plugins : Les plugins sont définis comme des classes Python qui héritent d'une classe de base `Plugin`
2. Enregistrement des plugins : Les plugins disponibles sont enregistrés dans un dictionnaire `ALL_PLUGINS`
3. Spécification des plugins : Les plugins sont associés à `Agent.sandbox_plugins: list[PluginRequirement]`. Les utilisateurs peuvent spécifier quels plugins charger lors de l'initialisation du runtime
4. Initialisation : Les plugins sont initialisés de manière asynchrone lorsque le client runtime démarre
5. Utilisation : Le client runtime peut utiliser les plugins initialisés pour étendre ses capacités (par exemple, le JupyterPlugin pour exécuter des cellules IPython)

View File

@@ -0,0 +1,387 @@
# Options de configuration
Ce guide détaille toutes les options de configuration disponibles pour OpenHands, vous aidant à personnaliser son comportement et à l'intégrer avec d'autres services.
:::note
Si vous exécutez en [Mode GUI](https://docs.all-hands.dev/modules/usage/how-to/gui-mode), les paramètres disponibles dans l'interface utilisateur des paramètres auront toujours
la priorité.
:::
---
# Table des matières
1. [Configuration de base](#core-configuration)
- [Clés API](#api-keys)
- [Espace de travail](#workspace)
- [Débogage et journalisation](#debugging-and-logging)
- [Trajectoires](#trajectories)
- [Stockage de fichiers](#file-store)
- [Gestion des tâches](#task-management)
- [Configuration du bac à sable](#sandbox-configuration)
- [Divers](#miscellaneous)
2. [Configuration LLM](#llm-configuration)
- [Informations d'identification AWS](#aws-credentials)
- [Configuration de l'API](#api-configuration)
- [Fournisseur LLM personnalisé](#custom-llm-provider)
- [Embeddings](#embeddings)
- [Gestion des messages](#message-handling)
- [Sélection du modèle](#model-selection)
- [Nouvelles tentatives](#retrying)
- [Options avancées](#advanced-options)
3. [Configuration de l'agent](#agent-configuration)
- [Configuration de la mémoire](#memory-configuration)
- [Configuration LLM](#llm-configuration-1)
- [Configuration de l'espace d'action](#actionspace-configuration)
- [Utilisation du micro-agent](#microagent-usage)
4. [Configuration du bac à sable](#sandbox-configuration-1)
- [Exécution](#execution)
- [Image de conteneur](#container-image)
- [Mise en réseau](#networking)
- [Linting et plugins](#linting-and-plugins)
- [Dépendances et environnement](#dependencies-and-environment)
- [Évaluation](#evaluation)
5. [Configuration de sécurité](#security-configuration)
- [Mode de confirmation](#confirmation-mode)
- [Analyseur de sécurité](#security-analyzer)
---
## Configuration de base
Les options de configuration de base sont définies dans la section `[core]` du fichier `config.toml`.
**Clés API**
- `e2b_api_key`
- Type : `str`
- Valeur par défaut : `""`
- Description : Clé API pour E2B
- `modal_api_token_id`
- Type : `str`
- Valeur par défaut : `""`
- Description : ID du jeton API pour Modal
- `modal_api_token_secret`
- Type : `str`
- Valeur par défaut : `""`
- Description : Secret du jeton API pour Modal
**Espace de travail**
- `workspace_base`
- Type : `str`
- Valeur par défaut : `"./workspace"`
- Description : Chemin de base pour l'espace de travail
- `cache_dir`
- Type : `str`
- Valeur par défaut : `"/tmp/cache"`
- Description : Chemin du répertoire de cache
**Débogage et journalisation**
- `debug`
- Type : `bool`
- Valeur par défaut : `false`
- Description : Activer le débogage
- `disable_color`
- Type : `bool`
- Valeur par défaut : `false`
- Description : Désactiver la couleur dans la sortie du terminal
**Trajectoires**
- `save_trajectory_path`
- Type : `str`
- Valeur par défaut : `"./trajectories"`
- Description : Chemin pour stocker les trajectoires (peut être un dossier ou un fichier). Si c'est un dossier, les trajectoires seront enregistrées dans un fichier nommé avec l'ID de session et l'extension .json, dans ce dossier.
**Stockage de fichiers**
- `file_store_path`
- Type : `str`
- Valeur par défaut : `"/tmp/file_store"`
- Description : Chemin de stockage des fichiers
- `file_store`
- Type : `str`
- Valeur par défaut : `"memory"`
- Description : Type de stockage de fichiers
- `file_uploads_allowed_extensions`
- Type : `list of str`
- Valeur par défaut : `[".*"]`
- Description : Liste des extensions de fichiers autorisées pour les téléchargements
- `file_uploads_max_file_size_mb`
- Type : `int`
- Valeur par défaut : `0`
- Description : Taille maximale des fichiers pour les téléchargements, en mégaoctets
- `file_uploads_restrict_file_types`
- Type : `bool`
- Valeur par défaut : `false`
- Description : Restreindre les types de fichiers pour les téléchargements de fichiers
- `file_uploads_allowed_extensions`
- Type : `list of str`
- Valeur par défaut : `[".*"]`
- Description : Liste des extensions de fichiers autorisées pour les téléchargements
**Gestion des tâches**
- `max_budget_per_task`
- Type : `float`
- Valeur par défaut : `0.0`
- Description : Budget maximal par tâche (0.0 signifie aucune limite)
- `max_iterations`
- Type : `int`
- Valeur par défaut : `100`
- Description : Nombre maximal d'itérations
**Configuration du bac à sable**
- `workspace_mount_path_in_sandbox`
- Type : `str`
- Valeur par défaut : `"/workspace"`
- Description : Chemin de montage de l'espace de travail dans le bac à sable
- `workspace_mount_path`
- Type : `str`
- Valeur par défaut : `""`
- Description : Chemin de montage de l'espace de travail
- `workspace_mount_rewrite`
- Type : `str`
- Valeur par défaut : `""`
- Description : Chemin pour réécrire le chemin de montage de l'espace de travail. Vous pouvez généralement ignorer cela, cela fait référence à des cas spéciaux d'exécution à l'intérieur d'un autre conteneur.
**Divers**
- `run_as_openhands`
- Type : `bool`
- Valeur par défaut : `true`
- Description : Exécuter en tant qu'OpenHands
- `runtime`
- Type : `str`
- Valeur par défaut : `"docker"`
- Description : Environnement d'exécution
- `default_agent`
- Type : `str`
- Valeur par défaut : `"CodeActAgent"`
- Description : Nom de l'agent par défaut
- `jwt_secret`
- Type : `str`
- Valeur par défaut : `uuid.uuid4().hex`
- Description : Secret JWT pour l'authentification. Veuillez le définir sur votre propre valeur.
## Configuration LLM
Les options de configuration LLM (Large Language Model) sont définies dans la section `[llm]` du fichier `config.toml`.
Pour les utiliser avec la commande docker, passez `-e LLM_<option>`. Exemple : `-e LLM_NUM_RETRIES`.
:::note
Pour les configurations de développement, vous pouvez également définir des configurations LLM personnalisées. Voir [Configurations LLM personnalisées](./llms/custom-llm-configs) pour plus de détails.
:::
**Informations d'identification AWS**
- `aws_access_key_id`
- Type : `str`
- Valeur par défaut : `""`
- Description : ID de clé d'accès AWS
- `aws_region_name`
- Type : `str`
- Valeur par défaut : `""`
- Description : Nom de la région AWS
- `aws_secret_access_key`
- Type : `str`
- Valeur par défaut : `""`
- Description : Clé d'accès secrète AWS
**Configuration de l'API**
- `api_key`
- Type : `str`
- Valeur par défaut : `None`
- Description : Clé API à utiliser
- `base_url`
- Type : `str`
- Valeur par défaut : `""`
- Description : URL de base de l'API
- `api_version`
- Type : `str`
- Valeur par défaut : `""`
- Description : Version de l'API
- `input_cost_per_token`
- Type : `float`
- Valeur par défaut : `0.0`
- Description : Coût par jeton d'entrée
- `output_cost_per_token`
- Type : `float`
- Valeur par défaut : `0.0`
- Description : Coût par jeton de sortie
**Fournisseur LLM personnalisé**
- `custom_llm_provider`
- Type : `str`
- Valeur par défaut : `""`
- Description : Fournisseur LLM personnalisé
**Embeddings**
- `embedding_base_url`
- Type : `str`
- Valeur par défaut : `""`
- Description : URL de base de l'API d'embedding
- `embedding_deployment_name`
- Type : `str`
- Valeur par défaut : `""`
- Description : Nom du déploiement d'embedding
- `embedding_model`
- Type : `str`
- Valeur par défaut : `"local"`
- Description : Modèle d'embedding à utiliser
**Gestion des messages**
- `max_message_chars`
- Type : `int`
- Valeur par défaut : `30000`
- Description : Le nombre maximum approximatif de caractères dans le contenu d'un événement inclus dans l'invite au LLM. Les observations plus grandes sont tronquées.
- `max_input_tokens`
- Type : `int`
- Valeur par défaut : `0`
- Description : Nombre maximal de jetons d'entrée
- `max_output_tokens`
- Type : `int`
- Valeur par défaut : `0`
- Description : Nombre maximal de jetons de sortie
**Sélection du modèle**
- `model`
- Type : `str`
- Valeur par défaut : `"claude-3-5-sonnet-20241022"`
- Description : Modèle à utiliser
**Nouvelles tentatives**
- `num_retries`
- Type : `int`
- Valeur par défaut : `8`
- Description : Nombre de nouvelles tentatives à effectuer
- `retry_max_wait`
- Type : `int`
- Valeur par défaut : `120`
- Description : Temps d'attente maximal (en secondes) entre les tentatives de nouvelle tentative
- `retry_min_wait`
- Type : `int`
- Valeur par défaut : `15`
- Description : Temps d'attente minimal (en secondes) entre les tentatives de nouvelle tentative
- `retry_multiplier`
- Type : `float`
- Valeur par défaut : `2.0`
- Description : Multiplicateur pour le calcul du backoff exponentiel
**Options avancées**
- `drop_params`
- Type : `bool`
- Valeur par défaut : `false`
- Description : Supprimer tous les paramètres non mappés (non pris en charge) sans provoquer d'exception
- `caching_prompt`
- Type : `bool`
- Valeur par défaut : `true`
- Description : Utiliser la fonctionnalité de mise en cache des invites si elle est fournie par le LLM et prise en charge
- `ollama_base_url`
- Type : `str`
- Valeur par défaut : `""`
- Description : URL de base pour l'API OLLAMA
- `temperature`
- Type : `float`
- Valeur par défaut : `0.0`
- Description : Température pour l'API
- `timeout`
- Type : `int`
- Valeur par défaut : `0`
- Description : Délai d'expiration pour l'API
- `top_p`
- Type : `float`
- Valeur par défaut : `1.0`
- Description : Top p pour l'API
- `disable_vision`
- Type : `bool`
- Valeur par défaut : `None`
- Description : Si le modèle est capable de vision, cette option permet de désactiver le traitement des images (utile pour réduire les coûts)
## Configuration de l'agent
Les options de configuration de l'agent sont définies dans les sections `[agent]` et `[agent.<agent_name>]` du fichier `config.toml`.
**Configuration de la mémoire**
- `memory_enabled`
- Type : `bool`
- Valeur par défaut : `false`
- Description : Si la mémoire à long terme (embeddings) est activée
- `memory_max_threads`
- Type : `int`
- Valeur par défaut : `3`
- Description : Le nombre maximum de threads indexant en même temps pour les embeddings
**Configuration LLM**
- `llm_config`
- Type : `str`
- Valeur par défaut : `'your-llm-config-group'`
- Description : Le nom de la configuration LLM à utiliser
**Configuration de l'espace d'action**
- `function_calling`
- Type : `bool`
- Valeur par défaut : `true`
- Description : Si l'appel de fonction est activé
- `enable_browsing`
- Type : `bool`
- Valeur par défaut : `false`
- Description : Si le délégué de navigation est activé dans l'espace d'action (fonctionne uniquement avec l'appel de fonction)
- `enable_llm_editor`
- Type : `bool`
- Valeur par défaut : `false`
- Description : Si l'éditeur LLM est activé dans l'espace d'action (fonctionne uniquement avec l'appel de fonction)
**Utilisation du micro-agent**
- `enable_prompt_extensions`
- Type : `bool`
- Valeur par défaut : `true`
- Description : Indique si l'utilisation des micro-agents est activée ou non
- `disabled_microagents`
- Type : `list of str`
- Valeur par défaut : `None`
- Description : Liste des micro-agents à désactiver
### Exécution
- `timeout`
- Type : `int`
- Valeur par défaut : `120`
- Description : Délai d'expiration du bac à sable, en secondes
- `user_id`
- Type : `int`
- Valeur par défaut : `1000`
- Description : ID de l'utilisateur du bac à sable

View File

@@ -0,0 +1,81 @@
# 💿 Comment Créer un Soutien Docker sur Mesure
Le sandbox par défaut OpenHands est équipé d'une configuration ubuntu minimaliste. Votre cas d'utilisation pourrait nécessiter des logiciels installés par défaut. Cet article vous enseignera comment réaliser cela en utilisant une image docker personnalisée.
## Configuration
Assurez-vous de pouvoir utiliser OpenHands en suivant la documentation [Development.md](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md).
## Créer Votre Image Docker
Ensuite, vous devez créer votre image docker personnalisée qui doit être basée sur debian/ubuntu. Par exemple, si nous souhaitons que OpenHands ait accès au "node" binaire, nous utiliserions ce Dockerfile:
```bash
# Commencez avec l'image ubuntu la plus récente
FROM ubuntu:latest
# Effectuez les mises à jour nécessaires
RUN apt-get update && apt-get install
# Installez nodejs
RUN apt-get install -y nodejs
```
Ensuite, construisez votre image docker avec le nom de votre choix. Par exemple "image_personnalisée". Pour cela, créez un répertoire et placez le fichier à l'intérieur avec le nom "Dockerfile", puis dans le répertoire exécutez cette commande:
```bash
docker build -t image_personnalisée .
```
Cela produira une nouvelle image appelée ```image_personnalisée``` qui sera disponible dans Docker Engine.
> Remarque: Dans la configuration décrite ici, OpenHands va fonctionner en tant que utilisateur "openhands" à l'intérieur du sandbox et donc tous les packages installés via le Dockerfile seront disponibles pour tous les utilisateurs sur le système, pas seulement root.
>
> L'installation avec apt-get ci-dessus installe nodejs pour tous les utilisateurs.
## Spécifiez votre image personnalisée dans le fichier config.toml
La configuration OpenHands se fait via le fichier de niveau supérieur ```config.toml``` .
Créez un fichier ```config.toml``` dans le répertoire OpenHands et entrez ces contenus:
```toml
[core]
workspace_base="./workspace"
run_as_openhands=true
[sandbox]
base_container_image="image_personnalisée"
```
> Assurez-vous que ```base_container_image``` est défini sur le nom de votre image personnalisée précédente.
## Exécution
Exécutez OpenHands en exécutant ```make run``` dans le répertoire racine.
Naviguez vers ```localhost:3001``` et vérifiez si vos dépendances souhaitées sont disponibles.
Dans le cas de l'exemple ci-dessus, la commande ```node -v``` dans la console produit ```v18.19.1```
Félicitations !
## Explication technique
Veuillez consulter le [chapitre sur les images Docker personnalisées dans la documentation d'exécution](https://docs.all-hands.dev/fr/modules/usage/architecture/runtime) pour obtenir des explications plus détaillées.
## Dépannage / Erreurs
### Erreur: ```useradd: UID 1000 est non unique```
Si vous voyez cette erreur dans la sortie de la console, il s'agit du fait que OpenHands essaie de créer le utilisateur openhands dans le sandbox avec un ID d'utilisateur de 1000, cependant cet ID d'utilisateur est déjà utilisé dans l'image (pour une raison inconnue). Pour résoudre ce problème, changez la valeur du champ user_id dans le fichier config.toml en une valeur différente:
```toml
[core]
workspace_base="./workspace"
run_as_openhands=true
[sandbox]
base_container_image="image_personnalisée"
user_id="1001"
```
### Erreurs de port d'utilisation
Si vous voyez un message d'erreur indiquant que le port est utilisé ou indisponible, essayez de supprimer toutes les containers docker en cours d'exécution (exécutez `docker ps` et `docker rm` des containers concernés) puis ré-exécutez ```make run```

View File

@@ -0,0 +1,41 @@
# ✅ Fournir des commentaires
Lorsque vous utilisez OpenHands, vous rencontrerez des cas où les choses fonctionnent bien, et d'autres où elles ne fonctionnent pas. Nous vous encourageons à fournir des commentaires lorsque vous utilisez OpenHands pour aider à donner des retours à l'équipe de développement, et peut-être plus important encore, créer un corpus ouvert d'exemples d'entraînement d'agents de codage -- Share-OpenHands !
## 📝 Comment fournir des commentaires
Fournir des commentaires est facile ! Lorsque vous utilisez OpenHands, vous pouvez appuyer sur le bouton pouce vers le haut ou pouce vers le bas à tout moment pendant votre interaction. Vous serez invité à fournir votre adresse e-mail (par exemple, afin que nous puissions vous contacter si nous voulons poser des questions de suivi), et vous pouvez choisir si vous souhaitez fournir des commentaires publiquement ou en privé.
<iframe width="560" height="315" src="https://www.youtube.com/embed/5rFx-StMVV0?si=svo7xzp6LhGK_GXr" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
## 📜 Utilisation des données et confidentialité
### Paramètres de partage des données
Lorsque vous soumettez des données, vous pouvez les soumettre publiquement ou en privé.
* Les données **publiques** seront distribuées sous la licence MIT, comme OpenHands lui-même, et pourront être utilisées par la communauté pour entraîner et tester des modèles. Évidemment, les commentaires que vous pouvez rendre publics seront plus précieux pour la communauté dans son ensemble, donc lorsque vous ne traitez pas d'informations sensibles, nous vous encourageons à choisir cette option !
* Les données **privées** ne seront partagées qu'avec l'équipe OpenHands dans le but d'améliorer OpenHands.
### Qui collecte et stocke les données ?
Les données sont collectées et stockées par [All Hands AI](https://all-hands.dev), une entreprise fondée par les mainteneurs d'OpenHands pour soutenir et améliorer OpenHands.
### Comment les données publiques seront-elles publiées ?
Les données publiques seront publiées lorsque nous atteindrons des jalons fixes, tels que 1 000 exemples publics, 10 000 exemples publics, etc.
À ce moment-là, nous suivrons le processus de publication suivant :
1. Toutes les personnes qui ont contribué à des commentaires publics recevront un e-mail décrivant la publication des données et auront la possibilité de se retirer.
2. La ou les personnes en charge de la publication des données effectueront un contrôle de la qualité des données, en supprimant les commentaires de mauvaise qualité, en supprimant les adresses e-mail des soumissionnaires et en essayant de supprimer toute information sensible.
3. Les données seront publiées publiquement sous la licence MIT via des sites couramment utilisés tels que GitHub ou Hugging Face.
### Que faire si je veux que mes données soient supprimées ?
Pour les données sur les serveurs d'All Hands AI, nous sommes heureux de les supprimer sur demande :
**Une pièce de données :** Si vous souhaitez supprimer une pièce de données, nous ajouterons prochainement un mécanisme pour supprimer les pièces de données en utilisant le lien et le mot de passe qui s'affichent sur l'interface lorsque vous soumettez des données.
**Toutes les données :** Si vous souhaitez que toutes vos données soient supprimées, ou si vous n'avez pas l'ID et le mot de passe que vous avez reçus lors de la soumission des données, veuillez contacter `contact@all-hands.dev` à partir de l'adresse e-mail que vous avez enregistrée lorsque vous avez initialement soumis les données.

View File

@@ -0,0 +1,113 @@
# Démarrer avec OpenHands
Vous avez donc [installé OpenHands](./installation) et avez
[configuré votre LLM](./installation#setup). Et maintenant ?
OpenHands peut vous aider à aborder une grande variété de tâches d'ingénierie. Mais la technologie
est encore nouvelle, et nous sommes loin d'avoir des agents capables de prendre en charge des tâches
d'ingénierie vastes et compliquées sans aucune aide. Il est donc important de se faire une idée de ce que l'agent
fait bien, et où il pourrait avoir besoin d'un coup de main.
## Hello World
La première chose que vous voudrez peut-être essayer est un simple exemple "hello world".
Cela peut être plus compliqué qu'il n'y paraît !
Essayez de demander à l'agent :
> Veuillez écrire un script bash hello.sh qui affiche "hello world!"
Vous devriez constater que l'agent non seulement écrit le script, mais définit également les
permissions correctes et exécute le script pour vérifier la sortie.
Vous pouvez continuer à demander à l'agent d'affiner votre code. C'est une excellente façon de
travailler avec les agents. Commencez simplement, et itérez.
> Veuillez modifier hello.sh pour qu'il accepte un nom comme premier argument, mais par défaut "world"
Vous pouvez également travailler dans n'importe quel langage dont vous avez besoin, bien que l'agent puisse avoir besoin de passer du
temps à configurer son environnement !
> Veuillez convertir hello.sh en un script Ruby, et l'exécuter
## Construire à partir de zéro
Les agents se débrouillent exceptionnellement bien pour les tâches "greenfield" (tâches où ils n'ont pas besoin
de contexte sur une base de code existante) et ils peuvent simplement commencer à partir de zéro.
Il est préférable de commencer par une tâche simple, puis d'itérer. Il est également préférable d'être
aussi précis que possible sur ce que vous voulez, sur la pile technologique à utiliser, etc.
Par exemple, nous pourrions construire une application TODO :
> Veuillez créer une application basique de liste de tâches en React. Elle devrait être uniquement frontend, et tout l'état
> devrait être conservé dans localStorage.
Nous pouvons continuer à itérer sur l'application une fois le squelette en place :
> Veuillez permettre d'ajouter une date d'échéance optionnelle à chaque tâche
Tout comme avec le développement normal, il est bon de commiter et de pousser votre code fréquemment.
De cette façon, vous pouvez toujours revenir à un ancien état si l'agent dévie.
Vous pouvez demander à l'agent de commiter et de pousser pour vous :
> Veuillez commiter les changements et les pousser sur une nouvelle branche appelée "feature/due-dates"
## Ajouter du nouveau code
OpenHands peut également faire un excellent travail en ajoutant du nouveau code à une base de code existante.
Par exemple, vous pouvez demander à OpenHands d'ajouter une nouvelle action GitHub à votre projet
qui analyse votre code. OpenHands peut jeter un coup d'œil à votre base de code pour voir quel langage
il doit utiliser, mais ensuite il peut simplement déposer un nouveau fichier dans `./github/workflows/lint.yml`
> Veuillez ajouter une action GitHub qui analyse le code dans ce dépôt
Certaines tâches peuvent nécessiter un peu plus de contexte. Bien qu'OpenHands puisse utiliser `ls` et `grep`
pour rechercher dans votre base de code, fournir le contexte à l'avance lui permet d'aller plus vite,
et plus précisément. Et cela vous coûtera moins de tokens !
> Veuillez modifier ./backend/api/routes.js pour ajouter une nouvelle route qui renvoie une liste de toutes les tâches
> Veuillez ajouter un nouveau composant React qui affiche une liste de Widgets dans le répertoire ./frontend/components.
> Il devrait utiliser le composant Widget existant.
## Refactoring
OpenHands est excellent pour refactoriser du code existant, surtout par petits morceaux.
Vous ne voulez probablement pas essayer de réarchitecturer toute votre base de code, mais diviser
les longs fichiers et fonctions, renommer les variables, etc. ont tendance à très bien fonctionner.
> Veuillez renommer toutes les variables à une lettre dans ./app.go
> Veuillez diviser la fonction `build_and_deploy_widgets` en deux fonctions, `build_widgets` et `deploy_widgets` dans widget.php
> Veuillez diviser ./api/routes.js en fichiers séparés pour chaque route
## Corrections de bugs
OpenHands peut également vous aider à traquer et corriger des bugs dans votre code. Mais, comme tout
développeur le sait, la correction de bugs peut être extrêmement délicate, et souvent OpenHands aura besoin de plus de contexte.
Cela aide si vous avez diagnostiqué le bug, mais que vous voulez qu'OpenHands comprenne la logique.
> Actuellement, le champ email dans le point de terminaison `/subscribe` rejette les domaines .io. Veuillez corriger cela.
> La fonction `search_widgets` dans ./app.py effectue une recherche sensible à la casse. Veuillez la rendre insensible à la casse.
Il est souvent utile de faire du développement piloté par les tests lors de la correction de bugs avec un agent.
Vous pouvez demander à l'agent d'écrire un nouveau test, puis d'itérer jusqu'à ce qu'il corrige le bug :
> La fonction `hello` plante sur la chaîne vide. Veuillez écrire un test qui reproduit ce bug, puis corrigez le code pour qu'il passe.
## Plus
OpenHands est capable d'aider sur à peu près n'importe quelle tâche de codage. Mais il faut de la pratique
pour en tirer le meilleur parti. N'oubliez pas de :
* Garder vos tâches petites
* Être aussi précis que possible
* Fournir autant de contexte que possible
* Commiter et pousser fréquemment
Voir [Bonnes pratiques de prompting](./prompting/prompting-best-practices) pour plus de conseils sur la façon de tirer le meilleur parti d'OpenHands.

View File

@@ -0,0 +1,112 @@
# Mode CLI
OpenHands peut être exécuté en mode CLI interactif, ce qui permet aux utilisateurs de démarrer une session interactive via la ligne de commande.
Ce mode est différent du [mode headless](headless-mode), qui est non interactif et mieux adapté aux scripts.
## Avec Python
Pour démarrer une session OpenHands interactive via la ligne de commande, suivez ces étapes :
1. Assurez-vous d'avoir suivi les [instructions de configuration de développement](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md).
2. Exécutez la commande suivante :
```bash
poetry run python -m openhands.core.cli
```
Cette commande démarrera une session interactive où vous pourrez saisir des tâches et recevoir des réponses d'OpenHands.
Vous devrez vous assurer de définir votre modèle, votre clé API et d'autres paramètres via des variables d'environnement
[ou le fichier `config.toml`](https://github.com/All-Hands-AI/OpenHands/blob/main/config.template.toml).
## Avec Docker
Pour exécuter OpenHands en mode CLI avec Docker, suivez ces étapes :
1. Définissez `WORKSPACE_BASE` sur le répertoire que vous voulez qu'OpenHands modifie :
```bash
WORKSPACE_BASE=$(pwd)/workspace
```
2. Définissez `LLM_MODEL` sur le modèle que vous voulez utiliser :
```bash
LLM_MODEL="anthropic/claude-3-5-sonnet-20241022"
```
3. Définissez `LLM_API_KEY` sur votre clé API :
```bash
LLM_API_KEY="sk_test_12345"
```
4. Exécutez la commande Docker suivante :
```bash
docker run -it \
--pull=always \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.34-nikolaik \
-e SANDBOX_USER_ID=$(id -u) \
-e WORKSPACE_MOUNT_PATH=$WORKSPACE_BASE \
-e LLM_API_KEY=$LLM_API_KEY \
-e LLM_MODEL=$LLM_MODEL \
-v $WORKSPACE_BASE:/opt/workspace_base \
-v /var/run/docker.sock:/var/run/docker.sock \
--add-host host.docker.internal:host-gateway \
--name openhands-app-$(date +%Y%m%d%H%M%S) \
docker.all-hands.dev/all-hands-ai/openhands:0.34 \
python -m openhands.core.cli
```
Cette commande démarrera une session interactive dans Docker où vous pourrez saisir des tâches et recevoir des réponses d'OpenHands.
## Exemples de commandes CLI et de sorties attendues
Voici quelques exemples de commandes CLI et leurs sorties attendues :
### Exemple 1 : Tâche simple
```bash
How can I help? >> Écrivez un script Python qui affiche "Hello, World!"
```
Sortie attendue :
```bash
🤖 Bien sûr ! Voici un script Python qui affiche "Hello, World!" :
print("Hello, World!")
```
### Exemple 2 : Commande Bash
```bash
How can I help? >> Créez un répertoire nommé "test_dir"
```
Sortie attendue :
```bash
🤖 Création d'un répertoire nommé "test_dir" :
mkdir test_dir
```
### Exemple 3 : Gestion des erreurs
```bash
How can I help? >> Supprimez un fichier inexistant
```
Sortie attendue :
```bash
🤖 Une erreur s'est produite. Veuillez réessayer.
```

View File

@@ -0,0 +1,62 @@
# Sandbox Personnalisé
Le sandbox est l'endroit où l'agent effectue ses tâches. Au lieu d'exécuter des commandes directement sur votre ordinateur (ce qui pourrait être risqué), l'agent les exécute à l'intérieur d'un conteneur Docker.
Le sandbox OpenHands par défaut (`python-nodejs:python3.12-nodejs22` de [nikolaik/python-nodejs](https://hub.docker.com/r/nikolaik/python-nodejs)) est livré avec certains paquets installés tels que Python et Node.js mais peut nécessiter l'installation d'autres logiciels par défaut.
Vous avez deux options pour la personnalisation :
1. Utiliser une image existante avec les logiciels requis.
2. Créer votre propre image Docker personnalisée.
Si vous choisissez la première option, vous pouvez passer la section `Créer Votre Image Docker`.
## Créer Votre Image Docker
Pour créer une image Docker personnalisée, elle doit être basée sur Debian.
Par exemple, si vous voulez qu'OpenHands ait `ruby` installé, créez un `Dockerfile` avec le contenu suivant :
```dockerfile
FROM debian:latest
# Installer les paquets requis
RUN apt-get update && apt-get install -y ruby
```
Enregistrez ce fichier dans un dossier. Ensuite, construisez votre image Docker (par exemple, nommée custom-image) en naviguant vers le dossier dans le terminal et en exécutant :
```bash
docker build -t custom-image .
```
Cela produira une nouvelle image appelée `custom-image`, qui sera disponible dans Docker.
> Notez que dans la configuration décrite dans ce document, OpenHands s'exécutera en tant qu'utilisateur "openhands" à l'intérieur du sandbox et donc tous les paquets installés via le docker file devraient être disponibles pour tous les utilisateurs du système, pas seulement root.
## Utilisation du Workflow de Développement
### Configuration
Tout d'abord, assurez-vous de pouvoir exécuter OpenHands en suivant les instructions dans [Development.md](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md).
### Spécifier l'Image de Base du Sandbox
Dans le fichier `config.toml` dans le répertoire OpenHands, définissez `base_container_image` sur l'image que vous souhaitez utiliser. Cela peut être une image que vous avez déjà extraite ou une que vous avez construite :
```bash
[core]
...
[sandbox]
base_container_image="custom-image"
```
### Exécution
Exécutez OpenHands en exécutant ```make run``` dans le répertoire de niveau supérieur.
## Explication Technique
Veuillez vous référer à la [section image docker personnalisée de la documentation d'exécution](https://docs.all-hands.dev/modules/usage/architecture/runtime#advanced-how-openhands-builds-and-maintains-od-runtime-images) pour plus de détails.

View File

@@ -0,0 +1,73 @@
# Débogage
Ce qui suit est destiné à servir d'introduction au débogage d'OpenHands à des fins de développement.
## Serveur / VSCode
Le `launch.json` suivant permettra de déboguer les éléments agent, contrôleur et serveur, mais pas le bac à sable (qui s'exécute dans docker). Il ignorera toutes les modifications à l'intérieur du répertoire `workspace/` :
```
{
"version": "0.2.0",
"configurations": [
{
"name": "OpenHands CLI",
"type": "debugpy",
"request": "launch",
"module": "openhands.core.cli",
"justMyCode": false
},
{
"name": "OpenHands WebApp",
"type": "debugpy",
"request": "launch",
"module": "uvicorn",
"args": [
"openhands.server.listen:app",
"--reload",
"--reload-exclude",
"${workspaceFolder}/workspace",
"--port",
"3000"
],
"justMyCode": false
}
]
}
```
Des configurations de débogage plus spécifiques qui incluent plus de paramètres peuvent être spécifiées :
```
...
{
"name": "Debug CodeAct",
"type": "debugpy",
"request": "launch",
"module": "openhands.core.main",
"args": [
"-t",
"Demandez-moi quelle est votre tâche.",
"-d",
"${workspaceFolder}/workspace",
"-c",
"CodeActAgent",
"-l",
"llm.o1",
"-n",
"prompts"
],
"justMyCode": false
}
...
```
Les valeurs dans l'extrait ci-dessus peuvent être mises à jour de telle sorte que :
* *t* : la tâche
* *d* : le répertoire de l'espace de travail openhands
* *c* : l'agent
* *l* : la configuration LLM (prédéfinie dans config.toml)
* *n* : le nom de la session (par exemple, le nom du flux d'événements)

View File

@@ -0,0 +1,280 @@
# Évaluation
Ce guide fournit un aperçu de la façon d'intégrer votre propre benchmark d'évaluation dans le framework OpenHands.
## Configuration de l'environnement et de la configuration LLM
Veuillez suivre les instructions [ici](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md) pour configurer votre environnement de développement local.
OpenHands en mode développement utilise `config.toml` pour garder une trace de la plupart des configurations.
Voici un exemple de fichier de configuration que vous pouvez utiliser pour définir et utiliser plusieurs LLMs :
```toml
[llm]
# IMPORTANT : ajoutez votre clé API ici et définissez le modèle que vous souhaitez évaluer
model = "claude-3-5-sonnet-20241022"
api_key = "sk-XXX"
[llm.eval_gpt4_1106_preview_llm]
model = "gpt-4-1106-preview"
api_key = "XXX"
temperature = 0.0
[llm.eval_some_openai_compatible_model_llm]
model = "openai/MODEL_NAME"
base_url = "https://OPENAI_COMPATIBLE_URL/v1"
api_key = "XXX"
temperature = 0.0
```
## Comment utiliser OpenHands en ligne de commande
OpenHands peut être exécuté depuis la ligne de commande en utilisant le format suivant :
```bash
poetry run python ./openhands/core/main.py \
-i <max_iterations> \
-t "<task_description>" \
-c <agent_class> \
-l <llm_config>
```
Par exemple :
```bash
poetry run python ./openhands/core/main.py \
-i 10 \
-t "Écrivez-moi un script bash qui affiche hello world." \
-c CodeActAgent \
-l llm
```
Cette commande exécute OpenHands avec :
- Un maximum de 10 itérations
- La description de tâche spécifiée
- En utilisant CodeActAgent
- Avec la configuration LLM définie dans la section `llm` de votre fichier `config.toml`
## Comment fonctionne OpenHands
Le point d'entrée principal d'OpenHands se trouve dans `openhands/core/main.py`. Voici un flux simplifié de son fonctionnement :
1. Analyse des arguments de ligne de commande et chargement de la configuration
2. Création d'un environnement d'exécution à l'aide de `create_runtime()`
3. Initialisation de l'agent spécifié
4. Exécution du contrôleur à l'aide de `run_controller()`, qui :
- Attache l'environnement d'exécution à l'agent
- Exécute la tâche de l'agent
- Renvoie un état final une fois terminé
La fonction `run_controller()` est le cœur de l'exécution d'OpenHands. Elle gère l'interaction entre l'agent, l'environnement d'exécution et la tâche, en gérant des choses comme la simulation d'entrée utilisateur et le traitement des événements.
## Le moyen le plus simple de commencer : Explorer les benchmarks existants
Nous vous encourageons à examiner les différents benchmarks d'évaluation disponibles dans le [répertoire `evaluation/benchmarks/`](https://github.com/All-Hands-AI/OpenHands/blob/main/evaluation/benchmarks) de notre dépôt.
Pour intégrer votre propre benchmark, nous vous suggérons de commencer par celui qui ressemble le plus à vos besoins. Cette approche peut considérablement rationaliser votre processus d'intégration, vous permettant de vous appuyer sur les structures existantes et de les adapter à vos exigences spécifiques.
## Comment créer un workflow d'évaluation
Pour créer un workflow d'évaluation pour votre benchmark, suivez ces étapes :
1. Importez les utilitaires OpenHands pertinents :
```python
import openhands.agenthub
from evaluation.utils.shared import (
EvalMetadata,
EvalOutput,
make_metadata,
prepare_dataset,
reset_logger_for_multiprocessing,
run_evaluation,
)
from openhands.controller.state.state import State
from openhands.core.config import (
AppConfig,
SandboxConfig,
get_llm_config_arg,
parse_arguments,
)
from openhands.core.logger import openhands_logger as logger
from openhands.core.main import create_runtime, run_controller
from openhands.events.action import CmdRunAction
from openhands.events.observation import CmdOutputObservation, ErrorObservation
from openhands.runtime.runtime import Runtime
```
2. Créez une configuration :
```python
def get_config(instance: pd.Series, metadata: EvalMetadata) -> AppConfig:
config = AppConfig(
default_agent=metadata.agent_class,
runtime='docker',
max_iterations=metadata.max_iterations,
sandbox=SandboxConfig(
base_container_image='your_container_image',
enable_auto_lint=True,
timeout=300,
),
)
config.set_llm_config(metadata.llm_config)
return config
```
3. Initialisez l'environnement d'exécution et configurez l'environnement d'évaluation :
```python
def initialize_runtime(runtime: Runtime, instance: pd.Series):
# Configurez votre environnement d'évaluation ici
# Par exemple, définir des variables d'environnement, préparer des fichiers, etc.
pass
```
4. Créez une fonction pour traiter chaque instance :
```python
from openhands.utils.async_utils import call_async_from_sync
def process_instance(instance: pd.Series, metadata: EvalMetadata) -> EvalOutput:
config = get_config(instance, metadata)
runtime = create_runtime(config)
call_async_from_sync(runtime.connect)
initialize_runtime(runtime, instance)
instruction = get_instruction(instance, metadata)
state = run_controller(
config=config,
task_str=instruction,
runtime=runtime,
fake_user_response_fn=your_user_response_function,
)
# Évaluez les actions de l'agent
evaluation_result = await evaluate_agent_actions(runtime, instance)
return EvalOutput(
instance_id=instance.instance_id,
instruction=instruction,
test_result=evaluation_result,
metadata=metadata,
history=compatibility_for_eval_history_pairs(state.history),
metrics=state.metrics.get() if state.metrics else None,
error=state.last_error if state and state.last_error else None,
)
```
5. Exécutez l'évaluation :
```python
metadata = make_metadata(llm_config, dataset_name, agent_class, max_iterations, eval_note, eval_output_dir)
output_file = os.path.join(metadata.eval_output_dir, 'output.jsonl')
instances = prepare_dataset(your_dataset, output_file, eval_n_limit)
await run_evaluation(
instances,
metadata,
output_file,
num_workers,
process_instance
)
```
Ce workflow configure la configuration, initialise l'environnement d'exécution, traite chaque instance en exécutant l'agent et en évaluant ses actions, puis collecte les résultats dans un objet `EvalOutput`. La fonction `run_evaluation` gère la parallélisation et le suivi de la progression.
N'oubliez pas de personnaliser les fonctions `get_instruction`, `your_user_response_function` et `evaluate_agent_actions` en fonction des exigences spécifiques de votre benchmark.
En suivant cette structure, vous pouvez créer un workflow d'évaluation robuste pour votre benchmark dans le framework OpenHands.
## Comprendre la `user_response_fn`
La `user_response_fn` est un composant crucial dans le workflow d'évaluation d'OpenHands. Elle simule l'interaction de l'utilisateur avec l'agent, permettant des réponses automatisées pendant le processus d'évaluation. Cette fonction est particulièrement utile lorsque vous voulez fournir des réponses cohérentes et prédéfinies aux requêtes ou actions de l'agent.
### Workflow et interaction
Le workflow correct pour gérer les actions et la `user_response_fn` est le suivant :
1. L'agent reçoit une tâche et commence à la traiter
2. L'agent émet une Action
3. Si l'Action est exécutable (par exemple, CmdRunAction, IPythonRunCellAction) :
- Le Runtime traite l'Action
- Le Runtime renvoie une Observation
4. Si l'Action n'est pas exécutable (généralement une MessageAction) :
- La `user_response_fn` est appelée
- Elle renvoie une réponse utilisateur simulée
5. L'agent reçoit soit l'Observation, soit la réponse simulée
6. Les étapes 2 à 5 se répètent jusqu'à ce que la tâche soit terminée ou que le nombre maximum d'itérations soit atteint
Voici une représentation visuelle plus précise :
```
[Agent]
|
v
[Émettre une Action]
|
v
[L'Action est-elle exécutable ?]
/ \
Oui Non
| |
v v
[Runtime] [user_response_fn]
| |
v v
[Renvoyer une Observation] [Réponse simulée]
\ /
\ /
v v
[L'agent reçoit le feedback]
|
v
[Continuer ou terminer la tâche]
```
Dans ce workflow :
- Les actions exécutables (comme l'exécution de commandes ou de code) sont gérées directement par le Runtime
- Les actions non exécutables (généralement lorsque l'agent veut communiquer ou demander des clarifications) sont gérées par la `user_response_fn`
- L'agent traite ensuite le feedback, qu'il s'agisse d'une Observation du Runtime ou d'une réponse simulée de la `user_response_fn`
Cette approche permet une gestion automatisée des actions concrètes et des interactions utilisateur simulées, ce qui la rend adaptée aux scénarios d'évaluation où vous voulez tester la capacité de l'agent à accomplir des tâches avec une intervention humaine minimale.
### Exemple d'implémentation
Voici un exemple de `user_response_fn` utilisée dans l'évaluation SWE-Bench :
```python
def codeact_user_response(state: State | None) -> str:
msg = (
'Veuillez continuer à travailler sur la tâche avec l\'approche que vous jugez appropriée.\n'
'Si vous pensez avoir résolu la tâche, veuillez d\'abord envoyer votre réponse à l\'utilisateur via un message, puis <execute_bash> exit </execute_bash>.\n'
'IMPORTANT : VOUS NE DEVEZ JAMAIS DEMANDER DE L\'AIDE HUMAINE.\n'
)
if state and state.history:
# vérifier si l'agent a essayé de parler à l'utilisateur 3 fois, si oui, faire savoir à l'agent qu'il peut abandonner
user_msgs = [
event
for event in state.history
if isinstance(event, MessageAction) and event.source == 'user'
]
if len(user_msgs) >= 2:
# faire savoir à l'agent qu'il peut abandonner quand il a essayé 3 fois
return (
msg
+ 'Si vous voulez abandonner, exécutez : <execute_bash> exit </execute_bash>.\n'
)
return msg
```
Cette fonction fait ce qui suit :
1. Fournit un message standard encourageant l'agent à continuer à travailler
2. Vérifie combien de fois l'agent a tenté de communiquer avec l'utilisateur
3. Si l'agent a fait plusieurs tentatives, il lui donne la possibilité d'abandonner
En utilisant cette fonction, vous pouvez assurer un comportement cohérent sur plusieurs exécutions d'évaluation et empêcher l'agent de rester bloqué en attendant une entrée humaine.

View File

@@ -0,0 +1,51 @@
# Utilisation de l'Action GitHub OpenHands
Ce guide explique comment utiliser l'Action GitHub OpenHands, à la fois dans le dépôt OpenHands et dans vos propres projets.
## Utilisation de l'Action dans le dépôt OpenHands
Pour utiliser l'Action GitHub OpenHands dans un dépôt, vous pouvez :
1. Créer un ticket dans le dépôt.
2. Ajouter l'étiquette `fix-me` au ticket ou laisser un commentaire sur le ticket commençant par `@openhands-agent`.
L'action se déclenchera automatiquement et tentera de résoudre le ticket.
## Installation de l'Action dans un nouveau dépôt
Pour installer l'Action GitHub OpenHands dans votre propre dépôt, suivez le [README pour le Resolver OpenHands](https://github.com/All-Hands-AI/OpenHands/blob/main/openhands/resolver/README.md).
## Conseils d'utilisation
### Résolution itérative
1. Créez un ticket dans le dépôt.
2. Ajoutez l'étiquette `fix-me` au ticket, ou laissez un commentaire commençant par `@openhands-agent`
3. Examinez la tentative de résolution du ticket en vérifiant la pull request
4. Faites un suivi avec des commentaires via des commentaires généraux, des commentaires de revue ou des commentaires de fil en ligne
5. Ajoutez l'étiquette `fix-me` à la pull request, ou adressez un commentaire spécifique en commençant par `@openhands-agent`
### Étiquette versus Macro
- Étiquette (`fix-me`) : Demande à OpenHands de traiter le ticket ou la pull request dans son **intégralité**.
- Macro (`@openhands-agent`) : Demande à OpenHands de ne considérer que la description du ticket/de la pull request et **le commentaire spécifique**.
## Paramètres avancés
### Ajouter des paramètres de dépôt personnalisés
Vous pouvez fournir des instructions personnalisées pour OpenHands en suivant le [README pour le resolver](https://github.com/All-Hands-AI/OpenHands/blob/main/openhands/resolver/README.md#providing-custom-instructions).
### Configurations personnalisées
Le resolver Github vérifiera automatiquement les [secrets de dépôt](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions?tool=webui#creating-secrets-for-a-repository) ou les [variables de dépôt](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables#creating-configuration-variables-for-a-repository) valides pour personnaliser son comportement.
Les options de personnalisation que vous pouvez définir sont :
| **Nom de l'attribut** | **Type** | **Objectif** | **Exemple** |
|----------------------------------| -------- |-------------------------------------------------------------------------------------------------------------|------------------------------------------------------|
| `LLM_MODEL` | Variable | Définir le LLM à utiliser avec OpenHands | `LLM_MODEL="anthropic/claude-3-5-sonnet-20241022"` |
| `OPENHANDS_MAX_ITER` | Variable | Définir la limite maximale pour les itérations de l'agent | `OPENHANDS_MAX_ITER=10` |
| `OPENHANDS_MACRO` | Variable | Personnaliser la macro par défaut pour invoquer le resolver | `OPENHANDS_MACRO=@resolveit` |
| `OPENHANDS_BASE_CONTAINER_IMAGE` | Variable | Sandbox personnalisé ([en savoir plus](https://docs.all-hands.dev/modules/usage/how-to/custom-sandbox-guide))| `OPENHANDS_BASE_CONTAINER_IMAGE="custom_image"` |

View File

@@ -0,0 +1,168 @@
# Mode Interface Graphique
## Introduction
OpenHands fournit un mode Interface Graphique (GUI) convivial pour interagir avec l'assistant IA. Ce mode offre une façon intuitive de configurer l'environnement, gérer les paramètres et communiquer avec l'IA.
## Installation et Configuration
1. Suivez les instructions du guide [Installation](../installation) pour installer OpenHands.
2. Après avoir exécuté la commande, accédez à OpenHands à l'adresse [http://localhost:3000](http://localhost:3000).
## Interagir avec l'Interface Graphique
### Configuration Initiale
1. Lors du premier lancement, vous verrez une fenêtre modale de paramètres.
2. Sélectionnez un `Fournisseur LLM` et un `Modèle LLM` dans les menus déroulants.
3. Entrez la `Clé API` correspondante pour le fournisseur choisi.
4. Cliquez sur "Enregistrer" pour appliquer les paramètres.
### Jetons de Contrôle de Version
OpenHands prend en charge plusieurs fournisseurs de contrôle de version. Vous pouvez configurer des jetons pour plusieurs fournisseurs simultanément.
#### Configuration du Jeton GitHub
OpenHands exporte automatiquement un `GITHUB_TOKEN` vers l'environnement shell s'il est disponible. Cela peut se produire de deux manières :
1. **Localement (OSS)** : L'utilisateur saisit directement son jeton GitHub
2. **En ligne (SaaS)** : Le jeton est obtenu via l'authentification OAuth GitHub
##### Configuration d'un Jeton GitHub Local
1. **Générer un Personal Access Token (PAT)** :
- Allez dans Paramètres GitHub > Paramètres développeur > Personal Access Tokens > Tokens (classique)
- Cliquez sur "Générer un nouveau jeton (classique)"
- Portées requises :
- `repo` (Contrôle total des dépôts privés)
- `workflow` (Mettre à jour les workflows GitHub Action)
- `read:org` (Lire les données de l'organisation)
2. **Entrer le Jeton dans OpenHands** :
- Cliquez sur le bouton Paramètres (icône d'engrenage) en haut à droite
- Accédez à la section "Git Provider Settings"
- Collez votre jeton dans le champ "Jeton GitHub"
- Cliquez sur "Enregistrer" pour appliquer les modifications
##### Politiques de Jetons Organisationnels
Si vous travaillez avec des dépôts organisationnels, une configuration supplémentaire peut être nécessaire :
1. **Vérifier les Exigences de l'Organisation** :
- Les administrateurs de l'organisation peuvent appliquer des politiques de jetons spécifiques
- Certaines organisations exigent que les jetons soient créés avec SSO activé
- Consultez les [paramètres de politique de jetons](https://docs.github.com/en/organizations/managing-programmatic-access-to-your-organization/setting-a-personal-access-token-policy-for-your-organization) de votre organisation
2. **Vérifier l'Accès à l'Organisation** :
- Allez dans les paramètres de votre jeton sur GitHub
- Recherchez l'organisation sous "Accès à l'organisation"
- Si nécessaire, cliquez sur "Activer SSO" à côté de votre organisation
- Terminez le processus d'autorisation SSO
##### Authentification OAuth (Mode En Ligne)
Lorsque vous utilisez OpenHands en mode en ligne, le flux OAuth GitHub :
1. Demande les autorisations suivantes :
- Accès au dépôt (lecture/écriture)
- Gestion des workflows
- Accès en lecture à l'organisation
2. Étapes d'authentification :
- Cliquez sur "Se connecter avec GitHub" lorsque vous y êtes invité
- Examinez les autorisations demandées
- Autorisez OpenHands à accéder à votre compte GitHub
- Si vous utilisez une organisation, autorisez l'accès à l'organisation si vous y êtes invité
##### Dépannage
Problèmes courants et solutions :
1. **Jeton Non Reconnu** :
- Assurez-vous que le jeton est correctement enregistré dans les paramètres
- Vérifiez que le jeton n'a pas expiré
- Vérifiez que le jeton a les portées requises
- Essayez de régénérer le jeton
2. **Accès à l'Organisation Refusé** :
- Vérifiez si SSO est requis mais non activé
- Vérifiez l'appartenance à l'organisation
- Contactez l'administrateur de l'organisation si les politiques de jetons bloquent l'accès
3. **Vérifier que le Jeton Fonctionne** :
- L'application affichera une coche verte si le jeton est valide
- Essayez d'accéder à un dépôt pour confirmer les autorisations
- Vérifiez la console du navigateur pour tout message d'erreur
- Utilisez le bouton "Tester la connexion" dans les paramètres s'il est disponible
#### Configuration du Jeton GitLab
OpenHands exporte automatiquement un `GITLAB_TOKEN` vers l'environnement shell, uniquement pour les installations locales, s'il est disponible.
##### Configuration d'un Jeton GitLab
1. **Générer un Personal Access Token (PAT)** :
- Sur GitLab, allez dans Paramètres utilisateur > Jetons d'accès
- Créez un nouveau jeton avec les portées suivantes :
- `api` (Accès API)
- `read_user` (Lecture des informations utilisateur)
- `read_repository` (Lecture du dépôt)
- `write_repository` (Écriture du dépôt)
- Définissez une date d'expiration ou laissez vide pour un jeton sans expiration
2. **Entrer le Jeton dans OpenHands** :
- Cliquez sur le bouton Paramètres (icône d'engrenage)
- Accédez à la section `Git Provider Settings`
- Collez votre jeton dans le champ `Jeton GitLab`
- Si vous utilisez GitLab auto-hébergé, entrez l'URL de votre instance GitLab
- Cliquez sur `Enregistrer les modifications` pour appliquer les changements
##### Dépannage
Problèmes courants et solutions :
1. **Jeton Non Reconnu** :
- Assurez-vous que le jeton est correctement enregistré dans les paramètres
- Vérifiez que le jeton n'a pas expiré
- Vérifiez que le jeton a les portées requises
- Pour les instances auto-hébergées, vérifiez l'URL correcte de l'instance
2. **Accès Refusé** :
- Vérifiez les permissions d'accès au projet
- Vérifiez si le jeton possède les portées nécessaires
- Pour les dépôts de groupe/organisation, assurez-vous d'avoir les accès appropriés
### Paramètres Avancés
1. Basculez sur `Options Avancées` pour accéder aux paramètres supplémentaires.
2. Utilisez la zone de texte `Modèle Personnalisé` pour saisir manuellement un modèle s'il ne figure pas dans la liste.
3. Spécifiez une `URL de Base` si requis par votre fournisseur LLM.
### Interface Principale
L'interface principale se compose de plusieurs composants clés :
1. **Fenêtre de Chat** : La zone centrale où vous pouvez voir l'historique de conversation avec l'assistant IA.
2. **Zone de Saisie** : Située en bas de l'écran, utilisez-la pour taper vos messages ou commandes à l'IA.
3. **Bouton Envoyer** : Cliquez dessus pour envoyer votre message à l'IA.
4. **Bouton Paramètres** : Une icône d'engrenage qui ouvre la fenêtre modale des paramètres, vous permettant d'ajuster votre configuration à tout moment.
5. **Panneau Espace de Travail** : Affiche les fichiers et dossiers de votre espace de travail, vous permettant de naviguer et de visualiser les fichiers, ou les commandes passées de l'agent ou l'historique de navigation web.
### Interagir avec l'IA
1. Tapez votre question, demande ou description de tâche dans la zone de saisie.
2. Cliquez sur le bouton d'envoi ou appuyez sur Entrée pour soumettre votre message.
3. L'IA traitera votre saisie et fournira une réponse dans la fenêtre de chat.
4. Vous pouvez poursuivre la conversation en posant des questions de suivi ou en fournissant des informations supplémentaires.
## Conseils pour une Utilisation Efficace
1. Soyez précis dans vos demandes pour obtenir les réponses les plus précises et utiles, comme décrit dans les [meilleures pratiques d'incitation](../prompting/prompting-best-practices).
2. Utilisez le panneau d'espace de travail pour explorer la structure de votre projet.
3. Utilisez l'un des modèles recommandés, comme décrit dans la section [LLMs](usage/llms/llms.md).
N'oubliez pas que le mode Interface Graphique d'OpenHands est conçu pour rendre votre interaction avec l'assistant IA aussi fluide et intuitive que possible. N'hésitez pas à explorer ses fonctionnalités pour maximiser votre productivité.

View File

@@ -0,0 +1,61 @@
# Mode sans interface
Vous pouvez exécuter OpenHands avec une seule commande, sans démarrer l'application web.
Cela facilite l'écriture de scripts et l'automatisation des tâches avec OpenHands.
Ceci est différent du [Mode CLI](cli-mode), qui est interactif et mieux adapté au développement actif.
## Avec Python
Pour exécuter OpenHands en mode sans interface avec Python,
[suivez les instructions de configuration de développement](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md),
puis exécutez :
```bash
poetry run python -m openhands.core.main -t "write a bash script that prints hi"
```
Vous devrez vous assurer de définir votre modèle, votre clé API et d'autres paramètres via des variables d'environnement
[ou le fichier `config.toml`](https://github.com/All-Hands-AI/OpenHands/blob/main/config.template.toml).
## Avec Docker
1. Définissez `WORKSPACE_BASE` sur le répertoire que vous voulez qu'OpenHands modifie :
```bash
WORKSPACE_BASE=$(pwd)/workspace
```
2. Définissez `LLM_MODEL` sur le modèle que vous voulez utiliser :
```bash
LLM_MODEL="anthropic/claude-3-5-sonnet-20241022"
```
3. Définissez `LLM_API_KEY` sur votre clé API :
```bash
LLM_API_KEY="sk_test_12345"
```
4. Exécutez la commande Docker suivante :
```bash
docker run -it \
--pull=always \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.34-nikolaik \
-e SANDBOX_USER_ID=$(id -u) \
-e WORKSPACE_MOUNT_PATH=$WORKSPACE_BASE \
-e LLM_API_KEY=$LLM_API_KEY \
-e LLM_MODEL=$LLM_MODEL \
-e LOG_ALL_EVENTS=true \
-v $WORKSPACE_BASE:/opt/workspace_base \
-v /var/run/docker.sock:/var/run/docker.sock \
--add-host host.docker.internal:host-gateway \
--name openhands-app-$(date +%Y%m%d%H%M%S) \
docker.all-hands.dev/all-hands-ai/openhands:0.34 \
python -m openhands.core.main -t "write a bash script that prints hi" --no-auto-continue
```

View File

@@ -0,0 +1,18 @@
# Persistance des données de session
Avec l'installation standard, les données de session sont stockées en mémoire. Actuellement, si le service OpenHands est redémarré,
les sessions précédentes deviennent invalides (un nouveau secret est généré) et ne sont donc pas récupérables.
## Comment persister les données de session
### Workflow de développement
Dans le fichier `config.toml`, spécifiez ce qui suit :
```
[core]
...
file_store="local"
file_store_path="/absolute/path/to/openhands/cache/directory"
jwt_secret="secretpass"
```

View File

@@ -0,0 +1,57 @@
# Exécution d'OpenHands
## Configuration système requise
* Docker version 26.0.0+ ou Docker Desktop 4.31.0+.
* Vous devez utiliser Linux ou Mac OS.
* Si vous êtes sous Windows, vous devez utiliser [WSL](https://learn.microsoft.com/en-us/windows/wsl/install).
## Démarrer l'application
La façon la plus simple d'exécuter OpenHands est avec Docker.
```bash
docker pull docker.all-hands.dev/all-hands-ai/runtime:0.34-nikolaik
docker run -it --rm --pull=always \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.34-nikolaik \
-e LOG_ALL_EVENTS=true \
-v /var/run/docker.sock:/var/run/docker.sock \
-p 3000:3000 \
--add-host host.docker.internal:host-gateway \
--name openhands-app \
docker.all-hands.dev/all-hands-ai/openhands:0.34
```
Vous pouvez également exécuter OpenHands en mode [headless scriptable](https://docs.all-hands.dev/modules/usage/how-to/headless-mode), en tant que [CLI interactive](https://docs.all-hands.dev/modules/usage/how-to/cli-mode), ou en utilisant l'[Action GitHub OpenHands](https://docs.all-hands.dev/modules/usage/how-to/github-action).
## Configuration
Après avoir exécuté la commande ci-dessus, vous trouverez OpenHands en cours d'exécution à l'adresse [http://localhost:3000](http://localhost:3000).
Au lancement d'OpenHands, vous verrez une fenêtre modale de paramètres. Vous **devez** sélectionner un `Fournisseur LLM` et un `Modèle LLM`, et entrer une `Clé API` correspondante.
Ces paramètres peuvent être modifiés à tout moment en sélectionnant le bouton `Paramètres` (icône d'engrenage) dans l'interface utilisateur.
Si le `Modèle LLM` requis n'existe pas dans la liste, vous pouvez activer les `Options avancées` et l'entrer manuellement avec le préfixe correct
dans la zone de texte `Modèle personnalisé`.
Les `Options avancées` vous permettent également de spécifier une `URL de base` si nécessaire.
<div style={{ display: 'flex', justifyContent: 'center', gap: '20px' }}>
<img src="/img/settings-screenshot.png" alt="settings-modal" width="340" />
<img src="/img/settings-advanced.png" alt="settings-modal" width="335" />
</div>
## Versions
La commande ci-dessus récupère la version stable la plus récente d'OpenHands. Vous avez également d'autres options :
- Pour une version spécifique, utilisez `docker.all-hands.dev/all-hands-ai/openhands:$VERSION`, en remplaçant $VERSION par le numéro de version.
- Nous utilisons semver et publions des tags majeurs, mineurs et de patch. Ainsi, `0.9` pointera automatiquement vers la dernière version `0.9.x`, et `0` pointera vers la dernière version `0.x.x`.
- Pour la version de développement la plus à jour, vous pouvez utiliser `docker.all-hands.dev/all-hands-ai/openhands:main`. Cette version est instable et n'est recommandée qu'à des fins de test ou de développement.
Vous pouvez choisir le tag qui convient le mieux à vos besoins en fonction des exigences de stabilité et des fonctionnalités souhaitées.
Pour le workflow de développement, consultez [Development.md](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md).
Vous rencontrez des problèmes ? Consultez notre [Guide de dépannage](https://docs.all-hands.dev/modules/usage/troubleshooting).

View File

@@ -0,0 +1,109 @@
---
sidebar_position: 1
---
# 💻 OpenHands
OpenHands est un **ingénieur logiciel IA autonome** capable d'exécuter des tâches d'ingénierie complexes et de collaborer activement avec les utilisateurs sur des projets de développement logiciel.
Ce projet est entièrement open-source, vous pouvez donc l'utiliser et le modifier comme bon vous semble.
:::tip
Explorez le code source d'OpenHands sur [GitHub](https://github.com/All-Hands-AI/OpenHands) ou rejoignez l'une de nos communautés !
<a href="https://github.com/All-Hands-AI/OpenHands/graphs/contributors">
<img
src="https://img.shields.io/github/contributors/All-Hands-AI/OpenHands?style=for-the-badge"
alt="Contributors"
/>
</a>
<a href="https://github.com/All-Hands-AI/OpenHands/network/members">
<img
src="https://img.shields.io/github/forks/All-Hands-AI/OpenHands?style=for-the-badge"
alt="Forks"
/>
</a>
<a href="https://github.com/All-Hands-AI/OpenHands/stargazers">
<img
src="https://img.shields.io/github/stars/All-Hands-AI/OpenHands?style=for-the-badge"
alt="Stargazers"
/>
</a>
<a href="https://github.com/All-Hands-AI/OpenHands/issues">
<img
src="https://img.shields.io/github/issues/All-Hands-AI/OpenHands?style=for-the-badge"
alt="Issues"
/>
</a>
<br></br>
<a href="https://github.com/All-Hands-AI/OpenHands/blob/main/LICENSE">
<img
src="https://img.shields.io/github/license/All-Hands-AI/OpenHands?style=for-the-badge"
alt="MIT License"
/>
</a>
<br></br>
<a href="https://join.slack.com/t/openhands-ai/shared_invite/zt-2ngejmfw6-9gW4APWOC9XUp1n~SiQ6iw">
<img
src="https://img.shields.io/badge/Slack-Join%20Us-red?logo=slack&logoColor=white&style=for-the-badge"
alt="Join our Slack community"
/>
</a>
<a href="https://discord.gg/ESHStjSjD4">
<img
src="https://img.shields.io/badge/Discord-Join%20Us-purple?logo=discord&logoColor=white&style=for-the-badge"
alt="Join our Discord community"
/>
</a>
:::
## 🛠️ Pour commencer
La manière la plus simple d'exécuter OpenHands est à l'intérieur d'un conteneur Docker. Il fonctionne mieux avec la version la plus récente de Docker, `26.0.0`.
Vous devez utiliser Linux, Mac OS ou WSL sur Windows.
Pour démarrer OpenHands dans un conteneur docker, exécutez les commandes suivantes dans votre terminal :
:::warning
Lorsque vous exécutez la commande suivante, les fichiers dans `./workspace` peuvent être modifiés ou supprimés.
:::
```bash
WORKSPACE_BASE=$(pwd)/workspace
docker run -it \
--pull=always \
-e SANDBOX_USER_ID=$(id -u) \
-e WORKSPACE_MOUNT_PATH=$WORKSPACE_BASE \
-v $WORKSPACE_BASE:/opt/workspace_base \
-v /var/run/docker.sock:/var/run/docker.sock \
-p 3000:3000 \
--add-host host.docker.internal:host-gateway \
--name openhands-app-$(date +%Y%m%d%H%M%S) \
ghcr.io/all-hands-ai/openhands:main
```
Vous trouverez OpenHands fonctionnant à l'adresse [http://localhost:3000](http://localhost:3000) avec accès à `./workspace`. Pour qu'OpenHands fonctionne sur votre code, placez-le dans `./workspace`.
OpenHands n'aura accès qu'à ce dossier de workspace. Le reste de votre système ne sera pas affecté car il s'exécute dans un bac à sable sécurisé de docker.
:::tip
Si vous souhaitez utiliser la version **(instable !)** la plus récente, vous pouvez utiliser `ghcr.io/all-hands-ai/openhands:main` comme image (dernière ligne).
:::
Pour le workflow de développement, consultez [Development.md](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md).
Avez-vous des problèmes ? Consultez notre [Guide de dépannage](https://docs.all-hands.dev/modules/usage/troubleshooting).
:::warning
OpenHands est actuellement en cours de développement, mais vous pouvez déjà exécuter la version alpha pour voir le système de bout en bout en action.
:::
[contributors-shield]: https://img.shields.io/github/contributors/All-Hands-AI/OpenHands?style=for-the-badge
[contributors-url]: https://github.com/All-Hands-AI/OpenHands/graphs/contributors
[forks-shield]: https://img.shields.io/github/forks/All-Hands-AI/OpenHands?style=for-the-badge
[forks-url]: https://github.com/All-Hands-AI/OpenHands/network/members
[stars-shield]: https://img.shields.io/github/stars/All-Hands-AI/OpenHands?style=for-the-badge
[stars-url]: https://github.com/All-Hands-AI/OpenHands/stargazers
[issues-shield]: https://img.shields.io/github/issues/All-Hands-AI/OpenHands?style=for-the-badge
[issues-url]: https://github.com/All-Hands-AI/OpenHands/issues
[license-shield]: https://img.shields.io/github/license/All-Hands-AI/OpenHands?style=for-the-badge
[license-url]: https://github.com/All-Hands-AI/OpenHands/blob/main/LICENSE

View File

@@ -0,0 +1,48 @@
# Azure
OpenHands utilise LiteLLM pour faire des appels aux modèles de chat d'Azure. Vous pouvez trouver leur documentation sur l'utilisation d'Azure comme fournisseur [ici](https://docs.litellm.ai/docs/providers/azure).
## Configuration d'Azure OpenAI
Lorsque vous exécutez OpenHands, vous devrez définir la variable d'environnement suivante en utilisant `-e` dans la
[commande docker run](/modules/usage/installation#start-the-app) :
```
LLM_API_VERSION="<api-version>" # par exemple "2023-05-15"
```
Exemple :
```bash
docker run -it --pull=always \
-e LLM_API_VERSION="2023-05-15"
...
```
Ensuite, définissez les éléments suivants dans l'interface utilisateur d'OpenHands via les paramètres :
:::note
Vous aurez besoin du nom de votre déploiement ChatGPT qui peut être trouvé sur la page des déploiements dans Azure. Il est référencé comme
&lt;deployment-name&gt; ci-dessous.
:::
* Activez `Advanced Options`
* `Custom Model` à azure/&lt;deployment-name&gt;
* `Base URL` à votre URL de base de l'API Azure (par exemple `https://example-endpoint.openai.azure.com`)
* `API Key` à votre clé API Azure
## Embeddings
OpenHands utilise llama-index pour les embeddings. Vous pouvez trouver leur documentation sur Azure [ici](https://docs.llamaindex.ai/en/stable/api_reference/embeddings/azure_openai/).
### Configuration d'Azure OpenAI
Lorsque vous exécutez OpenHands, définissez les variables d'environnement suivantes en utilisant `-e` dans la
[commande docker run](/modules/usage/installation#start-the-app) :
```
LLM_EMBEDDING_MODEL="azureopenai"
LLM_EMBEDDING_DEPLOYMENT_NAME="<your-embedding-deployment-name>" # par exemple "TextEmbedding...<etc>"
LLM_API_VERSION="<api-version>" # par exemple "2024-02-15-preview"
```

View File

@@ -0,0 +1,37 @@
# Azure OpenAI LLM
## Complétion
OpenHands utilise LiteLLM pour les appels de complétion. Vous pouvez trouver leur documentation sur Azure [ici](https://docs.litellm.ai/docs/providers/azure)
### Configurations openai Azure
Lors de l'exécution de l'image Docker OpenHands, vous devrez définir les variables d'environnement suivantes en utilisant `-e` :
```
LLM_BASE_URL="<azure-api-base-url>" # e.g. "https://openai-gpt-4-test-v-1.openai.azure.com/"
LLM_API_KEY="<azure-api-key>"
LLM_MODEL="azure/<your-gpt-deployment-name>"
LLM_API_VERSION = "<api-version>" # e.g. "2024-02-15-preview"
```
:::note
Vous pouvez trouver le nom de votre déploiement ChatGPT sur la page des déploiements sur Azure. Par défaut ou initialement, il pourrait être le même que le nom du modèle de chat (par exemple 'GPT4-1106-preview'), mais il n'est pas obligé de l'être. Exécutez OpenHands, et une fois chargé dans le navigateur, allez dans Paramètres et définissez le modèle comme suit : "azure/&lt;your-actual-gpt-deployment-name&gt;". Si ce n'est pas dans la liste, entrez votre propre texte et enregistrez-le.
:::
## Embeddings
OpenHands utilise llama-index pour les embeddings. Vous pouvez trouver leur documentation sur Azure [ici](https://docs.llamaindex.ai/en/stable/api_reference/embeddings/azure_openai/)
### Configurations openai Azure
Le modèle utilisé pour les embeddings Azure OpenAI est "text-embedding-ada-002".
Vous avez besoin du nom de déploiement correct pour ce modèle dans votre compte Azure.
Lors de l'exécution d'OpenHands dans Docker, définissez les variables d'environnement suivantes en utilisant `-e` :
```
LLM_EMBEDDING_MODEL="azureopenai"
LLM_EMBEDDING_DEPLOYMENT_NAME = "<your-embedding-deployment-name>" # e.g. "TextEmbedding...<etc>"
LLM_API_VERSION = "<api-version>" # e.g. "2024-02-15-preview"
```

View File

@@ -0,0 +1,106 @@
# Configurations LLM personnalisées
OpenHands permet de définir plusieurs configurations LLM nommées dans votre fichier `config.toml`. Cette fonctionnalité vous permet d'utiliser différentes configurations LLM pour différents usages, comme utiliser un modèle moins coûteux pour les tâches qui ne nécessitent pas de réponses de haute qualité, ou utiliser différents modèles avec différents paramètres pour des agents spécifiques.
## Comment ça fonctionne
Les configurations LLM nommées sont définies dans le fichier `config.toml` en utilisant des sections qui commencent par `llm.`. Par exemple :
```toml
# Configuration LLM par défaut
[llm]
model = "gpt-4"
api_key = "votre-clé-api"
temperature = 0.0
# Configuration LLM personnalisée pour un modèle moins coûteux
[llm.gpt3]
model = "gpt-3.5-turbo"
api_key = "votre-clé-api"
temperature = 0.2
# Une autre configuration personnalisée avec des paramètres différents
[llm.haute-creativite]
model = "gpt-4"
api_key = "votre-clé-api"
temperature = 0.8
top_p = 0.9
```
Chaque configuration nommée hérite de tous les paramètres de la section `[llm]` par défaut et peut remplacer n'importe lequel de ces paramètres. Vous pouvez définir autant de configurations personnalisées que nécessaire.
## Utilisation des configurations personnalisées
### Avec les agents
Vous pouvez spécifier quelle configuration LLM un agent doit utiliser en définissant le paramètre `llm_config` dans la section de configuration de l'agent :
```toml
[agent.RepoExplorerAgent]
# Utiliser la configuration GPT-3 moins coûteuse pour cet agent
llm_config = 'gpt3'
[agent.CodeWriterAgent]
# Utiliser la configuration haute créativité pour cet agent
llm_config = 'haute-creativite'
```
### Options de configuration
Chaque configuration LLM nommée prend en charge toutes les mêmes options que la configuration LLM par défaut. Celles-ci incluent :
- Sélection du modèle (`model`)
- Configuration de l'API (`api_key`, `base_url`, etc.)
- Paramètres du modèle (`temperature`, `top_p`, etc.)
- Paramètres de nouvelle tentative (`num_retries`, `retry_multiplier`, etc.)
- Limites de jetons (`max_input_tokens`, `max_output_tokens`)
- Et toutes les autres options de configuration LLM
Pour une liste complète des options disponibles, consultez la section Configuration LLM dans la documentation des [Options de configuration](../configuration-options).
## Cas d'utilisation
Les configurations LLM personnalisées sont particulièrement utiles dans plusieurs scénarios :
- **Optimisation des coûts** : Utiliser des modèles moins coûteux pour les tâches qui ne nécessitent pas de réponses de haute qualité, comme l'exploration de dépôt ou les opérations simples sur les fichiers.
- **Réglage spécifique aux tâches** : Configurer différentes valeurs de température et de top_p pour les tâches qui nécessitent différents niveaux de créativité ou de déterminisme.
- **Différents fournisseurs** : Utiliser différents fournisseurs LLM ou points d'accès API pour différentes tâches.
- **Tests et développement** : Basculer facilement entre différentes configurations de modèles pendant le développement et les tests.
## Exemple : Optimisation des coûts
Un exemple pratique d'utilisation des configurations LLM personnalisées pour optimiser les coûts :
```toml
# Configuration par défaut utilisant GPT-4 pour des réponses de haute qualité
[llm]
model = "gpt-4"
api_key = "votre-clé-api"
temperature = 0.0
# Configuration moins coûteuse pour l'exploration de dépôt
[llm.repo-explorer]
model = "gpt-3.5-turbo"
temperature = 0.2
# Configuration pour la génération de code
[llm.code-gen]
model = "gpt-4"
temperature = 0.0
max_output_tokens = 2000
[agent.RepoExplorerAgent]
llm_config = 'repo-explorer'
[agent.CodeWriterAgent]
llm_config = 'code-gen'
```
Dans cet exemple :
- L'exploration de dépôt utilise un modèle moins coûteux car il s'agit principalement de comprendre et de naviguer dans le code
- La génération de code utilise GPT-4 avec une limite de jetons plus élevée pour générer des blocs de code plus importants
- La configuration par défaut reste disponible pour les autres tâches
:::note
Les configurations LLM personnalisées ne sont disponibles que lors de l'utilisation d'OpenHands en mode développement, via `main.py` ou `cli.py`. Lors de l'exécution via `docker run`, veuillez utiliser les options de configuration standard.
:::

View File

@@ -0,0 +1,31 @@
# Google Gemini/Vertex
OpenHands utilise LiteLLM pour faire des appels aux modèles de chat de Google. Vous pouvez trouver leur documentation sur l'utilisation de Google comme fournisseur :
- [Gemini - Google AI Studio](https://docs.litellm.ai/docs/providers/gemini)
- [VertexAI - Google Cloud Platform](https://docs.litellm.ai/docs/providers/vertex)
## Configurations de Gemini - Google AI Studio
Lors de l'exécution d'OpenHands, vous devrez définir les éléments suivants dans l'interface utilisateur d'OpenHands via les paramètres :
* `LLM Provider` à `Gemini`
* `LLM Model` au modèle que vous utiliserez.
Si le modèle ne figure pas dans la liste, activez `Advanced Options` et entrez-le dans `Custom Model` (par exemple, gemini/&lt;model-name&gt; comme `gemini/gemini-1.5-pro`).
* `API Key` à votre clé API Gemini
## Configurations de VertexAI - Google Cloud Platform
Pour utiliser Vertex AI via Google Cloud Platform lors de l'exécution d'OpenHands, vous devrez définir les variables d'environnement suivantes en utilisant `-e` dans la [commande docker run](/modules/usage/installation#start-the-app) :
```
GOOGLE_APPLICATION_CREDENTIALS="<json-dump-of-gcp-service-account-json>"
VERTEXAI_PROJECT="<your-gcp-project-id>"
VERTEXAI_LOCATION="<your-gcp-location>"
```
Ensuite, définissez les éléments suivants dans l'interface utilisateur d'OpenHands via les paramètres :
* `LLM Provider` à `VertexAI`
* `LLM Model` au modèle que vous utiliserez.
Si le modèle ne figure pas dans la liste, activez `Advanced Options` et entrez-le dans `Custom Model` (par exemple, vertex_ai/&lt;model-name&gt;).

View File

@@ -0,0 +1,28 @@
# Google Gemini/Vertex LLM
## Complétion
OpenHands utilise LiteLLM pour les appels de complétion. Les ressources suivantes sont pertinentes pour utiliser OpenHands avec les LLMs de Google :
- [Gemini - Google AI Studio](https://docs.litellm.ai/docs/providers/gemini)
- [VertexAI - Google Cloud Platform](https://docs.litellm.ai/docs/providers/vertex)
### Configurations de Gemini - Google AI Studio
Pour utiliser Gemini via Google AI Studio lors de l'exécution de l'image Docker d'OpenHands, vous devez définir les variables d'environnement suivantes en utilisant `-e` :
```
GEMINI_API_KEY="<votre-cle-api-google>"
LLM_MODEL="gemini/gemini-1.5-pro"
```
### Configurations de Vertex AI - Google Cloud Platform
Pour utiliser Vertex AI via Google Cloud Platform lors de l'exécution de l'image Docker d'OpenHands, vous devez définir les variables d'environnement suivantes en utilisant `-e` :
```
GOOGLE_APPLICATION_CREDENTIALS="<dump-json-du-compte-de-service-gcp-json>"
VERTEXAI_PROJECT="<votre-id-de-projet-gcp>"
VERTEXAI_LOCATION="<votre-localisation-gcp>"
LLM_MODEL="vertex_ai/<modele-llm-desire>"
```

View File

@@ -0,0 +1,22 @@
# Groq
OpenHands utilise LiteLLM pour faire des appels aux modèles de chat sur Groq. Vous pouvez trouver leur documentation sur l'utilisation de Groq comme fournisseur [ici](https://docs.litellm.ai/docs/providers/groq).
## Configuration
Lorsque vous exécutez OpenHands, vous devrez définir les éléments suivants dans l'interface utilisateur d'OpenHands via les paramètres :
* `LLM Provider` à `Groq`
* `LLM Model` au modèle que vous utiliserez. [Visitez ici pour voir la liste des modèles hébergés par Groq](https://console.groq.com/docs/models). Si le modèle n'est pas dans la liste, activez les `Advanced Options` et entrez-le dans `Custom Model` (par exemple, groq/&lt;model-name&gt; comme `groq/llama3-70b-8192`).
* `API key` à votre clé API Groq. Pour trouver ou créer votre clé API Groq, [voir ici](https://console.groq.com/keys).
## Utilisation de Groq comme point de terminaison compatible OpenAI
Le point de terminaison Groq pour la complétion de chat est [principalement compatible OpenAI](https://console.groq.com/docs/openai). Par conséquent, vous pouvez accéder aux modèles Groq comme vous le feriez pour n'importe quel point de terminaison compatible OpenAI. Vous pouvez définir les éléments suivants dans l'interface utilisateur d'OpenHands via les paramètres :
* Activer les `Advanced Options`
* `Custom Model` au préfixe `openai/` + le modèle que vous utiliserez (par exemple, `openai/llama3-70b-8192`)
* `Base URL` à `https://api.groq.com/openai/v1`
* `API Key` à votre clé API Groq

View File

@@ -0,0 +1,22 @@
# Proxy LiteLLM
OpenHands prend en charge l'utilisation du [proxy LiteLLM](https://docs.litellm.ai/docs/proxy/quick_start) pour accéder à divers fournisseurs de LLM.
## Configuration
Pour utiliser le proxy LiteLLM avec OpenHands, vous devez :
1. Configurer un serveur proxy LiteLLM (voir la [documentation LiteLLM](https://docs.litellm.ai/docs/proxy/quick_start))
2. Lors de l'exécution d'OpenHands, vous devrez définir les éléments suivants dans l'interface utilisateur d'OpenHands via les paramètres :
* Activer les `Options avancées`
* `Custom Model` au préfixe `litellm_proxy/` + le modèle que vous utiliserez (par exemple, `litellm_proxy/anthropic.claude-3-5-sonnet-20241022-v2:0`)
* `Base URL` à l'URL de votre proxy LiteLLM (par exemple, `https://your-litellm-proxy.com`)
* `API Key` à votre clé API du proxy LiteLLM
## Modèles pris en charge
Les modèles pris en charge dépendent de la configuration de votre proxy LiteLLM. OpenHands prend en charge tous les modèles que votre proxy LiteLLM est configuré pour gérer.
Reportez-vous à la configuration de votre proxy LiteLLM pour obtenir la liste des modèles disponibles et leurs noms.

View File

@@ -0,0 +1,84 @@
# 🤖 Backends LLM
OpenHands peut se connecter à n'importe quel LLM supporté par LiteLLM. Cependant, il nécessite un modèle puissant pour fonctionner.
## Recommandations de modèles
Sur la base de nos évaluations des modèles de langage pour les tâches de codage (en utilisant le jeu de données SWE-bench), nous pouvons fournir quelques recommandations pour la sélection des modèles. Certaines analyses peuvent être trouvées dans [cet article de blog comparant les LLM](https://www.all-hands.dev/blog/evaluation-of-llms-as-coding-agents-on-swe-bench-at-30x-speed) et [cet article de blog avec des résultats plus récents](https://www.all-hands.dev/blog/openhands-codeact-21-an-open-state-of-the-art-software-development-agent).
Lors du choix d'un modèle, considérez à la fois la qualité des sorties et les coûts associés. Voici un résumé des résultats :
- Claude 3.5 Sonnet est le meilleur de loin, atteignant un taux de résolution de 53% sur SWE-Bench Verified avec l'agent par défaut dans OpenHands.
- GPT-4o est à la traîne, et o1-mini a en fait obtenu des performances légèrement inférieures à celles de GPT-4o. Nous avons analysé les résultats un peu, et brièvement, il semblait que o1 "réfléchissait trop" parfois, effectuant des tâches de configuration d'environnement supplémentaires alors qu'il aurait pu simplement aller de l'avant et terminer la tâche.
- Enfin, les modèles ouverts les plus puissants étaient Llama 3.1 405 B et deepseek-v2.5, et ils ont obtenu des performances raisonnables, surpassant même certains des modèles fermés.
Veuillez vous référer à [l'article complet](https://www.all-hands.dev/blog/evaluation-of-llms-as-coding-agents-on-swe-bench-at-30x-speed) pour plus de détails.
Sur la base de ces résultats et des commentaires de la communauté, il a été vérifié que les modèles suivants fonctionnent raisonnablement bien avec OpenHands :
- claude-3-5-sonnet (recommandé)
- gpt-4 / gpt-4o
- llama-3.1-405b
- deepseek-v2.5
:::warning
OpenHands enverra de nombreuses invites au LLM que vous configurez. La plupart de ces LLM sont payants, alors assurez-vous de définir des limites de dépenses et de surveiller l'utilisation.
:::
Si vous avez réussi à exécuter OpenHands avec des LLM spécifiques qui ne figurent pas dans la liste, veuillez les ajouter à la liste vérifiée. Nous vous encourageons également à ouvrir une PR pour partager votre processus de configuration afin d'aider les autres utilisant le même fournisseur et LLM !
Pour une liste complète des fournisseurs et des modèles disponibles, veuillez consulter la [documentation litellm](https://docs.litellm.ai/docs/providers).
:::note
La plupart des modèles locaux et open source actuels ne sont pas aussi puissants. Lors de l'utilisation de tels modèles, vous pouvez constater de longs temps d'attente entre les messages, des réponses médiocres ou des erreurs concernant du JSON mal formé. OpenHands ne peut être aussi puissant que les modèles qui le pilotent. Cependant, si vous en trouvez qui fonctionnent, veuillez les ajouter à la liste vérifiée ci-dessus.
:::
## Configuration LLM
Les éléments suivants peuvent être définis dans l'interface utilisateur d'OpenHands via les paramètres :
- `Fournisseur LLM`
- `Modèle LLM`
- `Clé API`
- `URL de base` (via `Paramètres avancés`)
Il existe certains paramètres qui peuvent être nécessaires pour certains LLM/fournisseurs et qui ne peuvent pas être définis via l'interface utilisateur. Au lieu de cela, ils peuvent être définis via des variables d'environnement passées à la [commande docker run](/modules/usage/installation#start-the-app) en utilisant `-e` :
- `LLM_API_VERSION`
- `LLM_EMBEDDING_MODEL`
- `LLM_EMBEDDING_DEPLOYMENT_NAME`
- `LLM_DROP_PARAMS`
- `LLM_DISABLE_VISION`
- `LLM_CACHING_PROMPT`
Nous avons quelques guides pour exécuter OpenHands avec des fournisseurs de modèles spécifiques :
- [Azure](llms/azure-llms)
- [Google](llms/google-llms)
- [Groq](llms/groq)
- [LiteLLM Proxy](llms/litellm-proxy)
- [OpenAI](llms/openai-llms)
- [OpenRouter](llms/openrouter)
### Nouvelles tentatives d'API et limites de débit
Les fournisseurs de LLM ont généralement des limites de débit, parfois très basses, et peuvent nécessiter de nouvelles tentatives. OpenHands réessaiera automatiquement les requêtes s'il reçoit une erreur de limite de débit (code d'erreur 429), une erreur de connexion API ou d'autres erreurs transitoires.
Vous pouvez personnaliser ces options selon vos besoins pour le fournisseur que vous utilisez. Consultez leur documentation et définissez les variables d'environnement suivantes pour contrôler le nombre de nouvelles tentatives et le temps entre les tentatives :
- `LLM_NUM_RETRIES` (Par défaut 8)
- `LLM_RETRY_MIN_WAIT` (Par défaut 15 secondes)
- `LLM_RETRY_MAX_WAIT` (Par défaut 120 secondes)
- `LLM_RETRY_MULTIPLIER` (Par défaut 2)
Si vous exécutez OpenHands en mode développement, vous pouvez également définir ces options dans le fichier `config.toml` :
```toml
[llm]
num_retries = 8
retry_min_wait = 15
retry_max_wait = 120
retry_multiplier = 2
```

View File

@@ -0,0 +1,193 @@
# LLM local avec Ollama
:::warning
Lors de l'utilisation d'un LLM local, OpenHands peut avoir des fonctionnalités limitées.
:::
Assurez-vous que le serveur Ollama est opérationnel.
Pour des instructions détaillées sur le démarrage, référez-vous à [ici](https://github.com/ollama/ollama).
Ce guide suppose que vous avez démarré ollama avec `ollama serve`. Si vous exécutez ollama différemment (par exemple dans docker), les instructions peuvent nécessiter des modifications. Veuillez noter que si vous utilisez WSL, la configuration par défaut d'ollama bloque les requêtes provenant des conteneurs docker. Voir [ici](#configuring-ollama-service-wsl-fr).
## Récupérer les modèles
Les noms des modèles Ollama peuvent être trouvés [ici](https://ollama.com/library). Pour un petit exemple, vous pouvez utiliser le modèle `codellama:7b`. Les modèles plus gros auront généralement de meilleures performances.
```bash
ollama pull codellama:7b
```
Vous pouvez vérifier quels modèles vous avez téléchargés comme ceci :
```bash
~$ ollama list
NAME ID SIZE MODIFIED
codellama:7b 8fdf8f752f6e 3.8 GB 6 weeks ago
mistral:7b-instruct-v0.2-q4_K_M eb14864c7427 4.4 GB 2 weeks ago
starcoder2:latest f67ae0f64584 1.7 GB 19 hours ago
```
## Exécuter OpenHands avec Docker
### Démarrer OpenHands
Utilisez les instructions [ici](../getting-started) pour démarrer OpenHands en utilisant Docker.
Mais lorsque vous exécutez `docker run`, vous devrez ajouter quelques arguments supplémentaires :
```bash
docker run # ...
--add-host host.docker.internal:host-gateway \
-e LLM_OLLAMA_BASE_URL="http://host.docker.internal:11434" \
# ...
```
LLM_OLLAMA_BASE_URL est optionnel. Si vous le définissez, il sera utilisé pour afficher
les modèles installés disponibles dans l'interface utilisateur.
### Configurer l'application Web
Lors de l'exécution d'`openhands`, vous devrez définir les éléments suivants dans l'interface utilisateur d'OpenHands via les paramètres :
- le modèle à "ollama/&lt;nom-du-modèle&gt;"
- l'URL de base à `http://host.docker.internal:11434`
- la clé API est optionnelle, vous pouvez utiliser n'importe quelle chaîne, comme `ollama`.
## Exécuter OpenHands en mode développement
### Compiler à partir du code source
Utilisez les instructions dans [Development.md](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md) pour compiler OpenHands.
Assurez-vous que `config.toml` est présent en exécutant `make setup-config` qui en créera un pour vous. Dans `config.toml`, entrez ce qui suit :
```
[core]
workspace_base="./workspace"
[llm]
embedding_model="local"
ollama_base_url="http://localhost:11434"
```
Terminé ! Vous pouvez maintenant démarrer OpenHands avec : `make run`. Vous devriez maintenant pouvoir vous connecter à `http://localhost:3000/`
### Configurer l'application Web
Dans l'interface utilisateur d'OpenHands, cliquez sur la roue des paramètres dans le coin inférieur gauche.
Ensuite, dans le champ `Model`, entrez `ollama/codellama:7b`, ou le nom du modèle que vous avez récupéré précédemment.
S'il n'apparaît pas dans la liste déroulante, activez `Advanced Settings` et tapez-le. Veuillez noter : vous avez besoin du nom du modèle tel qu'il est listé par `ollama list`, avec le préfixe `ollama/`.
Dans le champ API Key, entrez `ollama` ou n'importe quelle valeur, puisque vous n'avez pas besoin d'une clé particulière.
Dans le champ Base URL, entrez `http://localhost:11434`.
Et maintenant vous êtes prêt à démarrer !
## Configurer le service ollama (WSL) {#configuring-ollama-service-wsl-fr}
La configuration par défaut d'ollama dans WSL ne sert que localhost. Cela signifie que vous ne pouvez pas y accéder depuis un conteneur docker. Par ex. cela ne fonctionnera pas avec OpenHands. Testons d'abord qu'ollama fonctionne correctement.
```bash
ollama list # obtenir la liste des modèles installés
curl http://localhost:11434/api/generate -d '{"model":"[NOM]","prompt":"hi"}'
#ex. curl http://localhost:11434/api/generate -d '{"model":"codellama:7b","prompt":"hi"}'
#ex. curl http://localhost:11434/api/generate -d '{"model":"codellama","prompt":"hi"}' #le tag est optionnel s'il n'y en a qu'un
```
Une fois cela fait, testez qu'il autorise les requêtes "extérieures", comme celles provenant d'un conteneur docker.
```bash
docker ps # obtenir la liste des conteneurs docker en cours d'exécution, pour un test plus précis choisissez le conteneur sandbox OpenHands.
docker exec [ID CONTENEUR] curl http://host.docker.internal:11434/api/generate -d '{"model":"[NOM]","prompt":"hi"}'
#ex. docker exec cd9cc82f7a11 curl http://host.docker.internal:11434/api/generate -d '{"model":"codellama","prompt":"hi"}'
```
## Résoudre le problème
Maintenant, faisons en sorte que cela fonctionne. Modifiez /etc/systemd/system/ollama.service avec des privilèges sudo. (Le chemin peut varier selon la distribution Linux)
```bash
sudo vi /etc/systemd/system/ollama.service
```
ou
```bash
sudo nano /etc/systemd/system/ollama.service
```
Dans le bloc [Service], ajoutez ces lignes
```
Environment="OLLAMA_HOST=0.0.0.0:11434"
Environment="OLLAMA_ORIGINS=*"
```
Ensuite, sauvegardez, rechargez la configuration et redémarrez le service.
```bash
sudo systemctl daemon-reload
sudo systemctl restart ollama
```
Enfin, testez qu'ollama est accessible depuis le conteneur
```bash
ollama list # obtenir la liste des modèles installés
docker ps # obtenir la liste des conteneurs docker en cours d'exécution, pour un test plus précis choisissez le conteneur sandbox OpenHands.
docker exec [ID CONTENEUR] curl http://host.docker.internal:11434/api/generate -d '{"model":"[NOM]","prompt":"hi"}'
```
# LLM local avec LM Studio
Étapes pour configurer LM Studio :
1. Ouvrez LM Studio
2. Allez dans l'onglet Serveur local.
3. Cliquez sur le bouton "Démarrer le serveur".
4. Sélectionnez le modèle que vous souhaitez utiliser dans la liste déroulante.
Définissez les configurations suivantes :
```bash
LLM_MODEL="openai/lmstudio"
LLM_BASE_URL="http://localhost:1234/v1"
CUSTOM_LLM_PROVIDER="openai"
```
### Docker
```bash
docker run # ...
-e LLM_MODEL="openai/lmstudio" \
-e LLM_BASE_URL="http://host.docker.internal:1234/v1" \
-e CUSTOM_LLM_PROVIDER="openai" \
# ...
```
Vous devriez maintenant pouvoir vous connecter à `http://localhost:3000/`
Dans l'environnement de développement, vous pouvez définir les configurations suivantes dans le fichier `config.toml` :
```
[core]
workspace_base="./workspace"
[llm]
model="openai/lmstudio"
base_url="http://localhost:1234/v1"
custom_llm_provider="openai"
```
Terminé ! Vous pouvez maintenant démarrer OpenHands avec : `make run` sans Docker. Vous devriez maintenant pouvoir vous connecter à `http://localhost:3000/`
# Note
Pour WSL, exécutez les commandes suivantes dans cmd pour configurer le mode réseau en miroir :
```
python -c "print('[wsl2]\nnetworkingMode=mirrored',file=open(r'%UserProfile%\.wslconfig','w'))"
wsl --shutdown
```

View File

@@ -0,0 +1,141 @@
# LLM Local avec Ollama
Assurez-vous que le serveur Ollama est en cours d'exécution.
Pour des instructions détaillées de démarrage, consultez [ici](https://github.com/ollama/ollama)
Ce guide suppose que vous avez démarré ollama avec `ollama serve`. Si vous exécutez ollama différemment (par exemple, à l'intérieur de docker), les instructions pourraient devoir être modifiées. Veuillez noter que si vous utilisez WSL, la configuration par défaut de ollama bloque les requêtes des conteneurs docker. Voir [ici](#configuring-ollama-service-fr).
## Télécharger des modèles
Les noms des modèles Ollama peuvent être trouvés [ici](https://ollama.com/library). Pour un petit exemple, vous pouvez utiliser
le modèle `codellama:7b`. Des modèles plus grands offriront généralement de meilleures performances.
```bash
ollama pull codellama:7b
```
vous pouvez vérifier quels modèles vous avez téléchargés de cette manière :
```bash
~$ ollama list
NAME ID SIZE MODIFIED
codellama:7b 8fdf8f752f6e 3.8 GB 6 weeks ago
mistral:7b-instruct-v0.2-q4_K_M eb14864c7427 4.4 GB 2 weeks ago
starcoder2:latest f67ae0f64584 1.7 GB 19 hours ago
```
## Démarrer OpenHands
### Docker
Utilisez les instructions [ici](../intro) pour démarrer OpenHands en utilisant Docker.
Mais lors de l'exécution de `docker run`, vous devrez ajouter quelques arguments supplémentaires :
```bash
--add-host host.docker.internal:host-gateway \
-e LLM_API_KEY="ollama" \
-e LLM_BASE_URL="http://host.docker.internal:11434" \
```
Par exemple :
```bash
# Le répertoire que vous souhaitez qu'OpenHands modifie. DOIT être un chemin absolu !
export WORKSPACE_BASE=$(pwd)/workspace
docker run \
-it \
--pull=always \
--add-host host.docker.internal:host-gateway \
-e SANDBOX_USER_ID=$(id -u) \
-e LLM_API_KEY="ollama" \
-e LLM_BASE_URL="http://host.docker.internal:11434" \
-e WORKSPACE_MOUNT_PATH=$WORKSPACE_BASE \
-v $WORKSPACE_BASE:/opt/workspace_base \
-v /var/run/docker.sock:/var/run/docker.sock \
-p 3000:3000 \
ghcr.io/all-hands-ai/openhands:main
```
Vous devriez maintenant pouvoir vous connecter à `http://localhost:3000/`
### Compiler à partir des sources
Utilisez les instructions dans [Development.md](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md) pour compiler OpenHands.
Assurez-vous que `config.toml` soit présent en exécutant `make setup-config` qui en créera un pour vous. Dans `config.toml`, saisissez les éléments suivants :
```
LLM_MODEL="ollama/codellama:7b"
LLM_API_KEY="ollama"
LLM_EMBEDDING_MODEL="local"
LLM_BASE_URL="http://localhost:11434"
WORKSPACE_BASE="./workspace"
WORKSPACE_DIR="$(pwd)/workspace"
```
Remplacez `LLM_MODEL` par celui de votre choix si nécessaire.
Fini ! Vous pouvez maintenant démarrer OpenHands avec : `make run` sans Docker. Vous devriez maintenant pouvoir vous connecter à `http://localhost:3000/`
## Sélection de votre modèle
Dans l'interface OpenHands, cliquez sur l'icône des paramètres en bas à gauche.
Ensuite, dans l'entrée `Model`, saisissez `ollama/codellama:7b`, ou le nom du modèle que vous avez téléchargé précédemment.
S'il n'apparaît pas dans un menu déroulant, ce n'est pas grave, tapez-le simplement. Cliquez sur Enregistrer lorsque vous avez terminé.
Et maintenant, vous êtes prêt à démarrer !
## Configuration du service ollama (WSL){#configuring-ollama-service-fr}
La configuration par défaut pour ollama sous WSL ne sert que localhost. Cela signifie que vous ne pouvez pas l'atteindre depuis un conteneur docker, par exemple, il ne fonctionnera pas avec OpenHands. Testons d'abord que ollama est en cours d'exécution correctement.
```bash
ollama list # obtenir la liste des modèles installés
curl http://localhost:11434/api/generate -d '{"model":"[NAME]","prompt":"hi"}'
#ex. curl http://localhost:11434/api/generate -d '{"model":"codellama:7b","prompt":"hi"}'
#ex. curl http://localhost:11434/api/generate -d '{"model":"codellama","prompt":"hi"}' #le tag est optionnel s'il n'y en a qu'un seul
```
Une fois cela fait, testez qu'il accepte les requêtes "externes", comme celles provenant d'un conteneur docker.
```bash
docker ps # obtenir la liste des conteneurs docker en cours d'exécution, pour un test le plus précis choisissez le conteneur de sandbox OpenHands.
docker exec [CONTAINER ID] curl http://host.docker.internal:11434/api/generate -d '{"model":"[NAME]","prompt":"hi"}'
#ex. docker exec cd9cc82f7a11 curl http://host.docker.internal:11434/api/generate -d '{"model":"codellama","prompt":"hi"}'
```
## Correction
Maintenant faisons en sorte que cela fonctionne. Modifiez /etc/systemd/system/ollama.service avec les privilèges sudo. (Le chemin peut varier selon la distribution Linux)
```bash
sudo vi /etc/systemd/system/ollama.service
```
ou
```bash
sudo nano /etc/systemd/system/ollama.service
```
Dans la section [Service], ajoutez ces lignes
```
Environment="OLLAMA_HOST=0.0.0.0:11434"
Environment="OLLAMA_ORIGINS=*"
```
Ensuite, sauvegardez, rechargez la configuration et redémarrez le service.
```bash
sudo systemctl daemon-reload
sudo systemctl restart ollama
```
Enfin, testez que ollama est accessible depuis le conteneur
```bash
ollama list # obtenir la liste des modèles installés
docker ps # obtenir la liste des conteneurs docker en cours d'exécution, pour un test le plus précis choisissez le conteneur de sandbox OpenHands.
docker exec [CONTAINER ID] curl http://host.docker.internal:11434/api/generate -d '{"model":"[NAME]","prompt":"hi"}'
```

View File

@@ -0,0 +1,26 @@
# OpenAI
OpenHands utilise LiteLLM pour effectuer des appels aux modèles de chat d'OpenAI. Vous pouvez trouver leur documentation sur l'utilisation d'OpenAI en tant que fournisseur [ici](https://docs.litellm.ai/docs/providers/openai).
## Configuration
Lors de l'exécution d'OpenHands, vous devrez définir les éléments suivants dans l'interface utilisateur d'OpenHands via les paramètres :
* `LLM Provider` à `OpenAI`
* `LLM Model` au modèle que vous utiliserez.
[Visitez ce lien pour voir une liste complète des modèles OpenAI pris en charge par LiteLLM.](https://docs.litellm.ai/docs/providers/openai#openai-chat-completion-models)
Si le modèle ne figure pas dans la liste, activez les `Advanced Options` et entrez-le dans `Custom Model` (par exemple, openai/&lt;model-name&gt; comme `openai/gpt-4o`).
* `API Key` à votre clé API OpenAI. Pour trouver ou créer votre clé API de projet OpenAI, [voir ici](https://platform.openai.com/api-keys).
## Utilisation des endpoints compatibles OpenAI
Tout comme pour les chat completions OpenAI, nous utilisons LiteLLM pour les endpoints compatibles OpenAI. Vous pouvez trouver leur documentation complète sur ce sujet [ici](https://docs.litellm.ai/docs/providers/openai_compatible).
## Utilisation d'un proxy OpenAI
Si vous utilisez un proxy OpenAI, vous devrez définir les éléments suivants dans l'interface utilisateur d'OpenHands via les paramètres :
* Activer les `Advanced Options`
* `Custom Model` à openai/&lt;model-name&gt; (par exemple, `openai/gpt-4o` ou openai/&lt;proxy-prefix&gt;/&lt;model-name&gt;)
* `Base URL` à l'URL de votre proxy OpenAI
* `API Key` à votre clé API OpenAI

View File

@@ -0,0 +1,14 @@
# OpenRouter
OpenHands utilise LiteLLM pour effectuer des appels aux modèles de chat sur OpenRouter. Vous pouvez trouver leur documentation sur l'utilisation d'OpenRouter en tant que fournisseur [ici](https://docs.litellm.ai/docs/providers/openrouter).
## Configuration
Lors de l'exécution d'OpenHands, vous devrez définir les éléments suivants dans l'interface utilisateur d'OpenHands via les paramètres :
* `LLM Provider` à `OpenRouter`
* `LLM Model` au modèle que vous utiliserez.
[Visitez ici pour voir une liste complète des modèles OpenRouter](https://openrouter.ai/models).
Si le modèle ne figure pas dans la liste, activez `Advanced Options`, et entrez-le dans `Custom Model` (par exemple openrouter/&lt;model-name&gt; comme `openrouter/anthropic/claude-3.5-sonnet`).
* `API Key` à votre clé API OpenRouter.

Some files were not shown because too many files have changed in this diff Show More