refactor(langgraph,prebuilt): merge EventLog into StreamChannel with optional name (#7637)

This commit is contained in:
Nick Hollon
2026-04-28 18:43:51 -04:00
committed by GitHub
parent f4388df77f
commit 5af4c5addf
13 changed files with 435 additions and 544 deletions
@@ -11,7 +11,7 @@ from __future__ import annotations
from collections.abc import AsyncIterator, Iterator
from typing import Any
from langgraph.stream._event_log import EventLog
from langgraph.stream.stream_channel import StreamChannel
class ToolCallStream:
@@ -21,7 +21,7 @@ class ToolCallStream:
are populated as events arrive:
- `tool_call_id`, `tool_name`, `input`: stable from the start event.
- `output_deltas`: an `EventLog` of delta chunks. Iterate (sync or
- `output_deltas`: a `StreamChannel` of delta chunks. Iterate (sync or
async) to consume partial output in arrival order.
- `output`: terminal payload from `tool-finished`, or `None` if the
call failed or is still in flight.
@@ -51,14 +51,14 @@ class ToolCallStream:
self.tool_call_id = tool_call_id
self.tool_name = tool_name
self.input = input
self._output_deltas: EventLog[Any] = EventLog()
self._output_deltas: StreamChannel[Any] = StreamChannel()
self.output: Any = None
self.error: str | None = None
self.completed = False
@property
def output_deltas(self) -> EventLog[Any]:
"""The EventLog of streamed `tool-output-delta` payloads.
def output_deltas(self) -> StreamChannel[Any]:
"""The channel of streamed `tool-output-delta` payloads.
Iterate (sync or async depending on how the run was started)
to consume partial output in arrival order. The log closes when
@@ -5,8 +5,8 @@ from __future__ import annotations
from collections.abc import Awaitable, Callable
from typing import Any
from langgraph.stream._event_log import EventLog
from langgraph.stream._types import ProtocolEvent, StreamTransformer
from langgraph.stream.stream_channel import StreamChannel
from langgraph.prebuilt._tool_call_stream import ToolCallStream
@@ -21,11 +21,12 @@ class ToolCallTransformer(StreamTransformer):
Native transformer — the `tool_calls` projection is exposed as a
direct attribute on the run stream.
`EventLog[ToolCallStream]` is used (not `StreamChannel`) because the
live handles are not serializable and should not be auto-forwarded
onto the main event log. Wire consumers subscribe to the `tools`
channel instead, where the raw protocol events flow through
untouched by this transformer (`process` returns `True`).
A nameless `StreamChannel[ToolCallStream]` is used (no protocol
auto-forwarding) because the live handles are not serializable and
should not be injected into the main event log. Wire consumers
subscribe to the `tools` channel instead, where the raw protocol
events flow through untouched by this transformer (`process`
returns `True`).
Registered explicitly by users at compile time via
`builder.compile(transformers=[ToolCallTransformer])` — not a
@@ -37,7 +38,7 @@ class ToolCallTransformer(StreamTransformer):
def __init__(self, scope: tuple[str, ...] = ()) -> None:
super().__init__(scope)
self._log: EventLog[ToolCallStream] = EventLog()
self._log: StreamChannel[ToolCallStream] = StreamChannel()
self._active: dict[str, ToolCallStream] = {}
self._is_async = False
self._pump_fn: Callable[[], bool] | None = None
@@ -11,9 +11,9 @@ from langchain_core.tools import tool
from langgraph.constants import END, START
from langgraph.graph import StateGraph
from langgraph.graph.message import add_messages
from langgraph.stream._event_log import EventLog
from langgraph.stream._mux import StreamMux
from langgraph.stream._types import ProtocolEvent
from langgraph.stream.stream_channel import StreamChannel
from langgraph.stream.transformers import (
MessagesTransformer,
ValuesTransformer,
@@ -63,7 +63,7 @@ def _tool_event(
}
def _subscribe(log: EventLog) -> None:
def _subscribe(log: StreamChannel) -> None:
log._subscribed = True