diff --git a/docs/docs/cloud/deployment/cloud.md b/docs/docs/cloud/deployment/cloud.md
index c53d516a6..638d095ba 100644
--- a/docs/docs/cloud/deployment/cloud.md
+++ b/docs/docs/cloud/deployment/cloud.md
@@ -1,4 +1,4 @@
-# How to Deploy to Cloud SaaS
+# How to Deploy to Cloud SaaS (Beta)
Before deploying, review the [conceptual guide for the Cloud SaaS](../../concepts/langgraph_cloud.md) deployment option.
diff --git a/docs/docs/cloud/deployment/self_hosted_control_plane.md b/docs/docs/cloud/deployment/self_hosted_control_plane.md
index f72de8bd2..c9e8265c1 100644
--- a/docs/docs/cloud/deployment/self_hosted_control_plane.md
+++ b/docs/docs/cloud/deployment/self_hosted_control_plane.md
@@ -1,4 +1,4 @@
-# How to Deploy Self-Hosted Control Plane
+# How to Deploy Self-Hosted Control Plane (Beta)
Before deploying, review the [conceptual guide for the Self-Hosted Control Plane](../../concepts/langgraph_self_hosted_control_plane.md) deployment option.
diff --git a/docs/docs/cloud/deployment/self_hosted_data_plane.md b/docs/docs/cloud/deployment/self_hosted_data_plane.md
index 652842e49..c9512eb10 100644
--- a/docs/docs/cloud/deployment/self_hosted_data_plane.md
+++ b/docs/docs/cloud/deployment/self_hosted_data_plane.md
@@ -1,4 +1,4 @@
-# How to Deploy Self-Hosted Data Plane
+# How to Deploy Self-Hosted Data Plane (Beta)
Before deploying, review the [conceptual guide for the Self-Hosted Data Plane](../../concepts/langgraph_self_hosted_data_plane.md) deployment option.
diff --git a/docs/docs/concepts/deployment_options.md b/docs/docs/concepts/deployment_options.md
index f5af7f3ff..554c0d87c 100644
--- a/docs/docs/concepts/deployment_options.md
+++ b/docs/docs/concepts/deployment_options.md
@@ -10,11 +10,11 @@
There are 4 main options for deploying with the LangGraph Platform:
-1. **[Cloud SaaS](#cloud-saas)**: Available for **Plus** and **Enterprise** plans.
+1. **Cloud SaaS(Beta)**: Available for **Plus** and **Enterprise** plans.
-1. **[Self-Hosted Data Plane](#self-hosted-data-plane)**: Available for the **Enterprise** plan.
+1. **Self-Hosted Data Plane(Beta)**: Available for the **Enterprise** plan.
-1. **[Self-Hosted Control Plane](#self-hosted-control-plane)**: Available for the **Enterprise** plan.
+1. **Self-Hosted Control Plane(Beta)**: Available for the **Enterprise** plan.
1. **[Standalone Container](#standalone-container)**: Available for all plans.
diff --git a/docs/docs/concepts/langgraph_cloud.md b/docs/docs/concepts/langgraph_cloud.md
index 557b39e60..1e083dca8 100644
--- a/docs/docs/concepts/langgraph_cloud.md
+++ b/docs/docs/concepts/langgraph_cloud.md
@@ -1,4 +1,4 @@
-# Cloud SaaS
+# Cloud SaaS (Beta)
To deploy a [LangGraph Server](../concepts/langgraph_server.md), follow the how-to guide for [how to deploy to Cloud SaaS](../cloud/deployment/cloud.md).
diff --git a/docs/docs/concepts/langgraph_platform.md b/docs/docs/concepts/langgraph_platform.md
index bde8917d7..77d3f7c06 100644
--- a/docs/docs/concepts/langgraph_platform.md
+++ b/docs/docs/concepts/langgraph_platform.md
@@ -5,6 +5,10 @@ search:
# LangGraph Platform
+Watch this 4-minute overview of LangGraph Platform to see how it helps you build, deploy, and evaluate agentic applications.
+
+
+
## Overview
LangGraph Platform is a commercial solution for deploying agentic applications to production, built on the open-source [LangGraph framework](./high_level.md).
diff --git a/docs/docs/concepts/langgraph_self_hosted_control_plane.md b/docs/docs/concepts/langgraph_self_hosted_control_plane.md
index 9ab2c2549..718556dc7 100644
--- a/docs/docs/concepts/langgraph_self_hosted_control_plane.md
+++ b/docs/docs/concepts/langgraph_self_hosted_control_plane.md
@@ -1,4 +1,4 @@
-# Self-Hosted Control Plane
+# Self-Hosted Control Plane (Beta)
To deploy a [LangGraph Server](../concepts/langgraph_server.md), follow the how-to guide for [how to deploy the Self-Hosted Control Plane](../cloud/deployment/self_hosted_control_plane.md).
diff --git a/docs/docs/concepts/langgraph_self_hosted_data_plane.md b/docs/docs/concepts/langgraph_self_hosted_data_plane.md
index bc4c65c0c..51f0114e1 100644
--- a/docs/docs/concepts/langgraph_self_hosted_data_plane.md
+++ b/docs/docs/concepts/langgraph_self_hosted_data_plane.md
@@ -1,4 +1,4 @@
-# Self-Hosted Data Plane
+# Self-Hosted Data Plane (Beta)
To deploy a [LangGraph Server](../concepts/langgraph_server.md), follow the how-to guide for [how to deploy the Self-Hosted Data Plane](../cloud/deployment/self_hosted_data_plane.md).
diff --git a/docs/docs/tutorials/deployment.md b/docs/docs/tutorials/deployment.md
index 021d52aad..d2c7567e7 100644
--- a/docs/docs/tutorials/deployment.md
+++ b/docs/docs/tutorials/deployment.md
@@ -17,9 +17,9 @@ Get started deploying your LangGraph applications locally or on the cloud with
## Deployment Options
-- [Cloud SaaS](../concepts/langgraph_cloud.md): Connect to your GitHub repositories and deploy LangGraph Servers to LangChain's cloud. We manage everything.
-- [Self-Hosted Data Plane](../concepts/langgraph_self_hosted_data_plane.md): Create deployments from the [Control Plane UI](../concepts/langgraph_control_plane.md#control-plane-ui) and deploy LangGraph Servers to your cloud. We manage the [control plane](../concepts/langgraph_control_plane.md), you manage the deployments.
-- [Self-Hosted Control Plane](../concepts/langgraph_self_hosted_control_plane.md#control-plane-ui): Create deployments from a self-hosted [Control Plane UI](../concepts/langgraph_control_plane.md) and deploy LangGraph Servers to your cloud. You manage everything.
+- Cloud SaaS(Beta): Connect to your GitHub repositories and deploy LangGraph Servers to LangChain's cloud. We manage everything.
+- Self-Hosted Data Plane(Beta): Create deployments from the [Control Plane UI](../concepts/langgraph_control_plane.md#control-plane-ui) and deploy LangGraph Servers to your cloud. We manage the [control plane](../concepts/langgraph_control_plane.md), you manage the deployments.
+- Self-Hosted Control Plane(Beta): Create deployments from a self-hosted [Control Plane UI](../concepts/langgraph_control_plane.md#control-plane-ui) and deploy LangGraph Servers to your cloud. You manage everything.
- [Standalone Container](../concepts/langgraph_standalone_container.md): Deploy LangGraph Server Docker images however you like.
A quick comparison...
diff --git a/libs/langgraph/langgraph/graph/state.py b/libs/langgraph/langgraph/graph/state.py
index ce2f898d0..2316fc004 100644
--- a/libs/langgraph/langgraph/graph/state.py
+++ b/libs/langgraph/langgraph/graph/state.py
@@ -44,6 +44,7 @@ from langgraph.constants import (
NS_END,
NS_SEP,
TAG_HIDDEN,
+ TASKS,
)
from langgraph.errors import (
ErrorCode,
@@ -78,7 +79,7 @@ from langgraph.store.base import BaseStore
from langgraph.types import All, Checkpointer, Command, RetryPolicy
from langgraph.utils.fields import get_field_default
from langgraph.utils.pydantic import create_model
-from langgraph.utils.runnable import RunnableCallable, RunnableLike, coerce_to_runnable
+from langgraph.utils.runnable import RunnableLike, coerce_to_runnable
logger = logging.getLogger(__name__)
@@ -670,10 +671,6 @@ class StateGraph(Graph):
for key, node in self.nodes.items():
compiled.attach_node(key, node)
- compiled.nodes[START].writers.append(CONTROL_BRANCH_PATH)
- for key in self.nodes:
- compiled.nodes[key].writers.append(CONTROL_BRANCH_PATH)
-
for start, end in self.edges:
compiled.attach_edge(start, end)
@@ -802,6 +799,7 @@ class CompiledStateGraph(CompiledGraph):
ChannelWriteTupleEntry(
mapper=_get_root if output_keys == ["__root__"] else _get_updates
),
+ ChannelWriteTupleEntry(mapper=_control_branch),
)
# add node and output channel
@@ -936,7 +934,7 @@ class CompiledStateGraph(CompiledGraph):
if end != END:
self.nodes[end].writers.append(
ChannelWrite(
- [ChannelWriteEntry(channel_name, end)], tags=[TAG_HIDDEN]
+ (ChannelWriteEntry(channel_name, end),), tags=[TAG_HIDDEN]
)
)
@@ -1062,10 +1060,9 @@ def _coerce_state(schema: Type[Any], input: dict[str, Any]) -> dict[str, Any]:
return schema(**input)
-def _control_branch(value: Any, config: RunnableConfig) -> Any:
+def _control_branch(value: Any) -> Sequence[tuple[str, Any]]:
if isinstance(value, Send):
- ChannelWrite.do_write(config, (value,))
- return value
+ return ((TASKS, value),)
commands: list[Command] = []
if isinstance(value, Command):
commands.append(value)
@@ -1073,66 +1070,22 @@ def _control_branch(value: Any, config: RunnableConfig) -> Any:
for cmd in value:
if isinstance(cmd, Command):
commands.append(cmd)
- rtn: list[Union[ChannelWriteEntry, Send]] = []
+ rtn: list[tuple[str, Any]] = []
for command in commands:
if command.graph == Command.PARENT:
raise ParentCommand(command)
if isinstance(command.goto, Send):
- rtn.append(command.goto)
+ rtn.append((TASKS, command.goto))
elif isinstance(command.goto, str):
- rtn.append(ChannelWriteEntry(CHANNEL_BRANCH_TO.format(command.goto), None))
+ rtn.append((CHANNEL_BRANCH_TO.format(command.goto), None))
else:
rtn.extend(
- go
+ (TASKS, go)
if isinstance(go, Send)
- else ChannelWriteEntry(CHANNEL_BRANCH_TO.format(go), None)
+ else (CHANNEL_BRANCH_TO.format(go), None)
for go in command.goto
)
- if rtn:
- ChannelWrite.do_write(config, rtn)
- return value
-
-
-async def _acontrol_branch(value: Any, config: RunnableConfig) -> Any:
- if isinstance(value, Send):
- ChannelWrite.do_write(config, (value,))
- return value
- commands: list[Command] = []
- if isinstance(value, Command):
- commands.append(value)
- elif isinstance(value, (list, tuple)):
- for cmd in value:
- if isinstance(cmd, Command):
- commands.append(cmd)
- rtn: list[Union[ChannelWriteEntry, Send]] = []
- for command in commands:
- if command.graph == Command.PARENT:
- raise ParentCommand(command)
- if isinstance(command.goto, Send):
- rtn.append(command.goto)
- elif isinstance(command.goto, str):
- rtn.append(ChannelWriteEntry(CHANNEL_BRANCH_TO.format(command.goto), None))
- else:
- rtn.extend(
- go
- if isinstance(go, Send)
- else ChannelWriteEntry(CHANNEL_BRANCH_TO.format(go), None)
- for go in command.goto
- )
- if rtn:
- ChannelWrite.do_write(config, rtn)
- return value
-
-
-CONTROL_BRANCH_PATH = RunnableCallable(
- _control_branch,
- _acontrol_branch,
- tags=[TAG_HIDDEN],
- trace=False,
- recurse=False,
- set_context=False,
- func_accepts_config=True,
-)
+ return rtn
def _get_root(input: Any) -> Optional[Sequence[tuple[str, Any]]]:
diff --git a/libs/langgraph/tests/test_large_cases.py b/libs/langgraph/tests/test_large_cases.py
index f5be91cee..bb8e124ff 100644
--- a/libs/langgraph/tests/test_large_cases.py
+++ b/libs/langgraph/tests/test_large_cases.py
@@ -4660,7 +4660,7 @@ def test_root_graph(
content="result for query",
name="search_api",
tool_call_id="tool_call123",
- id="00000000-0000-4000-8000-000000000040",
+ id="00000000-0000-4000-8000-000000000033",
)
]
},
@@ -4683,7 +4683,7 @@ def test_root_graph(
content="result for another",
name="search_api",
tool_call_id="tool_call456",
- id="00000000-0000-4000-8000-000000000049",
+ id="00000000-0000-4000-8000-000000000041",
)
]
},
@@ -5387,7 +5387,7 @@ def test_root_graph(
"__root__": [
HumanMessage(
content="what is weather in sf",
- id="00000000-0000-4000-8000-000000000083",
+ id="00000000-0000-4000-8000-000000000070",
),
AIMessage(
content="",
@@ -5407,7 +5407,7 @@ def test_root_graph(
),
AIMessage(content="answer", id="ai2"),
AIMessage(
- content="an extra message", id="00000000-0000-4000-8000-000000000107"
+ content="an extra message", id="00000000-0000-4000-8000-000000000091"
),
HumanMessage(content="what is weather in la"),
],