Compare commits

...

44 Commits
0.4.0 ... 0.4.1

Author SHA1 Message Date
Aleksandar
5989853f7a Fix duplicate LLM_BASE_URL entry in config.toml and enable different ollama embeddings (#1437)
Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
2024-04-30 02:26:02 +02:00
Xingyao Wang
fe8bb51f17 Update debug instruction for SSH Box (#1425)
* update debug instruction for sshbox

* fix typo

---------

Co-authored-by: Robert Brennan <accounts@rbren.io>
2024-04-29 20:09:56 -04:00
Jirka Borovec
0c2ebfd6e1 Ruff: use I rule for isort (#1410)
Ruff: use I rule for isort
2024-04-29 15:41:58 -07:00
Xia Zhenhua
086a2ed17f feat: make the response of agent_controller better to process when exception in step execution (#1445)
* feat: make the response of agent_controller better to process when exception occurred during executing step.

* Update opendevin/controller/agent_controller.py

---------

Co-authored-by: aaren.xzh <aaren.xzh@antfin.com>
Co-authored-by: Robert Brennan <accounts@rbren.io>
2024-04-29 21:21:26 +00:00
Alex Bäuerle
fa067edbac feat: set API key from settings modal (#1319)
* feat: set API key from settings modal

* feat: init with api key

* test

* fix

* fixes

* fix api key reference

* test

* minor fixes

* fix settings update

* combine settings call

---------

Co-authored-by: Robert Brennan <accounts@rbren.io>
Co-authored-by: sp.wack <83104063+amanape@users.noreply.github.com>
2024-04-29 23:18:00 +03:00
Robert Brennan
11d48cc2f3 Run docker on forked pull requests (#1450)
* build docker on pull request

* run docker build on PRs

* remove if

* add permissions

* change ghcr login

* empty commit

* always use opendevin as org

* lowercase

* no client token

* dont push on forks

* remove env

* only cache-to if pushing

* fix org name

* fix owner

* Update containers/build.sh

Co-authored-by: Graham Neubig <neubig@gmail.com>

* lowercase

* remove tag prefix

* lowercase

---------

Co-authored-by: Graham Neubig <neubig@gmail.com>
2024-04-29 14:24:28 -04:00
Graham Neubig
c821d0967c Point docker errors to troubleshooting doc (#1453) 2024-04-29 18:21:55 +00:00
Alex Bäuerle
b47fdbb23b docs(readme): remove demo video (#1455)
The demo video is included in our homepage now. If we're linking to a video file local to the repository from the README, it does not get displayed. Instead, there is just a link to it. I don't think it's a good idea to always have to update both the readme video and the website video, so I am removing the readme video.
2024-04-29 11:09:48 -07:00
Alex Bäuerle
b3930ad195 ci: fix deploy config (#1454) 2024-04-29 17:28:30 +00:00
Alex Bäuerle
cd58194d2a docs(docs): start implementing docs website (#1372)
* docs(docs): start implementing docs website

* update video url

* add autogenerated codebase docs for backend

* precommit

* update links

* fix config and video

* gh actions

* rename

* workdirs

* path

* path

* fix doc1

* redo markdown

* docs

* change main folder name

* simplify readme

* add back architecture

* Fix lint errors

* lint

* update poetry lock

---------

Co-authored-by: Jim Su <jimsu@protonmail.com>
2024-04-29 10:00:51 -07:00
Jirka Borovec
46bd83678a precommit: add pyproject's hooks (#1412)
* precommit: add `pyproject`'s hooks

* apply precommit

* Update dev_config/python/.pre-commit-config.yaml

---------

Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
Co-authored-by: Robert Brennan <accounts@rbren.io>
2024-04-29 14:58:21 +00:00
sp.wack
1597f0093e fix custom llm model value not displaying (#1447) 2024-04-29 10:46:39 -04:00
sp.wack
c02b681728 update chat input tests to expect new behaviour (#1443) 2024-04-29 10:37:33 -04:00
Boxuan Li
319b9ac0f3 Fix micro-agents schema bug (#1424)
* Fix micro agents definitions

* Add tests for micro agents

* Add to CI

* Revert "Add to CI"

This reverts commit 94f3b4e7c8.

* Remove test artifacts for ManagerAgent

---------

Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
2024-04-29 10:34:03 -04:00
Jirka Borovec
5a9b6b0c9f precommit: remove unused setup-cfg-fmt (#1411) 2024-04-29 10:33:50 -04:00
Boxuan Li
a5a1545c59 Add Codecov test coverage (#1397)
* Add pytest-cov dependency

* Add codecov to unit test CI

* Codecov: Use secrets

* Add codecov for integration tests
2024-04-29 10:33:13 -04:00
Arno.Edwards
03ecec1e76 ci: refine job matrix and enable cache for poetry (#1381)
* ci: refine job matrix and enable cache for poetry

- Replace direct installation of Poetry with pipx to ensure isolated environment setups.
- Enable caching for Poetry dependencies using setup-python action to improve build efficiency.
- Refactor the job matrix specifications.

* ci: enable Homebrew caching in Actions

* ci: optimize Docker and Colima installation in GitHub Actions

- Check if Docker and Colima are already installed before attempting to install them. Link and start each service appropriately to avoid unnecessary reinstallation and ensure they are ready for immediate use in the CI pipeline.

* ci: remove Homebrew cache.

* fix typo

* fix: specified the Python version to avoid errors in actions.

---------

Co-authored-by: Robert Brennan <accounts@rbren.io>
Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
2024-04-29 10:32:25 -04:00
sp.wack
8954855ba3 refactor(frontend): settings and friends (#1400)
* refactor settings and friends

* extend base modal to support disabled property

* extend settings handler to change language via i18next

* remove unused settings.d.ts

---------

Co-authored-by: Jim Su <jimsu@protonmail.com>
Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
2024-04-28 21:59:26 -04:00
Christian Balcom
24b71927c3 fix(backend) changes to improve Command-R+ behavior, plus file i/o error improvements, attempt 2 (#1417)
* Some improvements to prompts, some better exception handling for various file IO errors, added timeout and max return token configurations for the LLM api.

* More monologue prompt improvements

* Dynamically set username provided in prompt.

* Remove absolute paths from llm prompts, fetch working directory from sandbox when resolving paths in fileio operations, add customizable timeout for bash commands, mention said timeout in llm prompt.

* Switched ssh_box to disabling tty echo and removed the logic attempting to delete it from the response afterwards, fixed get_working_directory for ssh_box.

* Update prompts in integration tests to match monologue agent changes.

* Minor tweaks to make merge easier.

* Another minor prompt tweak, better invalid json handling.

* Fix lint error

* More catch-up to fix lint errors introduced by merge.

* Force WORKSPACE_MOUNT_PATH_IN_SANDBOX to match WORKSPACE_MOUNT_PATH in local sandbox mode, combine exception handlers in prompts.py.

---------

Co-authored-by: Jim Su <jimsu@protonmail.com>
Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
2024-04-28 21:58:53 -04:00
Graham Neubig
a5f61caae9 Add actions for github push and send PR (#1415)
* Added a push action

* Tests

* Add tests

* Fix capitalization

* Update

* Fix typo

* Fix integration tests

* Added poetry.lock

* Set lock

* Fix action parsing

* Update integration test output

* Updated prompt

* Update integration test

* Add github token to default config

---------

Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
2024-04-29 00:56:23 +00:00
Graham Neubig
0d224de369 Fixed typo in integration tests README.md (#1438)
* Fixed typo in integration tests README.md

* Update tests/integration/README.md

---------

Co-authored-by: ThoughtfulRobot <robot@example.com>
Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
2024-04-28 20:44:58 -04:00
Graham Neubig
567e2c2b35 Add poetry install to makefile (#1436) 2024-04-28 22:40:37 +01:00
Xingyao Wang
a7e42ff0a3 allow interaction with local box (#1429) 2024-04-28 23:24:01 +08:00
Robert Brennan
d1f62bb6be Add final step for matrix tests, some cleanup (#1408)
* add final step for matrix tests

* change test names

* add names

* change run conditions

* fix test names
2024-04-27 14:34:07 -04:00
Robert Brennan
9c9aee29f0 Revert "fix(backend) changes to improve Command-R+ behavior, plus file i/o er…" (#1405)
This reverts commit 44aea95dde.
2024-04-27 08:57:04 -04:00
sp.wack
d8386366d9 feature(frontend): improve chat overflow handling and syntax highlighting (#1402)
* improve overflow handling and syntax highlighting

* add reference to gh page
2024-04-27 08:21:29 -04:00
Engel Nyst
ca73ecb499 message in setup-config about model (#1398) 2024-04-27 08:19:31 -04:00
Leo
6f90239521 Fix: enable input but don't be allowed to submit when agent init (#1353)
* Fix: enable input but don't be allowed to submit when agent initializing.

* Prevent Enter from adding a newline when disabled.

---------

Co-authored-by: Jim Su <jimsu@protonmail.com>
Co-authored-by: Robert Brennan <accounts@rbren.io>
2024-04-27 12:17:58 +00:00
Christian Balcom
546be7ca8e Handle Unicode errors (#1388)
* Add errors for non-unicode file data or command return, trim excessively long command returns.

* Fix lint issue.

* Fix lint issue (try 2).

* Realized that prompts were trimmed elsewhere and dropped the new addition.
2024-04-27 08:15:16 -04:00
Robert Brennan
ce47461c5a disable host network (#1404) 2024-04-27 08:07:25 -04:00
Christian Balcom
44aea95dde fix(backend) changes to improve Command-R+ behavior, plus file i/o error improvements. (#1347)
* Some improvements to prompts, some better exception handling for various file IO errors, added timeout and max return token configurations for the LLM api.

* More monologue prompt improvements

* Dynamically set username provided in prompt.

* Remove absolute paths from llm prompts, fetch working directory from sandbox when resolving paths in fileio operations, add customizable timeout for bash commands, mention said timeout in llm prompt.

* Switched ssh_box to disabling tty echo and removed the logic attempting to delete it from the response afterwards, fixed get_working_directory for ssh_box.

* Update prompts in integration tests to match monologue agent changes.

* Minor tweaks to make merge easier.

* Another minor prompt tweak, better invalid json handling.

* Fix lint error

* More catch-up to fix lint errors introduced by merge.

---------

Co-authored-by: Jim Su <jimsu@protonmail.com>
Co-authored-by: Robert Brennan <accounts@rbren.io>
2024-04-27 11:58:34 +00:00
Jirka Borovec
e32d95cb1a lint: simplify hooks already covered by Ruff (#1204)
* lint: simplify hooks already covered by Ruff

* prune dev dependency

* setting E, W, F

* poetry?

* autopep8

* quote-style = "single"

* double-quote-string-fixer

* --all-files

* apply

* Q

* drop double-quote-string-fixer

* --all-files

* apply pre-commit

* python3.11 -m poetry lock --no-update

---------

Co-authored-by: Robert Brennan <accounts@rbren.io>
2024-04-27 11:32:14 +00:00
Boxuan Li
7d5856e36b local sandbox: Create workspace base during init (#1377) 2024-04-27 11:50:58 +08:00
Robert Brennan
fd9e598136 add options for controlling memory (#1364)
* add options for controlling memory

* Update agenthub/monologue_agent/utils/memory.py

Co-authored-by: Jim Su <jimsu@protonmail.com>

* move memory initialization switch back

* fix lint

* fix type

---------

Co-authored-by: Jim Su <jimsu@protonmail.com>
2024-04-26 21:53:54 +00:00
Jim Su
c0adb55bfa Fix mock server (#1392) 2024-04-26 17:16:29 -04:00
Alex Bäuerle
e9a9186717 build(backend): change reload to ignore workspace correctly (#1393)
Co-authored-by: Jim Su <jimsu@protonmail.com>
2024-04-26 18:19:18 +00:00
Jim Su
93d8ee1400 Render messages in markdown (#1391) 2024-04-26 14:05:17 -04:00
Boxuan Li
831e934dab Refactor: Use enum for config keys (#1376) 2024-04-26 10:26:01 -04:00
Engel Nyst
5a0ef2b5de Doc: update Azure guide with setting model in the UI (#1386)
* Update AzureLLMs.md

Add note about saving the actual model in the UI.

* Update AzureLLMs.md

Add note about saving the actual value in the UI.
2024-04-26 09:17:06 -04:00
sp.wack
0fb3d63406 fix/improve terminal hook (#1371) 2024-04-25 19:13:42 -04:00
Alex Bäuerle
65558df1f7 feat(frontend): multiple design changes (#1370) 2024-04-25 14:24:05 -07:00
Robert Brennan
5515c08624 update to 0.4.0 (#1362)
Co-authored-by: Jim Su <jimsu@protonmail.com>
2024-04-25 19:27:25 +00:00
Robert Brennan
f407382a5a handle IsADirectory errors (#1365) 2024-04-25 15:15:06 -04:00
Xingyao Wang
110e7f0c4c make WORKSPACE_MOUNT_PATH as abspath (#1361) 2024-04-25 13:31:05 -04:00
271 changed files with 23302 additions and 2648 deletions

2
.gitattributes vendored
View File

@@ -1 +1 @@
*.ipynb linguist-vendored
*.ipynb linguist-vendored

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

@@ -0,0 +1,55 @@
name: Deploy Docs to GitHub Pages
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
build:
name: Build Docusaurus
runs-on: ubuntu-latest
defaults:
run:
working-directory: docs
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 18
cache: npm
cache-dependency-path: docs/package-lock.json
- name: Install dependencies
run: npm ci
- name: Build website
run: npm run build
- name: Upload Build Artifact
if: github.ref == 'refs/heads/main'
uses: actions/upload-pages-artifact@v3
with:
path: docs/build
deploy:
name: Deploy to GitHub Pages
needs: build
if: github.ref == 'refs/heads/main'
# 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 }}
runs-on: ubuntu-latest
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4

View File

@@ -2,6 +2,9 @@ name: Publish Docker Image
on:
push:
branches:
- main
pull_request:
workflow_dispatch:
inputs:
reason:
@@ -12,7 +15,11 @@ on:
jobs:
ghcr_build_and_push:
runs-on: ubuntu-latest
if: github.event_name == 'push' || github.event.inputs.reason != ''
permissions:
contents: read
packages: write
strategy:
matrix:
image: ["app", "evaluation", "sandbox"]
@@ -28,13 +35,29 @@ jobs:
id: buildx
uses: docker/setup-buildx-action@v3
- name: Log-in to ghcr.io
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
- name: Login to ghcr
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Delete huge unnecessary tools folder
run: rm -rf /opt/hostedtoolcache
- name: Build and push ${{ matrix.image }}
if: github.event.pull_request.head.repo.full_name == github.repository
run: |
ORG_NAME=$(echo "${{ github.repository }}" | tr '[A-Z]' '[a-z]' | cut -d '/' -f 1)
./containers/build.sh ${{ matrix.image }} $ORG_NAME --push
./containers/build.sh ${{ matrix.image }} ${{ github.repository_owner }} --push
- name: Build ${{ matrix.image }}
if: github.event.pull_request.head.repo.full_name != github.repository
run: |
./containers/build.sh ${{ matrix.image }} ${{ github.repository_owner }}
docker_build_success:
name: Docker Build Success
runs-on: ubuntu-latest
needs: ghcr_build_and_push
steps:
- run: echo Done!

View File

@@ -1,9 +1,14 @@
name: Lint
on: [push, pull_request]
on:
push:
branches:
- main
pull_request:
jobs:
lint-frontend:
name: Lint frontend
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@@ -32,7 +37,12 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: 3.11
cache: 'pip'
- name: Install pre-commit
run: pip install pre-commit==3.7.0
- name: Run pre-commit hooks
run: pre-commit run --files opendevin/**/* agenthub/**/* --show-diff-on-failure --config ./dev_config/python/.pre-commit-config.yaml
run: |
pre-commit run \
--all-files \
--show-diff-on-failure \
--config ./dev_config/python/.pre-commit-config.yaml

View File

@@ -1,63 +1,52 @@
name: Run Integration Tests
on: [push, pull_request]
on:
push:
branches:
- main
pull_request:
jobs:
on-linux:
integration-tests:
name: Integration Tests
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.11"]
agent: ["SWEAgent", "PlannerAgent", "MonologueAgent", "CodeActAgent"]
sandbox: ["ssh", "exec"]
include:
- name: SWEAgent-py311-ssh
python-version: "3.11"
agent: "SWEAgent"
embedding-model: "none"
sandbox: "ssh"
- name: PlannerAgent-py311-ssh
python-version: "3.11"
agent: "PlannerAgent"
embedding-model: "none"
sandbox: "ssh"
- name: MonologueAgent-py311-ssh
python-version: "3.11"
agent: "MonologueAgent"
- agent: "MonologueAgent"
embedding-model: "local"
sandbox: "ssh"
- name: CodeActAgent-py311-ssh
python-version: "3.11"
agent: "CodeActAgent"
embedding-model: "none"
sandbox: "ssh"
- name: SWEAgent-py311-exec
python-version: "3.11"
agent: "SWEAgent"
embedding-model: "none"
sandbox: "exec"
- name: PlannerAgent-py311-exec
python-version: "3.11"
agent: "PlannerAgent"
embedding-model: "none"
sandbox: "exec"
- name: MonologueAgent-py311-exec
python-version: "3.11"
agent: "MonologueAgent"
- agent: "MonologueAgent"
# sufficient to have one agent testing against local sandbox
sandbox: "local"
embedding-model: "local"
sandbox: "exec"
- name: CodeActAgent-py311-exec
python-version: "3.11"
agent: "CodeActAgent"
- agent: "SWEAgent"
embedding-model: "none"
- agent: "PlannerAgent"
embedding-model: "none"
- agent: "CodeActAgent"
embedding-model: "none"
sandbox: "exec"
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
- name: Install poetry via pipx
run: pipx install poetry
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install Poetry
run: curl -sSL https://install.python-poetry.org | python3 -
python-version: '3.11'
cache: 'poetry'
- name: Install Python dependencies using Poetry
run: poetry install
- name: Build Environment
run: make build
- name: Run Integration Tests
env:
SANDBOX_TYPE: ${{ matrix.sandbox }}
@@ -67,4 +56,17 @@ jobs:
run: |
rm -rf workspace
mkdir workspace
WORKSPACE_BASE="$GITHUB_WORKSPACE/workspace" WORKSPACE_MOUNT_PATH="$GITHUB_WORKSPACE/workspace" poetry run pytest -s ./tests/integration
WORKSPACE_BASE="$GITHUB_WORKSPACE/workspace" \
WORKSPACE_MOUNT_PATH="$GITHUB_WORKSPACE/workspace" \
poetry run pytest --cov=agenthub --cov=opendevin --cov-report=xml \
-s ./tests/integration
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
test_matrix_success:
name: All Integration Tests Passed
runs-on: ubuntu-latest
needs: [integration-tests]
steps:
- run: echo Done!

View File

@@ -1,9 +1,14 @@
name: Run Unit Tests
on: [push, pull_request]
on:
push:
branches:
- main
pull_request:
jobs:
on-macos:
test-on-macos:
name: Test on macOS
runs-on: macos-13
strategy:
matrix:
@@ -11,23 +16,35 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Install poetry via pipx
run: pipx install poetry
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'poetry'
- name: Install Python dependencies using Poetry
run: poetry install
- name: Install & Start Docker
run: |
brew install colima docker
colima start
- name: Install and configure Poetry
uses: snok/install-poetry@v1
with:
version: latest
- name: Build Environment
run: make build
- name: Run Tests
run: poetry run pytest ./tests/unit
on-linux:
run: poetry run pytest --cov=agenthub --cov=opendevin --cov-report=xml ./tests/unit
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
test-on-linux:
name: Test on Linux
runs-on: ubuntu-latest
strategy:
matrix:
@@ -35,13 +52,31 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
- name: Install poetry via pipx
run: pipx install poetry
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install Poetry
run: curl -sSL https://install.python-poetry.org | python3 -
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 ./tests/unit
run: poetry run pytest --cov=agenthub --cov=opendevin --cov-report=xml ./tests/unit
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
test_matrix_success:
name: All Mac/Linux Tests Passed
runs-on: ubuntu-latest
needs: [test-on-macos, test-on-linux]
steps:
- run: echo Done!

View File

@@ -128,6 +128,7 @@ install-python-dependencies:
poetry run pip install chroma-hnswlib; \
fi
@poetry install --without evaluation
@poetry run playwright install --with-deps chromium
@echo "$(GREEN)Python dependencies installed successfully.$(RESET)"
install-frontend-dependencies:
@@ -149,7 +150,7 @@ install-precommit-hooks:
lint:
@echo "$(YELLOW)Running linters...$(RESET)"
@poetry run pre-commit run --files opendevin/**/* agenthub/**/* --show-diff-on-failure --config $(PRECOMMIT_CONFIG_PATH)
@poetry run pre-commit run --all-files --show-diff-on-failure --config $(PRECOMMIT_CONFIG_PATH)
build-frontend:
@echo "$(YELLOW)Building frontend...$(RESET)"
@@ -158,7 +159,7 @@ build-frontend:
# Start backend
start-backend:
@echo "$(YELLOW)Starting backend...$(RESET)"
@poetry run uvicorn opendevin.server.listen:app --port $(BACKEND_PORT) --reload --reload-dir opendevin --reload-dir agenthub --reload-dir evaluation
@poetry run uvicorn opendevin.server.listen:app --port $(BACKEND_PORT) --reload --reload-exclude workspace/*
# Start frontend
start-frontend:
@@ -189,7 +190,7 @@ setup-config:
@echo "$(GREEN)Config.toml setup completed.$(RESET)"
setup-config-prompts:
@read -p "Enter your LLM Model name (see https://docs.litellm.ai/docs/providers for full list) [default: $(DEFAULT_MODEL)]: " llm_model; \
@read -p "Enter your LLM Model name, used for running without UI. Set the model in the UI after you start the app. (see https://docs.litellm.ai/docs/providers for full list) [default: $(DEFAULT_MODEL)]: " llm_model; \
llm_model=$${llm_model:-$(DEFAULT_MODEL)}; \
echo "LLM_MODEL=\"$$llm_model\"" > $(CONFIG_FILE).tmp
@@ -199,12 +200,22 @@ 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 "LLM_BASE_URL=\"$$llm_base_url\"" >> $(CONFIG_FILE).tmp; fi
@echo "Enter your LLM Embedding Model\nChoices are openai, azureopenai, llama2 or leave blank to default to 'BAAI/bge-small-en-v1.5' via huggingface"; \
read -p "> " llm_embedding_model; \
echo "LLM_EMBEDDING_MODEL=\"$$llm_embedding_model\"" >> $(CONFIG_FILE).tmp; \
if [ "$$llm_embedding_model" = "llama2" ]; then \
read -p "Enter the local model URL (will overwrite LLM_BASE_URL): " llm_base_url; \
echo "LLM_BASE_URL=\"$$llm_base_url\"" >> $(CONFIG_FILE).tmp; \
@echo "Enter your LLM Embedding Model"; \
echo "Choices are:"; \
echo " - openai"; \
echo " - azureopenai"; \
echo " - Embeddings available only with OllamaEmbedding:"; \
echo " - llama2"; \
echo " - mxbai-embed-large"; \
echo " - nomic-embed-text"; \
echo " - all-minilm"; \
echo " - stable-code"; \
echo " - Leave blank to default to 'BAAI/bge-small-en-v1.5' via huggingface"; \
read -p "> " llm_embedding_model; \
echo "LLM_EMBEDDING_MODEL=\"$$llm_embedding_model\"" >> $(CONFIG_FILE).tmp; \
if [ "$$llm_embedding_model" = "llama2" ] || [ "$$llm_embedding_model" = "mxbai-embed-large" ] || [ "$$llm_embedding_model" = "nomic-embed-text" ] || [ "$$llm_embedding_model" = "all-minilm" ] || [ "$$llm_embedding_model" = "stable-code" ]; then \
read -p "Enter the local model URL for the embedding model (will set LLM_EMBEDDING_BASE_URL): " llm_embedding_base_url; \
echo "LLM_EMBEDDING_BASE_URL=\"$$llm_embedding_base_url\"" >> $(CONFIG_FILE).tmp; \
elif [ "$$llm_embedding_model" = "azureopenai" ]; then \
read -p "Enter the Azure endpoint URL (will overwrite LLM_BASE_URL): " llm_base_url; \
echo "LLM_BASE_URL=\"$$llm_base_url\"" >> $(CONFIG_FILE).tmp; \

167
README.md
View File

@@ -1,5 +1,3 @@
[English](README.md) | [中文](docs/README-zh.md)
<a name="readme-top"></a>
<!--
@@ -32,168 +30,15 @@
<!-- PROJECT LOGO -->
<div align="center">
<img src="./logo.png" alt="Logo" width="200" height="200">
<img src="./docs/static/img/logo.png" alt="Logo" width="200" height="200">
<h1 align="center">OpenDevin: Code Less, Make More</h1>
</div>
<!-- TABLE OF CONTENTS -->
<details>
<summary>🗂️ Table of Contents</summary>
<ol>
<li><a href="#-mission">🎯 Mission</a></li>
<li><a href="#-what-is-devin">🤔 What is Devin?</a></li>
<li><a href="#-why-opendevin">🐚 Why OpenDevin?</a></li>
<li><a href="#-project-status">🚧 Project Status</a></li>
<a href="#-get-started">🚀 Get Started</a>
<ul>
<li><a href="#1-requirements">1. Requirements</a></li>
<li><a href="#2-build-and-setup">2. Build and Setup</a></li>
<li><a href="#3-run-the-application">3. Run the Application</a></li>
<li><a href="#4-individual-server-startup">4. Individual Server Startup</a></li>
<li><a href="#5-help">5. Help</a></li>
</ul>
</li>
<li><a href="#%EF%B8%8F-research-strategy">⭐️ Research Strategy</a></li>
<li><a href="#-how-to-contribute">🤝 How to Contribute</a></li>
<li><a href="#-join-our-community">🤖 Join Our Community</a></li>
<li><a href="#%EF%B8%8F-built-with">🛠️ Built With</a></li>
<li><a href="#-license">📜 License</a></li>
</ol>
</details>
## 🎯 Mission
[Project Demo Video](https://github.com/OpenDevin/OpenDevin/assets/38853559/71a472cc-df34-430c-8b1d-4d7286c807c9)
Welcome to OpenDevin, an open-source project aiming to replicate Devin, an autonomous AI software engineer who is capable of executing complex engineering tasks and collaborating actively with users on software development projects. This project aspires to replicate, enhance, and innovate upon Devin through the power of the open-source community.
<p align="right" style="font-size: 14px; color: #555; margin-top: 20px;">
<a href="#readme-top" style="text-decoration: none; color: #007bff; font-weight: bold;">
↑ Back to Top ↑
</a>
</p>
## 🤔 What is Devin?
Devin represents a cutting-edge autonomous agent designed to navigate the complexities of software engineering. It leverages a combination of tools such as a shell, code editor, and web browser, showcasing the untapped potential of LLMs in software development. Our goal is to explore and expand upon Devin's capabilities, identifying both its strengths and areas for improvement, to guide the progress of open code models.
<p align="right" style="font-size: 14px; color: #555; margin-top: 20px;">
<a href="#readme-top" style="text-decoration: none; color: #007bff; font-weight: bold;">
↑ Back to Top ↑
</a>
</p>
## 🐚 Why OpenDevin?
The OpenDevin project is born out of a desire to replicate, enhance, and innovate beyond the original Devin model. By engaging the open-source community, we aim to tackle the challenges faced by Code LLMs in practical scenarios, producing works that significantly contribute to the community and pave the way for future advancements.
<p align="right" style="font-size: 14px; color: #555; margin-top: 20px;">
<a href="#readme-top" style="text-decoration: none; color: #007bff; font-weight: bold;">
↑ Back to Top ↑
</a>
</p>
## 🚧 Project Status
OpenDevin is currently a work in progress, but you can already run the alpha version to see the end-to-end system in action. The project team is actively working on the following key milestones:
- **UI**: Developing a user-friendly interface, including a chat interface, a shell demonstrating commands, and a web browser.
- **Architecture**: Building a stable agent framework with a robust backend that can read, write, and run simple commands.
- **Agent Capabilities**: Enhancing the agent's abilities to generate bash scripts, run tests, and perform other software engineering tasks.
- **Evaluation**: Establishing a minimal evaluation pipeline that is consistent with Devin's evaluation criteria.
After completing the MVP, the team will focus on research in various areas, including foundation models, specialist capabilities, evaluation, and agent studies.
<p align="right" style="font-size: 14px; color: #555; margin-top: 20px;">
<a href="#readme-top" style="text-decoration: none; color: #007bff; font-weight: bold;">
↑ Back to Top ↑
</a>
</p>
## ⚠️ Caveats and Warnings
- OpenDevin is still an alpha project. It is changing very quickly and is unstable. We are working on getting a stable release out in the coming weeks.
- OpenDevin will issue many prompts to the LLM you configure. Most of these LLMs cost money--be sure to set spending limits and monitor usage.
- OpenDevin runs `bash` commands within a Docker sandbox, so it should not affect your machine. But your workspace directory will be attached to that sandbox, and files in the directory may be modified or deleted.
- Our default Agent is currently the MonologueAgent, which has limited capabilities, but is fairly stable. We're working on other Agent implementations, including [SWE Agent](https://swe-agent.com/). You can [read about our current set of agents here](./docs/Agents.md).
## 🚀 Get Started
The easiest way to run OpenDevin is inside a Docker container.
To start the app, run these commands, replacing `$(pwd)/workspace` with the path to the code you want OpenDevin to work with.
```bash
# Your OpenAI API key, or any other LLM API key
export LLM_API_KEY="sk-..."
# The directory you want OpenDevin to modify. MUST be an absolute path!
export WORKSPACE_BASE=$(pwd)/workspace
docker run \
-e LLM_API_KEY \
-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 \
ghcr.io/opendevin/opendevin:0.3.1
```
You'll find opendevin running at `http://localhost:3000`.
If you want to use the (unstable!) bleeding edge, you can use `ghcr.io/opendevin/opendevin:main` as the image.
See [Development.md](Development.md) for instructions on running OpenDevin without Docker.
Having trouble? Check out our [Troubleshooting Guide](./docs/guides/Troubleshooting.md).
## 🤖 LLM Backends
OpenDevin can work with any LLM backend.
For a full list of the LM providers and models available, please consult the
[litellm documentation](https://docs.litellm.ai/docs/providers).
The `LLM_MODEL` environment variable controls which model is used in programmatic interactions.
But when using the OpenDevin UI, you'll need to choose your model in the settings window (the gear
wheel on the bottom left).
The following environment variables might be necessary for some LLMs:
- `LLM_API_KEY`
- `LLM_BASE_URL`
- `LLM_EMBEDDING_MODEL`
- `LLM_EMBEDDING_DEPLOYMENT_NAME`
- `LLM_API_VERSION`
We have a few guides for running OpenDevin with specific model providers:
- [ollama](./docs/guides/LocalLLMs.md)
- [Azure](./docs/guides/AzureLLMs.md)
If you're using another provider, we encourage you to open a PR to share your setup!
**Note on Alternative Models:**
The best models are GPT-4 and Claude 3. Current local and open source models are
not nearly as powerful. When using an alternative model,
you may see long wait times between messages,
poor responses, or errors about malformed JSON. OpenDevin
can only be as powerful as the models driving it--fortunately folks on our team
are actively working on building better open source models!
**Note on API retries and rate limits:**
Some LLMs have rate limits and may require retries. OpenDevin will automatically retry requests if it receives a 429 error or API connection error.
You can set LLM_NUM_RETRIES, LLM_RETRY_MIN_WAIT, LLM_RETRY_MAX_WAIT environment variables to control the number of retries and the time between retries.
By default, LLM_NUM_RETRIES is 5 and LLM_RETRY_MIN_WAIT, LLM_RETRY_MAX_WAIT are 3 seconds and respectively 60 seconds.
## ⭐️ Research Strategy
Achieving full replication of production-grade applications with LLMs is a complex endeavor. Our strategy involves:
1. **Core Technical Research:** Focusing on foundational research to understand and improve the technical aspects of code generation and handling.
2. **Specialist Abilities:** Enhancing the effectiveness of core components through data curation, training methods, and more.
3. **Task Planning:** Developing capabilities for bug detection, codebase management, and optimization.
4. **Evaluation:** Establishing comprehensive evaluation metrics to better understand and improve our models.
To learn more and to use OpenDevin, check out our [documentation](https://opendevin.github.io/OpenDevin/).
<p align="right" style="font-size: 14px; color: #555; margin-top: 20px;">
<a href="#readme-top" style="text-decoration: none; color: #007bff; font-weight: bold;">
@@ -230,14 +75,6 @@ If you would love to contribute, feel free to join our community (note that now
[![Star History Chart](https://api.star-history.com/svg?repos=OpenDevin/OpenDevin&type=Date)](https://star-history.com/#OpenDevin/OpenDevin&Date)
## 🛠️ Built With
OpenDevin is built using a combination of powerful frameworks and libraries, providing a robust foundation for its development. Here are the key technologies used in the project:
![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)
Please note that the selection of these technologies is in progress, and additional technologies may be added or existing ones may be removed as the project evolves. We strive to adopt the most suitable and efficient tools to enhance the capabilities of OpenDevin.
<p align="right" style="font-size: 14px; color: #555; margin-top: 20px;">
<a href="#readme-top" style="text-decoration: none; color: #007bff; font-weight: bold;">
↑ Back to Top ↑

View File

@@ -1,4 +1,5 @@
from opendevin.agent import Agent
from .agent import SWEAgent
Agent.register('SWEAgent', SWEAgent)

View File

@@ -1,23 +1,23 @@
from typing import List
from opendevin.agent import Agent
from opendevin.llm.llm import LLM
from opendevin.state import State
from opendevin.action import (
Action,
AgentThinkAction,
FileReadAction,
FileWriteAction,
)
from opendevin.agent import Agent
from opendevin.llm.llm import LLM
from opendevin.observation import Observation
from opendevin.state import State
from .parser import parse_command
from .prompts import (
SYSTEM_MESSAGE,
STEP_PROMPT,
CONTEXT_PROMPT,
MEMORY_FORMAT,
NO_ACTION,
CONTEXT_PROMPT
STEP_PROMPT,
SYSTEM_MESSAGE,
)

View File

@@ -1,17 +1,17 @@
import re
from opendevin.action import (
Action,
AgentEchoAction,
AgentFinishAction,
AgentThinkAction,
BrowseURLAction,
CmdRunAction,
FileReadAction,
FileWriteAction,
BrowseURLAction,
AgentEchoAction,
AgentThinkAction,
)
import re
from .prompts import CUSTOM_DOCS, COMMAND_USAGE
from .prompts import COMMAND_USAGE, CUSTOM_DOCS
# commands: exit, read, write, browse, kill, search_file, search_dir
@@ -20,7 +20,7 @@ no_open_file_error = AgentEchoAction(
def invalid_error(cmd, docs):
return f'''ERROR:
return f"""ERROR:
Invalid command structure for
```
{cmd}
@@ -30,7 +30,7 @@ If so, try again by running only one of the commands:
Try again using this format:
{COMMAND_USAGE[docs]}
'''
"""
def get_action_from_string(command_string: str, path: str, line: int, thoughts: str = '') -> Action | None:

View File

@@ -1,7 +1,7 @@
DEFAULT_COMMANDS_DICT = {
'exit': 'Executed when task is complete',
'read <file_name> [<start_line>] [<end_line>]': 'Shows a given file\'s contents starting from <start_line> up to <end_line>. Default: start_line = 0, end_line = -1. By default the whole file will be read.',
'read <file_name> [<start_line>] [<end_line>]': "Shows a given file's contents starting from <start_line> up to <end_line>. Default: start_line = 0, end_line = -1. By default the whole file will be read.",
'write <file> <changes> [<start_line>] [<end_line>]': 'Modifies a <file> by replacing the current lines between <start_line> and <end_line> with <changes>. Default start_line = 0 and end_line = -1. Calling this with no line args will replace the whole file.',
'browse <url>': 'Returns the text version of any url, this can be useful to look up documentation or finding issues on github',
'scroll_up': 'Takes no arguments. This will scroll up and show you the 100 lines above your current lines',
@@ -16,7 +16,7 @@ DEFAULT_COMMANDS_DICT = {
COMMAND_USAGE = {
'exit': 'Usage:\n```\nexit\n```\nExecuted when task is complete',
'read': 'Args:\n<file_name> [<start_line>] [<end_line>]\nUsage:\n```\nread file.py\n```\nor\n```\nread example.py <start_line> <end_line>\n```\nShows a given file\'s contents starting from <start_line> up to <end_line>. Default: start_line = 0, end_line = -1. by default the whole file will be read.',
'read': "Args:\n<file_name> [<start_line>] [<end_line>]\nUsage:\n```\nread file.py\n```\nor\n```\nread example.py <start_line> <end_line>\n```\nShows a given file's contents starting from <start_line> up to <end_line>. Default: start_line = 0, end_line = -1. by default the whole file will be read.",
'write': 'Args:\n<file> <changes> [<start_line>] [<end_line>]\nUsage:\n```\nwrite "def main():\n print("This is line one")" 0 2\n```\nModifies a <file> by replacing the current lines between <start_line> and <end_line> with <changes>. Default start_line = 0 and end_line = -1. Calling this with no line args will replace the whole file.',
'edit': 'Args:\n<start_line> <end_line> <changes>\nUsage:\n```\nedit 0 1 import pandas as pd\n```\nThis will modify the current file you are in with the changes you make between the line numbers you designate',
'goto': 'Args:\n<line_num>\nUsage:\n```\ngoto <line_num>\n```\nThis will show you the 100 lines below and including the line you specify within your current file.',
@@ -52,7 +52,7 @@ To modify the current file use 'edit'. To move through the current file use 'got
when using write and edit do not surround the code with any "" just write the code.
"""
GENERAL_GUIDELINES = '''INSTRUCTIONS:
GENERAL_GUIDELINES = """INSTRUCTIONS:
Now, you're going to solve this issue on your own. You can use any bash commands or custom commands you wish to complete your task. Edit all the files you need to and run any checks or tests that you want.
Remember, YOU CAN ONLY ENTER ONE COMMAND AT A TIME. You should always wait for feedback after every command.
When you're satisfied with all of the changes you've made, you can indicate that you are done by running the exit command.
@@ -69,9 +69,9 @@ IMPORTANT TIPS:
5. Understand your context: Always make sure to look at the currently open file and the current working directory. The currently open file might be in a different directory than the working directory.
6. Verify your edits: When editing files, it is easy to accidentally specify a wrong line number or to write code with incorrect indentation. Always check the code after you issue an edit to make sure that it reflects what you wanted to accomplish. If it didn't, issue another command to fix it.
7. Thoroughly test your solution: After making any changes to fix a bug, be sure to thoroughly test your solution to ensure the bug has been resolved. Re-run the bug reproduction script and verify that the issue has been addressed.
'''
"""
RESPONSE_FORMAT = '''RESPONSE FORMAT:
RESPONSE_FORMAT = """RESPONSE FORMAT:
This is the format of the response you will make in order to solve the current issue.
You will be given multiple iterations to complete this task so break it into steps and solve them one by one.
@@ -113,9 +113,9 @@ Action:
[ END FORMAT ]
Do not provide anything extra just your thought and action.
'''
"""
SYSTEM_MESSAGE = f'''SYSTEM INFO:
SYSTEM_MESSAGE = f"""SYSTEM INFO:
You am an autonomous coding agent, here to provide solutions for coding issues.
You have been designed to assist you with a wide range of programming tasks, from code editing and debugging to testing and deployment.
You have access to a variety of tools and commands that you can use to help you solve problems efficiently.
@@ -123,10 +123,10 @@ You have access to a variety of tools and commands that you can use to help you
{GENERAL_GUIDELINES}
{DOCUMENTATION}
'''.strip()
""".strip()
def NO_ACTION(latest): return f'''
def NO_ACTION(latest): return f"""
You did not include any action to take in your most recent output:
===== Output ======
@@ -141,20 +141,20 @@ This time, be sure to use the exact format below, replacing anything in <> with
{RESPONSE_FORMAT}
It is crucial you use the format provided as the output will be parsed automatically.
'''
"""
def file_info(file: str, line: int):
if file:
return f'''CURRENT WORKSPACE:
return f"""CURRENT WORKSPACE:
Open File: {file} on line {line}
You can use these commands with the current file:
Navigation: `scroll_up`, `scroll_down`, and `goto <line>`
Modification: `edit <start_line> <end_line> <changes>`
'''
"""
def STEP_PROMPT(task, file, line_num): return f'''
def STEP_PROMPT(task, file, line_num): return f"""
{RESPONSE_FORMAT}
You are currently trying to complete this task:
{task}
@@ -168,7 +168,7 @@ Be very strict about the formatting that you use and make sure you follow the gu
NEVER output multiple commands. ONLY take ONE STEP at a time.
When you have completed your task run the "exit" command.
Begin with your thought about the next step and then come up with an action to perform your thought.
'''.strip()
""".strip()
def unpack_dict(data: dict, restrict: list[str] = []):
@@ -185,13 +185,13 @@ def unpack_dict(data: dict, restrict: list[str] = []):
return '\n'.join(lines)
def MEMORY_FORMAT(act, obs): return f'''
def MEMORY_FORMAT(act, obs): return f"""
Previous Action:
{unpack_dict(act, ["content"])}
Output from Action:
{unpack_dict(obs)}
'''.strip()
""".strip()
def CONTEXT_PROMPT(memory, window):

View File

@@ -1,17 +1,21 @@
from .micro.registry import all_microagents
from .micro.agent import MicroAgent
from dotenv import load_dotenv
from opendevin.agent import Agent
from dotenv import load_dotenv
from .micro.agent import MicroAgent
from .micro.registry import all_microagents
load_dotenv()
# Import agents after environment variables are loaded
from . import monologue_agent # noqa: E402
from . import codeact_agent # noqa: E402
from . import planner_agent # noqa: E402
from . import SWE_agent # noqa: E402
from . import delegator_agent # noqa: E402
from . import ( # noqa: E402
SWE_agent,
codeact_agent,
delegator_agent,
monologue_agent,
planner_agent,
)
__all__ = ['monologue_agent', 'codeact_agent',
'planner_agent', 'SWE_agent', 'delegator_agent']

View File

@@ -1,4 +1,5 @@
from opendevin.agent import Agent
from .codeact_agent import CodeActAgent
Agent.register('CodeActAgent', CodeActAgent)

View File

@@ -13,8 +13,8 @@ from opendevin.observation import (
AgentMessageObservation,
CmdOutputObservation,
)
from opendevin.sandbox.plugins import JupyterRequirement, PluginRequirement
from opendevin.state import State
from opendevin.sandbox.plugins import PluginRequirement, JupyterRequirement
SYSTEM_MESSAGE = """You are a helpful assistant. You will be provided access (as root) to a bash shell to complete user-provided tasks.
You will be able to execute commands in the bash shell, interact with the file system, install packages, and receive the output of your commands.

View File

@@ -1,4 +1,5 @@
from opendevin.agent import Agent
from .agent import DelegatorAgent
Agent.register('DelegatorAgent', DelegatorAgent)

View File

@@ -1,11 +1,10 @@
from typing import List
from opendevin.action import Action, AgentDelegateAction, AgentFinishAction
from opendevin.agent import Agent
from opendevin.action import AgentFinishAction, AgentDelegateAction
from opendevin.observation import AgentDelegateObservation
from opendevin.llm.llm import LLM
from opendevin.observation import AgentDelegateObservation
from opendevin.state import State
from opendevin.action import Action
class DelegatorAgent(Agent):

View File

View File

@@ -0,0 +1,23 @@
"""Module for a Dummy agent."""
from typing import List
from opendevin.action import Action
from opendevin.action.base import NullAction
from opendevin.agent import Agent
from opendevin.controller.agent_controller import AgentController
from opendevin.observation.base import NullObservation, Observation
from opendevin.state import State
class DummyAgent(Agent):
"""A dummy agent that does nothing but can be used in testing."""
async def run(self, controller: AgentController) -> Observation:
return NullObservation('')
def step(self, state: State) -> Action:
return NullAction('')
def search_memory(self, query: str) -> List[str]:
return []

View File

@@ -1,13 +1,13 @@
import json
from typing import List, Dict
from typing import Dict, List
from jinja2 import Environment, BaseLoader
from jinja2 import BaseLoader, Environment
from opendevin.action import Action, action_from_dict
from opendevin.agent import Agent
from opendevin.exceptions import LLMOutputError
from opendevin.llm.llm import LLM
from opendevin.state import State
from opendevin.action import Action, action_from_dict
from opendevin.exceptions import LLMOutputError
from .instructions import instructions
from .registry import all_microagents
@@ -56,14 +56,9 @@ class MicroAgent(Agent):
super().__init__(llm)
if 'name' not in self.agent_definition:
raise ValueError('Agent definition must contain a name')
self.name = self.agent_definition['name']
self.description = self.agent_definition['description'] if 'description' in self.agent_definition else ''
self.inputs = self.agent_definition['inputs'] if 'inputs' in self.agent_definition else []
self.outputs = self.agent_definition['outputs'] if 'outputs' in self.agent_definition else []
self.examples = self.agent_definition['examples'] if 'examples' in self.agent_definition else []
self.prompt_template = Environment(loader=BaseLoader).from_string(self.prompt)
self.delegates = all_microagents.copy()
del self.delegates[self.name]
del self.delegates[self.agent_definition['name']]
def step(self, state: State) -> Action:
prompt = self.prompt_template.render(

View File

@@ -1,6 +1,6 @@
name: Coder
name: CoderAgent
description: Given a particular task, and a detailed description of the codebase, accomplishes the task
inputs:
- task: string
- codebase_summary: string
outputs: []
task: string
codebase_summary: string
outputs: {}

View File

@@ -1,5 +1,5 @@
from typing import Dict
import os
from typing import Dict
instructions: Dict = {}

View File

@@ -1,5 +1,6 @@
name: Manager
name: ManagerAgent
description: Delegates tasks to microagents based on their area of expertise
generates: Action
inputs:
task: string
outputs: {}

View File

@@ -7,19 +7,19 @@ inputs:
outputs:
answer: string
examples:
- input:
- inputs:
task: "What is 2 + 2?"
output:
outputs:
answer: "4"
- input:
- inputs:
task: "What is the area of a circle with radius 7.324 inches?"
output:
answer: "168.518 square inches"
- input:
- inputs:
task: "What day of the week is 2099-01-01?"
output:
outputs:
answer: "Saturday"
- input:
- inputs:
task: "What is the integral of sin(x^2) evaluated from -1 to 1?"
output:
outputs:
answer: "0.603848"

View File

@@ -2,5 +2,5 @@ name: PostgresAgent
description: Writes and maintains PostgreSQL migrations
generates: Action
inputs:
- task: string
outputs: []
task: string
outputs: {}

View File

@@ -1,4 +1,5 @@
import os
import yaml
all_microagents = {}

View File

@@ -1,5 +1,5 @@
name: RepoExplorer
name: RepoExplorerAgent
description: Generates a detailed summary of an existing codebase
inputs: []
inputs: {}
outputs:
- summary: string
summary: string

View File

@@ -1,6 +1,6 @@
name: StudyRepoForTaskAgent
description: Given a particular task, finds and describes all relevant parts of the codebase
inputs:
- task: string
task: string
outputs:
- summary: string
summary: string

View File

@@ -1,7 +1,7 @@
name: Verifier
name: VerifierAgent
description: Given a particular task, verifies that the task has been completed
inputs:
- task: string
task: string
outputs:
- completed: boolean
- summary: string
completed: boolean
summary: string

View File

@@ -1,4 +1,5 @@
from opendevin.agent import Agent
from .agent import MonologueAgent
Agent.register('MonologueAgent', MonologueAgent)

View File

@@ -1,33 +1,36 @@
from typing import List
from opendevin.agent import Agent
from opendevin.state import State
from opendevin.llm.llm import LLM
from opendevin.schema import ActionType, ObservationType
from opendevin.exceptions import AgentNoInstructionError
from opendevin.action import (
Action,
NullAction,
CmdRunAction,
FileWriteAction,
FileReadAction,
AgentRecallAction,
BrowseURLAction,
AgentThinkAction,
)
from opendevin.observation import (
Observation,
NullObservation,
CmdOutputObservation,
FileReadObservation,
AgentRecallObservation,
BrowserOutputObservation,
)
import agenthub.monologue_agent.utils.prompts as prompts
from agenthub.monologue_agent.utils.monologue import Monologue
from agenthub.monologue_agent.utils.memory import LongTermMemory
from opendevin import config
from opendevin.action import (
Action,
AgentRecallAction,
AgentThinkAction,
BrowseURLAction,
CmdRunAction,
FileReadAction,
FileWriteAction,
GitHubPushAction,
NullAction,
)
from opendevin.agent import Agent
from opendevin.exceptions import AgentNoInstructionError
from opendevin.llm.llm import LLM
from opendevin.observation import (
AgentRecallObservation,
BrowserOutputObservation,
CmdOutputObservation,
FileReadObservation,
NullObservation,
Observation,
)
from opendevin.schema import ActionType
from opendevin.schema.config import ConfigType
from opendevin.state import State
if config.get(ConfigType.AGENT_MEMORY_ENABLED):
from agenthub.monologue_agent.utils.memory import LongTermMemory
MAX_MONOLOGUE_LENGTH = 20000
MAX_OUTPUT_LENGTH = 5000
@@ -68,13 +71,17 @@ INITIAL_THOUGHTS = [
'BROWSE google.com',
'<form><input type="text"></input><button type="submit"></button></form>',
'I can browse the web too!',
'If I have done some work and I want to push it to github, I can do that also!',
"Let's do it.",
'PUSH owner/repo branch',
'The repo was successfully pushed to https://github.com/owner/repo/branch',
'And once I have completed my task, I can use the finish action to stop working.',
"But I should only use the finish action when I'm absolutely certain that I've completed my task and have tested my work.",
'Very cool. Now to accomplish my task.',
"I'll need a strategy. And as I make progress, I'll need to keep refining that strategy. I'll need to set goals, and break them into sub-goals.",
'In between actions, I must always take some time to think, strategize, and set new goals. I should never take two actions in a row.',
"OK so my task is to $TASK. I haven't made any progress yet. Where should I start?",
"It seems like there might be an existing project here. I should probably start by running `ls` to see what's here.",
'It seems like there might be an existing project here. I should probably start by running `pwd` and `ls` to orient myself.',
]
@@ -86,6 +93,8 @@ class MonologueAgent(Agent):
"""
_initialized = False
monologue: Monologue
memory: 'LongTermMemory | None'
def __init__(self, llm: LLM):
"""
@@ -95,8 +104,6 @@ class MonologueAgent(Agent):
- llm (LLM): The llm to be used by this agent
"""
super().__init__(llm)
self.monologue = Monologue()
self.memory = LongTermMemory()
def _add_event(self, event: dict):
"""
@@ -119,7 +126,8 @@ class MonologueAgent(Agent):
)
self.monologue.add_event(event)
self.memory.add_event(event)
if self.memory is not None:
self.memory.add_event(event)
if self.monologue.get_total_length() > MAX_MONOLOGUE_LENGTH:
self.monologue.condense(self.llm)
@@ -141,35 +149,39 @@ class MonologueAgent(Agent):
if task is None or task == '':
raise AgentNoInstructionError()
self.monologue = Monologue()
self.memory = LongTermMemory()
output_type = ''
self.monologue = Monologue()
if config.get(ConfigType.AGENT_MEMORY_ENABLED):
self.memory = LongTermMemory()
else:
self.memory = None
previous_action = ''
for thought in INITIAL_THOUGHTS:
thought = thought.replace('$TASK', task)
if output_type != '':
if previous_action != '':
observation: Observation = NullObservation(content='')
if output_type == ObservationType.RUN:
if previous_action in {ActionType.RUN, ActionType.PUSH}:
observation = CmdOutputObservation(
content=thought, command_id=0, command=''
)
elif output_type == ObservationType.READ:
elif previous_action == ActionType.READ:
observation = FileReadObservation(content=thought, path='')
elif output_type == ObservationType.RECALL:
elif previous_action == ActionType.RECALL:
observation = AgentRecallObservation(
content=thought, memories=[])
elif output_type == ObservationType.BROWSE:
elif previous_action == ActionType.BROWSE:
observation = BrowserOutputObservation(
content=thought, url='', screenshot=''
)
self._add_event(observation.to_memory())
output_type = ''
previous_action = ''
else:
action: Action = NullAction()
if thought.startswith('RUN'):
command = thought.split('RUN ')[1]
action = CmdRunAction(command)
output_type = ActionType.RUN
previous_action = ActionType.RUN
elif thought.startswith('WRITE'):
parts = thought.split('WRITE ')[1].split(' > ')
path = parts[1]
@@ -178,15 +190,20 @@ class MonologueAgent(Agent):
elif thought.startswith('READ'):
path = thought.split('READ ')[1]
action = FileReadAction(path=path)
output_type = ActionType.READ
previous_action = ActionType.READ
elif thought.startswith('RECALL'):
query = thought.split('RECALL ')[1]
action = AgentRecallAction(query=query)
output_type = ActionType.RECALL
previous_action = ActionType.RECALL
elif thought.startswith('BROWSE'):
url = thought.split('BROWSE ')[1]
action = BrowseURLAction(url=url)
output_type = ActionType.BROWSE
previous_action = ActionType.BROWSE
elif thought.startswith('PUSH'):
owner_repo, branch = thought.split('PUSH ')[1].split(' ')
owner, repo = owner_repo.split('/')
action = GitHubPushAction(owner=owner, repo=repo, branch=branch)
previous_action = ActionType.PUSH
else:
action = AgentThinkAction(thought=thought)
self._add_event(action.to_memory())
@@ -233,8 +250,14 @@ class MonologueAgent(Agent):
Returns:
- List[str]: A list of top 10 text results that matched the query
"""
if self.memory is None:
return []
return self.memory.search(query)
def reset(self) -> None:
super().reset()
self.monologue = Monologue()
if config.get(ConfigType.AGENT_MEMORY_ENABLED):
self.memory = LongTermMemory()
else:
self.memory = None

View File

@@ -1,4 +1,5 @@
import json
from json_repair import repair_json

View File

@@ -1,21 +1,27 @@
import llama_index.embeddings.openai.base as llama_openai
from threading import Thread
import threading
import chromadb
from llama_index.core import Document
import llama_index.embeddings.openai.base as llama_openai
from llama_index.core import Document, VectorStoreIndex
from llama_index.core.retrievers import VectorIndexRetriever
from llama_index.core import VectorStoreIndex
from llama_index.vector_stores.chroma import ChromaVectorStore
from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_random_exponential
from openai._exceptions import APIConnectionError, RateLimitError, InternalServerError
from openai._exceptions import APIConnectionError, InternalServerError, RateLimitError
from tenacity import (
retry,
retry_if_exception_type,
stop_after_attempt,
wait_random_exponential,
)
from opendevin import config
from opendevin.logger import opendevin_logger as logger
from opendevin.schema.config import ConfigType
from . import json
num_retries = config.get('LLM_NUM_RETRIES')
retry_min_wait = config.get('LLM_RETRY_MIN_WAIT')
retry_max_wait = config.get('LLM_RETRY_MAX_WAIT')
num_retries = config.get(ConfigType.LLM_NUM_RETRIES)
retry_min_wait = config.get(ConfigType.LLM_RETRY_MIN_WAIT)
retry_max_wait = config.get(ConfigType.LLM_RETRY_MAX_WAIT)
# llama-index includes a retry decorator around openai.get_embeddings() function
# it is initialized with hard-coded values and errors
@@ -46,32 +52,33 @@ def wrapper_get_embeddings(*args, **kwargs):
llama_openai.get_embeddings = wrapper_get_embeddings
embedding_strategy = config.get('LLM_EMBEDDING_MODEL')
embedding_strategy = config.get(ConfigType.LLM_EMBEDDING_MODEL)
# TODO: More embeddings: https://docs.llamaindex.ai/en/stable/examples/embeddings/OpenAI/
# There's probably a more programmatic way to do this.
if embedding_strategy == 'llama2':
supported_ollama_embed_models = ['llama2', 'mxbai-embed-large', 'nomic-embed-text', 'all-minilm', 'stable-code']
if embedding_strategy in supported_ollama_embed_models:
from llama_index.embeddings.ollama import OllamaEmbedding
embed_model = OllamaEmbedding(
model_name='llama2',
base_url=config.get('LLM_BASE_URL', required=True),
model_name=embedding_strategy,
base_url=config.get(ConfigType.LLM_EMBEDDING_BASE_URL, required=True),
ollama_additional_kwargs={'mirostat': 0},
)
elif embedding_strategy == 'openai':
from llama_index.embeddings.openai import OpenAIEmbedding
embed_model = OpenAIEmbedding(
model='text-embedding-ada-002',
api_key=config.get('LLM_API_KEY', required=True)
api_key=config.get(ConfigType.LLM_API_KEY, required=True)
)
elif embedding_strategy == 'azureopenai':
# Need to instruct to set these env variables in documentation
from llama_index.embeddings.azure_openai import AzureOpenAIEmbedding
embed_model = AzureOpenAIEmbedding(
model='text-embedding-ada-002',
deployment_name=config.get('LLM_EMBEDDING_DEPLOYMENT_NAME', required=True),
api_key=config.get('LLM_API_KEY', required=True),
azure_endpoint=config.get('LLM_BASE_URL', required=True),
api_version=config.get('LLM_API_VERSION', required=True),
deployment_name=config.get(ConfigType.LLM_EMBEDDING_DEPLOYMENT_NAME, required=True),
api_key=config.get(ConfigType.LLM_API_KEY, required=True),
azure_endpoint=config.get(ConfigType.LLM_BASE_URL, required=True),
api_version=config.get(ConfigType.LLM_API_VERSION, required=True),
)
elif (embedding_strategy is not None) and (embedding_strategy.lower() == 'none'):
# TODO: this works but is not elegant enough. The incentive is when
@@ -85,6 +92,9 @@ else:
)
sema = threading.Semaphore(value=config.get(ConfigType.AGENT_MEMORY_MAX_THREADS))
class LongTermMemory:
"""
Responsible for storing information that the agent can call on later for better insights and context.
@@ -101,6 +111,7 @@ class LongTermMemory:
self.index = VectorStoreIndex.from_vector_store(
vector_store, embed_model=embed_model)
self.thought_idx = 0
self._add_threads = []
def add_event(self, event: dict):
"""
@@ -128,11 +139,13 @@ class LongTermMemory:
)
self.thought_idx += 1
logger.debug('Adding %s event to memory: %d', t, self.thought_idx)
thread = Thread(target=self._add_doc, args=(doc,))
thread = threading.Thread(target=self._add_doc, args=(doc,))
self._add_threads.append(thread)
thread.start() # We add the doc concurrently so we don't have to wait ~500ms for the insert
def _add_doc(self, doc):
self.index.insert(doc)
with sema:
self.index.insert(doc)
def search(self, query: str, k: int = 10):
"""

View File

@@ -1,8 +1,8 @@
from opendevin.llm.llm import LLM
from opendevin.exceptions import AgentEventTypeError
import agenthub.monologue_agent.utils.json as json
import agenthub.monologue_agent.utils.prompts as prompts
from opendevin.exceptions import AgentEventTypeError
from opendevin.llm.llm import LLM
from opendevin.logger import opendevin_logger as logger

View File

@@ -1,19 +1,19 @@
import re
from json import JSONDecodeError
from typing import List
from . import json
from json import JSONDecodeError
import re
from opendevin import config
from opendevin.action import (
action_from_dict,
Action,
action_from_dict,
)
from opendevin.exceptions import LLMOutputError
from opendevin.observation import (
CmdOutputObservation,
)
from opendevin.exceptions import LLMOutputError
from opendevin import config
from opendevin.schema.config import ConfigType
from . import json
ACTION_PROMPT = """
You're a thoughtful robot. Your main task is this:
@@ -27,8 +27,8 @@ This is your internal monologue, in JSON format:
Your most recent thought is at the bottom of that monologue. Continue your train of thought.
What is your next thought or action? Your response must be in JSON format.
It must be an object, and it must contain two fields:
What is your next single thought or action? Your response must be in JSON format.
It must be a single object, and it must contain two fields:
* `action`, which is one of the actions below
* `args`, which is a map of key-value pairs, specifying the arguments for that action
@@ -45,6 +45,10 @@ Here are the possible actions:
* `id` - the ID of the background command to kill
* `browse` - opens a web page. Arguments:
* `url` - the URL to open
* `push` - Push a branch from the current repo to github:
* `owner` - the owner of the repo to push to
* `repo` - the name of the repo to push to
* `branch` - the name of the branch to push
* `recall` - recalls a past memory. Arguments:
* `query` - the query to search for
* `think` - make a plan, set a goal, or record your thoughts. Arguments:
@@ -53,16 +57,20 @@ Here are the possible actions:
%(background_commands)s
You MUST take time to think in between read, write, run, browse, and recall actions.
You MUST take time to think in between read, write, run, browse, push, and recall actions.
You should never act twice in a row without thinking. But if your last several
actions are all "think" actions, you should consider taking a different action.
Notes:
* your environment is Debian Linux. You can install software with `apt`
* your working directory will not change, even if you run `cd`. All commands will be run in the `%(WORKSPACE_MOUNT_PATH_IN_SANDBOX)s` directory.
* you are logged in as %(user)s, but sudo will always work without a password.
* all non-background commands will be forcibly stopped if they remain running for over %(timeout)s seconds.
* your environment is Debian Linux. You can install software with `sudo apt-get`, but remember to use -y.
* don't run interactive commands, or commands that don't return (e.g. `node server.js`). You may run commands in the background (e.g. `node server.js &`)
* don't run interactive text editors (e.g. `nano` or 'vim'), instead use the 'write' or 'read' action.
* don't run gui applications (e.g. software IDEs (like vs code or codium), web browsers (like firefox or chromium), or other complex software packages). Use non-interactive cli applications, or special actions instead.
* whenever an action fails, always `think` about why it may have happened before acting again.
What is your next thought or action? Again, you must reply with JSON, and only with JSON.
What is your next single thought or action? Again, you must reply with JSON, and only with JSON. You must respond with exactly one 'action' object.
%(hint)s
"""
@@ -141,12 +149,16 @@ def get_request_action_prompt(
)
bg_commands_message += '\nYou can end any process by sending a `kill` action with the numerical `id` above.'
user = 'opendevin' if config.get(ConfigType.RUN_AS_DEVIN) else 'root'
return ACTION_PROMPT % {
'task': task,
'monologue': json.dumps(thoughts, indent=2),
'background_commands': bg_commands_message,
'hint': hint,
'WORKSPACE_MOUNT_PATH_IN_SANDBOX': config.get('WORKSPACE_MOUNT_PATH_IN_SANDBOX'),
'user': user,
'timeout': config.get(ConfigType.SANDBOX_TIMEOUT),
'WORKSPACE_MOUNT_PATH_IN_SANDBOX': config.get(ConfigType.WORKSPACE_MOUNT_PATH_IN_SANDBOX),
}
@@ -176,7 +188,7 @@ def parse_action_response(response: str) -> Action:
raise LLMOutputError(
'Invalid JSON, the response must be well-formed JSON as specified in the prompt.'
)
except ValueError:
except (ValueError, TypeError):
raise LLMOutputError(
'Invalid JSON, the response must be well-formed JSON as specified in the prompt.'
)

View File

@@ -1,4 +1,5 @@
from opendevin.agent import Agent
from .agent import PlannerAgent
Agent.register('PlannerAgent', PlannerAgent)

View File

@@ -1,11 +1,11 @@
from typing import List
from .prompt import get_prompt, parse_response
from opendevin.action import Action, AgentFinishAction
from opendevin.agent import Agent
from opendevin.action import AgentFinishAction
from opendevin.llm.llm import LLM
from opendevin.state import State
from opendevin.action import Action
from .prompt import get_prompt, parse_response
class PlannerAgent(Agent):

View File

@@ -1,29 +1,29 @@
import json
from typing import List, Tuple, Dict, Type
from opendevin.plan import Plan
from opendevin.action import Action, action_from_dict
from opendevin.observation import Observation
from opendevin.schema import ActionType
from opendevin.logger import opendevin_logger as logger
from typing import Dict, List, Tuple, Type
from opendevin.action import (
NullAction,
CmdRunAction,
CmdKillAction,
Action,
AddTaskAction,
AgentFinishAction,
AgentRecallAction,
AgentSummarizeAction,
AgentThinkAction,
BrowseURLAction,
CmdKillAction,
CmdRunAction,
FileReadAction,
FileWriteAction,
AgentRecallAction,
AgentThinkAction,
AgentFinishAction,
AgentSummarizeAction,
AddTaskAction,
ModifyTaskAction,
NullAction,
action_from_dict,
)
from opendevin.logger import opendevin_logger as logger
from opendevin.observation import (
NullObservation,
Observation,
)
from opendevin.plan import Plan
from opendevin.schema import ActionType
ACTION_TYPE_TO_CLASS: Dict[str, Type[Action]] = {
ActionType.RUN: CmdRunAction,
@@ -134,12 +134,12 @@ def get_hint(latest_action_id: str) -> str:
""" Returns action type hint based on given action_id """
hints = {
'': 'You haven\'t taken any actions yet. Start by using `ls` to check out what files you\'re working with.',
'': "You haven't taken any actions yet. Start by using `ls` to check out what files you're working with.",
ActionType.RUN: 'You should think about the command you just ran, what output it gave, and how that affects your plan.',
ActionType.READ: 'You should think about the file you just read, what you learned from it, and how that affects your plan.',
ActionType.WRITE: 'You just changed a file. You should think about how it affects your plan.',
ActionType.BROWSE: 'You should think about the page you just visited, and what you learned from it.',
ActionType.THINK: 'Look at your last thought in the history above. What does it suggest? Don\'t think anymore--take action.',
ActionType.THINK: "Look at your last thought in the history above. What does it suggest? Don't think anymore--take action.",
ActionType.RECALL: 'You should think about the information you just recalled, and how it should affect your plan.',
ActionType.ADD_TASK: 'You should think about the next action to take.',
ActionType.MODIFY_TASK: 'You should think about the next action to take.',

View File

@@ -33,7 +33,7 @@ FROM python:3.12-slim as runtime
WORKDIR /app
ENV RUN_AS_DEVIN=false
ENV USE_HOST_NETWORK=true
ENV USE_HOST_NETWORK=false
ENV SSH_HOSTNAME=host.docker.internal
ENV WORKSPACE_BASE=/opt/workspace_base
ENV OPEN_DEVIN_BUILD_VERSION=$OPEN_DEVIN_BUILD_VERSION

View File

@@ -44,6 +44,7 @@ if [[ -n "$org_name" ]]; then
DOCKER_ORG="$org_name"
fi
DOCKER_REPOSITORY=$DOCKER_REGISTRY/$DOCKER_ORG/$DOCKER_IMAGE
DOCKER_REPOSITORY=${DOCKER_REPOSITORY,,} # lowercase
echo "Repo: $DOCKER_REPOSITORY"
echo "Base dir: $DOCKER_BASE_DIR"
@@ -53,12 +54,12 @@ for tag in ${tags[@]}; do
done
if [[ $push -eq 1 ]]; then
args+=" --push"
args+=" --cache-to=type=registry,ref=$DOCKER_REPOSITORY:$cache_tag,mode=max"
fi
docker buildx build \
$args \
--build-arg OPEN_DEVIN_BUILD_VERSION=$OPEN_DEVIN_BUILD_VERSION \
--cache-to=type=registry,ref=$DOCKER_REPOSITORY:$cache_tag,mode=max \
--cache-from=type=registry,ref=$DOCKER_REPOSITORY:$cache_tag \
--cache-from=type=registry,ref=$DOCKER_REPOSITORY:$cache_tag_base-main \
--platform linux/amd64,linux/arm64 \

View File

@@ -3,29 +3,20 @@ repos:
rev: v4.5.0
hooks:
- id: trailing-whitespace
exclude: docs/modules/python
- id: end-of-file-fixer
exclude: docs/modules/python
- id: check-yaml
- id: debug-statements
- repo: https://github.com/PyCQA/flake8
rev: 7.0.0
- repo: https://github.com/tox-dev/pyproject-fmt
rev: 1.7.0
hooks:
- id: flake8
args: ['--select=Q000'] # Q000 is the error code for single quote enforcement
additional_dependencies:
- flake8-quotes
- repo: https://github.com/hhatto/autopep8
rev: v2.1.0
- id: pyproject-fmt
- repo: https://github.com/abravalheri/validate-pyproject
rev: v0.16
hooks:
- id: autopep8
- repo: https://github.com/asottile/setup-cfg-fmt
rev: v2.5.0
hooks:
- id: setup-cfg-fmt
always_run: true
pass_filenames: false
- id: validate-pyproject
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
@@ -34,18 +25,24 @@ repos:
# Run the linter.
- id: ruff
entry: ruff check --config dev_config/python/ruff.toml opendevin/ agenthub/
types_or: [ python, pyi, jupyter ]
args: [ --fix ]
types_or: [python, pyi, jupyter]
args: [--fix]
# Run the formatter.
- id: ruff-format
entry: ruff check --config dev_config/python/ruff.toml opendevin/ agenthub/
types_or: [ python, pyi, jupyter ]
types_or: [python, pyi, jupyter]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.9.0
hooks:
- id: mypy
additional_dependencies: [types-requests, types-setuptools, types-pyyaml, types-toml]
additional_dependencies:
[types-requests, types-setuptools, types-pyyaml, types-toml]
entry: mypy --config-file dev_config/python/mypy.ini opendevin/ agenthub/
always_run: true
pass_filenames: false
- repo: https://github.com/NiklasRosenstein/pydoc-markdown
rev: develop
hooks:
- id: pydoc-markdown

View File

@@ -1,3 +1,21 @@
exclude = [
"agenthub/monologue_agent/regression/",
]
]
[lint]
select = [
"E",
"W",
"F",
"I",
"Q",
]
ignore = [
"E501",
]
flake8-quotes = {inline-quotes = "single"}
[format]
quote-style = "single"

20
docs/.gitignore vendored Normal file
View File

@@ -0,0 +1,20 @@
# Dependencies
/node_modules
# Production
/build
# 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

@@ -1,96 +0,0 @@
# Agents and Capabilities
## Monologue Agent:
### Description:
The Monologue Agent utilizes long and short term memory to complete tasks.
Long term memory is stored as a LongTermMemory object and the model uses it to search for examples from the past.
Short term memory is stored as a Monologue object and the model can condense it as necessary.
### Actions:
`Action`,
`NullAction`,
`CmdRunAction`,
`FileWriteAction`,
`FileReadAction`,
`AgentRecallAction`,
`BrowseURLAction`,
`AgentThinkAction`
### Observations:
`Observation`,
`NullObservation`,
`CmdOutputObservation`,
`FileReadObservation`,
`AgentRecallObservation`,
`BrowserOutputObservation`
### Methods:
`__init__`: Initializes the agent with a long term memory, and an internal monologue
`_add_event`: Appends events to the monologue of the agent and condenses with summary automatically if the monologue is too long
`_initialize`: Utilizes the `INITIAL_THOUGHTS` list to give the agent a context for its capabilities and how to navigate the `/workspace`
`step`: Modifies the current state by adding the most recent actions and observations, then prompts the model to think about its next action to take.
`search_memory`: Uses `VectorIndexRetriever` to find related memories within the long term memory.
## Planner Agent:
### Description:
The planner agent utilizes a special prompting strategy to create long term plans for solving problems.
The agent is given its previous action-observation pairs, current task, and hint based on last action taken at every step.
### Actions:
`NullAction`,
`CmdRunAction`,
`CmdKillAction`,
`BrowseURLAction`,
`FileReadAction`,
`FileWriteAction`,
`AgentRecallAction`,
`AgentThinkAction`,
`AgentFinishAction`,
`AgentSummarizeAction`,
`AddTaskAction`,
`ModifyTaskAction`,
### Observations:
`Observation`,
`NullObservation`,
`CmdOutputObservation`,
`FileReadObservation`,
`AgentRecallObservation`,
`BrowserOutputObservation`
### Methods:
`__init__`: Initializes an agent with `llm`
`step`: Checks to see if current step is completed, returns `AgentFinishAction` if True. Otherwise, creates a plan prompt and sends to model for inference, adding the result as the next action.
`search_memory`: Not yet implemented
## CodeAct Agent:
### Description:
The Code Act Agent is a minimalist agent. The agent works by passing the model a list of action-observation pairs and prompting the model to take the next step.
### Actions:
`Action`,
`CmdRunAction`,
`AgentEchoAction`,
`AgentFinishAction`,
### Observations:
`CmdOutputObservation`,
`AgentMessageObservation`,
### Methods:
`__init__`: Initializes an agent with `llm` and a list of messages `List[Mapping[str, str]]`
`step`: First, gets messages from state and then compiles them into a list for context. Next, pass the context list with the prompt to get the next command to execute. Finally, Execute command if valid, else return `AgentEchoAction(INVALID_INPUT_MESSAGE)`
`search_memory`: Not yet implemented

View File

@@ -1,253 +0,0 @@
> 警告:此说明文件可能已过时。应将 README.md 视为真实的来源。如果您注意到差异,请打开一个拉取请求以更新此说明文件。
[English](../README.md) | [中文](README-zh.md)
<a name="readme-top"></a>
<!--
*** Thanks for checking out the Best-README-Template. If you have a suggestion
*** that would make this better, please fork the repo and create a pull request
*** or simply open an issue with the tag "enhancement".
*** Don't forget to give the project a star!
*** Thanks again! Now go create something AMAZING! :D
-->
<!-- PROJECT SHIELDS -->
<!--
*** I'm using markdown "reference style" links for readability.
*** Reference links are enclosed in brackets [ ] instead of parentheses ( ).
*** See the bottom of this document for the declaration of the reference variables
*** for contributors-url, forks-url, etc. This is an optional, concise syntax you may use.
*** https://www.markdownguide.org/basic-syntax/#reference-style-links
-->
<div align="center">
<a href="https://github.com/OpenDevin/OpenDevin/graphs/contributors"><img src="https://img.shields.io/github/contributors/opendevin/opendevin?style=for-the-badge" alt="Contributors"></a>
<a href="https://github.com/OpenDevin/OpenDevin/network/members"><img src="https://img.shields.io/github/forks/opendevin/opendevin?style=for-the-badge" alt="Forks"></a>
<a href="https://github.com/OpenDevin/OpenDevin/stargazers"><img src="https://img.shields.io/github/stars/opendevin/opendevin?style=for-the-badge" alt="Stargazers"></a>
<a href="https://github.com/OpenDevin/OpenDevin/issues"><img src="https://img.shields.io/github/issues/opendevin/opendevin?style=for-the-badge" alt="Issues"></a>
<a href="https://github.com/OpenDevin/OpenDevin/blob/main/LICENSE"><img src="https://img.shields.io/github/license/opendevin/opendevin?style=for-the-badge" alt="MIT License"></a>
</br>
<a href="https://join.slack.com/t/opendevin/shared_invite/zt-2etftj1dd-X1fDL2PYIVpsmJZkqEYANw"><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/mBuDGRzzES"><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>
</div>
<!-- PROJECT LOGO -->
<div align="center">
<img src="../logo.png" alt="Logo" width="200" height="200">
<h1 align="center">OpenDevin少写代码多创作</h1>
</div>
<!-- TABLE OF CONTENTS -->
<details>
<summary>🗂️ Table of Contents</summary>
<ol>
<li><a href="#-mission">🎯 Mission</a></li>
<li><a href="#-what-is-devin">🤔 What is Devin?</a></li>
<li><a href="#-why-opendevin">🐚 Why OpenDevin?</a></li>
<li><a href="#-project-status">🚧 Project Status</a></li>
<a href="#-get-started">🚀 Get Started</a>
<ul>
<li><a href="#1-requirements">1. Requirements</a></li>
<li><a href="#2-build-and-setup">2. Build and Setup</a></li>
<li><a href="#3-run-the-application">3. Run the Application</a></li>
<li><a href="#4-individual-server-startup">4. Individual Server Startup</a></li>
<li><a href="#5-help">5. Help</a></li>
</ul>
</li>
<li><a href="#%EF%B8%8F-research-strategy">⭐️ Research Strategy</a></li>
<li><a href="#-how-to-contribute">🤝 How to Contribute</a></li>
<li><a href="#-join-our-community">🤖 Join Our Community</a></li>
<li><a href="#%EF%B8%8F-built-with">🛠️ Built With</a></li>
<li><a href="#-license">📜 License</a></li>
</ol>
</details>
## 🎯 使命
[Project Demo Video](https://github.com/OpenDevin/OpenDevin/assets/38853559/71a472cc-df34-430c-8b1d-4d7286c807c9)
欢迎来到 OpenDevin一个开源项目旨在复制 Devin一款自主的 AI 软件工程师,能够执行复杂的工程任务,并与用户积极合作,共同进行软件开发项目。该项目立志通过开源社区的力量复制、增强和创新 Devin。
<p align="right" style="font-size: 14px; color: #555; margin-top: 20px;">
<a href="#readme-top" style="text-decoration: none; color: #007bff; font-weight: bold;">
↑ Back to Top ↑
</a>
</p>
## 🤔 Devin 是什么?
Devin 代表着一种尖端的自主代理程序,旨在应对软件工程的复杂性。它利用诸如 shell、代码编辑器和 Web 浏览器等工具的组合,展示了在软件开发中利用 LLMs大型语言模型的未开发潜力。我们的目标是探索和拓展 Devin 的能力,找出其优势和改进空间,以指导开源代码模型的进展。
<p align="right" style="font-size: 14px; color: #555; margin-top: 20px;">
<a href="#readme-top" style="text-decoration: none; color: #007bff; font-weight: bold;">
↑ Back to Top ↑
</a>
</p>
## 🐚 为什么选择 OpenDevin
OpenDevin 项目源于对复制、增强和超越原始 Devin 模型的愿望。通过与开源社区的互动,我们旨在解决 Code LLMs 在实际场景中面临的挑战,创作出对社区有重大贡献并为未来进步铺平道路的作品。
<p align="right" style="font-size: 14px; color: #555; margin-top: 20px;">
<a href="#readme-top" style="text-decoration: none; color: #007bff; font-weight: bold;">
↑ Back to Top ↑
</a>
</p>
## 🚧 项目状态
OpenDevin 目前仍在进行中,但您已经可以运行 alpha 版本来查看端到端系统的运行情况。项目团队正在积极努力实现以下关键里程碑:
- **用户界面UI**:开发用户友好的界面,包括聊天界面、演示命令的 shell 和 Web 浏览器。
- **架构**:构建一个稳定的代理框架,具有强大的后端,可以读取、写入和运行简单的命令。
- **代理能力**:增强代理的能力,以生成 bash 脚本、运行测试和执行其他软件工程任务。
- **评估**:建立一个与 Devin 评估标准一致的最小评估流水线。
在完成 MVP 后,团队将专注于各个领域的研究,包括基础模型、专家能力、评估和代理研究。
<p align="right" style="font-size: 14px; color: #555; margin-top: 20px;">
<a href="#readme-top" style="text-decoration: none; color: #007bff; font-weight: bold;">
↑ Back to Top ↑
</a>
</p>
## ⚠️ 注意事项和警告
- OpenDevin 仍然是一个 alpha 项目。它变化很快且不稳定。我们正在努力在未来几周发布稳定版本。
- OpenDevin 会向您配置的 LLM 发出许多提示。大多数 LLM 都需要花费金钱,请务必设置花费限制并监控使用情况。
- OpenDevin 在 Docker 沙箱中运行 `bash` 命令,因此不应影响您的计算机。但您的工作区目录将附加到该沙箱,并且目录中的文件可能会被修改或删除。
- 我们默认的代理目前是 MonologueAgent具有有限的功能但相当稳定。我们正在开发其他代理实现包括 [SWE 代理](https://swe-agent.com/)。您可以[在这里阅读我们当前的代理集合](./docs/documentation/Agents.md)。
## 🚀 开始
开始使用 OpenDevin 项目非常简单。按照以下简单步骤在您的系统上设置和运行 OpenDevin
运行 OpenDevin 最简单的方法是在 Docker 容器中。
您可以运行:
```bash
# 您的 OpenAI API 密钥,或任何其他 LLM API 密钥
export LLM_API_KEY="sk-..."
# 您想要 OpenDevin 修改的目录。必须是绝对路径!
export WORKSPACE_BASE=$(pwd)/workspace
docker run \
-e LLM_API_KEY \
-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/opendevin/opendevin:latest
```
`$(pwd)/workspace` 替换为您希望 OpenDevin 使用的代码路径。
您可以在 `http://localhost:3000` 找到正在运行的 OpenDevin。
请参阅[Development.md](Development.md)以获取在没有 Docker 的情况下运行 OpenDevin 的说明。
## 🤖 LLM 后端
OpenDevin 可以与任何 LLM 后端配合使用。
要获取提供的 LM 提供商和模型的完整列表,请参阅
[litellm 文档](https://docs.litellm.ai/docs/providers)。
`LLM_MODEL` 环境变量控制在编程交互中使用哪个模型,
但在 OpenDevin UI 中选择模型将覆盖此设置。
对于某些 LLM可能需要以下环境变量
- `LLM_API_KEY`
- `LLM_BASE_URL`
- `LLM_EMBEDDING_MODEL`
- `LLM_EMBEDDING_DEPLOYMENT_NAME`
- `LLM_API_VERSION`
**关于替代模型的说明:**
某些替代模型可能比其他模型更具挑战性。
不要害怕,勇敢的冒险家!我们将很快公布 LLM 特定的文档,指导您完成您的探险。
如果您已经掌握了除 OpenAI 的 GPT 之外的模型使用技巧,
我们鼓励您[与我们分享您的设置说明](https://github.com/OpenDevin/OpenDevin/issues/417)。
还有[使用 ollama 运行本地模型的文档](./docs/documentation/LOCAL_LLM_GUIDE.md)。
## ⭐️ 研究策略
利用 LLMs 实现生产级应用程序的完全复制是一个复杂的任务。我们的策略包括:
1. **核心技术研究:** 专注于基础研究,以了解和改进代码生成和处理的技术方面。
2. **专业能力:** 通过数据整理、训练方法等手段增强核心组件的效能。
3. **任务规划:** 开发能力,用于错误检测、代码库管理和优化。
4. **评估:** 建立全面的评估指标,以更好地了解和改进我们的模型。
<p align="right" style="font-size: 14px; color: #555; margin-top: 20px;">
<a href="#readme-top" style="text-decoration: none; color: #007bff; font-weight: bold;">
↑ Back to Top ↑
</a>
</p>
## 🤝 如何贡献
OpenDevin 是一个社区驱动的项目,我们欢迎所有人的贡献。无论您是开发人员、研究人员,还是对利用人工智能推动软件工程领域发展充满热情的人,都有许多参与方式:
- **代码贡献:** 帮助我们开发核心功能、前端界面或沙盒解决方案。
- **研究和评估:** 为我们对软件工程中的 LLMs 的理解做出贡献,参与评估模型,或提出改进意见。
- **反馈和测试:** 使用 OpenDevin 工具集,报告错误,提出功能建议,或就可用性提供反馈。
详情请查看[此文档](./CONTRIBUTING.md)。
<p align="right" style="font-size: 14px; color: #555; margin-top: 20px;">
<a href="#readme-top" style="text-decoration: none; color: #007bff; font-weight: bold;">
↑ Back to Top ↑
</a>
</p>
## 🤖 加入我们的社区
现在我们既有 Slack 工作空间用于协作构建 OpenDevin也有 Discord 服务器用于讨论与项目、LLM、Agent 等相关的任何事情。
- [Slack 工作空间](https://join.slack.com/t/opendevin/shared_invite/zt-2etftj1dd-X1fDL2PYIVpsmJZkqEYANw)
- [Discord 服务器](https://discord.gg/mBuDGRzzES)
如果你愿意贡献,欢迎加入我们的社区(请注意,现在无需填写[表格](https://forms.gle/758d5p6Ve8r2nxxq6))。让我们一起简化软件工程!
🐚 **少写代码,用 OpenDevin 创造更多。**
[![Star History Chart](https://api.star-history.com/svg?repos=OpenDevin/OpenDevin&type=Date)](https://star-history.com/#OpenDevin/OpenDevin&Date)
## 🛠️ 技术栈
OpenDevin 使用了一系列强大的框架和库的组合,为其开发提供了坚实的基础。以下是项目中使用的关键技术:
![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)
请注意,这些技术的选择正在进行中,随着项目的发展,可能会添加其他技术或移除现有技术。我们致力于采用最合适和最有效的工具,以增强 OpenDevin 的功能。
<p align="right" style="font-size: 14px; color: #555; margin-top: 20px;">
<a href="#readme-top" style="text-decoration: none; color: #007bff; font-weight: bold;">
↑ Back to Top ↑
</a>
</p>
## 📜 许可证
根据 MIT 许可证分发。有关更多信息,请参阅 [`LICENSE`](./LICENSE)。
<p align="right" style="font-size: 14px; color: #555; margin-top: 20px;">
<a href="#readme-top" style="text-decoration: none; color: #007bff; font-weight: bold;">
↑ Back to Top ↑
</a>
</p>
[contributors-shield]: https://img.shields.io/github/contributors/opendevin/opendevin?style=for-the-badge
[contributors-url]: https://github.com/OpenDevin/OpenDevin/graphs/contributors
[forks-shield]: https://img.shields.io/github/forks/opendevin/opendevin?style=for-the-badge
[forks-url]: https://github.com/OpenDevin/OpenDevin/network/members
[stars-shield]: https://img.shields.io/github/stars/opendevin/opendevin?style=for-the-badge
[stars-url]: https://github.com/OpenDevin/OpenDevin/stargazers
[issues-shield]: https://img.shields.io/github/issues/opendevin/opendevin?style=for-the-badge
[issues-url]: https://github.com/OpenDevin/OpenDevin/issues
[license-shield]: https://img.shields.io/github/license/opendevin/opendevin?style=for-the-badge
[license-url]: https://github.com/OpenDevin/OpenDevin/blob/main/LICENSE

41
docs/README.md Normal file
View File

@@ -0,0 +1,41 @@
# Website
This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator.
### Installation
```
$ yarn
```
### Local Development
```
$ yarn start
```
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
### Build
```
$ yarn build
```
This command generates static content into the `build` directory and can be served using any static contents hosting service.
### Deployment
Using SSH:
```
$ USE_SSH=true yarn deploy
```
Not using SSH:
```
$ GIT_USER=<Your GitHub username> yarn deploy
```
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.

View File

@@ -1,14 +0,0 @@
# System Architecture Overview
This is a high-level overview of the system architecture. The system is divided into two main components: the frontend and the backend. The frontend is responsible for handling user interactions and displaying the results. The backend is responsible for handling the business logic and executing the agents.
![system_architecture.svg](system_architecture.svg)
This Overview is simplified to show the main components and their interactions. For a more detailed view of the backend architecture, see the [Backend Architecture](#backend-architecture) section.
# Backend Architecture
*__Disclaimer__: The backend architecture is a work in progress and is subject to change. The following diagram shows the current architecture of the backend based on the commit that is shown in the footer of the diagram.*
![backend_architecture.svg](backend_architecture.svg)

View File

@@ -1,23 +0,0 @@
# Process for updating the backend architecture diagram
The generation of the backend architecture diagram is partially automated. The diagram is generated from the type hints in the code using the py2puml tool. The diagram is then manually reviewed, adjusted and exported to PNG and SVG.
## Prerequisites
- Running python environment in which opendevin is executable (according to the instructions in the README.md file in the root of the repository)
- [py2puml](https://github.com/lucsorel/py2puml) installed
## Steps
1. Autogenerate the diagram by running the following command from the root of the repository:
```py2puml opendevin opendevin > docs/architecture/backend_architecture.puml```
2. Open the generated file in a PlantUML editor, e.g. Visual Studio Code with the PlantUML extension or [PlantText](https://www.planttext.com/)
3. Review the generated PUML and make all necessary adjustments to the diagram (add missing parts, fix mistakes, improve positioning).
*py2puml creates the diagram based on the type hints in the code, so missing or incorrect type hints may result in an incomplete or incorrect diagram.*
4. Review the diff between the new and the previous diagram and manually check if the changes are correct.
*Make sure not to remove parts that were manually added to the diagram in the past and are still relevant.*
4. Add the commit hash of the commit that was used to generate the diagram to the diagram footer.
5. Export the diagram as PNG and SVG files and replace the existing diagrams in the `docs/architecture` directory. This can be done with (e.g. [PlantText](https://www.planttext.com/))

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

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

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

@@ -0,0 +1,128 @@
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: "OpenDevin",
tagline: "Code Less, Make More",
favicon: "img/logo.png",
// Set the production url of your site here
url: "https://OpenDevin.github.io",
baseUrl: "/OpenDevin/",
// GitHub pages deployment config.
organizationName: "OpenDevin",
projectName: "OpenDevin",
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"],
},
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: "OpenDevin",
logo: {
alt: "OpenDevin",
src: "img/logo.png",
},
items: [
{
type: "docSidebar",
sidebarId: "docsSidebar",
position: "left",
label: "Docs",
},
{
type: "docSidebar",
sidebarId: "apiSidebar",
position: "left",
label: "Codebase",
},
{ to: "/faq", label: "FAQ", position: "left" },
{
href: "https://github.com/OpenDevin/OpenDevin",
label: "GitHub",
position: "right",
},
],
},
footer: {
style: "dark",
links: [
{
title: "OpenDevin",
items: [
{
label: "Docs",
to: "/modules/usage/intro",
},
],
},
{
title: "Community",
items: [
{
label: "Slack",
href: "https://join.slack.com/t/opendevin/shared_invite/zt-2etftj1dd-X1fDL2PYIVpsmJZkqEYANw",
},
{
label: "Discord",
href: "https://discord.gg/mBuDGRzzES",
},
],
},
{
title: "More",
items: [
{
label: "GitHub",
href: "https://github.com/OpenDevin/OpenDevin",
},
],
},
],
copyright: `Copyright © ${new Date().getFullYear()} OpenDevin`,
},
prism: {
theme: prismThemes.oneLight,
darkTheme: prismThemes.oneDark,
},
} satisfies Preset.ThemeConfig,
};
export default config;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

View File

@@ -0,0 +1,34 @@
---
sidebar_label: agent
title: agenthub.SWE_agent.agent
---
## SWEAgent Objects
```python
class SWEAgent(Agent)
```
An attempt to recreate swe_agent with output parsing, prompting style, and Application Computer Interface (ACI).
SWE-agent includes ACI functions like &#x27;goto&#x27;, &#x27;search_for&#x27;, &#x27;edit&#x27;, &#x27;scroll&#x27;, &#x27;run&#x27;
#### step
```python
def step(state: State) -> Action
```
SWE-Agent step:
1. Get context - past actions, custom commands, current step
2. Perform think-act - prompt model for action and reasoning
3. Catch errors - ensure model takes action (5 attempts max)
#### reset
```python
def reset() -> None
```
Used to reset the agent

View File

@@ -0,0 +1,34 @@
---
sidebar_label: parser
title: agenthub.SWE_agent.parser
---
#### get\_action\_from\_string
```python
def get_action_from_string(command_string: str,
path: str,
line: int,
thoughts: str = '') -> Action | None
```
Parses the command string to find which command the agent wants to run
Converts the command into a proper Action and returns
#### parse\_command
```python
def parse_command(input_str: str, path: str, line: int)
```
Parses a given string and separates the command (enclosed in triple backticks) from any accompanying text.
**Arguments**:
- `input_str` _str_ - The input string to be parsed.
**Returns**:
- `tuple` - A tuple containing the command and the accompanying text (if any).

View File

@@ -0,0 +1,50 @@
---
sidebar_label: codeact_agent
title: agenthub.codeact_agent.codeact_agent
---
## CodeActAgent Objects
```python
class CodeActAgent(Agent)
```
The Code Act Agent is a minimalist agent.
The agent works by passing the model a list of action-observation pairs and prompting the model to take the next step.
#### \_\_init\_\_
```python
def __init__(llm: LLM) -> None
```
Initializes a new instance of the CodeActAgent class.
**Arguments**:
- llm (LLM): The llm to be used by this agent
#### step
```python
def step(state: State) -> Action
```
Performs one step using the Code Act Agent.
This includes gathering info on previous steps and prompting the model to make a command to execute.
**Arguments**:
- state (State): used to get updated info and background commands
**Returns**:
- CmdRunAction(command) - command action to run
- AgentEchoAction(content=INVALID_INPUT_MESSAGE) - invalid command output
**Raises**:
- NotImplementedError - for actions other than CmdOutputObservation or AgentMessageObservation

View File

@@ -0,0 +1,45 @@
---
sidebar_label: agent
title: agenthub.delegator_agent.agent
---
## DelegatorAgent Objects
```python
class DelegatorAgent(Agent)
```
The planner agent utilizes a special prompting strategy to create long term plans for solving problems.
The agent is given its previous action-observation pairs, current task, and hint based on last action taken at every step.
#### \_\_init\_\_
```python
def __init__(llm: LLM)
```
Initialize the Delegator Agent with an LLM
**Arguments**:
- llm (LLM): The llm to be used by this agent
#### step
```python
def step(state: State) -> Action
```
Checks to see if current step is completed, returns AgentFinishAction if True.
Otherwise, creates a plan prompt and sends to model for inference, returning the result as the next action.
**Arguments**:
- state (State): The current state given the previous actions and observations
**Returns**:
- AgentFinishAction: If the last state was &#x27;completed&#x27;, &#x27;verified&#x27;, or &#x27;abandoned&#x27;
- Action: The next action to take based on llm response

View File

@@ -0,0 +1,15 @@
---
sidebar_label: agent
title: agenthub.dummy_agent.agent
---
Module for a Dummy agent.
## DummyAgent Objects
```python
class DummyAgent(Agent)
```
A dummy agent that does nothing but can be used in testing.

View File

@@ -0,0 +1,30 @@
---
sidebar_label: agent
title: agenthub.micro.agent
---
#### my\_encoder
```python
def my_encoder(obj)
```
Encodes objects as dictionaries
**Arguments**:
- obj (Object): An object that will be converted
**Returns**:
- dict: If the object can be converted it is returned in dict format
#### to\_json
```python
def to_json(obj, **kwargs)
```
Serialize an object to str format

View File

@@ -0,0 +1,62 @@
---
sidebar_label: agent
title: agenthub.monologue_agent.agent
---
## MonologueAgent Objects
```python
class MonologueAgent(Agent)
```
The Monologue Agent utilizes long and short term memory to complete tasks.
Long term memory is stored as a LongTermMemory object and the model uses it to search for examples from the past.
Short term memory is stored as a Monologue object and the model can condense it as necessary.
#### \_\_init\_\_
```python
def __init__(llm: LLM)
```
Initializes the Monologue Agent with an llm, monologue, and memory.
**Arguments**:
- llm (LLM): The llm to be used by this agent
#### step
```python
def step(state: State) -> Action
```
Modifies the current state by adding the most recent actions and observations, then prompts the model to think about it&#x27;s next action to take using monologue, memory, and hint.
**Arguments**:
- state (State): The current state based on previous steps taken
**Returns**:
- Action: The next action to take based on LLM response
#### search\_memory
```python
def search_memory(query: str) -> List[str]
```
Uses VectorIndexRetriever to find related memories within the long term memory.
Uses search to produce top 10 results.
**Arguments**:
- query (str): The query that we want to find related memories for
**Returns**:
- List[str]: A list of top 10 text results that matched the query

View File

@@ -0,0 +1,38 @@
---
sidebar_label: json
title: agenthub.monologue_agent.utils.json
---
#### my\_encoder
```python
def my_encoder(obj)
```
Encodes objects as dictionaries
**Arguments**:
- obj (Object): An object that will be converted
**Returns**:
- dict: If the object can be converted it is returned in dict format
#### dumps
```python
def dumps(obj, **kwargs)
```
Serialize an object to str format
#### loads
```python
def loads(s, **kwargs)
```
Create a JSON object from str

View File

@@ -0,0 +1,52 @@
---
sidebar_label: memory
title: agenthub.monologue_agent.utils.memory
---
## LongTermMemory Objects
```python
class LongTermMemory()
```
Responsible for storing information that the agent can call on later for better insights and context.
Uses chromadb to store and search through memories.
#### \_\_init\_\_
```python
def __init__()
```
Initialize the chromadb and set up ChromaVectorStore for later use.
#### add\_event
```python
def add_event(event: dict)
```
Adds a new event to the long term memory with a unique id.
**Arguments**:
- event (dict): The new event to be added to memory
#### search
```python
def search(query: str, k: int = 10)
```
Searches through the current memory using VectorIndexRetriever
**Arguments**:
- query (str): A query to match search results to
- k (int): Number of top results to return
**Returns**:
- List[str]: List of top k results found in current memory

View File

@@ -0,0 +1,80 @@
---
sidebar_label: monologue
title: agenthub.monologue_agent.utils.monologue
---
## Monologue Objects
```python
class Monologue()
```
The monologue is a representation for the agent&#x27;s internal monologue where it can think.
The agent has the capability of using this monologue for whatever it wants.
#### \_\_init\_\_
```python
def __init__()
```
Initialize the empty list of thoughts
#### add\_event
```python
def add_event(t: dict)
```
Adds an event to memory if it is a valid event.
**Arguments**:
- t (dict): The thought that we want to add to memory
**Raises**:
- AgentEventTypeError: If t is not a dict
#### get\_thoughts
```python
def get_thoughts()
```
Get the current thoughts of the agent.
**Returns**:
- List: The list of thoughts that the agent has.
#### get\_total\_length
```python
def get_total_length()
```
Gives the total number of characters in all thoughts
**Returns**:
- Int: Total number of chars in thoughts.
#### condense
```python
def condense(llm: LLM)
```
Attempts to condense the monologue by using the llm
**Arguments**:
- llm (LLM): llm to be used for summarization
**Raises**:
- Exception: the same exception as it got from the llm or processing the response

View File

@@ -0,0 +1,73 @@
---
sidebar_label: prompts
title: agenthub.monologue_agent.utils.prompts
---
#### get\_summarize\_monologue\_prompt
```python
def get_summarize_monologue_prompt(thoughts: List[dict])
```
Gets the prompt for summarizing the monologue
**Returns**:
- str: A formatted string with the current monologue within the prompt
#### get\_request\_action\_prompt
```python
def get_request_action_prompt(
task: str,
thoughts: List[dict],
background_commands_obs: List[CmdOutputObservation] = [])
```
Gets the action prompt formatted with appropriate values.
**Arguments**:
- task (str): The current task the agent is trying to accomplish
- thoughts (List[dict]): The agent&#x27;s current thoughts
- background_commands_obs (List[CmdOutputObservation]): List of all observed background commands running
**Returns**:
- str: Formatted prompt string with hint, task, monologue, and background included
#### parse\_action\_response
```python
def parse_action_response(response: str) -> Action
```
Parses a string to find an action within it
**Arguments**:
- response (str): The string to be parsed
**Returns**:
- Action: The action that was found in the response string
#### parse\_summary\_response
```python
def parse_summary_response(response: str) -> List[dict]
```
Parses a summary of the monologue
**Arguments**:
- response (str): The response string to be parsed
**Returns**:
- List[dict]: The list of summaries output by the model

View File

@@ -0,0 +1,45 @@
---
sidebar_label: agent
title: agenthub.planner_agent.agent
---
## PlannerAgent Objects
```python
class PlannerAgent(Agent)
```
The planner agent utilizes a special prompting strategy to create long term plans for solving problems.
The agent is given its previous action-observation pairs, current task, and hint based on last action taken at every step.
#### \_\_init\_\_
```python
def __init__(llm: LLM)
```
Initialize the Planner Agent with an LLM
**Arguments**:
- llm (LLM): The llm to be used by this agent
#### step
```python
def step(state: State) -> Action
```
Checks to see if current step is completed, returns AgentFinishAction if True.
Otherwise, creates a plan prompt and sends to model for inference, returning the result as the next action.
**Arguments**:
- state (State): The current state given the previous actions and observations
**Returns**:
- AgentFinishAction: If the last state was &#x27;completed&#x27;, &#x27;verified&#x27;, or &#x27;abandoned&#x27;
- Action: The next action to take based on llm response

View File

@@ -0,0 +1,49 @@
---
sidebar_label: prompt
title: agenthub.planner_agent.prompt
---
#### get\_hint
```python
def get_hint(latest_action_id: str) -> str
```
Returns action type hint based on given action_id
#### get\_prompt
```python
def get_prompt(plan: Plan, history: List[Tuple[Action, Observation]]) -> str
```
Gets the prompt for the planner agent.
Formatted with the most recent action-observation pairs, current task, and hint based on last action
**Arguments**:
- plan (Plan): The original plan outlined by the user with LLM defined tasks
- history (List[Tuple[Action, Observation]]): List of corresponding action-observation pairs
**Returns**:
- str: The formatted string prompt with historical values
#### parse\_response
```python
def parse_response(response: str) -> Action
```
Parses the model output to find a valid action to take
**Arguments**:
- response (str): A response from the model that potentially contains an Action.
**Returns**:
- Action: A valid next action to perform from model output

View File

@@ -0,0 +1,9 @@
---
sidebar_label: action
title: opendevin.action
---
#### ACTION\_TYPE\_TO\_CLASS
type: ignore[attr-defined]

View File

@@ -0,0 +1,14 @@
---
sidebar_label: base
title: opendevin.action.base
---
## NullAction Objects
```python
@dataclass
class NullAction(NotExecutableAction)
```
An action that does nothing.

View File

@@ -0,0 +1,16 @@
---
sidebar_label: fileop
title: opendevin.action.fileop
---
## FileReadAction Objects
```python
@dataclass
class FileReadAction(ExecutableAction)
```
Reads a file from a given path.
Can be set to read specific lines using start and end
Default lines 0:-1 (whole file)

View File

@@ -0,0 +1,46 @@
---
sidebar_label: github
title: opendevin.action.github
---
## GitHubPushAction Objects
```python
@dataclass
class GitHubPushAction(ExecutableAction)
```
This pushes the current branch to github.
To use this, you need to set the GITHUB_TOKEN environment variable.
The agent will return a message with a URL that you can click to make a pull
request.
**Attributes**:
- `owner` - The owner of the source repo
- `repo` - The name of the source repo
- `branch` - The branch to push
- `action` - The action identifier
## GitHubSendPRAction Objects
```python
@dataclass
class GitHubSendPRAction(ExecutableAction)
```
An action to send a github PR.
To use this, you need to set the GITHUB_TOKEN environment variable.
**Attributes**:
- `owner` - The owner of the source repo
- `repo` - The name of the source repo
- `title` - The title of the PR
- `head` - The branch to send the PR from
- `head_repo` - The repo to send the PR from
- `base` - The branch to send the PR to
- `body` - The body of the PR

View File

@@ -0,0 +1,14 @@
---
sidebar_label: tasks
title: opendevin.action.tasks
---
## TaskStateChangedAction Objects
```python
@dataclass
class TaskStateChangedAction(NotExecutableAction)
```
Fake action, just to notify the client that a task state has changed.

View File

@@ -0,0 +1,121 @@
---
sidebar_label: agent
title: opendevin.agent
---
## Agent Objects
```python
class Agent(ABC)
```
This abstract base class is an general interface for an agent dedicated to
executing a specific instruction and allowing human interaction with the
agent during execution.
It tracks the execution status and maintains a history of interactions.
#### complete
```python
@property
def complete() -> bool
```
Indicates whether the current instruction execution is complete.
**Returns**:
- complete (bool): True if execution is complete; False otherwise.
#### step
```python
@abstractmethod
def step(state: 'State') -> 'Action'
```
Starts the execution of the assigned instruction. This method should
be implemented by subclasses to define the specific execution logic.
#### search\_memory
```python
@abstractmethod
def search_memory(query: str) -> List[str]
```
Searches the agent&#x27;s memory for information relevant to the given query.
**Arguments**:
- query (str): The query to search for in the agent&#x27;s memory.
**Returns**:
- response (str): The response to the query.
#### reset
```python
def reset() -> None
```
Resets the agent&#x27;s execution status and clears the history. This method can be used
to prepare the agent for restarting the instruction or cleaning up before destruction.
#### register
```python
@classmethod
def register(cls, name: str, agent_cls: Type['Agent'])
```
Registers an agent class in the registry.
**Arguments**:
- name (str): The name to register the class under.
- agent_cls (Type[&#x27;Agent&#x27;]): The class to register.
**Raises**:
- AgentAlreadyRegisteredError: If name already registered
#### get\_cls
```python
@classmethod
def get_cls(cls, name: str) -> Type['Agent']
```
Retrieves an agent class from the registry.
**Arguments**:
- name (str): The name of the class to retrieve
**Returns**:
- agent_cls (Type[&#x27;Agent&#x27;]): The class registered under the specified name.
**Raises**:
- AgentNotRegisteredError: If name not registered
#### list\_agents
```python
@classmethod
def list_agents(cls) -> list[str]
```
Retrieves the list of all agent names from the registry.
**Raises**:
- AgentNotRegisteredError: If no agent is registered

View File

@@ -0,0 +1,13 @@
---
sidebar_label: config
title: opendevin.config
---
#### get
```python
def get(key: ConfigType, required: bool = False)
```
Get a key from the environment variables or config.toml or default configs.

View File

@@ -0,0 +1,36 @@
---
sidebar_label: agent_controller
title: opendevin.controller.agent_controller
---
## AgentController Objects
```python
class AgentController()
```
#### setup\_task
```python
async def setup_task(task: str, inputs: dict = {})
```
Sets up the agent controller with a task.
#### start
```python
async def start(task: str)
```
Starts the agent controller with a task.
If task already run before, it will continue from the last step.
#### get\_task\_state
```python
def get_task_state()
```
Returns the current state of the agent task.

View File

@@ -0,0 +1,40 @@
---
sidebar_label: files
title: opendevin.files
---
## WorkspaceFile Objects
```python
class WorkspaceFile()
```
#### to\_dict
```python
def to_dict() -> Dict[str, Any]
```
Converts the File object to a dictionary.
**Returns**:
The dictionary representation of the File object.
#### get\_folder\_structure
```python
def get_folder_structure(workdir: Path) -> WorkspaceFile
```
Gets the folder structure of a directory.
**Arguments**:
- `workdir` - The directory path.
**Returns**:
The folder structure.

View File

@@ -0,0 +1,56 @@
---
sidebar_label: llm
title: opendevin.llm.llm
---
## LLM Objects
```python
class LLM()
```
The LLM class represents a Language Model instance.
#### \_\_init\_\_
```python
def __init__(model=DEFAULT_MODEL_NAME,
api_key=DEFAULT_API_KEY,
base_url=DEFAULT_BASE_URL,
api_version=DEFAULT_API_VERSION,
num_retries=LLM_NUM_RETRIES,
retry_min_wait=LLM_RETRY_MIN_WAIT,
retry_max_wait=LLM_RETRY_MAX_WAIT,
llm_timeout=LLM_TIMEOUT,
llm_max_return_tokens=LLM_MAX_RETURN_TOKENS)
```
**Arguments**:
- `model` _str, optional_ - The name of the language model. Defaults to LLM_MODEL.
- `api_key` _str, optional_ - The API key for accessing the language model. Defaults to LLM_API_KEY.
- `base_url` _str, optional_ - The base URL for the language model API. Defaults to LLM_BASE_URL. Not necessary for OpenAI.
- `api_version` _str, optional_ - The version of the API to use. Defaults to LLM_API_VERSION. Not necessary for OpenAI.
- `num_retries` _int, optional_ - The number of retries for API calls. Defaults to LLM_NUM_RETRIES.
- `retry_min_wait` _int, optional_ - The minimum time to wait between retries in seconds. Defaults to LLM_RETRY_MIN_TIME.
- `retry_max_wait` _int, optional_ - The maximum time to wait between retries in seconds. Defaults to LLM_RETRY_MAX_TIME.
- `llm_timeout` _int, optional_ - The maximum time to wait for a response in seconds. Defaults to LLM_TIMEOUT.
- `llm_max_return_tokens` _int, optional_ - The maximum number of tokens to return. Defaults to LLM_MAX_RETURN_TOKENS.
**Attributes**:
- `model_name` _str_ - The name of the language model.
- `api_key` _str_ - The API key for accessing the language model.
- `base_url` _str_ - The base URL for the language model API.
- `api_version` _str_ - The version of the API to use.
#### completion
```python
@property
def completion()
```
Decorator for the litellm completion function.

View File

@@ -0,0 +1,92 @@
---
sidebar_label: logger
title: opendevin.logger
---
#### get\_console\_handler
```python
def get_console_handler()
```
Returns a console handler for logging.
#### get\_file\_handler
```python
def get_file_handler()
```
Returns a file handler for logging.
#### log\_uncaught\_exceptions
```python
def log_uncaught_exceptions(ex_cls, ex, tb)
```
Logs uncaught exceptions along with the traceback.
**Arguments**:
- `ex_cls` _type_ - The type of the exception.
- `ex` _Exception_ - The exception instance.
- `tb` _traceback_ - The traceback object.
**Returns**:
None
## LlmFileHandler Objects
```python
class LlmFileHandler(logging.FileHandler)
```
__LLM prompt and response logging__
#### \_\_init\_\_
```python
def __init__(filename, mode='a', encoding='utf-8', delay=False)
```
Initializes an instance of LlmFileHandler.
**Arguments**:
- `filename` _str_ - The name of the log file.
- `mode` _str, optional_ - The file mode. Defaults to &#x27;a&#x27;.
- `encoding` _str, optional_ - The file encoding. Defaults to None.
- `delay` _bool, optional_ - Whether to delay file opening. Defaults to False.
#### emit
```python
def emit(record)
```
Emits a log record.
**Arguments**:
- `record` _logging.LogRecord_ - The log record to emit.
#### get\_llm\_prompt\_file\_handler
```python
def get_llm_prompt_file_handler()
```
Returns a file handler for LLM prompt logging.
#### get\_llm\_response\_file\_handler
```python
def get_llm_response_file_handler()
```
Returns a file handler for LLM response logging.

View File

@@ -0,0 +1,29 @@
---
sidebar_label: main
title: opendevin.main
---
#### read\_task\_from\_file
```python
def read_task_from_file(file_path: str) -> str
```
Read task from the specified file.
#### read\_task\_from\_stdin
```python
def read_task_from_stdin() -> str
```
Read task from stdin.
#### main
```python
async def main(task_str: str = '')
```
Main coroutine to run the agent controller with task input flexibility.

View File

@@ -0,0 +1,9 @@
---
sidebar_label: observation
title: opendevin.observation
---
#### OBSERVATION\_TYPE\_TO\_CLASS
type: ignore[attr-defined]

View File

@@ -0,0 +1,49 @@
---
sidebar_label: base
title: opendevin.observation.base
---
## Observation Objects
```python
@dataclass
class Observation()
```
This data class represents an observation of the environment.
#### to\_dict
```python
def to_dict() -> dict
```
Converts the observation to a dictionary and adds user message.
#### to\_memory
```python
def to_memory() -> dict
```
Converts the observation to a dictionary.
#### message
```python
@property
def message() -> str
```
Returns a message describing the observation.
## NullObservation Objects
```python
@dataclass
class NullObservation(Observation)
```
This data class represents a null observation.
This is used when the produced action is NOT executable.

View File

@@ -0,0 +1,14 @@
---
sidebar_label: browse
title: opendevin.observation.browse
---
## BrowserOutputObservation Objects
```python
@dataclass
class BrowserOutputObservation(Observation)
```
This data class represents the output of a browser.

View File

@@ -0,0 +1,15 @@
---
sidebar_label: delegate
title: opendevin.observation.delegate
---
## AgentDelegateObservation Objects
```python
@dataclass
class AgentDelegateObservation(Observation)
```
This data class represents a delegate observation.
This is used when the produced action is NOT executable.

View File

@@ -0,0 +1,14 @@
---
sidebar_label: error
title: opendevin.observation.error
---
## AgentErrorObservation Objects
```python
@dataclass
class AgentErrorObservation(Observation)
```
This data class represents an error encountered by the agent.

View File

@@ -0,0 +1,23 @@
---
sidebar_label: files
title: opendevin.observation.files
---
## FileReadObservation Objects
```python
@dataclass
class FileReadObservation(Observation)
```
This data class represents the content of a file.
## FileWriteObservation Objects
```python
@dataclass
class FileWriteObservation(Observation)
```
This data class represents a file write operation

View File

@@ -0,0 +1,23 @@
---
sidebar_label: message
title: opendevin.observation.message
---
## UserMessageObservation Objects
```python
@dataclass
class UserMessageObservation(Observation)
```
This data class represents a message sent by the user.
## AgentMessageObservation Objects
```python
@dataclass
class AgentMessageObservation(Observation)
```
This data class represents a message sent by the agent.

View File

@@ -0,0 +1,14 @@
---
sidebar_label: recall
title: opendevin.observation.recall
---
## AgentRecallObservation Objects
```python
@dataclass
class AgentRecallObservation(Observation)
```
This data class represents a list of memories recalled by the agent.

View File

@@ -0,0 +1,14 @@
---
sidebar_label: run
title: opendevin.observation.run
---
## CmdOutputObservation Objects
```python
@dataclass
class CmdOutputObservation(Observation)
```
This data class represents the output of a command.

View File

@@ -0,0 +1,182 @@
---
sidebar_label: plan
title: opendevin.plan
---
## Task Objects
```python
class Task()
```
#### \_\_init\_\_
```python
def __init__(parent: 'Task | None',
goal: str,
state: str = OPEN_STATE,
subtasks: List = [])
```
Initializes a new instance of the Task class.
**Arguments**:
- `parent` - The parent task, or None if it is the root task.
- `goal` - The goal of the task.
- `state` - The initial state of the task.
- `subtasks` - A list of subtasks associated with this task.
#### to\_string
```python
def to_string(indent='')
```
Returns a string representation of the task and its subtasks.
**Arguments**:
- `indent` - The indentation string for formatting the output.
**Returns**:
A string representation of the task and its subtasks.
#### to\_dict
```python
def to_dict()
```
Returns a dictionary representation of the task.
**Returns**:
A dictionary containing the task&#x27;s attributes.
#### set\_state
```python
def set_state(state)
```
Sets the state of the task and its subtasks.
Args: state: The new state of the task.
**Raises**:
- `PlanInvalidStateError` - If the provided state is invalid.
#### get\_current\_task
```python
def get_current_task() -> 'Task | None'
```
Retrieves the current task in progress.
**Returns**:
The current task in progress, or None if no task is in progress.
## Plan Objects
```python
class Plan()
```
Represents a plan consisting of tasks.
**Attributes**:
- `main_goal` - The main goal of the plan.
- `task` - The root task of the plan.
#### \_\_init\_\_
```python
def __init__(task: str)
```
Initializes a new instance of the Plan class.
**Arguments**:
- `task` - The main goal of the plan.
#### \_\_str\_\_
```python
def __str__()
```
Returns a string representation of the plan.
**Returns**:
A string representation of the plan.
#### get\_task\_by\_id
```python
def get_task_by_id(id: str) -> Task
```
Retrieves a task by its ID.
**Arguments**:
- `id` - The ID of the task.
**Returns**:
The task with the specified ID.
**Raises**:
- `ValueError` - If the provided task ID is invalid or does not exist.
#### add\_subtask
```python
def add_subtask(parent_id: str, goal: str, subtasks: List = [])
```
Adds a subtask to a parent task.
**Arguments**:
- `parent_id` - The ID of the parent task.
- `goal` - The goal of the subtask.
- `subtasks` - A list of subtasks associated with the new subtask.
#### set\_subtask\_state
```python
def set_subtask_state(id: str, state: str)
```
Sets the state of a subtask.
**Arguments**:
- `id` - The ID of the subtask.
- `state` - The new state of the subtask.
#### get\_current\_task
```python
def get_current_task()
```
Retrieves the current task in progress.
**Returns**:
The current task in progress, or None if no task is in progress.

View File

@@ -0,0 +1,19 @@
---
sidebar_label: sandbox
title: opendevin.sandbox.e2b.sandbox
---
## E2BBox Objects
```python
class E2BBox(Sandbox)
```
#### copy\_to
```python
def copy_to(host_src: str, sandbox_dest: str, recursive: bool = False)
```
Copies a local file or directory to the sandbox.

View File

@@ -0,0 +1,16 @@
---
sidebar_label: jupyter
title: opendevin.sandbox.plugins.jupyter
---
## JupyterRequirement Objects
```python
@dataclass
class JupyterRequirement(PluginRequirement)
```
#### host\_src
The directory of this file (sandbox/plugins/jupyter)

View File

@@ -0,0 +1,21 @@
---
sidebar_label: mixin
title: opendevin.sandbox.plugins.mixin
---
## PluginMixin Objects
```python
class PluginMixin()
```
Mixin for Sandbox to support plugins.
#### init\_plugins
```python
def init_plugins(requirements: List[PluginRequirement])
```
Load a plugin into the sandbox.

View File

@@ -0,0 +1,14 @@
---
sidebar_label: requirement
title: opendevin.sandbox.plugins.requirement
---
## PluginRequirement Objects
```python
@dataclass
class PluginRequirement()
```
Requirement for a plugin.

View File

@@ -0,0 +1,76 @@
---
sidebar_label: action
title: opendevin.schema.action
---
## ActionTypeSchema Objects
```python
class ActionTypeSchema(BaseModel)
```
#### INIT
Initializes the agent. Only sent by client.
#### START
Starts a new development task. Only sent by the client.
#### READ
Reads the content of a file.
#### WRITE
Writes the content to a file.
#### RUN
Runs a command.
#### KILL
Kills a background command.
#### BROWSE
Opens a web page.
#### RECALL
Searches long-term memory
#### THINK
Allows the agent to make a plan, set a goal, or record thoughts
#### DELEGATE
Delegates a task to another agent.
#### FINISH
If you&#x27;re absolutely certain that you&#x27;ve completed your task and have tested your work,
use the finish action to stop working.
#### PAUSE
Pauses the task.
#### RESUME
Resumes the task.
#### STOP
Stops the task. Must send a start action to restart a new task.
#### PUSH
Push a branch to github.
#### SEND\_PR
Send a PR to github.

View File

@@ -0,0 +1,35 @@
---
sidebar_label: observation
title: opendevin.schema.observation
---
## ObservationTypeSchema Objects
```python
class ObservationTypeSchema(BaseModel)
```
#### READ
The content of a file
#### BROWSE
The HTML content of a URL
#### RUN
The output of a command
#### RECALL
The result of a search
#### CHAT
A message from the user
#### DELEGATE
The result of a task delegated to another agent

View File

@@ -0,0 +1,57 @@
---
sidebar_label: task
title: opendevin.schema.task
---
## TaskState Objects
```python
class TaskState(str, Enum)
```
#### INIT
Initial state of the task.
#### RUNNING
The task is running.
#### PAUSED
The task is paused.
#### STOPPED
The task is stopped.
#### FINISHED
The task is finished.
#### ERROR
An error occurred during the task.
## TaskStateAction Objects
```python
class TaskStateAction(str, Enum)
```
#### START
Starts the task.
#### PAUSE
Pauses the task.
#### RESUME
Resumes the task.
#### STOP
Stops the task.

View File

@@ -0,0 +1,132 @@
---
sidebar_label: agent
title: opendevin.server.agent.agent
---
## AgentUnit Objects
```python
class AgentUnit()
```
Represents a session with an agent.
**Attributes**:
- `controller` - The AgentController instance for controlling the agent.
- `agent_task` - The task representing the agent&#x27;s execution.
#### \_\_init\_\_
```python
def __init__(sid)
```
Initializes a new instance of the Session class.
#### send\_error
```python
async def send_error(message)
```
Sends an error message to the client.
**Arguments**:
- `message` - The error message to send.
#### send\_message
```python
async def send_message(message)
```
Sends a message to the client.
**Arguments**:
- `message` - The message to send.
#### send
```python
async def send(data)
```
Sends data to the client.
**Arguments**:
- `data` - The data to send.
#### dispatch
```python
async def dispatch(action: str | None, data: dict)
```
Dispatches actions to the agent from the client.
#### get\_arg\_or\_default
```python
def get_arg_or_default(_args: dict, key: ConfigType) -> str
```
Gets an argument from the args dictionary or the default value.
**Arguments**:
- `_args` - The args dictionary.
- `key` - The key to get.
**Returns**:
The value of the key or the default value.
#### create\_controller
```python
async def create_controller(start_event: dict)
```
Creates an AgentController instance.
**Arguments**:
- `start_event` - The start event data (optional).
#### start\_task
```python
async def start_task(start_event)
```
Starts a task for the agent.
**Arguments**:
- `start_event` - The start event data.
#### set\_task\_state
```python
async def set_task_state(new_state_action: TaskStateAction)
```
Sets the state of the agent task.
#### on\_agent\_event
```python
async def on_agent_event(event: Observation | Action)
```
Callback function for agent events.
**Arguments**:
- `event` - The agent event (Observation or Action).

View File

@@ -0,0 +1,31 @@
---
sidebar_label: manager
title: opendevin.server.agent.manager
---
## AgentManager Objects
```python
class AgentManager()
```
#### register\_agent
```python
def register_agent(sid: str)
```
Registers a new agent.
**Arguments**:
- `sid` - The session ID of the agent.
#### dispatch
```python
async def dispatch(sid: str, action: str | None, data: dict)
```
Dispatches actions to the agent from the client.

View File

@@ -0,0 +1,30 @@
---
sidebar_label: auth
title: opendevin.server.auth.auth
---
#### get\_sid\_from\_token
```python
def get_sid_from_token(token: str) -> str
```
Retrieves the session id from a JWT token.
**Arguments**:
- `token` _str_ - The JWT token from which the session id is to be extracted.
**Returns**:
- `str` - The session id if found and valid, otherwise an empty string.
#### sign\_token
```python
def sign_token(payload: Dict[str, object]) -> str
```
Signs a JWT token.

View File

@@ -0,0 +1,34 @@
---
sidebar_label: listen
title: opendevin.server.listen
---
#### get\_litellm\_models
```python
@app.get('/api/litellm-models')
async def get_litellm_models()
```
Get all models supported by LiteLLM.
#### get\_agents
```python
@app.get('/api/agents')
async def get_agents()
```
Get all agents supported by LiteLLM.
#### get\_token
```python
@app.get('/api/auth')
async def get_token(
credentials: HTTPAuthorizationCredentials = Depends(security_scheme))
```
Generate a JWT for authentication when starting a WebSocket connection. This endpoint checks if valid credentials
are provided and uses them to get a session ID. If no valid credentials are provided, it generates a new session ID.

View File

@@ -0,0 +1,35 @@
---
sidebar_label: manager
title: opendevin.server.session.manager
---
## SessionManager Objects
```python
class SessionManager()
```
#### send
```python
async def send(sid: str, data: Dict[str, object]) -> bool
```
Sends data to the client.
#### send\_error
```python
async def send_error(sid: str, message: str) -> bool
```
Sends an error message to the client.
#### send\_message
```python
async def send_message(sid: str, message: str) -> bool
```
Sends a message to the client.

View File

@@ -0,0 +1,15 @@
---
sidebar_label: msg_stack
title: opendevin.server.session.msg_stack
---
## Message Objects
```python
class Message()
```
#### role
&quot;user&quot;| &quot;assistant&quot;

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