Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -4,7 +4,6 @@ import os
|
|
| 4 |
from google import genai
|
| 5 |
from google.genai import types
|
| 6 |
import random
|
| 7 |
-
import re
|
| 8 |
from formulas import headline_formulas
|
| 9 |
from angles import angles
|
| 10 |
|
|
@@ -21,18 +20,6 @@ if not api_key:
|
|
| 21 |
client = genai.Client(api_key=api_key)
|
| 22 |
|
| 23 |
|
| 24 |
-
SPANISH_STOPWORDS = {
|
| 25 |
-
"de", "del", "la", "el", "los", "las", "y", "o", "u", "a", "en", "con",
|
| 26 |
-
"para", "por", "sin", "un", "una", "unos", "unas", "al", "lo", "que", "tu", "tus"
|
| 27 |
-
}
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
def extract_product_keywords(product):
|
| 31 |
-
words = re.findall(r"[a-záéíóúñA-ZÁÉÍÓÚÑ0-9]+", product.lower())
|
| 32 |
-
keywords = [w for w in words if len(w) >= 4 and w not in SPANISH_STOPWORDS]
|
| 33 |
-
return list(dict.fromkeys(keywords))
|
| 34 |
-
|
| 35 |
-
|
| 36 |
def build_headline_context(selected_formula_key, selected_angle, target_audience, product):
|
| 37 |
selected_formula = headline_formulas[selected_formula_key]
|
| 38 |
|
|
@@ -104,56 +91,22 @@ def generate_headlines(number_of_headlines, target_audience, product, temperatur
|
|
| 104 |
"- Usa contraste, curiosidad o resultado específico para detener el scroll.",
|
| 105 |
"- Evita formato tipo bullet (por ejemplo: 'Beneficio: detalle', listas fragmentadas o etiquetas).",
|
| 106 |
"- Evita signos innecesarios, mayúsculas exageradas y relleno.",
|
| 107 |
-
"- Longitud sugerida: entre 8 y 16 palabras por titular."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
])
|
| 109 |
-
product_keywords = extract_product_keywords(product)
|
| 110 |
-
|
| 111 |
-
system_prompt = f"""Eres un copywriter de clase mundial especializado en escribir titulares, hooks y líneas de asunto que captan la atención rápidamente y despiertan una curiosidad genuina.
|
| 112 |
-
|
| 113 |
-
OBJETIVO:
|
| 114 |
-
Generar titulares atractivos, claros y creíbles para el público indicado.
|
| 115 |
-
|
| 116 |
-
FORMATO OBLIGATORIO:
|
| 117 |
-
- Devuelve EXACTAMENTE {number_of_headlines} líneas.
|
| 118 |
-
- Cada línea debe empezar con número y punto (ejemplo: 1. ...).
|
| 119 |
-
- No agregues introducciones, notas, categorías ni cierre.
|
| 120 |
-
- Una sola idea por línea.
|
| 121 |
-
- Cada línea debe sonar como titular completo, no como viñeta o fragmento.
|
| 122 |
-
|
| 123 |
-
CALIDAD:
|
| 124 |
-
- Evita clichés y frases vacías.
|
| 125 |
-
- Prioriza beneficio concreto + especificidad.
|
| 126 |
-
- Mantén tono natural para el público objetivo.
|
| 127 |
-
- No copies ejemplos literalmente.
|
| 128 |
-
- Evita repetir estructuras entre líneas.
|
| 129 |
-
- Enfatiza el beneficio del producto sin depender de nombrarlo de forma explícita en todos los titulares.
|
| 130 |
-
|
| 131 |
-
PRINCIPIOS DE TITULACIÓN:
|
| 132 |
-
- Abre con la promesa o ángulo principal en las primeras palabras.
|
| 133 |
-
- Usa contraste, curiosidad o resultado específico para detener el scroll.
|
| 134 |
-
- Evita formato tipo bullet (por ejemplo: "Beneficio: detalle", listas fragmentadas o etiquetas).
|
| 135 |
-
- Evita signos innecesarios, mayúsculas exageradas y relleno.
|
| 136 |
-
- Longitud sugerida: entre 8 y 16 palabras por titular.
|
| 137 |
-
- Enfatiza el beneficio del producto sin depender de nombrarlo de forma explícita en todos los titulares.
|
| 138 |
-
- No menciones explícitamente el producto o servicio en ningún titular.
|
| 139 |
-
"""
|
| 140 |
|
| 141 |
headlines_instruction = (
|
| 142 |
f"{system_prompt}\n\n"
|
| 143 |
f"PÚBLICO: {target_audience}\n"
|
| 144 |
f"PRODUCTO/SERVICIO (USAR COMO CONTEXTO, PRIORIZAR BENEFICIO): {product}\n"
|
| 145 |
-
f"CONTEXTO INTERNO (NO MENCIONAR EN EL OUTPUT): {product}\n"
|
| 146 |
f"FÓRMULA: {selected_formula_key}\n"
|
| 147 |
f"DESCRIPCIÓN CORTA DE LA FÓRMULA:\n{context['formula_description_short']}\n\n"
|
| 148 |
)
|
| 149 |
|
| 150 |
-
if product_keywords:
|
| 151 |
-
blocked_terms = ", ".join(product_keywords)
|
| 152 |
-
headlines_instruction += (
|
| 153 |
-
"PALABRAS PROHIBIDAS EN EL TITULAR (derivadas del producto): "
|
| 154 |
-
f"{blocked_terms}\n\n"
|
| 155 |
-
)
|
| 156 |
-
|
| 157 |
if selected_angle != "NINGUNO":
|
| 158 |
headlines_instruction += (
|
| 159 |
f"ÁNGULO: {selected_angle}\n"
|
|
@@ -171,6 +124,14 @@ PRINCIPIOS DE TITULACIÓN:
|
|
| 171 |
for guidance in context["extra_guidance"]:
|
| 172 |
headlines_instruction += f"- {guidance}\n"
|
| 173 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 174 |
headlines_instruction += "\n"
|
| 175 |
headlines_instruction += f"Genera ahora {number_of_headlines} titulares."
|
| 176 |
|
|
|
|
| 4 |
from google import genai
|
| 5 |
from google.genai import types
|
| 6 |
import random
|
|
|
|
| 7 |
from formulas import headline_formulas
|
| 8 |
from angles import angles
|
| 9 |
|
|
|
|
| 20 |
client = genai.Client(api_key=api_key)
|
| 21 |
|
| 22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
def build_headline_context(selected_formula_key, selected_angle, target_audience, product):
|
| 24 |
selected_formula = headline_formulas[selected_formula_key]
|
| 25 |
|
|
|
|
| 91 |
"- Usa contraste, curiosidad o resultado específico para detener el scroll.",
|
| 92 |
"- Evita formato tipo bullet (por ejemplo: 'Beneficio: detalle', listas fragmentadas o etiquetas).",
|
| 93 |
"- Evita signos innecesarios, mayúsculas exageradas y relleno.",
|
| 94 |
+
"- Longitud sugerida: entre 8 y 16 palabras por titular.",
|
| 95 |
+
"",
|
| 96 |
+
"ANÁLISIS DEL AVATAR (INTERNO, NO MOSTRAR):",
|
| 97 |
+
"- Antes de escribir, identifica deseos, frustraciones, objeciones y transformación que busca el avatar.",
|
| 98 |
+
"- Piensa en situaciones reales y cotidianas del avatar (momento, contexto, tensión real).",
|
| 99 |
+
"- Cada titular debe reflejar al menos una situación concreta del avatar, no ideas genéricas."
|
| 100 |
])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
|
| 102 |
headlines_instruction = (
|
| 103 |
f"{system_prompt}\n\n"
|
| 104 |
f"PÚBLICO: {target_audience}\n"
|
| 105 |
f"PRODUCTO/SERVICIO (USAR COMO CONTEXTO, PRIORIZAR BENEFICIO): {product}\n"
|
|
|
|
| 106 |
f"FÓRMULA: {selected_formula_key}\n"
|
| 107 |
f"DESCRIPCIÓN CORTA DE LA FÓRMULA:\n{context['formula_description_short']}\n\n"
|
| 108 |
)
|
| 109 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
if selected_angle != "NINGUNO":
|
| 111 |
headlines_instruction += (
|
| 112 |
f"ÁNGULO: {selected_angle}\n"
|
|
|
|
| 124 |
for guidance in context["extra_guidance"]:
|
| 125 |
headlines_instruction += f"- {guidance}\n"
|
| 126 |
|
| 127 |
+
headlines_instruction += (
|
| 128 |
+
"\nCHECKLIST DE REALISMO DEL AVATAR (aplícalo en cada titular):\n"
|
| 129 |
+
"- Incluye una situación cotidiana reconocible del público.\n"
|
| 130 |
+
"- Incluye una tensión real (dolor, objeción o limitación concreta).\n"
|
| 131 |
+
"- Conecta con una transformación deseada y creíble.\n"
|
| 132 |
+
"- Evita titulares intercambiables que podrían servir para cualquier audiencia.\n"
|
| 133 |
+
)
|
| 134 |
+
|
| 135 |
headlines_instruction += "\n"
|
| 136 |
headlines_instruction += f"Genera ahora {number_of_headlines} titulares."
|
| 137 |
|