mirror of
https://github.com/aljazceru/dev-gpt.git
synced 2025-12-19 22:54:21 +01:00
⚽ refactor: playground more stable generation
This commit is contained in:
@@ -27,7 +27,9 @@ FILE_AND_TAG_PAIRS = [
|
||||
]
|
||||
|
||||
INDICATOR_TO_IMPORT_STATEMENT = {
|
||||
'io.BytesIO': 'import io',
|
||||
'BytesIO': 'from io import BytesIO',
|
||||
'base64': 'import base64',
|
||||
}
|
||||
|
||||
FLOW_URL_PLACEHOLDER = 'jcloud.jina.ai'
|
||||
|
||||
@@ -49,7 +49,8 @@ Note: If you are not sure about the details, then come up with the minimal numbe
|
||||
|
||||
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.'''
|
||||
Note: If you are not sure about the details, then come up with the minimal number of parameters possible.
|
||||
Note: If you can decide to return files as URLs or as base64 encoded strings, then choose the base64 encoded strings.'''
|
||||
|
||||
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.
|
||||
|
||||
@@ -250,7 +250,7 @@ metas:
|
||||
line.replace('{{APT_GET_PACKAGES}}', '').replace('{{DOCKER_BASE_IMAGE_VERSION}}', DOCKER_BASE_IMAGE_VERSION)
|
||||
for line in docker_file_template_lines
|
||||
]
|
||||
docker_file_content = '\n'.join(docker_file_template_lines)
|
||||
docker_file_content = ''.join(docker_file_template_lines)
|
||||
persist_file(docker_file_content, os.path.join(self.cur_microservice_path, 'Dockerfile'))
|
||||
|
||||
self.write_config_yml(self.microservice_name, self.cur_microservice_path)
|
||||
@@ -259,12 +259,16 @@ metas:
|
||||
|
||||
|
||||
def add_missing_imports_post_process_fn(self, content_dict: dict):
|
||||
for indicator, import_statement in INDICATOR_TO_IMPORT_STATEMENT.items():
|
||||
for file_name, file_content in content_dict.items():
|
||||
if indicator in file_content and import_statement not in file_content:
|
||||
content_dict[file_name] = f'{import_statement}\n{file_content}'
|
||||
for file_name, file_content in content_dict.items():
|
||||
file_content = self.add_missing_imports_for_file(file_content)
|
||||
content_dict[file_name] = file_content
|
||||
return content_dict
|
||||
|
||||
def add_missing_imports_for_file(self, file_content):
|
||||
for indicator, import_statement in INDICATOR_TO_IMPORT_STATEMENT.items():
|
||||
if indicator in file_content and import_statement not in file_content:
|
||||
file_content = f'{import_statement}\n{file_content}'
|
||||
return file_content
|
||||
|
||||
@staticmethod
|
||||
def read_docker_template():
|
||||
@@ -295,12 +299,15 @@ pytest
|
||||
def generate_playground(self):
|
||||
print_colored('', '\n\n############# Playground #############', 'blue')
|
||||
|
||||
with open(os.path.join(os.path.dirname(__file__), 'static_files', 'gateway', 'app_template.py'), 'r', encoding='utf-8') as f:
|
||||
playground_template = f.read()
|
||||
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']),
|
||||
code_files_wrapped=self.files_to_string(file_name_to_content, ['test_microservice.py', 'microservice.py']),
|
||||
microservice_name=self.microservice_name,
|
||||
playground_template=playground_template,
|
||||
)
|
||||
)
|
||||
playground_content_raw = conversation.chat(
|
||||
@@ -316,6 +323,7 @@ pytest
|
||||
playground_content = self.extract_content_from_result(
|
||||
content_raw, 'app.py', match_single_block=True
|
||||
)
|
||||
playground_content = self.add_missing_imports_for_file(playground_content)
|
||||
|
||||
gateway_path = os.path.join(self.cur_microservice_path, 'gateway')
|
||||
shutil.copytree(os.path.join(os.path.dirname(__file__), 'static_files', 'gateway'), gateway_path)
|
||||
|
||||
@@ -1,53 +1,53 @@
|
||||
import json
|
||||
import os
|
||||
import base64
|
||||
|
||||
import streamlit as st
|
||||
from jina import Client, Document, DocumentArray
|
||||
import io
|
||||
|
||||
st.set_page_config(
|
||||
page_title="<page title here>",
|
||||
page_icon="<page icon here>",
|
||||
layout="<page layout here>",
|
||||
initial_sidebar_state="<sidebar state here>",
|
||||
layout="centered",
|
||||
initial_sidebar_state="auto",
|
||||
)
|
||||
|
||||
st.title("<thematic emoji here> <header title here>")
|
||||
st.markdown(
|
||||
"<10 word description here>"
|
||||
"To deploy your own microservice, click [here](https://github.com/jina-ai/dev-gpt)."
|
||||
"To generate and deploy your own microservice, click [here](https://github.com/jina-ai/dev-gpt)."
|
||||
)
|
||||
|
||||
st.header("<another thematic emoji here> Input Parameters") # only if input parameters are needed
|
||||
st.subheader("<a unique thematic emoji here> <sub header title here>") # only if input parameters are needed
|
||||
with st.form(key="input_form"):
|
||||
<input parameter definition here>
|
||||
# <input parameter definition here>
|
||||
input_json_dict = {} #
|
||||
|
||||
input_data = {
|
||||
<input parameters here>
|
||||
}
|
||||
input_json = json.dumps(input_data)
|
||||
input_json_dict_string = json.dumps(input_json_dict)
|
||||
submitted = st.form_submit_button("<submit button text>")
|
||||
|
||||
# Process input and call microservice
|
||||
if submit_button:
|
||||
with st.spinner("Generating collage..."):
|
||||
|
||||
|
||||
if submitted:
|
||||
with st.spinner("<spinner text here>..."):
|
||||
client = Client(host="http://localhost:8080")
|
||||
d = Document(text=input_json)
|
||||
d = Document(text=input_json_dict_string)
|
||||
response = client.post("/", inputs=DocumentArray([d]))
|
||||
|
||||
output_data = json.loads(response[0].text)
|
||||
<visualization of results>
|
||||
# <visualization of results here>
|
||||
|
||||
# Display curl command
|
||||
deployment_id = os.environ.get("K8S_NAMESPACE_NAME", "")
|
||||
host = (
|
||||
api_endpoint = (
|
||||
f"https://dev-gpt-{deployment_id.split('-')[1]}.wolf.jina.ai/post"
|
||||
if deployment_id
|
||||
else "http://localhost:8080/post"
|
||||
)
|
||||
|
||||
with st.expander("See curl command"):
|
||||
st.markdown("You can use the following curl command to send a request to the microservice from the command line:")
|
||||
escaped_input_json_dict_string = input_json_dict_string.replace('"', '\\"')
|
||||
|
||||
st.code(
|
||||
f'curl -X "POST" "{host}" -H "accept: application/json" -H "Content-Type: application/json" -d \'{{"data": [{{"text": "{input_json}"}}]}}\'',
|
||||
f'curl -X "POST" "{api_endpoint}" -H "accept: application/json" -H "Content-Type: application/json" -d \'{{"data": [{{"text": "{escaped_input_json_dict_string}"}}]}}\'',
|
||||
language="bash",
|
||||
)
|
||||
)
|
||||
@@ -132,9 +132,10 @@ def template_generate_function_constructor(is_using_gpt_3_5_turbo, is_using_goog
|
||||
general_guidelines_string + f'''
|
||||
|
||||
Write a python function which receives as \
|
||||
input json string (that can be parsed with the python function json.loads) and \
|
||||
outputs a json string (that can be parsed with the python function json.loads). \
|
||||
The function is called 'func'.
|
||||
input json dictionary string (that can be parsed with the python function json.loads) and \
|
||||
outputs a json dictionary string (that can be parsed with the python function json.loads). \
|
||||
The function is called 'func' and has the following signature:
|
||||
def func(input_json_dict_string: str) -> str:
|
||||
The function must fulfill the following description: '{{microservice_description}}'.
|
||||
It will be tested with the following scenario: '{{test_description}}'.
|
||||
For the implementation use the following package(s): '{{packages}}'.
|
||||
@@ -433,13 +434,12 @@ Use the exact following syntax to wrap the code:
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
**implementation.py**
|
||||
```python
|
||||
import json
|
||||
|
||||
def func(json_input: str) -> str:
|
||||
return json_input['img_base64']
|
||||
def func(input_json_dict_string: str) -> str:
|
||||
return json.dumps('output_param1': input_json_dict_string['img_base64'])
|
||||
```'''
|
||||
)
|
||||
|
||||
@@ -449,50 +449,30 @@ template_generate_playground = PromptTemplate.from_template(
|
||||
|
||||
{code_files_wrapped}
|
||||
|
||||
Create a playground for the executor {microservice_name} using streamlit.
|
||||
The playground must look like it was made by a professional designer.
|
||||
All the ui elements are well thought out to make them visually appealing and easy to use.
|
||||
Don't mention the word Playground in the title.
|
||||
The playground contains many emojis that fit the theme of the playground and has an emoji as favicon.
|
||||
The playground encourages the user to deploy their own microservice by clicking on this link: https://github.com/jina-ai/dev-gpt
|
||||
The playground uses the following code to send a request to the microservice:
|
||||
1. Write down the json request model required by microservice.py.
|
||||
2. Generate a playground for the microservice {microservice_name} using the following streamlit template by replacing all the placeholders (<...>) with the correct values:
|
||||
**app_template.py**
|
||||
```python
|
||||
{playground_template}
|
||||
```
|
||||
from jina import Client, Document, DocumentArray
|
||||
client = Client(host='http://localhost:8080')
|
||||
d = Document(text=json.dumps(INPUT_DICTIONARY)) # fill-in dictionary which takes input
|
||||
response = client.post('/', inputs=DocumentArray([d])) # always use '/'
|
||||
print(response[0].text) # can also be blob in case of image/audio..., this should be visualized in the streamlit app
|
||||
```
|
||||
Note that the response will always be in response[0].text
|
||||
The playground displays a code block containing the microservice specific curl code that can be used to send the request to the microservice.
|
||||
While the exact payload in the curl might change, the host and deployment ID always stay the same. Example:
|
||||
```
|
||||
deployment_id = os.environ.get("K8S_NAMESPACE_NAME", "")
|
||||
host = f'https://dev-gpt-{{deployment_id.split("-")[1]}}.wolf.jina.ai/post' if deployment_id else "http://localhost:8080/post"
|
||||
with st.expander("See curl command"):
|
||||
st.code(
|
||||
f'curl -X \\'POST\\' \\'host\\' -H \\'accept: application/json\\' -H \\'Content-Type: application/json\\' -d \\'{{{{"data": [{{{{"text": "hello, world!"}}}}]}}}}\\'',
|
||||
language='bash'
|
||||
)
|
||||
```
|
||||
You must provide the complete app.py file using the following syntax to wrap the code:
|
||||
Note: Don't mention the word Playground in the title.
|
||||
Most importantly: You must generate the complete app.py file using the following syntax to wrap the code:
|
||||
**app.py**
|
||||
```python
|
||||
...
|
||||
```
|
||||
The playground (app.py) must always use the host on http://localhost:8080 and must not let the user configure the host on the UI.
|
||||
The playground (app.py) must not import the executor.
|
||||
'''
|
||||
```'''
|
||||
)
|
||||
|
||||
|
||||
template_chain_of_thought = PromptTemplate.from_template(
|
||||
'''First, write down an extensive list of obvious and non-obvious observations about {file_name_purpose} that could need an adjustment. Explain why.
|
||||
Think if all the changes are required and finally decide for the changes you want to make, but you are not allowed disregard the instructions in the previous message.
|
||||
Be very hesitant to change the code. Only make a change if you are sure that it is necessary.
|
||||
|
||||
Output only {file_name_purpose}
|
||||
Write the whole content of {file_name_purpose} - even if you decided to change only a small thing or even nothing.
|
||||
'''\
|
||||
1. write down an extensive list (5 words per item) of obvious and non-obvious observations about {file_name_purpose} that could need an adjustment.
|
||||
2. Explain why. (5 words per item)
|
||||
3. Think if all the changes are required
|
||||
4. decide for the changes you want to make, but you are not allowed disregard the instructions in the previous message.
|
||||
5. Write the whole content of {file_name_purpose} - even if you decided to change only a small thing or even nothing.
|
||||
Note: Be very hesitant to change the code. Only make a change if you are sure that it is necessary.
|
||||
Note: Output only {file_name_purpose}
|
||||
''' + '\n' + template_code_wrapping_string + '''
|
||||
|
||||
Remember:
|
||||
|
||||
Reference in New Issue
Block a user