refactor: cleanup

This commit is contained in:
Florian Hönicke
2023-05-09 23:30:53 +02:00
parent c29c212e12
commit 53e627aa81
7 changed files with 123 additions and 86 deletions

View File

@@ -0,0 +1,57 @@
import json
from dev_gpt.apis.gpt import ask_gpt
from dev_gpt.options.generate.chains.extract_information import extract_information
from dev_gpt.options.generate.parser import identity_parser
from dev_gpt.options.generate.prompt_factory import context_to_string
def auto_refine_description(context):
context['microservice_description'] = ask_gpt(
better_description_prompt,
identity_parser,
context_string=context_to_string(context)
)
context['request_schema'] = ask_gpt(
generate_request_schema_prompt,
identity_parser,
context_string=context_to_string(context)
)
context['response_schema'] = ask_gpt(
generate_output_schema_prompt,
identity_parser,
context_string=context_to_string(context)
)
context['microservice_description'] = ask_gpt(
summarize_description_and_schemas_prompt,
identity_parser,
context_string=context_to_string(context)
)
# details = extract_information(context['microservice_description'], ['database connection details', 'URL', 'secret'])
# if details:
# context['microservice_description'] += '\n\nAdditional information:' + json.dumps(details, indent=4)
# del context['details']
better_description_prompt = f'''{{context_string}}
Update the description of the Microservice to make it more precise without adding or removing information.
Note: the output must be a list of tasks the Microservice has to perform.
Example for the description: "return the average temperature of the 5 days weather forecast for a given location."
1. get the 5 days weather forcast from the https://openweathermap.org/ API
2. extract the temperature from the response
3. calculate the average temperature'''
generate_request_schema_prompt = '''{context_string}
Generate the lean request json schema of the Microservice.
Note: If you are not sure about the details, then come up with the minimal number of parameters possible.'''
generate_output_schema_prompt = '''{context_string}
Generate the lean response json schema for the Microservice.
Note: If you are not sure about the details, then come up with the minimal number of parameters possible.'''
summarize_description_and_schemas_prompt = '''{context_string}
Write an updated microservice description by incorporating information about the request and response parameters in a concise way without losing any information.
Note: You must not mention any details about algorithms or the technical implementation.
Note: You must not mention that there is a request and response JSON schema
Note: You must not use any formatting like triple backticks.'''

View File

@@ -0,0 +1,29 @@
from typing import Dict
from dev_gpt.apis.gpt import ask_gpt
from dev_gpt.options.generate.chains.question_answering import answer_yes_no_question
from dev_gpt.options.generate.parser import identity_parser, boolean_parser
def extract_information(text, info_keys) -> Dict[str, str]:
extracted_infos = {}
for info_key in info_keys:
is_information_in_text = answer_yes_no_question(text, f'Is a {info_key} mentioned above?')
if is_information_in_text:
extracted_info = ask_gpt(
extract_information_prompt,
identity_parser,
text=text,
info_key=info_key
)
extracted_infos[info_key] = extracted_info
return extracted_infos
extract_information_prompt = '''\
{text}
Your task:
Return all {info_key}s from above.'
Note: you must only output your answer.
'''

View File

