Spaces:
Running
Running
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() |