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 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=prompt_refiner_model, messages=messages, max_tokens=2000, temperature=0.8 ) response_content = response.choices[0].message.content.strip() try: json_match = re.search(r'\s*(.*?)\s*', response_content, re.DOTALL) if json_match: json_str = json_match.group(1) json_str = re.sub(r'\n\s*', ' ', json_str) json_str = json_str.replace('"', '\\"') json_output = json.loads(f'"{json_str}"') if isinstance(json_output, str): json_output = json.loads(json_output) 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}") 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] = "" return RefinementOutput(**output, raw_content=response_content) def apply_prompt(self, prompt: str, model: 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=model, messages=messages, max_tokens=2000, temperature=0.8 ) output = response.choices[0].message.content.strip() 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="star",info=lambda x: metaprompt_explanations.get(x, "No explanation available.")) 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,visible=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( [ "Qwen/Qwen2.5-72B-Instruct", "meta-llama/Meta-Llama-3-70B-Instruct", "meta-llama/Llama-3.1-8B-Instruct", "NousResearch/Hermes-3-Llama-3.1-8B", "HuggingFaceH4/zephyr-7b-alpha", "meta-llama/Llama-2-7b-chat-hf", "microsoft/Phi-3.5-mini-instruct" ], value="meta-llama/Meta-Llama-3-70B-Instruct", label="Choose the Model to apply to the prompts (the one you will used)" ) apply_button = gr.Button("Apply Prompts") with gr.Tab("Original Prompt Output"): # gr.Markdown("### Original Prompt Output") original_output = gr.Markdown(label="Original Prompt Output") with gr.Tab("Refined Prompt Output"): #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, apply_model], outputs=[original_output, refined_output] ) with gr.Accordion("Examples", open=True): gr.Examples( examples=[ ["Write a story on the end of prompt engineering replaced by an Ai specialized in refining prompts.", "star"], ["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"], ["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, model: str): original_output = self.prompt_refiner.apply_prompt(original_prompt, model) refined_output = self.prompt_refiner.apply_prompt(refined_prompt, model) return original_output, refined_output def launch(self, share=False): self.interface.launch(share=share) metaprompt_explanations = { "star": "The ECHO (Enhanced Chain of Harmonized Optimization) method, which provides a comprehensive and structured approach to prompt refinement, including multiple stages of analysis, expansion, and synthesis.", "done": "A detailed, multi-step approach that emphasizes role-playing, structured output, and various advanced prompting techniques like Chain-of-Thought and Tree of Thoughts.", "physics": "A prompt enhancement method that focuses on role-playing, structured output, and incorporating multiple advanced prompting techniques such as Chain-of-Thought and Tree of Thoughts.", "morphosis": "A simplified approach that focuses on clear language, logical flow, and essential elements of prompt engineering without complex techniques.", "verse": "A structured method that emphasizes analyzing the initial prompt, evaluating its strengths and weaknesses, and refining it with a focus on information flow and versatility.", "phor": "An advanced prompt engineering approach that combines multiple techniques, including clarity enhancement, structural improvement, and various specialized prompting methods like Chain-of-Thought and Few-Shot Learning.", "bolism": "A prompt refinement method that emphasizes leveraging the autoregressive nature of language models, encouraging reasoning before conclusions, and providing detailed instructions for output formatting." } # Main code to run the application if __name__ == '__main__': meta_info="" 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') prompt_refiner_model = os.getenv('prompt_refiner_model') 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)