@elizaos/sweagent-root 2.0.0-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (323) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +270 -0
  3. package/package.json +71 -0
  4. package/python/LICENSE +21 -0
  5. package/python/config/README.md +15 -0
  6. package/python/config/bash_only.yaml +222 -0
  7. package/python/config/benchmarks/250212_sweagent_heavy_sbl.yaml +188 -0
  8. package/python/config/benchmarks/250225_anthropic_filemap_simple_review.yaml +75 -0
  9. package/python/config/benchmarks/250522_anthropic_filemap_simple_review.yaml +92 -0
  10. package/python/config/benchmarks/250526_anthropic_filemap_simple_review_sbl.yaml +93 -0
  11. package/python/config/benchmarks/anthropic_filemap_multilingual.yaml +66 -0
  12. package/python/config/coding_challenge.yaml +104 -0
  13. package/python/config/default.yaml +69 -0
  14. package/python/config/default_backticks.yaml +69 -0
  15. package/python/config/default_mm_no_images.yaml +82 -0
  16. package/python/config/default_mm_with_images.yaml +83 -0
  17. package/python/config/demo/default.yaml +80 -0
  18. package/python/config/demo/no_instructions.yaml +69 -0
  19. package/python/config/demo/only_bash.yaml +60 -0
  20. package/python/config/exotic/default_shell.yaml +52 -0
  21. package/python/config/exotic/windowed_replace.yaml +125 -0
  22. package/python/config/exotic/windowed_replace_late_repro.yaml +127 -0
  23. package/python/config/human/human.yaml +24 -0
  24. package/python/config/human/human_demo.yaml +52 -0
  25. package/python/config/sweagent_0_7/07.yaml +101 -0
  26. package/python/config/sweagent_0_7/07_fcalling.yaml +100 -0
  27. package/python/config/sweagent_0_7/07_from_url.yaml +114 -0
  28. package/python/config/sweagent_0_7/07_thought_action.yaml +102 -0
  29. package/python/config/sweagent_0_7/07_thought_action_xml.yaml +96 -0
  30. package/python/mlc_config.json +44 -0
  31. package/python/pyproject.toml +262 -0
  32. package/python/sweagent/__init__.py +114 -0
  33. package/python/sweagent/__main__.py +4 -0
  34. package/python/sweagent/agent/__init__.py +0 -0
  35. package/python/sweagent/agent/action_sampler.py +317 -0
  36. package/python/sweagent/agent/agents.py +1294 -0
  37. package/python/sweagent/agent/extra/shell_agent.py +106 -0
  38. package/python/sweagent/agent/history_processors.py +399 -0
  39. package/python/sweagent/agent/hooks/__init__.py +0 -0
  40. package/python/sweagent/agent/hooks/abstract.py +139 -0
  41. package/python/sweagent/agent/hooks/status.py +34 -0
  42. package/python/sweagent/agent/models.py +896 -0
  43. package/python/sweagent/agent/problem_statement.py +312 -0
  44. package/python/sweagent/agent/reviewer.py +664 -0
  45. package/python/sweagent/environment/__init__.py +0 -0
  46. package/python/sweagent/environment/hooks/__init__.py +0 -0
  47. package/python/sweagent/environment/hooks/abstract.py +60 -0
  48. package/python/sweagent/environment/hooks/status.py +28 -0
  49. package/python/sweagent/environment/repo.py +219 -0
  50. package/python/sweagent/environment/swe_env.py +276 -0
  51. package/python/sweagent/exceptions.py +54 -0
  52. package/python/sweagent/inspector/README.md +6 -0
  53. package/python/sweagent/inspector/__init__.py +0 -0
  54. package/python/sweagent/inspector/favicon.ico +0 -0
  55. package/python/sweagent/inspector/fileViewer.js +354 -0
  56. package/python/sweagent/inspector/icons/computer.png +0 -0
  57. package/python/sweagent/inspector/icons/edit_icon.svg +11 -0
  58. package/python/sweagent/inspector/icons/swe-agent-logo-50.png +0 -0
  59. package/python/sweagent/inspector/icons/swellama_blue.png +0 -0
  60. package/python/sweagent/inspector/icons/swellama_brown.png +0 -0
  61. package/python/sweagent/inspector/icons/swellama_grey.png +0 -0
  62. package/python/sweagent/inspector/icons/swellama_tan.png +0 -0
  63. package/python/sweagent/inspector/index.html +25 -0
  64. package/python/sweagent/inspector/server.py +354 -0
  65. package/python/sweagent/inspector/static.py +169 -0
  66. package/python/sweagent/inspector/style.css +454 -0
  67. package/python/sweagent/run/__init__.py +0 -0
  68. package/python/sweagent/run/_progress.py +158 -0
  69. package/python/sweagent/run/batch_instances.py +419 -0
  70. package/python/sweagent/run/common.py +387 -0
  71. package/python/sweagent/run/compare_runs.py +123 -0
  72. package/python/sweagent/run/extract_pred.py +19 -0
  73. package/python/sweagent/run/hooks/__init__.py +0 -0
  74. package/python/sweagent/run/hooks/abstract.py +67 -0
  75. package/python/sweagent/run/hooks/apply_patch.py +106 -0
  76. package/python/sweagent/run/hooks/open_pr.py +244 -0
  77. package/python/sweagent/run/hooks/swe_bench_evaluate.py +113 -0
  78. package/python/sweagent/run/inspector_cli.py +493 -0
  79. package/python/sweagent/run/merge_predictions.py +64 -0
  80. package/python/sweagent/run/quick_stats.py +96 -0
  81. package/python/sweagent/run/remove_unfinished.py +63 -0
  82. package/python/sweagent/run/rich_test.py +91 -0
  83. package/python/sweagent/run/run.py +147 -0
  84. package/python/sweagent/run/run_batch.py +442 -0
  85. package/python/sweagent/run/run_replay.py +219 -0
  86. package/python/sweagent/run/run_shell.py +155 -0
  87. package/python/sweagent/run/run_single.py +225 -0
  88. package/python/sweagent/run/run_traj_to_demo.py +85 -0
  89. package/python/sweagent/tools/__init__.py +0 -0
  90. package/python/sweagent/tools/bundle.py +57 -0
  91. package/python/sweagent/tools/commands.py +220 -0
  92. package/python/sweagent/tools/parsing.py +619 -0
  93. package/python/sweagent/tools/tools.py +430 -0
  94. package/python/sweagent/tools/utils.py +108 -0
  95. package/python/sweagent/types.py +102 -0
  96. package/python/sweagent/utils/__init__.py +0 -0
  97. package/python/sweagent/utils/config.py +80 -0
  98. package/python/sweagent/utils/files.py +27 -0
  99. package/python/sweagent/utils/github.py +118 -0
  100. package/python/sweagent/utils/jinja_warnings.py +14 -0
  101. package/python/sweagent/utils/log.py +175 -0
  102. package/python/sweagent/utils/patch_formatter.py +152 -0
  103. package/python/sweagent/utils/serialization.py +45 -0
  104. package/python/tests/__init__.py +0 -0
  105. package/python/tests/conftest.py +191 -0
  106. package/python/tests/test_agent.py +258 -0
  107. package/python/tests/test_batch_instance.py +43 -0
  108. package/python/tests/test_commands/_interactive_dummy.py +35 -0
  109. package/python/tests/test_commands/interactive_dummy_wrapper.sh +29 -0
  110. package/python/tests/test_data/config_files/dummy_interactive.yaml +62 -0
  111. package/python/tests/test_data/data_sources/ctf/crypto/Katy/Dockerfile +20 -0
  112. package/python/tests/test_data/data_sources/ctf/crypto/Katy/README.md +13 -0
  113. package/python/tests/test_data/data_sources/ctf/crypto/Katy/challenge.json +12 -0
  114. package/python/tests/test_data/data_sources/ctf/crypto/Katy/customrandom.c +50 -0
  115. package/python/tests/test_data/data_sources/ctf/crypto/Katy/docker-compose.yml +14 -0
  116. package/python/tests/test_data/data_sources/ctf/crypto/Katy/release +0 -0
  117. package/python/tests/test_data/data_sources/ctf/crypto/Katy/server +0 -0
  118. package/python/tests/test_data/data_sources/ctf/crypto/Katy/solver.py +12 -0
  119. package/python/tests/test_data/data_sources/ctf/forensics/flash/README.md +16 -0
  120. package/python/tests/test_data/data_sources/ctf/forensics/flash/challenge.json +9 -0
  121. package/python/tests/test_data/data_sources/ctf/forensics/flash/flash_c8429a430278283c0e571baebca3d139.zip +0 -0
  122. package/python/tests/test_data/data_sources/ctf/misc/networking_1/README.md +15 -0
  123. package/python/tests/test_data/data_sources/ctf/misc/networking_1/challenge.json +10 -0
  124. package/python/tests/test_data/data_sources/ctf/misc/networking_1/networking.pcap +0 -0
  125. package/python/tests/test_data/data_sources/ctf/pwn/warmup/Dockerfile +28 -0
  126. package/python/tests/test_data/data_sources/ctf/pwn/warmup/README.md +14 -0
  127. package/python/tests/test_data/data_sources/ctf/pwn/warmup/challenge.json +14 -0
  128. package/python/tests/test_data/data_sources/ctf/pwn/warmup/docker-compose.yml +14 -0
  129. package/python/tests/test_data/data_sources/ctf/pwn/warmup/flag.txt +1 -0
  130. package/python/tests/test_data/data_sources/ctf/pwn/warmup/warmup +0 -0
  131. package/python/tests/test_data/data_sources/ctf/pwn/warmup/warmup.c +26 -0
  132. package/python/tests/test_data/data_sources/ctf/pwn/warmup/warmup.py +9 -0
  133. package/python/tests/test_data/data_sources/ctf/rev/rock/README.md +14 -0
  134. package/python/tests/test_data/data_sources/ctf/rev/rock/challenge.json +8 -0
  135. package/python/tests/test_data/data_sources/ctf/rev/rock/rock +0 -0
  136. package/python/tests/test_data/data_sources/ctf/rev/rock/rock.cpp +167 -0
  137. package/python/tests/test_data/data_sources/ctf/rev/rock/solution.cpp +24 -0
  138. package/python/tests/test_data/data_sources/ctf/rev/rock/test_solver/solution.py +6 -0
  139. package/python/tests/test_data/data_sources/ctf/rev/rock/test_solver/test.sh +10 -0
  140. package/python/tests/test_data/data_sources/ctf/web/i_got_id_demo/000-default.conf +18 -0
  141. package/python/tests/test_data/data_sources/ctf/web/i_got_id_demo/Dockerfile +20 -0
  142. package/python/tests/test_data/data_sources/ctf/web/i_got_id_demo/cgi/file.pl +38 -0
  143. package/python/tests/test_data/data_sources/ctf/web/i_got_id_demo/cgi/forms.pl +40 -0
  144. package/python/tests/test_data/data_sources/ctf/web/i_got_id_demo/cgi/hello.pl +11 -0
  145. package/python/tests/test_data/data_sources/ctf/web/i_got_id_demo/challenge.json +12 -0
  146. package/python/tests/test_data/data_sources/ctf/web/i_got_id_demo/docker-compose.yml +14 -0
  147. package/python/tests/test_data/data_sources/ctf/web/i_got_id_demo/flag +1 -0
  148. package/python/tests/test_data/data_sources/ctf/web/i_got_id_demo/index.html +11 -0
  149. package/python/tests/test_data/data_sources/ctf/web/i_got_id_demo/solution.txt +1 -0
  150. package/python/tests/test_data/data_sources/debug_20240322.json +1 -0
  151. package/python/tests/test_data/data_sources/expert_instances.yaml +16 -0
  152. package/python/tests/test_data/data_sources/human_eval.json +1 -0
  153. package/python/tests/test_data/data_sources/simple_instances.yaml +3 -0
  154. package/python/tests/test_data/data_sources/simple_instances_long.yaml +30 -0
  155. package/python/tests/test_data/data_sources/swe-bench-dev-easy.json +1 -0
  156. package/python/tests/test_data/data_sources/swe-bench-dev-easy_first_only.json +1 -0
  157. package/python/tests/test_data/data_sources/swe-bench-lite-test.json +1 -0
  158. package/python/tests/test_data/trajectories/gpt4__swe-agent-test-repo__default_from_url__t-0.00__p-0.95__c-3.00__install-1/6e44b9__sweagenttestrepo-1c2844.traj +342 -0
  159. package/python/tests/test_data/trajectories/gpt4__swe-agent-test-repo__default_from_url__t-0.00__p-0.95__c-3.00__install-1/solution_missing_colon.py +15 -0
  160. package/python/tests/test_data/trajectories/gpt4__swe-agent__test-repo__default_from_url__t-0.00__p-0.95__c-3.00__install-1/args.yaml +518 -0
  161. package/python/tests/test_data/trajectories/gpt4__swe-agent__test-repo__default_from_url__t-0.00__p-0.95__c-3.00__install-1/swe-agent__test-repo-i1.traj +124 -0
  162. package/python/tests/test_data/trajectories/gpt4__swe-bench-dev-easy_first_only__default__t-0.00__p-0.95__c-3.00__install-1/all_preds.jsonl +1 -0
  163. package/python/tests/test_data/trajectories/gpt4__swe-bench-dev-easy_first_only__default__t-0.00__p-0.95__c-3.00__install-1/args.yaml +520 -0
  164. package/python/tests/test_data/trajectories/gpt4__swe-bench-dev-easy_first_only__default__t-0.00__p-0.95__c-3.00__install-1/patches/pydicom__pydicom-1458.patch +18 -0
  165. package/python/tests/test_data/trajectories/gpt4__swe-bench-dev-easy_first_only__default__t-0.00__p-0.95__c-3.00__install-1/pydicom__pydicom-1458.traj +257 -0
  166. package/python/tests/test_env.py +66 -0
  167. package/python/tests/test_env_utils.py +129 -0
  168. package/python/tests/test_history_processors.py +40 -0
  169. package/python/tests/test_models.py +23 -0
  170. package/python/tests/test_openai_live.py +164 -0
  171. package/python/tests/test_packaging.py +7 -0
  172. package/python/tests/test_parsing.py +131 -0
  173. package/python/tests/test_problem_statement_multimodal.py +111 -0
  174. package/python/tests/test_quick_stats.py +42 -0
  175. package/python/tests/test_run.py +37 -0
  176. package/python/tests/test_run_batch.py +110 -0
  177. package/python/tests/test_run_hooks.py +114 -0
  178. package/python/tests/test_run_replay.py +33 -0
  179. package/python/tests/test_run_single.py +125 -0
  180. package/python/tests/test_tools_command_parsing.py +193 -0
  181. package/python/tests/test_utils.py +15 -0
  182. package/python/tests/tools/__init__.py +0 -0
  183. package/python/tests/tools/conftest.py +12 -0
  184. package/python/tests/tools/test_default_utils.py +153 -0
  185. package/python/tests/tools/test_edit_replace.py +0 -0
  186. package/python/tests/tools/test_split_string.py +82 -0
  187. package/python/tests/utils.py +29 -0
  188. package/python/tools/diff_state/bin/_state_diff_state +52 -0
  189. package/python/tools/diff_state/config.yaml +2 -0
  190. package/python/tools/edit_anthropic/bin/_state_anthropic +21 -0
  191. package/python/tools/edit_anthropic/bin/str_replace_editor +710 -0
  192. package/python/tools/edit_anthropic/config.yaml +56 -0
  193. package/python/tools/edit_anthropic/install.sh +3 -0
  194. package/python/tools/filemap/bin/filemap +45 -0
  195. package/python/tools/filemap/config.yaml +9 -0
  196. package/python/tools/filemap/install.sh +2 -0
  197. package/python/tools/forfeit/bin/exit_forfeit +5 -0
  198. package/python/tools/forfeit/config.yaml +5 -0
  199. package/python/tools/image_tools/bin/view_image +36 -0
  200. package/python/tools/image_tools/config.yaml +9 -0
  201. package/python/tools/multilingual_setup/bin/do_nothing +2 -0
  202. package/python/tools/multilingual_setup/config.yaml +1 -0
  203. package/python/tools/multilingual_setup/install.sh +45 -0
  204. package/python/tools/registry/bin/_read_env +10 -0
  205. package/python/tools/registry/bin/_write_env +10 -0
  206. package/python/tools/registry/config.yaml +1 -0
  207. package/python/tools/registry/install.sh +6 -0
  208. package/python/tools/registry/lib/__init__.py +0 -0
  209. package/python/tools/registry/lib/registry.py +56 -0
  210. package/python/tools/review_on_submit_m/README.md +6 -0
  211. package/python/tools/review_on_submit_m/bin/submit +54 -0
  212. package/python/tools/review_on_submit_m/config.yaml +6 -0
  213. package/python/tools/review_on_submit_m/install.sh +0 -0
  214. package/python/tools/search/bin/find_file +31 -0
  215. package/python/tools/search/bin/search_dir +39 -0
  216. package/python/tools/search/bin/search_file +55 -0
  217. package/python/tools/search/config.yaml +37 -0
  218. package/python/tools/search/install.sh +3 -0
  219. package/python/tools/submit/bin/submit +17 -0
  220. package/python/tools/submit/config.yaml +5 -0
  221. package/python/tools/web_browser/bin/click_mouse +41 -0
  222. package/python/tools/web_browser/bin/close_site +28 -0
  223. package/python/tools/web_browser/bin/double_click_mouse +37 -0
  224. package/python/tools/web_browser/bin/drag_mouse +46 -0
  225. package/python/tools/web_browser/bin/execute_script_on_page +39 -0
  226. package/python/tools/web_browser/bin/get_console_output +48 -0
  227. package/python/tools/web_browser/bin/move_mouse +35 -0
  228. package/python/tools/web_browser/bin/navigate_back +33 -0
  229. package/python/tools/web_browser/bin/navigate_forward +33 -0
  230. package/python/tools/web_browser/bin/open_site +36 -0
  231. package/python/tools/web_browser/bin/press_keys_on_page +51 -0
  232. package/python/tools/web_browser/bin/reload_page +33 -0
  233. package/python/tools/web_browser/bin/run_web_browser_server +394 -0
  234. package/python/tools/web_browser/bin/screenshot_site +38 -0
  235. package/python/tools/web_browser/bin/scroll_on_page +40 -0
  236. package/python/tools/web_browser/bin/set_browser_window_size +40 -0
  237. package/python/tools/web_browser/bin/type_text +34 -0
  238. package/python/tools/web_browser/bin/wait_time +39 -0
  239. package/python/tools/web_browser/config.yaml +155 -0
  240. package/python/tools/web_browser/install.sh +22 -0
  241. package/python/tools/web_browser/lib/browser_manager.py +404 -0
  242. package/python/tools/web_browser/lib/web_browser_config.py +33 -0
  243. package/python/tools/web_browser/lib/web_browser_utils.py +126 -0
  244. package/python/tools/web_browser/test_console.html +1 -0
  245. package/python/tools/windowed/bin/_state +25 -0
  246. package/python/tools/windowed/bin/create +29 -0
  247. package/python/tools/windowed/bin/goto +37 -0
  248. package/python/tools/windowed/bin/open +49 -0
  249. package/python/tools/windowed/bin/scroll_down +12 -0
  250. package/python/tools/windowed/bin/scroll_up +13 -0
  251. package/python/tools/windowed/config.yaml +38 -0
  252. package/python/tools/windowed/install.sh +15 -0
  253. package/python/tools/windowed/lib/__init__.py +0 -0
  254. package/python/tools/windowed/lib/flake8_utils.py +147 -0
  255. package/python/tools/windowed/lib/windowed_file.py +312 -0
  256. package/python/tools/windowed_edit_linting/bin/edit +128 -0
  257. package/python/tools/windowed_edit_linting/config.yaml +31 -0
  258. package/python/tools/windowed_edit_linting/install.sh +5 -0
  259. package/python/tools/windowed_edit_replace/bin/edit +172 -0
  260. package/python/tools/windowed_edit_replace/bin/insert +77 -0
  261. package/python/tools/windowed_edit_replace/config.yaml +60 -0
  262. package/python/tools/windowed_edit_replace/install.sh +5 -0
  263. package/python/tools/windowed_edit_rewrite/bin/edit +78 -0
  264. package/python/tools/windowed_edit_rewrite/config.yaml +11 -0
  265. package/python/tools/windowed_edit_rewrite/install.sh +5 -0
  266. package/python/trajectories/demonstrations/ctf/crypto/BabyEncryption.traj +318 -0
  267. package/python/trajectories/demonstrations/ctf/crypto/BabyTimeCapsule.traj +197 -0
  268. package/python/trajectories/demonstrations/ctf/crypto/eps.traj +289 -0
  269. package/python/trajectories/demonstrations/ctf/crypto/katy.traj +368 -0
  270. package/python/trajectories/demonstrations/ctf/forensics/flash.traj +102 -0
  271. package/python/trajectories/demonstrations/ctf/misc/networking_1.traj +102 -0
  272. package/python/trajectories/demonstrations/ctf/pwn/warmup.traj +159 -0
  273. package/python/trajectories/demonstrations/ctf/rev/rock.traj +251 -0
  274. package/python/trajectories/demonstrations/ctf/web/i_got_id_demo.traj +422 -0
  275. package/python/trajectories/demonstrations/function_calling_simple.traj +151 -0
  276. package/python/trajectories/demonstrations/human_thought__swe-bench-HumanEvalFix-python__lcb__t-0.00__p-0.95__c-4.00__install-0/humanevalfix-python-0.traj +129 -0
  277. package/python/trajectories/demonstrations/replay__marshmallow-code__marshmallow-1867__default__t-0.20__p-0.95__c-2.00__install-1___install_from_source/marshmallow-code__marshmallow-1867.traj +318 -0
  278. package/python/trajectories/demonstrations/replay__marshmallow-code__marshmallow-1867__default_sys-env_cursors_window100__t-0.20__p-0.95__c-2.00__install-1/marshmallow-code__marshmallow-1867.traj +251 -0
  279. package/python/trajectories/demonstrations/replay__marshmallow-code__marshmallow-1867__default_sys-env_window100__t-0.20__p-0.95__c-2.00__install-1/marshmallow-code__marshmallow-1867.traj +399 -0
  280. package/python/trajectories/demonstrations/replay__marshmallow-code__marshmallow-1867__function_calling__install-1/marshmallow-code__marshmallow-1867.traj +594 -0
  281. package/python/trajectories/demonstrations/replay__marshmallow-code__marshmallow-1867__function_calling_replace__install-1/marshmallow-code__marshmallow-1867.traj +592 -0
  282. package/python/trajectories/demonstrations/replay__marshmallow-code__marshmallow-1867__function_calling_replace_from_source/marshmallow-code__marshmallow-1867.traj +3316 -0
  283. package/python/trajectories/demonstrations/replay__marshmallow-code__marshmallow-1867__xml_sys-env_cursors_window100__t-0.20__p-0.95__c-2.00__install-1/marshmallow-code__marshmallow-1867.traj +251 -0
  284. package/python/trajectories/demonstrations/replay__marshmallow-code__marshmallow-1867__xml_sys-env_window100__t-0.20__p-0.95__c-2.00__install-1/marshmallow-code__marshmallow-1867.traj +399 -0
  285. package/python/trajectories/demonstrations/str_replace_anthropic_demo.yaml +432 -0
  286. package/rust/Cargo.toml +100 -0
  287. package/rust/README.md +49 -0
  288. package/rust/src/agent/action_sampler.rs +130 -0
  289. package/rust/src/agent/agents.rs +1029 -0
  290. package/rust/src/agent/history_processors.rs +277 -0
  291. package/rust/src/agent/hooks/mod.rs +208 -0
  292. package/rust/src/agent/mod.rs +24 -0
  293. package/rust/src/agent/models.rs +837 -0
  294. package/rust/src/agent/problem_statement.rs +355 -0
  295. package/rust/src/agent/reviewer.rs +505 -0
  296. package/rust/src/bin/sweagent.rs +784 -0
  297. package/rust/src/environment/deployment.rs +631 -0
  298. package/rust/src/environment/hooks/mod.rs +114 -0
  299. package/rust/src/environment/mod.rs +16 -0
  300. package/rust/src/environment/repo.rs +265 -0
  301. package/rust/src/environment/runtime.rs +237 -0
  302. package/rust/src/environment/swe_env.rs +248 -0
  303. package/rust/src/exceptions.rs +228 -0
  304. package/rust/src/lib.rs +68 -0
  305. package/rust/src/monitoring.rs +482 -0
  306. package/rust/src/run/hooks/mod.rs +134 -0
  307. package/rust/src/run/mod.rs +12 -0
  308. package/rust/src/run/run_batch.rs +563 -0
  309. package/rust/src/run/run_single.rs +196 -0
  310. package/rust/src/tools/bundle.rs +224 -0
  311. package/rust/src/tools/commands.rs +173 -0
  312. package/rust/src/tools/mod.rs +295 -0
  313. package/rust/src/tools/parsing.rs +354 -0
  314. package/rust/src/tools/registry.rs +143 -0
  315. package/rust/src/types.rs +554 -0
  316. package/rust/src/utils/config.rs +105 -0
  317. package/rust/src/utils/files.rs +137 -0
  318. package/rust/src/utils/github.rs +171 -0
  319. package/rust/src/utils/log.rs +65 -0
  320. package/rust/src/utils/mod.rs +17 -0
  321. package/rust/src/utils/serialization.rs +181 -0
  322. package/rust/src/utils/template.rs +173 -0
  323. package/typescript/README.md +335 -0
