File size: 12,216 Bytes
c287226
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5f637fd
c287226
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9289c18
 
 
 
 
 
 
 
 
 
 
a1b46ea
 
9289c18
 
 
 
 
 
 
 
 
 
 
a1b46ea
 
 
 
 
 
 
 
 
 
9289c18
 
 
 
a1b46ea
9289c18
 
 
a1b46ea
 
 
 
 
 
 
 
 
9289c18
 
 
 
c287226
 
 
 
5f637fd
c287226
 
 
9289c18
5f637fd
9289c18
 
ee5f52d
9289c18
 
c287226
 
 
 
 
 
 
 
 
5f637fd
c287226
5f637fd
c287226
 
 
 
5f637fd
c287226
 
 
 
5f637fd
c287226
 
 
 
5f637fd
c287226
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d388506
 
 
 
 
 
 
 
c287226
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d388506
c287226
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d388506
c287226
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
import streamlit as st
import asyncio
from workflows_v2 import startup_validation_workflow
import time

# Real-time progress tracking class
class StreamlitProgressTracker:
    def __init__(self):
        self.progress_container = None
        self.status_text = None
        self.progress_bar = None
        self.log_container = None
        self.current_phase = 0
        self.total_phases = 4
        
    def setup_ui(self):
        self.progress_container = st.container()
        with self.progress_container:
            self.status_text = st.empty()
            self.progress_bar = st.progress(0)
            self.log_container = st.container()
    
    def update_progress(self, message):
        """Called by workflow for each progress update"""
        
        # Track phases based on message content
        if "PHASE 1:" in message:
            self.current_phase = 1
        elif "PHASE 2:" in message:
            self.current_phase = 2
        elif "PHASE 3:" in message:
            self.current_phase = 3
        elif "PHASE 4:" in message:
            self.current_phase = 4
        
        # Update progress bar
        progress = (self.current_phase / self.total_phases) * 100
        self.progress_bar.progress(int(progress))
        
        # Update status
        if "PHASE" in message and ":" in message:
            self.status_text.info(f"πŸ”„ {message}")
        elif "βœ…" in message:
            self.status_text.success(f"{message}")
        else:
            self.status_text.info(f"πŸ”„ {message}")
        
        # Add to log (skip the "=" separator lines)
        if message and message.strip() and not all(c == '=' for c in message.strip()):
            with self.log_container:
                st.text(message)
    
    def complete(self):
        self.progress_bar.progress(100)
        self.status_text.success("βœ… Validation completed!")

