Spaces:
Running
Running
| from dotenv import load_dotenv | |
| import streamlit as st | |
| import os | |
| import google.generativeai as genai | |
| from story_formulas import story_formulas | |
| from styles import apply_styles, format_story_output | |
| from story_moods import story_moods # Agregar esta importación al inicio | |
| # Cargar variables de entorno | |
| load_dotenv() | |
| # Configurar API de Google Gemini | |
| genai.configure(api_key=os.getenv("GOOGLE_API_KEY")) | |
| # Función para obtener la respuesta del modelo Gemini | |
| def get_gemini_response(input_prompt, formula_type, length, mood, target_audience, cta_type, temperature): | |
| if not input_prompt: | |
| return "Por favor, escribe un mensaje para generar contenido." | |
| formula = story_formulas[formula_type] | |
| model = genai.GenerativeModel('gemini-2.0-flash') | |
| full_prompt = f""" | |
| You are a creative storyteller. Write THREE different {mood} stories in Spanish about "{input_prompt}" using everyday words and natural conversation. | |
| Each story should use exactly {length} words. | |
| Target Audience: {target_audience} | |
| Call to Action: {cta_type} | |
| Story Formula: {formula_type} | |
| {formula["description"]} | |
| Keep in mind: | |
| - Write for {target_audience} | |
| - Use simple, clear language | |
| - Tell the story in short paragraphs | |
| - The CTA must be conversational and focus on benefits: | |
| * Instead of: "Inscríbete al curso de marketing" | |
| * Use: "¿Quieres aprender a conseguir más clientes? Acompáñanos este jueves..." | |
| * Instead of: "Reserva tu consulta" | |
| * Use: "Da el primer paso hacia tu transformación aquí..." | |
| CRITICAL INSTRUCTIONS: | |
| - Output ONLY the story text | |
| - DO NOT include any labels like (Problem), (Solution), etc. | |
| - DO NOT include any structural markers or formula explanations | |
| - Write as a continuous narrative with natural paragraph breaks | |
| - The story should flow naturally between sections without any visible structure markers | |
| - Make the CTA feel like a natural part of the conversation, focusing on what the reader will gain | |
| - Avoid promotional language in the CTA | |
| - DO NOT explain or mention the formula parts in the text | |
| - Separate each story with "---" | |
| Format: Three clean story texts with natural paragraphs, separated by "---", no labels, no explanations. | |
| """ | |
| response = model.generate_content([full_prompt], generation_config={"temperature": temperature}) | |
| return response.parts[0].text if response and response.parts else "Error al generar contenido." | |
| # Configurar la aplicación Streamlit | |
| st.set_page_config(page_title="Story Generator", page_icon=":pencil:", layout="wide") | |
| st.markdown(apply_styles(), unsafe_allow_html=True) # Add this line here | |
| # Leer y mostrar el manual en el sidebar | |
| with open("manual.md", "r", encoding="utf-8") as file: | |
| manual_content = file.read() | |
| st.sidebar.markdown(manual_content) | |
| # Título de la app | |
| st.markdown("<h1>Story Genius Maker</h1>", unsafe_allow_html=True) | |
| st.markdown("<h3>Teje historias inolvidables en segundos, guiado por la magia de la inteligencia artificial que da vida a tus ideas en relatos cautivadores.</h3>", unsafe_allow_html=True) | |
| # Crear dos columnas | |
| col1, col2 = st.columns([1, 1]) | |
| # Columna izquierda para inputs | |
| # Remove the benefit input field | |
| with col1: | |
| # Entrada de texto principal | |
| input_prompt = st.text_area("Escribe de qué quieres que trate la historia:", placeholder="Escribe aquí tu idea...") | |
| target_audience = st.text_input("Público Objetivo:", placeholder="Ejemplo: Profesionales de 25-35 años...") | |
| cta_type = st.text_input("Llamado a la acción:", placeholder="Ejemplo: Curso de marketing digital...") | |
| with st.expander("Opciones avanzadas"): | |
| formula_type = st.selectbox( | |
| "Fórmula narrativa:", | |
| options=list(story_formulas.keys()), | |
| ) | |
| mood = st.selectbox( | |
| "Ángulo de Historia:", | |
| options=list(story_moods.keys()), | |
| ) | |
| length = st.slider("Longitud del texto (palabras):", | |
| min_value=100, | |
| max_value=150, | |
| value=125, | |
| step=5) | |
| temperature = st.slider( | |
| "Nivel de creatividad:", | |
| min_value=0.0, | |
| max_value=2.0, | |
| value=1.0, | |
| step=0.1, | |
| help="Valores más altos generan historias más creativas pero menos predecibles. Valores más bajos producen historias más consistentes." | |
| ) | |
| mood = st.selectbox("Estado de ánimo:", ["Emocional", "Triste", "Feliz", "Horror", "Comedia", "Romántico"]) | |
| generate_button = st.button("Generar historia") | |
| # Al inicio de la app | |
| apply_styles() | |
| # En la sección donde muestras la historia generada | |
| with col2: | |
| if generate_button: | |
| response = get_gemini_response( | |
| input_prompt, formula_type, length, | |
| mood, target_audience, cta_type, | |
| temperature | |
| ) | |
| stories = response.split("---") | |
| for i, story in enumerate(stories, 1): | |
| st.subheader(f"Historia {i}:") | |
| st.write(story.strip()) | |
| st.divider() |