Skip to content

Commit ebad989

Browse files
committed
chore(showcase/langgraph-python): manifest, runtime, e2e, cleanup
Cross-cutting changes that don't belong with any one demo: manifest + landing-page tags, runtime route adjustments, e2e + QA notes that follow the demo renames, and a few small cleanups. Manifest (manifest.yaml + src/app/page.tsx tag labels): - Naming convention: every demo uses `Thing: Subthing` (Generative UI: Tool Rendering - Default / Custom Default / Specific; Open Generative UI: Default / Advanced; Shared State: Streaming / Read + Write; Reasoning: Default / Custom; Frontend Tools: In-App Actions / Async; Human in the Loop: In-chat / In-App / Interrupt based; Chat Customization: CSS / Slots; Headless UI: Simple / Complete). - Retags: Auth → `platform`; HITL Step Selection + Interrupt-based → `interactivity`; Reasoning Default + Custom → `chat-ui`; Generative UI: Tools → `generative-ui`. - Renames: Readonly State (Agent Context) → Frontend Context Sharing. - HITL slot points at /demos/hitl-in-chat (working useHumanInTheLoop+interrupt path) instead of the previous /demos/hitl that had no backend `interrupt()` calls. - Highlight paths corrected for the rebuilt headless demos (root-level paths replaced with hooks/, chat/, tools/, attachments/ subdirs). - Descriptions rewritten where they had drifted from the implementation (gen-ui-agent: dropped useCoAgentStateRender claim; headless-simple: shadcn primitives, not raw Tailwind; headless-complete: enumerates the actual hooks wired). Runtime / route: - src/app/api/copilotkit/route.ts — 30 agents registered (incl. the reasoning-custom rename from agentic-chat-reasoning). - copilotkit-mcp-apps/route.ts replaced with [[...slug]]/route.ts so v2 subpath POSTs (/v2/agent/run) resolve. - src/app/api/copilotkit-voice/[[...slug]]/route.ts — env var standardized (was `AGENT_URL || LANGGRAPH_DEPLOYMENT_URL`, now matches the rest of the showcase with just LANGGRAPH_DEPLOYMENT_URL); trailing `/` removed from deploymentUrl. Tests / QA: - e2e specs renamed and paths updated for the demo renames. - qa notes for a2ui-fixed-schema (booked-state checklist removed) and byoc-json-render (Wave 4a residue removed). - docs-links.json key renamed for reasoning-custom. Cleanup: - Removed remaining stub agent.py files in demo dirs (real graphs in src/agents/); removed dead beautiful-chat/components/headless-chat.tsx (zero importers); removed [A2UI-DEBUG] / [A2UI-RESPONSE] print statements from beautiful_chat.py; gpt-5.4-mini → gpt-5-mini typo fix in beautiful_chat.py:249 (would have 4xx'd every model call); stripped iframe-restriction LLM-prompt copy bleed from open-gen-ui-advanced suggestion titles. The convention pass that ran across ~28 demos earlier in this branch is already reflected in their per-demo commits — every page.tsx reads as imports + provider + suggestions hook + JSX, with `useConfigureSuggestions` extracted to a sibling suggestions.ts.
1 parent 7a380ec commit ebad989

10 files changed

Lines changed: 89 additions & 248 deletions

File tree