def main():
    st.set_page_config(
        page_title="StartupScan",
        page_icon="πŸš€",
        layout="wide",
        initial_sidebar_state="expanded"
    )
    
    # Custom CSS for better styling
    st.markdown("""
    <style>
    .main-header {
        font-size: 3rem;
        font-weight: bold;
        text-align: center;
        margin-bottom: 2rem;
        background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
    }
    .stButton > button {
        background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
        color: white;
        border: none;
        padding: 0.5rem 2rem;
        border-radius: 10px;
        font-weight: bold;
    }
    .result-section {
        background-color: #f8f9fa;
        padding: 2rem;
        border-radius: 15px;
        border-left: 5px solid #667eea;
        margin: 2rem 0;
    }
    .log-container {
        background-color: #f1f3f4;
        padding: 1rem;
        border-radius: 8px;
        font-family: monospace;
        font-size: 0.9rem;
        max-height: 300px;
        overflow-y: auto;
        border: 1px solid #ddd;
    }
    .header-buttons {
        display: flex;
        justify-content: center;
        gap: 15px;
        margin: 1.5rem 0;
        flex-wrap: wrap;
    }
    .header-btn {
        display: inline-block;
        padding: 12px 24px;
        background: linear-gradient(135deg, #17a2b8 0%, #138496 100%);
        color: white !important;
        text-decoration: none !important;
        border-radius: 25px;
        font-weight: 600;
        font-size: 0.95rem;
        transition: all 0.3s ease;
        box-shadow: 0 4px 15px rgba(23, 162, 184, 0.3);
        border: none;
        cursor: pointer;
    }
    .header-btn:hover {
        transform: translateY(-2px);
        box-shadow: 0 6px 20px rgba(23, 162, 184, 0.4);
        color: white !important;
        text-decoration: none !important;
    }
    .header-btn:visited {
        color: white !important;
        text-decoration: none !important;
    }
    .header-btn:link {
        color: white !important;
        text-decoration: none !important;
    }
    .header-btn.secondary {
        background: linear-gradient(135deg, #fd7e14 0%, #e55b13 100%);
        box-shadow: 0 4px 15px rgba(253, 126, 20, 0.3);
        color: white !important;
    }
    .header-btn.secondary:hover {
        box-shadow: 0 6px 20px rgba(253, 126, 20, 0.4);
        color: white !important;
    }
    .header-btn.secondary:visited {
        color: white !important;
        text-decoration: none !important;
    }
    .header-btn.secondary:link {
        color: white !important;
        text-decoration: none !important;
    }
    .header-btn .emoji {
        margin-right: 8px;
    }
    </style>
    """, unsafe_allow_html=True)
    
    # Header
    st.markdown('<h1 class="main-header">πŸš€ StartupScan</h1>', unsafe_allow_html=True)

    # Subtitle with demo and guide links
    st.markdown("""
    <div class="header-buttons">
        <a href="https://app.atla-ai.com/app/atla-demo-802mg" target="_blank" class="header-btn">
            <span class="emoji">πŸ”</span>View your traces on Atla
        </a>
        <a href="https://www.agno.com/?utm_source=atla&utm_medium=partner-content&utm_campaign=partner-technical&utm_content=atla" target="_blank" class="header-btn secondary">
            <span class="emoji">πŸ› οΈ</span>Built with Agno
        </a>
    </div>
    """, unsafe_allow_html=True)

    st.markdown("---")
    
    # Sidebar with information
    with st.sidebar:
        st.markdown("## πŸ“‹ About This Tool")
        st.markdown("""
        This agentic tool validates your startup idea through:
        
        🎯 **Idea Clarification Agent**
        - Originality assessment
        - Mission definition
        - Objective setting
        
        πŸ“Š **Market Research Agent**
        - TAM/SAM/SOM analysis
        - Customer segmentation
        - Market trends
        
        🏒 **Competitor Analysis Agent**
        - SWOT analysis
        - Positioning assessment
        - Market gaps
        
        πŸ“‹ **Validation Report Agent**
        - Executive summary
        - Strategic recommendations
        - Next steps
        """)
        
        st.markdown("---")
        st.markdown("πŸ’‘ **Tip:** Be as specific as possible about your startup idea for better results!")
    
    # Main content area
    col1, col2 = st.columns([2, 1])
    
    with col1:
        st.markdown("## πŸ’‘ Tell us about your startup idea")
        
        # Input form
        with st.form("startup_form", clear_on_submit=False):
            # Get default value from session state if an example was selected
            default_value = st.session_state.get('selected_example', '')
            
            startup_idea = st.text_area(
                "Describe your startup idea in detail:",
                value=default_value,
                height=150,
                placeholder="e.g., A marketplace for Christmas Ornaments made from leather that connects artisans with customers looking for unique holiday decorations...",
                help="The more detailed your description, the better the validation will be."
            )
            
            # Model selection toggle
            model_id = st.selectbox(
                "πŸ€– Model to use:",
                options=["gpt-4o", "gpt-4o-mini", "o1", "o3-mini"],
                index=0,  # Default to gpt-4o
                help="Choose which AI model to use for the validation analysis"
            )
            
            submitted = st.form_submit_button("πŸ” Validate My Idea", use_container_width=True)
    
    with col2:
        st.markdown("## 🎯 Quick Examples")
        st.markdown("*Click any example to populate the idea field*")
        
        examples = [
            "AI-powered personal finance coach for millennials",
            "Sustainable packaging solutions for e-commerce",
            "Virtual reality fitness platform for remote workers",
            "Marketplace for local artisan food products",
            "Smart home energy optimization system"
        ]
        
        for i, example in enumerate(examples):
            if st.button(f"πŸ’‘ {example}", key=f"example_{i}", help="Click to populate the startup idea field"):
                st.session_state.selected_example = example
                st.rerun()
    
    # Clear the selected example from session state after form renders
    if 'selected_example' in st.session_state and startup_idea:
        if startup_idea == st.session_state.selected_example:
            # Example has been loaded into the form, show success message
            st.success(f"βœ… Example loaded: {startup_idea[:50]}...")
        # Keep the example in session state until form is submitted
    
    # Process the form submission
    if submitted and startup_idea and model_id:
        # Clear the selected example when submitting
        if 'selected_example' in st.session_state:
            del st.session_state.selected_example
            
        st.markdown("---")
        st.markdown("## πŸ”„ Real-time Validation Progress")
        
        # Initialize progress tracker
        tracker = StreamlitProgressTracker()
        tracker.setup_ui()
        
        try:
            # Prepare the message
            message = "Please validate this startup idea with comprehensive market research and competitive analysis"
            
            # Run the workflow with real-time progress
            async def run_validation():
                return await startup_validation_workflow.arun(
                    message=message,
                    startup_idea=startup_idea,
                    model_id=model_id,  # Pass the selected model
                    progress_callback=tracker.update_progress  # Pass the real-time callback
                )
            
            # Execute the async workflow
            result = asyncio.run(run_validation())
            
            # Complete progress
            tracker.complete()
            
            # Display results with improved formatting
            st.markdown("---")
            st.markdown("## πŸ“Š Validation Results")
            
            # Extract clean content from WorkflowRunResponse
            validation_content = ""
            
            if hasattr(result, 'content') and result.content:
                validation_content = result.content
            elif hasattr(result, 'response') and result.response:
                validation_content = result.response
            else:
                validation_content = str(result)
            
            # Clean up content if needed
            if validation_content:
                validation_content = validation_content.replace('\\n', '\n')
                validation_content = validation_content.replace('\\"', '"')
            
            # Display in a formatted code block for consistent appearance
            st.code(validation_content, language="markdown")
            
            # Add download button for the report
            st.download_button(
                label="πŸ“₯ Download Report",
                data=validation_content,
                file_name=f"startup_validation_{startup_idea[:30].replace(' ', '_')}.md",
                mime="text/markdown"
            )
            
        except Exception as e:
            st.error(f"❌ An error occurred during validation: {str(e)}")
            st.error("Please check your environment variables and try again.")
            
            # Display error details in expander
            with st.expander("πŸ” Error Details"):
                st.code(str(e))
    
    elif submitted and not startup_idea:
        st.warning("⚠️ Please enter a startup idea before submitting.")
    
    # Footer
    st.markdown("---")
    st.markdown("""
    <div style='text-align: center; color: #666; font-size: 0.9rem;'>
        <p>πŸ”¬ Powered by AI agents and comprehensive market research</p>
        <p>⚠️ This validation is for informational purposes only. Conduct additional due diligence before making investment decisions.</p>
    </div>
    """, unsafe_allow_html=True)

if __name__ == "__main__":
    main()