Resolve event-renderer.ts onRunFinishedEvent: keep the native turn stream open
(finalized in finish()) AND retain the legacy per-message stream drain from main
(#5573) as a no-op-in-native safety net. app/index.ts (telegram adapter from
#5520 + showToolStatus:false) and create-bot.test.ts auto-merged.
- showcase-canonical-pins.json: bump canonicalCopilotKitVersion 1.59.4 -> 1.60.2;
remove ms-agent-harness-dotnet override (caught up to canonical in prior commit).
- fail-baseline.json: re-ratchet validatePinsFailCount 39 -> 38 and hash to match
the one-item drop (ms-agent-harness-dotnet override no longer counted).
- @ag-ui/mastra: revert 0.2.4 -> 0.2.1-beta.2. 0.2.4 imports
'@mastra/core/runtime-context' which the pinned @mastra/core@1.41.0 does not
export, breaking 'next build' (failing mastra build-check in CI). Holding
@ag-ui/mastra at the prior pin until a coordinated @mastra/core upgrade lands.
Aligns dependency versions across all 19 showcase integrations to current
released minor versions for the 1.60.2 release cycle.
Package families:
- @copilotkit/{a2ui-renderer, react-core, react-ui, runtime, shared, sdk-js, voice}
1.59.4 -> 1.60.2 (18 integrations already staged; ms-agent-harness-dotnet
catches up from 1.57.2)
- @ag-ui/{client, core, encoder} 0.0.55 -> 0.0.57
- @ag-ui/mastra 0.2.1-beta.2 -> 0.2.4 (stable on 0.x; 1.0.x major held back)
Includes the previously-missed ms-agent-harness-dotnet integration in the
@copilotkit/* bump, plus the @copilotkit/web-inspector override pin.
Lockfile-only reconciliation via npm install --package-lock-only
--legacy-peer-deps (cmdk@0.2.1 pre-existing react^18 peer-dep is unaffected).
Pre-existing crewai backend defect: tool-rendering-custom-catchall agentId was routed to the shared LatestAiDevelopment ChatWithCrewFlow at /, with no get_weather/get_stock_price handlers. tool_result never returns, second LLM call never fires, toolCallId-gated narration fixture entries unreachable, A7 requireContentPhrase=true probe fails.
Fix: add get_stock_price_impl in src/agents/tool_rendering.py mirroring LGP-python tool shape; re-route 'tool-rendering-custom-catchall' agentId in src/app/api/copilotkit/route.ts to createAgent('/tool-rendering').
Local verification on cr5495/fix-a14-crewai-green:
- /tmp/cr/a14-green-crewai.log: 1 passed (6.8s), INNER_EXIT=0
- /tmp/cr/a14-green-lgp.log (LGP regression): 1 passed (9.0s), INNER_EXIT=0
(cherry picked from commit 208d90018a3fc41c263fd4514b104c78815f8303)
Each integration's interrupt-headless demo defines a local useHeadlessInterrupt
hook around the framework useInterrupt. Slot-2 originally identified 8
quarantined integrations (claude-sdk-typescript, langgraph-{fastapi,python,
typescript}, langroid, pydantic-ai, spring-ai, strands); review-round
follow-ups extended the sweep to llamaindex, mastra, ag2, agno, and
crewai-crews (5 more integrations sharing the same byte-identical hook).
The demo-local resolve() previously fire-and-forgot copilotkit.runAgent(...)
via `void runAgent(...).catch(() => {})`. Mirroring the framework fix:
- Make resolve async, return await copilotkit.runAgent(...).
- Use a pendingRef so resolve has stable identity (drop pending from
useMemo deps).
- Type signature: resolve: (response: unknown) => Promise<unknown>.
- Wrap in try/catch + setPending(null) + console.error + rethrow,
symmetric with the framework hook.
- onRunFailed also setPending(null).
13 integrations patched byte-identically.
- Scope clickPill locator to data-message-role='user' bubble so the pill
button itself can no longer satisfy the dispatch guard
- Dedup clickPill retry: skip click if the user bubble already exists
- Hero pill: assert declarative-card count=0 (OSS-136 no-Card rule),
metric count >=4 (was >=3 — KPI strip is 4 tiles per composition rule)
- At-risk pill: assert no chart and no table testids (composition rule)
- Top-account pill: assert no data-table and no status-badge testids
- Rename hero test title to 'KPI strip + pie + bar (no surrounding card)'
so the title no longer falsifies the body
- QA docs: replace 'card + metrics + pie + bar' Expected Results with
'4 KPI metrics + 1 PieChart + 1 BarChart, no surrounding Card per OSS-136'
- Probe responseTimeoutMs derived from FIRST_SIGNAL_TIMEOUT_MS so it
matches the e2e 90s budget
- DataTable rowKey uses first-column value + index instead of bare index,
with JSON.stringify(row) fallback (stops re-mount on dynamic A2UI re-emits)
- Card emits data-card-id={props.title} so multi-card pills no longer
collide on a single declarative-card testid
- PieChart/BarChart value coercion replaced 'Number(x) || 0' with
finite-number check + console.warn on drift (no longer masks legitimate 0)
Replace the misleading 'single source of truth' claim with an explicit
DUPLICATION NOTICE describing the per-integration parity convention and
a TODO(OSS-136) for the future shared-module extraction. Both copies
remain byte-identical.
Override the basic catalog's Text (its built-in 8px margin misaligned
card rows), keep badges content-sized instead of stretched by flex
parents, and prefix each badge with a hardcoded lucide icon per variant
(error/warning/success/info). Renderer-only — payloads and fixtures are
unaffected.
Hero loses its surrounding card (bare KPI strip over the chart cards,
pinned to all six months); team performance pairs the rep table with a
quota-attainment bar chart; top account pairs the fact card with a
product-line pie (new dataset entry); at-risk becomes a risk panel — KPI
strip (ARR at risk / accounts / biggest exposure) over three side-by-side
severity cards with reason + next action. Fixtures re-captured from live
responses; D5 probe drops declarative-card from the hero set; e2e asserts
the accompanying charts and the risk panel; QA docs updated.
Ports beautiful-chat's exact visual language into the catalog renderers:
DashboardCard chrome (12px radius, 20px padding, soft shadow) for Card and
chart wrappers, its Metric typography with colored trend deltas, a recharts
donut (innerRadius 40, paddingAngle 2, tooltip, no legend) replacing the
custom SVG donut, and uniform blue bars on a dashed grid. E2E pie
fingerprints move from circle/legend assertions to recharts sectors; the
hero surface-count guard allows the two ResponsiveContainers (pie + bar)
one composed dashboard now produces.
Click a pill, then require the user-message bubble before asserting on
the surface; retry the click if it was swallowed. On slow dev-server
hydration the first click can land before the chat send pipeline is
wired, which previously burned the full surface-assertion budget and
masked the real failure point.
The demo now plays an embedded sales analyst for a fictional company:
suggestion pills are natural business questions (chart-type steering moved
from user prompts into the system prompt), the hero pill composes a full
dashboard (KPI metrics + pie + bar in one surface) modelled on
beautiful-chat's sales dashboard, and the catalog gains DataTable,
gap-aware Row/Column, Metric trendValue, and the beautiful-chat palette.
Dataset + composition rules ship as frontend agent context
(sales-context.ts) so they reach both the primary agent and the secondary
A2UI planner in LGP and ADK alike. E2E specs and QA docs updated to the
new pill set.
* duplicate ceiling 290→291: tool-rendering.json's tightened 'current
price of AAPL' matchers now share two match keys with the existing
tool-rendering-custom-catchall.json entries in the same BIA context,
runtime-disambiguated by feature route.
* shadow ceiling 134→132 (ratchet down): the bare 'AAPL' vs 'current
price of AAPL' shadow pair on the tool-rendering.json side is gone.
* PARITY_NOTES: replaces the 'headless-complete turns 3+4 server-tool
reprompt loop' known-issue section with a resolved-via-sequenceIndex
description; the architectural reprompt loop now converges via the
sequenceIndex-gated emitter + narration-fallback pattern in
gen-ui-headless-complete.json.
The injected/streamed a2ui fixtures all included catalogId, so aimock
replay never exercised the basic-catalog fallback that broke production
(real models omit catalogId per the tool-usage guide). Strip catalogId
from the langgraph-python sales-dashboard secondary-call fixtures and
hard-assert "Catalog not found" is absent outside the charts-rendered
soft branch, so the spec fails without a route defaultCatalogId.
Also repoint the on-demand e2e workflow at the d4/d5-recorded/d6/shared
fixture dirs — it still referenced feature-parity.json, deleted in the
1e66a5f8d fixture reorg, so every /test-aimock run died at aimock start.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The injected render_a2ui tool guide instructs models to omit catalogId
("the catalog id is set by the host"), and backend-owned generate_a2ui
tools see real models omit or late-stream it. Without defaultCatalogId
the a2ui middleware falls back to the spec basic catalog, which no
showcase page registers — surfaces fail with "Catalog not found:
https://a2ui.org/specification/v0_9/basic_catalog.json" (reported on
beautiful-chat / langgraph-python).
Pin each route to the catalog its page registers: beautiful-chat ->
copilotkit://app-dashboard-catalog, declarative-gen-ui ->
declarative-gen-ui-catalog. Routes with no a2ui block never attach the
middleware and are left untouched.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Documentation companion to the BIA D6 readiness work:
- PARITY_NOTES.md: tracks built-in-agent feature parity vs LGP +
a 'Known Issues' section documenting 3 D6 demos that remain red
due to downstream renderer/state gaps in @copilotkit/react-core
(a2ui renderer host doesn't mount Card; STATE_DELTA → useAgent
state-subscription gap; declarative-gen-ui renderer host shares
the same class). All three require fixes outside this PR's scope.
- feature-registry.json: adds threadid-frontend-tool-roundtrip
feature entry covering the new gen-ui-agent STATE_DELTA wiring.
Adds the set_steps tool definition to state-tools and wires it through
the tanstack factory so the gen-ui-agent demo emits STATE_DELTA events
on its agent-plan stream the same way the LGP integration does.
Extracts the inline subagents page DelegationCard into three reusable
components that mirror the LGP integration layout, enabling D6 testid
coverage:
- subagent-activity-card.tsx: per-subagent activity panel
- delegation-log.tsx: cumulative delegation event log
- supervisor-activity-banner.tsx: supervisor-level status banner
The subagents page now composes these components instead of inlining
the markup, with data-testid hooks for D6 selectors.
Adds inline comments next to the data-testid="headless-message-{user,assistant}"
markers in assistant-bubble.tsx, user-bubble.tsx, and headless-simple/page.tsx
explaining that the testids intentionally repeat once per message — mirroring
the canonical LGP implementation — and that role discrimination for the D6
conversation-runner is via data-message-role, not unique testids.
Backfills the data-testid markers the D6 probes assert against across the
auth, headless-simple, headless-complete, a2ui-fixed-schema,
declarative-gen-ui, and gen-ui-interrupt demos; aligns the python
a2ui_fixed agent + a2ui definitions/renderers with the canonical LGP
shapes; and switches the gen-ui-interrupt CopilotKit provider import to
@copilotkit/react-core/v2 so the demo mounts under the V2 runtime that
the D6 probe drives.
Adds the chart-card renderer and wires it into the headless-complete
tool-renderers map so the D6 probe for the headless-revenue-chart feature
can mount and assert against a real chart component.
Replaces useLangGraphInterrupt with useInterrupt (LangGraph-specific hook
not exported from the V2 React core) and switches the CopilotKit provider
import to @copilotkit/react-core/v2 so the demo mounts under the V2
runtime that the D6 probe drives.
Annotates 14 integration manifests with d6_not_supported_features entries
and aligns d6_supported_features with what each backend actually implements,
so the D6 fleet probe only enumerates demos that the backend can serve.
Align showcase integration requirements.txt files (strands,
langgraph-fastapi, langgraph-python, pydantic-ai, google-adk,
crewai-crews) to the fleet pin standard, including an accurate
typing_extensions comment in crewai-crews and a trailing newline in
langgraph-python.
Replace floating "beta" dist-tags with exact versions for @ag-ui/mastra,
@mastra/{client-js,core,libsql,memory}, and mastra in both the examples
and showcase mastra packages. Showcase mastra also raises its zod floor
^3.24.0 -> ^3.25.0. The examples mastra package additionally carries the
fleet-wide @ag-ui/client 0.0.55 bump and single-tree overrides here, since
its manifest mixes both changes.