baconnier's picture
Update app.py
2db28ae verified
raw
history blame
10.2 kB
import os
import json
import re
from huggingface_hub import InferenceClient
import gradio as gr
from pydantic import BaseModel, Field
from typing import Optional, Literal
import json
import re
import json
import re
from huggingface_hub import InferenceClient
from pydantic import BaseModel, Field
from typing import Optional, Literal
class PromptInput(BaseModel):
text: str = Field(..., description="The initial prompt text")
meta_prompt_choice: Literal["star","done","physics","morphosis", "verse", "phor","bolism"] = Field(..., description="Choice of meta prompt strategy")
class RefinementOutput(BaseModel):
query_analysis: Optional[str] = None
initial_prompt_evaluation: Optional[str] = None
refined_prompt: Optional[str] = None
explanation_of_refinements: Optional[str] = None
raw_content: Optional[str] = None
class PromptRefiner:
def __init__(self, api_token: str):
self.client = InferenceClient(token=api_token)
def refine_prompt(self, prompt_input: PromptInput) -> RefinementOutput:
if prompt_input.meta_prompt_choice == "morphosis":
selected_meta_prompt = original_meta_prompt
elif prompt_input.meta_prompt_choice == "verse":
selected_meta_prompt = new_meta_prompt
elif prompt_input.meta_prompt_choice == "physics":
selected_meta_prompt = metaprompt1
elif prompt_input.meta_prompt_choice == "bolism":
selected_meta_prompt = loic_metaprompt
elif prompt_input.meta_prompt_choice == "done":
selected_meta_prompt = metadone
elif prompt_input.meta_prompt_choice == "star":
selected_meta_prompt = echo_prompt_refiner
else:
selected_meta_prompt = advanced_meta_prompt
messages = [
{"role": "system", "content": 'You are an expert at refining and extending prompts. Given a basic prompt, provide a more detailed.'},
{"role": "user", "content": selected_meta_prompt.replace("[Insert initial prompt here]", prompt_input.text)}
]
response = self.client.chat_completion(
model="meta-llama/Meta-Llama-3-70B-Instruct",
messages=messages,
max_tokens=4000,
temperature=0.3
)
response_content = response.choices[0].message.content.strip()
try:
# Extract JSON from between <json> tags
json_match = re.search(r'<json>\s*(.*?)\s*</json>', response_content, re.DOTALL)
if json_match:
json_str = json_match.group(1)
# Remove newlines and escape quotes within the JSON string
json_str = re.sub(r'\n\s*', ' ', json_str)
json_str = json_str.replace('"', '\\"')
# Wrap the entire string in quotes and parse it
json_output = json.loads(f'"{json_str}"')
# Ensure json_output is a dictionary
if isinstance(json_output, str):
json_output = json.loads(json_output)
# Unescape the parsed JSON
for key, value in json_output.items():
if isinstance(value, str):
json_output[key] = value.replace('\\"', '"')
return RefinementOutput(**json_output, raw_content=response_content)
else:
raise ValueError("No JSON found in the response")
except (json.JSONDecodeError, ValueError) as e:
print(f"Error parsing JSON: {e}")
print(f"Raw content: {response_content}")
# If JSON parsing fails, attempt to extract the content manually
output = {}
for key in ["initial_prompt_evaluation", "refined_prompt", "explanation_of_refinements"]:
pattern = rf'"{key}":\s*"(.*?)"(?:,|\}})'
match = re.search(pattern, response_content, re.DOTALL)
if match:
output[key] = match.group(1).replace('\\n', '\n').replace('\\"', '"')
else:
output[key] = "" # Set empty string if content not found
return RefinementOutput(**output, raw_content=response_content)
def apply_prompt(self, prompt: str) -> str:
try:
messages = [
{"role": "system", "content": "You are a helpful assistant. Answer in stylized version with latex format or markdown if relevant. Separate your answer into logical sections using level 2 headers (##) for sections and bolding (**) for subsections.Incorporate a variety of lists, headers, and text to make the answer visually appealing"},
{"role": "user", "content": prompt}
]
response = self.client.chat_completion(
model="meta-llama/Meta-Llama-3-70B-Instruct",
messages=messages,
max_tokens=4000, # Increased token limit
temperature=0.8
)
output = response.choices[0].message.content.strip()
# Basic post-processing
output = output.replace('\n\n', '\n').strip()
return output
except Exception as e:
return f"Error: {str(e)}"
class GradioInterface:
def __init__(self, prompt_refiner: PromptRefiner):
self.prompt_refiner = prompt_refiner
with gr.Blocks() as self.interface:
gr.Markdown("# PROMPT++")
gr.Markdown("### Automating Prompt Engineering by Refining your Prompts")
gr.Markdown("Learn how to generate an improved version of your prompts. Enter a main idea for a prompt, choose a meta prompt, and the model will attempt to generate an improved version.")
with gr.Row():
prompt_text = gr.Textbox(label="Type the prompt here")
with gr.Row():
meta_prompt_choice = gr.Radio(["star","done","physics","morphosis", "verse", "phor","bolism"], label="Choose Meta Prompt", value="morphosis")
refine_button = gr.Button("Refine Prompt")
with gr.Row():
gr.Markdown("### Initial prompt analysis")
with gr.Column():
analysis_evaluation = gr.Markdown(label="Analysis and Evaluation")
gr.Markdown("### Refined Prompt")
refined_prompt = gr.Textbox(label="Refined Prompt")
gr.Markdown("### Explanation of Refinements")
explanation_of_refinements = gr.Markdown(label="Explanation of Refinements")
with gr.Accordion("Full Response JSON", open=False):
full_response_json = gr.JSON()
refine_button.click(
fn=self.refine_prompt,
inputs=[prompt_text, meta_prompt_choice],
outputs=[analysis_evaluation, refined_prompt, explanation_of_refinements, full_response_json]
)
with gr.Row():
# apply_model=gr.Dropdown(["meta-llama/Llama-3.1-70B-Instruct",'Qwen/Qwen2.5-72B-Instruct'], value="meta-llama/Llama-3.1-70B-Instruct", label="Model"),
apply_button = gr.Button("Apply Prompts")
with gr.Row():
with gr.Column():
gr.Markdown("### Original Prompt Output")
original_output = gr.Markdown(label="Original Prompt Output")
with gr.Column():
gr.Markdown("### Refined Prompt Output")
refined_output = gr.Markdown(label="Refined Prompt Output")
apply_button.click(
fn=self.apply_prompts,
inputs=[prompt_text, refined_prompt],
outputs=[original_output, refined_output]
)
gr.Examples(
examples=[
["Tell me about that guy who invented the light bulb", "physics"],
["Explain the universe.", "star"],
["What's the population of New York City and how tall is the Empire State Building and who was the first mayor?", "morphosis"],
["List American presidents.", "verse"],
["Write a story.", "bolism"],
["Explain why the experiment failed.", "morphosis"],
["Is nuclear energy good?", "verse"],
["How does a computer work?", "phor"],
["How to make money fast?", "done"],
["how can you prove IT0's lemma in stochastic calculus ?", "star"],
],
inputs=[prompt_text, meta_prompt_choice]
)
def refine_prompt(self, prompt: str, meta_prompt_choice: str) -> tuple:
input_data = PromptInput(text=prompt, meta_prompt_choice=meta_prompt_choice)
result = self.prompt_refiner.refine_prompt(input_data)
analysis_evaluation = f"\n\n{result.initial_prompt_evaluation}"
return (
analysis_evaluation,
result.refined_prompt,
result.explanation_of_refinements,
result.dict()
)
def apply_prompts(self,original_prompt: str, refined_prompt: str):
original_output = self.prompt_refiner.apply_prompt(original_prompt)
refined_output = self.prompt_refiner.apply_prompt(refined_prompt)
return original_output, refined_output
def launch(self, share=False):
self.interface.launch()
# Main code to run the application
if __name__ == '__main__':
api_token = os.getenv('HF_API_TOKEN')
if not api_token:
raise ValueError("HF_API_TOKEN not found in environment variables")
metadone=os.getenv('metadone')
echo_prompt_refiner = os.getenv('echo_prompt_refiner')
metaprompt1 = os.getenv('metaprompt1')
loic_metaprompt = os.getenv('loic_metaprompt')
openai_metaprompt=os.getenv('openai_metaprompt')
original_meta_prompt = os.getenv('original_meta_prompt')
new_meta_prompt = os.getenv('new_meta_prompt')
advanced_meta_prompt = os.getenv('advanced_meta_prompt')
prompt_refiner = PromptRefiner(api_token)
gradio_interface = GradioInterface(prompt_refiner)
gradio_interface.launch(share=True)