import os
import streamlit as st
import streamlit.components.v1 as components
from dotenv import load_dotenv
import base64
from openai import OpenAI
from repo_library.prompts import combine_prompts, get_available_prompts
# Load environment variables
load_dotenv()
def refine_with_openai(prompt: str, api_key: str) -> str:
"""
Use OpenAI to refine and improve the combined prompt.
"""
if not api_key:
return prompt
try:
client = OpenAI(api_key=api_key)
response = client.chat.completions.create(
model="gpt-4",
messages=[
{
"role": "system",
"content": "You are an expert at crafting system prompts. Your task is to take the provided prompt components and combine them into a natural, cohesive system prompt that maintains the essence of each component while ensuring they flow together seamlessly."
},
{
"role": "user",
"content": f"Please refine this system prompt while maintaining its core elements:\n\n{prompt}"
}
]
)
return response.choices[0].message.content
except Exception as e:
st.error(f"Error refining prompt with OpenAI: {str(e)}")
return prompt
def get_download_link(text, filename="system_prompt.txt"):
"""Generate a download link for text content."""
b64 = base64.b64encode(text.encode()).decode()
return f'📥 Download System Prompt'
def reset_all_fields():
"""Reset all session state variables."""
for key in st.session_state.keys():
del st.session_state[key]
def display_prompt_preview(prompt: str):
"""Display a preview of the prompt with proper formatting."""
st.code(prompt, language="markdown")
def main():
# Initialize session state
if 'active_tab' not in st.session_state:
st.session_state.active_tab = 0
st.set_page_config(
page_title="System Prompt Factory",
page_icon="🎯",
layout="wide",
initial_sidebar_state="expanded",
menu_items={
'Get Help': 'https://github.com/All-Hands-AI/OpenHands',
'About': 'System Prompt Factory - Enhanced by OpenHands'
}
)
# Set sidebar width and ensure it's always expanded
st.markdown("""
""", unsafe_allow_html=True)
# Custom CSS for better styling
st.markdown("""
""", unsafe_allow_html=True)
# Header with improved design
st.markdown("""
🎯 System Prompt Factory
Create perfectly tailored AI system prompts
""", unsafe_allow_html=True)
# Add welcome message
st.markdown("""
Follow the steps in the sidebar to create your perfect AI assistant.
Each step builds upon the last to create a comprehensive system prompt.
""", unsafe_allow_html=True)
# Get available prompts
available_prompts = get_available_prompts()
# OpenAI API Key input in sidebar
with st.sidebar:
st.subheader("OpenAI Integration")
api_key = st.text_input(
"OpenAI API Key (optional)",
type="password",
help="Enter your OpenAI API key to enable AI-powered prompt refinement"
)
st.subheader("Prompt Settings")
target_length = st.selectbox(
"Target Word Length",
options=[0, 100, 200, 300, 400, 500],
help="Set a target word length for the prompt. Select 0 for no limit.",
format_func=lambda x: "No Limit" if x == 0 else f"{x} words"
)
st.divider()
st.markdown("""
### About
This tool helps you create custom system prompts by combining different components:
- Model Personality
- User Location/Culture
- User Type/Background
- Worldview/Perspective
Each component adds a unique aspect to the final prompt.
""")
# Style tabs
st.markdown("""
""", unsafe_allow_html=True)
# Create sections using tabs with active tab from session state
tab_titles = ["🤖 Configure AI Assistant", "👤 Set User Preferences", "📝 Choose Output Format"]
tabs = st.tabs(tab_titles)
# Ensure the correct tab is shown based on sidebar selection
current_tab = st.session_state.active_tab
with tabs[0]:
st.markdown("""
AI Identity & Behavior
Configure how your AI assistant should present itself and interact
""", unsafe_allow_html=True)
# Create three sections with cards
st.markdown("""
🎭 Core Identity
💬 Communication Style
🎨 Personality & Expression
""", unsafe_allow_html=True)
# Core Identity Section
with st.container():
st.markdown("##### Core Identity Settings")
identity_type = st.selectbox(
"AI Identity Type",
options=available_prompts["model_identity"],
help="Choose how your AI assistant should present itself",
format_func=lambda x: {
"neutral": "🤖 Standard AI Assistant",
"bot": "⚡ Proud AI Bot",
"alien": "👽 Extraterrestrial Intelligence",
"sloth": "🦥 Laid-back Sloth"
}.get(x, "🤖 " + x.replace("_", " ").title())
)
col1, col2 = st.columns(2)
with col1:
ai_name = st.text_input(
"AI Name",
help="Give your AI assistant a unique name",
placeholder="e.g., Atlas, Nova, Sage"
)
with col2:
personality = st.selectbox(
"Base Personality",
options=available_prompts["model_personalities"],
help="Select the core personality trait",
format_func=lambda x: "😊 " + x.replace("_", " ").title()
)
backstory = st.text_area(
"Backstory (optional)",
help="Add a brief backstory to give your AI more character",
placeholder="e.g., Created in a secret lab beneath Mount Everest...",
max_chars=200,
height=100
)
st.divider()
# Communication Style Section
st.markdown("##### Communication Preferences")
col1, col2 = st.columns(2)
with col1:
formality = st.select_slider(
"Formality Level",
options=available_prompts["model_formality"],
help="Adjust how formal or casual the AI should be",
format_func=lambda x: x.replace("_", " ").title()
)
expertise = st.select_slider(
"Expertise Level",
options=available_prompts["model_expertise"],
help="Set the depth of knowledge and explanation",
format_func=lambda x: x.replace("_", " ").title()
)
with col2:
response_style = st.selectbox(
"Response Style",
options=available_prompts["model_response_style"],
help="How should the AI structure its responses?",
format_func=lambda x: x.replace("_", " ").title()
)
language_style = st.selectbox(
"Language Style",
options=available_prompts["model_language_style"],
help="Choose the linguistic style",
format_func=lambda x: {
"neutral": "🔤 Modern English",
"shakespearean": "📜 Shakespearean",
"middle_ages": "⚔️ Medieval",
"rhyming": "🎵 Rhyming"
}.get(x, "🔤 " + x.replace("_", " ").title())
)
with tabs[1]:
st.markdown("""
User Preferences
Customize how the AI understands and interacts with you
""", unsafe_allow_html=True)
# Create three card sections
st.markdown("""
👤 Personal Profile
🌍 Context & Background
🎯 Learning Preferences
""", unsafe_allow_html=True)
# Personal Profile Section
st.markdown("##### Personal Information")
col1, col2, col3 = st.columns(3)
with col1:
user_name = st.text_input(
"Name (optional)",
help="Your preferred name for personalized interactions",
placeholder="e.g., John Doe"
)
with col2:
age_group = st.selectbox(
"Age Group",
options=["", "Under 18", "18-25", "26-35", "36-50", "51+"],
help="Help the AI adjust its communication style",
format_func=lambda x: "🔹 " + (x if x else "Not specified")
)
with col3:
occupation = st.text_input(
"Occupation",
help="Helps the AI provide relevant examples",
placeholder="e.g., Software Engineer"
)
st.divider()
# Context & Background Section
st.markdown("##### Cultural & Perspective Settings")
col1, col2 = st.columns(2)
with col1:
location = st.selectbox(
"Cultural Context",
options=available_prompts["user_geolocation"],
help="Adapt responses to your cultural background",
format_func=lambda x: "🌍 " + x.replace("_", " ").title()
)
worldview = st.selectbox(
"Worldview",
options=available_prompts["user_worldview"],
help="Choose a philosophical perspective",
format_func=lambda x: "🔮 " + x.replace("_", " ").title()
)
with col2:
political_leaning = st.selectbox(
"Political Perspective",
options=available_prompts["user_political_leaning"],
help="Select your preferred political framing",
format_func=lambda x: "⚖️ " + x.replace("_", " ").title()
)
user_type = st.selectbox(
"Interaction Style",
options=available_prompts["user_personality"],
help="How would you like the AI to interact with you?",
format_func=lambda x: "🤝 " + x.replace("_", " ").title()
)
st.divider()
# Learning Preferences Section
st.markdown("##### Learning & Communication Style")
col1, col2 = st.columns(2)
with col1:
learning_style = st.select_slider(
"Learning Approach",
options=available_prompts["user_learning_style"],
help="How do you prefer to learn new information?",
format_func=lambda x: x.replace("_", " ").title()
)
with col2:
communication_pace = st.select_slider(
"Communication Pace",
options=available_prompts["user_communication_pace"],
help="How detailed should the responses be?",
format_func=lambda x: x.replace("_", " ").title()
)
with tabs[2]:
st.markdown("""
Output Format
Customize how the AI should structure and present information
""", unsafe_allow_html=True)
# Create two card sections
st.markdown("""
📄 Documentation Style
🔢 Data Format
""", unsafe_allow_html=True)
# Documentation Format Section
st.markdown("##### Documentation Preferences")
doc_style = st.select_slider(
"Documentation Structure",
options=available_prompts["user_output_preference"],
help="How should information be organized and presented?",
format_func=lambda x: x.replace("_", " ").title()
)
st.divider()
# Data Structure Section
st.markdown("##### Data Formatting")
data_format = st.select_slider(
"Data Structure",
options=["neutral", "data_format"],
help="Choose how structured data should be presented",
format_func=lambda x: {
"neutral": "Standard Text Format",
"data_format": "Strict Data Format (CSV, JSON, etc.)"
}.get(x, x.replace("_", " ").title())
)
# Final section with generate button and results
st.markdown("""
🎯 Ready to Create Your System Prompt?
Review your settings and generate your customized prompt
""", unsafe_allow_html=True)
# Create a row for the action buttons
col1, col2 = st.columns([3, 1])
with col1:
if st.button("✨ Generate System Prompt", type="primary", use_container_width=True):
generate_prompt = True
with col2:
if st.button("↺ Reset All", type="secondary", use_container_width=True, on_click=reset_all_fields):
st.rerun()
st.markdown("
", unsafe_allow_html=True)
if 'generate_prompt' in locals():
# Combine selected components
combined_prompt = combine_prompts(
personality=personality,
geolocation=location,
user_type=user_type,
worldview=worldview,
response_style=response_style,
expertise=expertise,
learning_style=learning_style,
communication_pace=communication_pace,
political_leaning=political_leaning,
formality=formality,
language_style=language_style,
identity_type=identity_type,
ai_name=ai_name,
backstory=backstory,
output_preference=doc_style,
data_format=data_format,
user_name=user_name,
age_group=age_group,
occupation=occupation,
target_length=target_length if target_length > 0 else None
)
# Results section with improved design
st.markdown("""
🎨 Generated System Prompt
""", unsafe_allow_html=True)
# Create tabs for different views with custom styling
tab_style = """
"""
st.markdown(tab_style, unsafe_allow_html=True)
raw_tab, refined_tab = st.tabs(["📝 Base Prompt", "✨ AI-Enhanced Version"])
with raw_tab:
st.markdown("##### Generated from your selections")
display_prompt_preview(combined_prompt)
col1, col2 = st.columns([1, 2])
with col1:
if st.button("📋 Copy Prompt", type="secondary", use_container_width=True):
st.toast("✅ Prompt copied to clipboard!")
with col2:
st.markdown(get_download_link(combined_prompt), unsafe_allow_html=True)
with refined_tab:
if api_key:
st.markdown("##### Enhanced by AI for natural flow")
with st.spinner("✨ Enhancing your prompt with AI..."):
refined_prompt = refine_with_openai(combined_prompt, api_key)
display_prompt_preview(refined_prompt)
col1, col2 = st.columns([1, 2])
with col1:
if st.button("📋 Copy Enhanced", type="secondary", use_container_width=True):
st.toast("✅ Enhanced prompt copied to clipboard!")
with col2:
st.markdown(get_download_link(refined_prompt, "enhanced_system_prompt.txt"), unsafe_allow_html=True)
else:
st.info("💡 Enter your OpenAI API key in the sidebar to enable AI enhancement of your prompt.")
# Add footer with improved design
st.markdown("""
""", unsafe_allow_html=True)
if __name__ == "__main__":
main()