kaikaidai commited on
Commit
c287226
Β·
0 Parent(s):

Initial commit: Startup Idea Validator app (cleaned - removed sensitive files)

Browse files
Files changed (8) hide show
  1. .gitattributes +35 -0
  2. .gitignore +85 -0
  3. Dockerfile +21 -0
  4. README.md +65 -0
  5. blogpost.md +0 -0
  6. requirements.txt +38 -0
  7. src/streamlit_app.py +276 -0
  8. src/workflows_v2.py +461 -0
.gitattributes ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Environment variables and secrets
2
+ .env
3
+ .env.local
4
+ .env.development.local
5
+ .env.test.local
6
+ .env.production.local
7
+
8
+ # Python cache files
9
+ __pycache__/
10
+ *.py[cod]
11
+ *$py.class
12
+
13
+ # Distribution / packaging
14
+ .Python
15
+ build/
16
+ develop-eggs/
17
+ dist/
18
+ downloads/
19
+ eggs/
20
+ .eggs/
21
+ lib/
22
+ lib64/
23
+ parts/
24
+ sdist/
25
+ var/
26
+ wheels/
27
+ *.egg-info/
28
+ .installed.cfg
29
+ *.egg
30
+ MANIFEST
31
+
32
+ # PyInstaller
33
+ *.manifest
34
+ *.spec
35
+
36
+ # Installer logs
37
+ pip-log.txt
38
+ pip-delete-this-directory.txt
39
+
40
+ # Unit test / coverage reports
41
+ htmlcov/
42
+ .tox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ .hypothesis/
50
+ .pytest_cache/
51
+
52
+ # Virtual environments
53
+ .env
54
+ .venv
55
+ env/
56
+ venv/
57
+ ENV/
58
+ env.bak/
59
+ venv.bak/
60
+
61
+ # IDE files
62
+ .vscode/
63
+ .idea/
64
+ *.swp
65
+ *.swo
66
+ *~
67
+
68
+ # OS files
69
+ .DS_Store
70
+ .DS_Store?
71
+ ._*
72
+ .Spotlight-V100
73
+ .Trashes
74
+ ehthumbs.db
75
+ Thumbs.db
76
+
77
+ # Streamlit specific
78
+ .streamlit/
79
+
80
+ # Logs
81
+ *.log
82
+
83
+ # Temporary files
84
+ *.tmp
85
+ *.bak
Dockerfile ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10-slim
2
+
3
+ WORKDIR /app
4
+
5
+ RUN apt-get update && apt-get install -y \
6
+ build-essential \
7
+ curl \
8
+ software-properties-common \
9
+ git \
10
+ && rm -rf /var/lib/apt/lists/*
11
+
12
+ COPY requirements.txt ./
13
+ COPY src/ ./src/
14
+
15
+ RUN pip3 install -r requirements.txt
16
+
17
+ EXPOSE 8501
18
+
19
+ HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
20
+
21
+ ENTRYPOINT ["streamlit", "run", "src/streamlit_app.py", "--server.port=8501", "--server.address=0.0.0.0"]
README.md ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # πŸš€ Startup Idea Validator - Streamlit App
2
+
3
+ A comprehensive AI-powered tool for validating startup ideas with market research and competitive analysis.
4
+
5
+ ## Features
6
+
7
+ - **🎯 Idea Clarification**: AI assessment of originality, mission, and objectives
8
+ - **πŸ“Š Market Research**: TAM/SAM/SOM analysis and customer segmentation
9
+ - **🏒 Competitor Analysis**: SWOT analysis and positioning assessment
10
+ - **πŸ“‹ Validation Report**: Executive summary with strategic recommendations
11
+
12
+ ## Setup & Installation
13
+
14
+ 1. **Install Dependencies**:
15
+ ```bash
16
+ pip install -r requirements.txt
17
+ ```
18
+
19
+ 2. **Set Environment Variables**:
20
+ ```bash
21
+ export OPENAI_API_KEY="your-openai-api-key"
22
+ export ATLA_INSIGHTS_TOKEN="your-atla-insights-token"
23
+ export GOOGLE_API_KEY="your-google-api-key" # For search functionality
24
+ ```
25
+
26
+ 3. **Run the Streamlit App**:
27
+ ```bash
28
+ streamlit run streamlit_app.py
29
+ ```
30
+
31
+ 4. **Open Your Browser**:
32
+ The app will automatically open at `http://localhost:8501`
33
+
34
+ ## Usage
35
+
36
+ 1. **Enter Your Startup Idea**: Describe your startup idea in detail in the text area
37
+ 2. **Add Context** (Optional): Provide additional information about your target market or business model
38
+ 3. **Click "Validate My Idea"**: The AI agents will analyze your idea through multiple phases
39
+ 4. **Review Results**: Get a comprehensive validation report with recommendations
40
+ 5. **Download Report**: Save the validation report as a markdown file
41
+
42
+ ## Example Startup Ideas
43
+
44
+ - AI-powered personal finance coach for millennials
45
+ - Sustainable packaging solutions for e-commerce
46
+ - Virtual reality fitness platform for remote workers
47
+ - Marketplace for local artisan food products
48
+ - Smart home energy optimization system
49
+
50
+ ## Requirements
51
+
52
+ - Python 3.8+
53
+ - Valid OpenAI API key
54
+ - Atla Insights token (for monitoring)
55
+ - Google API key (for search functionality)
56
+
57
+ ## Troubleshooting
58
+
59
+ - **API Errors**: Ensure all environment variables are set correctly
60
+ - **Slow Performance**: The validation process typically takes 2-5 minutes
61
+ - **Connection Issues**: Check your internet connection and API limits
62
+
63
+ ## Note
64
+
65
+ This validation is for informational purposes only. Conduct additional due diligence before making investment decisions.
blogpost.md ADDED
File without changes
requirements.txt ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Core Framework
2
+ agno>=1.7.5
3
+ streamlit>=1.47.0
4
+
5
+ # AI/ML Libraries
6
+ openai>=1.97.1
7
+ anthropic>=0.58.2
8
+ groq>=0.30.0
9
+ google-generativeai>=0.8.5
10
+
11
+ # Search and Research Tools
12
+ google-search-results>=2.4.2
13
+ duckduckgo-search>=8.1.1
14
+ exa-py>=1.14.18
15
+ googlesearch-python>=1.3.0
16
+ pycountry>=24.6.1
17
+
18
+ # Monitoring and Observability
19
+ atla-insights[openai]>=0.0.11
20
+ atla-insights[agno]>=0.0.11
21
+
22
+ # Core Python Libraries
23
+ pydantic>=2.11.7
24
+ pydantic-settings>=2.10.1
25
+ python-dotenv>=1.1.1
26
+ httpx>=0.28.1
27
+ requests>=2.32.4
28
+
29
+ # Data and UI
30
+ pandas>=2.3.1
31
+ numpy>=1.24.0,<2.0.0
32
+ rich>=14.0.0
33
+
34
+ # Async Support
35
+ nest-asyncio>=1.6.0
36
+
37
+ # Database (if needed)
38
+ sqlalchemy>=2.0.41
src/streamlit_app.py ADDED
@@ -0,0 +1,276 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import asyncio
3
+ from workflows_v2 import startup_validation_workflow
4
+ import time
5
+
6
+ # Real-time progress tracking class
7
+ class StreamlitProgressTracker:
8
+ def __init__(self):
9
+ self.progress_container = None
10
+ self.status_text = None
11
+ self.progress_bar = None
12
+ self.log_container = None
13
+ self.current_phase = 0
14
+ self.total_phases = 4
15
+
16
+ def setup_ui(self):
17
+ self.progress_container = st.container()
18
+ with self.progress_container:
19
+ self.status_text = st.empty()
20
+ self.progress_bar = st.progress(0)
21
+ self.log_container = st.container()
22
+
23
+ def update_progress(self, message):
24
+ """Called by workflow for each progress update"""
25
+
26
+ # Track phases based on message content
27
+ if "PHASE 1:" in message:
28
+ self.current_phase = 1
29
+ elif "PHASE 2:" in message:
30
+ self.current_phase = 2
31
+ elif "PHASE 3:" in message:
32
+ self.current_phase = 3
33
+ elif "PHASE 4:" in message:
34
+ self.current_phase = 4
35
+
36
+ # Update progress bar
37
+ progress = (self.current_phase / self.total_phases) * 100
38
+ self.progress_bar.progress(int(progress))
39
+
40
+ # Update status
41
+ if "PHASE" in message and ":" in message:
42
+ self.status_text.info(f"πŸ”„ {message}")
43
+ elif "βœ…" in message:
44
+ self.status_text.success(f"{message}")
45
+ else:
46
+ self.status_text.info(f"πŸ”„ {message}")
47
+
48
+ # Add to log (skip the "=" separator lines)
49
+ if message and message.strip() and not all(c == '=' for c in message.strip()):
50
+ with self.log_container:
51
+ st.text(message)
52
+
53
+ def complete(self):
54
+ self.progress_bar.progress(100)
55
+ self.status_text.success("βœ… Validation completed!")
56
+
57
+ def main():
58
+ st.set_page_config(
59
+ page_title="Startup Idea Validator",
60
+ page_icon="πŸš€",
61
+ layout="wide",
62
+ initial_sidebar_state="expanded"
63
+ )
64
+
65
+ # Custom CSS for better styling
66
+ st.markdown("""
67
+ <style>
68
+ .main-header {
69
+ font-size: 3rem;
70
+ font-weight: bold;
71
+ text-align: center;
72
+ margin-bottom: 2rem;
73
+ background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
74
+ -webkit-background-clip: text;
75
+ -webkit-text-fill-color: transparent;
76
+ }
77
+ .stButton > button {
78
+ background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
79
+ color: white;
80
+ border: none;
81
+ padding: 0.5rem 2rem;
82
+ border-radius: 10px;
83
+ font-weight: bold;
84
+ }
85
+ .result-section {
86
+ background-color: #f8f9fa;
87
+ padding: 2rem;
88
+ border-radius: 15px;
89
+ border-left: 5px solid #667eea;
90
+ margin: 2rem 0;
91
+ }
92
+ .log-container {
93
+ background-color: #f1f3f4;
94
+ padding: 1rem;
95
+ border-radius: 8px;
96
+ font-family: monospace;
97
+ font-size: 0.9rem;
98
+ max-height: 300px;
99
+ overflow-y: auto;
100
+ border: 1px solid #ddd;
101
+ }
102
+ </style>
103
+ """, unsafe_allow_html=True)
104
+
105
+ # Header
106
+ st.markdown('<h1 class="main-header">πŸš€ Startup Idea Validator</h1>', unsafe_allow_html=True)
107
+
108
+ # Subtitle with demo and guide links
109
+ st.markdown("""
110
+ <div style='text-align: center; margin-bottom: 1rem; color: #666;'>
111
+ <p>πŸ” <a href="https://app.atla-ai.com/app/atla-demo-802mg?startDate=2025-07-25&endDate=2025-07-31" target="_blank">View your traces on Atla Insights</a> |
112
+ πŸ“š <a href="https://www.atla-ai.com/find-and-fix-ai-agent-failures" target="_blank">Understand the Insights platform</a></p>
113
+ <p style='font-size: 0.85rem; margin-top: 0.5rem;'>πŸ› οΈ <a href="https://docs.agno.com/introduction" target="_blank" style="color: #667eea; text-decoration: none;">Built with Agno</a></p>
114
+ </div>
115
+ """, unsafe_allow_html=True)
116
+
117
+ st.markdown("---")
118
+
119
+ # Sidebar with information
120
+ with st.sidebar:
121
+ st.markdown("## πŸ“‹ About This Tool")
122
+ st.markdown("""
123
+ This AI-powered tool validates your startup idea through:
124
+
125
+ 🎯 **Idea Clarification**
126
+ - Originality assessment
127
+ - Mission definition
128
+ - Objective setting
129
+
130
+ πŸ“Š **Market Research**
131
+ - TAM/SAM/SOM analysis
132
+ - Customer segmentation
133
+ - Market trends
134
+
135
+ 🏒 **Competitor Analysis**
136
+ - SWOT analysis
137
+ - Positioning assessment
138
+ - Market gaps
139
+
140
+ πŸ“‹ **Validation Report**
141
+ - Executive summary
142
+ - Strategic recommendations
143
+ - Next steps
144
+ """)
145
+
146
+ st.markdown("---")
147
+ st.markdown("πŸ’‘ **Tip:** Be as specific as possible about your startup idea for better results!")
148
+
149
+ # Main content area
150
+ col1, col2 = st.columns([2, 1])
151
+
152
+ with col1:
153
+ st.markdown("## πŸ’‘ Tell us about your startup idea")
154
+
155
+ # Input form
156
+ with st.form("startup_form", clear_on_submit=False):
157
+ # Get default value from session state if an example was selected
158
+ default_value = st.session_state.get('selected_example', '')
159
+
160
+ startup_idea = st.text_area(
161
+ "Describe your startup idea in detail:",
162
+ value=default_value,
163
+ height=150,
164
+ placeholder="e.g., A marketplace for Christmas Ornaments made from leather that connects artisans with customers looking for unique holiday decorations...",
165
+ help="The more detailed your description, the better the validation will be."
166
+ )
167
+
168
+ submitted = st.form_submit_button("πŸ” Validate My Idea", use_container_width=True)
169
+
170
+ with col2:
171
+ st.markdown("## 🎯 Quick Examples")
172
+ st.markdown("*Click any example to populate the idea field*")
173
+
174
+ examples = [
175
+ "AI-powered personal finance coach for millennials",
176
+ "Sustainable packaging solutions for e-commerce",
177
+ "Virtual reality fitness platform for remote workers",
178
+ "Marketplace for local artisan food products",
179
+ "Smart home energy optimization system"
180
+ ]
181
+
182
+ for i, example in enumerate(examples):
183
+ if st.button(f"πŸ’‘ {example}", key=f"example_{i}", help="Click to populate the startup idea field"):
184
+ st.session_state.selected_example = example
185
+ st.rerun()
186
+
187
+ # Clear the selected example from session state after form renders
188
+ if 'selected_example' in st.session_state and startup_idea:
189
+ if startup_idea == st.session_state.selected_example:
190
+ # Example has been loaded into the form, show success message
191
+ st.success(f"βœ… Example loaded: {startup_idea[:50]}...")
192
+ # Keep the example in session state until form is submitted
193
+
194
+ # Process the form submission
195
+ if submitted and startup_idea:
196
+ # Clear the selected example when submitting
197
+ if 'selected_example' in st.session_state:
198
+ del st.session_state.selected_example
199
+
200
+ st.markdown("---")
201
+ st.markdown("## πŸ”„ Real-time Validation Progress")
202
+
203
+ # Initialize progress tracker
204
+ tracker = StreamlitProgressTracker()
205
+ tracker.setup_ui()
206
+
207
+ try:
208
+ # Prepare the message
209
+ message = "Please validate this startup idea with comprehensive market research and competitive analysis"
210
+
211
+ # Run the workflow with real-time progress
212
+ async def run_validation():
213
+ return await startup_validation_workflow.arun(
214
+ message=message,
215
+ startup_idea=startup_idea,
216
+ progress_callback=tracker.update_progress # Pass the real-time callback
217
+ )
218
+
219
+ # Execute the async workflow
220
+ result = asyncio.run(run_validation())
221
+
222
+ # Complete progress
223
+ tracker.complete()
224
+
225
+ # Display results with improved formatting
226
+ st.markdown("---")
227
+ st.markdown("## πŸ“Š Validation Results")
228
+
229
+ # Extract clean content from WorkflowRunResponse
230
+ validation_content = ""
231
+
232
+ if hasattr(result, 'content') and result.content:
233
+ validation_content = result.content
234
+ elif hasattr(result, 'response') and result.response:
235
+ validation_content = result.response
236
+ else:
237
+ validation_content = str(result)
238
+
239
+ # Clean up content if needed
240
+ if validation_content:
241
+ validation_content = validation_content.replace('\\n', '\n')
242
+ validation_content = validation_content.replace('\\"', '"')
243
+
244
+ # Display in a formatted code block for consistent appearance
245
+ st.code(validation_content, language="markdown")
246
+
247
+ # Add download button for the report
248
+ st.download_button(
249
+ label="πŸ“₯ Download Report",
250
+ data=validation_content,
251
+ file_name=f"startup_validation_{startup_idea[:30].replace(' ', '_')}.md",
252
+ mime="text/markdown"
253
+ )
254
+
255
+ except Exception as e:
256
+ st.error(f"❌ An error occurred during validation: {str(e)}")
257
+ st.error("Please check your environment variables and try again.")
258
+
259
+ # Display error details in expander
260
+ with st.expander("πŸ” Error Details"):
261
+ st.code(str(e))
262
+
263
+ elif submitted and not startup_idea:
264
+ st.warning("⚠️ Please enter a startup idea before submitting.")
265
+
266
+ # Footer
267
+ st.markdown("---")
268
+ st.markdown("""
269
+ <div style='text-align: center; color: #666; font-size: 0.9rem;'>
270
+ <p>πŸ”¬ Powered by AI agents and comprehensive market research</p>
271
+ <p>⚠️ This validation is for informational purposes only. Conduct additional due diligence before making investment decisions.</p>
272
+ </div>
273
+ """, unsafe_allow_html=True)
274
+
275
+ if __name__ == "__main__":
276
+ main()
src/workflows_v2.py ADDED
@@ -0,0 +1,461 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ from typing import Any
3
+
4
+ from agno.agent import Agent
5
+ from agno.models.openai import OpenAIChat
6
+ from agno.tools.googlesearch import GoogleSearchTools
7
+ from agno.utils.pprint import pprint_run_response
8
+ from agno.workflow.v2.types import WorkflowExecutionInput
9
+ from agno.workflow.v2.workflow import Workflow
10
+ from pydantic import BaseModel, Field
11
+
12
+ from dotenv import load_dotenv
13
+ import os
14
+
15
+ script_dir = os.path.dirname(os.path.abspath(__file__))
16
+ env_path = os.path.join(script_dir, '.env')
17
+ load_dotenv(env_path)
18
+
19
+ # --- Atla Insights Configuration ---
20
+ from atla_insights import configure, instrument, instrument_agno, instrument_openai, mark_success, mark_failure, tool
21
+
22
+ # Define metadata for tracing
23
+ metadata = {
24
+ "model": "gpt-4o",
25
+ "prompt": "v1.1",
26
+ "environment": "prod",
27
+ "agent_name": "Startup Idea Validator"
28
+ }
29
+
30
+ # Configure Atla Insights with metadata - REQUIRED FIRST
31
+ configure(token=os.getenv("ATLA_INSIGHTS_TOKEN"), metadata=metadata)
32
+
33
+ # Instrument based on detected framework and LLM provider
34
+ instrument_agno("openai") # Agno framework with OpenAI
35
+ instrument_openai() # OpenAI LLM provider
36
+
37
+ # --- Response models ---
38
+ class IdeaClarification(BaseModel):
39
+ originality: str = Field(..., description="Originality of the idea.")
40
+ mission: str = Field(..., description="Mission of the company.")
41
+ objectives: str = Field(..., description="Objectives of the company.")
42
+
43
+
44
+ class MarketResearch(BaseModel):
45
+ total_addressable_market: str = Field(
46
+ ..., description="Total addressable market (TAM) with specific dollar amount."
47
+ )
48
+ total_addressable_market_calculation: str = Field(
49
+ ..., description="Step-by-step calculation methodology used to derive TAM."
50
+ )
51
+ total_addressable_market_sources: str = Field(
52
+ ..., description="Specific data sources and citations used for TAM calculation."
53
+ )
54
+ serviceable_available_market: str = Field(
55
+ ..., description="Serviceable available market (SAM) with specific dollar amount."
56
+ )
57
+ serviceable_available_market_calculation: str = Field(
58
+ ..., description="Step-by-step calculation methodology used to derive SAM from TAM."
59
+ )
60
+ serviceable_obtainable_market: str = Field(
61
+ ..., description="Serviceable obtainable market (SOM) with specific dollar amount."
62
+ )
63
+ serviceable_obtainable_market_calculation: str = Field(
64
+ ..., description="Step-by-step calculation methodology used to derive SOM from SAM."
65
+ )
66
+ market_size_validation: str = Field(
67
+ ..., description="Self-validation check: Does SOM < SAM < TAM? Are calculations logical and consistent?"
68
+ )
69
+ target_customer_segments: str = Field(..., description="Target customer segments with detailed demographics, needs, and market sizes.")
70
+ data_quality_assessment: str = Field(
71
+ ..., description="Assessment of the reliability and recency of the data sources used."
72
+ )
73
+
74
+
75
+ class CompetitorAnalysis(BaseModel):
76
+ competitors: str = Field(..., description="List of identified competitors.")
77
+ swot_analysis: str = Field(..., description="SWOT analysis for each competitor.")
78
+ positioning: str = Field(
79
+ ..., description="Startup's potential positioning relative to competitors."
80
+ )
81
+
82
+
83
+ class ValidationReport(BaseModel):
84
+ executive_summary: str = Field(
85
+ ..., description="Executive summary of the validation."
86
+ )
87
+ idea_assessment: str = Field(..., description="Assessment of the startup idea.")
88
+ market_opportunity: str = Field(..., description="Market opportunity analysis.")
89
+ competitive_landscape: str = Field(
90
+ ..., description="Competitive landscape overview."
91
+ )
92
+ recommendations: str = Field(..., description="Strategic recommendations.")
93
+ next_steps: str = Field(..., description="Recommended next steps.")
94
+
95
+
96
+ # --- Agents ---
97
+ idea_clarifier_agent = Agent(
98
+ name="Idea Clarifier",
99
+ model=OpenAIChat(id="gpt-4o"),
100
+ instructions=[
101
+ "Given a user's startup idea, your goal is to refine that idea.",
102
+ "Evaluate the originality of the idea by comparing it with existing concepts.",
103
+ "Define the mission and objectives of the startup.",
104
+ "Provide clear, actionable insights about the core business concept.",
105
+ ],
106
+ add_history_to_messages=True,
107
+ add_datetime_to_instructions=True,
108
+ response_model=IdeaClarification,
109
+ debug_mode=False,
110
+ )
111
+
112
+ market_research_agent = Agent(
113
+ name="Market Research Agent",
114
+ model=OpenAIChat(id="gpt-4o"),
115
+ tools=[GoogleSearchTools()],
116
+ instructions=[
117
+ "You are provided with a startup idea and the company's mission and objectives.",
118
+ "Estimate the total addressable market (TAM), serviceable available market (SAM), and serviceable obtainable market (SOM).",
119
+ "Define target customer segments and their characteristics.",
120
+ "Search the web for resources and data to support your analysis.",
121
+ "Provide specific market size estimates with supporting data sources.",
122
+ ],
123
+ add_history_to_messages=True,
124
+ add_datetime_to_instructions=True,
125
+ response_model=MarketResearch,
126
+ )
127
+
128
+ competitor_analysis_agent = Agent(
129
+ name="Competitor Analysis Agent",
130
+ model=OpenAIChat(id="gpt-4o"),
131
+ tools=[GoogleSearchTools()],
132
+ instructions=[
133
+ "You are provided with a startup idea and market research data.",
134
+ "Identify existing competitors in the market.",
135
+ "Perform Strengths, Weaknesses, Opportunities, and Threats (SWOT) analysis for each competitor.",
136
+ "Assess the startup's potential positioning relative to competitors.",
137
+ "Search for recent competitor information and market positioning.",
138
+ ],
139
+ add_history_to_messages=True,
140
+ add_datetime_to_instructions=True,
141
+ response_model=CompetitorAnalysis,
142
+ debug_mode=False,
143
+ )
144
+
145
+ report_agent = Agent(
146
+ name="Report Generator",
147
+ model=OpenAIChat(id="gpt-4o"),
148
+ instructions=[
149
+ "You are provided with comprehensive data about a startup idea including clarification, market research, and competitor analysis.",
150
+ "Synthesize all information into a comprehensive validation report.",
151
+ "Provide clear executive summary, assessment, and actionable recommendations.",
152
+ "Structure the report professionally with clear sections and insights.",
153
+ "Include specific next steps for the entrepreneur.",
154
+ ],
155
+ add_history_to_messages=True,
156
+ add_datetime_to_instructions=True,
157
+ response_model=ValidationReport,
158
+ debug_mode=False,
159
+ )
160
+
161
+
162
+ # --- Execution function ---
163
+ @instrument("Startup Idea Validation Workflow")
164
+ async def startup_validation_execution(
165
+ workflow: Workflow,
166
+ execution_input: WorkflowExecutionInput,
167
+ startup_idea: str,
168
+ progress_callback=None,
169
+ **kwargs: Any,
170
+ ) -> str:
171
+ """Execute the complete startup idea validation workflow"""
172
+
173
+ # Get inputs
174
+ message: str = execution_input.message
175
+ idea: str = startup_idea
176
+
177
+ if not idea:
178
+ mark_failure()
179
+ return "❌ No startup idea provided"
180
+
181
+ if progress_callback:
182
+ progress_callback(f"πŸš€ Starting startup idea validation for: {idea}")
183
+ progress_callback(f"πŸ’‘ Validation request: {message}")
184
+ else:
185
+ print(f"πŸš€ Starting startup idea validation for: {idea}")
186
+ print(f"πŸ’‘ Validation request: {message}")
187
+
188
+ # Phase 1: Idea Clarification
189
+ if progress_callback:
190
+ progress_callback(f"\n🎯 PHASE 1: IDEA CLARIFICATION & REFINEMENT")
191
+ progress_callback("=" * 60)
192
+ else:
193
+ print(f"\n🎯 PHASE 1: IDEA CLARIFICATION & REFINEMENT")
194
+ print("=" * 60)
195
+
196
+ clarification_prompt = f"""
197
+ {message}
198
+
199
+ Please analyze and refine the following startup idea:
200
+
201
+ STARTUP IDEA: {idea}
202
+
203
+ Evaluate:
204
+ 1. The originality of this idea compared to existing solutions
205
+ 2. Define a clear mission statement for this startup
206
+ 3. Outline specific, measurable objectives
207
+
208
+ Provide insights on how to strengthen and focus the core concept.
209
+ """
210
+
211
+ if progress_callback:
212
+ progress_callback(f"πŸ” Analyzing and refining the startup concept...")
213
+ else:
214
+ print(f"πŸ” Analyzing and refining the startup concept...")
215
+
216
+ try:
217
+ clarification_result = await idea_clarifier_agent.arun(clarification_prompt)
218
+ idea_clarification = clarification_result.content
219
+
220
+ if progress_callback:
221
+ progress_callback(f"βœ… Idea clarification completed")
222
+ progress_callback(f"πŸ“ Mission: {idea_clarification.mission[:100]}...")
223
+ else:
224
+ print(f"βœ… Idea clarification completed")
225
+ print(f"πŸ“ Mission: {idea_clarification.mission[:100]}...")
226
+
227
+ except Exception as e:
228
+ mark_failure()
229
+ return f"❌ Failed to clarify idea: {str(e)}"
230
+
231
+ # Phase 2: Market Research
232
+ if progress_callback:
233
+ progress_callback(f"\nπŸ“Š PHASE 2: MARKET RESEARCH & ANALYSIS")
234
+ progress_callback("=" * 60)
235
+ else:
236
+ print(f"\nπŸ“Š PHASE 2: MARKET RESEARCH & ANALYSIS")
237
+ print("=" * 60)
238
+
239
+ market_research_prompt = f"""
240
+ Based on the refined startup idea and clarification below, conduct comprehensive market research:
241
+
242
+ STARTUP IDEA: {idea}
243
+ ORIGINALITY: {idea_clarification.originality}
244
+ MISSION: {idea_clarification.mission}
245
+ OBJECTIVES: {idea_clarification.objectives}
246
+
247
+ Please research and provide:
248
+ 1. Total Addressable Market (TAM) - overall market size
249
+ 2. Serviceable Available Market (SAM) - portion you could serve
250
+ 3. Serviceable Obtainable Market (SOM) - realistic market share
251
+ 4. Target customer segments with detailed characteristics
252
+
253
+ Use web search to find current market data and trends.
254
+ """
255
+
256
+ if progress_callback:
257
+ progress_callback(f"πŸ“ˆ Researching market size and customer segments...")
258
+ else:
259
+ print(f"πŸ“ˆ Researching market size and customer segments...")
260
+
261
+ try:
262
+ market_result = await market_research_agent.arun(market_research_prompt)
263
+ market_research = market_result.content
264
+
265
+ if progress_callback:
266
+ progress_callback(f"βœ… Market research completed")
267
+ progress_callback(f"🎯 TAM: {market_research.total_addressable_market[:100]}...")
268
+ else:
269
+ print(f"βœ… Market research completed")
270
+ print(f"🎯 TAM: {market_research.total_addressable_market[:100]}...")
271
+
272
+ except Exception as e:
273
+ mark_failure()
274
+ return f"❌ Failed to complete market research: {str(e)}"
275
+
276
+ # Phase 3: Competitor Analysis
277
+ if progress_callback:
278
+ progress_callback(f"\n🏒 PHASE 3: COMPETITIVE LANDSCAPE ANALYSIS")
279
+ progress_callback("=" * 60)
280
+ else:
281
+ print(f"\n🏒 PHASE 3: COMPETITIVE LANDSCAPE ANALYSIS")
282
+ print("=" * 60)
283
+
284
+ competitor_prompt = f"""
285
+ Based on the startup idea and market research below, analyze the competitive landscape:
286
+
287
+ STARTUP IDEA: {idea}
288
+ TAM: {market_research.total_addressable_market}
289
+ SAM: {market_research.serviceable_available_market}
290
+ SOM: {market_research.serviceable_obtainable_market}
291
+ TARGET SEGMENTS: {market_research.target_customer_segments}
292
+
293
+ Please research and provide:
294
+ 1. Identify direct and indirect competitors
295
+ 2. SWOT analysis for each major competitor
296
+ 3. Assessment of startup's potential competitive positioning
297
+ 4. Market gaps and opportunities
298
+
299
+ Use web search to find current competitor information.
300
+ """
301
+
302
+ if progress_callback:
303
+ progress_callback(f"πŸ”Ž Analyzing competitive landscape...")
304
+ else:
305
+ print(f"πŸ”Ž Analyzing competitive landscape...")
306
+
307
+ try:
308
+ competitor_result = await competitor_analysis_agent.arun(competitor_prompt)
309
+ competitor_analysis = competitor_result.content
310
+
311
+ if progress_callback:
312
+ progress_callback(f"βœ… Competitor analysis completed")
313
+ progress_callback(f"πŸ† Positioning: {competitor_analysis.positioning[:100]}...")
314
+ else:
315
+ print(f"βœ… Competitor analysis completed")
316
+ print(f"πŸ† Positioning: {competitor_analysis.positioning[:100]}...")
317
+
318
+ except Exception as e:
319
+ mark_failure()
320
+ return f"❌ Failed to complete competitor analysis: {str(e)}"
321
+
322
+ # Phase 4: Final Validation Report
323
+ if progress_callback:
324
+ progress_callback(f"\nπŸ“‹ PHASE 4: COMPREHENSIVE VALIDATION REPORT")
325
+ progress_callback("=" * 60)
326
+ else:
327
+ print(f"\nπŸ“‹ PHASE 4: COMPREHENSIVE VALIDATION REPORT")
328
+ print("=" * 60)
329
+
330
+ report_prompt = f"""
331
+ Synthesize all the research and analysis into a comprehensive startup validation report:
332
+
333
+ STARTUP IDEA: {idea}
334
+
335
+ IDEA CLARIFICATION:
336
+ - Originality: {idea_clarification.originality}
337
+ - Mission: {idea_clarification.mission}
338
+ - Objectives: {idea_clarification.objectives}
339
+
340
+ MARKET RESEARCH:
341
+ - TAM: {market_research.total_addressable_market}
342
+ - SAM: {market_research.serviceable_available_market}
343
+ - SOM: {market_research.serviceable_obtainable_market}
344
+ - Target Segments: {market_research.target_customer_segments}
345
+
346
+ COMPETITOR ANALYSIS:
347
+ - Competitors: {competitor_analysis.competitors}
348
+ - SWOT: {competitor_analysis.swot_analysis}
349
+ - Positioning: {competitor_analysis.positioning}
350
+
351
+ Create a professional validation report with:
352
+ 1. Executive summary
353
+ 2. Idea assessment (strengths/weaknesses)
354
+ 3. Market opportunity analysis
355
+ 4. Competitive landscape overview
356
+ 5. Strategic recommendations
357
+ 6. Specific next steps for the entrepreneur
358
+ """
359
+
360
+ if progress_callback:
361
+ progress_callback(f"πŸ“ Generating comprehensive validation report...")
362
+ else:
363
+ print(f"πŸ“ Generating comprehensive validation report...")
364
+
365
+ try:
366
+ final_result = await report_agent.arun(report_prompt)
367
+ validation_report = final_result.content
368
+
369
+ if progress_callback:
370
+ progress_callback(f"βœ… Validation report completed")
371
+ else:
372
+ print(f"βœ… Validation report completed")
373
+
374
+ except Exception as e:
375
+ mark_failure()
376
+ return f"❌ Failed to generate final report: {str(e)}"
377
+
378
+ # Final summary
379
+ summary = f"""
380
+ πŸŽ‰ STARTUP IDEA VALIDATION COMPLETED!
381
+
382
+ πŸ“Š Validation Summary:
383
+ β€’ Startup Idea: {idea}
384
+ β€’ Idea Clarification: βœ… Completed
385
+ β€’ Market Research: βœ… Completed
386
+ β€’ Competitor Analysis: βœ… Completed
387
+ β€’ Final Report: βœ… Generated
388
+
389
+ πŸ“ˆ Key Market Insights:
390
+ β€’ TAM: {market_research.total_addressable_market[:150]}...
391
+ β€’ Target Segments: {market_research.target_customer_segments[:150]}...
392
+
393
+ πŸ† Competitive Positioning:
394
+ {competitor_analysis.positioning[:200]}...
395
+
396
+ πŸ“‹ COMPREHENSIVE VALIDATION REPORT:
397
+
398
+ ## Executive Summary
399
+ {validation_report.executive_summary}
400
+
401
+ ## Idea Assessment
402
+ {validation_report.idea_assessment}
403
+
404
+ ## Market Opportunity
405
+ {validation_report.market_opportunity}
406
+
407
+ ## Competitive Landscape
408
+ {validation_report.competitive_landscape}
409
+
410
+ ## Strategic Recommendations
411
+ {validation_report.recommendations}
412
+
413
+ ## Next Steps
414
+ {validation_report.next_steps}
415
+
416
+ ⚠️ Disclaimer: This validation is for informational purposes only. Conduct additional due diligence before making investment decisions.
417
+ """
418
+
419
+ # Mark successful completion
420
+ mark_success()
421
+ return summary
422
+
423
+
424
+ # --- Workflow definition ---
425
+ startup_validation_workflow = Workflow(
426
+ name="Startup Idea Validator",
427
+ description="Comprehensive startup idea validation with market research and competitive analysis",
428
+ steps=startup_validation_execution,
429
+ workflow_session_state={}, # Initialize empty workflow session state
430
+ )
431
+
432
+
433
+ if __name__ == "__main__":
434
+
435
+ async def main():
436
+ from rich.prompt import Prompt
437
+
438
+ # Get idea from user
439
+ idea = Prompt.ask(
440
+ "[bold]What is your startup idea?[/bold]\n✨",
441
+ default="A marketplace for Christmas Ornaments made from leather",
442
+ )
443
+
444
+ print("πŸ§ͺ Testing Startup Idea Validator with New Workflow Structure")
445
+ print("=" * 70)
446
+
447
+ try:
448
+ result = await startup_validation_workflow.arun(
449
+ message="Please validate this startup idea with comprehensive market research and competitive analysis",
450
+ startup_idea=idea,
451
+ )
452
+
453
+ pprint_run_response(result, markdown=True)
454
+ mark_success()
455
+
456
+ except Exception as e:
457
+ print(f"❌ Application failed: {str(e)}")
458
+ mark_failure()
459
+ raise
460
+
461
+ asyncio.run(main())