Supervisor Team LangGraph
What it does
A supervisor agent owns the task and decides who works next: a researcher who searches the web, or a coder who reads and edits a repository. Each specialist does one turn and hands control back. The supervisor keeps routing until it judges the work finished, then assembles the final result from what the team produced. This is the canonical supervisor pattern and the starting point for most multi-agent systems — swap in your own specialists and it holds.
The cast · 4 agents
Read the relevant files and make the change the supervisor asked for, opening a pull request rather than committing directly. Append what you did to the scratchpad.
Assemble the final result the task asked for from the scratchpad. Be complete and drop the intermediate chatter.
Gather the specific information the supervisor asked for using web search. Report concise findings with sources and append them to the scratchpad.
Read the task and the scratchpad so far. Decide the next move: route to 'research' when information is missing, 'code' when the repo needs reading or editing, or set done when the task is complete. Return an object with 'next' and a 'done' boolean. Do not do the work yourself.
Flow
Interface
Depends on · 2 MCP servers
io.github.brave/brave-search-mcpnot in the registry yetsearch
io.github.github/github-mcpnot in the registry yetgh# Generated by @socketcat/compiler for target: langgraph
# blueprint: com.socketcat/supervisor-team v1.0.0 schema: socketcat.dev/blueprint/v0
# This code is yours. Edit it freely. The socketcat_runtime helper is optional and can be vendored.
from typing import TypedDict
from langgraph.graph import StateGraph, START, END
import socketcat_runtime as _rt
class State(TypedDict, total=False):
task: object
result: object
__loop_0: object
decision: object
__route_Route_4: object
scratchpad: object
def node_LoopHeader_0(state):
return {}
def node_LoopTick_1(state):
return {"__loop_0": state.get("__loop_0", 0) + 1}
def node_Nop_2(state):
return {}
def node_AgentInvoke_3(state):
return _rt.run_agent("supervisor", state, {"task":"task","decision":"decision","scratchpad":"scratchpad"}, "decision")
def node_Route_4(state):
return _rt.run_route("decision.next", state, "__route_Route_4")
def node_Join_5(state):
return {}
def node_AgentInvoke_6(state):
return _rt.run_agent("researcher", state, {"decision":"decision"}, "scratchpad")
def node_AgentInvoke_7(state):
return _rt.run_agent("coder", state, {"decision":"decision"}, "scratchpad")
def node_AgentInvoke_8(state):
return _rt.run_agent("assembler", state, {"task":"task","scratchpad":"scratchpad"}, "result")
def route_LoopHeader_0(state):
count = state.get("__loop_0", 0)
return "exit" if (_rt.cond("decision.done == true", state) or count >= 6) else "loop"
def route_Route_4(state):
lbl = state.get("__route_Route_4")
if lbl == "research": return "AgentInvoke_6"
if lbl == "code": return "AgentInvoke_7"
return "AgentInvoke_6"
def build():
b = StateGraph(State)
b.add_node("LoopHeader_0", node_LoopHeader_0)
b.add_node("LoopTick_1", node_LoopTick_1)
b.add_node("Nop_2", node_Nop_2)
b.add_node("AgentInvoke_3", node_AgentInvoke_3)
b.add_node("Route_4", node_Route_4)
b.add_node("Join_5", node_Join_5)
b.add_node("AgentInvoke_6", node_AgentInvoke_6)
b.add_node("AgentInvoke_7", node_AgentInvoke_7)
b.add_node("AgentInvoke_8", node_AgentInvoke_8)
b.add_edge(START, "AgentInvoke_3")
b.add_conditional_edges("LoopHeader_0", route_LoopHeader_0, {"loop": "AgentInvoke_3", "exit": "Nop_2"})
b.add_edge("LoopTick_1", "LoopHeader_0")
b.add_edge("Nop_2", "AgentInvoke_8")
b.add_edge("AgentInvoke_3", "Route_4")
b.add_conditional_edges("Route_4", route_Route_4, {"AgentInvoke_6": "AgentInvoke_6", "AgentInvoke_7": "AgentInvoke_7"})
b.add_edge("Join_5", "LoopTick_1")
b.add_edge("AgentInvoke_6", "Join_5")
b.add_edge("AgentInvoke_7", "Join_5")
b.add_edge("AgentInvoke_8", END)
return b.compile()
INPUTS = ["task"]
OUTPUTS = ["result"]
if __name__ == "__main__":
_rt.main(build, INPUTS, OUTPUTS)
▸blueprint.json (the portable format)
{
"id": "com.socketcat/supervisor-team",
"flow": {
"type": "sequence",
"blocks": [
{
"max": 6,
"type": "loop",
"until": "decision.done == true",
"blocks": [
{
"in": {
"task": "task",
"decision": "decision",
"scratchpad": "scratchpad"
},
"out": "decision",
"use": "supervisor",
"type": "agent"
},
{
"by": "decision.next",
"type": "route",
"cases": [
{
"label": "research",
"blocks": [
{
"in": {
"decision": "decision"
},
"out": "scratchpad",
"use": "researcher",
"type": "agent"
}
]
},
{
"label": "code",
"blocks": [
{
"in": {
"decision": "decision"
},
"out": "scratchpad",
"use": "coder",
"type": "agent"
}
]
}
]
}
]
},
{
"in": {
"task": "task",
"scratchpad": "scratchpad"
},
"out": "result",
"use": "assembler",
"type": "agent"
}
]
},
"tags": [
"multi-agent",
"routing",
"supervisor",
"orchestration"
],
"title": "Supervisor Team",
"agents": {
"coder": {
"model": {
"hint": "coding"
},
"title": "Coder",
"tools": [
"gh.get_file",
"gh.open_pr"
],
"instructions": "Read the relevant files and make the change the supervisor asked for, opening a pull request rather than committing directly. Append what you did to the scratchpad."
},
"assembler": {
"model": {
"hint": "fast"
},
"title": "Assembler",
"instructions": "Assemble the final result the task asked for from the scratchpad. Be complete and drop the intermediate chatter."
},
"researcher": {
"model": {
"hint": "fast"
},
"title": "Researcher",
"tools": [
"search.web"
],
"instructions": "Gather the specific information the supervisor asked for using web search. Report concise findings with sources and append them to the scratchpad."
},
"supervisor": {
"model": {
"hint": "reasoning"
},
"title": "Supervisor",
"output": {
"type": "object",
"required": [
"next",
"done"
],
"properties": {
"done": {
"type": "boolean"
},
"next": {
"type": "string"
}
}
},
"instructions": "Read the task and the scratchpad so far. Decide the next move: route to 'research' when information is missing, 'code' when the repo needs reading or editing, or set done when the task is complete. Return an object with 'next' and a 'done' boolean. Do not do the work yourself."
}
},
"estate": {
"decision": {
"type": "object",
"description": "The supervisor's routing decision, including 'next' and a 'done' flag."
},
"scratchpad": {
"type": "object",
"description": "The running record of what each specialist has produced."
}
},
"$schema": "socketcat.dev/blueprint/v0",
"authors": [
{
"url": "https://socketcat.com",
"name": "SocketCat"
}
],
"license": "MIT",
"servers": [
{
"ref": "io.github.brave/brave-search-mcp",
"alias": "search"
},
{
"ref": "io.github.github/github-mcp",
"alias": "gh"
}
],
"summary": "A supervisor routes each turn to a researcher or a coder and assembles the result when the work is done.",
"targets": [
"langgraph",
"*"
],
"version": "1.0.0",
"interface": {
"inputs": {
"task": {
"type": "string",
"description": "The task for the team."
}
},
"outputs": {
"result": {
"type": "string",
"description": "The assembled result."
}
}
},
"extensions": {
"dev.langgraph": {
"checkpointer": "memory"
}
},
"description": "A supervisor agent owns the task and decides who works next: a researcher who searches the web, or a coder who reads and edits a repository. Each specialist does one turn and hands control back. The supervisor keeps routing until it judges the work finished, then assembles the final result from what the team produced. This is the canonical supervisor pattern and the starting point for most multi-agent systems — swap in your own specialists and it holds."
}More in Core patterns
Browse all →Deep Research
Splits a hard question into sub-questions, researches them in parallel to keep the wall-clock low, then synthesizes one brief with citations.