Spaces:
Build error
Build error
import streamlit as st | |
from engine import AdvancedPromptOptimizer | |
from llm_optimizer import optimize_with_llm, PERSONAS, get_accurate_token_count, optimize_with_agent | |
from dotenv import load_dotenv | |
import os | |
load_dotenv() | |
cost_model = { | |
"GPT-4": (0.01, 0.03), | |
"GPT-5": (0.012, 0.04), # Premium pricing for latest model | |
"Claude Opus": (0.015, 0.075), | |
"Claude Sonnet": (0.003, 0.015), | |
"LLaMA 2": (0.012, 0.04), | |
"Custom": (None, None), | |
} | |
def format_cost(tokens, cost_per_k): | |
return f"${tokens * cost_per_k / 1000:.4f}" | |
def run_chat_interface(): | |
"""Chat interface for agent-based interactions""" | |
st.subheader("π¬ Chat with AI Agent") | |
# Initialize chat history | |
if "chat_messages" not in st.session_state: | |
st.session_state.chat_messages = [] | |
# Display chat messages | |
for message in st.session_state.chat_messages: | |
with st.chat_message(message["role"]): | |
st.markdown(message["content"]) | |
# Chat input | |
if prompt := st.chat_input("Ask the agent about prompt optimization..."): | |
# Add user message to chat history | |
st.session_state.chat_messages.append({"role": "user", "content": prompt}) | |
with st.chat_message("user"): | |
st.markdown(prompt) | |
# Generate assistant response | |
with st.chat_message("assistant"): | |
response = "π€ Advanced agent functionality coming soon! This will include:\n\n" \ | |
"β’ Memory of conversation context\n" \ | |
"β’ Interactive clarification questions\n" \ | |
"β’ Multi-turn optimization refinement\n" \ | |
"β’ Personalized optimization strategies\n\n" \ | |
f"For now, you asked: '{prompt}'" | |
st.markdown(response) | |
# Add assistant response to chat history | |
st.session_state.chat_messages.append({"role": "assistant", "content": response}) | |
def main(): | |
st.set_page_config(layout="wide", page_title="Prompt Optimizer") | |
st.title("πβ¨ Welcome from the PromptCraft Team β¨π‘") | |
st.title("π AI Prompt Optimizer") | |
col1, col2 = st.columns([0.6, 0.4]) # 60/40 split for better space utilization | |
with col1: | |
st.subheader("LLM Cost") | |
model = st.selectbox("Select LLM Model", list(cost_model.keys())) | |
if model == "Custom": | |
input_cost = st.number_input("Input Cost ($/1K tokens)", 0.01, 1.0, 0.03) | |
output_cost = st.number_input("Output Cost ($/1K tokens)", 0.01, 1.0, 0.06) | |
else: | |
input_cost, output_cost = cost_model[model] | |
st.subheader("Optimization Model") | |
# Create columns for the optimizer section | |
opt_col1, opt_col2 = st.columns([1, 1]) | |
with opt_col1: | |
optimizer_model = st.selectbox( | |
"Choose Optimizer", | |
[ | |
"spaCy + Lemminflect", | |
"GPT-5 (Simple LLM Optimization)", | |
"GPT-5 Search (Agent-Based with Search)", | |
"Agent (Chat Interface)" | |
] | |
) | |
persona = "Default" | |
api_key_input = "" | |
tavily_api_key_input = "" | |
aggressiveness = 1.0 # Initialize default value | |
# Handle different optimizer configurations | |
if optimizer_model in ["GPT-5 (Simple LLM Optimization)", "GPT-5 Search (Agent-Based with Search)"]: | |
with opt_col2: | |
persona = st.selectbox("Choose Persona", list(PERSONAS.keys())) | |
# API Keys in the same row | |
api_col1, api_col2 = st.columns([1, 1]) | |
with api_col1: | |
api_key_input = st.text_input("AIMLAPI API Key (optional)", type="password", help="If you don't provide a key, the one in your .env file will be used.") | |
if optimizer_model == "GPT-5 Search (Agent-Based with Search)": | |
with api_col2: | |
tavily_api_key_input = st.text_input("Tavily API Key (optional)", type="password", help="If you don't provide a key, the one in your .env file will be used.") | |
elif optimizer_model == "spaCy + Lemminflect": | |
with opt_col2: | |
aggressiveness = st.slider( | |
"Optimization Level", | |
0.0, | |
1.0, | |
0.7, | |
help="Higher = more aggressive shortening", | |
) | |
elif optimizer_model == "Agent (Chat Interface)": | |
with opt_col2: | |
persona = st.selectbox("Choose Persona", list(PERSONAS.keys())) | |
# API Keys for agent | |
api_col1, api_col2 = st.columns([1, 1]) | |
with api_col1: | |
api_key_input = st.text_input("AIMLAPI API Key (optional)", type="password", help="Required for agent functionality") | |
with api_col2: | |
tavily_api_key_input = st.text_input("Tavily API Key (optional)", type="password", help="Optional for search capabilities") | |
# Show different interfaces based on optimizer choice | |
if optimizer_model == "Agent (Chat Interface)": | |
# Chat interface takes over the main area | |
st.markdown("---") | |
run_chat_interface() | |
return # Exit early for chat interface | |
else: | |
# Traditional prompt optimization interface | |
prompt = st.text_area( | |
"Original Prompt", height=200, placeholder="Paste your AI prompt here..." | |
) | |
# Optimization button and results (only for non-chat interfaces) | |
if st.button("Optimize", type="primary"): | |
if optimizer_model == "spaCy + Lemminflect": | |
optimizer = AdvancedPromptOptimizer() | |
optimized, orig_toks, new_toks = optimizer.optimize(prompt, aggressiveness) | |
elif optimizer_model == "GPT-5 (Simple LLM Optimization)": | |
api_key = api_key_input if api_key_input else os.getenv("AIMLAPI_API_KEY") | |
if not api_key or api_key == "<YOUR_API_KEY>": | |
st.error("Please set your AIMLAPI_API_KEY in the .env file or enter it above.") | |
return | |
optimized = optimize_with_llm(prompt, api_key, persona) | |
orig_toks = get_accurate_token_count(prompt, "gpt-5") | |
new_toks = get_accurate_token_count(optimized, "gpt-5") | |
elif optimizer_model == "GPT-5 Search (Agent-Based with Search)": | |
api_key = api_key_input if api_key_input else os.getenv("AIMLAPI_API_KEY") | |
tavily_api_key = tavily_api_key_input if tavily_api_key_input else os.getenv("TAVILY_API_KEY") | |
if not api_key or api_key == "<YOUR_API_KEY>": | |
st.error("Please set your AIMLAPI_API_KEY in the .env file or enter it above.") | |
return | |
optimized = optimize_with_agent(prompt, api_key, persona, tavily_api_key=tavily_api_key) | |
orig_toks = get_accurate_token_count(prompt, "gpt-5") | |
new_toks = get_accurate_token_count(optimized, "gpt-5") | |
if orig_toks == 0: | |
st.warning("Please enter a valid prompt.") | |
return | |
# Calculate savings | |
token_savings = orig_toks - new_toks | |
percent_savings = (token_savings / orig_toks) * 100 if orig_toks > 0 else 0 | |
input_cost_savings = token_savings * input_cost / 1000 | |
output_cost_savings = token_savings * output_cost / 1000 | |
total_cost_savings = input_cost_savings + output_cost_savings | |
with col1: | |
st.subheader("Optimized Prompt") | |
st.code(optimized, language="text") | |
# Add download button | |
st.download_button( | |
"π₯ Download Optimized Prompt", | |
optimized, | |
file_name="optimized_prompt.txt", | |
) | |
with col2: | |
st.subheader("π° Optimization Results") | |
# Show method-specific info | |
if optimizer_model == "GPT-5 Search (Agent-Based with Search)": | |
st.info("π Research-Enhanced Optimization with intelligent search integration.") | |
elif optimizer_model == "GPT-5 (Simple LLM Optimization)": | |
st.info("β‘ Fast LLM-based optimization without search.") | |
elif optimizer_model == "spaCy + Lemminflect": | |
st.info("π§ Rule-based linguistic optimization.") | |
# Token Savings - Percentage First | |
st.markdown( | |
f""" | |
<div style=\"background-color:#f0f2f6;padding:15px;border-radius:10px;margin-bottom:15px;"> | |
<h3 style=\"color:#2e86c1;margin-top:0;\">Token Reduction</h3> | |
<div style=\"font-size:28px;font-weight:bold;color:#27ae60;text-align:center;\"> | |
{percent_savings:.1f}% | |
</div> | |
<div style=\"text-align:center;color:#7f8c8d;font-size:14px;\"> | |
{token_savings} tokens saved | |
</div> | |
</div> | |
""", | |
unsafe_allow_html=True, | |
) | |
# Cost Savings - Percentage First | |
if orig_toks > 0 and (input_cost + output_cost) > 0: | |
cost_percent_savings = ( | |
total_cost_savings | |
/ (orig_toks * (input_cost + output_cost) / 1000) | |
* 100 | |
) | |
else: | |
cost_percent_savings = 0 | |
st.markdown( | |
f""" | |
<div style=\"background-color:#f0f2f6;padding:15px;border-radius:10px;margin-bottom:15px;"> | |
<h3 style=\"color:#2e86c1;margin-top:0;\">Cost Reduction</h3> | |
<div style=\"font-size:28px;font-weight:bold;color:#27ae60;text-align:center;\"> | |
{cost_percent_savings:.1f}% | |
</div> | |
<div style=\"text-align:center;color:#7f8c8d;font-size:14px;\"> | |
${total_cost_savings:.4f} saved per call | |
</div> | |
</div> | |
""", | |
unsafe_allow_html=True, | |
) | |
# Visual indicator with percentage | |
st.progress(min(1.0, max(0.0, percent_savings / 100))) | |
st.caption(f"Prompt reduced to {100-percent_savings:.1f}% of original size") | |
# Detailed Breakdown | |
with st.expander("π Cost Analysis"): | |
col_a, col_b = st.columns(2) | |
with col_a: | |
st.markdown( | |
f"**Input Cost**\n\n" | |
f"Original: {format_cost(orig_toks, input_cost)}\n\n" | |
f"Optimized: {format_cost(new_toks, input_cost)}\n\n" | |
f"Saved: {format_cost(token_savings, input_cost)}" | |
) | |
with col_b: | |
st.markdown( | |
f"**Output Cost**\n\n" | |
f"Original: {format_cost(orig_toks, output_cost)}\n\n" | |
f"Optimized: {format_cost(new_toks, output_cost)}\n\n" | |
f"Saved: {format_cost(token_savings, output_cost)}" | |
) | |
# Optimization report | |
with st.expander("π Applied Optimizations"): | |
if optimizer_model == "GPT-5 Search (Agent-Based with Search)": | |
st.markdown("π€ **Agent-Based Optimization**") | |
st.markdown("β’ Intelligent search query generation") | |
st.markdown("β’ Context-aware prompt enhancement") | |
st.markdown("β’ Persona-specific optimization") | |
st.markdown("β’ Autonomous decision-making process") | |
elif optimizer_model == "GPT-5 (Simple LLM Optimization)": | |
st.markdown("β‘ **Simple LLM Optimization**") | |
st.markdown("β’ Direct prompt optimization") | |
st.markdown("β’ Persona-specific guidelines") | |
st.markdown("β’ Fast processing") | |
st.markdown("β’ No search enhancement") | |
else: | |
st.markdown("π§ **Rule-Based Optimization**") | |
st.markdown(f"β’ Optimization aggressiveness: {aggressiveness*100:.0f}%") | |
st.markdown("### Share Your Savings") | |
optimization_method = { | |
"spaCy + Lemminflect": f"Rule-based (Level: {aggressiveness*100:.0f}%)", | |
"GPT-5 (Simple LLM Optimization)": f"Simple LLM ({persona})", | |
"GPT-5 Search (Agent-Based with Search)": f"Agent+Search ({persona})" | |
} | |
st.code( | |
f"Saved {token_savings} tokens (${total_cost_savings:.4f}) with #PromptOptimizer\n" | |
f"Method: {optimization_method.get(optimizer_model, 'Unknown')}" | |
) | |
if __name__ == "__main__": | |
main() |