mirror of
https://github.com/aljazceru/dev-gpt.git
synced 2025-12-21 07:34:20 +01:00
Merge branch 'main' of https://github.com/jina-ai/gptdeploy into refactor-langchain
# Conflicts: # src/apis/gpt.py # src/cli.py # src/options/generate/generator.py # src/options/generate/prompt_system.py # src/options/generate/prompt_tasks.py
This commit is contained in:
43
README.md
43
README.md
@@ -100,54 +100,67 @@ jc delete <microservice id>
|
|||||||
|
|
||||||
<img src="res/teaser.png" alt="QR Code Generator" width="600" />
|
<img src="res/teaser.png" alt="QR Code Generator" width="600" />
|
||||||
|
|
||||||
|
### Chemical Formula Visualization
|
||||||
|
```bash
|
||||||
|
generate --description "Convert a chemical formula into a 2D chemical structure diagram" --test "C=C, CN=C=O, CCC(=O)O" --path microservice
|
||||||
|
```
|
||||||
|
|
||||||
|
<img src="res/chemical_formula_example.png" alt="Chemical Formula Visualization" width="600" />
|
||||||
|
|
||||||
### Animal Detector
|
### Animal Detector
|
||||||
```bash
|
```bash
|
||||||
|
|
||||||
gptdeploy generate --description "Given an image, return the image with bounding boxes of all animals (https://pjreddie.com/media/files/yolov3.weights, https://raw.githubusercontent.com/pjreddie/darknet/master/cfg/yolov3.cfg)" --test "https://images.unsplash.com/photo-1444212477490-ca407925329e contains animals" --model gpt-4
|
gptdeploy generate --description "Given an image, return the image with bounding boxes of all animals (https://pjreddie.com/media/files/yolov3.weights, https://raw.githubusercontent.com/pjreddie/darknet/master/cfg/yolov3.cfg)" --test "https://images.unsplash.com/photo-1444212477490-ca407925329e contains animals" --model gpt-4 --path microservice
|
||||||
```
|
```
|
||||||
|
|
||||||
<img src="res/animal_detector_example.png" alt="Animal Detector" width="600" />
|
<img src="res/animal_detector_example.png" alt="Animal Detector" width="600" />
|
||||||
|
|
||||||
### Meme Generator
|
### Meme Generator
|
||||||
```bash
|
```bash
|
||||||
gptdeploy generate --description "Generate a meme from an image and a caption" --test "Surprised Pikachu: https://media.wired.com/photos/5f87340d114b38fa1f8339f9/master/w_1600%2Cc_limit/Ideas_Surprised_Pikachu_HD.jpg, TOP:When you discovered GPTDeploy" --model gpt-4
|
gptdeploy generate --description "Generate a meme from an image and a caption" --test "Surprised Pikachu: https://media.wired.com/photos/5f87340d114b38fa1f8339f9/master/w_1600%2Cc_limit/Ideas_Surprised_Pikachu_HD.jpg, TOP:When you discovered GPTDeploy" --model gpt-4 --path microservice
|
||||||
```
|
```
|
||||||
|
|
||||||
<img src="res/meme_example.png" alt="Meme Generator" width="600" />
|
<img src="res/meme_example.png" alt="Meme Generator" width="600" />
|
||||||
|
|
||||||
### Rhyme Generator
|
### Rhyme Generator
|
||||||
```bash
|
```bash
|
||||||
gptdeploy generate --description "Given a word, return a list of rhyming words using the datamuse api" --test "hello" --model gpt-4
|
gptdeploy generate --description "Given a word, return a list of rhyming words using the datamuse api" --test "hello" --model gpt-4 --path microservice
|
||||||
```
|
```
|
||||||
<img src="res/rhyme_generator_example.png" alt="Rhyme Generator" width="600" />
|
<img src="res/rhyme_generator_example.png" alt="Rhyme Generator" width="600" />
|
||||||
|
|
||||||
### Word Cloud Generator
|
### Word Cloud Generator
|
||||||
```bash
|
```bash
|
||||||
gptdeploy generate --description "Generate a word cloud from a given text" --test "Lorem ipsum dolor sit amet, consectetur adipiscing elit." --model gpt-4
|
gptdeploy generate --description "Generate a word cloud from a given text" --test "Lorem ipsum dolor sit amet, consectetur adipiscing elit." --model gpt-4 --path microservice
|
||||||
```
|
```
|
||||||
<img src="res/word_cloud_example.png" alt="Word Cloud Generator" width="600" />
|
<img src="res/word_cloud_example.png" alt="Word Cloud Generator" width="600" />
|
||||||
|
|
||||||
### 3d model info
|
### 3d model info
|
||||||
```bash
|
```bash
|
||||||
gptdeploy generate --description "Given a 3d object, return vertex count and face count" --test "https://raw.githubusercontent.com/polygonjs/polygonjs-assets/master/models/wolf.obj" --model gpt-4
|
gptdeploy generate --description "Given a 3d object, return vertex count and face count" --test "https://raw.githubusercontent.com/polygonjs/polygonjs-assets/master/models/wolf.obj" --model gpt-4 --path microservice
|
||||||
```
|
```
|
||||||
<img src="res/obj_info_example.png" alt="3D Model Info" width="600" />
|
<img src="res/obj_info_example.png" alt="3D Model Info" width="600" />
|
||||||
|
|
||||||
|
### 2d rendering of 3d model
|
||||||
|
```bash
|
||||||
|
gptdeploy generate --description "create a 2d rendering of a whole 3d object and x,y,z object rotation using trimesh and pyrender.OffscreenRenderer with os.environ['PYOPENGL_PLATFORM'] = 'egl' and freeglut3-dev library" --test "input: https://graphics.stanford.edu/courses/cs148-10-summer/as3/code/as3/teapot.obj output: assert the image is not completely white or black" --model gpt-4 --path microservice
|
||||||
|
```
|
||||||
|
<img src="res/obj_render_example.gif" alt="2D Rendering of 3D Model" width="600" />
|
||||||
|
|
||||||
### Table extraction
|
### Table extraction
|
||||||
```bash
|
```bash
|
||||||
gptdeploy generate --description "Given a URL, extract all tables as csv" --test "http://www.ins.tn/statistiques/90" --model gpt-4
|
gptdeploy generate --description "Given a URL, extract all tables as csv" --test "http://www.ins.tn/statistiques/90" --model gpt-4 --path microservice
|
||||||
```
|
```
|
||||||
<img src="res/table_extraction_example.png" alt="Table Extraction" width="600" />
|
<img src="res/table_extraction_example.png" alt="Table Extraction" width="600" />
|
||||||
|
|
||||||
### Audio to mel spectrogram
|
### Audio to mel spectrogram
|
||||||
```bash
|
```bash
|
||||||
gptdeploy generate --description "Create mel spectrograms from audio file" --test "https://cdn.pixabay.com/download/audio/2023/02/28/audio_550d815fa5.mp3" --model gpt-4
|
gptdeploy generate --description "Create mel spectrograms from audio file" --test "https://cdn.pixabay.com/download/audio/2023/02/28/audio_550d815fa5.mp3" --model gpt-4 --path microservice
|
||||||
```
|
```
|
||||||
<img src="res/audio_to_mel_example.png" alt="Audio to Mel Spectrogram" width="600" />
|
<img src="res/audio_to_mel_example.png" alt="Audio to Mel Spectrogram" width="600" />
|
||||||
|
|
||||||
### Text to speech
|
### Text to speech
|
||||||
```bash
|
```bash
|
||||||
gptdeploy generate --description "Convert text to speech" --test "Hello, welcome to GPT Deploy!" --model gpt-4
|
gptdeploy generate --description "Convert text to speech" --test "Hello, welcome to GPT Deploy!" --model gpt-4 --path microservice
|
||||||
```
|
```
|
||||||
<a href=res/text_to_speech_example.wav><img src="res/text_to_speech_example.png" alt="Text to Speech" width="600" /></a>
|
<a href=res/text_to_speech_example.wav><img src="res/text_to_speech_example.png" alt="Text to Speech" width="600" /></a>
|
||||||
|
|
||||||
@@ -158,20 +171,20 @@ gptdeploy generate --description "Convert text to speech" --test "Hello, welcome
|
|||||||
|
|
||||||
### Heatmap Generator
|
### Heatmap Generator
|
||||||
```bash
|
```bash
|
||||||
gptdeploy generate --description "Create a heatmap from an image and a list of relative coordinates" --test "https://images.unsplash.com/photo-1574786198875-49f5d09fe2d2, [[0.1, 0.2], [0.3, 0.4], [0.5, 0.6], [0.2, 0.1], [0.7, 0.2], [0.4, 0.2]]" --model gpt-4
|
gptdeploy generate --description "Create a heatmap from an image and a list of relative coordinates" --test "https://images.unsplash.com/photo-1574786198875-49f5d09fe2d2, [[0.1, 0.2], [0.3, 0.4], [0.5, 0.6], [0.2, 0.1], [0.7, 0.2], [0.4, 0.2]]" --model gpt-4 --path microservice
|
||||||
```
|
```
|
||||||
<img src="res/heatmap_example.png" alt="Heatmap Generator" width="600" />
|
<img src="res/heatmap_example.png" alt="Heatmap Generator" width="600" />
|
||||||
|
|
||||||
### QR Code Generator
|
### QR Code Generator
|
||||||
```bash
|
```bash
|
||||||
gptdeploy generate --description "Generate QR code from URL" --test "https://www.example.com" --model gpt-4
|
gptdeploy generate --description "Generate QR code from URL" --test "https://www.example.com" --model gpt-4 --path microservice
|
||||||
```
|
```
|
||||||
<img src="res/qr_example.png" alt="QR Code Generator" width="600" />
|
<img src="res/qr_example.png" alt="QR Code Generator" width="600" />
|
||||||
|
|
||||||
### Mandelbrot Set Visualizer
|
### Mandelbrot Set Visualizer
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
gptdeploy generate --description "Visualize the Mandelbrot set with custom parameters" --test "center=-0+1i, zoom=1.0, size=800x800, iterations=1000" --model gpt-4
|
gptdeploy generate --description "Visualize the Mandelbrot set with custom parameters" --test "center=-0+1i, zoom=1.0, size=800x800, iterations=1000" --model gpt-4 --path microservice
|
||||||
```
|
```
|
||||||
<img src="res/mandelbrot_example.png" alt="Mandelbrot Set Visualizer" width="600" />
|
<img src="res/mandelbrot_example.png" alt="Mandelbrot Set Visualizer" width="600" />
|
||||||
|
|
||||||
@@ -341,14 +354,6 @@ gptdeploy generate --description "Visualize the Mandelbrot set with custom param
|
|||||||
|
|
||||||
[//]: # (## Upcoming Challenges)
|
[//]: # (## Upcoming Challenges)
|
||||||
|
|
||||||
[//]: # (### Chemical Structure Drawing)
|
|
||||||
|
|
||||||
[//]: # (```bash)
|
|
||||||
|
|
||||||
[//]: # (gptdeploy generate --description "Convert a chemical formula into a 2D chemical structure diagram" --test "C6H6")
|
|
||||||
|
|
||||||
[//]: # (```)
|
|
||||||
|
|
||||||
[//]: # (### Color Palette Generator)
|
[//]: # (### Color Palette Generator)
|
||||||
|
|
||||||
[//]: # (```bash)
|
[//]: # (```bash)
|
||||||
|
|||||||
BIN
res/chemical_formula_example.png
Normal file
BIN
res/chemical_formula_example.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 110 KiB |
BIN
res/obj_render_example.gif
Normal file
BIN
res/obj_render_example.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 898 KiB |
2
setup.py
2
setup.py
@@ -7,7 +7,7 @@ def read_requirements():
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='gptdeploy',
|
name='gptdeploy',
|
||||||
version='0.18.16',
|
version='0.18.18',
|
||||||
description='Use natural language interface to generate, deploy and update your microservice infrastructure.',
|
description='Use natural language interface to generate, deploy and update your microservice infrastructure.',
|
||||||
long_description=open('README.md', 'r', encoding='utf-8').read(),
|
long_description=open('README.md', 'r', encoding='utf-8').read(),
|
||||||
long_description_content_type='text/markdown',
|
long_description_content_type='text/markdown',
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
__version__ = '0.18.16'
|
__version__ = '0.18.18'
|
||||||
from src.cli import main
|
from src.cli import main
|
||||||
@@ -15,7 +15,9 @@ from src.utils.string_tools import print_colored
|
|||||||
|
|
||||||
|
|
||||||
class GPTSession:
|
class GPTSession:
|
||||||
def __init__(self, model: str = 'gpt-4'):
|
def __init__(self, task_description, test_description, model: str = 'gpt-4', ):
|
||||||
|
self.task_description = task_description
|
||||||
|
self.test_description = test_description
|
||||||
self.configure_openai_api_key()
|
self.configure_openai_api_key()
|
||||||
self.model_name = 'gpt-4' if model == 'gpt-4' and self.is_gpt4_available() else 'gpt-3.5-turbo'
|
self.model_name = 'gpt-4' if model == 'gpt-4' and self.is_gpt4_available() else 'gpt-3.5-turbo'
|
||||||
|
|
||||||
@@ -51,7 +53,7 @@ If you have updated it already, please restart your terminal.
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def get_conversation(self, system_definition_examples: List[str] = ['executor', 'docarray', 'client']):
|
def get_conversation(self, system_definition_examples: List[str] = ['executor', 'docarray', 'client']):
|
||||||
return _GPTConversation(self.model_name, system_definition_examples)
|
return _GPTConversation(self.model_name, self.task_description, self.test_description, system_definition_examples)
|
||||||
|
|
||||||
|
|
||||||
class AssistantStreamingStdOutCallbackHandler(StreamingStdOutCallbackHandler):
|
class AssistantStreamingStdOutCallbackHandler(StreamingStdOutCallbackHandler):
|
||||||
@@ -62,7 +64,7 @@ class AssistantStreamingStdOutCallbackHandler(StreamingStdOutCallbackHandler):
|
|||||||
|
|
||||||
|
|
||||||
class _GPTConversation:
|
class _GPTConversation:
|
||||||
def __init__(self, model: str, system_definition_examples: List[str] = ['executor', 'docarray', 'client']):
|
def __init__(self, model: str, task_description, test_description, system_definition_examples: List[str] = ['executor', 'docarray', 'client']):
|
||||||
self.chat = ChatOpenAI(
|
self.chat = ChatOpenAI(
|
||||||
model_name=model,
|
model_name=model,
|
||||||
streaming=True,
|
streaming=True,
|
||||||
@@ -85,7 +87,7 @@ class _GPTConversation:
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _create_system_message(system_definition_examples: List[str] = []) -> SystemMessage:
|
def _create_system_message(task_description, test_description, system_definition_examples: List[str] = []) -> SystemMessage:
|
||||||
system_message = system_message_base
|
system_message = system_message_base
|
||||||
if 'executor' in system_definition_examples:
|
if 'executor' in system_definition_examples:
|
||||||
system_message += f'\n{executor_example}'
|
system_message += f'\n{executor_example}'
|
||||||
@@ -93,4 +95,5 @@ class _GPTConversation:
|
|||||||
system_message += f'\n{docarray_example}'
|
system_message += f'\n{docarray_example}'
|
||||||
if 'client' in system_definition_examples:
|
if 'client' in system_definition_examples:
|
||||||
system_message += f'\n{client_example}'
|
system_message += f'\n{client_example}'
|
||||||
|
# create from template
|
||||||
return SystemMessage(content=system_message)
|
return SystemMessage(content=system_message)
|
||||||
|
|||||||
@@ -248,10 +248,18 @@ def update_client_line_in_file(file_path, host):
|
|||||||
file.write(replaced_content)
|
file.write(replaced_content)
|
||||||
|
|
||||||
|
|
||||||
def remove_after_stderr(relevant_lines):
|
def shorten_logs(relevant_lines):
|
||||||
|
# handle duplicate error messages
|
||||||
for index, line in enumerate(relevant_lines):
|
for index, line in enumerate(relevant_lines):
|
||||||
if '--- Captured stderr call ----' in line:
|
if '--- Captured stderr call ----' in line:
|
||||||
return relevant_lines[:index]
|
relevant_lines = relevant_lines[:index]
|
||||||
|
# filter pip install logs
|
||||||
|
relevant_lines = [line for line in relevant_lines if ' Requirement already satisfied: ' not in line]
|
||||||
|
# filter version not found logs
|
||||||
|
for index, line in enumerate(relevant_lines):
|
||||||
|
if 'ERROR: Could not find a version that satisfies the requirement ' in line:
|
||||||
|
start_and_end = line[:150] + '...' + line[-150:]
|
||||||
|
relevant_lines[index] = start_and_end
|
||||||
return relevant_lines
|
return relevant_lines
|
||||||
|
|
||||||
|
|
||||||
@@ -270,9 +278,9 @@ def process_error_message(error_message):
|
|||||||
if last_matching_line_index is not None:
|
if last_matching_line_index is not None:
|
||||||
relevant_lines = lines[last_matching_line_index:]
|
relevant_lines = lines[last_matching_line_index:]
|
||||||
|
|
||||||
relevant_lines = remove_after_stderr(relevant_lines)
|
relevant_lines = shorten_logs(relevant_lines)
|
||||||
|
|
||||||
response = '\n'.join(relevant_lines[-25:]).strip()
|
response = '\n'.join(relevant_lines[-100:]).strip()
|
||||||
|
|
||||||
# the following code tests the case that the docker file is corrupted and can not be parsed
|
# the following code tests the case that the docker file is corrupted and can not be parsed
|
||||||
# the method above will not return a relevant error message in this case
|
# the method above will not return a relevant error message in this case
|
||||||
@@ -282,21 +290,3 @@ def process_error_message(error_message):
|
|||||||
if not response and last_line.startswith('error: '):
|
if not response and last_line.startswith('error: '):
|
||||||
return last_line
|
return last_line
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
def build_docker(path):
|
|
||||||
# The command to build the Docker image
|
|
||||||
cmd = f"docker build -t micromagic {path}"
|
|
||||||
|
|
||||||
# Run the command and capture the output
|
|
||||||
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
|
|
||||||
stdout, stderr = process.communicate()
|
|
||||||
|
|
||||||
# Check if there was an error
|
|
||||||
if process.returncode != 0:
|
|
||||||
error_message = stderr.decode("utf-8")
|
|
||||||
relevant_error_message = process_error_message(error_message)
|
|
||||||
return relevant_error_message
|
|
||||||
else:
|
|
||||||
print("Docker build completed successfully.")
|
|
||||||
return ''
|
|
||||||
|
|||||||
@@ -64,13 +64,12 @@ def generate(
|
|||||||
return
|
return
|
||||||
|
|
||||||
from src.options.generate.generator import Generator
|
from src.options.generate.generator import Generator
|
||||||
generator = Generator(model=model)
|
generator = Generator(description, test, model=model)
|
||||||
with get_openai_callback() as cb:
|
with get_openai_callback() as cb:
|
||||||
generator.generate(description, test, path)
|
generator.generate(path)
|
||||||
print(f"Prompt/Completion/Total Tokens: {cb.prompt_tokens}/{cb.completion_tokens}/{cb.total_tokens}")
|
print(f"Prompt/Completion/Total Tokens: {cb.prompt_tokens}/{cb.completion_tokens}/{cb.total_tokens}")
|
||||||
print(f"Total Cost on OpenAI (USD): ${cb.total_cost}")
|
print(f"Total Cost on OpenAI (USD): ${cb.total_cost}")
|
||||||
|
|
||||||
|
|
||||||
@main.command()
|
@main.command()
|
||||||
@path_param
|
@path_param
|
||||||
def run(path):
|
def run(path):
|
||||||
|
|||||||
@@ -30,5 +30,6 @@ MAX_DEBUGGING_ITERATIONS = 10
|
|||||||
DEMO_TOKEN = '45372338e04f5a41af949024db929d46'
|
DEMO_TOKEN = '45372338e04f5a41af949024db929d46'
|
||||||
|
|
||||||
PROBLEMATIC_PACKAGES = [
|
PROBLEMATIC_PACKAGES = [
|
||||||
'Pyrender', 'Trimesh', 'ModernGL', 'PyOpenGL', 'Pyglet', 'pythreejs', 'panda3d' # because they need a screen
|
# 'Pyrender', 'Trimesh',
|
||||||
|
'ModernGL', 'PyOpenGL', 'Pyglet', 'pythreejs', 'panda3d' # because they need a screen
|
||||||
]
|
]
|
||||||
@@ -1,13 +1,19 @@
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
def get_latest_folder(path):
|
def get_latest_folder(path, max_fn=max):
|
||||||
return max([os.path.join(path, f) for f in os.listdir(path) if os.path.isdir(os.path.join(path, f))])
|
return max_fn([os.path.join(path, f) for f in os.listdir(path) if os.path.isdir(os.path.join(path, f))])
|
||||||
|
|
||||||
|
def version_max_fn(path_list):
|
||||||
|
version_list = [int(path.split('/')[-1].replace('v', '')) for path in path_list]
|
||||||
|
max_version = max(version_list)
|
||||||
|
max_index = version_list.index(max_version)
|
||||||
|
return path_list[max_index]
|
||||||
|
|
||||||
def get_latest_version_path(microservice_path):
|
def get_latest_version_path(microservice_path):
|
||||||
executor_name_path = get_latest_folder(microservice_path)
|
executor_name_path = get_latest_folder(microservice_path)
|
||||||
latest_approach_path = get_latest_folder(executor_name_path)
|
latest_approach_path = get_latest_folder(executor_name_path)
|
||||||
latest_version_path = get_latest_folder(latest_approach_path)
|
latest_version_path = get_latest_folder(latest_approach_path, max_fn=version_max_fn)
|
||||||
return latest_version_path
|
return latest_version_path
|
||||||
|
|
||||||
def get_executor_name(microservice_path):
|
def get_executor_name(microservice_path):
|
||||||
|
|||||||
@@ -17,21 +17,22 @@ from src.utils.string_tools import print_colored
|
|||||||
|
|
||||||
|
|
||||||
class Generator:
|
class Generator:
|
||||||
def __init__(self, model='gpt-4'):
|
def __init__(self, task_description, test_description, model='gpt-4'):
|
||||||
self.gpt_session = gpt.GPTSession(model=model)
|
self.gpt_session = gpt.GPTSession(task_description, test_description, model=model)
|
||||||
|
self.task_description = task_description
|
||||||
|
self.test_description = test_description
|
||||||
|
|
||||||
def extract_content_from_result(self, plain_text, file_name, match_single_block=False):
|
def extract_content_from_result(self, plain_text, file_name, match_single_block=False):
|
||||||
pattern = fr"^\*\*{file_name}\*\*\n```(?:\w+\n)?([\s\S]*?)```"
|
pattern = fr"^\*\*{file_name}\*\*\n```(?:\w+\n)?([\s\S]*?)```"
|
||||||
match = re.search(pattern, plain_text, re.MULTILINE)
|
match = re.search(pattern, plain_text, re.MULTILINE)
|
||||||
if match:
|
if match:
|
||||||
return match.group(1).strip()
|
return match.group(1).strip()
|
||||||
else:
|
elif match_single_block:
|
||||||
# Check for a single code block
|
# Check for a single code block
|
||||||
single_code_block_pattern = r"^```(?:\w+\n)?([\s\S]*?)```"
|
single_code_block_pattern = r"^```(?:\w+\n)?([\s\S]*?)```"
|
||||||
single_code_block_match = re.findall(single_code_block_pattern, plain_text, re.MULTILINE)
|
single_code_block_match = re.findall(single_code_block_pattern, plain_text, re.MULTILINE)
|
||||||
if match_single_block and len(single_code_block_match) == 1:
|
if len(single_code_block_match) == 1:
|
||||||
return single_code_block_match[0].strip()
|
return single_code_block_match[0].strip()
|
||||||
else:
|
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def write_config_yml(self, microservice_name, dest_folder):
|
def write_config_yml(self, microservice_name, dest_folder):
|
||||||
@@ -58,10 +59,10 @@ metas:
|
|||||||
test,
|
test,
|
||||||
path,
|
path,
|
||||||
microservice_name,
|
microservice_name,
|
||||||
package,
|
packages,
|
||||||
num_approach,
|
num_approach,
|
||||||
):
|
):
|
||||||
MICROSERVICE_FOLDER_v1 = get_microservice_path(path, microservice_name, package, num_approach, 1)
|
MICROSERVICE_FOLDER_v1 = get_microservice_path(path, microservice_name, packages, num_approach, 1)
|
||||||
os.makedirs(MICROSERVICE_FOLDER_v1)
|
os.makedirs(MICROSERVICE_FOLDER_v1)
|
||||||
|
|
||||||
print_colored('', '############# Microservice #############', 'blue')
|
print_colored('', '############# Microservice #############', 'blue')
|
||||||
@@ -168,7 +169,6 @@ metas:
|
|||||||
persist_file(playground_content, os.path.join(microservice_path, 'app.py'))
|
persist_file(playground_content, os.path.join(microservice_path, 'app.py'))
|
||||||
|
|
||||||
def debug_microservice(self, path, microservice_name, num_approach, packages, description, test):
|
def debug_microservice(self, path, microservice_name, num_approach, packages, description, test):
|
||||||
error_before = ''
|
|
||||||
for i in range(1, MAX_DEBUGGING_ITERATIONS):
|
for i in range(1, MAX_DEBUGGING_ITERATIONS):
|
||||||
print('Debugging iteration', i)
|
print('Debugging iteration', i)
|
||||||
print('Trying to build the microservice. Might take a while...')
|
print('Trying to build the microservice. Might take a while...')
|
||||||
@@ -178,20 +178,22 @@ metas:
|
|||||||
error = process_error_message(log_hubble)
|
error = process_error_message(log_hubble)
|
||||||
if error:
|
if error:
|
||||||
print('An error occurred during the build process. Feeding the error back to the assistent...')
|
print('An error occurred during the build process. Feeding the error back to the assistent...')
|
||||||
self.do_debug_iteration(description, error, error_before, next_microservice_path,
|
self.do_debug_iteration(description, error, next_microservice_path,
|
||||||
previous_microservice_path, test)
|
previous_microservice_path, test)
|
||||||
error_before = error
|
if i == MAX_DEBUGGING_ITERATIONS - 1:
|
||||||
|
raise self.MaxDebugTimeReachedException('Could not debug the microservice.')
|
||||||
else:
|
else:
|
||||||
print('Successfully build microservice.')
|
print('Successfully build microservice.')
|
||||||
break
|
break
|
||||||
if i == MAX_DEBUGGING_ITERATIONS - 1:
|
|
||||||
raise self.MaxDebugTimeReachedException('Could not debug the microservice.')
|
|
||||||
return get_microservice_path(path, microservice_name, packages, num_approach, i)
|
return get_microservice_path(path, microservice_name, packages, num_approach, i)
|
||||||
|
|
||||||
def do_debug_iteration(self, description, error, error_before, next_microservice_path, previous_microservice_path,
|
def do_debug_iteration(self, description, error, next_microservice_path, previous_microservice_path,
|
||||||
test):
|
test):
|
||||||
os.makedirs(next_microservice_path)
|
os.makedirs(next_microservice_path)
|
||||||
file_name_to_content = get_all_microservice_files_with_content(previous_microservice_path)
|
file_name_to_content = get_all_microservice_files_with_content(previous_microservice_path)
|
||||||
|
|
||||||
|
summarized_error = self.summarize_error(error)
|
||||||
is_dependency_issue = self.is_dependency_issue(error, file_name_to_content['Dockerfile'])
|
is_dependency_issue = self.is_dependency_issue(error, file_name_to_content['Dockerfile'])
|
||||||
if is_dependency_issue:
|
if is_dependency_issue:
|
||||||
all_files_string = self.files_to_string({
|
all_files_string = self.files_to_string({
|
||||||
@@ -199,11 +201,11 @@ metas:
|
|||||||
key in ['requirements.txt', 'Dockerfile']
|
key in ['requirements.txt', 'Dockerfile']
|
||||||
})
|
})
|
||||||
user_query = template_solve_dependency_issue.format(
|
user_query = template_solve_dependency_issue.format(
|
||||||
description=description, error=error, all_files_string=all_files_string,
|
description=description, summarized_error=summarized_error, all_files_string=all_files_string,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
user_query = template_solve_code_issue.format(
|
user_query = template_solve_code_issue.format(
|
||||||
description=description, error=error, all_files_string=self.files_to_string(file_name_to_content),
|
description=description, summarized_error=summarized_error, all_files_string=self.files_to_string(file_name_to_content),
|
||||||
)
|
)
|
||||||
conversation = self.gpt_session.get_conversation()
|
conversation = self.gpt_session.get_conversation()
|
||||||
returned_files_raw = conversation.chat(user_query)
|
returned_files_raw = conversation.chat(user_query)
|
||||||
@@ -211,6 +213,7 @@ metas:
|
|||||||
updated_file = self.extract_content_from_result(returned_files_raw, file_name)
|
updated_file = self.extract_content_from_result(returned_files_raw, file_name)
|
||||||
if updated_file and (not is_dependency_issue or file_name in ['requirements.txt', 'Dockerfile']):
|
if updated_file and (not is_dependency_issue or file_name in ['requirements.txt', 'Dockerfile']):
|
||||||
file_name_to_content[file_name] = updated_file
|
file_name_to_content[file_name] = updated_file
|
||||||
|
print(f'Updated {file_name}')
|
||||||
for file_name, content in file_name_to_content.items():
|
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(next_microservice_path, file_name))
|
||||||
|
|
||||||
@@ -240,12 +243,12 @@ metas:
|
|||||||
template_generate_possible_packages.format(description=description)
|
template_generate_possible_packages.format(description=description)
|
||||||
)
|
)
|
||||||
packages_csv_string = self.extract_content_from_result(packages_raw, 'packages.csv')
|
packages_csv_string = self.extract_content_from_result(packages_raw, 'packages.csv')
|
||||||
packages = [package.split(',') for package in packages_csv_string.split('\n')]
|
packages_list = [[pkg.strip() for pkg in packages_string.split(',')] for packages_string in packages_csv_string.split('\n')]
|
||||||
packages = packages[:NUM_IMPLEMENTATION_STRATEGIES]
|
packages_list = packages_list[:NUM_IMPLEMENTATION_STRATEGIES]
|
||||||
return packages
|
return packages_list
|
||||||
|
|
||||||
def generate(self, description, test, microservice_path):
|
def generate(self, microservice_path):
|
||||||
generated_name = self.generate_microservice_name(description)
|
generated_name = self.generate_microservice_name(self.task_description)
|
||||||
microservice_name = f'{generated_name}{random.randint(0, 10_000_000)}'
|
microservice_name = f'{generated_name}{random.randint(0, 10_000_000)}'
|
||||||
packages_list = self.get_possible_packages(description)
|
packages_list = self.get_possible_packages(description)
|
||||||
packages_list = [
|
packages_list = [
|
||||||
@@ -254,7 +257,7 @@ metas:
|
|||||||
for num_approach, packages in enumerate(packages_list):
|
for num_approach, packages in enumerate(packages_list):
|
||||||
try:
|
try:
|
||||||
self.generate_microservice(
|
self.generate_microservice(
|
||||||
description, test, microservice_path, microservice_name, packages, num_approach
|
self.task_description, self.test_description, microservice_path, microservice_name, packages, num_approach
|
||||||
)
|
)
|
||||||
final_version_path = self.debug_microservice(
|
final_version_path = self.debug_microservice(
|
||||||
microservice_path, microservice_name, num_approach, packages, description, test
|
microservice_path, microservice_name, num_approach, packages, description, test
|
||||||
@@ -274,3 +277,14 @@ gptdeploy deploy --path {microservice_path}
|
|||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
def summarize_error(self, error):
|
||||||
|
conversation = self.gpt_session.get_conversation([])
|
||||||
|
user_query = f'''
|
||||||
|
Here is an error message I encountered during the docker build process:
|
||||||
|
"{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.
|
||||||
|
'''
|
||||||
|
error_summary = conversation.query(user_query)
|
||||||
|
return error_summary
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class MyInfoExecutor(Executor):
|
|||||||
for d in docs:
|
for d in docs:
|
||||||
content = json.loads(d.text)
|
content = json.loads(d.text)
|
||||||
...
|
...
|
||||||
d.text = json.dumps(modified_content)
|
d.text = json.dumps(modified_content) # serialized json
|
||||||
return docs
|
return docs
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ A Document is a python class that represents a single document.
|
|||||||
Here is the protobuf definition of a Document:
|
Here is the protobuf definition of a Document:
|
||||||
```
|
```
|
||||||
message DocumentProto {{
|
message DocumentProto {{
|
||||||
// used to store json data the executor gets and returns
|
// used to store serialized json data the executor gets and returns
|
||||||
string text = 1;
|
string text = 1;
|
||||||
}}
|
}}
|
||||||
```
|
```
|
||||||
@@ -71,7 +71,16 @@ print(response[0].text)
|
|||||||
```'''
|
```'''
|
||||||
|
|
||||||
|
|
||||||
system_message_base = '''It is the year 2021.
|
system_base_definition = '''It is the year 2021.
|
||||||
You are a principal engineer working at Jina - an open source company.
|
You are a principal engineer working at Jina - an open source company.
|
||||||
You accurately satisfy all of the user's requirements.
|
You accurately satisfy all of the user's requirements.
|
||||||
Your goal is to build a microservice that: {description}'''
|
To be more specific, you help the user to build a microservice with the following requirements:
|
||||||
|
```
|
||||||
|
{task_description}
|
||||||
|
```
|
||||||
|
and the following test scenario:
|
||||||
|
```
|
||||||
|
{test_description}
|
||||||
|
```
|
||||||
|
|
||||||
|
You must obey the following rules:''' + f'\n{not_allowed_executor}\n{not_allowed_docker}'
|
||||||
|
|||||||
0
src/options/generate/prompt_tasks.py
Normal file
0
src/options/generate/prompt_tasks.py
Normal file
@@ -9,8 +9,8 @@ import docker
|
|||||||
from docker import APIClient
|
from docker import APIClient
|
||||||
|
|
||||||
|
|
||||||
def get_microservice_path(path, microservice_name, package, num_approach, version):
|
def get_microservice_path(path, microservice_name, packages, num_approach, version):
|
||||||
package_path = '_'.join(package)
|
package_path = '_'.join(packages)
|
||||||
return os.path.join(path, microservice_name, f'{num_approach}_{package_path}', f'v{version}')
|
return os.path.join(path, microservice_name, f'{num_approach}_{package_path}', f'v{version}')
|
||||||
|
|
||||||
def persist_file(file_content, file_path):
|
def persist_file(file_content, file_path):
|
||||||
|
|||||||
@@ -25,5 +25,5 @@ def test_generator(tmpdir):
|
|||||||
# Use mock.patch as a context manager to replace the original methods with the mocks
|
# Use mock.patch as a context manager to replace the original methods with the mocks
|
||||||
with mock.patch("openai.ChatCompletion.create", side_effect=mock_create), \
|
with mock.patch("openai.ChatCompletion.create", side_effect=mock_create), \
|
||||||
mock.patch.object(GPTSession, "configure_openai_api_key", side_effect=mock_get_openai_api_key):
|
mock.patch.object(GPTSession, "configure_openai_api_key", side_effect=mock_get_openai_api_key):
|
||||||
generator = Generator()
|
generator = Generator("my description", "my test")
|
||||||
generator.generate("my description", "my test", str(tmpdir))
|
generator.generate(str(tmpdir))
|
||||||
|
|||||||
Reference in New Issue
Block a user