@@ -4,13 +4,14 @@ from dev_gpt.options.generate.parser import identity_parser
def get_user_input_if_needed(context, conditions, question_gen_prompt_part):
if all([c(context) for c in conditions]):
return ask_gpt(
if all([c(context_to_string(context)) for c in conditions]):
question_to_user = ask_gpt(
generate_question_for_file_input_prompt,
identity_parser,
context_string=context_to_string(context),
question_gen_prompt_part=question_gen_prompt_part
)
return input(question_to_user)
return None
generate_question_for_file_input_prompt = '''\

View File

@@ -0,0 +1,16 @@
from dev_gpt.apis.gpt import ask_gpt
from dev_gpt.options.generate.parser import boolean_parser
def answer_yes_no_question(text, question):
prompt = question_prompt.format(
question=question,
text=text
)
return ask_gpt(prompt, boolean_parser)
question_prompt = '''\
{text}
{question}
Note: You must answer "yes" or "no".
'''

View File

@@ -1,22 +1,10 @@
from dev_gpt.apis.gpt import ask_gpt
from dev_gpt.options.generate.prompt_factory import context_to_string
from dev_gpt.options.generate.parser import boolean_parser
from dev_gpt.options.generate.chains.question_answering import answer_yes_no_question
def is_true(question):
def fn(context):
prompt = question_prompt.format(
question=question,
context_string=context_to_string(context)
)
return ask_gpt(prompt, boolean_parser)
def is_question_true(question):
def fn(text):
return answer_yes_no_question(text, question)
return fn
def is_false(question):
return lambda context: not is_true(question)(context)
question_prompt = '''\
{context_string}
{question}
Note: You must answer "yes" or "no".
'''
def is_question_false(question):
return lambda context: not is_question_true(question)(context)

View File

@@ -1,7 +1,8 @@
from dev_gpt.apis import gpt
from dev_gpt.apis.gpt import ask_gpt
from dev_gpt.options.generate.chains.auto_refine_description import auto_refine_description
from dev_gpt.options.generate.chains.user_confirmation_feedback_loop import user_feedback_loop
from dev_gpt.options.generate.condition import is_false, is_true
from dev_gpt.options.generate.condition import is_question_false, is_question_true
from dev_gpt.options.generate.chains.get_user_input_if_needed import get_user_input_if_needed
from dev_gpt.options.generate.parser import identity_parser
# from dev_gpt.options.generate.pm.task_tree_schema import TaskTree
@@ -38,11 +39,9 @@ Description of the microservice:
# return sub_task_tree
def refine_description(self, microservice_description):
context = {
'microservice_description': microservice_description
}
self.auto_refine_description(context)
user_feedback_loop(context, microservice_description)
context = {'microservice_description': microservice_description}
auto_refine_description(context)
microservice_description = user_feedback_loop(context, context['microservice_description'])
test_description = ask_gpt(
generate_test_description_prompt,
@@ -56,8 +55,8 @@ Description of the microservice:
'Response schema': context['response_schema'],
},
conditions=[
is_true('Does request schema contain an example file url?'),
is_false('Is input url specified in the description?'),
is_question_true('Does request schema require a file?'),
# is_question_false('Is input url specified in the description?'),
],
question_gen_prompt_part="Generate a question that asks for an example file url.",
)
@@ -66,26 +65,7 @@ Description of the microservice:
return microservice_description, test_description
def auto_refine_description(self, context):
context['microservice_description'] = ask_gpt(
better_description_prompt,
identity_parser,
**context
)
context['request_schema'] = ask_gpt(
generate_request_schema_prompt,
identity_parser,
**context
)
context['response_schema'] = ask_gpt(
generate_output_schema_prompt,
identity_parser,
**context
)
context['microservice_description'] = ask_gpt(
summarize_description_and_schemas_prompt, identity_parser,
**context
)
# def get_nlp_fns(self, microservice_description):
# return ask_gpt(
@@ -229,28 +209,10 @@ Microservice description:
{microservice_description}
```'''
better_description_prompt = client_description + '''
Update the description of the Microservice to make it more precise without adding or removing information.
Note: the output must be a list of tasks the Microservice has to perform.
Example for the description: "return the average temperature of the 5 days weather forecast for a given location."
1. get the 5 days weather forcast from the https://openweathermap.org/ API
2. extract the temperature from the response
3. calculate the average temperature'''
# better_description_prompt = client_description + '''
# Update the description of the Microservice to make it more precise without adding or removing information.'''
generate_request_schema_prompt = client_description + '''
Generate the lean request json schema of the Microservice.
Note: If you are not sure about the details, then come up with the minimal number of parameters possible.'''
generate_output_schema_prompt = client_description + '''
request json schema:
```
{request_schema}
```
Generate the lean response json schema for the Microservice.
Note: If you are not sure about the details, then come up with the minimal number of parameters possible.'''
# If we want to activate this back, then it first needs to work. Currently, it outputs "no" for too many cases.
# is_feedback_valuable_prompt = client_description + '''
@@ -263,20 +225,6 @@ Note: If you are not sure about the details, then come up with the minimal numbe
# Note: If the user does not want to provide feedback, then you must answer "no".'''
summarize_description_and_schemas_prompt = client_description + '''
Request json schema:
```
{request_schema}
```
Response json schema:
```
{response_schema}
```
Write an updated microservice description by incorporating information about the request and response parameters in a concise way without losing any information.
Note: You must not mention any details about algorithms or the technical implementation.
Note: You must not mention that there is a request and response JSON schema
Note: You must not use any formatting like triple backticks.'''
# summarize_description_prompt = client_description + '''

View File

@@ -51,7 +51,7 @@ But hey, at least SOMEONE's enjoying their lunch. #officelife\'''',
assert generator.generate() == 0
@pytest.mark.parametrize('mock_input_sequence', [['y']], indirect=True)
@pytest.mark.parametrize('mock_input_sequence', [['y', 'https://www.africau.edu/images/default/sample.pdf']], indirect=True)
def test_generation_level_2(microservice_dir, mock_input_sequence):
"""
Requirements:
@@ -64,7 +64,7 @@ def test_generation_level_2(microservice_dir, mock_input_sequence):
"""
os.environ['VERBOSE'] = 'true'
generator = Generator(
"The input is a PDF like https://www.africau.edu/images/default/sample.pdf and the output the summarized text (50 words).",
"The input is a PDF and the output the summarized text (50 words).",
str(microservice_dir),
'gpt-3.5-turbo'
)
@@ -95,7 +95,7 @@ Example input: 'AAPL'
)
assert generator.generate() == 0
@pytest.mark.parametrize('mock_input_sequence', [['y']], indirect=True)
@pytest.mark.parametrize('mock_input_sequence', [['y', 'https://www.signalogic.com/melp/EngSamples/Orig/ENG_M.wav']], indirect=True)
def test_generation_level_4(microservice_dir, mock_input_sequence):
"""
Requirements:
@@ -125,14 +125,13 @@ print('This is the text from the audio file:', response.json()['text'])
2. Summarize the text (~50 words) while still maintaining the key facts.
3. Create an audio file of the summarized text using a tts library.
4. Return the the audio file as base64 encoded binary.
Example input file: https://www.signalogic.com/melp/EngSamples/Orig/ENG_M.wav
''',
str(microservice_dir),
'gpt-4'
)
assert generator.generate() == 0
@pytest.mark.parametrize('mock_input_sequence', [['y']], indirect=True)
@pytest.mark.parametrize('mock_input_sequence', [['y', 'https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/PNG_transparency_demonstration_1.png/560px-PNG_transparency_demonstration_1.png']], indirect=True)
def test_generation_level_5(microservice_dir, mock_input_sequence):
"""
Requirements:
@@ -165,7 +164,6 @@ Result format:
The description is then used to generate a joke.
The joke is the put on the image.
The output is the image with the joke on it.
Example input image: https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/PNG_transparency_demonstration_1.png/560px-PNG_transparency_demonstration_1.png
''',
str(microservice_dir),
'gpt-3.5-turbo'