Commit Graph

133 Commits

Author SHA1 Message Date
Benjamin Taylor e27aeb687d refactor(showcase): retire the v1 runtime adapter across every integration
Moves all 239 showcase integration routes off
`copilotRuntimeNextJSAppRouterEndpoint`, the deprecated v1 Next.js adapter, so
the v1 entrypoint has no remaining code-level users under
`showcase/integrations/`.

    const copilotHandler = createCopilotRuntimeHandler({
      runtime,
      basePath: "/api/copilotkit-x",
      mode: "single-route",
    });
    ...
    return await copilotHandler(req);

## Why single-route, and why this handler

**Single-route** because these demos' frontends are
`<CopilotKit runtimeUrl="/api/copilotkit-x">` with no transport prop, and every
released provider pins the single-route transport. Single-route mode is
therefore a drop-in for the v1 adapter: no frontend change, no path change, no
`GET` export, and nothing here probes `/info`. Migrating to multi-route instead
would have required editing every demo page in lockstep for no functional gain.

**`createCopilotRuntimeHandler`** rather than `createCopilotEndpointSingleRoute`
because that helper is itself deprecated in favour of the `mode` option (see the
deprecated-aliases table in `docs/backend/runtime-endpoints.mdx`), and because
the fetch handler needs no `hono` dependency and composes directly with the
wrappers these routes already have.

The statement is rewritten in place, inside whatever wrapper it already sat in,
so `withForwardedHeaders`, the try/catch envelopes, `wrapStreamingResponse` and
`withCvdiagBackend` are all untouched. 75 of these routes construct the runtime
inline in the call; rewriting in place preserves that per-request construction
exactly as v1 did. No `runner` is added — it is optional, and none of these
routes passed one before.

13 `copilotkit-auth/[[...slug]]` routes already use the v2 fetch handler and are
left alone; they only mention the v1 name in explanatory comments.

## Collateral

- `mastra`'s main route declared a module-level
  `const serviceAdapter = new ExperimentalEmptyAdapter()` plus a startup log
  about the adapter choice. V2 has no service adapters, so both are gone and the
  comment now explains that there is nothing to configure.
- The three `mastra` vitest suites mocked `@copilotkit/runtime` and the v1
  `{ handleRequest }` return shape; they now mock `@copilotkit/runtime/v2` and
  `createCopilotRuntimeHandler`, which returns the handler directly.
- 27 `@ts-expect-error` directives guarded the **v1** `CopilotRuntime` agents
  type ("wraps Record in MaybePromise<NonEmptyRecord<...>>"). Under `/v2` that
  hole is gone, which makes the directive unused — a hard error. They are
  demoted to `@ts-ignore`, which compiles whether or not the mismatch survives
  in a given integration, because 19 of these apps cannot be built locally to
  prove it either way. Removing all ~220 now-stale suppressions is left as
  follow-up once CI has built every integration green.

## Verified

`mastra` is the one integration installed and exercised locally (19 routes, the
`withCvdiagBackend` main route, and the only vitest suites that touch routes).
Measured against `origin/main` in the same tree:

    tsc --noEmit    baseline: errors in 10 files
                    after:    errors in  9 files
                    new errors introduced: NONE
                    fixed: src/app/api/copilotkit-mcp-apps/route.ts, whose
                           @ts-expect-error was ALREADY unused on main

    vitest run      baseline: 2 files failed, 13 tests failed, 21 passed
                    after:    2 files failed, 13 tests failed, 21 passed
                    → test-neutral; those 13 failures are pre-existing on main

Structural audit over all 239 routes: none still imports the v1 root, uses the
v1 adapter, references `ExperimentalEmptyAdapter` or `handleRequest` in code, or
is missing `createCopilotRuntimeHandler` / `basePath` / `mode: "single-route"`.

The shape itself was proved end-to-end before the rollout, in a real running
app with an untouched provider (aimock as the model backend):
`POST /api/copilotkit` -> 200 twice, chat turn rendered.

## Two pre-existing problems found on the way

- `npm ci` fails in `showcase/integrations/mastra`: `Missing:
  @types/http-errors@2.0.5 from lock file`. Its Dockerfile uses
  `npm ci --legacy-peer-deps`, which does succeed, so the image still builds —
  but a plain `npm ci` does not. Untouched here; no manifest or lockfile is in
  this diff.
- `mastra`'s vitest suite is red on `main` (13 failures, mostly
  `extractXHeaders` dereferencing `req.headers` on a `{}` fake request).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 18:59:27 -05:00
