Wave 4a. Port the starter's hashbrown renderer into a dedicated
single-mode langgraph-python demo at /demos/byoc-hashbrown so the
byoc-hashbrown row goes green on the dashboard.
- @hashbrownai/core + @hashbrownai/react + recharts deps added.
- Dedicated /api/copilotkit-byoc-hashbrown route with byoc_hashbrown
graph (ChatOpenAI + CopilotKitMiddleware) and a catalog-aware
system prompt coaching the LLM to emit a <ui>...</ui> envelope.
- Ported MetricCard + bar-chart + pie-chart + chart-config from
showcase/starters/template/frontend with data-testid hooks on
chart roots for E2E coverage.
- Ported hashbrown renderer with local RenderMessageProps /
AssistantMessage types so @copilotkit/react-ui and @ag-ui/core
do not become direct deps of this package.
- Updated hashbrown schema calls to @0.5.0-beta.4 surface:
enumeration for SalesStage; description-first streaming.array +
object; dropped the non-existent .optional() chain.
- v2 CopilotChat uses messageView.assistantMessage slot and
useConfigureSuggestions for 3 canned prompts (sales dashboard /
revenue by category / expense trend).
- QA checklist + Playwright E2E authored (not run pre-deploy).
- Manifest / constraints / docs-links updated and derived registry +
demo-content + docs-status bundles regenerated.
- Extend scripts/hooks/check-binaries.sh whitelist to include the
shell-docs and shell-dojo demo-content bundles so the pre-commit
hook does not reject the regenerated 1.5 MB files it produced.
Wire CopilotChat AttachmentsConfig (image + PDF, inline base64) into a
dedicated /demos/multimodal cell backed by a vision-capable LangGraph
agent (gpt-4o). Scoped to its own runtime route so the vision cost
stays on this demo.
- Dedicated /api/copilotkit-multimodal route registering the new
multimodal graph under the multimodal-demo slug
- src/agents/multimodal_agent.py with an AgentMiddleware that flattens
PDF content parts to text server-side via pypdf
- Try with sample image / PDF buttons that drive CopilotChats own
hidden file input via DataTransfer + change event, so the sample and
paperclip paths exercise the same useAttachments pipeline
- public/demo-files/ placeholder — sample.png / sample.pdf binaries
are produced by the user at the end of the Wave 2b rollout
- Manifest + registry + constraints + docs-links wired; normalized
multi-modal -> multimodal in constraints to match the feature
registry id
- QA checklist + Playwright E2E spec (not run yet — pending deploy)
- aimock fixtures for sample prompts so CI runs are deterministic
- Extend the check-binaries hook allowlist to cover the shell-docs and
shell-dojo demo-content.json mirrors (same size as shell/src/data,
already allowed) so regenerated derived data can be committed
Integrates @json-render/{core,react} as an alternative BYOC generative-UI
rendering technology in langgraph-python, paired with Wave 4a's hashbrown
demo. Both demos share the same sales-dashboard catalog (MetricCard +
BarChart + PieChart) so the dashboard rows are directly comparable.
- Adds @json-render/{core,react} @ 0.18.0 pinned.
- New /demos/byoc-json-render page using CopilotChat's messageView.assistantMessage
slot to bridge CopilotKit output into @json-render/react Renderer.
- New /api/copilotkit-byoc-json-render route + byoc_json_render graph in
langgraph.json.
- Zod-validated catalog reusing @json-render/react/schema's prebuilt spec shape.
- System prompt with 3 worked examples inlined so the agent emits valid
{ root, elements } JSON deterministically.
- QA checklist + Playwright spec authored (E2E run deferred to post-deploy
stabilization).
- Adds shell-docs/shell-dojo demo-content.json to the check-binaries.sh
allowlist (same 1MB-allowed rationale as shell/demo-content.json).
Framework-native request authentication demo for the langgraph-python
showcase. Demonstrates both the unauthenticated (401) failure path and
the authenticated success path via a shared bearer token.
- New /demos/auth page with sticky AuthBanner + in-memory React auth state
- Dedicated /api/copilotkit-auth runtime route using createCopilotRuntimeHandler
from @copilotkit/runtime/v2 with an onRequest hook validating
Authorization: Bearer demo-token-123
- Shared DEMO_TOKEN constant imported by both client and server to prevent drift
- <CopilotKit headers={...}> injects Authorization reactively when authenticated
- Page-level error surface captures 401s via onError and renders a stable
data-testid=auth-demo-error for QA + E2E assertions
- QA checklist + Playwright E2E spec authored (E2E run deferred to post-deploy)
- Manifest, feature list, docs-links, constraints, and derived registry /
demo-content / constraints / docs-status data regenerated
- Allowlist shell-docs / shell-dojo demo-content.json in the binary-size
pre-commit hook (mirrors the Wave 2a voice commit; they are bundled
fixtures already over 1 MB on main)
Declare open-gen-ui and open-gen-ui-advanced in langgraph-python
manifest (code existed, was never registered). Add both to
constrained-explicit allowlist, fill shell_docs_path for 5 demos,
add hitl-in-app override, drop stale chat-customization-css fallback.
Regenerate registry.json, demo-content.json, constraints.json,
and docs-status.json across shell / shell-dojo / shell-docs.
Bump feature/demo count assertion 30→32 in generate-registry test.
Extend check-binaries.sh whitelist for sister-shell demo-content.
The scrub and #4084 touched the same surface: #4084 re-added an `open:`
generative_ui profile listing `open-gen-ui`/`open-gen-ui-advanced`, and
re-added both features to `constrained-explicit.allowed`. Extending the
branch's scrub to both re-additions keeps the semantic consistent with
the schema (which already dropped `open` from the approaches enum).
- `showcase/shared/constraints.yaml`: drop `open-gen-ui` +
`open-gen-ui-advanced` from `constrained-explicit.allowed`; drop main's
re-added `open:` profile entirely.
- `showcase/packages/langgraph-python/manifest.yaml`: drop the now-orphan
`open-gen-ui` + `open-gen-ui-advanced` feature and demo entries
(validator confirmed they had no allowed approach left).
- Regenerated `showcase/shell/src/data/registry.json` + sibling
`shell-docs`/`shell-dojo` registries and `constraints.json` via
`pnpm --dir showcase/scripts generate-registry`. All 17 integrations
validate.
`feature-registry.json` intentionally still defines both features — the
original scrub commits (2b996c54d, 27f886e59) left it untouched, so the
demo source files on disk also stay. Follow-up deletion if desired is
out of scope for this merge.
Reorders gen-ui-agent (Agentic Generative UI / In-Chat State Rendering)
to appear AFTER Reasoning (Default Render) in the Operational
Generative UI category, per user preference.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
gen-ui-interrupt and hitl-in-chat both render an interactive time-picker
inline in the chat, but via different API layers:
- gen-ui-interrupt -> useInterrupt (low-level primitive)
- hitl-in-chat -> useHumanInTheLoop (ergonomic wrapper)
Rename to make the dashboard row label reflect the API distinction.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Introduces the "Frontend Tools (Async)" showcase cell — the async sibling
to the in-app-actions "Frontend Tools" cell. Demonstrates the canonical
async useFrontendTool pattern where the handler awaits a real client-side
async operation and RETURNS A RESULT the agent uses.
Concept: a simulated client-side "notes database" query. The frontend
registers a `query_notes` tool whose async handler sleeps 500ms (emulating
IndexedDB / localStorage / local-cache latency) then filters an in-browser
notes array by keyword and returns matching notes. The agent awaits the
result and summarizes matches for the user.
Files:
- src/agents/frontend_tools_async.py — helpful-assistant graph with no
backend tools; system prompt instructs the model to call `query_notes`
for note searches (schema is injected at runtime from the frontend via
CopilotKitMiddleware)
- src/app/demos/frontend-tools-async/page.tsx — CopilotKit provider +
CopilotChat, `useFrontendTool({ handler: async (...) => { await sleep;
return matches; } })` + per-tool render hook that shows a branded
NotesCard, `useConfigureSuggestions` with three prompts
- src/app/demos/frontend-tools-async/notes-card.tsx — emerald/teal
gradient card listing matched notes with tag chips
- langgraph.json — register `frontend_tools_async` graph
- manifest.yaml — features list + demos entry
- feature-registry.json — expanded description + docs URLs point to the
canonical /frontend-tools docs (shared with the sibling cell)
- constraints.yaml — added to all three generative_ui profiles
- docs-links.json — langgraph-python override pointing at /frontend-tools
Validated end-to-end: agent successfully calls `query_notes` with keywords
extracted from natural-language prompts, awaits the async handler, and
summarizes the returned notes for the user.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Clarify the positioning of the In-App Human in the Loop cell. The old
label was ambiguous with the in-chat variant; the new label surfaces
the core technical story at-a-glance: this is the async useFrontendTool
pattern where the approval UI pops up OUTSIDE the chat surface.
Also register the cell in the langgraph-python manifest (features list
+ demos entry pointing to the new files).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The advanced variant's distinguishing feature is that the agent-authored,
sandboxed UI can invoke frontend-registered sandbox functions via
Websandbox.connection.remote.<name>(args). The old label "(Advanced)"
did not convey this. Rename to "Open-Ended Gen UI (Advanced: with
frontend function calling)" in both the feature registry and the
langgraph-python manifest, and update descriptions to match. The id
stays `open-gen-ui-advanced` so URLs remain stable.
Regenerate derived bundles (registry.json, demo-content.json,
docs-status.json).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The "Declarative Generative UI (A2UI — Custom Catalog)" single-file
prototype variant was a testing-only companion to the canonical
declarative-gen-ui 3-file BYOC pattern. Drop it everywhere:
- Delete src/app/demos/declarative-gen-ui-hardcoded/ cell directory
- Delete src/agents/a2ui_dynamic_hardcoded.py
- Remove from langgraph-python manifest.yaml (features + demos) and
langgraph.json graphs
- Remove from docs-links.json, route.ts (agent entry + a2ui agents
list), shared/feature-registry.json, shared/constraints.yaml
- Drop the Callout promoting it from a2ui/dynamic-schema.mdx
- Bump expected langgraph-python count 32 → 31 in generate-registry
test; regenerate all bundles
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pre-Built: Chat was redundant with Pre-Built: CopilotChat — both rows
referred to the same CopilotChat surface with slightly different
framing. Drop prebuilt-chat everywhere:
- Delete src/app/demos/prebuilt-chat/ cell directory
- Remove from langgraph-python manifest.yaml features + demos
- Remove from shared/feature-registry.json features + chat-ui allowlist
- Remove from shared/constraints.yaml constrained-explicit
- Remove from src/app/api/copilotkit/route.ts neutral-fallthrough list
- Update expected counts in bundle-demo-content + generate-registry
tests (langgraph now exposes 32 features, down from 33)
- Fix stale src/agents/main.py test expectation to
src/agents/agentic_chat.py (main.py was split into a neutral assistant
by an earlier Phase-1 fix commit)
- Regenerate shell/src/data/{registry,constraints,demo-content,
docs-status}.json
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add prebuilt-chat feature to the registry and constrained-explicit
allowlist so the 4085 manifest's intentional prebuilt-chat wiring
validates cleanly (4084 omits it; 4085 committed the cell earlier)
- Bump expected langgraph-python feature count in generate-registry
test from 32 to 33 to reflect the new row
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Port the 4084 internal-showcase-followups state of the shared showcase
schema to 4085 (no Docker restructure):
- feature-registry.json: new Dev Ex category, category reorder
(Dev Ex → Chat & UI → Platform → Controlled → Declarative → Open →
Operational → Interactivity → Agent State → Multi-Agent → BYOC);
+8 new features (beautiful-chat, cli-start, interrupt-headless,
reasoning-default-render, tool-rendering-reasoning-chain,
open-gen-ui-advanced, declarative-gen-ui-hardcoded,
readonly-state-agent-context); renames (shared-state-write →
shared-state-read-write, shared-state-agent-readonly →
readonly-state-agent-context); removals (shared-state-read,
state-rendering, a2ui-*, shared-state-io, shared-state, readables,
a2a-chat, deep-agents, vnext-chat, byoc-a2ui, byoc-tambo);
gen-ui-agent → kind: testing.
- constraints.yaml: allowlists updated to reference the new IDs.
- manifest.schema.json: `route` is optional; `command` field added for
informational demos (e.g. cli-start).
- All 17 column manifests: shared-state-read removed,
shared-state-write renamed to shared-state-read-write.
- langgraph-python manifest: full 4084 features list + demos entries
with 4085-appropriate highlight paths (src/agents/*.py +
src/app/demos/<cell>/* rather than backend/ + frontend/).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Split generative-ui category into 4 (controlled/declarative/open/
operational), add chat-customization-css + tool-rendering-frontend-tools,
replace old tool-rendering-status/-result IDs with default-catchall /
custom-catchall. Port langgraph-python manifest features + highlight:
paths (column-relative to preserve pre-existing Docker structure).
Update tests for new category/feature counts.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Problem: shell's /code viewer was showing every `.py` file under
`src/agents/` for every demo of a package. Visually contaminating:
opening gen-ui-tool-based (Controlled Gen-UI Display) showed
a2ui_dynamic, a2ui_fixed, mcp_apps_agent, open_gen_ui_agent,
reasoning_agent, interrupt_agent, and tool_rendering_agent in the
file picker even though none of them are relevant to that demo.
Root cause: `bundle-demo-content.ts` ran `discoverBackendFiles()` once
per package and attached the same union of all agent files to every
demo. This was fine when all demos shared one graph, but since we
split demos into dedicated graphs the bundle stopped matching reality.
Fix:
- `manifest.schema.json`: add optional `backend_files` field per demo
(string array, paths relative to the package root).
- `bundle-demo-content.ts`: when `demo.backend_files` is present, bundle
exactly those. Otherwise fall back to the legacy full-package scan
so packages that haven't adopted the field still work as before.
- `langgraph-python/manifest.yaml`: populate `backend_files` for every
demo. Each demo bundles `src/agent_server.py` plus only the agent
file its graph routes to (main.py for shared-graph demos;
reasoning_agent.py / interrupt_agent.py / a2ui_dynamic.py /
a2ui_fixed.py / mcp_apps_agent.py / open_gen_ui_agent.py /
tool_rendering_agent.py for demos with dedicated graphs).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Move `agentic-chat-reasoning` from `chat-ui` category to
`generative-ui`, positioned after `tool-rendering`.
- Rename display "Agentic Chat (Reasoning)" -> "Reasoning".
- Update langgraph-python manifest demo entry's name, description,
and tag to match.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
These 7 feature ids had zero manifest references, zero demo dirs, and
zero matching packages backing them in the showcase. They added noise
to the feature matrix without carrying substance:
- mobile-react-native
- mobile-swiftui
- mobile-android
- web-svelte
- web-vue
- web-tanstack — conceptually misplaced anyway; TanStack Start is a
React meta-framework, not a React alternative
- web-angular — `packages/angular/` exists as a published SDK, but the
showcase has zero integration for it. Angular support is really its
own matrix/story; removing this placeholder row until there's a real
showcase integration.
Also drops the `mobile` and `web-frameworks` categories now that they
have no members. Regenerates registry.json + constraints.json.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds rows for the demos being built in this branch:
- Split `chat-prebuilt` into `prebuilt-chat`, `prebuilt-sidebar`,
`prebuilt-popup` (CopilotChat / CopilotSidebar / CopilotPopup).
- Reorder `generative-ui` rows and add: `hitl-in-chat` (In-Chat HITL),
`gen-ui-interrupt`, `declarative-gen-ui` (Dynamic Schema),
`a2ui-fixed-schema` (new), `mcp-apps`, `open-gen-ui`, `gen-ui-agent`,
`tool-rendering`.
- `constraints.yaml`: expand `constrained-explicit` allowlist so the
langgraph-python manifest validates against the new feature ids.
- Bump expected langgraph-python feature/demo count in
`generate-registry.test.ts` from 10 -> 22 to match the manifest.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Feature matrix (generative-ui category):
- Order: Controlled Gen-UI (Display) -> (Interactive) / In-Chat HITL
-> (Interrupt) -> Declarative Generative UI (A2UI) -> MCP Apps
-> Fully Open-Ended Generative UI -> Agentic Generative UI
(In-Chat State Rendering) -> Tool Rendering.
- Merge `hitl-in-chat` with the Controlled Gen-UI (Interactive) idea;
drop the unused `gen-ui-interactive` placeholder.
- Merge standalone `a2ui` entry into Declarative Generative UI (A2UI);
drop the duplicate.
- Rename `gen-ui-agent` display to "Agentic Generative UI (In-Chat
State Rendering)". Moved `tool-rendering` next to it.
- Rename `gen-ui-tool-based` display from "Controlled Generative UI"
to "Controlled Gen-UI (Display)". Dropped the placeholder
`gen-ui-display` entry (was zero-use).
Agentic chat demo (langgraph-python):
- Removed the "Weather in SF" suggestion and the associated
`useRenderTool`/`get_weather` code. The slimmed agent has no backend
tools, so this demo is now pure chat -- just `CopilotChat`, a user
context tag, and one sonnet suggestion.
Regenerated registry + demo-content.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a single command to spin up the exact image Railway deploys,
for any of the 17 showcase packages, with a single shared .env:
./showcase/scripts/dev-local.sh up [<slug> ...] # all if empty
./showcase/scripts/dev-local.sh down|build|logs|ps|ports
Pieces:
- `docker-compose.local.yml` with a service per package. Ports come
from `shared/local-ports.json` (langgraph-python -> 3100, ...).
- `.env.example` as a commit-safe template. Real `.env` is gitignored
and fed to every container via `env_file`, so keys (OPENAI_API_KEY,
etc.) live in one place.
- `dev-local.sh` wraps `docker compose` and handles the
`shared_python/` / `shared_typescript/` staging step that CI does
before `docker build` (see showcase_deploy.yml).
- Staged `shared_*` dirs added to .gitignore.
Shell wiring:
- `shell/next.config.ts` reads `shared/local-ports.json` when
`SHOWCASE_LOCAL=1` is set and injects it as a public env.
- `/integrations/[slug]/[demo]/preview` uses that map to iframe
`http://localhost:<port>` instead of `integration.backend_url`.
Per-slug; any slug not running locally falls back to Railway.
Unset SHOWCASE_LOCAL -> prod behavior, unchanged.
Full workflow + prerequisites (Colima / Docker Desktop) documented in
showcase/README.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1. EACCES on /home/app: Dockerfile templates now create home dir for
non-root user before USER app (langgraph-ts, claude-sdk-ts, mastra)
2. IndexError Path.parents[4]: search_flights.py schema fallback now
guards against shallow Docker paths (agno, claude-sdk-py, ms-agent-py)
3. Wrong import path: rewritePythonImports() now converts
from agents.X to relative imports in starter agent dirs (langroid, crewai)
Remove showcase/shared/frontend/ directory and its pnpm-workspace.yaml
entry. All 17 demo packages and 17 starters are fully self-contained
with no shared frontend dependency.
useAgentContext is not in the npm-published @copilotkit/react-core,
causing TypeError during Next.js static page generation in Docker.
Remove the calls — backend middleware falls back to tool-based when
no render_mode context is present.
Lockfile was stale after rebase — hashbrown deps not in pnpm-lock.yaml.
Also applies oxfmt formatting and syncs next.config.ts webpack alias
with the simplified form from main.