File size: 6,387 Bytes
852ea09
 
e32fa28
 
 
 
 
 
 
 
852ea09
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e32fa28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
852ea09
 
 
 
e32fa28
 
 
 
852ea09
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import asyncio
import os
import sys

# Add current directory to path and import prompts
current_dir = os.path.dirname(__file__)
if current_dir not in sys.path:
    sys.path.insert(0, current_dir)

import prompts
from IPython.display import display, Markdown
from dotenv import load_dotenv
from pydantic import BaseModel, Field
from google.adk.agents.llm_agent import LlmAgent
from google.adk.agents.sequential_agent import SequentialAgent
from google.adk.models.lite_llm import LiteLlm
from google.adk.sessions import InMemorySessionService
from google.adk.runners import Runner
from google.genai import types
from google.adk.tools.langchain_tool import LangchainTool
from langchain_tavily import TavilySearch

load_dotenv()

APP_NAME = "startup_validator"
USER_ID = "arindam_1729"
SESSION_ID = "startup_validation_session"


async def run_validation(idea: str, nebius_api_key: str, tavily_api_key: str):
    if not nebius_api_key:
        raise ValueError("Missing Nebius API key")
    if not tavily_api_key:
        raise ValueError("Missing Tavily API key")

    # Build model and tools using provided API keys
    nebius_llm = LiteLlm(
        model="nebius/Qwen/Qwen3-235B-A22B-Instruct-2507", api_key=nebius_api_key
    )

    tavily_tool_instance = TavilySearch(
        max_results=3,
        search_depth="basic",
        include_answer=True,
        include_raw_content=False,
        include_images=False,
        tavily_api_key=tavily_api_key,
    )
    tavily_search = LangchainTool(tool=tavily_tool_instance)

    # Define agents
    idea_clarifier_agent = LlmAgent(
        name="IdeaClarifierAgent",
        model=nebius_llm,
        instruction=prompts.IDEA_PROMPT,
        description="Helps clarify and refine the startup idea.",
        output_key="clarified_idea",
    )

    market_research_agent = LlmAgent(
        name="MarketResearchAgent",
        model=nebius_llm,
        instruction=prompts.MARKET_RESEARCH_PROMPT,
        description="Conducts market research for the startup idea.",
        tools=[tavily_search],
        output_key="market_research",
    )

    competitor_analysis_agent = LlmAgent(
        name="CompetitorAnalysisAgent",
        model=nebius_llm,
        instruction=prompts.COMPETITOR_ANALYSIS_PROMPT,
        description="Conducts competitor analysis for the startup idea.",
        tools=[tavily_search],
        output_key="competitor_analysis",
    )

    report_agent = LlmAgent(
        name="ReportAgent",
        model=nebius_llm,
        instruction=prompts.REPORT_PROMPT,
        description="Generates a report based on the analysis findings.",
        output_key="validation_report",
    )

    startup_validation_agent = SequentialAgent(
        name="StartupValidationAgent",
        sub_agents=[
            idea_clarifier_agent,
            market_research_agent,
            competitor_analysis_agent,
            report_agent,
        ],
        description="Validates startup ideas through a structured analysis process.",
    )

    initial_state = {"idea": idea}
    session_service = InMemorySessionService()
    await session_service.create_session(
        app_name=APP_NAME, user_id=USER_ID, session_id=SESSION_ID, state=initial_state
    )

    runner = Runner(
        agent=startup_validation_agent,
        app_name=APP_NAME,
        session_service=session_service,
    )

    content = types.Content(role="user", parts=[types.Part(text=idea)])
    
    # Handle the runner.run() method properly
    run_result = runner.run(user_id=USER_ID, session_id=SESSION_ID, new_message=content)
    
    # Check if it's a generator and consume it
    if hasattr(run_result, '__aiter__'):
        # It's an async generator, consume it
        async for _ in run_result:
            pass  # Just consume the generator
    elif hasattr(run_result, '__await__'):
        # It's a coroutine, await it normally
        await run_result
    else:
        # It's a regular generator, consume it
        try:
            while True:
                next(run_result)
        except StopIteration:
            pass

    session = await session_service.get_session(
        app_name=APP_NAME, user_id=USER_ID, session_id=SESSION_ID
    )
    
    # Debug: Print session state for troubleshooting
    print(f"Session state keys: {list(session.state.keys())}")
    print(f"Session state: {session.state}")

    import ast

    def safe_parse(val):
        if isinstance(val, dict):
            return val
        try:
            return ast.literal_eval(val)
        except Exception:
            return {}

    market_research = safe_parse(session.state.get("market_research", {}))
    competitor_analysis = safe_parse(session.state.get("competitor_analysis", {}))
    validation_report = safe_parse(session.state.get("validation_report", {}))

    summary = f"""
πŸŽ‰ **STARTUP IDEA VALIDATION COMPLETED!**

## πŸ“Š Validation Summary

- **Startup Idea:** {idea}
- **Idea Clarification:** βœ… Completed
- **Market Research:** βœ… Completed
- **Competitor Analysis:** βœ… Completed
- **Final Report:** βœ… Generated

## πŸ“ˆ Key Market Insights

### **TAM:** 
{market_research.get("total_addressable_market", "")}
### **Target Segments:** 
{market_research.get("target_customer_segments", "")}
### **SOM:** 
{market_research.get("serviceable_obtainable_market", "")}
### **SAM:** 
{market_research.get("serviceable_available_market", "")}

## πŸ† Competitive Positioning

{competitor_analysis.get("competitors", "")}

{competitor_analysis.get("swot_analysis", "")}

{competitor_analysis.get("positioning", "")}

---

## πŸ“‹ Comprehensive Validation Report

{validation_report.get("executive_summary", "")}

{validation_report.get("idea_assessment", "")}

{validation_report.get("market_opportunity", "")}

{validation_report.get("competitive_landscape", "")}

{validation_report.get("recommendations", "")}

{validation_report.get("next_steps", "")}

---

> ⚠️ *Disclaimer: This validation is for informational purposes only. Conduct additional due diligence before making investment decisions.*

"""

    return summary


if __name__ == "__main__":
    nebius_key = os.getenv("NEBIUS_API_KEY", "")
    tavily_key = os.getenv("TAVILY_API_KEY", "")
    asyncio.run(
        run_validation(
            "A CodeReview Agent that reviews your code in each PR",
            nebius_key,
            tavily_key,
        )
    )