mirror of
https://github.com/CopilotKit/CopilotKit.git
synced 2026-09-14 16:26:20 +08:00
codex/cloudplot-showcase-migration
15424 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
d7ccfd3977 | fix(deprecation): warn v1 users to use v2 in IDEs | ||
|
|
06a461ee95 | fix(deprecation): direct v1 users to v2 everywhere | ||
|
|
19c65b23cb | fix(deprecation): use file-specific v2 paths | ||
|
|
08b89de667 | chore: add v1 SDK deprecation pilot | ||
|
|
9542519822 |
feat: share Ops Clerk session in Docs header (#6190)
## Summary - Add a shell-docs public Clerk provider backed by runtime config. - Replace Docs desktop/mobile auth-entry controls with Clerk-aware controls that keep the public CTA until a signed-in Ops session is resolved. - Preserve exact Docs return URLs in dashboard auth-entry links. ## PRD Coverage - Docs remains public and ungated when Clerk is missing, loading, or unavailable. - Signed-in shared Ops sessions render Clerk's standard `UserButton` in the existing auth-control slots. - `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` is included in server/client runtime config. - No Clerk satellite or `satelliteAutoSync` behavior added. ## Validation - `npm run test -- src/lib/runtime-config.test.ts src/lib/runtime-config.client.test.ts src/components/__tests__/brand-nav.test.tsx` (16 tests) - `npm run test` (46 files, 239 tests; required hydrating existing Git LFS image assets locally) - `npm run typecheck` - `npm run lint` (passes with pre-existing warnings) - `npm run build` (passes with pre-existing content/frontmatter warnings) |
||
|
|
a470d61c18 | fix(docs): restore light Channels architecture image | ||
|
|
00339fc028 | Merge branch 'main' into codex/ent-1157-shared-clerk-session | ||
|
|
b203d8f709 |
chore: release monorepo v1.69.0 (#6651)
## Release monorepo v1.69.0 **Scope:** `monorepo` | **Bump:** `minor` --- ### How this release process works 1. **This PR was created automatically** by the "release / create-pr" workflow. It bumped the `monorepo` packages to `1.69.0` and generated AI-enhanced release notes. 2. **CI runs on this PR** — the full test suite (unit tests, lint, type checks, build) must pass before merging. This is the review gate. 3. **Review the release notes** in `release-notes.md` in this PR. If a Notion draft was created, you can edit the release notes there before merging. 4. **When this PR is merged**, the `release / publish` workflow automatically: - Builds all packages - Publishes the `monorepo` packages to npm at version `1.69.0` - Creates git tag `monorepo/v1.69.0` - Creates a GitHub Release with the final release notes ### Before merging - [ ] CI is green (tests, lint, types, build) - [ ] Version bumps look correct - [ ] Release notes are accurate (edit in Notion if a draft was created) --- > **Do not merge until CI is fully green.** The full test suite runs automatically on this PR.v1.69.0 |
||
|
|
fd1c03a9d5 |
docs(showcase): define the Intelligence client the runtime examples reference (#6647)
Closes OSS-900. ## Problem Four docs pages configure a `CopilotRuntime` with an `intelligence` option that nothing on the page produces. `snippets/shared/threads/threads-lifecycle.mdx` was the worst case — `intelligence,` appeared exactly once in the file, never imported, never constructed, never explained — and it renders on `/mastra/threads-lifecycle` plus ten sibling integration routes. A Mastra onboarding run hit this and stopped rather than invent a constructor, which is the correct behaviour and the reason OSS-900 exists. The wiring itself is not missing: `/premium/connect-your-runtime` was published under OSS-881 (#6595) and is already reachable from every framework sidebar. These pages were simply never connected to it. Two further defects surfaced while fixing the first: - `headless-threads.mdx` imported `CopilotRuntime` from `@copilotkit/runtime` — the **v1** root export, whose runtime has no `intelligence` option at all — in the step titled "Configure your Runtime with Enterprise Intelligence", while showing a runtime with no `intelligence` key. - The same example omitted `identifyUser`, which `CopilotIntelligenceRuntimeOptions` requires alongside `intelligence` (absent a Channel). As written it could not type-check, and if forced through would give every visitor one shared thread history. ## Changes - `threads-lifecycle.mdx` and `headless-threads.mdx` build the client inline, so the block a reader copies is complete, and link to `/premium/connect-your-runtime` for the full constructor. - `headless-threads.mdx` moves to the `@copilotkit/runtime/v2` entrypoint and gains the required `identifyUser`. - `auth.mdx` and `backend/copilot-runtime.mdx` keep their focused examples — `intelligence` as a given is right for what they teach — and gain a one-line pointer to the wiring page. - New `intelligence-wiring-docs.test.ts` enforces the contract page-scoped rather than per-fence, which is how `backend/runtime-endpoints.mdx` already satisfies it. ## Testing **The reachability defect I first suspected does not exist.** Before writing anything I probed the sidebar builder, because `docs/integrations/mastra/premium/meta.json` lists only `["overview","self-hosting"]`. `buildFrameworkNav` merges the full root tree with sparse framework overrides, so the Mastra sidebar already carries the page: ``` === MASTRA NAV === section :: Intelligence Platform :: page :: Enterprise Intelligence Platform :: premium/overview page :: Cloud-Hosted Enterprise Intelligence :: premium/managed-intelligence-platform page :: Connect your runtime to Intelligence :: premium/connect-your-runtime page :: Self-Hosting Enterprise Intelligence :: premium/self-hosting === MASTRA has connect-your-runtime: true ``` No nav changes are needed, so none are made. The defect is purely that the pages using `intelligence` never pointed at it. **Scan for the defect class across all 1000+ content files** found six sites, not the one in the ticket — `auth.mdx`, `backend/copilot-runtime.mdx` (×2), `backend/runtime-endpoints.mdx`, and the two threads snippets. `runtime-endpoints.mdx` was already correct (it constructs the client at lines 259/279 with explanatory prose), which is what drove the page-scoped rule. **New test:** ``` ✓ either build the client or link to the page that does ✓ import the runtime from the v2 entrypoint ✓ pair Intelligence with a user identity Tests 3 passed (3) ``` **Mutation-checked** — each assertion fails only when its own mechanism is broken, and the other two stay green: | Mutation | Result | | --- | --- | | Strip the constructor + link from `threads-lifecycle` | `× either build the client or link to the page that does` — 1 failed, 2 passed | | Restore the v1 root import in `headless-threads` | `× import the runtime from the v2 entrypoint` — 1 failed, 2 passed | | Drop `identifyUser` from `headless-threads` | `× pair Intelligence with a user identity` — 1 failed, 2 passed | **No regressions.** Full `showcase/shell-docs` library suite, with all generated data present: ``` Test Files 33 passed (33) Tests 326 passed (326) ``` (An earlier run here reported failures; those were entirely stale/missing generated data in the worktree — `registry.json`, `frontend-registry.json`, `angular-source-content.json`, `search-index.json`. Regenerating them clears every one. Nothing in this diff was implicated.) ## Out of scope `examples/integrations/*/src/app/api/copilotkit/[[...slug]]/route.ts` — all 16 still use `createCopilotEndpoint`, deprecated at `packages/runtime/src/v2/runtime/endpoints/hono.ts:89`. Real, but a separate change. Worth flagging for whoever picks up ENT-1142: main has unified on `INTELLIGENCE_API_KEY` and there is now a pre-commit hook enforcing it (`scripts/validate-intelligence-env-names.ts`). ENT-1151 and ENT-1142's done-when both specify `CPK_INTELLIGENCE_API_KEY`, which contradicts shipped main. 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
dfac2c6347 | Merge branch 'main' into codex/ent-1157-shared-clerk-session | ||
|
|
9fdce06c58 |
Merge remote-tracking branch 'origin/main' into ben1/oss-900-surface-intelligence-wiring
# Conflicts: # showcase/shell-docs/src/content/snippets/shared/threads/headless-threads.mdx |
||
|
|
71977ddfce | chore: release monorepo v1.69.0 | ||
|
|
d2c3b5c306 |
fix: move docs and examples off the v1 runtime entrypoint (#6617)
Moves docs and examples off the deprecated v1 runtime entrypoint, so a reader who follows a quickstart ends up with a runtime that can actually be probed (`GET /api/copilotkit/info`). **Stage 0** proves the target shape in a real running app; **Stage 1** propagates that proven code into the docs. 50 files. No file owned by #6517 or #6582 is touched (verified against the full ownership list). Stacks cleanly with #6618, which does the same for `showcase/integrations/**`. ## Stage 0 — `examples/shadcn`, proven live A textbook instance of the reported bug: a v1, POST-only route behind a `@copilotkit/react-core/v2` frontend. | | Before | After | | --- | --- | --- | | `GET /api/copilotkit` | **405** Method Not Allowed | 404 (correct: multi-route serves nothing at the bare basePath) | | `GET /api/copilotkit/info` | **404** — Next.js HTML 404, the path did not route at all | **200** | | `POST /api/copilotkit/agent/default/run` | n/a | **200**, chat turn renders in the UI | Exact `GET /api/copilotkit/info` body from the running app: ```json { "version": "1.61.2", "agents": { "default": { "name": "default", "description": "", "className": "BuiltInAgent", "capabilities": { "tools": { "supported": true, "clientProvided": true }, "transport": { "streaming": true }, "humanInTheLoop": { "interrupts": true } } } }, "audioFileTranscriptionEnabled": false, "mode": "sse", "threadEndpoints": { "list": true, "inspect": true, "mutations": false, "realtimeMetadata": false }, "a2uiEnabled": false, "openGenerativeUIEnabled": false, "telemetryDisabled": false } ``` (Captured before the `@copilotkit/*` bump in the same commit, hence `1.61.2`.) The model backend was aimock — `@copilotkit/aimock` 1.37.4, the same mock the `test / integration / docs` CI job uses — so the chat turn is real traffic through the migrated route with no live API key. ## Three findings that changed the shape of this work All three came from running the code rather than reading it, and all three affect every page Stage 1 touches. ### 1. The plan's canonical shape was deprecated, and that is where `hono` came from The prescribed snippet was `createCopilotEndpoint` + `handle` from `hono/vercel`. `createCopilotEndpoint` is a **deprecated alias** — this repo's own handler table in `docs/backend/runtime-endpoints.mdx` lists it under "Deprecated → use `createCopilotHonoHandler`". `createCopilotRuntimeHandler` serves the same multi-route mode (it is the default), returns a plain fetch handler, is not deprecated, and needs **no `hono` at all**: ```ts const handler = createCopilotRuntimeHandler({ runtime, basePath: "/api/copilotkit", }); export const GET = handler; export const POST = handler; ``` I first propagated the deprecated shape and then documented installing `hono` to make `hono/vercel` resolve under pnpm. Both are reverted in `720910833e`: `hono` was an artifact of the shape, not a requirement of the library. Verified by **deleting `node_modules/hono` outright**, not merely removing it from `package.json`, so a hoisted copy could not mask the result — `GET /info` → 200, `POST /agent/default/run` → 200, turn renders. No sidecar lists `hono` any more, so CI proves by construction that these snippets do not need it. ### 2. The multi-route runtime needs a frontend co-change, and the docs said otherwise Published `<CopilotKit>` still ships ```js useSingleEndpoint={props.useSingleEndpoint ?? true} ``` (verified in the `@copilotkit/react-core` 1.68.3 bundle), pinning the single-route transport. A multi-route runtime answers that envelope with **404 while `GET /info` still returns 200**, so the app looks connected. The runtime diagnoses it itself: > Received a single-route request envelope (`{ method: "..." }`) but this runtime is mounted in multi-route mode, so the request matched no route. If the frontend uses `<CopilotKit>` from `@copilotkit/react-core/v2`, pass `useSingleEndpoint={false}` — that provider defaults it to true. `backend/runtime-endpoints.mdx` — the authoritative page — said the opposite: that omitting the prop is safe on either provider because the client negotiates. True on `main` (#6605 removed the pin, merged today, unreleased) and **false in every published release**. `auth.mdx`, `custom-agent.mdx` and two quickstart callouts repeated it. All corrected: the pairing table now splits `<CopilotKit>` from `<CopilotKitProvider>` and says passing `{false}` is the forward-compatible choice — required now, harmless later. **This is a live docs defect independent of the migration.** So the v2 multi-route shape is *not* a drop-in for a v1 route: changing only the route file converts a working POST-only app into a broken one. ### 3. `showcase/shell`'s `@ts-ignore` is stale Its canonical route carries `// @ts-ignore — BuiltInAgent type mismatch with AbstractAgent, pending upstream fix`. `tsc --noEmit` passes without it on 1.68.3, so the docs snippets carry no suppression. Angular needs none of this: `provideCopilotKit` defaults its transport to `"auto"`. Those snippets are unchanged. ## The docs snippets now have a real CI gate The plan assumed there is no automated gate on `.mdx` snippets. There are two, and both mattered: - **`showcase/scripts/verify-shell-docs.ts`** asserts the *content* of titled fences, and for the two Claude SDK quickstarts it **requires** `ExperimentalEmptyAdapter` and `copilotRuntimeNextJSAppRouterEndpoint` — actively pinning those pages to v1. - **`scripts/doc-tests/{extract,run}.ts`** runs in CI (`test / integration / docs`): a fence tagged `doctest="component"` is extracted and typechecked with `tsc --noEmit` against real npm-installed deps. Exactly **one** fence in the whole docs tree opted in. **20 route snippets across 20 pages are now tagged `doctest="component"`** and typechecked in CI against real npm-installed packages. I had claimed the integration pages couldn't be doctested (path aliases, per-integration deps) — that was an assumption I never checked and it was wrong: 47 of 52 fences import nothing project-relative. Five harness defects blocked this and are fixed: - `extract.ts` wrote a fence title as a path without creating intermediate directories → ENOENT on any titled route fence. - `run.ts` derived the npm package name from the snippet directory; a catch-all leaf directory is literally `[[...slug]]`, which npm rejects. - `run.ts` looked for `doctest.json` only in the snippet's own directory while the sidecar is copied per page, so a nested snippet silently installed nothing and failed with "Cannot find module". - `extract.ts` found sidecars only in a page's own directory, which would have meant ~20 duplicated dependency lists; it now walks up to the docs root, so one shared list lives at `content/doctest.json`. - `run.ts` installed dependencies per snippet — **7:58** for 21 snippets against a 15-minute job timeout. Each dep set now installs **once** into `.doctest-output/.deps/<hash>` and is linked in: **0:45** cold. **Mutation-checked:** restoring the v1 import in a gated fence turns the run red (20 passed, 1 failed). My first attempt at this check was a silent no-op — the pattern missed because the fence is JSX-indented, and it "passed" misleadingly. The real check asserts the mutation reached the extracted snippet before trusting the result. `@ag-ui/*` has to be pinned to what the runtime expects (`@ag-ui/client@0.0.57`, `@ag-ui/core@0.0.57` for runtime 1.68.3). Unpinned, npm installs a newer `@ag-ui/client` and two `AbstractAgent` declarations collide: `separate declarations of a private property '_debug'`. **Seven fences are deliberately not gated**, un-tagged with reasons rather than left red: two are illustrative fences with placeholder identifiers (`myAgent`, `verifyJwt`), and five langgraph-family fences hit that same `_debug` collision via `@copilotkit/runtime/langgraph`, which pinning does not fix. **That one is a pre-existing package defect, not a migration regression** — I reconstructed the v1 form of the langgraph quickstart snippet verbatim from `origin/main`, typechecked it against identical deps, and it fails the same way. Those snippets have never typechecked against published packages. Worth filing; it is also what the ~220 `@ts-ignore` comments in `showcase/integrations` were papering over. ## A mistake worth recording A block regex scoped to the fence's opening indentation corrupted five quickstart pages: their fences open and close at *different* indentation, so the match ran past the closing backticks and re-indented the following `</Step>` / `</Tab>` into the code block. Reverted and redone with a line-oriented pass that never re-indents and re-emits the closing line verbatim. (A malformed `runner:` insertion on three a2ui pages was caught and redone the same way.) Every modified page is now checked structurally — fence-marker count plus every JSX structural line, indentation included, must be byte-identical to `HEAD`. That check found the corruption; a diff review had already missed it. ## Verification ``` pnpm tsx scripts/doc-tests/extract.ts -> 21 snippets pnpm tsx scripts/doc-tests/run.ts -> 21 passed, 0 failed (0:45 cold) vitest extract + verify-shell-docs -> 34 passed showcase/shell-docs: pnpm typecheck -> exit 0 showcase/shell-docs: pnpm lint -> exit 0 (pre-existing warnings only) showcase/shell-docs: pnpm build -> exit 0 examples/shadcn: tsc --noEmit / eslint / next build -> all clean, route ƒ /api/copilotkit/[[...slug]] structural audit -> every modified page, fence + JSX identical to HEAD ``` CI was green on the previous head (35 pass / 3 skip), including `doc-tests` and `format`. This validates that the pages build and that the one doctested snippet compiles. **It does not execute the remaining 32 fences.** Their correctness rests on Stage 0: the boilerplate they now contain is the text that was run in `examples/shadcn`, and each page's agent wiring is untouched. `LangGraphAgent` + v2 `CopilotRuntime` + `createCopilotRuntimeHandler` were typechecked together against published 1.68.3, since many pages depend on that combination. ## What could not be migrated, and why | Page | Why | | --- | --- | | `agentic-protocols/mcp.mdx` (self-hosting section) | Built on `createMCPClient`, which exists only in v1 (`packages/runtime/src/lib/runtime/copilot-runtime.ts`). v2's equivalent is `mcpApps`; converting is a content rewrite, not a mechanical migration. | | `snippets/self-hosting-copilot-runtime-create-endpoint.mdx` | The whole page is templated on v1 service adapters (`{{adapterImport}}`, `{{adapterSetup}}`). v2 has no service adapters. Needs a rewrite of the page's premise. | | Pages Router / NestJS tabs in the `self-hosting-*` snippets | v2 exports no equivalent factory — only `createCopilotRuntimeHandler` and the Hono/Express/Node handlers. The App Router tab on each page **is** migrated. | | Node HTTP / Express tabs | v2 equivalents exist (`createCopilotNodeHandler`, `createCopilotExpressHandler`) but I have not run them, and the rule here was not to write a snippet I have not run. | | `custom-agent.mdx` (both copies) | Three fences each still call `createCopilotEndpoint` as `export default copilotEndpoint` — the Hono-app deployment pattern, not a Next.js route. Predates this PR; the documented replacement is `createCopilotHonoHandler`, which I have not run. The two copies have also drifted from each other. | Deliberate v1 *prose* is left alone: `backend/copilot-runtime.mdx`'s v1→v2 mapping table and `auth.mdx`'s note that the v1 adapter does not forward `hooks` are correct as written. ## Other out-of-scope gaps, recorded so they can be filed - **Mastra docs name `CopilotKitIntelligence`** but never document constructor, project, thread, or user wiring. - **The A2UI fixed-schema guide** depends on showcase helpers not published as a package, so it cannot be followed standalone. - **`showcase/shared/starter-template` is not a runnable app** — no `package.json`, `next.config`, or `tsconfig`, so its route cannot be proved by running it. It was the plan's Stage 0 target on the grounds that "the CLI scaffolds from it"; nothing in CopilotKit `packages/**` or `Intelligence/apps/cli/src` references it, so that rationale does not hold. Its route is still v1 and still exports a hand-rolled `GET` that fetches the *agent's* `/health` and shadows `/info`. Queued behind a decision on where that status payload should live. - **`@copilotkit/cli@latest` (0.0.6) has no `verify` command**, so the `runtime_reachable: pass` evidence the plan asked for cannot be produced with the public CLI. The Intelligence CLI's `verify` is the one that probes `<runtimeUrl>/info` (`apps/cli/src/services/verify-probes.ts`), and the Stage 0 app satisfies that probe with a 200 — but the public-CLI artifact does not exist to paste. - **Two generators still emit v1** and will re-seed the problem: `showcase/scripts/create-integration/index.ts` and `examples/showcases/chatkit-studio/apps/playground/src/utils/codeGenerator.ts`. ## Corrected counts The plan's figures were all low, partly because they matched only double-quoted imports. Measured on `origin/main` at `43f1ef3039`: | Surface | Plan said | Actual | | --- | --- | --- | | v1 code files (`examples/` + `showcase/`, excl. `examples/v1/**` and `_legacy/`) | 244 | **352** | | `showcase/**` importing `@copilotkit/runtime` | 229 | **289** | | Docs files touching the v1 entrypoint | 44 (37 in scope) | **22 (12 in scope)** — the plan counted only `from "@copilotkit/runtime"`; the real set is smaller but includes single-quoted and factory-only files it missed | | Mixed v1-runtime + v2-frontend pages | 20 | **26** | | Files already on `createCopilotEndpoint` | 10 | **43 call sites** | ## Remaining - **Docs:** 52 route fences across 40 pages are on the v2 shape, **20 of them gated in CI**. The two Claude SDK quickstarts are migrated now that #6618 has landed. 7 pages still reference v1, every one for a reason in the tables above (several are deliberate prose). - **Code:** `showcase/integrations/**` (239 files) is handled in **#6618**. `examples/v1/**` (12 files) is deliberately v1 and never in scope. The rest of `examples/` is not in either PR. 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
6e0f5773f0 |
Merge remote-tracking branch 'origin/main' into ben1/v2-runtime-migration
# Conflicts: # showcase/shell-docs/src/content/snippets/shared/generative-ui/a2ui.mdx |
||
|
|
6b9aadf025 |
fix(runtime): stop emitting a require() statement in published .d.cts (#6644)
Fixes the part of OSS-899 that is hard to defend: every `.d.cts` file we
publish from `@copilotkit/runtime` starts with a `require()` call.
## The bug
A consumer whose only source file is `import { CopilotRuntime } from
"@copilotkit/runtime";`, compiled with `strict` and `skipLibCheck:
false`, gets **81 errors** on a bare install of 1.68.3. **71 of them are
`TS1036` "Statements are not allowed in ambient contexts"**, raised
inside our own shipped declarations.
Cause is in `packages/runtime/tsdown.config.ts`. The banner that
guarantees `reflect-metadata` loads before `type-graphql` was returned
as a **string**. tsdown's `resolveChunkAddon` routes an *object* return
by chunk kind (`js` / `dts` / `css`) but applies a *string* return to
**every** emitted chunk — declarations included. So all 87 published
`.d.cts` files began:
```ts
require("reflect-metadata");
import { CopilotRuntimeLogger, ... } from "./lib/logger.cjs";
```
A `require()` call is a statement, and a `.d.ts` is an ambient context.
One error per file.
Two reasons this went unnoticed for so long:
- Every scaffolder sets `skipLibCheck: true`. Verified in genuine `ng
new` and `create-next-app` output. A developer who scaffolds normally
never sees it.
- The `.d.mts` flavour got `import "reflect-metadata";`, which is a
legal side-effect import in a declaration file. **ESM-resolving
consumers saw zero `TS1036`.** Only CJS resolution is affected.
## The fix
Return an object so tsdown routes by chunk kind — JS keeps its
`reflect-metadata` prologue, declarations get nothing.
The `fileName.includes("_virtual/_rolldown/runtime")` condition is
dropped as well, and that is the more interesting half.
`resolveChunkAddon` reassigns its own closure variable on the first
call:
```js
if (typeof chunkAddon === "function") chunkAddon = chunkAddon({ format, fileName: chunk.fileName });
```
so a function banner is evaluated **once** and its result reused for
every later chunk. The old config's comment ("propagates to all output
files per format") described that as intended behaviour, but it was
really a condition deciding the banner for the entire build based on
whichever chunk happened to be emitted first. Keying on `format` alone —
fixed per build — is order-independent.
The object form is tsdown's declared API, not a workaround:
`ChunkAddonFunction` returns `ChunkAddonObject | string | undefined`
where `ChunkAddonObject` is `{ js?, css?, dts? }`. `tsc --noEmit
--strict` on `tsdown.config.ts` against tsdown's own types is clean —
worth stating because the config is in no tsconfig `include`, so nothing
else typechecks it.
## The guard
`scripts/validate-dts-ambient.ts` parses each built declaration with the
TypeScript compiler API and fails on any top-level node that is not a
declaration, import, or export. Wired as a `check-dts` nx target shaped
exactly like the existing `publint` / `attw` / `compat-check` targets
(`dependsOn: ["build"]`, `inputs` on `dist/**`), and folded into the
`check:packages` script that the `package-quality` CI job already runs.
That job already builds runtime for `publint`, so the added cost is one
177-file parse.
Only `@copilotkit/runtime` opts in, because it is the only offender.
Running the validator itself over the built declarations of all 32
packages: **87 of runtime's 177** bad on the published 1.68.3 artifact,
and **0** in every other package. Others can opt in with the same
one-line script.
## Testing
**1. Reproduce the reported defect on the published package.** Bare `npm
install @copilotkit/runtime@1.68.3 typescript`, `probe.ts` importing
only `CopilotRuntime`, tsconfig with `strict`, `skipLibCheck: false`,
`module`/`moduleResolution` `nodenext`:
```
$ npx tsc --noEmit ; echo exit=$?
exit=1
$ grep -oE 'error TS[0-9]+' tsc.out | sort | uniq -c | sort -rn
71 error TS1036
5 error TS2416
2 error TS7016
2 error TS2307
1 error TS2694
```
81 errors, matching the issue. All 71 `TS1036` are at line 1, column 1
of a `.d.cts`.
**2. Confirm the mechanism.** Every published declaration's first line,
before the fix:
```
-- *.d.cts -- total: 87
87 require("reflect-metadata");
-- *.d.mts -- total: 90
90 import "reflect-metadata";
```
**3. Same probe across every public subpath, before and after.** Built
`packages/runtime` at 1.68.3 with this change and swapped the result
into the probe's `node_modules`. `total` is all errors; `1036` is the
subset this PR addresses.
| subpath | CJS before | CJS after | ESM before | ESM after |
| --- | --- | --- | --- | --- |
| `@copilotkit/runtime` | 81 (71×1036) | **10** (0) | 10 (0) | 10 (0) |
| `/v2` | 32 (29×1036) | **3** (0) | 3 (0) | 3 (0) |
| `/langgraph` | 15 (4×1036) | **7** (0) | 7 (0) | 7 (0) |
| `/v2/express` | 21 (18×1036) | **3** (0) | 3 (0) | 3 (0) |
| `/v2/hono` | 21 (19×1036) | **2** (0) | 2 (0) | 2 (0) |
| `/v2/node` | 22 (20×1036) | **2** (0) | 2 (0) | 2 (0) |
Zero `TS1036` on every subpath in both module modes, and **after the fix
each subpath's CJS count equals its ESM count** — the CJS-only penalty
is gone and nothing else moved. Every ESM column is untouched, which is
the expected result since `.d.mts` never carried the bad banner.
The errors that remain are the separate items catalogued on OSS-899
(optional-peer SDK types, `@types/cors`, a `lru-cache` variance error
from `graphql-yoga`, a zod namespace skew in
`@copilotkit/license-verifier`) and are not touched here.
**4. `reflect-metadata` still runs first in every JS output.** This is
what the banner exists for, so it is the thing most at risk from the
change:
```
cjs files with require("reflect-metadata") as line 1: 131 / total 131
mjs files with import "reflect-metadata" as line 1: 132 / total 132
```
**5. Nothing but the banner line changed.** Diffed every one of the 87
built `.d.cts` files against the published 1.68.3 artifact from line 2
onward. Exactly one file differs, and it is unrelated source drift — a
JSDoc env-var rename from `6f58b2c6a4` (`COPILOTKIT_API_KEY` →
`INTELLIGENCE_API_KEY`, refs OSS-881) that landed on main after 1.68.3
shipped. Line counts are also identical, so declaration sourcemaps do
not shift.
The `_virtual/_rolldown` reference count in declarations is 2 before and
2 after — that item is deliberately out of scope here.
**6. The guard catches the regression it exists for.** Reverted the
banner to its pre-fix string form, rebuilt, and ran the new target:
```
$ pnpm exec tsx ../../scripts/validate-dts-ambient.ts dist
Found 87 statement(s) in published declarations.
A .d.ts is an ambient context: only declarations, imports, and exports are
allowed. Each of these is a TS1036 error for consumers on skipLibCheck: false.
dist/agent/converters/aisdk.d.cts:1 require("reflect-metadata");
...
exit=1
```
Restored the fix and rebuilt:
```
$ pnpm exec tsx ../../scripts/validate-dts-ambient.ts dist
validate-dts-ambient: dist clean (177 files).
exit=0
```
**7. Validator unit tests, mutation-checked.**
`scripts/__tests__/validate-dts-ambient.test.ts`, 7 tests covering the
exact OSS-899 banner, the legal ESM form, every declaration form a real
`.d.ts` uses, line-number reporting, and ignoring sibling `.cjs`/`.map`
files.
```
Test Files 1 passed (1)
Tests 7 passed (7)
```
Then broke the mechanism three ways to confirm the tests are not
self-fulfilling:
| mutation | result |
|---|---|
| allow `ExpressionStatement` in the kind allowlist | 2 failed / 5
passed |
| drop the `line + 1` conversion | 2 failed / 5 passed |
| scan only `.d.ts`, not `.d.mts` / `.d.cts` | 3 failed / 4 passed |
| restored | 7 passed |
**8. Runtime suite and packaging targets, on a clean `pnpm install
--frozen-lockfile` in this worktree.**
```
$ nx run @copilotkit/runtime:test
Test Files 143 passed (143)
Tests 2073 passed (2073)
$ nx run-many -t publint,attw,check-dts --projects=@copilotkit/runtime
NX Successfully ran targets publint, attw, check-dts for project @copilotkit/runtime
```
`attw --profile node16` reports 🟢 from both CJS and ESM; the `node10`
failure is pre-existing and ignored by the profile.
**9. Formatting and types.** `oxfmt --check` clean on all three source
files; `tsc --noEmit --strict` clean on the new script.
## Overlap with #6476
#6476 (`adopt TypeScript 7 and tsdown 0.22`) bumps tsdown to 0.22.14 but
does **not** touch `packages/runtime/tsdown.config.ts`, so it does not
fix this. The two PRs conflict only textually — both add lines to
runtime's `scripts` block and to the root `package.json`. This fix uses
tsdown's documented object-banner form, so it holds whether or not 0.22
changed `resolveChunkAddon`'s memoization.
No changeset: this ships through the normal release scopes.
|
||
|
|
36d9f16a26 |
fix(showcase): make the A2UI fixed-schema guide followable (OSS-901) (#6645)
Closes OSS-901.
## Problem
`/mastra/generative-ui/a2ui/fixed-schema` could not be followed. A
Mastra onboarding run on Codex stopped there rather than invent an API,
reporting that the guide "depends on unbundled showcase helpers."
That is true, and the mechanism is worse than the report. Region bodies
are assembled at bundle time, so what ships is invisible in a source
diff. The `backend-render-operations` marker sits on **line 1** of
`mastra/src/mastra/tools/index.ts` — put there by the marker-hoist sweep
in
|
||
|
|
76c8e23a0b |
feat(web-inspector): add Event Snippets and save-as-snippet
Developers can compile, save, and replay AG-UI events from Inspector. Localhost chat can save a live turn as a snippet. |
||
|
|
7bff49739e | fix(runtime): replace retired Anthropic model IDs (#6616) | ||
|
|
018160e443 | docs(showcase): drop the plain-object contrast on the Intelligence client step | ||
|
|
5ca110e29c |
docs: gate 20 route snippets in CI and migrate the Claude SDK quickstarts
Two things this PR was missing, both now closed. ## The Claude SDK quickstarts are unblocked #6618 put `showcase/integrations/claude-sdk-{python,typescript}` on `createCopilotRuntimeHandler` with `mode: "single-route"`, at the **plain** `route.ts` path. That dissolves the coupling that forced these two pages to be reverted earlier: `verify-shell-docs.ts` asserts each page claims a starter file at `src/app/api/copilotkit/route.ts` AND that the file exists in the extracted starter. Single-route keeps that path, so the prose claims and `requiredStarterFiles` are unchanged — only the fence bodies move to v2. The two content assertions that pinned those pages to v1 (`ExperimentalEmptyAdapter`, `copilotRuntimeNextJSAppRouterEndpoint`) now require `createCopilotRuntimeHandler`, the `/v2` entrypoint, `mode: "single-route"` and a `POST` export. Mutation-checked: flipping the fixture to `mode: "multi-route"` fails with `app/api/copilotkit/route.ts missing single-route mode`. ## Snippet gating: 1 -> 20 route fences I previously claimed the integration pages could not be doctested because of path aliases and per-integration deps. **That was an assumption I never checked, and it was wrong.** Of the 52 migrated route fences, 47 import nothing project-relative; 36 are complete, self-standing routes. 27 pages were eligible, 20 now hold a gated fence — each extracted and typechecked by `tsc --noEmit` against real npm-installed packages in CI. One fence per (page, title): `extract.ts` concatenates tagged blocks sharing a title, so a second complete route on the same page would collide. Mutation-checked on `snippets/integrations/langsmith/index.mdx`: restoring the v1 import in the gated fence turns the run red (20 passed, 1 failed). My first attempt at this check was a no-op — the pattern missed because the fence is JSX-indented — and it "passed" misleadingly. The real check asserts the mutation reached the extracted snippet before trusting the result. ### Harness changes this needed - `extract.ts` now finds the nearest `doctest.json` by walking up to the docs root, instead of looking only in the page's own directory. Otherwise gating 20 pages means ~20 duplicated dependency lists that then drift. A shared list lives at `content/doctest.json`; `docs/integrations/langgraph/` keeps its own (Python deps) and now also carries the TS deps its page needs. - `run.ts` installs each dependency set **once**, into `.doctest-output/.deps/<hash>`, and links it into every snippet sharing that set. Per-snippet installs took **7:58** for 21 snippets, uncomfortably close to the job's 15-minute timeout; shared installs take **0:45** cold. Different dep sets still get separate stores, so this is a dedupe, not a merge. ### `@ag-ui/*` versions have to be pinned to what the runtime expects Unpinned, the gated fences failed with `HttpAgent is not assignable to AbstractAgent — separate declarations of a private property '_debug'`: npm installs a newer `@ag-ui/client` than `@copilotkit/runtime` depends on, so two `AbstractAgent` declarations collide. The sidecar pins `@ag-ui/client@0.0.57` and `@ag-ui/core@0.0.57` to match `@copilotkit/runtime@1.68.3`. ## Seven fences are deliberately NOT gated Un-tagged with the reason, rather than left failing or quietly dropped: - `docs/auth.mdx`, `docs/premium/connect-your-runtime.mdx` — illustrative fences referencing placeholders (`myAgent`, `verifyJwt`) that cannot compile standalone by design. - the four langgraph-family pages and `snippets/self-hosting-copilot-runtime-langgraph-endpoint.mdx` — these hit `LangGraphAgent is not assignable to AbstractAgent — separate declarations of a private property '_debug'`, which pinning does not fix. **That last one is a real pre-existing defect, not a migration regression.** I reconstructed the v1 form of the langgraph quickstart snippet verbatim from `origin/main` and typechecked it against the identical installed dependencies: it fails with the same error. So these snippets have never typechecked against published packages — worth filing separately. It is also what the ~220 `@ts-ignore` comments across `showcase/integrations` were papering over. ## Verified doc-tests (cold, no cache) -> 21 passed, 0 failed in 0:45 mutation check (real, verified) -> 20 passed, 1 failed vitest extract + verify-shell-docs -> 34 passed showcase/shell-docs typecheck -> exit 0 showcase/shell-docs build -> exit 0 structural audit -> 21/21 pages, fence + JSX identical to HEAD Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
26a1aa537c | docs(showcase): drop the redundant plain-object contrast | ||
|
|
49c0166629 |
chore(angular): Upgrade to Angular 22 (#6521)
Upgrade the Angular library, demo, and Storybook setup to Angular 22, including the Angular CLI, compiler, CDK, TypeScript, and related build tooling. Apply the Angular 22 migrations, retain strict template checking, adopt the migrated change-detection defaults, remove obsolete safe-navigation wrappers and empty imports, and update the icon integration from lucide-angular to @lucide/angular while retaining the core lucide package required by the inspector. Update the documented support policy and package metadata to Angular 22. The published library is compiled and tested against Angular 22.0 to protect the minimum supported version, including installation, SSR, hydration, and zoneless browser verification through a packed consumer. |
||
|
|
7975c5f3da |
docs(showcase): define the Intelligence client the runtime examples reference
Four docs pages configured a CopilotRuntime with an `intelligence` option that nothing on the page produced. A Mastra onboarding run hit this on /mastra/threads-lifecycle and stopped rather than invent a constructor (OSS-900). The wiring itself was published as /premium/connect-your-runtime under OSS-881; these pages were never connected to it. - threads-lifecycle and headless-threads now build the client inline, so the block a reader copies is complete - headless-threads imported CopilotRuntime from the v1 root, whose runtime has no `intelligence` option at all, and omitted the `identifyUser` that the Intelligence runtime requires - auth and backend/copilot-runtime keep their focused examples and gain a pointer to the wiring page The test enforces the contract page-scoped rather than per-fence, which is how backend/runtime-endpoints already satisfies it. |
||
|
|
0c9e4546c6 |
feat(web-inspector): signal wiring failures from the launcher
The launcher gains a red dot, and one beat, when the app's wiring is broken: the runtime connection is in its error state, or a thread load failed. It is a state indicator, so it clears itself when the problem goes and there is nothing to dismiss. A failed agent run deliberately does not raise it. A run failure is an event, not a state, and an hour of iteration produces many of them; the launcher would be red most of the time and carry no information. System Health already reports run errors inside the panel, which is a latest-activity readout rather than a health verdict. The core error channel is unused for the same reason: all but one of its emit sites are in the run handler, and its single wiring code already sets the connection state. Memory failures are excluded because the memory store subscribes lazily, so the state is unobservable until the Learning view has been opened once. Two signals now share a described table with a tone, a cadence, a priority and two destinations. The generic version of this was removed before the launcher-signal merge as speculative, which was right at the time: it had one user. It has two now. A pulse that cannot land is deferred rather than dropped, and only one runs at a time. Starting a beat while one runs does not restart the CSS animation, so the running beat would otherwise just change colour mid-flight and the new one would be lost. Telemetry gains oss.inspector.error_signal_viewed, modelled on the announcement equivalent, plus has_error_signal and error_signal_source on the open event. The failure message is never transmitted. The catalogue moves to twenty-four names. A runtime that dies mid-session is out of reach: the handshake runs once and a transport-level run failure is reported through the run channel without touching the connection state. Filed as OSS-904, to be fixed in core so every reader benefits. Refs OSS-903 |
||
|
|
42a0177fe7 |
style: drop a stray blank line in the strands a2ui module
Reapplies the formatter fix the CI auto-format job pushed (13bed7d4), which a rebase force-push dropped. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
a43bd7c5ae |
docs(a2ui): move the runtime snippet to the v2 handler
The A2UI setup page imported `ExperimentalEmptyAdapter` and `copilotRuntimeNextJSAppRouterEndpoint` and then used neither, so the block was a truncated route a reader could not run. Show a complete route — and show the current API while doing it: #6618 retired the v1 runtime adapter across every showcase integration, so the page now uses `createCopilotRuntimeHandler` from `@copilotkit/runtime/v2` in the single-route form, matching `mastra/src/app/api/copilotkit-a2ui-fixed-schema/route.ts` and the reference in /runtime-server-adapter. That also settles the entrypoint question OSS-901 raised. The complaint was that the page mixes v1 `@copilotkit/runtime` with `@copilotkit/react-core/v2` below — not a broken pairing (v1's `CopilotRuntime` forwards `a2ui` straight to the v2 runtime), but the v1 root import was the stale half, so both halves of the page are now v2 entry points. The legacy form is noted as still working for readers who are on it. On the fixed-schema page, note that the LLM-driven integrations have no `a2ui.render(...)` equivalent, so the operation builder in the snippet is part of what a reader copies — and that the operations are nested, since a flat `{ type: "create_surface" }` is silently ignored. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
737a9a86cb |
feat(showcase): guard published snippet bodies in the demo bundler
Region bodies are assembled at bundle time, so neither failure mode in the two preceding commits is visible in review — the source diff looks fine while the docs page renders a 400-line slab or an uninstallable import. Two checks over every region the bundler is about to publish: - Any `@copilotkit/showcase-*` specifier fails the build. These resolve only through a tsconfig path alias to a symlink in this repo, so they cannot appear in a snippet a reader is meant to copy. The corpus is at zero once OSS-901 is fixed, so there is no baseline. - Over 200 lines fails the build. The median region is 28 lines and p90 is 125, so 200 catches a marker sitting above unrelated code without arguing about genuinely long single-purpose files (the 344-line declarative-gen-ui renderers.tsx is the point of that page). The 48 regions already over the line are baselined by `slug::region::file` and the list only shrinks. Both are reported together for the whole run, so one build lists every unfollowable snippet instead of only the first. Verified against the pre-fix tree: the guard exits 1 and names both the mastra `@copilotkit/showcase-shared-tools` bodies and the 586-line strands region. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
38bb3f27e5 |
fix(showcase): give the strands A2UI tool its own module
Same defect as the mastra cell, same page: the `backend-render-operations`
marker is hoisted to the top of `agents/agent.py`, so
`/aws-strands/generative-ui/a2ui/fixed-schema` published 586 lines of a
1688-line module — the messages-snapshot wrapper, the weather/dice/query
tools, everything — instead of the A2UI tool the step is about.
Move `generate_a2ui` and its `_A2uiError` shape into
`agents/a2ui_generate.py`, which is what `gen_ui_agent.py` /
`a2ui_dynamic.py` already do for their own surfaces ("this module lives in
its own file so the surface area is reviewable in isolation"). `agent.py`
imports the tool back for the shared agent's tool list, so the wiring and
the tool id are unchanged; the published snippet is now 171 lines with its
own imports. `tools/generate_a2ui.py` joins the cell's highlighted files so
the guide also shows the helper the tool calls.
The error-handling suite patched `agents.agent.build_a2ui_operations_from_tool_call`,
which now lives on the new module — retargeted, and it still imports the
tool via `agents.agent` so the re-export stays covered.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
17385a8f6d |
fix(showcase): make the mastra A2UI fixed-schema snippet followable
`/mastra/generative-ui/a2ui/fixed-schema` published the entire 432-line
tools barrel, because the `backend-render-operations` marker sits at the
top of the file (the marker-hoist sweep in
|
||
|
|
b53edc0a6e |
docs: drop the hono dependency and the deprecated endpoint alias
The earlier commits in this PR taught `createCopilotEndpoint` paired with
`handle` from `hono/vercel`, and added `hono` to 20 install commands with a
callout explaining why readers must install it. Both were wrong, and the second
was a consequence of the first.
`createCopilotEndpoint` is a **deprecated alias**. This repo's own handler table
says so — `docs/backend/runtime-endpoints.mdx`:
| Deprecated | Use instead |
| `createCopilotEndpoint` | `createCopilotHonoHandler` |
| `createCopilotEndpointSingleRoute` | ... with mode: "single-route" |
`createCopilotRuntimeHandler` serves the same multi-route mode (it is the
default), returns a plain fetch handler, is not deprecated, and needs **no hono
at all**. So the route collapses to:
const handler = createCopilotRuntimeHandler({
runtime,
basePath: "/api/copilotkit",
});
export const GET = handler;
export const POST = handler;
`hono` was therefore an artifact of the shape, not a requirement of the library.
The install lines and the callout are reverted; nothing tells readers to install
it any more.
## Verified with hono deleted, not merely absent from package.json
`examples/shadcn` converted to this shape, `hono` removed from its
`package.json`, and `node_modules/hono` deleted outright so a hoisted copy could
not mask the result:
GET /api/copilotkit/info -> 200
POST /api/copilotkit/agent/default/run -> 200, chat turn rendered
tsc --noEmit / eslint / next build -> clean
next build route -> ƒ /api/copilotkit/[[...slug]]
The doctest sidecar drops `hono` too, so the CI gate now typechecks the
canonical snippet against `@copilotkit/runtime` alone — proof by construction
that the snippet needs nothing else.
pnpm tsx scripts/doc-tests/run.ts -> 2 passed, 0 failed
showcase/shell-docs: typecheck -> exit 0
showcase/shell-docs: build -> exit 0
structural audit: 31/31 mdx files, fence + JSX identical to HEAD
## Also corrected
`docs/backend/custom-agent.mdx` repeated the same incorrect transport claim the
earlier commit fixed in four other places ("Both `<CopilotKit>` and
`<CopilotKitProvider>` negotiate the transport when the prop is omitted").
Corrected to match released behaviour.
## Left alone deliberately
`snippets/shared/backend/custom-agent.mdx` and `docs/backend/custom-agent.mdx`
still call `createCopilotEndpoint` in three fences each, as
`export default copilotEndpoint` — the Hono-app deployment pattern rather than a
Next.js route handler. That predates this PR, the documented replacement is
`createCopilotHonoHandler`, and I have not run that shape. Recorded as follow-up
rather than guessed at. (The two files have also drifted from each other, which
is a separate problem.)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
c5d7b762bd |
docs: retitle v2 route fences that still claimed the plain path
Seven fences already imported from `@copilotkit/runtime/v2` but were still
titled `app/api/copilotkit/route.ts`. That is the same title/body mismatch this
sweep exists to fix, seen from the other side: a reader follows the title,
creates a plain route file for a runtime that needs the catch-all path, and gets
no `/info`.
Titles only — no bodies changed.
Two categories are deliberately left on the plain path, because there it is
correct:
- fences mentioning `createCopilotEndpointSingleRoute`. Single-route mode is
served from a plain `route.ts` and is POST-only by design; retitling one would
destroy what it demonstrates.
- fences still on the v1 entrypoint. Those are separate migrations, blocked for
the reasons recorded in the PR description.
Verified:
pnpm tsx scripts/doc-tests/run.ts -> 2 passed, 0 failed
showcase/shell-docs: pnpm build -> exit 0
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
62aca9e9aa |
docs: correct the transport-pairing guidance to match released behaviour
Finishes the tractable remainder of the v1 -> v2 runtime sweep, and fixes a
docs claim that the previous commit's `useSingleEndpoint={false}` edits exposed
as wrong.
## The pairing guidance described unreleased behaviour
`backend/runtime-endpoints.mdx` is the authoritative page for provider/handler
pairs, and it said omitting `useSingleEndpoint` is safe on either provider
because the client negotiates from `/info` — with `auth.mdx` and two quickstart
callouts repeating it. That is true on `main` and false in every published
release: the compat `<CopilotKit>` wrapper still ships
useSingleEndpoint={props.useSingleEndpoint ?? true}
(verified in the published `@copilotkit/react-core` 1.68.3 bundle), so omitting
the prop selects the single-route transport and 404s against a multi-route
Runtime. The Runtime's own error body says so. `<CopilotKitProvider>` does
negotiate; only the wrapper pins — and every docs snippet uses the wrapper.
So the pairing table now splits the two providers instead of grouping them,
states that the pin exists in released versions and is removed on `main`, and
says plainly that passing `{false}` is the forward-compatible choice. The
"pinning the wrong mode 404s silently" warning now covers omitting the prop on
`<CopilotKit>`, which is the same failure by a different route. Same correction
applied to `auth.mdx` and to the two "Which provider goes with which handler?"
callouts, which additionally still named `copilotRuntimeNextJSAppRouterEndpoint`
as the route above them after that route became `createCopilotEndpoint`.
## Remaining migrations
- `self-hosting-remote-endpoints.mdx` — three LangGraph fragments moved to
`@copilotkit/runtime/v2` for `CopilotRuntime` and
`@copilotkit/runtime/langgraph` for the agents, splitting what was a single
v1 root import.
- `copilot-runtime.mdx` — the transport callout rewritten to match the
authoritative page and link to it, rather than asserting the default itself.
## Verified
pnpm tsx scripts/doc-tests/run.ts -> 2 passed, 0 failed
showcase/shell-docs: pnpm typecheck -> exit 0
showcase/shell-docs: pnpm build -> exit 0
structural audit: 6/6 mdx files, fence + JSX structure identical to HEAD
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
e1830bbe91 |
docs: move the App Router runtime snippets onto the v2 endpoint
Migrates the Next.js App Router runtime fences across the docs from the v1
entrypoint to the v2 multi-route shape proved in `examples/shadcn`: catch-all
path, `createCopilotEndpoint`, a runner, and both verbs exported. 38 fences
across 33 pages.
Only the boilerplate is rewritten. Each page's agent wiring — `MastraAgent`,
`LangGraphAgent`, `HttpAgent`, `BuiltInAgent`, middleware `.use(...)` calls —
is left byte-identical, because that part is not what was broken.
Three co-changes travel with every migrated page, since the shape does not work
without them:
- `hono` added to the page's install command (20 lines). It is a dependency of
`@copilotkit/runtime`, not a peer, so `hono/vercel` resolves under npm's flat
layout but not under pnpm.
- `useSingleEndpoint={false}` on `<CopilotKit>` (27 provider tags). The
provider defaults to the single-route transport, which posts to the bare
`runtimeUrl`; a multi-route runtime answers with 404. Only tags carrying a
`runtimeUrl` are touched — a provider using `agents__unsafe_dev_only` has no
runtime to match. Angular's `provideCopilotKit` defaults its transport to
`"auto"` and needs no equivalent, so those snippets are unchanged.
- fence titles retitled to the catch-all path, plus the prose that introduces
them, so no snippet claims a path its body contradicts.
`LangGraphAgent` moves from the v1 root entrypoint to
`@copilotkit/runtime/langgraph` on one page. Both spellings resolve, but the
subpath is the one that survives the v1 entrypoint; verified by typechecking
`LangGraphAgent` + v2 `CopilotRuntime` + `createCopilotEndpoint` together
against the published 1.68.3.
## Two mistakes worth recording, since both were caught by a check rather than by reading
A block regex scoped to the fence's opening indentation corrupted five
quickstart pages: their fences open and close at *different* indentation, so
the match ran past the closing backticks and re-indented the following
`</Step>` / `</Tab>` boundary into the code block. The five pages were reverted
and redone with a line-oriented pass that never re-indents anything and
re-emits the original closing line verbatim.
Every modified page is now checked structurally — fence-marker count and the
full set of JSX structural lines, indentation included, must be identical to
`HEAD`. All 33 pass. That check is what found the corruption; a diff review had
already missed it on the first pass.
## Verified
pnpm tsx scripts/doc-tests/extract.ts -> 2 snippets
pnpm tsx scripts/doc-tests/run.ts -> 2 passed, 0 failed
showcase/shell-docs: pnpm typecheck -> exit 0
showcase/shell-docs: pnpm lint -> exit 0 (pre-existing warnings only)
showcase/shell-docs: pnpm build -> exit 0
structural audit: 33/33 pages, fence + JSX structure identical to HEAD
Note this validates that the pages still build and that the one doctested
snippet compiles. It does not execute the other 37 fences. Their correctness
rests on Stage 0: the boilerplate they now contain is the text that was run in
`examples/shadcn`, and their agent wiring is untouched.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
e7473a7a5a |
docs: teach the v2 runtime endpoint on the recommended runtime page
`snippets/copilot-runtime.mdx` calls itself "the recommended way to use
CopilotKit" and taught the v1 plain-POST route. A reader following it got an
endpoint that answers 405 on `GET /api/copilotkit` and does not route
`GET /api/copilotkit/info` at all, so nothing could discover the runtime.
The route fence is now the shape proved in `examples/shadcn`: catch-all path,
`createCopilotEndpoint`, a runner, and both verbs exported. The three other
fences on the page that were titled with the plain route path are retitled to
the catch-all path, so no snippet claims a path its body contradicts.
Also documents the two things the shape actually requires, both of which were
found by running it:
- `npm install @copilotkit/runtime hono` — `hono` is a dependency of the
runtime rather than a peer, so `hono/vercel` resolves under npm's flat
layout but not under pnpm.
- `useSingleEndpoint={false}` on `<CopilotKit>`. The provider defaults it to
`true` (single-route transport), which posts to the bare `runtimeUrl`; a
multi-route runtime answers that with 404. The Angular provider defaults its
transport to `"auto"` and needs no equivalent change, so that snippet is
unchanged.
## The snippet is now gated in CI
`scripts/doc-tests` already extracts fences tagged `doctest=` and, for
`component`, runs `tsc --noEmit` against real npm-installed dependencies — but
it could not handle a fence whose title is a path, which is exactly what a
Next.js route handler's title is. Two defects blocked it, both fixed here:
- `extract.ts` wrote the title as a path without creating intermediate
directories, so a titled route fence died on ENOENT.
- `run.ts` derived the npm package name from the snippet directory, and a
catch-all leaf directory is literally `[[...slug]]`, which npm rejects as an
invalid name. It also looked for `doctest.json` only in the snippet's own
directory, while the sidecar is copied once per page — so a nested snippet
silently installed no dependencies and failed with "Cannot find module".
With those fixed, the canonical route snippet is tagged `doctest="component"`
and typechecked in CI against the published `@copilotkit/runtime` 1.68.3 and
`hono`. This is the gate the docs did not have: snippet correctness no longer
rests on review alone.
Verified:
pnpm tsx scripts/doc-tests/extract.ts -> 2 snippets extracted
pnpm tsx scripts/doc-tests/run.ts -> 2 passed, 0 failed
mutation check: restoring the v1 import in the fence turns the run red
(1 passed, 1 failed), so the gate fails on the regression it exists to catch
vitest scripts/doc-tests/__tests__/extract.test.ts -> 10 passed
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
0be2aac315 |
fix(examples): move shadcn onto the v2 multi-route runtime endpoint
`examples/shadcn` paired a v1, POST-only runtime route with a
`@copilotkit/react-core/v2` frontend. `GET /api/copilotkit` answered 405 and
`GET /api/copilotkit/info` did not route at all (404), so nothing could probe
the runtime.
Convert the route to the v2 multi-route shape at a catch-all path, exporting
both verbs:
app/api/copilotkit/[[...slug]]/route.ts
createCopilotEndpoint({ runtime, basePath: "/api/copilotkit" })
export const GET = handle(app)
export const POST = handle(app)
Two co-changes this shape requires, both found by running the app rather than
by reading it:
- `hono` becomes a direct dependency. It is a dependency of
`@copilotkit/runtime`, not a peer, so under pnpm's strict layout
`import { handle } from "hono/vercel"` does not resolve from the app
without declaring it.
- the provider must pass `useSingleEndpoint={false}`. The published
`<CopilotKit>` from `@copilotkit/react-core/v2` defaults to the
single-route transport, which posts a single-route envelope to the bare
basePath; a multi-route runtime answers that with 404. The runtime says so
itself in the error body.
`@copilotkit/*` moves 1.61.2 -> 1.68.3 so the app runs the versions a reader
installing today would get.
Verified live (aimock on :4010 as the model backend):
GET /api/copilotkit/info -> 200, runtime /info payload
POST /api/copilotkit/agent/default/run -> 200, chat turn renders
before: GET /api/copilotkit -> 405, GET /api/copilotkit/info -> 404
tsc --noEmit, eslint, next build all clean
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
1b3bf74dc8 |
refactor(showcase): retire the v1 runtime adapter across every integration (#6618)
Retires the v1 runtime adapter from `showcase/integrations/`. After
this, **no code under `showcase/integrations/` calls
`copilotRuntimeNextJSAppRouterEndpoint`** — 239 routes across 20
integrations.
This is the cheap path we discussed: single-route mode, which is a
genuine drop-in. **No demo page changes, no route path changes, no `GET`
exports, no new dependencies.**
## The shape
```ts
const copilotHandler = createCopilotRuntimeHandler({
runtime,
basePath: "/api/copilotkit-x",
mode: "single-route",
});
...
return await copilotHandler(req);
```
**Why single-route:** these demos' frontends are `<CopilotKit
runtimeUrl="/api/copilotkit-x">` with no transport prop, and every
released provider pins the single-route transport. So single-route mode
is what the v1 adapter was already serving. Migrating to multi-route
instead would have meant editing every demo page in lockstep, for no
functional gain — nothing in the showcase probes `/info`.
**Why `createCopilotRuntimeHandler`** rather than
`createCopilotEndpointSingleRoute`: that helper is itself deprecated in
favour of the `mode` option (per the deprecated-aliases table in
`docs/backend/runtime-endpoints.mdx`), and 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 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's optional and none of these routes passed one.
13 `copilotkit-auth/[[...slug]]` routes already use the v2 fetch handler
and are left alone; they only name v1 in comments.
## Verified
The shape 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 in the browser.
It also typechecks against the exact version these integrations pin
(1.68.2).
`mastra` is the 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**:
| | baseline (`origin/main`) | after |
| --- | --- | --- |
| `tsc --noEmit` | errors in 10 files | errors in **9** |
| `vitest run` | 2 files / 13 tests failed, 21 passed | 2 files / 13
tests failed, 21 passed |
- **New type errors introduced: none.**
- **Fixed:** `src/app/api/copilotkit-mcp-apps/route.ts`, whose
`@ts-expect-error` was *already* unused on `main`.
- **Test-neutral:** those 13 failures are pre-existing on `main` (mostly
`extractXHeaders` dereferencing `req.headers` on a `{}` fake request).
Structural audit over all 239 routes, re-run after the pre-commit
formatter: none still imports the v1 root, calls the v1 adapter,
references `ExperimentalEmptyAdapter` or `handleRequest` in code, or is
missing `createCopilotRuntimeHandler` / `basePath` / `mode:
"single-route"`.
**CI has now built all 21 integrations green** — `showcase_build_check`
Docker-builds each changed integration and `next build` typechecks
inside it. That covers the ones I could not stand up locally, including
the non-JS backends (`spring-ai`, `ms-agent-dotnet`, `ms-agent-python`,
`ms-agent-harness-dotnet`, `langroid`, `strands`). Full run: 41 pass / 3
skip / 0 fail.
To be precise about what each gate proves: CI proves these 21 apps still
**build and typecheck**. It does not exercise a chat turn per
integration — that came from the pre-rollout live proof of the shape
itself, plus mastra's local test suite.
## Runtime verification on real cells
Docker is not running on my machine, and `bin/showcase test --d6
--direct` requires it
(`--direct` only swaps the in-process driver for the fleet
control-plane; the containers are
not optional). **So the sanctioned Iron Rule 4 probe has NOT been run**
— that gap is real and
a reviewer should weigh it. What I did instead was run a real
integration directly.
`showcase/integrations/mastra` on this branch, `npm run dev`, aimock as
the model backend.
Probing eight migrated routes with the exact envelope the released
provider sends
(`POST {basePath}` with `{"method":"info"}`) — all **200** with real
runtime payloads:
copilotkit-multimodal 200 agents: multimodal-demo
copilotkit-mcp-apps 200 agents: headless-complete
copilotkit-a2ui-fixed-schema 200 agents: a2ui-fixed-schema
copilotkit-beautiful-chat 200 agents: beautiful-chat
copilotkit-agent-config 200 agents: agent-config-demo
copilotkit-ogui 200 agents: open-gen-ui
copilotkit-declarative-gen-ui 200 agents: declarative-gen-ui
copilotkit-background-agents 200 agents: background-agents
Then three real demo cells driven in a browser, each rendering and
completing a chat turn
through its migrated route (two POSTs, both 200, assistant message
rendered):
/demos/beautiful-chat -> POST /api/copilotkit-beautiful-chat 200, 200
/demos/a2ui-fixed-schema -> POST /api/copilotkit-a2ui-fixed-schema 200,
200
/demos/multimodal -> POST /api/copilotkit-multimodal 200, 200
Deliberately spread across different route configs — plain, `a2ui`, and
a dedicated
vision-model route — rather than three variations of the same one.
### One route is 500, and it is pre-existing
`POST /api/copilotkit` (mastra's main route) returns 500 in dev:
`module-not-found` on
`./schema.js` from `src/cvdiag/cvdiag-emitter.ts`. `schema.ts` **is**
tracked and present —
Turbopack in dev just does not resolve the ESM-style `.js` specifier to
it. Proven
pre-existing by restoring **only** that file to `origin/main` and
re-probing: same 500 on the
v1 code. Its Docker build passes, which is why CI is green.
### A mistake in my own verification, recorded
My first pass at the above ran against the wrong branch — I was still on
the docs branch,
where these routes are v1, so the first six 200s I collected were the
**v1** routes. Caught it,
switched to this branch, and re-ran everything above against the
migrated code. The accidental
run was not wasted: it independently confirms the premise of this PR,
that the v1 adapter and
v2 single-route mode answer the same envelope the same way.
## Judgement call worth reviewing
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 compile error.
I demoted them to `@ts-ignore`, which compiles whether or not the
mismatch survives in a given integration. The honest reason at the time:
19 of these apps can't be built locally, so I couldn't prove per-file
which still need a suppression, and `@ts-ignore` is what 190 sibling
files already use.
Now that CI has built all 21 green, that constraint is gone — the ~220
now-stale suppressions (all of which cite a **v1** type hole that no
longer applies) can be removed and verified by the same 21 builds. I've
left them in place here to keep this PR mechanical and reviewable; say
the word and I'll do it as a second pass.
## 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`. The Dockerfile uses `npm ci
--legacy-peer-deps`, which *does* succeed, so the image still builds —
but a plain `npm ci` doesn't. No manifest or lockfile is in this diff.
- **`mastra`'s vitest suite is red on `main`** — 13 failures, as tabled
above.
## What's left of the v1 entrypoint
| Surface | Before | After |
| --- | --- | --- |
| `showcase/integrations/**` | 239 | **0** |
| `examples/v1/**` | 12 | 12 (deliberately v1, never in scope) |
| everything else in `examples/` | ~61 | ~61 (not in this PR) |
Stacks cleanly with #6617 (docs) — no file overlap. It also **unblocks
the two Claude SDK quickstart pages** I had to revert there:
single-route keeps the starter file at the plain `route.ts` path, so
those pages' prose claims and `verify-shell-docs.ts` starter-path checks
stay valid, and only the fence body needs updating.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
||
|
|
8951232a0f |
fix(runtime): stop emitting a require() statement in published .d.cts
A consumer who imports @copilotkit/runtime and compiles with strict +
skipLibCheck: false gets 81 errors from our published declarations, 71 of
them TS1036 "Statements are not allowed in ambient contexts". Cause: the
tsdown banner that guarantees reflect-metadata loads before type-graphql
was returned as a string, and tsdown applies a string banner to every
emitted chunk -- declarations included. So all 87 published .d.cts files
began with `require("reflect-metadata");`, which is a statement and
illegal in an ambient context.
Returning an object instead lets tsdown route the banner by chunk kind, so
JS keeps its reflect-metadata prologue and declarations get nothing. The
fileName condition is gone too: tsdown's resolveChunkAddon reassigns its
own closure variable on the first call, so a function banner is evaluated
once and reused, meaning that condition was really deciding the banner for
the entire build from whichever chunk was emitted first. Keying on format
alone is order-independent.
This was invisible to us because every scaffolder sets skipLibCheck: true,
and because .d.mts got the legal `import "reflect-metadata";` form -- ESM
consumers never saw a single TS1036.
Adds a check-dts target that parses the built declarations and fails on any
top-level statement, wired into the existing package-quality job so the
class cannot come back silently.
Refs OSS-899
|
||
|
|
053b136634 | fix(angular): retain lucide for demo inspector | ||
|
|
27685a30fb | chore(angular): remove obsolete safe navigation wrappers | ||
|
|
2247f548b3 | chore(angular): compile library at Angular 22 floor | ||
|
|
f0275a4431 | chore(angular): migrate demo icons to @lucide/angular | ||
|
|
d248f0a7f9 | chore(angular): remove empty component imports | ||
|
|
8b8097508e | style: auto-fix formatting | ||
|
|
18d008c423 | Align Angular 22 support policy and docs | ||
|
|
79c235035a | Apply Angular 22 framework migrations | ||
|
|
fea1a13b58 | Upgrade Angular toolchains to version 22 | ||
|
|
ddae645054 |
chore(showcase): mark CrewAI conversational flows live (#6638)
## Summary - mark CrewAI Conversational Flows `deployed: true` now that its production Railway instance is provisioned, SSOT-tracked, promoted, and healthy - update the parity note so it reflects the live production deployment - retain `docs_mode: hidden`; Conversational Flows remain documented within the existing CrewAI Flows docs rather than as a separate framework ## Production verification - `GET https://showcase-crewai-conversational-flows-production.up.railway.app/api/health` returns HTTP 200 with `status: ok` - post-promotion D5 run `frun_mt2lnj48_t8zh0h_1`, job `o8rkn6b0igh4rxd`: 40/40 cells passed, 0 failed ## Local verification - `nx run @copilotkit/showcase-scripts:validate-manifests` - `nx run @copilotkit/showcase-scripts:generate-registry` - `validate-constraints.ts crewai-conversational-flows` - formatter check and `git diff --check` - Nx affected lint, test, and build resolved no affected targets for this manifest/Markdown-only change |
||
|
|
e6fd1ed38f |
fix(web-inspector): stop Agent tab messages from showing template indent (#6640)
## What does this PR do? The Agent tab Current Messages list used `whitespace-pre-wrap` around the message text. The Lit template also had extra spaces and newlines around that value. As a result, a short message such as `test` rendered with a large empty block. This change puts the message text on the same line as the opening tag, so only the real message text is shown. Verified in the browser: the user row is now the exact string `test` (one line, 16px high). Inspector tests: 485 passed, including a new regression test. ## Related PRs and Issues None. Found while testing Playground on the react-router example. ## Checklist - [x] I have read the [Contribution Guide](https://github.com/copilotkit/copilotkit/blob/master/CONTRIBUTING.md) - [x] If the PR changes or adds functionality, I have updated the relevant documentation - [x] "Allow edits by maintainers" is checked |
||
|
|
3a04788243 |
feat(web-inspector): add agent playground (#6580)
## Summary - add an isolated Playground tab for chatting with the selected agent - fork saved thread history into a fresh Inspector-owned conversation - show the ephemeral-thread Intelligence CTA only for non-Intelligence runtimes ## Why OSS-869 needs a small, local-first surface for testing agents without changing the host application chat or its stored thread history. ## How - clone the active runtime agent and stream runs through the existing Core - reuse Inspector thread endpoints to seed scratch conversations - mirror the default CopilotKit chat treatment, including run/stop states and motion - cover navigation, input, saved-thread isolation, and Intelligence CTA behavior Verified with `pnpm nx run @copilotkit/web-inspector:test`, `build`, and `check-types`, plus a live React v2 demo run. |
||
|
|
041adfff94 | fix(web-inspector): stop Agent tab messages from showing template indent |