Jordan Ritter 069501d6dc chore(showcase): upgrade CopilotKit to 1.68.2 (lands #6576 readiness fix) 2026-08-19 20:16:28 -07:00
Benjamin Taylor 3ec309b724 docs(langgraph): fix 8 verified defects in the LangGraph onboarding docs (refs OSS-857)
Fixes defects 3, 4, 6, 7, 8, 10, 11 and 12 from the OSS-856 phase 1
validation run. Every claim below was re-verified against installed
package source or a live run, not recalled.

LangGraph quickstart (`integrations/langgraph/quickstart.mdx`):

- Route shape: a caution at the route step. The POST-only route runs the
  runtime in single-route mode, which is all chat needs; Threads and the
  Inspector need the multi-route catch-all with GET/POST/PATCH/DELETE.
  Links to the canonical runtime-endpoints section.
- Port: bare `langgraph dev` serves 2024, not 8123. Verified against both
  CLIs (`@langchain/langgraph-cli` help output, and `default=2024` in
  `langgraph_cli/cli.py`). The guide keeps `--port 8123` to stay
  consistent with every sibling page, and now says so.
- Drop `@copilotkit/react-ui` from the install list. `CopilotSidebar`
  lives in `@copilotkit/react-core/v2`; react-ui exports no `./v2` JS
  entry point and the v2 react example does not depend on it.
- Checkpointer: state the reason each tab differs. `langgraph dev` fails
  to load a graph compiled with a custom checkpointer (reproduced), while
  the FastAPI tab needs one because `ag-ui-langgraph` calls
  `graph.aget_state(...)`, which raises `ValueError: No checkpointer set`.
- Narrow the shared `uv add` line to what both tabs import, and warn that
  a project with exact pins should add them by hand.

A2UI fixed schema (`generative-ui/a2ui/fixed-schema.mdx`):

- Add the missing install step for `@copilotkit/a2ui-renderer` + `zod`,
  which the catalog/definitions/renderer snippets all import.
- Add a `StateGraph` + `ToolNode` form for developers who already have a
  hand-built graph, gated to the Python LangGraph slugs by a new
  `a2ui_agent_form` docs flag so the shared page does not show Python to
  langgraph-typescript or LangGraph code to LlamaIndex/ADK/Mastra.
- Repoint the cross-tree `/integrations/langgraph/...` link, which 301'd
  back to this same page, at the action-handler reference it promises.

Raw Markdown pipeline (`src/lib/llm-text.ts`):

- `renderPageToLlmText` never applied `filterFrameworkScopedBlocks`, so
  `/<framework>/<page>.md` emitted every `<WhenFrameworkHas>` branch with
  raw JSX tags, each carrying the one selected framework's snippet. On the
  A2UI page that produced three mutually-exclusive "how the schema is
  delivered" sections whose prose contradicted the identical code under
  each. Gate on the same framework the snippets resolve to, with a
  regression test.

Also corrects a factually wrong comment in the langgraph-python showcase
`.env.example` that claimed 8123 was the `langgraph dev` default — the
same mis-belief this ticket found in the docs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 12:19:52 -05:00
Mark 23e4709718 chore(showcase): upgrade CopilotKit to 1.68.1 (#6510)
## Summary

- advance the canonical Showcase CopilotKit pin to `1.68.1`
- apply the release consistently across all 21 integrations and the
Showcase shell
- regenerate the affected npm lockfiles, including the LangGraph
TypeScript agent lockfile and the Shell's strict peer-dependency entries

This picks up
[#5837](https://github.com/CopilotKit/CopilotKit/pull/5837), which
bounds the in-memory agent runner to prevent unbounded thread retention
and OOMs.

## Verification

- Showcase pin ratchet passes at the existing 26-failure baseline/hash
- `@copilotkit/showcase-scripts`: 2,511 tests pass
- strict Shell `npm ci --ignore-scripts` succeeds, matching the Showcase
validation workflow
- Shell unit tests pass (241/241) and its production build succeeds
- clean installs and production builds pass for Ag2, Langroid, and
Mastra
- comparison with `origin/main` found no pin-induced TypeScript
diagnostics; the standalone TypeScript failures are pre-existing and
outside the current production build gate
2026-08-17 14:27:57 -07:00
Mark db22a686cc chore(showcase): upgrade CopilotKit to 1.68.1 2026-08-15 18:46:53 -07:00
Jordan Ritter 49ab706614 perf(showcase): cap langgraph integration backend memory
Set MALLOC_ARENA_MAX=2 and MALLOC_TRIM_THRESHOLD_ on the langgraph-python and
langgraph-fastapi entrypoints to curb glibc arena fragmentation on the many-core
Railway host, and NODE_OPTIONS --max-old-space-size=1536 scoped to the
langgraph-typescript agent process (not the sibling Next.js server) to cap the
V8 heap. All values use ${VAR:-default} so explicit Railway overrides win.
2026-08-15 11:10:30 -07:00
Tyler Slaton 8a2d385a94 chore(docs): remove merge-only lint drift 2026-07-28 16:02:26 -04:00
Tyler Slaton af13ab447e Merge origin/main into agent/oss-615-channel-docs 2026-07-28 15:31:13 -04:00
lukasmoschitz eca1d741c8 fix(showcase): align langgraph-fastapi to north-star langgraph-python (OSS-582) (#6184)
## Summary

Aligns the **langgraph-fastapi** showcase integration to the north-star
**langgraph-python** (OSS-582 — "Align LangGraph (FastAPI) Showcase
demos and code"). Moves the integration onto the product-centric demo
set: backend agent graphs, runtime wiring, frontend chrome, the
demo-browser overview (`manifest.yaml`), and aimock fixtures.

Linear: OSS-582.

## What changed

**Backend agents (`src/agents/src/`)**
- Ported the missing dedicated graphs: `agentic_chat`, `gen_ui_agent`,
`gen_ui_tool_based`, `shared_state_streaming`.
- v2 `create_agent` ports + config alignment for `agent_config_agent`,
`headless_complete`, `reasoning_agent`, `tool_rendering_agent`,
`tool_rendering_reasoning_chain_agent`, `a2ui_dynamic`.

**Runtime wiring**
- `route.ts`: wired the canonical demos to their dedicated graphs and
removed them from the generic `sample_agent` fallthrough loop (this is
what made several demos behave correctly against a real LLM — see
below); added `recursion_limit`.
- `langgraph.json`: registered the 3 new graphs.
- Renamed the dedicated API routes
`copilotkit-byoc-{hashbrown,json-render}` →
`copilotkit-declarative-{hashbrown,json-render}`.

**Overview / content**
- `manifest.yaml`: demos + features aligned to LGP (names, descriptions,
tags, order, canonical ids; deprecated aliases migrated; phantom
`hitl-in-chat-booking` removed; `shared-state-streaming` un-quarantined
now that it works). Integration identity (name/slug/logo) preserved. The
demo-browser overview is now card-for-card identical to
langgraph-python.
- Restored two missing `@region` markers (factory-automation snippet
extraction).

**Frontend chrome**
- `globals.css`, `layout.tsx`, `middleware.ts` (was missing),
`declarative-gen-ui/*` + `sales-context.ts`, `beautiful-chat`;
`Dockerfile` now copies `manifest.yaml` (fixed an RSC crash on every
`/demos/*`).

**aimock fixtures (`aimock/d4|d6/langgraph-fastapi/`)**
- D6 fixture fixes for the previously-red cells (stale `turnIndex`
gates, cross-file substring shadowing, missing `chunkSize`, prompt
narrowing).

**Showcase tooling / docs**
- Fixed harness services racing on a shared image tag
(`docker-compose.local.yml`).
- `GOTCHAS.md` #8: documents that aimock D6 can be green while a demo is
broken against a real LLM (fixtures replay scripted tool calls
regardless of which graph ran), plus how to catch it.
- `PARITY_NOTES.md`: sanctioned divergences (a2ui-recovery per-slug
prompt isolation; declarative-json-render scoped-test divergence).

## Verification

- **D6 sweep: 38 green / 1 red.** The single red is **a2ui-recovery**,
which reproduces **identically on the north star** (shared Python
`ag_ui_langgraph` recovery loop; mastra's TS impl is green). It is not a
fastapi defect and is tracked as a separate PR against the north star.
Documented in `PARITY_NOTES.md`.
- `validate-manifests` (manifest → registry, all 20 integrations) —
green.
- `validate-routes --all` (runtime-route wiring) — green.
- Build + TypeScript typecheck (`next build` via the Docker image build)
— green.
- `@region` audit — all region pairs balanced and LGP-consistent (0
orphans/typos/mismatches).
- Live manual QA against real OpenAI (`:3102` vs `:3100`) confirmed the
key demos (reasoning-custom, shared-state-streaming, gen-ui-tool-based,
agentic-chat).

## Notable finding

Several demos were D6-green but broke against a real model because they
fell back to the generic `sample_agent` instead of their dedicated graph
— the aimock fixture masked the wiring bug by replaying scripted tool
calls. This PR fixes the wiring and documents the gap (GOTCHAS #8).
D6-green is necessary but not sufficient for graph/tool-dependent demos;
a real-LLM click-through is required.

## Deferred / follow-ups

- **a2ui-recovery** — shared north-star defect in the Python
`ag_ui_langgraph` recovery loop; separate PR against the north star.
- **d5-byoc probe** — always sends the hashbrown pill even on the
json-render page (fleet-wide harness limitation); tracked as a
follow-up. The gating `byoc` grid cell is green.

## Scope note

Only `langgraph-fastapi` integration code, its aimock fixtures, and
showcase tooling/docs changed. **langgraph-python (the north star) was
not touched.**
2026-07-28 12:49:57 +02:00
Tyler Slaton 6c15645b6b docs: organize Channels guides by provider and framework 2026-07-27 23:50:31 -04:00
github-actions[bot] b4cff204d1 style: auto-fix formatting 2026-07-27 15:10:04 +00:00
Lukas Moschitz c9d8a9ac14 fix(showcase): restore missing @region markers on 2 langgraph-fastapi agents
The factory automation extracts curated snippets via @region markers.
readonly_state_agent_context.py and shared_state_read_write.py were byte-aligned
to langgraph-python except their @region markers had been stripped, so the
factory would extract nothing for those two regions. Restore them to match LGP:
- agent-context-setup around create_agent in readonly_state_agent_context.py
- shared-state-setup around create_agent in shared_state_read_write.py
Comment-only; no behavior change. Audit confirms all 49 fastapi region pairs are
now balanced and LGP-consistent (0 orphans/typos/mismatches).
2026-07-27 17:03:08 +02:00
Lukas Moschitz efe51e7deb chore(showcase): remove fe-parity tool
fe-parity.ts was a scratch parity checker for this alignment work; it is no
longer needed in the worktree. Drop it and de-reference it from
langgraph-fastapi/PARITY_NOTES.md (reword the intro, convert the
machine-readable fe-parity-allow allowlist into a plain human-readable
'sanctioned file-level divergences' list). No other references existed. D6
behavior remains the parity judge.
2026-07-27 16:55:23 +02:00
Lukas Moschitz b8f37c0c85 docs(showcase): document declarative-json-render scoped-D6 divergence as sanctioned
The byoc D6 featureType covers both declarative demos; the grid cell is green
(hashbrown route+pill). A scoped declarative-json-render --d6 run reds for two
non-fastapi reasons: (1) the shared d5-byoc probe always sends the hashbrown
pill even on the json-render page (harness limitation — build context lacks
demos[]; tracked as a separate follow-up), and (2) fastapi deliberately keeps
hashbrown (@hashbrownai/react) and json-render (@json-render/react) as separate
library integrations with their own pills/fixtures, vs LGP's unified
render_dashboard contract. Sanctioned; do not collapse fastapi's json-render to
the unified contract (content downgrade) — the real fix is probe-side.
2026-07-27 16:49:05 +02:00
Lukas Moschitz bf2de51705 fix(showcase): wire langgraph-fastapi demos to dedicated graphs (drop sample_agent fallbacks)
Live QA surfaced demos that behaved wrong on fastapi because they fell back to
the generic sample_agent (or were unregistered) instead of the dedicated graph
LGP uses. aimock D6 masked these (fixtures script the tool calls), so they were
green in the grid but broken against a real model. Audit of fastapi's
agentNames fallthrough vs LGP's neutralAssistantCells found exactly these:

- gen-ui-tool-based: port gen_ui_tool_based graph (tools=[], frontend supplies
  render_bar/pie_chart via useComponent). Was sample_agent, whose query_data
  tool + prompt made the model loop on data queries instead of rendering.
- shared-state-streaming: port shared_state_streaming graph (StateStreaming
  middleware + write_document tool + document state). Was sample_agent, which
  never emits state.document, so it only wrote to chat. Remove from
  not_supported_features (now works, D6 green).
- agentic-chat: port agentic_chat graph (tools=[]). Was sample_agent (7+ tools).
- threadid-frontend-tool-roundtrip: wire to frontend_tools (was unregistered).
- reasoning-custom: align reasoning_agent config to LGP (gpt-5.4 / effort
  medium / summary detailed; were gpt-5-mini / low / auto).

Register the 3 new graphs in langgraph.json; remove the 3 names from the
sample_agent fallthrough loop in route.ts. D6 green x2 for reasoning-display,
gen-ui-custom, shared-state-streaming, agentic-chat; agent-config +
tool-rendering-reasoning-chain re-verified (no regression).
2026-07-27 16:24:50 +02:00
Lukas Moschitz 7bd1ca6e70 docs(showcase): record a2ui-recovery D6 red as a shared north-star defect
Soften the stale 'D6 green'/'under investigation' wording. A live trace
confirmed the a2ui-recovery surface-missing D6 red reproduces identically on
the langgraph-python north star (shared Python ag_ui_langgraph recovery loop;
mastra's TS impl is green), so fastapi is already behaviorally aligned and
there is nothing to fix under integrations/langgraph-fastapi/. Fixing the
shared loop is a separate PR against the north star / the package.
2026-07-27 14:30:21 +02:00
Lukas Moschitz 6af08217b2 fix(showcase): align langgraph-fastapi demo overview + canonical cell wiring to parity
The demo-browser overview (page.tsx, identical to LGP) groups cards by
demo.tags[0] and orders within a group by manifest.features[] index, so the
card arrangement is fully driven by manifest.yaml. fastapi's manifest was an
older curation: a different naming scheme (~26 demos), deprecated feature/demo
ids (agentic-chat-reasoning, reasoning-default-render, byoc-hashbrown,
byoc-json-render, hitl, phantom hitl-in-chat-booking), divergent tags/order,
and a missing shared-state-streaming/shared-state-read card.

Align manifest.yaml demos+features to LGP (names, descriptions, tags, order,
canonical ids), preserving fastapi identity (name/slug/logo/description) and
the sanctioned a2ui-recovery prompt divergence. Overview is now card-for-card
identical to langgraph-python.

Canonicalizing the ids pulled two cells into the D6 tested set that were
mis-wired to the old names; wire them to LGP's shape:
- reasoning-custom/reasoning-default -> reasoning_agent in copilotkit/route.ts
  (were wired under agentic-chat-reasoning/reasoning-default-render).
- rename api routes copilotkit-byoc-{hashbrown,json-render} ->
  copilotkit-declarative-{hashbrown,json-render}; align endpoints + the
  declarative-hashbrown-demo agent id to what the demo pages request.

Full D6 sweep: 37 green / 1 red; reasoning-display and byoc now green (two
real runs each); the lone red is a2ui-recovery (known shared north-star
defect, identical on LGP).
2026-07-27 14:30:21 +02:00
Lukas Moschitz a19ed403cf fix(showcase): port langgraph-fastapi tool-rendering-reasoning-chain to parity
Two independent fastapi divergences from the green north-star kept this red:

1. Missing chunkSize:9999 on the 8 tool-call fixtures. Under aimock's global
   8-byte chunking the large tool-call args failed to JSON-parse in one piece,
   so the AAPL->MSFT reasoning chain stopped at leg 1 (turns 1 & 2). Byte-align
   to LGP (and the green mastra/langgraph-typescript siblings carry the same
   pattern).

2. Fixture-pool shadowing broke turn 3. aimock pools all d4+d6 fixtures for a
   context and matches by userMessage substring, first-match-wins in load order
   (d4 before d6). fastapi had broad keys LGP doesn't:
   - d4/chat.json: 'weather' -> 'weather in San Francisco', 'flights from SFO
     to JFK' -> 'Find flights from SFO to JFK.' (period-terminated so it stops
     being a substring of turn 3's 'Find flights from SFO to JFK and show me
     the weather there.').
   - tool-rendering-{custom,default}-catchall.json: bare 'Find flights' ->
     'Find flights from SFO to JFK.' (now matches LGP's exact key).

Also byte-align the backend agent to LGP: scriptable get_stock_price signature,
the detailed chaining system prompt, model gpt-5.4, reasoning summary detailed.

D6 tool-rendering-reasoning-chain green (two real ~21s runs). Shared-fixture
regression all green: agentic-chat, tool-rendering, tool-rendering-custom-catchall,
tool-rendering-default-catchall, headless-complete (Tokyo-weather consumer).
2026-07-27 11:01:18 +02:00
Jordan Ritter b907a2660a Merge branch 'main' into fix/showcase-integration-page-titles 2026-07-25 23:04:04 -07:00
Jordan Ritter 51cc63d974 chore(showcase): store demo assets uniformly as Git LFS pointers
Demo assets under showcase/integrations/*/public/{demo-files,demo-audio}/
were stored two different ways. Ten integrations committed them as LFS
pointers (the root .gitattributes convention); eight carved themselves out
with a per-integration .gitattributes that re-declared the same paths
`-filter -diff -merge`, committing raw binaries instead.

Those carve-outs were added when the image build did not fetch LFS, so a
pointer stub shipped into the image and the multimodal sample-attachment
magic-bytes guard rejected it. That premise no longer holds: the deploy
build's Checkout step hardcodes `lfs: true` (7bde1eef3a), so every
integration image now gets real binaries regardless of storage form. The
overrides are dead weight that only buys divergence.

Delete all eight override files and renormalize the 21 affected assets
through the LFS clean filter. Each override contained nothing but demo-asset
exemptions, so each is removed in full; the root .gitattributes is untouched.

Storage form changes, content does not. Every asset's sha256 already equals
the LFS OID the pointer-mode integrations reference, so each renormalized
blob is bit-for-bit the pointer blob already committed on main -- no new LFS
objects are introduced and no pointer can dangle:

  sample.png  10083 B  oid 01aa5681de99461247543e9215c1e4da3242e26b2bee11593fcdbe209672d973
  sample.pdf   2486 B  oid 3da2afae36a1a81fd2c02f15e54bfc38b6c22e41655c31a5b54ff1e0e3daab41
  sample.wav  87078 B  oid bd4aa7b049f1c3e324dfd15af4068d7f8fbf2eae1dd044df270dddc5f38a5c57

All three OIDs return download actions from the LFS batch API and were
downloaded and confirmed to hash to their OID.
2026-07-24 16:33:14 -07:00
Jordan Ritter 510bb88553 fix(showcase): use each integration's own name in demo page titles
14 integrations' `src/app/demos/layout.tsx` hardcoded "LangChain - Python"
in `generateMetadata` — a copy-paste leftover from langgraph-python, which
the file was cloned from. Every `/demos/*` page in mastra, strands, ag2,
agno and 10 others rendered `<title>LangChain - Python</title>`.

Each now uses the display name from its own `manifest.yaml` `name:` field,
matching the convention the already-correct integrations use
(langgraph-typescript -> "LangGraph (TypeScript)", strands-typescript ->
"AWS Strands (TypeScript)").

langgraph-python itself is included: its manifest name and root layout both
say "LangGraph (Python)", so "LangChain - Python" (the legacy Notion
partner-column label) was stale there too.
2026-07-24 16:19:17 -07:00
Lukas Moschitz 9ab49609f0 fix(showcase): make langgraph-fastapi get_stock_price scriptable
tool-rendering-custom-catchall renders the ticker quote in the wildcard card.
fastapi's get_stock_price(ticker) had no scriptable args, so when the aimock
fixture emitted price_usd/change_pct the @tool silently dropped the unknown
kwargs and returned random numbers instead of the scripted quote — the card
showed nondeterministic values, diverging from the north star.

Port LGP's scriptable signature: get_stock_price(ticker, price_usd=None,
change_pct=None) — echoes scripted values verbatim when supplied, random when
omitted (backward-compatible with the other tool-rendering pills). Behavior
byte-aligned to langgraph-python.

D6 tool-rendering-custom-catchall green (two real ~8s runs); shared-backend
siblings tool-rendering, tool-rendering-default-catchall, headless-complete all
re-verified green.
2026-07-24 17:15:14 +02:00
Lukas Moschitz 797d30ca63 fix(showcase): port langgraph-fastapi gen-ui-headless-complete to parity
Two compounding defects kept this cell red:

1. Backend missing get_revenue_chart. headless_complete.py never registered
   the revenue-chart tool, so the chart-turn never emitted a tool call and the
   card never mounted. Port LGP's get_revenue_chart tool + its system-prompt
   routing rule (tool return shape byte-identical to LGP).

2. Stale turnIndex fixtures caused turn-2 and turn-4 loops to the recursion
   limit. Align to LGP's canonical shape:
   - tool-rendering.json (shared): AAPL first-leg turnIndex:0 -> hasToolResult:false
     so it stops re-firing at turnIndex>=2 in the multi-pill thread.
   - headless-complete.json: rewrite to LGP's structure (narration/toolCallId
     fixtures first, tool-call legs after with userMessage+context only, no
     stale turnIndex); drop the divergent fastapi-only highlight fixtures,
     subsumed by the broader substring fixture.

D6 langgraph-fastapi:gen-ui-headless-complete now green (two real ~29s runs);
tool-rendering re-verified green (shared-fixture no regression).
2026-07-24 16:39:55 +02:00
Lukas Moschitz 243acc7771 fix(showcase): add langgraph-fastapi gen-ui-agent graph + recursion limit
gen-ui-agent had no dedicated backend graph: langgraph.json lacked a
gen_ui_agent entry and route.ts routed the name through the neutral-assistant
loop to sample_agent, which has no steps state or set_steps tool, so the
progress card never mounted (agent hit the default recursion limit of 25).

- Port LGP's gen_ui_agent.py (byte-identical) and register it in langgraph.json.
- route.ts: bind gen-ui-agent to createAgent("gen_ui_agent") and bake
  assistantConfig.recursion_limit (default 100) into every LangGraphAgent —
  the graph's Python with_config isn't visible to the server runs API, so the
  multi-step set_steps walk overran 25. Mirrors langgraph-python.
- aimock: regenerate d6/gen-ui-agent.json from LGP (adds chunkSize:9999 on the
  24 tool-call fixtures) and narrow the over-broad d4 chat.json "summarize" key
  to "Summarize the sales pipeline" so it stops substring-shadowing the
  competitor set_steps chain (and other summarize prompts). Matches LGP.

D6 langgraph-fastapi:gen-ui-agent now green (two real ~14s runs);
agent-config re-verified green (no regression).
2026-07-24 16:23:48 +02:00
Lukas Moschitz 71f44d46f7 fix(showcase): port langgraph-fastapi agent-config to v2 create_agent
The fastapi agent_config_agent still used the v1 StateGraph pattern reading
tone/expertise/responseLength from RunnableConfig[configurable][properties].
The frontend (identical to LGP) publishes those knobs via the v2
useAgentContext hook and the route uses a plain LangGraphAgent, so the old
graph received nothing on configurable and the run errored (turn never
completed, D6 red).

Port the backend to LGP's v2 shape: create_agent + CopilotKitMiddleware with
a single static system prompt that reads the injected context entry. Update
the route comment to describe the useAgentContext path (runtime code
unchanged: plain LangGraphAgent + AGENT_URL env fallback preserved).

D6 langgraph-fastapi:agent-config now green (two real ~28s runs).
2026-07-24 15:51:42 +02:00
Lukas Moschitz cd8c94a492 feat(showcase): make fe-parity exception-aware via PARITY_NOTES allowlist
fe-parity.ts now reads a per-integration allowlist from
integrations/<slug>/PARITY_NOTES.md (an <!-- fe-parity-allow --> block of
'src-relative-path | reason' lines). Listed files report as ALLOWED
(sanctioned per-integration divergence), not DRIFT; the gate passes on zero
UNSANCTIONED drift instead of zero diffs. This stops the byte-identical goal
from being impossible for demos that legitimately must differ (e.g.
a2ui-recovery's per-slug prompt, which has no aimock context routing).

Add langgraph-fastapi/PARITY_NOTES.md documenting the a2ui-recovery frontend
divergence with reasons. D6 remains the correctness gate; fe-parity is the
'where to look' map.
2026-07-24 13:53:14 +02:00
Lukas Moschitz eaa49e55b3 feat(showcase): port langgraph-fastapi declarative-gen-ui to canonical sales-analyst demo
Task 2 of OSS-582. Replace fastapi's old generic 'chart-picker' declarative-gen-ui
with langgraph-python's canonical sales-analyst demo, so it matches the shared D6
probe (which asserts sales-dashboard / DataTable / StatusBadge / InfoRow per pill):
- backend src/agents/src/a2ui_dynamic.py: generic prompt -> LGP sales-analyst graph
  (persona + dataset grounding + composition rules + generate_a2ui tool)
- frontend definitions.ts/renderers.tsx/chat.tsx/suggestions.ts byte-identical to LGP,
  add sales-context.ts (fictional Vantage Threads dataset + composition rules)
- d6 fixtures gen-ui-declarative.json + render-a2ui.json: LGP's, re-keyed to
  context=langgraph-fastapi

Verified D6 green via control-plane (real 12s browser run, canonical testids asserted).
a2ui-recovery intentionally NOT aligned: its fixtures have no context routing, so each
integration must keep a unique pill prompt (sanctioned per-slug divergence).
2026-07-24 11:10:22 +02:00
Lukas Moschitz f3d01b83c7 fix(showcase): align langgraph-fastapi frontend chrome with langgraph-python
Task 1 of OSS-582 (frontend parity). Bring the app chrome + beautiful-chat
byte-identical to the langgraph-python north star:
- globals.css: adopt LGP theme (@theme inline tokens + green palette)
- middleware.ts: add (was missing) — sets x-pathname like LGP
- layout.tsx: adopt LGP structure; keep FastAPI in title/log (identity carve-out)
- beautiful-chat/page.tsx: sync stale doc comment

Also fix a Dockerfile parity gap: fastapi was missing the COPY manifest.yaml
that LGP has. demos/layout.tsx reads manifest.yaml at request time via
generateMetadata (headers() -> dynamic), so without it every /demos/* route
crashed with an RSC render error (ENOENT /app/manifest.yaml).
2026-07-23 16:26:52 +02:00
Mike Ryan 4d32d941eb feat(showcase): checkpoint 4 - all supported features and docs 2026-07-23 07:14:55 -07:00
Jordan Ritter 64b1409289 fix(showcase): add declarative-info-row testid to 3 lagging integrations for turn-4 parity
The gen-ui-declarative D6 probe drives a 4-turn conversation; turn 4
(the "top-account" pill) asserts a `declarative-info-row` surface
(a Card of InfoRow facts next to a PieChart). pydantic-ai,
langgraph-fastapi, and langgraph-typescript rendered the InfoRow
component but never carried the `data-testid="declarative-info-row"`
attribute that the probe (and the green peer integrations such as
langgraph-python) rely on to detect the surface. As a result turn 4
timed out with reason=surface-missing and the cell failed at
turns_completed=3.

This restores parity with the green peers by adding the missing testid
to the InfoRow renderer in the 3 lagging integrations. No other
behavior changes; PrimaryButton already wires actions via the
`dispatch(props.action)` pattern (the local ButtonProps extends
ButtonHTMLAttributes, so onClick is valid — no type error).
2026-07-18 12:14:05 -07:00
Jordan Ritter 2b9c3fe779 fix(showcase): add declarative DataTable renderer to 4 missing integrations
Commit 1e0d200f5 added the team-performance pill to d5-gen-ui-declarative,
which requires `[data-testid="declarative-data-table"]` to mount. It added
the DataTable renderer + Zod definition to langgraph-python and 6 others,
but missed 4 integrations whose declarative-gen-ui catalogs were drifted
copies from an earlier snapshot: claude-sdk-typescript, pydantic-ai,
langgraph-fastapi, langgraph-typescript.

Root cause: all 4 integrations serve a `next start` production build whose
`renderers.tsx` defines only Card/StatusBadge/Metric/InfoRow/PrimaryButton/
PieChart/BarChart — no DataTable. The backend SSE stream returns a valid
`render_a2ui` payload containing a DataTable component; with no client
renderer it is silently dropped → declarative probe turn 2 times out with
reason=surface-missing.

Decision: per-integration real files (not symlinks — confirmed by file size
diff: 12042 B vs 13515 B canonical). Added DataTable renderer + definition
to each integration's `declarative-gen-ui/a2ui/` matching their existing
ShadCN/card-based style (sourced from strands-typescript, which is the
correct peer, not the inline-style langgraph-python canonical).

Red-green value-test:
- pydantic-ai: RED (turn 2 surface-missing, 90s timeout, data-table=0) →
  GREEN (turn 2 assertions passed, "Here's how the team is tracking...")
- langgraph-typescript: RED (turn 2 surface-missing) →
  GREEN (turn 2 assertions passed, probe advances to turn 3/4)
- claude-sdk-typescript: RED confirmed (turn 2 surface-missing); GREEN
  blocked locally by separate aimock strict-mode miss on turn 1 — unrelated
  class B backend fixture issue, not DataTable. Fix is structurally identical
  to pydantic-ai/langgraph-typescript and confirmed correct by Docker build.
- langgraph-fastapi: container not running locally; fix structurally identical.
2026-07-17 23:22:17 -07:00
Jordan Ritter 34f615a0fb fix(showcase): restore single-source python tool symlinks + iron-rule guard
Restore the 12 Python integration tools/ dirs to symlinks into
shared/python/tools. They had eroded to real, drifting copies via an
accidental stage_shared() leak (commit 534cd1efa7) — the structural root
cause of showcase divergence bugs. Symlinking re-establishes the single
source of truth; content is identical to shared (only render_a2ui naming
and the shared roll_dice/sanitize additions are adopted).

Add showcase/AGENTS.md documenting the 4 iron rules and the single-source
symlink mechanism, plus a validate-shared-symlinks CI guard (shrink-only
baseline) that fails on any NEW erosion.
2026-07-14 22:17:54 -07:00
Tyler Slaton 0f5a916075 fix(docs): clean Claude generative UI snippets 2026-07-08 20:38:13 -07:00
github-actions[bot] 3b5474cb80 style: auto-fix formatting 2026-07-06 22:39:06 +00:00
Jordan Ritter c9907b07a2 fix(showcase): emit A2UI v0.9 nested op format for a2ui-middleware v0.0.10 (gen-ui-declarative surface-missing) 2026-07-06 15:34:40 -07:00
Jordan Ritter 9cbebe3d36 fix(showcase): gate per-request proxy logging behind SHOWCASE_ROUTE_DEBUG
Gates per-request POST + 2xx Response-status + GET health-probe logs behind SHOWCASE_ROUTE_DEBUG across 19 integrations to stay under Railway's 500-logs/sec cap, while logging non-2xx responses unconditionally so production errors stay visible.
2026-07-06 12:15:05 -07:00
Jordan Ritter b4adfc6296 fix(showcase/langgraph): disable watchfiles reload and file persistence in entrypoints
--no-reload stops the watchfiles log flood that tripped Railway's 500-logs/sec replica kill; LANGGRAPH_DISABLE_FILE_PERSISTENCE=true stops unbounded pickle-state growth (OOM). Applies to langgraph-python and langgraph-fastapi.
2026-07-06 12:15:04 -07:00
Ran Shemtov 74b041b29f Merge branch 'main' into claude/nervous-bardeen-37a398 2026-06-29 10:07:45 +02:00
Ran Shem Tov 965c91d594 docs(showcase): A2UI catalog auto-inject + manual opt-out for generated frameworks
Bring the agnostic root A2UI docs up to the catalog-on-provider model and
make every generated framework serve them consistently.

- Root /generative-ui/a2ui (index, fixed-schema, dynamic-schema): lead with
  passing a catalog on the provider (auto-enables A2UI and auto-injects the
  generate_a2ui tool), add a manual opt-out section explaining the two pieces
  you wire yourself (the generate_a2ui agent tool and the A2UIMiddleware), and
  set fixed-schema to injectA2UITool: false since the agent owns the tool.
- Flip langgraph-fastapi, strands, strands-typescript to docs_mode: generated
  so they serve the shared root A2UI docs 1:1 with langgraph-python.

Generated frameworks covered: langgraph-python/fastapi/typescript, google-adk,
strands, strands-typescript. deepagents (authored) is handled separately.
2026-06-26 19:08:23 +02:00
Ran Shem Tov b985449e50 feat(showcase): add A2UI Error Recovery demo for langgraph + strands
Port the google-adk a2ui-recovery demo to langgraph (python, fastapi,
typescript) and aws-strands (python, typescript). Each ships a dedicated
recovery agent, route, demo page/chat/suggestions, manifest entry, aimock
d6 fixtures, e2e spec, and QA doc.

Backend-owned recovery on langgraph via get_a2ui_tools / getA2UITools
(injectA2UITool=false); auto-inject recovery on the strands adapter path.
Heal stages an invalid-then-valid render via aimock sequenceIndex (the
toolkit validate->retry loop rejects the whole surface, so a single-pass
parse_and_fix heal is ADK-specific and does not apply here). Recovery
prompts are unique per framework and the fixtures carry no context match
field, so they fire for real browser (dojo) traffic, not just the harness.

Also harden the strands declarative-gen-ui composition guide to name the
exact catalog component (Metric, not MetricTile) and update the
generate-catalog + aimock-fixtures test expectations.
2026-06-26 16:17:58 +02:00
Jordan Ritter 5057efce1a fix(showcase): render post-sign-out auth rejection across showcase integrations
The auth demo capped at D4 across integrations because the post-sign-out
rejection banner never rendered. The post-sign-out `agent_run_failed` is
delivered only on the agent-scoped `<CopilotChat onError>` channel — never the
provider-level `<CopilotKit onError>` the demos listened on — so the D5/D6 auth
probe's rejection-surface assertion failed and the cell was capped at D4.

Fix (applied to all 19 integrations whose auth demo reproduced the bug): wire a
stable `handleAuthError` onto the agent-scoped `<CopilotChat onError>` (keeping
the provider handler), key the error surface off auth-error STATE alone with a
clear-on-auth effect (removing the `&& !isAuthenticated` cross-slice race), and
harden the rejection-banner message fallback against nullish error events.

Scope: 19 of 20 integrations. built-in-agent already passes (renders via its
ChatErrorBoundary); claude-sdk-python adapted to its legacy/error-boundary shape.
2026-06-25 20:34:01 -07:00
Ran Shem Tov 24a93672f1 feat(showcase): bump CopilotKit 1.61.1 -> 1.61.2 and adopt A2UI catalog auto-inject (#5611)
Bump the canonical CopilotKit pin across all showcase integrations + shell
to 1.61.2 (canonical-pins.json, every package.json + package-lock.json),
which carries CopilotKit#5611: passing a catalog to the provider
(`<CopilotKit a2ui={{ catalog }}>`) now auto-enables A2UI and defaults tool
injection on, so the runtime no longer needs an explicit `a2ui` config.

Demonstrate the feature on the A2UI dynamic (declarative-gen-ui) demos by
removing the now-redundant runtime `a2ui` block (`injectA2UITool: true` +
`defaultCatalogId`) from:
  - langgraph-python, langgraph-fastapi, langgraph-typescript
  - strands, strands-typescript
  - google-adk

The forwarded catalog supplies its own catalogId (sdk-js A2UI middleware
auto-derives `defaultCatalogId` from it), so the previous "Catalog not found"
fallback no longer applies.

Verified: validate-pins drift ratchet unchanged (38 / same hash);
langgraph-python D6 `gen-ui-declarative` green end-to-end (no Catalog-not-found).
2026-06-25 14:03:36 +02:00
Sam Julien 5507c75d2d docs: add framework-scoped Threads callouts (#5651)
## Summary

- Adds a `thread_persistence_pattern` manifest flag so shared docs can
render selected-framework Threads guidance.
- Marks LangGraph Python, LangGraph TypeScript, LangGraph FastAPI, and
Google ADK with the appropriate thread persistence pattern.
- Extends `WhenFrameworkHas` support so the shared Threads guide can
show LangGraph-only and ADK-only callouts.
- Clarifies that `useThreads` manages Enterprise Intelligence Platform
thread records, not native framework stores.
- Adds framework-selected callouts to the root/shared Threads guide
without adding a third setup path.

## Notes

The new callouts intentionally avoid claiming external store listing,
lifecycle sync, migration/import tooling, or durable ADK sessions by
default. Those remain product/runtime follow-ups tracked separately.

## Validation

- `git diff --check`
- `npm run pretypecheck` in `showcase/shell-docs`
- `npm run lint` in `showcase/shell-docs` (passes with existing
warnings)
- `npm run typecheck` in `showcase/shell-docs`
- `npm run build` in `showcase/shell-docs` (passes with existing
Turbopack/NFT warning)
- Local route smoke checks:
  - `/threads` hides framework callouts
  - `/langgraph-python/threads` shows LangGraph callout only
  - `/langgraph-typescript/threads` shows LangGraph callout only
  - `/langgraph-fastapi/threads` shows LangGraph callout only
  - `/google-adk/threads` shows ADK callout only
2026-06-24 11:11:22 -07:00
Ran Shem Tov 9b77e8eeed chore(showcase): upgrade @copilotkit packages to 1.61.1
Bump every @copilotkit/* dependency across the showcase integrations and
the shell from 1.60.2 (and stray "latest" override pins) to an exact
1.61.1 pin, and move the canonical pin source of truth to match.
Regenerate each standalone npm package-lock.json with the same
--legacy-peer-deps flag the Dockerfiles use for "npm ci".

- showcase/integrations/*/package.json + package-lock.json
- showcase/integrations/langgraph-typescript/src/agent/*
- showcase/shell/package.json + package-lock.json
- showcase/scripts/showcase-canonical-pins.json: canonical 1.60.2 to 1.61.1

aimock stays on its own version line (1.26.1). The Python copilotkit SDK
was already 0.1.94 across every requirements.txt, so no change there.

validate-pins ratchet is unchanged (FAIL=38, identical hash);
validate-parity, validate-fixture-tool-surface, and the showcase/scripts
vitest suite (2102 tests) all pass.
2026-06-24 10:39:59 +02:00
Sam Julien 81c716a4aa docs(shell-docs): add framework-scoped threads callouts 2026-06-23 15:07:13 -07:00
github-actions[bot] 691c036789 style: auto-fix formatting 2026-06-19 20:54:20 +00:00
Jordan Ritter 530649864e fix(cvdiag): LGP gates request.ingress/llm.call.*/sse.first_byte to VERBOSE tier matching canonical _BOUNDARY_TIER (M5 CR R3)
The four §6-VERBOSE-only backend boundaries (request.ingress, llm.call.start,
llm.call.response, sse.first_byte) called _emit with no tier_gate, so they
over-emitted at DEFAULT tier — 4 extra events/request vs the middleware family,
breaking the §7 tier budget and cross-backend apples-to-apples parity. Gate
them with tier_gate=_VERBOSE_TIERS, matching emit.ts:58-63 and the agno
_BOUNDARY_TIER. langgraph-fastapi received the identical change (the two LGP
files differ only by docstring/plan-unit/_SLUG). Adds default-suppressed +
verbose-emits red-green coverage; updates the pre-existing first_byte
correlation test to drive at VERBOSE tier (the boundary is VERBOSE-only).
2026-06-19 11:42:52 -07:00
Jordan Ritter a9d2dd342e fix(cvdiag): backend scrub URL-userinfo+Bearer-tail parity + size-guard, live-tier consistency, stop_heartbeat cooperative-cancel across 12 emitters (M5 CR R1) 2026-06-19 11:23:35 -07:00
Jordan Ritter 24de3d1710 feat(cvdiag): backend instrumentation for google-adk + langroid + langgraph-fastapi (L1-D3) 2026-06-18 14:40:32 -07:00
Jordan Ritter dc72e9cac8 feat(cvdiag): Python _shared bootstrap module + 12-integration reachability wiring (L0-C) 2026-06-18 14:06:57 -07:00