Latest Results
fix(core): escape node metadata in Mermaid labels (#41512)
`draw_mermaid` writes node metadata into node labels as-is, so a list
value like LangGraph's `__tools` produces brackets that Mermaid can't
parse. Any graph with a `ToolNode`, or user metadata containing
brackets, fails to render.
## Changes
- String, number and bool values render as before; lists, tuples and
sets of those are joined with `, `, with sets sorted so output is stable
across runs.
- Dicts and nested values are left out of the label; a node with nothing
left gets no metadata section.
- Mermaid-significant characters (`#[](){}"<>|`) are replaced with
Mermaid entity codes.
## Release note
`draw_mermaid` and `draw_mermaid_png` no longer produce invalid Mermaid
for nodes with list, dict, or bracketed metadata.
## Test Plan
- [x] Unit tests: list, sorted set, dict, escaped string, all-omitted
metadata; existing snapshots unchanged
This PR was written with help from an AI agent.
🤖 Generated with [Claude Code](https://claude.com/claude-code) fix(core): merge streamed `AIMessageChunk`s once instead of one at a time
`Runnable` adds up streamed chunks one at a time in several places: the
run callbacks' output and inputs in `_transform_stream_with_config` and
its async twin, the input buffer of the default `transform`, and
`RunnableLambda`'s input buffer and generator output. Every
`AIMessageChunk` addition re-parses the tool call arguments received so
far, so streaming a long tool call through a chain took quadratic time:
about 7.4 seconds for a 64,000-character tool call in 16-character
chunks through `prompt | model`, and 10.1 seconds with a `RunnableLambda`
after the model.
A shared accumulator now keeps leading `AIMessageChunk`s and merges them
in one addition, as `generate_from_stream` does for `invoke`. If that
addition raises, it adds them one at a time, as before. The same chains
now take 0.03 and 0.02 seconds.
`merge_content` also stops changing the content list of the first
message it merges. Merging the same chunks twice, as a model's own
stream and a step after it both do, added the text that follows a
list-content chunk, such as a reasoning block, twice: before this change
to the model's traced output, and with the single merge above to the
input of a `RunnableLambda` after the model.
Based on #40841 by @0xamlab; reported by @QHarshil in #40826.eliornl/core/linear-stream-chunk-merge Latest Branches
+1%
eliornl/core/linear-stream-chunk-merge +22%
sera-wi/core/mermaid-metadata-labels +22%
eyurtsev/core/v3-gateway-tracing © 2026 CodSpeed Technology