Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import asyncio | |
| import os | |
| import time | |
| from app.models.pitch_input import PitchInput, InvestorType | |
| from app.services.openai_agents import OpenAIAgentService | |
| from app.utils.aws_storage import AWSS3Storage | |
| # Initialize agent service | |
| agent_service = OpenAIAgentService() | |
| # Initialize AWS S3 storage | |
| s3_storage = AWSS3Storage() | |
| # Define a function to process the form data | |
| async def generate_pitch( | |
| investor_type, | |
| startup_name, | |
| problem_description, | |
| solution_description, | |
| target_customer, | |
| business_model, | |
| current_stage, | |
| competitors, | |
| differentiators, | |
| market_impact, | |
| funding_details, | |
| progress=gr.Progress() | |
| ): | |
| # Create PitchInput object | |
| pitch_input = PitchInput( | |
| investor_type=InvestorType(investor_type), | |
| startup_name=startup_name, | |
| problem_description=problem_description, | |
| solution_description=solution_description, | |
| target_customer=target_customer, | |
| business_model=business_model, | |
| current_stage=current_stage, | |
| competitors=competitors, | |
| differentiators=differentiators, | |
| market_impact=market_impact, | |
| funding_details=funding_details | |
| ) | |
| # Process through the RAG pipeline with progress updates | |
| progress(0, "Starting the RAG pipeline...") | |
| # Step 1: Market insights from Perplexity | |
| progress(0.1, "Step 1/3: Gathering market insights from Perplexity...") | |
| # Step 2: Business angle from Gemini | |
| progress(0.4, "Step 2/3: Refining business angle with Gemini...") | |
| # Step 3: Generate pitch with OpenAI | |
| progress(0.7, "Step 3/3: Generating pitch scripts with OpenAI...") | |
| # Generate the pitch based on investor type | |
| if investor_type == "Angel Investor": | |
| pitch_output = await agent_service.create_angel_investor_agent(pitch_input) | |
| else: | |
| pitch_output = await agent_service.create_vc_investor_agent(pitch_input) | |
| progress(0.9, "Saving pitch data to AWS S3...") | |
| # Format competitors for display | |
| competitors_md = "## Competitor Analysis\n\n" | |
| for competitor in pitch_output.identified_competitors: | |
| competitors_md += f"### {competitor.name}\n" | |
| competitors_md += f"{competitor.description}\n\n" | |
| competitors_md += "**Strengths:**\n" | |
| for strength in competitor.strengths: | |
| competitors_md += f"- {strength}\n" | |
| competitors_md += "\n**Weaknesses:**\n" | |
| for weakness in competitor.weaknesses: | |
| competitors_md += f"- {weakness}\n" | |
| competitors_md += "\n\n" | |
| # Format market insights | |
| market_insights_md = "## Market Insights\n\n" + pitch_output.market_insights if pitch_output.market_insights else "" | |
| # Save to AWS S3 | |
| storage_result = s3_storage.save_pitch_data( | |
| script_id=pitch_output.script_id, | |
| elevator_pitch=pitch_output.elevator_pitch, | |
| full_pitch=pitch_output.full_pitch, | |
| competitors_data=competitors_md, | |
| market_insights=market_insights_md | |
| ) | |
| # Update script_id display with storage status | |
| script_id_display = f"Script ID: {pitch_output.script_id}" | |
| if storage_result["success"]: | |
| script_id_display += f" (Saved to S3: {storage_result['s3_path']})" | |
| else: | |
| script_id_display += f" (Warning: Failed to save to S3 - {storage_result['message']})" | |
| progress(1.0, "Pitch generation complete!") | |
| # Return the results | |
| return ( | |
| script_id_display, | |
| pitch_output.elevator_pitch, | |
| pitch_output.full_pitch, | |
| competitors_md, | |
| market_insights_md | |
| ) | |
| # Define the Gradio interface | |
| with gr.Blocks(title="StartupPal - Pitch Generator", theme=gr.themes.Monochrome()) as demo: | |
| gr.Markdown("# StartupPal RAG Module") | |
| gr.Markdown("### Generate tailored startup pitch scripts with our AI pipeline") | |
| with gr.Tabs(): | |
| with gr.TabItem("Generate Pitch"): | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| gr.Markdown("## Startup Information") | |
| gr.Markdown("Fill in the details about your startup to generate a customized pitch") | |
| investor_type = gr.Radio( | |
| ["Angel Investor", "Venture Capitalist"], | |
| label="1. Investor Type", | |
| info="Who is this pitch for?", | |
| value="Angel Investor" | |
| ) | |
| startup_name = gr.Textbox( | |
| label="2. Startup Name", | |
| info="The name of your startup", | |
| placeholder="EcoShip" | |
| ) | |
| problem_description = gr.Textbox( | |
| label="3. Problem Description", | |
| info="What problem does your startup solve?", | |
| placeholder="The shipping industry contributes significantly to global carbon emissions with inefficient packaging and routes.", | |
| lines=3 | |
| ) | |
| solution_description = gr.Textbox( | |
| label="4. Solution Description", | |
| info="How does your product or solution work?", | |
| placeholder="Our platform uses AI to optimize packaging dimensions and shipping routes to reduce carbon footprint.", | |
| lines=3 | |
| ) | |
| target_customer = gr.Textbox( | |
| label="5. Target Customer", | |
| info="Who are your target customers?", | |
| placeholder="E-commerce businesses that ship more than 1000 packages monthly" | |
| ) | |
| business_model = gr.Textbox( | |
| label="6. Business Model", | |
| info="How will you make money?", | |
| placeholder="SaaS subscription with tiered pricing based on shipping volume" | |
| ) | |
| with gr.Column(scale=1): | |
| gr.Markdown("## Additional Details") | |
| current_stage = gr.Textbox( | |
| label="7. Current Stage", | |
| info="What stage is your startup at?", | |
| placeholder="MVP with 3 beta customers" | |
| ) | |
| competitors = gr.Textbox( | |
| label="8. Competitors", | |
| info="Who are your main competitors?", | |
| placeholder="ShipGreen, EcoLogistics, Traditional shipping optimizers", | |
| lines=2 | |
| ) | |
| differentiators = gr.Textbox( | |
| label="9. Differentiators", | |
| info="What makes your solution better?", | |
| placeholder="Our solution combines both packaging and route optimization, while competitors focus on only one aspect", | |
| lines=3 | |
| ) | |
| market_impact = gr.Textbox( | |
| label="10. Market Impact", | |
| info="What impact will your startup have?", | |
| placeholder="We aim to reduce e-commerce shipping emissions by 30% within 5 years", | |
| lines=2 | |
| ) | |
| funding_details = gr.Textbox( | |
| label="11. Funding Details", | |
| info="How much funding are you seeking and for what?", | |
| placeholder="$500K for engineering team expansion and marketing to initial target segments" | |
| ) | |
| generate_btn = gr.Button("Generate Pitch", variant="primary") | |
| with gr.Row(): | |
| with gr.Column(): | |
| script_id = gr.Textbox(label="Script ID", interactive=False) | |
| gr.Markdown("## Elevator Pitch (1 minute)") | |
| elevator_pitch = gr.Textbox(lines=6, label="", interactive=False) | |
| gr.Markdown("## Full Pitch (3 minutes)") | |
| full_pitch = gr.Textbox(lines=15, label="", interactive=False) | |
| gr.Markdown("## Analysis") | |
| with gr.Accordion("Competitor Analysis", open=False): | |
| competitors_md = gr.Markdown() | |
| with gr.Accordion("Market Insights", open=False): | |
| market_insights_md = gr.Markdown() | |
| with gr.TabItem("View Saved Pitches"): | |
| gr.Markdown("## Retrieve Saved Pitches") | |
| with gr.Row(): | |
| script_id_input = gr.Textbox( | |
| label="Script ID", | |
| placeholder="Enter a Script ID to retrieve", | |
| interactive=True | |
| ) | |
| retrieve_btn = gr.Button("Retrieve Pitch", variant="primary") | |
| with gr.Row(): | |
| retrieved_status = gr.Textbox(label="Status", interactive=False) | |
| with gr.Row(): | |
| with gr.Column(): | |
| gr.Markdown("## Retrieved Elevator Pitch") | |
| retrieved_elevator_pitch = gr.Textbox(lines=6, label="", interactive=False) | |
| gr.Markdown("## Retrieved Full Pitch") | |
| retrieved_full_pitch = gr.Textbox(lines=15, label="", interactive=False) | |
| with gr.Accordion("Additional Data", open=False): | |
| retrieved_additional_data = gr.JSON() | |
| with gr.TabItem("About"): | |
| gr.Markdown(""" | |
| # StartupPal RAG Module | |
| This application uses a multi-model Retrieval-Augmented Generation (RAG) pipeline to generate high-quality startup pitch scripts: | |
| 1. **Perplexity API** - Retrieves market insights and competitor analysis | |
| 2. **Gemini API** - Refines business positioning and strategy | |
| 3. **OpenAI API** - Generates the final pitch scripts using the aggregated data | |
| ## How it works | |
| ``` | |
| Input: Startup details | |
| β | |
| ββ> Perplexity API | |
| β ββ> Market research & competitor analysis | |
| β β | |
| β ββ> Gemini API | |
| β β ββ> Business angle refinement & market positioning | |
| β β β | |
| β β ββ> OpenAI API | |
| β β ββ> Final pitch script generation | |
| β | |
| Output: Elevator pitch & full presentation scripts | |
| ``` | |
| ## API Model Configuration | |
| The models used in this application can be customized in the `.env` file: | |
| ``` | |
| OPENAI_MODEL=gpt-4o | |
| GEMINI_MODEL=gemini-1.5-pro | |
| ``` | |
| ## Data Storage | |
| All generated pitches are automatically saved to an AWS S3 bucket for later retrieval. | |
| You can access previously generated pitches using the "View Saved Pitches" tab. | |
| """) | |
| # Function to retrieve saved pitch data | |
| def retrieve_pitch(script_id): | |
| if not script_id: | |
| return "Please enter a valid Script ID", "", "", None | |
| result = s3_storage.get_pitch_data(script_id) | |
| if result["success"]: | |
| data = result["data"] | |
| status = f"Successfully retrieved pitch: {script_id}" | |
| return ( | |
| status, | |
| data.get("elevator_pitch", ""), | |
| data.get("full_pitch", ""), | |
| data | |
| ) | |
| else: | |
| return ( | |
| f"Error: {result.get('message', 'Failed to retrieve pitch')}", | |
| "", | |
| "", | |
| None | |
| ) | |
| # Set up the form submission | |
| generate_btn.click( | |
| fn=generate_pitch, | |
| inputs=[ | |
| investor_type, | |
| startup_name, | |
| problem_description, | |
| solution_description, | |
| target_customer, | |
| business_model, | |
| current_stage, | |
| competitors, | |
| differentiators, | |
| market_impact, | |
| funding_details | |
| ], | |
| outputs=[ | |
| script_id, | |
| elevator_pitch, | |
| full_pitch, | |
| competitors_md, | |
| market_insights_md | |
| ] | |
| ) | |
| # Set up the retrieve button | |
| retrieve_btn.click( | |
| fn=retrieve_pitch, | |
| inputs=[script_id_input], | |
| outputs=[ | |
| retrieved_status, | |
| retrieved_elevator_pitch, | |
| retrieved_full_pitch, | |
| retrieved_additional_data | |
| ] | |
| ) | |
| # Main function to launch the app | |
| def main(): | |
| # Get port from environment variable or use default range | |
| port = os.environ.get("GRADIO_SERVER_PORT") | |
| if port: | |
| try: | |
| port = int(port) | |
| print(f"Using port {port} from environment variable") | |
| demo.launch(server_name="0.0.0.0", server_port=port) | |
| except ValueError: | |
| print(f"Invalid port in environment variable: {port}") | |
| demo.launch(server_name="0.0.0.0") | |
| else: | |
| # Try a range of ports starting from 8091 | |
| for port in range(8091, 8100): | |
| try: | |
| print(f"Attempting to start on port {port}...") | |
| demo.launch(server_name="0.0.0.0", server_port=port) | |
| print(f"Successfully started on port {port}") | |
| break | |
| except OSError: | |
| print(f"Port {port} is in use, trying next port...") | |
| else: | |
| # If all ports are taken, let Gradio choose a port | |
| print("All specified ports are in use. Letting Gradio choose an available port...") | |
| demo.launch(server_name="0.0.0.0") | |
| if __name__ == "__main__": | |
| demo.launch(server_name="0.0.0.0") # No custom port logic! |