Skip to main content

Edges

Edges connect nodes and determine the execution order.

Static edge

A static edge always routes from src to dst.

from synapsekit import StateGraph

graph = StateGraph()
graph.add_edge("node_a", "node_b")

Terminating with END

Use the END sentinel to indicate the graph should stop after a node.

from synapsekit import StateGraph, END

graph.add_edge("last_node", END)

# Shorthand:
graph.set_finish_point("last_node")

Conditional edge

A conditional edge calls a function at runtime to decide the next node.

from synapsekit import StateGraph, END

def route(state: dict) -> str:
if state["confidence"] >= 0.9:
return "publish"
return "review"

graph = StateGraph()
graph.add_conditional_edge(
"classify", # source node
route, # condition function
{ # mapping: return value → next node
"publish": "publish_node",
"review": "review_node",
},
)

Async condition function

async def async_route(state: dict) -> str:
score = await score_api(state["text"])
return "high" if score > 0.8 else "low"

graph.add_conditional_edge("scorer", async_route, {"high": "fast_path", "low": "slow_path"})

Routing to END from a condition

graph.add_conditional_edge(
"check",
lambda state: "done" if state["complete"] else "retry",
{"done": END, "retry": "process_node"},
)

Unknown mapping key

If the condition function returns a key not in mapping, the destination defaults to END (the graph stops). Handle unexpected keys explicitly in your mapping to avoid silent termination.

Multiple outgoing edges (fan-out)

A node can have multiple outgoing static edges. All destination nodes are added to the next wave and run in parallel.

graph.add_edge("start", "branch_a")
graph.add_edge("start", "branch_b")
# branch_a and branch_b execute concurrently after start

Cycle detection

Cycles in static edges are detected at compile() and raise GraphConfigError. Conditional edges are not checked for cycles — use the built-in _MAX_STEPS = 100 guard to prevent infinite runtime loops.