baconnier's picture
Update app.py
ffe3f76 verified
import gradio as gr
from prompt_refiner import PromptRefiner
from variables import models, explanation_markdown, metaprompt_list, examples
from custom_css import custom_css
class GradioInterface:
def __init__(self, prompt_refiner: PromptRefiner, custom_css):
self.prompt_refiner = prompt_refiner
# Set default model to second-to-last in the list
default_model = models[-1] if len(models) >= 1 else models[0] if models else None
#meta_prompt_choice=metaprompt_list[0]
with gr.Blocks(css=custom_css, theme=gr.themes.Default()) as self.interface:
# CONTAINER 1
with gr.Column(elem_classes=["container", "title-container"]):
gr.Markdown("# PROMPT++")
gr.Markdown("### Automating Prompt Engineering by Refining your Prompts")
gr.Markdown("Learn how to generate an improved version of your prompts.")
# CONTAINER 2
with gr.Column(elem_classes=["container", "input-container"]):
prompt_text = gr.Textbox(label="Type your prompt (or leave empty to see metaprompt)",lines=5)
with gr.Accordion("Prompt Examples", open=False, visible=True):
gr.Examples(examples=examples,inputs=[prompt_text])
automatic_metaprompt_button = gr.Button(
"Automatic Choice for Refinement Method",
elem_classes=["button-highlight"]
)
MetaPrompt_analysis = gr.Markdown()
# CONTAINER 3
with gr.Column(elem_classes=["container","meta-container"]):
meta_prompt_choice = gr.Radio(
choices=metaprompt_list,
label="Choose Meta Prompt",
value=metaprompt_list[0],
elem_classes=["no-background", "radio-group"]
)
refine_button = gr.Button(
"Refine Prompt",
elem_classes=["button-waiting"]
)
with gr.Accordion("Metaprompt Explanation", open=False, visible=True):
gr.Markdown(explanation_markdown)
with gr.Column(elem_classes=["container", "analysis-container"]):
gr.Markdown(" ")
prompt_evaluation = gr.Markdown()
gr.Markdown("### Refined Prompt")
refined_prompt = gr.Textbox(
label=" ",
interactive=True,
show_label=True,
show_copy_button=True,
)
explanation_of_refinements = gr.Markdown()
with gr.Column(elem_classes=["container", "model-container"]):
with gr.Row():
apply_model = gr.Dropdown(
choices=models,
value=default_model,
label="Choose the Model",
container=False,
scale=1,
min_width=300
)
apply_button = gr.Button(
"Apply Prompts",
elem_classes=["button-waiting"]
)
gr.Markdown("### Prompts on Chosen Model")
with gr.Tabs(elem_classes=["tabs"]):
with gr.TabItem("Prompts Output Comparison", elem_classes=["tabitem"]):
with gr.Row(elem_classes=["output-row"]):
with gr.Column(scale=1, elem_classes=["comparison-column"]):
gr.Markdown("### Original Prompt Output")
original_output1 = gr.Markdown(
# value="Output will appear here",
elem_classes=["output-content"],
visible=True
)
with gr.Column(scale=1, elem_classes=["comparison-column"]):
gr.Markdown("### Refined Prompt Output")
refined_output1 = gr.Markdown(
# value="Output will appear here",
elem_classes=["output-content"],
visible=True
)
with gr.TabItem("Original Prompt Output", elem_classes=["tabitem"]):
with gr.Row(elem_classes=["output-row"]):
with gr.Column(scale=1, elem_classes=["comparison-column"]):
gr.Markdown("### Original Prompt Output")
original_output = gr.Markdown(
# value="Output will appear here",
elem_classes=[ "output-content"],
visible=True
)
with gr.TabItem("Refined Prompt Output", elem_classes=["tabitem"]):
with gr.Row(elem_classes=["output-row"]):
with gr.Column(scale=1, elem_classes=["comparison-column"]):
gr.Markdown("### Refined Prompt Output")
refined_output = gr.Markdown(
# value="Output will appear here",
elem_classes=["output-content"],
visible=True
)
with gr.Accordion("Full Response JSON", open=False, visible=True):
full_response_json = gr.JSON()
# Button click handlers
automatic_metaprompt_button.click(
fn=self.automatic_metaprompt,
inputs=[prompt_text],
outputs=[MetaPrompt_analysis, meta_prompt_choice]
).then(
fn=lambda: None,
inputs=None,
outputs=None,
js="""
() => {
// Clear subsequent outputs
document.querySelectorAll('.analysis-container textarea, .analysis-container .markdown-text, .model-container .markdown-text, .comparison-output').forEach(el => {
if (el.value !== undefined) {
el.value = '';
} else {
el.textContent = '';
}
});
// Update button states
const allButtons = Array.from(document.querySelectorAll('button')).filter(btn =>
btn.textContent.includes('Automatic Choice') ||
btn.textContent.includes('Refine Prompt') ||
btn.textContent.includes('Apply Prompts')
);
allButtons.forEach(btn => btn.classList.remove('button-highlight'));
allButtons[1].classList.add('button-highlight'); // Highlight refine button
allButtons[0].classList.add('button-completed'); // Complete current button
allButtons[2].classList.add('button-waiting'); // Set apply button to waiting
}
"""
)
refine_button.click(
fn=self.refine_prompt,
inputs=[prompt_text, meta_prompt_choice],
outputs=[prompt_evaluation, refined_prompt, explanation_of_refinements, full_response_json]
).then(
fn=lambda: None,
inputs=None,
outputs=None,
js="""
() => {
// Clear model outputs
document.querySelectorAll('.model-container .markdown-text, .comparison-output').forEach(el => {
if (el.value !== undefined) {
el.value = '';
} else {
el.textContent = '';
}
});
// Update button states
const allButtons = Array.from(document.querySelectorAll('button')).filter(btn =>
btn.textContent.includes('Automatic Choice') ||
btn.textContent.includes('Refine Prompt') ||
btn.textContent.includes('Apply Prompts')
);
allButtons.forEach(btn => btn.classList.remove('button-highlight'));
allButtons[2].classList.add('button-highlight'); // Highlight apply button
allButtons[1].classList.add('button-completed'); // Complete current button
allButtons[2].classList.remove('button-waiting'); // Remove waiting from apply button
}
"""
)
apply_button.click(
fn=self.apply_prompts,
inputs=[prompt_text, refined_prompt, apply_model],
outputs=[original_output, refined_output, original_output1, refined_output1],
show_progress=True # Add this line
).then(
fn=lambda: None,
inputs=None,
outputs=None,
js="""
() => {
// Update button states
const allButtons = Array.from(document.querySelectorAll('button')).filter(btn =>
btn.textContent.includes('Automatic Choice') ||
btn.textContent.includes('Refine Prompt') ||
btn.textContent.includes('Apply Prompts')
);
allButtons.forEach(btn => btn.classList.remove('button-highlight', 'button-waiting'));
allButtons[2].classList.add('button-completed'); // Complete apply button
// Force refresh of output containers
document.querySelectorAll('.comparison-output').forEach(el => {
if (el.parentElement) {
el.parentElement.style.display = 'none';
setTimeout(() => {
el.parentElement.style.display = 'block';
}, 100);
}
});
}
"""
)
# Reset when input changes
prompt_text.change(
fn=lambda: None,
inputs=None,
outputs=None,
js="""
() => {
// Clear all outputs
document.querySelectorAll('.analysis-container textarea, .analysis-container .markdown-text, .model-container .markdown-text, .comparison-output').forEach(el => {
if (el.value !== undefined) {
el.value = '';
} else {
el.textContent = '';
}
});
// Reset all button states
const allButtons = Array.from(document.querySelectorAll('button')).filter(btn =>
btn.textContent.includes('Automatic Choice') ||
btn.textContent.includes('Refine Prompt') ||
btn.textContent.includes('Apply Prompts')
);
allButtons.forEach(btn => {
btn.classList.remove('button-completed', 'button-highlight', 'button-waiting');
});
allButtons[0].classList.add('button-highlight'); // Highlight first button
allButtons.slice(1).forEach(btn => btn.classList.add('button-waiting')); // Set subsequent buttons to waiting
}
"""
)
def automatic_metaprompt(self, prompt: str) -> tuple:
"""Handle automatic metaprompt selection"""
try:
if not prompt.strip():
return "Please enter a prompt to analyze.", None
metaprompt_analysis, recommended_key = self.prompt_refiner.automatic_metaprompt(prompt)
return metaprompt_analysis, recommended_key
except Exception as e:
error_message = f"Error in automatic metaprompt: {str(e)}"
return error_message, None
def refine_prompt(self, prompt: str, meta_prompt_choice: str) -> tuple:
"""Handle manual prompt refinement"""
try:
if not prompt.strip():
return ("No prompt provided.", "", "", {})
result = self.prompt_refiner.refine_prompt(prompt, meta_prompt_choice)
return (
result[0], # initial_prompt_evaluation
result[1], # refined_prompt
result[2], # explanation_of_refinements
result[3] # full_response
)
except Exception as e:
error_message = f"Error in refine_prompt: {str(e)}"
return error_message, "", "", {}
def apply_prompts(self, original_prompt: str, refined_prompt: str, model: str) -> tuple:
"""Apply both original and refined prompts to the selected model"""
try:
if not original_prompt or not refined_prompt:
return ("Please provide both original and refined prompts.",
"Please provide both original and refined prompts.",
"Please provide both original and refined prompts.",
"Please provide both original and refined prompts.")
if not model:
return ("Please select a model.",
"Please select a model.",
"Please select a model.",
"Please select a model.")
# Apply prompts and get outputs
try:
# print(original_prompt)
# print(refined_prompt)
#print(model)
original_output = self.prompt_refiner.apply_prompt(original_prompt, model)
#print(original_output)
refined_output = self.prompt_refiner.apply_prompt(refined_prompt, model)
except Exception as e:
return (f"Error applying prompts: {str(e)}",
f"Error applying prompts: {str(e)}",
f"Error applying prompts: {str(e)}",
f"Error applying prompts: {str(e)}")
# Ensure we have string outputs
original_output = str(original_output) if original_output is not None else "No output generated"
refined_output = str(refined_output) if refined_output is not None else "No output generated"
#print('-'*100)
#print(original_output)
#print('-'*100)
#print(refined_output)
#print('-'*100)
return (
original_output, # For Original Prompt Output tab
refined_output, # For Refined Prompt Output tab
original_output, # For Comparison tab - original
refined_output # For Comparison tab - refined
)
except Exception as e:
error_message = f"Error in apply_prompts: {str(e)}"
return (error_message, error_message, error_message, error_message)
def launch(self, share=False):
"""Launch the Gradio interface"""
self.interface.launch(share=share)
if __name__ == '__main__':
from variables import api_token, meta_prompts, metaprompt_explanations
# Initialize the prompt refiner
prompt_refiner = PromptRefiner(api_token, meta_prompts, metaprompt_explanations)
# Create and launch the Gradio interface
gradio_interface = GradioInterface(prompt_refiner, custom_css)
gradio_interface.launch(share=True)