The framework picker (sidebar + dropdown) and docs landing integration
grid previously rendered initials-as-image fallbacks (e.g. 'LG', 'Ma',
'Py') from /logos/<slug>.svg placeholder files. Replace with inline
SVG icons that use currentColor so they tint with the surrounding
text and adapt to light/dark mode.
Covers langgraph (python/typescript/fastapi), mastra, pydantic-ai,
crewai, agno, ag2, llamaindex, strands, google-adk, microsoft (ms-
agent-python/dotnet), claude-sdk (anthropic mark), and spring-ai.
Slugs without a branded mark fall through to the existing placeholder
SVG (currently only langroid).
Mirrors the upstream docs nav by adding a Free Developer Access link
to cloud.copilotkit.ai in the BrandNav, persistent across both the
CopilotKit and AG-UI tabs. Renders with cloud icon + external-link
arrow on desktop (icon-only below 1100px) and as a row in the mobile
slide-out menu.
## Summary
- Retire the `/unselected/*` content tree — 47 files
promoted/deleted/redirected to canonical homes; catch-all redirect
funnels any remaining inbound URLs through soft-default routing.
- Consolidate `/learn/*` — explanation-tier pages absorbed into
Concepts, the multi-conversation tutorial moved to `/tutorials/`, the
open-json-ui spec to `/generative-ui/`, and What's New promoted to its
own top-level section.
- New Agentic Protocols subgroup under Get Started — Overview / AG-UI /
MCP / A2A. Intelligence Platform + Threads explanation pages moved to
the Enterprise section. `generative-ui-overview` and
`three-types-of-gen-ui` merged into a single Generative UI Overview
page.
- Tutorials polish — Prev/Next on every step, Card link styling fixed
(no prose underline), info strip rewritten as `<div>` to fix
nested-`<p>` hydration error.
- 11 LFS-pointer-stub images replaced with real binaries pulled from the
production CDN at docs.copilotkit.ai.
- MDX hydration fixes: nested `<p>` in `/agentic-protocols/mcp`
Accordion, Card link underline escape via `not-prose`.
## Test plan
- [ ] `/agentic-protocols`, `/agentic-protocols/{ag-ui,mcp,a2a}` render
with no console errors and no broken images
- [ ] `/concepts/generative-ui-overview` renders with all four diagrams
(gen-ui-specs + 3 surfaces)
- [ ] `/premium/intelligence-platform` and `/premium/threads-explained`
render under the Enterprise section
- [ ] `/whats-new` and child pages render under the new top-level
section
- [ ] `/tutorials/multi-conversation-chat` and `/tutorials/ai-todo-app`
step through with Prev/Next on every step
- [ ] `/unselected`, `/unselected/quickstart`,
`/unselected/tutorials/ai-todo-app/overview`, etc. all 308 to canonical
homes
- [ ] `/learn`, `/learn/threads`, `/learn/agentic-protocols`,
`/learn/whats-new/v1-50`, etc. all 308 to canonical homes
- [ ] `/concepts/ag-ui-protocol`, `/concepts/intelligence-platform`,
`/concepts/three-types-of-gen-ui` 308 to their new homes
- [ ] Sidebar shows clean section labels with no duplicate group/page
names
## Summary
- **probe:smoke discovery failure**: `timeout_ms` was 10s — too tight
for Railway enumeration of 35+ services. Increased to 30s (matching
image-drift/qa probes), fixing `discoveryFailed: true`.
- **e2e_smoke:built-in-agent timeout**: Transport auto-detect race in
`CopilotKitProvider` when using `mode: "single-route"`. Without
`useSingleEndpoint`, auto-detect creates a provisional agent that
constructs REST-pattern URLs (`/agent/:id/run`) which don't exist in
single-route mode. Added `useSingleEndpoint` to all 8 built-in-agent
demo pages.
## Test plan
- [ ] Merge and deploy; trigger probe:smoke — should discover 35/35
- [ ] Trigger e2e-smoke — built-in-agent should complete instead of
timing out
- [ ] Verify other probes unaffected (image-drift, e2e-deep already
green)
The built-in-agent runtime uses mode: "single-route" which means all
requests go to a single POST endpoint (/api/copilotkit). Without
useSingleEndpoint, the CopilotKitProvider defaults to transport: "auto"
which auto-detects by trying GET /info first (404 from Next.js), then
falls back to single-endpoint POST. During this auto-detect window,
the provisional agent created by useAgent() has transport: "auto",
which constructs REST-style URLs (/api/copilotkit/agent/default/run)
that don't exist in single-route mode. If the user sends a message
before auto-detect completes, the request hits a Next.js 404 and the
run silently fails, causing the e2e-smoke probe to time out waiting
for an assistant response.
Adding useSingleEndpoint to all 8 demo pages forces transport:
"single" from initialization, so both the provisional agent and the
final agent use the correct single-endpoint POST format from the
start.
Split inline type imports into separate import-type statements per
oxlint consistent-type-specifier-style rule. Prefix unused connection
parameter. Apply oxfmt formatting.
Stats bar shows health/parity/docs summary counts that appear/hide
based on active overlays. Legend renders color-coded keys for each
active overlay layer.
OverlayColumnHeader shows health strip, parity badge, and tally based
on active overlays. RefDepthColumn is a frozen column pinned after the
feature name that appears when the parity overlay is active.
Stacks 4 overlay content layers (Links, Depth, Health, Docs) into a
single matrix cell. Each layer renders only when its overlay is active,
driven by the shared overlays Set from useOverlays.
Pill-style toggle bar for 5 overlay layers with 3 presets (Default,
Developer, Ops). Each pill shows active state; presets apply curated
overlay combinations with one click.
The smoke probe's timeout_ms (10s) was configured when the probe used a
static target list. After migrating to discovery-driven enumeration via
railway-services, the same timeout_ms governs the Railway enumerate
call — a project-level GraphQL query plus per-service variable lookups
(bounded at concurrency 8). With 35+ services, enumerate alone can take
5-12s on a slow tick, causing persistent discoveryFailed:true.
Increasing to 30s matches image-drift and qa (both Railway-discovery
probes that work reliably at this fleet size).
Root cause: timeout_ms is shared between discovery enumerate and
per-target driver invocation. 10s was appropriate for the driver
(3 sequential HTTP GETs) but too tight for the discovery phase
that queries Railway's API for every showcase service.
Remove the decommissioned "starter" shape type from 4 probe drivers
(e2e-deep, e2e-parity, e2e-readiness, qa) and their test files.
Starters no longer exist in the showcase fleet so the short-circuit
guards, type unions, and test cases are dead code.
- Narrow shape type unions from "package" | "starter" to "package"
- Remove starter short-circuit early-return blocks in all 4 drivers
- Remove starter-specific test cases from all 4 test files
- Clean up starter-referencing comments throughout
Showcase starters have been decommissioned. Remove all starter-specific
logic from the liveness and e2e-chat-tools probe drivers:
- Remove starter branch from deriveUrls() in liveness driver
- Remove E2eSmokeStarterSignal type and starter short-circuit from
e2e-chat-tools driver
- Remove all starter-shape test cases from both test files
- Clean up doc comments referencing showcase-starter-* patterns
All package-shape logic and tests remain intact (60 tests passing).
Showcase starters have been decommissioned. Remove the "starter" shape
from ShowcaseServiceShape (now a z.literal("package") instead of
z.enum), remove the showcase-starter-* regex and classification logic
in classifyShape(), remove the isOneEditDistance typo-nudge helper,
and clean up all starter-related comments and jsdoc. Update tests to
remove all starter fixtures, assertions, and test cases while keeping
all package-shape tests passing.
Remove residual showcase-starter-* references now that starters are
decommissioned:
- Delete showcase/ops/config/alerts/smoke-red-tick.yml (starter-only
alert rule with kind: starter filter)
- Delete showcase/ops/test/fixtures/rules/valid/smoke-red-tick.yml
(test fixture mirroring the deleted alert rule)
- Update showcase/ops/config/probes/smoke.yml comments to remove
showcase-starter-ag2 example and 34-service count
- Update showcase/ops/scripts/test-notify-ops-jq.sh to remove starter
build job fixtures and starter service names from jq partition test
- Update showcase/scripts/verify-railway-image-refs.ts to remove
showcase-starter-<slug> from canonical shape comment
The monitoring/alerting service is a test harness (probes, assertions,
alerting), not an operations service. Rename the directory, package
name (@copilotkit/showcase-ops → @copilotkit/showcase-harness), all
internal references (Dockerfile, Prometheus metric prefix
showcase_ops_ → showcase_harness_, orchestrator log messages, probe
YAML nameExcludes, test fixtures), and regenerate pnpm-lock.yaml.
Wire protocol names (X-Ops-* headers) and shell-dashboard internal
API naming (OPS_BASE_URL, ops-api.ts) are intentionally unchanged —
they are stable contracts between sender and receiver.
## Summary
- Switch the built-in-agent copilotkit route from multi-route (default)
to single-route mode
- Remove the `withProbeCompat` 404-to-400 wrapper (no longer needed)
## Why
The smoke probe POSTs a v1-style JSON envelope `{method, params, body}`
to `/api/copilotkit`. In multi-route mode, the v2 runtime tries to match
URL patterns (e.g. `/agent/:agentId/run`) and returns 404 for bare
`/api/copilotkit` POSTs. The `withProbeCompat` wrapper converted 404 to
400, but the smoke probe needs the runtime to actually parse the request
and return a real response, not just a non-404 status.
Single-route mode accepts the JSON envelope format directly, so the
smoke probe's `{method: "agent/run", params: {agentId: "default"}, body:
{...}}` payload is properly parsed and dispatched to the agent handler.
## Test plan
- [ ] Verify smoke:built-in-agent turns green after deploy
- [ ] Verify the copilotkit endpoint still handles normal agent/run
requests
## Summary
- Rename 3 confusingly-named probe driver files to reflect what they
actually do:
- `smoke` → `liveness` (HTTP liveness check, not a smoke test)
- `e2e-smoke` → `e2e-chat-tools` (Playwright chat + tool-rendering test)
- `e2e-demos` → `e2e-readiness` (Playwright structural check across all
demos)
- Reorder cell drilldown popup: D6 Parity → D5 Deep → E2E → Health →
Smoke (highest depth first)
Kind strings, PB dimension keys, and YAML configs are intentionally
unchanged — this is a file/export rename only with no data migration.
## Test plan
- [x] All 1343 showcase/ops tests pass
- [x] All imports verified via grep — zero stale references
- [x] YAML→driver mapping verified (loader uses kind strings, not file
paths)
- [x] 7-agent CR converged Round 1 with 0 findings
The previous commit (993746111) bundled image fixes with a structural
nav change that wasn't asked for. The ask was simply "rename the page
to Overview so there is no duplicated item in the nav" — a frontmatter
title change, nothing more.
Reverting just the structural pieces:
- agentic-protocols/overview.mdx → index.mdx (back to original filename)
- agentic-protocols/meta.json: pages list back to ["index", ...]
- top-level meta.json: drop "---Agentic Protocols---" section header so
agentic-protocols stays as a subgroup under Get Started
- next.config.ts: drop the new /agentic-protocols → /overview redirect;
restore /concepts/agentic-protocols and /learn/agentic-protocols
redirect targets to /agentic-protocols (not /overview)
The page's frontmatter title stays "Overview" — that part of 993746111
was the actual ask and it solves the duplicate-label problem on its own.
Image fixes from 993746111 are kept.
## Replaced 11 LFS-pointer-stub images with real binaries
The repo stores several diagram PNGs in Git LFS and the local clone
didn't have them resolved (git-lfs not installed). They were 131-byte
text-pointer files on disk, so every page that referenced them
showed a broken-image icon. Affected images:
- any-agentic-backend-{light,dark}.png (used on /agentic-protocols
overview, /agentic-protocols/a2a, /agentic-protocols/mcp)
- agui-ecosystem-{light,dark}.png (/agentic-protocols/ag-ui)
- mcp-and-a2a-through-agui-{light,dark}.png (overview)
- gen-ui-specs-{light,dark}.png (/concepts/generative-ui-overview)
- ai-protocol-stack.png, ag-ui-overview-with-partners-dark.png,
a2ui-composer.png (referenced from various promoted pages)
- generative-ui/{chat,chat-plus,chatless}-surface.png (the surfaces
section in /concepts/generative-ui-overview — these were missing
from public/images entirely after the gen-UI merge; copied from
upstream first, then replaced with the real binaries from the live
docs site since upstream's copies are also LFS stubs)
Source: production docs site at docs.copilotkit.ai/images/* (HTTP 200
on every file). Pulled via curl, sizes range 128KB–714KB — real
binaries, not pointers.
## Agentic Protocols promoted to its own section
Per design call: "Agentic Protocols" is now a top-level section
between Get Started and Build Chat UIs (was wedged into Get Started
as a spread group, which produced an awkward duplicate label —
"Agentic Protocols" group label with an "Agentic Protocols" page
entry inside it).
Changes:
- `agentic-protocols/index.mdx` renamed to `overview.mdx` so the
nav slug is `/agentic-protocols/overview` (was the ugly
`/agentic-protocols/index` because buildNavTree pushed `"index"`
through as a literal slug).
- The page's frontmatter title is now "Overview" (was "Agentic
Protocols", which duplicated the section header in the nav).
- `agentic-protocols/meta.json` lists `["overview", "ag-ui", "mcp",
"a2a"]`.
- Top-level `meta.json` adds `---Agentic Protocols---` section header
before the spread, dropping the wedged `...agentic-protocols` from
inside Get Started.
- `next.config.ts` adds `/agentic-protocols → /agentic-protocols/overview`
redirect (the bare path used to resolve via `index.mdx`; now needs
to land on the renamed overview page). The earlier `/learn/...`
and `/concepts/...` redirects for the same target updated to point
at `/overview` directly.
## Sidebar reads cleanly now
GET STARTED
Quickstart, Coding Agents, Concepts (3-page subgroup)
AGENTIC PROTOCOLS
Overview, AG-UI, MCP, A2A
BUILD CHAT UIS
...
The first Accordion body wrapped two paragraphs of prose in a manual
`<p>...</p>` tag. MDX auto-wraps each blank-line-separated paragraph
in its own `<p>`, so the rendered output became `<p><p>...</p><p>...</p></p>`
— invalid HTML and a hydration error in the browser.
Removed the outer `<p>` wrapper; the prose now relies on MDX's
default paragraph wrapping. Also fixed a typo in the same block
("a server the suits your needs" → "a server that suits your needs").
Inherited from the upstream `learn/connect-mcp-servers.mdx` source.
Verified zero nested-`<p>` occurrences across all 13 of the
moved/promoted pages on this branch.
Tightens the Concepts subgroup (which had ballooned to 10 entries
after the /learn/ consolidation) and gives the protocol pages and
Enterprise-flavoured explanation pages the homes they actually
belong in.
## Structural changes
**New `Agentic Protocols` section under Get Started.** The four
protocol-related pages move from `/concepts/*` into a dedicated
`/agentic-protocols/` folder so they live as a coherent section
rather than as four siblings inside Concepts. Titles drop the
`(Agents<->X)` parenthetical — folder + section context already
disambiguates.
/concepts/agentic-protocols → /agentic-protocols (now the section overview)
/concepts/ag-ui-protocol → /agentic-protocols/ag-ui
/concepts/mcp-servers → /agentic-protocols/mcp
/concepts/a2a-protocol → /agentic-protocols/a2a
`agentic-protocols/meta.json` lists the four pages with the section
overview as `index`. Top-level `meta.json` adds `...agentic-protocols`
under Get Started.
**Intelligence Platform + Threads explanation pages move to
Enterprise.** Both pages document Premium-only architecture
(threads + the platform that hosts them); they belong next to the
how-to and self-hosting pages, not in framework-agnostic Concepts.
/concepts/intelligence-platform → /premium/intelligence-platform
/concepts/threads → /premium/threads-explained
(renamed to disambiguate from
the existing how-to /threads)
`premium/meta.json` reordered so the explanation pages sit between
the overview and the how-to pages.
**Generative UI Overview merged.** The old
`concepts/generative-ui-overview.mdx` (long, with surfaces /
attributes / patterns / ecosystem mapping sections, but using
inconsistent terminology — "Static" vs "Controlled") and
`concepts/three-types-of-gen-ui.mdx` (concise, sharp prose, canonical
"Controlled / Declarative / Open-Ended" terminology that matches the
Build Generative UI nav section names) overlapped substantially.
Merged into a single `concepts/generative-ui-overview.mdx` with:
- Tight intro from three-types
- Application Surfaces section (chat / chat+ / chatless) from overview
— unique value, not duplicated elsewhere
- Three types section using three-types' prose + terminology, with
the tradeoff bullets borrowed from overview's PatternCard component
- Ecosystem Mapping table from overview, retitled with the unified
terminology
- "AG-UI / CopilotKit are gen-UI agnostic" closer with the dual
light/dark image
- "Where to go next" pointers for downstream guides
three-types-of-gen-ui deleted; redirect catches any inbound link.
## `<Image>` registry fix (load-bearing)
The MDX `<Image>` component was registered to destructure only `src`
and `alt`, silently dropping `className`. Every page that ships dual
light/dark variants (`block dark:hidden` / `hidden dark:block`)
rendered both versions stacked — the user-visible "duplicate image"
on agentic-protocols (and the same shape on ag-ui, a2a, mcp, the
gen-UI overview).
Updated the registry component to forward `className`, `width`, and
`height`. The dark/light Tailwind toggling now works as authored.
## Concepts post-restructure
After the moves, the Concepts subgroup is back to a focused set:
architecture
generative-ui-overview
oss-vs-enterprise
These are the framework-agnostic 5-minute primers under Get Started.
Everything that was specifically about a protocol, the Intelligence
Platform, or threads has a more accurate home.
## Redirects
Per-path rules in `next.config.ts` for every URL that was live
between the /learn/ consolidation pass and this restructure:
/concepts/agentic-protocols → /agentic-protocols
/concepts/ag-ui-protocol → /agentic-protocols/ag-ui
/concepts/mcp-servers → /agentic-protocols/mcp
/concepts/a2a-protocol → /agentic-protocols/a2a
/concepts/intelligence-platform → /premium/intelligence-platform
/concepts/threads → /premium/threads-explained
/concepts/three-types-of-gen-ui → /concepts/generative-ui-overview
The earlier /learn/ rules also rewritten to point straight at the
new canonical homes (avoiding 308→308 chains).
## Inbound link rewrites
All cross-page links in the moved pages, plus the architecture
concept page, oss-vs-enterprise concept page, threads how-to,
premium/self-hosting, useCapabilities reference, and the snippets
that referenced the old `/concepts/*` paths. Verified zero remaining
references to the old URLs (except the irrelevant external
`learn.microsoft.com` URLs in MS Agent Framework integration pages).
## Smoke tested
All 9 new canonical URLs return 200. All 10 sampled redirects
(7 /concepts/* + 3 /learn/*) hit the right destination in one hop.
The upstream `/learn/*` tree was largely a Diátaxis explanation-tier
parallel to the rest of the docs, and after the IA restructure shipped
the Concepts subgroup under Get Started in PR #4329, /learn/* read as
visible duplication: two "Threads" entries, two "Architecture"
entries, two "AG-UI" pages, etc. The earlier Notion plan kept the
split and proposed a nav-label fix; this PR reverses that call and
folds the explanation pages into Concepts where they belong.
## What moved
**Promoted to /concepts/** (7 files):
- learn/threads.mdx → concepts/threads.mdx
- learn/intelligence-platform.mdx → concepts/intelligence-platform.mdx
- learn/agentic-protocols.mdx → concepts/agentic-protocols.mdx
- learn/ag-ui-protocol.mdx → concepts/ag-ui-protocol.mdx
- learn/a2a-protocol.mdx → concepts/a2a-protocol.mdx
- learn/connect-mcp-servers.mdx → concepts/mcp-servers.mdx (renamed)
- learn/generative-ui/index.mdx → concepts/generative-ui-overview.mdx
The new Concepts subgroup is a 10-page cluster covering architecture,
the Intelligence Platform, the three gen-UI types + a deep overview,
the four agentic protocols (AG-UI, MCP, A2A, plus the meta page), and
threads + OSS-vs-Enterprise. Ordered by topic flow rather than
alphabetically.
**Moved to natural homes**:
- learn/tutorials/multi-conversation-chat.mdx → tutorials/multi-conversation-chat.mdx
- learn/generative-ui/specs/open-json-ui.mdx → generative-ui/open-json-ui.mdx (added under "Declarative" in the gen-UI nav alongside A2UI)
**Promoted to top-level /whats-new/**: 7 files. New top-level
nav section between Tutorials and Migrate. Release-cadence content
doesn't belong inside Concepts; promoting it gives it room to grow as
a real changelog.
**Deleted** (5 files, all stubs or duplicates):
- learn/index.mdx (the Learn landing — its card grid pointed at the
pages above, all of which now live elsewhere)
- learn/architecture.mdx (15L stub: just a heading + the same
ImageZoom that already lives in /concepts/architecture)
- learn/generative-ui/specs/{index, a2ui, mcp-apps}.mdx (7-line
component-stubs already covered by their canonical
/generative-ui/* pages)
- learn/generative-ui/{meta.json, specs/meta.json} + learn/meta.json
(now-empty meta scaffolding)
## Nav updates
- concepts/meta.json grows to 10 pages, ordered by topic cluster
- tutorials/meta.json adds multi-conversation-chat
- generative-ui/meta.json adds open-json-ui under "Declarative"
- whats-new/meta.json gets a clean "What's New" title (was a dated
"Updates - Jan 22, 2025") + the full file list in reverse-chrono
- top-level meta.json gets a new "What's New" section between
Tutorials and Migrate
## Redirects
15 redirect rules in next.config.ts cover every /learn/* path that
existed (literal pages + the /learn/whats-new/:path* and
/learn/generative-ui/specs/* sets). Plus a generic /learn → /concepts/architecture
catch-all so the old root URL doesn't 404.
## Inbound link rewrites
22 inbound /learn/* references rewritten across the docs tree
(snippets, threads.mdx, premium/self-hosting.mdx, useCapabilities,
useThreads, the existing Concepts pages that linked to /learn/*, and
internal cross-links inside the moved files themselves). Verified zero
remaining /learn/ references except the unrelated `learn.microsoft.com`
external URLs in the MS Agent Framework integration pages.
## Smoke tested
All 12 new canonical URLs return 200. All 8 sampled /learn/* legacy
URLs 308-redirect to the correct canonical home (/concepts/*, /tutorials/*,
/generative-ui/*, /whats-new/*).
Closes PDX-69.
Two follow-ups from the tutorial walkthrough.
**Standalone Card link styling.** Cards used outside a `<Cards>`
wrapper (the GitHub source link on tutorial overviews; the lone Next
card on step-1 before this commit) still showed prose-style
underlines. Reason: the escape-hatch CSS rule
`.reference-content .not-prose a { text-decoration: none }` is a
*descendant* selector — it requires `not-prose` to live on a parent
of the <a>. Standalone Cards have nothing above them carrying that
class, so the rule never fired. Cards inside `<Cards>` were fine
because the wrapper has `not-prose`.
Fixed by adding inline `style={{ textDecoration: "none", color:
"inherit" }}` to the linked Card. Inline styles win on specificity
in every shape, regardless of whether `not-prose` is present on a
parent. The class-based `not-prose` + `no-underline` stay too —
they're harmless and serve as documentation of intent.
**Previous on step-1.** Earlier "steps 2-end need Previous" was read
too literally; step-1 of both tutorials wasn't getting a Previous
link back to overview. Added Previous + Next pairs (in `<Cards>`
2-column grid) on step-1 of both tutorials, matching the layout used
on step-2 / step-3 / step-4.
The full chain now:
overview → Next only
step-1 → Prev (Overview) + Next
step-2 / 3 / 4 → Prev + Next
next-steps → Prev only
MDX wraps loose paragraphs in <p>. The hand-written `<p>` I'd used
for the time/difficulty meta line ended up inside another <p> wrapper
generated by MDX, producing `<p><p>...</p></p>` — invalid HTML and a
hydration error in the dev console.
Switching to a `<div>` keeps the same inline-styled muted-text
appearance without triggering the autoclose-then-reopen behaviour
that React/HTML enforces around block-vs-inline `<p>` rules.
Verified the rendered HTML for /tutorials/ai-todo-app/overview no
longer contains a `<p><p>` sequence.