Documentation Index
Fetch the complete documentation index at: https://mintlify.com/vrashmanyu605-eng/Agentic_Sales-Markerting/llms.txt
Use this file to discover all available pages before exploring further.
graph/workflow.py is the single source of truth for how agents connect. It registers all nodes, sets the entry point, defines static edges for the sequential pipeline, and adds a conditional edge from the supervisor that either starts the next lead’s pipeline or terminates the graph. Understanding this file tells you exactly what runs, in what order, and when the workflow stops.
Full source
graph/workflow.py
Graph initialization
StateGraph takes a typed state class as its schema. Every node in the graph receives the full SalesMarketingState dict as input and returns a (partial or full) dict that LangGraph merges back into the shared state. No node receives a separate input object — all context flows through state.
Node registration
All ten agents are registered withgraph.add_node. The string name used here is what the router returns to select the next node, and what appears in app.stream() event keys.
| Node name | Agent function |
|---|---|
"discovery_agent" | discovery_agent |
"supervisor" | supervisor_agent |
"lead_research_agent" | lead_research_agent |
"icp_matching_agent" | icp_matching_agent |
"competitor_analysis_agent" | competitor_analysis_agent |
"outreach_generation_agent" | outreach_generation_agent |
"proposal_generation_agent" | proposal_generation_agent |
"sales_strategy_agent" | sales_strategy_agent |
"marketing_content_agent" | marketing_content_agent |
"client_sentiment_agent" | client_sentiment_agent |
"crm_update_agent" | crm_update_agent |
sales_strategy_agent, marketing_content_agent, and client_sentiment_agent are registered but not connected by edges in the current pipeline. You can wire them in by adding add_edge calls.
Entry point
discovery_agent is always the first node to execute. It receives the full initial_state from main.py, searches for leads, and populates pending_leads. The next static edge sends it directly to the supervisor.
Static edge: discovery to supervisor
Conditional edge: supervisor router
supervisor_router function is the only point of dynamic routing in the graph. It reads state["next_agent"], which supervisor_agent sets based on whether pending_leads is empty:
"lead_research_agent"— a lead is available; start its pipeline"finished"— no leads remain; terminate the graph viaEND
add_conditional_edges constrains the router to exactly these two outcomes. Returning any other string raises a LangGraph error.
The supervisor terminates the workflow by returning
next_agent: "finished" when pending_leads is empty. The supervisor_router maps "finished" to LangGraph’s built-in END sentinel, which stops graph execution cleanly. You do not need to handle termination yourself.Deterministic sequential pipeline
add_edge calls define the per-lead pipeline. Every agent runs in this fixed order; there is no branching or skipping. The final edge returns control to the supervisor, closing the loop.
The loop works as follows:
- Supervisor pops lead #1, sets
next_agent: "lead_research_agent" - Pipeline runs: lead research → ICP matching → competitor analysis → outreach → proposal → CRM update
crm_update_agentfinishes; the edge sends execution back to the supervisor- Supervisor pops lead #2 (or sets
next_agent: "finished"if the queue is empty) - Repeat until the queue is drained
Compiled app and streaming
graph.compile() validates all edges and produces an executable app. In main.py, you run the graph with:
main.py
app.stream() yields one event dict per node execution. Each dict has a single key — the node name — mapped to the state snapshot after that node ran. This lets you inspect intermediate outputs without waiting for the full workflow to complete.
Learn more
State reference
All fields in SalesMarketingState — what each agent reads and writes
Architecture overview
Three-layer design and the full pipeline execution sequence