Resolves conflicts:
- manifest.yaml / constraints.yaml / docs-links.json: keep both byoc-json-render
and main's re-wired open-gen-ui + open-gen-ui-advanced entries
- scripts/hooks/check-binaries.sh: keep both shell-docs and shell-dojo
demo-content exclusions (identical lines, different ordering)
- pnpm-lock.yaml (langgraph-python): regenerated via pnpm install
- shell/shell-dojo/shell-docs data JSONs: accept main's deletion (now
regenerated by nx targets), then regenerate via scripts/generate-registry.ts
and scripts/bundle-demo-content.ts
Bump generate-registry.test expected feature/demo count 32 -> 33 to account
for the new byoc-json-render demo.
Resolves textual conflicts in manifest.yaml and docs-links.json (keeps
both open-gen-ui* from main and agent-config from this branch). Accepts
main's deletion of generated shell*/src/data/*.json (now gitignored).
Bumps langgraph-python feature/demo count test from 32 to 33.
Resolved conflicts:
- showcase/packages/langgraph-python/manifest.yaml: kept auth (HEAD) +
open-gen-ui / open-gen-ui-advanced (main) in both features and demos.
- showcase/packages/langgraph-python/docs-links.json: kept auth entry
from HEAD alongside updated subagents shell_docs_path.
- showcase/shared/constraints.yaml: kept auth + open-gen-ui* entries.
- Deleted shell/shell-dojo/shell-docs generated JSONs per main (now
generated at build, no longer committed).
Bumped langgraph-python feature/demo count 32 -> 33 in generate-registry
test to reflect the added auth demo.
## Summary
Widens the e2e-demos probe from LangGraph Python only (Wave 1) to all 17
integrations. Every integration now gets per-demo D3 structural checks —
the probe visits each `/demos/<featureId>` route and verifies the
copilot-chat-input selector renders.
Changes:
- `namePrefix`: `"showcase-langgraph-python"` → `"showcase-"` (full
fleet)
- `max_concurrency`: 1 → 2 (halves wall time for 17 services)
- `timeout_ms`: 600000 → 900000 (headroom for ~136 routes)
No driver code changes — the e2e-demos driver is already generic. The
infra `nameExcludes` list already drops non-demo services.
## Test plan
- [ ] Next e2e-demos tick (*/6h) produces `e2e:<slug>/<featureId>` rows
for all integrations
- [ ] Dashboard Cells tab shows D3 depth for non-LGP integrations
Relaxes the namePrefix filter from "showcase-langgraph-python" (Wave 1)
to "showcase-" (full fleet). All 17 integrations now get per-demo D3
structural checks — goto each /demos/<featureId> route + verify the
copilot-chat-input selector renders.
Also bumps max_concurrency from 1 to 2 (halves wall time for 17
services) and timeout from 600s to 900s (headroom for ~136 routes at
~5s each worst-case).
The infra nameExcludes list already drops non-demo services. No driver
code changes needed — the e2e-demos driver is already generic.
Seven concurrent useLiveStatus hooks each opened their own PocketBase
SSE connection during hydration. The PB SDK multiplexes subscriptions
over a single EventSource, but the concurrent subscribe() calls raced
the initial SSE handshake — some POST /api/realtime calls fired before
the clientId was available, returning 400. After MAX_RECONNECT_ATTEMPTS
(3), affected hooks set connection="error", triggering the "dashboard
unavailable" banner on all tabs.
Fix: replace 7 per-dimension hooks with a single useLiveStatus() call
(no dimension filter). All rows are fetched in one subscription and
the existing client-side keyFor() lookups filter by dimension
implicitly. Eliminates the 7-way race, reduces PB connection count
from 7 to 1, and removes the aggregateConnection helper entirely.
Verified live at dashboard.showcase.copilotkit.ai — zero banners, all
four tabs show real PB data with D2/D4 depth chips.
Three fixes batched to minimize PR churn:
1. Dockerfile: add ARG NEXT_PUBLIC_POCKETBASE_URL so the PB URL gets
baked into the Next.js bundle at build time. Without this, pb.ts
resolves to the sentinel URL and the dashboard shows "unavailable"
on every tab. Pre-existing bug exposed by fresh deploys.
2. showcase_deploy.yml: pass NEXT_PUBLIC_POCKETBASE_URL and
NEXT_PUBLIC_SHELL_URL as build args for the shell-dashboard service
in the CI matrix. Neither was ever passed before.
3. cell-matrix.tsx + parity-matrix.tsx: flatten nested table pattern
that caused column misalignment. Category rows used colSpan with
an inner <table> whose columns floated independently of the header.
Replaced with useCollapsible hook + flat sibling <tr> rows.
Also regenerates package-lock.json for the plugin-react downgrade
from PR #4241 (npm ci was failing in Docker).
Local Docker build verified with --build-arg for both NEXT_PUBLIC vars.
## Summary
- **ag2**: Add `max_consecutive_auto_reply=15` to `ConversableAgent` to
prevent infinite tool-call loops that flood Railway's log stream at 500+
logs/sec and starve health probes
- **agno**: Raise `OpenAIChat` timeout from default to 120s (aimock
proxy latency) and add `tool_call_limit=15` safety net
## Root Cause
**ag2 (9/12 ticks 503)**: AG2's `ConversableAgent` with
`human_input_mode="NEVER"` has no built-in turn limit. When the LLM
enters a repetitive tool-call pattern (observed: hundreds of
`get_weather(Tokyo)` calls per second), the agent loops indefinitely.
This generates 500+ log lines/sec hitting Railway's rate limit, the
agent becomes unresponsive to health probes, the watchdog kills it after
90s, and the container restarts. Cycle repeats.
**agno (3/12 ticks 503)**: The agno `OpenAIChat` model uses httpx's
default timeout, which is too short when requests route through the
aimock proxy under load. Observed `"Error in Agent run: Request timed
out."` in logs followed by agent restart. Less frequent than ag2 because
it only happens under concurrent load.
## Test plan
- [ ] Deploy ag2 and agno via CI (push to main triggers showcase_deploy)
- [ ] Monitor health for 30 min post-deploy: `curl
showcase-ag2-production.up.railway.app/api/health`
- [ ] Verify Railway logs no longer show rate-limit messages or infinite
tool-call output
- [ ] Verify watchdog kill events drop to zero
The previous commit edited package source files but didn't regenerate
the starters, causing drift-check to fail. Running generate-starters.ts
propagates the max_consecutive_auto_reply, timeout, and tool_call_limit
changes into the starter outputs.
ag2: The ConversableAgent with human_input_mode="NEVER" has no
built-in turn limit, so when the LLM repeatedly requests the same
tool call the agent loops indefinitely. This floods Railway's log
stream at 500+ logs/sec, makes the agent unresponsive to health
probes, and the watchdog kills it every ~90s. Add
max_consecutive_auto_reply=15 to cap the loop.
agno: The OpenAIChat model defaults to httpx's short timeout, which
is insufficient when requests route through aimock. Observed
"Request timed out" errors that crash the agent run. Raise timeout
to 120s and add tool_call_limit=15 as a safety net against runaway
loops.
6.0.1 requires vite ^8.0.0 but pnpm resolves vite 7.3.1, causing
ERR_PACKAGE_PATH_NOT_EXPORTED when vitest loads. 5.2.0 supports
vite ^4-8 and resolves the issue. Pre-existing on main.
Cross-joins 38 features x 17 integrations + 17 starters = 663 cells.
Each cell carries status (wired/stub/unshipped), auto-derived parity
tier, max depth, and human-readable display names from feature-registry
and manifests. Reference integration auto-detected by max wired count.
CSS :last-of-type matches the last element of a given tag type among
siblings, not the last element with a specific data-testid. A trailing
<div> after the assistant message causes zero matches, and Playwright
auto-waits 30s per failed textContent call, exhausting the timeout.
Switch to page.evaluate() with querySelectorAll to find the last
matching element by index. This returns immediately with whatever the
DOM holds, avoiding the 30s auto-wait trap entirely.
## Summary
- Syncs `deployed` flags in `integration-smoke.spec.ts` INTEGRATIONS
array with the source-of-truth `registry.json`
- 4 integrations were stale `deployed: false` but `true` in registry:
**claude-sdk-python**, **claude-sdk-typescript**, **langroid**,
**spring-ai**
- These integrations were silently skipped by the smoke suite
## Test plan
- [x] `npx prettier --check` passes
- [x] `npx playwright test --list` shows all 17 integrations in every
test level
- [ ] CI green
claude-sdk-python, claude-sdk-typescript, langroid, and spring-ai
were marked deployed: false in the smoke test INTEGRATIONS array
but deployed: true in the source-of-truth registry.json. This
caused the smoke suite to skip these four integrations entirely.
## Summary
The top-nav "Integrations" link on shell-docs (and the inline link
inside `IntegrationGrid`) both pointed at `/integrations` on shell-docs
itself — a redundant framework-picker + matrix page that duplicated the
sidebar's framework selector. The real integration explorer (live demos,
filtering, feature browsing) lives on the shell app at `/integrations`.
This PR routes both links to the shell host instead.
## Changes
- `showcase/shell-docs/src/components/brand-nav.tsx` — top-nav
"Integrations" href is now `${NEXT_PUBLIC_SHELL_URL}/integrations`.
- `showcase/shell-docs/src/components/integration-grid.tsx` — inline
"See Integrations" href updated the same way.
- `showcase/shell-docs/next.config.ts` — adds `NEXT_PUBLIC_SHELL_URL`
build-time validation mirroring the existing `NEXT_PUBLIC_BASE_URL`
pattern: throws during `next build` if missing, warns in dev.
- `showcase/shell-docs/src/content/docs/integrations/index.mdx` —
deleted. The redundant page those links targeted. Legacy per-framework
subtrees under `integrations/*` are unchanged.
Components use a localhost:3000 dev fallback via
`process.env.NEXT_PUBLIC_SHELL_URL ?? "http://localhost:3000"` — matches
the existing dev-fallback pattern documented in `next.config.ts` for
`NEXT_PUBLIC_BASE_URL`. No hardcoded prod URLs in the code.
## Prod safety
`next build` fails loudly if `NEXT_PUBLIC_SHELL_URL` is unset. Since
`NEXT_PUBLIC_*` values are inlined at build time, a successful prod
build ships with the correct host baked in; the localhost fallback is
only reachable in dev.
## Test plan
With shell running at `http://localhost:3000` and shell-docs running at
`http://localhost:3003`:
- [ ] Hover the "Integrations" link in shell-docs' top nav — status bar
shows `http://localhost:3000/integrations`
- [ ] Click it — lands on the live `IntegrationExplorer` at
`localhost:3000/integrations`
- [ ] The inline "See Integrations" link rendered by `<IntegrationGrid
/>` (e.g. on `/prebuilt-components`) behaves the same way
- [ ] Visiting `/integrations` on shell-docs directly (e.g.
`http://localhost:3003/integrations`) 404s — the page was deleted
- [ ] Sidebar and other nav elements unchanged
## Summary
- **Gitignore all generated `src/data/*.json` across the 4 shell apps**
— these are regenerated by every build path (Docker, CI, `npm run
build`, `npm run dev`) and don't need to be tracked. Removes 11 blobs
totaling ~28K lines of generated content.
- **Strip `generated_at` timestamps** from all 5 generator scripts and
all consumer interfaces/types — these were the root cause of constant
git noise (every build bumped the timestamp even when content was
identical).
- **Make shell-dashboard independent** — imports now use `@/data/`
instead of cross-importing from `../../../shell/src/data/`.
`probe-docs.ts` writes directly to shell-dashboard. Dockerfile no longer
copies the entire shell package.
- **Fix build scripts** — shell-dojo's `build` now runs generators
before `next build`; shell's `dev` now runs all one-shot generators on
startup (not just demo-content in watch mode).
- **Document generated data files** in `showcase/README.md` with a table
covering all 6 file types, their generators, and which shell apps
consume them.
## Test plan
- [ ] CI passes (scripts, shell builds, dashboard builds)
- [ ] `npm run dev` in each shell app generates fresh data files on
startup
- [ ] `npm run build` in shell-dojo completes (was previously bare `next
build`)
- [ ] shell-dashboard Docker build succeeds without copying shell/
- [ ] No `generated_at` fields in any generated JSON output
- [ ] Generated JSON files no longer show up in `git status` after
build/dev
Add a table covering all 6 generated JSON files, their generator
scripts, which shell apps consume them, and what each file does.
Explains that shells are independent and how to add a new shell app
that needs generated data.
- deploy workflow: add shared/scripts/manifest paths to shell-dashboard
and shell-docs filters (previously triggered implicitly by committed
JSON diffs in those directories)
- capture-previews: add generate-registry step before capture; use
git add -f for the gitignored registry.json
- e2e smoke test: document generator dependency in import comment
Now that generated JSON is gitignored, every path that consumes these
files must run generators first. Fixes:
- shell: add bundle-demo-content to dev preamble (eliminates race
between watcher and Next.js on fresh clone); add
bundle-starter-content to Dockerfile RUN chain
- shell-dojo: add predev hook (generate-registry + bundle-demo-content)
- shell-docs: add predev hook (generate-registry + bundle-demo-content
+ generate-search-index)
- ops: replace direct COPY of gitignored registry.json with
generate-registry.ts at build time (copy scripts+shared+packages,
npm ci, run generator)
Add */src/data/*.json patterns to showcase/.gitignore for all 4 shell
apps. Remove 11 tracked JSON blobs (~28K lines of generated content)
that were causing constant git noise from embedded timestamps and
leaking into PRs on every build/dev run.
Every build path (Docker, CI, npm run build, npm run dev) regenerates
these files — they never needed to be committed.
Shell apps should be independent — no shell cross-imports another
shell's data directory. Replace ../../../shell/src/data/ imports in
shell-dashboard with @/data/ (resolves to src/data/ via tsconfig path
alias). Update Dockerfile to copy shell-docs content (for probe-docs
MDX checks) instead of the entire shell package. Remove unused
bundle-demo-content from dashboard's build pipeline.
Every generator embedded `generated_at: new Date().toISOString()` in its
output, causing constant git noise on every build/dev run even when
actual content was unchanged. Remove the field from all 4 generator
scripts, all consumer interfaces (Registry, BundledContent,
BundledStarters, DocsStatusBundle), inline type casts, and test
assertions.
Also: add shell-dashboard as a generate-registry output directory (it
was cross-importing from shell); move probe-docs output to
shell-dashboard/src/data/ (sole consumer); update test beforeAll to
generate files instead of restoring from git HEAD (prep for gitignore).
Add health-path verification tests that assert getAgentHealthPath()
returns the correct path for every framework, derived from reading the
actual agent server source code. Tests verify:
- Fixture map covers all 17 FRAMEWORKS entries
- getAgentHealthPath(fw) matches the fixture for each framework
- Generated entrypoint.sh watchdog probes the correct URL
- langgraph starters probe /ok, all others probe /health
- Frontend health route uses the correct agent probe path
Also documents langgraph /ok verification: langgraph_cli Python and
@langchain/langgraph-cli TS both serve /ok as the only built-in
health endpoint. /health is NOT served. Keeping /ok is correct.
The Mastra pre-built server returns 404 on /api. The correct health
endpoint is GET /health (returns HTTP 200 {"success":true}). The
watchdog was probing the wrong URL, never seeing success, and killing
the agent after the 600s grace period.
Changes:
- getAgentHealthPath(): mastra returns "/health" instead of "/api"
- getWatchdogGraceSeconds(): mastra grace 600 -> 30 (starts in ~2s)
- Regenerated showcase/starters/mastra/entrypoint.sh
Shell owns /integrations (live explorer) and /matrix (feature matrix),
mirroring shell's existing redirect table that sends /docs/*, /ag-ui/*,
/reference/*, and /<framework>/* to the docs host. Adds the reverse
redirects in shell-docs' next.config so /integrations and /matrix jump
out to showcase.copilotkit.ai at the edge.
Removes the redundant shell-docs framework-picker page at
showcase/shell-docs/src/content/docs/integrations/index.mdx. All internal
links can now use bare /integrations hrefs — the redirect handles the
cross-host jump in production, and in dev it 404s cleanly (no local
page to render). Legacy per-framework subtrees under integrations/* are
unchanged.
## Summary
First round of the snippet-linking sweep: every code fence in shell-docs
should be a `<Snippet>` pointing to real showcase source, not
hand-written inline ```tsx.
Scope on this PR is **prebuilt-components + the unselected twin** — 4
commits, easy per-commit review.
### Commits
- `7efe08ae8` — **Strip hand-written fences from Styling sections** on
all 6 prebuilt-components pages (base + unselected ×
chat/sidebar/popup). Keeps the `## Styling` header, intro copy, and
bullet links to `/custom-look-and-feel/*`; drops only the duplicative
slot-override code.
- `157cdae57` — **Wording pass**: replace "showcase cell" references
with neutral phrasing ("the example below", etc.) across 21 files.
- `f6086011a` — **Snippet-ify the Code example section on both chat.mdx
pages.** Adds a new `@region[chat-component]` to
`showcase/packages/langgraph-python/src/app/demos/agentic-chat/page.tsx`
wrapping the existing `Chat` helper (hook + render). Hand-written tsx
fences on `docs/prebuilt-components/chat.mdx` and
`docs/unselected/prebuilt-components/chat.mdx` replaced with `<Snippet
region="chat-component">`. The three `demo-content.json` bundles are
regenerated to include the new region.
- `ef0823372` — **Snippet-ify variant code blocks on
`unselected/prebuilt-components/index.mdx`.** Three hand-written tsx
fences (CopilotChat, CopilotSidebar, CopilotPopup variants) become
Snippets pointing at `chat-component` (agentic-chat),
`sidebar-basic-setup` (prebuilt-sidebar), and `popup-basic-setup`
(prebuilt-popup). Drops the redundant Deep customization inline example
in favor of a link to the Slots guide.
### Showcase-source change
Only one: `@region[chat-component]` / `@endregion[chat-component]`
markers added around the existing `Chat` helper in
`showcase/packages/langgraph-python/src/app/demos/agentic-chat/page.tsx`
(2 lines, no runtime behavior change).
## Test plan
Run shell-docs at `localhost:3003`.
Prebuilt-components pages (clear framework selection to reach
`/unselected/*`):
- [ ] `/langgraph-python/prebuilt-components/chat` — Basic setup =
`provider-setup` Snippet; Code example = new `chat-component` Snippet
showing the full `Chat` function; Styling = header + intro + 3 bullet
links, no code
- [ ] `/langgraph-python/prebuilt-components/sidebar` — Basic setup =
`sidebar-basic-setup` Snippet; Configuring = `sidebar-configuration`
Snippet; Styling = header + intro + link, no code
- [ ] `/langgraph-python/prebuilt-components/popup` — Basic setup =
`popup-basic-setup` Snippet; Styling = header + intro + link, no code
- [ ] `/unselected/prebuilt-components/chat`, `/sidebar`, `/popup` —
same expected rendering as the langgraph-python variants
Index page (URL-only, not in sidebar):
- [ ] `/unselected/prebuilt-components` — 3 variant subsections
(CopilotChat, CopilotSidebar, CopilotPopup), each showing a real-source
Snippet block; Deep customization is a one-paragraph pointer to Slots,
no code
Replaces the three hand-written tsx fences (CopilotChat, CopilotSidebar,
CopilotPopup variants) with Snippet references pointing at real showcase
regions: chat-component in agentic-chat, sidebar-basic-setup in
prebuilt-sidebar, and popup-basic-setup in prebuilt-popup.
Also drops the redundant Deep customization inline example — the section
already links out to the dedicated Slots guide; a hand-written slot-pattern
example duplicates what that guide covers with real code. Shortened the
lead-in to point readers at Slots for runnable examples.
One fence remains on this page: the 'Setup' section's CSS stylesheet import,
a one-line CLI-style instruction with no corresponding showcase region.
Left inline as a legitimate snippet-linking exception (same pattern used
for npx commands).
Replaces the hand-written tsx fence in the 'Code example' section of both
docs/prebuilt-components/chat.mdx and docs/unselected/prebuilt-components/chat.mdx
with a <Snippet> reference to a new chat-component region in the
langgraph-python agentic-chat demo source.
The new @region[chat-component] wraps the whole Chat helper function in
showcase/packages/langgraph-python/src/app/demos/agentic-chat/page.tsx,
so readers see a self-contained real-code component (hook + render) with
the view-source link that a Snippet provides.
Also regenerates the three demo-content.json bundles to include the new
region.
The voice demo adds two new framework deps (@copilotkit/voice, openai)
to showcase/packages/langgraph-python. The Dojo example doesn't pin
either, so validate-pins emits [FAIL] "is not an exact pin in showcase"
for each. Both use the same non-exact spec style as the already-baselined
@copilotkit/react-core / @copilotkit/runtime entries (next-channel dist
tag + caret range). Bump the drift baseline by 2 so CI accepts the new
deps without lowering the overall pin discipline.