mirror of
https://github.com/All-Hands-AI/OpenHands.git
synced 2026-04-29 03:00:45 -04:00
Compare commits
461 Commits
0.9.5
...
rb/github-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ac8a35811 | ||
|
|
9d3c6d87fb | ||
|
|
7df7f43e3c | ||
|
|
4c935a84e7 | ||
|
|
2ad0831560 | ||
|
|
a45aba512a | ||
|
|
d865f1e4a7 | ||
|
|
a1a9d2f175 | ||
|
|
79492b6551 | ||
|
|
80fdb9a2f4 | ||
|
|
a38c45cf75 | ||
|
|
975e75531d | ||
|
|
1b5f5bcdad | ||
|
|
8c00d96024 | ||
|
|
bf8ccc8fc3 | ||
|
|
037d770f66 | ||
|
|
dd50246672 | ||
|
|
090771674c | ||
|
|
d8ab0208ba | ||
|
|
a07e8272da | ||
|
|
be82832eb1 | ||
|
|
67c8915d51 | ||
|
|
40b3ccb17c | ||
|
|
35c68863dc | ||
|
|
8bfee87bcf | ||
|
|
e1383afbc3 | ||
|
|
4ce3b9094a | ||
|
|
0a4e196670 | ||
|
|
8d32a59f55 | ||
|
|
38b92f4251 | ||
|
|
88dbe85594 | ||
|
|
f5003a7449 | ||
|
|
a6810fa6ad | ||
|
|
fc05d8d4eb | ||
|
|
1d6ef0e18e | ||
|
|
dc0e223d1a | ||
|
|
932de79154 | ||
|
|
fa625fed70 | ||
|
|
f9fa1d95cb | ||
|
|
5615d54f81 | ||
|
|
8166bf768a | ||
|
|
c3991c870d | ||
|
|
1a27619b39 | ||
|
|
cc15aee405 | ||
|
|
53390d9885 | ||
|
|
0335b1a634 | ||
|
|
bb362cd377 | ||
|
|
4405b109e3 | ||
|
|
47464a9cfa | ||
|
|
2b3fd94540 | ||
|
|
1bd46f3832 | ||
|
|
8a063fdf6a | ||
|
|
025dac5d8f | ||
|
|
0e5e754420 | ||
|
|
7a8e207985 | ||
|
|
a4de0f2142 | ||
|
|
27716171bf | ||
|
|
e5d7735d75 | ||
|
|
83ccb74d36 | ||
|
|
118957235d | ||
|
|
4a6406ed71 | ||
|
|
4bef974a89 | ||
|
|
e497438085 | ||
|
|
74b3335b7d | ||
|
|
55c41212c8 | ||
|
|
4374ea08d3 | ||
|
|
436ecb80a3 | ||
|
|
df9e9fca5a | ||
|
|
add0e7d05c | ||
|
|
145194c87b | ||
|
|
6eafe0d2a8 | ||
|
|
eeb2342509 | ||
|
|
edfba4618a | ||
|
|
98751a3ee2 | ||
|
|
24117143ae | ||
|
|
78f4712080 | ||
|
|
1d2a616be7 | ||
|
|
ba25b02978 | ||
|
|
966da7b7c8 | ||
|
|
f0af90bff3 | ||
|
|
1638968509 | ||
|
|
250fcbe62c | ||
|
|
0595d2336a | ||
|
|
387c8f1df3 | ||
|
|
f6c2b287bc | ||
|
|
ab188d026d | ||
|
|
316fc260f6 | ||
|
|
aab7fa483b | ||
|
|
496364ce53 | ||
|
|
4446d3180f | ||
|
|
7b8241e424 | ||
|
|
8857f02083 | ||
|
|
1747b3d6b2 | ||
|
|
36623a16da | ||
|
|
9d3b77bffc | ||
|
|
2682518d0e | ||
|
|
b27fabe504 | ||
|
|
adf7ab5849 | ||
|
|
456998175f | ||
|
|
b4afd9f170 | ||
|
|
73c7375b92 | ||
|
|
6414b1af6e | ||
|
|
dd55290f4e | ||
|
|
be77baea31 | ||
|
|
a812e2b5f1 | ||
|
|
4ebff5aaf3 | ||
|
|
0687608feb | ||
|
|
db4e1dbbec | ||
|
|
9442e4f9e3 | ||
|
|
e17f7b22a6 | ||
|
|
ce6939fc0d | ||
|
|
4705ef9ec2 | ||
|
|
9c2b48ff5d | ||
|
|
87906b96a7 | ||
|
|
c0a0d46eb2 | ||
|
|
0ea5dcc781 | ||
|
|
d9e0344619 | ||
|
|
1c9cdaf1a2 | ||
|
|
bde978cf0f | ||
|
|
2587220b12 | ||
|
|
87bc35d2c8 | ||
|
|
866ba6e3b2 | ||
|
|
2b0eada176 | ||
|
|
2e50a5bef5 | ||
|
|
3ae4bc0f8e | ||
|
|
faf774cdbd | ||
|
|
05645d1bbd | ||
|
|
e21abce786 | ||
|
|
75ee54bbc5 | ||
|
|
89406bac44 | ||
|
|
572b3ad682 | ||
|
|
981b05fc2b | ||
|
|
997dc80d18 | ||
|
|
e231776be8 | ||
|
|
d50425865a | ||
|
|
6d19c93d19 | ||
|
|
30eeaa641c | ||
|
|
ae13171194 | ||
|
|
421b4c108a | ||
|
|
affb2123d9 | ||
|
|
fdb385ab93 | ||
|
|
13d101e092 | ||
|
|
6cf3728247 | ||
|
|
ae188458ef | ||
|
|
a20da54e3a | ||
|
|
2a6740f4ba | ||
|
|
5ba7bc6be1 | ||
|
|
98d4884ced | ||
|
|
be3cbb045e | ||
|
|
8bfd2fcf4f | ||
|
|
d4e3982a6b | ||
|
|
1f23dc89b6 | ||
|
|
7340b78962 | ||
|
|
c3da25febc | ||
|
|
8d2b2d4318 | ||
|
|
c4f5c07be1 | ||
|
|
349e2dbe50 | ||
|
|
dcd4b04f57 | ||
|
|
78eacc4489 | ||
|
|
60990c128a | ||
|
|
c4c25ea229 | ||
|
|
930726f4e8 | ||
|
|
ee2c2ff2b8 | ||
|
|
8c064fe3df | ||
|
|
e878741ae7 | ||
|
|
90e2bf4883 | ||
|
|
615b94cf2f | ||
|
|
ce2430180f | ||
|
|
eaea94cc1b | ||
|
|
385cc8f512 | ||
|
|
2d5b360505 | ||
|
|
9b6fd239d0 | ||
|
|
dd15845b91 | ||
|
|
64adb64fef | ||
|
|
6573304014 | ||
|
|
29ddcdaf46 | ||
|
|
d0bbad8eda | ||
|
|
7b81df2a94 | ||
|
|
550044454c | ||
|
|
3927fc3616 | ||
|
|
864f81bc71 | ||
|
|
54250e3fe2 | ||
|
|
da548d308c | ||
|
|
6fe5482b20 | ||
|
|
520586a89c | ||
|
|
263798584e | ||
|
|
a9a593bb21 | ||
|
|
6471d0f94d | ||
|
|
5cc16cb82a | ||
|
|
cc68756b26 | ||
|
|
126bf316bc | ||
|
|
91308ba4dc | ||
|
|
b660aa99b8 | ||
|
|
cf793582a7 | ||
|
|
56fe905241 | ||
|
|
02abf60433 | ||
|
|
e6a5e39047 | ||
|
|
feee509de7 | ||
|
|
fd6facbf03 | ||
|
|
1ea3087eec | ||
|
|
2e09b4f95e | ||
|
|
d2d55f5ea2 | ||
|
|
0e467b1429 | ||
|
|
ec3152b6e1 | ||
|
|
642e01b673 | ||
|
|
6cb174b7d1 | ||
|
|
154854bbe3 | ||
|
|
678630c5bd | ||
|
|
ad800bf373 | ||
|
|
206788a0e8 | ||
|
|
ca3fbb2a80 | ||
|
|
cc500a622a | ||
|
|
5fb3dece93 | ||
|
|
83c096b974 | ||
|
|
015df47e53 | ||
|
|
c1b323a076 | ||
|
|
84a578ad20 | ||
|
|
8e5db345b2 | ||
|
|
f61266841c | ||
|
|
277d991b37 | ||
|
|
20aa66d5e2 | ||
|
|
9bc6252967 | ||
|
|
bb416009c5 | ||
|
|
226ea545fa | ||
|
|
e12bff5189 | ||
|
|
23d3becf1d | ||
|
|
be79ccdb39 | ||
|
|
2277897f86 | ||
|
|
be9619be3a | ||
|
|
cb58dab82b | ||
|
|
8ab293a667 | ||
|
|
8a93da51be | ||
|
|
6f2e678028 | ||
|
|
da23189e4c | ||
|
|
2cf77e2589 | ||
|
|
58e9b31d08 | ||
|
|
53c2932fa5 | ||
|
|
ad4e5b3851 | ||
|
|
a56850a4e3 | ||
|
|
173018eb58 | ||
|
|
6bbd75c6e7 | ||
|
|
50c13aad98 | ||
|
|
15df12cf15 | ||
|
|
9862d93cfb | ||
|
|
9566ca4a3c | ||
|
|
0ca66beac9 | ||
|
|
0d93c5914d | ||
|
|
d47f3e854b | ||
|
|
f60652dc5a | ||
|
|
746e6595d5 | ||
|
|
7c95fd6038 | ||
|
|
78cf9d5dec | ||
|
|
5eae10d1e2 | ||
|
|
8fa3591073 | ||
|
|
70bd710e82 | ||
|
|
63ff69fd97 | ||
|
|
640ce0f60d | ||
|
|
25f9413965 | ||
|
|
4e8cfb0d60 | ||
|
|
4dfc7a7ef0 | ||
|
|
7186224899 | ||
|
|
343cc8710f | ||
|
|
20455cea3e | ||
|
|
df23168c10 | ||
|
|
ff8a9a1a56 | ||
|
|
edcc391768 | ||
|
|
87021bd78f | ||
|
|
2692c0c8fd | ||
|
|
81d455a33b | ||
|
|
495fc47c28 | ||
|
|
6a7abcc7c9 | ||
|
|
4c5e2a339f | ||
|
|
caa77cf7a6 | ||
|
|
a3c49538fc | ||
|
|
c3764a7422 | ||
|
|
36e304b3da | ||
|
|
62a58ea5d3 | ||
|
|
33a74e2792 | ||
|
|
f867fda2f9 | ||
|
|
2d2d3ccfa5 | ||
|
|
b23c7aab5a | ||
|
|
a6993b7bf5 | ||
|
|
77772b6954 | ||
|
|
ea883d4d18 | ||
|
|
3f36338d19 | ||
|
|
ae6c489423 | ||
|
|
8937c2ff12 | ||
|
|
45fb4fb9bc | ||
|
|
aae9b5ba5d | ||
|
|
f2321dbfae | ||
|
|
5ec3cb0ac9 | ||
|
|
217eb5dee2 | ||
|
|
f47afa9ebc | ||
|
|
72db908251 | ||
|
|
45a9d0ba9a | ||
|
|
1a65094377 | ||
|
|
2d4c79f181 | ||
|
|
d5fc8bc65f | ||
|
|
51387a52c1 | ||
|
|
fe084b4b16 | ||
|
|
5097c4fe71 | ||
|
|
be5f9772e6 | ||
|
|
39798e9758 | ||
|
|
d81a330a13 | ||
|
|
81d3a2881a | ||
|
|
59fbc11afe | ||
|
|
1db912aed3 | ||
|
|
e459069941 | ||
|
|
411e66395d | ||
|
|
bf61bcb34a | ||
|
|
69f2bf93c1 | ||
|
|
3661893161 | ||
|
|
ebeda8bcfb | ||
|
|
ce18792b12 | ||
|
|
ef3e106543 | ||
|
|
9d6c1e569d | ||
|
|
cdd05a98db | ||
|
|
568c8ce993 | ||
|
|
9296cedbed | ||
|
|
98b39023f4 | ||
|
|
e6847e9e61 | ||
|
|
a3571ec510 | ||
|
|
0809d26f4d | ||
|
|
9c07370559 | ||
|
|
bfdd7fd620 | ||
|
|
0186674352 | ||
|
|
d4666cdc7d | ||
|
|
3886fa8b04 | ||
|
|
46299301f2 | ||
|
|
7be224e595 | ||
|
|
11ea248b41 | ||
|
|
097de51be2 | ||
|
|
cd0198b87f | ||
|
|
01ae54a69d | ||
|
|
93f95d85de | ||
|
|
6b1f23a20a | ||
|
|
09243eba07 | ||
|
|
e3450bb8c9 | ||
|
|
583b54c854 | ||
|
|
8c32ef2234 | ||
|
|
9d0e6a24bc | ||
|
|
40d2935911 | ||
|
|
42c118f4b4 | ||
|
|
e60eaf9a52 | ||
|
|
1354675ce3 | ||
|
|
2eb42cb4f4 | ||
|
|
00f961822a | ||
|
|
62c39def7c | ||
|
|
e986e78b31 | ||
|
|
6d461a4934 | ||
|
|
25462ae394 | ||
|
|
ad60ef11ad | ||
|
|
ceebbcac2a | ||
|
|
245334e89d | ||
|
|
80a631361b | ||
|
|
9cc9b19958 | ||
|
|
0c2a35b256 | ||
|
|
641a15356f | ||
|
|
42649745bd | ||
|
|
4678ae4ebd | ||
|
|
2f310d9338 | ||
|
|
ee6a1cf334 | ||
|
|
152f99c64f | ||
|
|
909e332207 | ||
|
|
053e2f90d5 | ||
|
|
bd4640924c | ||
|
|
f26861aa93 | ||
|
|
cf9f980a22 | ||
|
|
16a2cf37da | ||
|
|
9c95d0ff58 | ||
|
|
9641bfbd3e | ||
|
|
5c31fd9357 | ||
|
|
1abfd3b808 | ||
|
|
e0594432e2 | ||
|
|
e81c5597d6 | ||
|
|
c8a933590a | ||
|
|
dd228c07e0 | ||
|
|
e0f8a5d508 | ||
|
|
e93db80769 | ||
|
|
14a4e1018a | ||
|
|
bb151655cc | ||
|
|
471867859f | ||
|
|
a1d09c4437 | ||
|
|
240b500acf | ||
|
|
d518ca08b7 | ||
|
|
52e0630af8 | ||
|
|
178dbfaf4a | ||
|
|
240a470a1d | ||
|
|
dd2cb4399a | ||
|
|
4eaf28d7b1 | ||
|
|
5a45c648a8 | ||
|
|
3cf794faef | ||
|
|
04643d6f3c | ||
|
|
53a015f718 | ||
|
|
148d22e1af | ||
|
|
31b2e4b5b2 | ||
|
|
1d6633164f | ||
|
|
dd89cfba2a | ||
|
|
0144caaf1f | ||
|
|
ec1a86f150 | ||
|
|
926af7f5fd | ||
|
|
cc55c6dbe5 | ||
|
|
c777cfeacf | ||
|
|
823966c24e | ||
|
|
adba7dad96 | ||
|
|
1109637efb | ||
|
|
71adfeebab | ||
|
|
8059e8e298 | ||
|
|
54ac340e0b | ||
|
|
13901b4b5a | ||
|
|
0b27d51135 | ||
|
|
f0ce682fa0 | ||
|
|
3567911da8 | ||
|
|
215d227e5a | ||
|
|
50e6cc6156 | ||
|
|
8d6eda3623 | ||
|
|
d5f965b474 | ||
|
|
c3bbe604eb | ||
|
|
c7fe39998c | ||
|
|
ec6e07647f | ||
|
|
e744eadb8b | ||
|
|
e582806004 | ||
|
|
f427f9d8d4 | ||
|
|
d669c7b60d | ||
|
|
42be4ee5bc | ||
|
|
f994277d0f | ||
|
|
5ccee7c8a7 | ||
|
|
575a829d94 | ||
|
|
2bed3a424c | ||
|
|
a4cc010110 | ||
|
|
9651368e6a | ||
|
|
c5025fb66e | ||
|
|
3f9111c615 | ||
|
|
89e95f2671 | ||
|
|
5bfa0c2f8d | ||
|
|
84141f656d | ||
|
|
6ff7506581 | ||
|
|
41dc7f0256 | ||
|
|
34f3b61536 | ||
|
|
4533c47595 | ||
|
|
47774e60b0 | ||
|
|
b78f646b65 | ||
|
|
3e5c01dfc8 | ||
|
|
29c34e0b6a | ||
|
|
c919086e25 | ||
|
|
0a03c802f5 | ||
|
|
081ebdbdd8 | ||
|
|
572c7b726d | ||
|
|
cfc5bb70c1 | ||
|
|
008b866a38 | ||
|
|
676ad3e140 | ||
|
|
19278de5d0 | ||
|
|
891e4a8d34 | ||
|
|
85be8607e0 | ||
|
|
49b244610c | ||
|
|
b347b1d06f | ||
|
|
0c86a60b35 | ||
|
|
01317138e2 | ||
|
|
e03855cd7f | ||
|
|
757c9593f1 | ||
|
|
266e8ff951 |
@@ -2,7 +2,5 @@
|
||||
sudo apt update
|
||||
sudo apt install -y netcat
|
||||
sudo add-apt-repository -y ppa:deadsnakes/ppa
|
||||
sudo apt install -y python3.11
|
||||
curl -sSL https://install.python-poetry.org | python3.11 -
|
||||
# chromadb requires SQLite > 3.35 but SQLite in Python3.11.9 comes with 3.31.1
|
||||
sudo cp /opt/conda/lib/libsqlite3.so.0 /lib/x86_64-linux-gnu/libsqlite3.so.0
|
||||
sudo apt install -y python3.12
|
||||
curl -sSL https://install.python-poetry.org | python3.12 -
|
||||
|
||||
70
.github/ISSUE_TEMPLATE/bug_template.yml
vendored
70
.github/ISSUE_TEMPLATE/bug_template.yml
vendored
@@ -5,71 +5,57 @@ labels: ['bug']
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: Thank you for taking the time to fill out this bug report. We greatly appreciate your effort to complete this template fully. Please provide as much information as possible to help us understand and address the issue effectively.
|
||||
value: Thank you for taking the time to fill out this bug report. Please provide as much information as possible to help us understand and address the issue effectively.
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Is there an existing issue for the same bug?
|
||||
description: Please check if an issue already exists for the bug you encountered.
|
||||
options:
|
||||
- label: I have checked the troubleshooting document at https://docs.all-hands.dev/modules/usage/troubleshooting
|
||||
required: true
|
||||
- label: I have checked the existing issues.
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: bug-description
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: Provide a short description of the problem.
|
||||
label: Describe the bug and reproduction steps
|
||||
description: Provide a description of the issue along with any reproduction steps.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: current-version
|
||||
- type: dropdown
|
||||
id: installation
|
||||
attributes:
|
||||
label: Current OpenHands version
|
||||
description: What version of OpenHands are you using? If you're running in docker, tell us the tag you're using (e.g. ghcr.io/all-hands-ai/openhands:0.3.1).
|
||||
render: bash
|
||||
validations:
|
||||
required: true
|
||||
label: OpenHands Installation
|
||||
description: How are you running OpenHands?
|
||||
options:
|
||||
- Docker command in README
|
||||
- Development workflow
|
||||
- app.all-hands.dev
|
||||
- Other
|
||||
default: 0
|
||||
|
||||
- type: textarea
|
||||
id: config
|
||||
- type: input
|
||||
id: openhands-version
|
||||
attributes:
|
||||
label: Installation and Configuration
|
||||
description: Please provide any commands you ran and any configuration (redacting API keys)
|
||||
render: bash
|
||||
validations:
|
||||
required: true
|
||||
label: OpenHands Version
|
||||
description: What version of OpenHands are you using?
|
||||
placeholder: ex. 0.9.8, main, etc.
|
||||
|
||||
- type: textarea
|
||||
id: model-agent
|
||||
attributes:
|
||||
label: Model and Agent
|
||||
description: What model and agent are you using? You can see these settings in the UI by clicking the settings wheel.
|
||||
placeholder: |
|
||||
- Model:
|
||||
- Agent:
|
||||
|
||||
- type: textarea
|
||||
id: os-version
|
||||
- type: dropdown
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating System
|
||||
description: What Operating System are you using? Linux, Mac OS, WSL on Windows
|
||||
|
||||
- type: textarea
|
||||
id: repro-steps
|
||||
attributes:
|
||||
label: Reproduction Steps
|
||||
description: Please list the steps to reproduce the issue.
|
||||
placeholder: |
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
options:
|
||||
- MacOS
|
||||
- Linux
|
||||
- WSL on Windows
|
||||
|
||||
- type: textarea
|
||||
id: additional-context
|
||||
attributes:
|
||||
label: Logs, Errors, Screenshots, and Additional Context
|
||||
description: If you want to share the chat history you can click the thumbs-down (👎) button above the input field and you will get a shareable link (you can also click thumbs up when things are going well of course!). LLM logs will be stored in the `logs/llm/default` folder. Please add any additional context about the problem here.
|
||||
description: Please provide any additional information you think might help. If you want to share the chat history
|
||||
you can click the thumbs-down (👎) button above the input field and you will get a shareable link
|
||||
(you can also click thumbs up when things are going well of course!). LLM logs will be stored in the
|
||||
`logs/llm/default` folder. Please add any additional context about the problem here.
|
||||
|
||||
49
.github/dependabot.yml
vendored
49
.github/dependabot.yml
vendored
@@ -1,21 +1,35 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "pip"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
open-pull-requests-limit: 20
|
||||
open-pull-requests-limit: 1
|
||||
groups:
|
||||
# put packages in their own group if they have a history of breaking the build or needing to be reverted
|
||||
pre-commit:
|
||||
patterns:
|
||||
- "pre-commit"
|
||||
llama:
|
||||
patterns:
|
||||
- "llama*"
|
||||
chromadb:
|
||||
patterns:
|
||||
- "chromadb"
|
||||
security-all:
|
||||
applies-to: "security-updates"
|
||||
patterns:
|
||||
- "*"
|
||||
version-all:
|
||||
applies-to: "version-updates"
|
||||
patterns:
|
||||
- "*"
|
||||
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/frontend"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
open-pull-requests-limit: 20
|
||||
open-pull-requests-limit: 1
|
||||
groups:
|
||||
docusaurus:
|
||||
patterns:
|
||||
@@ -23,12 +37,21 @@ updates:
|
||||
eslint:
|
||||
patterns:
|
||||
- "*eslint*"
|
||||
security-all:
|
||||
applies-to: "security-updates"
|
||||
patterns:
|
||||
- "*"
|
||||
version-all:
|
||||
applies-to: "version-updates"
|
||||
patterns:
|
||||
- "*"
|
||||
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/docs"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
open-pull-requests-limit: 20
|
||||
interval: "weekly"
|
||||
day: "wednesday"
|
||||
open-pull-requests-limit: 1
|
||||
groups:
|
||||
docusaurus:
|
||||
patterns:
|
||||
@@ -36,3 +59,11 @@ updates:
|
||||
eslint:
|
||||
patterns:
|
||||
- "*eslint*"
|
||||
security-all:
|
||||
applies-to: "security-updates"
|
||||
patterns:
|
||||
- "*"
|
||||
version-all:
|
||||
applies-to: "version-updates"
|
||||
patterns:
|
||||
- "*"
|
||||
|
||||
4
.github/pull_request_template.md
vendored
4
.github/pull_request_template.md
vendored
@@ -1,6 +1,6 @@
|
||||
**Short description of the problem this fixes or functionality that this introduces. This may be used for the CHANGELOG**
|
||||
|
||||
**End-user friendly description of the problem this fixes or functionality that this introduces**
|
||||
|
||||
- [ ] Include this change in the Release Notes. If checked, you must provide an **end-user friendly** description for your change below
|
||||
|
||||
---
|
||||
**Give a summary of what the PR does, explaining any non-trivial design decisions**
|
||||
|
||||
7
.github/workflows/deploy-docs.yml
vendored
7
.github/workflows/deploy-docs.yml
vendored
@@ -14,6 +14,11 @@ on:
|
||||
branches:
|
||||
- main
|
||||
|
||||
# If triggered by a PR, it will be in the same group. However, each commit on main will be in its own unique group
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ (github.head_ref && github.ref) || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
# Build the documentation website
|
||||
build:
|
||||
@@ -32,7 +37,7 @@ jobs:
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
python-version: '3.12'
|
||||
- name: Generate Python Docs
|
||||
run: rm -rf docs/modules/python && pip install pydoc-markdown && pydoc-markdown
|
||||
- name: Install dependencies
|
||||
|
||||
9
.github/workflows/dummy-agent-test.yml
vendored
9
.github/workflows/dummy-agent-test.yml
vendored
@@ -9,6 +9,11 @@ on:
|
||||
- main
|
||||
pull_request:
|
||||
|
||||
# If triggered by a PR, it will be in the same group. However, each commit on main will be in its own unique group
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ (github.head_ref && github.ref) || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -36,7 +41,7 @@ jobs:
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
python-version: '3.12'
|
||||
cache: 'poetry'
|
||||
- name: Install Python dependencies using Poetry
|
||||
run: poetry install --without evaluation,llama-index
|
||||
@@ -45,7 +50,7 @@ jobs:
|
||||
- name: Run tests
|
||||
run: |
|
||||
set -e
|
||||
poetry run python3 openhands/core/main.py -t "do a flip" -d ./workspace/ -c DummyAgent
|
||||
SANDBOX_FORCE_REBUILD_RUNTIME=True poetry run python3 openhands/core/main.py -t "do a flip" -d ./workspace/ -c DummyAgent
|
||||
- name: Check exit code
|
||||
run: |
|
||||
if [ $? -ne 0 ]; then
|
||||
|
||||
160
.github/workflows/eval-runner.yml
vendored
Normal file
160
.github/workflows/eval-runner.yml
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
name: Run Evaluation
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [labeled]
|
||||
schedule:
|
||||
- cron: "0 1 * * *" # Run daily at 1 AM UTC
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
reason:
|
||||
description: "Reason for manual trigger"
|
||||
required: true
|
||||
default: ""
|
||||
|
||||
env:
|
||||
N_PROCESSES: 32 # Global configuration for number of parallel processes for evaluation
|
||||
|
||||
jobs:
|
||||
run-evaluation:
|
||||
if: github.event.label.name == 'eval-this' || github.event_name != 'pull_request'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: "read"
|
||||
id-token: "write"
|
||||
pull-requests: "write"
|
||||
issues: "write"
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.12"]
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install poetry via pipx
|
||||
run: pipx install poetry
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: "poetry"
|
||||
|
||||
- name: Comment on PR if 'eval-this' label is present
|
||||
if: github.event_name == 'pull_request' && github.event.label.name == 'eval-this'
|
||||
uses: KeisukeYamashita/create-comment@v1
|
||||
with:
|
||||
unique: false
|
||||
comment: |
|
||||
Hi! I started running the evaluation on your PR. You will receive a comment with the results shortly.
|
||||
|
||||
- name: Install Python dependencies using Poetry
|
||||
run: poetry install
|
||||
|
||||
- name: Configure config.toml for evaluation
|
||||
env:
|
||||
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_LLM_API_KEY }}
|
||||
run: |
|
||||
echo "[llm.eval]" > config.toml
|
||||
echo "model = \"deepseek/deepseek-chat\"" >> config.toml
|
||||
echo "api_key = \"$DEEPSEEK_API_KEY\"" >> config.toml
|
||||
echo "temperature = 0.0" >> config.toml
|
||||
|
||||
- name: Run integration test evaluation
|
||||
env:
|
||||
ALLHANDS_API_KEY: ${{ secrets.ALLHANDS_EVAL_RUNTIME_API_KEY }}
|
||||
RUNTIME: remote
|
||||
SANDBOX_REMOTE_RUNTIME_API_URL: https://runtime.eval.all-hands.dev
|
||||
EVAL_DOCKER_IMAGE_PREFIX: us-central1-docker.pkg.dev/evaluation-092424/swe-bench-images
|
||||
|
||||
run: |
|
||||
poetry run ./evaluation/integration_tests/scripts/run_infer.sh llm.eval HEAD CodeActAgent '' $N_PROCESSES
|
||||
|
||||
# get evaluation report
|
||||
REPORT_FILE=$(find evaluation/evaluation_outputs/outputs/integration_tests/CodeActAgent/deepseek-chat_maxiter_10_N* -name "report.md" -type f | head -n 1)
|
||||
echo "REPORT_FILE: $REPORT_FILE"
|
||||
echo "INTEGRATION_TEST_REPORT<<EOF" >> $GITHUB_ENV
|
||||
cat $REPORT_FILE >> $GITHUB_ENV
|
||||
echo >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
|
||||
- name: Run SWE-Bench evaluation
|
||||
env:
|
||||
ALLHANDS_API_KEY: ${{ secrets.ALLHANDS_EVAL_RUNTIME_API_KEY }}
|
||||
RUNTIME: remote
|
||||
SANDBOX_REMOTE_RUNTIME_API_URL: https://runtime.eval.all-hands.dev
|
||||
EVAL_DOCKER_IMAGE_PREFIX: us-central1-docker.pkg.dev/evaluation-092424/swe-bench-images
|
||||
|
||||
run: |
|
||||
poetry run ./evaluation/swe_bench/scripts/run_infer.sh llm.eval HEAD CodeActAgent 300 30 $N_PROCESSES "princeton-nlp/SWE-bench_Lite" test
|
||||
OUTPUT_FOLDER=$(find evaluation/evaluation_outputs/outputs/princeton-nlp__SWE-bench_Lite-test/CodeActAgent -name "deepseek-chat_maxiter_50_N_*-no-hint-run_1" -type d | head -n 1)
|
||||
echo "OUTPUT_FOLDER for SWE-bench evaluation: $OUTPUT_FOLDER"
|
||||
poetry run ./evaluation/swe_bench/scripts/eval_infer_remote.sh $OUTPUT_FOLDER/output.jsonl $N_PROCESSES "princeton-nlp/SWE-bench_Lite" test
|
||||
|
||||
poetry run ./evaluation/swe_bench/scripts/eval/summarize_outputs.py $OUTPUT_FOLDER/output.jsonl > summarize_outputs.log 2>&1
|
||||
echo "SWEBENCH_REPORT<<EOF" >> $GITHUB_ENV
|
||||
cat summarize_outputs.log >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
|
||||
- name: Create tar.gz of evaluation outputs
|
||||
run: |
|
||||
TIMESTAMP=$(date +'%y-%m-%d-%H-%M')
|
||||
tar -czvf evaluation_outputs_${TIMESTAMP}.tar.gz evaluation/evaluation_outputs/outputs
|
||||
|
||||
- name: Upload evaluation results as artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
id: upload_results_artifact
|
||||
with:
|
||||
name: evaluation-outputs
|
||||
path: evaluation_outputs_*.tar.gz
|
||||
|
||||
- name: Get artifact URL
|
||||
run: echo "ARTIFACT_URL=${{ steps.upload_results_artifact.outputs.artifact-url }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Authenticate to Google Cloud
|
||||
uses: 'google-github-actions/auth@v2'
|
||||
with:
|
||||
credentials_json: ${{ secrets.GCP_RESEARCH_OBJECT_CREATOR_SA_KEY }}
|
||||
|
||||
- name: Set timestamp and trigger reason
|
||||
run: |
|
||||
echo "TIMESTAMP=$(date +'%Y-%m-%d-%H-%M')" >> $GITHUB_ENV
|
||||
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
|
||||
echo "TRIGGER_REASON=pr-${{ github.event.pull_request.number }}" >> $GITHUB_ENV
|
||||
elif [[ "${{ github.event_name }}" == "schedule" ]]; then
|
||||
echo "TRIGGER_REASON=schedule" >> $GITHUB_ENV
|
||||
else
|
||||
echo "TRIGGER_REASON=manual-${{ github.event.inputs.reason }}" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Upload evaluation results to Google Cloud Storage
|
||||
uses: 'google-github-actions/upload-cloud-storage@v2'
|
||||
with:
|
||||
path: 'evaluation/evaluation_outputs/outputs'
|
||||
destination: 'openhands-oss-eval-results/${{ env.TIMESTAMP }}-${{ env.TRIGGER_REASON }}'
|
||||
|
||||
- name: Comment with evaluation results and artifact link
|
||||
id: create_comment
|
||||
uses: KeisukeYamashita/create-comment@v1
|
||||
with:
|
||||
number: ${{ github.event_name == 'pull_request' && github.event.pull_request.number || 4504 }}
|
||||
unique: false
|
||||
comment: |
|
||||
Trigger by: ${{ github.event_name == 'pull_request' && format('Pull Request (eval-this label on PR #{0})', github.event.pull_request.number) || github.event_name == 'schedule' && 'Daily Schedule' || format('Manual Trigger: {0}', github.event.inputs.reason) }}
|
||||
Commit: ${{ github.sha }}
|
||||
**SWE-Bench Evaluation Report**
|
||||
${{ env.SWEBENCH_REPORT }}
|
||||
---
|
||||
**Integration Tests Evaluation Report**
|
||||
${{ env.INTEGRATION_TEST_REPORT }}
|
||||
---
|
||||
You can download the full evaluation outputs [here](${{ env.ARTIFACT_URL }}).
|
||||
|
||||
- name: Post to a Slack channel
|
||||
id: slack
|
||||
uses: slackapi/slack-github-action@v1.27.0
|
||||
with:
|
||||
channel-id: 'C07SVQSCR6F'
|
||||
slack-message: "*Evaluation Trigger:* ${{ github.event_name == 'pull_request' && format('Pull Request (eval-this label on PR #{0})', github.event.pull_request.number) || github.event_name == 'schedule' && 'Daily Schedule' || format('Manual Trigger: {0}', github.event.inputs.reason) }}\n\nLink to summary: [here](https://github.com/${{ github.repository }}/issues/${{ github.event_name == 'pull_request' && github.event.pull_request.number || 4504 }}#issuecomment-${{ steps.create_comment.outputs.comment-id }})"
|
||||
env:
|
||||
SLACK_BOT_TOKEN: ${{ secrets.EVAL_NOTIF_SLACK_BOT_TOKEN }}
|
||||
5
.github/workflows/fe-unit-tests.yml
vendored
5
.github/workflows/fe-unit-tests.yml
vendored
@@ -12,6 +12,11 @@ on:
|
||||
- 'frontend/**'
|
||||
- '.github/workflows/fe-unit-tests.yml'
|
||||
|
||||
# If triggered by a PR, it will be in the same group. However, each commit on main will be in its own unique group
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ (github.head_ref && github.ref) || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
# Run frontend unit tests
|
||||
fe-test:
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
# Workflow that builds, tests and then pushes the runtime docker images to the ghcr.io repository
|
||||
name: Build, Test and Publish RT Image
|
||||
|
||||
# Only run one workflow of the same group at a time.
|
||||
# There can be at most one running and one pending job in a concurrency group at any time.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
|
||||
# Workflow that builds, tests and then pushes the OpenHands and runtime docker images to the ghcr.io repository
|
||||
name: Docker
|
||||
|
||||
# Always run on "main"
|
||||
# Always run on tags
|
||||
@@ -25,7 +19,76 @@ on:
|
||||
required: true
|
||||
default: ''
|
||||
|
||||
# If triggered by a PR, it will be in the same group. However, each commit on main will be in its own unique group
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ (github.head_ref && github.ref) || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
BASE_IMAGE_FOR_HASH_EQUIVALENCE_TEST: nikolaik/python-nodejs:python3.12-nodejs22
|
||||
RELEVANT_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
|
||||
jobs:
|
||||
# Builds the OpenHands Docker images
|
||||
ghcr_build_app:
|
||||
name: Build App Image
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
outputs:
|
||||
hash_from_app_image: ${{ steps.get_hash_in_app_image.outputs.hash_from_app_image }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Free Disk Space (Ubuntu)
|
||||
uses: jlumbroso/free-disk-space@main
|
||||
with:
|
||||
# this might remove tools that are actually needed,
|
||||
# if set to "true" but frees about 6 GB
|
||||
tool-cache: true
|
||||
# all of these default to true, but feel free to set to
|
||||
# "false" if necessary for your workflow
|
||||
android: true
|
||||
dotnet: true
|
||||
haskell: true
|
||||
large-packages: true
|
||||
docker-images: false
|
||||
swap-storage: true
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3.0.0
|
||||
with:
|
||||
image: tonistiigi/binfmt:latest
|
||||
- name: Login to GHCR
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Build and push app image
|
||||
if: "!github.event.pull_request.head.repo.fork"
|
||||
run: |
|
||||
./containers/build.sh -i openhands -o ${{ github.repository_owner }} --push
|
||||
- name: Build app image
|
||||
if: "github.event.pull_request.head.repo.fork"
|
||||
run: |
|
||||
./containers/build.sh -i openhands -o ${{ github.repository_owner }} --load
|
||||
- name: Get hash in App Image
|
||||
id: get_hash_in_app_image
|
||||
run: |
|
||||
# Lowercase the repository owner
|
||||
export REPO_OWNER=${{ github.repository_owner }}
|
||||
REPO_OWNER=$(echo $REPO_OWNER | tr '[:upper:]' '[:lower:]')
|
||||
# Run the build script in the app image
|
||||
docker run -e SANDBOX_USER_ID=0 -v /var/run/docker.sock:/var/run/docker.sock ghcr.io/${REPO_OWNER}/openhands:${{ env.RELEVANT_SHA }} /bin/bash -c "mkdir -p containers/runtime; python3 openhands/runtime/utils/runtime_build.py --base_image ${{ env.BASE_IMAGE_FOR_HASH_EQUIVALENCE_TEST }} --build_folder containers/runtime --force_rebuild" 2>&1 | tee docker-outputs.txt
|
||||
# Get the hash from the build script
|
||||
hash_from_app_image=$(cat docker-outputs.txt | grep "Hash for docker build directory" | awk -F "): " '{print $2}' | uniq | head -n1)
|
||||
echo "hash_from_app_image=$hash_from_app_image" >> $GITHUB_OUTPUT
|
||||
echo "Hash from app image: $hash_from_app_image"
|
||||
|
||||
# Builds the runtime Docker images
|
||||
ghcr_build_runtime:
|
||||
name: Build Image
|
||||
@@ -36,7 +99,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
base_image:
|
||||
- image: 'nikolaik/python-nodejs:python3.11-nodejs22'
|
||||
- image: 'nikolaik/python-nodejs:python3.12-nodejs22'
|
||||
tag: nikolaik
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -56,7 +119,9 @@ jobs:
|
||||
docker-images: false
|
||||
swap-storage: true
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
uses: docker/setup-qemu-action@v3.0.0
|
||||
with:
|
||||
image: tonistiigi/binfmt:latest
|
||||
- name: Login to GHCR
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
@@ -69,7 +134,7 @@ jobs:
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
python-version: '3.12'
|
||||
- name: Cache Poetry dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
@@ -88,13 +153,13 @@ jobs:
|
||||
- name: Build and push runtime image ${{ matrix.base_image.image }}
|
||||
if: github.event.pull_request.head.repo.fork != true
|
||||
run: |
|
||||
./containers/build.sh runtime ${{ github.repository_owner }} --push ${{ matrix.base_image.tag }}
|
||||
./containers/build.sh -i runtime -o ${{ github.repository_owner }} --push -t ${{ matrix.base_image.tag }}
|
||||
# Forked repos can't push to GHCR, so we need to upload the image as an artifact
|
||||
- name: Build runtime image ${{ matrix.base_image.image }} for fork
|
||||
if: github.event.pull_request.head.repo.fork
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
tags: ghcr.io/all-hands-ai/runtime:${{ github.sha }}-${{ matrix.base_image.tag }}
|
||||
tags: ghcr.io/all-hands-ai/runtime:${{ env.RELEVANT_SHA }}-${{ matrix.base_image.tag }}
|
||||
outputs: type=docker,dest=/tmp/runtime-${{ matrix.base_image.tag }}.tar
|
||||
context: containers/runtime
|
||||
- name: Upload runtime image for fork
|
||||
@@ -104,6 +169,56 @@ jobs:
|
||||
name: runtime-${{ matrix.base_image.tag }}
|
||||
path: /tmp/runtime-${{ matrix.base_image.tag }}.tar
|
||||
|
||||
verify_hash_equivalence_in_runtime_and_app:
|
||||
name: Verify Hash Equivalence in Runtime and Docker images
|
||||
runs-on: ubuntu-latest
|
||||
needs: [ghcr_build_runtime, ghcr_build_app]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
base_image: ['nikolaik']
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Cache Poetry dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cache/pypoetry
|
||||
~/.virtualenvs
|
||||
key: ${{ runner.os }}-poetry-${{ hashFiles('**/poetry.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-poetry-
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
- name: Install poetry via pipx
|
||||
run: pipx install poetry
|
||||
- name: Install Python dependencies using Poetry
|
||||
run: make install-python-dependencies
|
||||
- name: Get hash in App Image
|
||||
run: |
|
||||
echo "Hash from app image: ${{ needs.ghcr_build_app.outputs.hash_from_app_image }}"
|
||||
echo "hash_from_app_image=${{ needs.ghcr_build_app.outputs.hash_from_app_image }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Get hash using code (development mode)
|
||||
run: |
|
||||
mkdir -p containers/runtime
|
||||
poetry run python3 openhands/runtime/utils/runtime_build.py --base_image ${{ env.BASE_IMAGE_FOR_HASH_EQUIVALENCE_TEST }} --build_folder containers/runtime --force_rebuild > output.txt 2>&1
|
||||
hash_from_code=$(cat output.txt | grep "Hash for docker build directory" | awk -F "): " '{print $2}' | uniq | head -n1)
|
||||
echo "hash_from_code=$hash_from_code" >> $GITHUB_ENV
|
||||
|
||||
- name: Compare hashes
|
||||
run: |
|
||||
echo "Hash from App Image: ${{ env.hash_from_app_image }}"
|
||||
echo "Hash from Code: ${{ env.hash_from_code }}"
|
||||
if [ "${{ env.hash_from_app_image }}" = "${{ env.hash_from_code }}" ]; then
|
||||
echo "Hashes match!"
|
||||
else
|
||||
echo "Hashes do not match!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run unit tests with the EventStream runtime Docker images as root
|
||||
test_runtime_root:
|
||||
name: RT Unit Tests (Root)
|
||||
@@ -155,7 +270,7 @@ jobs:
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
python-version: '3.12'
|
||||
- name: Install poetry via pipx
|
||||
run: pipx install poetry
|
||||
- name: Install Python dependencies using Poetry
|
||||
@@ -168,7 +283,7 @@ jobs:
|
||||
# Install to be able to retry on failures for flaky tests
|
||||
poetry run pip install pytest-rerunfailures
|
||||
|
||||
image_name=ghcr.io/${{ github.repository_owner }}/runtime:${{ github.sha }}-${{ matrix.base_image }}
|
||||
image_name=ghcr.io/${{ github.repository_owner }}/runtime:${{ env.RELEVANT_SHA }}-${{ matrix.base_image }}
|
||||
image_name=$(echo $image_name | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
SKIP_CONTAINER_LOGS=true \
|
||||
@@ -177,7 +292,7 @@ jobs:
|
||||
SANDBOX_RUNTIME_CONTAINER_IMAGE=$image_name \
|
||||
TEST_IN_CI=true \
|
||||
RUN_AS_OPENHANDS=false \
|
||||
poetry run pytest -n 3 -raR --reruns 1 --reruns-delay 3 --cov=agenthub --cov=openhands --cov-report=xml -s ./tests/runtime
|
||||
poetry run pytest -n 3 -raRs --reruns 2 --reruns-delay 5 --cov=openhands --cov-report=xml -s ./tests/runtime
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v4
|
||||
env:
|
||||
@@ -233,7 +348,7 @@ jobs:
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
python-version: '3.12'
|
||||
- name: Install poetry via pipx
|
||||
run: pipx install poetry
|
||||
- name: Install Python dependencies using Poetry
|
||||
@@ -246,7 +361,7 @@ jobs:
|
||||
# Install to be able to retry on failures for flaky tests
|
||||
poetry run pip install pytest-rerunfailures
|
||||
|
||||
image_name=ghcr.io/${{ github.repository_owner }}/runtime:${{ github.sha }}-${{ matrix.base_image }}
|
||||
image_name=ghcr.io/${{ github.repository_owner }}/runtime:${{ env.RELEVANT_SHA }}-${{ matrix.base_image }}
|
||||
image_name=$(echo $image_name | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
SKIP_CONTAINER_LOGS=true \
|
||||
@@ -255,79 +370,7 @@ jobs:
|
||||
SANDBOX_RUNTIME_CONTAINER_IMAGE=$image_name \
|
||||
TEST_IN_CI=true \
|
||||
RUN_AS_OPENHANDS=true \
|
||||
poetry run pytest -n 3 -raR --reruns 1 --reruns-delay 3 --cov=agenthub --cov=openhands --cov-report=xml -s ./tests/runtime
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v4
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
# Run integration tests with the eventstream runtime Docker image
|
||||
runtime_integration_tests_on_linux:
|
||||
name: RT Integration Tests (Linux)
|
||||
runs-on: ubuntu-latest
|
||||
needs: [ghcr_build_runtime]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
base_image: ['nikolaik']
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Free Disk Space (Ubuntu)
|
||||
uses: jlumbroso/free-disk-space@main
|
||||
with:
|
||||
# this might remove tools that are actually needed,
|
||||
# if set to "true" but frees about 6 GB
|
||||
tool-cache: true
|
||||
# all of these default to true, but feel free to set to
|
||||
# "false" if necessary for your workflow
|
||||
android: true
|
||||
dotnet: true
|
||||
haskell: true
|
||||
large-packages: true
|
||||
docker-images: false
|
||||
swap-storage: true
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
# Forked repos can't push to GHCR, so we need to download the image as an artifact
|
||||
- name: Download runtime image for fork
|
||||
if: github.event.pull_request.head.repo.fork
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: runtime-${{ matrix.base_image }}
|
||||
path: /tmp
|
||||
- name: Load runtime image for fork
|
||||
if: github.event.pull_request.head.repo.fork
|
||||
run: |
|
||||
docker load --input /tmp/runtime-${{ matrix.base_image }}.tar
|
||||
- name: Cache Poetry dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cache/pypoetry
|
||||
~/.virtualenvs
|
||||
key: ${{ runner.os }}-poetry-${{ hashFiles('**/poetry.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-poetry-
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
- name: Install poetry via pipx
|
||||
run: pipx install poetry
|
||||
- name: Install Python dependencies using Poetry
|
||||
run: make install-python-dependencies
|
||||
- name: Run integration tests
|
||||
run: |
|
||||
image_name=ghcr.io/${{ github.repository_owner }}/runtime:${{ github.sha }}-${{ matrix.base_image }}
|
||||
image_name=$(echo $image_name | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
TEST_RUNTIME=eventstream \
|
||||
SANDBOX_USER_ID=$(id -u) \
|
||||
SANDBOX_RUNTIME_CONTAINER_IMAGE=$image_name \
|
||||
TEST_IN_CI=true \
|
||||
TEST_ONLY=true \
|
||||
./tests/integration/regenerate.sh
|
||||
poetry run pytest -n 3 -raRs --reruns 2 --reruns-delay 5 --cov=openhands --cov-report=xml -s ./tests/runtime
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v4
|
||||
env:
|
||||
@@ -341,7 +384,7 @@ jobs:
|
||||
name: All Runtime Tests Passed
|
||||
if: ${{ !cancelled() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: [test_runtime_root, test_runtime_oh, runtime_integration_tests_on_linux]
|
||||
needs: [test_runtime_root, test_runtime_oh, verify_hash_equivalence_in_runtime_and_app]
|
||||
steps:
|
||||
- name: All tests passed
|
||||
run: echo "All runtime tests have passed successfully!"
|
||||
@@ -350,9 +393,55 @@ jobs:
|
||||
name: All Runtime Tests Passed
|
||||
if: ${{ cancelled() || contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: [test_runtime_root, test_runtime_oh, runtime_integration_tests_on_linux]
|
||||
needs: [test_runtime_root, test_runtime_oh, verify_hash_equivalence_in_runtime_and_app]
|
||||
steps:
|
||||
- name: Some tests failed
|
||||
run: |
|
||||
echo "Some runtime tests failed or were cancelled"
|
||||
exit 1
|
||||
update_pr_description:
|
||||
name: Update PR Description
|
||||
if: github.event_name == 'pull_request' && !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]'
|
||||
needs: [ghcr_build_runtime]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Get short SHA
|
||||
id: short_sha
|
||||
run: echo "SHORT_SHA=$(echo ${{ github.event.pull_request.head.sha }} | cut -c1-7)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Update PR Description
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
REPO: ${{ github.repository }}
|
||||
SHORT_SHA: ${{ steps.short_sha.outputs.SHORT_SHA }}
|
||||
run: |
|
||||
echo "updating PR description"
|
||||
DOCKER_RUN_COMMAND="docker run -it --rm \
|
||||
-p 3000:3000 \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
--add-host host.docker.internal:host-gateway \
|
||||
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:$SHORT_SHA-nikolaik \
|
||||
--name openhands-app-$SHORT_SHA \
|
||||
docker.all-hands.dev/all-hands-ai/openhands:$SHORT_SHA"
|
||||
|
||||
PR_BODY=$(gh pr view $PR_NUMBER --json body --jq .body)
|
||||
|
||||
if echo "$PR_BODY" | grep -q "To run this PR locally, use the following command:"; then
|
||||
UPDATED_PR_BODY=$(echo "${PR_BODY}" | sed -E "s|docker run -it --rm.*|$DOCKER_RUN_COMMAND|")
|
||||
else
|
||||
UPDATED_PR_BODY="${PR_BODY}
|
||||
|
||||
---
|
||||
|
||||
To run this PR locally, use the following command:
|
||||
\`\`\`
|
||||
$DOCKER_RUN_COMMAND
|
||||
\`\`\`"
|
||||
fi
|
||||
|
||||
echo "updated body: $UPDATED_PR_BODY"
|
||||
gh pr edit $PR_NUMBER --body "$UPDATED_PR_BODY"
|
||||
65
.github/workflows/ghcr_app.yml
vendored
65
.github/workflows/ghcr_app.yml
vendored
@@ -1,65 +0,0 @@
|
||||
# Workflow that builds, tests and then pushes the app docker images to the ghcr.io repository
|
||||
name: Build and Publish App Image
|
||||
|
||||
# Always run on "main"
|
||||
# Always run on tags
|
||||
# Always run on PRs
|
||||
# Can also be triggered manually
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
tags:
|
||||
- '*'
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
reason:
|
||||
description: 'Reason for manual trigger'
|
||||
required: true
|
||||
default: ''
|
||||
|
||||
jobs:
|
||||
# Builds the OpenHands Docker images
|
||||
ghcr_build:
|
||||
name: Build App Image
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Free Disk Space (Ubuntu)
|
||||
uses: jlumbroso/free-disk-space@main
|
||||
with:
|
||||
# this might remove tools that are actually needed,
|
||||
# if set to "true" but frees about 6 GB
|
||||
tool-cache: true
|
||||
# all of these default to true, but feel free to set to
|
||||
# "false" if necessary for your workflow
|
||||
android: true
|
||||
dotnet: true
|
||||
haskell: true
|
||||
large-packages: true
|
||||
docker-images: false
|
||||
swap-storage: true
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
- name: Login to GHCR
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Build and push app image
|
||||
if: "!github.event.pull_request.head.repo.fork"
|
||||
run: |
|
||||
./containers/build.sh openhands ${{ github.repository_owner }} --push
|
||||
- name: Build app image
|
||||
if: "github.event.pull_request.head.repo.fork"
|
||||
run: |
|
||||
./containers/build.sh openhands image ${{ github.repository_owner }}
|
||||
9
.github/workflows/lint.yml
vendored
9
.github/workflows/lint.yml
vendored
@@ -10,6 +10,11 @@ on:
|
||||
- main
|
||||
pull_request:
|
||||
|
||||
# If triggered by a PR, it will be in the same group. However, each commit on main will be in its own unique group
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ (github.head_ref && github.ref) || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
# Run lint on the frontend code
|
||||
lint-frontend:
|
||||
@@ -41,9 +46,9 @@ jobs:
|
||||
- name: Set up python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.11
|
||||
python-version: 3.12
|
||||
cache: 'pip'
|
||||
- name: Install pre-commit
|
||||
run: pip install pre-commit==3.7.0
|
||||
- name: Run pre-commit hooks
|
||||
run: pre-commit run --files openhands/**/* agenthub/**/* evaluation/**/* tests/**/* --show-diff-on-failure --config ./dev_config/python/.pre-commit-config.yaml
|
||||
run: pre-commit run --files openhands/**/* evaluation/**/* tests/**/* --show-diff-on-failure --config ./dev_config/python/.pre-commit-config.yaml
|
||||
|
||||
15
.github/workflows/openhands-resolver.yml
vendored
Normal file
15
.github/workflows/openhands-resolver.yml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
name: Resolve Issues with OpenHands
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [labeled]
|
||||
pull_request:
|
||||
types: [labeled]
|
||||
|
||||
jobs:
|
||||
call-openhands-resolver:
|
||||
uses: All-Hands-AI/openhands-resolver/.github/workflows/openhands-resolver.yml@main
|
||||
if: github.event.label.name == 'fix-me'
|
||||
with:
|
||||
max_iterations: 50
|
||||
secrets: inherit
|
||||
96
.github/workflows/py-unit-tests-mac.yml
vendored
Normal file
96
.github/workflows/py-unit-tests-mac.yml
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
# Workflow that runs python unit tests on mac
|
||||
name: Run Python Unit Tests Mac
|
||||
|
||||
# This job is flaky so only run it nightly
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
|
||||
jobs:
|
||||
# Run python unit tests on macOS
|
||||
test-on-macos:
|
||||
name: Python Unit Tests on macOS
|
||||
runs-on: macos-14
|
||||
env:
|
||||
INSTALL_DOCKER: '1' # Set to '0' to skip Docker installation
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.12']
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Cache Poetry dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cache/pypoetry
|
||||
~/.virtualenvs
|
||||
key: ${{ runner.os }}-poetry-${{ hashFiles('**/poetry.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-poetry-
|
||||
- name: Install poetry via pipx
|
||||
run: pipx install poetry
|
||||
- name: Install Python dependencies using Poetry
|
||||
run: poetry install --without evaluation,llama-index
|
||||
- name: Install & Start Docker
|
||||
if: env.INSTALL_DOCKER == '1'
|
||||
run: |
|
||||
INSTANCE_NAME="colima-${GITHUB_RUN_ID}"
|
||||
|
||||
# Uninstall colima to upgrade to the latest version
|
||||
if brew list colima &>/dev/null; then
|
||||
brew uninstall colima
|
||||
# unlinking colima dependency: go
|
||||
brew uninstall go@1.21
|
||||
fi
|
||||
rm -rf ~/.colima ~/.lima
|
||||
brew install --HEAD colima
|
||||
brew install docker
|
||||
|
||||
start_colima() {
|
||||
# Find a free port in the range 10000-20000
|
||||
RANDOM_PORT=$((RANDOM % 10001 + 10000))
|
||||
|
||||
# Original line:
|
||||
if ! colima start --network-address --arch x86_64 --cpu=1 --memory=1 --verbose --ssh-port $RANDOM_PORT; then
|
||||
echo "Failed to start Colima."
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Attempt to start Colima for 5 total attempts:
|
||||
ATTEMPT_LIMIT=5
|
||||
for ((i=1; i<=ATTEMPT_LIMIT; i++)); do
|
||||
|
||||
if start_colima; then
|
||||
echo "Colima started successfully."
|
||||
break
|
||||
else
|
||||
colima stop -f
|
||||
sleep 10
|
||||
colima delete -f
|
||||
if [ $i -eq $ATTEMPT_LIMIT ]; then
|
||||
exit 1
|
||||
fi
|
||||
sleep 10
|
||||
fi
|
||||
done
|
||||
|
||||
# For testcontainers to find the Colima socket
|
||||
# https://github.com/abiosoft/colima/blob/main/docs/FAQ.md#cannot-connect-to-the-docker-daemon-at-unixvarrundockersock-is-the-docker-daemon-running
|
||||
sudo ln -sf $HOME/.colima/default/docker.sock /var/run/docker.sock
|
||||
- name: Build Environment
|
||||
run: make build
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Run Tests
|
||||
run: poetry run pytest --forked --cov=openhands --cov-report=xml ./tests/unit --ignore=tests/unit/test_memory.py
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v4
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
97
.github/workflows/py-unit-tests.yml
vendored
97
.github/workflows/py-unit-tests.yml
vendored
@@ -10,95 +10,12 @@ on:
|
||||
- main
|
||||
pull_request:
|
||||
|
||||
# If triggered by a PR, it will be in the same group. However, each commit on main will be in its own unique group
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ (github.head_ref && github.ref) || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
# Run python unit tests on macOS
|
||||
test-on-macos:
|
||||
name: Python Unit Tests on macOS
|
||||
runs-on: macos-12
|
||||
env:
|
||||
INSTALL_DOCKER: '1' # Set to '0' to skip Docker installation
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.11']
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Cache Poetry dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cache/pypoetry
|
||||
~/.virtualenvs
|
||||
key: ${{ runner.os }}-poetry-${{ hashFiles('**/poetry.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-poetry-
|
||||
- name: Install poetry via pipx
|
||||
run: pipx install poetry
|
||||
- name: Install Python dependencies using Poetry
|
||||
run: poetry install --without evaluation,llama-index
|
||||
- name: Install & Start Docker
|
||||
if: env.INSTALL_DOCKER == '1'
|
||||
run: |
|
||||
INSTANCE_NAME="colima-${GITHUB_RUN_ID}"
|
||||
|
||||
# Uninstall colima to upgrade to the latest version
|
||||
if brew list colima &>/dev/null; then
|
||||
brew uninstall colima
|
||||
# unlinking colima dependency: go
|
||||
brew uninstall go@1.21
|
||||
fi
|
||||
rm -rf ~/.colima ~/.lima
|
||||
brew install --HEAD colima
|
||||
brew install docker
|
||||
|
||||
start_colima() {
|
||||
# Find a free port in the range 10000-20000
|
||||
RANDOM_PORT=$((RANDOM % 10001 + 10000))
|
||||
|
||||
# Original line:
|
||||
if ! colima start --network-address --arch x86_64 --cpu=1 --memory=1 --verbose --ssh-port $RANDOM_PORT; then
|
||||
echo "Failed to start Colima."
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Attempt to start Colima for 5 total attempts:
|
||||
ATTEMPT_LIMIT=5
|
||||
for ((i=1; i<=ATTEMPT_LIMIT; i++)); do
|
||||
|
||||
if start_colima; then
|
||||
echo "Colima started successfully."
|
||||
break
|
||||
else
|
||||
colima stop -f
|
||||
sleep 10
|
||||
colima delete -f
|
||||
if [ $i -eq $ATTEMPT_LIMIT ]; then
|
||||
exit 1
|
||||
fi
|
||||
sleep 10
|
||||
fi
|
||||
done
|
||||
|
||||
# For testcontainers to find the Colima socket
|
||||
# https://github.com/abiosoft/colima/blob/main/docs/FAQ.md#cannot-connect-to-the-docker-daemon-at-unixvarrundockersock-is-the-docker-daemon-running
|
||||
sudo ln -sf $HOME/.colima/default/docker.sock /var/run/docker.sock
|
||||
- name: Build Environment
|
||||
run: make build
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Run Tests
|
||||
run: poetry run pytest --forked --cov=agenthub --cov=openhands --cov-report=xml ./tests/unit
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v4
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
# Run python unit tests on Linux
|
||||
test-on-linux:
|
||||
name: Python Unit Tests on Linux
|
||||
@@ -107,7 +24,7 @@ jobs:
|
||||
INSTALL_DOCKER: '0' # Set to '0' to skip Docker installation
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.11']
|
||||
python-version: ['3.12']
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Docker Buildx
|
||||
@@ -125,7 +42,7 @@ jobs:
|
||||
- name: Build Environment
|
||||
run: make build
|
||||
- name: Run Tests
|
||||
run: poetry run pytest --forked --cov=agenthub --cov=openhands --cov-report=xml -svv ./tests/unit
|
||||
run: poetry run pytest --forked --cov=openhands --cov-report=xml -svv ./tests/unit --ignore=tests/unit/test_memory.py
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v4
|
||||
env:
|
||||
|
||||
4
.github/workflows/pypi-release.yml
vendored
4
.github/workflows/pypi-release.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.11
|
||||
python-version: 3.12
|
||||
- name: Install Poetry
|
||||
uses: snok/install-poetry@v1.4.1
|
||||
with:
|
||||
@@ -26,6 +26,6 @@ jobs:
|
||||
- name: Install Poetry Dependencies
|
||||
run: poetry install --no-interaction --no-root
|
||||
- name: Build poetry project
|
||||
run: poetry build -v
|
||||
run: ./build.sh
|
||||
- name: publish
|
||||
run: poetry publish -u __token__ -p ${{ secrets.PYPI_TOKEN }}
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
|
||||
name: Regenerate Integration Tests
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
debug:
|
||||
description: 'Enable debug mode'
|
||||
type: boolean
|
||||
default: true
|
||||
log_to_file:
|
||||
description: 'Enable logging to file'
|
||||
type: boolean
|
||||
default: true
|
||||
force_regenerate_tests:
|
||||
description: 'Force regeneration of tests'
|
||||
type: boolean
|
||||
default: false
|
||||
force_use_llm:
|
||||
description: 'Force use of LLM'
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
jobs:
|
||||
regenerate_integration_tests:
|
||||
if: github.ref != 'refs/heads/main'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- name: Cache Poetry dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cache/pypoetry
|
||||
~/.virtualenvs
|
||||
key: ${{ runner.os }}-poetry-${{ hashFiles('**/poetry.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-poetry-
|
||||
- name: Install poetry via pipx
|
||||
run: pipx install poetry
|
||||
- name: Install Python dependencies using Poetry
|
||||
run: make install-python-dependencies
|
||||
- name: Build Environment
|
||||
run: make build
|
||||
- name: Regenerate integration tests
|
||||
run: |
|
||||
DEBUG=${{ inputs.debug }} \
|
||||
LOG_TO_FILE=${{ inputs.log_to_file }} \
|
||||
FORCE_REGENERATE_TESTS=${{ inputs.force_regenerate_tests }} \
|
||||
FORCE_USE_LLM=${{ inputs.force_use_llm }} \
|
||||
./tests/integration/regenerate.sh
|
||||
- name: Commit changes
|
||||
run: |
|
||||
if git diff --quiet --exit-code; then
|
||||
echo "No changes to commit"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
git config --global user.name 'github-actions[bot]'
|
||||
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
|
||||
git add .
|
||||
# run it twice in case pre-commit makes changes
|
||||
git commit -am "Regenerate integration tests" || git commit -am "Regenerate integration tests"
|
||||
git push
|
||||
2
.github/workflows/review-pr.yml
vendored
2
.github/workflows/review-pr.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
python-version: '3.12'
|
||||
- name: install git, github cli
|
||||
run: |
|
||||
sudo apt-get install -y git gh
|
||||
|
||||
116
.github/workflows/solve-issue.yml
vendored
116
.github/workflows/solve-issue.yml
vendored
@@ -1,116 +0,0 @@
|
||||
# Workflow that uses OpenHands to resolve a GitHub issue. Issue must be labeled 'solve-this'
|
||||
name: Use OpenHands to Resolve GitHub Issue
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [labeled]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
dogfood:
|
||||
if: github.event.label.name == 'solve-this'
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/all-hands-ai/openhands
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
steps:
|
||||
- name: install git, github cli
|
||||
run: apt-get install -y git gh
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Write Task File
|
||||
env:
|
||||
ISSUE_TITLE: ${{ github.event.issue.title }}
|
||||
ISSUE_BODY: ${{ github.event.issue.body }}
|
||||
run: |
|
||||
echo "TITLE:" > task.txt
|
||||
echo "${ISSUE_TITLE}" >> task.txt
|
||||
echo "" >> task.txt
|
||||
echo "BODY:" >> task.txt
|
||||
echo "${ISSUE_BODY}" >> task.txt
|
||||
- name: Set up environment
|
||||
run: |
|
||||
curl -sSL https://install.python-poetry.org | python3 -
|
||||
export PATH="/github/home/.local/bin:$PATH"
|
||||
poetry install --without evaluation,llama-index
|
||||
poetry run playwright install --with-deps chromium
|
||||
- name: Run OpenHands
|
||||
env:
|
||||
ISSUE_TITLE: ${{ github.event.issue.title }}
|
||||
ISSUE_BODY: ${{ github.event.issue.body }}
|
||||
LLM_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
run: |
|
||||
# Append path to launch poetry
|
||||
export PATH="/github/home/.local/bin:$PATH"
|
||||
# Append path to correctly import package, note: must set pwd at first
|
||||
export PYTHONPATH=$(pwd):$PYTHONPATH
|
||||
WORKSPACE_MOUNT_PATH=$GITHUB_WORKSPACE poetry run python ./openhands/core/main.py -i 50 -f task.txt -d $GITHUB_WORKSPACE
|
||||
rm task.txt
|
||||
- name: Setup Git, Create Branch, and Commit Changes
|
||||
run: |
|
||||
# Setup Git configuration
|
||||
git config --global --add safe.directory $PWD
|
||||
git config --global user.name 'OpenHands'
|
||||
git config --global user.email 'OpenHands@users.noreply.github.com'
|
||||
|
||||
# Create a unique branch name with a timestamp
|
||||
BRANCH_NAME="fix/${{ github.event.issue.number }}-$(date +%Y%m%d%H%M%S)"
|
||||
|
||||
# Checkout new branch
|
||||
git checkout -b $BRANCH_NAME
|
||||
|
||||
# Add all changes to staging, except task.txt
|
||||
git add --all -- ':!task.txt'
|
||||
|
||||
# Commit the changes, if any
|
||||
git commit -m "OpenHands: Resolve Issue #${{ github.event.issue.number }}"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "No changes to commit."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Push changes
|
||||
git push --set-upstream origin $BRANCH_NAME
|
||||
- name: Fetch Default Branch
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
# Fetch the default branch using gh cli
|
||||
DEFAULT_BRANCH=$(gh repo view --json defaultBranchRef --jq .defaultBranchRef.name)
|
||||
echo "Default branch is $DEFAULT_BRANCH"
|
||||
echo "DEFAULT_BRANCH=$DEFAULT_BRANCH" >> $GITHUB_ENV
|
||||
- name: Generate PR
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
# Create PR and capture URL
|
||||
PR_URL=$(gh pr create \
|
||||
--title "OpenHands: Resolve Issue #2" \
|
||||
--body "This PR was generated by OpenHands to resolve issue #2" \
|
||||
--repo "foragerr/OpenHands" \
|
||||
--head "${{ github.head_ref }}" \
|
||||
--base "${{ env.DEFAULT_BRANCH }}" \
|
||||
| grep -o 'https://github.com/[^ ]*')
|
||||
|
||||
# Extract PR number from URL
|
||||
PR_NUMBER=$(echo "$PR_URL" | grep -o '[0-9]\+$')
|
||||
|
||||
# Set environment vars
|
||||
echo "PR_URL=$PR_URL" >> $GITHUB_ENV
|
||||
echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_ENV
|
||||
|
||||
- name: Post Comment
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
gh issue comment ${{ github.event.issue.number }} \
|
||||
-b "OpenHands raised [PR #${{ env.PR_NUMBER }}](${{ env.PR_URL }}) to resolve this issue."
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -121,6 +121,7 @@ celerybeat.pid
|
||||
|
||||
# Environments
|
||||
.env
|
||||
frontend/.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
@@ -173,11 +174,11 @@ evaluation/bird/data
|
||||
evaluation/gaia/data
|
||||
evaluation/gorilla/data
|
||||
evaluation/toolqa/data
|
||||
evaluation/scienceagentbench/benchmark
|
||||
|
||||
# frontend
|
||||
|
||||
# dependencies
|
||||
frontend/node_modules
|
||||
frontend/.pnp
|
||||
frontend/bun.lockb
|
||||
frontend/yarn.lock
|
||||
@@ -217,8 +218,6 @@ config.toml
|
||||
config.toml_
|
||||
config.toml.bak
|
||||
|
||||
containers/agnostic_sandbox
|
||||
|
||||
# swe-bench-eval
|
||||
image_build_logs
|
||||
run_instance_logs
|
||||
@@ -229,3 +228,4 @@ runtime_*.tar
|
||||
containers/runtime/Dockerfile
|
||||
containers/runtime/project.tar.gz
|
||||
containers/runtime/code
|
||||
**/node_modules/
|
||||
|
||||
28
.openhands_instructions
Normal file
28
.openhands_instructions
Normal file
@@ -0,0 +1,28 @@
|
||||
OpenHands is an automated AI software engineer. It is a repo with a Python backend
|
||||
(in the `openhands` directory) and TypeScript frontend (in the `frontend` directory).
|
||||
|
||||
General Setup:
|
||||
- To set up the entire repo, including frontend and backend, run `make build`
|
||||
- To run linting and type-checking before finishing the job, run `poetry run pre-commit run --all-files --config ./dev_config/python/.pre-commit-config.yaml`
|
||||
|
||||
Backend:
|
||||
- Located in the `openhands` directory
|
||||
- Testing:
|
||||
- All tests are in `tests/unit/test_*.py`
|
||||
- To test new code, run `poetry run pytest tests/unit/test_xxx.py` where `xxx` is the appropriate file for the current functionality
|
||||
- Write all tests with pytest
|
||||
|
||||
Frontend:
|
||||
- Located in the `frontend` directory
|
||||
- Prerequisites: A recent version of NodeJS / NPM
|
||||
- Setup: Run `npm install` in the frontend directory
|
||||
- Testing:
|
||||
- Run tests: `npm run test`
|
||||
- To run specific tests: `npm run test -- -t "TestName"`
|
||||
- Building:
|
||||
- Build for production: `npm run build`
|
||||
- Environment Variables:
|
||||
- Set in `frontend/.env` or as environment variables
|
||||
- Available variables: VITE_BACKEND_HOST, VITE_USE_TLS, VITE_INSECURE_SKIP_VERIFY, VITE_FRONTEND_PORT
|
||||
- Internationalization:
|
||||
- Generate i18n declaration file: `npm run make-i18n`
|
||||
132
CONTRIBUTING.md
132
CONTRIBUTING.md
@@ -2,95 +2,70 @@
|
||||
|
||||
Thanks for your interest in contributing to OpenHands! We welcome and appreciate contributions.
|
||||
|
||||
## How Can I Contribute?
|
||||
|
||||
There are many ways that you can contribute:
|
||||
|
||||
1. **Download and use** OpenHands, and send [issues](https://github.com/All-Hands-AI/OpenHands/issues) when you encounter something that isn't working or a feature that you'd like to see.
|
||||
2. **Send feedback** after each session by [clicking the thumbs-up thumbs-down buttons](https://docs.all-hands.dev/modules/usage/feedback), so we can see where things are working and failing, and also build an open dataset for training code agents.
|
||||
3. **Improve the Codebase** by sending PRs (see details below). In particular, we have some [good first issue](https://github.com/All-Hands-AI/OpenHands/labels/good%20first%20issue) issues that may be ones to start on.
|
||||
|
||||
## Understanding OpenHands's CodeBase
|
||||
|
||||
To understand the codebase, please refer to the README in each module:
|
||||
- [frontend](./frontend/README.md)
|
||||
- [agenthub](./agenthub/README.md)
|
||||
- [evaluation](./evaluation/README.md)
|
||||
- [openhands](./openhands/README.md)
|
||||
- [server](./openhands/server/README.md)
|
||||
- [agenthub](./openhands/agenthub/README.md)
|
||||
- [server](./openhands/server/README.md)
|
||||
|
||||
## Setting up your development environment
|
||||
|
||||
We have a separate doc [Development.md](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md) that tells you how to set up a development workflow.
|
||||
|
||||
## How can I contribute?
|
||||
|
||||
There are many ways that you can contribute:
|
||||
|
||||
1. **Download and use** OpenHands, and send [issues](https://github.com/All-Hands-AI/OpenHands/issues) when you encounter something that isn't working or a feature that you'd like to see.
|
||||
2. **Send feedback** after each session by [clicking the thumbs-up thumbs-down buttons](https://docs.all-hands.dev/modules/usage/feedback), so we can see where things are working and failing, and also build an open dataset for training code agents.
|
||||
3. **Improve the Codebase** by sending PRs (see details below). In particular, we have some [good first issues](https://github.com/All-Hands-AI/OpenHands/labels/good%20first%20issue) that may be ones to start on.
|
||||
|
||||
## What can I build?
|
||||
Here are a few ways you can help improve the codebase.
|
||||
|
||||
#### UI/UX
|
||||
We're always looking to improve the look and feel of the application. If you've got a small fix
|
||||
for something that's bugging you, feel free to open up a PR that changes the `./frontend` directory.
|
||||
|
||||
If you're looking to make a bigger change, add a new UI element, or significantly alter the style
|
||||
of the application, please open an issue first, or better, join the #frontend channel in our Slack
|
||||
to gather consensus from our design team first.
|
||||
|
||||
#### Improving the agent
|
||||
Our main agent is the CodeAct agent. You can [see its prompts here](https://github.com/All-Hands-AI/OpenHands/tree/main/openhands/agenthub/codeact_agent)
|
||||
|
||||
Changes to these prompts, and to the underlying behavior in Python, can have a huge impact on user experience.
|
||||
You can try modifying the prompts to see how they change the behavior of the agent as you use the app
|
||||
locally, but we will need to do an end-to-end evaluation of any changes here to ensure that the agent
|
||||
is getting better over time.
|
||||
|
||||
We use the [SWE-bench](https://www.swebench.com/) benchmark to test our agent. You can join the #evaluation
|
||||
channel in Slack to learn more.
|
||||
|
||||
#### Adding a new agent
|
||||
You may want to experiment with building new types of agents. You can add an agent to `openhands/agenthub`
|
||||
to help expand the capabilities of OpenHands.
|
||||
|
||||
#### Adding a new runtime
|
||||
The agent needs a place to run code and commands. When you run OpenHands on your laptop, it uses a Docker container
|
||||
to do this by default. But there are other ways of creating a sandbox for the agent.
|
||||
|
||||
If you work for a company that provides a cloud-based runtime, you could help us add support for that runtime
|
||||
by implementing the [interface specified here](https://github.com/All-Hands-AI/OpenHands/blob/main/openhands/runtime/runtime.py).
|
||||
|
||||
#### Testing
|
||||
When you write code, it is also good to write tests. Please navigate to the `tests` folder to see existing test suites.
|
||||
At the moment, we have two kinds of tests: `unit` and `integration`. Please refer to the README for each test suite. These tests also run on GitHub's continuous integration to ensure quality of the project.
|
||||
|
||||
## Sending Pull Requests to OpenHands
|
||||
|
||||
### 1. Fork the Official Repository
|
||||
Fork the [OpenHands repository](https://github.com/All-Hands-AI/OpenHands) into your own account.
|
||||
Clone your own forked repository into your local environment:
|
||||
You'll need to fork our repository to send us a Pull Request. You can learn more
|
||||
about how to fork a GitHub repo and open a PR with your changes in [this article](https://medium.com/swlh/forks-and-pull-requests-how-to-contribute-to-github-repos-8843fac34ce8)
|
||||
|
||||
```shell
|
||||
git clone git@github.com:<YOUR-USERNAME>/OpenHands.git
|
||||
```
|
||||
|
||||
### 2. Configure Git
|
||||
|
||||
Set the official repository as your [upstream](https://www.atlassian.com/git/tutorials/git-forks-and-upstreams) to synchronize with the latest update in the official repository.
|
||||
Add the original repository as upstream:
|
||||
|
||||
```shell
|
||||
cd OpenHands
|
||||
git remote add upstream git@github.com:All-Hands-AI/OpenHands.git
|
||||
```
|
||||
|
||||
Verify that the remote is set:
|
||||
|
||||
```shell
|
||||
git remote -v
|
||||
```
|
||||
|
||||
You should see both `origin` and `upstream` in the output.
|
||||
|
||||
### 3. Synchronize with Official Repository
|
||||
Synchronize latest commit with official repository before coding:
|
||||
|
||||
```shell
|
||||
git fetch upstream
|
||||
git checkout main
|
||||
git merge upstream/main
|
||||
git push origin main
|
||||
```
|
||||
|
||||
### 4. Set up the Development Environment
|
||||
|
||||
We have a separate doc [Development.md](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md) that tells you how to set up a development workflow.
|
||||
|
||||
### 5. Write Code and Commit It
|
||||
|
||||
Once you have done this, you can write code, test it, and commit it to a branch (replace `my_branch` with an appropriate name):
|
||||
|
||||
```shell
|
||||
git checkout -b my_branch
|
||||
git add .
|
||||
git commit
|
||||
git push origin my_branch
|
||||
```
|
||||
|
||||
### 6. Open a Pull Request
|
||||
|
||||
* On GitHub, go to the page of your forked repository, and create a Pull Request:
|
||||
- Click on `Branches`
|
||||
- Click on the `...` beside your branch and click on `New pull request`
|
||||
- Set `base repository` to `All-Hands-AI/OpenHands`
|
||||
- Set `base` to `main`
|
||||
- Click `Create pull request`
|
||||
|
||||
The PR should appear in [OpenHands PRs](https://github.com/All-Hands-AI/OpenHands/pulls).
|
||||
|
||||
Then the OpenHands team will review your code.
|
||||
|
||||
## PR Rules
|
||||
|
||||
### 1. Pull Request title
|
||||
### Pull Request title
|
||||
As described [here](https://github.com/commitizen/conventional-commit-types/blob/master/index.json), a valid PR title should begin with one of the following prefixes:
|
||||
|
||||
- `feat`: A new feature
|
||||
@@ -111,6 +86,9 @@ For example, a PR title could be:
|
||||
|
||||
You may also check out previous PRs in the [PR list](https://github.com/All-Hands-AI/OpenHands/pulls).
|
||||
|
||||
### 2. Pull Request description
|
||||
### Pull Request description
|
||||
- If your PR is small (such as a typo fix), you can go brief.
|
||||
- If it contains a lot of changes, it's better to write more details.
|
||||
|
||||
If your changes are user-facing (e.g. a new feature in the UI, a change in behavior, or a bugfix)
|
||||
please include a short message that we can add to our changelog.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Contributors
|
||||
|
||||
We would like to thank all the [contributors](https://github.com/All-Hands-AI/OpenHands/graphs/contributors) who have helped make OpenHands possible. Your dedication and hard work are greatly appreciated.
|
||||
We would like to thank all the [contributors](https://github.com/All-Hands-AI/OpenHands/graphs/contributors) who have helped make OpenHands possible. We greatly appreciate your dedication and hard work.
|
||||
|
||||
## Open Source Projects
|
||||
|
||||
@@ -10,7 +10,7 @@ OpenHands includes and adapts the following open source projects. We are gratefu
|
||||
|
||||
#### [SWE Agent](https://github.com/princeton-nlp/swe-agent)
|
||||
- License: MIT License
|
||||
- Description: Adapted for use in OpenHands's agenthub
|
||||
- Description: Adapted for use in OpenHands's agent hub
|
||||
|
||||
#### [Aider](https://github.com/paul-gauthier/aider)
|
||||
- License: Apache License 2.0
|
||||
|
||||
@@ -5,12 +5,14 @@ Otherwise, you can clone the OpenHands project directly.
|
||||
|
||||
## Start the server for development
|
||||
### 1. Requirements
|
||||
* Linux, Mac OS, or [WSL on Windows](https://learn.microsoft.com/en-us/windows/wsl/install) [ Ubuntu <= 22.04]
|
||||
* Linux, Mac OS, or [WSL on Windows](https://learn.microsoft.com/en-us/windows/wsl/install) [Ubuntu <= 22.04]
|
||||
* [Docker](https://docs.docker.com/engine/install/) (For those on MacOS, make sure to allow the default Docker socket to be used from advanced settings!)
|
||||
* [Python](https://www.python.org/downloads/) = 3.11
|
||||
* [Python](https://www.python.org/downloads/) = 3.12
|
||||
* [NodeJS](https://nodejs.org/en/download/package-manager) >= 18.17.1
|
||||
* [Poetry](https://python-poetry.org/docs/#installing-with-the-official-installer) >= 1.8
|
||||
* netcat => sudo apt-get install netcat
|
||||
* OS-specific dependencies:
|
||||
- Ubuntu: build-essential => `sudo apt-get install build-essential`
|
||||
- WSL: netcat => `sudo apt-get install netcat`
|
||||
|
||||
Make sure you have all these dependencies installed before moving on to `make build`.
|
||||
|
||||
@@ -22,8 +24,8 @@ If you want to develop without system admin/sudo access to upgrade/install `Pyth
|
||||
curl -L -O "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh"
|
||||
bash Miniforge3-$(uname)-$(uname -m).sh
|
||||
|
||||
# Install Python 3.11, nodejs, and poetry
|
||||
mamba install python=3.11
|
||||
# Install Python 3.12, nodejs, and poetry
|
||||
mamba install python=3.12
|
||||
mamba install conda-forge::nodejs
|
||||
mamba install conda-forge::poetry
|
||||
```
|
||||
@@ -91,13 +93,15 @@ To run tests, refer to the following:
|
||||
poetry run pytest ./tests/unit/test_*.py
|
||||
```
|
||||
|
||||
#### Integration tests
|
||||
Please refer to [this README](./tests/integration/README.md) for details.
|
||||
|
||||
### 9. Add or update dependency
|
||||
1. Add your dependency in `pyproject.toml` or use `poetry add xxx`
|
||||
2. Update the poetry.lock file via `poetry lock --no-update`
|
||||
|
||||
### 9. Use existing Docker image
|
||||
To reduce build time (e.g., if no changes were made to the client-runtime component), you can use an existing Docker container image. Follow these steps:
|
||||
1. Set the SANDBOX_RUNTIME_CONTAINER_IMAGE environment variable to the desired Docker image.
|
||||
2. Example: export SANDBOX_RUNTIME_CONTAINER_IMAGE=ghcr.io/all-hands-ai/runtime:0.13-nikolaik
|
||||
|
||||
## Develop inside Docker container
|
||||
|
||||
TL;DR
|
||||
|
||||
8
Makefile
8
Makefile
@@ -10,7 +10,7 @@ DEFAULT_WORKSPACE_DIR = "./workspace"
|
||||
DEFAULT_MODEL = "gpt-4o"
|
||||
CONFIG_FILE = config.toml
|
||||
PRE_COMMIT_CONFIG_PATH = "./dev_config/python/.pre-commit-config.yaml"
|
||||
PYTHON_VERSION = 3.11
|
||||
PYTHON_VERSION = 3.12
|
||||
|
||||
# ANSI color codes
|
||||
GREEN=$(shell tput -Txterm setaf 2)
|
||||
@@ -190,12 +190,12 @@ build-frontend:
|
||||
# Start backend
|
||||
start-backend:
|
||||
@echo "$(YELLOW)Starting backend...$(RESET)"
|
||||
@poetry run uvicorn openhands.server.listen:app --host $(BACKEND_HOST) --port $(BACKEND_PORT) --reload --reload-exclude "workspace/*"
|
||||
@poetry run uvicorn openhands.server.listen:app --host $(BACKEND_HOST) --port $(BACKEND_PORT) --reload --reload-exclude "$(shell pwd)/workspace"
|
||||
|
||||
# Start frontend
|
||||
start-frontend:
|
||||
@echo "$(YELLOW)Starting frontend...$(RESET)"
|
||||
@cd frontend && VITE_BACKEND_HOST=$(BACKEND_HOST_PORT) VITE_FRONTEND_PORT=$(FRONTEND_PORT) npm run start
|
||||
@cd frontend && VITE_BACKEND_HOST=$(BACKEND_HOST_PORT) VITE_FRONTEND_PORT=$(FRONTEND_PORT) npm run dev -- --port $(FRONTEND_PORT) --host $(BACKEND_HOST)
|
||||
|
||||
# Common setup for running the app (non-callable)
|
||||
_run_setup:
|
||||
@@ -214,7 +214,7 @@ _run_setup:
|
||||
run:
|
||||
@echo "$(YELLOW)Running the app...$(RESET)"
|
||||
@$(MAKE) -s _run_setup
|
||||
@cd frontend && echo "$(BLUE)Starting frontend with npm...$(RESET)" && npm run start -- --port $(FRONTEND_PORT)
|
||||
@$(MAKE) -s start-frontend
|
||||
@echo "$(GREEN)Application started successfully.$(RESET)"
|
||||
|
||||
# Run the app (in docker)
|
||||
|
||||
40
README.md
40
README.md
@@ -12,7 +12,7 @@
|
||||
<a href="https://codecov.io/github/All-Hands-AI/OpenHands?branch=main"><img alt="CodeCov" src="https://img.shields.io/codecov/c/github/All-Hands-AI/OpenHands?style=for-the-badge&color=blue"></a>
|
||||
<a href="https://github.com/All-Hands-AI/OpenHands/blob/main/LICENSE"><img src="https://img.shields.io/github/license/All-Hands-AI/OpenHands?style=for-the-badge&color=blue" alt="MIT License"></a>
|
||||
<br/>
|
||||
<a href="https://join.slack.com/t/opendevin/shared_invite/zt-2oikve2hu-UDxHeo8nsE69y6T7yFX_BA"><img src="https://img.shields.io/badge/Slack-Join%20Us-red?logo=slack&logoColor=white&style=for-the-badge" alt="Join our Slack community"></a>
|
||||
<a href="https://join.slack.com/t/openhands-ai/shared_invite/zt-2tom0er4l-JeNUGHt_AxpEfIBstbLPiw"><img src="https://img.shields.io/badge/Slack-Join%20Us-red?logo=slack&logoColor=white&style=for-the-badge" alt="Join our Slack community"></a>
|
||||
<a href="https://discord.gg/ESHStjSjD4"><img src="https://img.shields.io/badge/Discord-Join%20Us-purple?logo=discord&logoColor=white&style=for-the-badge" alt="Join our Discord community"></a>
|
||||
<a href="https://github.com/All-Hands-AI/OpenHands/blob/main/CREDITS.md"><img src="https://img.shields.io/badge/Project-Credits-blue?style=for-the-badge&color=FFE165&logo=github&logoColor=white" alt="Credits"></a>
|
||||
<br/>
|
||||
@@ -33,33 +33,37 @@ Learn more at [docs.all-hands.dev](https://docs.all-hands.dev), or jump to the [
|
||||
|
||||
## ⚡ Quick Start
|
||||
|
||||
The easiest way to run OpenHands is in Docker. You can change `WORKSPACE_BASE` below to
|
||||
point OpenHands to existing code that you'd like to modify.
|
||||
|
||||
See the [Getting Started](https://docs.all-hands.dev/modules/usage/getting-started) guide for
|
||||
The easiest way to run OpenHands is in Docker.
|
||||
See the [Installation](https://docs.all-hands.dev/modules/usage/installation) guide for
|
||||
system requirements and more information.
|
||||
|
||||
```bash
|
||||
export WORKSPACE_BASE=$(pwd)/workspace
|
||||
docker pull docker.all-hands.dev/all-hands-ai/runtime:0.13-nikolaik
|
||||
|
||||
docker run -it --pull=always \
|
||||
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=ghcr.io/all-hands-ai/runtime:0.9-nikolaik \
|
||||
-e SANDBOX_USER_ID=$(id -u) \
|
||||
-e WORKSPACE_MOUNT_PATH=$WORKSPACE_BASE \
|
||||
-v $WORKSPACE_BASE:/opt/workspace_base \
|
||||
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.13-nikolaik \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-p 3000:3000 \
|
||||
-e LOG_ALL_EVENTS=true \
|
||||
--add-host host.docker.internal:host-gateway \
|
||||
--name openhands-app-$(date +%Y%m%d%H%M%S) \
|
||||
ghcr.io/all-hands-ai/openhands:0.9
|
||||
--name openhands-app \
|
||||
docker.all-hands.dev/all-hands-ai/openhands:0.13
|
||||
```
|
||||
|
||||
You'll find OpenHands running at [http://localhost:3000](http://localhost:3000)!
|
||||
|
||||
You can also run OpenHands in a scriptable [headless mode](https://docs.all-hands.dev/modules/usage/how-to/headless-mode),
|
||||
or as an [interactive CLI](https://docs.all-hands.dev/modules/usage/how-to/cli-mode).
|
||||
Finally, you'll need a model provider and API key.
|
||||
[Anthropic's Claude 3.5 Sonnet](https://www.anthropic.com/api) (`anthropic/claude-3-5-sonnet-20241022`)
|
||||
works best, but you have [many options](https://docs.all-hands.dev/modules/usage/llms).
|
||||
|
||||
Visit [Getting Started](https://docs.all-hands.dev/modules/usage/getting-started) for more information and setup instructions.
|
||||
---
|
||||
|
||||
You can also [connect OpenHands to your local filesystem](https://docs.all-hands.dev/modules/usage/runtimes),
|
||||
run OpenHands in a scriptable [headless mode](https://docs.all-hands.dev/modules/usage/how-to/headless-mode),
|
||||
interact with it via a [friendly CLI](https://docs.all-hands.dev/modules/usage/how-to/cli-mode),
|
||||
or run it on tagged issues with [a github action](https://github.com/All-Hands-AI/OpenHands-resolver).
|
||||
|
||||
Visit [Installation](https://docs.all-hands.dev/modules/usage/installation) for more information and setup instructions.
|
||||
|
||||
If you want to modify the OpenHands source code, check out [Development.md](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md).
|
||||
|
||||
@@ -90,7 +94,7 @@ For details, please check [CONTRIBUTING.md](./CONTRIBUTING.md).
|
||||
Whether you're a developer, a researcher, or simply enthusiastic about OpenHands, we'd love to have you in our community.
|
||||
Let's make software engineering better together!
|
||||
|
||||
- [Slack workspace](https://join.slack.com/t/opendevin/shared_invite/zt-2oikve2hu-UDxHeo8nsE69y6T7yFX_BA) - Here we talk about research, architecture, and future development.
|
||||
- [Slack workspace](https://join.slack.com/t/openhands-ai/shared_invite/zt-2tom0er4l-JeNUGHt_AxpEfIBstbLPiw) - Here we talk about research, architecture, and future development.
|
||||
- [Discord server](https://discord.gg/ESHStjSjD4) - This is a community-run server for general discussion, questions, and feedback.
|
||||
|
||||
## 📈 Progress
|
||||
@@ -114,8 +118,8 @@ For a list of open source projects and licenses used in OpenHands, please see ou
|
||||
## 📚 Cite
|
||||
|
||||
```
|
||||
@misc{opendevin,
|
||||
title={{OpenDevin: An Open Platform for AI Software Developers as Generalist Agents}},
|
||||
@misc{openhands,
|
||||
title={{OpenHands: An Open Platform for AI Software Developers as Generalist Agents}},
|
||||
author={Xingyao Wang and Boxuan Li and Yufan Song and Frank F. Xu and Xiangru Tang and Mingchen Zhuge and Jiayi Pan and Yueqi Song and Bowen Li and Jaskirat Singh and Hoang H. Tran and Fuqiang Li and Ren Ma and Mingzhang Zheng and Bill Qian and Yanjun Shao and Niklas Muennighoff and Yizhe Zhang and Binyuan Hui and Junyang Lin and Robert Brennan and Hao Peng and Heng Ji and Graham Neubig},
|
||||
year={2024},
|
||||
eprint={2407.16741},
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
import ast
|
||||
|
||||
from openhands.controller.action_parser import ActionParser, ResponseParser
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.events.action import (
|
||||
Action,
|
||||
BrowseInteractiveAction,
|
||||
)
|
||||
|
||||
|
||||
class BrowsingResponseParser(ResponseParser):
|
||||
def __init__(self):
|
||||
# Need to pay attention to the item order in self.action_parsers
|
||||
super().__init__()
|
||||
self.action_parsers = [BrowsingActionParserMessage()]
|
||||
self.default_parser = BrowsingActionParserBrowseInteractive()
|
||||
|
||||
def parse(self, response: str) -> Action:
|
||||
action_str = self.parse_response(response)
|
||||
return self.parse_action(action_str)
|
||||
|
||||
def parse_response(self, response) -> str:
|
||||
action_str = response['choices'][0]['message']['content']
|
||||
if action_str is None:
|
||||
return ''
|
||||
action_str = action_str.strip()
|
||||
if action_str and not action_str.endswith('```'):
|
||||
action_str = action_str + ')```'
|
||||
logger.debug(action_str)
|
||||
return action_str
|
||||
|
||||
def parse_action(self, action_str: str) -> Action:
|
||||
for action_parser in self.action_parsers:
|
||||
if action_parser.check_condition(action_str):
|
||||
return action_parser.parse(action_str)
|
||||
return self.default_parser.parse(action_str)
|
||||
|
||||
|
||||
class BrowsingActionParserMessage(ActionParser):
|
||||
"""Parser action:
|
||||
- BrowseInteractiveAction(browser_actions) - unexpected response format, message back to user
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
):
|
||||
pass
|
||||
|
||||
def check_condition(self, action_str: str) -> bool:
|
||||
return '```' not in action_str
|
||||
|
||||
def parse(self, action_str: str) -> Action:
|
||||
msg = f'send_msg_to_user("""{action_str}""")'
|
||||
return BrowseInteractiveAction(
|
||||
browser_actions=msg,
|
||||
thought=action_str,
|
||||
browsergym_send_msg_to_user=action_str,
|
||||
)
|
||||
|
||||
|
||||
class BrowsingActionParserBrowseInteractive(ActionParser):
|
||||
"""Parser action:
|
||||
- BrowseInteractiveAction(browser_actions) - handle send message to user function call in BrowserGym
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
):
|
||||
pass
|
||||
|
||||
def check_condition(self, action_str: str) -> bool:
|
||||
return True
|
||||
|
||||
def parse(self, action_str: str) -> Action:
|
||||
thought = action_str.split('```')[0].strip()
|
||||
action_str = action_str.split('```')[1].strip()
|
||||
msg_content = ''
|
||||
for sub_action in action_str.split('\n'):
|
||||
if 'send_msg_to_user(' in sub_action:
|
||||
tree = ast.parse(sub_action)
|
||||
args = tree.body[0].value.args # type: ignore
|
||||
msg_content = args[0].value
|
||||
|
||||
return BrowseInteractiveAction(
|
||||
browser_actions=action_str,
|
||||
thought=thought,
|
||||
browsergym_send_msg_to_user=msg_content,
|
||||
)
|
||||
@@ -1,285 +0,0 @@
|
||||
import os
|
||||
from itertools import islice
|
||||
|
||||
from agenthub.codeact_agent.action_parser import CodeActResponseParser
|
||||
from openhands.controller.agent import Agent
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import AgentConfig
|
||||
from openhands.core.message import ImageContent, Message, TextContent
|
||||
from openhands.events.action import (
|
||||
Action,
|
||||
AgentDelegateAction,
|
||||
AgentFinishAction,
|
||||
CmdRunAction,
|
||||
IPythonRunCellAction,
|
||||
MessageAction,
|
||||
)
|
||||
from openhands.events.observation import (
|
||||
AgentDelegateObservation,
|
||||
CmdOutputObservation,
|
||||
IPythonRunCellObservation,
|
||||
UserRejectObservation,
|
||||
)
|
||||
from openhands.events.observation.error import ErrorObservation
|
||||
from openhands.events.observation.observation import Observation
|
||||
from openhands.events.serialization.event import truncate_content
|
||||
from openhands.llm.llm import LLM
|
||||
from openhands.runtime.plugins import (
|
||||
AgentSkillsRequirement,
|
||||
JupyterRequirement,
|
||||
PluginRequirement,
|
||||
)
|
||||
from openhands.utils.microagent import MicroAgent
|
||||
from openhands.utils.prompt import PromptManager
|
||||
|
||||
|
||||
class CodeActAgent(Agent):
|
||||
VERSION = '1.9'
|
||||
"""
|
||||
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.
|
||||
|
||||
### Overview
|
||||
|
||||
This agent implements the CodeAct idea ([paper](https://arxiv.org/abs/2402.01030), [tweet](https://twitter.com/xingyaow_/status/1754556835703751087)) that consolidates LLM agents’ **act**ions into a unified **code** action space for both *simplicity* and *performance* (see paper for more details).
|
||||
|
||||
The conceptual idea is illustrated below. At each turn, the agent can:
|
||||
|
||||
1. **Converse**: Communicate with humans in natural language to ask for clarification, confirmation, etc.
|
||||
2. **CodeAct**: Choose to perform the task by executing code
|
||||
- Execute any valid Linux `bash` command
|
||||
- Execute any valid `Python` code with [an interactive Python interpreter](https://ipython.org/). This is simulated through `bash` command, see plugin system below for more details.
|
||||
|
||||

|
||||
|
||||
"""
|
||||
|
||||
sandbox_plugins: list[PluginRequirement] = [
|
||||
# NOTE: AgentSkillsRequirement need to go before JupyterRequirement, since
|
||||
# AgentSkillsRequirement provides a lot of Python functions,
|
||||
# and it needs to be initialized before Jupyter for Jupyter to use those functions.
|
||||
AgentSkillsRequirement(),
|
||||
JupyterRequirement(),
|
||||
]
|
||||
|
||||
action_parser = CodeActResponseParser()
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
llm: LLM,
|
||||
config: AgentConfig,
|
||||
) -> None:
|
||||
"""Initializes a new instance of the CodeActAgent class.
|
||||
|
||||
Parameters:
|
||||
- llm (LLM): The llm to be used by this agent
|
||||
"""
|
||||
super().__init__(llm, config)
|
||||
self.reset()
|
||||
|
||||
self.micro_agent = (
|
||||
MicroAgent(
|
||||
os.path.join(
|
||||
os.path.dirname(__file__), 'micro', f'{config.micro_agent_name}.md'
|
||||
)
|
||||
)
|
||||
if config.micro_agent_name
|
||||
else None
|
||||
)
|
||||
|
||||
self.prompt_manager = PromptManager(
|
||||
prompt_dir=os.path.join(os.path.dirname(__file__)),
|
||||
agent_skills_docs=AgentSkillsRequirement.documentation,
|
||||
micro_agent=self.micro_agent,
|
||||
)
|
||||
|
||||
def action_to_str(self, action: Action) -> str:
|
||||
if isinstance(action, CmdRunAction):
|
||||
return (
|
||||
f'{action.thought}\n<execute_bash>\n{action.command}\n</execute_bash>'
|
||||
)
|
||||
elif isinstance(action, IPythonRunCellAction):
|
||||
return f'{action.thought}\n<execute_ipython>\n{action.code}\n</execute_ipython>'
|
||||
elif isinstance(action, AgentDelegateAction):
|
||||
return f'{action.thought}\n<execute_browse>\n{action.inputs["task"]}\n</execute_browse>'
|
||||
elif isinstance(action, MessageAction):
|
||||
return action.content
|
||||
elif isinstance(action, AgentFinishAction) and action.source == 'agent':
|
||||
return action.thought
|
||||
return ''
|
||||
|
||||
def get_action_message(self, action: Action) -> Message | None:
|
||||
if (
|
||||
isinstance(action, AgentDelegateAction)
|
||||
or isinstance(action, CmdRunAction)
|
||||
or isinstance(action, IPythonRunCellAction)
|
||||
or isinstance(action, MessageAction)
|
||||
or (isinstance(action, AgentFinishAction) and action.source == 'agent')
|
||||
):
|
||||
content = [TextContent(text=self.action_to_str(action))]
|
||||
|
||||
if (
|
||||
self.llm.vision_is_active()
|
||||
and isinstance(action, MessageAction)
|
||||
and action.images_urls
|
||||
):
|
||||
content.append(ImageContent(image_urls=action.images_urls))
|
||||
|
||||
return Message(
|
||||
role='user' if action.source == 'user' else 'assistant', content=content
|
||||
)
|
||||
return None
|
||||
|
||||
def get_observation_message(self, obs: Observation) -> Message | None:
|
||||
max_message_chars = self.llm.config.max_message_chars
|
||||
obs_prefix = 'OBSERVATION:\n'
|
||||
if isinstance(obs, CmdOutputObservation):
|
||||
text = obs_prefix + truncate_content(obs.content, max_message_chars)
|
||||
text += (
|
||||
f'\n[Command {obs.command_id} finished with exit code {obs.exit_code}]'
|
||||
)
|
||||
return Message(role='user', content=[TextContent(text=text)])
|
||||
elif isinstance(obs, IPythonRunCellObservation):
|
||||
text = obs_prefix + obs.content
|
||||
# replace base64 images with a placeholder
|
||||
splitted = text.split('\n')
|
||||
for i, line in enumerate(splitted):
|
||||
if ' already displayed to user'
|
||||
)
|
||||
text = '\n'.join(splitted)
|
||||
text = truncate_content(text, max_message_chars)
|
||||
return Message(role='user', content=[TextContent(text=text)])
|
||||
elif isinstance(obs, AgentDelegateObservation):
|
||||
text = obs_prefix + truncate_content(
|
||||
obs.outputs['content'] if 'content' in obs.outputs else '',
|
||||
max_message_chars,
|
||||
)
|
||||
return Message(role='user', content=[TextContent(text=text)])
|
||||
elif isinstance(obs, ErrorObservation):
|
||||
text = obs_prefix + truncate_content(obs.content, max_message_chars)
|
||||
text += '\n[Error occurred in processing last action]'
|
||||
return Message(role='user', content=[TextContent(text=text)])
|
||||
elif isinstance(obs, UserRejectObservation):
|
||||
text = 'OBSERVATION:\n' + truncate_content(obs.content, max_message_chars)
|
||||
text += '\n[Last action has been rejected by the user]'
|
||||
return Message(role='user', content=[TextContent(text=text)])
|
||||
else:
|
||||
# If an observation message is not returned, it will cause an error
|
||||
# when the LLM tries to return the next message
|
||||
raise ValueError(f'Unknown observation type: {type(obs)}')
|
||||
|
||||
def reset(self) -> None:
|
||||
"""Resets the CodeAct Agent."""
|
||||
super().reset()
|
||||
|
||||
def step(self, state: State) -> Action:
|
||||
"""Performs one step using the CodeAct Agent.
|
||||
This includes gathering info on previous steps and prompting the model to make a command to execute.
|
||||
|
||||
Parameters:
|
||||
- state (State): used to get updated info
|
||||
|
||||
Returns:
|
||||
- CmdRunAction(command) - bash command to run
|
||||
- IPythonRunCellAction(code) - IPython code to run
|
||||
- AgentDelegateAction(agent, inputs) - delegate action for (sub)task
|
||||
- MessageAction(content) - Message action to run (e.g. ask for clarification)
|
||||
- AgentFinishAction() - end the interaction
|
||||
"""
|
||||
# if we're done, go back
|
||||
latest_user_message = state.history.get_last_user_message()
|
||||
if latest_user_message and latest_user_message.strip() == '/exit':
|
||||
return AgentFinishAction()
|
||||
|
||||
# prepare what we want to send to the LLM
|
||||
messages = self._get_messages(state)
|
||||
params = {
|
||||
'messages': self.llm.format_messages_for_llm(messages),
|
||||
'stop': [
|
||||
'</execute_ipython>',
|
||||
'</execute_bash>',
|
||||
'</execute_browse>',
|
||||
],
|
||||
}
|
||||
|
||||
if self.llm.is_caching_prompt_active():
|
||||
params['extra_headers'] = {
|
||||
'anthropic-beta': 'prompt-caching-2024-07-31',
|
||||
}
|
||||
|
||||
response = self.llm.completion(**params)
|
||||
|
||||
return self.action_parser.parse(response)
|
||||
|
||||
def _get_messages(self, state: State) -> list[Message]:
|
||||
messages: list[Message] = [
|
||||
Message(
|
||||
role='system',
|
||||
content=[
|
||||
TextContent(
|
||||
text=self.prompt_manager.system_message,
|
||||
cache_prompt=self.llm.is_caching_prompt_active(), # Cache system prompt
|
||||
)
|
||||
],
|
||||
),
|
||||
Message(
|
||||
role='user',
|
||||
content=[
|
||||
TextContent(
|
||||
text=self.prompt_manager.initial_user_message,
|
||||
cache_prompt=self.llm.is_caching_prompt_active(), # if the user asks the same query,
|
||||
)
|
||||
],
|
||||
),
|
||||
]
|
||||
|
||||
for event in state.history.get_events():
|
||||
# create a regular message from an event
|
||||
if isinstance(event, Action):
|
||||
message = self.get_action_message(event)
|
||||
elif isinstance(event, Observation):
|
||||
message = self.get_observation_message(event)
|
||||
else:
|
||||
raise ValueError(f'Unknown event type: {type(event)}')
|
||||
|
||||
# add regular message
|
||||
if message:
|
||||
# handle error if the message is the SAME role as the previous message
|
||||
# litellm.exceptions.BadRequestError: litellm.BadRequestError: OpenAIException - Error code: 400 - {'detail': 'Only supports u/a/u/a/u...'}
|
||||
# there shouldn't be two consecutive messages from the same role
|
||||
if messages and messages[-1].role == message.role:
|
||||
messages[-1].content.extend(message.content)
|
||||
else:
|
||||
messages.append(message)
|
||||
|
||||
# Add caching to the last 2 user messages
|
||||
if self.llm.is_caching_prompt_active():
|
||||
user_turns_processed = 0
|
||||
for message in reversed(messages):
|
||||
if message.role == 'user' and user_turns_processed < 2:
|
||||
message.content[
|
||||
-1
|
||||
].cache_prompt = True # Last item inside the message content
|
||||
user_turns_processed += 1
|
||||
|
||||
# The latest user message is important:
|
||||
# we want to remind the agent of the environment constraints
|
||||
latest_user_message = next(
|
||||
islice(
|
||||
(
|
||||
m
|
||||
for m in reversed(messages)
|
||||
if m.role == 'user'
|
||||
and any(isinstance(c, TextContent) for c in m.content)
|
||||
),
|
||||
1,
|
||||
),
|
||||
None,
|
||||
)
|
||||
if latest_user_message:
|
||||
reminder_text = f'\n\nENVIRONMENT REMINDER: You have {state.max_iterations - state.iteration} turns left to complete the task. When finished reply with <finish></finish>.'
|
||||
latest_user_message.content.append(TextContent(text=reminder_text))
|
||||
|
||||
return messages
|
||||
@@ -1,69 +0,0 @@
|
||||
---
|
||||
name: github
|
||||
agent: CodeActAgent
|
||||
require_env_var:
|
||||
SANDBOX_ENV_GITHUB_TOKEN: "Create a GitHub Personal Access Token (https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) and set it as SANDBOX_GITHUB_TOKEN in your environment variables."
|
||||
---
|
||||
|
||||
# How to Interact with Github
|
||||
|
||||
## Environment Variable Available
|
||||
|
||||
- `GITHUB_TOKEN`: A read-only token for Github.
|
||||
|
||||
## Using GitHub's RESTful API
|
||||
|
||||
Use `curl` with the `GITHUB_TOKEN` to interact with GitHub's API. Here are some common operations:
|
||||
|
||||
Here's a template for API calls:
|
||||
|
||||
```sh
|
||||
curl -H "Authorization: token $GITHUB_TOKEN" \
|
||||
"https://api.github.com/{endpoint}"
|
||||
```
|
||||
|
||||
First replace `{endpoint}` with the specific API path. Common operations:
|
||||
|
||||
1. View an issue or pull request:
|
||||
- Issues: `/repos/{owner}/{repo}/issues/{issue_number}`
|
||||
- Pull requests: `/repos/{owner}/{repo}/pulls/{pull_request_number}`
|
||||
|
||||
2. List repository issues or pull requests:
|
||||
- Issues: `/repos/{owner}/{repo}/issues`
|
||||
- Pull requests: `/repos/{owner}/{repo}/pulls`
|
||||
|
||||
3. Search issues or pull requests:
|
||||
- `/search/issues?q=repo:{owner}/{repo}+is:{type}+{search_term}+state:{state}`
|
||||
- Replace `{type}` with `issue` or `pr`
|
||||
|
||||
4. List repository branches:
|
||||
`/repos/{owner}/{repo}/branches`
|
||||
|
||||
5. Get commit details:
|
||||
`/repos/{owner}/{repo}/commits/{commit_sha}`
|
||||
|
||||
6. Get repository details:
|
||||
`/repos/{owner}/{repo}`
|
||||
|
||||
7. Get user information:
|
||||
`/user`
|
||||
|
||||
8. Search repositories:
|
||||
`/search/repositories?q={query}`
|
||||
|
||||
9. Get rate limit status:
|
||||
`/rate_limit`
|
||||
|
||||
Replace `{owner}`, `{repo}`, `{commit_sha}`, `{issue_number}`, `{pull_request_number}`,
|
||||
`{search_term}`, `{state}`, and `{query}` with appropriate values.
|
||||
|
||||
## Important Notes
|
||||
|
||||
1. Always use the GitHub API for operations instead of a web browser.
|
||||
2. The `GITHUB_TOKEN` is read-only. Avoid operations that require write access.
|
||||
3. Git config (username and email) is pre-set. Do not modify.
|
||||
4. Edit and test code locally. Never push directly to remote.
|
||||
5. Verify correct branch before committing.
|
||||
6. Commit changes frequently.
|
||||
7. If the issue or task is ambiguous or lacks sufficient detail, always request clarification from the user before proceeding.
|
||||
8. You should avoid using command line tools like `sed` for file editing.
|
||||
@@ -1,52 +0,0 @@
|
||||
{% set MINIMAL_SYSTEM_PREFIX %}
|
||||
A chat between a curious user and an artificial intelligence assistant. The assistant gives helpful, detailed answers to the user's questions.
|
||||
The assistant can use a Python environment with <execute_ipython>, e.g.:
|
||||
<execute_ipython>
|
||||
print("Hello World!")
|
||||
</execute_ipython>
|
||||
The assistant can execute bash commands wrapped with <execute_bash>, e.g. <execute_bash> ls </execute_bash>.
|
||||
If a bash command returns exit code `-1`, this means the process is not yet finished.
|
||||
The assistant must then send a second <execute_bash>. The second <execute_bash> can be empty
|
||||
(which will retrieve any additional logs), or it can contain text to be sent to STDIN of the running process,
|
||||
or it can contain the text `ctrl+c` to interrupt the process.
|
||||
|
||||
For commands that may run indefinitely, the output should be redirected to a file and the command run
|
||||
in the background, e.g. <execute_bash> python3 app.py > server.log 2>&1 & </execute_bash>
|
||||
If a command execution result says "Command timed out. Sending SIGINT to the process",
|
||||
the assistant should retry running the command in the background.
|
||||
{% endset %}
|
||||
{% set BROWSING_PREFIX %}
|
||||
The assistant can browse the Internet with <execute_browse> and </execute_browse>.
|
||||
For example, <execute_browse> Tell me the usa's president using google search </execute_browse>.
|
||||
Or <execute_browse> Tell me what is in http://example.com </execute_browse>.
|
||||
{% endset %}
|
||||
{% set PIP_INSTALL_PREFIX %}
|
||||
The assistant can install Python packages using the %pip magic command in an IPython environment by using the following syntax: <execute_ipython> %pip install [package needed] </execute_ipython> and should always import packages and define variables before starting to use them.
|
||||
{% endset %}
|
||||
{% set SYSTEM_PREFIX = MINIMAL_SYSTEM_PREFIX + BROWSING_PREFIX + PIP_INSTALL_PREFIX %}
|
||||
{% set COMMAND_DOCS %}
|
||||
Apart from the standard Python library, the assistant can also use the following functions (already imported) in <execute_ipython> environment:
|
||||
{{ agent_skills_docs }}
|
||||
IMPORTANT:
|
||||
- `open_file` only returns the first 100 lines of the file by default! The assistant MUST use `scroll_down` repeatedly to read the full file BEFORE making edits!
|
||||
- The assistant shall adhere to THE `edit_file_by_replace`, `append_file` and `insert_content_at_line` FUNCTIONS REQUIRING PROPER INDENTATION. If the assistant would like to add the line ' print(x)', it must fully write the line out, with all leading spaces before the code!
|
||||
- Indentation is important and code that is not indented correctly will fail and require fixing before it can be run.
|
||||
- Any code issued should be less than 50 lines to avoid context being cut off!
|
||||
- After EVERY `create_file` the method `append_file` shall be used to write the FIRST content!
|
||||
- For `edit_file_by_replace` NEVER provide empty parameters!
|
||||
- For `edit_file_by_replace` the file must be read fully before any replacements!
|
||||
{% endset %}
|
||||
{% set SYSTEM_SUFFIX %}
|
||||
Responses should be concise.
|
||||
The assistant should attempt fewer things at a time instead of putting too many commands OR too much code in one "execute" block.
|
||||
Include ONLY ONE <execute_ipython>, <execute_bash>, or <execute_browse> per response, unless the assistant is finished with the task or needs more input or action from the user in order to proceed.
|
||||
If the assistant is finished with the task you MUST include <finish></finish> in your response.
|
||||
IMPORTANT: Execute code using <execute_ipython>, <execute_bash>, or <execute_browse> whenever possible.
|
||||
The assistant should utilize full file paths and the `pwd` command to prevent path-related errors.
|
||||
The assistant must avoid apologies and thanks in its responses.
|
||||
|
||||
{% endset %}
|
||||
{# Combine all parts without newlines between them #}
|
||||
{{ SYSTEM_PREFIX -}}
|
||||
{{- COMMAND_DOCS -}}
|
||||
{{- SYSTEM_SUFFIX }}
|
||||
5
build.sh
Executable file
5
build.sh
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
cp pyproject.toml poetry.lock openhands
|
||||
poetry build -v
|
||||
@@ -7,7 +7,7 @@ services:
|
||||
image: openhands:latest
|
||||
container_name: openhands-app-${DATE:-}
|
||||
environment:
|
||||
- SANDBOX_RUNTIME_CONTAINER_IMAGE=${SANDBOX_RUNTIME_CONTAINER_IMAGE:-ghcr.io/all-hands-ai/runtime:0.9-nikolaik}
|
||||
- SANDBOX_RUNTIME_CONTAINER_IMAGE=${SANDBOX_RUNTIME_CONTAINER_IMAGE:-ghcr.io/all-hands-ai/runtime:0.13-nikolaik}
|
||||
- SANDBOX_USER_ID=${SANDBOX_USER_ID:-1234}
|
||||
- WORKSPACE_MOUNT_PATH=${WORKSPACE_BASE:-$PWD/workspace}
|
||||
ports:
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
# API key for E2B
|
||||
#e2b_api_key = ""
|
||||
|
||||
# API key for Modal
|
||||
#modal_api_token_id = ""
|
||||
#modal_api_token_secret = ""
|
||||
|
||||
# Base path for the workspace
|
||||
workspace_base = "./workspace"
|
||||
|
||||
@@ -28,6 +32,10 @@ workspace_base = "./workspace"
|
||||
# Enable saving and restoring the session when run from CLI
|
||||
#enable_cli_session = false
|
||||
|
||||
# Path to store trajectories, can be a folder or a file
|
||||
# If it's a folder, the session id will be used as the file name
|
||||
#trajectories_path="./trajectories"
|
||||
|
||||
# File store path
|
||||
#file_store_path = "/tmp/file_store"
|
||||
|
||||
@@ -112,7 +120,7 @@ api_key = "your-api-key"
|
||||
#embedding_deployment_name = ""
|
||||
|
||||
# Embedding model to use
|
||||
embedding_model = ""
|
||||
embedding_model = "local"
|
||||
|
||||
# Maximum number of characters in an observation's content
|
||||
#max_message_chars = 10000
|
||||
@@ -146,8 +154,8 @@ model = "gpt-4o"
|
||||
# Drop any unmapped (unsupported) params without causing an exception
|
||||
#drop_params = false
|
||||
|
||||
# Using the prompt caching feature provided by the LLM
|
||||
#caching_prompt = false
|
||||
# Using the prompt caching feature if provided by the LLM and supported
|
||||
#caching_prompt = true
|
||||
|
||||
# Base URL for the OLLAMA API
|
||||
#ollama_base_url = ""
|
||||
@@ -165,11 +173,9 @@ model = "gpt-4o"
|
||||
#disable_vision = true
|
||||
|
||||
[llm.gpt4o-mini]
|
||||
# API key to use
|
||||
api_key = "your-api-key"
|
||||
model = "gpt-4o"
|
||||
|
||||
# Model to use
|
||||
model = "gpt-4o-mini"
|
||||
|
||||
#################################### Agent ###################################
|
||||
# Configuration for agents (group name starts with 'agent')
|
||||
@@ -185,10 +191,10 @@ model = "gpt-4o-mini"
|
||||
#memory_enabled = false
|
||||
|
||||
# Memory maximum threads
|
||||
#memory_max_threads = 2
|
||||
#memory_max_threads = 3
|
||||
|
||||
# LLM config group to use
|
||||
#llm_config = 'llm'
|
||||
#llm_config = 'your-llm-config-group'
|
||||
|
||||
[agent.RepoExplorerAgent]
|
||||
# Example: use a cheaper model for RepoExplorerAgent to reduce cost, especially
|
||||
@@ -206,7 +212,7 @@ llm_config = 'gpt3'
|
||||
#user_id = 1000
|
||||
|
||||
# Container image to use for the sandbox
|
||||
#base_container_image = "nikolaik/python-nodejs:python3.11-nodejs22"
|
||||
#base_container_image = "nikolaik/python-nodejs:python3.12-nodejs22"
|
||||
|
||||
# Use host network
|
||||
#use_host_network = false
|
||||
@@ -232,7 +238,7 @@ llm_config = 'gpt3'
|
||||
[security]
|
||||
|
||||
# Enable confirmation mode
|
||||
#confirmation_mode = true
|
||||
#confirmation_mode = false
|
||||
|
||||
# The security analyzer to use
|
||||
#security_analyzer = ""
|
||||
|
||||
@@ -8,7 +8,7 @@ RUN npm install -g npm@10.5.1
|
||||
RUN npm ci
|
||||
|
||||
COPY ./frontend ./
|
||||
RUN npm run make-i18n && npm run build
|
||||
RUN npm run build
|
||||
|
||||
FROM python:3.12.3-slim AS backend-builder
|
||||
|
||||
@@ -28,7 +28,7 @@ COPY ./pyproject.toml ./poetry.lock ./
|
||||
RUN touch README.md
|
||||
RUN export POETRY_CACHE_DIR && poetry install --without evaluation,llama-index --no-root && rm -rf $POETRY_CACHE_DIR
|
||||
|
||||
FROM python:3.12.3-slim AS runtime
|
||||
FROM python:3.12.3-slim AS openhands-app
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
@@ -37,10 +37,11 @@ ARG OPENHANDS_BUILD_VERSION #re-declare for this section
|
||||
ENV RUN_AS_OPENHANDS=true
|
||||
# A random number--we need this to be different from the user's UID on the host machine
|
||||
ENV OPENHANDS_USER_ID=42420
|
||||
ENV SANDBOX_API_HOSTNAME=host.docker.internal
|
||||
ENV SANDBOX_LOCAL_RUNTIME_URL=http://host.docker.internal
|
||||
ENV USE_HOST_NETWORK=false
|
||||
ENV WORKSPACE_BASE=/opt/workspace_base
|
||||
ENV OPENHANDS_BUILD_VERSION=$OPENHANDS_BUILD_VERSION
|
||||
ENV SANDBOX_USER_ID=0
|
||||
RUN mkdir -p $WORKSPACE_BASE
|
||||
|
||||
RUN apt-get update -y \
|
||||
@@ -69,11 +70,12 @@ RUN playwright install --with-deps chromium
|
||||
|
||||
COPY --chown=openhands:app --chmod=770 ./openhands ./openhands
|
||||
COPY --chown=openhands:app --chmod=777 ./openhands/runtime/plugins ./openhands/runtime/plugins
|
||||
COPY --chown=openhands:app --chmod=770 ./agenthub ./agenthub
|
||||
COPY --chown=openhands:app --chmod=770 ./pyproject.toml ./pyproject.toml
|
||||
COPY --chown=openhands:app --chmod=770 ./poetry.lock ./poetry.lock
|
||||
COPY --chown=openhands:app --chmod=770 ./README.md ./README.md
|
||||
COPY --chown=openhands:app --chmod=770 ./MANIFEST.in ./MANIFEST.in
|
||||
COPY --chown=openhands:app --chmod=770 ./openhands/agenthub ./openhands/agenthub
|
||||
COPY --chown=openhands:app ./pyproject.toml ./pyproject.toml
|
||||
COPY --chown=openhands:app ./poetry.lock ./poetry.lock
|
||||
COPY --chown=openhands:app ./README.md ./README.md
|
||||
COPY --chown=openhands:app ./MANIFEST.in ./MANIFEST.in
|
||||
COPY --chown=openhands:app ./LICENSE ./LICENSE
|
||||
|
||||
# This is run as "openhands" user, and will create __pycache__ with openhands:openhands ownership
|
||||
RUN python openhands/core/download.py # No-op to download assets
|
||||
@@ -81,7 +83,7 @@ RUN python openhands/core/download.py # No-op to download assets
|
||||
# openhands:openhands -> openhands:app
|
||||
RUN find /app \! -group app -exec chgrp app {} +
|
||||
|
||||
COPY --chown=openhands:app --chmod=770 --from=frontend-builder /app/dist ./frontend/dist
|
||||
COPY --chown=openhands:app --chmod=770 --from=frontend-builder /app/build ./frontend/build
|
||||
COPY --chown=openhands:app --chmod=770 ./containers/app/entrypoint.sh /app/entrypoint.sh
|
||||
|
||||
USER root
|
||||
|
||||
@@ -18,6 +18,11 @@ if [ -z "$SANDBOX_USER_ID" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$WORKSPACE_MOUNT_PATH" ]; then
|
||||
# This is set to /opt/workspace in the Dockerfile. But if the user isn't mounting, we want to unset it so that OpenHands doesn't mount at all
|
||||
unset WORKSPACE_BASE
|
||||
fi
|
||||
|
||||
if [[ "$SANDBOX_USER_ID" -eq 0 ]]; then
|
||||
echo "Running OpenHands as root"
|
||||
export RUN_AS_OPENHANDS=false
|
||||
|
||||
@@ -1,13 +1,40 @@
|
||||
#!/bin/bash
|
||||
set -eo pipefail
|
||||
|
||||
image_name=$1
|
||||
org_name=$2
|
||||
# Initialize variables with default values
|
||||
image_name=""
|
||||
org_name=""
|
||||
push=0
|
||||
if [[ $3 == "--push" ]]; then
|
||||
push=1
|
||||
load=0
|
||||
tag_suffix=""
|
||||
|
||||
# Function to display usage information
|
||||
usage() {
|
||||
echo "Usage: $0 -i <image_name> [-o <org_name>] [--push] [--load] [-t <tag_suffix>]"
|
||||
echo " -i: Image name (required)"
|
||||
echo " -o: Organization name"
|
||||
echo " --push: Push the image"
|
||||
echo " --load: Load the image"
|
||||
echo " -t: Tag suffix"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Parse command-line options
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-i) image_name="$2"; shift 2 ;;
|
||||
-o) org_name="$2"; shift 2 ;;
|
||||
--push) push=1; shift ;;
|
||||
--load) load=1; shift ;;
|
||||
-t) tag_suffix="$2"; shift 2 ;;
|
||||
*) usage ;;
|
||||
esac
|
||||
done
|
||||
# Check if required arguments are provided
|
||||
if [[ -z "$image_name" ]]; then
|
||||
echo "Error: Image name is required."
|
||||
usage
|
||||
fi
|
||||
tag_suffix=$4
|
||||
|
||||
echo "Building: $image_name"
|
||||
tags=()
|
||||
@@ -17,10 +44,10 @@ OPENHANDS_BUILD_VERSION="dev"
|
||||
cache_tag_base="buildcache"
|
||||
cache_tag="$cache_tag_base"
|
||||
|
||||
if [[ -n $GITHUB_SHA ]]; then
|
||||
git_hash=$(git rev-parse --short "$GITHUB_SHA")
|
||||
if [[ -n $RELEVANT_SHA ]]; then
|
||||
git_hash=$(git rev-parse --short "$RELEVANT_SHA")
|
||||
tags+=("$git_hash")
|
||||
tags+=("$GITHUB_SHA")
|
||||
tags+=("$RELEVANT_SHA")
|
||||
fi
|
||||
|
||||
if [[ -n $GITHUB_REF_NAME ]]; then
|
||||
@@ -71,9 +98,9 @@ if [[ -n "$org_name" ]]; then
|
||||
DOCKER_ORG="$org_name"
|
||||
fi
|
||||
|
||||
# If $DOCKER_IMAGE_HASH_TAG is set, add it to the tags
|
||||
if [[ -n "$DOCKER_IMAGE_HASH_TAG" ]]; then
|
||||
tags+=("$DOCKER_IMAGE_HASH_TAG")
|
||||
# If $DOCKER_IMAGE_SOURCE_TAG is set, add it to the tags
|
||||
if [[ -n "$DOCKER_IMAGE_SOURCE_TAG" ]]; then
|
||||
tags+=("$DOCKER_IMAGE_SOURCE_TAG")
|
||||
fi
|
||||
# If $DOCKER_IMAGE_TAG is set, add it to the tags
|
||||
if [[ -n "$DOCKER_IMAGE_TAG" ]]; then
|
||||
@@ -95,14 +122,35 @@ if [[ $push -eq 1 ]]; then
|
||||
args+=" --cache-to=type=registry,ref=$DOCKER_REPOSITORY:$cache_tag,mode=max"
|
||||
fi
|
||||
|
||||
if [[ $load -eq 1 ]]; then
|
||||
args+=" --load"
|
||||
fi
|
||||
|
||||
echo "Args: $args"
|
||||
|
||||
# Modify the platform selection based on --load flag
|
||||
if [[ $load -eq 1 ]]; then
|
||||
# When loading, build only for the current platform
|
||||
platform=$(docker version -f '{{.Server.Os}}/{{.Server.Arch}}')
|
||||
else
|
||||
# For push or without load, build for multiple platforms
|
||||
platform="linux/amd64,linux/arm64"
|
||||
fi
|
||||
|
||||
echo "Building for platform(s): $platform"
|
||||
|
||||
docker buildx build \
|
||||
$args \
|
||||
--build-arg OPENHANDS_BUILD_VERSION="$OPENHANDS_BUILD_VERSION" \
|
||||
--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 \
|
||||
--platform $platform \
|
||||
--provenance=false \
|
||||
-f "$dir/Dockerfile" \
|
||||
"$DOCKER_BASE_DIR"
|
||||
|
||||
# If load was requested, print the loaded images
|
||||
if [[ $load -eq 1 ]]; then
|
||||
echo "Local images built:"
|
||||
docker images "$DOCKER_REPOSITORY" --format "{{.Repository}}:{{.Tag}}"
|
||||
fi
|
||||
|
||||
@@ -55,18 +55,18 @@ RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | d
|
||||
&& apt-get clean \
|
||||
&& apt-get autoremove -y
|
||||
|
||||
# Python 3.11
|
||||
# Python 3.12
|
||||
RUN add-apt-repository ppa:deadsnakes/ppa \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y python3.11 python3.11-venv python3.11-dev python3-pip \
|
||||
&& ln -s /usr/bin/python3.11 /usr/bin/python
|
||||
&& apt-get install -y python3.12 python3.12-venv python3.12-dev python3-pip \
|
||||
&& ln -s /usr/bin/python3.12 /usr/bin/python
|
||||
|
||||
# NodeJS >= 18.17.1
|
||||
RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
|
||||
&& apt-get install -y nodejs
|
||||
|
||||
# Poetry >= 1.8
|
||||
RUN curl -fsSL https://install.python-poetry.org | python3.11 - \
|
||||
RUN curl -fsSL https://install.python-poetry.org | python3.12 - \
|
||||
&& ln -s ~/.local/bin/poetry /usr/local/bin/poetry
|
||||
|
||||
#
|
||||
|
||||
@@ -11,7 +11,7 @@ services:
|
||||
- BACKEND_HOST=${BACKEND_HOST:-"0.0.0.0"}
|
||||
- SANDBOX_API_HOSTNAME=host.docker.internal
|
||||
#
|
||||
- SANDBOX_RUNTIME_CONTAINER_IMAGE=${SANDBOX_RUNTIME_CONTAINER_IMAGE:-ghcr.io/all-hands-ai/runtime:0.9-nikolaik}
|
||||
- SANDBOX_RUNTIME_CONTAINER_IMAGE=${SANDBOX_RUNTIME_CONTAINER_IMAGE:-ghcr.io/all-hands-ai/runtime:0.13-nikolaik}
|
||||
- SANDBOX_USER_ID=${SANDBOX_USER_ID:-1234}
|
||||
- WORKSPACE_MOUNT_PATH=${WORKSPACE_BASE:-$PWD/workspace}
|
||||
ports:
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
This folder builds a runtime image (sandbox), which will use a dynamically generated `Dockerfile`
|
||||
that depends on the `base_image` **AND** a [Python source distribution](https://docs.python.org/3.10/distutils/sourcedist.html) that is based on the current commit of `openhands`.
|
||||
|
||||
The following command will generate a `Dockerfile` file for `nikolaik/python-nodejs:python3.11-nodejs22` (the default base image), an updated `config.sh` and the runtime source distribution files/folders into `containers/runtime`:
|
||||
The following command will generate a `Dockerfile` file for `nikolaik/python-nodejs:python3.12-nodejs22` (the default base image), an updated `config.sh` and the runtime source distribution files/folders into `containers/runtime`:
|
||||
|
||||
```bash
|
||||
poetry run python3 openhands/runtime/utils/runtime_build.py \
|
||||
--base_image nikolaik/python-nodejs:python3.11-nodejs22 \
|
||||
--base_image nikolaik/python-nodejs:python3.12-nodejs22 \
|
||||
--build_folder containers/runtime
|
||||
```
|
||||
|
||||
@@ -4,4 +4,4 @@ DOCKER_BASE_DIR="./containers/runtime"
|
||||
DOCKER_IMAGE=runtime
|
||||
# These variables will be appended by the runtime_build.py script
|
||||
# DOCKER_IMAGE_TAG=
|
||||
# DOCKER_IMAGE_HASH_TAG=
|
||||
# DOCKER_IMAGE_SOURCE_TAG=
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
FROM ubuntu:22.04
|
||||
|
||||
# install basic packages
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
vim \
|
||||
nano \
|
||||
unzip \
|
||||
zip \
|
||||
python3 \
|
||||
python3-pip \
|
||||
python3-venv \
|
||||
python3-dev \
|
||||
build-essential \
|
||||
openssh-server \
|
||||
sudo \
|
||||
gcc \
|
||||
jq \
|
||||
g++ \
|
||||
make \
|
||||
iproute2 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN mkdir -p -m0755 /var/run/sshd
|
||||
|
||||
# symlink python3 to python
|
||||
RUN ln -s /usr/bin/python3 /usr/bin/python
|
||||
|
||||
# ==== OpenHands Runtime Client ====
|
||||
RUN mkdir -p /openhands && mkdir -p /openhands/logs && chmod 777 /openhands/logs
|
||||
RUN wget --progress=bar:force -O Miniforge3.sh "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh"
|
||||
RUN bash Miniforge3.sh -b -p /openhands/miniforge3
|
||||
RUN chmod -R g+w /openhands/miniforge3
|
||||
RUN bash -c ". /openhands/miniforge3/etc/profile.d/conda.sh && conda config --set changeps1 False && conda config --append channels conda-forge"
|
||||
RUN echo "" > /openhands/bash.bashrc
|
||||
RUN rm -f Miniforge3.sh
|
||||
|
||||
# - agentskills dependencies
|
||||
RUN /openhands/miniforge3/bin/pip install --upgrade pip
|
||||
RUN /openhands/miniforge3/bin/pip install jupyterlab notebook jupyter_kernel_gateway flake8
|
||||
RUN /openhands/miniforge3/bin/pip install python-docx PyPDF2 python-pptx pylatexenc openai
|
||||
RUN /openhands/miniforge3/bin/pip install python-dotenv toml termcolor pydantic python-docx pyyaml docker pexpect tenacity e2b browsergym minio
|
||||
@@ -1,4 +0,0 @@
|
||||
DOCKER_REGISTRY=ghcr.io
|
||||
DOCKER_ORG=all-hands-ai
|
||||
DOCKER_IMAGE=sandbox
|
||||
DOCKER_BASE_DIR="."
|
||||
@@ -38,6 +38,6 @@ repos:
|
||||
- id: mypy
|
||||
additional_dependencies:
|
||||
[types-requests, types-setuptools, types-pyyaml, types-toml]
|
||||
entry: mypy --config-file dev_config/python/mypy.ini openhands/ agenthub/
|
||||
entry: mypy --config-file dev_config/python/mypy.ini openhands/
|
||||
always_run: true
|
||||
pass_filenames: false
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
|
||||
|
||||
# Documentation Python
|
||||
|
||||
Les documents apparaîtront ici après le déploiement.
|
||||
La documentation apparaîtra ici après le déploiement.
|
||||
|
||||
@@ -1,53 +1,49 @@
|
||||
---
|
||||
sidebar_position: 7
|
||||
---
|
||||
# 📚 Divers
|
||||
|
||||
# 📚 Divers {#misc}
|
||||
## ⭐️ Stratégie de recherche
|
||||
|
||||
## ⭐️ Stratégie de Recherche {#research-strategy}
|
||||
La réplication complète d'applications de niveau production avec des LLM est une entreprise complexe. Notre stratégie implique :
|
||||
|
||||
La réalisation d'une réplication complète des applications de production avec les LLM est une entreprise complexe. Notre stratégie implique :
|
||||
1. **Recherche technique fondamentale :** Se concentrer sur la recherche fondamentale pour comprendre et améliorer les aspects techniques de la génération et de la gestion de code
|
||||
2. **Capacités spécialisées :** Améliorer l'efficacité des composants de base grâce à la curation de données, aux méthodes d'entraînement, etc.
|
||||
3. **Planification des tâches :** Développer des capacités de détection de bugs, de gestion de base de code et d'optimisation
|
||||
4. **Évaluation :** Établir des métriques d'évaluation complètes pour mieux comprendre et améliorer nos modèles
|
||||
|
||||
1. **Recherche Technique de Base :** Se concentrer sur la recherche fondamentale pour comprendre et améliorer les aspects techniques de la génération et de la gestion de code.
|
||||
2. **Compétences Spécialisées :** Améliorer l'efficacité des composants de base grâce à la curation des données, aux méthodes de formation, et plus encore.
|
||||
3. **Planification des Tâches :** Développer des capacités pour la détection de bogues, la gestion du code source et l'optimisation.
|
||||
4. **Évaluation :** Établir des métriques d'évaluation complètes pour mieux comprendre et améliorer nos modèles.
|
||||
## 🚧 Agent par défaut
|
||||
|
||||
## 🚧 Agent Par Défaut {#default-agent}
|
||||
Notre Agent par défaut est actuellement le [CodeActAgent](agents), qui est capable de générer du code et de gérer des fichiers.
|
||||
|
||||
- Notre agent par défaut est actuellement le CodeActAgent, capable de générer du code et de gérer des fichiers. Nous travaillons sur d'autres implémentations d'agents, y compris [SWE Agent](https://swe-agent.com/). Vous pouvez [lire à propos de notre ensemble actuel d'agents ici](./agents).
|
||||
## 🤝 Comment contribuer
|
||||
|
||||
## 🤝 Comment Contribuer {#how-to-contribute}
|
||||
OpenHands est un projet communautaire et nous accueillons les contributions de tous. Que vous soyez développeur, chercheur ou simplement enthousiaste à l'idée de faire progresser le domaine de l'ingénierie logicielle avec l'IA, il existe de nombreuses façons de s'impliquer :
|
||||
|
||||
OpenHands est un projet communautaire, et nous accueillons les contributions de tout le monde. Que vous soyez développeur, chercheur, ou simplement enthousiaste à l'idée de faire progresser le domaine de l'ingénierie logicielle avec l'IA, il existe de nombreuses façons de vous impliquer :
|
||||
|
||||
- **Contributions de Code :** Aidez-nous à développer les fonctionnalités de base, l'interface frontend ou les solutions de sandboxing.
|
||||
- **Recherche et Évaluation :** Contribuez à notre compréhension des LLM en ingénierie logicielle, participez à l'évaluation des modèles ou suggérez des améliorations.
|
||||
- **Retour d'Information et Tests :** Utilisez l'ensemble d'outils OpenHands, signalez des bogues, suggérez des fonctionnalités ou fournissez des retours sur l'ergonomie.
|
||||
- **Contributions de code :** Aidez-nous à développer les fonctionnalités de base, l'interface frontend ou les solutions de sandboxing
|
||||
- **Recherche et évaluation :** Contribuez à notre compréhension des LLM dans l'ingénierie logicielle, participez à l'évaluation des modèles ou suggérez des améliorations
|
||||
- **Retours et tests :** Utilisez la boîte à outils OpenHands, signalez des bugs, suggérez des fonctionnalités ou donnez votre avis sur la facilité d'utilisation
|
||||
|
||||
Pour plus de détails, veuillez consulter [ce document](https://github.com/All-Hands-AI/OpenHands/blob/main/CONTRIBUTING.md).
|
||||
|
||||
## 🤖 Rejoignez Notre Communauté {#join-our-community}
|
||||
## 🤖 Rejoignez notre communauté
|
||||
|
||||
Nous avons maintenant à la fois un espace de travail Slack pour la collaboration sur la construction d'OpenHands et un serveur Discord pour discuter de tout ce qui est lié, par exemple, à ce projet, aux LLM, aux agents, etc.
|
||||
Nous avons à la fois un espace de travail Slack pour la collaboration sur la construction d'OpenHands et un serveur Discord pour discuter de tout ce qui est lié, par exemple, à ce projet, LLM, agent, etc.
|
||||
|
||||
- [Espace de travail Slack](https://join.slack.com/t/opendevin/shared_invite/zt-2oikve2hu-UDxHeo8nsE69y6T7yFX_BA)
|
||||
- [Serveur Discord](https://discord.gg/ESHStjSjD4)
|
||||
|
||||
Si vous souhaitez contribuer, n'hésitez pas à rejoindre notre communauté. Simplifions l'ingénierie logicielle ensemble !
|
||||
Si vous souhaitez contribuer, n'hésitez pas à rejoindre notre communauté. Simplifions ensemble l'ingénierie logicielle !
|
||||
|
||||
🐚 **Codez moins, créez plus avec OpenHands.**
|
||||
🐚 **Codez moins, faites plus avec OpenHands.**
|
||||
|
||||
[](https://star-history.com/#All-Hands-AI/OpenHands&Date)
|
||||
|
||||
## 🛠️ Construit Avec {#built-with}
|
||||
## 🛠️ Construit avec
|
||||
|
||||
OpenHands est construit en utilisant une combinaison de cadres et de bibliothèques puissants, offrant une base robuste pour son développement. Voici les technologies clés utilisées dans le projet :
|
||||
OpenHands est construit en utilisant une combinaison de frameworks et de bibliothèques puissants, fournissant une base solide pour son développement. Voici les principales technologies utilisées dans le projet :
|
||||
|
||||
       
|
||||
|
||||
Veuillez noter que la sélection de ces technologies est en cours, et que des technologies supplémentaires peuvent être ajoutées ou des existantes supprimées au fur et à mesure de l'évolution du projet. Nous nous efforçons d'adopter les outils les plus adaptés et efficaces pour améliorer les capacités d'OpenHands.
|
||||
Veuillez noter que la sélection de ces technologies est en cours et que des technologies supplémentaires peuvent être ajoutées ou des technologies existantes peuvent être supprimées à mesure que le projet évolue. Nous nous efforçons d'adopter les outils les plus appropriés et les plus efficaces pour améliorer les capacités d'OpenHands.
|
||||
|
||||
## 📜 Licence {#license}
|
||||
## 📜 Licence
|
||||
|
||||
Distribué sous la licence MIT. Voir [notre licence](https://github.com/All-Hands-AI/OpenHands/blob/main/LICENSE) pour plus d'informations.
|
||||
|
||||
@@ -1,98 +1,25 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# 🧠 Agents et Capacités
|
||||
|
||||
## Agent CodeAct
|
||||
# 🧠 Agent Principal et Capacités
|
||||
|
||||
## CodeActAgent
|
||||
|
||||
### Description
|
||||
|
||||
Cet agent implémente l'idée CodeAct ([article](https://arxiv.org/abs/2402.01030), [tweet](https://twitter.com/xingyaow_/status/1754556835703751087)) qui consolide les **act**ions des agents LLM en un espace d'action **code** unifié pour à la fois la _simplicité_ et la _performance_ (voir article pour plus de détails).
|
||||
Cet agent implémente l'idée de CodeAct ([article](https://arxiv.org/abs/2402.01030), [tweet](https://twitter.com/xingyaow_/status/1754556835703751087)) qui consolide les **act**ions des agents LLM dans un espace d'action de **code** unifié à la fois pour la _simplicité_ et la _performance_.
|
||||
|
||||
L'idée conceptuelle est illustrée ci-dessous. À chaque tour, l'agent peut :
|
||||
|
||||
1. **Converse** : Communiquer avec les humains en langage naturel pour demander des clarifications, des confirmations, etc.
|
||||
2. **CodeAct** : Choisir d'accomplir la tâche en exécutant du code
|
||||
1. **Converser** : Communiquer avec les humains en langage naturel pour demander des clarifications, des confirmations, etc.
|
||||
2. **CodeAct** : Choisir d'effectuer la tâche en exécutant du code
|
||||
|
||||
- Exécuter toute commande `bash` Linux valide
|
||||
- Exécuter tout code `Python` valide avec [un interpréteur Python interactif](https://ipython.org/). Cela est simulé à travers la commande `bash`, voir le système de plugin ci-dessous pour plus de détails.
|
||||
- Exécuter n'importe quelle commande Linux `bash` valide
|
||||
- Exécuter n'importe quel code `Python` valide avec [un interpréteur Python interactif](https://ipython.org/). Ceci est simulé via une commande `bash`, voir le système de plugin ci-dessous pour plus de détails.
|
||||
|
||||

|
||||
|
||||
### Système de Plugin
|
||||
|
||||
Pour rendre l'agent CodeAct plus puissant avec seulement l'accès à l'espace d'action `bash`, l'agent CodeAct exploite le système de plugins d'OpenHands:
|
||||
|
||||
- [Plugin Jupyter](https://github.com/All-Hands-AI/OpenHands/tree/main/openhands/runtime/plugins/jupyter) : pour l'exécution d'IPython via la commande bash
|
||||
- [Plugin outil agent SWE](https://github.com/All-Hands-AI/OpenHands/tree/main/openhands/runtime/plugins/swe_agent_commands) : Outils de ligne de commande bash puissants pour les tâches de développement logiciel introduits par [swe-agent](https://github.com/princeton-nlp/swe-agent).
|
||||
|
||||
### Démonstration
|
||||
### Démo
|
||||
|
||||
https://github.com/All-Hands-AI/OpenHands/assets/38853559/f592a192-e86c-4f48-ad31-d69282d5f6ac
|
||||
|
||||
_Exemple de CodeActAgent avec `gpt-4-turbo-2024-04-09` effectuant une tâche de science des données (régression linéaire)_
|
||||
|
||||
### Actions
|
||||
|
||||
`Action`,
|
||||
`CmdRunAction`,
|
||||
`IPythonRunCellAction`,
|
||||
`AgentEchoAction`,
|
||||
`AgentFinishAction`,
|
||||
`AgentTalkAction`
|
||||
|
||||
### Observations
|
||||
|
||||
`CmdOutputObservation`,
|
||||
`IPythonRunCellObservation`,
|
||||
`AgentMessageObservation`,
|
||||
`UserMessageObservation`
|
||||
|
||||
### Méthodes
|
||||
|
||||
| Méthode | Description |
|
||||
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `__init__` | Initialise un agent avec `llm` et une liste de messages `list[Mapping[str, str]]` |
|
||||
| `step` | Effectue une étape en utilisant l'agent CodeAct. Cela inclut la collecte d'informations sur les étapes précédentes et invite le modèle à exécuter une commande. |
|
||||
|
||||
### En cours de réalisation & prochaine étape
|
||||
|
||||
[] Support de la navigation sur le web
|
||||
[] Compléter le workflow pour l'agent CodeAct afin de soumettre des PRs Github
|
||||
|
||||
## Agent Planificateur
|
||||
|
||||
### Description
|
||||
|
||||
L'agent planificateur utilise une stratégie d'incitation spéciale pour créer des plans à long terme pour résoudre les problèmes.
|
||||
L'agent reçoit ses paires action-observation précédentes, la tâche actuelle, et un indice basé sur la dernière action effectuée à chaque étape.
|
||||
|
||||
### Actions
|
||||
|
||||
`NullAction`,
|
||||
`CmdRunAction`,
|
||||
`BrowseURLAction`,
|
||||
`GithubPushAction`,
|
||||
`FileReadAction`,
|
||||
`FileWriteAction`,
|
||||
`AgentThinkAction`,
|
||||
`AgentFinishAction`,
|
||||
`AgentSummarizeAction`,
|
||||
`AddTaskAction`,
|
||||
`ModifyTaskAction`,
|
||||
|
||||
### Observations
|
||||
|
||||
`Observation`,
|
||||
`NullObservation`,
|
||||
`CmdOutputObservation`,
|
||||
`FileReadObservation`,
|
||||
`BrowserOutputObservation`
|
||||
|
||||
### Méthodes
|
||||
|
||||
| Méthode | Description |
|
||||
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `__init__` | Initialise un agent avec `llm` |
|
||||
| `step` | Vérifie si l'étape actuelle est terminée, retourne `AgentFinishAction` si oui. Sinon, crée une incitation de planification et l'envoie au modèle pour inférence, en ajoutant le résultat comme prochaine action. |
|
||||
_Exemple de CodeActAgent avec `gpt-4-turbo-2024-04-09` effectuant une tâche de science des données (régression linéaire)_.
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
|
||||
|
||||
# 🏛️ Architecture du Système
|
||||
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<img src="https://github.com/All-Hands-AI/OpenHands/assets/16201837/97d747e3-29d8-4ccb-8d34-6ad1adb17f38" alt="OpenHands System Architecture Diagram Jul 4 2024" />
|
||||
<p><em>Diagramme de l'Architecture du Système OpenHands (4 juillet 2024)</em></p>
|
||||
</div>
|
||||
|
||||
Ceci est une vue d'ensemble de haut niveau de l'architecture du système. Le système est divisé en deux composants principaux : le frontend et le backend. Le frontend est responsable de la gestion des interactions utilisateur et de l'affichage des résultats. Le backend est responsable de la gestion de la logique métier et de l'exécution des agents.
|
||||
|
||||
# Architecture du Frontend {#frontend-architecture-fr}
|
||||
|
||||

|
||||
|
||||
Cette vue d'ensemble est simplifiée pour montrer les principaux composants et leurs interactions. Pour une vue plus détaillée de l'architecture du backend, voir la section Architecture du Backend ci-dessous.
|
||||
|
||||
# Architecture du Backend {#backend-architecture-fr}
|
||||
|
||||
_**Avertissement** : L'architecture du backend est en cours de développement et est sujette à changement. Le diagramme suivant montre l'architecture actuelle du backend basée sur le commit indiqué dans le pied de page du diagramme._
|
||||
|
||||

|
||||
|
||||
<details>
|
||||
<summary>Mise à jour de ce Diagramme</summary>
|
||||
<div>
|
||||
La génération du diagramme d'architecture du backend est partiellement automatisée.
|
||||
Le diagramme est généré à partir des indications de type dans le code en utilisant l'outil py2puml. Le diagramme est ensuite manuellement revu, ajusté et exporté en PNG et SVG.
|
||||
|
||||
## Prérequis
|
||||
|
||||
- Environnement python fonctionnel dans lequel openhands est exécutable
|
||||
(selon les instructions du fichier README.md à la racine du dépôt)
|
||||
- [py2puml](https://github.com/lucsorel/py2puml) installé
|
||||
|
||||
## Étapes
|
||||
|
||||
1. Générer automatiquement le diagramme en exécutant la commande suivante depuis la racine du dépôt :
|
||||
`py2puml openhands openhands > docs/architecture/backend_architecture.puml`
|
||||
|
||||
2. Ouvrir le fichier généré dans un éditeur PlantUML, par ex. Visual Studio Code avec l'extension PlantUML ou [PlantText](https://www.planttext.com/)
|
||||
|
||||
3. Revoir le PUML généré et effectuer tous les ajustements nécessaires au diagramme (ajouter les parties manquantes, corriger les erreurs, améliorer le positionnement).
|
||||
_py2puml crée le diagramme en se basant sur les indications de type dans le code, donc des indications manquantes ou incorrectes peuvent entraîner un diagramme incomplet ou incorrect._
|
||||
|
||||
4. Revoir la différence entre le nouveau diagramme et le précédent et vérifier manuellement si les changements sont corrects.
|
||||
_S'assurer de ne pas supprimer des parties qui ont été ajoutées manuellement au diagramme par le passé et qui sont toujours pertinentes._
|
||||
|
||||
5. Ajouter le hash du commit qui a été utilisé pour générer le diagramme dans le pied de page du diagramme.
|
||||
|
||||
6. Exporter le diagramme sous forme de fichiers PNG et SVG et remplacer les diagrammes existants dans le répertoire `docs/architecture`. Cela peut être fait avec (par ex. [PlantText](https://www.planttext.com/))
|
||||
|
||||
</div>
|
||||
</details>
|
||||
@@ -0,0 +1,138 @@
|
||||
|
||||
|
||||
# 📦 Runtime EventStream
|
||||
|
||||
Le Runtime EventStream d'OpenHands est le composant principal qui permet l'exécution sécurisée et flexible des actions des agents d'IA.
|
||||
Il crée un environnement en bac à sable (sandbox) en utilisant Docker, où du code arbitraire peut être exécuté en toute sécurité sans risquer le système hôte.
|
||||
|
||||
## Pourquoi avons-nous besoin d'un runtime en bac à sable ?
|
||||
|
||||
OpenHands doit exécuter du code arbitraire dans un environnement sécurisé et isolé pour plusieurs raisons :
|
||||
|
||||
1. Sécurité : L'exécution de code non fiable peut poser des risques importants pour le système hôte. Un environnement en bac à sable empêche le code malveillant d'accéder ou de modifier les ressources du système hôte
|
||||
2. Cohérence : Un environnement en bac à sable garantit que l'exécution du code est cohérente sur différentes machines et configurations, éliminant les problèmes du type "ça fonctionne sur ma machine"
|
||||
3. Contrôle des ressources : Le bac à sable permet un meilleur contrôle de l'allocation et de l'utilisation des ressources, empêchant les processus incontrôlés d'affecter le système hôte
|
||||
4. Isolation : Différents projets ou utilisateurs peuvent travailler dans des environnements isolés sans interférer les uns avec les autres ou avec le système hôte
|
||||
5. Reproductibilité : Les environnements en bac à sable facilitent la reproduction des bugs et des problèmes, car l'environnement d'exécution est cohérent et contrôlable
|
||||
|
||||
## Comment fonctionne le Runtime ?
|
||||
|
||||
Le système Runtime d'OpenHands utilise une architecture client-serveur implémentée avec des conteneurs Docker. Voici un aperçu de son fonctionnement :
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[Image Docker personnalisée fournie par l'utilisateur] --> B[Backend OpenHands]
|
||||
B -->|Construit| C[Image OH Runtime]
|
||||
C -->|Lance| D[Exécuteur d'actions]
|
||||
D -->|Initialise| E[Navigateur]
|
||||
D -->|Initialise| F[Shell Bash]
|
||||
D -->|Initialise| G[Plugins]
|
||||
G -->|Initialise| L[Serveur Jupyter]
|
||||
|
||||
B -->|Génère| H[Agent]
|
||||
B -->|Génère| I[EventStream]
|
||||
I <--->|Exécute l'action pour
|
||||
obtenir l'observation
|
||||
via l'API REST
|
||||
| D
|
||||
|
||||
H -->|Génère l'action| I
|
||||
I -->|Obtient l'observation| H
|
||||
|
||||
subgraph "Conteneur Docker"
|
||||
D
|
||||
E
|
||||
F
|
||||
G
|
||||
L
|
||||
end
|
||||
```
|
||||
|
||||
1. Entrée utilisateur : L'utilisateur fournit une image Docker de base personnalisée
|
||||
2. Construction de l'image : OpenHands construit une nouvelle image Docker (l'"image OH runtime") basée sur l'image fournie par l'utilisateur. Cette nouvelle image inclut le code spécifique à OpenHands, principalement le "client runtime"
|
||||
3. Lancement du conteneur : Lorsqu'OpenHands démarre, il lance un conteneur Docker en utilisant l'image OH runtime
|
||||
4. Initialisation du serveur d'exécution des actions : Le serveur d'exécution des actions initialise un `ActionExecutor` à l'intérieur du conteneur, mettant en place les composants nécessaires comme un shell bash et chargeant les plugins spécifiés
|
||||
5. Communication : Le backend OpenHands (`openhands/runtime/impl/eventstream/eventstream_runtime.py`) communique avec le serveur d'exécution des actions via une API RESTful, envoyant des actions et recevant des observations
|
||||
6. Exécution des actions : Le client runtime reçoit les actions du backend, les exécute dans l'environnement en bac à sable et renvoie les observations
|
||||
7. Retour des observations : Le serveur d'exécution des actions renvoie les résultats d'exécution au backend OpenHands sous forme d'observations
|
||||
|
||||
|
||||
Le rôle du client :
|
||||
- Il agit comme un intermédiaire entre le backend OpenHands et l'environnement en bac à sable
|
||||
- Il exécute différents types d'actions (commandes shell, opérations sur les fichiers, code Python, etc.) en toute sécurité dans le conteneur
|
||||
- Il gère l'état de l'environnement en bac à sable, y compris le répertoire de travail courant et les plugins chargés
|
||||
- Il formate et renvoie les observations au backend, assurant une interface cohérente pour le traitement des résultats
|
||||
|
||||
|
||||
## Comment OpenHands construit et maintient les images OH Runtime
|
||||
|
||||
L'approche d'OpenHands pour la construction et la gestion des images runtime assure l'efficacité, la cohérence et la flexibilité dans la création et la maintenance des images Docker pour les environnements de production et de développement.
|
||||
|
||||
Consultez le [code pertinent](https://github.com/All-Hands-AI/OpenHands/blob/main/openhands/runtime/utils/runtime_build.py) si vous souhaitez plus de détails.
|
||||
|
||||
### Système de balises d'images
|
||||
|
||||
OpenHands utilise un système à trois balises pour ses images runtime afin d'équilibrer la reproductibilité et la flexibilité.
|
||||
Les balises peuvent être dans l'un des 2 formats suivants :
|
||||
|
||||
- **Balise versionnée** : `oh_v{openhands_version}_{base_image}` (ex : `oh_v0.9.9_nikolaik_s_python-nodejs_t_python3.12-nodejs22`)
|
||||
- **Balise de verrouillage** : `oh_v{openhands_version}_{16_digit_lock_hash}` (ex : `oh_v0.9.9_1234567890abcdef`)
|
||||
- **Balise source** : `oh_v{openhands_version}_{16_digit_lock_hash}_{16_digit_source_hash}`
|
||||
(ex : `oh_v0.9.9_1234567890abcdef_1234567890abcdef`)
|
||||
|
||||
|
||||
#### Balise source - La plus spécifique
|
||||
|
||||
Il s'agit des 16 premiers chiffres du MD5 du hash du répertoire pour le répertoire source. Cela donne un hash
|
||||
uniquement pour la source d'openhands
|
||||
|
||||
|
||||
#### Balise de verrouillage
|
||||
|
||||
Ce hash est construit à partir des 16 premiers chiffres du MD5 de :
|
||||
- Le nom de l'image de base sur laquelle l'image a été construite (ex : `nikolaik/python-nodejs:python3.12-nodejs22`)
|
||||
- Le contenu du `pyproject.toml` inclus dans l'image.
|
||||
- Le contenu du `poetry.lock` inclus dans l'image.
|
||||
|
||||
Cela donne effectivement un hash pour les dépendances d'Openhands indépendamment du code source.
|
||||
|
||||
#### Balise versionnée - La plus générique
|
||||
|
||||
Cette balise est une concaténation de la version d'openhands et du nom de l'image de base (transformé pour s'adapter au standard des balises).
|
||||
|
||||
#### Processus de construction
|
||||
|
||||
Lors de la génération d'une image...
|
||||
|
||||
- **Pas de reconstruction** : OpenHands vérifie d'abord si une image avec la même **balise source la plus spécifique** existe. S'il existe une telle image,
|
||||
aucune construction n'est effectuée - l'image existante est utilisée.
|
||||
- **Reconstruction la plus rapide** : OpenHands vérifie ensuite si une image avec la **balise de verrouillage générique** existe. S'il existe une telle image,
|
||||
OpenHands construit une nouvelle image basée sur celle-ci, en contournant toutes les étapes d'installation (comme `poetry install` et
|
||||
`apt-get`) sauf une opération finale pour copier le code source actuel. La nouvelle image est balisée avec une
|
||||
balise **source** uniquement.
|
||||
- **Reconstruction correcte** : Si ni une balise **source** ni une balise **de verrouillage** n'existe, une image sera construite sur la base de l'image avec la balise **versionnée**.
|
||||
Dans l'image avec la balise versionnée, la plupart des dépendances devraient déjà être installées, ce qui permet de gagner du temps.
|
||||
- **Reconstruction la plus lente** : Si les trois balises n'existent pas, une toute nouvelle image est construite à partir de
|
||||
l'image de base (ce qui est une opération plus lente). Cette nouvelle image est balisée avec toutes les balises **source**, **de verrouillage** et **versionnée**.
|
||||
|
||||
Cette approche de balisage permet à OpenHands de gérer efficacement les environnements de développement et de production.
|
||||
|
||||
1. Un code source et un Dockerfile identiques produisent toujours la même image (via des balises basées sur des hashs)
|
||||
2. Le système peut reconstruire rapidement les images lorsque des changements mineurs se produisent (en s'appuyant sur des images compatibles récentes)
|
||||
3. La balise **de verrouillage** (ex : `runtime:oh_v0.9.3_1234567890abcdef`) pointe toujours vers la dernière version pour une combinaison particulière d'image de base, de dépendances et de version d'OpenHands
|
||||
|
||||
## Système de plugins du Runtime
|
||||
|
||||
Le Runtime d'OpenHands prend en charge un système de plugins qui permet d'étendre les fonctionnalités et de personnaliser l'environnement d'exécution. Les plugins sont initialisés lorsque le client runtime démarre.
|
||||
|
||||
Consultez [un exemple de plugin Jupyter ici](https://github.com/All-Hands-AI/OpenHands/blob/ecf4aed28b0cf7c18d4d8ff554883ba182fc6bdd/openhands/runtime/plugins/jupyter/__init__.py#L21-L55) si vous souhaitez implémenter votre propre plugin.
|
||||
|
||||
*Plus de détails sur le système de plugins sont encore en construction - les contributions sont les bienvenues !*
|
||||
|
||||
Aspects clés du système de plugins :
|
||||
|
||||
1. Définition des plugins : Les plugins sont définis comme des classes Python qui héritent d'une classe de base `Plugin`
|
||||
2. Enregistrement des plugins : Les plugins disponibles sont enregistrés dans un dictionnaire `ALL_PLUGINS`
|
||||
3. Spécification des plugins : Les plugins sont associés à `Agent.sandbox_plugins: list[PluginRequirement]`. Les utilisateurs peuvent spécifier quels plugins charger lors de l'initialisation du runtime
|
||||
4. Initialisation : Les plugins sont initialisés de manière asynchrone lorsque le client runtime démarre
|
||||
5. Utilisation : Le client runtime peut utiliser les plugins initialisés pour étendre ses capacités (par exemple, le JupyterPlugin pour exécuter des cellules IPython)
|
||||
@@ -1,18 +1,41 @@
|
||||
---
|
||||
sidebar_position: 6
|
||||
---
|
||||
|
||||
# ✅ Fournir des Commentaires
|
||||
|
||||
Lorsque vous utilisez OpenHands, vous rencontrerez sans aucun doute des cas où les choses fonctionnent bien et d'autres où elles ne fonctionnent pas. Nous vous encourageons à fournir des commentaires lorsque vous utilisez OpenHands pour aider l'équipe de développement et, peut-être plus important encore, créer un corpus ouvert d'exemples de formation pour les agents de codage -- Partagez-OpenHands !
|
||||
# ✅ Fournir des commentaires
|
||||
|
||||
## 📝 Comment Fournir des Commentaires
|
||||
Lorsque vous utilisez OpenHands, vous rencontrerez des cas où les choses fonctionnent bien, et d'autres où elles ne fonctionnent pas. Nous vous encourageons à fournir des commentaires lorsque vous utilisez OpenHands pour aider à donner des retours à l'équipe de développement, et peut-être plus important encore, créer un corpus ouvert d'exemples d'entraînement d'agents de codage -- Share-OpenHands !
|
||||
|
||||
Fournir des commentaires est simple ! Lorsque vous utilisez OpenHands, vous pouvez appuyer sur le bouton de pouce vers le haut ou vers le bas à n'importe quel moment de votre interaction. Vous serez invité à fournir votre adresse email (par exemple, afin que nous puissions vous contacter si nous voulons poser des questions de suivi), et vous pouvez choisir si vous souhaitez fournir des commentaires publiquement ou en privé.
|
||||
## 📝 Comment fournir des commentaires
|
||||
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/5rFx-StMVV0?si=svo7xzp6LhGK_GXr" title="Lecteur vidéo YouTube" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
|
||||
Fournir des commentaires est facile ! Lorsque vous utilisez OpenHands, vous pouvez appuyer sur le bouton pouce vers le haut ou pouce vers le bas à tout moment pendant votre interaction. Vous serez invité à fournir votre adresse e-mail (par exemple, afin que nous puissions vous contacter si nous voulons poser des questions de suivi), et vous pouvez choisir si vous souhaitez fournir des commentaires publiquement ou en privé.
|
||||
|
||||
## 📜 Licence de Données et Confidentialité
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/5rFx-StMVV0?si=svo7xzp6LhGK_GXr" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
|
||||
|
||||
* Les données **publiques** seront distribuées sous la licence MIT, comme OpenHands lui-même, et pourront être utilisées par la communauté pour former et tester des modèles. Évidemment, les commentaires que vous pouvez rendre publics seront plus précieux pour la communauté dans son ensemble, donc lorsque vous ne traitez pas d'informations sensibles, nous vous encourageons à choisir cette option !
|
||||
## 📜 Utilisation des données et confidentialité
|
||||
|
||||
### Paramètres de partage des données
|
||||
|
||||
Lorsque vous soumettez des données, vous pouvez les soumettre publiquement ou en privé.
|
||||
|
||||
* Les données **publiques** seront distribuées sous la licence MIT, comme OpenHands lui-même, et pourront être utilisées par la communauté pour entraîner et tester des modèles. Évidemment, les commentaires que vous pouvez rendre publics seront plus précieux pour la communauté dans son ensemble, donc lorsque vous ne traitez pas d'informations sensibles, nous vous encourageons à choisir cette option !
|
||||
* Les données **privées** ne seront partagées qu'avec l'équipe OpenHands dans le but d'améliorer OpenHands.
|
||||
|
||||
### Qui collecte et stocke les données ?
|
||||
|
||||
Les données sont collectées et stockées par [All Hands AI](https://all-hands.dev), une entreprise fondée par les mainteneurs d'OpenHands pour soutenir et améliorer OpenHands.
|
||||
|
||||
### Comment les données publiques seront-elles publiées ?
|
||||
|
||||
Les données publiques seront publiées lorsque nous atteindrons des jalons fixes, tels que 1 000 exemples publics, 10 000 exemples publics, etc.
|
||||
À ce moment-là, nous suivrons le processus de publication suivant :
|
||||
|
||||
1. Toutes les personnes qui ont contribué à des commentaires publics recevront un e-mail décrivant la publication des données et auront la possibilité de se retirer.
|
||||
2. La ou les personnes en charge de la publication des données effectueront un contrôle de la qualité des données, en supprimant les commentaires de mauvaise qualité, en supprimant les adresses e-mail des soumissionnaires et en essayant de supprimer toute information sensible.
|
||||
3. Les données seront publiées publiquement sous la licence MIT via des sites couramment utilisés tels que GitHub ou Hugging Face.
|
||||
|
||||
### Que faire si je veux que mes données soient supprimées ?
|
||||
|
||||
Pour les données sur les serveurs d'All Hands AI, nous sommes heureux de les supprimer sur demande :
|
||||
|
||||
**Une pièce de données :** Si vous souhaitez supprimer une pièce de données, nous ajouterons prochainement un mécanisme pour supprimer les pièces de données en utilisant le lien et le mot de passe qui s'affichent sur l'interface lorsque vous soumettez des données.
|
||||
|
||||
**Toutes les données :** Si vous souhaitez que toutes vos données soient supprimées, ou si vous n'avez pas l'ID et le mot de passe que vous avez reçus lors de la soumission des données, veuillez contacter `contact@all-hands.dev` à partir de l'adresse e-mail que vous avez enregistrée lorsque vous avez initialement soumis les données.
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
|
||||
|
||||
# Démarrer avec OpenHands
|
||||
|
||||
Vous avez donc [installé OpenHands](./installation) et avez
|
||||
[configuré votre LLM](./installation#setup). Et maintenant ?
|
||||
|
||||
OpenHands peut vous aider à vous attaquer à une grande variété de tâches d'ingénierie. Mais la technologie
|
||||
est encore nouvelle, et nous sommes loin d'avoir des agents capables de prendre en charge des tâches
|
||||
d'ingénierie vastes et compliquées sans aucune aide. Il est donc important de se faire une idée de ce que l'agent
|
||||
fait bien, et où il pourrait avoir besoin d'un coup de main.
|
||||
|
||||
## Hello World
|
||||
|
||||
La première chose que vous voudrez peut-être essayer est un simple exemple "hello world".
|
||||
Cela peut être plus compliqué qu'il n'y paraît !
|
||||
|
||||
Essayez de demander à l'agent :
|
||||
> Please write a bash script hello.sh that prints "hello world!"
|
||||
|
||||
Vous devriez constater que l'agent non seulement écrit le script, mais définit également les
|
||||
permissions correctes et exécute le script pour vérifier la sortie.
|
||||
|
||||
Vous pouvez continuer à demander à l'agent d'affiner votre code. C'est une excellente façon de
|
||||
travailler avec les agents. Commencez simplement, et itérez.
|
||||
|
||||
> Please modify hello.sh so that it accepts a name as the first argument, but defaults to "world"
|
||||
|
||||
Vous pouvez également travailler dans n'importe quel langage dont vous avez besoin, bien que l'agent puisse avoir besoin de passer un peu de
|
||||
temps à configurer son environnement !
|
||||
|
||||
> Please convert hello.sh to a Ruby script, and run it
|
||||
|
||||
## Construire à partir de zéro
|
||||
|
||||
Les agents se débrouillent exceptionnellement bien pour les tâches "greenfield" (tâches où ils n'ont pas besoin
|
||||
de contexte sur une base de code existante) et ils peuvent simplement commencer à partir de zéro.
|
||||
|
||||
Il est préférable de commencer par une tâche simple, puis d'itérer. Il est également préférable d'être
|
||||
aussi précis que possible sur ce que vous voulez, sur la pile technologique à utiliser, etc.
|
||||
|
||||
Par exemple, nous pourrions construire une application TODO :
|
||||
|
||||
> Please build a basic TODO list app in React. It should be frontend-only, and all state
|
||||
> should be kept in localStorage.
|
||||
|
||||
Nous pouvons continuer à itérer sur l'application une fois le squelette en place :
|
||||
|
||||
> Please allow adding an optional due date to every task
|
||||
|
||||
Tout comme avec le développement normal, il est bon de commiter et de pousser votre code fréquemment.
|
||||
De cette façon, vous pouvez toujours revenir à un ancien état si l'agent dévie.
|
||||
Vous pouvez demander à l'agent de commiter et de pousser pour vous :
|
||||
|
||||
> Please commit the changes and push them to a new branch called "feature/due-dates"
|
||||
|
||||
|
||||
## Ajouter du nouveau code
|
||||
|
||||
OpenHands peut également faire un excellent travail en ajoutant du nouveau code à une base de code existante.
|
||||
|
||||
Par exemple, vous pouvez demander à OpenHands d'ajouter une nouvelle action GitHub à votre projet
|
||||
qui analyse votre code. OpenHands peut jeter un coup d'œil à votre base de code pour voir quel langage
|
||||
il doit utiliser, mais ensuite il peut simplement déposer un nouveau fichier dans `./github/workflows/lint.yml`.
|
||||
|
||||
> Please add a GitHub action that lints the code in this repository
|
||||
|
||||
Certaines tâches peuvent nécessiter un peu plus de contexte. Bien qu'OpenHands puisse utiliser `ls` et `grep`
|
||||
pour rechercher dans votre base de code, fournir le contexte à l'avance lui permet d'aller plus vite,
|
||||
et plus précisément. Et cela vous coûtera moins de tokens !
|
||||
|
||||
> Please modify ./backend/api/routes.js to add a new route that returns a list of all tasks
|
||||
|
||||
> Please add a new React component that displays a list of Widgets to the ./frontend/components
|
||||
> directory. It should use the existing Widget component.
|
||||
|
||||
## Refactoring
|
||||
|
||||
OpenHands est excellent pour refactoriser du code existant, surtout par petits morceaux.
|
||||
Vous ne voulez probablement pas essayer de réarchitecturer toute votre base de code, mais diviser
|
||||
les longs fichiers et fonctions, renommer les variables, etc. ont tendance à très bien fonctionner.
|
||||
|
||||
> Please rename all the single-letter variables in ./app.go
|
||||
|
||||
> Please break the function `build_and_deploy_widgets` into two functions, `build_widgets` and `deploy_widgets` in widget.php
|
||||
|
||||
> Please break ./api/routes.js into separate files for each route
|
||||
|
||||
## Corrections de bugs
|
||||
|
||||
OpenHands peut également vous aider à traquer et corriger des bugs dans votre code. Mais, comme tout
|
||||
développeur le sait, la correction de bugs peut être extrêmement délicate, et souvent OpenHands aura besoin de plus de contexte.
|
||||
Cela aide si vous avez diagnostiqué le bug, mais que vous voulez qu'OpenHands trouve la logique.
|
||||
|
||||
> Currently the email field in the `/subscribe` endpoint is rejecting .io domains. Please fix this.
|
||||
|
||||
> The `search_widgets` function in ./app.py is doing a case-sensitive search. Please make it case-insensitive.
|
||||
|
||||
Il est souvent utile de faire du développement piloté par les tests lors de la correction de bugs avec un agent.
|
||||
Vous pouvez demander à l'agent d'écrire un nouveau test, puis d'itérer jusqu'à ce qu'il corrige le bug :
|
||||
|
||||
> The `hello` function crashes on the empty string. Please write a test that reproduces this bug, then fix the code so it passes.
|
||||
|
||||
## Plus
|
||||
|
||||
OpenHands est capable d'aider sur à peu près n'importe quelle tâche de codage. Mais il faut un peu de pratique
|
||||
pour en tirer le meilleur parti. N'oubliez pas de :
|
||||
* Garder vos tâches petites
|
||||
* Être aussi précis que possible
|
||||
* Fournir autant de contexte que possible
|
||||
* Commiter et pousser fréquemment
|
||||
|
||||
Voir [Bonnes pratiques de prompting](./prompting-best-practices) pour plus de conseils sur la façon de tirer le meilleur parti d'OpenHands.
|
||||
@@ -0,0 +1,110 @@
|
||||
|
||||
|
||||
# Mode CLI
|
||||
|
||||
OpenHands peut être exécuté en mode CLI interactif, ce qui permet aux utilisateurs de démarrer une session interactive via la ligne de commande.
|
||||
|
||||
Ce mode est différent du [mode headless](headless-mode), qui est non interactif et mieux adapté aux scripts.
|
||||
|
||||
## Avec Python
|
||||
|
||||
Pour démarrer une session OpenHands interactive via la ligne de commande, suivez ces étapes :
|
||||
|
||||
1. Assurez-vous d'avoir suivi les [instructions de configuration de développement](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md).
|
||||
|
||||
2. Exécutez la commande suivante :
|
||||
|
||||
```bash
|
||||
poetry run python -m openhands.core.cli
|
||||
```
|
||||
|
||||
Cette commande démarrera une session interactive où vous pourrez saisir des tâches et recevoir des réponses d'OpenHands.
|
||||
|
||||
Vous devrez vous assurer de définir votre modèle, votre clé API et d'autres paramètres via des variables d'environnement
|
||||
[ou le fichier `config.toml`](https://github.com/All-Hands-AI/OpenHands/blob/main/config.template.toml).
|
||||
|
||||
|
||||
## Avec Docker
|
||||
|
||||
Pour exécuter OpenHands en mode CLI avec Docker, suivez ces étapes :
|
||||
|
||||
1. Définissez `WORKSPACE_BASE` sur le répertoire que vous souhaitez qu'OpenHands modifie :
|
||||
|
||||
```bash
|
||||
WORKSPACE_BASE=$(pwd)/workspace
|
||||
```
|
||||
|
||||
2. Définissez `LLM_MODEL` sur le modèle que vous souhaitez utiliser :
|
||||
|
||||
```bash
|
||||
LLM_MODEL="anthropic/claude-3-5-sonnet-20241022"
|
||||
```
|
||||
|
||||
3. Définissez `LLM_API_KEY` sur votre clé API :
|
||||
|
||||
```bash
|
||||
LLM_API_KEY="sk_test_12345"
|
||||
```
|
||||
|
||||
4. Exécutez la commande Docker suivante :
|
||||
|
||||
```bash
|
||||
docker run -it \
|
||||
--pull=always \
|
||||
-e SANDBOX_USER_ID=$(id -u) \
|
||||
-e WORKSPACE_MOUNT_PATH=$WORKSPACE_BASE \
|
||||
-e LLM_API_KEY=$LLM_API_KEY \
|
||||
-e LLM_MODEL=$LLM_MODEL \
|
||||
-v $WORKSPACE_BASE:/opt/workspace_base \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
--add-host host.docker.internal:host-gateway \
|
||||
--name openhands-app-$(date +%Y%m%d%H%M%S) \
|
||||
ghcr.io/all-hands-ai/openhands:0.11 \
|
||||
python -m openhands.core.cli
|
||||
```
|
||||
|
||||
Cette commande démarrera une session interactive dans Docker où vous pourrez saisir des tâches et recevoir des réponses d'OpenHands.
|
||||
|
||||
## Exemples de commandes CLI et de sorties attendues
|
||||
|
||||
Voici quelques exemples de commandes CLI et leurs sorties attendues :
|
||||
|
||||
### Exemple 1 : Tâche simple
|
||||
|
||||
```bash
|
||||
Comment puis-je vous aider ? >> Écrivez un script Python qui affiche "Hello, World!"
|
||||
```
|
||||
|
||||
Sortie attendue :
|
||||
|
||||
```bash
|
||||
🤖 Bien sûr ! Voici un script Python qui affiche "Hello, World!" :
|
||||
|
||||
❯ print("Hello, World!")
|
||||
```
|
||||
|
||||
### Exemple 2 : Commande Bash
|
||||
|
||||
```bash
|
||||
Comment puis-je vous aider ? >> Créez un répertoire nommé "test_dir"
|
||||
```
|
||||
|
||||
Sortie attendue :
|
||||
|
||||
```bash
|
||||
🤖 Création d'un répertoire nommé "test_dir" :
|
||||
|
||||
❯ mkdir test_dir
|
||||
```
|
||||
|
||||
### Exemple 3 : Gestion des erreurs
|
||||
|
||||
```bash
|
||||
Comment puis-je vous aider ? >> Supprimez un fichier inexistant
|
||||
```
|
||||
|
||||
Sortie attendue :
|
||||
|
||||
```bash
|
||||
🤖 Une erreur s'est produite. Veuillez réessayer.
|
||||
```
|
||||
@@ -0,0 +1,83 @@
|
||||
|
||||
|
||||
# Sandbox Personnalisé
|
||||
|
||||
Le sandbox est l'endroit où l'agent effectue ses tâches. Au lieu d'exécuter des commandes directement sur votre ordinateur (ce qui pourrait être risqué), l'agent les exécute à l'intérieur d'un conteneur Docker.
|
||||
|
||||
Le sandbox OpenHands par défaut (`python-nodejs:python3.12-nodejs22` de [nikolaik/python-nodejs](https://hub.docker.com/r/nikolaik/python-nodejs)) est livré avec certains paquets installés tels que Python et Node.js, mais peut nécessiter l'installation d'autres logiciels par défaut.
|
||||
|
||||
Vous avez deux options pour la personnalisation :
|
||||
|
||||
1. Utiliser une image existante avec les logiciels requis.
|
||||
2. Créer votre propre image Docker personnalisée.
|
||||
|
||||
Si vous choisissez la première option, vous pouvez passer la section `Créer Votre Image Docker`.
|
||||
|
||||
## Créer Votre Image Docker
|
||||
|
||||
Pour créer une image Docker personnalisée, elle doit être basée sur Debian.
|
||||
|
||||
Par exemple, si vous voulez qu'OpenHands ait `ruby` installé, créez un `Dockerfile` avec le contenu suivant :
|
||||
|
||||
```dockerfile
|
||||
FROM debian:latest
|
||||
|
||||
# Installer les paquets requis
|
||||
RUN apt-get update && apt-get install -y ruby
|
||||
```
|
||||
|
||||
Enregistrez ce fichier dans un dossier. Ensuite, construisez votre image Docker (par exemple, nommée custom-image) en naviguant vers le dossier dans le terminal et en exécutant :
|
||||
|
||||
```bash
|
||||
docker build -t custom-image .
|
||||
```
|
||||
|
||||
Cela produira une nouvelle image appelée `custom-image`, qui sera disponible dans Docker.
|
||||
|
||||
> Notez que dans la configuration décrite dans ce document, OpenHands s'exécutera en tant qu'utilisateur "openhands" à l'intérieur du sandbox et donc tous les paquets installés via le docker file devraient être disponibles pour tous les utilisateurs du système, pas seulement root.
|
||||
|
||||
## Utiliser le Workflow de Développement
|
||||
|
||||
### Configuration
|
||||
|
||||
Tout d'abord, assurez-vous de pouvoir exécuter OpenHands en suivant les instructions dans [Development.md](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md).
|
||||
|
||||
### Spécifier l'Image de Base du Sandbox
|
||||
|
||||
Dans le fichier `config.toml` dans le répertoire OpenHands, définissez `sandbox_base_container_image` sur l'image que vous souhaitez utiliser. Cela peut être une image que vous avez déjà extraite ou une que vous avez construite :
|
||||
|
||||
```bash
|
||||
[core]
|
||||
...
|
||||
sandbox_base_container_image="custom-image"
|
||||
```
|
||||
|
||||
### Exécuter
|
||||
|
||||
Exécutez OpenHands en exécutant ```make run``` dans le répertoire de niveau supérieur.
|
||||
|
||||
## Explication Technique
|
||||
|
||||
Veuillez vous référer à la [section image docker personnalisée de la documentation d'exécution](https://docs.all-hands.dev/modules/usage/architecture/runtime#advanced-how-openhands-builds-and-maintains-od-runtime-images) pour plus de détails.
|
||||
|
||||
## Dépannage / Erreurs
|
||||
|
||||
### Erreur : ```useradd: UID 1000 is not unique```
|
||||
|
||||
Si vous voyez cette erreur dans la sortie de la console, c'est parce qu'OpenHands essaie de créer l'utilisateur openhands dans le sandbox avec un UID de 1000, mais cet UID est déjà utilisé dans l'image (pour une raison quelconque). Pour corriger cela, changez le champ sandbox_user_id dans le fichier config.toml à une valeur différente :
|
||||
|
||||
```toml
|
||||
[core]
|
||||
workspace_base="./workspace"
|
||||
run_as_openhands=true
|
||||
sandbox_base_container_image="custom_image"
|
||||
sandbox_user_id="1001"
|
||||
```
|
||||
|
||||
### Erreurs d'utilisation de port
|
||||
|
||||
Si vous voyez une erreur concernant un port déjà utilisé ou indisponible, essayez de supprimer tous les conteneurs Docker en cours d'exécution (exécutez `docker ps` et `docker rm` sur les conteneurs pertinents) puis réexécutez ```make run```.
|
||||
|
||||
## Discuter
|
||||
|
||||
Pour d'autres problèmes ou questions, rejoignez le [Slack](https://join.slack.com/t/opendevin/shared_invite/zt-2oikve2hu-UDxHeo8nsE69y6T7yFX_BA) ou le [Discord](https://discord.gg/ESHStjSjD4) et demandez !
|
||||
@@ -0,0 +1,73 @@
|
||||
|
||||
|
||||
# Débogage
|
||||
|
||||
Ce qui suit est destiné à servir d'introduction au débogage d'OpenHands à des fins de développement.
|
||||
|
||||
## Serveur / VSCode
|
||||
|
||||
Le `launch.json` suivant permettra de déboguer les éléments agent, contrôleur et serveur, mais pas le bac à sable (qui s'exécute dans docker). Il ignorera toutes les modifications à l'intérieur du répertoire `workspace/` :
|
||||
|
||||
```
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "OpenHands CLI",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"module": "openhands.core.cli",
|
||||
"justMyCode": false
|
||||
},
|
||||
{
|
||||
"name": "OpenHands WebApp",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"module": "uvicorn",
|
||||
"args": [
|
||||
"openhands.server.listen:app",
|
||||
"--reload",
|
||||
"--reload-exclude",
|
||||
"${workspaceFolder}/workspace",
|
||||
"--port",
|
||||
"3000"
|
||||
],
|
||||
"justMyCode": false
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Des configurations de débogage plus spécifiques qui incluent plus de paramètres peuvent être spécifiées :
|
||||
|
||||
```
|
||||
...
|
||||
{
|
||||
"name": "Debug CodeAct",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"module": "openhands.core.main",
|
||||
"args": [
|
||||
"-t",
|
||||
"Demandez-moi quelle est votre tâche.",
|
||||
"-d",
|
||||
"${workspaceFolder}/workspace",
|
||||
"-c",
|
||||
"CodeActAgent",
|
||||
"-l",
|
||||
"llm.o1",
|
||||
"-n",
|
||||
"prompts"
|
||||
],
|
||||
"justMyCode": false
|
||||
}
|
||||
...
|
||||
```
|
||||
|
||||
Les valeurs dans l'extrait ci-dessus peuvent être mises à jour de telle sorte que :
|
||||
|
||||
* *t* : la tâche
|
||||
* *d* : le répertoire de l'espace de travail openhands
|
||||
* *c* : l'agent
|
||||
* *l* : la configuration LLM (prédéfinie dans config.toml)
|
||||
* *n* : le nom de la session (par exemple, le nom du flux d'événements)
|
||||
@@ -0,0 +1,281 @@
|
||||
|
||||
|
||||
# Évaluation
|
||||
|
||||
Ce guide fournit un aperçu de la façon d'intégrer votre propre benchmark d'évaluation dans le framework OpenHands.
|
||||
|
||||
## Configuration de l'environnement et de la configuration LLM
|
||||
|
||||
Veuillez suivre les instructions [ici](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md) pour configurer votre environnement de développement local.
|
||||
OpenHands en mode développement utilise `config.toml` pour garder une trace de la plupart des configurations.
|
||||
|
||||
Voici un exemple de fichier de configuration que vous pouvez utiliser pour définir et utiliser plusieurs LLMs :
|
||||
|
||||
```toml
|
||||
[llm]
|
||||
# IMPORTANT : ajoutez votre clé API ici et définissez le modèle que vous souhaitez évaluer
|
||||
model = "claude-3-5-sonnet-20241022"
|
||||
|
||||
api_key = "sk-XXX"
|
||||
|
||||
[llm.eval_gpt4_1106_preview_llm]
|
||||
model = "gpt-4-1106-preview"
|
||||
api_key = "XXX"
|
||||
temperature = 0.0
|
||||
|
||||
[llm.eval_some_openai_compatible_model_llm]
|
||||
model = "openai/MODEL_NAME"
|
||||
base_url = "https://OPENAI_COMPATIBLE_URL/v1"
|
||||
api_key = "XXX"
|
||||
temperature = 0.0
|
||||
```
|
||||
|
||||
|
||||
## Comment utiliser OpenHands en ligne de commande
|
||||
|
||||
OpenHands peut être exécuté depuis la ligne de commande en utilisant le format suivant :
|
||||
|
||||
```bash
|
||||
poetry run python ./openhands/core/main.py \
|
||||
-i <max_iterations> \
|
||||
-t "<task_description>" \
|
||||
-c <agent_class> \
|
||||
-l <llm_config>
|
||||
```
|
||||
|
||||
Par exemple :
|
||||
|
||||
```bash
|
||||
poetry run python ./openhands/core/main.py \
|
||||
-i 10 \
|
||||
-t "Écrivez-moi un script bash qui affiche hello world." \
|
||||
-c CodeActAgent \
|
||||
-l llm
|
||||
```
|
||||
|
||||
Cette commande exécute OpenHands avec :
|
||||
- Un maximum de 10 itérations
|
||||
- La description de tâche spécifiée
|
||||
- En utilisant CodeActAgent
|
||||
- Avec la configuration LLM définie dans la section `llm` de votre fichier `config.toml`
|
||||
|
||||
## Comment fonctionne OpenHands
|
||||
|
||||
Le point d'entrée principal d'OpenHands se trouve dans `openhands/core/main.py`. Voici un flux simplifié de son fonctionnement :
|
||||
|
||||
1. Analyse des arguments de ligne de commande et chargement de la configuration
|
||||
2. Création d'un environnement d'exécution à l'aide de `create_runtime()`
|
||||
3. Initialisation de l'agent spécifié
|
||||
4. Exécution du contrôleur à l'aide de `run_controller()`, qui :
|
||||
- Attache l'environnement d'exécution à l'agent
|
||||
- Exécute la tâche de l'agent
|
||||
- Renvoie un état final une fois terminé
|
||||
|
||||
La fonction `run_controller()` est le cœur de l'exécution d'OpenHands. Elle gère l'interaction entre l'agent, l'environnement d'exécution et la tâche, en gérant des choses comme la simulation d'entrée utilisateur et le traitement des événements.
|
||||
|
||||
|
||||
## Le moyen le plus simple de commencer : Explorer les benchmarks existants
|
||||
|
||||
Nous vous encourageons à examiner les différents benchmarks d'évaluation disponibles dans le [répertoire `evaluation/`](https://github.com/All-Hands-AI/OpenHands/blob/main/evaluation) de notre dépôt.
|
||||
|
||||
Pour intégrer votre propre benchmark, nous vous suggérons de commencer par celui qui ressemble le plus à vos besoins. Cette approche peut considérablement rationaliser votre processus d'intégration, vous permettant de vous appuyer sur les structures existantes et de les adapter à vos exigences spécifiques.
|
||||
|
||||
## Comment créer un workflow d'évaluation
|
||||
|
||||
|
||||
Pour créer un workflow d'évaluation pour votre benchmark, suivez ces étapes :
|
||||
|
||||
1. Importez les utilitaires OpenHands pertinents :
|
||||
```python
|
||||
import openhands.agenthub
|
||||
from evaluation.utils.shared import (
|
||||
EvalMetadata,
|
||||
EvalOutput,
|
||||
make_metadata,
|
||||
prepare_dataset,
|
||||
reset_logger_for_multiprocessing,
|
||||
run_evaluation,
|
||||
)
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
SandboxConfig,
|
||||
get_llm_config_arg,
|
||||
parse_arguments,
|
||||
)
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.core.main import create_runtime, run_controller
|
||||
from openhands.events.action import CmdRunAction
|
||||
from openhands.events.observation import CmdOutputObservation, ErrorObservation
|
||||
from openhands.runtime.runtime import Runtime
|
||||
```
|
||||
|
||||
2. Créez une configuration :
|
||||
```python
|
||||
def get_config(instance: pd.Series, metadata: EvalMetadata) -> AppConfig:
|
||||
config = AppConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
runtime='eventstream',
|
||||
max_iterations=metadata.max_iterations,
|
||||
sandbox=SandboxConfig(
|
||||
base_container_image='your_container_image',
|
||||
enable_auto_lint=True,
|
||||
timeout=300,
|
||||
),
|
||||
)
|
||||
config.set_llm_config(metadata.llm_config)
|
||||
return config
|
||||
```
|
||||
|
||||
3. Initialisez l'environnement d'exécution et configurez l'environnement d'évaluation :
|
||||
```python
|
||||
def initialize_runtime(runtime: Runtime, instance: pd.Series):
|
||||
# Configurez votre environnement d'évaluation ici
|
||||
# Par exemple, définir des variables d'environnement, préparer des fichiers, etc.
|
||||
pass
|
||||
```
|
||||
|
||||
4. Créez une fonction pour traiter chaque instance :
|
||||
```python
|
||||
from openhands.utils.async_utils import call_async_from_sync
|
||||
def process_instance(instance: pd.Series, metadata: EvalMetadata) -> EvalOutput:
|
||||
config = get_config(instance, metadata)
|
||||
runtime = create_runtime(config)
|
||||
call_async_from_sync(runtime.connect)
|
||||
initialize_runtime(runtime, instance)
|
||||
|
||||
instruction = get_instruction(instance, metadata)
|
||||
|
||||
state = run_controller(
|
||||
config=config,
|
||||
task_str=instruction,
|
||||
runtime=runtime,
|
||||
fake_user_response_fn=your_user_response_function,
|
||||
)
|
||||
|
||||
# Évaluez les actions de l'agent
|
||||
evaluation_result = await evaluate_agent_actions(runtime, instance)
|
||||
|
||||
return EvalOutput(
|
||||
instance_id=instance.instance_id,
|
||||
instruction=instruction,
|
||||
test_result=evaluation_result,
|
||||
metadata=metadata,
|
||||
history=compatibility_for_eval_history_pairs(state.history),
|
||||
metrics=state.metrics.get() if state.metrics else None,
|
||||
error=state.last_error if state and state.last_error else None,
|
||||
)
|
||||
```
|
||||
|
||||
5. Exécutez l'évaluation :
|
||||
```python
|
||||
metadata = make_metadata(llm_config, dataset_name, agent_class, max_iterations, eval_note, eval_output_dir)
|
||||
output_file = os.path.join(metadata.eval_output_dir, 'output.jsonl')
|
||||
instances = prepare_dataset(your_dataset, output_file, eval_n_limit)
|
||||
|
||||
await run_evaluation(
|
||||
instances,
|
||||
metadata,
|
||||
output_file,
|
||||
num_workers,
|
||||
process_instance
|
||||
)
|
||||
```
|
||||
|
||||
Ce workflow configure la configuration, initialise l'environnement d'exécution, traite chaque instance en exécutant l'agent et en évaluant ses actions, puis collecte les résultats dans un objet `EvalOutput`. La fonction `run_evaluation` gère la parallélisation et le suivi de la progression.
|
||||
|
||||
N'oubliez pas de personnaliser les fonctions `get_instruction`, `your_user_response_function` et `evaluate_agent_actions` en fonction des exigences spécifiques de votre benchmark.
|
||||
|
||||
En suivant cette structure, vous pouvez créer un workflow d'évaluation robuste pour votre benchmark dans le framework OpenHands.
|
||||
|
||||
|
||||
## Comprendre la `user_response_fn`
|
||||
|
||||
La `user_response_fn` est un composant crucial dans le workflow d'évaluation d'OpenHands. Elle simule l'interaction de l'utilisateur avec l'agent, permettant des réponses automatisées pendant le processus d'évaluation. Cette fonction est particulièrement utile lorsque vous souhaitez fournir des réponses cohérentes et prédéfinies aux requêtes ou actions de l'agent.
|
||||
|
||||
|
||||
### Workflow et interaction
|
||||
|
||||
Le workflow correct pour gérer les actions et la `user_response_fn` est le suivant :
|
||||
|
||||
1. L'agent reçoit une tâche et commence à la traiter
|
||||
2. L'agent émet une Action
|
||||
3. Si l'Action est exécutable (par exemple, CmdRunAction, IPythonRunCellAction) :
|
||||
- Le Runtime traite l'Action
|
||||
- Le Runtime renvoie une Observation
|
||||
4. Si l'Action n'est pas exécutable (généralement une MessageAction) :
|
||||
- La `user_response_fn` est appelée
|
||||
- Elle renvoie une réponse utilisateur simulée
|
||||
5. L'agent reçoit soit l'Observation, soit la réponse simulée
|
||||
6. Les étapes 2 à 5 se répètent jusqu'à ce que la tâche soit terminée ou que le nombre maximum d'itérations soit atteint
|
||||
|
||||
Voici une représentation visuelle plus précise :
|
||||
|
||||
```
|
||||
[Agent]
|
||||
|
|
||||
v
|
||||
[Émettre une Action]
|
||||
|
|
||||
v
|
||||
[L'Action est-elle exécutable ?]
|
||||
/ \
|
||||
Oui Non
|
||||
| |
|
||||
v v
|
||||
[Runtime] [user_response_fn]
|
||||
| |
|
||||
v v
|
||||
[Renvoyer une Observation] [Réponse simulée]
|
||||
\ /
|
||||
\ /
|
||||
v v
|
||||
[L'agent reçoit le feedback]
|
||||
|
|
||||
v
|
||||
[Continuer ou terminer la tâche]
|
||||
```
|
||||
|
||||
Dans ce workflow :
|
||||
|
||||
- Les actions exécutables (comme l'exécution de commandes ou de code) sont gérées directement par le Runtime
|
||||
- Les actions non exécutables (généralement lorsque l'agent veut communiquer ou demander des clarifications) sont gérées par la `user_response_fn`
|
||||
- L'agent traite ensuite le feedback, qu'il s'agisse d'une Observation du Runtime ou d'une réponse simulée de la `user_response_fn`
|
||||
|
||||
Cette approche permet une gestion automatisée des actions concrètes et des interactions utilisateur simulées, ce qui la rend adaptée aux scénarios d'évaluation où vous souhaitez tester la capacité de l'agent à effectuer des tâches avec une intervention humaine minimale.
|
||||
|
||||
### Exemple d'implémentation
|
||||
|
||||
Voici un exemple de `user_response_fn` utilisée dans l'évaluation SWE-Bench :
|
||||
|
||||
```python
|
||||
def codeact_user_response(state: State | None) -> str:
|
||||
msg = (
|
||||
'Veuillez continuer à travailler sur la tâche avec l\'approche que vous jugez appropriée.\n'
|
||||
'Si vous pensez avoir résolu la tâche, veuillez d\'abord envoyer votre réponse à l\'utilisateur via un message, puis <execute_bash> exit </execute_bash>.\n'
|
||||
'IMPORTANT : VOUS NE DEVEZ JAMAIS DEMANDER DE L\'AIDE HUMAINE.\n'
|
||||
)
|
||||
|
||||
if state and state.history:
|
||||
# vérifier si l'agent a essayé de parler à l'utilisateur 3 fois, si oui, faire savoir à l'agent qu'il peut abandonner
|
||||
user_msgs = [
|
||||
event
|
||||
for event in state.history
|
||||
if isinstance(event, MessageAction) and event.source == 'user'
|
||||
]
|
||||
if len(user_msgs) >= 2:
|
||||
# faire savoir à l'agent qu'il peut abandonner lorsqu'il a essayé 3 fois
|
||||
return (
|
||||
msg
|
||||
+ 'Si vous voulez abandonner, exécutez : <execute_bash> exit </execute_bash>.\n'
|
||||
)
|
||||
return msg
|
||||
```
|
||||
|
||||
Cette fonction fait ce qui suit :
|
||||
|
||||
1. Fournit un message standard encourageant l'agent à continuer à travailler
|
||||
2. Vérifie combien de fois l'agent a tenté de communiquer avec l'utilisateur
|
||||
3. Si l'agent a fait plusieurs tentatives, il lui donne la possibilité d'abandonner
|
||||
|
||||
En utilisant cette fonction, vous pouvez garantir un comportement cohérent sur plusieurs exécutions d'évaluation et empêcher l'agent de rester bloqué en attendant une entrée humaine.
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
|
||||
# Utilisation de l'Action GitHub OpenHands
|
||||
|
||||
Ce guide explique comment utiliser l'Action GitHub OpenHands, à la fois dans le dépôt OpenHands et dans vos propres projets.
|
||||
|
||||
## Utilisation de l'Action dans le dépôt OpenHands
|
||||
|
||||
Pour utiliser l'Action GitHub OpenHands dans le dépôt OpenHands, un mainteneur OpenHands peut :
|
||||
|
||||
1. Créer une issue dans le dépôt.
|
||||
2. Ajouter le label `fix-me` à l'issue.
|
||||
3. L'action se déclenchera automatiquement et tentera de résoudre l'issue.
|
||||
|
||||
## Installation de l'Action dans un nouveau dépôt
|
||||
|
||||
Pour installer l'Action GitHub OpenHands dans votre propre dépôt, suivez les [instructions dans le dépôt OpenHands Resolver](https://github.com/All-Hands-AI/OpenHands-resolver?tab=readme-ov-file#using-the-github-actions-workflow).
|
||||
@@ -0,0 +1,53 @@
|
||||
|
||||
|
||||
# Mode Interface Graphique
|
||||
|
||||
## Introduction
|
||||
|
||||
OpenHands fournit un mode Interface Graphique (GUI) convivial pour interagir avec l'assistant IA. Ce mode offre une façon intuitive de configurer l'environnement, gérer les paramètres et communiquer avec l'IA.
|
||||
|
||||
## Installation et Configuration
|
||||
|
||||
1. Suivez les instructions du guide d'[Installation](../installation) pour installer OpenHands.
|
||||
|
||||
2. Après avoir exécuté la commande, accédez à OpenHands à l'adresse [http://localhost:3000](http://localhost:3000).
|
||||
|
||||
## Interagir avec l'Interface Graphique
|
||||
|
||||
### Configuration Initiale
|
||||
|
||||
1. Lors du premier lancement, vous verrez une fenêtre modale de paramètres.
|
||||
2. Sélectionnez un `Fournisseur LLM` et un `Modèle LLM` dans les menus déroulants.
|
||||
3. Entrez la `Clé API` correspondante pour le fournisseur choisi.
|
||||
4. Cliquez sur "Enregistrer" pour appliquer les paramètres.
|
||||
|
||||
### Paramètres Avancés
|
||||
|
||||
1. Activez `Options Avancées` pour accéder aux paramètres supplémentaires.
|
||||
2. Utilisez la zone de texte `Modèle Personnalisé` pour entrer manuellement un modèle s'il n'est pas dans la liste.
|
||||
3. Spécifiez une `URL de Base` si requise par votre fournisseur LLM.
|
||||
|
||||
### Interface Principale
|
||||
|
||||
L'interface principale se compose de plusieurs éléments clés :
|
||||
|
||||
1. **Fenêtre de Chat** : La zone centrale où vous pouvez voir l'historique de conversation avec l'assistant IA.
|
||||
2. **Zone de Saisie** : Située en bas de l'écran, utilisez-la pour taper vos messages ou commandes à l'IA.
|
||||
3. **Bouton Envoyer** : Cliquez dessus pour envoyer votre message à l'IA.
|
||||
4. **Bouton Paramètres** : Une icône d'engrenage qui ouvre la fenêtre modale des paramètres, vous permettant d'ajuster votre configuration à tout moment.
|
||||
5. **Panneau Espace de Travail** : Affiche les fichiers et dossiers de votre espace de travail, vous permettant de naviguer et visualiser les fichiers, ou l'historique des commandes passées de l'agent ou de navigation web.
|
||||
|
||||
### Interagir avec l'IA
|
||||
|
||||
1. Tapez votre question, requête ou description de tâche dans la zone de saisie.
|
||||
2. Cliquez sur le bouton envoyer ou appuyez sur Entrée pour soumettre votre message.
|
||||
3. L'IA traitera votre saisie et fournira une réponse dans la fenêtre de chat.
|
||||
4. Vous pouvez poursuivre la conversation en posant des questions de suivi ou en fournissant des informations supplémentaires.
|
||||
|
||||
## Conseils pour une Utilisation Efficace
|
||||
|
||||
1. Soyez spécifique dans vos requêtes pour obtenir les réponses les plus précises et utiles, comme décrit dans les [meilleures pratiques d'invite](../prompting-best-practices).
|
||||
2. Utilisez le panneau d'espace de travail pour explorer la structure de votre projet.
|
||||
3. Utilisez l'un des modèles recommandés, comme décrit dans la section [LLMs](usage/llms/llms.md).
|
||||
|
||||
N'oubliez pas, le mode Interface Graphique d'OpenHands est conçu pour rendre votre interaction avec l'assistant IA aussi fluide et intuitive que possible. N'hésitez pas à explorer ses fonctionnalités pour maximiser votre productivité.
|
||||
@@ -0,0 +1,58 @@
|
||||
|
||||
|
||||
# Mode sans interface
|
||||
|
||||
Vous pouvez exécuter OpenHands avec une seule commande, sans démarrer l'application web.
|
||||
Cela facilite l'écriture de scripts et l'automatisation des tâches avec OpenHands.
|
||||
|
||||
Ceci est différent du [Mode CLI](cli-mode), qui est interactif et plus adapté au développement actif.
|
||||
|
||||
## Avec Python
|
||||
|
||||
Pour exécuter OpenHands en mode sans interface avec Python,
|
||||
[suivez les instructions de configuration de développement](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md),
|
||||
puis exécutez :
|
||||
|
||||
```bash
|
||||
poetry run python -m openhands.core.main -t "write a bash script that prints hi"
|
||||
```
|
||||
|
||||
Vous devrez vous assurer de définir votre modèle, votre clé API et d'autres paramètres via des variables d'environnement
|
||||
[ou le fichier `config.toml`](https://github.com/All-Hands-AI/OpenHands/blob/main/config.template.toml).
|
||||
|
||||
## Avec Docker
|
||||
|
||||
1. Définissez `WORKSPACE_BASE` sur le répertoire que vous voulez qu'OpenHands modifie :
|
||||
|
||||
```bash
|
||||
WORKSPACE_BASE=$(pwd)/workspace
|
||||
```
|
||||
|
||||
2. Définissez `LLM_MODEL` sur le modèle que vous voulez utiliser :
|
||||
|
||||
```bash
|
||||
LLM_MODEL="anthropic/claude-3-5-sonnet-20241022"
|
||||
```
|
||||
|
||||
3. Définissez `LLM_API_KEY` sur votre clé API :
|
||||
|
||||
```bash
|
||||
LLM_API_KEY="sk_test_12345"
|
||||
```
|
||||
|
||||
4. Exécutez la commande Docker suivante :
|
||||
|
||||
```bash
|
||||
docker run -it \
|
||||
--pull=always \
|
||||
-e SANDBOX_USER_ID=$(id -u) \
|
||||
-e WORKSPACE_MOUNT_PATH=$WORKSPACE_BASE \
|
||||
-e LLM_API_KEY=$LLM_API_KEY \
|
||||
-e LLM_MODEL=$LLM_MODEL \
|
||||
-v $WORKSPACE_BASE:/opt/workspace_base \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
--add-host host.docker.internal:host-gateway \
|
||||
--name openhands-app-$(date +%Y%m%d%H%M%S) \
|
||||
ghcr.io/all-hands-ai/openhands:0.11 \
|
||||
python -m openhands.core.main -t "write a bash script that prints hi"
|
||||
```
|
||||
@@ -0,0 +1,338 @@
|
||||
|
||||
|
||||
# Kubernetes
|
||||
|
||||
Il existe différentes façons d'exécuter OpenHands sur Kubernetes ou OpenShift. Ce guide présente une façon possible :
|
||||
1. Créer un PV "en tant qu'administrateur du cluster" pour mapper les données workspace_base et le répertoire docker au pod via le nœud worker
|
||||
2. Créer un PVC pour pouvoir monter ces PV sur le pod
|
||||
3. Créer un pod qui contient deux conteneurs : les conteneurs OpenHands et Sandbox
|
||||
|
||||
## Étapes détaillées pour l'exemple ci-dessus
|
||||
|
||||
> Remarque : Assurez-vous d'être connecté au cluster avec le compte approprié pour chaque étape. La création de PV nécessite un administrateur de cluster !
|
||||
|
||||
> Assurez-vous d'avoir les autorisations de lecture/écriture sur le hostPath utilisé ci-dessous (c'est-à-dire /tmp/workspace)
|
||||
|
||||
1. Créer le PV :
|
||||
Le fichier yaml d'exemple ci-dessous peut être utilisé par un administrateur de cluster pour créer le PV.
|
||||
- workspace-pv.yaml
|
||||
|
||||
```yamlfile
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
name: workspace-pv
|
||||
spec:
|
||||
capacity:
|
||||
storage: 2Gi
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
hostPath:
|
||||
path: /tmp/workspace
|
||||
```
|
||||
|
||||
```bash
|
||||
# appliquer le fichier yaml
|
||||
$ oc create -f workspace-pv.yaml
|
||||
persistentvolume/workspace-pv created
|
||||
|
||||
# vérifier :
|
||||
$ oc get pv
|
||||
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
|
||||
workspace-pv 2Gi RWO Retain Available 7m23s
|
||||
```
|
||||
|
||||
- docker-pv.yaml
|
||||
|
||||
```yamlfile
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
name: docker-pv
|
||||
spec:
|
||||
capacity:
|
||||
storage: 2Gi
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
hostPath:
|
||||
path: /var/run/docker.sock
|
||||
```
|
||||
|
||||
```bash
|
||||
# appliquer le fichier yaml
|
||||
$ oc create -f docker-pv.yaml
|
||||
persistentvolume/docker-pv created
|
||||
|
||||
# vérifier :
|
||||
oc get pv
|
||||
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
|
||||
docker-pv 2Gi RWO Retain Available 6m55s
|
||||
workspace-pv 2Gi RWO Retain Available 7m23s
|
||||
```
|
||||
|
||||
2. Créer le PVC :
|
||||
Exemple de fichier yaml PVC ci-dessous :
|
||||
|
||||
- workspace-pvc.yaml
|
||||
|
||||
```yamlfile
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: workspace-pvc
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
```
|
||||
|
||||
```bash
|
||||
# créer le pvc
|
||||
$ oc create -f workspace-pvc.yaml
|
||||
persistentvolumeclaim/workspace-pvc created
|
||||
|
||||
# vérifier
|
||||
$ oc get pvc
|
||||
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
|
||||
workspace-pvc Pending hcloud-volumes 4s
|
||||
|
||||
$ oc get events
|
||||
LAST SEEN TYPE REASON OBJECT MESSAGE
|
||||
8s Normal WaitForFirstConsumer persistentvolumeclaim/workspace-pvc waiting for first consumer to be created before binding
|
||||
```
|
||||
|
||||
- docker-pvc.yaml
|
||||
|
||||
```yamlfile
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: docker-pvc
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
```
|
||||
|
||||
```bash
|
||||
# créer le pvc
|
||||
$ oc create -f docker-pvc.yaml
|
||||
persistentvolumeclaim/docker-pvc created
|
||||
|
||||
# vérifier
|
||||
$ oc get pvc
|
||||
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
|
||||
docker-pvc Pending hcloud-volumes 4s
|
||||
workspace-pvc Pending hcloud-volumes 2m53s
|
||||
|
||||
$ oc get events
|
||||
LAST SEEN TYPE REASON OBJECT MESSAGE
|
||||
10s Normal WaitForFirstConsumer persistentvolumeclaim/docker-pvc waiting for first consumer to be created before binding
|
||||
10s Normal WaitForFirstConsumer persistentvolumeclaim/workspace-pvc waiting for first consumer to be created before binding
|
||||
```
|
||||
|
||||
3. Créer le fichier yaml du pod :
|
||||
Exemple de fichier yaml de pod ci-dessous :
|
||||
|
||||
- pod.yaml
|
||||
|
||||
```yamlfile
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: openhands-app-2024
|
||||
labels:
|
||||
app: openhands-app-2024
|
||||
spec:
|
||||
containers:
|
||||
- name: openhands-app-2024
|
||||
image: ghcr.io/all-hands-ai/openhands:main
|
||||
env:
|
||||
- name: SANDBOX_USER_ID
|
||||
value: "1000"
|
||||
- name: WORKSPACE_MOUNT_PATH
|
||||
value: "/opt/workspace_base"
|
||||
volumeMounts:
|
||||
- name: workspace-volume
|
||||
mountPath: /opt/workspace_base
|
||||
- name: docker-sock
|
||||
mountPath: /var/run/docker.sock
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
- name: openhands-sandbox-2024
|
||||
image: ghcr.io/all-hands-ai/sandbox:main
|
||||
ports:
|
||||
- containerPort: 51963
|
||||
command: ["/usr/sbin/sshd", "-D", "-p 51963", "-o", "PermitRootLogin=yes"]
|
||||
volumes:
|
||||
- name: workspace-volume
|
||||
persistentVolumeClaim:
|
||||
claimName: workspace-pvc
|
||||
- name: docker-sock
|
||||
persistentVolumeClaim:
|
||||
claimName: docker-pvc
|
||||
```
|
||||
|
||||
|
||||
```bash
|
||||
# créer le pod
|
||||
$ oc create -f pod.yaml
|
||||
W0716 11:22:07.776271 107626 warnings.go:70] would violate PodSecurity "restricted:v1.24": allowPrivilegeEscalation != false (containers "openhands-app-2024", "openhands-sandbox-2024" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (containers "openhands-app-2024", "openhands-sandbox-2024" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or containers "openhands-app-2024", "openhands-sandbox-2024" must set securityContext.runAsNonRoot=true), seccompProfile (pod or containers "openhands-app-2024", "openhands-sandbox-2024" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
|
||||
pod/openhands-app-2024 created
|
||||
|
||||
# L'avertissement ci-dessus peut être ignoré pour l'instant car nous ne modifierons pas les restrictions SCC.
|
||||
|
||||
# vérifier
|
||||
$ oc get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
openhands-app-2024 0/2 Pending 0 5s
|
||||
|
||||
$ oc get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
openhands-app-2024 0/2 ContainerCreating 0 15s
|
||||
|
||||
$ oc get events
|
||||
LAST SEEN TYPE REASON OBJECT MESSAGE
|
||||
38s Normal WaitForFirstConsumer persistentvolumeclaim/docker-pvc waiting for first consumer to be created before binding
|
||||
23s Normal ExternalProvisioning persistentvolumeclaim/docker-pvc waiting for a volume to be created, either by external provisioner "csi.hetzner.cloud" or manually created by system administrator
|
||||
27s Normal Provisioning persistentvolumeclaim/docker-pvc External provisioner is provisioning volume for claim "openhands/docker-pvc"
|
||||
17s Normal ProvisioningSucceeded persistentvolumeclaim/docker-pvc Successfully provisioned volume pvc-2b1d223a-1c8f-4990-8e3d-68061a9ae252
|
||||
16s Normal Scheduled pod/openhands-app-2024 Successfully assigned All-Hands-AI/OpenHands-app-2024 to worker1.hub.internal.blakane.com
|
||||
9s Normal SuccessfulAttachVolume pod/openhands-app-2024 AttachVolume.Attach succeeded for volume "pvc-2b1d223a-1c8f-4990-8e3d-68061a9ae252"
|
||||
9s Normal SuccessfulAttachVolume pod/openhands-app-2024 AttachVolume.Attach succeeded for volume "pvc-31f15b25-faad-4665-a25f-201a530379af"
|
||||
6s Normal AddedInterface pod/openhands-app-2024 Add eth0 [10.128.2.48/23] from openshift-sdn
|
||||
6s Normal Pulled pod/openhands-app-2024 Container image "ghcr.io/all-hands-ai/openhands:main" already present on machine
|
||||
6s Normal Created pod/openhands-app-2024 Created container openhands-app-2024
|
||||
6s Normal Started pod/openhands-app-2024 Started container openhands-app-2024
|
||||
6s Normal Pulled pod/openhands-app-2024 Container image "ghcr.io/all-hands-ai/sandbox:main" already present on machine
|
||||
5s Normal Created pod/openhands-app-2024 Created container openhands-sandbox-2024
|
||||
5s Normal Started pod/openhands-app-2024 Started container openhands-sandbox-2024
|
||||
83s Normal WaitForFirstConsumer persistentvolumeclaim/workspace-pvc waiting for first consumer to be created before binding
|
||||
27s Normal Provisioning persistentvolumeclaim/workspace-pvc External provisioner is provisioning volume for claim "openhands/workspace-pvc"
|
||||
17s Normal ProvisioningSucceeded persistentvolumeclaim/workspace-pvc Successfully provisioned volume pvc-31f15b25-faad-4665-a25f-201a530379af
|
||||
|
||||
$ oc get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
openhands-app-2024 2/2 Running 0 23s
|
||||
|
||||
$ oc get pvc
|
||||
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
|
||||
docker-pvc Bound pvc-2b1d223a-1c8f-4990-8e3d-68061a9ae252 10Gi RWO hcloud-volumes 10m
|
||||
workspace-pvc Bound pvc-31f15b25-faad-4665-a25f-201a530379af 10Gi RWO hcloud-volumes 13m
|
||||
|
||||
```
|
||||
|
||||
4. Créer un service NodePort.
|
||||
Exemple de commande de création de service ci-dessous :
|
||||
|
||||
```bash
|
||||
# créer le service de type NodePort
|
||||
$ oc create svc nodeport openhands-app-2024 --tcp=3000:3000
|
||||
service/openhands-app-2024 created
|
||||
|
||||
# vérifier
|
||||
|
||||
$ oc get svc
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
openhands-app-2024 NodePort 172.30.225.42 <none> 3000:30495/TCP 4s
|
||||
|
||||
$ oc describe svc openhands-app-2024
|
||||
Name: openhands-app-2024
|
||||
Namespace: openhands
|
||||
Labels: app=openhands-app-2024
|
||||
Annotations: <none>
|
||||
Selector: app=openhands-app-2024
|
||||
Type: NodePort
|
||||
IP Family Policy: SingleStack
|
||||
IP Families: IPv4
|
||||
IP: 172.30.225.42
|
||||
IPs: 172.30.225.42
|
||||
Port: 3000-3000 3000/TCP
|
||||
TargetPort: 3000/TCP
|
||||
NodePort: 3000-3000 30495/TCP
|
||||
Endpoints: 10.128.2.48:3000
|
||||
Session Affinity: None
|
||||
External Traffic Policy: Cluster
|
||||
Events: <none>
|
||||
```
|
||||
|
||||
6. Se connecter à l'interface utilisateur d'OpenHands, configurer l'Agent, puis tester :
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
## Déploiement d'Openhands sur GCP GKE
|
||||
|
||||
**Avertissement** : ce déploiement accorde à l'application OpenHands l'accès au socket docker de Kubernetes, ce qui crée un risque de sécurité. Utilisez à vos propres risques.
|
||||
1- Créer une politique pour l'accès privilégié
|
||||
2- Créer des informations d'identification gke (facultatif)
|
||||
3- Créer le déploiement openhands
|
||||
4- Commandes de vérification et d'accès à l'interface utilisateur
|
||||
5- Dépanner le pod pour vérifier le conteneur interne
|
||||
|
||||
1. créer une politique pour l'accès privilégié
|
||||
```bash
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: privileged-role
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["create", "get", "list", "watch", "delete"]
|
||||
- apiGroups: ["apps"]
|
||||
resources: ["deployments"]
|
||||
verbs: ["create", "get", "list", "watch", "delete"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods/exec"]
|
||||
verbs: ["create"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods/log"]
|
||||
verbs: ["get"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: privileged-role-binding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: privileged-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: default # Remplacez par le nom de votre compte de service
|
||||
namespace: default
|
||||
```
|
||||
2. créer des informations d'identification gke (facultatif)
|
||||
```bash
|
||||
kubectl create secret generic google-cloud-key \
|
||||
--from-file=key.json=/path/to/your/google-cloud-key.json
|
||||
```
|
||||
3. créer le déploiement openhands
|
||||
## comme cela est testé pour le nœud worker unique, si vous en avez plusieurs, spécifiez l'indicateur pour le worker unique
|
||||
|
||||
```bash
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: openhands-app-2024
|
||||
labels:
|
||||
app: openhands-app-2024
|
||||
spec:
|
||||
replicas: 1 # Vous pouvez augmenter ce nombre pour plusieurs réplicas
|
||||
selector:
|
||||
matchLabels:
|
||||
app: openhands-app-2024
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: openhands-app-2024
|
||||
spec:
|
||||
containers:
|
||||
-
|
||||
@@ -0,0 +1,65 @@
|
||||
|
||||
|
||||
# Installation
|
||||
|
||||
## Configuration requise
|
||||
|
||||
* Docker version 26.0.0+ ou Docker Desktop 4.31.0+.
|
||||
* Vous devez utiliser Linux ou Mac OS.
|
||||
* Si vous êtes sous Windows, vous devez utiliser [WSL](https://learn.microsoft.com/en-us/windows/wsl/install).
|
||||
|
||||
## Démarrer l'application
|
||||
|
||||
La façon la plus simple d'exécuter OpenHands est avec Docker. Vous pouvez modifier `WORKSPACE_BASE` ci-dessous pour pointer OpenHands vers
|
||||
du code existant que vous souhaitez modifier.
|
||||
|
||||
```bash
|
||||
export WORKSPACE_BASE=$(pwd)/workspace
|
||||
|
||||
docker pull ghcr.io/all-hands-ai/runtime:0.11-nikolaik
|
||||
|
||||
docker run -it --pull=always \
|
||||
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=ghcr.io/all-hands-ai/runtime:0.11-nikolaik \
|
||||
-e SANDBOX_USER_ID=$(id -u) \
|
||||
-e WORKSPACE_MOUNT_PATH=$WORKSPACE_BASE \
|
||||
-v $WORKSPACE_BASE:/opt/workspace_base \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-p 3000:3000 \
|
||||
--add-host host.docker.internal:host-gateway \
|
||||
--name openhands-app-$(date +%Y%m%d%H%M%S) \
|
||||
ghcr.io/all-hands-ai/openhands:0.11
|
||||
```
|
||||
|
||||
Vous pouvez également exécuter OpenHands en mode [headless scriptable](https://docs.all-hands.dev/modules/usage/how-to/headless-mode), comme un [CLI interactif](https://docs.all-hands.dev/modules/usage/how-to/cli-mode), ou en utilisant l'[Action GitHub OpenHands](https://docs.all-hands.dev/modules/usage/how-to/github-action).
|
||||
|
||||
## Configuration
|
||||
|
||||
Après avoir exécuté la commande ci-dessus, vous trouverez OpenHands en cours d'exécution à l'adresse [http://localhost:3000](http://localhost:3000).
|
||||
|
||||
L'agent aura accès au dossier `./workspace` pour effectuer son travail. Vous pouvez copier du code existant ici, ou modifier `WORKSPACE_BASE` dans la
|
||||
commande pour pointer vers un dossier existant.
|
||||
|
||||
Au lancement d'OpenHands, vous verrez une fenêtre modale de paramètres. Vous **devez** sélectionner un `Fournisseur LLM` et un `Modèle LLM` et entrer une `Clé API` correspondante.
|
||||
Ceux-ci peuvent être modifiés à tout moment en sélectionnant le bouton `Paramètres` (icône d'engrenage) dans l'interface utilisateur.
|
||||
|
||||
Si le `Modèle LLM` requis n'existe pas dans la liste, vous pouvez activer les `Options avancées` et le saisir manuellement avec le préfixe correct
|
||||
dans la zone de texte `Modèle personnalisé`.
|
||||
Les `Options avancées` vous permettent également de spécifier une `URL de base` si nécessaire.
|
||||
|
||||
<div style={{ display: 'flex', justifyContent: 'center', gap: '20px' }}>
|
||||
<img src="/img/settings-screenshot.png" alt="settings-modal" width="340" />
|
||||
<img src="/img/settings-advanced.png" alt="settings-modal" width="335" />
|
||||
</div>
|
||||
|
||||
## Versions
|
||||
|
||||
La commande ci-dessus récupère la version stable la plus récente d'OpenHands. Vous avez également d'autres options :
|
||||
- Pour une version spécifique, utilisez `ghcr.io/all-hands-ai/openhands:$VERSION`, en remplaçant $VERSION par le numéro de version.
|
||||
- Nous utilisons semver et publions des tags majeurs, mineurs et de correctifs. Ainsi, `0.9` pointera automatiquement vers la dernière version `0.9.x`, et `0` pointera vers la dernière version `0.x.x`.
|
||||
- Pour la version de développement la plus à jour, vous pouvez utiliser `ghcr.io/all-hands-ai/openhands:main`. Cette version est instable et n'est recommandée qu'à des fins de test ou de développement.
|
||||
|
||||
Vous pouvez choisir le tag qui correspond le mieux à vos besoins en fonction des exigences de stabilité et des fonctionnalités souhaitées.
|
||||
|
||||
Pour le workflow de développement, consultez [Development.md](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md).
|
||||
|
||||
Vous rencontrez des problèmes ? Consultez notre [Guide de dépannage](https://docs.all-hands.dev/modules/usage/troubleshooting).
|
||||
@@ -0,0 +1,48 @@
|
||||
|
||||
|
||||
# Azure
|
||||
|
||||
OpenHands utilise LiteLLM pour faire des appels aux modèles de chat d'Azure. Vous pouvez trouver leur documentation sur l'utilisation d'Azure comme fournisseur [ici](https://docs.litellm.ai/docs/providers/azure).
|
||||
|
||||
## Configuration d'Azure OpenAI
|
||||
|
||||
Lorsque vous exécutez OpenHands, vous devrez définir la variable d'environnement suivante en utilisant `-e` dans la
|
||||
[commande docker run](/modules/usage/installation#start-the-app) :
|
||||
|
||||
```
|
||||
LLM_API_VERSION="<api-version>" # par exemple "2023-05-15"
|
||||
```
|
||||
|
||||
Exemple :
|
||||
```bash
|
||||
docker run -it --pull=always \
|
||||
-e LLM_API_VERSION="2023-05-15"
|
||||
...
|
||||
```
|
||||
|
||||
Ensuite, définissez les éléments suivants dans l'interface utilisateur d'OpenHands via les paramètres :
|
||||
|
||||
:::note
|
||||
Vous aurez besoin du nom de votre déploiement ChatGPT qui peut être trouvé sur la page des déploiements dans Azure. Il est référencé comme
|
||||
<deployment-name> ci-dessous.
|
||||
:::
|
||||
|
||||
* Activez `Advanced Options`
|
||||
* `Custom Model` à azure/<deployment-name>
|
||||
* `Base URL` à votre URL de base de l'API Azure (par exemple `https://example-endpoint.openai.azure.com`)
|
||||
* `API Key` à votre clé API Azure
|
||||
|
||||
## Embeddings
|
||||
|
||||
OpenHands utilise llama-index pour les embeddings. Vous pouvez trouver leur documentation sur Azure [ici](https://docs.llamaindex.ai/en/stable/api_reference/embeddings/azure_openai/).
|
||||
|
||||
### Configuration d'Azure OpenAI
|
||||
|
||||
Lorsque vous exécutez OpenHands, définissez les variables d'environnement suivantes en utilisant `-e` dans la
|
||||
[commande docker run](/modules/usage/installation#start-the-app) :
|
||||
|
||||
```
|
||||
LLM_EMBEDDING_MODEL="azureopenai"
|
||||
LLM_EMBEDDING_DEPLOYMENT_NAME="<your-embedding-deployment-name>" # par exemple "TextEmbedding...<etc>"
|
||||
LLM_API_VERSION="<api-version>" # par exemple "2024-02-15-preview"
|
||||
```
|
||||
@@ -0,0 +1,31 @@
|
||||
|
||||
|
||||
# Google Gemini/Vertex
|
||||
|
||||
OpenHands utilise LiteLLM pour faire des appels aux modèles de chat de Google. Vous pouvez trouver leur documentation sur l'utilisation de Google comme fournisseur :
|
||||
|
||||
- [Gemini - Google AI Studio](https://docs.litellm.ai/docs/providers/gemini)
|
||||
- [VertexAI - Google Cloud Platform](https://docs.litellm.ai/docs/providers/vertex)
|
||||
|
||||
## Configurations de Gemini - Google AI Studio
|
||||
|
||||
Lors de l'exécution d'OpenHands, vous devrez définir les éléments suivants dans l'interface utilisateur d'OpenHands via les paramètres :
|
||||
* `LLM Provider` à `Gemini`
|
||||
* `LLM Model` au modèle que vous utiliserez.
|
||||
Si le modèle ne figure pas dans la liste, activez `Advanced Options` et entrez-le dans `Custom Model` (par exemple, gemini/<model-name> comme `gemini/gemini-1.5-pro`).
|
||||
* `API Key` à votre clé API Gemini
|
||||
|
||||
## Configurations de VertexAI - Google Cloud Platform
|
||||
|
||||
Pour utiliser Vertex AI via Google Cloud Platform lors de l'exécution d'OpenHands, vous devrez définir les variables d'environnement suivantes en utilisant `-e` dans la [commande docker run](/modules/usage/installation#start-the-app) :
|
||||
|
||||
```
|
||||
GOOGLE_APPLICATION_CREDENTIALS="<json-dump-of-gcp-service-account-json>"
|
||||
VERTEXAI_PROJECT="<your-gcp-project-id>"
|
||||
VERTEXAI_LOCATION="<your-gcp-location>"
|
||||
```
|
||||
|
||||
Ensuite, définissez les éléments suivants dans l'interface utilisateur d'OpenHands via les paramètres :
|
||||
* `LLM Provider` à `VertexAI`
|
||||
* `LLM Model` au modèle que vous utiliserez.
|
||||
Si le modèle ne figure pas dans la liste, activez `Advanced Options` et entrez-le dans `Custom Model` (par exemple, vertex_ai/<model-name>).
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
|
||||
# Groq
|
||||
|
||||
OpenHands utilise LiteLLM pour faire des appels aux modèles de chat sur Groq. Vous pouvez trouver leur documentation sur l'utilisation de Groq comme fournisseur [ici](https://docs.litellm.ai/docs/providers/groq).
|
||||
|
||||
## Configuration
|
||||
|
||||
Lorsque vous exécutez OpenHands, vous devrez définir les éléments suivants dans l'interface utilisateur d'OpenHands via les paramètres :
|
||||
* `LLM Provider` à `Groq`
|
||||
* `LLM Model` au modèle que vous utiliserez. [Visitez ici pour voir la liste des modèles hébergés par Groq](https://console.groq.com/docs/models). Si le modèle n'est pas dans la liste, activez les `Advanced Options` et entrez-le dans `Custom Model` (par exemple, groq/<model-name> comme `groq/llama3-70b-8192`).
|
||||
* `API key` à votre clé API Groq. Pour trouver ou créer votre clé API Groq, [voir ici](https://console.groq.com/keys).
|
||||
|
||||
|
||||
|
||||
## Utilisation de Groq comme point de terminaison compatible OpenAI
|
||||
|
||||
Le point de terminaison Groq pour la complétion de chat est [principalement compatible OpenAI](https://console.groq.com/docs/openai). Par conséquent, vous pouvez accéder aux modèles Groq comme vous le feriez pour n'importe quel point de terminaison compatible OpenAI. Vous pouvez définir les éléments suivants dans l'interface utilisateur d'OpenHands via les paramètres :
|
||||
* Activer les `Advanced Options`
|
||||
* `Custom Model` au préfixe `openai/` + le modèle que vous utiliserez (par exemple, `openai/llama3-70b-8192`)
|
||||
* `Base URL` à `https://api.groq.com/openai/v1`
|
||||
* `API Key` à votre clé API Groq
|
||||
@@ -1,44 +1,83 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
|
||||
# 🤖 Backends LLM
|
||||
|
||||
OpenHands peut fonctionner avec n'importe quel backend LLM.
|
||||
Pour une liste complète des fournisseurs et des modèles LM disponibles, veuillez consulter la
|
||||
[documentation litellm](https://docs.litellm.ai/docs/providers).
|
||||
OpenHands peut se connecter à n'importe quel LLM pris en charge par LiteLLM. Cependant, il nécessite un modèle puissant pour fonctionner.
|
||||
|
||||
## Recommandations de modèles
|
||||
|
||||
Sur la base d'une évaluation récente des modèles de langage pour les tâches de codage (en utilisant le jeu de données SWE-bench), nous pouvons fournir quelques recommandations pour la sélection des modèles. L'analyse complète se trouve dans [cet article de blog](https://www.all-hands.dev/blog/evaluation-of-llms-as-coding-agents-on-swe-bench-at-30x-speed).
|
||||
|
||||
Lors du choix d'un modèle, tenez compte à la fois de la qualité des sorties et des coûts associés. Voici un résumé des résultats :
|
||||
|
||||
- Claude 3.5 Sonnet est le meilleur d'une bonne marge, atteignant un taux de résolution de 27% avec l'agent par défaut dans OpenHands.
|
||||
- GPT-4o est à la traîne, et o1-mini a en fait obtenu des résultats légèrement inférieurs à ceux de GPT-4o. Nous avons analysé les résultats un peu, et brièvement, il semblait que o1 "réfléchissait trop" parfois, effectuant des tâches de configuration d'environnement supplémentaires alors qu'il aurait pu simplement aller de l'avant et terminer la tâche.
|
||||
- Enfin, les modèles ouverts les plus puissants étaient Llama 3.1 405 B et deepseek-v2.5, et ils ont obtenu des résultats raisonnables, surpassant même certains des modèles fermés.
|
||||
|
||||
Veuillez vous référer à [l'article complet](https://www.all-hands.dev/blog/evaluation-of-llms-as-coding-agents-on-swe-bench-at-30x-speed) pour plus de détails.
|
||||
|
||||
Sur la base de ces résultats et des commentaires de la communauté, il a été vérifié que les modèles suivants fonctionnent raisonnablement bien avec OpenHands :
|
||||
|
||||
- claude-3-5-sonnet (recommandé)
|
||||
- gpt-4 / gpt-4o
|
||||
- llama-3.1-405b
|
||||
- deepseek-v2.5
|
||||
|
||||
:::warning
|
||||
OpenHands émettra de nombreuses invitations au LLM que vous configurez. La plupart de ces LLM coûtent de l'argent -- assurez-vous de définir des limites de dépenses et de surveiller l'utilisation.
|
||||
OpenHands enverra de nombreuses invites au LLM que vous configurez. La plupart de ces LLM sont payants, alors assurez-vous de définir des limites de dépenses et de surveiller l'utilisation.
|
||||
:::
|
||||
|
||||
La variable d'environnement `LLM_MODEL` contrôle le modèle utilisé dans les interactions programmatiques.
|
||||
Mais en utilisant l'interface utilisateur OpenHands, vous devrez choisir votre modèle dans la fenêtre des paramètres (la roue dentée en bas à gauche).
|
||||
Si vous avez réussi à exécuter OpenHands avec des LLM spécifiques qui ne figurent pas dans la liste, veuillez les ajouter à la liste vérifiée. Nous vous encourageons également à ouvrir une PR pour partager votre processus de configuration afin d'aider les autres utilisant le même fournisseur et LLM !
|
||||
|
||||
Les variables d'environnement suivantes peuvent être nécessaires pour certains LLM :
|
||||
Pour une liste complète des fournisseurs et des modèles disponibles, veuillez consulter la [documentation litellm](https://docs.litellm.ai/docs/providers).
|
||||
|
||||
- `LLM_API_KEY`
|
||||
- `LLM_BASE_URL`
|
||||
:::note
|
||||
La plupart des modèles locaux et open source actuels ne sont pas aussi puissants. Lorsque vous utilisez de tels modèles, vous pouvez constater de longs temps d'attente entre les messages, des réponses médiocres ou des erreurs concernant du JSON malformé. OpenHands ne peut être aussi puissant que les modèles qui le pilotent. Cependant, si vous en trouvez qui fonctionnent, veuillez les ajouter à la liste vérifiée ci-dessus.
|
||||
:::
|
||||
|
||||
## Configuration LLM
|
||||
|
||||
Les éléments suivants peuvent être définis dans l'interface utilisateur d'OpenHands via les paramètres :
|
||||
|
||||
- `Fournisseur LLM`
|
||||
- `Modèle LLM`
|
||||
- `Clé API`
|
||||
- `URL de base` (via `Paramètres avancés`)
|
||||
|
||||
Certains paramètres peuvent être nécessaires pour certains LLM/fournisseurs qui ne peuvent pas être définis via l'interface utilisateur. Au lieu de cela, ceux-ci peuvent être définis via des variables d'environnement passées à la [commande docker run](/modules/usage/installation#start-the-app) en utilisant `-e` :
|
||||
|
||||
- `LLM_API_VERSION`
|
||||
- `LLM_EMBEDDING_MODEL`
|
||||
- `LLM_EMBEDDING_DEPLOYMENT_NAME`
|
||||
- `LLM_API_VERSION`
|
||||
- `LLM_DROP_PARAMS`
|
||||
- `LLM_DISABLE_VISION`
|
||||
- `LLM_CACHING_PROMPT`
|
||||
|
||||
Nous avons quelques guides pour exécuter OpenHands avec des fournisseurs de modèles spécifiques :
|
||||
|
||||
- [ollama](llms/local-llms)
|
||||
- [Azure](llms/azure-llms)
|
||||
- [Google](llms/google-llms)
|
||||
- [Groq](llms/groq)
|
||||
- [OpenAI](llms/openai-llms)
|
||||
- [OpenRouter](llms/openrouter)
|
||||
|
||||
Si vous utilisez un autre fournisseur, nous vous encourageons à ouvrir une PR pour partager votre configuration !
|
||||
### Nouvelles tentatives d'API et limites de débit
|
||||
|
||||
## Remarque sur les modèles alternatifs
|
||||
Les fournisseurs de LLM ont généralement des limites de débit, parfois très basses, et peuvent nécessiter de nouvelles tentatives. OpenHands réessaiera automatiquement les requêtes s'il reçoit une erreur de limite de débit (code d'erreur 429), une erreur de connexion API ou d'autres erreurs transitoires.
|
||||
|
||||
Les meilleurs modèles sont GPT-4 et Claude 3. Les modèles locaux et open source actuels ne sont pas aussi puissants.
|
||||
Lors de l'utilisation d'un modèle alternatif, vous pouvez constater des temps d'attente prolongés entre les messages,
|
||||
des réponses de mauvaise qualité ou des erreurs sur des JSON mal formés. OpenHands
|
||||
ne peut être aussi puissant que les modèles qui le pilotent -- heureusement, les membres de notre équipe travaillent activement à la construction de meilleurs modèles open source !
|
||||
Vous pouvez personnaliser ces options selon vos besoins pour le fournisseur que vous utilisez. Consultez leur documentation et définissez les variables d'environnement suivantes pour contrôler le nombre de nouvelles tentatives et le temps entre les tentatives :
|
||||
|
||||
## Réessais d'API et limites de taux
|
||||
- `LLM_NUM_RETRIES` (Par défaut 8)
|
||||
- `LLM_RETRY_MIN_WAIT` (Par défaut 15 secondes)
|
||||
- `LLM_RETRY_MAX_WAIT` (Par défaut 120 secondes)
|
||||
- `LLM_RETRY_MULTIPLIER` (Par défaut 2)
|
||||
|
||||
Certains LLM ont des limites de taux et peuvent nécessiter des réessais. OpenHands réessaiera automatiquement les demandes s'il reçoit une erreur 429 ou une erreur de connexion API.
|
||||
Vous pouvez définir les variables d'environnement `LLM_NUM_RETRIES`, `LLM_RETRY_MIN_WAIT`, `LLM_RETRY_MAX_WAIT` pour contrôler le nombre de réessais et le temps entre les réessais.
|
||||
Par défaut, `LLM_NUM_RETRIES` est 8 et `LLM_RETRY_MIN_WAIT`, `LLM_RETRY_MAX_WAIT` sont respectivement de 15 secondes et 120 secondes.
|
||||
Si vous exécutez OpenHands en mode développement, vous pouvez également définir ces options dans le fichier `config.toml` :
|
||||
|
||||
```toml
|
||||
[llm]
|
||||
num_retries = 8
|
||||
retry_min_wait = 15
|
||||
retry_max_wait = 120
|
||||
retry_multiplier = 2
|
||||
```
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
|
||||
|
||||
# LLM local avec Ollama
|
||||
|
||||
:::warning
|
||||
Lors de l'utilisation d'un LLM local, OpenHands peut avoir des fonctionnalités limitées.
|
||||
:::
|
||||
|
||||
Assurez-vous que le serveur Ollama est opérationnel.
|
||||
Pour des instructions détaillées sur le démarrage, référez-vous à [ici](https://github.com/ollama/ollama).
|
||||
|
||||
Ce guide suppose que vous avez démarré ollama avec `ollama serve`. Si vous exécutez ollama différemment (par exemple, à l'intérieur de docker), les instructions peuvent nécessiter des modifications. Veuillez noter que si vous utilisez WSL, la configuration par défaut d'ollama bloque les requêtes provenant des conteneurs docker. Voir [ici](#configuring-ollama-service-wsl-fr).
|
||||
|
||||
## Récupérer les modèles
|
||||
|
||||
Les noms des modèles Ollama peuvent être trouvés [ici](https://ollama.com/library). Pour un petit exemple, vous pouvez utiliser le modèle `codellama:7b`. Les modèles plus grands auront généralement de meilleures performances.
|
||||
|
||||
```bash
|
||||
ollama pull codellama:7b
|
||||
```
|
||||
|
||||
Vous pouvez vérifier quels modèles vous avez téléchargés comme ceci :
|
||||
|
||||
```bash
|
||||
~$ ollama list
|
||||
NAME ID SIZE MODIFIED
|
||||
codellama:7b 8fdf8f752f6e 3.8 GB 6 weeks ago
|
||||
mistral:7b-instruct-v0.2-q4_K_M eb14864c7427 4.4 GB 2 weeks ago
|
||||
starcoder2:latest f67ae0f64584 1.7 GB 19 hours ago
|
||||
```
|
||||
|
||||
## Exécuter OpenHands avec Docker
|
||||
|
||||
### Démarrer OpenHands
|
||||
Utilisez les instructions [ici](../getting-started) pour démarrer OpenHands en utilisant Docker.
|
||||
Mais lorsque vous exécutez `docker run`, vous devrez ajouter quelques arguments supplémentaires :
|
||||
|
||||
```bash
|
||||
--add-host host.docker.internal:host-gateway \
|
||||
-e LLM_OLLAMA_BASE_URL="http://host.docker.internal:11434" \
|
||||
```
|
||||
|
||||
LLM_OLLAMA_BASE_URL est facultatif. Si vous le définissez, il sera utilisé pour afficher les modèles installés disponibles dans l'interface utilisateur.
|
||||
|
||||
Exemple :
|
||||
|
||||
```bash
|
||||
# Le répertoire que vous voulez qu'OpenHands modifie. DOIT être un chemin absolu !
|
||||
export WORKSPACE_BASE=$(pwd)/workspace
|
||||
|
||||
docker run \
|
||||
-it \
|
||||
--pull=always \
|
||||
--add-host host.docker.internal:host-gateway \
|
||||
-e SANDBOX_USER_ID=$(id -u) \
|
||||
-e LLM_OLLAMA_BASE_URL="http://host.docker.internal:11434" \
|
||||
-e WORKSPACE_MOUNT_PATH=$WORKSPACE_BASE \
|
||||
-v $WORKSPACE_BASE:/opt/workspace_base \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-p 3000:3000 \
|
||||
ghcr.io/all-hands-ai/openhands:main
|
||||
```
|
||||
|
||||
Vous devriez maintenant pouvoir vous connecter à `http://localhost:3000/`
|
||||
|
||||
### Configurer l'application Web
|
||||
|
||||
Lors de l'exécution d'`openhands`, vous devrez définir les éléments suivants dans l'interface utilisateur d'OpenHands via les paramètres :
|
||||
- le modèle à "ollama/<nom-du-modèle>"
|
||||
- l'URL de base à `http://host.docker.internal:11434`
|
||||
- la clé API est facultative, vous pouvez utiliser n'importe quelle chaîne, comme `ollama`.
|
||||
|
||||
|
||||
## Exécuter OpenHands en mode développement
|
||||
|
||||
### Construire à partir de la source
|
||||
|
||||
Utilisez les instructions dans [Development.md](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md) pour construire OpenHands.
|
||||
Assurez-vous que `config.toml` est présent en exécutant `make setup-config` qui en créera un pour vous. Dans `config.toml`, entrez ce qui suit :
|
||||
|
||||
```
|
||||
[core]
|
||||
workspace_base="./workspace"
|
||||
|
||||
[llm]
|
||||
embedding_model="local"
|
||||
ollama_base_url="http://localhost:11434"
|
||||
|
||||
```
|
||||
|
||||
Terminé ! Vous pouvez maintenant démarrer OpenHands avec : `make run`. Vous devriez maintenant pouvoir vous connecter à `http://localhost:3000/`
|
||||
|
||||
### Configurer l'application Web
|
||||
|
||||
Dans l'interface utilisateur d'OpenHands, cliquez sur la roue des paramètres dans le coin inférieur gauche.
|
||||
Ensuite, dans le champ `Model`, entrez `ollama/codellama:7b`, ou le nom du modèle que vous avez récupéré précédemment.
|
||||
S'il n'apparaît pas dans le menu déroulant, activez `Advanced Settings` et tapez-le. Veuillez noter : vous avez besoin du nom du modèle tel qu'il est listé par `ollama list`, avec le préfixe `ollama/`.
|
||||
|
||||
Dans le champ API Key, entrez `ollama` ou n'importe quelle valeur, puisque vous n'avez pas besoin d'une clé particulière.
|
||||
|
||||
Dans le champ Base URL, entrez `http://localhost:11434`.
|
||||
|
||||
Et maintenant vous êtes prêt à démarrer !
|
||||
|
||||
## Configurer le service ollama (WSL) {#configuring-ollama-service-wsl-fr}
|
||||
|
||||
La configuration par défaut pour ollama dans WSL ne sert que localhost. Cela signifie que vous ne pouvez pas y accéder depuis un conteneur docker. Par ex. cela ne fonctionnera pas avec OpenHands. Testons d'abord qu'ollama fonctionne correctement.
|
||||
|
||||
```bash
|
||||
ollama list # obtenir la liste des modèles installés
|
||||
curl http://localhost:11434/api/generate -d '{"model":"[NOM]","prompt":"hi"}'
|
||||
#ex. curl http://localhost:11434/api/generate -d '{"model":"codellama:7b","prompt":"hi"}'
|
||||
#ex. curl http://localhost:11434/api/generate -d '{"model":"codellama","prompt":"hi"}' #le tag est facultatif s'il n'y en a qu'un seul
|
||||
```
|
||||
|
||||
Une fois cela fait, testez qu'il autorise les requêtes "extérieures", comme celles provenant d'un conteneur docker.
|
||||
|
||||
```bash
|
||||
docker ps # obtenir la liste des conteneurs docker en cours d'exécution, pour un test plus précis, choisissez le conteneur sandbox OpenHands.
|
||||
docker exec [ID CONTENEUR] curl http://host.docker.internal:11434/api/generate -d '{"model":"[NOM]","prompt":"hi"}'
|
||||
#ex. docker exec cd9cc82f7a11 curl http://host.docker.internal:11434/api/generate -d '{"model":"codellama","prompt":"hi"}'
|
||||
```
|
||||
|
||||
## Le réparer
|
||||
|
||||
Maintenant, faisons en sorte que cela fonctionne. Modifiez /etc/systemd/system/ollama.service avec des privilèges sudo. (Le chemin peut varier selon la distribution Linux)
|
||||
|
||||
```bash
|
||||
sudo vi /etc/systemd/system/ollama.service
|
||||
```
|
||||
|
||||
ou
|
||||
|
||||
```bash
|
||||
sudo nano /etc/systemd/system/ollama.service
|
||||
```
|
||||
|
||||
Dans le crochet [Service], ajoutez ces lignes
|
||||
|
||||
```
|
||||
Environment="OLLAMA_HOST=0.0.0.0:11434"
|
||||
Environment="OLLAMA_ORIGINS=*"
|
||||
```
|
||||
|
||||
Ensuite, enregistrez, rechargez la configuration et redémarrez le service.
|
||||
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl restart ollama
|
||||
```
|
||||
|
||||
Enfin, testez qu'ollama est accessible depuis le conteneur
|
||||
|
||||
```bash
|
||||
ollama list # obtenir la liste des modèles installés
|
||||
docker ps # obtenir la liste des conteneurs docker en cours d'exécution, pour un test plus précis, choisissez le conteneur sandbox OpenHands.
|
||||
docker exec [ID CONTENEUR] curl http://host.docker.internal:11434/api/generate -d '{"model":"[NOM]","prompt":"hi"}'
|
||||
```
|
||||
|
||||
|
||||
# LLM local avec LM Studio
|
||||
|
||||
Étapes pour configurer LM Studio :
|
||||
1. Ouvrez LM Studio
|
||||
2. Allez dans l'onglet Serveur local.
|
||||
3. Cliquez sur le bouton "Démarrer le serveur".
|
||||
4. Sélectionnez le modèle que vous souhaitez utiliser dans le menu déroulant.
|
||||
|
||||
|
||||
Définissez les configurations suivantes :
|
||||
```bash
|
||||
LLM_MODEL="openai/lmstudio"
|
||||
LLM_BASE_URL="http://localhost:1234/v1"
|
||||
CUSTOM_LLM_PROVIDER="openai"
|
||||
```
|
||||
|
||||
### Docker
|
||||
|
||||
```bash
|
||||
docker run \
|
||||
-it \
|
||||
--pull=always \
|
||||
-e SANDBOX_USER_ID=$(id -u) \
|
||||
-e LLM_MODEL="openai/lmstudio" \
|
||||
-e LLM_BASE_URL="http://host.docker.internal:1234/v1" \
|
||||
-e CUSTOM_LLM_PROVIDER="openai" \
|
||||
-e WORKSPACE_MOUNT_PATH=$WORKSPACE_BASE \
|
||||
-v $WORKSPACE_BASE:/opt/workspace_base \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-p 3000:3000 \
|
||||
ghcr.io/all-hands-ai/openhands:main
|
||||
```
|
||||
|
||||
Vous devriez maintenant pouvoir vous connecter à `http://localhost:3000/`
|
||||
|
||||
Dans l'environnement de développement, vous pouvez définir les configurations suivantes dans le fichier `config.toml` :
|
||||
|
||||
```
|
||||
[core]
|
||||
workspace_base="./workspace"
|
||||
|
||||
[llm]
|
||||
model="openai/lmstudio"
|
||||
base_url="http://localhost:1234/v1"
|
||||
custom_llm_provider="openai"
|
||||
```
|
||||
|
||||
Terminé ! Vous pouvez maintenant démarrer OpenHands avec : `make run` sans Docker. Vous devriez maintenant pouvoir vous connecter à `http://localhost:3000/`
|
||||
|
||||
# Note
|
||||
|
||||
Pour WSL, exécutez les commandes suivantes dans cmd pour configurer le mode réseau en mode miroir :
|
||||
|
||||
```
|
||||
python -c "print('[wsl2]\nnetworkingMode=mirrored',file=open(r'%UserProfile%\.wslconfig','w'))"
|
||||
wsl --shutdown
|
||||
```
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
|
||||
# OpenAI
|
||||
|
||||
OpenHands utilise LiteLLM pour effectuer des appels aux modèles de chat d'OpenAI. Vous pouvez trouver leur documentation sur l'utilisation d'OpenAI en tant que fournisseur [ici](https://docs.litellm.ai/docs/providers/openai).
|
||||
|
||||
## Configuration
|
||||
|
||||
Lors de l'exécution d'OpenHands, vous devrez définir les éléments suivants dans l'interface utilisateur d'OpenHands via les paramètres :
|
||||
* `LLM Provider` à `OpenAI`
|
||||
* `LLM Model` au modèle que vous utiliserez.
|
||||
[Visitez ce lien pour voir une liste complète des modèles OpenAI pris en charge par LiteLLM.](https://docs.litellm.ai/docs/providers/openai#openai-chat-completion-models)
|
||||
Si le modèle ne figure pas dans la liste, activez les `Advanced Options` et entrez-le dans `Custom Model` (par exemple, openai/<model-name> comme `openai/gpt-4o`).
|
||||
* `API Key` à votre clé API OpenAI. Pour trouver ou créer votre clé API de projet OpenAI, [voir ici](https://platform.openai.com/api-keys).
|
||||
|
||||
## Utilisation des endpoints compatibles OpenAI
|
||||
|
||||
Tout comme pour les chat completions OpenAI, nous utilisons LiteLLM pour les endpoints compatibles OpenAI. Vous pouvez trouver leur documentation complète sur ce sujet [ici](https://docs.litellm.ai/docs/providers/openai_compatible).
|
||||
|
||||
## Utilisation d'un proxy OpenAI
|
||||
|
||||
Si vous utilisez un proxy OpenAI, vous devrez définir les éléments suivants dans l'interface utilisateur d'OpenHands via les paramètres :
|
||||
* Activer les `Advanced Options`
|
||||
* `Custom Model` à openai/<model-name> (par exemple, `openai/gpt-4o` ou openai/<proxy-prefix>/<model-name>)
|
||||
* `Base URL` à l'URL de votre proxy OpenAI
|
||||
* `API Key` à votre clé API OpenAI
|
||||
@@ -0,0 +1,14 @@
|
||||
|
||||
|
||||
# OpenRouter
|
||||
|
||||
OpenHands utilise LiteLLM pour effectuer des appels aux modèles de chat sur OpenRouter. Vous pouvez trouver leur documentation sur l'utilisation d'OpenRouter en tant que fournisseur [ici](https://docs.litellm.ai/docs/providers/openrouter).
|
||||
|
||||
## Configuration
|
||||
|
||||
Lors de l'exécution d'OpenHands, vous devrez définir les éléments suivants dans l'interface utilisateur d'OpenHands via les paramètres :
|
||||
* `LLM Provider` à `OpenRouter`
|
||||
* `LLM Model` au modèle que vous utiliserez.
|
||||
[Visitez ici pour voir une liste complète des modèles OpenRouter](https://openrouter.ai/models).
|
||||
Si le modèle ne figure pas dans la liste, activez `Advanced Options`, et entrez-le dans `Custom Model` (par exemple openrouter/<model-name> comme `openrouter/anthropic/claude-3.5-sonnet`).
|
||||
* `API Key` à votre clé API OpenRouter.
|
||||
@@ -0,0 +1,43 @@
|
||||
|
||||
|
||||
# Meilleures pratiques pour les prompts
|
||||
|
||||
Lorsque vous travaillez avec le développeur de logiciels OpenHands AI, il est crucial de fournir des prompts clairs et efficaces. Ce guide décrit les meilleures pratiques pour créer des prompts qui produiront les réponses les plus précises et utiles.
|
||||
|
||||
## Caractéristiques des bons prompts
|
||||
|
||||
Les bons prompts sont :
|
||||
|
||||
1. **Concrets** : Ils expliquent exactement quelle fonctionnalité doit être ajoutée ou quelle erreur doit être corrigée.
|
||||
2. **Spécifiques à l'emplacement** : Si connu, ils expliquent les emplacements dans la base de code qui doivent être modifiés.
|
||||
3. **Correctement dimensionnés** : Ils doivent avoir la taille d'une seule fonctionnalité, ne dépassant généralement pas 100 lignes de code.
|
||||
|
||||
## Exemples
|
||||
|
||||
### Exemples de bons prompts
|
||||
|
||||
1. "Ajoutez une fonction `calculate_average` dans `utils/math_operations.py` qui prend une liste de nombres en entrée et renvoie leur moyenne."
|
||||
|
||||
2. "Corrigez le TypeError dans `frontend/src/components/UserProfile.tsx` se produisant à la ligne 42. L'erreur suggère que nous essayons d'accéder à une propriété de undefined."
|
||||
|
||||
3. "Implémentez la validation des entrées pour le champ email dans le formulaire d'inscription. Mettez à jour `frontend/src/components/RegistrationForm.tsx` pour vérifier si l'email est dans un format valide avant la soumission."
|
||||
|
||||
### Exemples de mauvais prompts
|
||||
|
||||
1. "Améliorez le code." (Trop vague, pas concret)
|
||||
|
||||
2. "Réécrivez tout le backend pour utiliser un framework différent." (Pas correctement dimensionné)
|
||||
|
||||
3. "Il y a un bug quelque part dans l'authentification des utilisateurs. Pouvez-vous le trouver et le corriger ?" (Manque de spécificité et d'informations de localisation)
|
||||
|
||||
## Conseils pour des prompts efficaces
|
||||
|
||||
1. Soyez aussi précis que possible sur le résultat souhaité ou le problème à résoudre.
|
||||
2. Fournissez du contexte, y compris les chemins de fichiers et les numéros de ligne pertinents si disponibles.
|
||||
3. Décomposez les grandes tâches en prompts plus petits et gérables.
|
||||
4. Incluez tous les messages d'erreur ou logs pertinents.
|
||||
5. Spécifiez le langage de programmation ou le framework s'il n'est pas évident d'après le contexte.
|
||||
|
||||
N'oubliez pas, plus votre prompt est précis et informatif, mieux l'IA pourra vous aider à développer ou à modifier le logiciel OpenHands.
|
||||
|
||||
Voir [Getting Started with OpenHands](./getting-started) pour plus d'exemples de prompts utiles.
|
||||
@@ -1,101 +1,53 @@
|
||||
---
|
||||
sidebar_position: 5
|
||||
---
|
||||
|
||||
|
||||
# 🚧 Dépannage
|
||||
|
||||
Il existe certains messages d'erreur qui sont souvent signalés par les utilisateurs.
|
||||
|
||||
Nous essaierons de rendre le processus d'installation plus facile et ces messages d'erreur
|
||||
mieux à l'avenir. Mais pour l'instant, vous pouvez rechercher votre message d'erreur ci-dessous et voir s'il existe des solutions de contournement.
|
||||
|
||||
Pour chacun de ces messages d'erreur, **il existe un problème existant**. Veuillez ne pas
|
||||
ouvrir un nouveau problème - commentez simplement dessus.
|
||||
|
||||
Si vous trouvez plus d'informations ou une solution de contournement pour l'un de ces problèmes, veuillez ouvrir un *PR* pour ajouter des détails à ce fichier.
|
||||
Il y a certains messages d'erreur qui sont fréquemment signalés par les utilisateurs.
|
||||
Nous allons essayer de rendre le processus d'installation plus facile, mais pour l'instant vous pouvez rechercher votre message d'erreur ci-dessous et voir s'il y a des solutions de contournement.
|
||||
Si vous trouvez plus d'informations ou une solution de contournement pour l'un de ces problèmes, veuillez ouvrir une *PR* pour ajouter des détails à ce fichier.
|
||||
|
||||
:::tip
|
||||
Si vous utilisez Windows et que vous rencontrez des problèmes, consultez notre [guide pour les utilisateurs de Windows (WSL)](troubleshooting/windows).
|
||||
OpenHands ne prend en charge Windows que via [WSL](https://learn.microsoft.com/en-us/windows/wsl/install).
|
||||
Veuillez vous assurer d'exécuter toutes les commandes à l'intérieur de votre terminal WSL.
|
||||
Consultez les [Notes pour les utilisateurs de WSL sur Windows](troubleshooting/windows) pour des guides de dépannage.
|
||||
:::
|
||||
|
||||
## Impossible de se connecter à Docker
|
||||
## Problèmes courants
|
||||
|
||||
[Problème GitHub](https://github.com/All-Hands-AI/OpenHands/issues/1226)
|
||||
* [Impossible de se connecter à Docker](#impossible-de-se-connecter-à-docker)
|
||||
* [404 Ressource introuvable](#404-ressource-introuvable)
|
||||
* [`make build` bloqué sur les installations de paquets](#make-build-bloqué-sur-les-installations-de-paquets)
|
||||
* [Les sessions ne sont pas restaurées](#les-sessions-ne-sont-pas-restaurées)
|
||||
|
||||
### Symptômes
|
||||
### Impossible de se connecter à Docker
|
||||
|
||||
[GitHub Issue](https://github.com/All-Hands-AI/OpenHands/issues/1226)
|
||||
|
||||
**Symptômes**
|
||||
|
||||
```bash
|
||||
Erreur lors de la création du contrôleur. Veuillez vérifier que Docker est en cours d'exécution et visitez `https://docs.all-hands.dev/modules/usage/troubleshooting` pour plus d'informations sur le débogage.
|
||||
Error creating controller. Please check Docker is running and visit `https://docs.all-hands.dev/modules/usage/troubleshooting` for more debugging information.
|
||||
```
|
||||
|
||||
```bash
|
||||
docker.errors.DockerException: Erreur lors de la récupération de la version de l'API du serveur : ('Connection aborted.', FileNotFoundError(2, 'Aucun fichier ou répertoire de ce type'))
|
||||
docker.errors.DockerException: Error while fetching server API version: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))
|
||||
```
|
||||
|
||||
### Détails
|
||||
**Détails**
|
||||
|
||||
OpenHands utilise un conteneur Docker pour effectuer son travail en toute sécurité, sans risquer de briser votre machine.
|
||||
OpenHands utilise un conteneur Docker pour faire son travail en toute sécurité, sans risquer de casser votre machine.
|
||||
|
||||
### Solutions de contournement
|
||||
**Solutions de contournement**
|
||||
|
||||
* Exécutez `docker ps` pour vous assurer que docker est en cours d'exécution
|
||||
* Assurez-vous que vous n'avez pas besoin de `sudo` pour exécuter docker [voir ici](https://www.baeldung.com/linux/docker-run-without-sudo)
|
||||
* Si vous êtes sur un Mac, vérifiez les [exigences en matière d'autorisations](https://docs.docker.com/desktop/mac/permission-requirements/) et envisagez particulièrement d'activer l'option `Allow the default Docker socket to be used` sous `Settings > Advanced` dans Docker Desktop.
|
||||
* De plus, mettez à jour Docker vers la dernière version sous `Check for Updates`
|
||||
* Si vous êtes sur un Mac, vérifiez les [exigences d'autorisation](https://docs.docker.com/desktop/mac/permission-requirements/) et en particulier envisagez d'activer `Allow the default Docker socket to be used` sous `Settings > Advanced` dans Docker Desktop.
|
||||
* De plus, mettez à niveau votre Docker vers la dernière version sous `Check for Updates`
|
||||
|
||||
## Impossible de se connecter à la boîte SSH
|
||||
---
|
||||
### `404 Ressource introuvable`
|
||||
|
||||
[Problème GitHub](https://github.com/All-Hands-AI/OpenHands/issues/1156)
|
||||
|
||||
### Symptômes
|
||||
|
||||
```python
|
||||
self.shell = DockerSSHBox(
|
||||
...
|
||||
pexpect.pxssh.ExceptionPxssh: Impossible d'établir une connexion avec l'hôte
|
||||
```
|
||||
|
||||
### Détails
|
||||
|
||||
Par défaut, OpenHands se connecte à un conteneur en cours d'exécution via SSH. Sur certaines machines,
|
||||
en particulier Windows, cela semble échouer.
|
||||
|
||||
### Solutions de contournement
|
||||
|
||||
* Redémarrez votre ordinateur (parfois cela fonctionne)
|
||||
* Assurez-vous d'avoir les dernières versions de WSL et Docker
|
||||
* Vérifiez que votre distribution dans WSL est également à jour
|
||||
* Essayez [ce guide de réinstallation](https://github.com/All-Hands-AI/OpenHands/issues/1156#issuecomment-2064549427)
|
||||
|
||||
## Impossible de se connecter à LLM
|
||||
|
||||
[Problème GitHub](https://github.com/All-Hands-AI/OpenHands/issues/1208)
|
||||
|
||||
### Symptômes
|
||||
|
||||
```python
|
||||
File "/app/.venv/lib/python3.12/site-packages/openai/_exceptions.py", line 81, in __init__
|
||||
super().__init__(message, response.request, body=body)
|
||||
^^^^^^^^^^^^^^^^
|
||||
AttributeError: 'NoneType' object has no attribute 'request'
|
||||
```
|
||||
|
||||
### Détails
|
||||
|
||||
[Problèmes GitHub](https://github.com/All-Hands-AI/OpenHands/issues?q=is%3Aissue+is%3Aopen+404)
|
||||
|
||||
Cela se produit généralement avec les configurations de LLM *locales*, lorsque OpenHands ne parvient pas à se connecter au serveur LLM.
|
||||
Consultez notre guide pour [LLMs locaux](llms/local-llms) pour plus d'informations.
|
||||
|
||||
### Solutions de contournement
|
||||
|
||||
* Vérifiez votre `base_url` dans votre config.toml (si elle existe) sous la section "llm"
|
||||
* Vérifiez que ollama (ou tout autre LLM que vous utilisez) fonctionne correctement
|
||||
* Assurez-vous d'utiliser `--add-host host.docker.internal:host-gateway` lorsque vous utilisez Docker
|
||||
|
||||
## `404 Ressource non trouvée`
|
||||
|
||||
### Symptômes
|
||||
**Symptômes**
|
||||
|
||||
```python
|
||||
Traceback (most recent call last):
|
||||
@@ -118,89 +70,81 @@ Traceback (most recent call last):
|
||||
^^^^^^^^^^^^^^
|
||||
File "/app/.venv/lib/python3.12/site-packages/openai/_base_client.py", line 1012, in _request
|
||||
raise self._make_status_error_from_response(err.response) from None
|
||||
openai.NotFoundError: Code d'erreur : 404 - {'error': {'code': '404', 'message': 'Ressource non trouvée'}}
|
||||
openai.NotFoundError: Error code: 404 - {'error': {'code': '404', 'message': 'Resource not found'}}
|
||||
```
|
||||
|
||||
### Détails
|
||||
**Détails**
|
||||
|
||||
Cela se produit lorsque LiteLLM (notre bibliothèque pour se connecter à différents fournisseurs de LLM) ne parvient pas à trouver
|
||||
le point de terminaison API avec lequel vous essayez de vous connecter. Cela arrive le plus souvent aux utilisateurs de Azure ou ollama.
|
||||
Cela se produit lorsque LiteLLM (notre bibliothèque pour se connecter à différents fournisseurs de LLM) ne peut pas trouver le point de terminaison d'API auquel vous essayez de vous connecter. Le plus souvent, cela se produit pour les utilisateurs d'Azure ou d'ollama.
|
||||
|
||||
### Solutions de contournement
|
||||
**Solutions de contournement**
|
||||
|
||||
* Vérifiez que vous avez correctement défini `LLM_BASE_URL`
|
||||
* Vérifiez que le modèle est correctement défini, en fonction des [docs de LiteLLM](https://docs.litellm.ai/docs/providers)
|
||||
* Si vous êtes en cours d'exécution dans l'interface utilisateur, assurez-vous de définir le `model` dans le modal des paramètres
|
||||
* Si vous êtes en cours d'exécution sans interface (via main.py), assurez-vous de définir `LLM_MODEL` dans votre env/config
|
||||
* Assurez-vous de suivre les instructions spéciales de votre fournisseur de LLM
|
||||
* [ollama](/fr/modules/usage/llms/local-llms)
|
||||
* [Azure](/fr/modules/usage/llms/azure-llms)
|
||||
* [Google](/fr/modules/usage/llms/google-llms)
|
||||
* Vérifiez que le modèle est correctement défini, en fonction de la [documentation de LiteLLM](https://docs.litellm.ai/docs/providers)
|
||||
* Si vous exécutez dans l'interface utilisateur, assurez-vous de définir le `model` dans la fenêtre modale des paramètres
|
||||
* Si vous exécutez en mode headless (via main.py), assurez-vous de définir `LLM_MODEL` dans votre env/config
|
||||
* Assurez-vous d'avoir suivi toutes les instructions spéciales pour votre fournisseur de LLM
|
||||
* [Azure](/modules/usage/llms/azure-llms)
|
||||
* [Google](/modules/usage/llms/google-llms)
|
||||
* Assurez-vous que votre clé API est correcte
|
||||
* Voyez si vous pouvez vous connecter au LLM en utilisant `curl`
|
||||
* Essayez de [vous connecter via LiteLLM directement](https://github.com/BerriAI/litellm) pour tester votre configuration
|
||||
* Essayez de [vous connecter directement via LiteLLM](https://github.com/BerriAI/litellm) pour tester votre configuration
|
||||
|
||||
## `make build` bloqué sur les installations de packages
|
||||
---
|
||||
### `make build` bloqué sur les installations de paquets
|
||||
|
||||
### Symptômes
|
||||
**Symptômes**
|
||||
|
||||
Installation de package bloquée sur `En attente...` sans aucun message d'erreur :
|
||||
L'installation des paquets est bloquée sur `Pending...` sans aucun message d'erreur :
|
||||
|
||||
```bash
|
||||
Opérations de package : 286 installations, 0 mises à jour, 0 suppressions
|
||||
Package operations: 286 installs, 0 updates, 0 removals
|
||||
|
||||
- Installation de certifi (2024.2.2) : En attente...
|
||||
- Installation de h11 (0.14.0) : En attente...
|
||||
- Installation de idna (3.7) : En attente...
|
||||
- Installation de sniffio (1.3.1) : En attente...
|
||||
- Installation de typing-extensions (4.11.0) : En attente...
|
||||
- Installing certifi (2024.2.2): Pending...
|
||||
- Installing h11 (0.14.0): Pending...
|
||||
- Installing idna (3.7): Pending...
|
||||
- Installing sniffio (1.3.1): Pending...
|
||||
- Installing typing-extensions (4.11.0): Pending...
|
||||
```
|
||||
|
||||
### Détails
|
||||
**Détails**
|
||||
|
||||
Dans de rares cas, `make build` peut sembler bloqué sur les installations de packages
|
||||
sans aucun message d'erreur.
|
||||
Dans de rares cas, `make build` peut sembler se bloquer sur les installations de paquets sans aucun message d'erreur.
|
||||
|
||||
### Solutions de contournement
|
||||
**Solutions de contournement**
|
||||
|
||||
* Le gestionnaire de packages Poetry peut manquer d'un paramètre de configuration concernant
|
||||
l'emplacement où doivent être recherchées les informations d'identification (keyring).
|
||||
L'installateur de paquets Poetry peut manquer un paramètre de configuration pour savoir où rechercher les informations d'identification (keyring).
|
||||
|
||||
### Solution de contournement
|
||||
|
||||
Tout d'abord, vérifiez avec `env` si une valeur pour `PYTHON_KEYRING_BACKEND` existe.
|
||||
Sinon, exécutez la commande ci-dessous pour la définir à une valeur connue et réessayez la construction :
|
||||
Vérifiez d'abord avec `env` si une valeur pour `PYTHON_KEYRING_BACKEND` existe.
|
||||
Si ce n'est pas le cas, exécutez la commande ci-dessous pour la définir sur une valeur connue et réessayez la construction :
|
||||
|
||||
```bash
|
||||
export PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring
|
||||
```
|
||||
|
||||
## Les sessions ne sont pas restaurées
|
||||
---
|
||||
### Les sessions ne sont pas restaurées
|
||||
|
||||
### Symptômes
|
||||
**Symptômes**
|
||||
|
||||
OpenHands demande généralement s'il faut reprendre ou commencer une nouvelle session lors de l'ouverture de l'interface utilisateur.
|
||||
Mais cliquer sur "Reprendre" démarre toujours une toute nouvelle discussion.
|
||||
OpenHands demande généralement s'il faut reprendre ou démarrer une nouvelle session lors de l'ouverture de l'interface utilisateur.
|
||||
Mais cliquer sur "Reprendre" démarre quand même un nouveau chat.
|
||||
|
||||
### Détails
|
||||
**Détails**
|
||||
|
||||
Avec une installation standard à ce jour, les données de session sont stockées en mémoire.
|
||||
Actuellement, si le service OpenHands est redémarré, les sessions précédentes deviennent
|
||||
invalides (un nouveau secret est généré) et donc non récupérables.
|
||||
Actuellement, si le service OpenHands est redémarré, les sessions précédentes deviennent invalides (un nouveau secret est généré) et donc non récupérables.
|
||||
|
||||
### Solutions de contournement
|
||||
**Solutions de contournement**
|
||||
|
||||
* Modifiez la configuration pour rendre les sessions persistantes en éditant le fichier `config.toml`
|
||||
(dans le dossier racine d'OpenHands) en spécifiant un `file_store` et un
|
||||
`file_store_path` absolu :
|
||||
* Modifiez la configuration pour rendre les sessions persistantes en éditant le fichier `config.toml` (dans le dossier racine d'OpenHands) en spécifiant un `file_store` et un `file_store_path` absolu :
|
||||
|
||||
```toml
|
||||
file_store="local"
|
||||
file_store_path="/absolute/path/to/openhands/cache/directory"
|
||||
```
|
||||
|
||||
* Ajoutez un secret jwt fixe dans votre .bashrc, comme ci-dessous, afin que les id de session précédents
|
||||
restent acceptés.
|
||||
* Ajoutez un secret jwt fixe dans votre .bashrc, comme ci-dessous, afin que les ID de session précédents restent acceptés.
|
||||
|
||||
```bash
|
||||
EXPORT JWT_SECRET=A_CONST_VALUE
|
||||
|
||||
@@ -1,49 +1,38 @@
|
||||
# Notes pour les utilisateurs de Windows et WSL
|
||||
|
||||
OpenHands ne supporte Windows que via [WSL](https://learn.microsoft.com/en-us/windows/wsl/install).
|
||||
Veuillez vous assurer de lancer toutes les commandes à l'intérieur de votre terminal WSL.
|
||||
|
||||
# Notes pour les utilisateurs de WSL sur Windows
|
||||
|
||||
OpenHands ne prend en charge Windows que via [WSL](https://learn.microsoft.com/en-us/windows/wsl/install).
|
||||
Veuillez vous assurer d'exécuter toutes les commandes dans votre terminal WSL.
|
||||
|
||||
## Dépannage
|
||||
|
||||
### Erreur : 'docker' n'a pas pu être trouvé dans cette distribution WSL 2.
|
||||
|
||||
Si vous utilisez Docker Desktop, assurez-vous de le démarrer avant d'exécuter toute commande docker depuis l'intérieur de WSL.
|
||||
Docker doit également avoir l'option d'intégration WSL activée.
|
||||
|
||||
### Recommandation : Ne pas exécuter en tant qu'utilisateur root
|
||||
|
||||
Pour des raisons de sécurité, il est fortement recommandé de ne pas exécuter OpenHands en tant qu'utilisateur root, mais en tant qu'utilisateur avec un UID non nul.
|
||||
De plus, les sandboxes persistants ne seront pas pris en charge lors de l'exécution en tant que root et un message approprié pourrait apparaître lors du démarrage d'OpenHands.
|
||||
|
||||
Références :
|
||||
|
||||
* [Pourquoi il est mauvais de se connecter en tant que root](https://askubuntu.com/questions/16178/why-is-it-bad-to-log-in-as-root)
|
||||
* [Définir l'utilisateur par défaut dans WSL](https://www.tenforums.com/tutorials/128152-set-default-user-windows-subsystem-linux-distro-windows-10-a.html#option2)
|
||||
Astuce pour la 2e référence : pour les utilisateurs d'Ubuntu, la commande pourrait en fait être "ubuntupreview" au lieu de "ubuntu".
|
||||
Astuce concernant la 2ème référence : pour les utilisateurs d'Ubuntu, la commande pourrait en fait être "ubuntupreview" au lieu de "ubuntu".
|
||||
|
||||
### Échec de la création de l'utilisateur openhands
|
||||
---
|
||||
### Erreur : 'docker' n'a pas pu être trouvé dans cette distribution WSL 2.
|
||||
|
||||
Si vous rencontrez l'erreur suivante lors de l'installation :
|
||||
|
||||
```sh
|
||||
Exception: Failed to create openhands user in sandbox: 'useradd: UID 0 is not unique'
|
||||
```
|
||||
|
||||
Vous pouvez la résoudre en exécutant :
|
||||
|
||||
```sh
|
||||
export SANDBOX_USER_ID=1000
|
||||
```
|
||||
Si vous utilisez Docker Desktop, assurez-vous de le démarrer avant d'appeler toute commande docker depuis WSL.
|
||||
Docker doit également avoir l'option d'intégration WSL activée.
|
||||
|
||||
---
|
||||
### Installation de Poetry
|
||||
|
||||
* Si vous rencontrez des problèmes pour exécuter Poetry même après l'avoir installé pendant le processus de construction, il peut être nécessaire d'ajouter son chemin binaire à votre environnement :
|
||||
* Si vous rencontrez des problèmes pour exécuter Poetry même après l'avoir installé pendant le processus de build, vous devrez peut-être ajouter son chemin binaire à votre environnement :
|
||||
|
||||
```sh
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
```
|
||||
|
||||
* Si `make build` s'arrête avec une erreur telle que :
|
||||
* Si make build s'arrête sur une erreur comme celle-ci :
|
||||
|
||||
```sh
|
||||
ModuleNotFoundError: no module named <module-name>
|
||||
@@ -57,9 +46,10 @@ rm -r ~/.cache/pypoetry
|
||||
make build
|
||||
```
|
||||
|
||||
---
|
||||
### L'objet NoneType n'a pas d'attribut 'request'
|
||||
|
||||
Si vous rencontrez des problèmes liés au réseau, tels que `NoneType object has no attribute 'request'` lors de l'exécution de `make run`, il peut être nécessaire de configurer vos paramètres réseau WSL2. Suivez ces étapes :
|
||||
Si vous rencontrez des problèmes liés au réseau, tels que `NoneType object has no attribute 'request'` lors de l'exécution de `make run`, vous devrez peut-être configurer les paramètres réseau de WSL2. Suivez ces étapes :
|
||||
|
||||
* Ouvrez ou créez le fichier `.wslconfig` situé à `C:\Users\%username%\.wslconfig` sur votre machine hôte Windows.
|
||||
* Ajoutez la configuration suivante au fichier `.wslconfig` :
|
||||
@@ -71,6 +61,6 @@ localhostForwarding=true
|
||||
```
|
||||
|
||||
* Enregistrez le fichier `.wslconfig`.
|
||||
* Redémarrez WSL2 complètement en quittant toute instance WSL2 en cours d'exécution et en exécutant la commande `wsl --shutdown` dans votre invite de commande ou terminal.
|
||||
* Après avoir redémarré WSL, essayez d'exécuter `make run` à nouveau.
|
||||
Le problème réseau devrait être résolu.
|
||||
* Redémarrez complètement WSL2 en quittant toutes les instances WSL2 en cours d'exécution et en exécutant la commande `wsl --shutdown` dans votre invite de commande ou terminal.
|
||||
* Après avoir redémarré WSL, essayez d'exécuter à nouveau `make run`.
|
||||
Le problème de réseau devrait être résolu.
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
|
||||
|
||||
# ⬆️ Guide de mise à niveau
|
||||
|
||||
## 0.8.0 (2024-07-13)
|
||||
|
||||
### Changements de configuration importants
|
||||
|
||||
Dans cette version, nous avons introduit quelques changements importants dans les configurations backend.
|
||||
Si vous avez uniquement utilisé OpenHands via l'interface frontend (interface web), aucune action n'est nécessaire.
|
||||
|
||||
Voici une liste des changements importants dans les configurations. Ils ne s'appliquent qu'aux utilisateurs qui
|
||||
utilisent OpenHands CLI via `main.py`. Pour plus de détails, voir [#2756](https://github.com/All-Hands-AI/OpenHands/pull/2756).
|
||||
|
||||
#### Suppression de l'option --model-name de main.py
|
||||
|
||||
Veuillez noter que l'option `--model-name`, ou `-m`, n'existe plus. Vous devez configurer les
|
||||
configurations LLM dans `config.toml` ou via des variables d'environnement.
|
||||
|
||||
#### Les groupes de configuration LLM doivent être des sous-groupes de 'llm'
|
||||
|
||||
Avant la version 0.8, vous pouviez utiliser un nom arbitraire pour la configuration LLM dans `config.toml`, par exemple :
|
||||
|
||||
```toml
|
||||
[gpt-4o]
|
||||
model="gpt-4o"
|
||||
api_key="<your_api_key>"
|
||||
```
|
||||
|
||||
puis utiliser l'argument CLI `--llm-config` pour spécifier le groupe de configuration LLM souhaité
|
||||
par nom. Cela ne fonctionne plus. Au lieu de cela, le groupe de configuration doit être sous le groupe `llm`,
|
||||
par exemple :
|
||||
|
||||
```toml
|
||||
[llm.gpt-4o]
|
||||
model="gpt-4o"
|
||||
api_key="<your_api_key>"
|
||||
```
|
||||
|
||||
Si vous avez un groupe de configuration nommé `llm`, il n'est pas nécessaire de le modifier, il sera utilisé
|
||||
comme groupe de configuration LLM par défaut.
|
||||
|
||||
#### Le groupe 'agent' ne contient plus le champ 'name'
|
||||
|
||||
Avant la version 0.8, vous pouviez avoir ou non un groupe de configuration nommé `agent` qui
|
||||
ressemblait à ceci :
|
||||
|
||||
```toml
|
||||
[agent]
|
||||
name="CodeActAgent"
|
||||
memory_max_threads=2
|
||||
```
|
||||
|
||||
Notez que le champ `name` est maintenant supprimé. Au lieu de cela, vous devez mettre le champ `default_agent`
|
||||
sous le groupe `core`, par exemple :
|
||||
|
||||
```toml
|
||||
[core]
|
||||
# autres configurations
|
||||
default_agent='CodeActAgent'
|
||||
|
||||
[agent]
|
||||
llm_config='llm'
|
||||
memory_max_threads=2
|
||||
|
||||
[agent.CodeActAgent]
|
||||
llm_config='gpt-4o'
|
||||
```
|
||||
|
||||
Notez que, comme pour les sous-groupes `llm`, vous pouvez également définir des sous-groupes `agent`.
|
||||
De plus, un agent peut être associé à un groupe de configuration LLM spécifique. Pour plus
|
||||
de détails, voir les exemples dans `config.template.toml`.
|
||||
@@ -1,3 +1,3 @@
|
||||
# Python 文档
|
||||
|
||||
部署后文档将会显示在这里。
|
||||
部署后文档将显示在此处。
|
||||
|
||||
@@ -1,53 +1,49 @@
|
||||
---
|
||||
sidebar_position: 7
|
||||
---
|
||||
|
||||
# 📚 杂项
|
||||
# 📚 其他
|
||||
|
||||
## ⭐️ 研究策略
|
||||
|
||||
通过 LLM 完全复制生产级应用程序是一个复杂的任务。我们的策略包含以下几个方面:
|
||||
使用大语言模型完全复制生产级应用程序是一项复杂的工作。我们的策略包括:
|
||||
|
||||
1. **核心技术研究:** 专注于基础研究,以理解和改进代码生成和处理的技术方面。
|
||||
2. **专家能力:** 通过数据策划、训练方法等方式增强核心组件的有效性。
|
||||
3. **任务规划:** 开发错误检测、代码库管理和优化的能力。
|
||||
4. **评价:** 建立全面的评价指标,以更好地理解和改进我们的模型。
|
||||
1. **核心技术研究:** 专注于基础研究,以理解和改进代码生成和处理的技术方面
|
||||
2. **专业能力:** 通过数据管理、训练方法等提高核心组件的效率
|
||||
3. **任务规划:** 开发错误检测、代码库管理和优化的能力
|
||||
4. **评估:** 建立全面的评估指标,以更好地理解和改进我们的模型
|
||||
|
||||
## 🚧 默认代理
|
||||
|
||||
- 我们当前的默认代理是 CodeActAgent,具备生成代码和处理文件的能力。我们正在开发其他代理实现,包括 [SWE Agent](https://swe-agent.com/)。您可以[在这里阅读我们当前的代理集合](./agents)。
|
||||
我们当前的默认代理是 [CodeActAgent](agents),它能够生成代码并处理文件。
|
||||
|
||||
## 🤝 如何贡献
|
||||
|
||||
OpenHands 是一个社区驱动的项目,我们欢迎每个人的贡献。无论您是开发人员、研究人员,还是对用 AI 提升软件工程领域有兴趣,只要您愿意参与,我们都有很多方式可供选择:
|
||||
OpenHands 是一个社区驱动的项目,我们欢迎每个人的贡献。无论你是开发人员、研究人员,还是只是对用 AI 推进软件工程领域感兴趣,都有很多方式可以参与:
|
||||
|
||||
- **代码贡献:** 帮助我们开发核心功能、前端界面或沙箱解决方案。
|
||||
- **研究和评价:** 贡献您对 LLM 在软件工程领域理解的见解,参与评估模型,或提出改进建议。
|
||||
- **反馈和测试:** 使用 OpenHands 工具集,报告错误,建议功能,或提供可用性方面的反馈。
|
||||
- **代码贡献:** 帮助我们开发核心功能、前端界面或沙盒解决方案
|
||||
- **研究和评估:** 为我们对大语言模型在软件工程中的应用的理解做出贡献,参与模型评估或提出改进建议
|
||||
- **反馈和测试:** 使用 OpenHands 工具集,报告错误,提出功能建议或提供可用性反馈
|
||||
|
||||
详情请查阅[此文件](https://github.com/All-Hands-AI/OpenHands/blob/main/CONTRIBUTING.md)。
|
||||
有关详细信息,请查看[此文档](https://github.com/All-Hands-AI/OpenHands/blob/main/CONTRIBUTING.md)。
|
||||
|
||||
## 🤖 加入我们的社区
|
||||
|
||||
我们现在有一个 Slack 工作区,用于合作建设 OpenHands,还设有一个 Discord 服务器,用于讨论与该项目、LLM、代理等相关的任何事情。
|
||||
我们有 Slack 工作区用于协作构建 OpenHands,也有 Discord 服务器用于讨论任何相关的内容,例如此项目、大语言模型、代理等。
|
||||
|
||||
- [Slack 工作区](https://join.slack.com/t/opendevin/shared_invite/zt-2oikve2hu-UDxHeo8nsE69y6T7yFX_BA)
|
||||
- [Discord 服务器](https://discord.gg/ESHStjSjD4)
|
||||
|
||||
如果您愿意贡献,请随时加入我们的社区。让我们一起简化软件工程!
|
||||
如果你想做出贡献,欢迎加入我们的社区。让我们一起简化软件工程!
|
||||
|
||||
🐚 **少写代码,用 OpenHands 做更多的事情。**
|
||||
🐚 **用 OpenHands 写更少的代码,做更多的事。**
|
||||
|
||||
[](https://star-history.com/#All-Hands-AI/OpenHands&Date)
|
||||
|
||||
## 🛠️ 技术选型
|
||||
## 🛠️ 构建技术
|
||||
|
||||
OpenHands 使用了一系列强大的框架和库,提供了坚实的开发基础。以下是项目中使用的关键技术:
|
||||
OpenHands 使用强大的框架和库组合构建,为其开发提供了坚实的基础。以下是项目中使用的关键技术:
|
||||
|
||||
       
|
||||
|
||||
请注意,这些技术选型仍在进行中,随着项目的发展,可能会添加新的技术或移除现有的技术。我们努力采用最适合、最高效的工具,以增强 OpenHands 的能力。
|
||||
请注意,这些技术的选择正在进行中,随着项目的发展,可能会添加其他技术或删除现有技术。我们努力采用最合适和最有效的工具来增强 OpenHands 的功能。
|
||||
|
||||
## 📜 许可证
|
||||
|
||||
根据 MIT 许可证分发。详见[我们的许可证](https://github.com/All-Hands-AI/OpenHands/blob/main/LICENSE)了解更多信息。
|
||||
根据 MIT 许可证分发。有关更多信息,请参阅[我们的许可证](https://github.com/All-Hands-AI/OpenHands/blob/main/LICENSE)。
|
||||
|
||||
@@ -1,98 +1,23 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
---
|
||||
# 🧠 主代理和能力
|
||||
|
||||
# 🧠 Agents and Capabilities
|
||||
|
||||
## CodeAct Agent
|
||||
## CodeActAgent
|
||||
|
||||
### 描述
|
||||
|
||||
该Agent实现了CodeAct的思想([论文](https://arxiv.org/abs/2402.01030),[推特](https://twitter.com/xingyaow_/status/1754556835703751087)),将LLM agents的**行为**合并到一个统一的**代码**动作空间中,以实现_简化_和_性能_(详情见论文)。
|
||||
这个代理实现了 CodeAct 的思想([论文](https://arxiv.org/abs/2402.01030),[推文](https://twitter.com/xingyaow_/status/1754556835703751087)),将 LLM 代理的**行动**整合到一个统一的**代码**行动空间中,以实现_简单性_和_性能_。
|
||||
|
||||
概念理念如下图所示。在每个回合,Agent可以:
|
||||
概念思想如下图所示。在每一轮中,代理可以:
|
||||
|
||||
1. **对话**:用自然语言与人类交流,进行澄清、确认等。
|
||||
2. **CodeAct**:选择通过执行代码来完成任务
|
||||
1. **对话**:用自然语言与人类交流,以寻求澄清、确认等。
|
||||
2. **CodeAct**:选择通过执行代码来执行任务
|
||||
|
||||
- 执行任何有效的Linux `bash`命令
|
||||
- 使用[交互式Python解释器](https://ipython.org/)执行任何有效的 `Python`代码。这是通过`bash`命令模拟的,详细信息请参见插件系统。
|
||||
- 执行任何有效的 Linux `bash` 命令
|
||||
- 使用 [交互式 Python 解释器](https://ipython.org/) 执行任何有效的 `Python` 代码。这是通过 `bash` 命令模拟的,有关更多详细信息,请参阅下面的插件系统。
|
||||
|
||||

|
||||
|
||||
### 插件系统
|
||||
|
||||
为了使CodeAct agent在仅能访问`bash`动作空间时更强大,CodeAct agent利用了OpenHands的插件系统:
|
||||
|
||||
- [Jupyter插件](https://github.com/All-Hands-AI/OpenHands/tree/main/openhands/runtime/plugins/jupyter):通过bash命令实现IPython执行
|
||||
- [SWE-agent工具插件](https://github.com/All-Hands-AI/OpenHands/tree/main/openhands/runtime/plugins/swe_agent_commands):为软件开发任务引入的强大bash命令行工具,由[swe-agent](https://github.com/princeton-nlp/swe-agent)提供。
|
||||
|
||||
### 演示
|
||||
|
||||
https://github.com/All-Hands-AI/OpenHands/assets/38853559/f592a192-e86c-4f48-ad31-d69282d5f6ac
|
||||
|
||||
_CodeActAgent使用`gpt-4-turbo-2024-04-09`执行数据科学任务(线性回归)的示例_
|
||||
|
||||
### 动作
|
||||
|
||||
`Action`,
|
||||
`CmdRunAction`,
|
||||
`IPythonRunCellAction`,
|
||||
`AgentEchoAction`,
|
||||
`AgentFinishAction`,
|
||||
`AgentTalkAction`
|
||||
|
||||
### 观测
|
||||
|
||||
`CmdOutputObservation`,
|
||||
`IPythonRunCellObservation`,
|
||||
`AgentMessageObservation`,
|
||||
`UserMessageObservation`
|
||||
|
||||
### 方法
|
||||
|
||||
| 方法 | 描述 |
|
||||
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `__init__` | 使用`llm`和一系列信息`list[Mapping[str, str]]`初始化Agent |
|
||||
| `step` | 使用CodeAct Agent执行一步操作,包括收集前一步的信息并提示模型执行命令。 |
|
||||
|
||||
### 进行中的工作 & 下一步
|
||||
|
||||
[] 支持Web浏览
|
||||
[] 完成CodeAct agent提交Github PR的工作流程
|
||||
|
||||
## Planner Agent
|
||||
|
||||
### 描述
|
||||
|
||||
Planner agent利用特殊的提示策略为解决问题创建长期计划。
|
||||
在每一步中,Agent会获得其先前的动作-观测对、当前任务以及基于上一次操作提供的提示。
|
||||
|
||||
### 动作
|
||||
|
||||
`NullAction`,
|
||||
`CmdRunAction`,
|
||||
`BrowseURLAction`,
|
||||
`GithubPushAction`,
|
||||
`FileReadAction`,
|
||||
`FileWriteAction`,
|
||||
`AgentThinkAction`,
|
||||
`AgentFinishAction`,
|
||||
`AgentSummarizeAction`,
|
||||
`AddTaskAction`,
|
||||
`ModifyTaskAction`
|
||||
|
||||
### 观测
|
||||
|
||||
`Observation`,
|
||||
`NullObservation`,
|
||||
`CmdOutputObservation`,
|
||||
`FileReadObservation`,
|
||||
`BrowserOutputObservation`
|
||||
|
||||
### 方法
|
||||
|
||||
| 方法 | 描述 |
|
||||
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `__init__` | 使用`llm`初始化Agent |
|
||||
| `step` | 检查当前步骤是否完成,如果是则返回`AgentFinishAction`。否则,创建计划提示并发送给模型进行推理,将结果作为下一步动作。 |
|
||||
_使用 `gpt-4-turbo-2024-04-09` 的 CodeActAgent 执行数据科学任务(线性回归)的示例_。
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
以下是翻译后的内容:
|
||||
|
||||
# 🏛️ 系统架构
|
||||
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<img src="https://github.com/All-Hands-AI/OpenHands/assets/16201837/97d747e3-29d8-4ccb-8d34-6ad1adb17f38" alt="OpenHands System Architecture Diagram Jul 4 2024" />
|
||||
<p><em>OpenHands 系统架构图 (2024年7月4日)</em></p>
|
||||
</div>
|
||||
|
||||
这是系统架构的高层次概述。系统分为两个主要组件:前端和后端。前端负责处理用户交互并显示结果。后端负责处理业务逻辑并执行代理。
|
||||
|
||||
# 前端架构 {#frontend-architecture-zh}
|
||||
|
||||

|
||||
|
||||
这个概述经过简化,只显示了主要组件及其交互。有关后端架构的更详细视图,请参阅下面的后端架构部分。
|
||||
|
||||
# 后端架构 {#backend-architecture-zh}
|
||||
|
||||
_**免责声明**:后端架构正在进行中,可能会发生变化。下图显示了基于图表页脚中显示的提交的后端当前架构。_
|
||||
|
||||

|
||||
|
||||
<details>
|
||||
<summary>更新此图表</summary>
|
||||
<div>
|
||||
后端架构图的生成是部分自动化的。
|
||||
该图是使用py2puml工具从代码中的类型提示生成的。然后手动审查、调整图表并导出为PNG和SVG格式。
|
||||
|
||||
## 先决条件
|
||||
|
||||
- 运行可执行openhands的python环境
|
||||
(根据存储库根目录中README.md文件中的说明)
|
||||
- 已安装[py2puml](https://github.com/lucsorel/py2puml)
|
||||
|
||||
## 步骤
|
||||
|
||||
1. 通过从存储库的根目录运行以下命令来自动生成图表:
|
||||
`py2puml openhands openhands > docs/architecture/backend_architecture.puml`
|
||||
|
||||
2. 在PlantUML编辑器中打开生成的文件,例如带有PlantUML扩展的Visual Studio Code或[PlantText](https://www.planttext.com/)
|
||||
|
||||
3. 审查生成的PUML,并对图表进行所有必要的调整(添加缺失的部分,修复错误,改进定位)。
|
||||
_py2puml根据代码中的类型提示创建图表,因此缺失或不正确的类型提示可能导致图表不完整或不正确。_
|
||||
|
||||
4. 审查新图表和以前图表之间的差异,并手动检查更改是否正确。
|
||||
_确保不要删除过去手动添加到图表中且仍然相关的部分。_
|
||||
|
||||
5. 将用于生成图表的提交的提交哈希添加到图表页脚。
|
||||
|
||||
6. 将图表导出为PNG和SVG文件,并替换`docs/architecture`目录中的现有图表。这可以使用(例如[PlantText](https://www.planttext.com/))完成
|
||||
|
||||
</div>
|
||||
</details>
|
||||
@@ -0,0 +1,131 @@
|
||||
以下是翻译后的内容:
|
||||
|
||||
# 📦 EventStream 运行时
|
||||
|
||||
OpenHands EventStream 运行时是实现 AI 代理操作安全灵活执行的核心组件。
|
||||
它使用 Docker 创建一个沙盒环境,可以安全地运行任意代码而不会危及主机系统。
|
||||
|
||||
## 为什么我们需要沙盒运行时?
|
||||
|
||||
OpenHands 需要在安全、隔离的环境中执行任意代码,原因如下:
|
||||
|
||||
1. 安全性:执行不受信任的代码可能会给主机系统带来重大风险。沙盒环境可以防止恶意代码访问或修改主机系统的资源
|
||||
2. 一致性:沙盒环境确保代码执行在不同机器和设置下保持一致,消除"在我的机器上可以工作"的问题
|
||||
3. 资源控制:沙盒允许更好地控制资源分配和使用,防止失控进程影响主机系统
|
||||
4. 隔离:不同的项目或用户可以在隔离的环境中工作,而不会相互干扰或影响主机系统
|
||||
5. 可重现性:沙盒环境使重现错误和问题变得更容易,因为执行环境是一致和可控的
|
||||
|
||||
## 运行时如何工作?
|
||||
|
||||
OpenHands 运行时系统使用 Docker 容器实现的客户端-服务器架构。以下是它的工作原理概述:
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[用户提供的自定义 Docker 镜像] --> B[OpenHands 后端]
|
||||
B -->|构建| C[OH 运行时镜像]
|
||||
C -->|启动| D[Action 执行器]
|
||||
D -->|初始化| E[浏览器]
|
||||
D -->|初始化| F[Bash Shell]
|
||||
D -->|初始化| G[插件]
|
||||
G -->|初始化| L[Jupyter 服务器]
|
||||
|
||||
B -->|生成| H[代理]
|
||||
B -->|生成| I[EventStream]
|
||||
I <--->|通过 REST API
|
||||
执行 Action 获取 Observation
|
||||
| D
|
||||
|
||||
H -->|生成 Action| I
|
||||
I -->|获取 Observation| H
|
||||
|
||||
subgraph "Docker 容器"
|
||||
D
|
||||
E
|
||||
F
|
||||
G
|
||||
L
|
||||
end
|
||||
```
|
||||
|
||||
1. 用户输入:用户提供自定义基础 Docker 镜像
|
||||
2. 镜像构建:OpenHands 基于用户提供的镜像构建新的 Docker 镜像("OH 运行时镜像")。这个新镜像包含 OpenHands 特定的代码,主要是"运行时客户端"
|
||||
3. 容器启动:当 OpenHands 启动时,它使用 OH 运行时镜像启动一个 Docker 容器
|
||||
4. Action 执行服务器初始化:Action 执行服务器在容器内初始化一个 `ActionExecutor`,设置必要的组件,如 bash shell,并加载任何指定的插件
|
||||
5. 通信:OpenHands 后端(`openhands/runtime/impl/eventstream/eventstream_runtime.py`)通过 RESTful API 与 Action 执行服务器通信,发送 Action 并接收 Observation
|
||||
6. Action 执行:运行时客户端从后端接收 Action,在沙盒环境中执行它们,并将 Observation 发送回去
|
||||
7. Observation 返回:Action 执行服务器将执行结果作为 Observation 发送回 OpenHands 后端
|
||||
|
||||
客户端的作用:
|
||||
- 它充当 OpenHands 后端和沙盒环境之间的中介
|
||||
- 它在容器内安全地执行各种类型的 Action(shell 命令、文件操作、Python 代码等)
|
||||
- 它管理沙盒环境的状态,包括当前工作目录和加载的插件
|
||||
- 它格式化 Observation 并将其返回给后端,确保处理结果的接口一致
|
||||
|
||||
## OpenHands 如何构建和维护 OH 运行时镜像
|
||||
|
||||
OpenHands 构建和管理运行时镜像的方法确保了在为生产和开发环境创建和维护 Docker 镜像时的效率、一致性和灵活性。
|
||||
|
||||
如果你对更多细节感兴趣,可以查看[相关代码](https://github.com/All-Hands-AI/OpenHands/blob/main/openhands/runtime/utils/runtime_build.py)。
|
||||
|
||||
### 镜像标签系统
|
||||
|
||||
OpenHands 为其运行时镜像使用三标签系统,以平衡可重现性和灵活性。
|
||||
标签可以是以下 2 种格式之一:
|
||||
|
||||
- **版本标签**: `oh_v{openhands_version}_{base_image}` (例如: `oh_v0.9.9_nikolaik_s_python-nodejs_t_python3.12-nodejs22`)
|
||||
- **锁定标签**: `oh_v{openhands_version}_{16_digit_lock_hash}` (例如: `oh_v0.9.9_1234567890abcdef`)
|
||||
- **源码标签**: `oh_v{openhands_version}_{16_digit_lock_hash}_{16_digit_source_hash}`
|
||||
(例如: `oh_v0.9.9_1234567890abcdef_1234567890abcdef`)
|
||||
|
||||
#### 源码标签 - 最具体
|
||||
|
||||
这是源目录的目录哈希的 MD5 的前 16 位数字。这为 openhands 源码提供了一个哈希值。
|
||||
|
||||
#### 锁定标签
|
||||
|
||||
这个哈希由以下内容的 MD5 的前 16 位数字构建:
|
||||
- 构建镜像所基于的基础镜像的名称(例如: `nikolaik/python-nodejs:python3.12-nodejs22`)
|
||||
- 镜像中包含的 `pyproject.toml` 的内容
|
||||
- 镜像中包含的 `poetry.lock` 的内容
|
||||
|
||||
这实际上为 Openhands 的依赖项提供了一个独立于源代码的哈希值。
|
||||
|
||||
#### 版本标签 - 最通用
|
||||
|
||||
这个标签是 openhands 版本和基础镜像名称的串联(转换以适应标签标准)。
|
||||
|
||||
#### 构建过程
|
||||
|
||||
在生成镜像时...
|
||||
|
||||
- **无需重建**:OpenHands 首先检查是否存在具有相同**最具体源码标签**的镜像。如果存在这样的镜像,
|
||||
则不执行构建 - 使用现有镜像。
|
||||
- **最快重建**:OpenHands 接下来检查是否存在具有**通用锁定标签**的镜像。如果存在这样的镜像,
|
||||
OpenHands 会基于它构建一个新镜像,绕过所有安装步骤(如 `poetry install` 和
|
||||
`apt-get`),除了最后一个复制当前源代码的操作。新镜像仅使用**源码**标签。
|
||||
- **还行的重建**:如果**源码**和**锁定**标签都不存在,将基于**版本**标签镜像构建镜像。
|
||||
在版本标签镜像中,大多数依赖项应该已经安装,从而节省时间。
|
||||
- **最慢重建**:如果三个标签都不存在,则基于基础镜像构建全新的镜像
|
||||
(这是一个较慢的操作)。这个新镜像使用**源码**、**锁定**和**版本**标签。
|
||||
|
||||
这种标记方法允许 OpenHands 高效地管理开发和生产环境。
|
||||
|
||||
1. 相同的源代码和 Dockerfile 总是产生相同的镜像(通过基于哈希的标签)
|
||||
2. 当发生小的更改时,系统可以快速重建镜像(通过利用最近兼容的镜像)
|
||||
3. **锁定**标签(例如: `runtime:oh_v0.9.3_1234567890abcdef`)总是指向特定基础镜像、依赖项和 OpenHands 版本组合的最新构建
|
||||
|
||||
## 运行时插件系统
|
||||
|
||||
OpenHands 运行时支持一个插件系统,允许扩展功能和自定义运行时环境。插件在运行时客户端启动时初始化。
|
||||
|
||||
如果你想实现自己的插件,可以查看[这里的 Jupyter 插件示例](https://github.com/All-Hands-AI/OpenHands/blob/ecf4aed28b0cf7c18d4d8ff554883ba182fc6bdd/openhands/runtime/plugins/jupyter/__init__.py#L21-L55)。
|
||||
|
||||
*关于插件系统的更多细节仍在建设中 - 欢迎贡献!*
|
||||
|
||||
插件系统的关键方面:
|
||||
|
||||
1. 插件定义:插件被定义为继承自基础 `Plugin` 类的 Python 类
|
||||
2. 插件注册:可用的插件在 `ALL_PLUGINS` 字典中注册
|
||||
3. 插件规范:插件与 `Agent.sandbox_plugins: list[PluginRequirement]` 相关联。用户可以在初始化运行时时指定要加载的插件
|
||||
4. 初始化:插件在运行时客户端启动时异步初始化
|
||||
5. 使用:运行时客户端可以使用初始化的插件来扩展其功能(例如,用于运行 IPython 单元格的 JupyterPlugin)
|
||||
@@ -1,18 +1,39 @@
|
||||
---
|
||||
sidebar_position: 6
|
||||
---
|
||||
|
||||
# ✅ 提供反馈
|
||||
|
||||
在使用 OpenHands 时,你无疑会遇到一些情况,某些地方工作得很好,而另一些地方则可能不尽如人意。我们鼓励你在使用 OpenHands 时提供反馈,这不仅有助于开发团队改善应用,更为重要的是,可以创建一个开放的编码代理训练样例语料库——Share-OpenHands!
|
||||
在使用 OpenHands 时,您会遇到一些工作良好的情况,也会遇到一些不太理想的情况。我们鼓励您在使用 OpenHands 时提供反馈,以帮助向开发团队提供反馈,更重要的是,创建一个开放的编码智能体训练示例语料库——Share-OpenHands!
|
||||
|
||||
## 📝 如何提供反馈
|
||||
|
||||
提供反馈很简单!在使用 OpenHands 时,你可以在任意时刻按下点赞或点踩按钮。你将被要求提供你的电子邮件地址(例如,以便我们在需要进一步询问时联系你),你可以选择公开或私密地提供反馈。
|
||||
提供反馈很容易!当您在使用 OpenHands 时,您可以在交互的任何时候按下竖起大拇指或竖起大拇指按钮。系统会提示您提供电子邮件地址(例如,以便我们在需要询问任何后续问题时与您联系),您可以选择公开或私下提供反馈。
|
||||
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/5rFx-StMVV0?si=svo7xzp6LhGK_GXr" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
|
||||
|
||||
## 📜 数据许可与隐私
|
||||
## 📜 数据使用和隐私
|
||||
|
||||
* **公开** 数据将与 OpenHands 本身一样以 MIT 许可协议发布,并可被社区用来训练和测试模型。显然,你能够公开的反馈对整个社区来说更有价值,因此当你不涉及敏感信息时,我们鼓励你选择这个选项!
|
||||
* **私密** 数据将仅与 OpenHands 团队分享,用于改进 OpenHands。
|
||||
### 数据共享设置
|
||||
|
||||
在提交数据时,您可以选择公开或私下提交。
|
||||
|
||||
* **公开**数据将在 MIT 许可下发布,与 OpenHands 本身一样,社区可以使用这些数据来训练和测试模型。显然,您可以公开的反馈对整个社区来说会更有价值,因此当您不处理敏感信息时,我们鼓励您选择这个选项!
|
||||
* **私有**数据将仅与 OpenHands 团队共享,用于改进 OpenHands。
|
||||
|
||||
### 谁收集和存储数据?
|
||||
|
||||
数据由 [All Hands AI](https://all-hands.dev) 收集和存储,这是一家由 OpenHands 维护者创立的公司,旨在支持和改进 OpenHands。
|
||||
|
||||
### 公开数据将如何发布?
|
||||
|
||||
公开数据将在我们达到固定的里程碑时发布,例如 1,000 个公开示例、10,000 个公开示例等。
|
||||
届时,我们将遵循以下发布流程:
|
||||
|
||||
1. 所有提供公开反馈的人都将收到一封电子邮件,描述数据发布情况,并有机会选择退出。
|
||||
2. 负责数据发布的人员将对数据进行质量控制,删除低质量的反馈,删除提交者的电子邮件地址,并尝试删除任何敏感信息。
|
||||
3. 数据将通过 github 或 Hugging Face 等常用网站在 MIT 许可下公开发布。
|
||||
|
||||
### 如果我想删除我的数据怎么办?
|
||||
|
||||
对于 All Hands AI 服务器上的数据,我们很乐意根据要求删除它:
|
||||
|
||||
**一条数据:**如果您想删除一条数据,我们将很快添加一种机制,使用您在提交数据时显示在界面上的链接和密码来删除数据。
|
||||
|
||||
**所有数据:**如果您想删除所有数据,或者您没有在提交数据时收到的 ID 和密码,请从您最初提交数据时注册的电子邮件地址联系`contact@all-hands.dev`。
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
# OpenHands 入门指南
|
||||
|
||||
你已经[安装了 OpenHands](./installation)并且[设置了你的 LLM](./installation#setup)。接下来呢?
|
||||
|
||||
OpenHands 可以帮助你处理各种各样的工程任务。但这项技术仍然很新,我们还有很长的路要走,才能拥有无需任何指导就能承担大型、复杂工程任务的智能体。因此,了解智能体擅长什么,以及可能需要什么帮助非常重要。
|
||||
|
||||
## Hello World
|
||||
|
||||
你可能想尝试的第一件事是一个简单的 "hello world" 示例。这听起来可能比实际操作更复杂!
|
||||
|
||||
尝试提示智能体:
|
||||
> 请编写一个 bash 脚本 hello.sh,打印 "hello world!"
|
||||
|
||||
你会发现,智能体不仅编写了脚本,还设置了正确的权限并运行脚本来检查输出。
|
||||
|
||||
你可以继续提示智能体优化你的代码。这是一个与智能体合作的好方法。从简单开始,然后迭代。
|
||||
|
||||
> 请修改 hello.sh,使其接受一个名称作为第一个参数,但默认为 "world"
|
||||
|
||||
你也可以使用任何你需要的语言,尽管智能体可能需要花一些时间来设置环境!
|
||||
|
||||
> 请将 hello.sh 转换为 Ruby 脚本,并运行它
|
||||
|
||||
## 从头开始构建
|
||||
|
||||
智能体在 "绿地" 任务(不需要任何关于现有代码库的上下文的任务)上表现得非常出色,它们可以从头开始。
|
||||
|
||||
最好从一个简单的任务开始,然后迭代它。同时也最好尽可能具体地说明你想要什么,技术栈应该是什么等等。
|
||||
|
||||
例如,我们可以构建一个 TODO 应用:
|
||||
|
||||
> 请用 React 构建一个基本的 TODO 列表应用。它应该只有前端,所有状态都应该保存在 localStorage 中。
|
||||
|
||||
一旦骨架搭建好,我们就可以继续迭代应用:
|
||||
|
||||
> 请允许为每个任务添加一个可选的截止日期
|
||||
|
||||
就像普通开发一样,经常提交和推送代码是一个好习惯。这样,如果智能体偏离了轨道,你总是可以恢复到旧的状态。你可以让智能体为你提交和推送:
|
||||
|
||||
> 请提交更改并将其推送到一个名为 "feature/due-dates" 的新分支
|
||||
|
||||
## 添加新代码
|
||||
|
||||
OpenHands 也可以很好地向现有代码库添加新代码。
|
||||
|
||||
例如,你可以要求 OpenHands 向你的项目添加一个新的 GitHub action,用于检查你的代码。OpenHands 可能会查看你的代码库,看看它应该使用什么语言,然后它可以直接将一个新文件放入 `./github/workflows/lint.yml`
|
||||
|
||||
> 请添加一个 GitHub action 来检查此仓库中的代码
|
||||
|
||||
有些任务可能需要更多的上下文。虽然 OpenHands 可以使用 `ls` 和 `grep` 来搜索你的代码库,但提前提供上下文可以让它移动得更快、更准确。而且这会让你花费更少的 tokens!
|
||||
|
||||
> 请修改 ./backend/api/routes.js 以添加一个新路由,返回所有任务的列表
|
||||
|
||||
> 请在 ./frontend/components 目录中添加一个新的 React 组件,用于显示 Widgets 列表。它应该使用现有的 Widget 组件。
|
||||
|
||||
## 重构
|
||||
|
||||
OpenHands 在重构现有代码方面做得很好,尤其是小块的重构。你可能不想尝试重新设计整个代码库,但拆分长文件和函数、重命名变量等往往效果很好。
|
||||
|
||||
> 请重命名 ./app.go 中所有单字母变量
|
||||
|
||||
> 请在 widget.php 中将函数 `build_and_deploy_widgets` 拆分为两个函数:`build_widgets` 和 `deploy_widgets`
|
||||
|
||||
> 请将 ./api/routes.js 拆分为每个路由的单独文件
|
||||
|
||||
## Bug 修复
|
||||
|
||||
OpenHands 还可以帮助你跟踪和修复代码中的 bug。但是,正如任何开发人员都知道的那样,修复 bug 可能非常棘手,OpenHands 通常需要更多的上下文。如果你已经诊断出了 bug,但希望 OpenHands 来解决逻辑问题,这会有所帮助。
|
||||
|
||||
> 目前 `/subscribe` 端点中的 email 字段正在拒绝 .io 域名。请修复这个问题。
|
||||
|
||||
> ./app.py 中的 `search_widgets` 函数正在执行区分大小写的搜索。请使其不区分大小写。
|
||||
|
||||
在使用智能体修复 bug 时,进行测试驱动开发通常很有帮助。你可以要求智能体编写一个新的测试,然后迭代直到它修复了 bug:
|
||||
|
||||
> `hello` 函数在空字符串上崩溃。请编写一个测试来重现这个 bug,然后修复代码,使其通过测试。
|
||||
|
||||
## 更多
|
||||
|
||||
OpenHands 能够在几乎任何编码任务上提供帮助。但是需要一些练习才能充分利用它。请记住:
|
||||
* 保持任务简单
|
||||
* 尽可能具体
|
||||
* 提供尽可能多的上下文
|
||||
* 经常提交和推送
|
||||
|
||||
有关如何充分利用 OpenHands 的更多提示,请参阅[提示最佳实践](./prompting-best-practices)。
|
||||
@@ -0,0 +1,109 @@
|
||||
以下是翻译后的内容:
|
||||
|
||||
# 命令行模式
|
||||
|
||||
OpenHands 可以在交互式命令行模式下运行,允许用户通过命令行启动交互式会话。
|
||||
|
||||
这种模式不同于[无头模式](headless-mode),后者是非交互式的,更适合脚本编写。
|
||||
|
||||
## 使用 Python
|
||||
|
||||
要通过命令行启动交互式 OpenHands 会话,请按照以下步骤操作:
|
||||
|
||||
1. 确保你已按照[开发设置说明](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md)进行操作。
|
||||
|
||||
2. 运行以下命令:
|
||||
|
||||
```bash
|
||||
poetry run python -m openhands.core.cli
|
||||
```
|
||||
|
||||
该命令将启动一个交互式会话,你可以在其中输入任务并接收来自 OpenHands 的响应。
|
||||
|
||||
你需要确保通过环境变量[或 `config.toml` 文件](https://github.com/All-Hands-AI/OpenHands/blob/main/config.template.toml)设置你的模型、API 密钥和其他设置。
|
||||
|
||||
|
||||
## 使用 Docker
|
||||
|
||||
要在 Docker 中以命令行模式运行 OpenHands,请按照以下步骤操作:
|
||||
|
||||
1. 将 `WORKSPACE_BASE` 设置为你希望 OpenHands 编辑的目录:
|
||||
|
||||
```bash
|
||||
WORKSPACE_BASE=$(pwd)/workspace
|
||||
```
|
||||
|
||||
2. 将 `LLM_MODEL` 设置为你要使用的模型:
|
||||
|
||||
```bash
|
||||
LLM_MODEL="anthropic/claude-3-5-sonnet-20241022"
|
||||
```
|
||||
|
||||
3. 将 `LLM_API_KEY` 设置为你的 API 密钥:
|
||||
|
||||
```bash
|
||||
LLM_API_KEY="sk_test_12345"
|
||||
```
|
||||
|
||||
4. 运行以下 Docker 命令:
|
||||
|
||||
```bash
|
||||
docker run -it \
|
||||
--pull=always \
|
||||
-e SANDBOX_USER_ID=$(id -u) \
|
||||
-e WORKSPACE_MOUNT_PATH=$WORKSPACE_BASE \
|
||||
-e LLM_API_KEY=$LLM_API_KEY \
|
||||
-e LLM_MODEL=$LLM_MODEL \
|
||||
-v $WORKSPACE_BASE:/opt/workspace_base \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
--add-host host.docker.internal:host-gateway \
|
||||
--name openhands-app-$(date +%Y%m%d%H%M%S) \
|
||||
ghcr.io/all-hands-ai/openhands:0.11 \
|
||||
python -m openhands.core.cli
|
||||
```
|
||||
|
||||
该命令将在 Docker 中启动一个交互式会话,你可以在其中输入任务并接收来自 OpenHands 的响应。
|
||||
|
||||
## 命令行命令和预期输出示例
|
||||
|
||||
以下是一些命令行命令及其预期输出的示例:
|
||||
|
||||
### 示例 1: 简单任务
|
||||
|
||||
```bash
|
||||
How can I help? >> Write a Python script that prints "Hello, World!"
|
||||
```
|
||||
|
||||
预期输出:
|
||||
|
||||
```bash
|
||||
🤖 Sure! Here is a Python script that prints "Hello, World!":
|
||||
|
||||
❯ print("Hello, World!")
|
||||
```
|
||||
|
||||
### 示例 2: Bash 命令
|
||||
|
||||
```bash
|
||||
How can I help? >> Create a directory named "test_dir"
|
||||
```
|
||||
|
||||
预期输出:
|
||||
|
||||
```bash
|
||||
🤖 Creating a directory named "test_dir":
|
||||
|
||||
❯ mkdir test_dir
|
||||
```
|
||||
|
||||
### 示例 3: 错误处理
|
||||
|
||||
```bash
|
||||
How can I help? >> Delete a non-existent file
|
||||
```
|
||||
|
||||
预期输出:
|
||||
|
||||
```bash
|
||||
🤖 An error occurred. Please try again.
|
||||
```
|
||||
@@ -0,0 +1,81 @@
|
||||
# 自定义沙箱
|
||||
|
||||
沙箱是代理执行任务的地方。代理不是直接在你的计算机上运行命令(这可能有风险),而是在 Docker 容器内运行。
|
||||
|
||||
默认的 OpenHands 沙箱(来自 [nikolaik/python-nodejs](https://hub.docker.com/r/nikolaik/python-nodejs) 的 `python-nodejs:python3.12-nodejs22`)预装了一些软件包,如 Python 和 Node.js,但可能需要默认安装其他软件。
|
||||
|
||||
你有两个自定义选项:
|
||||
|
||||
1. 使用已有的镜像,其中包含所需的软件。
|
||||
2. 创建你自己的自定义 Docker 镜像。
|
||||
|
||||
如果你选择第一个选项,可以跳过"创建你的 Docker 镜像"部分。
|
||||
|
||||
## 创建你的 Docker 镜像
|
||||
|
||||
要创建自定义 Docker 镜像,它必须基于 Debian。
|
||||
|
||||
例如,如果你想让 OpenHands 安装 `ruby`,创建一个包含以下内容的 `Dockerfile`:
|
||||
|
||||
```dockerfile
|
||||
FROM debian:latest
|
||||
|
||||
# Install required packages
|
||||
RUN apt-get update && apt-get install -y ruby
|
||||
```
|
||||
|
||||
将此文件保存在一个文件夹中。然后,通过在终端中导航到该文件夹并运行以下命令来构建你的 Docker 镜像(例如,名为 custom-image):
|
||||
|
||||
```bash
|
||||
docker build -t custom-image .
|
||||
```
|
||||
|
||||
这将生成一个名为 `custom-image` 的新镜像,该镜像将在 Docker 中可用。
|
||||
|
||||
> 请注意,在本文档描述的配置中,OpenHands 将以用户 "openhands" 的身份在沙箱内运行,因此通过 docker 文件安装的所有软件包应该对系统上的所有用户可用,而不仅仅是 root。
|
||||
|
||||
## 使用开发工作流
|
||||
|
||||
### 设置
|
||||
|
||||
首先,按照 [Development.md](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md) 中的说明确保你可以运行 OpenHands。
|
||||
|
||||
### 指定基础沙箱镜像
|
||||
|
||||
在 OpenHands 目录中的 `config.toml` 文件中,将 `sandbox_base_container_image` 设置为你要使用的镜像。这可以是你已经拉取的镜像或你构建的镜像:
|
||||
|
||||
```bash
|
||||
[core]
|
||||
...
|
||||
sandbox_base_container_image="custom-image"
|
||||
```
|
||||
|
||||
### 运行
|
||||
|
||||
通过在顶层目录中运行 ```make run``` 来运行 OpenHands。
|
||||
|
||||
## 技术解释
|
||||
|
||||
请参阅[运行时文档的自定义 docker 镜像部分](https://docs.all-hands.dev/modules/usage/architecture/runtime#advanced-how-openhands-builds-and-maintains-od-runtime-images)以获取更多详细信息。
|
||||
|
||||
## 故障排除/错误
|
||||
|
||||
### 错误:```useradd: UID 1000 is not unique```
|
||||
|
||||
如果你在控制台输出中看到此错误,是因为 OpenHands 试图在沙箱中创建 UID 为 1000 的 openhands 用户,但此 UID 已在镜像中使用(出于某种原因)。要解决此问题,请将 config.toml 文件中的 sandbox_user_id 字段更改为其他值:
|
||||
|
||||
```toml
|
||||
[core]
|
||||
workspace_base="./workspace"
|
||||
run_as_openhands=true
|
||||
sandbox_base_container_image="custom_image"
|
||||
sandbox_user_id="1001"
|
||||
```
|
||||
|
||||
### 端口使用错误
|
||||
|
||||
如果你看到有关端口正在使用或不可用的错误,请尝试删除所有正在运行的 Docker 容器(运行 `docker ps` 和 `docker rm` 相关容器),然后重新运行 ```make run```。
|
||||
|
||||
## 讨论
|
||||
|
||||
对于其他问题或疑问,请加入 [Slack](https://join.slack.com/t/opendevin/shared_invite/zt-2oikve2hu-UDxHeo8nsE69y6T7yFX_BA) 或 [Discord](https://discord.gg/ESHStjSjD4) 并提问!
|
||||
@@ -0,0 +1,73 @@
|
||||
以下是翻译后的内容:
|
||||
|
||||
# 调试
|
||||
|
||||
以下内容旨在作为开发目的下调试 OpenHands 的入门指南。
|
||||
|
||||
## 服务器 / VSCode
|
||||
|
||||
以下 `launch.json` 将允许调试 agent、controller 和 server 元素,但不包括 sandbox(它运行在 docker 内)。它将忽略 `workspace/` 目录内的任何更改:
|
||||
|
||||
```
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "OpenHands CLI",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"module": "openhands.core.cli",
|
||||
"justMyCode": false
|
||||
},
|
||||
{
|
||||
"name": "OpenHands WebApp",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"module": "uvicorn",
|
||||
"args": [
|
||||
"openhands.server.listen:app",
|
||||
"--reload",
|
||||
"--reload-exclude",
|
||||
"${workspaceFolder}/workspace",
|
||||
"--port",
|
||||
"3000"
|
||||
],
|
||||
"justMyCode": false
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
可以指定更具体的调试配置,其中包括更多参数:
|
||||
|
||||
```
|
||||
...
|
||||
{
|
||||
"name": "Debug CodeAct",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"module": "openhands.core.main",
|
||||
"args": [
|
||||
"-t",
|
||||
"Ask me what your task is.",
|
||||
"-d",
|
||||
"${workspaceFolder}/workspace",
|
||||
"-c",
|
||||
"CodeActAgent",
|
||||
"-l",
|
||||
"llm.o1",
|
||||
"-n",
|
||||
"prompts"
|
||||
],
|
||||
"justMyCode": false
|
||||
}
|
||||
...
|
||||
```
|
||||
|
||||
上面代码片段中的值可以更新,例如:
|
||||
|
||||
* *t*: 任务
|
||||
* *d*: openhands 工作区目录
|
||||
* *c*: agent
|
||||
* *l*: LLM 配置 (在 config.toml 中预定义)
|
||||
* *n*: 会话名称 (例如 eventstream 名称)
|
||||
@@ -0,0 +1,278 @@
|
||||
# 评估
|
||||
|
||||
本指南概述了如何将您自己的评估基准集成到 OpenHands 框架中。
|
||||
|
||||
## 设置环境和 LLM 配置
|
||||
|
||||
请按照[此处](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md)的说明设置您的本地开发环境。
|
||||
开发模式下的 OpenHands 使用 `config.toml` 来跟踪大多数配置。
|
||||
|
||||
以下是一个示例配置文件,您可以使用它来定义和使用多个 LLM:
|
||||
|
||||
```toml
|
||||
[llm]
|
||||
# 重要:在此处添加您的 API 密钥,并将模型设置为您要评估的模型
|
||||
model = "claude-3-5-sonnet-20241022"
|
||||
api_key = "sk-XXX"
|
||||
|
||||
[llm.eval_gpt4_1106_preview_llm]
|
||||
model = "gpt-4-1106-preview"
|
||||
api_key = "XXX"
|
||||
temperature = 0.0
|
||||
|
||||
[llm.eval_some_openai_compatible_model_llm]
|
||||
model = "openai/MODEL_NAME"
|
||||
base_url = "https://OPENAI_COMPATIBLE_URL/v1"
|
||||
api_key = "XXX"
|
||||
temperature = 0.0
|
||||
```
|
||||
|
||||
|
||||
## 如何在命令行中使用 OpenHands
|
||||
|
||||
可以使用以下格式从命令行运行 OpenHands:
|
||||
|
||||
```bash
|
||||
poetry run python ./openhands/core/main.py \
|
||||
-i <max_iterations> \
|
||||
-t "<task_description>" \
|
||||
-c <agent_class> \
|
||||
-l <llm_config>
|
||||
```
|
||||
|
||||
例如:
|
||||
|
||||
```bash
|
||||
poetry run python ./openhands/core/main.py \
|
||||
-i 10 \
|
||||
-t "Write me a bash script that prints hello world." \
|
||||
-c CodeActAgent \
|
||||
-l llm
|
||||
```
|
||||
|
||||
此命令使用以下参数运行 OpenHands:
|
||||
- 最大迭代次数为 10
|
||||
- 指定的任务描述
|
||||
- 使用 CodeActAgent
|
||||
- 使用 `config.toml` 文件的 `llm` 部分中定义的 LLM 配置
|
||||
|
||||
## OpenHands 如何工作
|
||||
|
||||
OpenHands 的主要入口点在 `openhands/core/main.py` 中。以下是它工作原理的简化流程:
|
||||
|
||||
1. 解析命令行参数并加载配置
|
||||
2. 使用 `create_runtime()` 创建运行时环境
|
||||
3. 初始化指定的代理
|
||||
4. 使用 `run_controller()` 运行控制器,它:
|
||||
- 将运行时附加到代理
|
||||
- 执行代理的任务
|
||||
- 完成后返回最终状态
|
||||
|
||||
`run_controller()` 函数是 OpenHands 执行的核心。它管理代理、运行时和任务之间的交互,处理用户输入模拟和事件处理等事项。
|
||||
|
||||
|
||||
## 入门最简单的方法:探索现有基准
|
||||
|
||||
我们鼓励您查看我们仓库的 [`evaluation/` 目录](https://github.com/All-Hands-AI/OpenHands/blob/main/evaluation)中提供的各种评估基准。
|
||||
|
||||
要集成您自己的基准,我们建议从最接近您需求的基准开始。这种方法可以显著简化您的集成过程,允许您在现有结构的基础上进行构建并使其适应您的特定要求。
|
||||
|
||||
## 如何创建评估工作流
|
||||
|
||||
|
||||
要为您的基准创建评估工作流,请按照以下步骤操作:
|
||||
|
||||
1. 导入相关的 OpenHands 实用程序:
|
||||
```python
|
||||
import openhands.agenthub
|
||||
from evaluation.utils.shared import (
|
||||
EvalMetadata,
|
||||
EvalOutput,
|
||||
make_metadata,
|
||||
prepare_dataset,
|
||||
reset_logger_for_multiprocessing,
|
||||
run_evaluation,
|
||||
)
|
||||
from openhands.controller.state.state import State
|
||||
from openhands.core.config import (
|
||||
AppConfig,
|
||||
SandboxConfig,
|
||||
get_llm_config_arg,
|
||||
parse_arguments,
|
||||
)
|
||||
from openhands.core.logger import openhands_logger as logger
|
||||
from openhands.core.main import create_runtime, run_controller
|
||||
from openhands.events.action import CmdRunAction
|
||||
from openhands.events.observation import CmdOutputObservation, ErrorObservation
|
||||
from openhands.runtime.runtime import Runtime
|
||||
```
|
||||
|
||||
2. 创建配置:
|
||||
```python
|
||||
def get_config(instance: pd.Series, metadata: EvalMetadata) -> AppConfig:
|
||||
config = AppConfig(
|
||||
default_agent=metadata.agent_class,
|
||||
runtime='eventstream',
|
||||
max_iterations=metadata.max_iterations,
|
||||
sandbox=SandboxConfig(
|
||||
base_container_image='your_container_image',
|
||||
enable_auto_lint=True,
|
||||
timeout=300,
|
||||
),
|
||||
)
|
||||
config.set_llm_config(metadata.llm_config)
|
||||
return config
|
||||
```
|
||||
|
||||
3. 初始化运行时并设置评估环境:
|
||||
```python
|
||||
def initialize_runtime(runtime: Runtime, instance: pd.Series):
|
||||
# 在此处设置您的评估环境
|
||||
# 例如,设置环境变量、准备文件等
|
||||
pass
|
||||
```
|
||||
|
||||
4. 创建一个函数来处理每个实例:
|
||||
```python
|
||||
from openhands.utils.async_utils import call_async_from_sync
|
||||
def process_instance(instance: pd.Series, metadata: EvalMetadata) -> EvalOutput:
|
||||
config = get_config(instance, metadata)
|
||||
runtime = create_runtime(config)
|
||||
call_async_from_sync(runtime.connect)
|
||||
initialize_runtime(runtime, instance)
|
||||
|
||||
instruction = get_instruction(instance, metadata)
|
||||
|
||||
state = run_controller(
|
||||
config=config,
|
||||
task_str=instruction,
|
||||
runtime=runtime,
|
||||
fake_user_response_fn=your_user_response_function,
|
||||
)
|
||||
|
||||
# 评估代理的操作
|
||||
evaluation_result = await evaluate_agent_actions(runtime, instance)
|
||||
|
||||
return EvalOutput(
|
||||
instance_id=instance.instance_id,
|
||||
instruction=instruction,
|
||||
test_result=evaluation_result,
|
||||
metadata=metadata,
|
||||
history=compatibility_for_eval_history_pairs(state.history),
|
||||
metrics=state.metrics.get() if state.metrics else None,
|
||||
error=state.last_error if state and state.last_error else None,
|
||||
)
|
||||
```
|
||||
|
||||
5. 运行评估:
|
||||
```python
|
||||
metadata = make_metadata(llm_config, dataset_name, agent_class, max_iterations, eval_note, eval_output_dir)
|
||||
output_file = os.path.join(metadata.eval_output_dir, 'output.jsonl')
|
||||
instances = prepare_dataset(your_dataset, output_file, eval_n_limit)
|
||||
|
||||
await run_evaluation(
|
||||
instances,
|
||||
metadata,
|
||||
output_file,
|
||||
num_workers,
|
||||
process_instance
|
||||
)
|
||||
```
|
||||
|
||||
此工作流设置配置,初始化运行时环境,通过运行代理并评估其操作来处理每个实例,然后将结果收集到 `EvalOutput` 对象中。`run_evaluation` 函数处理并行化和进度跟踪。
|
||||
|
||||
请记住根据您特定的基准要求自定义 `get_instruction`、`your_user_response_function` 和 `evaluate_agent_actions` 函数。
|
||||
|
||||
通过遵循此结构,您可以在 OpenHands 框架内为您的基准创建强大的评估工作流。
|
||||
|
||||
|
||||
## 理解 `user_response_fn`
|
||||
|
||||
`user_response_fn` 是 OpenHands 评估工作流中的关键组件。它模拟用户与代理的交互,允许在评估过程中自动响应。当您想要为代理的查询或操作提供一致的、预定义的响应时,此函数特别有用。
|
||||
|
||||
|
||||
### 工作流和交互
|
||||
|
||||
处理操作和 `user_response_fn` 的正确工作流如下:
|
||||
|
||||
1. 代理接收任务并开始处理
|
||||
2. 代理发出操作
|
||||
3. 如果操作可执行(例如 CmdRunAction、IPythonRunCellAction):
|
||||
- 运行时处理操作
|
||||
- 运行时返回观察结果
|
||||
4. 如果操作不可执行(通常是 MessageAction):
|
||||
- 调用 `user_response_fn`
|
||||
- 它返回模拟的用户响应
|
||||
5. 代理接收观察结果或模拟响应
|
||||
6. 重复步骤 2-5,直到任务完成或达到最大迭代次数
|
||||
|
||||
以下是更准确的可视化表示:
|
||||
|
||||
```
|
||||
[代理]
|
||||
|
|
||||
v
|
||||
[发出操作]
|
||||
|
|
||||
v
|
||||
[操作是否可执行?]
|
||||
/ \
|
||||
是 否
|
||||
| |
|
||||
v v
|
||||
[运行时] [user_response_fn]
|
||||
| |
|
||||
v v
|
||||
[返回观察结果] [模拟响应]
|
||||
\ /
|
||||
\ /
|
||||
v v
|
||||
[代理接收反馈]
|
||||
|
|
||||
v
|
||||
[继续或完成任务]
|
||||
```
|
||||
|
||||
在此工作流中:
|
||||
|
||||
- 可执行的操作(如运行命令或执行代码)由运行时直接处理
|
||||
- 不可执行的操作(通常是当代理想要通信或寻求澄清时)由 `user_response_fn` 处理
|
||||
- 然后,代理处理反馈,无论是来自运行时的观察结果还是来自 `user_response_fn` 的模拟响应
|
||||
|
||||
这种方法允许自动处理具体操作和模拟用户交互,使其适用于您想要测试代理在最少人工干预的情况下完成任务的能力的评估场景。
|
||||
|
||||
### 示例实现
|
||||
|
||||
以下是 SWE-Bench 评估中使用的 `user_response_fn` 示例:
|
||||
|
||||
```python
|
||||
def codeact_user_response(state: State | None) -> str:
|
||||
msg = (
|
||||
'Please continue working on the task on whatever approach you think is suitable.\n'
|
||||
'If you think you have solved the task, please first send your answer to user through message and then <execute_bash> exit </execute_bash>.\n'
|
||||
'IMPORTANT: YOU SHOULD NEVER ASK FOR HUMAN HELP.\n'
|
||||
)
|
||||
|
||||
if state and state.history:
|
||||
# 检查代理是否已尝试与用户对话 3 次,如果是,让代理知道它可以放弃
|
||||
user_msgs = [
|
||||
event
|
||||
for event in state.history
|
||||
if isinstance(event, MessageAction) and event.source == 'user'
|
||||
]
|
||||
if len(user_msgs) >= 2:
|
||||
# 让代理知道它在尝试 3 次后可以放弃
|
||||
return (
|
||||
msg
|
||||
+ 'If you want to give up, run: <execute_bash> exit </execute_bash>.\n'
|
||||
)
|
||||
return msg
|
||||
```
|
||||
|
||||
此函数执行以下操作:
|
||||
|
||||
1. 提供一条标准消息,鼓励代理继续工作
|
||||
2. 检查代理尝试与用户通信的次数
|
||||
3. 如果代理已多次尝试,它会提供放弃的选项
|
||||
|
||||
通过使用此函数,您可以确保在多次评估运行中保持一致的行为,并防止代理在等待人工输入时陷入困境。
|
||||
@@ -0,0 +1,15 @@
|
||||
# 使用 OpenHands GitHub Action
|
||||
|
||||
本指南解释了如何在 OpenHands 仓库内以及你自己的项目中使用 OpenHands GitHub Action。
|
||||
|
||||
## 在 OpenHands 仓库中使用 Action
|
||||
|
||||
要在 OpenHands 仓库中使用 OpenHands GitHub Action,OpenHands 维护者可以:
|
||||
|
||||
1. 在仓库中创建一个 issue。
|
||||
2. 为该 issue 添加 `fix-me` 标签。
|
||||
3. Action 将自动触发并尝试解决该 issue。
|
||||
|
||||
## 在新仓库中安装 Action
|
||||
|
||||
要在你自己的仓库中安装 OpenHands GitHub Action,请按照 [OpenHands Resolver 仓库中的说明](https://github.com/All-Hands-AI/OpenHands-resolver?tab=readme-ov-file#using-the-github-actions-workflow) 进行操作。
|
||||
@@ -0,0 +1,53 @@
|
||||
以下是翻译后的内容:
|
||||
|
||||
# 图形用户界面模式
|
||||
|
||||
## 简介
|
||||
|
||||
OpenHands 提供了一个用户友好的图形用户界面 (GUI) 模式,用于与 AI 助手进行交互。该模式提供了一种直观的方式来设置环境、管理设置以及与 AI 进行通信。
|
||||
|
||||
## 安装和设置
|
||||
|
||||
1. 按照[安装](../installation)指南中的说明安装 OpenHands。
|
||||
|
||||
2. 运行命令后,通过 [http://localhost:3000](http://localhost:3000) 访问 OpenHands。
|
||||
|
||||
## 与 GUI 交互
|
||||
|
||||
### 初始设置
|
||||
|
||||
1. 首次启动时,您将看到一个设置模态框。
|
||||
2. 从下拉菜单中选择一个 `LLM Provider` 和 `LLM Model`。
|
||||
3. 输入您选择的提供商对应的 `API Key`。
|
||||
4. 点击"保存"应用设置。
|
||||
|
||||
### 高级设置
|
||||
|
||||
1. 切换 `Advanced Options` 以访问其他设置。
|
||||
2. 如果列表中没有您需要的模型,请使用 `Custom Model` 文本框手动输入模型。
|
||||
3. 如果您的 LLM 提供商需要,请指定一个 `Base URL`。
|
||||
|
||||
### 主界面
|
||||
|
||||
主界面由几个关键组件组成:
|
||||
|
||||
1. **聊天窗口**:您可以查看与 AI 助手的对话历史记录的中心区域。
|
||||
2. **输入框**:位于屏幕底部,用于输入您要发送给 AI 的消息或命令。
|
||||
3. **发送按钮**:点击此按钮将您的消息发送给 AI。
|
||||
4. **设置按钮**:打开设置模态框的齿轮图标,允许您随时调整配置。
|
||||
5. **工作区面板**:显示工作区中的文件和文件夹,允许您导航和查看文件,或查看代理的过去命令或网页浏览历史记录。
|
||||
|
||||
### 与 AI 交互
|
||||
|
||||
1. 在输入框中输入您的问题、请求或任务描述。
|
||||
2. 点击发送按钮或按回车键提交您的消息。
|
||||
3. AI 将处理您的输入并在聊天窗口中提供响应。
|
||||
4. 您可以通过询问后续问题或提供额外信息来继续对话。
|
||||
|
||||
## 有效使用的提示
|
||||
|
||||
1. 在您的请求中要具体,以获得最准确和最有帮助的响应,如[提示最佳实践](../prompting-best-practices)中所述。
|
||||
2. 使用工作区面板探索您的项目结构。
|
||||
3. 使用[LLMs 部分](usage/llms/llms.md)中描述的推荐模型之一。
|
||||
|
||||
请记住,OpenHands 的 GUI 模式旨在使您与 AI 助手的交互尽可能流畅和直观。不要犹豫探索其功能以最大限度地提高您的工作效率。
|
||||
@@ -0,0 +1,60 @@
|
||||
以下是翻译后的内容:
|
||||
|
||||
# 无头模式
|
||||
|
||||
你可以使用单个命令运行 OpenHands,而无需启动 Web 应用程序。
|
||||
这使得使用 OpenHands 编写脚本和自动化任务变得很容易。
|
||||
|
||||
这与[CLI 模式](cli-mode)不同,后者是交互式的,更适合主动开发。
|
||||
|
||||
## 使用 Python
|
||||
|
||||
要在 Python 中以无头模式运行 OpenHands,
|
||||
[请按照开发设置说明](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md),
|
||||
然后运行:
|
||||
|
||||
```bash
|
||||
poetry run python -m openhands.core.main -t "write a bash script that prints hi"
|
||||
```
|
||||
|
||||
你需要确保通过环境变量
|
||||
[或 `config.toml` 文件](https://github.com/All-Hands-AI/OpenHands/blob/main/config.template.toml)
|
||||
设置你的模型、API 密钥和其他设置。
|
||||
|
||||
## 使用 Docker
|
||||
|
||||
1. 将 `WORKSPACE_BASE` 设置为你希望 OpenHands 编辑的目录:
|
||||
|
||||
```bash
|
||||
WORKSPACE_BASE=$(pwd)/workspace
|
||||
```
|
||||
|
||||
2. 将 `LLM_MODEL` 设置为你要使用的模型:
|
||||
|
||||
```bash
|
||||
LLM_MODEL="anthropic/claude-3-5-sonnet-20241022"
|
||||
|
||||
```
|
||||
|
||||
3. 将 `LLM_API_KEY` 设置为你的 API 密钥:
|
||||
|
||||
```bash
|
||||
LLM_API_KEY="sk_test_12345"
|
||||
```
|
||||
|
||||
4. 运行以下 Docker 命令:
|
||||
|
||||
```bash
|
||||
docker run -it \
|
||||
--pull=always \
|
||||
-e SANDBOX_USER_ID=$(id -u) \
|
||||
-e WORKSPACE_MOUNT_PATH=$WORKSPACE_BASE \
|
||||
-e LLM_API_KEY=$LLM_API_KEY \
|
||||
-e LLM_MODEL=$LLM_MODEL \
|
||||
-v $WORKSPACE_BASE:/opt/workspace_base \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
--add-host host.docker.internal:host-gateway \
|
||||
--name openhands-app-$(date +%Y%m%d%H%M%S) \
|
||||
ghcr.io/all-hands-ai/openhands:0.11 \
|
||||
python -m openhands.core.main -t "write a bash script that prints hi"
|
||||
```
|
||||
@@ -0,0 +1,343 @@
|
||||
以下是翻译后的内容:
|
||||
|
||||
# Kubernetes
|
||||
|
||||
在 Kubernetes 或 OpenShift 上运行 OpenHands 有不同的方式。本指南介绍了一种可能的方式:
|
||||
1. 作为集群管理员,创建一个 PV 将 workspace_base 数据和 docker 目录映射到 worker 节点上的 pod
|
||||
2. 创建一个 PVC 以便将这些 PV 挂载到 pod
|
||||
3. 创建一个包含两个容器的 pod:OpenHands 和 Sandbox 容器
|
||||
|
||||
## 上述示例的详细步骤
|
||||
|
||||
> 注意:确保首先使用适当的帐户登录到集群以执行每个步骤。创建 PV 需要集群管理员权限!
|
||||
|
||||
> 确保你对下面使用的 hostPath(即 /tmp/workspace)有读写权限
|
||||
|
||||
1. 创建 PV:
|
||||
集群管理员可以使用下面的示例 yaml 文件创建 PV。
|
||||
- workspace-pv.yaml
|
||||
|
||||
```yamlfile
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
name: workspace-pv
|
||||
spec:
|
||||
capacity:
|
||||
storage: 2Gi
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
hostPath:
|
||||
path: /tmp/workspace
|
||||
```
|
||||
|
||||
```bash
|
||||
# 应用 yaml 文件
|
||||
$ oc create -f workspace-pv.yaml
|
||||
persistentvolume/workspace-pv created
|
||||
|
||||
# 查看:
|
||||
$ oc get pv
|
||||
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
|
||||
workspace-pv 2Gi RWO Retain Available 7m23s
|
||||
```
|
||||
|
||||
- docker-pv.yaml
|
||||
|
||||
```yamlfile
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
name: docker-pv
|
||||
spec:
|
||||
capacity:
|
||||
storage: 2Gi
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
hostPath:
|
||||
path: /var/run/docker.sock
|
||||
```
|
||||
|
||||
```bash
|
||||
# 应用 yaml 文件
|
||||
$ oc create -f docker-pv.yaml
|
||||
persistentvolume/docker-pv created
|
||||
|
||||
# 查看:
|
||||
oc get pv
|
||||
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
|
||||
docker-pv 2Gi RWO Retain Available 6m55s
|
||||
workspace-pv 2Gi RWO Retain Available 7m23s
|
||||
```
|
||||
|
||||
2. 创建 PVC:
|
||||
下面是示例 PVC yaml 文件:
|
||||
|
||||
- workspace-pvc.yaml
|
||||
|
||||
```yamlfile
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: workspace-pvc
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
```
|
||||
|
||||
```bash
|
||||
# 创建 pvc
|
||||
$ oc create -f workspace-pvc.yaml
|
||||
persistentvolumeclaim/workspace-pvc created
|
||||
|
||||
# 查看
|
||||
$ oc get pvc
|
||||
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
|
||||
workspace-pvc Pending hcloud-volumes 4s
|
||||
|
||||
$ oc get events
|
||||
LAST SEEN TYPE REASON OBJECT MESSAGE
|
||||
8s Normal WaitForFirstConsumer persistentvolumeclaim/workspace-pvc waiting for first consumer to be created before binding
|
||||
```
|
||||
|
||||
- docker-pvc.yaml
|
||||
|
||||
```yamlfile
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: docker-pvc
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
```
|
||||
|
||||
```bash
|
||||
# 创建 pvc
|
||||
$ oc create -f docker-pvc.yaml
|
||||
persistentvolumeclaim/docker-pvc created
|
||||
|
||||
# 查看
|
||||
$ oc get pvc
|
||||
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
|
||||
docker-pvc Pending hcloud-volumes 4s
|
||||
workspace-pvc Pending hcloud-volumes 2m53s
|
||||
|
||||
$ oc get events
|
||||
LAST SEEN TYPE REASON OBJECT MESSAGE
|
||||
10s Normal WaitForFirstConsumer persistentvolumeclaim/docker-pvc waiting for first consumer to be created before binding
|
||||
10s Normal WaitForFirstConsumer persistentvolumeclaim/workspace-pvc waiting for first consumer to be created before binding
|
||||
```
|
||||
|
||||
3. 创建 pod yaml 文件:
|
||||
下面是示例 pod yaml 文件:
|
||||
|
||||
- pod.yaml
|
||||
|
||||
```yamlfile
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: openhands-app-2024
|
||||
labels:
|
||||
app: openhands-app-2024
|
||||
spec:
|
||||
containers:
|
||||
- name: openhands-app-2024
|
||||
image: ghcr.io/all-hands-ai/openhands:main
|
||||
env:
|
||||
- name: SANDBOX_USER_ID
|
||||
value: "1000"
|
||||
- name: WORKSPACE_MOUNT_PATH
|
||||
value: "/opt/workspace_base"
|
||||
volumeMounts:
|
||||
- name: workspace-volume
|
||||
mountPath: /opt/workspace_base
|
||||
- name: docker-sock
|
||||
mountPath: /var/run/docker.sock
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
- name: openhands-sandbox-2024
|
||||
image: ghcr.io/all-hands-ai/sandbox:main
|
||||
ports:
|
||||
- containerPort: 51963
|
||||
command: ["/usr/sbin/sshd", "-D", "-p 51963", "-o", "PermitRootLogin=yes"]
|
||||
volumes:
|
||||
- name: workspace-volume
|
||||
persistentVolumeClaim:
|
||||
claimName: workspace-pvc
|
||||
- name: docker-sock
|
||||
persistentVolumeClaim:
|
||||
claimName: docker-pvc
|
||||
```
|
||||
|
||||
|
||||
```bash
|
||||
# 创建 pod
|
||||
$ oc create -f pod.yaml
|
||||
W0716 11:22:07.776271 107626 warnings.go:70] would violate PodSecurity "restricted:v1.24": allowPrivilegeEscalation != false (containers "openhands-app-2024", "openhands-sandbox-2024" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (containers "openhands-app-2024", "openhands-sandbox-2024" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or containers "openhands-app-2024", "openhands-sandbox-2024" must set securityContext.runAsNonRoot=true), seccompProfile (pod or containers "openhands-app-2024", "openhands-sandbox-2024" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
|
||||
pod/openhands-app-2024 created
|
||||
|
||||
# 上面的警告可以暂时忽略,因为我们不会修改 SCC 限制。
|
||||
|
||||
# 查看
|
||||
$ oc get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
openhands-app-2024 0/2 Pending 0 5s
|
||||
|
||||
$ oc get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
openhands-app-2024 0/2 ContainerCreating 0 15s
|
||||
|
||||
$ oc get events
|
||||
LAST SEEN TYPE REASON OBJECT MESSAGE
|
||||
38s Normal WaitForFirstConsumer persistentvolumeclaim/docker-pvc waiting for first consumer to be created before binding
|
||||
23s Normal ExternalProvisioning persistentvolumeclaim/docker-pvc waiting for a volume to be created, either by external provisioner "csi.hetzner.cloud" or manually created by system administrator
|
||||
27s Normal Provisioning persistentvolumeclaim/docker-pvc External provisioner is provisioning volume for claim "openhands/docker-pvc"
|
||||
17s Normal ProvisioningSucceeded persistentvolumeclaim/docker-pvc Successfully provisioned volume pvc-2b1d223a-1c8f-4990-8e3d-68061a9ae252
|
||||
16s Normal Scheduled pod/openhands-app-2024 Successfully assigned All-Hands-AI/OpenHands-app-2024 to worker1.hub.internal.blakane.com
|
||||
9s Normal SuccessfulAttachVolume pod/openhands-app-2024 AttachVolume.Attach succeeded for volume "pvc-2b1d223a-1c8f-4990-8e3d-68061a9ae252"
|
||||
9s Normal SuccessfulAttachVolume pod/openhands-app-2024 AttachVolume.Attach succeeded for volume "pvc-31f15b25-faad-4665-a25f-201a530379af"
|
||||
6s Normal AddedInterface pod/openhands-app-2024 Add eth0 [10.128.2.48/23] from openshift-sdn
|
||||
6s Normal Pulled pod/openhands-app-2024 Container image "ghcr.io/all-hands-ai/openhands:main" already present on machine
|
||||
6s Normal Created pod/openhands-app-2024 Created container openhands-app-2024
|
||||
6s Normal Started pod/openhands-app-2024 Started container openhands-app-2024
|
||||
6s Normal Pulled pod/openhands-app-2024 Container image "ghcr.io/all-hands-ai/sandbox:main" already present on machine
|
||||
5s Normal Created pod/openhands-app-2024 Created container openhands-sandbox-2024
|
||||
5s Normal Started pod/openhands-app-2024 Started container openhands-sandbox-2024
|
||||
83s Normal WaitForFirstConsumer persistentvolumeclaim/workspace-pvc waiting for first consumer to be created before binding
|
||||
27s Normal Provisioning persistentvolumeclaim/workspace-pvc External provisioner is provisioning volume for claim "openhands/workspace-pvc"
|
||||
17s Normal ProvisioningSucceeded persistentvolumeclaim/workspace-pvc Successfully provisioned volume pvc-31f15b25-faad-4665-a25f-201a530379af
|
||||
|
||||
$ oc get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
openhands-app-2024 2/2 Running 0 23s
|
||||
|
||||
$ oc get pvc
|
||||
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
|
||||
docker-pvc Bound pvc-2b1d223a-1c8f-4990-8e3d-68061a9ae252 10Gi RWO hcloud-volumes 10m
|
||||
workspace-pvc Bound pvc-31f15b25-faad-4665-a25f-201a530379af 10Gi RWO hcloud-volumes 13m
|
||||
|
||||
```
|
||||
|
||||
4. 创建一个 NodePort 服务。
|
||||
下面是示例服务创建命令:
|
||||
|
||||
```bash
|
||||
# 创建 NodePort 类型的服务
|
||||
$ oc create svc nodeport openhands-app-2024 --tcp=3000:3000
|
||||
service/openhands-app-2024 created
|
||||
|
||||
# 查看
|
||||
|
||||
$ oc get svc
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
openhands-app-2024 NodePort 172.30.225.42 <none> 3000:30495/TCP 4s
|
||||
|
||||
$ oc describe svc openhands-app-2024
|
||||
Name: openhands-app-2024
|
||||
Namespace: openhands
|
||||
Labels: app=openhands-app-2024
|
||||
Annotations: <none>
|
||||
Selector: app=openhands-app-2024
|
||||
Type: NodePort
|
||||
IP Family Policy: SingleStack
|
||||
IP Families: IPv4
|
||||
IP: 172.30.225.42
|
||||
IPs: 172.30.225.42
|
||||
Port: 3000-3000 3000/TCP
|
||||
TargetPort: 3000/TCP
|
||||
NodePort: 3000-3000 30495/TCP
|
||||
Endpoints: 10.128.2.48:3000
|
||||
Session Affinity: None
|
||||
External Traffic Policy: Cluster
|
||||
Events: <none>
|
||||
```
|
||||
|
||||
6. 连接到 OpenHands UI,配置 Agent,然后测试:
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
## GCP GKE OpenHands 部署
|
||||
|
||||
**警告**:此部署授予 OpenHands 应用程序访问 Kubernetes docker socket 的权限,这会带来安全风险。请自行决定是否使用。
|
||||
1- 创建特权访问策略
|
||||
2- 创建 gke 凭证(可选)
|
||||
3- 创建 openhands 部署
|
||||
4- 验证和 UI 访问命令
|
||||
5- 排查 pod 以验证内部容器
|
||||
|
||||
1. 创建特权访问策略
|
||||
```bash
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: privileged-role
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["create", "get", "list", "watch", "delete"]
|
||||
- apiGroups: ["apps"]
|
||||
resources: ["deployments"]
|
||||
verbs: ["create", "get", "list", "watch", "delete"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods/exec"]
|
||||
verbs: ["create"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods/log"]
|
||||
verbs: ["get"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: privileged-role-binding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: privileged-role
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: default # 更改为你的服务帐户名称
|
||||
namespace: default
|
||||
```
|
||||
2. 创建 gke 凭证(可选)
|
||||
```bash
|
||||
kubectl create secret generic google-cloud-key \
|
||||
--from-file=key.json=/path/to/your/google-cloud-key.json
|
||||
```
|
||||
3. 创建 openhands 部署
|
||||
## 由于这是针对单个工作节点进行测试的,如果你有多个节点,请指定单个工作节点的标志
|
||||
|
||||
```bash
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: openhands-app-2024
|
||||
labels:
|
||||
app: openhands-app-2024
|
||||
spec:
|
||||
replicas: 1 # 你可以增加这个数字以获得多个副本
|
||||
selector:
|
||||
matchLabels:
|
||||
app: openhands-app-2024
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: openhands-app-2024
|
||||
spec:
|
||||
containers:
|
||||
- name: openhands-app-2024
|
||||
image: ghcr.io/all-hands-ai/openhands:main
|
||||
env:
|
||||
- name: SANDBOX_USER_ID
|
||||
value: "1000"
|
||||
- name: SANDBOX_API
|
||||
@@ -0,0 +1,58 @@
|
||||
# 安装
|
||||
|
||||
## 系统要求
|
||||
|
||||
* Docker 版本 26.0.0+ 或 Docker Desktop 4.31.0+。
|
||||
* 你必须使用 Linux 或 Mac OS。
|
||||
* 如果你使用的是 Windows,你必须使用 [WSL](https://learn.microsoft.com/en-us/windows/wsl/install)。
|
||||
|
||||
## 启动应用
|
||||
|
||||
在 Docker 中运行 OpenHands 是最简单的方式。你可以将下面的 `WORKSPACE_BASE` 更改为指向你想要修改的现有代码。
|
||||
|
||||
```bash
|
||||
export WORKSPACE_BASE=$(pwd)/workspace
|
||||
|
||||
docker pull ghcr.io/all-hands-ai/runtime:0.11-nikolaik
|
||||
|
||||
docker run -it --pull=always \
|
||||
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=ghcr.io/all-hands-ai/runtime:0.11-nikolaik \
|
||||
-e SANDBOX_USER_ID=$(id -u) \
|
||||
-e WORKSPACE_MOUNT_PATH=$WORKSPACE_BASE \
|
||||
-v $WORKSPACE_BASE:/opt/workspace_base \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-p 3000:3000 \
|
||||
--add-host host.docker.internal:host-gateway \
|
||||
--name openhands-app-$(date +%Y%m%d%H%M%S) \
|
||||
ghcr.io/all-hands-ai/openhands:0.11
|
||||
```
|
||||
|
||||
你也可以在可脚本化的[无头模式](https://docs.all-hands.dev/modules/usage/how-to/headless-mode)下运行 OpenHands,作为[交互式 CLI](https://docs.all-hands.dev/modules/usage/how-to/cli-mode),或使用 [OpenHands GitHub Action](https://docs.all-hands.dev/modules/usage/how-to/github-action)。
|
||||
|
||||
## 设置
|
||||
|
||||
运行上面的命令后,你会发现 OpenHands 运行在 [http://localhost:3000](http://localhost:3000)。
|
||||
|
||||
代理将可以访问 `./workspace` 文件夹来完成其工作。你可以将现有代码复制到这里,或在命令中更改 `WORKSPACE_BASE` 以指向现有文件夹。
|
||||
|
||||
启动 OpenHands 后,你会看到一个设置模态框。你**必须**选择一个 `LLM Provider` 和 `LLM Model`,并输入相应的 `API Key`。这些可以随时通过在 UI 中选择 `Settings` 按钮(齿轮图标)来更改。
|
||||
|
||||
如果所需的 `LLM Model` 不存在于列表中,你可以切换 `Advanced Options`,并在 `Custom Model` 文本框中使用正确的前缀手动输入它。`Advanced Options` 还允许你在需要时指定 `Base URL`。
|
||||
|
||||
<div style={{ display: 'flex', justifyContent: 'center', gap: '20px' }}>
|
||||
<img src="/img/settings-screenshot.png" alt="settings-modal" width="340" />
|
||||
<img src="/img/settings-advanced.png" alt="settings-modal" width="335" />
|
||||
</div>
|
||||
|
||||
## 版本
|
||||
|
||||
上面的命令拉取最新的 OpenHands 稳定版本。你还有其他选择:
|
||||
- 对于特定版本,使用 `ghcr.io/all-hands-ai/openhands:$VERSION`,将 $VERSION 替换为版本号。
|
||||
- 我们使用语义化版本,并发布主要、次要和补丁标签。因此,`0.9` 将自动指向最新的 `0.9.x` 版本,而 `0` 将指向最新的 `0.x.x` 版本。
|
||||
- 对于最新的开发版本,你可以使用 `ghcr.io/all-hands-ai/openhands:main`。此版本不稳定,仅建议用于测试或开发目的。
|
||||
|
||||
你可以根据稳定性要求和所需功能选择最适合你需求的标签。
|
||||
|
||||
有关开发工作流程,请参阅 [Development.md](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md)。
|
||||
|
||||
遇到问题了吗?查看我们的[故障排除指南](https://docs.all-hands.dev/modules/usage/troubleshooting)。
|
||||
@@ -0,0 +1,43 @@
|
||||
# Azure
|
||||
|
||||
OpenHands 使用 LiteLLM 调用 Azure 的聊天模型。你可以在[这里](https://docs.litellm.ai/docs/providers/azure)找到他们关于使用 Azure 作为提供商的文档。
|
||||
|
||||
## Azure OpenAI 配置
|
||||
|
||||
运行 OpenHands 时,你需要在 [docker run 命令](/modules/usage/installation#start-the-app)中使用 `-e` 设置以下环境变量:
|
||||
|
||||
```
|
||||
LLM_API_VERSION="<api-version>" # 例如 "2023-05-15"
|
||||
```
|
||||
|
||||
示例:
|
||||
```bash
|
||||
docker run -it --pull=always \
|
||||
-e LLM_API_VERSION="2023-05-15"
|
||||
...
|
||||
```
|
||||
|
||||
然后在 OpenHands UI 的设置中设置以下内容:
|
||||
|
||||
:::note
|
||||
你需要你的 ChatGPT 部署名称,可以在 Azure 的部署页面找到。下面将其称为 <deployment-name>。
|
||||
:::
|
||||
|
||||
* 启用 `Advanced Options`
|
||||
* 将 `Custom Model` 设置为 azure/<deployment-name>
|
||||
* 将 `Base URL` 设置为你的 Azure API 基础 URL(例如 `https://example-endpoint.openai.azure.com`)
|
||||
* 将 `API Key` 设置为你的 Azure API 密钥
|
||||
|
||||
## Embeddings
|
||||
|
||||
OpenHands 使用 llama-index 进行 embeddings。你可以在[这里](https://docs.llamaindex.ai/en/stable/api_reference/embeddings/azure_openai/)找到他们关于 Azure 的文档。
|
||||
|
||||
### Azure OpenAI 配置
|
||||
|
||||
运行 OpenHands 时,在 [docker run 命令](/modules/usage/installation#start-the-app)中使用 `-e` 设置以下环境变量:
|
||||
|
||||
```
|
||||
LLM_EMBEDDING_MODEL="azureopenai"
|
||||
LLM_EMBEDDING_DEPLOYMENT_NAME="<your-embedding-deployment-name>" # 例如 "TextEmbedding...<etc>"
|
||||
LLM_API_VERSION="<api-version>" # 例如 "2024-02-15-preview"
|
||||
```
|
||||
@@ -0,0 +1,29 @@
|
||||
# Google Gemini/Vertex
|
||||
|
||||
OpenHands 使用 LiteLLM 调用 Google 的聊天模型。你可以在以下文档中找到使用 Google 作为提供商的说明:
|
||||
|
||||
- [Gemini - Google AI Studio](https://docs.litellm.ai/docs/providers/gemini)
|
||||
- [VertexAI - Google Cloud Platform](https://docs.litellm.ai/docs/providers/vertex)
|
||||
|
||||
## Gemini - Google AI Studio 配置
|
||||
|
||||
运行 OpenHands 时,你需要在设置中设置以下内容:
|
||||
* 将 `LLM Provider` 设置为 `Gemini`
|
||||
* 将 `LLM Model` 设置为你将使用的模型。
|
||||
如果模型不在列表中,请切换 `Advanced Options`,并在 `Custom Model` 中输入(例如 gemini/<model-name> 如 `gemini/gemini-1.5-pro`)。
|
||||
* 将 `API Key` 设置为你的 Gemini API 密钥
|
||||
|
||||
## VertexAI - Google Cloud Platform 配置
|
||||
|
||||
要在运行 OpenHands 时通过 Google Cloud Platform 使用 Vertex AI,你需要使用 [docker run 命令](/modules/usage/installation#start-the-app) 中的 `-e` 设置以下环境变量:
|
||||
|
||||
```
|
||||
GOOGLE_APPLICATION_CREDENTIALS="<json-dump-of-gcp-service-account-json>"
|
||||
VERTEXAI_PROJECT="<your-gcp-project-id>"
|
||||
VERTEXAI_LOCATION="<your-gcp-location>"
|
||||
```
|
||||
|
||||
然后在设置中设置以下内容:
|
||||
* 将 `LLM Provider` 设置为 `VertexAI`
|
||||
* 将 `LLM Model` 设置为你将使用的模型。
|
||||
如果模型不在列表中,请切换 `Advanced Options`,并在 `Custom Model` 中输入(例如 vertex_ai/<model-name>)。
|
||||
@@ -0,0 +1,20 @@
|
||||
# Groq
|
||||
|
||||
OpenHands 使用 LiteLLM 在 Groq 上调用聊天模型。你可以在[这里](https://docs.litellm.ai/docs/providers/groq)找到他们关于使用 Groq 作为提供商的文档。
|
||||
|
||||
## 配置
|
||||
|
||||
在运行 OpenHands 时,你需要在设置中设置以下内容:
|
||||
* `LLM Provider` 设置为 `Groq`
|
||||
* `LLM Model` 设置为你将使用的模型。[访问此处查看 Groq 托管的模型列表](https://console.groq.com/docs/models)。如果模型不在列表中,切换 `Advanced Options`,并在 `Custom Model` 中输入它(例如 groq/<model-name> 如 `groq/llama3-70b-8192`)。
|
||||
* `API key` 设置为你的 Groq API 密钥。要查找或创建你的 Groq API 密钥,[请参见此处](https://console.groq.com/keys)。
|
||||
|
||||
|
||||
|
||||
## 使用 Groq 作为 OpenAI 兼容端点
|
||||
|
||||
Groq 的聊天完成端点[大部分与 OpenAI 兼容](https://console.groq.com/docs/openai)。因此,你可以像访问任何 OpenAI 兼容端点一样访问 Groq 模型。你可以在设置中设置以下内容:
|
||||
* 启用 `Advanced Options`
|
||||
* `Custom Model` 设置为前缀 `openai/` + 你将使用的模型(例如 `openai/llama3-70b-8192`)
|
||||
* `Base URL` 设置为 `https://api.groq.com/openai/v1`
|
||||
* `API Key` 设置为你的 Groq API 密钥
|
||||
@@ -1,46 +1,81 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
---
|
||||
# 🤖 LLM 后端
|
||||
|
||||
# 🤖 LLM 支持
|
||||
OpenHands 可以连接到 LiteLLM 支持的任何 LLM。但是,它需要一个强大的模型才能工作。
|
||||
|
||||
OpenHands 可以兼容任何 LLM 后端。
|
||||
关于所有可用 LM 提供商和模型的完整列表,请参阅
|
||||
[litellm 文档](https://docs.litellm.ai/docs/providers)。
|
||||
## 模型推荐
|
||||
|
||||
基于最近对编码任务的语言模型评估(使用 SWE-bench 数据集),我们可以为模型选择提供一些建议。完整的分析可以在[这篇博客文章](https://www.all-hands.dev/blog/evaluation-of-llms-as-coding-agents-on-swe-bench-at-30x-speed)中找到。
|
||||
|
||||
在选择模型时,需要同时考虑输出质量和相关成本。以下是调查结果的总结:
|
||||
|
||||
- Claude 3.5 Sonnet 是目前最好的,在 OpenHands 中使用默认 agent 可以达到 27% 的解决率。
|
||||
- GPT-4o 落后一些,而 o1-mini 的表现甚至比 GPT-4o 还要差一些。我们进行了一些分析,简单来说,o1 有时会"过度思考",在可以直接完成任务的情况下执行额外的环境配置任务。
|
||||
- 最后,最强大的开放模型是 Llama 3.1 405 B 和 deepseek-v2.5,它们表现得相当不错,甚至超过了一些封闭模型。
|
||||
|
||||
请参阅[完整文章](https://www.all-hands.dev/blog/evaluation-of-llms-as-coding-agents-on-swe-bench-at-30x-speed)以获取更多详细信息。
|
||||
|
||||
基于这些发现和社区反馈,以下模型已经验证可以与 OpenHands 很好地配合使用:
|
||||
|
||||
- claude-3-5-sonnet(推荐)
|
||||
- gpt-4 / gpt-4o
|
||||
- llama-3.1-405b
|
||||
- deepseek-v2.5
|
||||
|
||||
:::warning
|
||||
OpenHands 将向你配置的 LLM 发出许多提示。大多数这些 LLM 都是收费的——请务必设定支出限额并监控使用情况。
|
||||
OpenHands 将向您配置的 LLM 发出许多提示。这些 LLM 中的大多数都需要付费,因此请确保设置支出限制并监控使用情况。
|
||||
:::
|
||||
|
||||
`LLM_MODEL` 环境变量控制在编程交互中使用的模型。
|
||||
但在使用 OpenHands UI 时,你需要在设置窗口中选择你的模型(左下角的齿轮)。
|
||||
如果您已经成功地使用特定的未列出的 LLM 运行 OpenHands,请将它们添加到已验证列表中。我们也鼓励您提交 PR 分享您的设置过程,以帮助其他使用相同提供商和 LLM 的人!
|
||||
|
||||
某些 LLM 可能需要以下环境变量:
|
||||
有关可用提供商和模型的完整列表,请查阅 [litellm 文档](https://docs.litellm.ai/docs/providers)。
|
||||
|
||||
- `LLM_API_KEY`
|
||||
- `LLM_BASE_URL`
|
||||
:::note
|
||||
目前大多数本地和开源模型都没有那么强大。使用这些模型时,您可能会看到消息之间的长时间等待、响应不佳或有关 JSON 格式错误的错误。OpenHands 只能和驱动它的模型一样强大。但是,如果您确实找到了可以使用的模型,请将它们添加到上面的已验证列表中。
|
||||
:::
|
||||
|
||||
## LLM 配置
|
||||
|
||||
以下内容可以通过设置在 OpenHands UI 中设置:
|
||||
|
||||
- `LLM Provider`
|
||||
- `LLM Model`
|
||||
- `API Key`
|
||||
- `Base URL`(通过`Advanced Settings`)
|
||||
|
||||
有些设置可能对某些 LLM/提供商是必需的,但无法通过 UI 设置。相反,可以使用 `-e` 通过传递给 [docker run 命令](/modules/usage/installation#start-the-app)的环境变量来设置这些选项:
|
||||
|
||||
- `LLM_API_VERSION`
|
||||
- `LLM_EMBEDDING_MODEL`
|
||||
- `LLM_EMBEDDING_DEPLOYMENT_NAME`
|
||||
- `LLM_API_VERSION`
|
||||
- `LLM_DROP_PARAMS`
|
||||
- `LLM_DISABLE_VISION`
|
||||
- `LLM_CACHING_PROMPT`
|
||||
|
||||
我们有一些指南,介绍了如何使用特定模型提供商运行 OpenHands:
|
||||
我们有一些使用特定模型提供商运行 OpenHands 的指南:
|
||||
|
||||
- [ollama](llms/local-llms)
|
||||
- [Azure](llms/azure-llms)
|
||||
- [Google](llms/google-llms)
|
||||
- [Groq](llms/groq)
|
||||
- [OpenAI](llms/openai-llms)
|
||||
- [OpenRouter](llms/openrouter)
|
||||
|
||||
如果你使用其他提供商,我们鼓励你打开一个 PR 来分享你的配置!
|
||||
### API 重试和速率限制
|
||||
|
||||
## 关于替代模型的注意事项
|
||||
LLM 提供商通常有速率限制,有时非常低,可能需要重试。如果收到速率限制错误(429 错误代码)、API 连接错误或其他瞬时错误,OpenHands 将自动重试请求。
|
||||
|
||||
最好的模型是 GPT-4 和 Claude 3。目前的本地和开源模型
|
||||
远没有那么强大。当使用替代模型时,
|
||||
你可能会看到信息之间的长时间等待,
|
||||
糟糕的响应,或关于 JSON格式错误的错误。OpenHands
|
||||
的强大程度依赖于其驱动的模型——幸运的是,我们团队的人员
|
||||
正在积极致力于构建更好的开源模型!
|
||||
您可以根据正在使用的提供商的需要自定义这些选项。查看他们的文档,并设置以下环境变量来控制重试次数和重试之间的时间:
|
||||
|
||||
## API 重试和速率限制
|
||||
- `LLM_NUM_RETRIES`(默认为 8)
|
||||
- `LLM_RETRY_MIN_WAIT`(默认为 15 秒)
|
||||
- `LLM_RETRY_MAX_WAIT`(默认为 120 秒)
|
||||
- `LLM_RETRY_MULTIPLIER`(默认为 2)
|
||||
|
||||
一些 LLM 有速率限制,可能需要重试操作。OpenHands 会在收到 429 错误或 API 连接错误时自动重试请求。
|
||||
你可以设置 `LLM_NUM_RETRIES`,`LLM_RETRY_MIN_WAIT`,`LLM_RETRY_MAX_WAIT` 环境变量来控制重试次数和重试之间的时间。
|
||||
默认情况下,`LLM_NUM_RETRIES` 为 8,`LLM_RETRY_MIN_WAIT` 和 `LLM_RETRY_MAX_WAIT` 分别为 15 秒和 120 秒。
|
||||
如果您在开发模式下运行 OpenHands,也可以在 `config.toml` 文件中设置这些选项:
|
||||
|
||||
```toml
|
||||
[llm]
|
||||
num_retries = 8
|
||||
retry_min_wait = 15
|
||||
retry_max_wait = 120
|
||||
retry_multiplier = 2
|
||||
```
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
# 使用 Ollama 的本地 LLM
|
||||
|
||||
:::warning
|
||||
使用本地 LLM 时,OpenHands 可能会有功能限制。
|
||||
:::
|
||||
|
||||
确保你已经启动并运行了 Ollama 服务器。
|
||||
详细的启动说明,请参考[这里](https://github.com/ollama/ollama)。
|
||||
|
||||
本指南假设你已经使用 `ollama serve` 启动了 ollama。如果你以不同的方式运行 ollama(例如在 docker 内),则可能需要修改说明。请注意,如果你正在运行 WSL,默认的 ollama 配置会阻止来自 docker 容器的请求。请参阅[这里](#configuring-ollama-service-wsl-zh)。
|
||||
|
||||
## 拉取模型
|
||||
|
||||
Ollama 模型名称可以在[这里](https://ollama.com/library)找到。对于一个小例子,你可以使用
|
||||
`codellama:7b` 模型。更大的模型通常会有更好的表现。
|
||||
|
||||
```bash
|
||||
ollama pull codellama:7b
|
||||
```
|
||||
|
||||
你可以像这样检查已下载的模型:
|
||||
|
||||
```bash
|
||||
~$ ollama list
|
||||
NAME ID SIZE MODIFIED
|
||||
codellama:7b 8fdf8f752f6e 3.8 GB 6 weeks ago
|
||||
mistral:7b-instruct-v0.2-q4_K_M eb14864c7427 4.4 GB 2 weeks ago
|
||||
starcoder2:latest f67ae0f64584 1.7 GB 19 hours ago
|
||||
```
|
||||
|
||||
## 使用 Docker 运行 OpenHands
|
||||
|
||||
### 启动 OpenHands
|
||||
使用[这里](../getting-started)的说明,使用 Docker 启动 OpenHands。
|
||||
但在运行 `docker run` 时,你需要添加一些额外的参数:
|
||||
|
||||
```bash
|
||||
--add-host host.docker.internal:host-gateway \
|
||||
-e LLM_OLLAMA_BASE_URL="http://host.docker.internal:11434" \
|
||||
```
|
||||
|
||||
LLM_OLLAMA_BASE_URL 是可选的。如果设置了,它将用于在 UI 中显示可用的已安装模型。
|
||||
|
||||
示例:
|
||||
|
||||
```bash
|
||||
# 你希望 OpenHands 修改的目录。必须是绝对路径!
|
||||
export WORKSPACE_BASE=$(pwd)/workspace
|
||||
|
||||
docker run \
|
||||
-it \
|
||||
--pull=always \
|
||||
--add-host host.docker.internal:host-gateway \
|
||||
-e SANDBOX_USER_ID=$(id -u) \
|
||||
-e LLM_OLLAMA_BASE_URL="http://host.docker.internal:11434" \
|
||||
-e WORKSPACE_MOUNT_PATH=$WORKSPACE_BASE \
|
||||
-v $WORKSPACE_BASE:/opt/workspace_base \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-p 3000:3000 \
|
||||
ghcr.io/all-hands-ai/openhands:main
|
||||
```
|
||||
|
||||
现在你应该可以连接到 `http://localhost:3000/` 了。
|
||||
|
||||
### 配置 Web 应用程序
|
||||
|
||||
在运行 `openhands` 时,你需要在 OpenHands UI 的设置中设置以下内容:
|
||||
- 模型设置为 "ollama/<model-name>"
|
||||
- 基础 URL 设置为 `http://host.docker.internal:11434`
|
||||
- API 密钥是可选的,你可以使用任何字符串,例如 `ollama`。
|
||||
|
||||
|
||||
## 在开发模式下运行 OpenHands
|
||||
|
||||
### 从源代码构建
|
||||
|
||||
使用 [Development.md](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md) 中的说明来构建 OpenHands。
|
||||
通过运行 `make setup-config` 确保 `config.toml` 存在,它将为你创建一个。在 `config.toml` 中,输入以下内容:
|
||||
|
||||
```
|
||||
[core]
|
||||
workspace_base="./workspace"
|
||||
|
||||
[llm]
|
||||
embedding_model="local"
|
||||
ollama_base_url="http://localhost:11434"
|
||||
|
||||
```
|
||||
|
||||
完成!现在你可以通过 `make run` 启动 OpenHands。你现在应该可以连接到 `http://localhost:3000/` 了。
|
||||
|
||||
### 配置 Web 应用程序
|
||||
|
||||
在 OpenHands UI 中,点击左下角的设置齿轮。
|
||||
然后在 `Model` 输入框中,输入 `ollama/codellama:7b`,或者你之前拉取的模型名称。
|
||||
如果它没有出现在下拉菜单中,启用 `Advanced Settings` 并输入。请注意:你需要 `ollama list` 列出的模型名称,带有 `ollama/` 前缀。
|
||||
|
||||
在 API Key 字段中,输入 `ollama` 或任何值,因为你不需要特定的密钥。
|
||||
|
||||
在 Base URL 字段中,输入 `http://localhost:11434`。
|
||||
|
||||
现在你已经准备好了!
|
||||
|
||||
## 配置 ollama 服务(WSL){#configuring-ollama-service-wsl-zh}
|
||||
|
||||
WSL 中 ollama 的默认配置只服务于 localhost。这意味着你无法从 docker 容器中访问它。例如,它不能与 OpenHands 一起工作。首先让我们测试 ollama 是否正确运行。
|
||||
|
||||
```bash
|
||||
ollama list # 获取已安装模型的列表
|
||||
curl http://localhost:11434/api/generate -d '{"model":"[NAME]","prompt":"hi"}'
|
||||
#例如 curl http://localhost:11434/api/generate -d '{"model":"codellama:7b","prompt":"hi"}'
|
||||
#例如 curl http://localhost:11434/api/generate -d '{"model":"codellama","prompt":"hi"}' #如果只有一个,标签是可选的
|
||||
```
|
||||
|
||||
完成后,测试它是否允许"外部"请求,例如来自 docker 容器内部的请求。
|
||||
|
||||
```bash
|
||||
docker ps # 获取正在运行的 docker 容器列表,为了最准确的测试,选择 OpenHands 沙箱容器。
|
||||
docker exec [CONTAINER ID] curl http://host.docker.internal:11434/api/generate -d '{"model":"[NAME]","prompt":"hi"}'
|
||||
#例如 docker exec cd9cc82f7a11 curl http://host.docker.internal:11434/api/generate -d '{"model":"codellama","prompt":"hi"}'
|
||||
```
|
||||
|
||||
## 修复它
|
||||
|
||||
现在让我们让它工作。使用 sudo 权限编辑 /etc/systemd/system/ollama.service。(路径可能因 Linux 发行版而异)
|
||||
|
||||
```bash
|
||||
sudo vi /etc/systemd/system/ollama.service
|
||||
```
|
||||
|
||||
或
|
||||
|
||||
```bash
|
||||
sudo nano /etc/systemd/system/ollama.service
|
||||
```
|
||||
|
||||
在 [Service] 括号中添加这些行
|
||||
|
||||
```
|
||||
Environment="OLLAMA_HOST=0.0.0.0:11434"
|
||||
Environment="OLLAMA_ORIGINS=*"
|
||||
```
|
||||
|
||||
然后保存,重新加载配置并重启服务。
|
||||
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl restart ollama
|
||||
```
|
||||
|
||||
最后测试 ollama 是否可以从容器内访问
|
||||
|
||||
```bash
|
||||
ollama list # 获取已安装模型的列表
|
||||
docker ps # 获取正在运行的 docker 容器列表,为了最准确的测试,选择 OpenHands 沙箱容器。
|
||||
docker exec [CONTAINER ID] curl http://host.docker.internal:11434/api/generate -d '{"model":"[NAME]","prompt":"hi"}'
|
||||
```
|
||||
|
||||
|
||||
# 使用 LM Studio 的本地 LLM
|
||||
|
||||
设置 LM Studio 的步骤:
|
||||
1. 打开 LM Studio
|
||||
2. 转到 Local Server 选项卡。
|
||||
3. 点击 "Start Server" 按钮。
|
||||
4. 从下拉菜单中选择要使用的模型。
|
||||
|
||||
|
||||
设置以下配置:
|
||||
```bash
|
||||
LLM_MODEL="openai/lmstudio"
|
||||
LLM_BASE_URL="http://localhost:1234/v1"
|
||||
CUSTOM_LLM_PROVIDER="openai"
|
||||
```
|
||||
|
||||
### Docker
|
||||
|
||||
```bash
|
||||
docker run \
|
||||
-it \
|
||||
--pull=always \
|
||||
-e SANDBOX_USER_ID=$(id -u) \
|
||||
-e LLM_MODEL="openai/lmstudio" \
|
||||
-e LLM_BASE_URL="http://host.docker.internal:1234/v1" \
|
||||
-e CUSTOM_LLM_PROVIDER="openai" \
|
||||
-e WORKSPACE_MOUNT_PATH=$WORKSPACE_BASE \
|
||||
-v $WORKSPACE_BASE:/opt/workspace_base \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-p 3000:3000 \
|
||||
ghcr.io/all-hands-ai/openhands:main
|
||||
```
|
||||
|
||||
现在你应该可以连接到 `http://localhost:3000/` 了。
|
||||
|
||||
在开发环境中,你可以在 `config.toml` 文件中设置以下配置:
|
||||
|
||||
```
|
||||
[core]
|
||||
workspace_base="./workspace"
|
||||
|
||||
[llm]
|
||||
model="openai/lmstudio"
|
||||
base_url="http://localhost:1234/v1"
|
||||
custom_llm_provider="openai"
|
||||
```
|
||||
|
||||
完成!现在你可以通过 `make run` 启动 OpenHands,无需 Docker。你现在应该可以连接到 `http://localhost:3000/` 了。
|
||||
|
||||
# 注意
|
||||
|
||||
对于 WSL,在 cmd 中运行以下命令以将网络模式设置为镜像:
|
||||
|
||||
```
|
||||
python -c "print('[wsl2]\nnetworkingMode=mirrored',file=open(r'%UserProfile%\.wslconfig','w'))"
|
||||
wsl --shutdown
|
||||
```
|
||||
@@ -0,0 +1,24 @@
|
||||
# OpenAI
|
||||
|
||||
OpenHands 使用 LiteLLM 调用 OpenAI 的聊天模型。你可以在[这里](https://docs.litellm.ai/docs/providers/openai)找到他们关于使用 OpenAI 作为提供商的文档。
|
||||
|
||||
## 配置
|
||||
|
||||
运行 OpenHands 时,你需要在设置中设置以下内容:
|
||||
* `LLM Provider` 设置为 `OpenAI`
|
||||
* `LLM Model` 设置为你将使用的模型。
|
||||
[访问此处查看 LiteLLM 支持的 OpenAI 模型的完整列表。](https://docs.litellm.ai/docs/providers/openai#openai-chat-completion-models)
|
||||
如果模型不在列表中,请切换 `Advanced Options`,并在 `Custom Model` 中输入它(例如 openai/<model-name> 如 `openai/gpt-4o`)。
|
||||
* `API Key` 设置为你的 OpenAI API 密钥。要查找或创建你的 OpenAI 项目 API 密钥,[请参阅此处](https://platform.openai.com/api-keys)。
|
||||
|
||||
## 使用 OpenAI 兼容端点
|
||||
|
||||
就像 OpenAI 聊天补全一样,我们使用 LiteLLM 进行 OpenAI 兼容端点。你可以在[这里](https://docs.litellm.ai/docs/providers/openai_compatible)找到他们关于此主题的完整文档。
|
||||
|
||||
## 使用 OpenAI 代理
|
||||
|
||||
如果你使用 OpenAI 代理,你需要在设置中设置以下内容:
|
||||
* 启用 `Advanced Options`
|
||||
* `Custom Model` 设置为 openai/<model-name>(例如 `openai/gpt-4o` 或 openai/<proxy-prefix>/<model-name>)
|
||||
* `Base URL` 设置为你的 OpenAI 代理的 URL
|
||||
* `API Key` 设置为你的 OpenAI API 密钥
|
||||
@@ -0,0 +1,14 @@
|
||||
以下是翻译后的内容:
|
||||
|
||||
# OpenRouter
|
||||
|
||||
OpenHands 使用 LiteLLM 调用 OpenRouter 上的聊天模型。你可以在[这里](https://docs.litellm.ai/docs/providers/openrouter)找到他们关于使用 OpenRouter 作为提供者的文档。
|
||||
|
||||
## 配置
|
||||
|
||||
运行 OpenHands 时,你需要在设置中设置以下内容:
|
||||
* `LLM Provider` 设置为 `OpenRouter`
|
||||
* `LLM Model` 设置为你将使用的模型。
|
||||
[访问此处查看 OpenRouter 模型的完整列表](https://openrouter.ai/models)。
|
||||
如果模型不在列表中,请切换 `Advanced Options`,并在 `Custom Model` 中输入(例如 openrouter/<model-name> 如 `openrouter/anthropic/claude-3.5-sonnet`)。
|
||||
* `API Key` 设置为你的 OpenRouter API 密钥。
|
||||
@@ -0,0 +1,43 @@
|
||||
以下是翻译后的内容:
|
||||
|
||||
# 提示最佳实践
|
||||
|
||||
在使用 OpenHands AI 软件开发者时,提供清晰有效的提示至关重要。本指南概述了创建提示的最佳实践,以产生最准确和最有用的响应。
|
||||
|
||||
## 好的提示的特点
|
||||
|
||||
好的提示是:
|
||||
|
||||
1. **具体的**: 它们准确解释应该添加什么功能或需要修复什么错误。
|
||||
2. **位置特定的**: 如果已知,它们解释了应该修改代码库中的哪些位置。
|
||||
3. **适当范围的**: 它们应该是单个功能的大小,通常不超过100行代码。
|
||||
|
||||
## 示例
|
||||
|
||||
### 好的提示示例
|
||||
|
||||
1. "在 `utils/math_operations.py` 中添加一个函数 `calculate_average`,它接受一个数字列表作为输入并返回它们的平均值。"
|
||||
|
||||
2. "修复 `frontend/src/components/UserProfile.tsx` 中第42行发生的 TypeError。错误表明我们试图访问 undefined 的属性。"
|
||||
|
||||
3. "为注册表单中的电子邮件字段实现输入验证。更新 `frontend/src/components/RegistrationForm.tsx` 以在提交之前检查电子邮件是否为有效格式。"
|
||||
|
||||
### 不好的提示示例
|
||||
|
||||
1. "让代码更好。"(太模糊,不具体)
|
||||
|
||||
2. "重写整个后端以使用不同的框架。"(范围不合适)
|
||||
|
||||
3. "用户身份验证中有一个错误。你能找到并修复它吗?"(缺乏具体性和位置信息)
|
||||
|
||||
## 有效提示的技巧
|
||||
|
||||
1. 尽可能具体地说明期望的结果或要解决的问题。
|
||||
2. 提供上下文,包括相关的文件路径和行号(如果可用)。
|
||||
3. 将大型任务分解为更小、更易管理的提示。
|
||||
4. 包括任何相关的错误消息或日志。
|
||||
5. 如果从上下文中不明显,请指定编程语言或框架。
|
||||
|
||||
请记住,您的提示越精确和信息量大,AI 就越能帮助您开发或修改 OpenHands 软件。
|
||||
|
||||
有关更多有用提示的示例,请参阅 [OpenHands 入门](./getting-started)。
|
||||
@@ -1,97 +1,51 @@
|
||||
---
|
||||
sidebar_position: 5
|
||||
---
|
||||
以下是翻译后的内容:
|
||||
|
||||
# 🚧 故障排除
|
||||
|
||||
以下是用户经常报告的一些错误信息。
|
||||
|
||||
我们将努力使安装过程更加简单,并改善这些错误信息。不过,现在您可以在下面找到您的错误信息,并查看是否有任何解决方法。
|
||||
|
||||
对于这些错误信息,**都已经有相关的报告**。请不要打开新的报告——只需在现有的报告中发表评论即可。
|
||||
|
||||
如果您发现更多信息或者一个解决方法,请提交一个 *PR* 来添加细节到这个文件中。
|
||||
有一些错误信息经常被用户报告。我们会尽量让安装过程更简单,但目前您可以在下面查找您的错误信息,看看是否有任何解决方法。如果您找到了更多关于这些问题的信息或解决方法,请提交一个 *PR* 来添加详细信息到这个文件。
|
||||
|
||||
:::tip
|
||||
如果您在 Windows 上运行并遇到问题,请查看我们的[Windows (WSL) 用户指南](troubleshooting/windows)。
|
||||
OpenHands 仅通过 [WSL](https://learn.microsoft.com/en-us/windows/wsl/install) 支持 Windows。
|
||||
请确保在您的 WSL 终端内运行所有命令。
|
||||
查看 [Windows 用户的 WSL 注意事项](troubleshooting/windows) 以获取一些故障排除指南。
|
||||
:::
|
||||
|
||||
## 无法连接到 Docker
|
||||
## 常见问题
|
||||
|
||||
[GitHub 问题](https://github.com/All-Hands-AI/OpenHands/issues/1226)
|
||||
* [无法连接到 Docker](#unable-to-connect-to-docker)
|
||||
* [404 资源未找到](#404-resource-not-found)
|
||||
* [`make build` 在安装包时卡住](#make-build-getting-stuck-on-package-installations)
|
||||
* [会话没有恢复](#sessions-are-not-restored)
|
||||
|
||||
### 症状
|
||||
### 无法连接到 Docker
|
||||
|
||||
[GitHub Issue](https://github.com/All-Hands-AI/OpenHands/issues/1226)
|
||||
|
||||
**症状**
|
||||
|
||||
```bash
|
||||
创建控制器时出错。请检查 Docker 是否正在运行,并访问 `https://docs.all-hands.dev/modules/usage/troubleshooting` 获取更多调试信息。
|
||||
Error creating controller. Please check Docker is running and visit `https://docs.all-hands.dev/modules/usage/troubleshooting` for more debugging information.
|
||||
```
|
||||
|
||||
```bash
|
||||
docker.errors.DockerException: 获取服务器 API 版本时出错: ('连接中止。', FileNotFoundError(2, '没有这样的文件或目录'))
|
||||
docker.errors.DockerException: Error while fetching server API version: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))
|
||||
```
|
||||
|
||||
### 详情
|
||||
**详情**
|
||||
|
||||
OpenHands 使用 Docker 容器来安全地完成工作,而不会破坏您的机器。
|
||||
OpenHands 使用 Docker 容器来安全地工作,而不会潜在地破坏您的机器。
|
||||
|
||||
### 解决方法
|
||||
**解决方法**
|
||||
|
||||
* 运行 `docker ps` 以确保 Docker 正在运行
|
||||
* 确保您不需要使用 `sudo` 运行 Docker [请参见此处](https://www.baeldung.com/linux/docker-run-without-sudo)
|
||||
* 如果您使用的是 Mac,请检查[权限要求](https://docs.docker.com/desktop/mac/permission-requirements/) ,特别是考虑在 Docker Desktop 的 `Settings > Advanced` 下启用 `Allow the default Docker socket to be used`。
|
||||
* 另外,升级您的 Docker 到最新版本,选择 `Check for Updates`
|
||||
* 运行 `docker ps` 以确保 docker 正在运行
|
||||
* 确保您不需要 `sudo` 来运行 docker [参见此处](https://www.baeldung.com/linux/docker-run-without-sudo)
|
||||
* 如果您在 Mac 上,请检查 [权限要求](https://docs.docker.com/desktop/mac/permission-requirements/),特别是考虑在 Docker Desktop 的 `Settings > Advanced` 下启用 `Allow the default Docker socket to be used`。
|
||||
* 此外,在 `Check for Updates` 下将您的 Docker 升级到最新版本
|
||||
|
||||
## 无法连接到 DockerSSHBox
|
||||
---
|
||||
### `404 资源未找到`
|
||||
|
||||
[GitHub 问题](https://github.com/All-Hands-AI/OpenHands/issues/1156)
|
||||
|
||||
### 症状
|
||||
|
||||
```python
|
||||
self.shell = DockerSSHBox(
|
||||
...
|
||||
pexpect.pxssh.ExceptionPxssh: Could not establish connection to host
|
||||
```
|
||||
|
||||
### 详情
|
||||
|
||||
默认情况下,OpenHands 使用 SSH 连接到一个运行中的容器。在某些机器上,尤其是 Windows,这似乎会失败。
|
||||
|
||||
### 解决方法
|
||||
|
||||
* 重新启动您的计算机(有时会有用)
|
||||
* 确保拥有最新版本的 WSL 和 Docker
|
||||
* 检查您的 WSL 分发版也已更新
|
||||
* 尝试[此重新安装指南](https://github.com/All-Hands-AI/OpenHands/issues/1156#issuecomment-2064549427)
|
||||
|
||||
## 无法连接到 LLM
|
||||
|
||||
[GitHub 问题](https://github.com/All-Hands-AI/OpenHands/issues/1208)
|
||||
|
||||
### 症状
|
||||
|
||||
```python
|
||||
File "/app/.venv/lib/python3.12/site-packages/openai/_exceptions.py", line 81, in __init__
|
||||
super().__init__(message, response.request, body=body)
|
||||
^^^^^^^^^^^^^^^^
|
||||
AttributeError: 'NoneType' object has no attribute 'request'
|
||||
```
|
||||
|
||||
### 详情
|
||||
|
||||
[GitHub 问题](https://github.com/All-Hands-AI/OpenHands/issues?q=is%3Aissue+is%3Aopen+404)
|
||||
|
||||
这通常发生在本地 LLM 设置中,当 OpenHands 无法连接到 LLM 服务器时。请参阅我们的 [本地 LLM 指南](llms/local-llms) 以获取更多信息。
|
||||
|
||||
### 解决方法
|
||||
|
||||
* 检查您的 `config.toml` 文件中 "llm" 部分的 `base_url` 是否正确(如果存在)
|
||||
* 检查 Ollama(或您使用的其他 LLM)是否正常运行
|
||||
* 确保在 Docker 中运行时使用 `--add-host host.docker.internal:host-gateway`
|
||||
|
||||
## `404 Resource not found 资源未找到`
|
||||
|
||||
### 症状
|
||||
**症状**
|
||||
|
||||
```python
|
||||
Traceback (most recent call last):
|
||||
@@ -117,29 +71,29 @@ Traceback (most recent call last):
|
||||
openai.NotFoundError: Error code: 404 - {'error': {'code': '404', 'message': 'Resource not found'}}
|
||||
```
|
||||
|
||||
### 详情
|
||||
**详情**
|
||||
|
||||
当 LiteLLM(我们用于连接不同 LLM 提供商的库)找不到您要连接的 API 端点时,会发生这种情况。最常见的情况是 Azure 或 Ollama 用户。
|
||||
当 LiteLLM(我们用于连接不同 LLM 提供商的库)找不到您尝试连接的 API 端点时,就会发生这种情况。这种情况最常发生在 Azure 或 ollama 用户身上。
|
||||
|
||||
### 解决方法
|
||||
**解决方法**
|
||||
|
||||
* 检查您是否正确设置了 `LLM_BASE_URL`
|
||||
* 检查模型是否正确设置,基于 [LiteLLM 文档](https://docs.litellm.ai/docs/providers)
|
||||
* 如果您在 UI 中运行,请确保在设置模式中设置 `model`
|
||||
* 如果您通过 main.py 运行,请确保在环境变量/配置中设置 `LLM_MODEL`
|
||||
* 确保遵循了您的 LLM 提供商的任何特殊说明
|
||||
* [Ollama](/zh-Hans/modules/usage/llms/local-llms)
|
||||
* [Azure](/zh-Hans/modules/usage/llms/azure-llms)
|
||||
* [Google](/zh-Hans/modules/usage/llms/google-llms)
|
||||
* 确保您的 API 密钥正确无误
|
||||
* 尝试使用 `curl` 连接到 LLM
|
||||
* 尝试[直接通过 LiteLLM 连接](https://github.com/BerriAI/litellm)来测试您的设置
|
||||
* 根据 [LiteLLM 文档](https://docs.litellm.ai/docs/providers) 检查模型是否设置正确
|
||||
* 如果您在 UI 内运行,请确保在设置模态框中设置 `model`
|
||||
* 如果您在无头模式下运行(通过 main.py),请确保在您的 env/config 中设置 `LLM_MODEL`
|
||||
* 确保您已遵循 LLM 提供商的任何特殊说明
|
||||
* [Azure](/modules/usage/llms/azure-llms)
|
||||
* [Google](/modules/usage/llms/google-llms)
|
||||
* 确保您的 API 密钥正确
|
||||
* 看看您是否可以使用 `curl` 连接到 LLM
|
||||
* 尝试 [直接通过 LiteLLM 连接](https://github.com/BerriAI/litellm) 以测试您的设置
|
||||
|
||||
## `make build` 在安装包时卡住
|
||||
---
|
||||
### `make build` 在安装包时卡住
|
||||
|
||||
### 症状
|
||||
**症状**
|
||||
|
||||
安装包时卡在 `Pending...`,没有任何错误信息:
|
||||
包安装在 `Pending...` 处卡住,没有任何错误信息:
|
||||
|
||||
```bash
|
||||
Package operations: 286 installs, 0 updates, 0 removals
|
||||
@@ -151,42 +105,44 @@ Package operations: 286 installs, 0 updates, 0 removals
|
||||
- Installing typing-extensions (4.11.0): Pending...
|
||||
```
|
||||
|
||||
### 详情
|
||||
**详情**
|
||||
|
||||
在极少数情况下,`make build` 在安装包时似乎会卡住,没有任何错误信息。
|
||||
在极少数情况下,`make build` 可能会在安装包时看似卡住,没有任何错误信息。
|
||||
|
||||
### 解决方法
|
||||
**解决方法**
|
||||
|
||||
* 包管理器 Poetry 可能会错过用于查找凭据的配置设置(keyring)。
|
||||
包安装程序 Poetry 可能缺少一个配置设置,用于查找凭据的位置(keyring)。
|
||||
|
||||
### 解决方法
|
||||
|
||||
首先使用 `env` 检查是否存在 `PYTHON_KEYRING_BACKEND` 的值。如果不存在,运行以下命令将其设置为已知值,然后重试构建:
|
||||
首先用 `env` 检查是否存在 `PYTHON_KEYRING_BACKEND` 的值。
|
||||
如果没有,运行下面的命令将其设置为一个已知值,然后重试构建:
|
||||
|
||||
```bash
|
||||
export PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring
|
||||
```
|
||||
|
||||
## 会话未恢复
|
||||
---
|
||||
### 会话没有恢复
|
||||
|
||||
### 症状
|
||||
**症状**
|
||||
|
||||
通常情况下,当打开 UI 时,OpenHands 会询问是否要恢复或开始新会话。但点击“恢复”仍然会开始一个全新的聊天。
|
||||
OpenHands 通常在打开 UI 时询问是恢复还是开始新会话。
|
||||
但是点击"恢复"仍然会开始一个全新的聊天。
|
||||
|
||||
### 详情
|
||||
**详情**
|
||||
|
||||
按今天的标准安装,会话数据存储在内存中。目前,如果 OpenHands 的服务重启,以前的会话将失效(生成一个新秘密),因此无法恢复。
|
||||
截至目前,使用标准安装,会话数据存储在内存中。
|
||||
目前,如果 OpenHands 的服务重新启动,之前的会话会变得无效(生成一个新的密钥),因此无法恢复。
|
||||
|
||||
### 解决方法
|
||||
**解决方法**
|
||||
|
||||
* 通过编辑 OpenHands 根文件夹中的 `config.toml` 文件,更改配置以使会话持久化,指定一个 `file_store` 和一个绝对路径的 `file_store_path`:
|
||||
* 通过编辑 `config.toml` 文件(在 OpenHands 的根文件夹中)来更改配置,使会话持久化,指定一个 `file_store` 和一个绝对的 `file_store_path`:
|
||||
|
||||
```toml
|
||||
file_store="local"
|
||||
file_store_path="/absolute/path/to/openhands/cache/directory"
|
||||
```
|
||||
|
||||
* 在您的 .bashrc 中添加一个固定的 JWT 秘密,如下所示,以便以前的会话 ID 可以被接受。
|
||||
* 在您的 .bashrc 中添加一个固定的 jwt 密钥,如下所示,这样之前的会话 id 应该可以保持被接受。
|
||||
|
||||
```bash
|
||||
EXPORT JWT_SECRET=A_CONST_VALUE
|
||||
|
||||
@@ -1,68 +1,58 @@
|
||||
# Windows 和 WSL 用户须知
|
||||
以下是翻译后的内容:
|
||||
|
||||
OpenHands 仅支持通过 [WSL](https://learn.microsoft.com/en-us/windows/wsl/install) 在 Windows 上运行。
|
||||
请确保在 WSL 终端内运行所有命令。
|
||||
# 针对 Windows 上 WSL 用户的注意事项
|
||||
|
||||
OpenHands 仅通过 [WSL](https://learn.microsoft.com/en-us/windows/wsl/install) 支持 Windows。
|
||||
请确保在您的 WSL 终端内运行所有命令。
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 错误:在此 WSL 2 发行版中找不到 'docker'。
|
||||
### 建议: 不要以 root 用户身份运行
|
||||
|
||||
如果您使用的是 Docker Desktop,请确保在 WSL 内部调用任何 docker 命令之前启动它。
|
||||
Docker 还需要启用 WSL 集成选项。
|
||||
出于安全原因,强烈建议不要以 root 用户身份运行 OpenHands,而是以具有非零 UID 的用户身份运行。
|
||||
|
||||
### 建议:不要以 root 用户身份运行
|
||||
参考:
|
||||
|
||||
出于安全原因,非常建议不要以 root 用户身份运行 OpenHands,而是使用 UID 非零的用户身份运行。
|
||||
此外,当以 root 身份运行时,不支持持久化沙箱,并且在启动 OpenHands 时可能会出现相应消息。
|
||||
|
||||
参考资料:
|
||||
|
||||
* [为什么以 root 登录是不好的](https://askubuntu.com/questions/16178/why-is-it-bad-to-log-in-as-root)
|
||||
* [为什么以 root 身份登录不好](https://askubuntu.com/questions/16178/why-is-it-bad-to-log-in-as-root)
|
||||
* [在 WSL 中设置默认用户](https://www.tenforums.com/tutorials/128152-set-default-user-windows-subsystem-linux-distro-windows-10-a.html#option2)
|
||||
关于第二个参考资料的小提示:对于 Ubuntu 用户,该命令实际上可能是 "ubuntupreview" 而不是 "ubuntu"。
|
||||
关于第二个参考的提示:对于 Ubuntu 用户,命令实际上可能是 "ubuntupreview" 而不是 "ubuntu"。
|
||||
|
||||
### 创建 openhands 用户失败
|
||||
---
|
||||
### 错误: 在此 WSL 2 发行版中找不到 'docker'。
|
||||
|
||||
如果您在设置过程中遇到以下错误:
|
||||
|
||||
```sh
|
||||
Exception: Failed to create openhands user in sandbox: 'useradd: UID 0 is not unique'
|
||||
```
|
||||
|
||||
您可以通过运行以下命令解决:
|
||||
|
||||
```sh
|
||||
export SANDBOX_USER_ID=1000
|
||||
```
|
||||
如果您正在使用 Docker Desktop,请确保在从 WSL 内部调用任何 docker 命令之前启动它。
|
||||
Docker 还需要激活 WSL 集成选项。
|
||||
|
||||
---
|
||||
### Poetry 安装
|
||||
|
||||
* 如果在构建过程中安装 Poetry 后仍然面临运行 Poetry 的问题,您可能需要将其二进制路径添加到您的环境变量:
|
||||
* 如果您在构建过程中安装 Poetry 后仍然面临运行 Poetry 的问题,您可能需要将其二进制路径添加到环境中:
|
||||
|
||||
```sh
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
```
|
||||
|
||||
* 如果 make build 停止并出现如下错误:
|
||||
* 如果 make build 在如下错误上停止:
|
||||
|
||||
```sh
|
||||
ModuleNotFoundError: no module named <module-name>
|
||||
```
|
||||
|
||||
这可能是 Poetry 缓存的问题。
|
||||
尝试运行以下两个命令:
|
||||
尝试依次运行这两个命令:
|
||||
|
||||
```sh
|
||||
rm -r ~/.cache/pypoetry
|
||||
make build
|
||||
```
|
||||
|
||||
---
|
||||
### NoneType 对象没有属性 'request'
|
||||
|
||||
如果您在执行 `make run` 时遇到与网络相关的问题,例如 `NoneType object has no attribute 'request'`,您可能需要配置您的 WSL2 网络设置。请按照以下步骤操作:
|
||||
如果您在执行 `make run` 时遇到与网络相关的问题,例如 `NoneType 对象没有属性 'request'`,您可能需要配置 WSL2 网络设置。请按照以下步骤操作:
|
||||
|
||||
* 打开或创建位于 Windows 主机机器上的 `C:\Users\%username%\.wslconfig` 文件。
|
||||
* 向 `.wslconfig` 文件添加以下配置:
|
||||
* 在 Windows 主机上打开或创建位于 `C:\Users\%username%\.wslconfig` 的 `.wslconfig` 文件。
|
||||
* 将以下配置添加到 `.wslconfig` 文件中:
|
||||
|
||||
```sh
|
||||
[wsl2]
|
||||
@@ -71,6 +61,6 @@ localhostForwarding=true
|
||||
```
|
||||
|
||||
* 保存 `.wslconfig` 文件。
|
||||
* 通过退出所有正在运行的 WSL2 实例并在命令提示符或终端中执行 `wsl --shutdown` 命令,完全重启 WSL2。
|
||||
* 重新启动 WSL 后,尝试再次执行 `make run`。
|
||||
网络问题应该已经解决。
|
||||
* 通过退出任何正在运行的 WSL2 实例并在命令提示符或终端中执行 `wsl --shutdown` 命令来完全重启 WSL2。
|
||||
* 重新启动 WSL 后,再次尝试执行 `make run`。
|
||||
网络问题应该得到解决。
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
以下是翻译后的内容:
|
||||
|
||||
# ⬆️ 升级指南
|
||||
|
||||
## 0.8.0 (2024-07-13)
|
||||
|
||||
### 配置中的重大变更
|
||||
|
||||
在此版本中,我们对后端配置引入了一些重大变更。如果你只通过前端(Web GUI)使用OpenHands,则无需处理任何事情。
|
||||
|
||||
以下是配置中重大变更的列表。它们仅适用于通过 `main.py` 使用 OpenHands CLI 的用户。更多详情,请参阅 [#2756](https://github.com/All-Hands-AI/OpenHands/pull/2756)。
|
||||
|
||||
#### 从 main.py 中移除 --model-name 选项
|
||||
|
||||
请注意,`--model-name` 或 `-m` 选项已不再存在。你应该在 `config.toml` 中设置 LLM 配置,或通过环境变量进行设置。
|
||||
|
||||
#### LLM 配置组必须是 'llm' 的子组
|
||||
|
||||
在 0.8 版本之前,你可以在 `config.toml` 中为 LLM 配置使用任意名称,例如:
|
||||
|
||||
```toml
|
||||
[gpt-4o]
|
||||
model="gpt-4o"
|
||||
api_key="<your_api_key>"
|
||||
```
|
||||
|
||||
然后使用 `--llm-config` CLI 参数按名称指定所需的 LLM 配置组。这已不再有效。相反,配置组必须位于 `llm` 组下,例如:
|
||||
|
||||
```toml
|
||||
[llm.gpt-4o]
|
||||
model="gpt-4o"
|
||||
api_key="<your_api_key>"
|
||||
```
|
||||
|
||||
如果你有一个名为 `llm` 的配置组,则无需更改它,它将被用作默认的 LLM 配置组。
|
||||
|
||||
#### 'agent' 组不再包含 'name' 字段
|
||||
|
||||
在 0.8 版本之前,你可能有或没有一个名为 `agent` 的配置组,如下所示:
|
||||
|
||||
```toml
|
||||
[agent]
|
||||
name="CodeActAgent"
|
||||
memory_max_threads=2
|
||||
```
|
||||
|
||||
请注意,`name` 字段现已被移除。相反,你应该在 `core` 组下放置 `default_agent` 字段,例如:
|
||||
|
||||
```toml
|
||||
[core]
|
||||
# 其他配置
|
||||
default_agent='CodeActAgent'
|
||||
|
||||
[agent]
|
||||
llm_config='llm'
|
||||
memory_max_threads=2
|
||||
|
||||
[agent.CodeActAgent]
|
||||
llm_config='gpt-4o'
|
||||
```
|
||||
|
||||
请注意,与 `llm` 子组类似,你也可以定义 `agent` 子组。此外,代理可以与特定的 LLM 配置组相关联。更多详情,请参阅 `config.template.toml` 中的示例。
|
||||
@@ -1,7 +1,3 @@
|
||||
---
|
||||
sidebar_position: 8
|
||||
---
|
||||
|
||||
# 📚 Misc
|
||||
|
||||
## ⭐️ Research Strategy
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# 🧠 Main Agent and Capabilities
|
||||
|
||||
## CodeActAgent
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
---
|
||||
sidebar_position: 7
|
||||
---
|
||||
|
||||
# 🏛️ System Architecture
|
||||
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
|
||||
@@ -21,7 +21,7 @@ The OpenHands Runtime system uses a client-server architecture implemented with
|
||||
graph TD
|
||||
A[User-provided Custom Docker Image] --> B[OpenHands Backend]
|
||||
B -->|Builds| C[OH Runtime Image]
|
||||
C -->|Launches| D[Runtime Client]
|
||||
C -->|Launches| D[Action Executor]
|
||||
D -->|Initializes| E[Browser]
|
||||
D -->|Initializes| F[Bash Shell]
|
||||
D -->|Initializes| G[Plugins]
|
||||
@@ -49,10 +49,10 @@ graph TD
|
||||
1. User Input: The user provides a custom base Docker image
|
||||
2. Image Building: OpenHands builds a new Docker image (the "OH runtime image") based on the user-provided image. This new image includes OpenHands-specific code, primarily the "runtime client"
|
||||
3. Container Launch: When OpenHands starts, it launches a Docker container using the OH runtime image
|
||||
4. Client Initialization: The runtime client initializes inside the container, setting up necessary components like a bash shell and loading any specified plugins
|
||||
5. Communication: The OpenHands backend (`runtime.py`) communicates with the runtime client over RESTful API, sending actions and receiving observations
|
||||
4. Action Execution Server Initialization: The action execution server initializes an `ActionExecutor` inside the container, setting up necessary components like a bash shell and loading any specified plugins
|
||||
5. Communication: The OpenHands backend (`openhands/runtime/impl/eventstream/eventstream_runtime.py`) communicates with the action execution server over RESTful API, sending actions and receiving observations
|
||||
6. Action Execution: The runtime client receives actions from the backend, executes them in the sandboxed environment, and sends back observations
|
||||
7. Observation Return: The client sends execution results back to the OpenHands backend as observations
|
||||
7. Observation Return: The action execution server sends execution results back to the OpenHands backend as observations
|
||||
|
||||
|
||||
The role of the client:
|
||||
@@ -70,74 +70,54 @@ Check out the [relevant code](https://github.com/All-Hands-AI/OpenHands/blob/mai
|
||||
|
||||
### Image Tagging System
|
||||
|
||||
OpenHands uses a dual-tagging system for its runtime images to balance reproducibility with flexibility:
|
||||
OpenHands uses a three-tag system for its runtime images to balance reproducibility with flexibility.
|
||||
Tags may be in one of 2 formats:
|
||||
|
||||
1. Hash-based tag: `{target_image_repo}:{target_image_hash_tag}`.
|
||||
Example: `runtime:abc123def456`
|
||||
- **Versioned Tag**: `oh_v{openhands_version}_{base_image}` (e.g.: `oh_v0.9.9_nikolaik_s_python-nodejs_t_python3.12-nodejs22`)
|
||||
- **Lock Tag**: `oh_v{openhands_version}_{16_digit_lock_hash}` (e.g.: `oh_v0.9.9_1234567890abcdef`)
|
||||
- **Source Tag**: `oh_v{openhands_version}_{16_digit_lock_hash}_{16_digit_source_hash}`
|
||||
(e.g.: `oh_v0.9.9_1234567890abcdef_1234567890abcdef`)
|
||||
|
||||
- This tag is based on the MD5 hash of the Docker build folder, which includes the source code (of runtime client and related dependencies) and Dockerfile
|
||||
- Identical hash tags guarantee that the images were built with exactly the same source code and Dockerfile
|
||||
- This ensures reproducibility; the same hash always means the same image contents
|
||||
|
||||
2. Generic tag: `{target_image_repo}:{target_image_tag}`.
|
||||
Example: `runtime:oh_v0.9.3_ubuntu_tag_22.04`
|
||||
#### Source Tag - Most Specific
|
||||
|
||||
- This tag follows the format: `runtime:oh_v{OH_VERSION}_{BASE_IMAGE_NAME}_tag_{BASE_IMAGE_TAG}`
|
||||
- It represents the latest build for a particular base image and OpenHands version combination
|
||||
- This tag is updated whenever a new image is built from the same base image, even if the source code changes
|
||||
This is the first 16 digits of the MD5 of the directory hash for the source directory. This gives a hash
|
||||
for only the openhands source
|
||||
|
||||
The hash-based tag ensures reproducibility, while the generic tag provides a stable reference to the latest version of a particular configuration. This dual-tagging approach allows OpenHands to efficiently manage both development and production environments.
|
||||
|
||||
### Build Process
|
||||
#### Lock Tag
|
||||
|
||||
1. Image Naming Convention:
|
||||
- Hash-based tag: `{target_image_repo}:{target_image_hash_tag}`.
|
||||
Example: `runtime:abc123def456`
|
||||
- Generic tag: `{target_image_repo}:{target_image_tag}`.
|
||||
Example: `runtime:oh_v0.9.3_ubuntu_tag_22.04`
|
||||
This hash is built from the first 16 digits of the MD5 of:
|
||||
- The name of the base image upon which the image was built (e.g.: `nikolaik/python-nodejs:python3.12-nodejs22`)
|
||||
- The content of the `pyproject.toml` included in the image.
|
||||
- The content of the `poetry.lock` included in the image.
|
||||
|
||||
2. Build Process:
|
||||
- a. Convert the base image name to an OH runtime image name
|
||||
Example: `ubuntu:22.04` -> `runtime:oh_v0.9.3_ubuntu_tag_22.04`
|
||||
- b. Generate a build context (Dockerfile and OpenHands source code) and calculate its hash
|
||||
- c. Check for an existing image with the calculated hash
|
||||
- d. If not found, check for a recent compatible image to use as a base
|
||||
- e. If no compatible image exists, build from scratch using the original base image
|
||||
- f. Tag the new image with both hash-based and generic tags
|
||||
This effectively gives a hash for the dependencies of Openhands independent of the source code.
|
||||
|
||||
3. Image Reuse and Rebuilding Logic:
|
||||
The system follows these steps to determine whether to build a new image or use an existing one from a user-provided (base) image (e.g., `ubuntu:22.04`):
|
||||
- a. If an image exists with the same hash (e.g., `runtime:abc123def456`), it will be reused as is
|
||||
- b. If the exact hash is not found, the system will try to rebuild using the latest generic image (e.g., `runtime:oh_v0.9.3_ubuntu_tag_22.04`) as a base. This saves time by leveraging existing dependencies
|
||||
- c. If neither the hash-tagged nor the generic-tagged image is found, the system will build the image completely from scratch
|
||||
#### Versioned Tag - Most Generic
|
||||
|
||||
4. Caching and Efficiency:
|
||||
- The system attempts to reuse existing images when possible to save build time
|
||||
- If an exact match (by hash) is found, it's used without rebuilding
|
||||
- If a compatible image is found, it's used as a base for rebuilding, saving time on dependency installation
|
||||
This tag is a concatenation of openhands version and the base image name (transformed to fit in tag standard).
|
||||
|
||||
Here's a flowchart illustrating the build process:
|
||||
#### Build Process
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Start] --> B{Convert base image name}
|
||||
B --> |ubuntu:22.04 -> runtime:oh_v0.9.3_ubuntu_tag_22.04| C[Generate build context and hash]
|
||||
C --> D{Check for existing image with hash}
|
||||
D -->|Found runtime:abc123def456| E[Use existing image]
|
||||
D -->|Not found| F{Check for runtime:oh_v0.9.3_ubuntu_tag_22.04}
|
||||
F -->|Found| G[Rebuild based on recent image]
|
||||
F -->|Not found| H[Build from scratch]
|
||||
G --> I[Tag with hash and generic tags]
|
||||
H --> I
|
||||
E --> J[End]
|
||||
I --> J
|
||||
```
|
||||
When generating an image...
|
||||
|
||||
This approach ensures that:
|
||||
- **No re-build**: OpenHands first checks whether an image with the same **most specific source tag** exists. If there is such an image,
|
||||
no build is performed - the existing image is used.
|
||||
- **Fastest re-build**: OpenHands next checks whether an image with the **generic lock tag** exists. If there is such an image,
|
||||
OpenHands builds a new image based upon it, bypassing all installation steps (like `poetry install` and
|
||||
`apt-get`) except a final operation to copy the current source code. The new image is tagged with a
|
||||
**source** tag only.
|
||||
- **Ok-ish re-build**: If neither a **source** nor **lock** tag exists, an image will be built based upon the **versioned** tag image.
|
||||
In versioned tag image, most dependencies should already been installed hence saving time.
|
||||
- **Slowest re-build**: If all of the three tags don't exists, a brand new image is built based upon the base
|
||||
image (Which is a slower operation). This new image is tagged with all the **source**, **lock**, and **versioned** tags.
|
||||
|
||||
This tagging approach allows OpenHands to efficiently manage both development and production environments.
|
||||
|
||||
1. Identical source code and Dockerfile always produce the same image (via hash-based tags)
|
||||
2. The system can quickly rebuild images when minor changes occur (by leveraging recent compatible images)
|
||||
3. The generic tag (e.g., `runtime:oh_v0.9.3_ubuntu_tag_22.04`) always points to the latest build for a particular base image and OpenHands version combination
|
||||
3. The **lock** tag (e.g., `runtime:oh_v0.9.3_1234567890abcdef`) always points to the latest build for a particular base image, dependency, and OpenHands version combination
|
||||
|
||||
## Runtime Plugin System
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user