@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,196 @@
1
+ //! Single instance runner for SWE-agent
2
+
3
+ use super::hooks::{CombinedRunHook, RunHook};
4
+ use crate::agent::problem_statement::{
5
+ create_problem_statement, ProblemStatement, ProblemStatementConfig,
6
+ };
7
+ use crate::agent::{get_agent_from_config, Agent, AgentConfig};
8
+ use crate::environment::{EnvironmentConfig, SWEEnv};
9
+ use crate::exceptions::Result;
10
+ use crate::types::AgentRunResult;
11
+ use serde::{Deserialize, Serialize};
12
+ use std::path::PathBuf;
13
+
14
+ /// Actions to perform after agent run
15
+ #[derive(Debug, Clone, Default, Serialize, Deserialize)]
16
+ pub struct RunSingleActionConfig {
17
+ #[serde(default)]
18
+ pub open_pr: bool,
19
+ #[serde(default)]
20
+ pub apply_patch_locally: bool,
21
+ }
22
+
23
+ /// Configuration for running a single instance
24
+ #[derive(Debug, Clone, Serialize, Deserialize)]
25
+ pub struct RunSingleConfig {
26
+ #[serde(default)]
27
+ pub agent: AgentConfig,
28
+ #[serde(default)]
29
+ pub env: EnvironmentConfig,
30
+ #[serde(default)]
31
+ pub problem_statement: ProblemStatementConfig,
32
+ #[serde(default = "default_output_dir")]
33
+ pub output_dir: String,
34
+ #[serde(default)]
35
+ pub actions: RunSingleActionConfig,
36
+ }
37
+
38
+ fn default_output_dir() -> String {
39
+ "./trajectories".to_string()
40
+ }
41
+
42
+ impl Default for RunSingleConfig {
43
+ fn default() -> Self {
44
+ Self {
45
+ agent: AgentConfig::default(),
46
+ env: EnvironmentConfig::default(),
47
+ problem_statement: ProblemStatementConfig::Empty,
48
+ output_dir: default_output_dir(),
49
+ actions: RunSingleActionConfig::default(),
50
+ }
51
+ }
52
+ }
53
+
54
+ /// Runner for a single problem instance
55
+ pub struct RunSingle {
56
+ agent: Box<dyn Agent>,
57
+ env: SWEEnv,
58
+ problem_statement: Box<dyn ProblemStatement>,
59
+ output_dir: PathBuf,
60
+ actions: RunSingleActionConfig,
61
+ hooks: CombinedRunHook,
62
+ }
63
+
64
+ impl RunSingle {
65
+ pub fn new(
66
+ agent: Box<dyn Agent>,
67
+ env: SWEEnv,
68
+ problem_statement: Box<dyn ProblemStatement>,
69
+ output_dir: impl Into<PathBuf>,
70
+ actions: RunSingleActionConfig,
71
+ ) -> Self {
72
+ Self {
73
+ agent,
74
+ env,
75
+ problem_statement,
76
+ output_dir: output_dir.into(),
77
+ actions,
78
+ hooks: CombinedRunHook::new(),
79
+ }
80
+ }
81
+
82
+ /// Create from configuration
83
+ pub fn from_config(config: RunSingleConfig) -> Result<Self> {
84
+ let agent = get_agent_from_config(config.agent)?;
85
+ let env = SWEEnv::from_config(config.env)?;
86
+ let problem_statement = create_problem_statement(&config.problem_statement)?;
87
+
88
+ Ok(Self::new(
89
+ agent,
90
+ env,
91
+ problem_statement,
92
+ config.output_dir,
93
+ config.actions,
94
+ ))
95
+ }
96
+
97
+ /// Add a hook
98
+ pub fn add_hook(&mut self, hook: Box<dyn RunHook>) {
99
+ self.hooks.add_hook(hook);
100
+ }
101
+
102
+ /// Run the agent on the problem instance
103
+ pub async fn run(&mut self) -> Result<AgentRunResult> {
104
+ // Ensure output directory exists
105
+ std::fs::create_dir_all(&self.output_dir)?;
106
+
107
+ self.hooks.on_start();
108
+ self.hooks.on_instance_start(0, self.problem_statement.id());
109
+
110
+ // Start the environment
111
+ self.env.start().await?;
112
+
113
+ // Create a new problem statement for the agent (since we need to move it)
114
+ let ps_config = ProblemStatementConfig::Text {
115
+ text: self.problem_statement.get_problem_statement(),
116
+ id: self.problem_statement.id().to_string(),
117
+ };
118
+ let ps_for_agent = create_problem_statement(&ps_config)?;
119
+
120
+ // Run the agent
121
+ let result = match self
122
+ .agent
123
+ .run(&mut self.env, ps_for_agent, &self.output_dir)
124
+ .await
125
+ {
126
+ Ok(r) => r,
127
+ Err(e) => {
128
+ tracing::error!(error = %e, "Agent run failed");
129
+ self.env.stop().await?;
130
+ return Err(e);
131
+ }
132
+ };
133
+
134
+ // Stop the environment
135
+ self.env.stop().await?;
136
+
137
+ self.hooks.on_instance_completed(&result);
138
+ self.hooks.on_end();
139
+
140
+ // Handle post-run actions
141
+ if self.actions.apply_patch_locally {
142
+ self.apply_patch_locally(&result).await?;
143
+ }
144
+
145
+ if self.actions.open_pr {
146
+ self.open_pr(&result).await?;
147
+ }
148
+
149
+ Ok(result)
150
+ }
151
+
152
+ async fn apply_patch_locally(&self, result: &AgentRunResult) -> Result<()> {
153
+ if let Some(ref submission) = result.info.submission {
154
+ tracing::info!("Applying patch locally");
155
+ // In a full implementation, would apply the patch using git
156
+ let patch_path = self.output_dir.join("local.patch");
157
+ std::fs::write(&patch_path, submission)?;
158
+ tracing::info!(path = ?patch_path, "Patch saved");
159
+ }
160
+ Ok(())
161
+ }
162
+
163
+ async fn open_pr(&self, result: &AgentRunResult) -> Result<()> {
164
+ if result.info.submission.is_some() {
165
+ tracing::info!("Opening PR");
166
+ // In a full implementation, would create a GitHub PR
167
+ }
168
+ Ok(())
169
+ }
170
+ }
171
+
172
+ /// Run from configuration (convenience function)
173
+ pub async fn run_from_config(config: RunSingleConfig) -> Result<AgentRunResult> {
174
+ let mut runner = RunSingle::from_config(config)?;
175
+ runner.run().await
176
+ }
177
+
178
+ #[cfg(test)]
179
+ mod tests {
180
+ use super::*;
181
+ use crate::environment::DeploymentConfig;
182
+
183
+ #[tokio::test]
184
+ async fn test_run_single_creation() {
185
+ let config = RunSingleConfig {
186
+ env: EnvironmentConfig {
187
+ deployment: DeploymentConfig::Mock,
188
+ ..Default::default()
189
+ },
190
+ ..Default::default()
191
+ };
192
+
193
+ let runner = RunSingle::from_config(config);
194
+ assert!(runner.is_ok());
195
+ }
196
+ }
@@ -0,0 +1,224 @@
1
+ //! Tool bundle definitions
2
+
3
+ use crate::exceptions::Result;
4
+ use serde::{Deserialize, Serialize};
5
+ use std::collections::HashMap;
6
+
7
+ /// A command bundle defining a tool
8
+ #[derive(Debug, Clone, Serialize, Deserialize)]
9
+ pub struct Bundle {
10
+ pub name: String,
11
+ #[serde(skip_serializing_if = "Option::is_none")]
12
+ pub end_name: Option<String>,
13
+ #[serde(skip_serializing_if = "Option::is_none")]
14
+ pub install_script: Option<String>,
15
+ #[serde(skip_serializing_if = "Option::is_none")]
16
+ pub signature: Option<String>,
17
+ #[serde(skip_serializing_if = "Option::is_none")]
18
+ pub description: Option<String>,
19
+ #[serde(default)]
20
+ pub arguments: Vec<Argument>,
21
+ #[serde(flatten)]
22
+ pub extra: HashMap<String, serde_json::Value>,
23
+ }
24
+
25
+ impl Bundle {
26
+ pub fn new(name: impl Into<String>) -> Self {
27
+ Self {
28
+ name: name.into(),
29
+ end_name: None,
30
+ install_script: None,
31
+ signature: None,
32
+ description: None,
33
+ arguments: Vec::new(),
34
+ extra: HashMap::new(),
35
+ }
36
+ }
37
+
38
+ pub fn with_end_name(mut self, end_name: impl Into<String>) -> Self {
39
+ self.end_name = Some(end_name.into());
40
+ self
41
+ }
42
+
43
+ pub fn with_install_script(mut self, script: impl Into<String>) -> Self {
44
+ self.install_script = Some(script.into());
45
+ self
46
+ }
47
+
48
+ pub fn with_description(mut self, desc: impl Into<String>) -> Self {
49
+ self.description = Some(desc.into());
50
+ self
51
+ }
52
+
53
+ pub fn with_signature(mut self, sig: impl Into<String>) -> Self {
54
+ self.signature = Some(sig.into());
55
+ self
56
+ }
57
+
58
+ pub fn with_argument(mut self, arg: Argument) -> Self {
59
+ self.arguments.push(arg);
60
+ self
61
+ }
62
+
63
+ /// Generate documentation for this command
64
+ pub fn generate_docs(&self) -> String {
65
+ let mut docs = String::new();
66
+
67
+ docs.push_str(&format!("## {}\n\n", self.name));
68
+
69
+ if let Some(ref desc) = self.description {
70
+ docs.push_str(&format!("{}\n\n", desc));
71
+ }
72
+
73
+ if let Some(ref sig) = self.signature {
74
+ docs.push_str(&format!("**Signature:** `{}`\n\n", sig));
75
+ }
76
+
77
+ if !self.arguments.is_empty() {
78
+ docs.push_str("**Arguments:**\n\n");
79
+ for arg in &self.arguments {
80
+ let required = if arg.required { " (required)" } else { "" };
81
+ docs.push_str(&format!(
82
+ "- `{}`: {}{}\n",
83
+ arg.name,
84
+ arg.description.as_deref().unwrap_or(""),
85
+ required
86
+ ));
87
+ }
88
+ docs.push('\n');
89
+ }
90
+
91
+ docs
92
+ }
93
+ }
94
+
95
+ /// An argument for a command
96
+ #[derive(Debug, Clone, Serialize, Deserialize)]
97
+ pub struct Argument {
98
+ pub name: String,
99
+ #[serde(skip_serializing_if = "Option::is_none")]
100
+ pub description: Option<String>,
101
+ #[serde(default)]
102
+ pub required: bool,
103
+ #[serde(skip_serializing_if = "Option::is_none")]
104
+ pub default_value: Option<String>,
105
+ #[serde(skip_serializing_if = "Option::is_none")]
106
+ pub arg_type: Option<String>,
107
+ }
108
+
109
+ impl Argument {
110
+ pub fn new(name: impl Into<String>) -> Self {
111
+ Self {
112
+ name: name.into(),
113
+ description: None,
114
+ required: false,
115
+ default_value: None,
116
+ arg_type: None,
117
+ }
118
+ }
119
+
120
+ pub fn required(mut self) -> Self {
121
+ self.required = true;
122
+ self
123
+ }
124
+
125
+ pub fn with_description(mut self, desc: impl Into<String>) -> Self {
126
+ self.description = Some(desc.into());
127
+ self
128
+ }
129
+
130
+ pub fn with_default(mut self, default: impl Into<String>) -> Self {
131
+ self.default_value = Some(default.into());
132
+ self
133
+ }
134
+
135
+ pub fn with_type(mut self, arg_type: impl Into<String>) -> Self {
136
+ self.arg_type = Some(arg_type.into());
137
+ self
138
+ }
139
+ }
140
+
141
+ /// Configuration for creating a bundle
142
+ #[derive(Debug, Clone, Default, Serialize, Deserialize)]
143
+ pub struct BundleConfig {
144
+ pub name: String,
145
+ #[serde(skip_serializing_if = "Option::is_none")]
146
+ pub end_name: Option<String>,
147
+ #[serde(skip_serializing_if = "Option::is_none")]
148
+ pub install_script: Option<String>,
149
+ #[serde(skip_serializing_if = "Option::is_none")]
150
+ pub signature: Option<String>,
151
+ #[serde(skip_serializing_if = "Option::is_none")]
152
+ pub description: Option<String>,
153
+ #[serde(default)]
154
+ pub arguments: Vec<Argument>,
155
+ }
156
+
157
+ /// Create a bundle from configuration
158
+ pub fn create_bundle(config: &BundleConfig) -> Result<Bundle> {
159
+ let mut bundle = Bundle::new(&config.name);
160
+
161
+ if let Some(ref end_name) = config.end_name {
162
+ bundle = bundle.with_end_name(end_name);
163
+ }
164
+
165
+ if let Some(ref script) = config.install_script {
166
+ bundle = bundle.with_install_script(script);
167
+ }
168
+
169
+ if let Some(ref sig) = config.signature {
170
+ bundle = bundle.with_signature(sig);
171
+ }
172
+
173
+ if let Some(ref desc) = config.description {
174
+ bundle = bundle.with_description(desc);
175
+ }
176
+
177
+ bundle.arguments = config.arguments.clone();
178
+
179
+ Ok(bundle)
180
+ }
181
+
182
+ /// Generate documentation for all commands
183
+ pub fn generate_command_docs(bundles: &[Bundle]) -> String {
184
+ let mut docs = String::new();
185
+ docs.push_str("# Available Commands\n\n");
186
+
187
+ for bundle in bundles {
188
+ docs.push_str(&bundle.generate_docs());
189
+ }
190
+
191
+ docs
192
+ }
193
+
194
+ #[cfg(test)]
195
+ mod tests {
196
+ use super::*;
197
+
198
+ #[test]
199
+ fn test_bundle_creation() {
200
+ let bundle = Bundle::new("edit")
201
+ .with_end_name("ENDEDIT")
202
+ .with_description("Edit a file")
203
+ .with_argument(
204
+ Argument::new("file")
205
+ .required()
206
+ .with_description("The file to edit"),
207
+ );
208
+
209
+ assert_eq!(bundle.name, "edit");
210
+ assert_eq!(bundle.end_name, Some("ENDEDIT".to_string()));
211
+ assert_eq!(bundle.arguments.len(), 1);
212
+ }
213
+
214
+ #[test]
215
+ fn test_generate_docs() {
216
+ let bundle = Bundle::new("test")
217
+ .with_description("A test command")
218
+ .with_signature("test <arg>");
219
+
220
+ let docs = bundle.generate_docs();
221
+ assert!(docs.contains("## test"));
222
+ assert!(docs.contains("A test command"));
223
+ }
224
+ }
@@ -0,0 +1,173 @@
1
+ //! Command definitions and utilities
2
+
3
+ use serde::{Deserialize, Serialize};
4
+ use std::collections::HashMap;
5
+
6
+ /// A parsed command with its arguments
7
+ #[derive(Debug, Clone, Serialize, Deserialize)]
8
+ pub struct Command {
9
+ pub name: String,
10
+ pub args: Vec<String>,
11
+ pub kwargs: HashMap<String, String>,
12
+ pub raw: String,
13
+ }
14
+
15
+ impl Command {
16
+ pub fn new(name: impl Into<String>) -> Self {
17
+ Self {
18
+ name: name.into(),
19
+ args: Vec::new(),
20
+ kwargs: HashMap::new(),
21
+ raw: String::new(),
22
+ }
23
+ }
24
+
25
+ pub fn with_arg(mut self, arg: impl Into<String>) -> Self {
26
+ self.args.push(arg.into());
27
+ self
28
+ }
29
+
30
+ pub fn with_kwarg(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
31
+ self.kwargs.insert(key.into(), value.into());
32
+ self
33
+ }
34
+
35
+ pub fn with_raw(mut self, raw: impl Into<String>) -> Self {
36
+ self.raw = raw.into();
37
+ self
38
+ }
39
+
40
+ /// Get the first argument or None
41
+ pub fn first_arg(&self) -> Option<&str> {
42
+ self.args.first().map(|s| s.as_str())
43
+ }
44
+
45
+ /// Check if a flag is present
46
+ pub fn has_flag(&self, flag: &str) -> bool {
47
+ self.kwargs.contains_key(flag) || self.args.contains(&flag.to_string())
48
+ }
49
+ }
50
+
51
+ /// Parse a command string into a Command struct
52
+ pub fn parse_command(input: &str) -> Option<Command> {
53
+ let input = input.trim();
54
+ if input.is_empty() {
55
+ return None;
56
+ }
57
+
58
+ let parts: Vec<&str> = input.split_whitespace().collect();
59
+ if parts.is_empty() {
60
+ return None;
61
+ }
62
+
63
+ let name = parts[0].to_string();
64
+ let mut args = Vec::new();
65
+ let mut kwargs = HashMap::new();
66
+
67
+ let mut i = 1;
68
+ while i < parts.len() {
69
+ let part = parts[i];
70
+
71
+ if part.starts_with("--") {
72
+ // Long flag
73
+ let key = part.trim_start_matches("--");
74
+ if let Some(eq_pos) = key.find('=') {
75
+ let (k, v) = key.split_at(eq_pos);
76
+ kwargs.insert(k.to_string(), v[1..].to_string());
77
+ } else if i + 1 < parts.len() && !parts[i + 1].starts_with('-') {
78
+ kwargs.insert(key.to_string(), parts[i + 1].to_string());
79
+ i += 1;
80
+ } else {
81
+ kwargs.insert(key.to_string(), "true".to_string());
82
+ }
83
+ } else if part.starts_with('-') && part.len() == 2 {
84
+ // Short flag
85
+ let key = part.trim_start_matches('-');
86
+ if i + 1 < parts.len() && !parts[i + 1].starts_with('-') {
87
+ kwargs.insert(key.to_string(), parts[i + 1].to_string());
88
+ i += 1;
89
+ } else {
90
+ kwargs.insert(key.to_string(), "true".to_string());
91
+ }
92
+ } else {
93
+ args.push(part.to_string());
94
+ }
95
+
96
+ i += 1;
97
+ }
98
+
99
+ Some(Command {
100
+ name,
101
+ args,
102
+ kwargs,
103
+ raw: input.to_string(),
104
+ })
105
+ }
106
+
107
+ /// Quote a string for shell usage
108
+ pub fn shell_quote(s: &str) -> String {
109
+ if s.contains(' ') || s.contains('\'') || s.contains('"') || s.contains('\\') {
110
+ format!("'{}'", s.replace('\'', "'\\''"))
111
+ } else {
112
+ s.to_string()
113
+ }
114
+ }
115
+
116
+ /// Check if a string needs quoting
117
+ pub fn should_quote(s: &str) -> bool {
118
+ s.contains(' ')
119
+ || s.contains('\'')
120
+ || s.contains('"')
121
+ || s.contains('\\')
122
+ || s.contains('$')
123
+ || s.contains('!')
124
+ || s.contains('*')
125
+ || s.contains('?')
126
+ }
127
+
128
+ /// Get the signature of a command
129
+ pub fn get_signature(name: &str, args: &[&str]) -> String {
130
+ let mut sig = name.to_string();
131
+ for arg in args {
132
+ sig.push(' ');
133
+ if arg.starts_with('[') || arg.starts_with('<') {
134
+ sig.push_str(arg);
135
+ } else {
136
+ sig.push_str(&format!("<{}>", arg));
137
+ }
138
+ }
139
+ sig
140
+ }
141
+
142
+ #[cfg(test)]
143
+ mod tests {
144
+ use super::*;
145
+
146
+ #[test]
147
+ fn test_parse_command() {
148
+ let cmd = parse_command("git commit -m message").unwrap();
149
+ assert_eq!(cmd.name, "git");
150
+ assert_eq!(cmd.args, vec!["commit"]);
151
+ assert_eq!(cmd.kwargs.get("m"), Some(&"message".to_string()));
152
+ }
153
+
154
+ #[test]
155
+ fn test_parse_command_with_flags() {
156
+ let cmd = parse_command("ls --color=auto").unwrap();
157
+ assert_eq!(cmd.name, "ls");
158
+ assert_eq!(cmd.kwargs.get("color"), Some(&"auto".to_string()));
159
+ }
160
+
161
+ #[test]
162
+ fn test_shell_quote() {
163
+ assert_eq!(shell_quote("simple"), "simple");
164
+ assert_eq!(shell_quote("with space"), "'with space'");
165
+ assert_eq!(shell_quote("with'quote"), "'with'\\''quote'");
166
+ }
167
+
168
+ #[test]
169
+ fn test_get_signature() {
170
+ let sig = get_signature("edit", &["file", "[start_line]", "[end_line]"]);
171
+ assert_eq!(sig, "edit <file> [start_line] [end_line]");
172
+ }
173
+ }