Compare commits

...

352 Commits

Author SHA1 Message Date
Xingyao Wang
a4fd2402c2 support GPT-5-Codex in CLI 2025-10-06 17:02:09 -04:00
Graham Neubig
d1f8877600 Fix: Consolidate multi-line error logs into single-line JSON format (#11249)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-10-06 13:16:58 -04:00
Alona
08118d742b increase remote_runtime_api_timeout and handle duplicate secrets (#11239) 2025-10-06 22:40:45 +07:00
Hiep Le
c62a6616db feat(frontend): integrate with Reo.dev (#11251) 2025-10-06 21:37:25 +07:00
Xingyao Wang
fbf0429434 Filter all warnings in CLI when DEBUG is disabled (#11246)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-10-06 21:26:04 +08:00
Atharv Patil
0e2edb63f5 fix(frontend): Fixed prompt box resizing behavior (fixes #11025) (#11035) 2025-10-06 19:29:45 +07:00
Graham Neubig
50b38e9081 fix: migrate to PostHog v6.x API (#11241)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-10-05 21:38:37 -04:00
Yakshith
e9c3335656 fix: correct file ownership on mounted volumes (#11231) 2025-10-05 01:09:33 +00:00
Rohit Malhotra
3bf038ed7c CLI(V1) (#11220)
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: Xingyao Wang <xingyao@all-hands.dev>
2025-10-04 17:14:36 -04:00
caocao-sys
408f8aa50f fix: RollingLogger move_back method ignoring amount parameter (#10874) (#10875)
Co-authored-by: shikaixuan <shikaixuan@baidu.com>
2025-10-03 22:49:33 +02:00
mamoodi
025ac7672f Update docs (#11224) 2025-10-03 14:29:24 -04:00
Yakshith
aab6f4127c fix(frontend): improve chat input status indicator responsiveness (#11202)
Co-authored-by: Hiep Le <69354317+hieptl@users.noreply.github.com>
Co-authored-by: mamoodi <mamoodiha@gmail.com>
Co-authored-by: chuckbutkus <chuck@all-hands.dev>
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: Robert Brennan <accounts@rbren.io>
Co-authored-by: Jamie Chicago <87397251+jamiechicago312@users.noreply.github.com>
2025-10-03 01:36:38 +07:00
Hiep Le
c932cd0815 fix(frontend): org level microagents not appearing (microagent management) (#11218) 2025-10-02 22:19:02 +07:00
Hiep Le
d3395172f8 fix(frontend): search repos (microagent management) (#11217) 2025-10-02 22:18:43 +07:00
sp.wack
1e8851b244 feat: V1 client types (#11216)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-10-02 15:02:37 +00:00
Jamie Chicago
167fb3f429 Replace dub.sh/openhands links with all-hands.dev/joinslack (#11209)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-10-01 20:00:00 +00:00
Robert Brennan
df4d30addf Add POST /api/conversations/{id}/message endpoint (#11177)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-10-01 15:35:29 -04:00
chuckbutkus
37daf068c5 Allow custom user (#11013)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-10-01 17:48:25 +00:00
mamoodi
5452abe513 Release 0.58.0 (#11168) 2025-10-01 13:18:20 -04:00
Hiep Le
a8b6406dac fix: searching repositories (#11203) 2025-10-01 22:21:20 +07:00
Hiep Le
509d4a9513 fix(frontend): the horizontal scrollbar is not displayed for the markdown content (#11200) 2025-10-01 12:31:56 +07:00
Alona
d099c21f5d fix: add provider tokens to resume conversation endpoint (#11155) 2025-10-01 05:20:48 +07:00
Hiep Le
4c89b5ad91 fix: showing unrelated files in the changes tab (#11185)
Co-authored-by: Graham Neubig <neubig@gmail.com>
2025-10-01 01:44:36 +07:00
sp.wack
729c181313 Revert "fix(backend): Add validation for LLM settings to prevent non-pro user bypass" (#11192) 2025-09-30 17:54:33 +00:00
Hiep Le
2eb3a9e6ad refactor(frontend): migration of use-ws-error-message.ts to zustand (#11147) 2025-09-30 22:51:17 +07:00
Hiep Le
2382baacc2 feat(frontend): persist recent repos (#11171) 2025-09-30 22:15:36 +07:00
dependabot[bot]
98ce55e2fc chore(deps): bump the version-all group across 1 directory with 12 updates (#11174)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-30 13:18:09 +00:00
Ray Myers
c929447624 Tag enterprise-server image with PR Head (#11182) 2025-09-30 08:58:20 -04:00
Hiep Le
2cc77fb034 refactor(frontend): migration of use-optimistic-user-message.ts to zustand (#11148) 2025-09-30 19:56:07 +07:00
Hiep Le
d57462e8ca refactor(frontend): update the not found message displayed when no repositories match the search query (#11187) 2025-09-30 19:55:52 +07:00
Hiep Le
1e23017bb1 fix(frontend): pause agent button (chat interface) (#11172) 2025-09-30 19:55:25 +07:00
Hiep Le
3493348fac refactor(frontend): align chat message action buttons (#11173) 2025-09-30 19:55:09 +07:00
Web3 Outlaw
e63d981192 Upgrade Volta Node to 22.x (#11166) 2025-09-30 16:47:33 +04:00
Xingyao Wang
e19b3dd1f0 Add claude-sonnet-4-5 model support (#11179)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-30 03:27:19 +00:00
Ray Myers
c3da6c20bd chore - Upgrade to Debian Trixie in app image and runtime image option (#11114) 2025-09-29 21:08:48 +00:00
mamoodi
a022f505a8 Remove legacy README_CN.md and README_JA.md translation files (#11169)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-29 22:08:59 +02:00
Hiep Le
04196f8d53 fix(frontend): duplicate LLM navigation items in settings sidebar (#11176) 2025-09-29 15:34:04 -04:00
mamoodi
dcf00c34fa remove broken screenshot (#11167) 2025-09-29 09:35:57 -04:00
Robert Brennan
d4e94b32e1 Remove missing user message check for REMOTE_API_KEY (#11164) 2025-09-29 08:57:04 +08:00
Engel Nyst
a1b81fe923 Enable native tool calling for Anthropic Claude 3.5 Sonnet (dot-notation) models (#11156)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-28 00:38:37 +02:00
mamoodi
e6d799c51a Remove discord links as it winds down and some small doc updates (#11145) 2025-09-27 08:00:03 -04:00
sp.wack
fb6f688049 refactor(frontend): convert settings to vertical sidebar layout (#10971)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-26 13:57:37 +00:00
sp.wack
ef12adc107 fix(backend): Add validation for LLM settings to prevent non-pro user bypass (#11113) 2025-09-26 16:10:09 +04:00
Hiep Le
8a7a5cce5e refactor(frontend): remove store.ts file (#11119)
Co-authored-by: sp.wack <83104063+amanape@users.noreply.github.com>
2025-09-26 10:03:18 +07:00
mamoodi
b883fe37e6 fix MCP links (#11137) 2025-09-25 23:32:19 +00:00
mamoodi
182b7adcab Clean up MCP docs and move it to settings (#11133) 2025-09-25 18:28:29 -04:00
mamoodi
63829d0f45 Fix help links for OpenHands Provider (#11128)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-25 19:04:48 +00:00
jpelletier1
830a9e027f docs: Add Pro Subscription documentation page (#11115)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-25 13:07:30 -04:00
mamoodi
120a5d6ebd Add new settings folder for better organization (#11118) 2025-09-25 12:06:10 -04:00
mamoodi
6b1d1869f3 Run pypi workflow on tags (#11112) 2025-09-25 14:03:01 +00:00
Hiep Le
e376c2bfd1 refactor(frontend): migration of agent-slice.ts to zustand (#11102) 2025-09-25 12:44:21 +07:00
mamoodi
f8f74858da Update parts of the OpenHands Cloud docs (#11107) 2025-09-24 16:27:52 -04:00
Ray Myers
848a884b04 chore - Track Python test coverage (#11072) 2025-09-24 15:27:34 -05:00
Hiep Le
88a58a1748 refactor(frontend): migration of jupyter-slice.ts to zustand (#11019) 2025-09-25 00:56:55 +07:00
Hiep Le
f59ea69b70 refactor(frontend): migration of microagent-management-slice.ts to zustand (#11033) 2025-09-24 23:58:17 +07:00
dependabot[bot]
8f004a1f6d chore(deps-dev): bump @tanstack/eslint-plugin-query from 5.86.0 to 5.90.1 in /frontend in the eslint group (#11101)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-24 20:53:20 +04:00
sp.wack
15b4690ebf feat(frontend): Animate conversation panels (#11099) 2025-09-24 16:41:19 +00:00
Hiep Le
df1c5bbf85 refactor(frontend): migration of event-message-slice.ts to zustand (#11080) 2025-09-24 22:53:45 +07:00
Hiep Le
8adbb76bd7 refactor(frontend): migration of browser-slice.ts to zustand (#11081) 2025-09-24 22:52:48 +07:00
Hiep Le
0095672439 feat(frontend): keyboard shortcuts for file copy and paste (#11096) 2025-09-24 22:52:03 +07:00
Hiep Le
6a5d09660d fix(frontend): upgrade banner covers conversation panel in settings (#11094) 2025-09-24 21:40:16 +07:00
Hiep Le
a94906e15c refactor(frontend): migration of security-analyzer-slice.ts to zustand (#11082) 2025-09-24 21:32:25 +07:00
Hiep Le
12dc256b5a refactor(frontend): git actions should be enabled at all times (#11063) 2025-09-24 21:31:51 +07:00
Hiep Le
11edf33b97 refactor(frontend): remove file-state-slice.ts file (#11061) 2025-09-24 21:31:11 +07:00
Hiep Le
fce66e94e7 refactor(frontend): event message (#11001) 2025-09-24 21:30:55 +07:00
Hiep Le
5457392eae refactor(frontend): migration of conversation-slice.ts to zustand (#11032) 2025-09-24 21:30:37 +07:00
Ray Myers
1e7024b60a fix - Set claude sonnet output limit (#11098) 2025-09-24 13:31:20 +00:00
Hiep Le
3977d4fdd7 fix(frontend): insufficient spacing between last message and chat input (#11055) 2025-09-24 20:13:21 +07:00
Tejas Goyal
16004426a2 feat: Add configurable timeouts for MCP tool invocations (Good first issues: #10684) (#11029)
Co-authored-by: Tejas Goyal <tejas@Tejass-MacBook-Pro.local>
2025-09-24 16:43:54 +04:00
dependabot[bot]
73eb53a379 chore(deps): bump the version-all group across 1 directory with 21 updates (#11078)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-24 16:24:27 +04:00
BenYao21
d3d70fcc60 issue #9388, this will fix the issue (#10450)
Co-authored-by: mamoodi <mamoodiha@gmail.com>
Co-authored-by: Graham Neubig <neubig@gmail.com>
2025-09-22 16:56:53 -04:00
Xinyi He
7906eab6b1 Add inference generation of SWE-Perf Benchmark (#10246)
Co-authored-by: mamoodi <mamoodiha@gmail.com>
Co-authored-by: Graham Neubig <neubig@gmail.com>
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-22 20:35:30 +00:00
juanmichelini
547e1049f1 Multi swe gym (#10605)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-22 15:56:26 -04:00
mamoodi
818cc60b52 New label for not going stale (#11069) 2025-09-22 11:53:47 -04:00
Robert Brennan
431d2c1f43 security: upgrade setuptools to >=78.1.1 to address CVE-2025-47273 and CVE-2024-6345 (#11038)
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: enyst <engel.nyst@gmail.com>
2025-09-22 04:05:45 +00:00
Engel Nyst
07f23641a3 build(deps): pin litellm to avoid build failure (#11054)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-22 03:54:37 +02:00
Hiep Le
de84af5586 feat(frontend): display lock icon when confirmation mode is enabled (#11030) 2025-09-20 10:55:19 +07:00
Hiep Le
b7765ba3f7 refactor(frontend): fix typecheck (#11037) 2025-09-19 13:43:00 -04:00
Hiep Le
b89f2e51e4 refactor(frontend): migration of metrics-slice.ts to zustand (#11018) 2025-09-19 23:52:21 +07:00
mamoodi
e09f93aa75 Release 0.57.0 (#10981)
Co-authored-by: Ray Myers <ray.myers@gmail.com>
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: sp.wack <83104063+amanape@users.noreply.github.com>
Co-authored-by: Rohit Malhotra <rohitvinodmalhotra@gmail.com>
2025-09-19 12:40:56 -04:00
Hiep Le
9f529b105a refactor(frontend): migration of command-slice.ts to zustand (#11003) 2025-09-19 23:33:59 +07:00
Graham Neubig
89e3d2a867 Improve OpenHands provider pricing documentation (#10974)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-20 00:22:44 +08:00
Hiep Le
a7b9a4f291 refactor(frontend): migration of status-slice.ts to zustand (#11017) 2025-09-19 22:27:55 +07:00
Hiep Le
88cd16ae21 refactor(frontend): migration of initial-query-slice.ts to zustand (#11020) 2025-09-19 22:27:20 +07:00
Hiep Le
a8a3e9e604 refactor(frontend): remove the code-slice.ts file (#11021) 2025-09-19 21:22:29 +07:00
Hiep Le
0061bcc0b0 refactor(frontend): custom chat input (#10984) 2025-09-19 21:06:18 +07:00
Hiep Le
9c9fa780b0 refactor(frontend): task tracking observation content (#11002) 2025-09-19 20:03:05 +07:00
Alona
569ac16163 Improve token refresh error logging (#11026) 2025-09-19 14:18:38 +07:00
Robert Brennan
46f7738f41 Update Python packages to latest versions (#11023)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-18 19:52:46 +00:00
Rohit Malhotra
3f3669dd34 Hotfix: rm model choice override (#11022) 2025-09-18 14:40:06 -04:00
sp.wack
cd65645eea Hide Tavily search API key help text in SaaS mode (#11014)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-18 16:40:29 +00:00
Robert Brennan
8e88a7a277 fix: resolve critical and high CVEs in enterprise Docker image (#10987)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-18 11:25:33 -04:00
Hiep Le
b393d52439 refactor(frontend): conversation main (#10985) 2025-09-18 20:23:13 +07:00
Hiep Le
faeec48365 refactor(frontend): conversation card (#10986) 2025-09-18 20:22:59 +07:00
sp.wack
774caf0607 feat: refactor status indicators (#10983)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-17 22:32:55 +04:00
sp.wack
7222730df0 Fix SaaS callback URLs and pro pill positioning (#10998)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-17 16:56:02 +00:00
Hiep Le
910177fc57 refactor(frontend): system message modal (#10969) 2025-09-17 21:56:14 +07:00
Hiep Le
ac9badbd20 refactor(frontend): metrics modal (#10968) 2025-09-17 21:55:25 +07:00
Ray Myers
02c299d88f Fix Slack resolver failing on AWAITING_USER_INPUT state (#10992)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-17 09:20:12 -05:00
mamoodi
f65fbef649 Remove runtime settings (#10996) 2025-09-17 13:59:29 +00:00
Hiep Le
3c2acad28d refactor(frontend): microagents modal (#10970) 2025-09-16 22:32:23 +07:00
Boxuan Li
0f1780728e Update str_replace_editor tool to use dynamic workspace path from SANDBOX_VOLUMES (#10965)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-15 17:46:54 -07:00
sp.wack
d3f3378a4c feat: Upgrade banner for unsubscribed SaaS users (#10890)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-15 23:04:44 +00:00
Engel Nyst
65f4164749 [Docs] Add environment variables reference table (#10926)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-15 18:31:44 +00:00
Hiep Le
3f984d878b refactor(frontend): move conversation APIs to a dedicated service handler (#10957) 2025-09-16 00:57:15 +07:00
Eliot Jones
10b871f4ab feat: Add Cygnal integration (#10898) 2025-09-15 09:57:03 -04:00
Hiep Le
d664f516db refactor(frontend): conversation tab content component (#10956) 2025-09-15 20:56:38 +07:00
Hiep Le
e74bbd81d1 fix(frontend): suppressing event display in the absence of user messages (#10955) 2025-09-15 20:56:16 +07:00
Hiep Le
ab893f93f0 refactor(frontend): use-auto-resize hook (#10959) 2025-09-15 20:49:15 +07:00
Hiep Le
5aba498e77 refactor(frontend): move billing APIs to a dedicated service handler (#10958) 2025-09-15 20:37:07 +07:00
Hiep Le
1523555eea refactor(frontend): remove dead code (#10839) 2025-09-15 20:35:56 +07:00
Kaushik Ashodiya
30604c40fc fix: improve CLI help and version command performance (#10908)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-12 14:23:01 -04:00
Hiep Le
8dc46b7206 refactor(frontend): optimize pre-commit lint script (#10870)
Co-authored-by: amanape <83104063+amanape@users.noreply.github.com>
2025-09-12 15:23:29 +00:00
Hiep Le
69498bebb4 refactor(frontend): new conversation component (#10937)
Co-authored-by: sp.wack <83104063+amanape@users.noreply.github.com>
2025-09-12 22:15:26 +07:00
tksrmz
77ee9e25d9 fix(frontend): highlight preceding stars on hover in LikertScale (#10948) 2025-09-12 18:01:40 +04:00
Hiep Le
74753036bb refactor(frontend): move user APIs to a dedicated service handler (#10943) 2025-09-12 09:08:15 +07:00
Hiep Le
95d7c10608 refactor(frontend): move option APIs to a dedicated service handler (#10933) 2025-09-12 00:43:15 +07:00
Hiep Le
c142cc27ff refactor(frontend): home header component (#10930) 2025-09-12 00:10:58 +07:00
Hiep Le
0e20fc206b refactor(frontend): move settings APIs to a dedicated service handler (#10941) 2025-09-11 23:39:23 +07:00
Hiep Le
e21475a88e feat(frontend): persist drawer open/close state on page refresh (#10935)
Co-authored-by: sp.wack <83104063+amanape@users.noreply.github.com>
2025-09-11 15:58:00 +00:00
Hiep Le
921fec0019 refactor(frontend): expand repository pill to full available width (#10936) 2025-09-11 22:37:44 +07:00
Hiep Le
049f839a62 refactor(frontend): move auth APIs to a dedicated service handler (#10932) 2025-09-11 22:31:41 +07:00
Hiep Le
0dde758e13 refactor(frontend): move microagent management API to a dedicated service handler (#10934) 2025-09-11 22:27:56 +07:00
Tim O'Farrell
8257ae70cc Additional logs to debug container working directories (#10902)
Co-authored-by: Chuck Butkus <chuck@all-hands.dev>
2025-09-11 11:06:19 -04:00
Ray Myers
4513bcc622 chore - MyPy check Enterprise with OpenHands (#10858)
Co-authored-by: Tim O'Farrell <tofarr@gmail.com>
2025-09-11 11:05:50 -04:00
Hiep Le
b5b9a3f40b refactor(frontend): create waiting for runtime component (#10931) 2025-09-11 21:30:05 +07:00
Xingyao Wang
8ea1259943 Add GitHub workflow for MDX format checking and fix parsing error (#10924)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-10 23:04:54 +00:00
Ray Myers
ddb2794adf fix - Tag enterprise with the same SHA as app image. (#10921) 2025-09-10 16:47:31 -05:00
sp.wack
79fdcad7ef Fix status indicator and chat input synchronization issue (#10914)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-10 20:39:14 +00:00
chuckbutkus
1de70b8ce4 Fix runtime init (#10909) 2025-09-10 19:28:12 +00:00
sp.wack
3baeecb27c meta(frontend): Improve UX (#9845)
Co-authored-by: Mislav Lukach <mislavlukach@gmail.com>
Co-authored-by: Hiep Le <69354317+hieptl@users.noreply.github.com>
Co-authored-by: hieptl <hieptl.developer@gmail.com>
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-10 18:12:52 +00:00
Tim O'Farrell
b08238c841 Fix for issue where some attributes in pr_data are defined but are null or undefined (#10827) 2025-09-09 21:28:40 +00:00
sp.wack
831084df4c Remove git authentication requirement for secrets in SaaS mode (#10903)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-09 19:50:13 +00:00
sp.wack
eb4dacb577 Fix ruff formatting in enterprise token_manager.py (#10901) 2025-09-09 18:45:45 +00:00
jrobles98
8e71459601 Fix typo (#10702) 2025-09-09 12:39:58 -04:00
Tim O'Farrell
fc29815aa0 Value logged as error should be info (#10831) 2025-09-09 08:48:29 -06:00
mamoodi
a809d74b7d Release 0.56.0 (#10876) 2025-09-09 10:30:43 -04:00
Ryan H. Tran
b090d097ed Fix Docker build error 'groupadd: GID 1000 already exists' (#10888) 2025-09-09 21:50:23 +08:00
Graham Neubig
79f32a34a0 Fix SANDBOX_VOLUMES format in headless mode documentation (#10887)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-08 14:17:20 -04:00
Ashwin Kumar B V
805bc5608e Update deprecated dependencies: google-genai and yanked ddtrace (#10866)
Co-authored-by: enyst <engel.nyst@gmail.com>
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-08 10:04:16 -05:00
Ray Myers
61e1957cee chore - Make enterprise preview work when labeled after the fact (#10862) 2025-09-08 09:54:51 -05:00
Joe Axe
a25826a5f9 fix: resolve empty API keys to None and add Bedrock model support (#10573) 2025-09-08 14:45:10 +02:00
Ryan H. Tran
df9320f8ab Implement model routing support (#9738)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-08 16:19:34 +07:00
Boxuan Li
af0ab5a9f2 Fix working_dir bug in local runtime (#10801)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-07 23:44:55 -07:00
Ruilin Zhou
9960d11d08 feat(runtime): upgrade E2B runtime to v2.0 with full implementation (#10832) 2025-09-08 06:32:08 +02:00
mamoodi
d5d5e265f8 Fix issue #10729: Add x-ai/grok-code-fast-1 to MODELS_WITHOUT_STOP_WORDS (#10867)
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
2025-09-08 05:30:45 +02:00
Xingyao Wang
989a4e662b feat: integrate with unified docs repository (#10830)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-06 16:10:21 +02:00
骆艺轩
ecfbae2285 refactor: Tweak labels prompt (#10523) (#10757) 2025-09-06 03:17:44 +02:00
Tim O'Farrell
c9cf351697 Added type hints for experiment manager (#10851)
Co-authored-by: Ray Myers <ray.myers@gmail.com>
2025-09-05 12:14:16 -06:00
Tim O'Farrell
aca568cfbe More Type Safety (#10848) 2025-09-05 11:34:43 -06:00
dependabot[bot]
3366ad9de7 chore(deps): bump the version-all group in /frontend with 7 updates (#10844)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-05 19:10:32 +04:00
Ankit Kumar Yadav
f442e07b33 docs: replaced slack invite links with dub.sh link (fixes #10768) (#10779) 2025-09-05 08:57:49 -04:00
Ray Myers
fdf8b21b84 Update enterprise readme (#10826) 2025-09-04 17:20:06 -05:00
Engel Nyst
93e843a06b Revert "feat(agent): add security-related items in system prompt to defense against data exfiltration" (#10822) 2025-09-05 05:07:30 +08:00
Ray Myers
e37f7b0e0f Enterprise code and docker build (#10770) 2025-09-04 15:44:54 -04:00
Haowei Lin
bd8b1bfa25 Add a new benchmark: AlgoTune (#10724)
Co-authored-by: linhaowei <linhaowei@wizardquant.com>
Co-authored-by: Graham Neubig <neubig@gmail.com>
2025-09-04 18:08:50 +00:00
dependabot[bot]
a4f11006f6 chore(deps-dev): bump @tanstack/eslint-plugin-query from 5.83.1 to 5.86.0 in /frontend in the eslint group (#10817)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 15:51:28 +00:00
sp.wack
c6950946bb Add refetchInterval to useActiveHost hook for automatic host status updates (#10815)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-04 14:59:16 +00:00
Engel Nyst
81d6341f9d chore(server): rename Session to WebSession (#10565) 2025-09-04 16:49:54 +02:00
dependabot[bot]
55a6bbd9a4 chore(deps): bump the version-all group across 1 directory with 8 updates (#10799)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-04 17:08:42 +04:00
Zacharias Fisches
20e5c40969 Fix swe-bench run_infer.py config parsing from config.toml (#10792) 2025-09-04 20:10:08 +08:00
Xingyao Wang
3e8dc41bdf Add microagent for fixing E501 line too long errors (#10796)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-04 19:48:08 +08:00
Hiep Le
49d37119a9 chore(frontend): remove feature flag (microagent management) (#10769) 2025-09-02 19:46:09 +00:00
Jamie Chicago
cfd416c29f feat: update welcome-good-first-issue.yml (#10766) 2025-09-02 19:41:58 +00:00
Ray Myers
c052dd7da5 chore - Update license for enterprise folder (#10761) 2025-09-02 18:48:45 +00:00
Ryan H. Tran
3f77b8229a Add support for AGENTS.md files in microagent system (#10528)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-03 02:18:38 +08:00
Tim O'Farrell
8d13c9f328 UI for determining if llm options are enabled (#10665)
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: sp.wack <83104063+amanape@users.noreply.github.com>
2025-09-02 12:09:55 -06:00
mamoodi
f46b112f17 Add more troubleshooting for linux (#10704) 2025-09-02 14:02:16 -04:00
mamoodi
44dc7f9e9b Release 0.55.0 (#10657) 2025-09-02 13:49:02 -04:00
Hiep Le
00eaa7a6e1 refactor(frontend): remove the branch dropdown from the learn this repo modal (microagent management) (#10755) 2025-09-02 22:34:00 +07:00
Hiep Le
9f1d6963b8 feat(frontend): support pagination when loading repositories (microagent management) (#10708) 2025-09-02 17:03:58 +04:00
Rohit Malhotra
f61fa93596 Fix fragile URL parsing in Bitbucket service search_repositories method (#10733)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-01 02:59:24 -04:00
Rohit Malhotra
3e87c08631 refactor: introduce HTTPClient protocol for git service integrations (#10731)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-09-01 01:44:31 -04:00
Rohit Malhotra
21f3ef540f refactor: Apply GitHub mixins pattern to BitBucket service (#10728)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-31 16:09:41 -04:00
Rohit Malhotra
61a93d010c Refactor GitLab service into modular mixins pattern (#10727)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-31 19:10:40 +00:00
Rohit Malhotra
9d6afa09b6 Fix GraphQL URL configuration for GitHub Enterprise Server (#10725)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-30 18:06:00 -04:00
Rohit Malhotra
c648b6f74f Refactor: Modularize GitHubService into feature mixins (#10492)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-29 23:45:15 -04:00
sp.wack
c0fa41da65 fix: auto-load repositories when insufficient content in dropdown (#10697)
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: Rohit Malhotra <rohitvinodmalhotra@gmail.com>
2025-08-29 21:17:27 +00:00
Rohit Malhotra
6eb32e9ae4 Fix: Add method to merge conversation stats (#10667)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-29 20:15:44 +00:00
Rohit Malhotra
6a544d4274 (Hotfix): Branch pagination for GitLab (#10710)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-29 20:15:15 +00:00
Calvin Smith
4aada82b75 fix: Linking condensation and task tracking prompts (#10656)
Co-authored-by: Calvin Smith <calvin@all-hands.dev>
2025-08-29 09:18:31 -06:00
Ryan H. Tran
ab2da611f5 fix: validate task_list schema for task tracker (#10624) 2025-08-29 10:57:50 +00:00
Rohit Malhotra
e47bcf31e4 [Bug, GitLab]: fix missing context in cloud resolver (#10509)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-29 02:38:03 -04:00
mamoodi
83b9262379 Add troubleshooting guide for linux timeout issue (#10685) 2025-08-29 05:52:36 +02:00
Rohit Malhotra
edc95141f7 Implement branch pagination for repository selection and improve UI async dropdown behaviour (#10588)
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: amanape <83104063+amanape@users.noreply.github.com>
2025-08-29 03:38:42 +00:00
Hiep Le
5b35203253 refactor: remove branch dropdown, update title, fix pr_number issue (microagent management) (#10691) 2025-08-29 00:24:48 +04:00
Rohit Malhotra
7e3eabe777 (Hotfix): ConversationStats metrics loss for unregistered services (#10676)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-28 14:15:20 -04:00
dependabot[bot]
23713bfe8c chore(deps): bump the version-all group in /frontend with 5 updates (#10686)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-28 14:53:14 +00:00
Ryan H. Tran
81829289ab Add support for passing list of Message into LLM completion (#10671) 2025-08-28 21:22:28 +08:00
Ray Myers
9709431874 fix: cli dedupe TaskTrackingAction thoughts by using display_thought_if_new (#10660)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-28 21:20:39 +08:00
dependabot[bot]
0e9906f41e chore(deps): bump posthog-js from 1.260.3 to 1.261.0 in /frontend in the version-all group (#10658)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-28 16:15:31 +04:00
chuckbutkus
9ac9a47207 Missed a place for the group change (#10659) 2025-08-27 21:47:20 +00:00
Hiep Le
75653e805a refactor(frontend): enhance the launch microagent modal (memory UI). (#10651) 2025-08-28 01:41:58 +07:00
mamoodi
9630b536cd Revert "Add support for passing list of Message into LLM completion" (#10653) 2025-08-27 17:51:17 +00:00
Engel Nyst
6f5c8186b8 Fix(settings): enforce condenser max history size >= 20 and improve messaging (#10638) 2025-08-27 18:37:41 +02:00
Rohit Malhotra
36e0d8d3da [Fix]: token refresh for nested runtimes (#10637)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-27 12:20:34 -04:00
Ryan H. Tran
e68abf8d75 Add support for passing list of Message into LLM completion (#10650) 2025-08-27 22:39:26 +07:00
Ryan H. Tran
93ef1b0cda Remove image content filtering in ConversationMemory (#10645) 2025-08-27 22:28:09 +07:00
Web3 Outlaw
77b5c6b161 Fix Typos in Comment and Docs (#10644) 2025-08-27 14:06:39 +00:00
Hiep Le
57aa7d5c12 feat: hide conversations after PR closure or merge (microagent management) (#10600) 2025-08-27 16:32:04 +07:00
Hiep Le
50391ecdf3 feat(frontend): update learning repo flow (microagent management) (#10597)
Co-authored-by: amanape <83104063+amanape@users.noreply.github.com>
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-27 16:02:48 +07:00
dependabot[bot]
672650d3d9 chore(deps): bump the version-all group in /frontend with 7 updates (#10643)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-27 12:10:48 +04:00
Rohit Malhotra
9afedea170 [Bug, GitHub]: fix missing context in cloud resolver (#10517)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-27 07:07:09 +00:00
chuckbutkus
c0bb84dfa2 Non root user (#10155)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-27 02:23:39 -04:00
Hiep Le
18b5139237 fix(backend): show name of created branch in conversation list. (#10208) 2025-08-27 11:41:12 +07:00
Rohit Malhotra
4849369ede frontend(chat): render conversation_instructions from RecallObservation (#10639)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-26 23:32:18 -04:00
Xingyao Wang
b082ccc0fb feat(llm): add support for deepseek and gpt-5-mini, util for token count (#10626)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-27 11:03:35 +08:00
mamoodi
b0007076c0 Remove duplicated command in CLI (#10634) 2025-08-26 16:01:16 -04:00
Tim O'Farrell
4a4f213f57 Remove unused translation keys from translation.json (#10631)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-26 11:59:48 -06:00
Tim O'Farrell
f9099fe6db Refactor conversation status (#10590)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-26 08:06:26 -06:00
Xingyao Wang
8f46a0a7a3 Add gpt-5-mini-2025-08-07 as verified model & supported in OpenHands provider (#10628)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-26 13:15:16 +00:00
dependabot[bot]
55d204ae1b chore(deps): bump the version-all group in /frontend with 21 updates (#10614)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-26 06:09:20 +00:00
baii
4d7cd228da Fix(backend): correctly forward AWS Bedrock aws_access_key_id / aws_secret_access_key / aws_region_name to litellm (#9663)
Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
2025-08-25 22:07:28 +00:00
Tim O'Farrell
a3f92df4b3 Fix for issue where exceptions are swallowed (#10602) 2025-08-25 15:50:15 -06:00
Engel Nyst
e41f8f5215 feat(settings): configurable condenser max history size (FE+BE) (#10591) 2025-08-25 22:50:52 +02:00
Jamie Chicago
6448f5a681 docs: Add Ubuntu installation steps for Windows WSL setup (#10485)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-25 20:43:04 +00:00
Graham Neubig
5fcc648d5f Add E2E test for multi-conversation resume functionality (Issue #10384) (#10390)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-25 15:15:54 -04:00
danieljbruntz
c9d96038c1 feat: Add OPENHANDS_FORCE_VISION env var to override vision capability detection (#10255)
Co-authored-by: mamoodi <mamoodiha@gmail.com>
Co-authored-by: Engel Nyst <engel.nyst@gmail.com>
2025-08-25 19:05:58 +00:00
Calvin Smith
408af4e012 fix: Extend cases where truncation triggers (#10607)
Co-authored-by: Calvin Smith <calvin@all-hands.dev>
2025-08-25 12:59:41 -06:00
mamoodi
d9ac2faff6 Add backlog label to exemption (#10598) 2025-08-25 14:57:35 -04:00
Rohit Malhotra
64383a66e2 docs: Update Project Management integration docs (#10161)
Co-authored-by: OpenHands <openhands@all-hands.dev>
2025-08-25 14:51:06 -04:00
chuckbutkus
7fbcb29499 Allow for path based runtimes in the SAAS environment (#10518)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-25 14:31:07 -04:00
hereisok
e7aae1495c perf: remove the sleep before runtime initialization (#10033)
Signed-off-by: hereisok <hereisok@angai.wk@gmail.com>
Co-authored-by: mamoodi <mamoodiha@gmail.com>
2025-08-25 13:56:57 -04:00
Hiep Le
d33f27d141 refactor(frontend): separate the microagents and conversations (microagent management) (#10596)
Co-authored-by: amanape <83104063+amanape@users.noreply.github.com>
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-26 00:50:25 +07:00
Hiep Le
d08851859b refactor(frontend): update helper text (microagent management) (#10595)
Co-authored-by: amanape <83104063+amanape@users.noreply.github.com>
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-26 00:49:11 +07:00
Hiep Le
7f4d311294 fix: subscription logic by polling for available runtime (microagent management, memory UI) (#10519)
Co-authored-by: amanape <83104063+amanape@users.noreply.github.com>
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-25 20:44:00 +04:00
dependabot[bot]
049f058ed1 chore(deps-dev): bump eslint-plugin-unused-imports from 4.1.4 to 4.2.0 in /frontend in the eslint group (#10511)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-25 18:03:22 +04:00
Tim O'Farrell
bb6cf5a816 Refactor authentication error handling with global FastAPI exception handler (#10403)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-25 07:54:30 -06:00
Engel Nyst
d9bc5824a0 docs: add shell guidance to avoid set -e variants in this environment (#10579)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-24 13:39:37 +08:00
Xingyao Wang
fd5b5075d6 Simplify CLI markdown rendering; remove python-markdown deps; update tests (#10538)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-24 01:23:06 +08:00
Hiep Le
f5cd7b256d feat(frontend): Implement LLM risk analyzer UI (#10569)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: Xingyao Wang <xingyao@all-hands.dev>
Co-authored-by: Graham Neubig <neubig@gmail.com>
Co-authored-by: llamantino <213239228+llamantino@users.noreply.github.com>
Co-authored-by: mamoodi <mamoodiha@gmail.com>
Co-authored-by: Tim O'Farrell <tofarr@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Ryan H. Tran <descience.thh10@gmail.com>
Co-authored-by: Neeraj Panwar <49247372+npneeraj@users.noreply.github.com>
Co-authored-by: sp.wack <83104063+amanape@users.noreply.github.com>
Co-authored-by: Insop <1240382+insop@users.noreply.github.com>
Co-authored-by: test <test@test.com>
Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
Co-authored-by: Zhonghao Jiang <zhonghao.J@outlook.com>
Co-authored-by: Ray Myers <ray.myers@gmail.com>
2025-08-23 02:08:45 +07:00
Neeraj Panwar
df86fd275d Fixes bug 9682 (#9692)
Co-authored-by: Xingyao Wang <xingyao@all-hands.dev>
2025-08-22 16:51:53 +00:00
Xingyao Wang
d22a2e39e7 feat(agent): add security-related items in system prompt to defense against data exfiltration (#10477)
Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-22 15:53:13 +00:00
Xingyao Wang
ca424ec15d [agent] Add LLM risk analyzer (#9349)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: Graham Neubig <neubig@gmail.com>
Co-authored-by: llamantino <213239228+llamantino@users.noreply.github.com>
Co-authored-by: mamoodi <mamoodiha@gmail.com>
Co-authored-by: Tim O'Farrell <tofarr@gmail.com>
Co-authored-by: Hiep Le <69354317+hieptl@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Ryan H. Tran <descience.thh10@gmail.com>
Co-authored-by: Neeraj Panwar <49247372+npneeraj@users.noreply.github.com>
Co-authored-by: sp.wack <83104063+amanape@users.noreply.github.com>
Co-authored-by: Insop <1240382+insop@users.noreply.github.com>
Co-authored-by: test <test@test.com>
Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
Co-authored-by: Zhonghao Jiang <zhonghao.J@outlook.com>
Co-authored-by: Ray Myers <ray.myers@gmail.com>
2025-08-22 14:02:36 +00:00
Xingyao Wang
4507a25b85 Evaluation: redirect sessions to repo-local .eval_sessions via helper; apply across entrypoints; add tests (#10540)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-22 13:34:02 +00:00
llamantino
d9cf5b7302 ci: add GitHub Action to post welcome message on good first issues (#9707)
Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
2025-08-22 09:09:45 -04:00
Xingyao Wang
2a86e32263 fix(CI): Pin @modelcontextprotocol/server-filesystem to version 2025.8.18 (#10561)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-22 05:00:11 +08:00
Engel Nyst
b311ae6e15 fix: normalize malformed <parameter> tags (Qwen3) (#10539) 2025-08-21 19:03:20 +02:00
Ryan H. Tran
adb773789a Upgrade aci to 0.3.2: clamp view_range end to file length and emit warning instead of error (#10502) 2025-08-21 23:01:54 +07:00
Engel Nyst
91d3d1d20a Fix: expose aggregated LLM metrics in State for evaluation scripts (#10537)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-21 17:43:09 +02:00
llamantino
e9e2c98946 fix(tests): increase hard timeout in test_bash_server to avoid timeout on Windows (#9930) 2025-08-21 17:12:42 +02:00
Engel Nyst
7861c1ddf7 fix(anthropic): disable extended thinking for Opus 4.1 (#10532)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-21 00:13:15 +02:00
Engel Nyst
5ce5469bfa docs: update OpenAPI specification to include all current endpoints (#10412)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-20 21:58:35 +02:00
Xingyao Wang
4a3f5dd9b4 fix(runtime): correctly set session_api_key for local runtime (#10506) 2025-08-21 03:51:19 +08:00
Joe O'Connor
bc8b995dd3 Add additional networks (#9566)
Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
2025-08-20 18:52:31 +00:00
chuckbutkus
07c4742496 Add useful tools jq and gettext to image (#10531) 2025-08-20 18:27:09 +00:00
mamoodi
b5887f8a9d Fix CLI docs command (#10520) 2025-08-20 14:53:15 +00:00
mamoodi
0166df6575 Release 0.54.0 (#10465) 2025-08-20 10:29:15 -04:00
Ryan H. Tran
e03a1f4e37 Move TASKS.md to session-specific directory in ~/.openhands (#10493)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-20 22:26:55 +08:00
sp.wack
c763f0e368 chroe(vscode): Refresh vscode integration lockfile (#9965)
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
2025-08-20 15:33:11 +02:00
Engel Nyst
bb0e24d23b Centralize model feature checks (#10414)
Co-authored-by: OpenHands-GPT-5 <openhands@all-hands.dev>
2025-08-19 20:30:07 +00:00
sp.wack
aa6b454772 fix: Enhance GitHub repository search to include user organizations (#10324)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-19 15:56:15 +00:00
sp.wack
0297b3da18 Fix conversation ID validation to return 400 instead of 500 for long IDs (#10496) 2025-08-19 18:03:05 +04:00
Hiep Le
476954f3a4 refactor(frontend): update the styling for the microagent management page. (#10494) 2025-08-19 19:50:42 +07:00
dependabot[bot]
f296d7bde5 chore(deps): bump abatilo/actions-poetry from 3 to 4 (#10487)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-19 13:58:39 +02:00
Zacharias Fisches
f866b3f8ea Update modal runtime for modal>=1.0 (#10479)
Co-authored-by: Ryan H. Tran <descience.thh10@gmail.com>
2025-08-19 10:33:03 +00:00
Zacharias Fisches
36d31b74f7 fix jinja / dockerfile syntax by removing newlines (#10476)
Co-authored-by: Xingyao Wang <xingyao@all-hands.dev>
2025-08-19 02:50:41 +00:00
Engel Nyst
634a7691a2 tests: reorganize unit tests into subdirectories mirroring source modules (#10484)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-19 01:11:07 +02:00
Xingyao Wang
81ba4399fa fix(frontend): fix MCP tab in frontend unit tests (#10481)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-18 21:25:09 +00:00
Rohit Malhotra
875036d920 (Hotfix): Fix logs and filestore init for llm registry (#10470) 2025-08-18 20:57:08 +00:00
Xingyao Wang
39333dd5de feat: enable MCP in SaaS (#10480) 2025-08-18 20:40:42 +00:00
Rohit Malhotra
3660933d59 refactor: replace 'convo' naming with 'conversation' (#10473)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-18 15:10:32 -04:00
Xingyao Wang
baf2cc5c7e Pin OpenAI Python SDK to 1.99.9 to avoid LiteLLM import breakage (BerriAI/litellm#13711) (#10471)
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: Rohit Malhotra <rohitvinodmalhotra@gmail.com>
2025-08-18 18:45:34 +00:00
Rohit Malhotra
7b31d57a2f Update conversation stats filename (#10472) 2025-08-18 18:09:13 +00:00
Rohit Malhotra
61d90c31eb (Hotfix): Fix eval pipeline (#10466) 2025-08-18 12:51:51 -04:00
Xingyao Wang
3fea7fd2fc feat: improve MCP config UI with comprehensive add/edit/delete functionality (#10145)
Co-authored-by: OpenHands <openhands@all-hands.dev>
2025-08-18 16:33:27 +00:00
suixinio
c64b1ae111 fix(openrouter): Force string serialization for openrouter/anthropic/claude-sonnet-4 model (#10454) 2025-08-18 17:50:01 +02:00
Kevin Musgrave
74ba21bad0 feat(evaluation): Added INSTRUCTION_TEMPLATE_NAME to run_infer.py in swe_bench (#10270)
Co-authored-by: Xingyao Wang <xingyao@all-hands.dev>
Co-authored-by: mamoodi <mamoodiha@gmail.com>
2025-08-18 14:18:08 +00:00
Engel Nyst
bef6b1afee cli: fix Ubuntu white-on-white model autocomplete by merging default prompt_toolkit UI style (#10347) 2025-08-18 20:32:09 +08:00
Graham Neubig
ad85e3249a test(e2e): Add web browsing catchphrase E2E for #10378 and wire into CI (#10401)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-18 08:28:42 -04:00
Engel Nyst
822ce86150 Ensure .bashrc exists (#10461) 2025-08-18 20:18:11 +08:00
Graham Neubig
305caf1257 Implement configurable base URL for E2E tests (#10394)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-18 07:44:07 -04:00
Rohit Malhotra
25d9cf2890 [Refactor]: Add LLMRegistry for llm services (#9589)
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: Graham Neubig <neubig@gmail.com>
Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
2025-08-18 02:11:20 -04:00
Engel Nyst
17b1a21296 chore(ci): enhance lint-fix workflow for FE (#10448)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-18 05:21:13 +02:00
Engel Nyst
97bcb2162d Add instruction to use existing repository labels in PR/MR microagents (#10446)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-18 04:35:20 +02:00
Engel Nyst
8401641f7e Docs + Code: rename ‘convo’ to ‘conversation’ across codebase and docs (#10447) 2025-08-18 04:35:02 +02:00
Engel Nyst
e2343c0927 Runtime-backend docs update (arch) - cron agent run (#10423)
Co-authored-by: OpenHands-GPT-5 <openhands@all-hands.dev>
2025-08-18 02:04:31 +02:00
Xingyao Wang
277064720c chore: remove timeout >600s warning log in Event.set_hard_timeout (#10444)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-17 23:25:13 +02:00
Xingyao Wang
ef3e0c8dfe Fix think observation redundant rendering in frontend (#10409)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-17 10:55:03 +08:00
Engel Nyst
315d391414 Revert "tests: reorganize unit tests into subdirectories mirroring source modules" (#10437) 2025-08-17 00:33:17 +00:00
olyashok
95ef8965b7 Allow user actions over websockets (#10420)
Co-authored-by: Xingyao Wang <xingyaoww@gmail.com>
Co-authored-by: Xingyao Wang <xingyao@all-hands.dev>
2025-08-16 21:29:28 +00:00
Ray Myers
ab9fb50c4f fix - Thread-safety in BatchedWebHookFileStore (#10339) 2025-08-16 18:06:40 +00:00
Engel Nyst
f866da6bf2 tests: reorganize unit tests into subdirectories mirroring source modules (#10427)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-16 19:13:50 +02:00
Zhonghao Jiang
7229a16b45 feat(evaluation): Add NoCode-bench evaluation script (#10229) 2025-08-16 16:41:22 +00:00
llamantino
19105a2a13 fix(cli): send authentication error resume message to user, not llm (#10421) 2025-08-16 18:01:42 +02:00
Ryan H. Tran
fe486ad1f1 Add task tracking tool for long-horizon tasks (#10166)
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: Xingyao Wang <xingyao@all-hands.dev>
2025-08-16 20:05:59 +07:00
Engel Nyst
0ec6ed20cb fix(frontend): browser tab notification respects user-renamed titles; add unit test (#10406) 2025-08-16 07:00:45 +00:00
Xingyao Wang
794381c22b Add "The agent didn't finish the job" feedback reason to Likert scale (#10417) 2025-08-16 00:25:19 -04:00
Tim O'Farrell
0c581ea946 fix(nested_event_store): correct reverse pagination in search_events and add unit test (#10418)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-15 19:29:35 -06:00
Engel Nyst
f7f4fcf98f chore(eval): remove old, unused regression test framework under evaluation/regression (#10419) 2025-08-16 01:08:23 +02:00
Xingyao Wang
ab004478f6 feat(agent): include a new roleplay-based prompt (#10306)
Co-authored-by: test <test@test.com>
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-16 06:04:28 +08:00
Xingyao Wang
340606e68a microagent: Add /codereview-roasted microagent with Linus Torvalds engineering mindset (#10405)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-15 21:49:57 +00:00
Tim O'Farrell
daec23b5d7 Add get_issue_comments method to GitLabService (#10361)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-15 14:55:39 -06:00
Xingyao Wang
587b4c311a runtime(bash): clarify guidance when previous command still running; recommend execute_bash timeout (issue #10350) (#10389)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-16 02:15:05 +08:00
Xingyao Wang
7a86402c9c Add process management guidance to system prompt (#10083)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-16 02:09:20 +08:00
Insop
06d283dfa0 Temp fix for docker file and debug log (#10345) 2025-08-15 15:34:46 +00:00
sp.wack
a6a4246e30 fix(frontend): Failing tests (#10369) 2025-08-15 15:18:35 +00:00
Xingyao Wang
4830b9a67d fix(llm): include gpt-5 to fn call model; set top p default value to None (#10363) 2025-08-15 15:08:01 +00:00
Neeraj Panwar
d4489d62d7 fix(llm): set AWS credentials in config.toml (#10351) 2025-08-15 22:16:50 +08:00
Ryan H. Tran
e41c020073 [CLI] Fix MCP toml formatting issue (#10312)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-15 13:56:46 +00:00
Ryan H. Tran
3f44c8436f Fix swebench modal patch eval intermittent crash (#10353) 2025-08-15 21:51:03 +08:00
Graham Neubig
b740944075 Split E2E settings and conversation tests; run settings first in workflow (#10359)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-15 09:19:27 -04:00
dependabot[bot]
5618a3eebb chore(deps): bump the version-all group in /frontend with 9 updates (#10318)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-15 16:51:41 +04:00
Hiep Le
a1ffe5c936 fix(frontend): frontend UI keep flashing (#10352) 2025-08-15 12:19:30 +04:00
Hiep Le
f8376a9702 fix(frontend): status message missing (#10349) 2025-08-15 12:11:42 +07:00
Tim O'Farrell
985a634d60 Fix for issue where static system commands are truncated (#10292)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-15 04:16:50 +00:00
Xingyao Wang
e40681ca61 fix: increase max branches limit to 5000 to fix #10332 (#10333) 2025-08-14 20:44:12 +00:00
mamoodi
228e50df9c Release 0.53.0 (#10314) 2025-08-14 16:43:01 -04:00
llamantino
fd805eb835 fix(cli): remove unused mouse support and fix settings autocomplete (#10329) 2025-08-15 02:59:41 +08:00
Graham Neubig
426350224b Add Playwright-based end-to-end testing workflow (#10116)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-14 18:59:06 +00:00
Tim O'Farrell
3e36911038 Add unit test to detect circular imports (#10233)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-14 09:02:09 -06:00
Graham Neubig
4c3ba62665 Fix i18n language code handling to prevent 404 errors on first load (#10257)
Co-authored-by: OpenHands <openhands@all-hands.dev>
2025-08-14 00:10:49 -04:00
Bashwara Undupitiya
f5e7c602dc Jira, Jira DC and Linear integration UI tweaks (#10285) 2025-08-14 00:02:59 -04:00
787627858
2f32064778 fix file_ handler to TimedRotatingFileHandler type to prevent log fil… (#10089)
Co-authored-by: liwei136 <liwei136@baidu.com>
2025-08-14 03:16:44 +00:00
Xingyao Wang
5e85986f32 docs: Update documentation to promote uv as recommended installation method (#10291)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-13 23:11:02 +00:00
Xingyao Wang
4f436922ca fix: browser title not updating when conversation title changes (#10275)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-14 05:07:59 +08:00
Xingyao Wang
d256348a46 refactor(git): principled way to set git configuration for agents & re-enable git settings in UI (#10293)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-13 20:45:15 +00:00
aeft
6bdc5563cf feat: allow partial modification of CLI settings (#10240) 2025-08-13 19:26:35 +00:00
Xingyao Wang
c2f46200c0 chore(lint): Apply comprehensive linting and formatting fixes (#10287)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-13 21:13:19 +02:00
Xingyao Wang
e39bf80239 fix(prompt): Add explicit GitHub/GitLab/Slack push instructions to templates (#10290)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-14 02:44:06 +08:00
Rohit Malhotra
368a0248e3 Modify experiment manager defaults for nested runtimes (#10269)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-13 14:41:28 -04:00
mamoodi
db9ceb380a Patch release 0.52.1 (#10284)
Co-authored-by: Hiep Le <69354317+hieptl@users.noreply.github.com>
2025-08-13 14:16:34 -04:00
Copilot
c64971d0c4 Reorganize unit tests by source module into structured directory hierarchy (#10092)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: enyst <6080905+enyst@users.noreply.github.com>
Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
2025-08-13 15:22:56 +00:00
llamantino
69fa580899 fix(misc): MCP settings and other UI improvements/fixes (#10141) 2025-08-13 10:30:38 -04:00
mamoodi
e3411f743d Release 0.52.0 (#10144) 2025-08-13 09:53:20 -04:00
Hiep Le
2b65b8aff2 fix(frontend): UI breaks when user message contains codeblock that's too wide (#10276) 2025-08-13 15:14:28 +04:00
Hiep Le
11f364c5e4 fix(frontend): UI does not display triggered microagent knowledge well. (#10277) 2025-08-13 14:31:05 +08:00
Jesse
4e3a862571 Add llm disable stop word env var (#10274)
Co-authored-by: Xingyao Wang <xingyao@all-hands.dev>
2025-08-13 03:52:11 +00:00
Xingyao Wang
50aa014876 refactor(prompt): Consolidate system prompts with Jinja inheritance (#9797)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-13 03:04:08 +00:00
olyashok
500ab46918 Supprot for named volumes in docker_runtime (#10268) 2025-08-12 21:18:53 +00:00
Mislav Lukach
e311f3e70f fix(ui): increase settings page spacing (#10202) 2025-08-12 22:04:47 +04:00
Mislav Lukach
f68ad3695c Feat/maintenance banner dismissible (#10072)
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: amanape <83104063+amanape@users.noreply.github.com>
2025-08-12 22:02:36 +04:00
mamoodi
ed711318e4 Hide git settings again (#10261) 2025-08-12 17:30:57 +00:00
Calvin Smith
57a3d8f17d fix: Solvability setting not stored (#10258)
Co-authored-by: Calvin Smith <calvin@all-hands.dev>
2025-08-12 12:54:45 -04:00
jpelletier1
e1559651b8 Unhide Git Settings feature and add explanatory text (#10256)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-12 14:18:15 +00:00
Ibragim Badertdinov
19a6b6b618 feat(eval): Support evaluation on SWE-rebench (#10251) 2025-08-12 14:05:43 +00:00
Xingyao Wang
2b7e44819f chore(agent_prompt): Add EXTERNAL_SERVICES section to system prompt template (#10244)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-12 21:53:53 +08:00
Xingyao Wang
0699a0ce7c fix: copy microagents file into runtime image (#10245)
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: mamoodi <mamoodiha@gmail.com>
2025-08-12 12:42:42 +00:00
Insop
1d0d88d491 Readability improvement & remove duplicated and unused prompts (#10241) 2025-08-12 12:42:17 +08:00
Tim O'Farrell
6f21b6700a Fix for issues where callbacks are not batched (#10235) 2025-08-11 15:44:48 -06:00
Tim O'Farrell
af49b615b1 Add BatchedWebHookFileStore for batching webhook updates (#10119)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-11 12:51:08 -06:00
Tim O'Farrell
4651edd5b3 Fix circular import by moving refine_prompt to dedicated module (#10223)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-11 12:17:18 -06:00
olyashok
d7f72fec9c OverlayFS support for docker runtimes (#10222) 2025-08-11 18:11:08 +00:00
mamoodi
09011c91f8 Remove rbren from UI changes reviewers (#10230) 2025-08-11 13:32:29 -04:00
Xingyao Wang
e56fabfc5e feat(cli): Add markdown schema visualization in CLI (#10193)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-11 15:47:38 +00:00
Xingyao Wang
56f752557c Implement auto-pagination for conversation list with infinite scroll (#10129)
Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: sp.wack <83104063+amanape@users.noreply.github.com>
2025-08-11 15:03:29 +00:00
Calvin Smith
5f2ad7fbb0 Solvability setting switch (#9727)
Co-authored-by: Calvin Smith <calvin@all-hands.dev>
2025-08-11 08:57:47 -06:00
Ryan H. Tran
758e30c9a8 Remove SecretStr conversion in GAIA eval (#10204) 2025-08-11 21:30:18 +08:00
dependabot[bot]
28017f232e chore(deps): bump the version-all group across 1 directory with 9 updates (#10168)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-11 14:51:36 +04:00
Tim O'Farrell
3302c31c60 Removed Hack that is no longer required (#10195) 2025-08-10 12:13:19 -06:00
Xingyao Wang
116ba199d1 feat(agent): stop using short tool description for gpt-5 (#10184) 2025-08-09 17:56:52 -04:00
Boxuan Li
803bdced9c Fix Windows prompt refinement: ensure 'bash' is replaced with 'powershell' in all prompts (#10179)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-08 20:28:36 -07:00
1697 changed files with 149983 additions and 36617 deletions

2
.github/CODEOWNERS vendored
View File

@@ -2,7 +2,7 @@
# See https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
# Frontend code owners
/frontend/ @rbren @amanape
/frontend/ @amanape
/openhands-ui/ @amanape
# Evaluation code owners

View File

@@ -18,7 +18,7 @@ DOCKER_RUN_COMMAND="docker run -it --rm \
docker.all-hands.dev/all-hands-ai/openhands:${SHORT_SHA}"
# Define the uvx command
UVX_RUN_COMMAND="uvx --python 3.12 --from git+https://github.com/All-Hands-AI/OpenHands@${BRANCH_NAME} openhands"
UVX_RUN_COMMAND="uvx --python 3.12 --from git+https://github.com/All-Hands-AI/OpenHands@${BRANCH_NAME}#subdirectory=openhands-cli openhands"
# Get the current PR body
PR_BODY=$(gh pr view "$PR_NUMBER" --json body --jq .body)

58
.github/workflows/cli-build-test.yml vendored Normal file
View File

@@ -0,0 +1,58 @@
# Workflow that builds and tests the CLI binary executable
name: CLI - Build and Test Binary
# Run on pushes to main branch and all pull requests, but only when CLI files change
on:
push:
branches:
- main
paths:
- "openhands-cli/**"
pull_request:
paths:
- "openhands-cli/**"
# Cancel previous runs if a new commit is pushed
concurrency:
group: ${{ github.workflow }}-${{ (github.head_ref && github.ref) || github.run_id }}
cancel-in-progress: true
jobs:
build-and-test-binary:
name: Build and test binary executable
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.12
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
version: "latest"
- name: Install dependencies
working-directory: openhands-cli
run: |
uv sync
- name: Build binary executable
working-directory: openhands-cli
run: |
./build.sh --install-pyinstaller | tee output.log
echo "Full output:"
cat output.log
if grep -q "❌" output.log; then
echo "❌ Found failure marker in output"
exit 1
fi
echo "✅ Build & test finished without ❌ markers"

23
.github/workflows/dispatch-to-docs.yml vendored Normal file
View File

@@ -0,0 +1,23 @@
name: Dispatch to docs repo
on:
push:
branches: [main]
paths:
- 'docs/**'
workflow_dispatch:
jobs:
dispatch:
runs-on: ubuntu-latest
strategy:
matrix:
repo: ["All-Hands-AI/docs"]
steps:
- name: Push to docs repo
uses: peter-evans/repository-dispatch@v3
with:
token: ${{ secrets.ALLHANDS_BOT_GITHUB_PAT }}
repository: ${{ matrix.repo }}
event-type: update
client-payload: '{"ref": "${{ github.ref }}", "sha": "${{ github.sha }}", "module": "openhands", "branch": "main"}'

228
.github/workflows/e2e-tests.yml vendored Normal file
View File

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

View File

@@ -0,0 +1,29 @@
# Feature branch preview for enterprise code
name: Enterprise Preview
# Run on PRs labeled
on:
pull_request:
types: [labeled]
# Match ghcr-build.yml, but don't interrupt it.
concurrency:
group: ${{ github.workflow }}-${{ (github.head_ref && github.ref) || github.run_id }}
cancel-in-progress: false
jobs:
# This must happen for the PR Docker workflow when the label is present,
# and also if it's added after the fact. Thus, it exists in both places.
enterprise-preview:
name: Enterprise preview
if: github.event.label.name == 'deploy'
runs-on: blacksmith-4vcpu-ubuntu-2204
steps:
# This should match the version in ghcr-build.yml
- name: Trigger remote job
run: |
curl --fail-with-body -sS -X POST \
-H "Authorization: Bearer ${{ secrets.PAT_TOKEN }}" \
-H "Accept: application/vnd.github+json" \
-d "{\"ref\": \"main\", \"inputs\": {\"openhandsPrNumber\": \"${{ github.event.pull_request.number }}\", \"deployEnvironment\": \"feature\", \"enterpriseImageTag\": \"pr-${{ github.event.pull_request.number }}\" }}" \
https://api.github.com/repos/All-Hands-AI/deploy/actions/workflows/deploy.yaml/dispatches

View File

@@ -10,14 +10,14 @@ on:
branches:
- main
tags:
- '*'
- "*"
pull_request:
workflow_dispatch:
inputs:
reason:
description: 'Reason for manual trigger'
description: "Reason for manual trigger"
required: true
default: ''
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:
@@ -46,6 +46,7 @@ jobs:
else
json=$(jq -n -c '[
{ image: "nikolaik/python-nodejs:python3.12-nodejs22", tag: "nikolaik" },
{ image: "ghcr.io/all-hands-ai/python-nodejs:python3.13-nodejs22-trixie", tag: "trixie" },
{ image: "ubuntu:24.04", tag: "ubuntu" }
]')
fi
@@ -120,7 +121,7 @@ jobs:
- name: Set up Python
uses: useblacksmith/setup-python@v6
with:
python-version: '3.12'
python-version: "3.12"
cache: poetry
- name: Install Python dependencies using Poetry
run: make install-python-dependencies POETRY_GROUP=main INSTALL_PLAYWRIGHT=0
@@ -136,6 +137,7 @@ jobs:
if: github.event.pull_request.head.repo.fork != true
shell: bash
run: |
./containers/build.sh -i runtime -o ${{ env.REPO_OWNER }} -t ${{ matrix.base_image.tag }} --dry
DOCKER_BUILD_JSON=$(jq -c . < docker-build-dry.json)
@@ -166,6 +168,92 @@ jobs:
name: runtime-src-${{ matrix.base_image.tag }}
path: containers/runtime
ghcr_build_enterprise:
name: Push Enterprise Image
runs-on: blacksmith-8vcpu-ubuntu-2204
permissions:
contents: read
packages: write
needs: [define-matrix, ghcr_build_app]
# Do not build enterprise in forks
if: github.event.pull_request.head.repo.fork != true
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
# Set up Docker Buildx for better performance
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver-opts: network=host
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/all-hands-ai/enterprise-server
tags: |
type=ref,event=branch
type=ref,event=pr
type=sha
type=sha,format=long
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
flavor: |
latest=auto
prefix=
suffix=
env:
DOCKER_METADATA_PR_HEAD_SHA: true
- name: Determine app image tag
shell: bash
run: |
# Duplicated with build.sh
sanitized_ref_name=$(echo "$GITHUB_REF_NAME" | sed 's/[^a-zA-Z0-9.-]\+/-/g')
OPENHANDS_BUILD_VERSION=$sanitized_ref_name
sanitized_ref_name=$(echo "$sanitized_ref_name" | tr '[:upper:]' '[:lower:]') # lower case is required in tagging
echo "OPENHANDS_DOCKER_TAG=${sanitized_ref_name}" >> $GITHUB_ENV
- name: Build and push Docker image
uses: useblacksmith/build-push-action@v1
with:
context: .
file: enterprise/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
OPENHANDS_VERSION=${{ env.OPENHANDS_DOCKER_TAG }}
platforms: linux/amd64
# Add build provenance
provenance: true
# Add build attestations for better security
sbom: true
enterprise-preview:
name: Enterprise preview
if: github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deploy')
runs-on: blacksmith-4vcpu-ubuntu-2204
needs: [ghcr_build_enterprise]
steps:
# This should match the version in enterprise-preview.yml
- name: Trigger remote job
run: |
curl --fail-with-body -sS -X POST \
-H "Authorization: Bearer ${{ secrets.PAT_TOKEN }}" \
-H "Accept: application/vnd.github+json" \
-d "{\"ref\": \"main\", \"inputs\": {\"openhandsPrNumber\": \"${{ github.event.pull_request.number }}\", \"deployEnvironment\": \"feature\", \"enterpriseImageTag\": \"pr-${{ github.event.pull_request.number }}\" }}" \
https://api.github.com/repos/All-Hands-AI/deploy/actions/workflows/deploy.yaml/dispatches
# Run unit tests with the Docker runtime Docker images as root
test_runtime_root:
name: RT Unit Tests (Root)
@@ -202,7 +290,7 @@ jobs:
- name: Set up Python
uses: useblacksmith/setup-python@v6
with:
python-version: '3.12'
python-version: "3.12"
cache: poetry
- name: Install Python dependencies using Poetry
run: make install-python-dependencies INSTALL_PLAYWRIGHT=0
@@ -225,7 +313,7 @@ jobs:
SANDBOX_RUNTIME_CONTAINER_IMAGE=$image_name \
TEST_IN_CI=true \
RUN_AS_OPENHANDS=false \
poetry run pytest -n 7 -raRs --reruns 2 --reruns-delay 5 -s ./tests/runtime --ignore=tests/runtime/test_browsergym_envs.py --durations=10
poetry run pytest -n 0 -raRs --reruns 2 --reruns-delay 5 -s ./tests/runtime --ignore=tests/runtime/test_browsergym_envs.py --durations=10
env:
DEBUG: "1"
@@ -264,7 +352,7 @@ jobs:
- name: Set up Python
uses: useblacksmith/setup-python@v6
with:
python-version: '3.12'
python-version: "3.12"
cache: poetry
- name: Install Python dependencies using Poetry
run: make install-python-dependencies POETRY_GROUP=main,test,runtime INSTALL_PLAYWRIGHT=0
@@ -284,7 +372,7 @@ jobs:
SANDBOX_RUNTIME_CONTAINER_IMAGE=$image_name \
TEST_IN_CI=true \
RUN_AS_OPENHANDS=true \
poetry run pytest -n 7 -raRs --reruns 2 --reruns-delay 5 -s ./tests/runtime --ignore=tests/runtime/test_browsergym_envs.py --durations=10
poetry run pytest -n 0 -raRs --reruns 2 --reruns-delay 5 -s ./tests/runtime --ignore=tests/runtime/test_browsergym_envs.py --durations=10
env:
DEBUG: "1"

View File

@@ -29,6 +29,12 @@ jobs:
run: |
cd frontend
npm install --frozen-lockfile
- name: Generate i18n and route types
run: |
cd frontend
npm run make-i18n
npx react-router typegen || true
- name: Fix frontend lint issues
run: |
cd frontend
@@ -45,7 +51,7 @@ jobs:
git config --local user.email "openhands@all-hands.dev"
git config --local user.name "OpenHands Bot"
git add -A
git commit -m "🤖 Auto-fix frontend linting issues"
git commit -m "🤖 Auto-fix frontend linting issues" --no-verify
git push
# Python lint fixes
@@ -87,5 +93,5 @@ jobs:
git config --local user.email "openhands@all-hands.dev"
git config --local user.name "OpenHands Bot"
git add -A
git commit -m "🤖 Auto-fix Python linting issues"
git commit -m "🤖 Auto-fix Python linting issues" --no-verify
git push

View File

@@ -55,6 +55,42 @@ jobs:
- name: Run pre-commit hooks
run: pre-commit run --all-files --show-diff-on-failure --config ./dev_config/python/.pre-commit-config.yaml
lint-enterprise-python:
name: Lint enterprise python
runs-on: blacksmith-4vcpu-ubuntu-2204
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up python
uses: useblacksmith/setup-python@v6
with:
python-version: 3.12
cache: "pip"
- name: Install pre-commit
run: pip install pre-commit==4.2.0
- name: Run pre-commit hooks
working-directory: ./enterprise
run: pre-commit run --all-files --config ./dev_config/python/.pre-commit-config.yaml
lint-cli-python:
name: Lint CLI python
runs-on: blacksmith-4vcpu-ubuntu-2204
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up python
uses: useblacksmith/setup-python@v6
with:
python-version: 3.12
cache: "pip"
- name: Install pre-commit
run: pip install pre-commit==4.2.0
- name: Run pre-commit hooks
working-directory: ./openhands-cli
run: pre-commit run --all-files --config ./dev_config/python/.pre-commit-config.yaml
# Check version consistency across documentation
check-version-consistency:
name: Check version consistency

70
.github/workflows/mdx-lint.yml vendored Normal file
View File

@@ -0,0 +1,70 @@
# Workflow that checks MDX format in docs/ folder
name: MDX Lint
# Run on pushes to main and on pull requests that modify docs/ files
on:
push:
branches:
- main
paths:
- 'docs/**/*.mdx'
pull_request:
paths:
- 'docs/**/*.mdx'
# 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:
mdx-lint:
name: Lint MDX files
runs-on: blacksmith-4vcpu-ubuntu-2204
steps:
- uses: actions/checkout@v4
- name: Install Node.js 22
uses: useblacksmith/setup-node@v5
with:
node-version: 22
- name: Install MDX dependencies
run: |
npm install @mdx-js/mdx@3 glob@10
- name: Validate MDX files
run: |
node -e "
const {compile} = require('@mdx-js/mdx');
const fs = require('fs');
const path = require('path');
const glob = require('glob');
async function validateMDXFiles() {
const files = glob.sync('docs/**/*.mdx');
console.log('Found', files.length, 'MDX files to validate');
let hasErrors = false;
for (const file of files) {
try {
const content = fs.readFileSync(file, 'utf8');
await compile(content);
console.log('✅ MDX parsing successful for', file);
} catch (err) {
console.error('❌ MDX parsing failed for', file, ':', err.message);
hasErrors = true;
}
}
if (hasErrors) {
console.error('\\n❌ Some MDX files have parsing errors. Please fix them before merging.');
process.exit(1);
} else {
console.log('\\n✅ All MDX files are valid!');
}
}
validateMDXFiles();
"

View File

@@ -19,12 +19,16 @@ jobs:
# Run python tests on Linux
test-on-linux:
name: Python Tests on Linux
runs-on: blacksmith-4vcpu-ubuntu-2204
runs-on: blacksmith-4vcpu-ubuntu-2404
env:
INSTALL_DOCKER: '0' # Set to '0' to skip Docker installation
INSTALL_DOCKER: "0" # Set to '0' to skip Docker installation
strategy:
matrix:
python-version: ['3.12']
python-version: ["3.12"]
permissions:
# For coverage comment and python-coverage-comment-action branch
pull-requests: write
contents: write
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
@@ -35,32 +39,41 @@ jobs:
- name: Setup Node.js
uses: useblacksmith/setup-node@v5
with:
node-version: '22.x'
node-version: "22.x"
- name: Install poetry via pipx
run: pipx install poetry
- name: Set up Python
uses: useblacksmith/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
cache: 'poetry'
cache: "poetry"
- name: Install Python dependencies using Poetry
run: poetry install --with dev,test,runtime
- name: Build Environment
run: make build
- name: Run Unit Tests
run: PYTHONPATH=".:$PYTHONPATH" poetry run pytest --forked -n auto -svv ./tests/unit
run: PYTHONPATH=".:$PYTHONPATH" poetry run pytest --forked -n auto -s ./tests/unit --cov=openhands --cov-branch
env:
COVERAGE_FILE: ".coverage.${{ matrix.python_version }}"
- name: Run Runtime Tests with CLIRuntime
run: PYTHONPATH=".:$PYTHONPATH" TEST_RUNTIME=cli poetry run pytest -svv tests/runtime/test_bash.py
- name: Run E2E Tests
run: PYTHONPATH=".:$PYTHONPATH" poetry run pytest -svv tests/e2e
run: PYTHONPATH=".:$PYTHONPATH" TEST_RUNTIME=cli poetry run pytest -s tests/runtime/test_bash.py --cov=openhands --cov-branch
env:
COVERAGE_FILE: ".coverage.runtime.${{ matrix.python_version }}"
- name: Store coverage file
uses: actions/upload-artifact@v4
with:
name: coverage-openhands
path: |
.coverage.${{ matrix.python_version }}
.coverage.runtime.${{ matrix.python_version }}
include-hidden-files: true
# Run specific Windows python tests
test-on-windows:
name: Python Tests on Windows
runs-on: windows-latest
strategy:
matrix:
python-version: ['3.12']
python-version: ["3.12"]
steps:
- uses: actions/checkout@v4
- name: Install pipx
@@ -71,11 +84,11 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'poetry'
cache: "poetry"
- name: Install Python dependencies using Poetry
run: poetry install --with dev,test,runtime
- name: Run Windows unit tests
run: poetry run pytest -svv tests/unit/test_windows_bash.py
run: poetry run pytest -svv tests/unit/runtime/utils/test_windows_bash.py
env:
PYTHONPATH: ".;$env:PYTHONPATH"
DEBUG: "1"
@@ -85,3 +98,106 @@ jobs:
PYTHONPATH: ".;$env:PYTHONPATH"
TEST_RUNTIME: local
DEBUG: "1"
test-enterprise:
name: Enterprise Python Unit Tests
runs-on: blacksmith-4vcpu-ubuntu-2404
strategy:
matrix:
python-version: ["3.12"]
steps:
- uses: actions/checkout@v4
- name: Install poetry via pipx
run: pipx install poetry
- name: Set up Python
uses: useblacksmith/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
cache: "poetry"
- name: Install Python dependencies using Poetry
working-directory: ./enterprise
run: poetry install --with dev,test
- name: Run Unit Tests
# Use base working directory for coverage paths to line up.
run: PYTHONPATH=".:$PYTHONPATH" poetry run --project=enterprise pytest --forked -n auto -s -p no:ddtrace -p no:ddtrace.pytest_bdd -p no:ddtrace.pytest_benchmark ./enterprise/tests/unit --cov=enterprise --cov-branch
env:
COVERAGE_FILE: ".coverage.enterprise.${{ matrix.python_version }}"
- name: Store coverage file
uses: actions/upload-artifact@v4
with:
name: coverage-enterprise
path: ".coverage.enterprise.${{ matrix.python_version }}"
include-hidden-files: true
# Run CLI unit tests
test-cli-python:
name: CLI Unit Tests
runs-on: blacksmith-4vcpu-ubuntu-2404
strategy:
matrix:
python-version: ["3.12"]
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python
uses: useblacksmith/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
version: "latest"
- name: Install dependencies
working-directory: ./openhands-cli
run: |
uv sync --group dev
- name: Run CLI unit tests
working-directory: ./openhands-cli
env:
# write coverage to repo root so the merge step finds it
COVERAGE_FILE: "${{ github.workspace }}/.coverage.openhands-cli.${{ matrix.python-version }}"
run: |
uv run pytest --forked -n auto -s \
-p no:ddtrace -p no:ddtrace.pytest_bdd -p no:ddtrace.pytest_benchmark \
tests --cov=openhands_cli --cov-branch
- name: Store coverage file
uses: actions/upload-artifact@v4
with:
name: coverage-openhands-cli
path: ".coverage.openhands-cli.${{ matrix.python-version }}"
include-hidden-files: true
coverage-comment:
name: Coverage Comment
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
needs: [test-on-linux, test-enterprise, test-cli-python]
permissions:
pull-requests: write
contents: write
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v5
id: download
with:
pattern: coverage-*
merge-multiple: true
- name: Create symlink for CLI source files
run: ln -sf openhands-cli/openhands_cli openhands_cli
- name: Coverage comment
id: coverage_comment
uses: py-cov-action/python-coverage-comment-action@v3
with:
GITHUB_TOKEN: ${{ github.token }}
MERGE_COVERAGE_FILES: true

View File

@@ -1,7 +1,7 @@
# Publishes the OpenHands PyPi package
name: Publish PyPi Package
# Triggered manually
on:
workflow_dispatch:
inputs:
@@ -9,6 +9,9 @@ on:
description: 'Reason for manual trigger'
required: true
default: ''
push:
tags:
- "*"
jobs:
release:

View File

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

View File

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

5
.gitignore vendored
View File

@@ -254,3 +254,8 @@ containers/runtime/Dockerfile
containers/runtime/project.tar.gz
containers/runtime/code
**/node_modules/
# test results
test-results
.sessions
.eval_sessions

View File

@@ -142,6 +142,35 @@ Your specialized knowledge and instructions here...
- Add the setting to the `Settings` model in `openhands/storage/data_models/settings.py`
- Update any relevant backend code to apply the setting (e.g., in session creation)
#### Settings UI Patterns:
There are two main patterns for saving settings in the OpenHands frontend:
**Pattern 1: Entity-based Resources (Immediate Save)**
- Used for: API Keys, Secrets, MCP Servers
- Behavior: Changes are saved immediately when user performs actions (add/edit/delete)
- Implementation:
- No "Save Changes" button
- No local state management or `isDirty` tracking
- Uses dedicated mutation hooks for each operation (e.g., `use-add-mcp-server.ts`, `use-delete-mcp-server.ts`)
- Each mutation triggers immediate API call with query invalidation for UI updates
- Example: MCP settings, API Keys & Secrets tabs
- Benefits: Simpler UX, no risk of losing changes, consistent with modern web app patterns
**Pattern 2: Form-based Settings (Manual Save)**
- Used for: Application settings, LLM configuration
- Behavior: Changes are accumulated locally and saved when user clicks "Save Changes"
- Implementation:
- Has "Save Changes" button that becomes enabled when changes are detected
- Uses local state management with `isDirty` tracking
- Uses `useSaveSettings` hook to save all changes at once
- Example: LLM tab, Application tab
- Benefits: Allows bulk changes, explicit save action, can validate all fields before saving
**When to use each pattern:**
- Use Pattern 1 (Immediate Save) for entity management where each item is independent
- Use Pattern 2 (Manual Save) for configuration forms where settings are interdependent or need validation
### Adding New LLM Models
To add a new LLM model to OpenHands, you need to update multiple files across both frontend and backend:

View File

@@ -113,19 +113,19 @@ individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within the
community.
### Slack and Discord Etiquettes
### Slack Etiquettes
These Slack and Discord etiquette guidelines are designed to foster an inclusive, respectful, and productive environment for all community members. By following these best practices, we ensure effective communication and collaboration while minimizing disruptions. Lets work together to build a supportive and welcoming community!
These Slack etiquette guidelines are designed to foster an inclusive, respectful, and productive environment for all community members. By following these best practices, we ensure effective communication and collaboration while minimizing disruptions. Lets work together to build a supportive and welcoming community!
- Communicate respectfully and professionally, avoiding sarcasm or harsh language, and remember that tone can be difficult to interpret in text.
- Use threads for specific discussions to keep channels organized and easier to follow.
- Tag others only when their input is critical or urgent, and use @here, @channel or @everyone sparingly to minimize disruptions.
- Be patient, as open-source contributors and maintainers often have other commitments and may need time to respond.
- Post questions or discussions in the most relevant channel (e.g., for [slack - #general](https://openhands-ai.slack.com/archives/C06P5NCGSFP) for general topics, [slack - #questions](https://openhands-ai.slack.com/archives/C06U8UTKSAD) for queries/questions, [discord - #general](https://discord.com/channels/1222935860639563850/1222935861386018885)).
- Post questions or discussions in the most relevant channel (e.g., for [slack - #general](https://openhands-ai.slack.com/archives/C06P5NCGSFP) for general topics, [slack - #questions](https://openhands-ai.slack.com/archives/C06U8UTKSAD) for queries/questions.
- When asking for help or raising issues, include necessary details like links, screenshots, or clear explanations to provide context.
- Keep discussions in public channels whenever possible to allow others to benefit from the conversation, unless the matter is sensitive or private.
- Always adhere to [our standards](https://github.com/All-Hands-AI/OpenHands/blob/main/CODE_OF_CONDUCT.md#our-standards) to ensure a welcoming and collaborative environment.
- If you choose to mute a channel, consider setting up alerts for topics that still interest you to stay engaged. For Slack, Go to Settings → Notifications → My Keywords to add specific keywords that will notify you when mentioned. For example, if you're here for discussions about LLMs, mute the channel if its too busy, but set notifications to alert you only when “LLMs” appears in messages. Also for Discord, go to the channel notifications and choose the option that best describes your need.
- If you choose to mute a channel, consider setting up alerts for topics that still interest you to stay engaged. For Slack, Go to Settings → Notifications → My Keywords to add specific keywords that will notify you when mentioned. For example, if you're here for discussions about LLMs, mute the channel if its too busy, but set notifications to alert you only when “LLMs” appears in messages.
## Attribution

View File

@@ -159,7 +159,7 @@ poetry run pytest ./tests/unit/test_*.py
To reduce build time (e.g., if no changes were made to the client-runtime component), you can use an existing Docker
container image by setting the SANDBOX_RUNTIME_CONTAINER_IMAGE environment variable to the desired Docker image.
Example: `export SANDBOX_RUNTIME_CONTAINER_IMAGE=ghcr.io/all-hands-ai/runtime:0.51-nikolaik`
Example: `export SANDBOX_RUNTIME_CONTAINER_IMAGE=ghcr.io/all-hands-ai/runtime:0.58-nikolaik`
## Develop inside Docker container

View File

@@ -1,7 +1,12 @@
The MIT License (MIT)
Portions of this software are licensed as follows:
* All content that resides under the enterprise/ directory is licensed under the license defined in "enterprise/LICENSE".
* Content outside of the above mentioned directories or restrictions above is available under the MIT license as defined below.
=====================
Copyright © 2023
The MIT License (MIT)
Copyright © 2025
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation

View File

@@ -11,8 +11,7 @@
<a href="https://github.com/All-Hands-AI/OpenHands/stargazers"><img src="https://img.shields.io/github/stars/All-Hands-AI/OpenHands?style=for-the-badge&color=blue" alt="Stargazers"></a>
<a href="https://github.com/All-Hands-AI/OpenHands/blob/main/LICENSE"><img src="https://img.shields.io/github/license/All-Hands-AI/OpenHands?style=for-the-badge&color=blue" alt="MIT License"></a>
<br/>
<a href="https://join.slack.com/t/openhands-ai/shared_invite/zt-3847of6xi-xuYJIPa6YIPg4ElbDWbtSA"><img src="https://img.shields.io/badge/Slack-Join%20Us-red?logo=slack&logoColor=white&style=for-the-badge" alt="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://all-hands.dev/joinslack"><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://github.com/All-Hands-AI/OpenHands/blob/main/CREDITS.md"><img src="https://img.shields.io/badge/Project-Credits-blue?style=for-the-badge&color=FFE165&logo=github&logoColor=white" alt="Credits"></a>
<br/>
<a href="https://docs.all-hands.dev/usage/getting-started"><img src="https://img.shields.io/badge/Documentation-000?logo=googledocs&logoColor=FFE165&style=for-the-badge" alt="Check out the documentation"></a>
@@ -44,45 +43,69 @@ Learn more at [docs.all-hands.dev](https://docs.all-hands.dev), or [sign up for
> [this short form](https://docs.google.com/forms/d/e/1FAIpQLSet3VbGaz8z32gW9Wm-Grl4jpt5WgMXPgJ4EDPVmCETCBpJtQ/viewform)
> to join our Design Partner program, where you'll get early access to commercial features and the opportunity to provide input on our product roadmap.
![App screenshot](./docs/static/img/screenshot.png)
## ☁️ OpenHands Cloud
The easiest way to get started with OpenHands is on [OpenHands Cloud](https://app.all-hands.dev),
which comes with $20 in free credits for new users.
## 💻 Running OpenHands Locally
OpenHands can also run on your local system using Docker.
See the [Running OpenHands](https://docs.all-hands.dev/usage/installation) guide for
system requirements and more information.
### Option 1: CLI Launcher (Recommended)
> [!WARNING]
> On a public network? See our [Hardened Docker Installation Guide](https://docs.all-hands.dev/usage/runtimes/docker#hardened-docker-installation)
> to secure your deployment by restricting network binding and implementing additional security measures.
The easiest way to run OpenHands locally is using the CLI launcher with [uv](https://docs.astral.sh/uv/). This provides better isolation from your current project's virtual environment and is required for OpenHands' default MCP servers.
**Install uv** (if you haven't already):
See the [uv installation guide](https://docs.astral.sh/uv/getting-started/installation/) for the latest installation instructions for your platform.
**Launch OpenHands**:
```bash
# Launch the GUI server
uvx --python 3.12 --from openhands-ai openhands serve
# Or launch the CLI
uvx --python 3.12 --from openhands-ai openhands
```
You'll find OpenHands running at [http://localhost:3000](http://localhost:3000) (for GUI mode)!
### Option 2: Docker
<details>
<summary>Click to expand Docker command</summary>
You can also run OpenHands directly with Docker:
```bash
docker pull docker.all-hands.dev/all-hands-ai/runtime:0.51-nikolaik
docker pull docker.all-hands.dev/all-hands-ai/runtime:0.58-nikolaik
docker run -it --rm --pull=always \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.51-nikolaik \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.58-nikolaik \
-e LOG_ALL_EVENTS=true \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ~/.openhands:/.openhands \
-p 3000:3000 \
--add-host host.docker.internal:host-gateway \
--name openhands-app \
docker.all-hands.dev/all-hands-ai/openhands:0.51
docker.all-hands.dev/all-hands-ai/openhands:0.58
```
</details>
> **Note**: If you used OpenHands before version 0.44, you may want to run `mv ~/.openhands-state ~/.openhands` to migrate your conversation history to the new location.
You'll find OpenHands running at [http://localhost:3000](http://localhost:3000)!
> [!WARNING]
> On a public network? See our [Hardened Docker Installation Guide](https://docs.all-hands.dev/usage/runtimes/docker#hardened-docker-installation)
> to secure your deployment by restricting network binding and implementing additional security measures.
### Getting Started
When you open the application, you'll be asked to choose an LLM provider and add an API key.
[Anthropic's Claude Sonnet 4](https://www.anthropic.com/api) (`anthropic/claude-sonnet-4-20250514`)
[Anthropic's Claude Sonnet 4.5](https://www.anthropic.com/api) (`anthropic/claude-sonnet-4-5-20250929`)
works best, but you have [many options](https://docs.all-hands.dev/usage/llms).
See the [Running OpenHands](https://docs.all-hands.dev/usage/installation) guide for
system requirements and more information.
## 💡 Other ways to run OpenHands
> [!WARNING]
@@ -93,8 +116,8 @@ works best, but you have [many options](https://docs.all-hands.dev/usage/llms).
> [OpenHands Cloud Helm Chart](https://github.com/all-Hands-AI/OpenHands-cloud)
You can [connect OpenHands to your local filesystem](https://docs.all-hands.dev/usage/runtimes/docker#connecting-to-your-filesystem),
run OpenHands in a scriptable [headless mode](https://docs.all-hands.dev/usage/how-to/headless-mode),
interact with it via a [friendly CLI](https://docs.all-hands.dev/usage/how-to/cli-mode),
run OpenHands in a scriptable [headless mode](https://docs.all-hands.dev/usage/how-to/headless-mode),
or run it on tagged issues with [a github action](https://docs.all-hands.dev/usage/how-to/github-action).
Visit [Running OpenHands](https://docs.all-hands.dev/usage/installation) for more information and setup instructions.
@@ -104,7 +127,6 @@ If you want to modify the OpenHands source code, check out [Development.md](http
Having issues? The [Troubleshooting Guide](https://docs.all-hands.dev/usage/troubleshooting) can help.
## 📖 Documentation
<a href="https://deepwiki.com/All-Hands-AI/OpenHands"><img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki" title="Autogenerated Documentation by DeepWiki"></a>
To learn more about the project, and for tips on using OpenHands,
check out our [documentation](https://docs.all-hands.dev/usage/getting-started).
@@ -115,10 +137,9 @@ troubleshooting resources, and advanced configuration options.
## 🤝 How to Join the Community
OpenHands is a community-driven project, and we welcome contributions from everyone. We do most of our communication
through Slack, so this is the best place to start, but we also are happy to have you contact us on Discord or Github:
through Slack, so this is the best place to start, but we also are happy to have you contact us on Github:
- [Join our Slack workspace](https://join.slack.com/t/openhands-ai/shared_invite/zt-3847of6xi-xuYJIPa6YIPg4ElbDWbtSA) - Here we talk about research, architecture, and future development.
- [Join our Discord server](https://discord.gg/ESHStjSjD4) - This is a community-run server for general discussion, questions, and feedback.
- [Join our Slack workspace](https://all-hands.dev/joinslack) - Here we talk about research, architecture, and future development.
- [Read or post Github Issues](https://github.com/All-Hands-AI/OpenHands/issues) - Check out the issues we're working on, or add your own ideas.
See more about the community in [COMMUNITY.md](./COMMUNITY.md) or find details on contributing in [CONTRIBUTING.md](./CONTRIBUTING.md).
@@ -135,7 +156,7 @@ See the monthly OpenHands roadmap [here](https://github.com/orgs/All-Hands-AI/pr
## 📜 License
Distributed under the MIT License. See [`LICENSE`](./LICENSE) for more information.
Distributed under the MIT License, with the exception of the `enterprise/` folder. See [`LICENSE`](./LICENSE) for more information.
## 🙏 Acknowledgements

View File

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

View File

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

View File

@@ -93,8 +93,7 @@ def build_vscode_extension():
def build(setup_kwargs):
"""
This function is called by Poetry during the build process.
"""This function is called by Poetry during the build process.
`setup_kwargs` is a dictionary that will be passed to `setuptools.setup()`.
"""
print('--- Running custom Poetry build script (build_vscode.py) ---')

View File

@@ -219,6 +219,14 @@ correct_num = 5
api_key = ""
model = "gpt-4o"
# Example routing LLM configuration for multimodal model routing
# Uncomment and configure to enable model routing with a secondary model
#[llm.secondary_model]
#model = "kimi-k2"
#api_key = ""
#for_routing = true
#max_input_tokens = 128000
#################################### Agent ###################################
# Configuration for agents (group name starts with 'agent')
@@ -363,10 +371,11 @@ classpath = "my_package.my_module.MyCustomAgent"
#confirmation_mode = false
# The security analyzer to use (For Headless / CLI only - In Web this is overridden by Session Init)
#security_analyzer = ""
# Available options: 'llm' (default), 'invariant'
#security_analyzer = "llm"
# Whether to enable security analyzer
#enable_security_analyzer = false
#enable_security_analyzer = true
#################################### Condenser #################################
# Condensers control how conversation history is managed and compressed when
@@ -479,3 +488,55 @@ type = "noop"
# Run the runtime sandbox container in privileged mode for use with docker-in-docker
#privileged = false
#################################### MCP #####################################
# Configuration for Model Context Protocol (MCP) servers
# MCP allows OpenHands to communicate with external tool servers
##############################################################################
[mcp]
# SSE servers - Server-Sent Events transport (legacy)
#sse_servers = [
# # Basic SSE server with just a URL
# "http://localhost:8080/mcp/sse",
#
# # SSE server with authentication
# {url = "https://api.example.com/mcp/sse", api_key = "your-api-key"}
#]
# SHTTP servers - Streamable HTTP transport (recommended)
#shttp_servers = [
# # Basic SHTTP server with default 60s timeout
# "https://api.example.com/mcp/shttp",
#
# # SHTTP server with custom timeout for long-running tools
# {
# url = "https://api.example.com/mcp/shttp",
# api_key = "your-api-key",
# timeout = 180 # 3 minutes for processing-heavy tools (1-3600 seconds)
# }
#]
# Stdio servers - Direct process communication (development only)
#stdio_servers = [
# # Basic stdio server
# {name = "filesystem", command = "npx", args = ["@modelcontextprotocol/server-filesystem", "/"]},
#
# # Stdio server with environment variables
# {
# name = "fetch",
# command = "uvx",
# args = ["mcp-server-fetch"],
# env = {DEBUG = "true"}
# }
#]
#################################### Model Routing ############################
# Configuration for experimental model routing feature
# Enables intelligent switching between different LLM models for specific purposes
##############################################################################
[model_routing]
# Router to use for model selection
# Available options:
# - "noop_router" (default): No routing, always uses primary LLM
# - "multimodal_router": A router that switches between primary and secondary models, depending on whether the input is multimodal or not
#router_name = "noop_router"

View File

@@ -1,5 +1,5 @@
ARG OPENHANDS_BUILD_VERSION=dev
FROM node:24.3.0-bookworm-slim AS frontend-builder
FROM node:24.8-trixie-slim AS frontend-builder
WORKDIR /app
@@ -9,7 +9,7 @@ RUN npm ci
COPY frontend ./
RUN npm run build
FROM python:3.12.10-slim AS base
FROM python:3.13.7-slim-trixie AS base
FROM base AS backend-builder
WORKDIR /app
@@ -21,7 +21,7 @@ ENV POETRY_NO_INTERACTION=1 \
POETRY_CACHE_DIR=/tmp/poetry_cache
RUN apt-get update -y \
&& apt-get install -y curl make git build-essential \
&& apt-get install -y curl make git build-essential jq gettext \
&& python3 -m pip install poetry --break-system-packages
COPY pyproject.toml poetry.lock ./
@@ -58,34 +58,34 @@ RUN sed -i 's/^UID_MIN.*/UID_MIN 499/' /etc/login.defs
# Default is 60000, but we've seen up to 200000
RUN sed -i 's/^UID_MAX.*/UID_MAX 1000000/' /etc/login.defs
RUN groupadd --gid $OPENHANDS_USER_ID app
RUN groupadd --gid $OPENHANDS_USER_ID openhands
RUN useradd -l -m -u $OPENHANDS_USER_ID --gid $OPENHANDS_USER_ID -s /bin/bash openhands && \
usermod -aG app openhands && \
usermod -aG openhands openhands && \
usermod -aG sudo openhands && \
echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
RUN chown -R openhands:app /app && chmod -R 770 /app
RUN sudo chown -R openhands:app $WORKSPACE_BASE && sudo chmod -R 770 $WORKSPACE_BASE
RUN chown -R openhands:openhands /app && chmod -R 770 /app
RUN sudo chown -R openhands:openhands $WORKSPACE_BASE && sudo chmod -R 770 $WORKSPACE_BASE
USER openhands
ENV VIRTUAL_ENV=/app/.venv \
PATH="/app/.venv/bin:$PATH" \
PYTHONPATH='/app'
COPY --chown=openhands:app --chmod=770 --from=backend-builder ${VIRTUAL_ENV} ${VIRTUAL_ENV}
COPY --chown=openhands:openhands --chmod=770 --from=backend-builder ${VIRTUAL_ENV} ${VIRTUAL_ENV}
COPY --chown=openhands:app --chmod=770 ./microagents ./microagents
COPY --chown=openhands:app --chmod=770 ./openhands ./openhands
COPY --chown=openhands:app --chmod=777 ./openhands/runtime/plugins ./openhands/runtime/plugins
COPY --chown=openhands:app pyproject.toml poetry.lock README.md MANIFEST.in LICENSE ./
COPY --chown=openhands:openhands --chmod=770 ./microagents ./microagents
COPY --chown=openhands:openhands --chmod=770 ./openhands ./openhands
COPY --chown=openhands:openhands --chmod=777 ./openhands/runtime/plugins ./openhands/runtime/plugins
COPY --chown=openhands:openhands pyproject.toml poetry.lock README.md MANIFEST.in 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
# Add this line to set group ownership of all files/directories not already in "app" group
# openhands:openhands -> openhands:app
RUN find /app \! -group app -exec chgrp app {} +
# openhands:openhands -> openhands:openhands
RUN find /app \! -group openhands -exec chgrp openhands {} +
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
COPY --chown=openhands:openhands --chmod=770 --from=frontend-builder /app/build ./frontend/build
COPY --chown=openhands:openhands --chmod=770 ./containers/app/entrypoint.sh /app/entrypoint.sh
USER root

View File

@@ -54,7 +54,7 @@ else
fi
fi
fi
usermod -aG app enduser
usermod -aG openhands enduser
# get the user group of /var/run/docker.sock and set openhands to that group
DOCKER_SOCKET_GID=$(stat -c '%g' /var/run/docker.sock)
echo "Docker socket group id: $DOCKER_SOCKET_GID"

View File

@@ -12,7 +12,7 @@ services:
- SANDBOX_API_HOSTNAME=host.docker.internal
- DOCKER_HOST_ADDR=host.docker.internal
#
- SANDBOX_RUNTIME_CONTAINER_IMAGE=${SANDBOX_RUNTIME_CONTAINER_IMAGE:-ghcr.io/all-hands-ai/runtime:0.51-nikolaik}
- SANDBOX_RUNTIME_CONTAINER_IMAGE=${SANDBOX_RUNTIME_CONTAINER_IMAGE:-ghcr.io/all-hands-ai/runtime:0.58-nikolaik}
- SANDBOX_USER_ID=${SANDBOX_USER_ID:-1234}
- WORKSPACE_MOUNT_PATH=${WORKSPACE_BASE:-$PWD/workspace}
ports:

View File

@@ -3,9 +3,9 @@ repos:
rev: v5.0.0
hooks:
- id: trailing-whitespace
exclude: ^(docs/|modules/|python/|openhands-ui/|third_party/)
exclude: ^(docs/|modules/|python/|openhands-ui/|third_party/|enterprise/|openhands-cli/)
- id: end-of-file-fixer
exclude: ^(docs/|modules/|python/|openhands-ui/|third_party/)
exclude: ^(docs/|modules/|python/|openhands-ui/|third_party/|enterprise/|openhands-cli/)
- id: check-yaml
args: ["--allow-multiple-documents"]
- id: debug-statements
@@ -28,19 +28,28 @@ repos:
entry: ruff check --config dev_config/python/ruff.toml
types_or: [python, pyi, jupyter]
args: [--fix, --unsafe-fixes]
exclude: third_party/
exclude: ^(third_party/|enterprise/|openhands-cli/)
# Run the formatter.
- id: ruff-format
entry: ruff format --config dev_config/python/ruff.toml
types_or: [python, pyi, jupyter]
exclude: third_party/
exclude: ^(third_party/|enterprise/|openhands-cli/)
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.15.0
hooks:
- id: mypy
additional_dependencies:
[types-requests, types-setuptools, types-pyyaml, types-toml, types-docker, pydantic, lxml]
[
types-requests,
types-setuptools,
types-pyyaml,
types-toml,
types-docker,
types-Markdown,
pydantic,
lxml,
]
# To see gaps add `--html-report mypy-report/`
entry: mypy --config-file dev_config/python/mypy.ini openhands/
always_run: true

View File

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

View File

@@ -1,5 +1,5 @@
# Exclude third-party runtime directory from linting
exclude = ["third_party/"]
exclude = ["third_party/", "enterprise/"]
[lint]
select = [

View File

@@ -7,7 +7,7 @@ services:
image: openhands:latest
container_name: openhands-app-${DATE:-}
environment:
- SANDBOX_RUNTIME_CONTAINER_IMAGE=${SANDBOX_RUNTIME_CONTAINER_IMAGE:-docker.all-hands.dev/all-hands-ai/runtime:0.51-nikolaik}
- SANDBOX_RUNTIME_CONTAINER_IMAGE=${SANDBOX_RUNTIME_CONTAINER_IMAGE:-docker.all-hands.dev/all-hands-ai/runtime:0.58-nikolaik}
#- SANDBOX_USER_ID=${SANDBOX_USER_ID:-1234} # enable this only if you want a specific non-root sandbox user but you will have to manually adjust permissions of ~/.openhands for this user
- WORKSPACE_MOUNT_PATH=${WORKSPACE_BASE:-$PWD/workspace}
ports:

View File

@@ -1,17 +1,36 @@
# Setup
# OpenHands Documentation
```
This directory contains the documentation for OpenHands. The documentation is automatically synchronized with the [All-Hands-AI/docs](https://github.com/All-Hands-AI/docs) repository, which hosts the unified documentation site using Mintlify.
## Documentation Structure
The documentation files in this directory are automatically included in the main documentation site via Git submodules. When you make changes to documentation in this repository, they will be automatically synchronized to the docs repository.
## How It Works
1. **Automatic Sync**: When documentation changes are pushed to the `main` branch, a GitHub Action automatically notifies the docs repository
2. **Submodule Update**: The docs repository updates its submodule reference to include your latest changes
3. **Site Rebuild**: Mintlify automatically rebuilds and deploys the documentation site
## Making Documentation Changes
Simply edit the documentation files in this directory as usual. The synchronization happens automatically when changes are merged to the main branch.
## Local Development
For local documentation development in this repository only:
```bash
npm install -g mint
```
or
```
# or
yarn global add mint
```
# Preview
```
# Preview local changes
mint dev
```
For the complete unified documentation site, work with the [All-Hands-AI/docs](https://github.com/All-Hands-AI/docs) repository.
## Configuration
The Mintlify configuration (`docs.json`) has been moved to the root of the [All-Hands-AI/docs](https://github.com/All-Hands-AI/docs) repository to enable unified documentation across multiple repositories.

View File

@@ -3,18 +3,16 @@
"theme": "mint",
"name": "All Hands Docs",
"colors": {
"primary": "#99873c",
"light": "#ffe165",
"dark": "#ffe165"
"primary": "#99873c"
},
"background": {
"color": {
"light": "#f7f3ee",
"dark": "#0B0D0E"
"light": "#f7f3ee"
}
},
"appearance": {
"default": "light"
"default": "light",
"strict": true
},
"favicon": "/logo-square.png",
"navigation": {
@@ -31,6 +29,7 @@
"group": "OpenHands Cloud",
"pages": [
"usage/cloud/openhands-cloud",
"usage/cloud/pro-subscription",
{
"group": "Integrations",
"pages": [
@@ -109,8 +108,7 @@
},
"usage/configuration-options",
"usage/how-to/custom-sandbox-guide",
"usage/search-engine-setup",
"usage/mcp"
"usage/search-engine-setup"
]
}
]
@@ -118,7 +116,13 @@
{
"group": "Customizations & Settings",
"pages": [
"usage/common-settings",
{
"group": "OpenHands Settings",
"pages": [
"usage/settings/secrets-settings",
"usage/settings/mcp-settings"
]
},
"usage/prompting/repository",
{
"group": "Microagents",
@@ -208,9 +212,8 @@
},
"footer": {
"socials": {
"slack": "https://join.slack.com/t/openhands-ai/shared_invite/zt-3847of6xi-xuYJIPa6YIPg4ElbDWbtSA",
"github": "https://github.com/All-Hands-AI/OpenHands",
"discord": "https://discord.gg/ESHStjSjD4"
"slack": "https://all-hands.dev/joinslack",
"github": "https://github.com/All-Hands-AI/OpenHands"
}
},
"contextual": {

View File

@@ -4,7 +4,8 @@ description: OpenHands - Code Less, Make More
icon: book-open
mode: wide
---
Use AI to tackle the toil in your backlog. Our agents have all the same tools as a human developer: they can modify code, run commands, browse the web, call APIs, and yes-even copy code snippets from StackOverflow.
Use AI to tackle the toil in your backlog. Our agents have all the same tools as a human developer:
they can modify code, run commands, browse the web, call APIs, and yes-even copy code snippets from StackOverflow.
<iframe
className="w-full aspect-video"

File diff suppressed because it is too large Load Diff

14
docs/reo-init.js Normal file
View File

@@ -0,0 +1,14 @@
// Reo.dev tracking initialization
(function() {
var e, t, n;
e = "6bac7145b4ee6ec";
t = function() {
Reo.init({clientID: "6bac7145b4ee6ec"});
};
n = document.createElement("script");
n.src = "https://static.reo.dev/" + e + "/reo.js";
n.defer = true;
n.onload = t;
document.head.appendChild(n);
})();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 15 KiB

BIN
docs/static/img/jira-admin-configure.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
docs/static/img/jira-admin-edit.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

BIN
docs/static/img/jira-dc-admin-edit.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
docs/static/img/jira-dc-user-link.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
docs/static/img/jira-dc-user-unlink.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
docs/static/img/jira-user-link.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
docs/static/img/jira-user-unlink.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
docs/static/img/linear-admin-edit.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
docs/static/img/linear-user-link.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
docs/static/img/linear-user-unlink.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 663 KiB

View File

Before

Width:  |  Height:  |  Size: 113 KiB

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -2,55 +2,102 @@
title: Backend Architecture
---
<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 System Architecture Diagram (July 4, 2024)</em></p>
</div>
This is a high-level overview of the system architecture. The system is divided into two main components: the frontend and the backend. The frontend is responsible for handling user interactions and displaying the results. The backend is responsible for handling the business logic and executing the agents.
# Frontend architecture
# System overview
![system_architecture.svg](/static/img/system_architecture.svg)
```mermaid
flowchart LR
U["User"] --> FE["Frontend (SPA)"]
FE -- "HTTP/WS" --> BE["OpenHands Backend"]
BE --> ES["EventStream"]
BE --> ST["Storage"]
BE --> RT["Runtime Interface"]
BE --> LLM["LLM Providers"]
subgraph Runtime
direction TB
RT --> DRT["Docker Runtime"]
RT --> LRT["Local Runtime"]
RT --> RRT["Remote Runtime"]
DRT --> AES["Action Execution Server"]
LRT --> AES
RRT --> AES
AES --> Bash["Bash Session"]
AES --> Jupyter["Jupyter Plugin"]
AES --> Browser["BrowserEnv"]
end
```
This Overview is simplified to show the main components and their interactions. For a more detailed view of the backend architecture, see the Backend Architecture section below.
# Backend Architecture
_**Disclaimer**: The backend architecture is a work in progress and is subject to change. The following diagram shows the current architecture of the backend based on the commit that is shown in the footer of the diagram._
![backend_architecture.svg](/static/img/backend_architecture.svg)
```mermaid
classDiagram
class Agent {
<<abstract>>
+sandbox_plugins: list[PluginRequirement]
}
class CodeActAgent {
+tools
}
Agent <|-- CodeActAgent
class EventStream
class Observation
class Action
Action --> Observation
Agent --> EventStream
class Runtime {
+connect()
+send_action_for_execution()
}
class ActionExecutionClient {
+_send_action_server_request()
}
class DockerRuntime
class LocalRuntime
class RemoteRuntime
Runtime <|-- ActionExecutionClient
ActionExecutionClient <|-- DockerRuntime
ActionExecutionClient <|-- LocalRuntime
ActionExecutionClient <|-- RemoteRuntime
class ActionExecutionServer {
+/execute_action
+/alive
}
class BashSession
class JupyterPlugin
class BrowserEnv
ActionExecutionServer --> BashSession
ActionExecutionServer --> JupyterPlugin
ActionExecutionServer --> BrowserEnv
Agent --> Runtime
Runtime ..> ActionExecutionServer : REST
```
<details>
<summary>Updating this Diagram</summary>
<div>
The generation of the backend architecture diagram is partially automated.
The diagram is generated from the type hints in the code using the py2puml
tool. The diagram is then manually reviewed, adjusted and exported to PNG
and SVG.
We maintain architecture diagrams inline with Mermaid in this MDX.
## Prerequisites
- Running python environment in which openhands is executable
(according to the instructions in the README.md file in the root of the repository)
- [py2puml](https://github.com/lucsorel/py2puml) installed
## Steps
1. Autogenerate the diagram by running the following command from the root of the repository:
`py2puml openhands openhands > docs/architecture/backend_architecture.puml`
2. Open the generated file in a PlantUML editor, e.g. Visual Studio Code with the PlantUML extension or [PlantText](https://www.planttext.com/)
3. Review the generated PUML and make all necessary adjustments to the diagram (add missing parts, fix mistakes, improve positioning).
_py2puml creates the diagram based on the type hints in the code, so missing or incorrect type hints may result in an incomplete or incorrect diagram._
4. Review the diff between the new and the previous diagram and manually check if the changes are correct.
_Make sure not to remove parts that were manually added to the diagram in the past and are still relevant._
5. Add the commit hash of the commit that was used to generate the diagram to the diagram footer.
6. Export the diagram as PNG and SVG files and replace the existing diagrams in the `docs/architecture` directory. This can be done with (e.g. [PlantText](https://www.planttext.com/))
Guidance:
- Edit the Mermaid blocks directly (flowchart/classDiagram).
- Quote labels and edge text for GitHub preview compatibility.
- Keep relationships concise and reflect stable abstractions (agents, runtime client/server, plugins).
- Verify accuracy against code:
- openhands/runtime/impl/action_execution/action_execution_client.py
- openhands/runtime/impl/docker/docker_runtime.py
- openhands/runtime/impl/local/local_runtime.py
- openhands/runtime/action_execution_server.py
- openhands/runtime/plugins/*
- Build docs locally or view on GitHub to confirm diagrams render.
</div>
</details>

View File

@@ -52,7 +52,7 @@ graph TD
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. 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
5. Communication: The OpenHands backend (client: `openhands/runtime/impl/action_execution/action_execution_client.py`; runtimes: `openhands/runtime/impl/docker/docker_runtime.py`, `openhands/runtime/impl/local/local_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 action execution server sends execution results back to the OpenHands backend as observations
@@ -72,7 +72,7 @@ Check out the [relevant code](https://github.com/All-Hands-AI/OpenHands/blob/mai
### Image Tagging System
OpenHands uses a three-tag system for its runtime images to balance reproducibility with flexibility.
Tags may be in one of 2 formats:
The tags are:
- **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`)
@@ -119,18 +119,52 @@ This tagging approach allows OpenHands to efficiently manage both development an
2. The system can quickly rebuild images when minor changes occur (by leveraging recent compatible images)
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
## Volume mounts: named volumes and overlay
OpenHands supports both bind mounts and Docker named volumes in SandboxConfig.volumes:
- Bind mount: "/abs/host/path:/container/path[:mode]"
- Named volume: "volume:`<name>`:/container/path[:mode]" or any non-absolute host spec treated as a named volume
Overlay mode (copy-on-write layer) is supported for bind mounts by appending ":overlay" to the mode (e.g., ":ro,overlay").
To enable overlay COW, set SANDBOX_VOLUME_OVERLAYS to a writable host directory; per-container upper/work dirs are created under it. If SANDBOX_VOLUME_OVERLAYS is unset, overlay mounts are skipped.
Implementation references:
- openhands/runtime/impl/docker/docker_runtime.py (named volumes in _build_docker_run_args; overlay mounts in _process_overlay_mounts)
- openhands/core/config/sandbox_config.py (volumes field)
## Runtime Plugin System
The OpenHands Runtime supports a plugin system that allows for extending functionality and customizing the runtime environment. Plugins are initialized when the runtime client starts up.
The OpenHands Runtime supports a plugin system that allows for extending functionality and customizing the runtime environment. Plugins are initialized when the action execution server starts up inside the runtime.
Check [an example of Jupyter plugin here](https://github.com/All-Hands-AI/OpenHands/blob/ecf4aed28b0cf7c18d4d8ff554883ba182fc6bdd/openhands/runtime/plugins/jupyter/__init__.py#L21-L55) if you want to implement your own plugin.
## Ports and URLs
*More details about the Plugin system are still under construction - contributions are welcomed!*
- Host port allocation uses file-locked ranges for stability and concurrency:
- Main runtime port: find_available_port_with_lock on configured range
- VSCode port: SandboxConfig.sandbox.vscode_port if provided, else find_available_port_with_lock in VSCODE_PORT_RANGE
- App ports: two additional ranges for plugin/web apps
- DOCKER_HOST_ADDR (if set) adjusts how URLs are formed for LocalRuntime/Docker environments.
- VSCode URL is exposed with a connection token from the action execution server endpoint /vscode/connection_token and rendered as:
- Docker/Local: http://localhost:{port}/?tkn={token}&folder={workspace_mount_path_in_sandbox}
- RemoteRuntime: scheme://vscode-{host}/?tkn={token}&folder={workspace_mount_path_in_sandbox}
References:
- openhands/runtime/impl/docker/docker_runtime.py (port ranges, locking, DOCKER_HOST_ADDR, vscode_url)
- openhands/runtime/impl/local/local_runtime.py (vscode_url factory)
- openhands/runtime/impl/remote/remote_runtime.py (vscode_url mapping)
- openhands/runtime/action_execution_server.py (/vscode/connection_token)
Examples:
- Jupyter: openhands/runtime/plugins/jupyter/__init__.py (JupyterPlugin, Kernel Gateway)
- VS Code: openhands/runtime/plugins/vscode/* (VSCodePlugin, exposes tokenized URL)
- Agent Skills: openhands/runtime/plugins/agent_skills/*
Key aspects of the plugin system:
1. Plugin Definition: Plugins are defined as Python classes that inherit from a base `Plugin` class
2. Plugin Registration: Available plugins are registered in an `ALL_PLUGINS` dictionary
2. Plugin Registration: Available plugins are registered in `openhands/runtime/plugins/__init__.py` via `ALL_PLUGINS`
3. Plugin Specification: Plugins are associated with `Agent.sandbox_plugins: list[PluginRequirement]`. Users can specify which plugins to load when initializing the runtime
4. Initialization: Plugins are initialized asynchronously when the runtime client starts
5. Usage: The runtime client can use initialized plugins to extend its capabilities (e.g., the JupyterPlugin for running IPython cells)
4. Initialization: Plugins are initialized asynchronously when the runtime starts and are accessible to actions
5. Usage: Plugins extend capabilities (e.g., Jupyter for IPython cells); the server exposes any web endpoints (ports) via host port mapping

View File

@@ -8,9 +8,21 @@ description: This guide walks you through the process of installing OpenHands Cl
- Signed in to [OpenHands Cloud](https://app.all-hands.dev) with [a Bitbucket account](/usage/cloud/openhands-cloud).
## Adding Bitbucket Repository Access
Upon signing into OpenHands Cloud with a Bitbucket account, OpenHands will have access to your repositories.
## Working With Bitbucket Repos in Openhands Cloud
After signing in with a Bitbucket account, use the `Open Repository` section to select the appropriate repository and
branch you'd like OpenHands to work on. Then click on `Launch` to start the conversation!
![Connect Repo](/static/img/connect-repo.png)
## IP Whitelisting
If your Bitbucket Cloud instance has IP restrictions, you'll need to whitelist the following IP addresses to allow OpenHands to access your repositories:
If your Bitbucket Cloud instance has IP restrictions, you'll need to whitelist the following IP addresses to allow
OpenHands to access your repositories:
### Core App IP
```
@@ -31,17 +43,6 @@ If your Bitbucket Cloud instance has IP restrictions, you'll need to whitelist t
34.60.55.59
```
## Adding Bitbucket Repository Access
Upon signing into OpenHands Cloud with a Bitbucket account, OpenHands will have access to your repositories.
## Working With Bitbucket Repos in Openhands Cloud
After signing in with a Bitbucket account, use the `select a repo` and `select a branch` dropdowns to select the
appropriate repository and branch you'd like OpenHands to work on. Then click on `Launch` to start the conversation!
![Connect Repo](/static/img/connect-repo-no-github.png)
## Next Steps
- [Learn about the Cloud UI](/usage/cloud/cloud-ui).

View File

@@ -12,104 +12,92 @@ For the available API endpoints, refer to the
To use the OpenHands Cloud API, you'll need to generate an API key:
1. Log in to your [OpenHands Cloud](https://app.all-hands.dev) account.
2. Navigate to the [Settings page](https://app.all-hands.dev/settings).
3. Select the `API Keys` tab.
4. Click `Create API Key`.
5. Give your key a descriptive name (Example: "Development" or "Production") and select `Create`.
6. Copy the generated API key and store it securely. It will only be shown once.
2. Navigate to the [Settings > API Keys](https://app.all-hands.dev/settings/api-keys) page.
3. Click `Create API Key`.
4. Give your key a descriptive name (Example: "Development" or "Production") and select `Create`.
5. Copy the generated API key and store it securely. It will only be shown once.
![API Key Generation](/static/img/api-key-generation.png)
## API Usage
## API Usage Example
### Starting a New Conversation
To start a new conversation with OpenHands to perform a task, you'll need to make a POST request to the conversation endpoint.
To start a new conversation with OpenHands to perform a task,
[you'll need to make a POST request to the conversation endpoint](/api-reference/new-conversation).
#### Request Parameters
<Tabs>
<Tab title="cURL">
```bash
curl -X POST "https://app.all-hands.dev/api/conversations" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"initial_user_msg": "Check whether there is any incorrect information in the README.md file and send a PR to fix it if so.",
"repository": "yourusername/your-repo"
}'
```
</Tab>
<Tab title="Python (with requests)">
```python
import requests
| Parameter | Type | Required | Description |
|--------------------|----------|----------|------------------------------------------------------------------------------------------------------|
| `initial_user_msg` | string | Yes | The initial message to start the conversation. |
| `repository` | string | No | Git repository name to provide context in the format `owner/repo`. You must have access to the repo. |
api_key = "YOUR_API_KEY"
url = "https://app.all-hands.dev/api/conversations"
#### Examples
<Accordion title="cURL">
```bash
curl -X POST "https://app.all-hands.dev/api/conversations" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"initial_user_msg": "Check whether there is any incorrect information in the README.md file and send a PR to fix it if so.",
"repository": "yourusername/your-repo"
}'
```
</Accordion>
<Accordion title="Python (with requests)">
```python
import requests
api_key = "YOUR_API_KEY"
url = "https://app.all-hands.dev/api/conversations"
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
data = {
"initial_user_msg": "Check whether there is any incorrect information in the README.md file and send a PR to fix it if so.",
"repository": "yourusername/your-repo"
}
response = requests.post(url, headers=headers, json=data)
conversation = response.json()
print(f"Conversation Link: https://app.all-hands.dev/conversations/{conversation['conversation_id']}")
print(f"Status: {conversation['status']}")
```
</Accordion>
<Accordion title="TypeScript/JavaScript (with fetch)">
```typescript
const apiKey = "YOUR_API_KEY";
const url = "https://app.all-hands.dev/api/conversations";
const headers = {
"Authorization": `Bearer ${apiKey}`,
"Content-Type": "application/json"
};
const data = {
initial_user_msg: "Check whether there is any incorrect information in the README.md file and send a PR to fix it if so.",
repository: "yourusername/your-repo"
};
async function startConversation() {
try {
const response = await fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(data)
});
const conversation = await response.json();
console.log(`Conversation Link: https://app.all-hands.dev/conversations/${conversation.id}`);
console.log(`Status: ${conversation.status}`);
return conversation;
} catch (error) {
console.error("Error starting conversation:", error);
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
}
startConversation();
```
</Accordion>
data = {
"initial_user_msg": "Check whether there is any incorrect information in the README.md file and send a PR to fix it if so.",
"repository": "yourusername/your-repo"
}
response = requests.post(url, headers=headers, json=data)
conversation = response.json()
print(f"Conversation Link: https://app.all-hands.dev/conversations/{conversation['conversation_id']}")
print(f"Status: {conversation['status']}")
```
</Tab>
<Tab title="TypeScript/JavaScript (with fetch)">
```typescript
const apiKey = "YOUR_API_KEY";
const url = "https://app.all-hands.dev/api/conversations";
const headers = {
"Authorization": `Bearer ${apiKey}`,
"Content-Type": "application/json"
};
const data = {
initial_user_msg: "Check whether there is any incorrect information in the README.md file and send a PR to fix it if so.",
repository: "yourusername/your-repo"
};
async function startConversation() {
try {
const response = await fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(data)
});
const conversation = await response.json();
console.log(`Conversation Link: https://app.all-hands.dev/conversations/${conversation.id}`);
console.log(`Status: ${conversation.status}`);
return conversation;
} catch (error) {
console.error("Error starting conversation:", error);
}
}
startConversation();
```
</Tab>
</Tabs>
#### Response
@@ -128,42 +116,6 @@ You may receive an `AuthenticationError` if:
- You provided the wrong repository name.
- You don't have access to the repository.
### Retrieving Conversation Status
You can check the status of a conversation by making a GET request to the conversation endpoint.
#### Endpoint
```
GET https://app.all-hands.dev/api/conversations/{conversation_id}
```
#### Example
<Accordion title="cURL">
```bash
curl -X GET "https://app.all-hands.dev/api/conversations/{conversation_id}" \
-H "Authorization: Bearer YOUR_API_KEY"
```
</Accordion>
#### Response
The response is formatted as follows:
```json
{
"conversation_id":"abc1234",
"title":"Update README.md",
"created_at":"2025-04-29T15:13:51.370706Z",
"last_updated_at":"2025-04-29T15:13:57.199210Z",
"status":"RUNNING",
"selected_repository":"yourusername/your-repo",
"trigger":"gui"
}
```
## Rate Limits
If you have too many conversations running at once, older conversations will be paused to limit the number of concurrent conversations.

View File

@@ -8,24 +8,39 @@ description: The Cloud UI provides a web interface for interacting with OpenHand
The landing page is where you can:
- [Add GitHub repository access](/usage/cloud/github-installation#adding-github-repository-access) to OpenHands.
- [Select a GitHub repo](/usage/cloud/github-installation#working-with-github-repos-in-openhands-cloud),
[a GitLab repo](/usage/cloud/gitlab-installation#working-with-gitlab-repos-in-openhands-cloud) or
[a Bitbucket repo](/usage/cloud/bitbucket-installation#working-with-bitbucket-repos-in-openhands-cloud) to start working on.
- Launch an empty conversation using `New Conversation`.
- See `Suggested Tasks` for repositories that OpenHands has access to.
- Launch an empty conversation using `Launch from Scratch`.
- See your `Recent Conversations`.
## Settings
The Settings page allows you to:
Settings are divided across tabs, with each tab focusing on a specific area of configuration.
- [Configure GitHub repository access](/usage/cloud/github-installation#modifying-repository-access) for OpenHands.
- [Install the OpenHands Slack app](/usage/cloud/slack-installation).
- Set application settings like your preferred language, notifications and other preferences.
- Add credits to your account.
- [Generate custom secrets](/usage/common-settings#secrets-management).
- [Create API keys to work with OpenHands programmatically](/usage/cloud/cloud-api).
- Change your email address.
- `User`
- Change your email address.
- `Integrations`
- [Configure GitHub repository access](/usage/cloud/github-installation#modifying-repository-access) for OpenHands.
- [Install the OpenHands Slack app](/usage/cloud/slack-installation).
- `Application`
- Set your preferred language, notifications and other preferences.
- Toggle task suggestions on GitHub.
- Toggle Solvability Analysis.
- Set a maximum budget per conversation.
- Configure the username and email that OpenHands uses for commits.
- `LLM` (Available for [Pro subscription users](/usage/cloud/pro-subscription))
- Choose to use another LLM or use different models from the OpenHands provider.
- `Billing`
- Add credits for using the OpenHands provider.
- Cancel your `Pro subscription`.
- `Secrets`
- [Manage secrets](/usage/settings/secrets-settings).
- `API Keys`
- [Create API keys to work with OpenHands programmatically](/usage/cloud/cloud-api).
- `MCP`
- [Setup an MCP server](/usage/settings/mcp-settings)
## Key Features

View File

@@ -12,7 +12,7 @@ description: This guide walks you through the process of installing OpenHands Cl
You can grant OpenHands access to specific GitHub repositories:
1. Click on `Add GitHub repos` on the landing page.
1. Click on `+ Add GitHub Repos` in the repository selection dropdown.
2. Select your organization and choose the specific repositories to grant OpenHands access to.
<Accordion title="OpenHands permissions">
- OpenHands requests short-lived tokens (8-hour expiration) with these permissions:
@@ -34,20 +34,22 @@ You can grant OpenHands access to specific GitHub repositories:
## Modifying Repository Access
You can modify GitHub repository access at any time by:
- Selecting `Add GitHub repos` on the landing page or
- Visiting the Settings page and selecting `Configure GitHub Repositories` under the `Integrations` tab
- Selecting `+ Add GitHub Repos` in the repository selection dropdown or
- Visiting the `Settings > Integrations` page and selecting `Configure GitHub Repositories`
## Working With GitHub Repos in Openhands Cloud
Once you've granted GitHub repository access, you can start working with your GitHub repository. Use the `select a repo`
and `select a branch` dropdowns to select the appropriate repository and branch you'd like OpenHands to work on. Then
click on `Launch` to start the conversation!
Once you've granted GitHub repository access, you can start working with your GitHub repository. Use the
`Open Repository` section to select the appropriate repository and branch you'd like OpenHands to work on. Then click
on `Launch` to start the conversation!
![Connect Repo](/static/img/connect-repo.png)
## Working on Github Issues and Pull Requests Using Openhands
## Working on GitHub Issues and Pull Requests Using Openhands
Giving GitHub repository access to OpenHands also allows you to work on GitHub issues and pull requests directly.
To allow OpenHands to work directly from GitHub directly, you must
[give OpenHands access to your repository](/usage/cloud/github-installation#modifying-repository-access). Once access is
given, you can use OpenHands by labeling the issue or by tagging `@openhands`.
### Working with Issues
@@ -64,7 +66,12 @@ To get OpenHands to work on pull requests, mention `@openhands` in the comments
- Request updates
- Get code explanations
**Important Note**: The `@openhands` mention functionality in pull requests only works if the pull request is both *to* and *from* a repository that you have added through the interface. This is because OpenHands needs appropriate permissions to access both repositories.
<Note>
The `@openhands` mention functionality in pull requests only works if the pull request is both
*to* and *from* a repository that you have added through the interface. This is because OpenHands needs appropriate
permissions to access both repositories.
</Note>
## Next Steps

View File

@@ -14,16 +14,17 @@ Upon signing into OpenHands Cloud with a GitLab account, OpenHands will have acc
## Working With GitLab Repos in Openhands Cloud
After signing in with a Gitlab account, use the `select a repo` and `select a branch` dropdowns to select the
appropriate repository and branch you'd like OpenHands to work on. Then click on `Launch` to start the conversation!
After signing in with a Gitlab account, use the `Open Repository` section to select the appropriate repository and
branch you'd like OpenHands to work on. Then click on `Launch` to start the conversation!
![Connect Repo](/static/img/connect-repo-no-github.png)
![Connect Repo](/static/img/connect-repo.png)
## Using Tokens with Reduced Scopes
OpenHands requests an API-scoped token during OAuth authentication. By default, this token is provided to the agent.
To restrict the agent's permissions, you can define a custom secret `GITLAB_TOKEN`, which will override the default token assigned to the agent.
While the high-permission API token is still requested and used for other components of the application (e.g. opening merge requests), the agent will not have access to it.
To restrict the agent's permissions, [you can define a custom secret](/usage/settings/secrets-settings) `GITLAB_TOKEN`,
which will override the default token assigned to the agent. While the high-permission API token is still requested
and used for other components of the application (e.g. opening merge requests), the agent will not have access to it.
## Working on GitLab Issues and Merge Requests Using Openhands
@@ -32,7 +33,8 @@ This feature works for personal projects and is available for group projects wit
[Premium or Ultimate tier subscription](https://docs.gitlab.com/user/project/integrations/webhooks/#group-webhooks).
A webhook is automatically installed within a few minutes after the owner/maintainer of the project or group logs into
OpenHands Cloud. If you decide to delete the webhook, then re-installing will require the support of All Hands AI but we are planning to improve this in a future release.
OpenHands Cloud. If you decide to delete the webhook, then re-installing will require the support of All Hands AI but
we are planning to improve this in a future release.
</Note>
Giving GitLab repository access to OpenHands also allows you to work on GitLab issues and merge requests directly.

View File

@@ -0,0 +1,50 @@
---
title: "Pro Subscription"
description: "Learn about OpenHands Cloud Pro Subscription features and pricing."
---
## Overview
The OpenHands Pro Subscription unlocks additional features and better pricing when you run OpenHands conversations in
OpenHands Cloud.
## Base Features
All users start on the Pay-as-you-go plan and have access to these base features when they sign up:
* **Run multiple OpenHands conversations on OpenHands Cloud runtimes.**
* **API keys to the OpenHands LLM provider for use in OpenHands CLI or when running OpenHands on your own.**
* **$20 in initial OpenHands Cloud credits to get started.**
* **Support for GitHub, GitLab, Bitbucket, Slack, and more.**
## What you get with a Pro Subscription
The $20/month Pro subscription covers the cost of runtime compute in OpenHands Cloud, plus enables the following
features:
* **Bring Your Own LLM Keys:** Bring your own API keys from OpenAI, Anthropic, Mistral, and other providers.
* **Model Choice:** Unlocks access to OpenHands LLM provider models for use within OpenHands Cloud.
* **No Markup Pricing on LLM usage:** When you use the OpenHands LLM provider in OpenHands Cloud, you pay for
LLM usage at-cost (zero markup) based on API prices.
## Plan Comparison
Here are the key differences between Pay-as-you-go and Pro subscriptions:
### When running OpenHands conversations in OpenHands Cloud
| | Pay-as-you-go | Pro Subscription |
| :---- | ----- | ----- |
| Monthly price | None \- no commitment | $20/month |
| Can I bring my own LLM key? | No | ✅ Yes |
| Do I pay for LLM usage? | ✅ Yes | ✅ Yes |
| Can I select from different LLMs without bringing my own LLM key? | No \- defaults to Claude Sonnet 4 | ✅ Yes \- via OpenHands LLM provider <br/><br/>[*See models and pricing*](https://docs.all-hands.dev/usage/llms/openhands-llms#pricing) |
| How much am I charged for LLM usage? | **Marked up pricing** \- 2x Claude Sonnet 4 API prices. *This markup helps cover the cost of runtime compute.* | **No markup** \- 1x API prices. *The $20 monthly subscription covers the cost of runtime compute.* |
### When using the OpenHands LLM Provider outside of OpenHands Cloud
The following applies to **both** the Pay-as-you-go and Pro subscription:
| | Pay-as-you-go or Pro Subscription |
| :---- | :---- |
| Do I have access to multiple models via the OpenHands LLM provider? | ✅ Yes <br/><br/> [*See models and pricing*](https://docs.all-hands.dev/usage/llms/openhands-llms#pricing) |
| Can I generate and refresh OpenHands LLM API keys? | ✅ Yes |
| How much am I charged for LLM usage when I use the OpenHands LLM provider in other AI coding tools? | **No markup** \- pay 1x API prices <br/> [*See models and pricing*](https://docs.all-hands.dev/usage/llms/openhands-llms#pricing) <br/><br/> *Usage is deducted from your OpenHands Cloud credit balance.* <br/><br/> *The OpenHands LLM provider is available to all OpenHands Cloud users, and LLM usage is billed at-cost (zero markup). Use these models with OpenHands CLI, running OpenHands on your own, or even other AI coding agents\! [Learn more.](https://www.all-hands.dev/blog/access-state-of-the-art-llm-models-at-cost-via-openhands-gui-and-cli)* |

View File

@@ -1,5 +1,5 @@
---
title: Jira Data Center Integration (Beta)
title: Jira Data Center Integration (Coming soon...)
description: Complete guide for setting up Jira Data Center integration with OpenHands Cloud, including service account creation, personal access token generation, webhook configuration, and workspace integration setup.
---
@@ -78,6 +78,14 @@ description: Complete guide for setting up Jira Data Center integration with Ope
- **Service Account API Key**: The personal access token from Step 2 above
- Ensure **Active** toggle is enabled
<Note>
Workspace name is the host name of your Jira Data Center instance.
Eg: http://jira.all-hands.dev/projects/OH/issues/OH-77
Here the workspace name is **jira.all-hands.dev**.
</Note>
3. **Complete OAuth Flow**
- You'll be redirected to Jira Data Center to complete OAuth verification
- Grant the necessary permissions to verify your workspace access. If you have access to multiple workspaces, select the correct one that you initially provided
@@ -101,18 +109,18 @@ description: Complete guide for setting up Jira Data Center integration with Ope
<AccordionGroup>
<Accordion title="Workspace link flow">
![workspace-link.png](/static/img/workspace-link.png)
![workspace-link.png](/static/img/jira-dc-user-link.png)
</Accordion>
<Accordion title="Workspace Configure flow">
![workspace-link.png](/static/img/workspace-configure.png)
![workspace-link.png](/static/img/jira-dc-admin-configure.png)
</Accordion>
<Accordion title="Edit view as a user">
![workspace-link.png](/static/img/workspace-user-edit.png)
![workspace-link.png](/static/img/jira-dc-user-unlink.png)
</Accordion>
<Accordion title="Edit view as the workspace creator">
![workspace-link.png](/static/img/workspace-admin-edit.png)
![workspace-link.png](/static/img/jira-dc-admin-edit.png)
</Accordion>
</AccordionGroup>

View File

@@ -1,5 +1,5 @@
---
title: Jira Cloud Integration
title: Jira Cloud Integration (Coming soon...)
description: Complete guide for setting up Jira Cloud integration with OpenHands Cloud, including service account creation, API token generation, webhook configuration, and workspace integration setup.
---
@@ -15,28 +15,27 @@ description: Complete guide for setting up Jira Cloud integration with OpenHands
- Go to **Directory** > **Users**
2. **Create OpenHands Service Account**
- Click **Add user**
- Email: `openhands@yourcompany.com` (replace with your preferred service account email)
- Display name: `OpenHands Agent`
- Send invitation: **No** (you'll set password manually)
- Click **Add user**
3. **Configure Account**
- Locate the created user and click on it
- Set a secure password
- Add to relevant Jira projects with appropriate permissions
- Click **Service accounts**
- Click **Create a service account**
- Name: `OpenHands Agent`
- Click **Next**
- Select **User** role for Jira app
- Click **Create**
### Step 2: Generate API Token
1. **Access API Token Management**
- Log in as the OpenHands service account
- Go to [API Tokens](https://id.atlassian.com/manage-profile/security/api-tokens)
2. **Create API Token**
1. **Access Service Account Configuration**
- Locate the created service account from above step and click on it
- Click **Create API token**
- Label: `OpenHands Cloud Integration`
- Expiry: Set appropriate expiration (recommend 1 year)
- Click **Create**
- Set the expiry to 365 days (maximum allowed value)
- Click **Next**
- In **Select token scopes** screen, filter by following values
- App: Jira
- Scope type: Classic
- Scope actions: Write, Read
- Select `read:jira-work` and `write:jira-work` scopes
- Click **Next**
- Review and create API token
- **Important**: Copy and securely store the token immediately
### Step 3: Configure Webhook
@@ -83,6 +82,14 @@ description: Complete guide for setting up Jira Cloud integration with OpenHands
- **Service Account API Key**: The API token from Step 2 above
- Ensure **Active** toggle is enabled
<Note>
Workspace name is the host name when accessing a resource in Jira Cloud.
Eg: https://all-hands.atlassian.net/browse/OH-55
Here the workspace name is **all-hands**.
</Note>
3. **Complete OAuth Flow**
- You'll be redirected to Jira Cloud to complete OAuth verification
- Grant the necessary permissions to verify your workspace access.
@@ -106,18 +113,18 @@ description: Complete guide for setting up Jira Cloud integration with OpenHands
<AccordionGroup>
<Accordion title="Workspace link flow">
![workspace-link.png](/static/img/workspace-link.png)
![workspace-link.png](/static/img/jira-user-link.png)
</Accordion>
<Accordion title="Workspace Configure flow">
![workspace-link.png](/static/img/workspace-configure.png)
![workspace-link.png](/static/img/jira-admin-configure.png)
</Accordion>
<Accordion title="Edit view as a user">
![workspace-link.png](/static/img/workspace-user-edit.png)
![workspace-link.png](/static/img/jira-user-unlink.png)
</Accordion>
<Accordion title="Edit view as the workspace creator">
![workspace-link.png](/static/img/workspace-admin-edit.png)
![workspace-link.png](/static/img/jira-admin-edit.png)
</Accordion>
</AccordionGroup>

View File

@@ -1,5 +1,5 @@
---
title: Linear Integration
title: Linear Integration (Coming soon...)
description: Complete guide for setting up Linear integration with OpenHands Cloud, including service account creation, API key generation, webhook configuration, and workspace integration setup.
---
@@ -28,7 +28,7 @@ description: Complete guide for setting up Linear integration with OpenHands Clo
1. **Access API Settings**
- Log in as the service account
- Go to **Settings** > **API**
- Go to **Settings** > **Security & access**
2. **Create Personal API Key**
- Click **Create new key**
@@ -82,6 +82,14 @@ description: Complete guide for setting up Linear integration with OpenHands Clo
- **Service Account API Key**: The API key from Step 2 above
- Ensure **Active** toggle is enabled
<Note>
Workspace name is the identifier after the host name when accessing a resource in Linear.
Eg: https://linear.app/allhands/issue/OH-37
Here the workspace name is **allhands**.
</Note>
3. **Complete OAuth Flow**
- You'll be redirected to Linear to complete OAuth verification
- Grant the necessary permissions to verify your workspace access. If you have access to multiple workspaces, select the correct one that you initially provided
@@ -105,15 +113,15 @@ description: Complete guide for setting up Linear integration with OpenHands Clo
<AccordionGroup>
<Accordion title="Workspace link flow">
![workspace-link.png](/static/img/workspace-link.png)
![workspace-link.png](/static/img/linear-user-link.png)
</Accordion>
<Accordion title="Workspace Configure flow">
![workspace-link.png](/static/img/workspace-configure.png)
![workspace-link.png](/static/img/linear-admin-configure.png)
</Accordion>
<Accordion title="Edit view as a user">
![workspace-link.png](/static/img/workspace-user-edit.png)
![workspace-link.png](/static/img/linear-admin-edit.png)
</Accordion>
<Accordion title="Edit view as the workspace creator">

View File

@@ -1,5 +1,5 @@
---
title: Project Management Tool Integrations
title: Project Management Tool Integrations (Coming soon...)
description: Overview of OpenHands Cloud integrations with project management platforms including Jira Cloud, Jira Data Center, and Linear. Learn about setup requirements, usage methods, and troubleshooting.
---
@@ -18,9 +18,9 @@ Integration requires two levels of setup:
2. **Workspace Integration** - Self-service configuration through the OpenHands Cloud UI to link your OpenHands account to the target workspace
### Platform-Specific Setup Guides:
- [Jira Cloud Integration](./jira-integration.md)
- [Jira Data Center Integration](./jira-dc-integration.md)
- [Linear Integration](./linear-integration.md)
- [Jira Cloud Integration (Coming soon...)](./jira-integration.md)
- [Jira Data Center Integration (Coming soon...)](./jira-dc-integration.md)
- [Linear Integration (Coming soon...)](./linear-integration.md)
## Usage
@@ -58,17 +58,18 @@ The OpenHands agent needs to identify which Git repository to work with when pro
### Platform Configuration Issues
- **Webhook not triggering**: Verify the webhook URL is correct and the proper event types are selected (Comment, Issue updated)
- **API authentication failing**: Check API key/token validity and ensure required scopes are granted
- **API authentication failing**: Check API key/token validity and ensure required scopes are granted. If your current API token is expired, make sure to update it in the respective integration settings
- **Permission errors**: Ensure the service account has access to relevant projects/teams and appropriate permissions
### Workspace Integration Issues
- **Workspace linking requests credentials**: If there are no active workspace integrations for the workspace you specified, you need to configure it first. Contact your platform administrator that you want to integrate with (eg: Jira, Linear)
- **OAuth flow fails**: Ensure you're signing in with the same Git provider account that contains the repositories you want OpenHands to work on
- **Integration not found**: Verify the workspace name matches exactly and that platform configuration was completed first
- **OAuth flow fails**: Make sure that you're authorizing with the correct account with proper workspace access
### General Issues
- **Agent not responding**: Check webhook logs in your platform settings and verify service account status
- **Authentication errors**: Verify Git provider permissions and OpenHands Cloud access
- **Agent fails to identify git repo**: Ensure you're signing in with the same Git provider account that contains the repositories you want OpenHands to work on
- **Partial functionality**: Ensure both platform configuration and workspace integration are properly completed
### Getting Help

View File

@@ -13,7 +13,9 @@ description: This guide walks you through installing the OpenHands Slack app.
</iframe>
<Info>
OpenHands utilizes a large language model (LLM), which may generate responses that are inaccurate or incomplete. While we strive for accuracy, OpenHands' outputs are not guaranteed to be correct, and we encourage users to validate critical information independently.
OpenHands utilizes a large language model (LLM), which may generate responses that are inaccurate or incomplete.
While we strive for accuracy, OpenHands' outputs are not guaranteed to be correct, and we encourage users to
validate critical information independently.
</Info>
## Prerequisites
@@ -39,7 +41,7 @@ OpenHands utilizes a large language model (LLM), which may generate responses th
**Make sure your Slack workspace admin/owner has installed OpenHands Slack App first.**
Every user in the Slack workspace (including admins/owners) must link their OpenHands Cloud account to the OpenHands Slack App. To do this:
1. Visit [integrations settings](https://app.all-hands.dev/settings/integrations) in OpenHands Cloud.
1. Visit the [Settings > Integrations](https://app.all-hands.dev/settings/integrations) page in OpenHands Cloud.
2. Click `Install OpenHands Slack App`.
3. In the top right corner, select the workspace to install the OpenHands Slack app.
4. Review permissions and click allow.
@@ -57,7 +59,8 @@ To start a new conversation, you can mention `@openhands` in a new message or a
Once a conversation is started, all thread messages underneath it will be follow-up messages to OpenHands.
To send follow-up messages for the same conversation, mention `@openhands` in a thread reply to the original message. You must be the user who started the conversation.
To send follow-up messages for the same conversation, mention `@openhands` in a thread reply to the original message.
You must be the user who started the conversation.
## Example conversation
@@ -65,7 +68,7 @@ To send follow-up messages for the same conversation, mention `@openhands` in a
Conversation is started by mentioning `@openhands`.
![slack-create-convo.png](/static/img/slack-create-convo.png)
![slack-create-conversation.png](/static/img/slack-create-conversation.png)
### See agent response and send follow up messages

View File

@@ -8,6 +8,11 @@ description: This page outlines all available configuration options for OpenHand
In GUI Mode, any settings applied through the Settings UI will take precedence.
</Note>
<Note>
**Looking for Environment Variables?** All configuration options can also be set using environment variables.
See the [Environment Variables Reference](./environment-variables) for a complete list with examples.
</Note>
## Location of the `config.toml` File
When running OpenHands in CLI, headless, or development mode, you can use a project-specific `config.toml` file for configuration, which must be
@@ -18,6 +23,11 @@ specify a different path to the `config.toml` file.
The core configuration options are defined in the `[core]` section of the `config.toml` file.
Core configuration options can be set as environment variables by converting to uppercase. For example:
- `debug` → `DEBUG`
- `cache_dir` → `CACHE_DIR`
- `runtime` → `RUNTIME`
### Workspace
- `workspace_base` **(Deprecated)**
- Type: `str`
@@ -141,6 +151,11 @@ The LLM (Large Language Model) configuration options are defined in the `[llm]`
To use these with the docker command, pass in `-e LLM_<option>`. Example: `-e LLM_NUM_RETRIES`.
All LLM configuration options can be set as environment variables by prefixing with `LLM_` and converting to uppercase. For example:
- `model` → `LLM_MODEL`
- `api_key` → `LLM_API_KEY`
- `base_url` → `LLM_BASE_URL`
<Note>
For development setups, you can also define custom named LLM configurations. See [Custom LLM Configurations](./llms/custom-llm-configs) for details.
</Note>
@@ -277,6 +292,11 @@ For development setups, you can also define custom named LLM configurations. See
The agent configuration options are defined in the `[agent]` and `[agent.<agent_name>]` sections of the `config.toml` file.
Agent configuration options can be set as environment variables by prefixing with `AGENT_` and converting to uppercase. For example:
- `enable_browsing` → `AGENT_ENABLE_BROWSING`
- `function_calling` → `AGENT_FUNCTION_CALLING`
- `llm_config` → `AGENT_LLM_CONFIG`
### LLM Configuration
- `llm_config`
- Type: `str`
@@ -328,6 +348,11 @@ The sandbox configuration options are defined in the `[sandbox]` section of the
To use these with the docker command, pass in `-e SANDBOX_<option>`. Example: `-e SANDBOX_TIMEOUT`.
All sandbox configuration options can be set as environment variables by prefixing with `SANDBOX_` and converting to uppercase. For example:
- `timeout` → `SANDBOX_TIMEOUT`
- `user_id` → `SANDBOX_USER_ID`
- `base_container_image` → `SANDBOX_BASE_CONTAINER_IMAGE`
### Execution
- `timeout`
- Type: `int`
@@ -390,6 +415,10 @@ The security configuration options are defined in the `[security]` section of th
To use these with the docker command, pass in `-e SECURITY_<option>`. Example: `-e SECURITY_CONFIRMATION_MODE`.
All security configuration options can be set as environment variables by prefixing with `SECURITY_` and converting to uppercase. For example:
- `confirmation_mode` → `SECURITY_CONFIRMATION_MODE`
- `security_analyzer` → `SECURITY_SECURITY_ANALYZER`
### Confirmation Mode
- `confirmation_mode`
- Type: `bool`

View File

@@ -0,0 +1,52 @@
# Confirmation Mode and Security Analyzers
OpenHands provides a security framework to help protect users from potentially risky actions through **Confirmation Mode** and **Security Analyzers**. This system analyzes agent actions and prompts users for confirmation when high-risk operations are detected.
## Overview
The security system consists of two main components:
1. **Confirmation Mode**: When enabled, the agent will pause and ask for user confirmation before executing actions that are flagged as high-risk by the security analyzer.
2. **Security Analyzers**: These are modules that evaluate the risk level of agent actions and determine whether user confirmation is required.
## Configuration
### CLI
In CLI mode, confirmation is enabled by default. You will have an option to uses the LLM Analyzer and will automatically confirm LOW and MEDIUM risk actions, only prompting for HIGH risk actions.
## Security Analyzers
OpenHands includes multiple analyzers:
- **No Analyzer**: Do not use any security analyzer. The agent will prompt you to confirm *EVERY* action.
- **LLM Risk Analyzer** (default): Uses the same LLM as the agent to assess action risk levels
- **Invariant Analyzer**: Uses Invariant Labs' policy engine to evaluate action traces against security policies
### LLM Risk Analyzer
The default analyzer that leverages the agent's LLM to evaluate the security risk of each action. It considers the action type, parameters, and context to assign risk levels.
### Invariant Analyzer
An advanced analyzer that:
- Collects conversation events and parses them into a trace
- Checks the trace against an Invariant policy to classify risk (low, medium, high)
- Manages an Invariant server container automatically if needed
- Supports optional browsing-alignment and harmful-content checks
## How It Works
1. **Action Analysis**: When the agent wants to perform an action, the selected security analyzer evaluates its risk level.
2. **Risk Assessment**: The analyzer returns one of three risk levels:
- **LOW**: Action proceeds without confirmation
- **MEDIUM**: Action proceeds without confirmation (may be configurable in future)
- **HIGH**: Action is paused, and user confirmation is requested
3. **User Confirmation**: For high-risk actions, a confirmation dialog appears with:
- Description of the action
- Risk assessment explanation
- Options to approve or deny action
4. **Action Execution**: Based on user response:
- **Approve**: Action proceeds as planned
- **Deny**: Action is cancelled

View File

@@ -0,0 +1,251 @@
---
title: Environment Variables Reference
description: Complete reference of all environment variables supported by OpenHands
---
This page provides a reference of environment variables that can be used to configure OpenHands. Environment variables provide an alternative to TOML configuration files and are particularly useful for containerized deployments, CI/CD pipelines, and cloud environments.
## Environment Variable Naming Convention
OpenHands follows a consistent naming pattern for environment variables:
- **Core settings**: Direct uppercase mapping (e.g., `debug` → `DEBUG`)
- **LLM settings**: Prefixed with `LLM_` (e.g., `model` → `LLM_MODEL`)
- **Agent settings**: Prefixed with `AGENT_` (e.g., `enable_browsing` → `AGENT_ENABLE_BROWSING`)
- **Sandbox settings**: Prefixed with `SANDBOX_` (e.g., `timeout` → `SANDBOX_TIMEOUT`)
- **Security settings**: Prefixed with `SECURITY_` (e.g., `confirmation_mode` → `SECURITY_CONFIRMATION_MODE`)
## Core Configuration Variables
These variables correspond to the `[core]` section in `config.toml`:
| Environment Variable | Type | Default | Description |
|---------------------|------|---------|-------------|
| `DEBUG` | boolean | `false` | Enable debug logging throughout the application |
| `DISABLE_COLOR` | boolean | `false` | Disable colored output in terminal |
| `CACHE_DIR` | string | `"/tmp/cache"` | Directory path for caching |
| `SAVE_TRAJECTORY_PATH` | string | `"./trajectories"` | Path to store conversation trajectories |
| `REPLAY_TRAJECTORY_PATH` | string | `""` | Path to load and replay a trajectory file |
| `FILE_STORE_PATH` | string | `"/tmp/file_store"` | File store directory path |
| `FILE_STORE` | string | `"memory"` | File store type (`memory`, `local`, etc.) |
| `FILE_UPLOADS_MAX_FILE_SIZE_MB` | integer | `0` | Maximum file upload size in MB (0 = no limit) |
| `FILE_UPLOADS_RESTRICT_FILE_TYPES` | boolean | `false` | Whether to restrict file upload types |
| `FILE_UPLOADS_ALLOWED_EXTENSIONS` | list | `[".*"]` | List of allowed file extensions for uploads |
| `MAX_BUDGET_PER_TASK` | float | `0.0` | Maximum budget per task (0.0 = no limit) |
| `MAX_ITERATIONS` | integer | `100` | Maximum number of iterations per task |
| `RUNTIME` | string | `"docker"` | Runtime environment (`docker`, `local`, `cli`, etc.) |
| `DEFAULT_AGENT` | string | `"CodeActAgent"` | Default agent class to use |
| `JWT_SECRET` | string | auto-generated | JWT secret for authentication |
| `RUN_AS_OPENHANDS` | boolean | `true` | Whether to run as the openhands user |
| `VOLUMES` | string | `""` | Volume mounts in format `host:container[:mode]` |
## LLM Configuration Variables
These variables correspond to the `[llm]` section in `config.toml`:
| Environment Variable | Type | Default | Description |
|---------------------|------|---------|-------------|
| `LLM_MODEL` | string | `"claude-3-5-sonnet-20241022"` | LLM model to use |
| `LLM_API_KEY` | string | `""` | API key for the LLM provider |
| `LLM_BASE_URL` | string | `""` | Custom API base URL |
| `LLM_API_VERSION` | string | `""` | API version to use |
| `LLM_TEMPERATURE` | float | `0.0` | Sampling temperature |
| `LLM_TOP_P` | float | `1.0` | Top-p sampling parameter |
| `LLM_MAX_INPUT_TOKENS` | integer | `0` | Maximum input tokens (0 = no limit) |
| `LLM_MAX_OUTPUT_TOKENS` | integer | `0` | Maximum output tokens (0 = no limit) |
| `LLM_MAX_MESSAGE_CHARS` | integer | `30000` | Maximum characters that will be sent to the model in observation content |
| `LLM_TIMEOUT` | integer | `0` | API timeout in seconds (0 = no timeout) |
| `LLM_NUM_RETRIES` | integer | `8` | Number of retry attempts |
| `LLM_RETRY_MIN_WAIT` | integer | `15` | Minimum wait time between retries (seconds) |
| `LLM_RETRY_MAX_WAIT` | integer | `120` | Maximum wait time between retries (seconds) |
| `LLM_RETRY_MULTIPLIER` | float | `2.0` | Exponential backoff multiplier |
| `LLM_DROP_PARAMS` | boolean | `false` | Drop unsupported parameters without error |
| `LLM_CACHING_PROMPT` | boolean | `true` | Enable prompt caching if supported |
| `LLM_DISABLE_VISION` | boolean | `false` | Disable vision capabilities for cost reduction |
| `LLM_CUSTOM_LLM_PROVIDER` | string | `""` | Custom LLM provider name |
| `LLM_OLLAMA_BASE_URL` | string | `""` | Base URL for Ollama API |
| `LLM_INPUT_COST_PER_TOKEN` | float | `0.0` | Cost per input token |
| `LLM_OUTPUT_COST_PER_TOKEN` | float | `0.0` | Cost per output token |
| `LLM_REASONING_EFFORT` | string | `""` | Reasoning effort for o-series models (`low`, `medium`, `high`) |
### AWS Configuration
| Environment Variable | Type | Default | Description |
|---------------------|------|---------|-------------|
| `LLM_AWS_ACCESS_KEY_ID` | string | `""` | AWS access key ID |
| `LLM_AWS_SECRET_ACCESS_KEY` | string | `""` | AWS secret access key |
| `LLM_AWS_REGION_NAME` | string | `""` | AWS region name |
## Agent Configuration Variables
These variables correspond to the `[agent]` section in `config.toml`:
| Environment Variable | Type | Default | Description |
|---------------------|------|---------|-------------|
| `AGENT_LLM_CONFIG` | string | `""` | Name of LLM config group to use |
| `AGENT_FUNCTION_CALLING` | boolean | `true` | Enable function calling |
| `AGENT_ENABLE_BROWSING` | boolean | `false` | Enable browsing delegate |
| `AGENT_ENABLE_LLM_EDITOR` | boolean | `false` | Enable LLM-based editor |
| `AGENT_ENABLE_JUPYTER` | boolean | `false` | Enable Jupyter integration |
| `AGENT_ENABLE_HISTORY_TRUNCATION` | boolean | `true` | Enable history truncation |
| `AGENT_ENABLE_PROMPT_EXTENSIONS` | boolean | `true` | Enable microagents (prompt extensions) |
| `AGENT_DISABLED_MICROAGENTS` | list | `[]` | List of microagents to disable |
## Sandbox Configuration Variables
These variables correspond to the `[sandbox]` section in `config.toml`:
| Environment Variable | Type | Default | Description |
|---------------------|------|---------|-------------|
| `SANDBOX_TIMEOUT` | integer | `120` | Sandbox timeout in seconds |
| `SANDBOX_USER_ID` | integer | `1000` | User ID for sandbox processes |
| `SANDBOX_BASE_CONTAINER_IMAGE` | string | `"nikolaik/python-nodejs:python3.12-nodejs22"` | Base container image |
| `SANDBOX_USE_HOST_NETWORK` | boolean | `false` | Use host networking |
| `SANDBOX_RUNTIME_BINDING_ADDRESS` | string | `"0.0.0.0"` | Runtime binding address |
| `SANDBOX_ENABLE_AUTO_LINT` | boolean | `false` | Enable automatic linting |
| `SANDBOX_INITIALIZE_PLUGINS` | boolean | `true` | Initialize sandbox plugins |
| `SANDBOX_RUNTIME_EXTRA_DEPS` | string | `""` | Extra dependencies to install |
| `SANDBOX_RUNTIME_STARTUP_ENV_VARS` | dict | `{}` | Environment variables for runtime |
| `SANDBOX_BROWSERGYM_EVAL_ENV` | string | `""` | BrowserGym evaluation environment |
| `SANDBOX_VOLUMES` | string | `""` | Volume mounts (replaces deprecated workspace settings) |
| `SANDBOX_RUNTIME_CONTAINER_IMAGE` | string | `""` | Pre-built runtime container image |
| `SANDBOX_KEEP_RUNTIME_ALIVE` | boolean | `false` | Keep runtime alive after session ends |
| `SANDBOX_PAUSE_CLOSED_RUNTIMES` | boolean | `false` | Pause instead of stopping closed runtimes |
| `SANDBOX_CLOSE_DELAY` | integer | `300` | Delay before closing idle runtimes (seconds) |
| `SANDBOX_RM_ALL_CONTAINERS` | boolean | `false` | Remove all containers when stopping |
| `SANDBOX_ENABLE_GPU` | boolean | `false` | Enable GPU support |
| `SANDBOX_CUDA_VISIBLE_DEVICES` | string | `""` | Specify GPU devices by ID |
| `SANDBOX_VSCODE_PORT` | integer | auto | Specific port for VSCode server |
### Sandbox Environment Variables
Variables prefixed with `SANDBOX_ENV_` are passed through to the sandbox environment:
| Environment Variable | Description |
|---------------------|-------------|
| `SANDBOX_ENV_*` | Any variable with this prefix is passed to the sandbox (e.g., `SANDBOX_ENV_OPENAI_API_KEY`) |
## Security Configuration Variables
These variables correspond to the `[security]` section in `config.toml`:
| Environment Variable | Type | Default | Description |
|---------------------|------|---------|-------------|
| `SECURITY_CONFIRMATION_MODE` | boolean | `false` | Enable confirmation mode for actions |
| `SECURITY_SECURITY_ANALYZER` | string | `"llm"` | Security analyzer to use (`llm`, `invariant`) |
| `SECURITY_ENABLE_SECURITY_ANALYZER` | boolean | `true` | Enable security analysis |
## Debug and Logging Variables
| Environment Variable | Type | Default | Description |
|---------------------|------|---------|-------------|
| `DEBUG` | boolean | `false` | Enable general debug logging |
| `DEBUG_LLM` | boolean | `false` | Enable LLM-specific debug logging |
| `DEBUG_RUNTIME` | boolean | `false` | Enable runtime debug logging |
| `LOG_TO_FILE` | boolean | auto | Log to file (auto-enabled when DEBUG=true) |
## Runtime-Specific Variables
### Docker Runtime
| Environment Variable | Type | Default | Description |
|---------------------|------|---------|-------------|
| `SANDBOX_VOLUME_OVERLAYS` | string | `""` | Volume overlay configurations |
### Remote Runtime
| Environment Variable | Type | Default | Description |
|---------------------|------|---------|-------------|
| `SANDBOX_API_KEY` | string | `""` | API key for remote runtime |
| `SANDBOX_REMOTE_RUNTIME_API_URL` | string | `""` | Remote runtime API URL |
### Local Runtime
| Environment Variable | Type | Default | Description |
|---------------------|------|---------|-------------|
| `RUNTIME_URL` | string | `""` | Runtime URL for local runtime |
| `RUNTIME_URL_PATTERN` | string | `""` | Runtime URL pattern |
| `RUNTIME_ID` | string | `""` | Runtime identifier |
| `LOCAL_RUNTIME_MODE` | string | `""` | Enable local runtime mode (`1` to enable) |
## Integration Variables
### GitHub Integration
| Environment Variable | Type | Default | Description |
|---------------------|------|---------|-------------|
| `GITHUB_TOKEN` | string | `""` | GitHub personal access token |
### Third-Party API Keys
| Environment Variable | Type | Default | Description |
|---------------------|------|---------|-------------|
| `OPENAI_API_KEY` | string | `""` | OpenAI API key |
| `ANTHROPIC_API_KEY` | string | `""` | Anthropic API key |
| `GOOGLE_API_KEY` | string | `""` | Google API key |
| `AZURE_API_KEY` | string | `""` | Azure API key |
| `TAVILY_API_KEY` | string | `""` | Tavily search API key |
## Server Configuration Variables
These are primarily used when running OpenHands as a server:
| Environment Variable | Type | Default | Description |
|---------------------|------|---------|-------------|
| `FRONTEND_PORT` | integer | `3000` | Frontend server port |
| `BACKEND_PORT` | integer | `8000` | Backend server port |
| `FRONTEND_HOST` | string | `"localhost"` | Frontend host address |
| `BACKEND_HOST` | string | `"localhost"` | Backend host address |
| `WEB_HOST` | string | `"localhost"` | Web server host |
| `SERVE_FRONTEND` | boolean | `true` | Whether to serve frontend |
## Deprecated Variables
These variables are deprecated and should be replaced:
| Environment Variable | Replacement | Description |
|---------------------|-------------|-------------|
| `WORKSPACE_BASE` | `SANDBOX_VOLUMES` | Use volume mounting instead |
| `WORKSPACE_MOUNT_PATH` | `SANDBOX_VOLUMES` | Use volume mounting instead |
| `WORKSPACE_MOUNT_PATH_IN_SANDBOX` | `SANDBOX_VOLUMES` | Use volume mounting instead |
| `WORKSPACE_MOUNT_REWRITE` | `SANDBOX_VOLUMES` | Use volume mounting instead |
## Usage Examples
### Basic Setup with OpenAI
```bash
export LLM_MODEL="gpt-4o"
export LLM_API_KEY="your-openai-api-key"
export DEBUG=true
```
### Docker Deployment with Custom Volumes
```bash
export RUNTIME="docker"
export SANDBOX_VOLUMES="/host/workspace:/workspace:rw,/host/data:/data:ro"
export SANDBOX_TIMEOUT=300
```
### Remote Runtime Configuration
```bash
export RUNTIME="remote"
export SANDBOX_API_KEY="your-remote-api-key"
export SANDBOX_REMOTE_RUNTIME_API_URL="https://your-runtime-api.com"
```
### Security-Enhanced Setup
```bash
export SECURITY_CONFIRMATION_MODE=true
export SECURITY_SECURITY_ANALYZER="llm"
export DEBUG_RUNTIME=true
```
## Notes
1. **Boolean Values**: Environment variables expecting boolean values accept `true`/`false`, `1`/`0`, or `yes`/`no` (case-insensitive).
2. **List Values**: Lists should be provided as Python literal strings, e.g., `AGENT_DISABLED_MICROAGENTS='["microagent1", "microagent2"]'`.
3. **Dictionary Values**: Dictionaries should be provided as Python literal strings, e.g., `SANDBOX_RUNTIME_STARTUP_ENV_VARS='{"KEY": "value"}'`.
4. **Precedence**: Environment variables take precedence over TOML configuration files.
5. **Docker Usage**: When using Docker, pass environment variables with the `-e` flag:
```bash
docker run -e LLM_API_KEY="your-key" -e DEBUG=true openhands/openhands
```
6. **Validation**: Invalid environment variable values will be logged as errors and fall back to defaults.

View File

@@ -89,8 +89,7 @@ If you would like to set things up more systematically, you can:
1. **Search existing issues**: Check our [GitHub issues](https://github.com/All-Hands-AI/OpenHands/issues) to see if
others have encountered the same problem.
2. **Join our community**: Get help from other users and developers:
- [Slack community](https://join.slack.com/t/openhands-ai/shared_invite/zt-3847of6xi-xuYJIPa6YIPg4ElbDWbtSA)
- [Discord server](https://discord.gg/ESHStjSjD4)
- [Slack community](https://dub.sh/openhands)
3. **Check our troubleshooting guide**: Common issues and solutions are documented in
[Troubleshooting](/usage/troubleshooting/troubleshooting).
4. **Report bugs**: If you've found a bug, please [create an issue](https://github.com/All-Hands-AI/OpenHands/issues/new)

View File

@@ -20,27 +20,42 @@ for scripting.
### Running with Python
**Note** - OpenHands requires Python version 3.12 or higher (Python 3.14 is not currently supported) and `uvx` for the default `fetch` MCP server (more details below).
**Note** - OpenHands requires Python version 3.12 or higher (Python 3.14 is not currently supported) and `uv` for the default `fetch` MCP server (more details below).
1. Install OpenHands using pip:
```bash
pip install openhands-ai
```
#### Recommended: Using uv
Or if you prefer not to manage your own Python environment, you can use `uvx`:
We recommend using [uv](https://docs.astral.sh/uv/) for the best OpenHands experience. uv provides better isolation from your current project's virtual environment and is required for OpenHands' default MCP servers.
1. **Install uv** (if you haven't already):
See the [uv installation guide](https://docs.astral.sh/uv/getting-started/installation/) for the latest installation instructions for your platform.
2. **Launch OpenHands CLI**:
```bash
uvx --python 3.12 --from openhands-ai openhands
```
<AccordionGroup>
<Accordion title="Alternative: Traditional pip installation">
If you prefer to use pip:
```bash
# Install OpenHands
pip install openhands-ai
```
Note that you'll still need `uv` installed for the default MCP servers to work properly.
</Accordion>
<Accordion title="Create shell aliases for easy access across environments">
Add the following to your shell configuration file (`.bashrc`, `.zshrc`, etc.):
```bash
# Add OpenHands aliases
# Add OpenHands aliases (recommended)
alias openhands="uvx --python 3.12 --from openhands-ai openhands"
alias oh="uvx --python 3.12 --from openhands-ai openhands"
```
@@ -72,15 +87,10 @@ source ~/.bashrc # or source ~/.zshrc
</AccordionGroup>
2. Launch an interactive OpenHands conversation from the command line:
```bash
openhands
```
<Note>
If you have cloned the repository, you can also run the CLI directly using Poetry:
poetry run python -m openhands.cli.main
poetry run openhands
</Note>
3. Set your model, API key, and other preferences using the UI (or alternatively environment variables, below).
@@ -95,7 +105,7 @@ The conversation history will be saved in `~/.openhands/sessions`.
1. Set the following environment variables in your terminal:
- `SANDBOX_VOLUMES` to specify the directory you want OpenHands to access ([See using SANDBOX_VOLUMES for more info](../runtimes/docker#using-sandbox_volumes))
- `LLM_MODEL` - the LLM model to use (e.g. `export LLM_MODEL="anthropic/claude-sonnet-4-20250514"`)
- `LLM_MODEL` - the LLM model to use (e.g. `export LLM_MODEL="anthropic/claude-sonnet-4-20250514"` or `export LLM_MODEL="anthropic/claude-sonnet-4-5-20250929"`)
- `LLM_API_KEY` - your API key (e.g. `export LLM_API_KEY="sk_test_12345"`)
2. Run the following command:
@@ -103,7 +113,7 @@ The conversation history will be saved in `~/.openhands/sessions`.
```bash
docker run -it \
--pull=always \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.51-nikolaik \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.58-nikolaik \
-e SANDBOX_USER_ID=$(id -u) \
-e SANDBOX_VOLUMES=$SANDBOX_VOLUMES \
-e LLM_API_KEY=$LLM_API_KEY \
@@ -112,8 +122,8 @@ docker run -it \
-v ~/.openhands:/.openhands \
--add-host host.docker.internal:host-gateway \
--name openhands-app-$(date +%Y%m%d%H%M%S) \
docker.all-hands.dev/all-hands-ai/openhands:0.51 \
python -m openhands.cli.main --override-cli-mode true
docker.all-hands.dev/all-hands-ai/openhands:0.58 \
python -m openhands.cli.entry --override-cli-mode true
```
<Note>

View File

@@ -85,11 +85,11 @@ You can use the Settings page at any time to:
- Setup the LLM provider and model for OpenHands.
- [Setup the search engine](/usage/search-engine-setup).
- [Configure MCP servers](/usage/mcp).
- [Configure MCP servers](/usage/settings/mcp-settings).
- [Connect to GitHub](/usage/how-to/gui-mode#github-setup), [connect to GitLab](/usage/how-to/gui-mode#gitlab-setup)
and [connect to Bitbucket](/usage/how-to/gui-mode#bitbucket-setup).
- Set application settings like your preferred language, notifications and other preferences.
- [Manage custom secrets](/usage/common-settings#secrets-management).
- [Manage custom secrets](/usage/settings/secrets-settings).
#### GitHub Setup

View File

@@ -52,8 +52,8 @@ Set environment variables and run the Docker command:
```bash
# Set required environment variables
export SANDBOX_VOLUMES="/path/to/workspace" # See SANDBOX_VOLUMES docs for details
export LLM_MODEL="anthropic/claude-sonnet-4-20250514"
export SANDBOX_VOLUMES="/path/to/workspace:/workspace:rw" # Format: host_path:container_path:mode
export LLM_MODEL="anthropic/claude-sonnet-4-20250514" # or "anthropic/claude-sonnet-4-5-20250929"
export LLM_API_KEY="your-api-key"
export SANDBOX_SELECTED_REPO="owner/repo-name" # Optional: requires GITHUB_TOKEN
export GITHUB_TOKEN="your-token" # Required for repository operations
@@ -61,7 +61,7 @@ export GITHUB_TOKEN="your-token" # Required for repository operations
# Run OpenHands
docker run -it \
--pull=always \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.51-nikolaik \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.58-nikolaik \
-e SANDBOX_USER_ID=$(id -u) \
-e SANDBOX_VOLUMES=$SANDBOX_VOLUMES \
-e LLM_API_KEY=$LLM_API_KEY \
@@ -73,7 +73,7 @@ docker run -it \
-v ~/.openhands:/.openhands \
--add-host host.docker.internal:host-gateway \
--name openhands-app-$(date +%Y%m%d%H%M%S) \
docker.all-hands.dev/all-hands-ai/openhands:0.51 \
docker.all-hands.dev/all-hands-ai/openhands:0.58 \
python -m openhands.core.main -t "write a bash script that prints hi"
```

View File

@@ -4,16 +4,17 @@ description: Running OpenHands Cloud or running on your own.
icon: rocket
---
## OpenHands Cloud
<Tabs>
<Tab title="OpenHands Cloud">
The easiest way to get started with OpenHands is on OpenHands Cloud, which comes with $20 in free credits for new users.
The easiest way to get started with OpenHands is on OpenHands Cloud, which comes with $20 in free credits for new users.
To get started with OpenHands Cloud, visit [app.all-hands.dev](https://app.all-hands.dev).
To get started with OpenHands Cloud, visit [app.all-hands.dev](https://app.all-hands.dev).
For more information see [getting started with OpenHands Cloud.](/usage/cloud/openhands-cloud)
</Tab>
<Tab title="Running OpenHands on Your Own">
Run OpenHands on your local system and bring your own LLM and API key.
For more information see [getting started with OpenHands Cloud.](/usage/cloud/openhands-cloud)
## Running OpenHands on Your Own
Run OpenHands on your local system and bring your own LLM and API key.
For more information see [running OpenHands on your own.](/usage/local-setup)
For more information see [running OpenHands on your own.](/usage/local-setup)
</Tab>
</Tabs>

View File

@@ -18,6 +18,7 @@ Based on these findings and community feedback, these are the latest models that
### Cloud / API-Based Models
- [anthropic/claude-sonnet-4-20250514](https://www.anthropic.com/api) (recommended)
- [anthropic/claude-sonnet-4-5-20250929](https://www.anthropic.com/api) (recommended)
- [openai/gpt-5-2025-08-07](https://openai.com/api/) (recommended)
- [gemini/gemini-2.5-pro](https://blog.google/technology/google-deepmind/gemini-model-thinking-updates-march-2025/)
- [deepseek/deepseek-chat](https://api-docs.deepseek.com/)

View File

@@ -68,23 +68,23 @@ Download and install the LM Studio desktop app from [lmstudio.ai](https://lmstud
1. Check [the installation guide](/usage/local-setup) and ensure all prerequisites are met before running OpenHands, then run:
```bash
docker pull docker.all-hands.dev/all-hands-ai/runtime:0.51-nikolaik
docker pull docker.all-hands.dev/all-hands-ai/runtime:0.58-nikolaik
docker run -it --rm --pull=always \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.51-nikolaik \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.58-nikolaik \
-e LOG_ALL_EVENTS=true \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ~/.openhands:/.openhands \
-p 3000:3000 \
--add-host host.docker.internal:host-gateway \
--name openhands-app \
docker.all-hands.dev/all-hands-ai/openhands:0.51
docker.all-hands.dev/all-hands-ai/openhands:0.58
```
2. Wait until the server is running (see log below):
```
Digest: sha256:e72f9baecb458aedb9afc2cd5bc935118d1868719e55d50da73190d3a85c674f
Status: Image is up to date for docker.all-hands.dev/all-hands-ai/openhands:0.51
Status: Image is up to date for docker.all-hands.dev/all-hands-ai/openhands:0.58
Starting OpenHands...
Running OpenHands as root
14:22:13 - openhands:INFO: server_config.py:50 - Using config class None
@@ -119,7 +119,7 @@ When started for the first time, OpenHands will prompt you to set up the LLM pro
That's it! You can now start using OpenHands with the local LLM server.
If you encounter any issues, let us know on [Slack](https://join.slack.com/t/openhands-ai/shared_invite/zt-3847of6xi-xuYJIPa6YIPg4ElbDWbtSA) or [Discord](https://discord.gg/ESHStjSjD4).
If you encounter any issues, let us know on [Slack](https://dub.sh/openhands).
## Advanced: Alternative LLM Backends

View File

@@ -15,7 +15,7 @@ description: OpenHands LLM provider with access to state-of-the-art (SOTA) agent
When running OpenHands, you'll need to set the following in the OpenHands UI through the Settings under the `LLM` tab:
- `LLM Provider` to `OpenHands`
- `LLM Model` to the model you will be using (e.g. claude-sonnet-4-20250514)
- `LLM Model` to the model you will be using (e.g. claude-sonnet-4-20250514 or claude-sonnet-4-5-20250929)
- `API Key` to your OpenHands LLM API key copied from above
## Using OpenHands LLM Provider in the CLI
@@ -30,6 +30,21 @@ When running OpenHands, you'll need to set the following in the OpenHands UI thr
## Pricing
Pricing follows official API provider rates. [You can view model prices here.](https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json)
Pricing follows official API provider rates. Below are the current pricing details for OpenHands models:
For `qwen3-coder-480b`, we charge the cheapest FP8 rate available on openrouter: \$0.4 per million input tokens and \$1.6 per million output tokens.
| Model | Input Cost (per 1M tokens) | Cached Input Cost (per 1M tokens) | Output Cost (per 1M tokens) | Max Input Tokens | Max Output Tokens |
|-------|----------------------------|-----------------------------------|------------------------------|------------------|-------------------|
| claude-opus-4-20250514 | $15.00 | $1.50 | $75.00 | 200,000 | 32,000 |
| claude-sonnet-4-20250514 | $3.00 | $0.30 | $15.00 | 200,000 | 64,000 |
| claude-sonnet-4-5-20250929 | $3.00 | $0.30 | $15.00 | 200,000 | 64,000 |
| devstral-medium-2507 | $0.40 | N/A | $2.00 | 128,000 | 128,000 |
| devstral-small-2505 | $0.10 | N/A | $0.30 | 128,000 | 128,000 |
| devstral-small-2507 | $0.10 | N/A | $0.30 | 128,000 | 128,000 |
| gemini-2.5-pro | $1.25 | $0.31 | $10.00 | 1,048,576 | 65,535 |
| gpt-5-2025-08-07 | $1.25 | $0.125 | $10.00 | 400,000 | 128,000 |
| gpt-5-mini-2025-08-07 | $0.25 | $0.025 | $2.00 | 400,000 | 128,000 |
| o3 | $2.00 | $0.50 | $8.00 | 200,000 | 100,000 |
| o4-mini | $1.10 | $0.28 | $4.40 | 200,000 | 100,000 |
| qwen3-coder-480b | $0.40 | N/A | $1.60 | N/A | N/A |
**Note:** Cached input tokens are charged at a reduced rate when the same content is reused across requests. Models that don't support prompt caching show "N/A" for cached input cost.

View File

@@ -45,6 +45,13 @@ A system with a modern processor and a minimum of **4GB RAM** is recommended to
1. [Install WSL](https://learn.microsoft.com/en-us/windows/wsl/install).
2. Run `wsl --version` in powershell and confirm `Default Version: 2`.
**Ubuntu (Linux Distribution)**
1. Install Ubuntu: `wsl --install -d Ubuntu` in PowerShell as Administrator.
2. Restart computer when prompted.
3. Open Ubuntu from Start menu to complete setup.
4. Verify installation: `wsl --list` should show Ubuntu.
**Docker Desktop**
1. [Install Docker Desktop on Windows](https://docs.docker.com/desktop/setup/install/windows-install).
@@ -53,7 +60,7 @@ A system with a modern processor and a minimum of **4GB RAM** is recommended to
- Resources > WSL Integration: `Enable integration with my default WSL distro` is enabled.
<Note>
The docker command below to start the app must be run inside the WSL terminal.
The docker command below to start the app must be run inside the WSL terminal. Use `wsl -d Ubuntu` in PowerShell or search "Ubuntu" in the Start menu to access the Ubuntu terminal.
</Note>
**Alternative: Windows without WSL**
@@ -66,9 +73,31 @@ A system with a modern processor and a minimum of **4GB RAM** is recommended to
### Start the App
#### Option 1: Using the CLI Launcher (Recommended)
#### Option 1: Using the CLI Launcher with uv (Recommended)
If you have Python 3.12+ installed, you can use the CLI launcher for a simpler experience:
We recommend using [uv](https://docs.astral.sh/uv/) for the best OpenHands experience. uv provides better isolation from your current project's virtual environment and is required for OpenHands' default MCP servers (like the [fetch MCP server](https://github.com/modelcontextprotocol/servers/tree/main/src/fetch)).
**Install uv** (if you haven't already):
See the [uv installation guide](https://docs.astral.sh/uv/getting-started/installation/) for the latest installation instructions for your platform.
**Launch OpenHands**:
```bash
# Launch the GUI server
uvx --python 3.12 --from openhands-ai openhands serve
# Or with GPU support (requires nvidia-docker)
uvx --python 3.12 --from openhands-ai openhands serve --gpu
# Or with current directory mounted
uvx --python 3.12 --from openhands-ai openhands serve --mount-cwd
```
This will automatically handle Docker requirements checking, image pulling, and launching the GUI server. The `--gpu` flag enables GPU support via nvidia-docker, and `--mount-cwd` mounts your current directory into the container.
<Accordion title="Alternative: Traditional pip installation">
If you prefer to use pip and have Python 3.12+ installed:
```bash
# Install OpenHands
@@ -76,34 +105,32 @@ pip install openhands-ai
# Launch the GUI server
openhands serve
# Or with GPU support (requires nvidia-docker)
openhands serve --gpu
# Or with current directory mounted
openhands serve --mount-cwd
```
Or using `uvx --python 3.12 --from openhands-ai openhands serve` if you have [uv](https://docs.astral.sh/uv/) installed.
Note that you'll still need `uv` installed for the default MCP servers to work properly.
This will automatically handle Docker requirements checking, image pulling, and launching the GUI server. The `--gpu` flag enables GPU support via nvidia-docker, and `--mount-cwd` mounts your current directory into the container.
</Accordion>
#### Option 2: Using Docker Directly
<Accordion title="Docker Command (Click to expand)">
```bash
docker pull docker.all-hands.dev/all-hands-ai/runtime:0.51-nikolaik
docker pull docker.all-hands.dev/all-hands-ai/runtime:0.58-nikolaik
docker run -it --rm --pull=always \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.51-nikolaik \
-e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.58-nikolaik \
-e LOG_ALL_EVENTS=true \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ~/.openhands:/.openhands \
-p 3000:3000 \
--add-host host.docker.internal:host-gateway \
--name openhands-app \
docker.all-hands.dev/all-hands-ai/openhands:0.51
docker.all-hands.dev/all-hands-ai/openhands:0.58
```
</Accordion>
> **Note**: If you used OpenHands before version 0.44, you may want to run `mv ~/.openhands-state ~/.openhands` to migrate your conversation history to the new location.
You'll find OpenHands running at http://localhost:3000!

View File

@@ -1,196 +0,0 @@
---
title: Model Context Protocol (MCP)
description: This page outlines how to configure and use the Model Context Protocol (MCP) in OpenHands, allowing you
to extend the agent's capabilities with custom tools.
---
## Overview
Model Context Protocol (MCP) is a mechanism that allows OpenHands to communicate with external tool servers. These
servers can provide additional functionality to the agent, such as specialized data processing, external API access,
or custom tools. MCP is based on the open standard defined at [modelcontextprotocol.io](https://modelcontextprotocol.io).
<Note>
MCP is currently not available on OpenHands Cloud. This feature is only available when running OpenHands locally.
</Note>
### How MCP Works
When OpenHands starts, it:
1. Reads the MCP configuration.
2. Connects to any configured SSE and SHTTP servers.
3. Starts any configured stdio servers.
4. Registers the tools provided by these servers with the agent.
The agent can then use these tools just like any built-in tool. When the agent calls an MCP tool:
1. OpenHands routes the call to the appropriate MCP server.
2. The server processes the request and returns a response.
3. OpenHands converts the response to an observation and presents it to the agent.
## Configuration
MCP configuration can be defined in:
* The OpenHands UI through the Settings under the `MCP` tab.
* The `config.toml` file under the `[mcp]` section if not using the UI.
### Configuration Examples
#### Recommended: Using Proxy Servers (SSE/HTTP)
For stdio-based MCP servers, we recommend using MCP proxy tools like [`supergateway`](https://github.com/supercorp-ai/supergateway) instead of direct stdio connections.
[SuperGateway](https://github.com/supercorp-ai/supergateway) is a popular MCP proxy that converts stdio MCP servers to HTTP/SSE endpoints:
Start the proxy servers separately:
```bash
# Terminal 1: Filesystem server proxy
supergateway --stdio "npx @modelcontextprotocol/server-filesystem /" --port 8080
# Terminal 2: Fetch server proxy
supergateway --stdio "uvx mcp-server-fetch" --port 8081
```
Then configure OpenHands to use the HTTP endpoint:
```toml
[mcp]
# SSE Servers - Recommended approach using proxy tools
sse_servers = [
# Basic SSE server with just a URL
"http://example.com:8080/mcp",
# SuperGateway proxy for fetch server
"http://localhost:8081/sse",
# External MCP service with authentication
{url="https://api.example.com/mcp/sse", api_key="your-api-key"}
]
```
#### Alternative: Direct Stdio Servers (Not Recommended for Production)
```toml
[mcp]
# Direct stdio servers - use only for development/testing
stdio_servers = [
# Basic stdio server
{name="fetch", command="uvx", args=["mcp-server-fetch"]},
# Stdio server with environment variables
{
name="filesystem",
command="npx",
args=["@modelcontextprotocol/server-filesystem", "/"],
env={
"DEBUG": "true"
}
}
]
```
## Configuration Options
### SSE Servers
SSE servers are configured using either a string URL or an object with the following properties:
- `url` (required)
- Type: `str`
- Description: The URL of the SSE server
- `api_key` (optional)
- Type: `str`
- Description: API key for authentication
### SHTTP Servers
SHTTP (Streamable HTTP) servers are configured using either a string URL or an object with the following properties:
- `url` (required)
- Type: `str`
- Description: The URL of the SHTTP server
- `api_key` (optional)
- Type: `str`
- Description: API key for authentication
### Stdio Servers
**Note**: While stdio servers are supported, we recommend using MCP proxies (see above) for better reliability and performance.
Stdio servers are configured using an object with the following properties:
- `name` (required)
- Type: `str`
- Description: A unique name for the server
- `command` (required)
- Type: `str`
- Description: The command to run the server
- `args` (optional)
- Type: `list of str`
- Default: `[]`
- Description: Command-line arguments to pass to the server
- `env` (optional)
- Type: `dict of str to str`
- Default: `{}`
- Description: Environment variables to set for the server process
#### When to Use Direct Stdio
Direct stdio connections may still be appropriate in these scenarios:
- **Development and testing**: Quick prototyping of MCP servers
- **Simple, single-use tools**: Tools that don't require high reliability or concurrent access
- **Local-only environments**: When you don't want to manage additional proxy processes
For production use, we recommend using proxy tools like SuperGateway.
### Other Proxy Tools
Other options include:
- **Custom FastAPI/Express servers**: Build your own HTTP wrapper around stdio MCP servers
- **Docker-based proxies**: Containerized solutions for better isolation
- **Cloud-hosted MCP services**: Third-party services that provide MCP endpoints
### Troubleshooting MCP Connections
#### Common Issues with Stdio Servers
- **Process crashes**: Stdio processes may crash without proper error handling
- **Deadlocks**: Stdio communication can deadlock under high load
- **Resource leaks**: Zombie processes if not properly managed
- **Debugging difficulty**: Hard to inspect stdio communication
#### Benefits of Using Proxies
- **HTTP status codes**: Clear error reporting via standard HTTP responses
- **Request logging**: Easy to log and monitor HTTP requests
- **Load balancing**: Can distribute requests across multiple server instances
- **Health checks**: HTTP endpoints can provide health status
- **CORS support**: Better integration with web-based tools
## Transport Protocols
OpenHands supports three different MCP transport protocols:
### Server-Sent Events (SSE)
SSE is a legacy HTTP-based transport that uses Server-Sent Events for server-to-client communication and HTTP POST requests for client-to-server communication. This transport is suitable for basic streaming scenarios but has limitations in session management and connection resumability.
### Streamable HTTP (SHTTP)
SHTTP is the modern HTTP-based transport protocol that provides enhanced features over SSE:
- **Improved Session Management**: Supports stateful sessions with session IDs for maintaining context across requests
- **Connection Resumability**: Can resume broken connections and replay missed messages using event IDs
- **Bidirectional Communication**: Uses HTTP POST for client-to-server and optional SSE streams for server-to-client communication
- **Better Error Handling**: Enhanced error reporting and recovery mechanisms
SHTTP is the recommended transport for HTTP-based MCP servers as it provides better reliability and features compared to the legacy SSE transport.
### Standard Input/Output (stdio)
Stdio transport enables communication through standard input and output streams, making it ideal for local integrations and command-line tools. This transport is used for locally executed MCP servers that run as separate processes.

View File

@@ -130,3 +130,28 @@ docker run # ... \
<Note>
**Docker Desktop Required**: Network isolation features, including custom networks and `host.docker.internal` routing, require Docker Desktop. Docker Engine alone does not support these features on localhost across custom networks. If you're using Docker Engine without Docker Desktop, network isolation may not work as expected.
</Note>
### Sidecar Containers
If you want to run sidecar containers to the sandbox 'runner' containers without exposing the sandbox containers to the host network, you can use the `SANDBOX_ADDITIONAL_NETWORKS` environment variable to specify additional Docker network names that should be added to the sandbox containers.
```bash
docker network create openhands-sccache
docker run -d \
--hostname openhandsredis \
--network openhands-sccache \
redis
docker run # ...
-e SANDBOX_ADDITIONAL_NETWORKS='["openhands-sccache"]' \
# ...
```
Then all sandbox instances will have to access a shared redis instance at `openhandsredis:6379`.
#### Docker Compose gotcha
Note that Docker Compose adds a prefix (a scope) by default to created networks, which is not taken into account by the additional networks config. Therefore when using docker compose you have to either:
- specify a network name via the `name` field to remove the scoping (https://docs.docker.com/reference/compose-file/networks/#name)
- or provide the scope within the given config (e.g. `SANDBOX_ADDITIONAL_NETWORKS: '["myscope_openhands-sccache"]'` where `myscope` is the docker-compose assigned prefix).

View File

@@ -22,7 +22,7 @@ SDK to spawn and control these sandboxes.
You can use the E2B CLI to create a custom sandbox with a Dockerfile. Read the full guide
[here](https://e2b.dev/docs/guide/custom-sandbox). The premade OpenHands sandbox for E2B is set up in the `containers`
directory. and it's called `openhands`.
directory, and it's called `openhands`.
## Debugging

View File

@@ -0,0 +1,194 @@
---
title: Model Context Protocol (MCP)
description: This page outlines how to configure and use the Model Context Protocol (MCP) in OpenHands, allowing you
to extend the agent's capabilities with custom tools.
---
## Overview
Model Context Protocol (MCP) is a mechanism that allows OpenHands to communicate with external tool servers. These
servers can provide additional functionality to the agent, such as specialized data processing, external API access,
or custom tools. MCP is based on the open standard defined at [modelcontextprotocol.io](https://modelcontextprotocol.io).
## Supported MCPs
OpenHands supports the following MCP transport protocols:
* [Server-Sent Events (SSE)](https://modelcontextprotocol.io/specification/2024-11-05/basic/transports#http-with-sse)
* [Streamable HTTP (SHTTP)](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#streamable-http)
* [Standard Input/Output (stdio)](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#stdio)
## How MCP Works
When OpenHands starts, it:
1. Reads the MCP configuration.
2. Connects to any configured SSE and SHTTP servers.
3. Starts any configured stdio servers.
4. Registers the tools provided by these servers with the agent.
The agent can then use these tools just like any built-in tool. When the agent calls an MCP tool:
1. OpenHands routes the call to the appropriate MCP server.
2. The server processes the request and returns a response.
3. OpenHands converts the response to an observation and presents it to the agent.
## Configuration
MCP configuration can be defined in:
* The OpenHands UI in the `Settings > MCP` page.
* The `config.toml` file under the `[mcp]` section if not using the UI.
### Configuration Options
<Tabs>
<Tab title="SSE Servers">
SSE servers are configured using either a string URL or an object with the following properties:
- `url` (required)
- Type: `str`
- Description: The URL of the SSE server.
- `api_key` (optional)
- Type: `str`
- Description: API key for authentication.
</Tab>
<Tab title="SHTTP Servers">
SHTTP (Streamable HTTP) servers are configured using either a string URL or an object with the following properties:
- `url` (required)
- Type: `str`
- Description: The URL of the SHTTP server.
- `api_key` (optional)
- Type: `str`
- Description: API key for authentication.
- `timeout` (optional)
- Type: `int`
- Default: `60`
- Range: `1-3600` seconds (1 hour maximum)
- Description: Timeout in seconds for tool execution. This prevents tool calls from hanging indefinitely.
- **Use Cases:**
- **Short timeout (1-30s)**: For lightweight operations like status checks or simple queries.
- **Medium timeout (30-300s)**: For standard processing tasks like data analysis or API calls.
- **Long timeout (300-3600s)**: For heavy operations like file processing, complex calculations, or batch operations.
<Note>
This timeout only applies to individual tool calls, not server connection establishment.
</Note>
</Tab>
<Tab title="Stdio Servers">
<Note>
While stdio servers are supported, [we recommend using MCP proxies](/usage/settings/mcp-settings#configuration-examples) for
better reliability and performance.
</Note>
Stdio servers are configured using an object with the following properties:
- `name` (required)
- Type: `str`
- Description: A unique name for the server.
- `command` (required)
- Type: `str`
- Description: The command to run the server.
- `args` (optional)
- Type: `list of str`
- Default: `[]`
- Description: Command-line arguments to pass to the server.
- `env` (optional)
- Type: `dict of str to str`
- Default: `{}`
- Description: Environment variables to set for the server process.
</Tab>
</Tabs>
#### When to Use Direct Stdio
Direct stdio connections may still be appropriate in these scenarios:
- **Development and testing**: Quick prototyping of MCP servers.
- **Simple, single-use tools**: Tools that don't require high reliability or concurrent access.
- **Local-only environments**: When you don't want to manage additional proxy processes.
### Configuration Examples
<Tabs>
<Tab title="Proxy Servers (SSE/HTTP) - Recommended">
For stdio-based MCP servers, we recommend using MCP proxy tools like
[`supergateway`](https://github.com/supercorp-ai/supergateway) instead of direct stdio connections.
[SuperGateway](https://github.com/supercorp-ai/supergateway) is a popular MCP proxy that converts stdio MCP servers to
HTTP/SSE endpoints.
Start the proxy servers separately:
```bash
# Terminal 1: Filesystem server proxy
supergateway --stdio "npx @modelcontextprotocol/server-filesystem /" --port 8080
# Terminal 2: Fetch server proxy
supergateway --stdio "uvx mcp-server-fetch" --port 8081
```
Then configure OpenHands to use the HTTP endpoint:
```toml
[mcp]
# SSE Servers - Recommended approach using proxy tools
sse_servers = [
# Basic SSE server with just a URL
"http://example.com:8080/mcp",
# SuperGateway proxy for fetch server
"http://localhost:8081/sse",
# External MCP service with authentication
{url="https://api.example.com/mcp/sse", api_key="your-api-key"}
]
# SHTTP Servers - Modern streamable HTTP transport (recommended)
shttp_servers = [
# Basic SHTTP server with default 60s timeout
"https://api.example.com/mcp/shttp",
# Server with custom timeout for heavy operations
{
url = "https://files.example.com/mcp/shttp",
api_key = "your-api-key",
timeout = 1800 # 30 minutes for large file processing
}
]
```
</Tab>
<Tab title="Direct Stdio Servers">
<Note>
This setup is not Recommended for production.
</Note>
```toml
[mcp]
# Direct stdio servers - use only for development/testing
stdio_servers = [
# Basic stdio server
{name="fetch", command="uvx", args=["mcp-server-fetch"]},
# Stdio server with environment variables
{
name="filesystem",
command="npx",
args=["@modelcontextprotocol/server-filesystem", "/"],
env={
"DEBUG": "true"
}
}
]
```
For production use, we recommend using proxy tools like SuperGateway.
</Tab>
</Tabs>
Other options include:
- **Custom FastAPI/Express servers**: Build your own HTTP wrapper around stdio MCP servers.
- **Docker-based proxies**: Containerized solutions for better isolation.
- **Cloud-hosted MCP services**: Third-party services that provide MCP endpoints.

View File

@@ -1,28 +1,19 @@
---
title: OpenHands Settings
description: Overview of some of the settings available in OpenHands.
title: Secrets Management
description: How to manage secrets in OpenHands.
---
## Openhands Cloud vs Running on Your Own
There are some differences between the settings available in OpenHands Cloud and those available when running OpenHands
on your own:
* [OpenHands Cloud settings](/usage/cloud/cloud-ui#settings)
* [Settings available when running on your own](/usage/how-to/gui-mode#settings)
Refer to these pages for more detailed information.
## Secrets Management
## Overview
OpenHands provides a secrets manager that allows you to securely store and manage sensitive information that can be
accessed by the agent during runtime, such as API keys. These secrets are automatically exported as environment
variables in the agent's runtime environment.
### Accessing the Secrets Manager
## Accessing the Secrets Manager
In the Settings page, navigate to the `Secrets` tab. Here, you'll see a list of all your existing custom secrets.
Navigate to the `Settings > Secrets` page. Here, you'll see a list of all your existing custom secrets.
### Adding a New Secret
## Adding a New Secret
1. Click `Add a new secret`.
2. Fill in the following fields:
- **Name**: A unique identifier for your secret (e.g., `AWS_ACCESS_KEY`). This will be the environment variable name.
@@ -30,7 +21,7 @@ In the Settings page, navigate to the `Secrets` tab. Here, you'll see a list of
- **Description** (optional): A brief description of what the secret is used for, which is also provided to the agent.
3. Click `Add secret` to save.
### Editing a Secret
## Editing a Secret
1. Click the `Edit` button next to the secret you want to modify.
2. You can update the name and description of the secret.
@@ -39,14 +30,13 @@ In the Settings page, navigate to the `Secrets` tab. Here, you'll see a list of
value, delete the secret and create a new one.
</Note>
### Deleting a Secret
## Deleting a Secret
1. Click the `Delete` button next to the secret you want to remove.
2. Select `Confirm` to delete the secret.
### Using Secrets in the Agent
## Using Secrets in the Agent
- All custom secrets are automatically exported as environment variables in the agent's runtime environment.
- You can access them in your code using standard environment variable access methods
(e.g., `os.environ['SECRET_NAME']` in Python).
- Example: If you create a secret named `OPENAI_API_KEY`, you can access it in your code as
`process.env.OPENAI_API_KEY` in JavaScript or `os.environ['OPENAI_API_KEY']` in Python.
- You can access them in your code using standard environment variable access methods. For example, if you create a
secret named `OPENAI_API_KEY`, you can access it in your code as `process.env.OPENAI_API_KEY` in JavaScript or
`os.environ['OPENAI_API_KEY']` in Python.

View File

@@ -38,6 +38,23 @@ On initial prompt, an error is seen with `Permission Denied` or `PermissionError
* If mounting a local directory, ensure your `WORKSPACE_BASE` has the necessary permissions for the user running
OpenHands.
### On Linux, Getting ConnectTimeout Error
**Description**
When running on Linux, you might run into the error `ERROR:root:<class 'httpx.ConnectTimeout'>: timed out`.
**Resolution**
If you installed Docker from your distributions package repository (e.g., docker.io on Debian/Ubuntu), be aware that
these packages can sometimes be outdated or include changes that cause compatibility issues. try reinstalling Docker
[using the official instructions](https://docs.docker.com/engine/install/) to ensure you are running a compatible version.
If that does not solve the issue, try incrementally adding the following parameters to the docker run command:
* `--network host`
* `-e SANDBOX_USE_HOST_NETWORK=true`
* `-e DOCKER_HOST_ADDR=127.0.0.1`
### Internal Server Error. Ports are not available
**Description**

40
enterprise/Dockerfile Normal file
View File

@@ -0,0 +1,40 @@
ARG OPENHANDS_VERSION=latest
ARG BASE="ghcr.io/all-hands-ai/openhands"
FROM ${BASE}:${OPENHANDS_VERSION}
# Datadog labels
LABEL com.datadoghq.tags.service="deploy"
LABEL com.datadoghq.tags.env="${DD_ENV}"
# Install Node.js v20+ and npm (which includes npx)
# Apply security updates to fix CVEs
RUN apt-get update && \
apt-get install -y curl && \
curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
apt-get install -y nodejs && \
apt-get install -y jq gettext && \
# Apply security updates for packages with available fixes
apt-get upgrade -y \
libc-bin \
libc6 \
libgnutls30 \
libsqlite3-0 \
perl-base && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Install Python packages with security fixes
RUN pip install alembic psycopg2-binary cloud-sql-python-connector pg8000 gspread stripe python-keycloak asyncpg sqlalchemy[asyncio] resend tenacity slack-sdk ddtrace "posthog>=6.0.0" "limits==5.2.0" coredis prometheus-client shap scikit-learn pandas numpy && \
# Update packages with known CVE fixes
pip install --upgrade \
"mcp>=1.10.0" \
"pillow>=11.3.0"
WORKDIR /app
COPY enterprise .
RUN chown -R openhands:openhands /app && chmod -R 770 /app
USER openhands
# Command will be overridden by Kubernetes deployment template
CMD ["uvicorn", "saas_server:app", "--host", "0.0.0.0", "--port", "3000"]

89
enterprise/LICENSE Normal file
View File

@@ -0,0 +1,89 @@
# PolyForm Free Trial License 1.0.0
## Acceptance
In order to get any license under these terms, you must agree
to them as both strict obligations and conditions to all
your licenses.
## Copyright License
The licensor grants you a copyright license for the software
to do everything you might do with the software that would
otherwise infringe the licensor's copyright in it for any
permitted purpose. However, you may only make changes or
new works based on the software according to [Changes and New
Works License](#changes-and-new-works-license), and you may
not distribute copies of the software.
## Changes and New Works License
The licensor grants you an additional copyright license to
make changes and new works based on the software for any
permitted purpose.
## Patent License
The licensor grants you a patent license for the software that
covers patent claims the licensor can license, or becomes able
to license, that you would infringe by using the software.
## Fair Use
You may have "fair use" rights for the software under the
law. These terms do not limit them.
## Free Trial
Use of the software for more than 30 days per calendar year is not allowed without a commercial license.
## No Other Rights
These terms do not allow you to sublicense or transfer any of
your licenses to anyone else, or prevent the licensor from
granting licenses to anyone else. These terms do not imply
any other licenses.
## Patent Defense
If you make any written claim that the software infringes or
contributes to infringement of any patent, your patent license
for the software granted under these terms ends immediately. If
your company makes such a claim, your patent license ends
immediately for work on behalf of your company.
## Violations
If you violate any of these terms, or do anything with the
software not covered by your licenses, all your licenses
end immediately.
## No Liability
***As far as the law allows, the software comes as is, without
any warranty or condition, and the licensor will not be liable
to you for any damages arising out of these terms or the use
or nature of the software, under any kind of legal claim.***
## Definitions
The **licensor** is the individual or entity offering these
terms, and the **software** is the software the licensor makes
available under these terms.
**You** refers to the individual or entity agreeing to these
terms.
**Your company** is any legal entity, sole proprietorship,
or other kind of organization that you work for, plus all
organizations that have control over, are under the control of,
or are under common control with that organization. **Control**
means ownership of substantially all the assets of an entity,
or the power to direct its management and policies by vote,
contract, or otherwise. Control can be direct or indirect.
**Your licenses** are all the licenses granted to you for the
software under these terms.
**Use** means anything you do with the software requiring one
of your licenses.

42
enterprise/Makefile Normal file
View File

@@ -0,0 +1,42 @@
BACKEND_HOST ?= "127.0.0.1"
BACKEND_PORT = 3000
BACKEND_HOST_PORT = "$(BACKEND_HOST):$(BACKEND_PORT)"
FRONTEND_PORT = 3001
OPENHANDS_PATH ?= "../../OpenHands"
OPENHANDS := $(OPENHANDS_PATH)
OPENHANDS_FRONTEND_PATH = $(OPENHANDS)/frontend/build
# ANSI color codes
GREEN=$(shell tput -Txterm setaf 2)
YELLOW=$(shell tput -Txterm setaf 3)
RED=$(shell tput -Txterm setaf 1)
BLUE=$(shell tput -Txterm setaf 6)
RESET=$(shell tput -Txterm sgr0)
build:
@poetry install
@cd $(OPENHANDS) && $(MAKE) build
_run_setup:
@echo "$(YELLOW)Starting backend server...$(RESET)"
@cd app && FRONTEND_DIRECTORY=$(OPENHANDS_FRONTEND_PATH) poetry run uvicorn saas_server:app --host $(BACKEND_HOST) --port $(BACKEND_PORT) &
@echo "$(YELLOW)Waiting for the backend to start...$(RESET)"
@until nc -z localhost $(BACKEND_PORT); do sleep 0.1; done
@echo "$(GREEN)Backend started successfully.$(RESET)"
run:
@echo "$(YELLOW)Running the app...$(RESET)"
@$(MAKE) -s _run_setup
@cd $(OPENHANDS) && $(MAKE) -s start-frontend
@echo "$(GREEN)Application started successfully.$(RESET)"
# Start backend
start-backend:
@echo "$(YELLOW)Starting backend...$(RESET)"
@echo "$(OPENHANDS_FRONTEND_PATH)"
@cd app && FRONTEND_DIRECTORY=$(OPENHANDS_FRONTEND_PATH) poetry run uvicorn saas_server:app --host $(BACKEND_HOST) --port $(BACKEND_PORT) --reload-dir $(OPENHANDS_PATH) --reload --reload-dir ./ --reload-exclude "./workspace"
lint:
@poetry run pre-commit run --all-files --show-diff-on-failure --config ./dev_config/python/.pre-commit-config.yaml

56
enterprise/README.md Normal file
View File

@@ -0,0 +1,56 @@
# OpenHands Enterprise Server
> [!WARNING]
> This software is licensed under the [Polyform Free Trial License](./LICENSE). This is **NOT** an open source license. Usage is limited to 30 days per calendar year without a commercial license. If you would like to use it beyond 30 days, please [contact us](https://www.all-hands.dev/contact).
> [!WARNING]
> This is a work in progress and may contain bugs, incomplete features, or breaking changes.
This directory contains the enterprise server used by [OpenHands Cloud](https://github.com/All-Hands-AI/OpenHands-Cloud/). The official, public version of OpenHands Cloud is available at
[app.all-hands.dev](https://app.all-hands.dev).
You may also want to check out the MIT-licensed [OpenHands](https://github.com/All-Hands-AI/OpenHands)
## Extension of OpenHands (OSS)
The code in `/enterprise` directory builds on top of open source (OSS) code, extending its functionality. The enterprise code is entangled with the OSS code in two ways
- Enterprise stacks on top of OSS. For example, the middleware in enterprise is stacked right on top of the middlewares in OSS. In `SAAS`, the middleware from BOTH repos will be present and running (which can sometimes cause conflicts)
- Enterprise overrides the implementation in OSS (only one is present at a time). For example, the server config SaasServerConfig which overrides [`ServerConfig`](https://github.com/All-Hands-AI/OpenHands/blob/main/openhands/server/config/server_config.py#L8) on OSS. This is done through dynamic imports ([see here](https://github.com/All-Hands-AI/OpenHands/blob/main/openhands/server/config/server_config.py#L37-#L45))
Key areas that change on `SAAS` are
- Authentication
- User settings
- etc
### Authentication
| Aspect | OSS | Enterprise |
| ------------------------- | ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
| **Authentication Method** | User adds a personal access token (PAT) through the UI | User performs OAuth through the UI. The Github app provides a short-lived access token and refresh token |
| **Token Storage** | PAT is stored in **Settings** | Token is stored in **GithubTokenManager** (a file store in our backend) |
| **Authenticated status** | We simply check if token exists in `Settings` | We issue a signed cookie with `github_user_id` during oauth, so subsequent requests with the cookie can be considered authenticated |
Note that in the future, authentication will happen via keycloak. All modifications for authentication will happen in enterprise.
### GitHub Service
The github service is responsible for interacting with Github APIs. As a consequence, it uses the user's token and refreshes it if need be
| Aspect | OSS | Enterprise |
| ------------------------- | -------------------------------------- | ---------------------------------------------- |
| **Class used** | `GitHubService` | `SaaSGitHubService` |
| **Token used** | User's PAT fetched from `Settings` | User's token fetched from `GitHubTokenManager` |
| **Refresh functionality** | **N/A**; user provides PAT for the app | Uses the `GitHubTokenManager` to refresh |
NOTE: in the future we will simply replace the `GithubTokenManager` with keycloak. The `SaaSGithubService` should interact with keycloack instead.
# Areas that are BRITTLE!
## User ID vs User Token
- On OSS, the entire APP revolves around the Github token the user sets. `openhands/server` uses `request.state.github_token` for the entire app
- On Enterprise, the entire APP resolves around the Github User ID. This is because the cookie sets it, so `openhands/server` AND `enterprise/server` depend on it and completly ignore `request.state.github_token` (token is fetched from `GithubTokenManager` instead)
Note that introducing Github User ID on OSS, for instance, will cause large breakages.

1
enterprise/__init__.py Normal file
View File

@@ -0,0 +1 @@
# App package for OpenHands

79
enterprise/alembic.ini Normal file
View File

@@ -0,0 +1,79 @@
# A generic, single database configuration.
[alembic]
# path to migration scripts
script_location = migrations
# template used to generate migration file names; The default value is %%(rev)s_%%(slug)s
# file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s
# sys.path path, will be prepended to sys.path if present.
# defaults to the current working directory.
prepend_sys_path = .
# timezone to use when rendering the date within the migration file
# as well as the filename.
# If specified, requires the python>=3.9 or backports.zoneinfo library.
# timezone =
# max length of characters to apply to the "slug" field
# truncate_slug_length = 40
# set to 'true' to run the environment during
# the 'revision' command, regardless of autogenerate
# revision_environment = false
# set to 'true' to allow .pyc and .pyo files without
# a source .py file to be detected as revisions in the
# versions/ directory
# sourceless = false
# version path separator; As mentioned above, this is the character used to split
# version_locations. The default within new alembic.ini files is "os", which uses os.pathsep.
version_path_separator = os # Use os.pathsep. Default configuration used for new projects.
# the output encoding used when revision files
# are written from script.py.mako
# output_encoding = utf-8
sqlalchemy.url = driver://user:pass@localhost/dbname
[post_write_hooks]
# post_write_hooks defines scripts or Python functions that are run
# on newly generated revision scripts. See the documentation for further
# detail and examples
# Logging configuration
[loggers]
keys = root,sqlalchemy,alembic
[handlers]
keys = console
[formatters]
keys = generic
[logger_root]
level = DEBUG
handlers = console
qualname =
[logger_sqlalchemy]
level = DEBUG
handlers =
qualname = sqlalchemy.engine
[logger_alembic]
level = DEBUG
handlers =
qualname = alembic
[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic
[formatter_generic]
format = %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,57 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: trailing-whitespace
exclude: docs/modules/python
files: ^enterprise/
- id: end-of-file-fixer
exclude: docs/modules/python
files: ^enterprise/
- id: check-yaml
files: ^enterprise/
- id: debug-statements
files: ^enterprise/
- repo: https://github.com/abravalheri/validate-pyproject
rev: v0.16
hooks:
- id: validate-pyproject
types: [toml]
files: ^enterprise/pyproject\.toml$
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.4.1
hooks:
# Run the linter.
- id: ruff
entry: ruff check --config enterprise/dev_config/python/ruff.toml
types_or: [python, pyi, jupyter]
args: [--fix]
files: ^enterprise/
# Run the formatter.
- id: ruff-format
entry: ruff format --config enterprise/dev_config/python/ruff.toml
types_or: [python, pyi, jupyter]
files: ^enterprise/
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.9.0
hooks:
- id: mypy
additional_dependencies:
- types-requests
- types-setuptools
- types-pyyaml
- types-toml
- types-redis
- lxml
# OpenHands package in repo root
- ./
- stripe==11.5.0
- pygithub==2.6.1
# To see gaps add `--html-report mypy-report/`
entry: mypy --config-file enterprise/dev_config/python/mypy.ini enterprise/
always_run: true
pass_filenames: false
files: ^enterprise/

View File

@@ -0,0 +1,17 @@
[mypy]
warn_unused_configs = True
ignore_missing_imports = True
check_untyped_defs = True
explicit_package_bases = True
warn_unreachable = True
warn_redundant_casts = True
no_implicit_optional = True
strict_optional = True
disable_error_code = type-abstract
exclude = (^enterprise/migrations/.*)
[mypy-enterprise.tests.unit.test_auth_routes.*]
disable_error_code = union-attr
[mypy-enterprise.sync.install_gitlab_webhooks.*]
disable_error_code = redundant-cast

View File

@@ -0,0 +1,31 @@
[lint]
select = [
"E",
"W",
"F",
"I",
"Q",
"B",
]
ignore = [
"E501",
"B003",
"B007",
"B008", # Allow function calls in argument defaults (FastAPI Query pattern)
"B009",
"B010",
"B904",
"B018",
]
exclude = [
"app/migrations/*"
]
[lint.flake8-quotes]
docstring-quotes = "double"
inline-quotes = "single"
[format]
quote-style = "single"

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