Skip to content

test(a2ui-toolkit): de-flake deep child-chain cycle tests#1949

Merged
ranst91 merged 1 commit into
mainfrom
claude/mystifying-bartik-7f2b03
Jun 12, 2026
Merged

test(a2ui-toolkit): de-flake deep child-chain cycle tests#1949
ranst91 merged 1 commit into
mainfrom
claude/mystifying-bartik-7f2b03

Conversation

@ranst91

@ranst91 ranst91 commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Problem

The two deep-chain cycle tests in sdks/typescript/packages/a2ui-toolkit/src/__tests__/validate.test.ts intermittently trip vitest's 5000ms default timeout on CI (measured ~5358ms), reddening the unit workflow's typescript job repo-wide. Unrelated to any open PR — pure main-branch CI hygiene.

Introduced by ddb4184d (@contextablemark, #1944 child-cycle work).

Diagnosis

The validator is not quadratic. Profiled validateA2UIComponents on the exact 50k chain: ~59ms (build 6ms + validate 53ms). findChildCycles is already a linear, Set/Map-backed iterative DFS — no .includes() scan, no per-node re-lookup, no recursion to overflow. Nothing to optimize.

The flake is GC/scheduling jitter, not CPU. Each test allocates ~150k objects (50k components + 50k DFS frames + path/adjacency arrays). Two such tests under vitest's parallel-fork pool on a 2-vCPU runner stall on GC, inflating wall-clock far past the ~59ms of actual CPU work. Bigger N = more allocations = more stall susceptibility.

Fix (test-only — validator left untouched, it is optimal)

Changing the validator would be a fake fix. Instead, in both deep-chain tests:

  1. N 50000 → 20000. Measured V8 recursive-overflow depth is ~8807 (trivial frame; a real DFS frame overflows lower). 20k is still >2x past that, so it still proves the walk is iterative-not-recursive, while cutting allocations 2.5x to shrink the GC-stall window. Runtime ~25ms.
  2. Explicit 30000ms timeout (vitest 4 positional arg) to decouple the provably-fast assertion from CI runner scheduling jitter.

Verification

cd sdks/typescript/packages/a2ui-toolkit && pnpm test84/84 pass, validate.test.ts ~103ms total (both deep tests included), comfortably under timeout.

No product behavior change. cc @contextablemark — touches your #1944 cycle-check tests.

The two deep-chain cycle tests in validate.test.ts intermittently tripped
vitest's 5000ms default timeout on CI (~5358ms), reddening the unit
workflow's typescript job repo-wide.

Root cause is not the validator: validateA2UIComponents on the 50k chain
runs in ~59ms (build 6ms + validate 53ms). findChildCycles is already a
linear, Set/Map-backed iterative DFS — no quadratic scan to fix. The
flake is GC/scheduling jitter: each test allocates ~150k objects (50k
components + 50k DFS frames + path/adjacency), and two such tests under
parallel-fork contention on a 2-vCPU runner stall on GC, inflating
wall-clock far past CPU time.

Fix (test-only — validator left untouched, it is optimal):
- N 50000 -> 20000 in both deep tests. V8's recursive overflow depth is
  ~8807 (trivial frame; lower for a real DFS frame), so 20k is still >2x
  past it and proves the walk is iterative, while cutting allocations
  2.5x to shrink the GC-stall window.
- Add an explicit 30000ms timeout to decouple the provably-fast
  assertion from CI runner scheduling jitter.

Toolkit suite: 84/84 pass, validate.test.ts ~103ms.
@ranst91 ranst91 requested a review from a team as a code owner June 12, 2026 17:26
@vercel

vercel Bot commented Jun 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ag-ui-dojo Ready Ready Preview, Comment Jun 12, 2026 5:30pm

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

Python Preview Packages

Version 0.0.0.dev1781285184 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.dev1781285184' --index testpypi

# Integrations (each already depends on the matching ag-ui-protocol preview)
uv add 'ag-ui-langgraph==0.0.0.dev1781285184' --index testpypi
uv add 'ag-ui-crewai==0.0.0.dev1781285184' --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.dev1781285184' --index testpypi
uv add 'ag_ui_adk==0.0.0.dev1781285184' --index testpypi
uv add 'ag_ui_strands==0.0.0.dev1781285184' --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.dev1781285184

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


Commit: 074df4d

@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.

looks good

@pkg-pr-new

pkg-pr-new Bot commented Jun 12, 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@1949

@ag-ui/a2ui-middleware

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

@ag-ui/event-throttle-middleware

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

@ag-ui/mcp-apps-middleware

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

@ag-ui/mcp-middleware

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

@ag-ui/a2a

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

@ag-ui/adk

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

@ag-ui/ag2

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

@ag-ui/agno

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

@ag-ui/aws-strands

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

@ag-ui/claude-agent-sdk

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

@ag-ui/crewai

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

@ag-ui/langchain

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

@ag-ui/langgraph

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

@ag-ui/llamaindex

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

@ag-ui/mastra

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

@ag-ui/pydantic-ai

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

@ag-ui/vercel-ai-sdk

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

@ag-ui/watsonx

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

@ag-ui/a2ui-toolkit

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

create-ag-ui-app

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

@ag-ui/client

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

@ag-ui/core

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

@ag-ui/encoder

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

@ag-ui/proto

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

commit: 86128f9

@ranst91 ranst91 merged commit 1b71d76 into main Jun 12, 2026
39 checks passed
@ranst91 ranst91 deleted the claude/mystifying-bartik-7f2b03 branch June 12, 2026 17:36
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