Skip to content

fix(langgraph): stabilize load-sensitive stream ordering - #2593

Open
ranst91 wants to merge 4 commits into
mainfrom
codex/fix-langgraph-load-races
Open

fix(langgraph): stabilize load-sensitive stream ordering#2593
ranst91 wants to merge 4 commits into
mainfrom
codex/fix-langgraph-load-races

Conversation

@ranst91

@ranst91 ranst91 commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Summary

  • ignore late messages-tuple chunks before shared snapshot logic once events-mode streaming is active, while preserving tuple-only fallback behavior
  • seed the first newly discovered subgraph boundary from the ordered pre-entry root state instead of a potentially ahead live thread-head read
  • replace the shared-state E2E's fixed delay with a deterministic runtime-agent readiness signal before recipe edits

Verification

  • pnpm nx run-many -t test typecheck -p @ag-ui/langgraph --skip-nx-cache — 20 test files, 779 passed, 2 existing todo; typecheck passed
  • four concurrent uncached runs of stream-ordering-races.test.ts — all passed
  • pnpm nx run demo-viewer:lint --skip-nx-cache — passed
  • uncached Nx builds for @ag-ui/langgraph and demo-viewer — passed
  • LangGraph Python shared-state Playwright test repeated 10 times with 4 workers — all passed
  • Prettier check and git diff --check — passed

No event-trace goldens were changed.

@ranst91
ranst91 requested a review from a team as a code owner September 1, 2026 10:28
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Python Preview Packages

Version 0.0.0.dev1788434009 published to TestPyPI.

Warning: These packages are built from contributor code that may not yet have been vetted for correctness or security. Install at your own risk and do not use in production.

Install with uv

Add the TestPyPI index to your pyproject.toml:

[[tool.uv.index]]
name = "testpypi"
url = "https://test.pypi.org/simple/"
explicit = true

Then install the packages you need:

# Core SDK
uv add 'ag-ui-protocol==0.0.0.dev1788434009' --index testpypi

# Integrations (each already depends on the matching ag-ui-protocol preview)
uv add 'ag-ui-langgraph==0.0.0.dev1788434009' --index testpypi
uv add 'ag-ui-crewai==0.0.0.dev1788434009' --index testpypi
# NOTE: ag-ui-agent-spec depends on pyagentspec (git-only, not on PyPI).
# You will need to install pyagentspec separately from its git repo.
uv add 'ag-ui-agent-spec==0.0.0.dev1788434009' --index testpypi
uv add 'ag_ui_adk==0.0.0.dev1788434009' --index testpypi
uv add 'ag_ui_strands==0.0.0.dev1788434009' --index testpypi

Install with pip

pip install \
  --index-url https://test.pypi.org/simple/ \
  --extra-index-url https://pypi.org/simple/ \
  ag-ui-protocol==0.0.0.dev1788434009

Use --extra-index-url https://pypi.org/simple/ so pip can resolve
transitive dependencies (pydantic, fastapi, etc.) from real PyPI.


Commit: 4d46f8d

@pkg-pr-new

pkg-pr-new Bot commented Sep 1, 2026

Copy link
Copy Markdown

Open in StackBlitz

@ag-ui/a2a-middleware

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/a2a-middleware@2593

@ag-ui/a2ui-middleware

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/a2ui-middleware@2593

@ag-ui/event-throttle-middleware

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/event-throttle-middleware@2593

@ag-ui/mcp-apps-middleware

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/mcp-apps-middleware@2593

@ag-ui/mcp-middleware

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/mcp-middleware@2593

@ag-ui/a2a

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/a2a@2593

@ag-ui/adk

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/adk@2593

@ag-ui/ag2

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/ag2@2593

@ag-ui/agno

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/agno@2593

@ag-ui/aws-strands

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/aws-strands@2593

@ag-ui/claude-agent-sdk

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/claude-agent-sdk@2593

@ag-ui/claude-managed-agents

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/claude-managed-agents@2593

@ag-ui/crewai

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/crewai@2593

@ag-ui/langchain

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/langchain@2593

@ag-ui/langgraph

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/langgraph@2593

@ag-ui/llamaindex

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/llamaindex@2593

@ag-ui/mastra

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/mastra@2593

@ag-ui/pydantic-ai

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/pydantic-ai@2593

@ag-ui/vercel-ai-sdk

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/vercel-ai-sdk@2593

@ag-ui/watsonx

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/watsonx@2593

@ag-ui/a2ui-toolkit

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/a2ui-toolkit@2593

create-ag-ui-app

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/create-ag-ui-app@2593

@ag-ui/client

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/client@2593

@ag-ui/core

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/core@2593

@ag-ui/encoder

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/encoder@2593

@ag-ui/proto

pnpm add https://pkg.pr.new/ag-ui-protocol/ag-ui/@ag-ui/proto@2593

commit: 8c432f4

@contextablemark contextablemark left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There’s one state-cache gap I think we should fix before merging.

The default stream configuration appears safe: it includes values, and in a real Agent Server repro the updated root values arrived before the first nested event in 300/300 concurrent runs. The regression is still deterministic for the supported forwardedProps.streamMode override when values is omitted: after a root on_chain_end updates state, the first subgraph boundary reads the still-prepared latestRootStateValues, so AG-UI emits stale STATE_SNAPSHOTs during the subgraph. The final root snapshot repairs them, so this is P2 rather than P1, but consumers can still see a temporary rollback or act on stale state.

Please keep the ordered-root cache in sync when a root on_chain_end merges object or Command.update output, and add coverage for root on_chain_end → first subgraph event without a values chunk.

…n_end

When `values` is omitted from the stream modes, the first subgraph
boundary snapshots directly from the ordered root cache seeded by
prepareStream. A root `on_chain_end` that merged object or
`Command.update` output only updated `latestStateValues`, so the
boundary emitted a stale STATE_SNAPSHOT until the final root snapshot
repaired it.

Merge the same on_chain_end delta into `latestRootStateValues` when the
event is root-namespaced, and add coverage for
`root on_chain_end -> first subgraph event` without a `values` chunk for
both the object and the Command.update output shapes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants