@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.
- package/LICENSE +21 -0
- package/README.md +270 -0
- package/package.json +71 -0
- package/python/LICENSE +21 -0
- package/python/config/README.md +15 -0
- package/python/config/bash_only.yaml +222 -0
- package/python/config/benchmarks/250212_sweagent_heavy_sbl.yaml +188 -0
- package/python/config/benchmarks/250225_anthropic_filemap_simple_review.yaml +75 -0
- package/python/config/benchmarks/250522_anthropic_filemap_simple_review.yaml +92 -0
- package/python/config/benchmarks/250526_anthropic_filemap_simple_review_sbl.yaml +93 -0
- package/python/config/benchmarks/anthropic_filemap_multilingual.yaml +66 -0
- package/python/config/coding_challenge.yaml +104 -0
- package/python/config/default.yaml +69 -0
- package/python/config/default_backticks.yaml +69 -0
- package/python/config/default_mm_no_images.yaml +82 -0
- package/python/config/default_mm_with_images.yaml +83 -0
- package/python/config/demo/default.yaml +80 -0
- package/python/config/demo/no_instructions.yaml +69 -0
- package/python/config/demo/only_bash.yaml +60 -0
- package/python/config/exotic/default_shell.yaml +52 -0
- package/python/config/exotic/windowed_replace.yaml +125 -0
- package/python/config/exotic/windowed_replace_late_repro.yaml +127 -0
- package/python/config/human/human.yaml +24 -0
- package/python/config/human/human_demo.yaml +52 -0
- package/python/config/sweagent_0_7/07.yaml +101 -0
- package/python/config/sweagent_0_7/07_fcalling.yaml +100 -0
- package/python/config/sweagent_0_7/07_from_url.yaml +114 -0
- package/python/config/sweagent_0_7/07_thought_action.yaml +102 -0
- package/python/config/sweagent_0_7/07_thought_action_xml.yaml +96 -0
- package/python/mlc_config.json +44 -0
- package/python/pyproject.toml +262 -0
- package/python/sweagent/__init__.py +114 -0
- package/python/sweagent/__main__.py +4 -0
- package/python/sweagent/agent/__init__.py +0 -0
- package/python/sweagent/agent/action_sampler.py +317 -0
- package/python/sweagent/agent/agents.py +1294 -0
- package/python/sweagent/agent/extra/shell_agent.py +106 -0
- package/python/sweagent/agent/history_processors.py +399 -0
- package/python/sweagent/agent/hooks/__init__.py +0 -0
- package/python/sweagent/agent/hooks/abstract.py +139 -0
- package/python/sweagent/agent/hooks/status.py +34 -0
- package/python/sweagent/agent/models.py +896 -0
- package/python/sweagent/agent/problem_statement.py +312 -0
- package/python/sweagent/agent/reviewer.py +664 -0
- package/python/sweagent/environment/__init__.py +0 -0
- package/python/sweagent/environment/hooks/__init__.py +0 -0
- package/python/sweagent/environment/hooks/abstract.py +60 -0
- package/python/sweagent/environment/hooks/status.py +28 -0
- package/python/sweagent/environment/repo.py +219 -0
- package/python/sweagent/environment/swe_env.py +276 -0
- package/python/sweagent/exceptions.py +54 -0
- package/python/sweagent/inspector/README.md +6 -0
- package/python/sweagent/inspector/__init__.py +0 -0
- package/python/sweagent/inspector/favicon.ico +0 -0
- package/python/sweagent/inspector/fileViewer.js +354 -0
- package/python/sweagent/inspector/icons/computer.png +0 -0
- package/python/sweagent/inspector/icons/edit_icon.svg +11 -0
- package/python/sweagent/inspector/icons/swe-agent-logo-50.png +0 -0
- package/python/sweagent/inspector/icons/swellama_blue.png +0 -0
- package/python/sweagent/inspector/icons/swellama_brown.png +0 -0
- package/python/sweagent/inspector/icons/swellama_grey.png +0 -0
- package/python/sweagent/inspector/icons/swellama_tan.png +0 -0
- package/python/sweagent/inspector/index.html +25 -0
- package/python/sweagent/inspector/server.py +354 -0
- package/python/sweagent/inspector/static.py +169 -0
- package/python/sweagent/inspector/style.css +454 -0
- package/python/sweagent/run/__init__.py +0 -0
- package/python/sweagent/run/_progress.py +158 -0
- package/python/sweagent/run/batch_instances.py +419 -0
- package/python/sweagent/run/common.py +387 -0
- package/python/sweagent/run/compare_runs.py +123 -0
- package/python/sweagent/run/extract_pred.py +19 -0
- package/python/sweagent/run/hooks/__init__.py +0 -0
- package/python/sweagent/run/hooks/abstract.py +67 -0
- package/python/sweagent/run/hooks/apply_patch.py +106 -0
- package/python/sweagent/run/hooks/open_pr.py +244 -0
- package/python/sweagent/run/hooks/swe_bench_evaluate.py +113 -0
- package/python/sweagent/run/inspector_cli.py +493 -0
- package/python/sweagent/run/merge_predictions.py +64 -0
- package/python/sweagent/run/quick_stats.py +96 -0
- package/python/sweagent/run/remove_unfinished.py +63 -0
- package/python/sweagent/run/rich_test.py +91 -0
- package/python/sweagent/run/run.py +147 -0
- package/python/sweagent/run/run_batch.py +442 -0
- package/python/sweagent/run/run_replay.py +219 -0
- package/python/sweagent/run/run_shell.py +155 -0
- package/python/sweagent/run/run_single.py +225 -0
- package/python/sweagent/run/run_traj_to_demo.py +85 -0
- package/python/sweagent/tools/__init__.py +0 -0
- package/python/sweagent/tools/bundle.py +57 -0
- package/python/sweagent/tools/commands.py +220 -0
- package/python/sweagent/tools/parsing.py +619 -0
- package/python/sweagent/tools/tools.py +430 -0
- package/python/sweagent/tools/utils.py +108 -0
- package/python/sweagent/types.py +102 -0
- package/python/sweagent/utils/__init__.py +0 -0
- package/python/sweagent/utils/config.py +80 -0
- package/python/sweagent/utils/files.py +27 -0
- package/python/sweagent/utils/github.py +118 -0
- package/python/sweagent/utils/jinja_warnings.py +14 -0
- package/python/sweagent/utils/log.py +175 -0
- package/python/sweagent/utils/patch_formatter.py +152 -0
- package/python/sweagent/utils/serialization.py +45 -0
- package/python/tests/__init__.py +0 -0
- package/python/tests/conftest.py +191 -0
- package/python/tests/test_agent.py +258 -0
- package/python/tests/test_batch_instance.py +43 -0
- package/python/tests/test_commands/_interactive_dummy.py +35 -0
- package/python/tests/test_commands/interactive_dummy_wrapper.sh +29 -0
- package/python/tests/test_data/config_files/dummy_interactive.yaml +62 -0
- package/python/tests/test_data/data_sources/ctf/crypto/Katy/Dockerfile +20 -0
- package/python/tests/test_data/data_sources/ctf/crypto/Katy/README.md +13 -0
- package/python/tests/test_data/data_sources/ctf/crypto/Katy/challenge.json +12 -0
- package/python/tests/test_data/data_sources/ctf/crypto/Katy/customrandom.c +50 -0
- package/python/tests/test_data/data_sources/ctf/crypto/Katy/docker-compose.yml +14 -0
- package/python/tests/test_data/data_sources/ctf/crypto/Katy/release +0 -0
- package/python/tests/test_data/data_sources/ctf/crypto/Katy/server +0 -0
- package/python/tests/test_data/data_sources/ctf/crypto/Katy/solver.py +12 -0
- package/python/tests/test_data/data_sources/ctf/forensics/flash/README.md +16 -0
- package/python/tests/test_data/data_sources/ctf/forensics/flash/challenge.json +9 -0
- package/python/tests/test_data/data_sources/ctf/forensics/flash/flash_c8429a430278283c0e571baebca3d139.zip +0 -0
- package/python/tests/test_data/data_sources/ctf/misc/networking_1/README.md +15 -0
- package/python/tests/test_data/data_sources/ctf/misc/networking_1/challenge.json +10 -0
- package/python/tests/test_data/data_sources/ctf/misc/networking_1/networking.pcap +0 -0
- package/python/tests/test_data/data_sources/ctf/pwn/warmup/Dockerfile +28 -0
- package/python/tests/test_data/data_sources/ctf/pwn/warmup/README.md +14 -0
- package/python/tests/test_data/data_sources/ctf/pwn/warmup/challenge.json +14 -0
- package/python/tests/test_data/data_sources/ctf/pwn/warmup/docker-compose.yml +14 -0
- package/python/tests/test_data/data_sources/ctf/pwn/warmup/flag.txt +1 -0
- package/python/tests/test_data/data_sources/ctf/pwn/warmup/warmup +0 -0
- package/python/tests/test_data/data_sources/ctf/pwn/warmup/warmup.c +26 -0
- package/python/tests/test_data/data_sources/ctf/pwn/warmup/warmup.py +9 -0
- package/python/tests/test_data/data_sources/ctf/rev/rock/README.md +14 -0
- package/python/tests/test_data/data_sources/ctf/rev/rock/challenge.json +8 -0
- package/python/tests/test_data/data_sources/ctf/rev/rock/rock +0 -0
- package/python/tests/test_data/data_sources/ctf/rev/rock/rock.cpp +167 -0
- package/python/tests/test_data/data_sources/ctf/rev/rock/solution.cpp +24 -0
- package/python/tests/test_data/data_sources/ctf/rev/rock/test_solver/solution.py +6 -0
- package/python/tests/test_data/data_sources/ctf/rev/rock/test_solver/test.sh +10 -0
- package/python/tests/test_data/data_sources/ctf/web/i_got_id_demo/000-default.conf +18 -0
- package/python/tests/test_data/data_sources/ctf/web/i_got_id_demo/Dockerfile +20 -0
- package/python/tests/test_data/data_sources/ctf/web/i_got_id_demo/cgi/file.pl +38 -0
- package/python/tests/test_data/data_sources/ctf/web/i_got_id_demo/cgi/forms.pl +40 -0
- package/python/tests/test_data/data_sources/ctf/web/i_got_id_demo/cgi/hello.pl +11 -0
- package/python/tests/test_data/data_sources/ctf/web/i_got_id_demo/challenge.json +12 -0
- package/python/tests/test_data/data_sources/ctf/web/i_got_id_demo/docker-compose.yml +14 -0
- package/python/tests/test_data/data_sources/ctf/web/i_got_id_demo/flag +1 -0
- package/python/tests/test_data/data_sources/ctf/web/i_got_id_demo/index.html +11 -0
- package/python/tests/test_data/data_sources/ctf/web/i_got_id_demo/solution.txt +1 -0
- package/python/tests/test_data/data_sources/debug_20240322.json +1 -0
- package/python/tests/test_data/data_sources/expert_instances.yaml +16 -0
- package/python/tests/test_data/data_sources/human_eval.json +1 -0
- package/python/tests/test_data/data_sources/simple_instances.yaml +3 -0
- package/python/tests/test_data/data_sources/simple_instances_long.yaml +30 -0
- package/python/tests/test_data/data_sources/swe-bench-dev-easy.json +1 -0
- package/python/tests/test_data/data_sources/swe-bench-dev-easy_first_only.json +1 -0
- package/python/tests/test_data/data_sources/swe-bench-lite-test.json +1 -0
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- package/python/tests/test_env.py +66 -0
- package/python/tests/test_env_utils.py +129 -0
- package/python/tests/test_history_processors.py +40 -0
- package/python/tests/test_models.py +23 -0
- package/python/tests/test_openai_live.py +164 -0
- package/python/tests/test_packaging.py +7 -0
- package/python/tests/test_parsing.py +131 -0
- package/python/tests/test_problem_statement_multimodal.py +111 -0
- package/python/tests/test_quick_stats.py +42 -0
- package/python/tests/test_run.py +37 -0
- package/python/tests/test_run_batch.py +110 -0
- package/python/tests/test_run_hooks.py +114 -0
- package/python/tests/test_run_replay.py +33 -0
- package/python/tests/test_run_single.py +125 -0
- package/python/tests/test_tools_command_parsing.py +193 -0
- package/python/tests/test_utils.py +15 -0
- package/python/tests/tools/__init__.py +0 -0
- package/python/tests/tools/conftest.py +12 -0
- package/python/tests/tools/test_default_utils.py +153 -0
- package/python/tests/tools/test_edit_replace.py +0 -0
- package/python/tests/tools/test_split_string.py +82 -0
- package/python/tests/utils.py +29 -0
- package/python/tools/diff_state/bin/_state_diff_state +52 -0
- package/python/tools/diff_state/config.yaml +2 -0
- package/python/tools/edit_anthropic/bin/_state_anthropic +21 -0
- package/python/tools/edit_anthropic/bin/str_replace_editor +710 -0
- package/python/tools/edit_anthropic/config.yaml +56 -0
- package/python/tools/edit_anthropic/install.sh +3 -0
- package/python/tools/filemap/bin/filemap +45 -0
- package/python/tools/filemap/config.yaml +9 -0
- package/python/tools/filemap/install.sh +2 -0
- package/python/tools/forfeit/bin/exit_forfeit +5 -0
- package/python/tools/forfeit/config.yaml +5 -0
- package/python/tools/image_tools/bin/view_image +36 -0
- package/python/tools/image_tools/config.yaml +9 -0
- package/python/tools/multilingual_setup/bin/do_nothing +2 -0
- package/python/tools/multilingual_setup/config.yaml +1 -0
- package/python/tools/multilingual_setup/install.sh +45 -0
- package/python/tools/registry/bin/_read_env +10 -0
- package/python/tools/registry/bin/_write_env +10 -0
- package/python/tools/registry/config.yaml +1 -0
- package/python/tools/registry/install.sh +6 -0
- package/python/tools/registry/lib/__init__.py +0 -0
- package/python/tools/registry/lib/registry.py +56 -0
- package/python/tools/review_on_submit_m/README.md +6 -0
- package/python/tools/review_on_submit_m/bin/submit +54 -0
- package/python/tools/review_on_submit_m/config.yaml +6 -0
- package/python/tools/review_on_submit_m/install.sh +0 -0
- package/python/tools/search/bin/find_file +31 -0
- package/python/tools/search/bin/search_dir +39 -0
- package/python/tools/search/bin/search_file +55 -0
- package/python/tools/search/config.yaml +37 -0
- package/python/tools/search/install.sh +3 -0
- package/python/tools/submit/bin/submit +17 -0
- package/python/tools/submit/config.yaml +5 -0
- package/python/tools/web_browser/bin/click_mouse +41 -0
- package/python/tools/web_browser/bin/close_site +28 -0
- package/python/tools/web_browser/bin/double_click_mouse +37 -0
- package/python/tools/web_browser/bin/drag_mouse +46 -0
- package/python/tools/web_browser/bin/execute_script_on_page +39 -0
- package/python/tools/web_browser/bin/get_console_output +48 -0
- package/python/tools/web_browser/bin/move_mouse +35 -0
- package/python/tools/web_browser/bin/navigate_back +33 -0
- package/python/tools/web_browser/bin/navigate_forward +33 -0
- package/python/tools/web_browser/bin/open_site +36 -0
- package/python/tools/web_browser/bin/press_keys_on_page +51 -0
- package/python/tools/web_browser/bin/reload_page +33 -0
- package/python/tools/web_browser/bin/run_web_browser_server +394 -0
- package/python/tools/web_browser/bin/screenshot_site +38 -0
- package/python/tools/web_browser/bin/scroll_on_page +40 -0
- package/python/tools/web_browser/bin/set_browser_window_size +40 -0
- package/python/tools/web_browser/bin/type_text +34 -0
- package/python/tools/web_browser/bin/wait_time +39 -0
- package/python/tools/web_browser/config.yaml +155 -0
- package/python/tools/web_browser/install.sh +22 -0
- package/python/tools/web_browser/lib/browser_manager.py +404 -0
- package/python/tools/web_browser/lib/web_browser_config.py +33 -0
- package/python/tools/web_browser/lib/web_browser_utils.py +126 -0
- package/python/tools/web_browser/test_console.html +1 -0
- package/python/tools/windowed/bin/_state +25 -0
- package/python/tools/windowed/bin/create +29 -0
- package/python/tools/windowed/bin/goto +37 -0
- package/python/tools/windowed/bin/open +49 -0
- package/python/tools/windowed/bin/scroll_down +12 -0
- package/python/tools/windowed/bin/scroll_up +13 -0
- package/python/tools/windowed/config.yaml +38 -0
- package/python/tools/windowed/install.sh +15 -0
- package/python/tools/windowed/lib/__init__.py +0 -0
- package/python/tools/windowed/lib/flake8_utils.py +147 -0
- package/python/tools/windowed/lib/windowed_file.py +312 -0
- package/python/tools/windowed_edit_linting/bin/edit +128 -0
- package/python/tools/windowed_edit_linting/config.yaml +31 -0
- package/python/tools/windowed_edit_linting/install.sh +5 -0
- package/python/tools/windowed_edit_replace/bin/edit +172 -0
- package/python/tools/windowed_edit_replace/bin/insert +77 -0
- package/python/tools/windowed_edit_replace/config.yaml +60 -0
- package/python/tools/windowed_edit_replace/install.sh +5 -0
- package/python/tools/windowed_edit_rewrite/bin/edit +78 -0
- package/python/tools/windowed_edit_rewrite/config.yaml +11 -0
- package/python/tools/windowed_edit_rewrite/install.sh +5 -0
- package/python/trajectories/demonstrations/ctf/crypto/BabyEncryption.traj +318 -0
- package/python/trajectories/demonstrations/ctf/crypto/BabyTimeCapsule.traj +197 -0
- package/python/trajectories/demonstrations/ctf/crypto/eps.traj +289 -0
- package/python/trajectories/demonstrations/ctf/crypto/katy.traj +368 -0
- package/python/trajectories/demonstrations/ctf/forensics/flash.traj +102 -0
- package/python/trajectories/demonstrations/ctf/misc/networking_1.traj +102 -0
- package/python/trajectories/demonstrations/ctf/pwn/warmup.traj +159 -0
- package/python/trajectories/demonstrations/ctf/rev/rock.traj +251 -0
- package/python/trajectories/demonstrations/ctf/web/i_got_id_demo.traj +422 -0
- package/python/trajectories/demonstrations/function_calling_simple.traj +151 -0
- 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
- 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
- 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
- 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
- package/python/trajectories/demonstrations/replay__marshmallow-code__marshmallow-1867__function_calling__install-1/marshmallow-code__marshmallow-1867.traj +594 -0
- package/python/trajectories/demonstrations/replay__marshmallow-code__marshmallow-1867__function_calling_replace__install-1/marshmallow-code__marshmallow-1867.traj +592 -0
- package/python/trajectories/demonstrations/replay__marshmallow-code__marshmallow-1867__function_calling_replace_from_source/marshmallow-code__marshmallow-1867.traj +3316 -0
- 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
- 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
- package/python/trajectories/demonstrations/str_replace_anthropic_demo.yaml +432 -0
- package/rust/Cargo.toml +100 -0
- package/rust/README.md +49 -0
- package/rust/src/agent/action_sampler.rs +130 -0
- package/rust/src/agent/agents.rs +1029 -0
- package/rust/src/agent/history_processors.rs +277 -0
- package/rust/src/agent/hooks/mod.rs +208 -0
- package/rust/src/agent/mod.rs +24 -0
- package/rust/src/agent/models.rs +837 -0
- package/rust/src/agent/problem_statement.rs +355 -0
- package/rust/src/agent/reviewer.rs +505 -0
- package/rust/src/bin/sweagent.rs +784 -0
- package/rust/src/environment/deployment.rs +631 -0
- package/rust/src/environment/hooks/mod.rs +114 -0
- package/rust/src/environment/mod.rs +16 -0
- package/rust/src/environment/repo.rs +265 -0
- package/rust/src/environment/runtime.rs +237 -0
- package/rust/src/environment/swe_env.rs +248 -0
- package/rust/src/exceptions.rs +228 -0
- package/rust/src/lib.rs +68 -0
- package/rust/src/monitoring.rs +482 -0
- package/rust/src/run/hooks/mod.rs +134 -0
- package/rust/src/run/mod.rs +12 -0
- package/rust/src/run/run_batch.rs +563 -0
- package/rust/src/run/run_single.rs +196 -0
- package/rust/src/tools/bundle.rs +224 -0
- package/rust/src/tools/commands.rs +173 -0
- package/rust/src/tools/mod.rs +295 -0
- package/rust/src/tools/parsing.rs +354 -0
- package/rust/src/tools/registry.rs +143 -0
- package/rust/src/types.rs +554 -0
- package/rust/src/utils/config.rs +105 -0
- package/rust/src/utils/files.rs +137 -0
- package/rust/src/utils/github.rs +171 -0
- package/rust/src/utils/log.rs +65 -0
- package/rust/src/utils/mod.rs +17 -0
- package/rust/src/utils/serialization.rs +181 -0
- package/rust/src/utils/template.rs +173 -0
- package/typescript/README.md +335 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import base64
|
|
4
|
+
import functools
|
|
5
|
+
import sys
|
|
6
|
+
from enum import Enum
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
import requests
|
|
10
|
+
from flask import jsonify, request
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ScreenshotMode(Enum):
|
|
14
|
+
SAVE = "save" # saves screenshot to png file
|
|
15
|
+
PRINT = "print" # prints base64 encoded screenshot to stdout
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def normalize_url(url: str) -> str:
|
|
19
|
+
# if starts with http:// or https://, return as is
|
|
20
|
+
# if starts with file://, return as is
|
|
21
|
+
# elif local file path exists, return as file://
|
|
22
|
+
# else: return as https://
|
|
23
|
+
if any(url.startswith(prefix) for prefix in ["http://", "https://", "file://"]):
|
|
24
|
+
return url
|
|
25
|
+
elif Path(url).exists():
|
|
26
|
+
return f"file://{Path(url).resolve()}"
|
|
27
|
+
else:
|
|
28
|
+
return "https://" + url
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def validate_request(*required_keys):
|
|
32
|
+
"""Decorator to validate that all required keys are present in request JSON."""
|
|
33
|
+
|
|
34
|
+
def decorator(func):
|
|
35
|
+
@functools.wraps(func)
|
|
36
|
+
def wrapper(*args, **kwargs):
|
|
37
|
+
if not request.is_json:
|
|
38
|
+
return jsonify({"status": "error", "message": "Request must be JSON"})
|
|
39
|
+
|
|
40
|
+
request_data = request.get_json()
|
|
41
|
+
if not request_data:
|
|
42
|
+
return jsonify({"status": "error", "message": "Request body cannot be empty"})
|
|
43
|
+
|
|
44
|
+
missing_keys = [key for key in required_keys if key not in request_data]
|
|
45
|
+
if missing_keys:
|
|
46
|
+
return jsonify({"status": "error", "message": f"Missing required fields: {', '.join(missing_keys)}"})
|
|
47
|
+
|
|
48
|
+
return func(*args, **kwargs)
|
|
49
|
+
|
|
50
|
+
return wrapper
|
|
51
|
+
|
|
52
|
+
return decorator
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def catch_error(func):
|
|
56
|
+
"""Decorator to catch exceptions and return them as JSON."""
|
|
57
|
+
|
|
58
|
+
@functools.wraps(func)
|
|
59
|
+
def wrapper(*args, **kwargs):
|
|
60
|
+
try:
|
|
61
|
+
return func(*args, **kwargs)
|
|
62
|
+
except Exception as e:
|
|
63
|
+
return jsonify({"status": "error", "message": str(e)})
|
|
64
|
+
|
|
65
|
+
return wrapper
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _print_error(message, error_type="ERROR"):
|
|
69
|
+
"""Print error message in a normalized format."""
|
|
70
|
+
print(f"{error_type}: {message}", file=sys.stderr)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _format_metadata_info(response):
|
|
74
|
+
"""Format metadata information from API response for display."""
|
|
75
|
+
if "metadata" not in response or not response["metadata"]:
|
|
76
|
+
return ""
|
|
77
|
+
return "\n".join(f"{key}: {value}" for key, value in response["metadata"].items())
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def send_request(port, endpoint, method="GET", data=None):
|
|
81
|
+
url = f"http://localhost:{port}/{endpoint}"
|
|
82
|
+
if method == "GET":
|
|
83
|
+
response = requests.get(url)
|
|
84
|
+
else:
|
|
85
|
+
response = requests.post(url, json=data)
|
|
86
|
+
if response.status_code != 200:
|
|
87
|
+
_print_error(f"Internal error communicating with backend: {response.text}", "INTERNAL ERROR")
|
|
88
|
+
return None
|
|
89
|
+
data = response.json()
|
|
90
|
+
if data["status"] == "error":
|
|
91
|
+
metadata_info = _format_metadata_info(data)
|
|
92
|
+
error_message = data["message"]
|
|
93
|
+
_print_error(f"ACTION ERROR:\n{error_message}")
|
|
94
|
+
if metadata_info:
|
|
95
|
+
print(f"\nMETADATA:\n{metadata_info}", file=sys.stderr)
|
|
96
|
+
return None
|
|
97
|
+
return data
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def _print_response_with_metadata(response):
|
|
101
|
+
"""Print response message with formatted metadata information."""
|
|
102
|
+
message = response.get("message", "")
|
|
103
|
+
metadata_info = _format_metadata_info(response)
|
|
104
|
+
print(f"ACTION RESPONSE:\n{message}")
|
|
105
|
+
|
|
106
|
+
if metadata_info:
|
|
107
|
+
print(f"\nMETADATA:\n{metadata_info}")
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _handle_screenshot(screenshot_data, mode):
|
|
111
|
+
"""Handle screenshot data according to the specified mode"""
|
|
112
|
+
if mode == ScreenshotMode.SAVE:
|
|
113
|
+
path = Path("latest_screenshot.png")
|
|
114
|
+
path.write_bytes(base64.b64decode(screenshot_data))
|
|
115
|
+
print(f"")
|
|
116
|
+
elif mode == ScreenshotMode.PRINT:
|
|
117
|
+
print(f"")
|
|
118
|
+
else:
|
|
119
|
+
message = f"Invalid screenshot mode: {mode}"
|
|
120
|
+
raise ValueError(message)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def _autosave_screenshot_from_response(response, mode):
|
|
124
|
+
"""Handle screenshot from response data according to the specified mode"""
|
|
125
|
+
if "screenshot" in response:
|
|
126
|
+
_handle_screenshot(response["screenshot"], mode)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<script>console.log("Hello from console!"); console.error("Test error"); console.warn("Test warning");</script><h1>Test Page</h1>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from registry import registry # type: ignore
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def main():
|
|
11
|
+
state_path = Path("/root/state.json")
|
|
12
|
+
|
|
13
|
+
if state_path.exists():
|
|
14
|
+
state = json.loads(state_path.read_text())
|
|
15
|
+
else:
|
|
16
|
+
state = {}
|
|
17
|
+
|
|
18
|
+
current_file = registry.get("CURRENT_FILE")
|
|
19
|
+
open_file = "n/a" if not current_file else str(Path(current_file).resolve())
|
|
20
|
+
state["open_file"] = open_file
|
|
21
|
+
state["working_dir"] = os.getcwd()
|
|
22
|
+
state_path.write_text(json.dumps(state))
|
|
23
|
+
|
|
24
|
+
if __name__ == "__main__":
|
|
25
|
+
main()
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import sys
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from windowed_file import WindowedFile # type: ignore
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def main():
|
|
9
|
+
if len(sys.argv) < 2:
|
|
10
|
+
print("Usage: create <filename>")
|
|
11
|
+
sys.exit(1)
|
|
12
|
+
|
|
13
|
+
path = Path(sys.argv[1])
|
|
14
|
+
if not path.parent.is_dir():
|
|
15
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
16
|
+
|
|
17
|
+
if path.exists():
|
|
18
|
+
print(f"Warning: File '{path}' already exists.")
|
|
19
|
+
sys.exit(1)
|
|
20
|
+
|
|
21
|
+
path.touch()
|
|
22
|
+
|
|
23
|
+
wfile = WindowedFile(path=path)
|
|
24
|
+
wfile.first_line = 0
|
|
25
|
+
wfile.print_window()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
if __name__ == "__main__":
|
|
29
|
+
main()
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import sys
|
|
3
|
+
from typing import List
|
|
4
|
+
|
|
5
|
+
from windowed_file import WindowedFile # type: ignore
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def main(args: List[str]) -> int:
|
|
9
|
+
if len(args) > 1:
|
|
10
|
+
print("goto allows only one line number at a time.")
|
|
11
|
+
return 1
|
|
12
|
+
|
|
13
|
+
if not args:
|
|
14
|
+
print("Usage: goto <line>")
|
|
15
|
+
return 1
|
|
16
|
+
|
|
17
|
+
try:
|
|
18
|
+
line_number = int(args[0])
|
|
19
|
+
except ValueError:
|
|
20
|
+
print("Usage: goto <line>")
|
|
21
|
+
print("Error: <line> must be a number")
|
|
22
|
+
return 1
|
|
23
|
+
|
|
24
|
+
wf = WindowedFile()
|
|
25
|
+
|
|
26
|
+
if line_number > wf.n_lines:
|
|
27
|
+
print(f"Error: <line> must be less than or equal to {wf.n_lines}")
|
|
28
|
+
return 1
|
|
29
|
+
|
|
30
|
+
# Convert from 1-based line numbers (user input) to 0-based (internal representation)
|
|
31
|
+
wf.goto(line_number - 1, mode="top")
|
|
32
|
+
wf.print_window()
|
|
33
|
+
return 0
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
if __name__ == "__main__":
|
|
37
|
+
sys.exit(main(sys.argv[1:]))
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import sys
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
from windowed_file import FileNotOpened, WindowedFile # type: ignore
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def main(path: Optional[str] = None, line_number: Optional[str] = None) -> None:
|
|
9
|
+
if path is None:
|
|
10
|
+
try:
|
|
11
|
+
WindowedFile(exit_on_exception=False).print_window()
|
|
12
|
+
# If this passes, then there was already a file open and we just show it again
|
|
13
|
+
sys.exit(0)
|
|
14
|
+
except FileNotOpened:
|
|
15
|
+
print('Usage: open "<file>"')
|
|
16
|
+
sys.exit(1)
|
|
17
|
+
|
|
18
|
+
assert path is not None
|
|
19
|
+
|
|
20
|
+
wf = WindowedFile(path=path)
|
|
21
|
+
|
|
22
|
+
if line_number is not None:
|
|
23
|
+
try:
|
|
24
|
+
line_num = int(line_number)
|
|
25
|
+
except ValueError:
|
|
26
|
+
print('Usage: open "<file>" [<line_number>]')
|
|
27
|
+
print("Error: <line_number> must be a number")
|
|
28
|
+
sys.exit(1)
|
|
29
|
+
if line_num > wf.n_lines:
|
|
30
|
+
print(f"Warning: <line_number> ({line_num}) is greater than the number of lines in the file ({wf.n_lines})")
|
|
31
|
+
print(f"Warning: Setting <line_number> to {wf.n_lines}")
|
|
32
|
+
line_num = wf.n_lines
|
|
33
|
+
elif line_num < 1:
|
|
34
|
+
print(f"Warning: <line_number> ({line_num}) is less than 1")
|
|
35
|
+
print("Warning: Setting <line_number> to 1")
|
|
36
|
+
line_num = 1
|
|
37
|
+
else:
|
|
38
|
+
# Default to middle of window if no line number provided
|
|
39
|
+
line_num = wf.first_line
|
|
40
|
+
|
|
41
|
+
wf.goto(line_num - 1, mode="top")
|
|
42
|
+
wf.print_window()
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
if __name__ == "__main__":
|
|
46
|
+
args = sys.argv[1:]
|
|
47
|
+
file_path = args[0] if args else None
|
|
48
|
+
line_number = args[1] if len(args) > 1 else None
|
|
49
|
+
main(file_path, line_number)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
tools:
|
|
2
|
+
goto:
|
|
3
|
+
signature: "goto <line_number>"
|
|
4
|
+
docstring: "moves the window to show <line_number>"
|
|
5
|
+
arguments:
|
|
6
|
+
- name: line_number
|
|
7
|
+
type: integer
|
|
8
|
+
description: "the line number to move the window to"
|
|
9
|
+
required: true
|
|
10
|
+
open:
|
|
11
|
+
signature: 'open "<path>" [<line_number>]'
|
|
12
|
+
docstring: "opens the file at the given path in the editor. If line_number is provided, the window will be move to include that line"
|
|
13
|
+
arguments:
|
|
14
|
+
- name: path
|
|
15
|
+
type: string
|
|
16
|
+
description: "the path to the file to open"
|
|
17
|
+
required: true
|
|
18
|
+
- name: line_number
|
|
19
|
+
type: integer
|
|
20
|
+
description: "the line number to move the window to (if not provided, the window will start at the top of the file)"
|
|
21
|
+
required: false
|
|
22
|
+
create:
|
|
23
|
+
signature: "create <filename>"
|
|
24
|
+
docstring: "creates and opens a new file with the given name"
|
|
25
|
+
arguments:
|
|
26
|
+
- name: filename
|
|
27
|
+
type: string
|
|
28
|
+
description: "the name of the file to create"
|
|
29
|
+
required: true
|
|
30
|
+
scroll_up:
|
|
31
|
+
signature: "scroll_up"
|
|
32
|
+
docstring: "moves the window up {WINDOW} lines"
|
|
33
|
+
arguments: []
|
|
34
|
+
scroll_down:
|
|
35
|
+
signature: "scroll_down"
|
|
36
|
+
docstring: "moves the window down {WINDOW} lines"
|
|
37
|
+
arguments: []
|
|
38
|
+
state_command: "_state"
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# script_dir=$(dirname "$(readlink -f "$0")")
|
|
4
|
+
bundle_dir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
|
5
|
+
|
|
6
|
+
export PYTHONPATH="$bundle_dir/lib":$PYTHONPATH
|
|
7
|
+
|
|
8
|
+
# Write default environment variables into the environment storage
|
|
9
|
+
_write_env "WINDOW" "${WINDOW:-100}"
|
|
10
|
+
_write_env "OVERLAP" "${OVERLAP:-2}"
|
|
11
|
+
_write_env "FIRST_LINE" "${FIRST_LINE:-0}"
|
|
12
|
+
_write_env "CURRENT_FILE" "${CURRENT_FILE:-}"
|
|
13
|
+
|
|
14
|
+
# install jq
|
|
15
|
+
# apt-get update && apt-get install -y jq
|
|
File without changes
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
"""This helper command is used to parse and print flake8 output."""
|
|
4
|
+
|
|
5
|
+
import subprocess
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
try:
|
|
9
|
+
from sweagent import TOOLS_DIR
|
|
10
|
+
except ImportError:
|
|
11
|
+
pass
|
|
12
|
+
else:
|
|
13
|
+
import sys
|
|
14
|
+
|
|
15
|
+
default_lib = TOOLS_DIR / "windowed" / "lib"
|
|
16
|
+
assert default_lib.is_dir()
|
|
17
|
+
sys.path.append(str(default_lib))
|
|
18
|
+
sys.path.append(str(TOOLS_DIR / "registry" / "lib"))
|
|
19
|
+
|
|
20
|
+
from registry import registry
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Flake8Error:
|
|
24
|
+
"""A class to represent a single flake8 error"""
|
|
25
|
+
|
|
26
|
+
def __init__(self, filename: str, line_number: int, col_number: int, problem: str):
|
|
27
|
+
self.filename = filename
|
|
28
|
+
self.line_number = line_number
|
|
29
|
+
self.col_number = col_number
|
|
30
|
+
self.problem = problem
|
|
31
|
+
|
|
32
|
+
@classmethod
|
|
33
|
+
def from_line(cls, line: str):
|
|
34
|
+
try:
|
|
35
|
+
prefix, _sep, problem = line.partition(": ")
|
|
36
|
+
filename, line_number, col_number = prefix.split(":")
|
|
37
|
+
except (ValueError, IndexError) as e:
|
|
38
|
+
msg = f"Invalid flake8 error line: {line}"
|
|
39
|
+
raise ValueError(msg) from e
|
|
40
|
+
return cls(filename, int(line_number), int(col_number), problem)
|
|
41
|
+
|
|
42
|
+
def __eq__(self, other):
|
|
43
|
+
if not isinstance(other, Flake8Error):
|
|
44
|
+
return NotImplemented
|
|
45
|
+
return (
|
|
46
|
+
self.filename == other.filename
|
|
47
|
+
and self.line_number == other.line_number
|
|
48
|
+
and self.col_number == other.col_number
|
|
49
|
+
and self.problem == other.problem
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
def __repr__(self):
|
|
53
|
+
return f"Flake8Error(filename={self.filename}, line_number={self.line_number}, col_number={self.col_number}, problem={self.problem})"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _update_previous_errors(
|
|
57
|
+
previous_errors: list[Flake8Error],
|
|
58
|
+
replacement_window: tuple[int, int],
|
|
59
|
+
replacement_n_lines: int,
|
|
60
|
+
) -> list[Flake8Error]:
|
|
61
|
+
"""Update the line numbers of the previous errors to what they would be after the edit window.
|
|
62
|
+
This is a helper function for `_filter_previous_errors`.
|
|
63
|
+
|
|
64
|
+
All previous errors that are inside of the edit window should not be ignored,
|
|
65
|
+
so they are removed from the previous errors list.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
previous_errors: list of errors with old line numbers
|
|
69
|
+
replacement_window: the window of the edit/lines that will be replaced
|
|
70
|
+
replacement_n_lines: the number of lines that will be used to replace the text
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
list of errors with updated line numbers
|
|
74
|
+
"""
|
|
75
|
+
updated = []
|
|
76
|
+
lines_added = replacement_n_lines - (replacement_window[1] - replacement_window[0] + 1)
|
|
77
|
+
for error in previous_errors:
|
|
78
|
+
if error.line_number < replacement_window[0]:
|
|
79
|
+
# no need to adjust the line number
|
|
80
|
+
updated.append(error)
|
|
81
|
+
continue
|
|
82
|
+
if replacement_window[0] <= error.line_number <= replacement_window[1]:
|
|
83
|
+
# The error is within the edit window, so let's not ignore it
|
|
84
|
+
# either way (we wouldn't know how to adjust the line number anyway)
|
|
85
|
+
continue
|
|
86
|
+
# We're out of the edit window, so we need to adjust the line number
|
|
87
|
+
updated.append(Flake8Error(error.filename, error.line_number + lines_added, error.col_number, error.problem))
|
|
88
|
+
return updated
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def format_flake8_output(
|
|
92
|
+
input_string: str,
|
|
93
|
+
show_line_numbers: bool = False,
|
|
94
|
+
*,
|
|
95
|
+
previous_errors_string: str = "",
|
|
96
|
+
replacement_window: tuple[int, int] | None = None,
|
|
97
|
+
replacement_n_lines: int | None = None,
|
|
98
|
+
) -> str:
|
|
99
|
+
"""Filter flake8 output for previous errors and print it for a given file.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
input_string: The flake8 output as a string
|
|
103
|
+
show_line_numbers: Whether to show line numbers in the output
|
|
104
|
+
previous_errors_string: The previous errors as a string
|
|
105
|
+
replacement_window: The window of the edit (lines that will be replaced)
|
|
106
|
+
replacement_n_lines: The number of lines used to replace the text
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
The filtered flake8 output as a string
|
|
110
|
+
"""
|
|
111
|
+
errors = [Flake8Error.from_line(line.strip()) for line in input_string.split("\n") if line.strip()]
|
|
112
|
+
# print(f"New errors before filtering: {errors=}")
|
|
113
|
+
lines = []
|
|
114
|
+
if previous_errors_string:
|
|
115
|
+
assert replacement_window is not None
|
|
116
|
+
assert replacement_n_lines is not None
|
|
117
|
+
previous_errors = [
|
|
118
|
+
Flake8Error.from_line(line.strip()) for line in previous_errors_string.split("\n") if line.strip()
|
|
119
|
+
]
|
|
120
|
+
# print(f"Previous errors before updating: {previous_errors=}")
|
|
121
|
+
previous_errors = _update_previous_errors(previous_errors, replacement_window, replacement_n_lines)
|
|
122
|
+
# print(f"Previous errors after updating: {previous_errors=}")
|
|
123
|
+
errors = [error for error in errors if error not in previous_errors]
|
|
124
|
+
# Sometimes new errors appear above the replacement window that were 'shadowed' by the previous errors
|
|
125
|
+
# they still clearly aren't caused by the edit.
|
|
126
|
+
errors = [error for error in errors if error.line_number >= replacement_window[0]]
|
|
127
|
+
# print(f"New errors after filtering: {errors=}")
|
|
128
|
+
for error in errors:
|
|
129
|
+
if not show_line_numbers:
|
|
130
|
+
lines.append(f"- {error.problem}")
|
|
131
|
+
else:
|
|
132
|
+
lines.append(f"- line {error.line_number} col {error.col_number}: {error.problem}")
|
|
133
|
+
return "\n".join(lines)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def flake8(file_path: str) -> str:
|
|
137
|
+
"""Run flake8 on a given file and return the output as a string"""
|
|
138
|
+
if Path(file_path).suffix != ".py":
|
|
139
|
+
return ""
|
|
140
|
+
cmd = registry.get("LINT_COMMAND", "flake8 --isolated --select=F821,F822,F831,E111,E112,E113,E999,E902 {file_path}")
|
|
141
|
+
out = subprocess.run(
|
|
142
|
+
cmd.format(file_path=file_path),
|
|
143
|
+
shell=True,
|
|
144
|
+
capture_output=True,
|
|
145
|
+
text=True,
|
|
146
|
+
)
|
|
147
|
+
return out.stdout
|