Spaces:
Running
Running
File size: 9,476 Bytes
8056e64 25e4a50 8056e64 25e4a50 8056e64 25e4a50 8056e64 25e4a50 8056e64 25e4a50 8056e64 25e4a50 8056e64 25e4a50 8056e64 25e4a50 8056e64 25e4a50 8056e64 25e4a50 8056e64 25e4a50 8056e64 25e4a50 8056e64 25e4a50 8056e64 25e4a50 8056e64 25e4a50 8056e64 25e4a50 8056e64 25e4a50 8056e64 25e4a50 8056e64 25e4a50 8056e64 25e4a50 8056e64 25e4a50 8056e64 25e4a50 8056e64 25e4a50 8056e64 25e4a50 |
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 |
from dotenv import load_dotenv
import streamlit as st
import os
import google.generativeai as genai
import random
from streamlit import session_state as state
from formulas import headline_formulas
from angles import angles
# Cargar las variables de entorno
load_dotenv()
# Configurar la API de Google
genai.configure(api_key=os.getenv("GOOGLE_API_KEY"))
# Fórmulas con ejemplos y explicaciones
# headline_formulas dictionary has been moved to formulas/headline_formulas.py
def generate_headlines(number_of_headlines, target_audience, product, temperature, selected_formula, selected_angle):
# Crear la configuración del modelo
generation_config = {
"temperature": temperature,
"top_p": 0.65,
"top_k": 360,
"max_output_tokens": 8196,
}
model = genai.GenerativeModel(
model_name="gemini-2.0-flash",
generation_config=generation_config,
)
# Angle dictionaries have been moved to angles/angle_data.py
# Incluir las instrucciones del sistema en el prompt principal
system_prompt = f"""You are a world-class copywriter, with expertise in crafting hooks, headlines, and subject lines that immediately capture the reader's attention, prompting them to open the email or continue reading.
FORMAT RULES:
- Each headline must start with number and period
- One headline per line
- No explanations or categories
- Add a line break between each headline
- Avoid unnecessary : symbols
- Each headline must be a complete and intriguing sentence
IMPORTANT ANGLE INSTRUCTIONS:
- The selected angle MUST be applied to EVERY headline
- The angle modifies HOW the formula is expressed, not its structure
- Think of the angle as a "tone overlay" on the formula
- The formula provides the structure, the angle provides the style
- Both must work together seamlessly
FORMAT EXAMPLE:
1. Titular 1.
2. Titular 2.
3. Titular 3.
4. Titular 4.
5. Titular 5.
IMPORTANT:
- Each headline must be unique and memorable
- Avoid clichés and generalities
- Maintain an intriguing but credible tone
- Adapt speaking language from the audience
- Focus on transformative benefits
- Follow the selected angle style while maintaining formula structure"""
# Iniciar el prompt con las instrucciones del sistema
headlines_instruction = f"{system_prompt}\n\n"
# Añadir instrucciones de ángulo solo si no es "NINGUNO"
if selected_angle != "NINGUNO":
headlines_instruction += f"""
ÁNGULO PRINCIPAL: {selected_angle}
INSTRUCCIONES DE ÁNGULO ESPECÍFICAS:
{angles[selected_angle]["instruction"]}
IMPORTANTE: El ángulo {selected_angle} debe aplicarse como una "capa de estilo" sobre la estructura de la fórmula:
1. Mantén la estructura base de la fórmula intacta
2. Aplica el tono y estilo del ángulo {selected_angle}
3. Asegura que cada elemento de la fórmula refleje el ángulo
4. El ángulo afecta al "cómo" se dice, no al "qué" se dice
EJEMPLOS EXITOSOS DEL ÁNGULO {selected_angle}:
"""
for example in angles[selected_angle]["examples"]:
headlines_instruction += f"- {example}\n"
headlines_instruction += (
f"\nTu tarea es crear {number_of_headlines} titulares irresistibles para {target_audience} "
f"que capturen la atención instantáneamente y generen curiosidad sobre {product}. "
)
if selected_angle != "NINGUNO":
headlines_instruction += f"IMPORTANTE: Cada titular DEBE seguir el ángulo {selected_angle} de manera clara y consistente.\n\n"
headlines_instruction += (
f"Evita menciones obvias de {product} y enfócate en despertar interés genuino"
)
if selected_angle != "NINGUNO":
headlines_instruction += f" usando el ángulo seleccionado"
headlines_instruction += ".\n\n"
headlines_instruction += (
f"IMPORTANTE: Estudia cuidadosamente estos ejemplos de la fórmula seleccionada. "
f"Cada ejemplo representa el estilo y estructura a seguir"
)
if selected_angle != "NINGUNO":
headlines_instruction += f", adaptados al ángulo {selected_angle}"
headlines_instruction += ":\n\n"
# Agregar 5 ejemplos aleatorios de la fórmula
random_examples = random.sample(selected_formula['examples'], min(5, len(selected_formula['examples'])))
headlines_instruction += "EJEMPLOS DE LA FÓRMULA A SEGUIR:\n"
for i, example in enumerate(random_examples, 1):
headlines_instruction += f"{i}. {example}\n"
headlines_instruction += "\nINSTRUCCIONES ESPECÍFICAS:\n"
headlines_instruction += "1. Mantén la misma estructura y longitud que los ejemplos anteriores\n"
headlines_instruction += "2. Usa el mismo tono y estilo de escritura\n"
headlines_instruction += "3. Replica los patrones de construcción de frases\n"
headlines_instruction += "4. Conserva el nivel de especificidad y detalle\n"
headlines_instruction += f"5. Adapta el contenido para {target_audience} manteniendo la esencia de los ejemplos\n\n"
headlines_instruction += f"FÓRMULA A SEGUIR:\n{selected_formula['description']}\n\n"
# CORRECTO (con indentación):
if selected_angle != "NINGUNO":
headlines_instruction += f"""
RECORDATORIO FINAL:
1. Sigue la estructura de la fórmula seleccionada
2. Aplica el ángulo como una "capa de estilo"
3. Mantén la coherencia entre fórmula y ángulo
4. Asegura que cada titular refleje ambos elementos
GENERA AHORA:
Crea {number_of_headlines} titulares que sigan fielmente el estilo y estructura de los ejemplos mostrados.
"""
else:
headlines_instruction += f"""
GENERA AHORA:
Crea {number_of_headlines} titulares que sigan fielmente el estilo y estructura de los ejemplos mostrados.
"""
# Enviar el mensaje al modelo (sin condiciones de imagen)
chat_session = model.start_chat(
history=[
{
"role": "user",
"parts": [headlines_instruction],
},
]
)
response = chat_session.send_message("Genera los titulares siguiendo exactamente el estilo de los ejemplos mostrados.")
return response.text
# Configurar la interfaz de usuario con Streamlit
st.set_page_config(page_title="Enchanted Hooks", layout="wide")
# Leer el contenido del archivo manual.md
with open("manual.md", "r", encoding="utf-8") as file:
manual_content = file.read()
# Mostrar el contenido del manual en el sidebar
st.sidebar.markdown(manual_content)
# Load CSS from file
with open("styles/main.css", "r") as f:
css = f.read()
# Apply the CSS
st.markdown(f"<style>{css}</style>", unsafe_allow_html=True)
# Centrar el título y el subtítulo
st.markdown("<h1 style='text-align: center;'>Enchanted Hooks</h1>", unsafe_allow_html=True)
st.markdown("<h4 style='text-align: center;'>Imagina poder conjurar títulos que no solo informan, sino que encantan. Esta app es tu varita mágica en el mundo del copywriting, transformando cada concepto en un titular cautivador que deja a todos deseando más.</h4>", unsafe_allow_html=True)
# Crear columnas
col1, col2 = st.columns([1, 2])
# Columnas de entrada
with col1:
target_audience = st.text_input("¿Quién es tu público objetivo?", placeholder="Ejemplo: Estudiantes Universitarios")
product = st.text_input("¿Qué producto tienes en mente?", placeholder="Ejemplo: Curso de Inglés")
number_of_headlines = st.selectbox("Número de Titulares", options=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], index=4)
# Crear un único acordeón para fórmula, creatividad y ángulo
with st.expander("Personaliza tus titulares"):
temperature = st.slider("Creatividad", min_value=0.0, max_value=2.0, value=1.0, step=0.1)
selected_formula_key = st.selectbox(
"Selecciona una fórmula para tus titulares",
options=list(headline_formulas.keys())
)
# Automatically use the keys from the angles dictionary
# Make sure "NINGUNO" appears first, then the rest alphabetically
angle_keys = ["NINGUNO"] + sorted([key for key in angles.keys() if key != "NINGUNO"])
selected_angle = st.selectbox(
"Selecciona el ángulo para tus titulares",
options=angle_keys
)
selected_formula = headline_formulas[selected_formula_key]
# Botón de enviar
submit = st.button("Generar Titulares")
# Mostrar los titulares generados
if submit:
# Check if we have valid inputs
has_product = product.strip() != ""
has_audience = target_audience.strip() != ""
# Valid combination: Product + Audience
valid_inputs = has_product and has_audience
if valid_inputs and selected_formula:
try:
generated_headlines = generate_headlines(
number_of_headlines,
target_audience,
product,
temperature,
selected_formula,
selected_angle
)
col2.markdown(f"""
<div class="results-container">
<h4>Observa la magia en acción:</h4>
<p>{generated_headlines}</p>
</div>
""", unsafe_allow_html=True)
except ValueError as e:
col2.error(f"Error: {str(e)}")
else:
if not selected_formula:
col2.error("Por favor, selecciona una fórmula.")
else:
col2.error("Por favor, proporciona el público objetivo y el producto.")
|