Plan and Execute LangGraph
What it does
A planner decomposes the goal into ordered steps. An executor performs the next step using real tools and reports the result. A replanner revises the remaining plan in light of that result — removing finished steps, adding newly needed ones, or marking the goal complete — and the loop repeats. A finalizer assembles the outcome. This keeps an agent coherent over long tasks that a single prompt would lose track of. Wire the executor to whatever tools your task needs.
The cast · 4 agents
Break the goal into a short, ordered list of concrete steps. Each step should be something a single execution can complete. Do not execute anything.
Carry out the first unfinished step in the plan using the available tools. Report what you did and what you found. Do only that step.
Assemble the results of the completed steps into the final deliverable the goal asked for. Keep it clean and complete.
Given the plan and the latest result, revise the remaining steps: drop what's done, add what's newly needed, reorder if reality changed. Return an object with the updated steps and a 'done' boolean, set true only when the goal is fully met.
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 yetcode# Generated by @socketcat/compiler for target: langgraph
# blueprint: com.socketcat/plan-and-execute 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):
goal: object
result: object
plan: object
__loop_1: object
def node_AgentInvoke_0(state):
return _rt.run_agent("planner", state, {"goal":"goal"}, "plan")
def node_LoopHeader_1(state):
return {}
def node_LoopTick_2(state):
return {"__loop_1": state.get("__loop_1", 0) + 1}
def node_Nop_3(state):
return {}
def node_AgentInvoke_4(state):
return _rt.run_agent("executor", state, {"plan":"plan"}, "result")
def node_AgentInvoke_5(state):
return _rt.run_agent("replanner", state, {"plan":"plan","result":"result"}, "plan")
def node_AgentInvoke_6(state):
return _rt.run_agent("finalizer", state, {"goal":"goal","plan":"plan"}, "result")
def route_LoopHeader_1(state):
count = state.get("__loop_1", 0)
return "exit" if (_rt.cond("plan.done == true", state) or count >= 6) else "loop"
def build():
b = StateGraph(State)
b.add_node("AgentInvoke_0", node_AgentInvoke_0)
b.add_node("LoopHeader_1", node_LoopHeader_1)
b.add_node("LoopTick_2", node_LoopTick_2)
b.add_node("Nop_3", node_Nop_3)
b.add_node("AgentInvoke_4", node_AgentInvoke_4)
b.add_node("AgentInvoke_5", node_AgentInvoke_5)
b.add_node("AgentInvoke_6", node_AgentInvoke_6)
b.add_edge(START, "AgentInvoke_0")
b.add_edge("AgentInvoke_0", "AgentInvoke_4")
b.add_conditional_edges("LoopHeader_1", route_LoopHeader_1, {"loop": "AgentInvoke_4", "exit": "Nop_3"})
b.add_edge("LoopTick_2", "LoopHeader_1")
b.add_edge("Nop_3", "AgentInvoke_6")
b.add_edge("AgentInvoke_4", "AgentInvoke_5")
b.add_edge("AgentInvoke_5", "LoopTick_2")
b.add_edge("AgentInvoke_6", END)
return b.compile()
INPUTS = ["goal"]
OUTPUTS = ["result"]
if __name__ == "__main__":
_rt.main(build, INPUTS, OUTPUTS)
▸blueprint.json (the portable format)
{
"id": "com.socketcat/plan-and-execute",
"flow": {
"type": "sequence",
"blocks": [
{
"in": {
"goal": "goal"
},
"out": "plan",
"use": "planner",
"type": "agent"
},
{
"max": 6,
"type": "loop",
"until": "plan.done == true",
"blocks": [
{
"in": {
"plan": "plan"
},
"out": "result",
"use": "executor",
"type": "agent"
},
{
"in": {
"plan": "plan",
"result": "result"
},
"out": "plan",
"use": "replanner",
"type": "agent"
}
]
},
{
"in": {
"goal": "goal",
"plan": "plan"
},
"out": "result",
"use": "finalizer",
"type": "agent"
}
]
},
"tags": [
"planning",
"orchestration",
"long-horizon",
"plan-execute"
],
"title": "Plan and Execute",
"agents": {
"planner": {
"model": {
"hint": "reasoning"
},
"title": "Planner",
"instructions": "Break the goal into a short, ordered list of concrete steps. Each step should be something a single execution can complete. Do not execute anything."
},
"executor": {
"model": {
"hint": "coding"
},
"title": "Executor",
"tools": [
"search.web",
"code.get_file"
],
"instructions": "Carry out the first unfinished step in the plan using the available tools. Report what you did and what you found. Do only that step."
},
"finalizer": {
"model": {
"hint": "fast"
},
"title": "Finalizer",
"instructions": "Assemble the results of the completed steps into the final deliverable the goal asked for. Keep it clean and complete."
},
"replanner": {
"model": {
"hint": "reasoning"
},
"title": "Replanner",
"output": {
"type": "object",
"required": [
"done"
],
"properties": {
"done": {
"type": "boolean"
},
"steps": {
"type": "array"
}
}
},
"instructions": "Given the plan and the latest result, revise the remaining steps: drop what's done, add what's newly needed, reorder if reality changed. Return an object with the updated steps and a 'done' boolean, set true only when the goal is fully met."
}
},
"estate": {
"plan": {
"type": "object",
"description": "The current plan: remaining steps and a 'done' flag."
},
"result": {
"type": "object",
"description": "The executor's result from the most recent step."
}
},
"$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": "code"
}
],
"summary": "Plans a multi-step task, executes one step at a time, and replans from what actually happened until the goal is met.",
"targets": [
"langgraph",
"*"
],
"version": "1.0.0",
"interface": {
"inputs": {
"goal": {
"type": "string",
"description": "The multi-step goal to accomplish."
}
},
"outputs": {
"result": {
"type": "string",
"description": "The finished outcome once the plan is complete."
}
}
},
"extensions": {
"dev.langgraph": {
"checkpointer": "memory"
}
},
"description": "A planner decomposes the goal into ordered steps. An executor performs the next step using real tools and reports the result. A replanner revises the remaining plan in light of that result — removing finished steps, adding newly needed ones, or marking the goal complete — and the loop repeats. A finalizer assembles the outcome. This keeps an agent coherent over long tasks that a single prompt would lose track of. Wire the executor to whatever tools your task needs."
}More in Core patterns
Browse all →Supervisor Team
A supervisor decides who works next — a researcher who searches or a coder who edits the repo — and assembles the result when the work is done.