Two issues found after the example merged:
1. The closed chat panel is only translated off-screen, so its inputs/buttons
stayed in the tab order and the a11y tree. Mark the <aside> `inert` while
closed (`[attr.inert]`), so focus/AT skip it; removed when open.
2. The dev web inspector (and its @copilotkit/web-inspector dep, ~660 kB) shipped
in the production initial bundle. Gate it behind `@defer (when isDev)` so it's
split into a lazy chunk that a prod build (isDev=false) never loads.
Verified: prod `ng build` initial bundle 4.59 MB -> 3.93 MB with web-inspector now
a lazy chunk; dev serve still mounts the inspector; closed-panel focus is blocked
(activeElement falls back to body), open panel unaffected.
When the viewport is wide enough (>=1200px) the chat starts expanded and DOCKS:
.layout--pushed adds a right margin equal to the chat width so the proverbs
content reflows beside the chat instead of being covered (mirrors React's
CopilotSidebar margin-inline-end push). Below the breakpoint the chat starts
closed and OVERLAYS on open, so narrow screens aren't smushed.
- DOCK_BREAKPOINT_PX (1200) gates the initial open state; a matching
@media (min-width:1200px) rule applies the push margin
- --chat-width var keeps the panel width and push margin in sync
Verified live: 1400px starts expanded, content pushed beside the chat (right
929 <= chat left 960), 0 overflow; 1000px starts closed, opening overlays with
no push and no overflow.
Previously the FAB swapped to an X when open and sat above the panel, so an open
chat showed TWO X's (header + bottom-right). React never does that: its toggle
FAB is always a MessageCircle, and the sidebar (z-1200) covers the FAB (z-1100)
when open, so the only visible close is the header X.
- FAB icon is always MessageCircle (no X swap)
- chat panel z-index 1200 > FAB 1100, so an open panel covers the FAB
Verified live: OPEN shows only the top-right header X (FAB covered); CLOSED shows
the bottom-right MessageCircle FAB to reopen. No bottom-right X in either state.
Replace the hand-rolled unicode/emoji controls with lucide icons matching React:
- header close = lucide X (in a title-left/close-right, border-b bar like CopilotModalHeader)
- toggle FAB = lucide MessageCircle (open) / X (close), ALWAYS visible, fixed
bottom-6 right-6, h-14 w-14, rounded-full, primary-dark — matches CopilotChatToggleButton
Verified live: FAB shows X when open / MessageCircle when closed and stays visible
(React's toggle behavior); close + FAB both drive chatOpen; 0 console errors.
Replaces the permanent 420px chat column with a collapsible slide-over panel
(toggle FAB + close button), mirroring React's CopilotSidebar. The chat now
OVERLAYS rather than reserving a grid track, so the threads drawer's desktop
push no longer smushes the content and the medium-width layout has room.
- app.ts: 2-track grid (drawer + content); fixed .chat slide-over + open FAB;
chatOpen signal (defaults open, like React defaultOpen). Theme var hoisted to
the component HOST so the weather card (now in the fixed chat) still inherits it.
- styles.css + web-inspector.ts: move the dev inspector FAB to bottom-left; its
default top-right anchor (max z-index, transform-positioned) sat over the chat's
close button and ate the click.
Verified live (real Gemini key): open/close/reopen slide-over; content 880px at
1200w (no smush); 0 horizontal overflow + no clipping at 580/1050/1200; inspector
clears both the close button and open-FAB; 'set theme to teal, then weather in
Paris' recolors the panel AND renders a teal-themed weather card in the floating chat.
The proverbs card is width:100% + padding:2rem; with the default content-box the
padding was added ON TOP of 100%, making the card wider than its column and
getting clipped by the layout's overflow:hidden (visible as cut-off content on
narrow/medium screens). React/Next examples get border-box from Tailwind's
preflight; the Angular app had no global reset.
Verified live at 580px (card 578px, no clip, 0 overflow) and 1050px (card fits
its grid track, no overlap with the chat). Matches the React adk's overflow-free
responsive behavior.
setThemeColor (and any frontend-registered tool) never reached the LLM: the ADK
agent's tools were static [set_proverbs, get_weather], and ag_ui_adk only injects
the run's forwarded client tools when the agent's tools include an AGUIToolset
placeholder (it swaps it for a ClientProxyToolset wired to input.tools). Added
AGUIToolset() so gemini-2.5-flash sees the forwarded setThemeColor and calls it.
Verified LIVE (real Gemini key): 'Set the theme to green' now recolors the panel
(--app-theme-color: green) — previously the agent declined ('I can only help with
proverbs or the weather'). Same root cause affects the React adk example (fixed
in a companion change).
The get_weather generative-UI card never rendered: a CR round-3 "consistency"
tweak added agentId: AGENT_ID to the renderToolCalls entry, which scoped the
renderer such that the incoming (server-side) tool call didn't match and the
card was filtered out. The internal examples/v2/angular/demo renderer sets no
agentId; omitting it here restores rendering.
Verified LIVE against the running app (real Gemini key): the WeatherCard now
renders for 'Get the weather in San Francisco' (location + weather chrome),
matching the React adk reference. Caught by a live React-vs-Angular comparison
that the static CR loop could not.
(Note: setThemeColor NOT calling the agent is inherited — the React adk example
behaves identically; ag_ui_adk doesn't bridge forwarded client tools into the
ADK LLM tool set. Separate upstream concern, tracked as bucket-d follow-up.)
Mounts the framework-agnostic cpk-web-inspector web component (dev aid for
watching AG-UI events / agent state / runtime connectivity), handing it the
shared CopilotKit.core. Mirrors the internal examples/v2/angular/demo pattern —
@copilotkit/angular does not integrate the inspector via the provider the way
React's <CopilotKit inspectorDefaultAnchor> does. Matches the richer React
integration examples (langgraph-python et al.); a deliberate extra vs. the
leaner adk reference.
- add @copilotkit/web-inspector@1.63.1
- src/app/web-inspector.ts + <app-web-inspector /> in app.ts
- README file map updated
ng build green; oxlint 0/0.
- app.ts: setThemeColor comment notes it also recolors the weather card
- server.ts: identifyUser comment notes the id must exist in the platform
- README: document that INTELLIGENCE_API_KEY must accompany COPILOTKIT_LICENSE_TOKEN
Comment/doc only — no behavioral change.
- proverbs.ts: latch the seed one-shot UP FRONT (per agent instance) so a first
snapshot with defined proverbs can't leave the effect subscribed and re-seed on
a later transient undefined; spread existing state in the seed too. Comment now
states the new-thread-hydration race honestly (inherited from React's [agent])
- server.ts: fix the runtime port at 8200 (matches the hardcoded UI runtimeUrl);
don't read env PORT — resolves both the client/server port drift and the
shared-PORT collision with the Python agent
- app.config.ts: pass agentId to the get_weather renderToolCalls entry (parity with
the setThemeColor frontend tool; future-proofs multi-agent)
- app.ts: correct the theme comment (center panel themes via its input, not the var)
Verified: ng build green; oxlint 0/0. Deferred (bucket c/d, inherited from React adk):
Intelligence empty-API-key fail-loud, .sh||.bat + dev:debug + postinstall-uv script
patterns, demo-user stub, dead ProverbsState — aggregated for a cross-example follow-up.
- app.ts: theme via a demo-specific --app-theme-color, not --copilot-kit-primary-color
(the chat re-declares that token on [data-copilotkit] hosts, shadowing the layout
value, so the weather card never themed — round 1's fix was ineffective)
- app.ts: mobile overrides the desktop 100dvh on .center/.chat so the chat row isn't
starved to 0 and clipped (regression introduced by round 1's mobile stack)
- proverbs.ts: seed ONCE per agent instance (mirror React [agent]) instead of on every
state emission — stops transient undefined mid-run/on thread-restore from re-seeding
- proverbs.ts: remove() spreads existing state (setState is a full replace; was wiping
any non-proverbs state)
- server.ts: read RUNTIME_PORT (not the shared PORT the Python agent also reads)
- main-content.ts: drop the redundant/shadowed --copilot-kit-primary-color binding
- weather-card.ts: location required (matches React/backend) + 'Weather' fallback label
- real favicon.ico (was a 12-byte stub); README file map + Node 20.19+/≥22 notes
Verified: ng build green; oxlint 0/0. Refuted in review: no dual @copilotkit/core
(published angular@0.2.0 depends on core/shared@1.63.1 exactly).
- server.ts now loads .env (import dotenv/config) so COPILOTKIT_LICENSE_TOKEN /
INTELLIGENCE_* / AGENT_URL / PORT are honored — Intelligence/threads were
unreachable before (tsx does not auto-load .env like Next.js did)
- .env.example: drop PORT=8200 (the agent's load_dotenv read it and bound 8200,
colliding with the runtime); align AGENT_URL trailing slash
- app.ts: set --copilot-kit-primary-color on the .layout root so setThemeColor
reaches the chat-rendered weather card (was scoped to .main-content only)
- app.ts: mobile stacks center+chat instead of hiding the chat (kept assistant reachable)
- proverbs.ts: re-seed on every fresh thread (drop lifetime latch); mirror React
- agent-state.ts: proverbs?: string[] (code depends on undefined-before-seed)
- package.json: drop unused hono/@hono/node-server/@angular/forms/@angular/router; add dotenv
- .gitignore: !.env.example so the tracked template can't be dropped by the .env* rule
- scripts/run-agent.bat: quote cd path + exit guard (match setup-agent.bat)
- agent/main.py: fix garbled prompt rule 5, stray quote, wether/provers/incude/recipe typos
- README: Intelligence path needs Node >=22 + a real provisioned user (not demo-user)
Verified: ng build green; server.ts binds .env PORT (dotenv loads); oxlint 0/0
The agno starter's Dockerfile installs Python deps via 'uv pip install --system -e .', resolving from pyproject.toml (not uv.lock). agno>=1.7.8 now resolves to 2.7.4, which dropped python-multipart as a hard dependency. AgentOS registers a FastAPI form-data route, so the app raised 'RuntimeError: Form data requires python-multipart' at import time, crash-looping starter-agno. Pin python-multipart>=0.0.20 directly so it installs regardless of agno's transitive deps.
CodeRabbit flagged that the form onSubmit added to headless-chat could submit
empty/whitespace messages. The handler now returns early on blank input and the
submit button is disabled when the message is empty. Applied to the claude-sdk
starters (where the form lives); headless-chat.tsx is already declared
allowedDivergence for these instances, so parity stays green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Revert the cross-demo parity sync from b34a9a348: langgraph-python (north-star)
and the langgraph-js / langgraph-fastapi / strands-python instances are restored
to their origin/main state — this PR should not mutate the canonical demo or its
siblings.
Instead, keep the CodeRabbit fixes on the claude-sdk-* starters and declare the
affected shared files as per-instance `allowedDivergence` in the parity manifest,
so `pnpm parity:check` passes without touching the other demos. The starters
carry fixes the north-star has not caught up to yet:
- border-3 -> border-[3px]; bg-[--x] / text-[--x] -> [var(--x)] (Tailwind v4)
- JSX.IntrinsicElements -> React.JSX.IntrinsicElements; Recharts <Bar shape> type
- tool-rendering args?: unknown; mode-toggle a11y; headless-chat <form>
- docker-route-override AGENT_URL trailing-slash normalization
next.config.ts is left matching the north-star template (its ignoreBuildErrors is
a shared build-config concern and the Docker build re-adds it regardless).
parity:check green (5/5 instances, 0 errors); claude-sdk tsc + oxfmt clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The CodeRabbit fixes in d4ef84f2c edited verbatim parity-tracked files
directly in the claude-sdk-* instances, diverging them from the north-star
(langgraph-python) and failing `pnpm parity:check`.
Move the shared-surface fixes to the north-star and propagate to every
tracked instance via `pnpm parity:sync --all`:
- border-3 -> border-[3px] (border-3 is not a Tailwind utility)
- bg-[--x] / text-[--x] -> [var(--x)] (Tailwind v4 CSS-variable syntax)
- JSX.IntrinsicElements -> React.JSX.IntrinsicElements (@types/react 19)
- Recharts <Bar shape> callback typing
- tool-rendering args?: unknown
- mode-toggle aria-pressed/type/role, headless-chat <form> + aria-label
- docker-route-override AGENT_URL trailing-slash normalization
Also revert the next.config.ts `ignoreBuildErrors` removal: next.config.ts is
a north-star template file shared across all integration demos, so the
suppression can't be dropped on a subset without breaking parity, and dropping
it template-wide would need every demo verified to build clean without it. The
two real type errors it was masking are now fixed at the north-star, so the
shared surface is type-clean regardless.
parity:check green (5/5 instances, 0 errors); claude-sdk tsc + oxfmt clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Resolve the real issues surfaced by CodeRabbit on the new claude-sdk-python /
claude-sdk-typescript starters (frontend files are shared, so most fixes apply
to both):
- Fix two type errors that `ignoreBuildErrors` was masking: `JSX.IntrinsicElements`
-> `React.JSX.IntrinsicElements` (@types/react 19) and the Recharts `<Bar shape>`
callback type; then drop the blanket `typescript.ignoreBuildErrors` from
next.config.ts so source type-checks. The Dockerfile's build-time patch still
re-adds it for the `next@latest` Docker build, so deploy behavior is unchanged.
- Fix Tailwind v4 CSS-variable syntax: `bg-[--x]` -> `bg-[var(--x)]`, and
`border-3` -> `border-[3px]` (border-3 is not a utility -> invisible spinner).
- Harden the agent tools: omit the empty ANTHROPIC_API_KEY, wrap the Anthropic
call in try/catch (TS + Python), normalize the AGENT_URL trailing slash, and
make the Flight schema's id/airlineLogo/statusIcon required to match the
"must have" tool description.
- Minor a11y: mode-toggle `aria-pressed`/`type`/`role`, headless-chat `<form>`
+ `aria-label` (Enter-to-submit).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two clonable starter templates showing CopilotKit driving a Claude Agent SDK
agent over AG-UI, mirroring the langgraph-python showcase (todos canvas, charts,
flight cards, dynamic dashboards, HITL, theme, threads drawer).
Each agent is a thin, idiomatic layer on the official ag-ui-claude-sdk /
@ag-ui/claude-agent-sdk adapters: three backend tools (query_data, search_flights,
generate_a2ui) live in per-tool modules and are wired into ClaudeAgentAdapter,
while the shared todo board is driven by the adapter's built-in ag_ui_update_state
tool. The default model is claude-sonnet-5 and local dev uses a real
ANTHROPIC_API_KEY (matching the official AG-UI dojo). Both instances are
registered in the _parity manifest so their frontends stay synced with the
langgraph-python north-star.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The 1.62.3 release publishes the CopilotThreadsDrawer redesign (web-components +
react-core wrapper) and the stateless /suggest feature. Bump the 15 integration
examples that consume the drawer from 1.62.2 -> 1.62.3 (package.json + lockfiles)
so they pick up the released packages alongside this branch's example CSS.
Validated: langgraph-js runs on the published 1.62.3 (no local links) — the
redesigned drawer renders (New Conversation, Recent Conversations, filter funnel,
desktop collapse toggle, per-row kebab), threads are licensed, and a real agent
message round-trips.
- ModeToggle: one style on both breakpoints (top-4/right-4 = 16px gutter,
46px min-height, 4px corners); symmetric p-1.5 + fixed 20px button leading
so the selected pill has an even gap on all four sides (was tight L/R vs T/B).
- Launcher: uniform 16px gutter (top + left) on both breakpoints so it mirrors
the toggle; drop the mobile-only 7px override.
- Logo: centered on the launcher/toggle middle line (pt-[23px]); wordmark
padding normalized so its height matches on both breakpoints.
- Inspector FAB: sits beneath the toggle, gap = the 16px top gutter (one rule,
no media query, since the toggle is identical across breakpoints).
Net: launcher, logo, toggle share center-y; launcher + toggle are both 46px;
the FAB tucks under the toggle with a matching gap; the selected toggle pill is
evenly inset.
- ModeToggle: move left (right-[72px]) so the top-right inspector FAB no longer
covers the App segment; grow to 46px (lg:min-h) + center on the logo line
(top-6) to match the launcher; keep the 4px corners.
- Launcher: left gutter -> 16px to match the right-side controls' inset.
- Logo: pt-7 so it centers on the same line as the launcher + toggle.
- Mobile header: max-lg:pb-0 -> pb-4 so chat content clears the fixed launcher/
toggle strip instead of butting right under it (no boundary).
- Chat/App ModeToggle: rounded-full -> rounded-[4px] container + rounded-[2px]
buttons, matching the drawer's 4px radius cap so the header controls are
visually consistent.
The 7px/16px launcher inset was tuned for the mobile off-canvas launcher; on
desktop it leaked onto the collapsed cluster. Move it into the mobile media
query so desktop-collapse uses the element's own 24px gutter default.
The floating launcher/collapsed cluster is fixed at the top-left corner. Below
1024px it always shows (already cleared via max-lg:pl-24); on desktop it appears
only when the drawer is COLLAPSED. Drive the header's left padding off
--cpk-drawer-reserved-width (0px when collapsed, 320px default otherwise) so the
logo starts at ~6rem when collapsed and pl-6 when expanded — no overlap. No-op
on current packages (var never set → stays pl-6).
Read grid-template-columns' first track from var(--cpk-drawer-reserved-width, 320px)
so when the drawer collapses on desktop (it sets the var to 0) the reserved
column collapses and the chat reclaims the space — instead of leaving an empty
placeholder column. Mobile (single-column) is unchanged.
- Add full StateGraph + Annotation setup with CopilotKitStateAnnotation.spec
- Show complete tool implementation with proper ToolMessage handling
- Include graph compilation with nodes, edges, and routing logic
- Pattern examples after working shared-state-streaming.ts reference
- Fix both Deep Agents and LangGraph docs versions
- Include formatter fixes for JSON files
Fixes FAC-101
The langgraph/strands examples pinned @copilotkit/runtime via a
self-referential npm alias (npm:@copilotkit/runtime@x) left over from the
de-fork branch (2155821b8), where it forced registry resolution while
react-core used workspace:*. That alias is functionally identical to a
raw pin and react-core was already reverted, so drop the alias in the four
remaining files (langgraph-fastapi, langgraph-js, langgraph-python,
strands-python) and regenerate their lockfiles.
Bump the 16 integration examples already on the 1.62.x line from 1.62.1
to 1.62.2 (the just-published release), including their in-tree agent
sub-packages (langgraph-js/agent sdk-js, agentcore CDK lambda runtime)
that had drifted to 1.61.0. Regenerated the co-located package-lock.json
files against the published 1.62.2.
a2a-a2ui and agent-spec remain at 1.61.0 (QA-held; out of scope).
Resolve the single conflict in packages/web-inspector/src/index.ts by keeping
both additions: this branch's CpkMemoryList memory-tab element and main's
ɵCpkThreadDetails back-compat alias (independent top-level declarations).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Address PR review: delete the 4 stray package.json.bak files left by the
version-bump tooling, and restore examples/teams/appPackage/{color,outline}.png
to main (the de-fork commit had rewritten them into raw LFS-pointer text —
incidental fallout unrelated to this PR's scope).
A stray comment edit left langgraph-js's example-layout/index.tsx one line
off from the langgraph-python north-star, tripping the verbatim parity check.
Match it exactly.
The drawer shipped in 1.62.1 (react-core + the previously-missing
web-components package). Move the de-forked examples off the workspace:*
placeholder (and 1.61.0 runtime) onto the published 1.62.1, so they consume
the real SDK CopilotThreadsDrawer. Verified: a standalone install + next build
of pydantic-ai resolves CopilotThreadsDrawer from the published packages.
Rename import + usage from CopilotDrawer to CopilotThreadsDrawer across the
de-forked examples, and drop the now-redundant onUpsell handler: ENT-1027
makes the element open the Intelligence docs URL by default via licenseUrl.
Comments updated; --cpk-drawer-* tokens unchanged. Holds until the drawer
packages are published.