mirror of
https://github.com/aljazceru/dev-gpt.git
synced 2025-12-23 00:24:20 +01:00
⏪ fix: self healing response parser
This commit is contained in:
32
dev_gpt/options/generate/chains/fix_based_on_error.py
Normal file
32
dev_gpt/options/generate/chains/fix_based_on_error.py
Normal 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}.
|
||||
'''
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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**
|
||||
'''
|
||||
|
||||
@@ -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]
|
||||
Reference in New Issue
Block a user