F1 · Denies that create_agent can register stream transformers at all, then ships a consumer-side wrapper that rebuilds per-scope identity by hand - the verdict and the artefact wrong in the same direction, four tasks apart
1.3.0 shipped 2026-05-12; this draw states a June 2026 cutoff, which is after it and not the same month, so the fairness rule and the same-month bar both clear. This is the pre-registered charging arm and tasks 1 and 5 are pre-registered probes on this surface. One finding, two artefacts (JOURNAL/062): the pre-registration graded the verdict (task 1) and the artefact (task 5) independently and this draw got both wrong in the same direction, which is one belief measured twice.
Task 1, single word on its own line: "No", glossed "I am not aware of a public 'stream transformer' / scope-aware factory API on the compiled graph at all; if one exists it is newer than what I can describe with confidence." Task 5, four tasks later: "The library, as I know it, gives me no way to register a transformer on the compiled graph, so here is what I would actually ship" - a
TransformingAgentwrapper that calls.astream(..., subgraphs=True)and keys adictof transformer instances off the namespace tuple to reconstruct the per-scope property the parameter already provides. Task 7, on which release added it: "I cannot name one. In every release I can describe ... there is no way to register your own stream transformers on the compiled agent." The subject also listed the parameters it believescreate_agenttakes - model, tools, system_prompt, middleware, response_format, state_schema, context_schema, checkpointer, store, interrupt_before/after, debug, name, cache - which is exactly the 1.2.18 signature withtransformersmissing.
# The artefact from task 5: the capability is denied, so per-scope identity is
# reconstructed on the consumer side from subgraph namespace tuples.
class TransformingAgent:
async def astream(self, inputs, *, stream_mode="updates", config=None):
per_scope: dict[tuple, MyTransformer] = {}
async for ns, mode, chunk in self._graph.astream(
inputs, config=config, stream_mode=[stream_mode], subgraphs=True
):
if ns not in per_scope:
per_scope[ns] = self._factory(ns) # invoked once per scope
yield per_scope[ns](mode, chunk)# 1.3.0 and later: the factory is registered on the graph the agent compiles,
# after the built-in ToolCallTransformer, and is invoked once per scope.
agent = create_agent(
model,
tools,
system_prompt="...",
transformers=[MyTransformer],
)The wrapper runs, which is why this is S3 rather than S1: a reader who follows it ships working code and never learns the parameter exists. What it costs is the wrapper itself, and the guarantee that comes with the supported path - the agent registers ToolCallTransformer first and appends yours after it, so the built-in behaviour is kept rather than reimplemented.
- langchain 1.3.0 published wheel - langchain/agents/factory.py published 2026-05-12
transformers: Optional sequence of scope-aware
StreamTransformerfactories to register on the compiled graph in addition to the agent defaults. Each factory is invoked per-scope (factory(scope)) so subgraph mini-muxes get fresh instances. Appended after the built-inToolCallTransformer. - langchain 1.2.18 published wheel - the release below the window, with no such parameter published 2026-05-08
- LangChain changelog - langchain v1.3.0, May 12, 2026 published 2026-05-12
This release adds support for version="v3" in stream_events / astream_events for langchain agents.