Spaces:
Sleeping
Sleeping
File size: 3,621 Bytes
65ade69 | 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 | from typing import TypedDict
from langgraph.graph import StateGraph, START, END
from pydantic import BaseModel, Field
from src.state import AgentState
from src.agents import competitor_agent, market_sizing_agent, sentiment_agent, os_risk_agent, get_llm
# --- Structured Output Schema ---
# We use Pydantic to tell the LLM exactly what JSON structure we want back.
class FinalReport(BaseModel):
score: int = Field(description="A confidence score from 0 to 100 based on the viability of the startup idea.")
verdict: str = Field(description="A categorical verdict: 'Go', 'Caution', or 'No-Go'.")
summary: str = Field(description="A brief 2-3 sentence summary explaining the final verdict and score.")
# --- The Scoring Engine (Node) ---
# This node runs AFTER all 4 parallel agents have finished.
def scoring_node(state: AgentState) -> dict:
idea = state["idea"]
results = state["results"]
print(f"\n[Scoring Engine] All 4 agents finished. Analyzing results for: {idea[:30]}...")
# Format the findings from all 4 agents into a readable string for the LLM
compiled_research = ""
for result in results:
compiled_research += f"\n### {result['agent'].replace('_', ' ').title()} ###\n"
compiled_research += f"{result['findings']}\n"
prompt = f"""You are a harsh but fair Y Combinator partner evaluating a startup idea.
Idea: '{idea}'
Here is the research from your 4 analysts:
{compiled_research}
Based on this research, provide a final evaluation.
- Score (0-100): How viable is this? (100 = Guaranteed unicorn, 0 = Terrible idea)
- Verdict: 'Go', 'Caution', or 'No-Go'
- Summary: Justify your decision in 2-3 sentences based on the research.
"""
llm = get_llm()
# We use `.with_structured_output` to force the LLM to return a JSON object matching our Pydantic schema
structured_llm = llm.with_structured_output(FinalReport)
response = structured_llm.invoke([{"role": "user", "content": prompt}])
# Return the updates to the state. We are updating the 3 final fields.
return {
"score": response.score,
"verdict": response.verdict,
"summary": response.summary
}
# --- Construct the Graph ---
def build_graph():
# 1. Initialize the graph with our state schema
workflow = StateGraph(AgentState)
# 2. Add all the nodes (functions)
workflow.add_node("competitor_agent", competitor_agent)
workflow.add_node("market_sizing_agent", market_sizing_agent)
workflow.add_node("sentiment_agent", sentiment_agent)
workflow.add_node("os_risk_agent", os_risk_agent)
workflow.add_node("scoring_node", scoring_node)
# 3. Define the routing (Edges)
# Fan-out: START branches to all 4 research agents simultaneously
workflow.add_edge(START, "competitor_agent")
workflow.add_edge(START, "market_sizing_agent")
workflow.add_edge(START, "sentiment_agent")
workflow.add_edge(START, "os_risk_agent")
# Fan-in: All 4 agents must finish and point to the scoring node
# LangGraph automatically waits for all incoming edges to a node to complete
workflow.add_edge("competitor_agent", "scoring_node")
workflow.add_edge("market_sizing_agent", "scoring_node")
workflow.add_edge("sentiment_agent", "scoring_node")
workflow.add_edge("os_risk_agent", "scoring_node")
# Finish the graph
workflow.add_edge("scoring_node", END)
# Compile the graph into an executable format
return workflow.compile()
# Export the compiled graph
app = build_graph()
|