Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(agent): Introduce Python code execution as prompt strategy #7142

Open
wants to merge 24 commits into
base: master
Choose a base branch
from

Conversation

majdyz
Copy link
Contributor

@majdyz majdyz commented May 10, 2024

Background

Add support for executing agent steps by running Python code. This allows for more complicated composite function calls within each step of agent execution.

Changes πŸ—οΈ

  • Introduced a new PromptStrategy: CodeFlowAgentPromptStrategy under code_flow.py
  • Introduced a new utils.function package that handle a python code validation that utilize ruff & pyRight as the validation engines.
  • Set CodeFlowAgentPromptStrategy as the existing default strategy.

PR Quality Scorecard ✨

  • Have you used the PR description template?   +2 pts
  • Is your pull request atomic, focusing on a single change?   +5 pts
  • Have you linked the GitHub issue(s) that this PR addresses?   +5 pts
  • Have you documented your changes clearly and comprehensively?   +5 pts
  • Have you changed or added a feature?   -4 pts
    • Have you added/updated corresponding documentation?   +4 pts
    • Have you added/updated corresponding integration tests?   +5 pts
  • Have you changed the behavior of AutoGPT?   -5 pts
    • Have you also run agbenchmark to verify that these changes do not regress performance?   +10 pts

Copy link

netlify bot commented May 10, 2024

βœ… Deploy Preview for auto-gpt-docs canceled.

Name Link
πŸ”¨ Latest commit ae63aa8
πŸ” Latest deploy log https://app.netlify.com/sites/auto-gpt-docs/deploys/664b6ec9af92290008decd36

Copy link

codecov bot commented May 10, 2024

Codecov Report

Attention: Patch coverage is 86.66667% with 10 lines in your changes are missing coverage. Please review.

Project coverage is 24.08%. Comparing base (e8d7dfa) to head (ae63aa8).
Report is 2 commits behind head on master.

Files Patch % Lines
...ogpt/autogpt/agents/prompt_strategies/code_flow.py 87.69% 5 Missing and 3 partials ⚠️
autogpts/autogpt/autogpt/agents/agent.py 77.77% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #7142      +/-   ##
==========================================
+ Coverage   22.53%   24.08%   +1.54%     
==========================================
  Files          66       67       +1     
  Lines        2702     2774      +72     
  Branches      307      312       +5     
