Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| from dotenv import load_dotenv | |
| import os | |
| import time | |
| from typing import Dict, Any | |
| # Load environment variables | |
| load_dotenv() | |
| # Import crew agents after environment setup | |
| from crewai import Agent, Task, Crew, LLM | |
| from crewai_tools import SerperDevTool | |
| # Initialize tools | |
| search_tool = SerperDevTool() | |
| # Initialize LLM | |
| llm = LLM( | |
| model="gemini/gemini-2.0-flash", | |
| temperature=0.7, | |
| stream=False # Set to False for Gradio compatibility | |
| ) | |
| def create_crew_for_topic(topic: str) -> Crew: | |
| """Create a crew with agents for the given topic""" | |
| # Research Specialist Agent | |
| research_agent = Agent( | |
| role="Research Specialist", | |
| goal=f"Research interesting facts about the topic: {topic}", | |
| backstory="You are a highly skilled research assistant that can research the web and provide factual data", | |
| llm=llm, | |
| tools=[search_tool], | |
| verbose=False | |
| ) | |
| # Creative Writer Agent | |
| writer_agent = Agent( | |
| role="Creative Writer", | |
| goal="Write a 250 words blog using the research and it must start with a hook, introduction para, body para, conclusion para and end with a call to action", | |
| backstory="You are a highly skilled writer assistant that can write a blog post about the topic", | |
| llm=llm, | |
| verbose=False | |
| ) | |
| # Create tasks | |
| task1 = Task( | |
| description=f"Research interesting 4-5 facts about the topic: {topic}", | |
| expected_output="A bullet point list of 4-5 facts about the topic", | |
| agent=research_agent | |
| ) | |
| task2 = Task( | |
| description=f"Write a 250 words blog using the research on {topic} and must be a casual tone", | |
| expected_output="Blog post", | |
| agent=writer_agent, | |
| context=[task1] | |
| ) | |
| # Create crew | |
| crew = Crew( | |
| agents=[research_agent, writer_agent], | |
| tasks=[task1, task2], | |
| verbose=False | |
| ) | |
| return crew | |
| def generate_blog(topic: str, progress=gr.Progress()) -> Dict[str, Any]: | |
| """Generate blog content using crew agents""" | |
| if not topic.strip(): | |
| return { | |
| "status": "error", | |
| "message": "Please enter a topic for blog generation." | |
| } | |
| try: | |
| progress(0.1, desc="Initializing crew agents...") | |
| # Create crew for the topic | |
| crew = create_crew_for_topic(topic) | |
| progress(0.3, desc="Researching topic...") | |
| # Execute the crew tasks | |
| response = crew.kickoff(inputs={"topic": topic}) | |
| progress(0.8, desc="Finalizing blog post...") | |
| # Simulate some processing time for better UX | |
| time.sleep(0.5) | |
| progress(1.0, desc="Blog generated successfully!") | |
| return { | |
| "status": "success", | |
| "topic": topic, | |
| "blog_content": response, | |
| "timestamp": time.strftime("%Y-%m-%d %H:%M:%S") | |
| } | |
| except Exception as e: | |
| return { | |
| "status": "error", | |
| "message": f"An error occurred: {str(e)}" | |
| } | |
| def format_blog_output(result: Dict[str, Any]) -> str: | |
| """Format the blog output for display""" | |
| if result["status"] == "error": | |
| return f"β **Error**: {result['message']}" | |
| blog_content = result["blog_content"] | |
| topic = result["topic"] | |
| timestamp = result["timestamp"] | |
| formatted_output = f""" | |
| # π Blog Post: {topic} | |
| **Generated on:** {timestamp} | |
| --- | |
| {blog_content} | |
| --- | |
| *This blog post was generated using AI-powered research and writing agents.* | |
| """ | |
| return formatted_output | |
| # Create Gradio interface | |
| with gr.Blocks( | |
| title="Crew Agents - AI Blog Generator", | |
| theme=gr.themes.Soft(), | |
| css=""" | |
| .gradio-container { | |
| max-width: 1200px !important; | |
| margin: 0 auto !important; | |
| } | |
| .header { | |
| text-align: center; | |
| padding: 20px; | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| color: white; | |
| border-radius: 2px; | |
| margin-bottom: 30px; | |
| } | |
| .output-section { | |
| background: white !important; | |
| padding: 25px !important; | |
| border-radius: 5px !important; | |
| border: none !important; | |
| outline: none !important; | |
| box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1) !important; | |
| } | |
| /* Remove all borders from Gradio components */ | |
| .output-section * { | |
| border: none !important; | |
| outline: none !important; | |
| } | |
| .output-section .gr-box { | |
| border: none !important; | |
| outline: none !important; | |
| } | |
| /* Remove borders from Group components */ | |
| .gr-group { | |
| border: none !important; | |
| outline: none !important; | |
| } | |
| /* Remove borders from all form elements */ | |
| .gr-form { | |
| border: none !important; | |
| outline: none !important; | |
| } | |
| /* Target the specific border classes */ | |
| .border { | |
| border: none !important; | |
| } | |
| .border-2 { | |
| border: none !important; | |
| } | |
| .border-solid { | |
| border: none !important; | |
| } | |
| .border-gray-200 { | |
| border: none !important; | |
| } | |
| /* Remove any remaining borders */ | |
| * { | |
| border-color: transparent !important; | |
| } | |
| """ | |
| ) as demo: | |
| # Header | |
| gr.HTML(""" | |
| <div class="header"> | |
| <h1>π€ Crew Agents - AI Blog Generator</h1> | |
| <p>Powered by CrewAI - Generate well-researched blog posts in seconds!</p> | |
| </div> | |
| """) | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| # Input Section | |
| with gr.Group(): | |
| gr.Markdown("## π― **Enter Your Blog Topic**") | |
| topic_input = gr.Textbox( | |
| label="Blog Topic", | |
| placeholder="e.g., How AI is transforming healthcare, The future of renewable energy...", | |
| lines=3, | |
| max_lines=5, | |
| info="Describe what you want to write about. Be specific for better results!" | |
| ) | |
| generate_btn = gr.Button( | |
| "π Generate Blog Post", | |
| variant="primary", | |
| size="lg" | |
| ) | |
| # Example topics | |
| gr.Markdown(""" | |
| **π‘ Example Topics:** | |
| - How AI is revolutionizing agriculture | |
| - The impact of climate change on coastal cities | |
| - Future of remote work in 2026 | |
| - Sustainable fashion trends | |
| """) | |
| with gr.Column(scale=2): | |
| # Output Section | |
| with gr.Group(): | |
| gr.Markdown("## π **Generated Blog Post**") | |
| output_markdown = gr.Markdown( | |
| value="Enter a topic above and click 'Generate Blog Post' to get started!", | |
| label="Blog Content" | |
| ) | |
| # Status indicator | |
| status_text = gr.Textbox( | |
| label="Status", | |
| value="Ready to generate", | |
| interactive=False | |
| ) | |
| # Footer | |
| gr.HTML(""" | |
| <div style="text-align: center; margin-top: 30px; padding: 20px; color: #666;"> | |
| <p>Built with β€οΈ using <a href="https://github.com/joaomdmoura/crewAI" target="_blank">CrewAI</a> and <a href="https://ai.google.dev/" target="_blank">Google Gemini</a></p> | |
| </div> | |
| """) | |
| # Event handlers | |
| def on_generate(topic): | |
| if not topic.strip(): | |
| return "Please enter a topic for blog generation.", "No topic provided" | |
| # Update status | |
| yield "Generating blog post...", "Processing..." | |
| # Generate blog | |
| result = generate_blog(topic) | |
| if result["status"] == "success": | |
| formatted_blog = format_blog_output(result) | |
| yield formatted_blog, "Blog generated successfully!" | |
| else: | |
| yield f"β **Error**: {result['message']}", "Generation failed" | |
| generate_btn.click( | |
| fn=on_generate, | |
| inputs=[topic_input], | |
| outputs=[output_markdown, status_text] | |
| ) | |
| # Enter key support | |
| topic_input.submit( | |
| fn=on_generate, | |
| inputs=[topic_input], | |
| outputs=[output_markdown, status_text] | |
| ) | |
| # Launch the app | |
| if __name__ == "__main__": | |
| demo.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| share=False, | |
| show_error=True | |
| ) | |