fix: self healing response parser

This commit is contained in:
Florian Hönicke
2023-05-26 17:35:00 +02:00
parent 70b37f7d14
commit 43bcfc31e2
5 changed files with 80 additions and 10 deletions

View File

@@ -0,0 +1,32 @@
import traceback
def fix_based_on_error_chain(context_string, content_type, original_content, parser):
from dev_gpt.apis.gpt import ask_gpt
current_content = original_content
for i in range(3):
try:
return parser(current_content)
except Exception:
error_message = traceback.format_exc()
current_content = ask_gpt(fix_based_on_error_prompt, context_string=context_string, content_type=content_type, current_content=current_content, error_message=error_message)
raise Exception(f'Could not fix the content:\n{original_content}')
fix_based_on_error_prompt = '''\
Context:
{context_string}
Original {content_type}:
{current_content}
Error message:
{error_message}
Your task:
You must return the fixed {content_type}.
Most importantly, you are not allowed to return something else - only the fixed {content_type}.
'''

View File

@@ -21,6 +21,7 @@ from dev_gpt.constants import FILE_AND_TAG_PAIRS, NUM_IMPLEMENTATION_STRATEGIES,
IMPLEMENTATION_FILE_TAG, LANGUAGE_PACKAGES, UNNECESSARY_PACKAGES, DOCKER_BASE_IMAGE_VERSION, SEARCH_PACKAGES, \
INDICATOR_TO_IMPORT_STATEMENT
from dev_gpt.options.generate.conversation_logger import Timer
from dev_gpt.options.generate.parser import json_parser
from dev_gpt.options.generate.pm.pm import PM
from dev_gpt.options.generate.templates_user import template_generate_microservice_name, \
template_generate_possible_packages, \
@@ -439,8 +440,7 @@ pytest
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(
json_string = self.generate_and_persist_file(
section_title='Suggest solution for code issue',
template=template_suggest_solutions_code_issue,
file_name_s=['solutions.json'],
@@ -449,9 +449,10 @@ pytest
test_description=self.microservice_specification.test,
all_files_string=all_files_string,
response_format_example=response_format_suggest_solutions,
)['solutions.json']
)
suggested_solutions = json_parser(json_string)['solutions.json']
if len(self.previous_errors) > 0:
was_error_seen_before = json.loads(
self.generate_and_persist_file(

View File

@@ -1,6 +1,8 @@
import json
import re
from dev_gpt.options.generate.chains.fix_based_on_error import fix_based_on_error_chain
def identity_parser(x):
return x
@@ -16,6 +18,10 @@ def boolean_parser(x):
def json_parser(x):
if '```' in x:
pattern = r'```(.+)```'
x = re.findall(pattern, x, re.DOTALL)[-1]
pattern = r'```(json)?(.+)```'
x = re.findall(pattern, x, re.DOTALL)[-1][-1]
return json.loads(x)
def self_healing_json_parser(original_json_string):
return fix_based_on_error_chain('I want to load my JSON string using json.loads(x) but get the following error:', 'JSON',
original_json_string, parser=json_parser)

View File

@@ -310,14 +310,22 @@ Output the apt-get packages that need to be placed at {{APT_GET_PACKAGES}} as js
```json
{{"packages": ["<package1>", "<package2>"]}}
```
Example:
Error is about missing package `libgl1-mesa-glx`.
The output is:
Example output for an error is about missing package `libgl1-mesa-glx`:
**apt-get-packages.json**
```json
{{"packages": [libgl1-mesa-glx]}}
```
Only output content of the apt-get-packages.json file. Ensure the response can be parsed by Python json.loads
Negative example1:
```json
{{"packages": [libgl1-mesa-glx]}}
```
Negative example2:
{{"packages": [libgl1-mesa-glx]}}
Note: Only output content of the apt-get-packages.json file.
Note: you must not output the content of any other. Especially don't output the Dockerfile or requirements.txt.
Note: the first line you output must be: **apt-get-packages.json**
'''

View File

@@ -1,6 +1,11 @@
import os
import pytest
from dev_gpt.apis.gpt import GPTSession
from dev_gpt.options.generate.generator import Generator
from dev_gpt.options.generate.parser import self_healing_json_parser
def create_code_block(with_backticks, asterisks, with_highlight_info, file_name, start_inline, content):
code_block = f'''
@@ -42,3 +47,21 @@ def test_extract_content_from_result(plain_text, expected1, expected2):
parsed_result2 = Generator.extract_content_from_result(plain_text, 'test100.json', True, False)
assert parsed_result2 == expected2
def test_self_healing_json_parser(tmpdir):
os.environ['VERBOSE'] = 'true'
GPTSession(os.path.join(str(tmpdir), 'log.json'), model='gpt-3.5-turbo')
json_response = '''\
solutions.json
```json
{
"1": "Change line 7 of microservice.py to 'pdf_file = input_dict['pdf_file'].encode('latin-1')' to convert the bytes object to a string before passing it to PyPDF2.",
"2": "Change line 7 of microservice.py to 'pdf_file = input_dict['pdf_file'].decode('utf-8')' to decode the bytes object to a string before passing it to PyPDF2.",
"3": "Change line 13 of test_microservice.py to 'input_dict = {"pdf_file": 'Sample PDF file content'.encode('latin-1')}' to encode the string to a bytes object before passing it to func.",
"4": "Change line 13 of test_microservice.py to 'input_dict = {"pdf_file": 'Sample PDF file content'.decode('utf-8')}' to decode the string to a bytes object before passing it to func."
}
```'''
parsed_json = self_healing_json_parser(json_response)
for key in ['1', '2', '3', '4']:
assert key in parsed_json
assert 'Change' in parsed_json[key]