@@ -0,0 +1,155 @@
1
+ """[cyan][bold]Run SWE-agent in semi-interactive mode.[/bold][/cyan]
2
+
3
+ [cyan][bold]sweagen-sh is EXPERIMENTAL[/bold][/cyan]
4
+
5
+ [cyan][bold]=== BASIC OPTIONS ===[/bold][/cyan]
6
+
7
+ -h --help Show help text and exit
8
+ --help_option Print specific help text and exit
9
+ --config CONFIG Load additional config files. Use this option multiple times to load
10
+ multiple files, e.g., --config config1.yaml --config config2.yaml
11
+
12
+ """
13
+
14
+ import argparse
15
+ import logging
16
+ from pathlib import Path
17
+
18
+ import yaml
19
+ from rich.prompt import Prompt
20
+ from swerex.deployment.config import DockerDeploymentConfig
21
+
22
+ from sweagent import CONFIG_DIR
23
+ from sweagent.agent.agents import AbstractAgent, ShellAgentConfig
24
+ from sweagent.agent.extra.shell_agent import ShellAgent
25
+ from sweagent.agent.problem_statement import (
26
+ GithubIssue,
27
+ ProblemStatement,
28
+ ProblemStatementConfig,
29
+ TextProblemStatement,
30
+ )
31
+ from sweagent.environment.repo import PreExistingRepoConfig
32
+ from sweagent.environment.swe_env import EnvironmentConfig, SWEEnv
33
+ from sweagent.run.common import save_predictions
34
+ from sweagent.run.hooks.abstract import CombinedRunHooks, RunHook
35
+ from sweagent.utils.config import load_environment_variables
36
+ from sweagent.utils.github import _is_github_issue_url
37
+ from sweagent.utils.log import add_file_handler, get_logger, set_stream_handler_levels
38
+
39
+
40
+ class RunShell:
41
+ def __init__(
42
+ self,
43
+ env: SWEEnv,
44
+ agent: AbstractAgent,
45
+ problem_statement: ProblemStatement | ProblemStatementConfig,
46
+ *,
47
+ output_dir: Path = Path("."),
48
+ hooks: list[RunHook] | None = None,
49
+ ):
50
+ """Note: When initializing this class, make sure to add the hooks that are required by your actions.
51
+ See `from_config` for an example.
52
+ """
53
+ self.logger = get_logger("swea-run", emoji="🏃")
54
+ instance_id = problem_statement.id
55
+ _log_filename_template = f"{instance_id}.{{level}}.log"
56
+ for level in ["trace", "debug", "info"]:
57
+ add_file_handler(
58
+ output_dir / instance_id / _log_filename_template.format(level=level),
59
+ level=level,
60
+ id_=f"{instance_id}-{level}",
61
+ )
62
+ self.env = env
63
+ self.agent = agent
64
+ self.output_dir = output_dir
65
+ self._hooks = []
66
+ self._chooks = CombinedRunHooks()
67
+ self.problem_statement = problem_statement
68
+ for hook in hooks or []:
69
+ self.add_hook(hook)
70
+
71
+ @property
72
+ def hooks(self) -> list[RunHook]:
73
+ return self._chooks.hooks
74
+
75
+ def add_hook(self, hook: RunHook) -> None:
76
+ hook.on_init(run=self)
77
+ self._chooks.add_hook(hook)
78
+
79
+ def run(self):
80
+ self._chooks.on_start()
81
+ self.logger.info("Starting environment")
82
+ self.env.start()
83
+ self.logger.info("Running agent")
84
+ self._chooks.on_instance_start(index=0, env=self.env, problem_statement=self.problem_statement)
85
+ output_dir = self.output_dir / self.problem_statement.id
86
+ output_dir.mkdir(parents=True, exist_ok=True)
87
+ result = self.agent.run(
88
+ problem_statement=self.problem_statement,
89
+ env=self.env,
90
+ output_dir=output_dir,
91
+ )
92
+ self._chooks.on_instance_completed(result=result)
93
+ self.logger.info("Done")
94
+ self._chooks.on_end()
95
+ save_predictions(self.output_dir, self.problem_statement.id, result)
96
+ self.env.close()
97
+
98
+
99
+ def get_cli():
100
+ parser = argparse.ArgumentParser(description=__doc__)
101
+ parser.add_argument("-r", "--repo", type=Path, help="Path to the repository.", default=None)
102
+ # parser.add_argument(dest="--model", type=str, help="Model to use.", default="claude-sonnet-4-20250514")
103
+ parser.add_argument(
104
+ "--config",
105
+ type=Path,
106
+ help="Path to the agent config file.",
107
+ default=CONFIG_DIR / "exotic" / "default_shell.yaml",
108
+ )
109
+ parser.add_argument(
110
+ "-p",
111
+ type=str,
112
+ help="Problem statement.",
113
+ default="",
114
+ )
115
+ return parser
116
+
117
+
118
+ def run_from_cli(args: list[str] | None = None):
119
+ set_stream_handler_levels(logging.INFO)
120
+ cli_args = get_cli().parse_args(args)
121
+ try:
122
+ load_environment_variables(Path(".env"))
123
+ except FileNotFoundError:
124
+ print("Env file .env not found, please set API key as env variables.")
125
+ env_config = EnvironmentConfig(
126
+ repo=PreExistingRepoConfig(repo_name="repo", reset=False),
127
+ deployment=DockerDeploymentConfig(
128
+ image="python:3.11",
129
+ docker_args=[
130
+ "-v",
131
+ f"{cli_args.repo}:/repo",
132
+ ],
133
+ python_standalone_dir="/root",
134
+ ),
135
+ )
136
+ agent_config = ShellAgentConfig.model_validate(yaml.safe_load(cli_args.config.read_text())["agent"])
137
+ agent = ShellAgent.from_config(agent_config)
138
+ env = SWEEnv.from_config(env_config)
139
+ if cli_args.repo is None:
140
+ cli_args.repo = Path(Prompt.ask("[cyan]Repository path[/cyan]", default="", show_default=False))
141
+ problem_input = cli_args.p
142
+ if not problem_input:
143
+ problem_input = Prompt.ask("[cyan]Problem statement or GitHub issue URL[/cyan]", default="", show_default=False)
144
+ if _is_github_issue_url(problem_input):
145
+ problem_statement = GithubIssue(github_url=problem_input)
146
+ else:
147
+ problem_statement = TextProblemStatement(
148
+ text=problem_input,
149
+ )
150
+ run_shell = RunShell(env, agent, problem_statement=problem_statement, output_dir=Path.home() / "sweagent_shell")
151
+ run_shell.run()
152
+
153
+
154
+ if __name__ == "__main__":
155
+ run_from_cli()
@@ -0,0 +1,225 @@
1
+ """[cyan][bold]Run SWE-agent on a single instance taken from github or similar.[/bold][/cyan]
2
+
3
+ [cyan][bold]=== BASIC OPTIONS ===[/bold][/cyan]
4
+
5
+ -h --help Show help text and exit
6
+ --help_option Print specific help text and exit
7
+ --config CONFIG Load additional config files. Use this option multiple times to load
8
+ multiple files, e.g., --config config1.yaml --config config2.yaml
9
+
10
+ [cyan][bold]=== EXAMPLES ===[/bold][/cyan]
11
+
12
+ Basic usage: Run over a [bold][cyan]github issue[/bold][/cyan][green]:
13
+
14
+ sweagent run --config config/default.yaml --agent.model.name "gpt-4o" \\
15
+ --env.repo.github_url=https://github.com/SWE-agent/test-repo/ \\
16
+ --problem_statement.github_url=https://github.com/SWE-agent/test-repo/issues/1
17
+ [/green]
18
+
19
+ By default this will start a docker container and run the agent in there.
20
+ You can set the image with [green]--env.docker.image[/green].
21
+
22
+ Here's an example that uses [bold][cyan]modal[/bold][/cyan] instead of docker and also a [bold][cyan]local repository[/bold][/cyan]:
23
+
24
+ [green]sweagent run --config config/default.yaml --agent.model.name "gpt-4o" \\
25
+ --env.deployment.type=modal --env.repo.path /path/to/repo \\
26
+ --problem_statement.path=path/to/problem_statement.md
27
+ [/green]
28
+ """
29
+
30
+ import getpass
31
+ import sys
32
+ from pathlib import Path
33
+ from typing import Self
34
+
35
+ import yaml
36
+ from pydantic import BaseModel, ConfigDict, Field
37
+ from pydantic_settings import BaseSettings, SettingsConfigDict
38
+
39
+ from sweagent.agent.agents import AbstractAgent, AgentConfig, get_agent_from_config
40
+ from sweagent.agent.problem_statement import (
41
+ EmptyProblemStatement,
42
+ ProblemStatement,
43
+ ProblemStatementConfig,
44
+ )
45
+ from sweagent.environment.swe_env import EnvironmentConfig, SWEEnv
46
+ from sweagent.run.common import AutoCorrectSuggestion as ACS
47
+ from sweagent.run.common import BasicCLI, ConfigHelper, save_predictions
48
+ from sweagent.run.hooks.abstract import CombinedRunHooks, RunHook
49
+ from sweagent.run.hooks.apply_patch import SaveApplyPatchHook
50
+ from sweagent.run.hooks.open_pr import OpenPRConfig, OpenPRHook
51
+ from sweagent.utils.config import load_environment_variables
52
+ from sweagent.utils.log import add_file_handler, get_logger
53
+
54
+
55
+ class RunSingleActionConfig(BaseModel):
56
+ """Run real-life actions (opening PRs, etc.) if we can solve the issue."""
57
+
58
+ # Open a PR with the patch if we can solve the issue
59
+ open_pr: bool = False
60
+ pr_config: OpenPRConfig = Field(default_factory=OpenPRConfig)
61
+ # When working with local repository: Apply patch
62
+ apply_patch_locally: bool = False
63
+
64
+ # pydantic config
65
+ model_config = ConfigDict(extra="forbid")
66
+
67
+
68
+ def _get_default_output_dir(output_dir: Path, problem_statement: ProblemStatement, agent: AgentConfig) -> Path:
69
+ if output_dir == Path("DEFAULT"):
70
+ user_id = getpass.getuser()
71
+ problem_id = problem_statement.id
72
+ try:
73
+ model_id = agent.model.id # type: ignore[attr-defined]
74
+ except AttributeError:
75
+ model_id = "unknown_model"
76
+ config_file = getattr(agent, "_config_files", ["no_config"])[0]
77
+ if isinstance(config_file, Path):
78
+ config_file = config_file.stem
79
+ return Path.cwd() / "trajectories" / user_id / f"{config_file}__{model_id}___{problem_id}"
80
+ return output_dir
81
+
82
+
83
+ class RunSingleConfig(BaseSettings, cli_implicit_flags=False):
84
+ env: EnvironmentConfig = Field(default_factory=EnvironmentConfig, description="Environment options.")
85
+ agent: AgentConfig = Field(description="Agent options.")
86
+ problem_statement: ProblemStatementConfig = Field(
87
+ default_factory=EmptyProblemStatement, description="Problem statement options."
88
+ )
89
+ output_dir: Path = Field(default=Path("DEFAULT"), description="Output directory.")
90
+
91
+ actions: RunSingleActionConfig = Field(default_factory=RunSingleActionConfig)
92
+
93
+ env_var_path: Path | None = None
94
+ """Path to a .env file to load environment variables from."""
95
+
96
+ # pydantic config
97
+ model_config = SettingsConfigDict(extra="forbid", env_prefix="SWE_AGENT_")
98
+
99
+ def set_default_output_dir(self) -> None:
100
+ # Needs to be called explicitly, because self._config_files will be setup
101
+ # post-init.
102
+ self.output_dir = _get_default_output_dir(self.output_dir, self.problem_statement, self.agent)
103
+
104
+ @classmethod
105
+ def _get_auto_correct(cls) -> list[ACS]:
106
+ return [
107
+ ACS("model", "agent.model.name"),
108
+ ACS("agent.model", "agent.model.name"),
109
+ ACS("model.name", "agent.model.name"),
110
+ ACS("per_instance_cost_limit", "agent.model.per_instance_cost_limit"),
111
+ ACS("model.per_instance_cost_limit", "agent.model.per_instance_cost_limit"),
112
+ ACS("config_file", "config"),
113
+ ACS(
114
+ "data_path",
115
+ help="--data_path is no longer support for SWE-A 1.0. Please check the tutorial and use one of the --problem_statement options, e.g., --problem_statement.github_url or --problem_statement.path",
116
+ ),
117
+ ACS(
118
+ "repo_path",
119
+ help="--repo_path is no longer support for SWE-A 1.0. Please check the tutorial and use one of the --env.repo options, e.g., --env.repo.github_url or --env.repo.path",
120
+ ),
121
+ ACS("repo.path", "env.repo.path"),
122
+ ]
123
+
124
+
125
+ class RunSingle:
126
+ def __init__(
127
+ self,
128
+ env: SWEEnv,
129
+ agent: AbstractAgent,
130
+ problem_statement: ProblemStatement | ProblemStatementConfig,
131
+ *,
132
+ output_dir: Path = Path("."),
133
+ hooks: list[RunHook] | None = None,
134
+ actions: RunSingleActionConfig | None = None,
135
+ ):
136
+ """Note: When initializing this class, make sure to add the hooks that are required by your actions.
137
+ See `from_config` for an example.
138
+ """
139
+ self.logger = get_logger("swea-run", emoji="🏃")
140
+ instance_id = problem_statement.id
141
+ _log_filename_template = f"{instance_id}.{{level}}.log"
142
+ for level in ["trace", "debug", "info"]:
143
+ add_file_handler(
144
+ output_dir / instance_id / _log_filename_template.format(level=level),
145
+ level=level,
146
+ id_=f"{instance_id}-{level}",
147
+ )
148
+ self.env = env
149
+ self.agent = agent
150
+ self.output_dir = output_dir
151
+ self._hooks = []
152
+ if actions is not None:
153
+ actions = RunSingleActionConfig()
154
+ self.actions = actions
155
+ self._chooks = CombinedRunHooks()
156
+ self.problem_statement = problem_statement
157
+ for hook in hooks or []:
158
+ self.add_hook(hook)
159
+
160
+ @property
161
+ def hooks(self) -> list[RunHook]:
162
+ return self._chooks.hooks
163
+
164
+ @classmethod
165
+ def from_config(cls, config: RunSingleConfig) -> Self:
166
+ load_environment_variables(config.env_var_path)
167
+ config.set_default_output_dir()
168
+ config.output_dir.mkdir(parents=True, exist_ok=True)
169
+ agent = get_agent_from_config(config.agent)
170
+ agent.replay_config = config # type: ignore[attr-defined]
171
+ self = cls(
172
+ env=SWEEnv.from_config(config.env),
173
+ agent=agent,
174
+ problem_statement=config.problem_statement,
175
+ output_dir=config.output_dir,
176
+ actions=config.actions,
177
+ )
178
+ self.add_hook(SaveApplyPatchHook(apply_patch_locally=config.actions.apply_patch_locally))
179
+ if config.actions.open_pr:
180
+ self.logger.debug("Adding OpenPRHook")
181
+ self.add_hook(OpenPRHook(config.actions.pr_config))
182
+ return self
183
+
184
+ def add_hook(self, hook: RunHook) -> None:
185
+ hook.on_init(run=self)
186
+ self._chooks.add_hook(hook)
187
+
188
+ def run(self):
189
+ self._chooks.on_start()
190
+ self.logger.info("Starting environment")
191
+ self.env.start()
192
+ self.logger.info("Running agent")
193
+ self._chooks.on_instance_start(index=0, env=self.env, problem_statement=self.problem_statement)
194
+ output_dir = self.output_dir / self.problem_statement.id
195
+ output_dir.mkdir(parents=True, exist_ok=True)
196
+ if self.agent.replay_config is not None: # type: ignore[attr-defined]
197
+ (output_dir / "config.yaml").write_text(yaml.dump(self.agent.replay_config.model_dump_json(), indent=2)) # type: ignore[attr-defined]
198
+ result = self.agent.run(
199
+ problem_statement=self.problem_statement,
200
+ env=self.env,
201
+ output_dir=output_dir,
202
+ )
203
+ self._chooks.on_instance_completed(result=result)
204
+ self.logger.info("Done")
205
+ self._chooks.on_end()
206
+ save_predictions(self.output_dir, self.problem_statement.id, result)
207
+ self.env.close()
208
+
209
+
210
+ def run_from_config(config: RunSingleConfig):
211
+ RunSingle.from_config(config).run()
212
+
213
+
214
+ def run_from_cli(args: list[str] | None = None):
215
+ if args is None:
216
+ args = sys.argv[1:]
217
+ assert __doc__ is not None
218
+ help_text = ( # type: ignore
219
+ __doc__ + "\n[cyan][bold]=== ALL THE OPTIONS ===[/bold][/cyan]\n\n" + ConfigHelper().get_help(RunSingleConfig)
220
+ )
221
+ run_from_config(BasicCLI(RunSingleConfig, help_text=help_text).get_config(args)) # type: ignore
222
+
223
+
224
+ if __name__ == "__main__":
225
+ run_from_cli()
@@ -0,0 +1,85 @@
1
+ """Convert a trajectory file to a yaml file for editing of demos.
2
+ You can then load the yaml file with `run_replay.py` to replay the actions in an environment to get
3
+ environment output.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ import json
9
+ from argparse import ArgumentParser
10
+ from pathlib import Path
11
+
12
+ from sweagent.utils.log import get_logger
13
+ from sweagent.utils.serialization import _yaml_serialization_with_linebreaks
14
+
15
+ logger = get_logger("traj2demo")
16
+
17
+ DEMO_COMMENT = """# This is a demo file generated from trajectory file:
18
+ # {traj_path}
19
+ # You can use this demo file to replay the actions in the trajectory with run_replay.py.
20
+ # You can edit the content of the actions in this file to modify the replay behavior.
21
+ # NOTICE:
22
+ # Only the actions of the assistant will be replayed.
23
+ # You do not need to modify the observation's contents or any other fields.
24
+ # You can add or remove actions to modify the replay behavior."""
25
+
26
+
27
+ def save_demo(data: str | dict | list, file: Path, traj_path: Path) -> None:
28
+ """Save demo data as a yaml file. Takes care of multi-line strings and adds a header."""
29
+ content = _yaml_serialization_with_linebreaks(data)
30
+ header = DEMO_COMMENT.format(traj_path=str(traj_path))
31
+ with open(file, "w") as f:
32
+ f.write(f"{header}\n{content}")
33
+
34
+
35
+ def convert_traj_to_action_demo(traj_path: Path, output_file: Path, include_user: bool = False) -> None:
36
+ with open(traj_path) as file:
37
+ traj = json.load(file)
38
+ replay_config = traj["replay_config"]
39
+ if isinstance(traj["replay_config"], str):
40
+ replay_config = json.loads(traj["replay_config"])
41
+ history = traj["history"]
42
+
43
+ copy_fields = {"content", "role", "tool_calls", "agent", "message_type", "tool_call_ids"}
44
+
45
+ admissible_roles = {"assistant", "user", "tool"} if include_user else {"assistant"}
46
+ filtered_history = [
47
+ {k: v for k, v in step.items() if k in copy_fields}
48
+ for step in history
49
+ if step["role"] in admissible_roles
50
+ and step.get("agent", "main") in {"main", "primary"}
51
+ and not step.get("is_demo")
52
+ ]
53
+
54
+ output_data = {"history": filtered_history, "replay_config": replay_config}
55
+ save_demo(output_data, output_file, traj_path)
56
+ logger.info(f"Saved demo to {output_file}")
57
+
58
+
59
+ def main(traj_path: Path, output_dir: Path, suffix: str = "", overwrite: bool = False, include_user: bool = False):
60
+ output_file = output_dir / (traj_path.parent.name + suffix) / (traj_path.stem.removesuffix(".traj") + ".demo.yaml")
61
+ if output_file.exists() and not overwrite:
62
+ msg = f"Output file already exists: {output_file}. Use --overwrite to overwrite."
63
+ raise FileExistsError(msg)
64
+ output_file.parent.mkdir(parents=True, exist_ok=True)
65
+ convert_traj_to_action_demo(traj_path, output_file, include_user)
66
+
67
+
68
+ def run_from_cli(args: list[str] | None = None):
69
+ """Convert a trajectory file to a demo file."""
70
+ parser = ArgumentParser(description=__doc__)
71
+ parser.add_argument("traj_path", type=Path, help="Path to trajectory file")
72
+ parser.add_argument("--output_dir", type=Path, help="Output directory for action demos", default=Path("./demos"))
73
+ parser.add_argument("--suffix", type=str, help="Suffix for the output file", default="")
74
+ parser.add_argument("--overwrite", help="Overwrite existing files", action="store_true")
75
+ parser.add_argument(
76
+ "--include_user",
77
+ help="Include user responses (computer)",
78
+ action="store_true",
79
+ )
80
+ parsed_args = parser.parse_args(args)
81
+ main(**vars(parsed_args))
82
+
83
+
84
+ if __name__ == "__main__":
85
+ run_from_cli()
File without changes
@@ -0,0 +1,57 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+
5
+ import yaml
6
+ from pydantic import BaseModel, Field, PrivateAttr, model_validator
7
+
8
+ from sweagent.tools.commands import Command
9
+ from sweagent.utils.config import _convert_path_to_abspath
10
+
11
+
12
+ class BundleConfig(BaseModel):
13
+ tools: dict[str, dict]
14
+ state_command: str | None = None
15
+
16
+
17
+ class Bundle(BaseModel):
18
+ path: Path
19
+ hidden_tools: list[str] = Field(default_factory=list)
20
+ _config: BundleConfig = PrivateAttr(default=None)
21
+
22
+ @model_validator(mode="after")
23
+ def validate_tools(self):
24
+ self.path = _convert_path_to_abspath(self.path)
25
+ if not self.path.exists():
26
+ msg = f"Bundle path '{self.path}' does not exist."
27
+ raise ValueError(msg)
28
+
29
+ config_path = self.path / "config.yaml"
30
+ if not config_path.exists():
31
+ msg = f"Bundle config file '{config_path}' does not exist."
32
+ raise ValueError(msg)
33
+
34
+ config_data = yaml.safe_load(config_path.read_text())
35
+ self._config = BundleConfig(**config_data)
36
+
37
+ invalid_hidden_tools = set(self.hidden_tools) - set(self._config.tools.keys())
38
+ if invalid_hidden_tools:
39
+ msg = f"Hidden tools {invalid_hidden_tools} do not exist in available tools"
40
+ raise ValueError(msg)
41
+ return self
42
+
43
+ @property
44
+ def state_command(self) -> str | None:
45
+ return self.config.state_command
46
+
47
+ @property
48
+ def config(self) -> BundleConfig:
49
+ return self._config
50
+
51
+ @property
52
+ def commands(self) -> list[Command]:
53
+ return [
54
+ Command(name=tool, **tool_config.model_dump() if isinstance(tool_config, Command) else tool_config)
55
+ for tool, tool_config in self.config.tools.items()
56
+ if tool not in self.hidden_tools
57
+ ]