Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import re | |
| import anthropic | |
| import os | |
| st.set_page_config(page_title="Prompt Coach", layout="wide") | |
| # ✅ Titolo e sottotitolo in verde fluo | |
| st.markdown("<h1 style='text-align: center; color: #39FF14;'>🧠 Prompt Coach</h1>", unsafe_allow_html=True) | |
| st.markdown("<p style='text-align: center; color: #39FF14;'>Scrivi prompt migliori, capendo come si costruiscono.</p>", unsafe_allow_html=True) | |
| # ✅ CSS personalizzato | |
| st.markdown( | |
| ''' | |
| <style> | |
| div.stButton > button { | |
| background-color: #003366; | |
| color: white; | |
| padding: 0.75em 1.5em; | |
| font-size: 1.1em; | |
| border-radius: 10px; | |
| border: none; | |
| } | |
| @keyframes pulse { | |
| 0% { box-shadow: 0 0 0 0 rgba(57,255,20, 0.5); } | |
| 70% { box-shadow: 0 0 0 10px rgba(57,255,20, 0); } | |
| 100% { box-shadow: 0 0 0 0 rgba(57,255,20, 0); } | |
| } | |
| .pulsing-button { | |
| animation: pulse 2s infinite; | |
| } | |
| </style> | |
| ''', | |
| unsafe_allow_html=True | |
| ) | |
| # ✅ Espandi guida | |
| with st.expander("📘 Le 6 regole fondamentali del prompting"): | |
| st.markdown( | |
| "<div style='color:#39FF14'>" | |
| "<ol>" | |
| "<li><b>RUOLO</b> – Chi è il modello?</li>" | |
| "<li><b>TONO / STILE</b> – Che tono usare?</li>" | |
| "<li><b>OUTPUT ATTESO</b> – Che tipo di contenuto vuoi?</li>" | |
| "<li><b>VINCOLI</b> – Cosa deve includere o evitare?</li>" | |
| "<li><b>CONTESTO</b> – A chi è rivolto?</li>" | |
| "<li><b>RESPONSABILITÀ</b> – Qual è lo scopo?</li>" | |
| "</ol>" | |
| "</div>", | |
| unsafe_allow_html=True | |
| ) | |
| # ✅ Layout due colonne | |
| col1, col2 = st.columns([1.2, 1]) | |
| with col1: | |
| st.markdown("<h3 style='color: #39FF14;'>✍️ Inserisci il tuo prompt</h3>", unsafe_allow_html=True) | |
| prompt_input = st.text_area("Prompt grezzo", height=200, label_visibility="collapsed") | |
| with col2: | |
| st.markdown("<h3 style='color: #39FF14;'>🎯 Prompt raffinato + spiegazione</h3>", unsafe_allow_html=True) | |
| def analizza_e_riscrivi(prompt): | |
| sezioni = [] | |
| spiegazioni = [] | |
| base = prompt.strip() | |
| if not re.search(r"agisc[ia] come|sei un|ti comporti come", base.lower()): | |
| base += " 🟨 **[Aggiunto: Agisci come un esperto HR e copywriter SEO.]**" | |
| spiegazioni.append("🟨 RUOLO mancante.") | |
| if "tono" not in base.lower(): | |
| base += " 🟨 **[Aggiunto: Usa un tono professionale e accessibile.]**" | |
| spiegazioni.append("🟨 TONO mancante.") | |
| if not any(x in base.lower() for x in ["scrivi", "genera", "crea", "elabora"]): | |
| base += " 🟨 **[Aggiunto: Genera un articolo strutturato con H2 e bullet.]**" | |
| spiegazioni.append("🟨 OUTPUT ATTESO mancante.") | |
| if "keyword" not in base.lower(): | |
| base += " 🟨 **[Aggiunto: Includi la keyword 'digitalizzazione HR'.]**" | |
| spiegazioni.append("🟨 VINCOLI mancanti.") | |
| if "pubblico" not in base.lower(): | |
| base += " 🟨 **[Aggiunto: Il target è un HR manager di PMI italiane.]**" | |
| spiegazioni.append("🟨 CONTESTO mancante.") | |
| if "obiettivo" not in base.lower() and "scopo" not in base.lower(): | |
| base += " 🟨 **[Aggiunto: Obiettivo: informare e spingere alla prova gratuita di Fluida.]**" | |
| spiegazioni.append("🟨 RESPONSABILITÀ mancante.") | |
| sezioni.append("### ✅ Prompt raffinato:") | |
| sezioni.append(base) | |
| sezioni.append("---\n### 📚 Spiegazione didattica:") | |
| for s in spiegazioni: | |
| sezioni.append(f"- {s}") | |
| return "\n\n".join(sezioni), base | |
| risultato = "" | |
| raffinato = "" | |
| if st.button("🧠 Analizza il prompt", type="primary"): | |
| if prompt_input.strip(): | |
| risultato, raffinato = analizza_e_riscrivi(prompt_input) | |
| st.markdown(f"<div style='background-color: #f5f5f5; padding: 20px; border-radius: 10px; color: #39FF14;'>{risultato}</div>", unsafe_allow_html=True) | |
| else: | |
| st.warning("⚠️ Inserisci prima un prompt.") | |
| if prompt_input.strip(): | |
| raffinato, _ = analizza_e_riscrivi(prompt_input) | |
| st.download_button("⬇️ Scarica prompt raffinato", data=raffinato, file_name="prompt_raffinato.txt") | |
| st.text_area("📋 Copia prompt", value=raffinato, height=150, label_visibility="collapsed") | |
| if st.button("🤖 Genera risposta con Claude", type="secondary"): | |
| if prompt_input.strip(): | |
| with st.spinner("Sto generando la risposta..."): | |
| client = anthropic.Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY")) | |
| full_prompt, _ = analizza_e_riscrivi(prompt_input) | |
| response = client.messages.create( | |
| model="claude-3-sonnet-20240229", | |
| max_tokens=600, | |
| temperature=0.7, | |
| messages=[{"role": "user", "content": full_prompt}] | |
| ) | |
| risposta = response.content[0].text | |
| st.markdown("<h4 style='color: #39FF14;'>📝 Risposta generata da Claude:</h4>", unsafe_allow_html=True) | |
| st.markdown(f"<div style='color:#39FF14'>{risposta}</div>", unsafe_allow_html=True) | |
| else: | |
| st.warning("⚠️ Inserisci prima un prompt.") |