showcase/integrations/langgraph-python/docs-links.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
"og_docs_url": "https://docs.copilotkit.ai/langgraph/custom-look-and-feel/headless-ui",
3838
"shell_docs_path": "/custom-look-and-feel/headless-ui"
3939
},
40-
"agentic-chat-reasoning": {
40+
"reasoning-custom": {
4141
"og_docs_url": "https://docs.copilotkit.ai/custom-look-and-feel/reasoning-messages",
4242
"shell_docs_path": "/custom-look-and-feel/reasoning-messages"
4343
},

showcase/integrations/langgraph-python/manifest.yaml

Lines changed: 69 additions & 115 deletions
Large diffs are not rendered by default.

showcase/integrations/langgraph-python/qa/a2ui-fixed-schema.md

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
- Demo is deployed and accessible at `/demos/a2ui-fixed-schema` on the dashboard host
66
- Agent backend is healthy; `OPENAI_API_KEY` is set on Railway; `LANGGRAPH_DEPLOYMENT_URL` points at a LangGraph deployment exposing the `a2ui_fixed` graph (registered as agent name `a2ui-fixed-schema` — see `src/app/api/copilotkit-a2ui-fixed-schema/route.ts`)
7-
- Note: the demo source contains no `data-testid` attributes. Checks below rely on verbatim visible text, DOM structure, and the two JSON schemas under `src/agents/a2ui_schemas/`
7+
- Note: the demo source contains no `data-testid` attributes. Checks below rely on verbatim visible text, DOM structure, and the JSON schema at `src/agents/a2ui_schemas/flight_schema.json`
88

99
## Test Steps
1010

@@ -32,18 +32,9 @@
3232
- `Button` renders full-width with label "Book flight" (black `#010507` background, white text, 12px radius)
3333
- [ ] Verify all four data-model fields resolved correctly (origin=`SFO`, destination=`JFK`, airline=`United`, price=`$289`) — each is a `{ path: "/..." }` binding in the schema and must reach the DOM as a plain string via the `GenericBinder` (no literal `{path}` leak and no React error #31)
3434

35-
#### Book-Flight Interaction (stateful `Button` override)
35+
#### Book-Flight Button (inert — pure presentation)
3636

37-
- [ ] Click the "Book flight" button inside the rendered card; verify it transitions to the confirmed state WITHOUT re-rendering the surface:
38-
- button background becomes the mint tint `rgba(133, 236, 206, 0.15)` with border `#85ECCE4D`
39-
- label text changes to "Booked" (color `#189370`)
40-
- a green check SVG (`polyline 20 6 9 17 4 12`, stroke `#189370`) appears to the left of the label
41-
- button is disabled; further clicks are no-ops
42-
- [ ] Note: the agent-side action handler for `book_flight` is intentionally not wired (see comment in `src/agents/a2ui_fixed.py` — SDK doesn't yet accept `action_handlers=`). So the `booked_schema.json` swap is NOT expected to occur. Verify only the local optimistic button state change.
43-
44-
#### Booked Schema Readiness (`booked_schema.json` — wired-but-inert)
45-
46-
- [ ] Verify `src/agents/a2ui_schemas/booked_schema.json` exists and declares a 3-node tree (`root` Column with children `title` + `detail`, both `Text` with path bindings `/title` and `/detail`). No runtime check — the schema is kept so the handoff is ready once the SDK supports `action_handlers`. Log a test note if this file is ever removed.
37+
- [ ] Verify the "Book flight" button is rendered with the schema-declared label and is clickable, but the click is a no-op: the agent is not invoked, no schema swap occurs, and the button does not transition to a "Booked" state. Schema-swap-on-action will be wired up once the Python SDK exposes `action_handlers=` on `a2ui.render` (see comment in `src/agents/a2ui_fixed.py`).
4738

4839
#### Follow-up Prompt (data-model refresh)
4940

@@ -59,6 +50,6 @@
5950

6051
- Chat loads within 3s; plain-text response within 10s; flight card renders within 20s of the search prompt
6152
- `display_flight` is called exactly once per search prompt; result contains an `a2ui_operations` container with `catalogId: "copilotkit://flight-fixed-catalog"` and the full 12-node flight schema
62-
- All five custom renderers in `a2ui/renderers.tsx` (`Title`, `Airport`, `Arrow`, `AirlineBadge`, `PriceTag`, plus the stateful `Button` override) render at least once per search-flights run
63-
- Clicking "Book flight" produces a local optimistic confirmation (mint background + check icon + disabled state)
53+
- All custom renderers in `a2ui/renderers.tsx` (`Card`, `Title`, `Airport`, `Arrow`, `AirlineBadge`, `PriceTag`, `Button`) render at least once per search-flights run
54+
- Clicking "Book flight" is a no-op (inert presentation button — see comment in `src/agents/a2ui_fixed.py`)
6455
- No UI layout breaks, no `{path}` leak into the DOM, no uncaught console errors

showcase/integrations/langgraph-python/qa/byoc-json-render.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,6 @@
5151

5252
## Expected Results
5353

54-
- Suggestion renders land within 60 seconds. Budget is slightly higher than Wave 4a because a JSON `{ root, elements }` spec is more verbose than hashbrown's token stream.
54+
- Suggestion renders land within 60 seconds. Budget is slightly higher than the hashbrown demo because a JSON `{ root, elements }` spec is more verbose than hashbrown's token stream.
5555
- No uncaught errors in the console.
5656
- Streaming falls back to plain text until the JSON parses, then swaps to rendered components.

showcase/integrations/langgraph-python/src/app/api/copilotkit-mcp-apps/route.ts

Lines changed: 0 additions & 80 deletions
This file was deleted.

showcase/integrations/langgraph-python/src/app/api/copilotkit-voice/[[...slug]]/route.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,10 @@ import { TranscriptionServiceOpenAI } from "@copilotkit/voice";
3434
import OpenAI from "openai";
3535

3636
const LANGGRAPH_URL =
37-
process.env.AGENT_URL ||
38-
process.env.LANGGRAPH_DEPLOYMENT_URL ||
39-
"http://localhost:8123";
37+
process.env.LANGGRAPH_DEPLOYMENT_URL || "http://localhost:8123";
4038

4139
const voiceDemoAgent = new LangGraphAgent({
42-
deploymentUrl: `${LANGGRAPH_URL}/`,
40+
deploymentUrl: LANGGRAPH_URL,
4341
graphId: "sample_agent",
4442
});
4543

showcase/integrations/langgraph-python/src/app/api/copilotkit/route.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,12 @@ agents["frontend-tools-async"] = createAgent("frontend_tools_async");
8282
agents["gen-ui-agent"] = createAgent("gen_ui_agent");
8383
// Tool-Based Generative UI — chart-viz system prompt lives in its own graph.
8484
agents["gen-ui-tool-based"] = createAgent("gen_ui_tool_based");
85-
// Reasoning variants.
86-
agents["agentic-chat-reasoning"] = createAgent("reasoning_agent");
87-
agents["reasoning-default-render"] = createAgent("reasoning_agent");
85+
// Reasoning variants. The Custom demo (`reasoning-custom`) and the
86+
// Default demo (`reasoning-default`) both share the same backend graph;
87+
// the only difference is whether the frontend overrides the
88+
// `messageView.reasoningMessage` slot.
89+
agents["reasoning-custom"] = createAgent("reasoning_agent");
90+
agents["reasoning-default"] = createAgent("reasoning_agent");
8891
// Interrupt variants.
8992
agents["gen-ui-interrupt"] = createAgent("interrupt_agent");
9093
agents["interrupt-headless"] = createAgent("interrupt_agent");

showcase/integrations/langgraph-python/tests/e2e/a2ui-fixed-schema.spec.ts

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,9 @@ import { test, expect } from "@playwright/test";
1212
// PriceTag, Button) bind path strings like "/airline" / "/price" to the
1313
// incoming data model.
1414
//
15-
// The "Book flight" Button has a stateful override (ActionButton in
16-
// a2ui/renderers.tsx) that transitions to a "Booked" state with a green
17-
// check SVG on click — purely local, because the SDK doesn't yet support
18-
// `action_handlers=` on the Python side (see the comment in
19-
// a2ui_fixed.py). The `booked_schema.json` swap path is therefore NOT
20-
// expected to fire and is intentionally not tested.
15+
// This is a pure-presentation demo: the "Book flight" Button is inert —
16+
// schema-swap-on-action will be wired up once the Python SDK exposes
17+
// `action_handlers=` on `a2ui.render` (see comment in a2ui_fixed.py).
2118
//
2219
// No data-testid anywhere in the demo. Assertions ride on:
2320
// - verbatim label text hardcoded in flight_schema.json ("Flight
@@ -89,26 +86,4 @@ test.describe("A2UI Fixed Schema (flight card)", () => {
8986
);
9087
});
9188

92-
test("Book flight button transitions to Booked on click", async ({
93-
page,
94-
}) => {
95-
const suggestions = page.locator('[data-testid="copilot-suggestion"]');
96-
await suggestions.filter({ hasText: "Find SFO → JFK" }).first().click();
97-
98-
// Render budget is 90s here: the first click after cold-start can
99-
// burn most of a minute before `display_flight` emits the
100-
// a2ui_operations container, and we then need the full 12-node tree
101-
// to resolve before the Book flight button exists.
102-
const bookBtn = page.getByRole("button", { name: "Book flight" });
103-
await expect(bookBtn).toBeVisible({ timeout: 90_000 });
104-
await bookBtn.click();
105-
106-
// After click: label switches to "Booked" and the button becomes
107-
// disabled. This is the purely-local ActionButton state transition;
108-
// no agent round-trip is involved.
109-
await expect(page.getByRole("button", { name: "Booked" })).toBeVisible({
110-
timeout: 10_000,
111-
});
112-
await expect(page.getByRole("button", { name: "Booked" })).toBeDisabled();
113-
});
11489
});

showcase/integrations/langgraph-python/tests/e2e/byoc-hashbrown.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* E2E spec for the byoc-hashbrown demo (Wave 4a).
2+
* E2E spec for the byoc-hashbrown demo.
33
*
44
* Authored but not executed pre-deploy — Railway stabilization runs happen
55
* post-deploy per the plan's scope modification. Selectors match the ported

showcase/integrations/langgraph-python/tests/e2e/byoc-json-render.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { test, expect } from "@playwright/test";
77
* Task 12 scope note).
88
*
99
* Structurally mirrors `gen-ui-tool-based.spec.ts` so the agent
10-
* dashboard's Wave 4a/4b rows exercise the same surfaces.
10+
* dashboard's BYOC rows exercise the same surfaces.
1111
*/
1212
test.describe("BYOC json-render", () => {
1313
test.beforeEach(async ({ page }) => {

0 commit comments

Comments
 (0)