Conflict resolutions:
- page.tsx: keep the threads layout; swap the dead v1 sidebar labels
(title/initial) for the v2 keys (modalHeaderTitle 'Popup Assistant' +
welcomeMessageText) the starter smoke asserts, and carry over main's
disableSystemMessage + clickOutsideToClose. Keep her useRenderTool
render({ parameters }) — that is the actual v2 RenderToolProps shape;
main's render({ args }) was a latent runtime bug (args is not a prop).
- package.json: keep the drawer UI deps (class-variance-authority, clsx).
- integration test: fold into the parameterized batch-2 contract test;
migratedIntegrations now crewai-flows + llamaindex + pydantic-ai (18/18).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Conflict resolutions:
- page.tsx: keep the threads layout (drawer + gate + provider) and restore
the v2 sidebar labels (modalHeaderTitle 'Popup Assistant' +
welcomeMessageText) the starter smoke asserts, plus clickOutsideToClose.
- layout.tsx: keep the REST-transport explainer comment.
- integration test: keep the parameterized batch-2 contract test from
crewai-flows and add llamaindex to migratedIntegrations (12/12 pass).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
labels.title/initial are dead v1 keys in the v2 CopilotSidebar — the header
rendered the default 'CopilotKit Chat' instead of 'Popup Assistant' and the
greeting never showed. Map to the v2 CopilotChatLabels keys
(modalHeaderTitle / welcomeMessageText), matching every other migrated
starter.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Brings in the base-branch fixes (main merge, v2 label keys, parity sync,
starter heals) so this PR's CI reflects its own change rather than the
pre-fix base. No conflicts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Same dead-v1-labels bug as the batch-1 starters: labels.title/initial are
ignored by the v2 CopilotSidebar, so the header rendered the default
'CopilotKit Chat' and the starter smoke's text=Popup Assistant wait timed
out (crewai-crews @interaction). Map to the v2 keys (modalHeaderTitle /
welcomeMessageText) in the two v2-migrated starters that were missed in the
earlier pass.
Verified with the exact CI compose for crewai-crews: 4 passed, exit 0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
These three starters were migrated to the v2 API surface (23af69041c, already
on main) but never got the matching @copilotkit version bump or provider
config, so their starter smoke is red ON MAIN today (main's latest run is red
for 9 starters) — not a regression from this PR. Healing them here to green
the required check:
- bump @copilotkit/react-core + runtime to 1.59.1 (the v2 pages don't work
against the 1.55.2 pair — same failure mastra had pre-bump; runs 404/hang)
- add useSingleEndpoint={false} to the CopilotKit provider, matching every
batch-1 example: without it the v2 client's endpoint-detection probe GETs
the bare /api/copilotkit, which 404s on the multi-route endpoint and trips
the smoke's zero-console-errors assertion
Verified with the exact CI command (docker compose -f docker-compose.test.yml
up --exit-code-from tests) for llamaindex: 4 passed, exit 0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Addresses the blocking review on #5151:
1. Starter smoke 'Popup Assistant' timeouts (adk, agno, mastra,
ms-agent-framework-python/dotnet): the pages passed the dead v1 label keys
(labels.title / labels.initial), which v2 CopilotSidebar ignores — the
header rendered the default 'CopilotKit Chat' so the smoke's
text=Popup Assistant wait timed out. Map to the v2 CopilotChatLabels keys:
title -> modalHeaderTitle, initial -> welcomeMessageText. Verified live:
SSR now renders 'Popup Assistant'.
2. llamaindex TypeError (reading 'proverbs'): the page still used the v1
useAgent API ({ state, setState } = useAgent({ name, initialState })) —
v2 returns { agent }, so state was undefined at render. Migrate to the v2
pattern (agent.state with a guarded default + agent.setState + one-time
seed effect), and fix its dead v1 label keys too. Verified: next build
prerenders all pages cleanly.
3. parity-check drift: ran _parity/sync.ts --all — syncs example-layout
(mobile-header fix), layout.tsx, docker-route-override.ts to the
north-star, and bumps @copilotkit/* to 1.59.1 in langgraph-fastapi and
strands-python. parity verify: 0 errors across all instances.
(next-env.d.ts is gitignored repo-wide; verify warns-and-skips it in a
clean checkout, so it is intentionally not committed.)
4. Trailing-whitespace diff-check failure (showcase google-adk agent): already
resolved by the merge of main (the file matches main; diff --check clean).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Resolves 5 conflicts from main's e793257650 (v2 frontend tool parameters
array -> Zod) overlapping the threads-wired examples:
- adk/mastra/ms-agent-framework-{dotnet,python} page.tsx: keep the branch
versions — they already use Zod parameters and add the threads drawer
wiring + the reviewed v2 restructure on top of what main converted.
- adk/package.json: union — keep the branch's threads-drawer deps +
@copilotkit 1.59.1 bump, and take main's zod dependency (which our adk
page imports but the branch never declared — main's line fixes that gap).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The langgraph-js agent `dev` script ran `npx @langchain/langgraph-cli@1.2.1`,
which resolves its own isolated dependency tree. That tree pulled a 1.2.x
`@langchain/langgraph` to satisfy the `@langchain/langgraph-api` peer
dependency, but the API hard-imports `STREAM_EVENTS_V3_MODES` from
`@langchain/langgraph/web` — a symbol only present in langgraph 1.3.0+ —
crashing the agent at startup with a SyntaxError.
Install `@langchain/langgraph-cli@1.2.4` as a devDependency and invoke the
local `langgraphjs` binary so the `@langchain/langgraph` peer resolves from
the agent's own pinned 1.3.0, which exports the symbol. Verified the agent
boots cleanly (graph registered, API on :8123, no SyntaxError).
The v1→v2 migration left tool `parameters` in the old v1 array shape
(`[{ name, type, description, required }]`), which does not satisfy the
v2 `FrontendTool.parameters?: StandardSchemaV1` contract. This produced a
`Property '"~standard"' is missing` TypeScript error, failing the
Next.js build for starters whose Docker smoke build typechecks (mastra,
ms-agent-framework-python, adk).
Convert each tool's parameters to a `z.object({...})` schema so typed
`args`/handler arguments resolve correctly. Add `zod` as a dependency to
the two starters (adk, a2a-middleware) that lacked it.
Affected starters: adk, agno, llamaindex, mastra, pydantic-ai,
ms-agent-framework-dotnet, ms-agent-framework-python, a2a-middleware.
The .NET example's page.tsx pointed its Shared State and Generative UI doc
links at /pydantic-ai/ (copy-paste leftovers) instead of
/microsoft-agent-framework/. Also fix the threads-drawer CSS header comment
that still referenced 'mastra's CopilotSidebar'.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The no-license locked panel is a fixed-width (w-80 / 18-20rem) block. In the
single-column mobile grid it left a dead background strip beside it and pushed
the app content down. Hide it below 1024px (max-lg:hidden / .lockedPanel
display:none) — consistent with the real drawer + first-paint placeholder,
which also reserve no column on mobile. Content now gets the full width.
Applied across all 7 migrated examples.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
On the no-license locked threads panel:
- widen the panel slightly (w-72 -> w-80 / lockedPanel 18rem -> 20rem) and
add white-space: nowrap so `copilotkit add-intelligence` stays on one line
instead of wrapping mid-command
- add a 'with:' lead-in above the command box so it reads as a runnable command
rather than loose text
Applied across all 7 migrated examples (Card-based locked state in adk/agno/
langgraph-js/langgraph-python; themed .lockedPanel in mastra/ms-agent-*).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The disabled-state ThreadsPanelGate (shown when no Intelligence license is
present) rendered its locked card in a bare `w-72` container with no
background, so the threads column showed the page background (a black column in
dark-themed examples, white in light) instead of the drawer surface.
Give that container the drawer surface (bg + hairline right border) so the
locked card sits in a panel that matches the drawer, consistent with the
already-surfaced .lockedPanel examples (mastra, ms-agent-framework-*).
Affects adk, agno, langgraph-js, langgraph-python (the Card-based locked state).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The ThreadsPanelGate renders a first-paint placeholder while the client-only
drawer mounts. It was either a bare `w-72` div (no surface → a black/white
column flash in the page bg) or a fixed 18rem inline-styled div (correct color
but, on mobile where the mounted drawer floats, the reserved 18rem collapsed on
mount → content shifted left).
Replace both with a shared `.drawerPlaceholder` class that matches the open
drawer's footprint + surface (18rem, drawer bg, hairline border) on desktop and
`display: none` below 1024px (the mobile drawer floats, so reserve no column).
Result: no color flash and no content shift on load. Applied across all 7
migrated examples (themed vs raw surface tokens per example).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Port the langgraph-python mobile-header fix to langgraph-js (same shared
canvas/header demo). Below 1024px the threads drawer's floating launcher is
fixed top-left and collided with the top-left CopilotKit header:
- max-lg:pl-24 on the header so the logo clears the launcher pill
- max-lg:pt-2.5 + pb-0 (and drop the logo span's pb-1.5 on mobile) so the
logo is vertically centered with the launcher + the Chat/App toggle
- trim the collapsed launcher's icon buttons (2rem -> 1.75rem) + tighter
padding so the pill height lines up with the toggle
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
On phones/tablets (≤1024px) the threads drawer's floating launcher is fixed
at the top-left corner, and it collided with this example's top-left
CopilotKit header. Three small fixes so the header reads as one tidy row:
- max-lg:pl-24 on the header so the logo clears the launcher pill
- max-lg:pt-2.5 + pb-0 (and drop the logo span's pb-1.5 on mobile) so the
logo is vertically centered with the launcher + the Chat/App toggle
(was sitting ~7px low)
- trim the collapsed launcher's icon buttons (2rem -> 1.75rem) + tighter
padding so the pill height (~36px) lines up with the toggle instead of
towering over it
Local to langgraph-python (the only rollout example with a top-left header).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Below 1024px the in-flow threads column squeezed the demo content and the
(full-screen) CopilotSidebar chat into slivers. Raise the responsive
breakpoint from 900→1024 and make the panel a true off-canvas overlay:
- collapsed → a small floating launcher pill pinned top-left (z-1300),
above the full-screen mobile chat, so threads stay reachable
- open → a fixed full-height panel sliding in from the left (z-1300),
content + chat use the full width behind it
- default the drawer to collapsed when innerWidth ≤ 1024 on mount
Applied across all 7 integration examples' shared threads-drawer, each
adapted to its own theme tokens (themed examples use --threads-drawer-*,
raw examples use --card/--border for the launcher surface).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Below 900px the drawer already overlays the content when open (existing media
query), but it defaulted to open — so on phones the 16rem panel covered the
content + chat on load. Default isOpen from window.innerWidth (> 900) so narrow
screens start at the 3.5rem rail; the user expands to the overlay on demand.
The drawer is client-mounted, so reading window in the initializer is safe.
Applied to the shared threads-drawer.tsx across all examples + north-star.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- New thread (header + collapsed rail) now switches to a fresh threadId
(crypto.randomUUID()) instead of setting it to undefined. Setting threadId
undefined after a thread was selected did not reset the V2 chat — it kept
showing the previous conversation. A new id forces the configuration provider
to re-thread to an empty conversation.
- Collapsed-rail buttons use a native title tooltip instead of the styled
::after one, which clipped horizontally against the viewport's left edge in
the narrow rail. The wider expanded row keeps the styled tooltip.
Applied to the shared threads-drawer.tsx across all examples + north-star.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The threads-drawer had drifted into two near-identical .tsx variants (a 1-char
encoding diff) during the bespoke passes. Unify all examples onto a single
shared threads-drawer.tsx, which also propagates the mastra review fixes:
- collapsed rail: hover tooltips on the expand + new-thread buttons, and the
non-interactive decorative icon (read as a dead button) removed;
- tooltip renders below the trigger in each example's themed module.css (the
styled ::after tooltip was clipped when shown above the trigger).
Per-example theming (the module.css token values) is unchanged — only the
shared logic + the tooltip positioning rule are reconciled.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Next route handlers only declared GET/POST, so the threads REST API's
DELETE (delete thread) and PATCH (archive/restore) were 405'd by Next before
reaching the runtime — thread deletion and archive were broken in every
example. Export PATCH + DELETE → handle(app) across all 7 routes.
mastra threads-drawer review fixes:
- tooltip renders below the trigger (the styled ::after tooltip was clipped by
the drawer's overflow containers when shown above);
- collapsed rail drops a non-interactive decorative icon (read as a dead button)
and adds hover tooltips to the expand + new-thread buttons.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Tokenize the last hardcoded literals in threads-drawer.module.css into --threads-*
CSS variables (with fallbacks to the existing design tokens / prior literals, so
the north-star is visually unchanged). Add THEME.md documenting the token contract
so each example can theme the drawer by defining tokens — no per-example CSS edits.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add src/components/threads-drawer/** to verbatimFiles (north-star is canonical).
Stage langgraph-js / langgraph-fastapi / strands-python in allowedDivergence for
the threads files (threads-drawer/**, src/app/page.tsx, next.config.ts) so parity
stays green while the frontend rolls out per batch; entries are removed as each
instance is synced. Verified: adds zero new parity failures (pre-existing
example-layout / docker-route-override / next-env.d.ts drift is unrelated).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Restore the threads-drawer components + locked-state gate, page.tsx wiring
(threadId state + CopilotChatConfigurationProvider + two-column shell), and the
next.config build-time derivation of NEXT_PUBLIC_COPILOTKIT_THREADS_ENABLED from
the license token. Without a license the gate renders the locked panel; the
drawer is client-mounted (SSR-safe). This is the canonical north-star frontend
that parity:sync distributes to instances per batch.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
docker-compose (postgres + redis + intelligence/composite) with its load-bearing
init-db SQL, a .env.intelligence fragment (appended on activation), and a README.
Framework-agnostic; consumed by copilotkit init -i / add-intelligence.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
When COPILOTKIT_LICENSE_TOKEN is set, wire CopilotKitIntelligence + identifyUser +
licenseToken (marker-fenced for opt-out); otherwise InMemoryAgentRunner — today's
behavior, unchanged. Document the optional Intelligence env keys (commented) in
.env.example. No visible change to the example until a license is provided.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Root cause of the parity-check CI failures:
The 5 verbatim-tracked files in `examples/integrations/langgraph-python/`
(the north-star) all carried `typescript/consistent-type-imports` and
`react/self-closing-comp` warnings that oxlint wants to auto-fix.
The lefthook pre-commit `lint-fix` hook is scoped to staged files
and re-stages fixes via `stage_fixed: true`. So when I ran
`pnpm parity:sync --target=strands-python` and staged the synced
files, oxlint --fix rewrote them on commit to satisfy the
type-imports rule — turning `import { NextRequest }` into
`import type { NextRequest }`, etc. The north-star was never touched
by the hook (nothing staged in langgraph-python/), so it kept the
un-fixed form. The two diverged at commit time and parity:check
caught the drift.
Two prior commits (0559faf3d, 80425fcc8) tried to land the sync but
each landed empty: lefthook + stage_fixed reverted the working-tree
changes to match the north-star's un-fixed form, then the linter's
auto-fix re-applied the same delta the hook had just undone — net
zero file content but with the linter-fixed form, which the post-
commit hook then reverted again. Hard to debug because `git
commit` reported success and shortstat hid the no-op.
This commit fixes the root cause instead of the symptom:
1. Apply `pnpm exec oxlint --fix` directly to the 5 north-star
files (`docker-route-override.ts`,
`src/app/declarative-generative-ui/renderers.tsx`,
`src/components/ui/{badge,button}.tsx`, `src/lib/utils.ts`).
The fixes match what the pre-commit hook would have applied:
type-only imports → `import type`, self-closing JSX → `<X />`.
2. Re-run `pnpm parity:sync` for all three instances
(strands-python, langgraph-fastapi, langgraph-js) so they
verbatim-match the new north-star.
3. Verified `pnpm parity:check` exits 0; all four trees lint clean
(`pnpm exec oxlint examples/integrations/.../`).
Net effect: every instance now matches the north-star byte-for-byte,
and the lint-fix hook is a no-op on these files going forward.
Files touched per directory (5 each, except strands-python which had
docker-route-override.ts already synced in a prior attempt):
examples/integrations/langgraph-python/ — 5 files
examples/integrations/langgraph-fastapi/ — 5 files
examples/integrations/langgraph-js/ — 5 files
examples/integrations/strands-python/ — 4 files
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Previous commit wired LANGGRAPH_DEPLOYMENT_URL into the strands route.ts
to satisfy the verbatim langgraph-python docker-compose.test.yml — that
leaks the wrong runtime's name into a strands-only file.
Instead, mark docker-compose.test.yml as allowed-divergence for strands
(parity manifest) and give strands its own compose stack:
- agent on port 8000 (matches `npm run dev:agent` locally)
- healthcheck on /health (already exposed by main.py)
- app reads AGENT_URL (strands-native), no LANGGRAPH_DEPLOYMENT_URL
Reverts:
- Dockerfile.agent: EXPOSE/uvicorn back to 8000
- main.py: drop the /ok endpoint added in 2994b3a96
- route.ts: drop the LANGGRAPH_DEPLOYMENT_URL fallback
Keeps:
- Dockerfile.agent: COPY src/ ./src/ (needed for db.csv + a2ui schemas)