==========================================
+ Hits          609      668      +59     
- Misses       2060     2070      +10     
- Partials       33       36       +3     
Flag Coverage Ξ”
Linux 24.08% <86.66%> (+1.54%) ⬆️
Windows ?
autogpt-agent 24.08% <86.66%> (+1.54%) ⬆️
macOS 24.08% <86.66%> (+1.54%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

β˜” View full report in Codecov by Sentry.
πŸ“’ Have feedback on the report? Share it here.

@ntindle
Copy link
Member

ntindle commented May 10, 2024

Should this be in forge??

Copy link

codiumai-pr-agent-pro bot commented May 10, 2024

CI Failure Feedback 🧐

(Checks updated until commit ca7ca22)

Action: test (3.10, windows)

Failed stage: Run pytest with coverage [❌]

Failed test name: test_code_validation

Failure summary:

The action failed due to a PermissionError encountered when attempting to delete a temporary file
used during the test test_code_validation. The error message indicates that the file could not be
accessed because it was still being used by another process. This suggests an issue with file
handling or resource cleanup in the test or related utility functions.

Relevant error logs:
1:  ##[group]Operating System
2:  Microsoft Windows Server 2022
...

690:  tests/unit/test_local_file_storage.py::test_get_path_inaccessible[inaccessible_path4] 
691:  tests/unit/test_local_file_storage.py::test_get_path_inaccessible[inaccessible_path13] 
692:  [gw3] [ 23%] PASSED tests/unit/test_local_file_storage.py::test_get_path_inaccessible[inaccessible_path4] 
693:  [gw2] [ 23%] PASSED tests/unit/test_local_file_storage.py::test_get_path_inaccessible[inaccessible_path13] 
694:  [gw1] [ 24%] PASSED tests/unit/test_config.py::test_create_config_gpt4only 
695:  tests/unit/test_local_file_storage.py::test_get_path_inaccessible[inaccessible_path5] 
696:  tests/unit/test_local_file_storage.py::test_get_path_inaccessible[inaccessible_path14] 
697:  tests/unit/test_config.py::test_create_config_gpt3only 
698:  [gw0] [ 24%] FAILED tests/unit/test_function_code_validation.py::test_code_validation 
...

723:  tests/unit/test_logs.py::test_remove_color_codes[-] 
724:  [gw2] [ 29%] PASSED tests/unit/test_logs.py::test_remove_color_codes[-] 
725:  tests/unit/test_logs.py::test_remove_color_codes[hello-hello] 
726:  [gw2] [ 30%] PASSED tests/unit/test_logs.py::test_remove_color_codes[hello-hello] 
727:  tests/unit/test_logs.py::test_remove_color_codes[hello\x1b[31m world-hello world] 
728:  [gw2] [ 30%] PASSED tests/unit/test_logs.py::test_remove_color_codes[hello\x1b[31m world-hello world] 
729:  tests/unit/test_url_validation.py::test_url_validation_succeeds[http://a.lot.of.domain.net/param1/param2] 
730:  [gw2] [ 31%] PASSED tests/unit/test_url_validation.py::test_url_validation_succeeds[http://a.lot.of.domain.net/param1/param2] 
731:  tests/unit/test_url_validation.py::test_url_validation_fails_invalid_url[htt://example.com-Invalid URL format] 
732:  [gw1] [ 31%] PASSED tests/unit/test_file_operations.py::test_read_file 
733:  [gw2] [ 32%] PASSED tests/unit/test_url_validation.py::test_url_validation_fails_invalid_url[htt://example.com-Invalid URL format] 
734:  tests/unit/test_file_operations.py::test_read_file_not_found 
735:  tests/unit/test_url_validation.py::test_url_validation_fails_invalid_url[httppp://example.com-Invalid URL format] 
736:  [gw0] [ 32%] PASSED tests/unit/test_git_commands.py::test_clone_auto_gpt_repository 
737:  tests/unit/test_git_commands.py::test_clone_repository_error 
738:  [gw2] [ 32%] PASSED tests/unit/test_url_validation.py::test_url_validation_fails_invalid_url[httppp://example.com-Invalid URL format] 
739:  tests/unit/test_url_validation.py::test_url_validation_fails_invalid_url[ https://example.com-Invalid URL format] 
740:  [gw2] [ 33%] PASSED tests/unit/test_url_validation.py::test_url_validation_fails_invalid_url[ https://example.com-Invalid URL format] 
741:  tests/unit/test_url_validation.py::test_url_validation_fails_invalid_url[http://?query=q-Missing Scheme or Network location] 
742:  [gw2] [ 33%] PASSED tests/unit/test_url_validation.py::test_url_validation_fails_invalid_url[http://?query=q-Missing Scheme or Network location] 
743:  tests/unit/test_url_validation.py::test_url_validation_fails_local_path[file://localhost] 
744:  [gw2] [ 34%] PASSED tests/unit/test_url_validation.py::test_url_validation_fails_local_path[file://localhost] 
745:  tests/unit/test_url_validation.py::test_url_validation_fails_local_path[file://localhost/home/reinier/secrets.txt] 
746:  [gw2] [ 34%] PASSED tests/unit/test_url_validation.py::test_url_validation_fails_local_path[file://localhost/home/reinier/secrets.txt] 
747:  tests/unit/test_url_validation.py::test_url_validation_fails_local_path[file:///home/reinier/secrets.txt] 
748:  [gw2] [ 35%] PASSED tests/unit/test_url_validation.py::test_url_validation_fails_local_path[file:///home/reinier/secrets.txt] 
749:  tests/unit/test_url_validation.py::test_url_validation_fails_local_path[file:///C:/Users/Reinier/secrets.txt] 
750:  [gw2] [ 35%] PASSED tests/unit/test_url_validation.py::test_url_validation_fails_local_path[file:///C:/Users/Reinier/secrets.txt] 
...

756:  [gw1] [ 36%] PASSED tests/unit/test_file_operations.py::test_read_file_not_found 
757:  [gw2] [ 37%] PASSED tests/unit/test_url_validation.py::test_general_behavior_additional_path_parameters_query_string 
758:  tests/unit/test_file_operations.py::test_write_to_file_relative_path 
759:  [gw3] [ 37%] PASSED tests/unit/test_text_file_parsers.py::test_parsers[.json-mock_json_file] 
760:  tests/unit/test_url_validation.py::test_edge_case_missing_scheme_or_network_location 
761:  tests/unit/test_text_file_parsers.py::test_parsers[.xml-mock_xml_file] 
762:  [gw2] [ 37%] PASSED tests/unit/test_url_validation.py::test_edge_case_missing_scheme_or_network_location 
763:  tests/unit/test_url_validation.py::test_edge_case_local_file_access 
764:  [gw0] [ 38%] PASSED tests/unit/test_git_commands.py::test_clone_repository_error 
...

809:  tests/unit/test_json_utils.py::test_json_loads_fixable[fixable_json10] 
810:  [gw2] [ 48%] PASSED tests/unit/test_utils.py::test_validate_yaml_file_not_found 
811:  tests/unit/test_utils.py::test_validate_yaml_file_invalid 
812:  [gw0] [ 48%] PASSED tests/unit/test_json_utils.py::test_json_loads_fixable[fixable_json10] 
813:  tests/unit/test_utils.py::test_extract_json_from_response_wrapped_in_code_block 
814:  [gw2] [ 48%] PASSED tests/unit/test_utils.py::test_validate_yaml_file_invalid 
815:  tests/unit/test_utils.py::test_get_bulletin_from_web_success 
816:  [gw2] [ 49%] PASSED tests/unit/test_utils.py::test_get_bulletin_from_web_success 
817:  tests/unit/test_utils.py::test_get_bulletin_from_web_failure 
818:  [gw0] [ 49%] PASSED tests/unit/test_utils.py::test_extract_json_from_response_wrapped_in_code_block 
819:  tests/unit/test_utils.py::test_extract_json_from_response_wrapped_in_code_block_with_language 
820:  [gw2] [ 50%] PASSED tests/unit/test_utils.py::test_get_bulletin_from_web_failure 
...

848:  [gw3] [ 56%] PASSED tests/unit/test_utils.py::test_get_latest_bulletin_with_new_bulletin 
849:  tests/unit/test_utils.py::test_get_latest_bulletin_new_bulletin_same_as_old_bulletin 
850:  [gw3] [ 56%] PASSED tests/unit/test_utils.py::test_get_latest_bulletin_new_bulletin_same_as_old_bulletin 
851:  tests/unit/test_utils.py::test_get_current_git_branch 
852:  [gw3] [ 56%] SKIPPED tests/unit/test_utils.py::test_get_current_git_branch 
853:  tests/unit/test_utils.py::test_get_current_git_branch_success 
854:  [gw3] [ 57%] PASSED tests/unit/test_utils.py::test_get_current_git_branch_success 
855:  [gw2] [ 57%] PASSED tests/unit/test_web_search.py::test_google_search[-1-expected_output_parts1-return_value1] 
856:  tests/unit/test_utils.py::test_get_current_git_branch_failure 
857:  tests/unit/test_web_search.py::test_google_search[no results-1-expected_output_parts2-return_value2] 
858:  [gw3] [ 58%] PASSED tests/unit/test_utils.py::test_get_current_git_branch_failure 
859:  tests/unit/test_utils.py::test_extract_json_from_response 
860:  [gw3] [ 58%] PASSED tests/unit/test_utils.py::test_extract_json_from_response 
861:  tests/integration/test_execute_code.py::test_execute_shell_local_commands_not_allowed 
862:  [gw1] [ 59%] PASSED tests/unit/test_file_operations.py::test_list_files 
863:  tests/unit/test_logs.py::test_remove_color_codes[\x1b[36mHello,\x1b[32m World!-Hello, World!] 
864:  [gw1] [ 59%] PASSED tests/unit/test_logs.py::test_remove_color_codes[\x1b[36mHello,\x1b[32m World!-Hello, World!] 
865:  [gw0] [ 59%] PASSED tests/unit/test_web_search.py::test_google_search[test-1-expected_output_parts0-return_value0] 
866:  tests/unit/test_logs.py::test_remove_color_codes[\x1b[1m\x1b[31mError:\x1b[0m\x1b[31m file not found-Error: file not found] 
867:  [gw1] [ 60%] PASSED tests/unit/test_logs.py::test_remove_color_codes[\x1b[1m\x1b[31mError:\x1b[0m\x1b[31m file not found-Error: file not found] 
...

911:  tests/integration/test_image_gen.py::test_sd_webui[256] 
912:  [gw0] [ 69%] XFAIL tests/integration/test_image_gen.py::test_huggingface[256-stabilityai/stable-diffusion-2-1] 
913:  tests/integration/test_image_gen.py::test_huggingface[512-CompVis/stable-diffusion-v1-4] 
914:  [gw3] [ 70%] XFAIL tests/integration/test_image_gen.py::test_sd_webui[256] 
915:  tests/integration/test_image_gen.py::test_sd_webui[512] 
916:  [gw0] [ 70%] XFAIL tests/integration/test_image_gen.py::test_huggingface[512-CompVis/stable-diffusion-v1-4] 
917:  tests/integration/test_image_gen.py::test_sd_webui[1024] 
918:  [gw3] [ 70%] XFAIL tests/integration/test_image_gen.py::test_sd_webui[512] 
919:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-10-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading"}] 
920:  [gw0] [ 71%] XFAIL tests/integration/test_image_gen.py::test_sd_webui[1024] 
921:  tests/integration/test_image_gen.py::test_sd_webui_negative_prompt[256] 
922:  [gw3] [ 71%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-10-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading"}] 
923:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-10-CompVis/stable-diffusion-v1-4-{"error:}] 
924:  [gw3] [ 72%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-10-CompVis/stable-diffusion-v1-4-{"error:}] 
925:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-10-CompVis/stable-diffusion-v1-4-] 
926:  [gw3] [ 72%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-10-CompVis/stable-diffusion-v1-4-] 
927:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-10-stabilityai/stable-diffusion-2-1-{"error":"Model [model] is currently loading","estimated_time": [delay]}] 
928:  [gw3] [ 72%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-10-stabilityai/stable-diffusion-2-1-{"error":"Model [model] is currently loading","estimated_time": [delay]}] 
929:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-10-stabilityai/stable-diffusion-2-1-{"error":"Model [model] is currently loading"}] 
930:  [gw3] [ 73%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-10-stabilityai/stable-diffusion-2-1-{"error":"Model [model] is currently loading"}] 
931:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-10-stabilityai/stable-diffusion-2-1-{"error:}] 
932:  [gw3] [ 73%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-10-stabilityai/stable-diffusion-2-1-{"error:}] 
933:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-10-stabilityai/stable-diffusion-2-1-] 
934:  [gw3] [ 74%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-10-stabilityai/stable-diffusion-2-1-] 
935:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-0-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading","estimated_time": [delay]}] 
936:  [gw3] [ 74%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-0-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading","estimated_time": [delay]}] 
937:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-0-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading"}] 
938:  [gw3] [ 75%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-0-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading"}] 
939:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-0-CompVis/stable-diffusion-v1-4-{"error:}] 
940:  [gw3] [ 75%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-0-CompVis/stable-diffusion-v1-4-{"error:}] 
941:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-0-CompVis/stable-diffusion-v1-4-] 
942:  [gw3] [ 75%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-0-CompVis/stable-diffusion-v1-4-] 
943:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-0-stabilityai/stable-diffusion-2-1-{"error":"Model [model] is currently loading","estimated_time": [delay]}] 
944:  [gw1] [ 76%] PASSED tests/unit/test_spinner.py::test_spinner_stops_spinning 
945:  tests/unit/test_spinner.py::test_spinner_can_be_used_as_context_manager 
946:  [gw3] [ 76%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-0-stabilityai/stable-diffusion-2-1-{"error":"Model [model] is currently loading","estimated_time": [delay]}] 
947:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-0-stabilityai/stable-diffusion-2-1-{"error":"Model [model] is currently loading"}] 
948:  [gw3] [ 77%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-0-stabilityai/stable-diffusion-2-1-{"error":"Model [model] is currently loading"}] 
949:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-0-stabilityai/stable-diffusion-2-1-{"error:}] 
950:  [gw3] [ 77%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-0-stabilityai/stable-diffusion-2-1-{"error:}] 
951:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-0-stabilityai/stable-diffusion-2-1-] 
952:  [gw1] [ 78%] PASSED tests/unit/test_spinner.py::test_spinner_can_be_used_as_context_manager 
953:  tests/unit/test_text_file_parsers.py::test_parsers[.txt-mock_text_file] 
954:  [gw1] [ 78%] PASSED tests/unit/test_text_file_parsers.py::test_parsers[.txt-mock_text_file] 
955:  tests/unit/test_text_file_parsers.py::test_parsers[.csv-mock_csv_file] 
956:  [gw1] [ 78%] PASSED tests/unit/test_text_file_parsers.py::test_parsers[.csv-mock_csv_file] 
957:  tests/unit/test_text_file_parsers.py::test_parsers[.pdf-mock_pdf_file] 
958:  [gw3] [ 79%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-0-stabilityai/stable-diffusion-2-1-] 
959:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-10-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading","estimated_time": [delay]}] 
960:  [gw3] [ 79%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-10-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading","estimated_time": [delay]}] 
961:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-10-stabilityai/stable-diffusion-2-1-{"error":"Model [model] is currently loading","estimated_time": [delay]}] 
962:  [gw3] [ 80%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-10-stabilityai/stable-diffusion-2-1-{"error":"Model [model] is currently loading","estimated_time": [delay]}] 
963:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-10-stabilityai/stable-diffusion-2-1-{"error":"Model [model] is currently loading"}] 
964:  [gw3] [ 80%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-10-stabilityai/stable-diffusion-2-1-{"error":"Model [model] is currently loading"}] 
965:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-10-stabilityai/stable-diffusion-2-1-{"error:}] 
966:  [gw3] [ 81%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-10-stabilityai/stable-diffusion-2-1-{"error:}] 
967:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-10-stabilityai/stable-diffusion-2-1-] 
968:  [gw3] [ 81%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-10-stabilityai/stable-diffusion-2-1-] 
969:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-0-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading","estimated_time": [delay]}] 
970:  [gw1] [ 81%] PASSED tests/unit/test_text_file_parsers.py::test_parsers[.pdf-mock_pdf_file] 
971:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-10-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading"}] 
972:  [gw3] [ 82%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-0-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading","estimated_time": [delay]}] 
973:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-0-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading"}] 
974:  [gw3] [ 82%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-0-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading"}] 
975:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-0-CompVis/stable-diffusion-v1-4-{"error:}] 
976:  [gw1] [ 83%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-10-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading"}] 
977:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-10-CompVis/stable-diffusion-v1-4-{"error:}] 
978:  [gw3] [ 83%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-0-CompVis/stable-diffusion-v1-4-{"error:}] 
979:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-0-CompVis/stable-diffusion-v1-4-] 
980:  [gw1] [ 83%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-10-CompVis/stable-diffusion-v1-4-{"error:}] 
981:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-10-CompVis/stable-diffusion-v1-4-] 
982:  [gw3] [ 84%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-0-CompVis/stable-diffusion-v1-4-] 
983:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-0-stabilityai/stable-diffusion-2-1-{"error":"Model [model] is currently loading","estimated_time": [delay]}] 
984:  [gw3] [ 84%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-0-stabilityai/stable-diffusion-2-1-{"error":"Model [model] is currently loading","estimated_time": [delay]}] 
985:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-0-stabilityai/stable-diffusion-2-1-{"error":"Model [model] is currently loading"}] 
986:  [gw3] [ 85%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-0-stabilityai/stable-diffusion-2-1-{"error":"Model [model] is currently loading"}] 
987:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-10-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading","estimated_time": [delay]}] 
988:  [gw1] [ 85%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-10-CompVis/stable-diffusion-v1-4-] 
989:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-0-stabilityai/stable-diffusion-2-1-{"error:}] 
990:  [gw3] [ 86%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-10-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading","estimated_time": [delay]}] 
991:  [gw1] [ 86%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-0-stabilityai/stable-diffusion-2-1-{"error:}] 
992:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-10-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading"}] 
993:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-0-stabilityai/stable-diffusion-2-1-] 
994:  [gw1] [ 86%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[512-0-stabilityai/stable-diffusion-2-1-] 
995:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-10-CompVis/stable-diffusion-v1-4-] 
996:  [gw3] [ 87%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-10-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading"}] 
997:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-10-CompVis/stable-diffusion-v1-4-{"error:}] 
998:  [gw1] [ 87%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-10-CompVis/stable-diffusion-v1-4-] 
999:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-10-stabilityai/stable-diffusion-2-1-{"error":"Model [model] is currently loading","estimated_time": [delay]}] 
1000:  [gw3] [ 88%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-10-CompVis/stable-diffusion-v1-4-{"error:}] 
1001:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-10-stabilityai/stable-diffusion-2-1-{"error":"Model [model] is currently loading"}] 
1002:  [gw1] [ 88%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-10-stabilityai/stable-diffusion-2-1-{"error":"Model [model] is currently loading","estimated_time": [delay]}] 
1003:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-10-stabilityai/stable-diffusion-2-1-{"error:}] 
1004:  [gw3] [ 89%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-10-stabilityai/stable-diffusion-2-1-{"error":"Model [model] is currently loading"}] 
1005:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-10-stabilityai/stable-diffusion-2-1-] 
1006:  [gw1] [ 89%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-10-stabilityai/stable-diffusion-2-1-{"error:}] 
1007:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-0-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading","estimated_time": [delay]}] 
1008:  [gw3] [ 89%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-10-stabilityai/stable-diffusion-2-1-] 
1009:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-0-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading"}] 
1010:  [gw1] [ 90%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-0-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading","estimated_time": [delay]}] 
1011:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-0-CompVis/stable-diffusion-v1-4-{"error:}] 
1012:  [gw3] [ 90%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-0-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading"}] 
1013:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-0-CompVis/stable-diffusion-v1-4-] 
1014:  [gw1] [ 91%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-0-CompVis/stable-diffusion-v1-4-{"error:}] 
1015:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-0-stabilityai/stable-diffusion-2-1-{"error":"Model [model] is currently loading","estimated_time": [delay]}] 
1016:  [gw3] [ 91%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-0-CompVis/stable-diffusion-v1-4-] 
1017:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-0-stabilityai/stable-diffusion-2-1-{"error":"Model [model] is currently loading"}] 
1018:  [gw3] [ 91%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-0-stabilityai/stable-diffusion-2-1-{"error":"Model [model] is currently loading"}] 
1019:  [gw1] [ 92%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-0-stabilityai/stable-diffusion-2-1-{"error":"Model [model] is currently loading","estimated_time": [delay]}] 
1020:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-0-stabilityai/stable-diffusion-2-1-] 
1021:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-0-stabilityai/stable-diffusion-2-1-{"error:}] 
1022:  [gw1] [ 92%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-0-stabilityai/stable-diffusion-2-1-{"error:}] 
1023:  [gw3] [ 93%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[1024-0-stabilityai/stable-diffusion-2-1-] 
1024:  tests/integration/test_image_gen.py::test_huggingface_fail_request_bad_json 
1025:  tests/integration/test_image_gen.py::test_huggingface_fail_request_no_delay 
1026:  [gw1] [ 93%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_bad_json 
1027:  tests/integration/test_image_gen.py::test_huggingface_fail_request_bad_image 
1028:  [gw3] [ 94%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_no_delay 
1029:  tests/integration/test_image_gen.py::test_huggingface_fail_missing_api_token 
1030:  [gw1] [ 94%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_bad_image 
1031:  tests/integration/test_setup.py::test_apply_overrides_to_ai_settings 
1032:  [gw1] [ 94%] PASSED tests/integration/test_setup.py::test_apply_overrides_to_ai_settings 
1033:  tests/integration/test_web_selenium.py::test_browse_website_nonexistent_url 
1034:  [gw3] [ 95%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_missing_api_token 
1035:  tests/integration/test_setup.py::test_interactively_revise_ai_settings 
1036:  [gw3] [ 95%] PASSED tests/integration/test_setup.py::test_interactively_revise_ai_settings 
1037:  [gw2] [ 96%] PASSED tests/unit/test_web_search.py::test_google_search[no results-1-expected_output_parts2-return_value2] 
1038:  tests/unit/test_web_search.py::test_google_official_search[test-3-search_results0-expected_output0] 
1039:  [gw2] [ 96%] PASSED tests/unit/test_web_search.py::test_google_official_search[test-3-search_results0-expected_output0] 
1040:  tests/unit/test_web_search.py::test_google_official_search[-3-search_results1-expected_output1] 
1041:  [gw2] [ 97%] PASSED tests/unit/test_web_search.py::test_google_official_search[-3-search_results1-expected_output1] 
1042:  tests/unit/test_web_search.py::test_google_official_search_errors[invalid query-3-HttpError-400-Invalid Value] 
1043:  [gw2] [ 97%] PASSED tests/unit/test_web_search.py::test_google_official_search_errors[invalid query-3-HttpError-400-Invalid Value] 
1044:  tests/unit/test_web_search.py::test_google_official_search_errors[invalid API key-3-ConfigurationError-403-invalid API key] 
1045:  [gw2] [ 97%] PASSED tests/unit/test_web_search.py::test_google_official_search_errors[invalid API key-3-ConfigurationError-403-invalid API key] 
1046:  [gw0] [ 98%] XFAIL tests/integration/test_image_gen.py::test_sd_webui_negative_prompt[256] 
1047:  tests/integration/test_image_gen.py::test_sd_webui_negative_prompt[512] 
1048:  [gw0] [ 98%] XFAIL tests/integration/test_image_gen.py::test_sd_webui_negative_prompt[512] 
1049:  tests/integration/test_image_gen.py::test_sd_webui_negative_prompt[1024] 
1050:  [gw0] [ 99%] XFAIL tests/integration/test_image_gen.py::test_sd_webui_negative_prompt[1024] 
1051:  tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-10-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading","estimated_time": [delay]}] 
1052:  [gw0] [ 99%] PASSED tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-10-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading","estimated_time": [delay]}] 
1053:  [gw1] [100%] PASSED tests/integration/test_web_selenium.py::test_browse_website_nonexistent_url 
1054:  ================================== FAILURES ===================================
1055:  ____________________________ test_code_validation _____________________________
1056:  [gw0] win32 -- Python 3.10.11 C:\Users\runneradmin\AppData\Local\pypoetry\Cache\virtualenvs\agpt-bO72ey-r-py3.10\Scripts\python.exe
1057:  command_arguments = ['ruff', 'check', '--fix', '--ignore', 'F841', '--ignore', ...]
1058:  file_contents = '#------Code-Start------#\n\n\n\n\nasync def read_webpage(url: str, query: str) -> str: # type: ignore\n    """\n    R...\n        info = await crawl_info(url, query)\n        if info:\n            return info\n    return \'No info found\''
1059:  suffix = '.py', output_type = <OutputType.BOTH: 'both'>
1060:  raise_file_contents_on_error = True
1061:  async def exec_external_on_contents(
1062:  command_arguments: list[str],
1063:  file_contents,
1064:  suffix: str = ".py",
1065:  output_type: OutputType = OutputType.BOTH,
1066:  raise_file_contents_on_error: bool = False,
...

1077:  the command. There is no need to provide the file path as an argument, as it will
1078:  be appended to the command arguments.
1079:  Example:
1080:  exec_external(["ruff", "check"], "print('Hello World')")
1081:  will run the command "ruff check <temp_file_path>" with the file contents
1082:  "print('Hello World')" and return the file contents after the command
1083:  has been executed.
1084:  """
1085:  errors = ""
1086:  if len(command_arguments) == 0:
1087:  raise ExecError("No command arguments provided")
...

1109:  protocol = <SubprocessStreamProtocol>
1110:  args = ('ruff', 'check', '--fix', '--ignore', 'F841', '--ignore', ...)
1111:  shell = False, stdin = None, stdout = -1, stderr = -1, bufsize = 0, extra = None
1112:  kwargs = {}
1113:  async def _make_subprocess_transport(self, protocol, args, shell,
1114:  stdin, stdout, stderr, bufsize,
1115:  extra=None, **kwargs):
1116:  """Create subprocess transport."""
1117:  >       raise NotImplementedError
1118:  E       NotImplementedError
1119:  C:\hostedtoolcache\windows\Python\3.10.11\x64\lib\asyncio\base_events.py:498: NotImplementedError
...

1178:  """,
1179:  packages=[],
1180:  )
1181:  tests\unit\test_function_code_validation.py:44: 
1182:  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
1183:  autogpt\utils\function\code_validation.py:206: in validate_code
1184:  await static_code_analysis(result)
1185:  autogpt\utils\function\code_validation.py:276: in static_code_analysis
1186:  validation_errors += await __execute_ruff(func)
1187:  autogpt\utils\function\code_validation.py:301: in __execute_ruff
1188:  code = await exec_external_on_contents(
1189:  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
1190:  command_arguments = ['ruff', 'check', '--fix', '--ignore', 'F841', '--ignore', ...]
1191:  file_contents = '#------Code-Start------#\n\n\n\n\nasync def read_webpage(url: str, query: str) -> str: # type: ignore\n    """\n    R...\n        info = await crawl_info(url, query)\n        if info:\n            return info\n    return \'No info found\''
1192:  suffix = '.py', output_type = <OutputType.BOTH: 'both'>
1193:  raise_file_contents_on_error = True
1194:  async def exec_external_on_contents(
1195:  command_arguments: list[str],
1196:  file_contents,
1197:  suffix: str = ".py",
1198:  output_type: OutputType = OutputType.BOTH,
1199:  raise_file_contents_on_error: bool = False,
...

1210:  the command. There is no need to provide the file path as an argument, as it will
1211:  be appended to the command arguments.
1212:  Example:
1213:  exec_external(["ruff", "check"], "print('Hello World')")
1214:  will run the command "ruff check <temp_file_path>" with the file contents
1215:  "print('Hello World')" and return the file contents after the command
1216:  has been executed.
1217:  """
1218:  errors = ""
1219:  if len(command_arguments) == 0:
1220:  raise ExecError("No command arguments provided")
...

1231:  stdout=subprocess.PIPE,
1232:  stderr=subprocess.PIPE,
1233:  )
1234:  result = await r.communicate()
1235:  stdout, stderr = result[0].decode("utf-8"), result[1].decode("utf-8")
1236:  logger.debug(f"Output: {stdout}")
1237:  if temp_file_path in stdout:
1238:  stdout = stdout  # .replace(temp_file.name, "/generated_file")
1239:  logger.debug(f"Errors: {stderr}")
1240:  if output_type == OutputType.STD_OUT:
1241:  errors = stdout
1242:  elif output_type == OutputType.STD_ERR:
1243:  errors = stderr
1244:  else:
1245:  errors = stdout + "\n" + stderr
1246:  with open(temp_file_path, "r") as f:
1247:  file_contents = f.read()
1248:  finally:
1249:  # Ensure the temporary file is deleted
1250:  >               os.remove(temp_file_path)
1251:  E               PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\tmp_x2mo_6h.py'
1252:  autogpt\utils\function\exec.py:90: PermissionError
...

1455:  Setting random seed to 42
1456:  ============================ slowest 10 durations =============================
1457:  47.75s call     tests/integration/test_web_selenium.py::test_browse_website_nonexistent_url
1458:  4.15s call     tests/integration/test_image_gen.py::test_sd_webui_negative_prompt[256]
1459:  4.04s call     tests/integration/test_image_gen.py::test_sd_webui_negative_prompt[512]
1460:  4.03s call     tests/integration/test_image_gen.py::test_sd_webui_negative_prompt[1024]
1461:  3.02s call     tests/unit/test_web_search.py::test_google_search[no results-1-expected_output_parts2-return_value2]
1462:  1.07s call     tests/unit/test_spinner.py::test_spinner_stops_spinning
1463:  0.54s setup    tests/integration/test_image_gen.py::test_huggingface_fail_request_with_delay[256-10-CompVis/stable-diffusion-v1-4-{"error":"Model [model] is currently loading","estimated_time": [delay]}]
1464:  0.32s call     tests/unit/test_text_file_parsers.py::test_parsers[.pdf-mock_pdf_file]
1465:  0.29s call     tests/unit/test_config.py::test_fallback_to_gpt3_if_gpt4_not_available
1466:  0.21s call     tests/unit/test_spinner.py::test_spinner_initializes_with_custom_values
1467:  =========================== short test summary info ===========================
1468:  FAILED tests/unit/test_function_code_validation.py::test_code_validation - PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\tmp_x2mo_6h.py'
1469:  = 1 failed, 220 passed, 6 skipped, 12 xfailed, 23 warnings in 68.57s (0:01:08) =
1470:  ##[error]Process completed with exit code 1.

✨ CI feedback usage guide:

The CI feedback tool (/checks) automatically triggers when a PR has a failed check.
The tool analyzes the failed checks and provides several feedbacks:

  • Failed stage
  • Failed test name
  • Failure summary
  • Relevant error logs

In addition to being automatically triggered, the tool can also be invoked manually by commenting on a PR:

/checks "https://github.com/{repo_name}/actions/runs/{run_number}/job/{job_number}"

where {repo_name} is the name of the repository, {run_number} is the run number of the failed check, and {job_number} is the job number of the failed check.

Configuration options

  • enable_auto_checks_feedback - if set to true, the tool will automatically provide feedback when a check is failed. Default is true.
  • excluded_checks_list - a list of checks to exclude from the feedback, for example: ["check1", "check2"]. Default is an empty list.
  • enable_help_text - if set to true, the tool will provide a help message with the feedback. Default is true.
  • persistent_comment - if set to true, the tool will overwrite a previous checks comment with the new feedback. Default is true.
  • final_update_message - if persistent_comment is true and updating a previous checks message, the tool will also create a new message: "Persistent checks updated to latest commit". Default is true.

See more information about the checks tool in the docs.

@github-actions github-actions bot added the conflicts Automatically applied to PRs with merge conflicts label May 14, 2024
Copy link

This pull request has conflicts with the base branch, please resolve those so we can evaluate the pull request.

Copy link

Conflicts have been resolved! πŸŽ‰ A maintainer will review the pull request shortly.

@github-actions github-actions bot removed the conflicts Automatically applied to PRs with merge conflicts label May 14, 2024
from .base import BaseAgent, BaseAgentActionProposal
from .prompt_strategies.one_shot import OneShotAgentActionProposal
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OneShotAgentActionProposal is not part of .agent

@@ -97,19 +103,20 @@ def __init__(
llm_provider: ChatModelProvider,
file_storage: FileStorage,
legacy_config: Config,
prompt_strategy_class: type[PromptStrategy] = CodeFlowAgentPromptStrategy,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

decouple agent.py & OneShot. pass this class for custom prompt strategy

if not parsed_response.python_code:
raise ValueError("python_code is empty")

available_functions = {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for the generated code validation.

@@ -2,18 +2,21 @@
from logging import _nameToLevel as logLevelMap
from pathlib import Path
from typing import Optional
from dotenv import load_dotenv
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore this, for debugging purpose, will revert

logger = logging.getLogger(__name__)


class CodeFlowExecutionComponent(CommandProvider):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So... BaseAgentActionProposal use use_tool which only executes a single tool, and it's already intertwined with the agent implementation. So my approach on having this code flow execution is by returning BaseAgentActionProposal that use this newly created tool, which is basically executing python code using already existing other tools as variables.

@@ -158,6 +159,37 @@ def fmt_line(self) -> str:
)
return f"{self.name}: {self.description}. Params: ({params})"

def fmt_header(self, callable=None) -> str:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

callable part here is unused, will revert

@@ -443,6 +443,8 @@ async def create_chat_completion(
if not parse_errors:
try:
parsed_result = completion_parser(assistant_msg)
if isinstance(parsed_result, Coroutine):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So completion_parser needs to be async for the code validation, I did this instead of changing the whole usage of it to async.

Copy link

This pull request has conflicts with the base branch, please resolve those so we can evaluate the pull request.

@github-actions github-actions bot added the conflicts Automatically applied to PRs with merge conflicts label May 15, 2024
Copy link

Conflicts have been resolved! πŸŽ‰ A maintainer will review the pull request shortly.

@github-actions github-actions bot added Forge and removed conflicts Automatically applied to PRs with merge conflicts labels May 20, 2024
@majdyz majdyz changed the title [DRAFT] Add code validation feat: introduce Python code execution as prompt strategy May 20, 2024
@majdyz majdyz requested review from Pwuts and kcze May 20, 2024 11:32
@github-actions github-actions bot added the conflicts Automatically applied to PRs with merge conflicts label May 21, 2024
Copy link

This pull request has conflicts with the base branch, please resolve those so we can evaluate the pull request.

@Pwuts Pwuts changed the title feat: introduce Python code execution as prompt strategy feat(agent): introduce Python code execution as prompt strategy May 22, 2024
@Pwuts Pwuts changed the title feat(agent): introduce Python code execution as prompt strategy feat(agent): Introduce Python code execution as prompt strategy May 22, 2024
@Pwuts Pwuts self-assigned this May 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
AutoGPT Agent conflicts Automatically applied to PRs with merge conflicts Forge size/xl
Projects
Status: πŸ†• Needs initial review
Development

Successfully merging this pull request may close these issues.

None yet

3 participants