Bug: in a single chat session, running both HITL booking flows
back-to-back (Alice 1:1 → then Sales call without refresh) used to
skip the time-picker on the second flow and jump straight to
"Booked ..." text.
Cause: confirmation fixtures were matched on `hasToolResult: true`,
which fires whenever the conversation has ANY tool message in
history. After the first flow finished, the second user message
short-circuited to a confirmation match before the second flow's
toolCall fixture (gated on `hasToolResult: false`) had a chance to
fire. The picker never rendered.
Fix: re-key the two confirmation fixtures on `toolCallId` (the
specific tool_call_id of the matching `book_call` invocation), which
only fires when the LAST conversation message is a tool result with
that id — exactly the moment we want the confirmation. Drop the
`hasToolResult: false` constraint on the toolCall fixtures so they
match a fresh user request regardless of prior tool history.
Add a back-to-back regression test to all 17 hitl-in-chat specs:
walk Alice flow to completion, then sales flow without refresh,
assert two `time-picker-card` elements rendered. If the multi-flow
regression returns, the second card never appears and the test
fails at `toHaveCount(2)`.
The hitl-in-chat demo ships in 17 integrations (langgraph-python plus
16 others — mastra, strands, ag2, agno, crewai-crews,
langgraph-typescript, langgraph-fastapi, pydantic-ai, llamaindex,
langroid, claude-sdk-python, claude-sdk-typescript, ms-agent-python,
ms-agent-dotnet, spring-ai, google-adk). All shipped placeholder e2e
specs that only checked the chat input was visible — none exercised
the actual booking flow.
Replace each with the full booking-flow spec written for
langgraph-python:
1. The "Schedule a 1:1 with Alice" suggestion renders the time-picker
card AND the Tokyo greeting is absent (regression guard against
the broad aimock `userMessage: "Alice"` matcher).
2. Picking a slot transitions to the picked-state card and produces
a "Booked … Alice" assistant follow-up.
3. The "Book a call with sales" suggestion runs the same flow with
the sales attendee.
Also add the matching aimock fixture pair for the sales suggestion
in feature-parity.json — without it, case 3 would only pass against
real OpenAI, not the aimock-backed CI deployments. The pair mirrors
the Alice fixture pair: `book_call` toolCall on first turn,
confirmation message after the picker resolves.
Per-integration coverage matters because each integration has its
own framework-specific HITL wiring (`useHumanInTheLoop` binding to
the agent, agent-side tool registration, run streaming protocol)
that can regress independently of the shared aimock fixture.
- Add dedicated tool-free voice agents for strands, llamaindex,
ms-agent-python (aimock returns tool calls when tools are registered,
which the adapters don't loop on)
- Add sample_agent alias to langgraph-typescript langgraph.json
(was only in dev-mode config)
- Add SampleAudioButton and voice route to google-adk
- Add sample.wav to agno, ms-agent-dotnet, ms-agent-python, google-adk
Replace gen-ui-interrupt and interrupt-headless "not supported" stubs
with working demos using useFrontendTool + async Promise pattern.
Backend agents use system prompt + tools=[] — CopilotKit runtime
routes tool calls to the frontend handler. Pattern proven by
ms-agent-python/dotnet, now extended to ag2, agno, built-in-agent,
claude-sdk-python, claude-sdk-typescript, crewai-crews, google-adk,
langroid, llamaindex, mastra, pydantic-ai, strands.
Fix chat-slots agent name (dashes to underscores), prebuilt-popup
defaultOpen prop, auth demo defaults to unauthenticated state, and
add missing data-testid attributes to byoc renderers.
The voice demo route handler imports @copilotkit/voice which was not
declared in these two package.json files. Other integrations either
had it or resolved it via hoisting, but mastra's Docker build failed.
Recent feature commits added new dependencies to integration package.json
files (@copilotkit/voice, @hashbrownai/{core,react}, @json-render/{core,react})
and bumped Next.js from 15.4.10 to 15.5.15, but never regenerated the
corresponding package-lock.json. The Showcase Build & Deploy workflow runs
`npm ci --legacy-peer-deps` which strictly enforces lock sync, so every
deploy attempt has been failing at the install step. No new images have been
pushed to GHCR, so Railway services have stayed on stale code and any cell
added since each fw's last successful deploy iframes 404.
Regenerated all 18 lockfiles via `npm install --legacy-peer-deps
--package-lock-only --ignore-scripts` per integration. Verified each with
`npm ci --dry-run --legacy-peer-deps` — all clean.
Refs PDX-90.
`custom-bubbles.snippet.tsx` in google-adk and llamaindex was built in
PR #4439 by concatenating two source files (user-bubble.tsx +
assistant-bubble.tsx). Each source had its own `import React from "react"`,
so the resulting sibling carried two copies and tripped
oxlint's no-redeclare rule.
Drops the second `import React from "react"` in each file. React is
already imported by the first one — the duplicate was always dead.
Resolves the 2 oxlint errors that were causing CI failure.
The first pass of /voice.mdx had inline code blocks. Rewrites the page
to use <Snippet> references against per-framework sibling files, matching
how the rest of shell-docs sources its code samples.
- Two siblings per framework (×18 fws = 36 files):
- voice-runtime.snippet.ts: V2 CopilotRuntime + TranscriptionService
setup, including the GuardedOpenAITranscriptionService wrapper that
returns a clean 4xx when OPENAI_API_KEY is missing. Regions:
`voice-runtime`, `transcription-service-guard`.
- voice-frontend.snippet.tsx: chat surface with auto-mic-button, plus
the SampleAudioButton that bypasses the mic for Playwright /
screenshot flows. Regions: `voice-page`, `sample-audio-button`.
- /voice.mdx now uses 4 `<Snippet region="..." />` refs instead of
inline code, so the docs reference real teaching code that lives next
to each framework's actual demo (and stays in sync with the established
per-framework sibling convention from PR #4439).
5 cells unblocked by removing per-framework null overrides that were
overriding the canonical defaults landing in the companion commit:
- google-adk: drop nulls for voice, byoc-hashbrown, byoc-json-render
(canonicals now wired in feature-registry).
- langgraph-python: drop nulls for voice, byoc-hashbrown,
byoc-json-render (same).
After this commit, no framework has a stale `null` override for any
documented feature. The remaining intentional opt-outs (subagents on 4
fws) keep their existing nulls because they're genuinely framework-
specific decisions, not stale config.
7 cells unblocked by removing per-framework null overrides that were
overriding working canonical defaults:
- google-adk: drop nulls for `chat-customization-css`, `subagents`,
`multimodal` (canonicals already wired), and the now-canonical
`agent-config` + `auth` (added in companion commits). `voice`,
`byoc-hashbrown`, and `byoc-json-render` kept null pending PDX-85,
PDX-88, PDX-89.
- langgraph-python: drop nulls for `multimodal` + `agent-config` (now
resolvable via canonical defaults). `voice` + `byoc-*` kept null
pending the same tickets.
Adds two new manifest pattern flags (matching the existing
`interrupt_pattern` / `a2ui_pattern` convention) so the canonical
`/agent-config` and `/auth` shell-docs pages can gate their per-pattern
sections via `<WhenFrameworkHas>` and only render the implementation that
applies to the framework the user has selected.
- `agent_config_pattern: shared-state | runtime-properties | null`
- `runtime-properties` (1 fw): built-in-agent
- `shared-state` (17 fws): everything else that wires agent-config
- `auth_pattern: langgraph | ag2-context-variables | microsoft-agent-framework | runtime-onrequest | null`
- `langgraph` (3 fws): langgraph-python, langgraph-typescript, langgraph-fastapi
- `ag2-context-variables` (1 fw): ag2
- `microsoft-agent-framework` (2 fws): ms-agent-python, ms-agent-dotnet
- `runtime-onrequest` (12 fws): everything else
Also fills in the previously-missing `a2ui_pattern` flag on 6 frameworks
that have wired demos but were rendering near-empty doc pages because
none of the existing `<WhenFrameworkHas>` gates matched. Audit-driven:
ag2/agno/claude-sdk-{python,typescript}/langroid use schema-loading;
built-in-agent uses schema-inline.
## Summary
Fixes the root causes for **30+ live-dashboard cells stuck at D2**
across 31 integration rows on https://dashboard.showcase.copilotkit.ai/.
Five surgical fixes plus one structural depth-walk fix; deploy-stale
cells (~40) are flagged separately for ops since they are not
code-fixable.
## Why these fixes ship together
A scrape of the live dashboard found 100 D2 chips. Bucketing them by
failure mode revealed the pattern is **structural + per-framework**, not
100 independent failures. Five frameworks ship genuine probe/integration
bugs we can fix in code; three frameworks are deploy-stale (Railway
image is older than the recent commit landings); one cell is a
per-feature slot-API contract bug. The dashboard itself also has a
structural bug that under-reports cells whose D5 is green when D3 has no
row yet.
## What ships
### Slot-agent fixes (Phase A/B/C of the blitz)
| Commit | What |
|---|---|
| `1de1556be` D5-green bypass for missing/red D3 in depth walk |
`deriveDepth` in
`showcase/shell-dashboard/src/components/depth-utils.ts` was
contiguous-walk-only, so 13 cells whose `d5:<slug>/<feature>` row is
green but whose `e2e:<slug>/<feature>` row is missing or red were stuck
at D2. Per the harness model, the e2e-deep driver only emits D5 after D3
+ D4 have passed at some point; D5-green is sufficient evidence. After
the D2 (agent) gate passes, `deriveDepth` now checks D5 first; if green,
achieved jumps to 5 and proceeds to D6. D1+D2 remain hard gates - D5
cannot bypass health/agent. 7 new tests pin every asymmetry. |
| `e0d89e0fe` fail loud on slug missing from registry in e2e-demos
driver | `E2eDemosResolver` previously returned `E2eDemoEntry[]`,
conflating "registry has the slug with zero demos" (legitimate brand-new
package) with "slug absent from registry" (operational fault - manifest
gap, stale mount, slug rename). Both collapsed silently into "aggregate
green / no per-feature rows" - exactly the symptom shape on the live
dashboard for several frameworks (`mastra`, `langroid`, `llamaindex`,
`langgraph-typescript`, `langgraph-fastapi`,
`ms-agent-{python,dotnet}`). Resolver now returns `{ present: boolean,
entries: E2eDemoEntry[] }`; when `present === false`, the driver emits a
synthetic red `e2e:<slug>/__missing-registry` side row + flips the
aggregate red with `errorClass: "registry-missing"`. Read-failure path
still goes through the existing green/silent branch to avoid swamping
the dashboard with N noisy red dots when the registry isn't mounted at
all. |
| `00e801209` claude-sdk-python missing openai dep crashed agent on
import | `src/agents/a2ui_dynamic.py` had a top-level `import openai`
but `openai` was never declared in `requirements.txt`. `agent_server.py`
imports `a2ui_dynamic` at module load, so `ModuleNotFoundError` cascaded
through `entrypoint.sh`'s "Agent failed to start - exiting" gate,
preventing Next.js from booting at all. Result: every `/demos/<id>`
route across the integration was unreachable - explaining all 9 red E2E
cells in the `claude-sdk-python` framework column uniformly. Two-line
fix: add `openai>=1.50.0` to `requirements.txt` and move `import openai`
to a lazy import inside `_generate_a2ui` (mirrors the existing pattern
in `agents/agent.py`). |
| `cb2ef9411` remove __future__ annotations from ag2 agent_config_agent
| Same class of bug as commit `e38fab4d6` (Apr 28) which fixed
`shared_state_read_write.py` and `subagents.py`: `from __future__ import
annotations` turns `ContextVariables` in the `@tool`-decorated
`get_current_config(context_variables: ContextVariables) -> str`
signature into a ForwardRef. Autogen's `TypeAdapter` can't resolve it,
registration raises `PydanticUserError` at module import,
`agent_server.py` fails to load, the whole AG2 integration goes
unreachable. Drop the `__future__` import. |
| `b377b78a6` render input slot in google-adk chat-slots welcome screen
| The custom welcome screen at
`src/app/demos/chat-slots/custom-welcome-screen.tsx` did not accept or
render the `input` ReactElement that `CopilotChatView` passes into the
`welcomeScreen` slot. `CopilotChatView` only mounts the chat composer
inside the welcome screen on the empty-thread path
(`CopilotChatView.tsx:301-348`), so when the empty-state welcome was
active no `<textarea>` ever reached the DOM. The e2e-readiness probe's
structural selectors all timed out, flipping the D2 chat-slots cell red.
Mirrors the canonical pattern used by 16+ other integrations (strands,
langgraph-python, claude-sdk-python). |
### cr-loop fixes (Round 1+2 review findings, applied during
convergence)
| Commit | What |
|---|---|
| `b1768f5db` return red aggregate when e2e-readiness resolver throws |
Round 1 finding (3 of 7 reviewers converged independently). When
`demosResolver(slug)` throws, the catch path was emitting a `__resolver`
red side row but `slugPresentInRegistry` defaulted to `true` and was
never flipped, so the fail-loud branch was skipped and the aggregate
fell through to green with `note: "no demos declared"`. Catch now
returns early with a red aggregate (`errorDesc: "resolver-error"`),
mirroring the missing-registry early-return shape. New C12b test pins
the aggregate state, since the existing C12 test only asserted the side
row. |
| `44037b9ce` align claude-sdk-python requirements.txt comment with
lazy-import implementation | Round 1 trivial - the comment block above
the `openai` dep claimed it was "imported at module top". The
`00e801209` fix moved the import to a lazy import; the comment was now
falsified by the diff. Updated to describe the actual two-layer
protection (lazy import as runtime safety net, requirements.txt as
authoritative dep declaration). |
| `070ecd051` empty in-band input.demos no longer suppresses
missing-registry red | Round 2 finding. The in-band fallback `if
(demos.length === 0 && Array.isArray(input.demos))` triggered even when
`input.demos === []`, forcing `slugPresentInRegistry = true` and
silently bypassing the fail-loud branch. A misconfigured probe YAML with
`demos: []` for a slug not in the registry would have rendered green.
Tightened to also require `input.demos.length > 0`. |
## Live-dashboard impact
After deploy:
- **13 cells** whose `d5:<slug>/<feature>` is already green flip to D5
immediately (purely from the depth-walk fix; no probe/agent change
required).
- **30+ cells** across `mastra` / `langroid` / `llamaindex` /
`langgraph-typescript` / `langgraph-fastapi` / `ms-agent-python` /
`ms-agent-dotnet` will surface as red `__missing-registry` rows on the
next probe tick (the previously-silent missing-registry fault becomes
loud and actionable).
- **9 cells** in `claude-sdk-python` flip green once the integration
container rebuilds with the openai dep.
- **15 cells** in `ag2` framework column should flip green once the
agent server boots cleanly (the `agent_config_agent` import crash was
preventing `agent_server.py` from loading at all).
- **1 cell** `google-adk` × `chat-slots` flips green on next deploy
(welcome screen now renders the chat composer).
## Deploy-stale cohort (NOT code-fixable, flagged for ops)
| Framework | D2 cells | Status |
|---|---|---|
| `built-in-agent` | 28 | **Needs Railway redeploy** - local `next
build` succeeds for all 53 routes; live
`https://showcase-built-in-agent-production.up.railway.app` returns HTTP
404 for every demo added in commits `e18ee1d25 e4afffd4f7abb1d07674e57483869cb5f51c7c44b71f6 53455bfeb`. Source healthy; deploy is
older than the demo-landing commits. |
| `claude-sdk-typescript` | 10 | **Needs Railway redeploy** - same
pattern: local build green, live URL returns 404 for newly-added demos
(`b9dbacd99 / 70522b1a6 / 417e3b397`). |
| `ms-agent-python` | 2 | Probable snapshot-stale - live HTML now
renders the canonical `data-testid="copilot-chat-textarea"` selector;
the readiness scan was probably running before the redeploy completed.
Should self-heal on next probe tick. |
Slack thread to Jordan with the `built-in-agent` deploy-stale evidence
already sent earlier in the run.
## Test plan
- [x] `pnpm --filter @copilotkit/showcase-harness exec vitest run
e2e-readiness` - 34/34 pass (32 pre-existing + 1 new C12b resolver-throw
aggregate-red + 1 new empty-in-band missing-registry)
- [x] `npx vitest run depth-utils` (in `showcase/shell-dashboard/`) -
30/30 pass (23 pre-existing + 7 new D5-bypass cohort)
- [x] `pnpm typecheck` on `showcase/harness` - clean
- [x] `npx tsc --noEmit` on `showcase/shell-dashboard` - touched files
(`depth-utils.ts`, `depth-utils.test.ts`) clean. Pre-existing TS errors
in `compute-tally-detail.test.tsx` are on `main`, not introduced by this
PR.
- [x] cr-loop converged on Round 3 (7 unbiased reviewers, 0 bucket (a)
findings, byte-identical verbatim prompts)
- [ ] CI green on PR HEAD
- [ ] After merge: ops triggers Railway redeploy of
`showcase-built-in-agent-production` and
`showcase-claude-sdk-typescript-production` - those 38 cells flip green
without any code change.
## Out of scope (deferred to follow-up PRs)
A 7-agent unbiased CR surfaced ~50 pre-existing concerns in files this
PR happens to touch but whose subject is distinct (bucket (d) per
cr-loop's classification rules). They have coherent, named subjects and
belong in their own PRs:
- **a2ui_dynamic.py agent observability audit** (claude-sdk-python):
broad `except Exception` leaks tracebacks to chat content; sync `openai`
call in async generator blocks the event loop; Anthropic-format messages
forwarded to OpenAI's `chat.completions.create` will 400 on the second
tool round; no max-iteration cap on the outer `while True` loop;
empty-string `ANTHROPIC_API_KEY` fallback masks misconfig;
`tool_call_id` falls back to empty string.
- **e2e-readiness probe robustness audit**: `Math.max(0, deadline -
Date.now())` returns `0` after deadline expiry, which Playwright treats
as "no timeout" instead of "fail immediately"; whitespace-only `route`
strings bypass the `config-invalid` guard; URL concatenation does not
normalize trailing/leading slashes; no abort check between `newPage()`
and `page.goto()`; `setTimeout` overflow on huge `E2E_DEMOS_TIMEOUT_MS`
env values; `__resolver` / `__missing-registry` sentinel namespacing
speculation.
- **e2e-readiness test hygiene**: the C7 "aborts mid-selector-loop
without walking all 6 selectors" test asserts behavior the
implementation no longer has (single compound selector replaced the
sequential loop); the assertion
`expect(selectorsTried.length).toBeLessThan(5)` is now trivially true.
- **depth-walk semantics audit**: D6 unreachable when `isD5Green` is
false (D6 was always gated on D5-green even before this PR; design
discussion on whether D6-green should imply D5-green - the same way
D5-green now implies D3/D4-pass).
- **agent_config_agent observability**: invalid frontend values
(`tone="snarky"`) silently coerce to defaults with no log; `logger`
instance imported but never used.
## Worktrees / cleanup
- Integration worktree at
`<repo>/.claude/worktrees/blitz-d2-to-d4-integration` retained alive
across cr-loop rounds per blitz protocol; will be removed after this PR
merges.
- 8 per-slot blitz worktrees and 2 ephemeral cr-fix worktrees were
created; 7 cleaned up successfully, 3 had Windows file-lock issues
(built-in-agent, claude-sdk-typescript, ms-agent-python) - git metadata
is gone, just stale dirs that need a manual `rm -rf`.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sweep across all `.snippet.*` files (existing + new in this branch) to
remove non-teaching content that distracts from the docs-page render.
Changes:
- 6 files (5 hitl + 1 tool-rendering): replace `(props: any)` +
`eslint-disable-next-line @typescript-eslint/no-explicit-any` with
proper structural prop types. Reads identical to the eye but no lint
suppression in the rendered snippet.
- 1 file (state-streaming-middleware.snippet.py): drop 2
`# type: ignore[name-defined]` markers. The stand-in identifiers
(`write_document`, `AgentState`) already read as docs-only references.
- 1 file (delegation-log-frontend.snippet.tsx, BIA): rewrite the in-region
JSDoc to be framework-agnostic. The file was ported from ag2 and still
named `AG2 sub-agent` + referenced `ReplyResult` / `ContextVariables`
in the BIA copy. Also drop a historical bug-fix note ("Per-status
color map…") that is irrelevant outside ag2's commit history.
- 2 files (use-rendered-messages.snippet.tsx, google-adk + llamaindex):
strip brittle internal-path references (`packages/react-core/src/v2/.../
CopilotChatMessageView.tsx:542-612`, `react-core/v2/components/chat/
CopilotChatToolCallsView.tsx`) that would rot within months. Replaced
with conceptual references to the public component name only.
No region markers changed; audit still reports B-docs-gap: 0.
The shell-docs `/headless` page teaches the truly-headless composition
pattern via 5 regions:
- page-send-message (page-level wiring)
- use-rendered-messages-hook (composition hook)
- manual-activity-message-rendering (per-role dispatch)
- manual-tool-call-rendering (assistant + tool calls)
- custom-bubbles (pure-chrome user/assistant bubbles)
google-adk's headless-complete demo uses custom message-list/bubble
composition that diverges from this canonical pattern; llamaindex's
demo has its own use-rendered-messages.tsx but doesn't match the
canonical regions either. Per the established sibling convention, both
frameworks now ship docs-only siblings exposing all 5 regions adapted
from claude-sdk-typescript's canonical implementation.
Files per framework:
- use-rendered-messages.snippet.tsx (3 regions)
- custom-bubbles.snippet.tsx (combines user-bubble + assistant-bubble)
- page-send-message.snippet.tsx (1 region, minimal teaching variant)
Closes 10 B-docs-gap refs from PDX-83.
The shell-docs `/generative-ui/tool-based` page teaches the
`useComponent` bar-chart pattern via `<Snippet region="bar-chart-renderer" />`,
but 14 frameworks ship a haiku-generator demo that uses
`useFrontendTool` instead — a fundamentally different API. Per the
established sibling convention (matching `tool-rendering/render-flight-tool.snippet.tsx`),
each framework now ships a docs-only `bar-chart-renderer.snippet.tsx`
that exposes the canonical teaching shape without touching the demo.
Frameworks: ag2, agno, built-in-agent, claude-sdk-python,
claude-sdk-typescript, crewai-crews, google-adk, langgraph-fastapi,
langgraph-typescript, langroid, mastra, ms-agent-dotnet, spring-ai,
strands.
Closes 14 of the 45 remaining B-docs-gap refs from PDX-83.
Audit-driven corrections to per-framework docs-links.json so every
supported (wired/stub) cell on the dashboard resolves to a real
shell-docs page and a non-stale OG URL. Result: 545 → 613 cells fully
working; remaining 78 cells are known docs gaps tracked separately
(voice → PDX-85; auth/agent-config/byoc-* across frameworks where no
canonical page exists).
- built-in-agent: drop 6 stale `/features/*` OG overrides retired by
the IA reorg. Cells now inherit canonical OGs that still exist on
docs.copilotkit.ai (`/human-in-the-loop`, `/generative-ui/...`,
etc.).
- langgraph-python: fix `auth` OG (`/langgraph/authentication` →
`/langgraph/auth`) + add framework-specific shell override (`/auth`
resolves to `integrations/langgraph/auth.mdx`). Null `voice` and
`byoc-hashbrown` OGs that pointed to retired pages.
- google-adk: replace 27 `shell_docs_path: null` opt-outs with
explicit canonical paths so cells route to real shell-docs pages
(mix of canonical root + adk-specific overrides). The original
rationale ("shell does not have a google-adk-scoped docs tree") is
now stale — shell-docs has an `integrations/adk/` tree (11 pages),
and the rest resolve via canonical inheritance. Also fix two retired
a2ui sub-paths (dynamic-schema/fixed-schema) that are now combined
on a single `/adk/generative-ui/a2ui` page on docs.copilotkit.ai.
- ag2 / ms-agent-python / ms-agent-dotnet: add framework-specific auth
overrides pointing at `/<framework>/auth` on both OG and shell.
The custom welcome screen replaced CopilotChat's default empty-state
view but never rendered the bound input element passed in via slot
props. CopilotChatView only mounts the chat composer inside the
welcome screen on the empty-thread path, so dropping {input} meant the
V2 textarea never reached the DOM and the e2e-readiness probe's
structural selectors (copilot-chat-textarea, textarea, etc.) timed
out, flipping the chat-slots D2 cell red while every other google-adk
feature stayed green.
Match the established pattern used by strands, langgraph-python,
claude-sdk-python, and the other chat-slots demos: accept the
{ input, suggestionView } slot props, render input below the branded
card, and tag the wrapper with data-testid="custom-welcome-screen"
for parity with the e2e specs in those frameworks. Production
behavior (Google ADK branding, Powered by Google ADK heading) is
preserved.
Sets the per-framework values that drive the new <WhenFrameworkHas>
gating on /generative-ui/a2ui/fixed-schema and /human-in-the-loop/* docs
pages.
a2ui_pattern values:
schema-loading — backend loads schema from JSON at startup
(langgraph-python/typescript/fastapi, llamaindex,
crewai-crews, pydantic-ai, ms-agent-python,
google-adk)
schema-inline — backend defines schema inline in code
(spring-ai, ms-agent-dotnet)
llm-driven — backend generates schema dynamically per request
(mastra, strands)
omit — cell unshipped for the framework
interrupt_pattern values:
native — framework has interrupt() primitive
(langgraph-python/typescript/fastapi)
promise-based — demo uses useFrontendTool + Promise resolution
(ms-agent-python, ms-agent-dotnet)
omit — cells unshipped for the framework
Same commit also closes a presentation gap on the shell-dashboard
drilldown by adding the missing a2ui sibling files to highlight: lists:
- strands: catalog.ts, definitions.ts, renderers.tsx
- crewai-crews: same three
- google-adk: definitions.ts
ag-ui-adk has no interrupt() primitive and does not emit on_interrupt
custom events, so useInterrupt and useHeadlessInterrupt have nothing to
subscribe to. Add not_supported_features to the manifest and provide
README + stub page.tsx for each, pointing to the langgraph-python
reference implementation.
Adds a dedicated CopilotRuntime route configured with mcpApps.servers pointing at the public Excalidraw MCP server, plus a no-tools ADK agent. The MCP middleware injects the remote tools and emits activity events that CopilotKit's built-in MCPAppsActivityRenderer renders inline as a sandboxed iframe.
Frontend-tool HITL via useHumanInTheLoop with an in-chat time-picker. Adds a dedicated ADK agent that prompts the model to call the frontend-defined book_call tool; the picker card is rendered inline by useHumanInTheLoop and resolves with the chosen slot or a cancellation.
Add demo entries for hitl, hitl-in-app, hitl-in-chat, tool-rendering,
shared-state-read-write, and gen-ui-tool-based across 14 integrations.
Ensure every demo ID also appears in the features list so the showcase
matrix and D5 probes discover them correctly.
STATE_SNAPSHOT can deliver a Preferences object with interests undefined,
crashing .includes(), .filter(), and spread at 4 sites per file. Add
(value.interests ?? []) guards across all 17 integrations.
Two additional sibling files in the same docs-only pattern as
chat-component.snippet.tsx and render-flight-tool.snippet.tsx, picking
up cells that were deferred in the previous commit because the
production demo doesn't use the slots/customizations the docs teach.
- chat-slots/disclaimer-and-assistant-message.snippet.tsx — wraps
register-disclaimer-slot and register-assistant-message-slot regions.
google-adk's production chat-slots only registers the welcome slot;
these regions now have a real teaching example without changing the
runtime demo.
- agentic-chat-reasoning/reasoning-block-render.snippet.tsx — wraps
reasoning-block-render. The production demo uses default reasoning
rendering and the ReasoningBlock component file exists but isn't
wired into the messageView slot. This file imports ReasoningBlock and
teaches the slot wiring pattern, leaving page.tsx untouched.
Both files follow the established convention: not imported, not
rendered, picked up by the bundler via @region markers, captioned via
the docs <Snippet title="…">. Two more cells (chat-slots,
agentic-chat-reasoning) flip from B to A — google-adk now at 20 cells
fully tagged.
Remaining deferred (engineering / cross-cutting only):
- gen-ui-tool-based (generate_haiku vs pie-chart shape mismatch)
- declarative-gen-ui::runtime-inject-tool (cross-cutting; PDX-70)
- headless-complete (5 regions; production demo simpler than canonical)
The packages/starters merge (PR #4351) eliminated starters as separate
deployable units. Remove the starter: block (path, name, description,
github_url, demo_url, clone_command) from all 17 integration manifests
to stop propagating stale showcase-starter-* Railway URLs through the
data pipeline.
All 25 demo pages had CopilotKit imported from @copilotkit/react-core
(V1) while V2 hooks (useRenderTool, useFrontendTool, useAgent, etc.)
were imported from @copilotkit/react-core/v2. This mixed-import causes
V2 hooks to silently fail because they cannot find the V2 context
provided by the V1 CopilotKit provider.
Consolidated all imports so CopilotKit comes from
@copilotkit/react-core/v2 alongside the other V2 hooks. The only
remaining V1 import is useLangGraphInterrupt in hitl/page.tsx, which
is not available in V2.
The aimock D5 fixtures send tool calls with argument names `topic`,
`brief`/`facts`, and `draft` for the three sub-agent tools, but the
google-adk Python functions all used `task: str`. Google ADK maps
function arguments strictly by name, so the mismatch caused every
sub-agent tool call to fail silently.
- research_agent: task -> topic
- writing_agent: task -> brief + facts (optional)
- critique_agent: task -> draft
- Updated supervisor instruction to reference correct parameter names
Replace sys.path.insert hacks in Python agent files with direct
imports via symlinks to shared/{python,typescript}/tools.
Update Dockerfiles, entrypoints, and configs to support the new
symlink-based tool resolution. Add PARITY_NOTES for frameworks
that have known gaps.
The showcase framework directories better reflect their role as
integration examples rather than distributable packages.
Renames showcase/packages/ -> showcase/integrations/ and updates
the test docker-compose file reference accordingly.