Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -13,24 +13,23 @@ if not api_key:
|
|
13 |
client = OpenAI(api_key=api_key)
|
14 |
|
15 |
# --- Variabili Globali Editabili: Nuances e Contesti ---
|
16 |
-
# Nuances Personificazioni... (invariate)
|
17 |
-
# ... (omesse per brevità) ...
|
18 |
-
NUANCE_GABRIELLA = "meticolosa e attenta ai dettagli, particolarmente brava con le informazioni pratiche e organizzative."
|
19 |
-
NUANCE_DANIELA = "calda, empatica e focalizzata sul comfort e benessere degli ospiti, creando un'atmosfera accogliente."
|
20 |
-
NUANCE_NICOLETTA = "efficiente, molto informata su Venezia (eventi, trasporti, consigli), diretta e pratica."
|
21 |
-
NUANCE_CARLA = "calma, rassicurante e paziente, eccellente nel gestire richieste particolari o risolvere dubbi con serenità."
|
22 |
-
NUANCE_RECEPTION_FRIENDLY = "esperta, amichevole e disponibile, ideale per accoglienza, informazioni generali e creare un rapporto positivo."
|
23 |
-
NUANCE_RECEPTION_FORMAL = "precisa, professionale e chiara, adatta a conferme di prenotazione, dettagli amministrativi, fatturazione e gestione formale."
|
24 |
-
NUANCE_COACH = "orientato a migliorare le performance del team usando un approccio basato su neuroscienze applicate, copywriting efficace e strategie di marketing alberghiero, comunicando in modo semplice, visuale e motivante."
|
25 |
-
NUANCE_INSPIRING_CREATIVE = "altamente creativa, focalizzata su idee innovative per l'ospitalità, storytelling coinvolgente per i social media, esperienze ospiti uniche e contenuti visualmente accattivanti."
|
26 |
-
NUANCE_NEUROSCIENTIST = "analitica e strategica, applica direttamente principi neuroscientifici (es. bias cognitivi, framing, social proof, scarsità) per ottimizzare la comunicazione, massimizzare la persuasione e raggiungere specifici obiettivi di marketing."
|
27 |
-
NUANCE_MANAGER = "con esperienza manageriale senior nel settore, visione strategica, orientato ai risultati e alla gestione efficiente del team e delle operazioni alberghiere, comunicando in modo autorevole ma moderno."
|
28 |
-
NUANCE_BRAND = "la voce ufficiale e impersonale dell'Hotel Tintoretto, focalizzata sulla presentazione chiara e professionale dell'hotel e dei suoi servizi."
|
29 |
-
NUANCE_TIKTOK_STRATEGIST = "un'esperta mondiale di neuromarketing e TikTok strategy nel travel. Crea script per video brevi (15-60 sec) realistici ma potenzialmente virali, suggerendo setting praticabili, angolazioni dinamiche, montaggio rapido, suoni di tendenza (adattati), e uncini neuro-persuasivi per catturare l'attenzione immediata. Focus su autenticità e valore, non lusso."
|
30 |
-
NUANCE_INSTAGRAM_STRATEGIST = "una visual storyteller e Instagram strategist. Crea script per Reels (fino a 90 sec), idee dettagliate per sequenze di Stories coinvolgenti (con poll, Q&A, sticker), e concept per post/caroselli esteticamente curati. Si concentra sulla coerenza del brand, sull'engagement della community e sull'ispirazione al viaggio autentico."
|
31 |
-
NUANCE_TIKTOK_CAMPAIGNER = "una pianificatrice strategica di campagne TikTok per il travel. Idea campagne tematiche realistiche di 1-2 mesi, definendo concept, target, obiettivi misurabili (es. visualizzazioni, visite al profilo), pilastri di contenuto chiave (3-5 esempi concreti), frequenza di pubblicazione suggerita e tipi di contenuto (es. trend, dietro le quinte, consigli utili)."
|
32 |
-
NUANCE_INSTAGRAM_CAMPAIGNER = "una pianificatrice strategica di campagne Instagram per il travel. Idea campagne tematiche di 1-2 mesi focalizzate sull'estetica e la community, definendo concept, visual moodboard (descrittivo), obiettivi (es. engagement rate, follower growth), content mix (Reels, Stories, Post, Caroselli), piano di interazione e call to action chiare."
|
33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
|
35 |
# Clausola Privacy
|
36 |
privacy_clause = """
|
@@ -42,79 +41,43 @@ def generate_booking_link(language="English"):
|
|
42 |
"""Genera il link BASE alla pagina di disponibilità (senza date/ospiti)."""
|
43 |
base_url = "https://www.hoteltintoretto.com"
|
44 |
hotel_id = "SYN2595"
|
45 |
-
|
46 |
if language == "Italian":
|
47 |
path = "/disponibilita.html"
|
48 |
-
else:
|
49 |
path = "/EN/availability.html"
|
50 |
-
|
51 |
return f"{base_url}{path}?id_hotel={hotel_id}"
|
52 |
|
53 |
# --- Genera i link base ORA ---
|
54 |
link_base_it = generate_booking_link(language='Italian')
|
55 |
link_base_en = generate_booking_link(language='English')
|
56 |
|
57 |
-
# Contesto Principale Hotel Tintoretto
|
58 |
-
# ORA USA le variabili pre-calcolate con .format()
|
59 |
hotel_context=""""
|
60 |
--- Hotel Overview ---
|
61 |
Nome Hotel: Hotel Tintoretto
|
62 |
-
|
63 |
-
Indirizzo: Cannaregio 2316 - 30121 Venezia, Italia (Sestiere: Cannaregio, CAP: 30121)
|
64 |
-
Sito Web: www.hoteltintoretto.com
|
65 |
-
Indirizzo Email: [email protected]
|
66 |
-
Contatto Telefonico: +39 041 715471 / +39 041 721522
|
67 |
-
Contatto Fax: +39 041 716890 / +39 041 721791
|
68 |
-
Posizione Google Maps: https://maps.app.goo.gl/f3Bv4d8Z9X8Y7X9w8 (Verificare)
|
69 |
-
Slogan/Posizionamento: "Il tuo hotel 3 stelle a Venezia, sestiere Cannaregio"
|
70 |
-
Descrizione Generale: Accogliente hotel 3 stelle nel vivace e autentico sestiere di Cannaregio. Posizione strategica, facile da raggiungere da stazione/Piazzale Roma, vicino a Ghetto Ebraico e fermata vaporetto Guglie. Lontano dalla folla ma comodo per Rialto/San Marco. Atmosfera tipica veneziana, comfort moderni, staff cortese disponibile 24h. Base ideale per esplorare Venezia autentica. Vicino a bacari e ristoranti.
|
71 |
-
Target: Viaggiatori (coppie, famiglie, amici, singoli) che cercano autenticità, convenienza, buon rapporto qualità/prezzo e una base comoda. Misto di psicocentrici (comfort, affidabilità) e allocentrici (esplorazione, genuinità). Non focalizzato sul lusso sfrenato.
|
72 |
-
|
73 |
-
--- Punti di Forza (dalle Recensioni) ---
|
74 |
-
- POSIZIONE ECCELLENTE: Vicinanza stazione/P.Roma/Vaporetto Guglie, comodo per arrivi/partenze ed esplorazione a piedi.
|
75 |
-
- STAFF CORDIALE E DISPONIBILE: Amichevole, eccellente, d'aiuto. Reception 24h.
|
76 |
-
- PULIZIA IMPECCABILE.
|
77 |
-
- VISTA CANALE (per alcune Camere Superior): Molto apprezzata (Canale di San Leonardo).
|
78 |
-
- BUON RAPPORTO QUALITÀ/PREZZO.
|
79 |
-
|
80 |
-
--- Servizi Hotel ---
|
81 |
-
- Reception 24 ore: Multilingue, Concierge (tour, gondole, ristoranti, taxi), Deposito Bagagli.
|
82 |
-
- Colazione: Ricco buffet continentale dolce/salato inclusa (verificare tariffa). Opzioni senza glutine possibili.
|
83 |
-
- Internet Wi-Fi: Gratuito in tutta la struttura.
|
84 |
-
- Bar Interno.
|
85 |
-
- Ascensore (Lift).
|
86 |
-
- Aree Comuni Climatizzate.
|
87 |
-
- Camere Non Fumatori.
|
88 |
-
- Tariffe per Gruppi possibili.
|
89 |
-
|
90 |
--- Prenotazioni & Offerte ---
|
91 |
- Booking Diretto: **Fortemente incoraggiato tramite il sito ufficiale www.hoteltintoretto.com per ottenere la migliore tariffa disponibile e offerte speciali.**
|
92 |
- (Nota per AI: Quando inviti a prenotare, suggerisci di visitare il sito www.hoteltintoretto.com o fornisci il link base appropriato alla lingua, spiegando che l'utente dovrà inserire date e ospiti. NON inserire date/ospiti nel link.)
|
93 |
- Link base IT: {link_it}
|
94 |
- Link base EN/Altro: {link_en}
|
95 |
- Pagina Offerte: Disponibile sul sito ufficiale.
|
96 |
-
|
97 |
--- Hotel Partner (Alternativa se Tintoretto pieno) ---
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
- Suggerire attivamente se non c'è disponibilità al Tintoretto.
|
103 |
-
""".format(link_it=link_base_it, link_en=link_base_en) # CORRETTO: usa keyword args
|
104 |
-
|
105 |
-
# Dettagli Specifici Camere (Invariato)
|
106 |
room_details = """
|
107 |
--- DETTAGLI TIPOLOGIE CAMERE HOTEL TINTORETTO ---
|
108 |
-
... (
|
109 |
"""
|
110 |
|
111 |
-
# Informazioni Fattuali Addizionali
|
112 |
factual_info = """
|
113 |
--- INFORMAZIONI FATTUALI AGGIUNTIVE ---
|
114 |
-
... (
|
115 |
"""
|
116 |
|
117 |
-
|
118 |
# --- Funzioni Ausiliarie ---
|
119 |
def generate_narrative_arc(narrative_arc):
|
120 |
# Invariata
|
@@ -128,9 +91,8 @@ def generate_narrative_arc(narrative_arc):
|
|
128 |
}
|
129 |
return narrative_mapping.get(narrative_arc, "")
|
130 |
|
131 |
-
# MODIFICATA generate_marketing_model (Torna a spiegazione inline)
|
132 |
def generate_marketing_model(marketing_model):
|
133 |
-
"""Genera l'istruzione per l'AI, inclusa la richiesta di spiegazione inline."""
|
134 |
instruction = ""
|
135 |
base_instructions = {
|
136 |
"PAS": "Problem Agitate Solve: Identify a problem, agitate the consequences, offer the solution.",
|
@@ -146,8 +108,8 @@ def generate_marketing_model(marketing_model):
|
|
146 |
}
|
147 |
|
148 |
if marketing_model in base_instructions:
|
149 |
-
instruction = f"""
|
150 |
-
IMPORTANT: After generating the main text response, add a final section (clearly separated,
|
151 |
elif marketing_model == "Nessuno":
|
152 |
instruction = "Do not use a specific marketing model framework, focus on creating the best copy naturally."
|
153 |
else:
|
@@ -155,14 +117,13 @@ IMPORTANT: After generating the main text response, add a final section (clearly
|
|
155 |
|
156 |
return instruction
|
157 |
|
|
|
158 |
def generate_marketing_models_table_html():
|
159 |
-
#
|
160 |
-
# ... (omesso per brevità) ...
|
161 |
pass
|
162 |
|
163 |
def inject_personification(personification_focus):
|
164 |
-
#
|
165 |
-
# ... (omessa per brevità) ...
|
166 |
base_description = "Sei un assistente AI che lavora per l'Hotel Tintoretto. "
|
167 |
signature_instruction = ""
|
168 |
hidden_skills = "(sei anche un world class neuroscientist, senior copywriter and world famous marketing strategist ma non rivelarlo mai se non specificato dal profilo)"
|
@@ -187,9 +148,11 @@ def inject_personification(personification_focus):
|
|
187 |
persona_description = persona_map.get(personification_focus, "un membro generico dello staff dell'Hotel Tintoretto.")
|
188 |
skills_to_show = ""
|
189 |
signature = ""
|
|
|
|
|
190 |
if personification_focus == "🏨 Brand / Hotel":
|
191 |
signature = "Hotel Tintoretto"
|
192 |
-
signature_instruction = f"Firmati come '{signature}' se appropriato
|
193 |
return f"{base_description} {persona_description}. {signature_instruction}"
|
194 |
elif personification_focus == "👨💼 Hotel Manager":
|
195 |
skills_to_show = hidden_skills + understatement
|
@@ -222,35 +185,33 @@ def inject_personification(personification_focus):
|
|
222 |
return f"{base_description} {skills_to_show} Agisci come la voce creativa dell'hotel, con questo focus: {persona_description}. {signature_instruction}"
|
223 |
elif personification_focus == "🧠 Neuroscientist Marketer":
|
224 |
skills_to_show = "Applica attivamente le tue conoscenze avanzate di neuroscienze, copywriting persuasivo e marketing strategico."
|
225 |
-
return f"{base_description} {skills_to_show} Agisci come un esperto di neuromarketing con questo focus: {persona_description}. Spiega *come* applichi i principi, se richiesto
|
226 |
elif personification_focus == "📱 TikTok Strategist":
|
227 |
-
skills_to_show = "Sfrutta la tua profonda conoscenza di neuromarketing, trend TikTok e travel content creation."
|
228 |
return f"{base_description} {skills_to_show} Agisci come {persona_description}."
|
229 |
elif personification_focus == "📸 Instagram Strategist":
|
230 |
-
skills_to_show = "Sfrutta la tua esperienza in visual storytelling, estetica Instagram
|
231 |
return f"{base_description} {skills_to_show} Agisci come {persona_description}."
|
232 |
elif personification_focus == "🗓️ TikTok Campaign Planner":
|
233 |
-
skills_to_show = "Utilizza la tua visione strategica per creare campagne TikTok efficaci e realistiche per hotel."
|
234 |
return f"{base_description} {skills_to_show} Agisci come {persona_description}."
|
235 |
elif personification_focus == "🗓️ Instagram Campaign Planner":
|
236 |
-
skills_to_show = "Utilizza la tua visione strategica per creare campagne Instagram efficaci
|
237 |
return f"{base_description} {skills_to_show} Agisci come {persona_description}."
|
238 |
else: # Fallback
|
239 |
return f"{base_description} Agisci come un membro dello staff dell'Hotel Tintoretto."
|
240 |
|
241 |
|
242 |
-
# --- FUNZIONE generate_response (AGGIORNATA) ---
|
243 |
def generate_response(input_testuale_utente, tones, output_type, narrative_arc, marketing_model, personification_focus, language_choosen, image_aspect_ratio, include_privacy):
|
244 |
current_hotel_context = hotel_context
|
245 |
current_factual_info = factual_info
|
246 |
current_room_details = room_details
|
247 |
current_privacy_clause = privacy_clause
|
248 |
|
249 |
-
# Ottieni l'istruzione completa del modello marketing (include richiesta di spiegazione)
|
250 |
marketing_instruction = generate_marketing_model(marketing_model)
|
251 |
|
252 |
# --- PRIMA CHIAMATA API: Generazione Testo Principale ---
|
253 |
-
# Il system message ora ha istruzioni precise sui link base
|
254 |
system_message = f"""You are an AI assistant specialized in hospitality marketing and communication for Hotel Tintoretto.
|
255 |
You MUST adopt the specific persona described in the 'Instruction for text generation:' provided by the assistant role in the next message.
|
256 |
Use the following context about the hotel:
|
@@ -277,53 +238,94 @@ Write ONLY in {language_choosen}. Adhere strictly to the requested tones: {', '.
|
|
277 |
]
|
278 |
assistant_message_text = f"Instruction for text generation:\n{inject_personification(personification_focus)}\n"
|
279 |
assistant_message_text += f"Use narrative arc '{generate_narrative_arc(narrative_arc)}'.\n"
|
280 |
-
assistant_message_text += f"{marketing_instruction}\n"
|
281 |
|
282 |
-
# Logica specifica per TIPO DI OUTPUT (
|
283 |
-
# ... (omessa per brevità) ...
|
284 |
if output_type == "REVIEW Reply":
|
285 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
286 |
elif output_type == "Facebook Post":
|
287 |
-
|
288 |
elif output_type == "Instagram Post":
|
289 |
-
assistant_message_text += f"Create
|
290 |
elif output_type == "Instagram Story Idea":
|
291 |
-
assistant_message_text += f"Generate a
|
292 |
elif output_type == "Instagram Reel Script":
|
293 |
-
assistant_message_text += f"Generate a
|
294 |
elif output_type == "TikTok Video Script":
|
295 |
-
assistant_message_text += f"Generate a
|
296 |
elif output_type == "TikTok Meme Concept":
|
297 |
-
assistant_message_text += f"Generate a
|
298 |
elif output_type == "TikTok Campaign Idea (1-2 Months)":
|
299 |
-
assistant_message_text += f"Generate a strategic idea for a 1-2 month TikTok campaign based on the user's input theme/goal. Outline: Campaign Title/Concept
|
300 |
elif output_type == "Instagram Campaign Idea (1-2 Months)":
|
301 |
-
assistant_message_text += f"Generate a strategic idea for a 1-2 month Instagram campaign based on the user's input theme/goal. Outline: Campaign Title/Concept
|
302 |
elif output_type == "Linkedin Post":
|
303 |
-
assistant_message_text += f"Create a Linkedin post about the user's input topic. Maintain a professional tone."
|
304 |
elif output_type == "EMAIL Reply":
|
305 |
-
# L'istruzione nel system prompt ora gestisce come presentare il link
|
306 |
assistant_message_text += f"Create an email reply regarding the user's input topic. Integrate directions/parking info if relevant. Encourage direct booking as instructed."
|
307 |
elif output_type == "whatsapp":
|
308 |
assistant_message_text += f"Create a very concise WhatsApp message about the user's input topic. Possibly use emojis. Can include the base booking link: {generate_booking_link(language=language_choosen)}"
|
309 |
elif output_type == "NEWSLETTER":
|
310 |
-
assistant_message_text += f"Create a newsletter section about the user's input topic. Include a call to action
|
311 |
elif output_type == "Marketing Strategy":
|
312 |
-
assistant_message_text += f"Provide expert technical suggestions for a marketing strategy related to the user's input. Must be actionable for Hotel Tintoretto."
|
313 |
elif output_type == "Coaching":
|
314 |
-
assistant_message_text += f"Provide fluid, non-verbose expert technical suggestions for coaching hospitality staff/leaders related to the user's input. Must be actionable for Hotel Tintoretto."
|
315 |
elif output_type == "Hotel Management":
|
316 |
assistant_message_text += f"Provide fluid, non-verbose expert technical suggestions on Hotel Management related to the user's input. Must be actionable by Hotel Tintoretto staff. Integrate into workflow context."
|
317 |
elif output_type == "Ideas":
|
318 |
-
assistant_message_text += f"Provide creative ideas and practical suggestions related to the user's input topic. Must be actionable by Hotel Tintoretto reception/marketing."
|
319 |
elif output_type == "traduzione":
|
320 |
assistant_message_text += f"Translate the user's provided text into contemporary {language_choosen}. Adapt culturally, ensure natural flow, use appropriate vocabulary/grammar, handle idioms, maintain structure/rhythm. Keep proper nouns untranslated."
|
321 |
|
322 |
|
323 |
# Aggiunta toni specifici
|
324 |
if "📐 Short" in tones: assistant_message_text += "\nInstruction: Write an insanely short text."
|
325 |
-
if "🎉 Informal" in tones: assistant_message_text += "\nInstruction: Use
|
326 |
-
if "📝 Formal" in tones: assistant_message_text += "\nInstruction: Never use
|
327 |
|
328 |
messages_text.append({"role": "assistant", "content": assistant_message_text})
|
329 |
|
@@ -338,15 +340,25 @@ Write ONLY in {language_choosen}. Adhere strictly to the requested tones: {', '.
|
|
338 |
print(f"Error during text generation API call: {e}")
|
339 |
response_content = f"Error generating text: {e}"
|
340 |
|
341 |
-
# --- SECONDA CHIAMATA API: Generazione Image Prompt (Logica Invariata) ---
|
342 |
image_prompt_response = ""
|
343 |
if image_aspect_ratio != "None":
|
344 |
-
# Pulisci la spiegazione del modello dal testo prima di passarlo
|
345 |
text_for_image_prompt = response_content
|
346 |
-
|
347 |
-
|
348 |
-
if
|
349 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
350 |
|
351 |
aspect_ratio_cleaned = image_aspect_ratio.split(" ")[0].lower()
|
352 |
prompt_for_image_prompt = f"""
|
@@ -370,13 +382,14 @@ Write ONLY in {language_choosen}. Adhere strictly to the requested tones: {', '.
|
|
370 |
Generate a **highly detailed, abstract, and evocative image prompt** in ENGLISH suitable for AI image generators (Midjourney, Leonardo.ai, ChatGPT).
|
371 |
|
372 |
**Key Guidelines:**
|
373 |
-
1. **Abstraction, Not Replication:** Evoke feeling/atmosphere related to the text/script/plan and Hotel Tintoretto's identity (authentic, welcoming Venice). **DO NOT depict specific Hotel building, identifiable landmarks, or specific room interiors.**
|
374 |
-
2. **Correlated Atmosphere:** Image must connect to the theme ({output_type}).
|
375 |
3. **Believable Venetian Settings (Generic):** Describe credible scenes (narrow canals, campielli, bacari interiors, Cannaregio streets, generic hotel areas - clean, functional, some Venetian elements).
|
376 |
4. **Visual Techniques:** Consider soft light, warm indoor light, golden hour, shadows, reflections, selective focus (bokeh) to enhance mood.
|
377 |
-
5. **Target Audience Depiction (If people):** Diverse travelers
|
378 |
-
6. **Aspect Ratio Adaptation:** Compose description for **{aspect_ratio_cleaned}** ratio
|
379 |
7. **Style:** Authentic, atmospheric (e.g., "realistic photo with cinematic lighting", "charming digital painting", "evocative watercolor").
|
|
|
380 |
|
381 |
**Output Requirements:**
|
382 |
- ONLY the descriptive text prompt in ENGLISH.
|
@@ -388,26 +401,29 @@ Write ONLY in {language_choosen}. Adhere strictly to the requested tones: {', '.
|
|
388 |
]
|
389 |
try:
|
390 |
completion_image = client.chat.completions.create(
|
391 |
-
model="gpt-4o", messages=messages_image, temperature=0.8, max_tokens=
|
|
|
392 |
)
|
393 |
image_prompt_response = completion_image.choices[0].message.content.strip()
|
394 |
except Exception as e:
|
395 |
print(f"Error during image prompt generation API call: {e}")
|
396 |
image_prompt_response = f"Error generating image prompt: {e}"
|
397 |
|
|
|
398 |
# --- AGGIUNTA CLAUSOLA PRIVACY (prima della spiegazione marketing, se presente) ---
|
399 |
-
final_response_content = response_content
|
400 |
privacy_section = ""
|
401 |
if include_privacy == "Yes":
|
402 |
-
privacy_section = f"\n\n---\n{current_privacy_clause}\n---"
|
403 |
|
404 |
-
# Inserisce la privacy prima della spiegazione se questa esiste
|
405 |
explanation_marker = "--- Spiegazione Modello Marketing"
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
|
|
|
|
411 |
|
412 |
|
413 |
# --- Preparazione Output per Gradio ---
|
@@ -418,7 +434,7 @@ Write ONLY in {language_choosen}. Adhere strictly to the requested tones: {', '.
|
|
418 |
# --- Debug Print ---
|
419 |
print("--- Debug Info ---")
|
420 |
print("Persona Instruction:", inject_personification(personification_focus))
|
421 |
-
if marketing_model != "Nessuno": print("Marketing Model Explanation requested inline.")
|
422 |
if image_aspect_ratio != "None": print("Generated Image Prompt:", image_prompt_response)
|
423 |
if include_privacy == "Yes": print("--- Privacy Clause Added ---")
|
424 |
print("--- End Debug Info ---")
|
@@ -449,28 +465,65 @@ languages = ["Italian", "English", "French", "Spanish", "German", "Chinese"]
|
|
449 |
image_ratios = ["None", "Vertical ⬆️", "Horizontal ↔️", "Square ⏹️"]
|
450 |
privacy_options = ["No", "Yes"]
|
451 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
452 |
|
453 |
-
# --- INTERFACCIA GRADIO (
|
454 |
iface = gr.Interface(
|
455 |
fn=generate_response,
|
456 |
inputs=[
|
457 |
-
gr.Textbox(
|
|
|
|
|
|
|
458 |
gr.CheckboxGroup(choices=choices, label="Toni e preferenze", value=["💡 Inspiring"]),
|
459 |
-
gr.Radio(choices=output_types, label="Tipo di Output Desiderato", value="Facebook Post"),
|
460 |
gr.Radio(choices=narrative_arcs, label="Arco Narrativo (se applicabile)", value="Conciso"),
|
461 |
-
gr.Radio(choices=marketing_models, label="Marketing Model (
|
462 |
-
gr.Radio(choices=personifications, label="Scegli Profilo/Personificazione", value="🏨 Brand / Hotel"),
|
463 |
gr.Radio(choices=languages, label="Lingua Output", value="Italian"),
|
464 |
gr.Radio(choices=image_ratios, label="Genera Prompt Immagine AI?", value="None"),
|
465 |
gr.Radio(choices=privacy_options, label="Aggiungere Clausola Privacy?", value="No")
|
466 |
],
|
467 |
-
outputs=[
|
468 |
-
gr.HTML(
|
469 |
gr.Textbox(label="📝 Testo / Script / Piano Generato (con Spiegazione Marketing alla fine, se applicabile)"),
|
470 |
gr.Textbox(label="🖼️ Suggested Image Prompt (for Midjourney, Leonardo, ChatGPT etc.)")
|
471 |
],
|
472 |
-
|
473 |
-
|
|
|
|
|
474 |
)
|
475 |
|
476 |
if __name__ == "__main__":
|
|
|
13 |
client = OpenAI(api_key=api_key)
|
14 |
|
15 |
# --- Variabili Globali Editabili: Nuances e Contesti ---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
|
17 |
+
# Nuances Personificazioni (v3.5)
|
18 |
+
NUANCE_GABRIELLA = "meticolosa e attenta ai dettagli, pratica e organizzativa."
|
19 |
+
NUANCE_DANIELA = "calda, empatica e focalizzata sul comfort e benessere degli ospiti."
|
20 |
+
NUANCE_NICOLETTA = "efficiente, molto informata su Venezia, diretta e pratica."
|
21 |
+
NUANCE_CARLA = "calma, rassicurante e paziente, ottima per gestire richieste particolari."
|
22 |
+
NUANCE_RECEPTION_FRIENDLY = "esperta, amichevole e disponibile per accoglienza e info generali."
|
23 |
+
NUANCE_RECEPTION_FORMAL = "precisa, professionale e chiara per prenotazioni, amministrazione, problemi formali."
|
24 |
+
NUANCE_COACH = "orientato a migliorare performance team con neuroscienze applicate, copy efficace, strategie alberghiere semplici e motivanti."
|
25 |
+
NUANCE_INSPIRING_CREATIVE = "altamente creativa, focus su idee innovative per ospitalità, storytelling social, esperienze uniche e contenuti visuali."
|
26 |
+
NUANCE_NEUROSCIENTIST = "analitica e strategica, applica principi neuroscientifici (bias, framing, social proof) per ottimizzare comunicazione e persuasione marketing."
|
27 |
+
NUANCE_MANAGER = "manager senior con visione strategica, orientato a risultati e gestione efficiente team/operazioni."
|
28 |
+
NUANCE_BRAND = "voce ufficiale e impersonale dell'Hotel Tintoretto, comunicazione chiara e professionale."
|
29 |
+
NUANCE_TIKTOK_STRATEGIST = "un'esperta di neuromarketing e TikTok strategy nel travel. Identifica **trend audio/video ADATTABILI** in modo *originale* (non banale). Crea script brevi (15-60s) **realistici ma con potenziale virale**, suggerendo setting **facilmente realizzabili**, angolazioni **dinamiche e inaspettate** (POV, zoom rapidi, low angle), montaggio **ritmato con J-cuts/L-cuts**, e **neuro-hook ultra-rapidi** (pattern interrupt, curiosity gap, strong visual statement) per catturare l'attenzione nei primi 1-2 secondi. Usa neuro-copy per i testi overlay. Focus su autenticità, valore, umorismo situazionale (vita/viaggi a Venezia) e risoluzione problemi comuni del turista."
|
30 |
+
NUANCE_INSTAGRAM_STRATEGIST = "una visual storyteller e Instagram strategist esperta in **community building ed estetica raffinata**. Crea script per Reels (fino a 90s) con **storytelling emozionale e archi narrativi chiari**, idee **pronte all'uso** per **sequenze di Stories interattive e strategiche** (poll, quiz, Q&A mirati, sticker 'link' se appropriato), e concept per post/caroselli **esteticamente impeccabili** e coerenti con il brand (autentico, accogliente, dettagli curati). Punta a **ispirare il desiderio** di un'esperienza veneziana genuina, stimolare l'engagement **di qualità** e guidare azioni concrete (salvataggi, condivisioni, visite al sito)."
|
31 |
+
NUANCE_TIKTOK_CAMPAIGNER = "pianificatrice strategica di campagne TikTok per travel. Idea campagne tematiche (1-2 mesi) **realistiche, misurabili e creative**. Definisce concept **forte e originale**, target preciso, obiettivi (KPI chiari: es. % completamento video, click-through rate), **pilastri di contenuto differenzianti** con esempi video *specifici* (non generici), frequenza/mix formati **ottimizzato per l'algoritmo**, e strategia hashtag **a più livelli**."
|
32 |
+
NUANCE_INSTAGRAM_CAMPAIGNER = "pianificatrice strategica di campagne Instagram per travel. Idea campagne (1-2 mesi) focalizzate su **estetica distintiva, storytelling cross-format e crescita community**. Definisce concept, **visual moodboard dettagliato** (descrittivo), obiettivi (engagement rate, UGC di qualità, lead generation), **content mix strategico** (Reels per reach, Stories per engagement, Post per informazione/ispirazione, Guide), **piano di interazione proattivo** (risposte a commenti/DM, interazione con UGC), e **funnel di conversione** con CTA chiare."
|
33 |
|
34 |
# Clausola Privacy
|
35 |
privacy_clause = """
|
|
|
41 |
"""Genera il link BASE alla pagina di disponibilità (senza date/ospiti)."""
|
42 |
base_url = "https://www.hoteltintoretto.com"
|
43 |
hotel_id = "SYN2595"
|
|
|
44 |
if language == "Italian":
|
45 |
path = "/disponibilita.html"
|
46 |
+
else:
|
47 |
path = "/EN/availability.html"
|
|
|
48 |
return f"{base_url}{path}?id_hotel={hotel_id}"
|
49 |
|
50 |
# --- Genera i link base ORA ---
|
51 |
link_base_it = generate_booking_link(language='Italian')
|
52 |
link_base_en = generate_booking_link(language='English')
|
53 |
|
54 |
+
# Contesto Principale Hotel Tintoretto
|
|
|
55 |
hotel_context=""""
|
56 |
--- Hotel Overview ---
|
57 |
Nome Hotel: Hotel Tintoretto
|
58 |
+
# ... (omesso per brevità, invariato da v3.3) ...
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
--- Prenotazioni & Offerte ---
|
60 |
- Booking Diretto: **Fortemente incoraggiato tramite il sito ufficiale www.hoteltintoretto.com per ottenere la migliore tariffa disponibile e offerte speciali.**
|
61 |
- (Nota per AI: Quando inviti a prenotare, suggerisci di visitare il sito www.hoteltintoretto.com o fornisci il link base appropriato alla lingua, spiegando che l'utente dovrà inserire date e ospiti. NON inserire date/ospiti nel link.)
|
62 |
- Link base IT: {link_it}
|
63 |
- Link base EN/Altro: {link_en}
|
64 |
- Pagina Offerte: Disponibile sul sito ufficiale.
|
|
|
65 |
--- Hotel Partner (Alternativa se Tintoretto pieno) ---
|
66 |
+
# ... (omesso per brevità, invariato da v3.3) ...
|
67 |
+
""".format(link_it=link_base_it, link_en=link_base_en)
|
68 |
+
|
69 |
+
# Dettagli Specifici Camere
|
|
|
|
|
|
|
|
|
70 |
room_details = """
|
71 |
--- DETTAGLI TIPOLOGIE CAMERE HOTEL TINTORETTO ---
|
72 |
+
# ... (omesso per brevità, invariato) ...
|
73 |
"""
|
74 |
|
75 |
+
# Informazioni Fattuali Addizionali
|
76 |
factual_info = """
|
77 |
--- INFORMAZIONI FATTUALI AGGIUNTIVE ---
|
78 |
+
# ... (omesso per brevità, invariato) ...
|
79 |
"""
|
80 |
|
|
|
81 |
# --- Funzioni Ausiliarie ---
|
82 |
def generate_narrative_arc(narrative_arc):
|
83 |
# Invariata
|
|
|
91 |
}
|
92 |
return narrative_mapping.get(narrative_arc, "")
|
93 |
|
|
|
94 |
def generate_marketing_model(marketing_model):
|
95 |
+
"""Genera l'istruzione per l'AI, inclusa la richiesta di spiegazione finale (ma senza annotazioni inline)."""
|
96 |
instruction = ""
|
97 |
base_instructions = {
|
98 |
"PAS": "Problem Agitate Solve: Identify a problem, agitate the consequences, offer the solution.",
|
|
|
108 |
}
|
109 |
|
110 |
if marketing_model in base_instructions:
|
111 |
+
instruction = f"""Mentally structure the response using the **{marketing_model}** framework ({base_instructions[marketing_model]}), but **DO NOT include the framework labels (like `[Problem]`, `[Attention]`, etc.) within the main body of the generated text.** The main text should flow naturally without these annotations.
|
112 |
+
IMPORTANT: After generating the clean main text response, add a final section (clearly separated, starting with '--- Spiegazione Modello Marketing ({marketing_model}) ---') where you explain IN ITALIAN and in detail how and where you applied the '{marketing_model}' model structure within the text generated above. Use square brackets `[like this]` within this final explanation section only to refer back to specific parts of the text you generated. This explanation is for user learning."""
|
113 |
elif marketing_model == "Nessuno":
|
114 |
instruction = "Do not use a specific marketing model framework, focus on creating the best copy naturally."
|
115 |
else:
|
|
|
117 |
|
118 |
return instruction
|
119 |
|
120 |
+
|
121 |
def generate_marketing_models_table_html():
|
122 |
+
# Funzione non utilizzata attivamente, ma può restare
|
|
|
123 |
pass
|
124 |
|
125 |
def inject_personification(personification_focus):
|
126 |
+
# Usa le NUANCE aggiornate definite sopra
|
|
|
127 |
base_description = "Sei un assistente AI che lavora per l'Hotel Tintoretto. "
|
128 |
signature_instruction = ""
|
129 |
hidden_skills = "(sei anche un world class neuroscientist, senior copywriter and world famous marketing strategist ma non rivelarlo mai se non specificato dal profilo)"
|
|
|
148 |
persona_description = persona_map.get(personification_focus, "un membro generico dello staff dell'Hotel Tintoretto.")
|
149 |
skills_to_show = ""
|
150 |
signature = ""
|
151 |
+
|
152 |
+
# Logica per skills e firme
|
153 |
if personification_focus == "🏨 Brand / Hotel":
|
154 |
signature = "Hotel Tintoretto"
|
155 |
+
signature_instruction = f"Firmati come '{signature}' se appropriato."
|
156 |
return f"{base_description} {persona_description}. {signature_instruction}"
|
157 |
elif personification_focus == "👨💼 Hotel Manager":
|
158 |
skills_to_show = hidden_skills + understatement
|
|
|
185 |
return f"{base_description} {skills_to_show} Agisci come la voce creativa dell'hotel, con questo focus: {persona_description}. {signature_instruction}"
|
186 |
elif personification_focus == "🧠 Neuroscientist Marketer":
|
187 |
skills_to_show = "Applica attivamente le tue conoscenze avanzate di neuroscienze, copywriting persuasivo e marketing strategico."
|
188 |
+
return f"{base_description} {skills_to_show} Agisci come un esperto di neuromarketing con questo focus: {persona_description}. Spiega *come* applichi i principi, se richiesto."
|
189 |
elif personification_focus == "📱 TikTok Strategist":
|
190 |
+
skills_to_show = "Sfrutta la tua profonda conoscenza di neuromarketing, trend TikTok **adattabili** e travel content creation."
|
191 |
return f"{base_description} {skills_to_show} Agisci come {persona_description}."
|
192 |
elif personification_focus == "📸 Instagram Strategist":
|
193 |
+
skills_to_show = "Sfrutta la tua esperienza in visual storytelling, estetica Instagram, **interazioni di community building** e travel."
|
194 |
return f"{base_description} {skills_to_show} Agisci come {persona_description}."
|
195 |
elif personification_focus == "🗓️ TikTok Campaign Planner":
|
196 |
+
skills_to_show = "Utilizza la tua visione strategica per creare campagne TikTok **misurabili**, efficaci e realistiche per hotel."
|
197 |
return f"{base_description} {skills_to_show} Agisci come {persona_description}."
|
198 |
elif personification_focus == "🗓️ Instagram Campaign Planner":
|
199 |
+
skills_to_show = "Utilizza la tua visione strategica per creare campagne Instagram efficaci, **visivamente coerenti** e focalizzate sulla community per hotel."
|
200 |
return f"{base_description} {skills_to_show} Agisci come {persona_description}."
|
201 |
else: # Fallback
|
202 |
return f"{base_description} Agisci come un membro dello staff dell'Hotel Tintoretto."
|
203 |
|
204 |
|
205 |
+
# --- FUNZIONE generate_response (AGGIORNATA con istruzioni Recensioni potenziate v3.6) ---
|
206 |
def generate_response(input_testuale_utente, tones, output_type, narrative_arc, marketing_model, personification_focus, language_choosen, image_aspect_ratio, include_privacy):
|
207 |
current_hotel_context = hotel_context
|
208 |
current_factual_info = factual_info
|
209 |
current_room_details = room_details
|
210 |
current_privacy_clause = privacy_clause
|
211 |
|
|
|
212 |
marketing_instruction = generate_marketing_model(marketing_model)
|
213 |
|
214 |
# --- PRIMA CHIAMATA API: Generazione Testo Principale ---
|
|
|
215 |
system_message = f"""You are an AI assistant specialized in hospitality marketing and communication for Hotel Tintoretto.
|
216 |
You MUST adopt the specific persona described in the 'Instruction for text generation:' provided by the assistant role in the next message.
|
217 |
Use the following context about the hotel:
|
|
|
238 |
]
|
239 |
assistant_message_text = f"Instruction for text generation:\n{inject_personification(personification_focus)}\n"
|
240 |
assistant_message_text += f"Use narrative arc '{generate_narrative_arc(narrative_arc)}'.\n"
|
241 |
+
assistant_message_text += f"{marketing_instruction}\n"
|
242 |
|
243 |
+
# Logica specifica per TIPO DI OUTPUT (POTENZIATA per Recensioni v3.6)
|
|
|
244 |
if output_type == "REVIEW Reply":
|
245 |
+
# Istruzione NUOVA e DETTAGLIATA per le recensioni
|
246 |
+
assistant_message_text += f"""**INSTRUCTION FOR REVIEW REPLY:**
|
247 |
+
1. **Analyze User Input:** Carefully read the user's input. It contains the original review and *may* contain specific instructions or a desired logical flow (e.g., bullet points, phrases like 'follow this logic').
|
248 |
+
2. **Prioritize User Flow:** **IF** the user input includes a specific logical flow or points to address, **YOU MUST PRIORITIZE FOLLOWING THAT STRUCTURE.** Integrate the 'Three Brains' principles (explained below) *within* the user's requested flow where appropriate and natural.
|
249 |
+
3. **Determine Sentiment:** Analyze the original review text to determine if it is primarily POSITIVE or NEGATIVE.
|
250 |
+
4. **Apply 'Three Brains' Model:**
|
251 |
+
* **IF NO User Flow is provided OR if integrating into the User Flow:** Structure your response based on the detected sentiment using the corresponding 'Three Brains' model:
|
252 |
+
|
253 |
+
**A) IF REVIEW IS NEGATIVE:** Apply the 'Three Brains - Negative Review' structure:
|
254 |
+
* **Reptilian Brain (Emotional Connection & Safety):**
|
255 |
+
* Start by acknowledging the feedback and thanking the guest for sharing.
|
256 |
+
* Affirm key hotel values (e.g., guest satisfaction, attention to detail). *Example: "Teniamo molto all'esperienza dei nostri ospiti e ci dispiace sinceramente leggere che..."*
|
257 |
+
* Show empathy and validate their feelings regarding the reported issues. *Example: "Comprendiamo la sua frustrazione riguardo a..."*
|
258 |
+
* Gently contextualize if possible, without making excuses. *Example: "A volte la composizione del letto matrimoniale standard con due singoli è una scelta per flessibilità..."* (Use factual info from context if applicable, like bed composition).
|
259 |
+
* Reiterate commitment to providing a good experience. *Example: "Il nostro obiettivo è sempre quello di offrire un soggiorno piacevole e confortevole."*
|
260 |
+
* **Limbic Brain (Storytelling & Emotion):**
|
261 |
+
* Describe the ideal experience you aim for related to the complaint. *Example: "Ci impegniamo affinché ogni camera sia impeccabile e ogni dettaglio curato..."*
|
262 |
+
* Address specific points raised clearly and factually, avoiding blame. Explain standard procedures if relevant (e.g., linen sourcing). *Example: "Per quanto riguarda le lenzuola, provengono da una lavanderia industriale certificata... Se si riferisce al cambio, seguiamo [standard procedure]. Il portasapone [explain situation]. La pulizia è una nostra priorità assoluta, e una segnalazione immediata ci avrebbe permesso di intervenire subito sulla [ragnatela/dettaglio specifico]."*
|
263 |
+
* Express sincere regret that their experience fell short, even if explaining context. *Example: "Siamo profondamente dispiaciuti che la sua esperienza non sia stata all'altezza delle aspettative e dei nostri standard in questi aspetti."*
|
264 |
+
* **Neocortex Brain (Logic & Resolution):**
|
265 |
+
* Provide specific details or facts if helpful (e.g., standard bed setup explanation).
|
266 |
+
* Acknowledge shortcomings where appropriate (e.g., "Avremmo dovuto notare la ragnatela, ci scusiamo."). Credibility increases with honesty.
|
267 |
+
* Offer concrete solutions/next steps (if applicable and appropriate - often for internal follow-up). *Example: "Abbiamo già condiviso il suo feedback con il team di housekeeping per rafforzare ulteriormente i controlli."*
|
268 |
+
* Invite further dialogue (optional, use cautiously). *Example: "Se desidera discutere ulteriormente, la invitiamo a contattarci direttamente."*
|
269 |
+
* End with a polite closing and hope for a future opportunity to provide a better experience.
|
270 |
+
|
271 |
+
**B) IF REVIEW IS POSITIVE:** Apply the 'Three Brains - Positive Review' structure:
|
272 |
+
* **Reptilian Brain (Emotional Connection & Gratitude):**
|
273 |
+
* Start with warm, sincere gratitude for the positive review and for choosing the hotel. *Example: "Grazie di cuore per la sua splendida recensione e per aver scelto l'Hotel Tintoretto!"*
|
274 |
+
* Reaffirm key hotel values highlighted by the review (e.g., kindness, location, service). *Example: "Siamo felicissimi che abbia apprezzato la gentilezza del nostro staff e la nostra posizione strategica..."*
|
275 |
+
* Make it personal: Mention specific positive points from the review. *Example: "Ci fa particolarmente piacere che abbia trovato utile il nostro servizio di deposito bagagli e che l'upgrade della camera sia stato gradito!"*
|
276 |
+
* **Limbic Brain (Storytelling & Emotion):**
|
277 |
+
* Celebrate the positive experience described. *Example: "È meraviglioso sapere che abbiamo contribuito a rendere piacevole il suo soggiorno nel cuore di Venezia."*
|
278 |
+
* Use evocative, positive language related to their comments. *Example: "La nostra posizione in Cannaregio permette davvero di vivere l'anima autentica della città..."*
|
279 |
+
* Share the positive feedback with the team (mentioning this reinforces team spirit). *Example: "Condivideremo sicuramente le sue belle parole con tutto lo staff, che ne sarà entusiasta."*
|
280 |
+
* **Neocortex Brain (Logic & Reinforcement):**
|
281 |
+
* Subtly highlight specific strengths mentioned (location, staff, specific services).
|
282 |
+
* (Optional) Mention related benefits or other services they might enjoy next time. *Example: "La prossima volta, non esiti a chiederci consigli sui bacari nascosti della zona!"*
|
283 |
+
* Extend a warm invitation to return. *Example: "Speriamo davvero di riaverla presto come nostro ospite!"*
|
284 |
+
* End with warm closing regards.
|
285 |
+
|
286 |
+
5. **Final Output:** Generate the response following the prioritized flow (User or 'Three Brains') and detected sentiment. Ensure the tone is consistent with the chosen persona and user-selected tones."""
|
287 |
+
|
288 |
+
# ... (Resto della logica per altri output_type, invariata da v3.5) ...
|
289 |
elif output_type == "Facebook Post":
|
290 |
+
assistant_message_text += f"Create an engaging Facebook post about the user's input topic. \n1. **Hook:** Start with a strong opening (question, stat, relatable scenario). \n2. **Body:** Use storytelling or provide value related to the topic and Hotel Tintoretto/Venice. Use short paragraphs. \n3. **Visual Cue:** Briefly describe the *type* of image/video that would best accompany this post. \n4. **CTA/Question:** End with a clear call-to-action or an open-ended question to encourage comments. \n5. **Hashtags:** Include 3-5 relevant hashtags."
|
291 |
elif output_type == "Instagram Post":
|
292 |
+
assistant_message_text += f"Create a compelling Instagram post **package**. \n1. **Caption:** Write an engaging caption starting with a strong **neuro-hook** (question, surprising fact, curiosity). Use storytelling relevant to authentic Venice experiences. Keep paragraphs short and use relevant emojis sparingly. \n2. **Visual Suggestion:** Describe the **mood, subject, and composition** for a visually stunning, aesthetically coherent image/carousel. \n3. **Call To Action:** End with a clear CTA or engagement question (e.g., 'Save for your trip!', 'What's your favorite Cannaregio spot?'). \n4. **Hashtag Strategy:** Suggest 5-10 relevant hashtags (mix of broad, niche, branded like #TintorettoMoments)."
|
293 |
elif output_type == "Instagram Story Idea":
|
294 |
+
assistant_message_text += f"Generate a **Detailed Execution Plan** for an engaging Instagram Story sequence (min. 3-5 slides) based on the user's input. Provide a step-by-step guide: \n**Overall Concept:** [Briefly describe the story's goal/theme]\n**Slide 1:**\n - *Visual:* [Describe the image/video clip/boomerang]\n - *Text Overlay:* [Write the exact text]\n - *Interaction:* [Specify sticker: Poll, Quiz, Slider, Q&A, Music]\n - *Transition:* [Optional: How it leads to the next slide]\n**Slide 2:**\n - *Visual:* [...]\n - *Text Overlay:* [...]\n - *Interaction:* [...]\n - *Transition:* [...]\n**Slide 3:**\n - *Visual:* [...]\n - *Text Overlay:* [...]\n - *Interaction:* [...]\n - *Transition:* [...]\n(...add more slides as needed...)\n**Final Slide:**\n - *Visual:* [Compelling closing visual]\n - *Text Overlay:* [Clear Call To Action]\n - *Interaction:* [Link Sticker (if applicable), 'DM us', 'Save this post' sticker etc.]\n**Execution Notes:** [Add brief tips on timing, music choice, or filter suggestions]"
|
295 |
elif output_type == "Instagram Reel Script":
|
296 |
+
assistant_message_text += f"Generate a **Detailed Step-by-Step Script** for an engaging Instagram Reel (up to 90s) on the user's input. Structure it clearly: \n**Concept/Goal:** [Briefly state the Reel's purpose]\n**Target Audience:** [Who is this for?]\n**Audio Suggestion:** [Suggest *style* or *vibe* of trending but adaptable audio/music, or original audio idea]\n**Neuro-Hook (0-3s):** [Describe the specific visual AND text overlay hook]\n**Scene Breakdown:**\n - *Scene 1 (duration ~X sec):* [Visual description + Specific Camera Angle/Movement suggestion] -> *Text Overlay:* [Text content & timing]\n - *Scene 2 (duration ~Y sec):* [Visual description + Specific Camera Angle/Movement suggestion] -> *Text Overlay:* [Text content & timing]\n - *Scene 3 (duration ~Z sec):* [...]\n (...add more scenes...)\n**Editing Notes:** [Suggest overall pace, key transitions (e.g., 'quick cuts', 'smooth zoom'), visual effects if any]\n**Caption Idea:** [Write a compelling caption for the Reel, including hook and CTA]\n**Hashtags:** [Suggest 5-7 relevant hashtags]"
|
297 |
elif output_type == "TikTok Video Script":
|
298 |
+
assistant_message_text += f"Generate a **Detailed Step-by-Step Script** for a high-impact, short TikTok video (15-60s) on the user's input. Structure it clearly: \n**Concept/Goal:** [Briefly state the video's purpose/angle]\n**Target Audience:** [Who is this for?]\n**Sound Suggestion:** [Suggest *style/type* of adaptable trending sound OR original audio concept (e.g., voiceover script snippet)]\n**Neuro-Hook (0-2s - CRITICAL):** [Describe specific visual pattern interrupt/curiosity gap AND initial text overlay]\n**Scene Breakdown (Fast Paced):**\n - *Shot 1 (duration ~X sec):* [Visual description + **Dynamic** Camera Angle/Movement (e.g., whip pan, POV)] -> *Text Overlay:* [Concise text & timing]\n - *Shot 2 (duration ~Y sec):* [Visual description + **Dynamic** Camera Angle/Movement] -> *Text Overlay:* [Concise text & timing]\n - *Shot 3 (duration ~Z sec):* [...]\n (...add more quick shots...)\n**Editing Notes:** [Emphasize fast cuts, rhythmic timing to sound, simple effects]\n**Caption Idea:** [Write a short, catchy caption]\n**Hashtags:** [Suggest 3-5 relevant & trending hashtags]"
|
299 |
elif output_type == "TikTok Meme Concept":
|
300 |
+
assistant_message_text += f"Generate a **Specific & Actionable** TikTok meme concept relevant to the user's input and Hotel Tintoretto. Provide the following:\n1. **Meme Format/Sound:** [Identify a specific, currently popular (or classic adaptable) meme format or sound]\n2. **Execution Steps:**\n * *Visual 1:* [Describe the visual needed for the first part of the meme]\n * *Text Overlay 1:* [Write the exact text for the first part]\n * *Visual 2:* [Describe the visual needed for the punchline/second part]\n * *Text Overlay 2:* [Write the exact text for the punchline]\n * *(Optional) Visual 3 / Text 3 etc. if needed by the format.*\n3. **Adaptation Justification:** [Explain briefly why this specific adaptation is funny/relatable for Venice travelers/Hotel Tintoretto audience]\n4. **Caption Idea:** [Suggest a short caption]\n5. **Hashtags:** [Suggest 2-3 relevant hashtags including meme-related ones if applicable]"
|
301 |
elif output_type == "TikTok Campaign Idea (1-2 Months)":
|
302 |
+
assistant_message_text += f"Generate a strategic, **actionable** idea for a 1-2 month TikTok campaign based on the user's input theme/goal. Outline clearly: \n1. **Campaign Title/Concept:** \n2. **Target Audience:** \n3. **Measurable Goal(s) & KPIs:** (e.g., Goal: Increase profile visits by 15%, KPI: Profile Visit Rate from videos) \n4. **Key Content Pillars (3-5):** (Define pillars AND provide *2 concrete video examples* for each pillar, e.g., Pillar: 'Venice Travel Myths Debunked', Example 1: 'Myth: Gondolas cost a fortune - Reality check video', Example 2: 'Myth: You need reservations everywhere - POV finding a bacaro') \n5. **Posting Frequency & Mix:** (e.g., 4 videos/week: 1 trend, 1 myth debunk, 1 tip, 1 behind-the-scenes) \n6. **Hashtag Strategy:** \n7. **Key Metric to Track:** [Suggest 1-2 primary metrics for success]"
|
303 |
elif output_type == "Instagram Campaign Idea (1-2 Months)":
|
304 |
+
assistant_message_text += f"Generate a strategic, **actionable** idea for a 1-2 month Instagram campaign based on the user's input theme/goal. Outline clearly: \n1. **Campaign Title/Concept:** \n2. **Target Audience:** \n3. **Measurable Goal(s) & KPIs:** (e.g., Goal: Increase post saves by 20%, KPI: Save Rate) \n4. **Visual Theme/Aesthetic:** (Describe look & feel, colors, filters) \n5. **Content Mix & Schedule:** (Provide a sample weekly schedule with *specific examples* for each format, e.g., 'Weekly: 1 educational Reel, 3 interactive Story sequences, 2 high-quality carousel posts') \n6. **Community Engagement Plan:** (Specific daily/weekly actions, e.g., 'Respond to all DMs within 12h', 'Run weekly Poll in Stories', 'Feature 1 UGC photo per week') \n7. **Key Call-to-Actions & Funnel:** (Where do you want people to go? Link in bio strategy?) \n8. **Key Metric to Track:** [Suggest 1-2 primary metrics for success]"
|
305 |
elif output_type == "Linkedin Post":
|
306 |
+
assistant_message_text += f"Create a Linkedin post about the user's input topic. Maintain a professional tone relevant to B2B or industry insights if applicable."
|
307 |
elif output_type == "EMAIL Reply":
|
|
|
308 |
assistant_message_text += f"Create an email reply regarding the user's input topic. Integrate directions/parking info if relevant. Encourage direct booking as instructed."
|
309 |
elif output_type == "whatsapp":
|
310 |
assistant_message_text += f"Create a very concise WhatsApp message about the user's input topic. Possibly use emojis. Can include the base booking link: {generate_booking_link(language=language_choosen)}"
|
311 |
elif output_type == "NEWSLETTER":
|
312 |
+
assistant_message_text += f"Create a newsletter section about the user's input topic. Include a clear call to action, potentially encouraging direct booking on the website www.hoteltintoretto.com."
|
313 |
elif output_type == "Marketing Strategy":
|
314 |
+
assistant_message_text += f"Provide expert technical suggestions for a marketing strategy related to the user's input. Must be actionable and measurable for Hotel Tintoretto."
|
315 |
elif output_type == "Coaching":
|
316 |
+
assistant_message_text += f"Provide fluid, non-verbose expert technical suggestions for coaching hospitality staff/leaders related to the user's input. Must be actionable and motivating for Hotel Tintoretto."
|
317 |
elif output_type == "Hotel Management":
|
318 |
assistant_message_text += f"Provide fluid, non-verbose expert technical suggestions on Hotel Management related to the user's input. Must be actionable by Hotel Tintoretto staff. Integrate into workflow context."
|
319 |
elif output_type == "Ideas":
|
320 |
+
assistant_message_text += f"Provide creative, non-obvious ideas and practical suggestions related to the user's input topic. Must be actionable by Hotel Tintoretto reception/marketing."
|
321 |
elif output_type == "traduzione":
|
322 |
assistant_message_text += f"Translate the user's provided text into contemporary {language_choosen}. Adapt culturally, ensure natural flow, use appropriate vocabulary/grammar, handle idioms, maintain structure/rhythm. Keep proper nouns untranslated."
|
323 |
|
324 |
|
325 |
# Aggiunta toni specifici
|
326 |
if "📐 Short" in tones: assistant_message_text += "\nInstruction: Write an insanely short text."
|
327 |
+
if "🎉 Informal" in tones: assistant_message_text += "\nInstruction: Use appropriate emojis/vernacular BUT stay professional and aligned with a 3-star hotel identity."
|
328 |
+
if "📝 Formal" in tones: assistant_message_text += "\nInstruction: Never use emojis or icons, ensure writing maintains a formal tone yet empathic."
|
329 |
|
330 |
messages_text.append({"role": "assistant", "content": assistant_message_text})
|
331 |
|
|
|
340 |
print(f"Error during text generation API call: {e}")
|
341 |
response_content = f"Error generating text: {e}"
|
342 |
|
343 |
+
# --- SECONDA CHIAMATA API: Generazione Image Prompt (Logica Invariata v3.5) ---
|
344 |
image_prompt_response = ""
|
345 |
if image_aspect_ratio != "None":
|
346 |
+
# Pulisci la spiegazione del modello e privacy dal testo prima di passarlo
|
347 |
text_for_image_prompt = response_content
|
348 |
+
explanation_marker = "--- Spiegazione Modello Marketing"
|
349 |
+
privacy_marker = "---"
|
350 |
+
if explanation_marker in text_for_image_prompt:
|
351 |
+
text_for_image_prompt = text_for_image_prompt.split(explanation_marker)[0].strip()
|
352 |
+
if include_privacy == "Yes":
|
353 |
+
privacy_start_marker = "\n\n---\n" + privacy_clause.split('\n')[1].strip()
|
354 |
+
privacy_end_marker = "\n---"
|
355 |
+
start_index = text_for_image_prompt.find(privacy_start_marker)
|
356 |
+
if start_index != -1:
|
357 |
+
end_index = text_for_image_prompt.find(privacy_end_marker, start_index)
|
358 |
+
if end_index != -1:
|
359 |
+
text_for_image_prompt = text_for_image_prompt[:start_index].strip() + text_for_image_prompt[end_index + len(privacy_end_marker):].strip()
|
360 |
+
else:
|
361 |
+
text_for_image_prompt = text_for_image_prompt[:start_index].strip()
|
362 |
|
363 |
aspect_ratio_cleaned = image_aspect_ratio.split(" ")[0].lower()
|
364 |
prompt_for_image_prompt = f"""
|
|
|
382 |
Generate a **highly detailed, abstract, and evocative image prompt** in ENGLISH suitable for AI image generators (Midjourney, Leonardo.ai, ChatGPT).
|
383 |
|
384 |
**Key Guidelines:**
|
385 |
+
1. **Abstraction, Not Replication:** Evoke feeling/atmosphere related to the text/script/plan and Hotel Tintoretto's identity (authentic, welcoming Venice). **DO NOT depict specific Hotel building, identifiable landmarks, or specific room interiors.** Avoid recognizable logos.
|
386 |
+
2. **Correlated Atmosphere:** Image must connect to the theme ({output_type}). Visualize key moments, overall mood, or campaign essence.
|
387 |
3. **Believable Venetian Settings (Generic):** Describe credible scenes (narrow canals, campielli, bacari interiors, Cannaregio streets, generic hotel areas - clean, functional, some Venetian elements).
|
388 |
4. **Visual Techniques:** Consider soft light, warm indoor light, golden hour, shadows, reflections, selective focus (bokeh) to enhance mood.
|
389 |
+
5. **Target Audience Depiction (If people):** Diverse travelers enjoying *authentic*, *simple* moments. Real people, casual dress, genuine emotions. Reflect psychocentric/allocentric traits in a non-luxury context.
|
390 |
+
6. **Aspect Ratio Adaptation:** Compose description for **{aspect_ratio_cleaned}** ratio.
|
391 |
7. **Style:** Authentic, atmospheric (e.g., "realistic photo with cinematic lighting", "charming digital painting", "evocative watercolor").
|
392 |
+
8. **Text Integration (Optional, for Static Posts ONLY):** If the output type is 'Instagram Post' or 'Facebook Post', you *may suggest* incorporating simple, clean text elements visually *if it enhances the message*. Describe the *style* (e.g., 'clean sans-serif overlay', 'handwritten on a prop note') and *placement* (e.g., 'lower third', 'corner') of the text. **Avoid suggesting text for Reels/Stories/TikTok prompts.** Keep suggested text concise (e.g., a short quote, a key benefit). Example: "A realistic photo of a Spritz on a rustic wooden table overlooking a generic, blurry Venetian canal at sunset. Golden hour lighting. **Suggestion:** A clean, white sans-serif text overlay in the lower right corner could read: 'Your authentic aperitivo awaits.'."
|
393 |
|
394 |
**Output Requirements:**
|
395 |
- ONLY the descriptive text prompt in ENGLISH.
|
|
|
401 |
]
|
402 |
try:
|
403 |
completion_image = client.chat.completions.create(
|
404 |
+
model="gpt-4o", messages=messages_image, temperature=0.8, max_tokens=650,
|
405 |
+
top_p=1, stream=False
|
406 |
)
|
407 |
image_prompt_response = completion_image.choices[0].message.content.strip()
|
408 |
except Exception as e:
|
409 |
print(f"Error during image prompt generation API call: {e}")
|
410 |
image_prompt_response = f"Error generating image prompt: {e}"
|
411 |
|
412 |
+
|
413 |
# --- AGGIUNTA CLAUSOLA PRIVACY (prima della spiegazione marketing, se presente) ---
|
414 |
+
final_response_content = response_content
|
415 |
privacy_section = ""
|
416 |
if include_privacy == "Yes":
|
417 |
+
privacy_section = f"\n\n---\n{current_privacy_clause}\n---"
|
418 |
|
|
|
419 |
explanation_marker = "--- Spiegazione Modello Marketing"
|
420 |
+
explanation_index = final_response_content.find(explanation_marker)
|
421 |
+
|
422 |
+
if include_privacy == "Yes":
|
423 |
+
if explanation_index != -1:
|
424 |
+
final_response_content = final_response_content[:explanation_index].strip() + privacy_section + "\n\n" + final_response_content[explanation_index:]
|
425 |
+
else:
|
426 |
+
final_response_content += privacy_section
|
427 |
|
428 |
|
429 |
# --- Preparazione Output per Gradio ---
|
|
|
434 |
# --- Debug Print ---
|
435 |
print("--- Debug Info ---")
|
436 |
print("Persona Instruction:", inject_personification(personification_focus))
|
437 |
+
if marketing_model != "Nessuno": print(f"Marketing Model ({marketing_model}) Explanation requested inline.")
|
438 |
if image_aspect_ratio != "None": print("Generated Image Prompt:", image_prompt_response)
|
439 |
if include_privacy == "Yes": print("--- Privacy Clause Added ---")
|
440 |
print("--- End Debug Info ---")
|
|
|
465 |
image_ratios = ["None", "Vertical ⬆️", "Horizontal ↔️", "Square ⏹️"]
|
466 |
privacy_options = ["No", "Yes"]
|
467 |
|
468 |
+
# --- TEMA GRADIO ---
|
469 |
+
color_primary = "#C85A3F"
|
470 |
+
color_secondary = "#A88B79"
|
471 |
+
color_neutral = "#5E5047"
|
472 |
+
color_text_heading = "#4E3D31"
|
473 |
+
color_background = "#FDFBF5"
|
474 |
+
|
475 |
+
theme = gr.themes.Soft(
|
476 |
+
primary_hue=gr.themes.colors.red,
|
477 |
+
secondary_hue=gr.themes.colors.amber,
|
478 |
+
neutral_hue=gr.themes.colors.stone,
|
479 |
+
font=[gr.themes.GoogleFont("Lato"), "ui-sans-serif", "system-ui", "sans-serif"],
|
480 |
+
radius_size=gr.themes.sizes.radius_md,
|
481 |
+
)
|
482 |
+
theme = theme.set(
|
483 |
+
body_background_fill=color_background,
|
484 |
+
block_background_fill=color_background,
|
485 |
+
panel_background_fill=color_background,
|
486 |
+
background_fill_primary=color_background,
|
487 |
+
background_fill_secondary=color_background,
|
488 |
+
button_primary_background_fill=color_primary,
|
489 |
+
button_primary_text_color="#FFFFFF",
|
490 |
+
button_primary_border_color=color_primary,
|
491 |
+
button_secondary_background_fill=color_background,
|
492 |
+
button_secondary_text_color=color_primary,
|
493 |
+
button_secondary_border_color=color_primary,
|
494 |
+
input_background_fill="#FFFFFF",
|
495 |
+
input_border_color=color_secondary,
|
496 |
+
input_shadow="none",
|
497 |
+
block_border_width="1px", # Aggiunge bordo ai blocchi
|
498 |
+
panel_border_width="1px",
|
499 |
+
)
|
500 |
|
501 |
+
# --- INTERFACCIA GRADIO (CON TEMA, SENZA TITOLO/DESCRIZIONE, INPUT AGGIORNATO) ---
|
502 |
iface = gr.Interface(
|
503 |
fn=generate_response,
|
504 |
inputs=[
|
505 |
+
gr.Textbox(
|
506 |
+
label="Input Utente: Incolla qui l'email/recensione a cui rispondere (puoi aggiungere sotto la recensione un elenco puntato con il filo logico da seguire), oppure descrivi l'idea/tema per post, script, campagna, newsletter, o l'obiettivo che vuoi raggiungere.", # Label aggiornata
|
507 |
+
lines=10 # Aumenta altezza iniziale
|
508 |
+
),
|
509 |
gr.CheckboxGroup(choices=choices, label="Toni e preferenze", value=["💡 Inspiring"]),
|
510 |
+
gr.Radio(choices=output_types, label="Tipo di Output Desiderato", value="Facebook Post"),
|
511 |
gr.Radio(choices=narrative_arcs, label="Arco Narrativo (se applicabile)", value="Conciso"),
|
512 |
+
gr.Radio(choices=marketing_models, label="Marketing Model (spiegato alla fine)", value="Nessuno"),
|
513 |
+
gr.Radio(choices=personifications, label="Scegli Profilo/Personificazione", value="🏨 Brand / Hotel"),
|
514 |
gr.Radio(choices=languages, label="Lingua Output", value="Italian"),
|
515 |
gr.Radio(choices=image_ratios, label="Genera Prompt Immagine AI?", value="None"),
|
516 |
gr.Radio(choices=privacy_options, label="Aggiungere Clausola Privacy?", value="No")
|
517 |
],
|
518 |
+
outputs=[
|
519 |
+
gr.HTML(visible=False),
|
520 |
gr.Textbox(label="📝 Testo / Script / Piano Generato (con Spiegazione Marketing alla fine, se applicabile)"),
|
521 |
gr.Textbox(label="🖼️ Suggested Image Prompt (for Midjourney, Leonardo, ChatGPT etc.)")
|
522 |
],
|
523 |
+
theme=theme,
|
524 |
+
title=None,
|
525 |
+
description=None,
|
526 |
+
css=".gradio-container { background-color: " + color_background + "; max-width: 100% !important; }"
|
527 |
)
|
528 |
|
529 |
if __name__ == "__main__":
|