Spaces:
Sleeping
Sleeping
File size: 8,574 Bytes
877bedf ffbefb9 877bedf ffbefb9 877bedf ffbefb9 877bedf | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | """
Email Assistant Agent - Gradio Interface
This is the main application file that provides a Gradio web interface
for the AI-powered Email Assistant using OpenAI Agents SDK.
"""
import gradio as gr
import os
from agent import process_email
def load_email_examples() -> list:
"""
Loads email examples from the external text file.
Returns:
list: List of email examples for the Gradio interface
"""
examples_file = os.path.join(os.path.dirname(__file__), "email_examples.txt")
try:
with open(examples_file, 'r', encoding='utf-8') as f:
content = f.read()
# Split examples by the separator "---"
examples = [example.strip() for example in content.split('---') if example.strip()]
return examples
except FileNotFoundError:
print(f"Warning: Examples file not found at {examples_file}")
return []
except Exception as e:
print(f"Error loading examples: {e}")
return []
def flag_inappropriate_content(output_text: str) -> str:
"""
Flags inappropriate content and saves it for review.
Args:
output_text (str): The output content to flag
Returns:
str: Confirmation message
"""
import datetime
# Create flagged content directory if it doesn't exist
import os
flagged_dir = "flagged_content"
if not os.path.exists(flagged_dir):
os.makedirs(flagged_dir)
# Save flagged content with timestamp
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"{flagged_dir}/flagged_{timestamp}.txt"
try:
with open(filename, 'w', encoding='utf-8') as f:
f.write(f"Flagged at: {datetime.datetime.now()}\n")
f.write("=" * 50 + "\n")
f.write(output_text)
return f"✅ Content flagged and saved to {filename}"
except Exception as e:
return f"❌ Error saving flagged content: {str(e)}"
def process_email_interface(api_key: str, email_text: str) -> str:
"""
Gradio interface function to process emails through the AI agent.
Args:
api_key (str): OpenAI API key
email_text (str): Email content to process
Returns:
str: Formatted response with category, summary, and suggested reply
"""
print("Starting email processing...")
# Validate inputs first
if not api_key or not api_key.strip():
return "**Error:** OpenAI API key is required. Please enter your API key."
if not email_text or not email_text.strip():
return "**Error:** Email content is required. Please enter the email text to process."
print("Inputs validated, calling process_email...")
# Process the email through the agent
result = process_email(email_text, api_key)
print(f"Process email result: {result}")
if not result['success']:
return f"**Error:** {result['error']}"
# Format the reply text for HTML display
formatted_reply = result['reply']
print("=" * 80)
print("DEBUG: HTML FORMATTING IN APP.PY")
print("=" * 80)
print(f"Original reply from result: '{result['reply']}'")
print(f"Reply length: {len(result['reply'])} characters")
if formatted_reply:
# Convert \n to HTML line breaks for proper rendering in Gradio
formatted_reply = formatted_reply.replace('\n', '<br>')
print(f"After HTML formatting: '{formatted_reply}'")
print(f"Formatted reply length: {len(formatted_reply)} characters")
else:
print("WARNING: Reply is empty or None!")
print("=" * 80)
# Format the successful response
response = f"""
## Email Analysis Results
### **Detected Category:** {result['category']}
### **Summary:**
{result['summary']}
### **Suggested Reply:**
{formatted_reply}
---
*Generated by Email Assistant Agent using OpenAI Agents SDK*
"""
print("DEBUG: FINAL RESPONSE FOR GRADIO")
print("=" * 80)
print(f"Final response length: {len(response)} characters")
print(f"Final response content:\n{response}")
print("=" * 80)
return response
def create_gradio_interface() -> gr.Blocks:
"""
Creates and configures the Gradio interface for the Email Assistant.
Returns:
gr.Blocks: Configured Gradio interface with separate API key field
"""
# Load email examples from external file
email_examples = load_email_examples()
with gr.Blocks(
title="Email Assistant Agent",
theme=gr.themes.Soft(),
css="""
.gradio-container {
max-width: 1000px !important;
}
.main-header {
text-align: center;
margin-bottom: 2rem;
}
"""
) as interface:
gr.Markdown("""
# Email Assistant Agent
**Automatically classify, summarize, and respond to business emails using OpenAI Agents SDK.**
This AI agent will:
- **Classify** your email into categories (Inquiry, Complaint, Feedback, Other)
- **Summarize** the content in two concise sentences
- **Generate** a professional reply suggestion
**Note:** You need a valid OpenAI API key to use this service. The key is not stored and is only used for processing your request.
**Flag Button:** Use the flag button to report inappropriate, offensive, or incorrect responses. This helps improve the AI's performance and ensures a better experience for all users.
""")
# Two-column layout
with gr.Row():
# Left column: API Key, Email input and controls
with gr.Column(scale=1):
api_key_input = gr.Textbox(
label="OpenAI API Key",
placeholder="Enter your OpenAI API key here...",
type="password",
info="Your API key is not stored and is only used for this session"
)
email_input = gr.Textbox(
label="Email Content",
placeholder="Paste your business email here...",
lines=10,
max_lines=20,
info="Enter the full email content you want to analyze"
)
# Examples for email content only
gr.Examples(
examples=email_examples,
inputs=email_input,
label="Email Examples (click to load)"
)
with gr.Row():
submit_btn = gr.Button("Submit", variant="primary")
clear_btn = gr.Button("Clear", variant="secondary")
# Right column: Output results
with gr.Column(scale=1):
output = gr.Markdown(
label="Analysis Results",
show_copy_button=True
)
# Manual flag button for inappropriate content
with gr.Row():
flag_btn = gr.Button("🚩 Flag Inappropriate Content", variant="stop", size="sm")
flag_status = gr.Textbox(label="Flag Status", visible=False)
# Connect the function with flagging
submit_btn.click(
fn=process_email_interface,
inputs=[api_key_input, email_input],
outputs=output,
api_name="process_email"
)
clear_btn.click(
fn=lambda: ("", ""),
outputs=[api_key_input, email_input]
)
# Connect flag button
flag_btn.click(
fn=flag_inappropriate_content,
inputs=output,
outputs=flag_status
)
return interface
def main():
"""
Main function to launch the Gradio interface.
"""
# Create and launch the interface
interface = create_gradio_interface()
# Launch the interface
interface.launch(
server_name="0.0.0.0", # Allow external connections for Hugging Face Spaces
server_port=7860, # Default Gradio port
share=False, # Don't create public link (for Hugging Face Spaces)
show_error=True, # Show errors in the interface
quiet=False # Show startup messages
)
if __name__ == "__main__":
main()
|