From 811acc44366cb483125d625fcb4529067b6d1ffc Mon Sep 17 00:00:00 2001 From: Joschka Braun Date: Tue, 2 May 2023 15:17:11 +0200 Subject: [PATCH 01/30] :sparkles: feat: avoid loops --- src/options/generate/generator.py | 28 +++++++++++---- .../static_files/microservice/Dockerfile | 2 +- src/options/generate/templates_user.py | 35 +++++++++++++++---- 3 files changed, 51 insertions(+), 14 deletions(-) diff --git a/src/options/generate/generator.py b/src/options/generate/generator.py index ad6b45b..d8c901f 100644 --- a/src/options/generate/generator.py +++ b/src/options/generate/generator.py @@ -21,12 +21,12 @@ from src.constants import FILE_AND_TAG_PAIRS, NUM_IMPLEMENTATION_STRATEGIES, MAX from src.options.generate.templates_system import system_task_iteration, system_task_introduction, system_test_iteration from src.options.generate.templates_user import template_generate_microservice_name, \ template_generate_possible_packages, \ - template_solve_code_issue, \ + template_implement_solution_code_issue, \ template_solve_pip_dependency_issue, template_is_dependency_issue, template_generate_playground, \ template_generate_function, template_generate_test, template_generate_requirements, \ template_chain_of_thought, template_summarize_error, \ template_generate_apt_get_install, template_solve_apt_get_dependency_issue, template_pm_task_iteration, \ - template_pm_test_iteration + template_pm_test_iteration, template_suggest_solutions_code_issue from src.options.generate.ui import get_random_employee from src.utils.io import persist_file, get_all_microservice_files_with_content, get_microservice_path @@ -201,7 +201,6 @@ metas: # }) # ) - with open(os.path.join(os.path.dirname(__file__), 'static_files', 'microservice', 'Dockerfile'), 'r', encoding='utf-8') as f: docker_file_template_lines = f.readlines() docker_file_template_lines = [line for line in docker_file_template_lines if not line.startswith('RUN apt-get update')] @@ -348,15 +347,32 @@ pytest all_files_string=dock_req_string, ) else: + all_files_string = self.files_to_string( + {key: val for key, val in file_name_to_content.items() if key != EXECUTOR_FILE_NAME} + ) + suggested_solutions = json.loads( + self.generate_and_persist_file( + section_title='Suggest solution for code issue', + template=template_suggest_solutions_code_issue, + destination_folder=next_microservice_path, + file_name_s=['solutions.json'], + summarized_error=summarized_error, + task_description=self.microservice_specification.task, + test_description=self.microservice_specification.test, + all_files_string=all_files_string, + )['solutions.json'] + ) + self.generate_and_persist_file( - section_title='Debugging code issue', - template=template_solve_code_issue, + section_title='Implementing suggestion solution for code issue', + template=template_implement_solution_code_issue, destination_folder=next_microservice_path, file_name_s=[IMPLEMENTATION_FILE_NAME, TEST_EXECUTOR_FILE_NAME, REQUIREMENTS_FILE_NAME], summarized_error=summarized_error, task_description=self.microservice_specification.task, test_description=self.microservice_specification.test, - all_files_string=self.files_to_string({key: val for key, val in file_name_to_content.items() if key != EXECUTOR_FILE_NAME}), + all_files_string=all_files_string, + suggested_solution=suggested_solutions["1"], ) class MaxDebugTimeReachedException(BaseException): diff --git a/src/options/generate/static_files/microservice/Dockerfile b/src/options/generate/static_files/microservice/Dockerfile index d0de26d..cbe5f8e 100644 --- a/src/options/generate/static_files/microservice/Dockerfile +++ b/src/options/generate/static_files/microservice/Dockerfile @@ -1,4 +1,4 @@ -FROM jinaai/jina:3.14.1-py39-standard +FROM jinaai/jina:3.15.1-dev14-py39-standard # update pip RUN pip install --upgrade pip diff --git a/src/options/generate/templates_user.py b/src/options/generate/templates_user.py index a505435..2d53c0f 100644 --- a/src/options/generate/templates_user.py +++ b/src/options/generate/templates_user.py @@ -272,7 +272,7 @@ Output them as a white space separated list:''' ) -template_solve_code_issue = PromptTemplate.from_template( +template_suggest_solutions_code_issue = PromptTemplate.from_template( '''General rules: ''' + not_allowed_function_string + ''' @@ -288,14 +288,35 @@ Here are all the files I use: Here is the summary of the error that occurred: {summarized_error} -To solve this error, you should: -1. Suggest 3 to 5 possible solutions on how to solve it. You have no access to the documentation of the package. -2. Decide for the best solution and explain it in detail. -3. Write down the files that need to be changed, but not files that don't need to be changed. -Note that any changes needed to make the test pass must be written under the constraint that ''' + IMPLEMENTATION_FILE_NAME + ''' will be used in a different file as well. +You should suggest 3 to 5 possible solutions on how to solve it. Obey the following rules: +You have no access to the documentation of the package. +Note that any changes needed to make the test pass must be written under the constraint that ''' + IMPLEMENTATION_FILE_NAME + ''' will be used in a different file as well. ''' + f'{not_allowed_function_string}\n{not_allowed_docker_string}\n{gpt_35_turbo_usage_string}' + ''' + +After thinking about the possible solutions, output them as JSON ranked from best to worst. Like this: +**solutions.json** +```json +{{ + "1": "", + "2": "<2nd best solution>" +}} +```''' +) + + +template_implement_solution_code_issue = PromptTemplate.from_template( + '''Here is the description of the task the function must solve: +{task_description} + +Here is the test scenario the function must pass: +{test_description} +Here are all the files I use: +{all_files_string} + +Implemented the suggested solution: {suggested_solution} + Output all the files that need change. You must not change the Dockerfile. Don't output files that don't need change. If you output a file, then write the complete file. Use the exact following syntax to wrap the code: @@ -307,7 +328,7 @@ Use the exact following syntax to wrap the code: Example: -**microservice.py** +**implementation.py** ```python print('hello world') ```''' From e21f952665c4dc209e0bb69b7aacc383af3ab571 Mon Sep 17 00:00:00 2001 From: Joschka Braun Date: Wed, 3 May 2023 10:09:19 +0200 Subject: [PATCH 02/30] :bug: fix: import --- src/options/generate/generator.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/options/generate/generator.py b/src/options/generate/generator.py index 4add6fd..16ac304 100644 --- a/src/options/generate/generator.py +++ b/src/options/generate/generator.py @@ -26,9 +26,8 @@ from src.options.generate.templates_user import template_generate_microservice_n template_generate_function, template_generate_test, template_generate_requirements, \ template_chain_of_thought, template_summarize_error, \ template_solve_apt_get_dependency_issue, template_pm_task_iteration, \ - template_pm_test_iteration - template_generate_apt_get_install, template_solve_apt_get_dependency_issue, template_pm_task_iteration, \ - template_pm_test_iteration, template_suggest_solutions_code_issue + template_pm_test_iteration, template_generate_apt_get_install, template_solve_apt_get_dependency_issue,\ + template_pm_task_iteration, template_pm_test_iteration, template_suggest_solutions_code_issue from src.options.generate.ui import get_random_employee from src.utils.io import persist_file, get_all_microservice_files_with_content, get_microservice_path From 879579926b41f9775c0dbe17ab22dd070b0aa25e Mon Sep 17 00:00:00 2001 From: Joschka Braun Date: Wed, 3 May 2023 16:17:05 +0200 Subject: [PATCH 03/30] :bug: fix: don't change docker --- src/options/generate/templates_user.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/options/generate/templates_user.py b/src/options/generate/templates_user.py index 03069e2..1871a48 100644 --- a/src/options/generate/templates_user.py +++ b/src/options/generate/templates_user.py @@ -323,6 +323,7 @@ Here is the summary of the error that occurred: You should suggest 3 to 5 possible solutions on how to solve it. Obey the following rules: You have no access to the documentation of the package. +You must not change the Dockerfile. Note that any changes needed to make the test pass must be written under the constraint that ''' + IMPLEMENTATION_FILE_NAME + ''' will be used in a different file as well. ''' + f'{not_allowed_function_string}\n{not_allowed_docker_string}\n{gpt_35_turbo_usage_string}' + ''' From 0763b9a12ec3fc8ac5021e231e07404a616c851b Mon Sep 17 00:00:00 2001 From: Joschka Braun Date: Wed, 3 May 2023 16:17:16 +0200 Subject: [PATCH 04/30] :bug: fix: summarize error --- src/options/generate/templates_user.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/options/generate/templates_user.py b/src/options/generate/templates_user.py index 1871a48..9fab116 100644 --- a/src/options/generate/templates_user.py +++ b/src/options/generate/templates_user.py @@ -209,10 +209,9 @@ The output would be: template_summarize_error = PromptTemplate.from_template( - '''Here is an error message I encountered during the docker build process: + '''Your task is to condense an error encountered during the docker build process. The error message is as follows: "{error}" -Your task is to summarize the error message as compact and informative as possible while maintaining all information necessary to debug the core issue. -Warnings are not worth mentioning.''' +Your response should be concise and informative, highlighting the core issue while omitting any warnings. It should also provide some additional context regarding the specific file and line number where the error occurred. The actual core error message should also be included.''' ) From 19d561a0f265e866479378a1064b1da79c799677 Mon Sep 17 00:00:00 2001 From: Joschka Braun Date: Wed, 3 May 2023 16:39:46 +0200 Subject: [PATCH 05/30] :bug: fix: pattern to extract --- src/options/generate/generator.py | 2 +- src/options/generate/templates_user.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/options/generate/generator.py b/src/options/generate/generator.py index 00f4a80..22fe0be 100644 --- a/src/options/generate/generator.py +++ b/src/options/generate/generator.py @@ -48,7 +48,7 @@ class Generator: def extract_content_from_result(self, plain_text, file_name, match_single_block=False, can_contain_code_block=True): optional_line_break = '\n' if can_contain_code_block else '' # the \n at the end makes sure that ``` within the generated code is not matched because it is not right before a line break - pattern = fr"\*?\*?{file_name}\*?\*?\n```(?:\w+\n)?([\s\S]*?){optional_line_break}```" + pattern = fr"^\*?\*?{file_name}\*?\*?\n```(?:\w+\n)?([\s\S]*?){optional_line_break}```" matches = re.findall(pattern, plain_text, re.MULTILINE) if matches: return matches[-1].strip() diff --git a/src/options/generate/templates_user.py b/src/options/generate/templates_user.py index c7412cc..9bb1f65 100644 --- a/src/options/generate/templates_user.py +++ b/src/options/generate/templates_user.py @@ -203,9 +203,9 @@ template_summarize_error = PromptTemplate.from_template( "{error}" Your task is to summarize the error message as compact and informative as possible \ while maintaining all information necessary to debug the core issue (100 words). +It should also provide some additional context regarding the specific file and line number where the error occurred. \ Note that you must not suggest a solution to the error. -Warnings are not worth mentioning. -Your response should be concise and informative, highlighting the core issue while omitting any warnings. It should also provide some additional context regarding the specific file and line number where the error occurred. The actual core error message should also be included.''' +Warnings are not worth mentioning.''' ) From 6d14ebef2f22ad1950e5dcd4166ff8d2585bc84d Mon Sep 17 00:00:00 2001 From: Joschka Braun Date: Thu, 4 May 2023 16:40:45 +0200 Subject: [PATCH 06/30] :recycle: refactor: use generator attributes --- src/options/generate/generator.py | 148 +++++++++++++++++------------- 1 file changed, 82 insertions(+), 66 deletions(-) diff --git a/src/options/generate/generator.py b/src/options/generate/generator.py index 22fe0be..89cdb9d 100644 --- a/src/options/generate/generator.py +++ b/src/options/generate/generator.py @@ -25,9 +25,9 @@ from src.options.generate.templates_user import template_generate_microservice_n template_solve_pip_dependency_issue, template_is_dependency_issue, template_generate_playground, \ template_generate_function, template_generate_test, template_generate_requirements, \ template_chain_of_thought, template_summarize_error, \ - template_solve_apt_get_dependency_issue, template_pm_task_iteration, \ - template_pm_test_iteration, template_generate_apt_get_install, template_solve_apt_get_dependency_issue,\ - template_pm_task_iteration, template_pm_test_iteration, template_suggest_solutions_code_issue + template_solve_apt_get_dependency_issue, \ + template_pm_task_iteration, template_pm_test_iteration, template_suggest_solutions_code_issue, \ + template_was_error_seen_before, template_was_solution_tried_before from src.options.generate.ui import get_random_employee from src.utils.io import persist_file, get_all_microservice_files_with_content, get_microservice_path @@ -45,10 +45,13 @@ class Generator: self.gpt_session = gpt.GPTSession(task_description, model=model) self.microservice_specification = TaskSpecification(task=task_description, test=None) self.microservice_root_path = path + self.microservice_name = None + self.previous_microservice_path = None + self.cur_microservice_path = None def extract_content_from_result(self, plain_text, file_name, match_single_block=False, can_contain_code_block=True): optional_line_break = '\n' if can_contain_code_block else '' # the \n at the end makes sure that ``` within the generated code is not matched because it is not right before a line break - pattern = fr"^\*?\*?{file_name}\*?\*?\n```(?:\w+\n)?([\s\S]*?){optional_line_break}```" + pattern = fr"(?:\*|\*\*| ){file_name}\*?\*?\n```(?:\w+\n)?([\s\S]*?){optional_line_break}```" matches = re.findall(pattern, plain_text, re.MULTILINE) if matches: return matches[-1].strip() @@ -92,7 +95,7 @@ metas: self, section_title: str, template: PromptTemplate, - destination_folder: str, + destination_folder: str = None, file_name_s: List[str] = None, parse_result_fn: Callable = None, system_definition_examples: List[str] = [], @@ -104,7 +107,8 @@ metas: Args: section_title (str): The title of the section to be printed in the console. template (PromptTemplate): The template to be used for generating the file(s). - destination_folder (str): The destination folder where the generated file(s) should be persisted. + destination_folder (str): The destination folder where the generated file(s) should be persisted. If None, + the current microservice path is used. Defaults to None. file_name_s (List[str], optional): The name of the file(s) to be generated. Defaults to None. parse_result_fn (Callable, optional): A function that parses the generated content and returns a dictionary mapping file_name to its content. If no content could be extract, it returns an empty dictionary. @@ -112,6 +116,9 @@ metas: system_definition_examples (List[str], optional): The system definition examples to be used for the conversation. Defaults to []. **template_kwargs: The keyword arguments to be passed to the template. """ + if destination_folder is None: + destination_folder = self.cur_microservice_path + if parse_result_fn is None: parse_result_fn = self.get_default_parse_result_fn(file_name_s) @@ -139,27 +146,26 @@ metas: def generate_microservice( self, - microservice_name, packages, num_approach, ): - MICROSERVICE_FOLDER_v1 = get_microservice_path(self.microservice_root_path, microservice_name, packages, - num_approach, 1) - os.makedirs(MICROSERVICE_FOLDER_v1) + self.cur_microservice_path = get_microservice_path( + self.microservice_root_path, self.microservice_name, packages, num_approach, 1 + ) + os.makedirs(self.cur_microservice_path) with open(os.path.join(os.path.dirname(__file__), 'static_files', 'microservice', 'jina_wrapper.py'), 'r', encoding='utf-8') as f: microservice_executor_boilerplate = f.read() microservice_executor_code = microservice_executor_boilerplate.replace('class GPTDeployExecutor(Executor):', - f'class {microservice_name}(Executor):') - persist_file(microservice_executor_code, os.path.join(MICROSERVICE_FOLDER_v1, EXECUTOR_FILE_NAME)) + f'class {self.microservice_name}(Executor):') + persist_file(microservice_executor_code, os.path.join(self.cur_microservice_path, EXECUTOR_FILE_NAME)) with open(os.path.join(os.path.dirname(__file__), 'static_files', 'microservice', 'apis.py'), 'r', encoding='utf-8') as f: - persist_file(f.read(), os.path.join(MICROSERVICE_FOLDER_v1, 'apis.py')) + persist_file(f.read(), os.path.join(self.cur_microservice_path, 'apis.py')) microservice_content = self.generate_and_persist_file( section_title='Microservice', template=template_generate_function, - destination_folder=MICROSERVICE_FOLDER_v1, microservice_description=self.microservice_specification.task, test_description=self.microservice_specification.test, packages=packages, @@ -171,9 +177,8 @@ metas: test_microservice_content = self.generate_and_persist_file( 'Test Microservice', template_generate_test, - MICROSERVICE_FOLDER_v1, code_files_wrapped=self.files_to_string({EXECUTOR_FILE_NAME: microservice_content}), - microservice_name=microservice_name, + microservice_name=self.microservice_name, microservice_description=self.microservice_specification.task, test_description=self.microservice_specification.test, file_name_purpose=TEST_EXECUTOR_FILE_NAME, @@ -181,10 +186,9 @@ metas: file_name_s=[TEST_EXECUTOR_FILE_NAME], )[TEST_EXECUTOR_FILE_NAME] - requirements_content = self.generate_and_persist_file( + self.generate_and_persist_file( 'Requirements', template_generate_requirements, - MICROSERVICE_FOLDER_v1, code_files_wrapped=self.files_to_string({ IMPLEMENTATION_FILE_NAME: microservice_content, TEST_EXECUTOR_FILE_NAME: test_microservice_content, @@ -193,21 +197,7 @@ metas: file_name_s=[REQUIREMENTS_FILE_NAME], parse_result_fn=self.parse_result_fn_requirements, tag_name=REQUIREMENTS_FILE_TAG, - )[REQUIREMENTS_FILE_NAME] - - # I deactivated this because 3.5-turbo was halucinating packages that were not needed - # now, in the first iteration the default dockerfile is used - # self.generate_and_persist_file( - # section_title='Generate Dockerfile', - # template=template_generate_apt_get_install, - # destination_folder=MICROSERVICE_FOLDER_v1, - # file_name_s=None, - # parse_result_fn=self.parse_result_fn_dockerfile, - # docker_file_wrapped=self.read_docker_template(), - # requirements_file_wrapped=self.files_to_string({ - # REQUIREMENTS_FILE_NAME: requirements_content, - # }) - # ) + ) with open(os.path.join(os.path.dirname(__file__), 'static_files', 'microservice', 'Dockerfile'), 'r', encoding='utf-8') as f: @@ -217,9 +207,9 @@ metas: for line in docker_file_template_lines ] docker_file_content = '\n'.join(docker_file_template_lines) - persist_file(docker_file_content, os.path.join(MICROSERVICE_FOLDER_v1, 'Dockerfile')) + persist_file(docker_file_content, os.path.join(self.cur_microservice_path, 'Dockerfile')) - self.write_config_yml(microservice_name, MICROSERVICE_FOLDER_v1) + self.write_config_yml(self.microservice_name, self.cur_microservice_path) print('\nFirst version of the microservice generated. Start iterating on it to make the tests pass...') @@ -249,15 +239,15 @@ pytest {os.linesep.join(lines)}''' return {REQUIREMENTS_FILE_NAME: content_modified} - def generate_playground(self, microservice_name, microservice_path): + def generate_playground(self): print_colored('', '\n\n############# Playground #############', 'blue') - file_name_to_content = get_all_microservice_files_with_content(microservice_path) + file_name_to_content = get_all_microservice_files_with_content(self.cur_microservice_path) conversation = self.gpt_session.get_conversation() conversation.chat( template_generate_playground.format( code_files_wrapped=self.files_to_string(file_name_to_content, ['test_microservice.py']), - microservice_name=microservice_name, + microservice_name=self.microservice_name, ) ) playground_content_raw = conversation.chat( @@ -274,12 +264,12 @@ pytest content_raw, 'app.py', match_single_block=True ) - gateway_path = os.path.join(microservice_path, 'gateway') + gateway_path = os.path.join(self.cur_microservice_path, 'gateway') shutil.copytree(os.path.join(os.path.dirname(__file__), 'static_files', 'gateway'), gateway_path) persist_file(playground_content, os.path.join(gateway_path, 'app.py')) # fill-in name of microservice - gateway_name = f'Gateway{microservice_name}' + gateway_name = f'Gateway{self.microservice_name}' custom_gateway_path = os.path.join(gateway_path, 'custom_gateway.py') with open(custom_gateway_path, 'r', encoding='utf-8') as f: custom_gateway_content = f.read() @@ -297,40 +287,38 @@ pytest print('Final step...') hubble_log = push_executor(gateway_path) if not is_executor_in_hub(gateway_name): - raise Exception(f'{microservice_name} not in hub. Hubble logs: {hubble_log}') + raise Exception(f'{self.microservice_name} not in hub. Hubble logs: {hubble_log}') - def debug_microservice(self, microservice_name, num_approach, packages): + def debug_microservice(self, num_approach, packages): for i in range(1, MAX_DEBUGGING_ITERATIONS): print('Debugging iteration', i) print('Trying to debug the microservice. Might take a while...') - previous_microservice_path = get_microservice_path(self.microservice_root_path, microservice_name, packages, - num_approach, i) - next_microservice_path = get_microservice_path(self.microservice_root_path, microservice_name, packages, - num_approach, i + 1) - clean_requirements_txt(previous_microservice_path) - log_hubble = push_executor(previous_microservice_path) + clean_requirements_txt(self.cur_microservice_path) + log_hubble = push_executor(self.cur_microservice_path) error = process_error_message(log_hubble) if error: print('An error occurred during the build process. Feeding the error back to the assistant...') - self.do_debug_iteration(error, next_microservice_path, previous_microservice_path) + self.previous_microservice_path = self.cur_microservice_path + self.cur_microservice_path = get_microservice_path( + self.microservice_root_path, self.microservice_name, packages, num_approach, i + 1 + ) + os.makedirs(self.cur_microservice_path) + self.do_debug_iteration(error) if i == MAX_DEBUGGING_ITERATIONS - 1: raise self.MaxDebugTimeReachedException('Could not debug the microservice.') else: # at the moment, there can be cases where no error log is extracted but the executor is still not published # it leads to problems later on when someone tries a run or deployment - if is_executor_in_hub(microservice_name): + if is_executor_in_hub(self.microservice_name): print('Successfully build microservice.') break else: - raise Exception(f'{microservice_name} not in hub. Hubble logs: {log_hubble}') + raise Exception(f'{self.microservice_name} not in hub. Hubble logs: {log_hubble}') - return get_microservice_path(self.microservice_root_path, microservice_name, packages, num_approach, i) - - def do_debug_iteration(self, error, next_microservice_path, previous_microservice_path): - os.makedirs(next_microservice_path) - file_name_to_content = get_all_microservice_files_with_content(previous_microservice_path) + def do_debug_iteration(self, error): + file_name_to_content = get_all_microservice_files_with_content(self.previous_microservice_path) for file_name, content in file_name_to_content.items(): - persist_file(content, os.path.join(next_microservice_path, file_name)) + persist_file(content, os.path.join(self.cur_microservice_path, file_name)) summarized_error = self.summarize_error(error) dock_req_string = self.files_to_string({ @@ -343,7 +331,6 @@ pytest self.generate_and_persist_file( section_title='Debugging apt-get dependency issue', template=template_solve_apt_get_dependency_issue, - destination_folder=next_microservice_path, file_name_s=['apt-get-packages.json'], parse_result_fn=self.parse_result_fn_dockerfile, system_definition_examples=[], @@ -357,7 +344,6 @@ pytest self.generate_and_persist_file( section_title='Debugging pip dependency issue', template=template_solve_pip_dependency_issue, - destination_folder=next_microservice_path, file_name_s=[REQUIREMENTS_FILE_NAME], summarized_error=summarized_error, all_files_string=dock_req_string, @@ -370,7 +356,6 @@ pytest self.generate_and_persist_file( section_title='Suggest solution for code issue', template=template_suggest_solutions_code_issue, - destination_folder=next_microservice_path, file_name_s=['solutions.json'], summarized_error=summarized_error, task_description=self.microservice_specification.task, @@ -379,16 +364,47 @@ pytest )['solutions.json'] ) + was_error_seen_before = json.loads( + self.generate_and_persist_file( + section_title='Check if error was seen before', + template=template_was_error_seen_before, + file_name_s=['response.json'], + summarized_error=summarized_error, + previous_errors=None, # todo: fill-in mapping from previous errors to suggested solutions + system_definition_examples=None, + )['response.json'] + )['was_error_seen_before'].lower() == 'yes' + + suggested_solution = None + if was_error_seen_before: + for _num_solution in range(len(suggested_solutions)): + _suggested_solution = suggested_solutions[str(_num_solution)] + was_solution_tried_before = json.loads( + self.generate_and_persist_file( + section_title='Check if solution was tried before', + template=template_was_solution_tried_before, + file_name_s=['response.json'], + tried_solutions=None, # todo: fill-in mapping from tried solutions to suggested solutions + suggested_solution=_suggested_solution, + system_definition_examples=None, + )['response.json'] + )['will_lead_to_different_actions'].lower() == 'no' + if not was_solution_tried_before: + suggested_solution = _suggested_solution + break + + if suggested_solution is None: + suggested_solution = f"solve error: {summarized_error}" + self.generate_and_persist_file( section_title='Implementing suggestion solution for code issue', template=template_implement_solution_code_issue, - destination_folder=next_microservice_path, file_name_s=[IMPLEMENTATION_FILE_NAME, TEST_EXECUTOR_FILE_NAME, REQUIREMENTS_FILE_NAME], summarized_error=summarized_error, task_description=self.microservice_specification.task, test_description=self.microservice_specification.test, all_files_string=all_files_string, - suggested_solution=suggested_solutions["1"], + suggested_solution=suggested_solution, ) class MaxDebugTimeReachedException(BaseException): @@ -449,13 +465,13 @@ pytest self.refine_specification() os.makedirs(self.microservice_root_path) generated_name = self.generate_microservice_name(self.microservice_specification.task) - microservice_name = f'{generated_name}{random.randint(0, 10_000_000)}' + self.microservice_name = f'{generated_name}{random.randint(0, 10_000_000)}' packages_list = self.get_possible_packages() for num_approach, packages in enumerate(packages_list): try: - self.generate_microservice(microservice_name, packages, num_approach) - final_version_path = self.debug_microservice(microservice_name, num_approach, packages) - self.generate_playground(microservice_name, final_version_path) + self.generate_microservice(packages, num_approach) + self.debug_microservice(num_approach, packages) + self.generate_playground() except self.MaxDebugTimeReachedException: print('Could not debug the Microservice with the approach:', packages) if num_approach == len(packages_list) - 1: From dc4b17d2efdf20fff65fe8b669f728421a9c87b0 Mon Sep 17 00:00:00 2001 From: Joschka Braun Date: Thu, 4 May 2023 16:56:46 +0200 Subject: [PATCH 07/30] :rocket: feat: generate novel solution suggestions --- src/options/generate/generator.py | 99 +++++++++++++++----------- src/options/generate/templates_user.py | 47 ++++++++++-- 2 files changed, 97 insertions(+), 49 deletions(-) diff --git a/src/options/generate/generator.py b/src/options/generate/generator.py index 89cdb9d..b035ba9 100644 --- a/src/options/generate/generator.py +++ b/src/options/generate/generator.py @@ -13,7 +13,7 @@ from pydantic.dataclasses import dataclass from src.apis import gpt from src.apis.gpt import _GPTConversation from src.apis.jina_cloud import process_error_message, push_executor, is_executor_in_hub -from src.apis.pypi import is_package_on_pypi, get_latest_package_version, clean_requirements_txt +from src.apis.pypi import is_package_on_pypi, clean_requirements_txt from src.constants import FILE_AND_TAG_PAIRS, NUM_IMPLEMENTATION_STRATEGIES, MAX_DEBUGGING_ITERATIONS, \ BLACKLISTED_PACKAGES, EXECUTOR_FILE_NAME, TEST_EXECUTOR_FILE_NAME, TEST_EXECUTOR_FILE_TAG, \ REQUIREMENTS_FILE_NAME, REQUIREMENTS_FILE_TAG, DOCKER_FILE_NAME, IMPLEMENTATION_FILE_NAME, \ @@ -48,6 +48,8 @@ class Generator: self.microservice_name = None self.previous_microservice_path = None self.cur_microservice_path = None + self.previous_errors = [] + self.previous_solutions = [] def extract_content_from_result(self, plain_text, file_name, match_single_block=False, can_contain_code_block=True): optional_line_break = '\n' if can_contain_code_block else '' # the \n at the end makes sure that ``` within the generated code is not matched because it is not right before a line break @@ -352,49 +354,8 @@ pytest all_files_string = self.files_to_string( {key: val for key, val in file_name_to_content.items() if key != EXECUTOR_FILE_NAME} ) - suggested_solutions = json.loads( - self.generate_and_persist_file( - section_title='Suggest solution for code issue', - template=template_suggest_solutions_code_issue, - file_name_s=['solutions.json'], - summarized_error=summarized_error, - task_description=self.microservice_specification.task, - test_description=self.microservice_specification.test, - all_files_string=all_files_string, - )['solutions.json'] - ) - was_error_seen_before = json.loads( - self.generate_and_persist_file( - section_title='Check if error was seen before', - template=template_was_error_seen_before, - file_name_s=['response.json'], - summarized_error=summarized_error, - previous_errors=None, # todo: fill-in mapping from previous errors to suggested solutions - system_definition_examples=None, - )['response.json'] - )['was_error_seen_before'].lower() == 'yes' - - suggested_solution = None - if was_error_seen_before: - for _num_solution in range(len(suggested_solutions)): - _suggested_solution = suggested_solutions[str(_num_solution)] - was_solution_tried_before = json.loads( - self.generate_and_persist_file( - section_title='Check if solution was tried before', - template=template_was_solution_tried_before, - file_name_s=['response.json'], - tried_solutions=None, # todo: fill-in mapping from tried solutions to suggested solutions - suggested_solution=_suggested_solution, - system_definition_examples=None, - )['response.json'] - )['will_lead_to_different_actions'].lower() == 'no' - if not was_solution_tried_before: - suggested_solution = _suggested_solution - break - - if suggested_solution is None: - suggested_solution = f"solve error: {summarized_error}" + suggested_solution = self.generate_solution_suggestion(summarized_error, all_files_string) self.generate_and_persist_file( section_title='Implementing suggestion solution for code issue', @@ -407,6 +368,58 @@ pytest suggested_solution=suggested_solution, ) + def generate_solution_suggestion(self, summarized_error, all_files_string): + suggested_solutions = json.loads( + self.generate_and_persist_file( + section_title='Suggest solution for code issue', + template=template_suggest_solutions_code_issue, + file_name_s=['solutions.json'], + summarized_error=summarized_error, + task_description=self.microservice_specification.task, + test_description=self.microservice_specification.test, + all_files_string=all_files_string, + )['solutions.json'] + ) + + if len(self.previous_errors) > 0: + was_error_seen_before = json.loads( + self.generate_and_persist_file( + section_title='Check if error was seen before', + template=template_was_error_seen_before, + file_name_s=['response.json'], + summarized_error=summarized_error, + previous_errors=f'- "{os.linesep}"'.join(self.previous_errors), + system_definition_examples=None, + )['response.json'] + )['was_error_seen_before'].lower() == 'yes' + + suggested_solution = None + if was_error_seen_before: + for _num_solution in range(1, len(suggested_solutions) + 1): + _suggested_solution = suggested_solutions[str(_num_solution)] + was_solution_tried_before = json.loads( + self.generate_and_persist_file( + section_title='Check if solution was tried before', + template=template_was_solution_tried_before, + file_name_s=['response.json'], + tried_solutions=f'- "{os.linesep}"'.join(self.previous_solutions), + suggested_solution=_suggested_solution, + system_definition_examples=None, + )['response.json'] + )['will_lead_to_different_actions'].lower() == 'no' + if not was_solution_tried_before: + suggested_solution = _suggested_solution + break + else: + suggested_solution = suggested_solutions['1'] + + if suggested_solution is None: + suggested_solution = f"solve error: {summarized_error}" + else: + suggested_solution = suggested_solutions['1'] + + return suggested_solution + class MaxDebugTimeReachedException(BaseException): pass diff --git a/src/options/generate/templates_user.py b/src/options/generate/templates_user.py index 9bb1f65..4ac0af2 100644 --- a/src/options/generate/templates_user.py +++ b/src/options/generate/templates_user.py @@ -62,7 +62,7 @@ e) the implementation of the core problem using the package would obey the follo When answering, just write "yes" or "no". 4. For each approach, list the required python package combinations as discibed in the following. -You must output the package combinations as json wrapped into tripple backticks ``` and name it **strategies.json**. \ +You must output the package combinations as json wrapped into triple backticks ``` and name it **strategies.json**. \ Note that you can also leave a list empty to indicate that one of the strategies does not require any package and can be done in plain python. Write the output using double asterisks and triple backticks like this: **strategies.json** @@ -78,7 +78,7 @@ Write the output using double asterisks and triple backticks like this: template_code_wrapping_string = '''The code will go into {file_name_purpose}. -Note that you must obey the double asterisk and tripple backtick syntax from like this: +Note that you must obey the double asterisk and triple backtick syntax from like this: **{file_name}** ```{tag_name} ...code... @@ -228,7 +228,7 @@ Is this error happening because a PACKAGE_MANAGER package is missing or failed t ```json {{"dependency_installation_failure": ""}} ``` -Note that you must obey the double asterisk and tripple backtick syntax from above. +Note that you must obey the double asterisk and triple backtick syntax from above. ''' ) @@ -313,8 +313,9 @@ Here are all the files I use: Here is the summary of the error that occurred: {summarized_error} -You should suggest 3 to 5 possible solutions on how to solve it. +You should suggest 3 to 5 possible solution approaches on how to solve it. Obey the following rules: +Do not implement the solution. You have no access to the documentation of the package. You must not change the Dockerfile. Note that any changes needed to make the test pass must be written under the constraint that ''' + IMPLEMENTATION_FILE_NAME + ''' will be used in a different file as well. @@ -332,6 +333,40 @@ After thinking about the possible solutions, output them as JSON ranked from bes ) +template_was_error_seen_before = PromptTemplate.from_template( + '''Previously encountered error messages: +{previous_errors} + +Now encountered error message: "{summarized_error}" +Was this error message encountered before? + +Write down your final answer as json in the following format: +**response.json** +```json +{{"was_error_seen_before": ""}} +``` +Note that you must obey the double asterisk and triple backtick syntax from above. +''' +) + + +template_was_solution_tried_before = PromptTemplate.from_template( + '''Previously tried solutions: +{tried_solutions} + +Suggested solution: "{suggested_solution}" + +Will the suggested solution lead to different actions than the previously tried solutions? + +Write down your final answer as json in the following format: +**response.json** +```json +{{"will_lead_to_different_actions": ""}} +``` +Note that you must obey the double asterisk and triple backtick syntax from above.''' +) + + template_implement_solution_code_issue = PromptTemplate.from_template( '''Here is the description of the task the function must solve: {task_description} @@ -442,7 +477,7 @@ Or write the detailed microservice description all mentioned code samples, docum }} ``` Note that your response must be either prompt.json or final.json. You must not write both. -Note that you must obey the double asterisk and tripple backtick syntax from above. +Note that you must obey the double asterisk and triple backtick syntax from above. Note that the last sequence of characters in your response must be ``` (triple backtick). Note that prompt.json must not only contain one question. Note that if urls, secrets, database names, etc. are mentioned, they must be part of the summary. @@ -486,7 +521,7 @@ Example for the case where the example is already mentioned in the refined descr }} ``` Note that your response must be either prompt.json or final.json. You must not write both. -Note that you must obey the double asterisk and tripple backtick syntax from above. +Note that you must obey the double asterisk and triple backtick syntax from above. Note that the last sequence of characters in your response must be ``` (triple backtick). Note that your response must start with the character sequence ** (double asterisk). Note that prompt.json must only contain one question. From 3aa670ccd6d408b72013bf869b2cd3e88f68c400 Mon Sep 17 00:00:00 2001 From: Joschka Braun Date: Thu, 4 May 2023 17:33:49 +0200 Subject: [PATCH 08/30] :rocket: feat: generate novel solution suggestions --- src/options/generate/generator.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/options/generate/generator.py b/src/options/generate/generator.py index 1c96c48..48fe280 100644 --- a/src/options/generate/generator.py +++ b/src/options/generate/generator.py @@ -369,6 +369,9 @@ pytest suggested_solution=suggested_solution, ) + self.previous_errors.append(summarized_error) + self.previous_solutions.append(suggested_solution) + def generate_solution_suggestion(self, summarized_error, all_files_string): suggested_solutions = json.loads( self.generate_and_persist_file( From 649c64fe3f023967e9aad3e7e294a194e229ff41 Mon Sep 17 00:00:00 2001 From: Joschka Braun Date: Thu, 4 May 2023 17:43:33 +0200 Subject: [PATCH 09/30] :rocket: fix: fix typo --- src/options/generate/generator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/options/generate/generator.py b/src/options/generate/generator.py index 48fe280..6004002 100644 --- a/src/options/generate/generator.py +++ b/src/options/generate/generator.py @@ -129,7 +129,7 @@ metas: system_introduction_message = _GPTConversation._create_system_message(self.microservice_specification.task, self.microservice_specification.test, system_definition_examples) - conversation = self.gpt_session.get_conversation(messages=[system_introduction_message]) + conversation = self.gpt_session.get_conversation(messages=[system_introduction_message] if system_introduction_message else []) template_kwargs = {k: v for k, v in template_kwargs.items() if k in template.input_variables} if 'file_name' in template.input_variables and len(file_name_s) == 1: template_kwargs['file_name'] = file_name_s[0] From d4741d466c52d35b066ee998fc5a708575610435 Mon Sep 17 00:00:00 2001 From: Joschka Braun Date: Fri, 5 May 2023 11:49:26 +0200 Subject: [PATCH 10/30] :rocket: fix: merge main --- dev_gpt/options/generate/generator.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/dev_gpt/options/generate/generator.py b/dev_gpt/options/generate/generator.py index f03f566..28aeb4f 100644 --- a/dev_gpt/options/generate/generator.py +++ b/dev_gpt/options/generate/generator.py @@ -26,7 +26,8 @@ from dev_gpt.options.generate.templates_user import template_generate_microservi template_generate_function, template_generate_test, template_generate_requirements, \ template_chain_of_thought, template_summarize_error, \ template_solve_apt_get_dependency_issue, template_pm_task_iteration, \ - template_pm_test_iteration + template_pm_test_iteration, template_suggest_solutions_code_issue, template_was_error_seen_before, \ + template_was_solution_tried_before from dev_gpt.options.generate.ui import get_random_employee from dev_gpt.utils.io import persist_file, get_all_microservice_files_with_content, get_microservice_path from dev_gpt.utils.string_tools import print_colored @@ -99,7 +100,7 @@ metas: destination_folder: str = None, file_name_s: List[str] = None, parse_result_fn: Callable = None, - system_definition_examples: List[str] = [], # todo: rename to use_system_definition_exampels: bool = True + use_system_message: bool = True, **template_kwargs ): """This function generates file(s) using the given template and persists it/them in the given destination folder. @@ -114,7 +115,7 @@ metas: parse_result_fn (Callable, optional): A function that parses the generated content and returns a dictionary mapping file_name to its content. If no content could be extract, it returns an empty dictionary. Defaults to None. If None, default parsing is used which uses the file_name to extract from the generated content. - system_definition_examples (List[str], optional): The system definition examples to be used for the conversation. Defaults to []. + use_system_message (bool, optional): whether to use custom system message or not. Defaults to True. **template_kwargs: The keyword arguments to be passed to the template. """ if destination_folder is None: @@ -128,7 +129,9 @@ metas: self.microservice_specification.task, self.microservice_specification.test ) - conversation = self.gpt_session.get_conversation(messages=[system_introduction_message] if use_system_message else []) + conversation = self.gpt_session.get_conversation( + messages=[system_introduction_message] if use_system_message else [] + ) template_kwargs = {k: v for k, v in template_kwargs.items() if k in template.input_variables} if 'file_name' in template.input_variables and len(file_name_s) == 1: template_kwargs['file_name'] = file_name_s[0] @@ -158,8 +161,8 @@ metas: with open(os.path.join(os.path.dirname(__file__), 'static_files', 'microservice', 'jina_wrapper.py'), 'r', encoding='utf-8') as f: microservice_executor_boilerplate = f.read() - microservice_executor_code = microservice_executor_boilerplate.replace('class DevGPTExecutor(Executor):', - f'class {microservice_name}(Executor):') + microservice_executor_code = microservice_executor_boilerplate \ + .replace('class DevGPTExecutor(Executor):', f'class {self.microservice_name}(Executor):') persist_file(microservice_executor_code, os.path.join(self.cur_microservice_path, EXECUTOR_FILE_NAME)) with open(os.path.join(os.path.dirname(__file__), 'static_files', 'microservice', 'apis.py'), 'r', encoding='utf-8') as f: @@ -335,7 +338,6 @@ pytest template=template_solve_apt_get_dependency_issue, file_name_s=['apt-get-packages.json'], parse_result_fn=self.parse_result_fn_dockerfile, - system_definition_examples=[], summarized_error=summarized_error, all_files_string=dock_req_string, ) @@ -392,7 +394,7 @@ pytest file_name_s=['response.json'], summarized_error=summarized_error, previous_errors=f'- "{os.linesep}"'.join(self.previous_errors), - system_definition_examples=None, + use_system_message=False, )['response.json'] )['was_error_seen_before'].lower() == 'yes' @@ -407,7 +409,7 @@ pytest file_name_s=['response.json'], tried_solutions=f'- "{os.linesep}"'.join(self.previous_solutions), suggested_solution=_suggested_solution, - system_definition_examples=None, + use_system_message=False, )['response.json'] )['will_lead_to_different_actions'].lower() == 'no' if not was_solution_tried_before: @@ -466,7 +468,6 @@ pytest template=template_generate_possible_packages, destination_folder=self.microservice_root_path, file_name_s=['strategies.json'], - system_definition_examples=[], description=self.microservice_specification.task )['strategies.json'] packages_list = [[pkg.strip().lower() for pkg in packages] for packages in json.loads(packages_json_string)] From 7063a7e25dc408c7e2709345d69fd28a5e60257c Mon Sep 17 00:00:00 2001 From: Joschka Braun Date: Fri, 5 May 2023 11:52:32 +0200 Subject: [PATCH 11/30] :rocket: test: add level 5 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index abfc233..b3b71b3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ jobs: strategy: fail-fast: false matrix: - group: [0, 1, 2, 3, 4] + group: [0, 1, 2, 3, 4, 5] steps: - uses: actions/checkout@v2 - name: Set up Python 3.8 From 55c0e52c5d69c81aec77adb46d22e6720d95f9df Mon Sep 17 00:00:00 2001 From: Joschka Braun Date: Fri, 5 May 2023 12:19:14 +0200 Subject: [PATCH 12/30] :rocket: fix: fix asking for content --- dev_gpt/apis/gpt.py | 1 - dev_gpt/options/generate/generator.py | 10 +++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/dev_gpt/apis/gpt.py b/dev_gpt/apis/gpt.py index f9416e3..3ebf3d9 100644 --- a/dev_gpt/apis/gpt.py +++ b/dev_gpt/apis/gpt.py @@ -109,7 +109,6 @@ class _GPTConversation: self.print_stream = print_stream self.print_costs = print_costs - def print_messages(self, messages): for i, message in enumerate(messages): if os.environ['VERBOSE'].lower() == 'true': diff --git a/dev_gpt/options/generate/generator.py b/dev_gpt/options/generate/generator.py index 28aeb4f..ea516e4 100644 --- a/dev_gpt/options/generate/generator.py +++ b/dev_gpt/options/generate/generator.py @@ -142,8 +142,16 @@ metas: ) content = parse_result_fn(content_raw) if content == {}: + conversation = self.gpt_session.get_conversation(messages=[AIMessage(content=content_raw)]) content_raw = conversation.chat( - 'You must add the content' + (f' for {file_name_s[0]}' if len(file_name_s) == 1 else '')) + 'You must add the content' + (f' for {file_name_s[0]}' if len(file_name_s) == 1 else '') + + ''' in triple backticks. A general example is this: + +**file_name.file_ending** +``` +```''' + ) content = parse_result_fn(content_raw) for _file_name, _file_content in content.items(): persist_file(_file_content, os.path.join(destination_folder, _file_name)) From 23dedf3ccc0686acd56ab6af96e29e7aa820618a Mon Sep 17 00:00:00 2001 From: Joschka Braun Date: Fri, 5 May 2023 15:02:41 +0200 Subject: [PATCH 13/30] :rocket: fix: fix asking for content --- dev_gpt/options/generate/generator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_gpt/options/generate/generator.py b/dev_gpt/options/generate/generator.py index ea516e4..be50f58 100644 --- a/dev_gpt/options/generate/generator.py +++ b/dev_gpt/options/generate/generator.py @@ -145,7 +145,7 @@ metas: conversation = self.gpt_session.get_conversation(messages=[AIMessage(content=content_raw)]) content_raw = conversation.chat( 'You must add the content' + (f' for {file_name_s[0]}' if len(file_name_s) == 1 else '') + - ''' in triple backticks. A general example is this: + '''. Make sure to wrap any code in triple backticks in the beginning and end of any code. A general example is this: **file_name.file_ending** ``` Date: Fri, 5 May 2023 15:10:47 +0200 Subject: [PATCH 14/30] :rocket: fix: fix asking for content --- dev_gpt/options/generate/generator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev_gpt/options/generate/generator.py b/dev_gpt/options/generate/generator.py index be50f58..315a493 100644 --- a/dev_gpt/options/generate/generator.py +++ b/dev_gpt/options/generate/generator.py @@ -144,8 +144,8 @@ metas: if content == {}: conversation = self.gpt_session.get_conversation(messages=[AIMessage(content=content_raw)]) content_raw = conversation.chat( - 'You must add the content' + (f' for {file_name_s[0]}' if len(file_name_s) == 1 else '') + - '''. Make sure to wrap any code in triple backticks in the beginning and end of any code. A general example is this: + 'You must add the content' + (f' for `{file_name_s[0]}`' if len(file_name_s) == 1 else '') + + '''. You must wrap any code in triple backticks at the beginning and end of any file.. A general example is this: **file_name.file_ending** ``` Date: Fri, 5 May 2023 16:43:13 +0200 Subject: [PATCH 15/30] :rocket: fix: use system message for playground --- dev_gpt/options/generate/generator.py | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/dev_gpt/options/generate/generator.py b/dev_gpt/options/generate/generator.py index 315a493..151201b 100644 --- a/dev_gpt/options/generate/generator.py +++ b/dev_gpt/options/generate/generator.py @@ -100,7 +100,7 @@ metas: destination_folder: str = None, file_name_s: List[str] = None, parse_result_fn: Callable = None, - use_system_message: bool = True, + use_custom_system_message: bool = True, **template_kwargs ): """This function generates file(s) using the given template and persists it/them in the given destination folder. @@ -115,7 +115,7 @@ metas: parse_result_fn (Callable, optional): A function that parses the generated content and returns a dictionary mapping file_name to its content. If no content could be extract, it returns an empty dictionary. Defaults to None. If None, default parsing is used which uses the file_name to extract from the generated content. - use_system_message (bool, optional): whether to use custom system message or not. Defaults to True. + use_custom_system_message (bool, optional): whether to use custom system message or not. Defaults to True. **template_kwargs: The keyword arguments to be passed to the template. """ if destination_folder is None: @@ -125,12 +125,15 @@ metas: parse_result_fn = self.get_default_parse_result_fn(file_name_s) print_colored('', f'\n\n############# {section_title} #############', 'blue') - system_introduction_message = _GPTConversation._create_system_message( - self.microservice_specification.task, - self.microservice_specification.test - ) + if use_custom_system_message: + system_introduction_message = _GPTConversation._create_system_message( + self.microservice_specification.task, + self.microservice_specification.test + ) + else: + system_introduction_message = SystemMessage(content='You are a helpful assistant.') conversation = self.gpt_session.get_conversation( - messages=[system_introduction_message] if use_system_message else [] + messages=[system_introduction_message] if use_custom_system_message else [] ) template_kwargs = {k: v for k, v in template_kwargs.items() if k in template.input_variables} if 'file_name' in template.input_variables and len(file_name_s) == 1: @@ -142,10 +145,12 @@ metas: ) content = parse_result_fn(content_raw) if content == {}: - conversation = self.gpt_session.get_conversation(messages=[AIMessage(content=content_raw)]) + conversation = self.gpt_session.get_conversation( + messages=[SystemMessage(content='You are a helpful assistant.'), AIMessage(content=content_raw)] + ) content_raw = conversation.chat( 'You must add the content' + (f' for `{file_name_s[0]}`' if len(file_name_s) == 1 else '') + - '''. You must wrap any code in triple backticks at the beginning and end of any file.. A general example is this: + '''. You must wrap any code in triple backticks at the beginning and end of it. A general example is this: **file_name.file_ending** ``` Date: Fri, 5 May 2023 17:26:26 +0200 Subject: [PATCH 16/30] :rocket: fix: example of for file wrapping --- dev_gpt/options/generate/generator.py | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/dev_gpt/options/generate/generator.py b/dev_gpt/options/generate/generator.py index 151201b..a88a023 100644 --- a/dev_gpt/options/generate/generator.py +++ b/dev_gpt/options/generate/generator.py @@ -148,14 +148,27 @@ metas: conversation = self.gpt_session.get_conversation( messages=[SystemMessage(content='You are a helpful assistant.'), AIMessage(content=content_raw)] ) - content_raw = conversation.chat( - 'You must add the content' + (f' for `{file_name_s[0]}`' if len(file_name_s) == 1 else '') + - '''. You must wrap any code in triple backticks at the beginning and end of it. A general example is this: - -**file_name.file_ending** + if len(file_name_s) == 1: + file_ending = file_name_s[0].split('.')[-1] + if file_ending == 'py': + tag = 'python' + elif file_ending == 'json': + tag = 'json' + else: + tag = '' + file_wrapping_example = f'''**{file_name_s[0]}** +```{tag} + +```''' + else: + file_wrapping_example = '''**file_name.file_ending** ``` ```''' + content_raw = conversation.chat( + 'You must add the content' + (f' for `{file_name_s[0]}`' if len(file_name_s) == 1 else '') + + '. You must wrap any file in triple backticks at the beginning and end of it. Like this:\n' + + file_wrapping_example ) content = parse_result_fn(content_raw) for _file_name, _file_content in content.items(): @@ -406,7 +419,7 @@ pytest template=template_was_error_seen_before, file_name_s=['response.json'], summarized_error=summarized_error, - previous_errors=f'- "{os.linesep}"'.join(self.previous_errors), + previous_errors=f'- "{os.linesep}"\n'.join(self.previous_errors), use_custom_system_message=False, )['response.json'] )['was_error_seen_before'].lower() == 'yes' @@ -420,7 +433,7 @@ pytest section_title='Check if solution was tried before', template=template_was_solution_tried_before, file_name_s=['response.json'], - tried_solutions=f'- "{os.linesep}"'.join(self.previous_solutions), + tried_solutions=f'- "{os.linesep}"\n'.join(self.previous_solutions), suggested_solution=_suggested_solution, use_custom_system_message=False, )['response.json'] From b8a3d12be559917014d2001ca9be7fb70773419a Mon Sep 17 00:00:00 2001 From: Joschka Braun Date: Mon, 8 May 2023 10:11:01 +0200 Subject: [PATCH 17/30] :rocket: fix: fix name --- dev_gpt/options/generate/generator.py | 4 ++-- dev_gpt/options/generate/templates_user.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dev_gpt/options/generate/generator.py b/dev_gpt/options/generate/generator.py index a88a023..f4dc278 100644 --- a/dev_gpt/options/generate/generator.py +++ b/dev_gpt/options/generate/generator.py @@ -417,7 +417,7 @@ pytest self.generate_and_persist_file( section_title='Check if error was seen before', template=template_was_error_seen_before, - file_name_s=['response.json'], + file_name_s=['was_error_seen_before.json'], summarized_error=summarized_error, previous_errors=f'- "{os.linesep}"\n'.join(self.previous_errors), use_custom_system_message=False, @@ -432,7 +432,7 @@ pytest self.generate_and_persist_file( section_title='Check if solution was tried before', template=template_was_solution_tried_before, - file_name_s=['response.json'], + file_name_s=['will_lead_to_different_actions.json'], tried_solutions=f'- "{os.linesep}"\n'.join(self.previous_solutions), suggested_solution=_suggested_solution, use_custom_system_message=False, diff --git a/dev_gpt/options/generate/templates_user.py b/dev_gpt/options/generate/templates_user.py index 34913a5..d51bb18 100644 --- a/dev_gpt/options/generate/templates_user.py +++ b/dev_gpt/options/generate/templates_user.py @@ -338,7 +338,7 @@ Now encountered error message: "{summarized_error}" Was this error message encountered before? Write down your final answer as json in the following format: -**response.json** +**was_error_seen_before.json** ```json {{"was_error_seen_before": ""}} ``` @@ -356,7 +356,7 @@ Suggested solution: "{suggested_solution}" Will the suggested solution lead to different actions than the previously tried solutions? Write down your final answer as json in the following format: -**response.json** +**will_lead_to_different_actions.json** ```json {{"will_lead_to_different_actions": ""}} ``` From 9f24ee9c75948f88168f3ce94a652eec43cab383 Mon Sep 17 00:00:00 2001 From: Joschka Braun Date: Mon, 8 May 2023 10:19:05 +0200 Subject: [PATCH 18/30] :rocket: fix: fix typo --- dev_gpt/options/generate/generator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev_gpt/options/generate/generator.py b/dev_gpt/options/generate/generator.py index f4dc278..0e4bfdb 100644 --- a/dev_gpt/options/generate/generator.py +++ b/dev_gpt/options/generate/generator.py @@ -421,7 +421,7 @@ pytest summarized_error=summarized_error, previous_errors=f'- "{os.linesep}"\n'.join(self.previous_errors), use_custom_system_message=False, - )['response.json'] + )['was_error_seen_before.json'] )['was_error_seen_before'].lower() == 'yes' suggested_solution = None @@ -436,7 +436,7 @@ pytest tried_solutions=f'- "{os.linesep}"\n'.join(self.previous_solutions), suggested_solution=_suggested_solution, use_custom_system_message=False, - )['response.json'] + )['will_lead_to_different_actions.json'] )['will_lead_to_different_actions'].lower() == 'no' if not was_solution_tried_before: suggested_solution = _suggested_solution From fdc8d0414c8268076e6b29cd3d67672db49fc942 Mon Sep 17 00:00:00 2001 From: Joschka Braun Date: Mon, 8 May 2023 10:39:54 +0200 Subject: [PATCH 19/30] :rocket: fix: fix typo --- dev_gpt/options/generate/generator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev_gpt/options/generate/generator.py b/dev_gpt/options/generate/generator.py index 0e4bfdb..63fe836 100644 --- a/dev_gpt/options/generate/generator.py +++ b/dev_gpt/options/generate/generator.py @@ -419,7 +419,7 @@ pytest template=template_was_error_seen_before, file_name_s=['was_error_seen_before.json'], summarized_error=summarized_error, - previous_errors=f'- "{os.linesep}"\n'.join(self.previous_errors), + previous_errors='- "' + f'"{os.linesep}- "'.join(self.previous_errors) + '"', use_custom_system_message=False, )['was_error_seen_before.json'] )['was_error_seen_before'].lower() == 'yes' @@ -433,7 +433,7 @@ pytest section_title='Check if solution was tried before', template=template_was_solution_tried_before, file_name_s=['will_lead_to_different_actions.json'], - tried_solutions=f'- "{os.linesep}"\n'.join(self.previous_solutions), + tried_solutions='- "' + f'"{os.linesep}- "'.join(self.previous_solutions) + '"', suggested_solution=_suggested_solution, use_custom_system_message=False, )['will_lead_to_different_actions.json'] From 5377b214dca46618a6feaf98355bddf5201b37a8 Mon Sep 17 00:00:00 2001 From: Joschka Braun Date: Mon, 8 May 2023 15:40:08 +0200 Subject: [PATCH 20/30] :rocket: feat: add explicit response format --- dev_gpt/options/generate/generator.py | 9 +++++++-- dev_gpt/options/generate/templates_user.py | 22 ++++++++++++++-------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/dev_gpt/options/generate/generator.py b/dev_gpt/options/generate/generator.py index 63fe836..044f3bc 100644 --- a/dev_gpt/options/generate/generator.py +++ b/dev_gpt/options/generate/generator.py @@ -27,7 +27,7 @@ from dev_gpt.options.generate.templates_user import template_generate_microservi template_chain_of_thought, template_summarize_error, \ template_solve_apt_get_dependency_issue, template_pm_task_iteration, \ template_pm_test_iteration, template_suggest_solutions_code_issue, template_was_error_seen_before, \ - template_was_solution_tried_before + template_was_solution_tried_before, response_format_was_error_seen_before, response_format_was_solution_tried_before from dev_gpt.options.generate.ui import get_random_employee from dev_gpt.utils.io import persist_file, get_all_microservice_files_with_content, get_microservice_path from dev_gpt.utils.string_tools import print_colored @@ -101,6 +101,7 @@ metas: file_name_s: List[str] = None, parse_result_fn: Callable = None, use_custom_system_message: bool = True, + response_format_example: str = None, **template_kwargs ): """This function generates file(s) using the given template and persists it/them in the given destination folder. @@ -148,7 +149,9 @@ metas: conversation = self.gpt_session.get_conversation( messages=[SystemMessage(content='You are a helpful assistant.'), AIMessage(content=content_raw)] ) - if len(file_name_s) == 1: + if response_format_example is not None: + file_wrapping_example = response_format_example + elif len(file_name_s) == 1: file_ending = file_name_s[0].split('.')[-1] if file_ending == 'py': tag = 'python' @@ -421,6 +424,7 @@ pytest summarized_error=summarized_error, previous_errors='- "' + f'"{os.linesep}- "'.join(self.previous_errors) + '"', use_custom_system_message=False, + response_format_example=response_format_was_error_seen_before, )['was_error_seen_before.json'] )['was_error_seen_before'].lower() == 'yes' @@ -436,6 +440,7 @@ pytest tried_solutions='- "' + f'"{os.linesep}- "'.join(self.previous_solutions) + '"', suggested_solution=_suggested_solution, use_custom_system_message=False, + response_format_example=response_format_was_solution_tried_before, )['will_lead_to_different_actions.json'] )['will_lead_to_different_actions'].lower() == 'no' if not was_solution_tried_before: diff --git a/dev_gpt/options/generate/templates_user.py b/dev_gpt/options/generate/templates_user.py index d51bb18..930c871 100644 --- a/dev_gpt/options/generate/templates_user.py +++ b/dev_gpt/options/generate/templates_user.py @@ -330,6 +330,12 @@ After thinking about the possible solutions, output them as JSON ranked from bes ) +response_format_was_error_seen_before = '''**was_error_seen_before.json** +```json +{{"was_error_seen_before": ""}} +```''' + + template_was_error_seen_before = PromptTemplate.from_template( '''Previously encountered error messages: {previous_errors} @@ -338,15 +344,18 @@ Now encountered error message: "{summarized_error}" Was this error message encountered before? Write down your final answer as json in the following format: -**was_error_seen_before.json** -```json -{{"was_error_seen_before": ""}} -``` +''' + response_format_was_error_seen_before + ''' Note that you must obey the double asterisk and triple backtick syntax from above. ''' ) +response_format_was_solution_tried_before = '''**will_lead_to_different_actions.json** +```json +{{"will_lead_to_different_actions": ""}} +```''' + + template_was_solution_tried_before = PromptTemplate.from_template( '''Previously tried solutions: {tried_solutions} @@ -356,10 +365,7 @@ Suggested solution: "{suggested_solution}" Will the suggested solution lead to different actions than the previously tried solutions? Write down your final answer as json in the following format: -**will_lead_to_different_actions.json** -```json -{{"will_lead_to_different_actions": ""}} -``` +''' + response_format_was_solution_tried_before + ''' Note that you must obey the double asterisk and triple backtick syntax from above.''' ) From 9ef6e82171598ac09b911154383786076483ccd1 Mon Sep 17 00:00:00 2001 From: Joschka Braun Date: Mon, 8 May 2023 16:45:28 +0200 Subject: [PATCH 21/30] :rocket: feat: add explicit response format for solutions --- dev_gpt/options/generate/generator.py | 4 +++- dev_gpt/options/generate/templates_user.py | 17 ++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/dev_gpt/options/generate/generator.py b/dev_gpt/options/generate/generator.py index 044f3bc..7f08571 100644 --- a/dev_gpt/options/generate/generator.py +++ b/dev_gpt/options/generate/generator.py @@ -27,7 +27,8 @@ from dev_gpt.options.generate.templates_user import template_generate_microservi template_chain_of_thought, template_summarize_error, \ template_solve_apt_get_dependency_issue, template_pm_task_iteration, \ template_pm_test_iteration, template_suggest_solutions_code_issue, template_was_error_seen_before, \ - template_was_solution_tried_before, response_format_was_error_seen_before, response_format_was_solution_tried_before + template_was_solution_tried_before, response_format_was_error_seen_before, \ + response_format_was_solution_tried_before, response_format_suggest_solutions from dev_gpt.options.generate.ui import get_random_employee from dev_gpt.utils.io import persist_file, get_all_microservice_files_with_content, get_microservice_path from dev_gpt.utils.string_tools import print_colored @@ -412,6 +413,7 @@ pytest task_description=self.microservice_specification.task, test_description=self.microservice_specification.test, all_files_string=all_files_string, + response_format_example=response_format_suggest_solutions, )['solutions.json'] ) diff --git a/dev_gpt/options/generate/templates_user.py b/dev_gpt/options/generate/templates_user.py index 930c871..51867f5 100644 --- a/dev_gpt/options/generate/templates_user.py +++ b/dev_gpt/options/generate/templates_user.py @@ -294,6 +294,15 @@ Only output the apt-get-packages.json file. ) +response_format_suggest_solutions = '''**solutions.json** +```json +{{ + "1": "", + "2": "<2nd best solution>" +}} +```''' + + template_suggest_solutions_code_issue = PromptTemplate.from_template( '''General rules: ''' + not_allowed_function_string + ''' @@ -320,13 +329,7 @@ Note that any changes needed to make the test pass must be written under the con After thinking about the possible solutions, output them as JSON ranked from best to worst. Like this: -**solutions.json** -```json -{{ - "1": "", - "2": "<2nd best solution>" -}} -```''' +''' + response_format_suggest_solutions ) From cf671ffa8ce56fc1083af53eab1199189351f3f4 Mon Sep 17 00:00:00 2001 From: Joschka Braun Date: Tue, 9 May 2023 09:42:09 +0200 Subject: [PATCH 22/30] :rocket: feat: ensure json loads --- dev_gpt/options/generate/templates_user.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dev_gpt/options/generate/templates_user.py b/dev_gpt/options/generate/templates_user.py index 51867f5..edb8371 100644 --- a/dev_gpt/options/generate/templates_user.py +++ b/dev_gpt/options/generate/templates_user.py @@ -289,7 +289,7 @@ The output is: {{"packages": [libgl1-mesa-glx]}} ``` Note that you must not output the content of any other files like the Dockerfile or requirements.txt. -Only output the apt-get-packages.json file. +Only output the apt-get-packages.json file. Ensure the response can be parsed by Python json.loads ''' ) @@ -329,7 +329,8 @@ Note that any changes needed to make the test pass must be written under the con After thinking about the possible solutions, output them as JSON ranked from best to worst. Like this: -''' + response_format_suggest_solutions +''' + response_format_suggest_solutions + ''' +Ensure the response can be parsed by Python json.loads''' ) @@ -348,7 +349,7 @@ Was this error message encountered before? Write down your final answer as json in the following format: ''' + response_format_was_error_seen_before + ''' -Note that you must obey the double asterisk and triple backtick syntax from above. +Note that you must obey the double asterisk and triple backtick syntax from above. Ensure the response can be parsed by Python json.loads ''' ) @@ -369,7 +370,7 @@ Will the suggested solution lead to different actions than the previously tried Write down your final answer as json in the following format: ''' + response_format_was_solution_tried_before + ''' -Note that you must obey the double asterisk and triple backtick syntax from above.''' +Note that you must obey the double asterisk and triple backtick syntax from above. Ensure the response can be parsed by Python json.loads''' ) From 82e1e88ea36976226981c852e8cc401a73fa32d0 Mon Sep 17 00:00:00 2001 From: Joschka Braun Date: Tue, 9 May 2023 10:09:22 +0200 Subject: [PATCH 23/30] :rocket: fix: don't output docker --- dev_gpt/options/generate/templates_user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_gpt/options/generate/templates_user.py b/dev_gpt/options/generate/templates_user.py index edb8371..2673cae 100644 --- a/dev_gpt/options/generate/templates_user.py +++ b/dev_gpt/options/generate/templates_user.py @@ -288,8 +288,8 @@ The output is: ```json {{"packages": [libgl1-mesa-glx]}} ``` -Note that you must not output the content of any other files like the Dockerfile or requirements.txt. Only output the apt-get-packages.json file. Ensure the response can be parsed by Python json.loads +Note that you must not output the content of any other. Especially don't output the Dockerfile or requirements.txt. ''' ) From 335518f848e0f6aeb545a3777ea861a9c29d8ee9 Mon Sep 17 00:00:00 2001 From: Joschka Braun Date: Tue, 9 May 2023 10:25:29 +0200 Subject: [PATCH 24/30] :rocket: fix: extraction --- dev_gpt/options/generate/generator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_gpt/options/generate/generator.py b/dev_gpt/options/generate/generator.py index 7f08571..b5f247a 100644 --- a/dev_gpt/options/generate/generator.py +++ b/dev_gpt/options/generate/generator.py @@ -170,7 +170,7 @@ metas: ```''' content_raw = conversation.chat( - 'You must add the content' + (f' for `{file_name_s[0]}`' if len(file_name_s) == 1 else '') + + 'Based on your previous response, only output the content' + (f' for `{file_name_s[0]}`' if len(file_name_s) == 1 else '') + '. You must wrap any file in triple backticks at the beginning and end of it. Like this:\n' + file_wrapping_example ) From d474082964b6d7221a017e41061f1b64637efff3 Mon Sep 17 00:00:00 2001 From: Joschka Braun Date: Tue, 9 May 2023 14:40:45 +0200 Subject: [PATCH 25/30] :rocket: fix: ci --- .github/workflows/ci.yml | 2 +- dev_gpt/options/generate/generator.py | 2 +- dev_gpt/options/generate/templates_user.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b3b71b3..abfc233 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ jobs: strategy: fail-fast: false matrix: - group: [0, 1, 2, 3, 4, 5] + group: [0, 1, 2, 3, 4] steps: - uses: actions/checkout@v2 - name: Set up Python 3.8 diff --git a/dev_gpt/options/generate/generator.py b/dev_gpt/options/generate/generator.py index b5f247a..50057d8 100644 --- a/dev_gpt/options/generate/generator.py +++ b/dev_gpt/options/generate/generator.py @@ -171,7 +171,7 @@ metas: ```''' content_raw = conversation.chat( 'Based on your previous response, only output the content' + (f' for `{file_name_s[0]}`' if len(file_name_s) == 1 else '') + - '. You must wrap any file in triple backticks at the beginning and end of it. Like this:\n' + + '. Like this:\n' + file_wrapping_example ) content = parse_result_fn(content_raw) diff --git a/dev_gpt/options/generate/templates_user.py b/dev_gpt/options/generate/templates_user.py index 2673cae..e020faa 100644 --- a/dev_gpt/options/generate/templates_user.py +++ b/dev_gpt/options/generate/templates_user.py @@ -288,7 +288,7 @@ The output is: ```json {{"packages": [libgl1-mesa-glx]}} ``` -Only output the apt-get-packages.json file. Ensure the response can be parsed by Python json.loads +Only output content of the apt-get-packages.json file. Ensure the response can be parsed by Python json.loads Note that you must not output the content of any other. Especially don't output the Dockerfile or requirements.txt. ''' ) From 8a1b49281c8c23a5184608de4dfeaff0281e431e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Ho=CC=88nicke?= Date: Thu, 11 May 2023 09:35:04 +0200 Subject: [PATCH 26/30] =?UTF-8?q?=E2=9E=B0=20feat:=20avoid=20loops?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dev_gpt/options/generate/generator.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dev_gpt/options/generate/generator.py b/dev_gpt/options/generate/generator.py index 277986a..22fde4a 100644 --- a/dev_gpt/options/generate/generator.py +++ b/dev_gpt/options/generate/generator.py @@ -7,6 +7,7 @@ from typing import Callable from typing import List, Text, Optional from langchain import PromptTemplate +from langchain.schema import SystemMessage from pydantic.dataclasses import dataclass from dev_gpt.apis import gpt @@ -24,12 +25,10 @@ from dev_gpt.options.generate.templates_user import template_generate_microservi template_solve_pip_dependency_issue, template_is_dependency_issue, template_generate_playground, \ template_generate_function, template_generate_test, template_generate_requirements, \ template_chain_of_thought, template_summarize_error, \ - template_solve_apt_get_dependency_issue, template_pm_task_iteration, \ - template_pm_test_iteration, template_suggest_solutions_code_issue, template_was_error_seen_before, \ + template_solve_apt_get_dependency_issue, \ + template_suggest_solutions_code_issue, template_was_error_seen_before, \ template_was_solution_tried_before, response_format_was_error_seen_before, \ response_format_was_solution_tried_before, response_format_suggest_solutions -from dev_gpt.options.generate.ui import get_random_employee - template_solve_apt_get_dependency_issue from dev_gpt.utils.io import persist_file, get_all_microservice_files_with_content, get_microservice_path from dev_gpt.utils.string_tools import print_colored From 9931f97dde9cc4e4a2bd89a0e9a47ce7cda50480 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Ho=CC=88nicke?= Date: Thu, 11 May 2023 09:48:00 +0200 Subject: [PATCH 27/30] =?UTF-8?q?=E2=9E=B0=20feat:=20avoid=20loops?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dev_gpt/options/generate/generator.py | 2 +- test/integration/test_generator.py | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/dev_gpt/options/generate/generator.py b/dev_gpt/options/generate/generator.py index 22fde4a..22aabe7 100644 --- a/dev_gpt/options/generate/generator.py +++ b/dev_gpt/options/generate/generator.py @@ -7,7 +7,7 @@ from typing import Callable from typing import List, Text, Optional from langchain import PromptTemplate -from langchain.schema import SystemMessage +from langchain.schema import SystemMessage, AIMessage from pydantic.dataclasses import dataclass from dev_gpt.apis import gpt diff --git a/test/integration/test_generator.py b/test/integration/test_generator.py index e03f3ce..f4a8f7a 100644 --- a/test/integration/test_generator.py +++ b/test/integration/test_generator.py @@ -70,6 +70,26 @@ def test_generation_level_2(microservice_dir, mock_input_sequence): ) assert generator.generate() == 0 +@pytest.mark.parametrize('mock_input_sequence', [['y', 'https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png']], indirect=True) +def test_generation_level_2_svg(microservice_dir, mock_input_sequence): + """ + Requirements: + coding challenge: ✅ + pip packages: ✅ + environment: ❌ + GPT-3.5-turbo: ❌ + APIs: ❌ + Databases: ❌ + """ + os.environ['VERBOSE'] = 'true' + generator = Generator( + "Get a png as input and return a vectorized version as svg.", + str(microservice_dir), + 'gpt-3.5-turbo' + ) + assert generator.generate() == 0 + + @pytest.mark.parametrize('mock_input_sequence', [['y', 'yfinance.Ticker("MSFT").info']], indirect=True) def test_generation_level_3(microservice_dir, mock_input_sequence): """ From 6201b4a94265d0aa1143ce489341e85bf4994b87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Ho=CC=88nicke?= Date: Sat, 13 May 2023 21:34:15 +0200 Subject: [PATCH 28/30] =?UTF-8?q?=E2=9E=B0=20feat:=20avoid=20loop?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dev_gpt/options/generate/templates_user.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/dev_gpt/options/generate/templates_user.py b/dev_gpt/options/generate/templates_user.py index a726b17..45ad093 100644 --- a/dev_gpt/options/generate/templates_user.py +++ b/dev_gpt/options/generate/templates_user.py @@ -37,10 +37,15 @@ The executor name must fulfill the following criteria: - only consists of lower and upper case characters - end with Executor. -The output is a the raw string wrapped into ``` and starting with **name.txt** like this: +The name is witten in the following format: **name.txt** ``` -PDFParserExecutor + +``` +Example for: "Get a png as input and return a vectorized version as svg.": +**name.txt** +``` +PngToSvgExecutor ```''' ) From 2e3431e667df5dd543ea8e6ddba29119c9250242 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20Ho=CC=88nicke?= Date: Sat, 13 May 2023 21:43:15 +0200 Subject: [PATCH 29/30] =?UTF-8?q?=E2=9E=B0=20feat:=20avoid=20loop?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dev_gpt/options/generate/templates_user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev_gpt/options/generate/templates_user.py b/dev_gpt/options/generate/templates_user.py index 45ad093..3f6a07f 100644 --- a/dev_gpt/options/generate/templates_user.py +++ b/dev_gpt/options/generate/templates_user.py @@ -37,7 +37,7 @@ The executor name must fulfill the following criteria: - only consists of lower and upper case characters - end with Executor. -The name is witten in the following format: +Your response must exactly match the following block code format (double asterisks for the file name and triple backticks for the file block): **name.txt** ``` From 56042201ec663f4dc65985b609c2567f8841bafa Mon Sep 17 00:00:00 2001 From: Han Xiao Date: Tue, 16 May 2023 11:46:42 +0200 Subject: [PATCH 30/30] chore: fix discord link --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 99c1292..61eb866 100644 --- a/README.md +++ b/README.md @@ -49,9 +49,8 @@ Your imagination is the limit! Downloads - - Discord Chat - + +