176 Commits

Author SHA1 Message Date
MikeRyanDev 71977ddfce chore: release monorepo v1.69.0 2026-08-21 18:09:45 +00:00
Benjamin Taylor 6e0f5773f0 Merge remote-tracking branch 'origin/main' into ben1/v2-runtime-migration
# Conflicts:
#	showcase/shell-docs/src/content/snippets/shared/generative-ui/a2ui.mdx
2026-08-21 12:49:37 -05:00
Mike Ryan 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.
2026-08-21 10:44:36 -07:00
Tyler Slaton 7bff49739e fix(runtime): replace retired Anthropic model IDs (#6616) 2026-08-21 09:06:33 -07:00
Benjamin Taylor 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>
2026-08-21 09:25:19 -05:00
Benjamin Taylor 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>
2026-08-21 08:32:29 -05:00
Benjamin Taylor 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
2026-08-21 08:24:46 -05:00
Rainer Hahnekamp 2247f548b3 chore(angular): compile library at Angular 22 floor 2026-08-21 15:19:21 +02:00
Rainer Hahnekamp 18d008c423 Align Angular 22 support policy and docs 2026-08-21 15:18:02 +02:00
Tyler Slaton 7180a14dcb Merge main into Inspector docs quickstart callouts 2026-08-20 18:15:00 -07:00
Tyler Slaton 0ae1e188a8 ci: reject retired Anthropic model references 2026-08-20 16:40:52 -07:00
Tyler Slaton 5d19399fdd fix(release): default AI release notes to Opus 4.8 2026-08-20 16:40:26 -07:00
Tyler Slaton 518feae6cd docs: update Anthropic model references to Opus 4.8 2026-08-20 16:40:09 -07:00
Mike Ryan b8b19834a2 fix(runtime): unify the Intelligence key name and publish the wiring (refs OSS-881) (#6595)
## What does this PR do?

Closes the naming and documentation half of
[OSS-881](https://linear.app/copilotkit/issue/OSS-881). Paired with
CopilotKit/Intelligence#890, which adds `copilotkit verify` and tightens
the evaluation rubric.

### 1. One name for the Intelligence key

**Three** names for one value were live in CopilotKit's own
documentation, and following the wrong one with a CLI-provisioned
project yields an undefined key:

| Name | Where | Code readers |
| --- | --- | --- |
| `INTELLIGENCE_API_KEY` | what `copilotkit project select` writes; all
34 integration examples; the docs site | 34 |
| `COPILOTKIT_INTELLIGENCE_API_KEY` | 7 Channels package READMEs +
packaged skills | **0** |
| `COPILOTKIT_API_KEY` | `examples/slack`, `examples/teams`, and the
TSDoc on `CopilotKitIntelligence` itself | 2 |

`INTELLIGENCE_API_KEY` wins — it is the name the CLI provisions, and
changing it would break every scaffolded project in the wild.

- `COPILOTKIT_INTELLIGENCE_API_KEY` is **retired outright**. Nothing
ever read it, so there is nothing to keep compatible.
- `COPILOTKIT_API_KEY` stays **readable as a deprecated alias** in the
two examples that consume it, so an existing `.env` keeps working, and
is documented as deprecated everywhere it appears.

The third name was the worst placed: it was in the TSDoc on
`CopilotKitIntelligence`, which is what an IDE shows on hover.

This was not only untidy. The CLI's own `channels-preflight` accepts
`INTELLIGENCE_API_KEY` or `COPILOTKIT_API_KEY` — **not**
`COPILOTKIT_INTELLIGENCE_API_KEY`, the name the Channels READMEs told
people to set. So following a Channels README verbatim made `copilotkit
channels` warn that no runtime API key was present while the key sat
visibly in `.env`. After this PR the documented name is one preflight
accepts.

> [!NOTE]
> `NEXT_PUBLIC_COPILOTKIT_API_KEY` is a **different value** — the legacy
Copilot Cloud public key — and is deliberately left alone.

### 2. A real defect, not just naming skew

`skills/runtime/references/intelligence-mode.md` documented
`organizationId` as a `CopilotKitIntelligence` option, sourced from two
further env names (`COPILOTKIT_INTELLIGENCE_ORG_ID`,
`COPILOTKIT_ORG_ID`).

`CopilotKitIntelligenceConfig` has no such field — the copy-pasteable
sample it appeared in **would not compile**. Removed from the samples,
and the prose telling readers to fetch a value for it corrected. That
file is the only place those two names ever existed, which is very
likely why the failing validation run reported that "the runtime reads
`COPILOTKIT_INTELLIGENCE_API_KEY` and `COPILOTKIT_INTELLIGENCE_ORG_ID`".

### 3. Publish the Intelligence wiring

The wiring instructions existed only inside
`node_modules/@copilotkit/runtime/skills/`, and the only docs pages
mentioning `CopilotKitIntelligence` at all were the two Channels
frontends — so a developer on the plain web path had no page to reach it
from.

Adds **`/premium/connect-your-runtime`**: the wiring itself, how to
confirm the credential is actually consumed, the self-hosted
both-URLs-or-neither rule, and a troubleshooting table. Linked into both
navs, and the skills reference now points at the published page.

### 4. A guard so it cannot drift back

`scripts/validate-intelligence-env-names.ts` (`pnpm
check:intelligence-env-names`), wired to lefthook and a new workflow.

The workflow is **intentionally unfiltered**. The two workflows that
would otherwise cover this both filter: `plugin-skills-check` by
`paths:`, and `static/quality` by `paths-ignore: examples/**` — which is
exactly where the deprecated alias lives. Scoping the job would re-open
the hole it exists to close. Legitimate alias sites live in
`ALIAS_ALLOWLIST`.

## Related PRs and Issues

- [OSS-881](https://linear.app/copilotkit/issue/OSS-881) — needs
**both** PRs; neither closes it alone
- CopilotKit/Intelligence#890 — items 1 and 4 (`copilotkit verify` +
rubric contract 1.3.0)

## Verification

- Full lefthook pre-commit ran green: `check-plugin-skills`, `lint-fix`,
the new `check-intelligence-env-names`, and `test`/`publint`/`attw`
across **25 projects**.
- `examples/slack` `managed.test.ts` extended to cover **both** the
canonical name and the alias fallback, and proven non-vacuous — removing
the fallback turns the new test red.
- The drift guard proven non-vacuous the same way: reintroducing a
retired name fails it, exit 1.
- `oxfmt` and `oxlint` clean on every file touched (0 errors).

## 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

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-08-20 12:00:52 -07:00
BenTaylorDev aa3fb29dce chore: release monorepo v1.68.3 2026-08-20 10:27:07 -07:00
Alem Tuzlak a9714d1c02 docs: call Inspector out in quickstarts and feature pages
After the first chat, web quickstarts now tell the reader to open Inspector and confirm Agents, AG-UI Events, and Threads. Feature pages that map to a shipped pane get a short Callout. Angular links the Inspector install page first. Vue sets show-dev-console=auto so the overlay appears on localhost. The inspector-docs skill keeps pane-to-docs pointers in sync when Inspector panes change.
2026-08-20 13:50:15 +02:00
contextablemark b0233c4eb0 chore: release monorepo v1.68.2 2026-08-20 02:19:06 +00:00
Benjamin Taylor 6f58b2c6a4 fix(runtime): unify the Intelligence key name and publish the wiring (refs OSS-881)
Three names for one value were live in CopilotKit's own documentation, and
following the wrong one with a CLI-provisioned project yields an undefined
key:

- `INTELLIGENCE_API_KEY` — what `copilotkit project select` writes, used by
  all 34 integration examples and the docs site.
- `COPILOTKIT_INTELLIGENCE_API_KEY` — the seven Channels package READMEs and
  the packaged skills. Nothing ever read it.
- `COPILOTKIT_API_KEY` — the Slack and Teams examples, and the TSDoc on
  `CopilotKitIntelligence` itself, which is what an IDE shows on hover.

`INTELLIGENCE_API_KEY` wins, because it is the name the CLI provisions and
changing it would break every scaffolded project in the wild.
`COPILOTKIT_INTELLIGENCE_API_KEY` is retired outright — no code read it.
`COPILOTKIT_API_KEY` stays readable as a deprecated alias in the two
examples that consume it, so an existing `.env` keeps working, and is
documented as deprecated everywhere it appears.

The skills reference also documented `organizationId`, sourced from a fourth
and fifth env name, as a `CopilotKitIntelligence` option. It is not one:
`CopilotKitIntelligenceConfig` has no such field, so the copy-pasteable
sample it appeared in would not compile. Removed from the samples, and the
prose that told readers to fetch a value for it corrected.

The Intelligence wiring itself was published only inside
`node_modules/@copilotkit/runtime/skills/`, and the only docs pages showing
`CopilotKitIntelligence` were the two Channels frontends — so a developer on
the plain web path had no page to reach it from. Adds
`/premium/connect-your-runtime`, which covers the wiring, how to confirm the
credential is actually consumed, and the self-hosted two-URL rule.

`scripts/validate-intelligence-env-names.ts` keeps this from drifting back.
It runs unfiltered in CI on purpose: the two workflows that would otherwise
cover it filter paths, and static/quality ignores `examples/**` — exactly
where the deprecated alias lives.
2026-08-19 17:50:09 -05:00
tylerslaton 1f9b60b231 chore: release monorepo v1.68.1 2026-08-14 21:05:45 +00:00
tylerslaton f8cb4d2447 chore: release channels v0.9.0 2026-08-14 20:42:01 +00:00
tylerslaton e6864b6bdd chore: release monorepo v1.68.0 2026-08-14 20:11:31 +00:00
Tyler Slaton dedd07591d fix(release): sync package skill versions during releases 2026-08-14 12:57:55 -07:00
Sam Julien e9759825b6 test(skills): simplify public contract guard 2026-08-12 10:36:26 -07:00
Sam Julien 7bba4446ff test(skills): narrow public API contract checks 2026-08-12 10:31:51 -07:00
Sam Julien 4f258e409a test(skills): add manifest-backed public evals 2026-08-12 10:31:51 -07:00
Murat Sari 8c670653ce fix: align Angular 20 support and resolve packed smoke paths (#6452)
## What broke

The regression was introduced by commit fec70d086 (feat(angular):
checkpoint 2 - core and package), merged through PR #6109 as b07482da5.

That commit established Angular 20 as the package’s compiler and support
floor, but the demo remained on Angular 21 after 8b13fbcb7 (build:
update ng).
It also introduced the packed smoke runner without canonicalizing macOS
temporary paths, allowing /var/... and /private/var/... to resolve
  inconsistently.

  ## Why I made this change

I moved the demo back to Angular 20 so it exercises the lowest supported
Angular version, aligned the Angular 20 dependencies and support
contract on
20.3.27, and canonicalized the packed consumer directory before starting
the SSR server.

This keeps the demo, package metadata, tests, and lockfile consistent
while making the packed smoke test reliable across symlinked temporary
  directories.

  ## Changes

  - Align the Angular demo with the Angular 20 support floor.
  - Update Angular 20 dependencies and support-policy tests to 20.3.27.
- Resolve the packed consumer directory to its real path before
launching SSR.
2026-08-12 11:28:22 +02:00
Murat Sari cbf79ef52a fix: align Angular 20 support and resolve packed smoke paths 2026-08-11 21:49:36 +02:00
Sam Julien 6540848745 chore: refresh agent artifacts for 1.67.1 2026-08-10 20:35:22 -07:00
Sam Julien 1853a24d00 fix(skills): align public guidance with current APIs 2026-08-10 20:32:31 -07:00
Sam Julien 73d1df29a2 feat(release): add a generated public API manifest 2026-08-10 20:32:30 -07:00
Benjamin Taylor 6e702c906b feat(telemetry): emit telemetry-registry fragments for runtime + docs surfaces
Adds scripts/telemetry/ (emit-fragment.ts + extract.ts) and two CI workflows
that generate CopilotKit's telemetry-registry fragments and open path-limited
PRs into CopilotKit/oss-path-to-production:

- runtime (bespoke catalog): reads the AnalyticsEvents type map for event names
  + properties, scans capture() sites for call_sites, fails loud if the v1/v2
  catalogs diverge. Triggered on stable monorepo release.
- docs (callee mode): extracts inline posthog.capture literals from
  showcase/shell-docs (drops $-reserved events). Triggered on push to main
  touching showcase/shell-docs/**.

Both are content-gated: the fragment is left untouched (and no PR opened) when
the event set is unchanged, so releases/edits don't churn the registry. Cross-
repo token follows the least-privilege recipe (no owner, bare repositories,
contents+PR write); mint gated on a job-level env var. zizmor clean (one
justified cache-poisoning suppression). 13 unit tests; tsc + oxlint clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-05 13:24:13 -05:00
Benjamin Taylor 4c2ba2d161 feat(skills): add channels-setup pointing at the hosted onboarding guide
The Channels onboarding workflow is served at
https://copilotkit.ai/channels-guide.md, and every other entry point now
copies one line that points there (#6357 for the docs surfaces). Coding
agents invoked through a skill had no such pointer, so they fell back to
setup-slack-channel, which is scoped to Slack, to the provider half, and to
an OpenTag checkout.

channels-setup is a pointer, not a copy. The workflow stays in one place and
is corrected there instead of drifting against the CLI on its own schedule.

Verifying the fetch is the substance of the file. The site answers unknown
paths with a "Page not found" HTML page under HTTP 200, so a status check
proves nothing: an agent that keys on the status code gets a marketing 404
and improvises the workflow from memory. The skill checks the body instead
-- markdown, the guide's H1, five Phase headings -- and stops if any fail.

Standalone skills are not generated from packages/*/skills, so the slug is
registered in RESERVED_LIFECYCLE_SLUGS. Without that entry the sync treats
the directory as an orphan and deletes it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 10:30:02 -05:00
GeneralJerel d51fe15c71 Merge branch 'main' into feat/channel-setup-skills
Resolves the one conflict in skills/copilotkit-channels/SKILL.md, where main
(#6320) rewrote the same frontmatter description this branch narrowed.

The two sides disagreed on Teams. This branch scoped the skill to the code half
and said it "assumes the provider app already exists"; main established that
Teams provider setup *is* this skill's job, because the CLI or dashboard wizard
performs it. Kept the branch's code-half framing and the handoff to
setup-slack-channel, but scoped that handoff to first-time Slack app creation
only, so it no longer contradicts main's Teams sections or the Slack provider
troubleshooting that stays in this file. Took main's version 1.1.0.

Also registers setup-slack-channel in RESERVED_LIFECYCLE_SLUGS. Standalone
skills have no packages/*/skills source, so without an entry the sync script
treats the directory as an orphan: `pnpm check:plugin-skills` fails, and
`pnpm sync:plugin-skills` deletes all 8 files of the new skill. Verified both
behaviours against the pre-fix script before fixing. The paired size assertion
in the unit test moves 9 -> 10.
2026-08-03 11:17:09 -07:00
Mike Ryan b88f9b7e4f feat(channels): complete native JSX contracts 2026-08-03 09:23:15 -07:00
Benjamin Taylor 065d525340 feat(skills): make managed Intelligence the default setup path, add a Channels skill
The most-used "add CopilotKit to your project" path walked every new user into the
self-hosted SSE runtime and never offered the managed one.
`CopilotIntelligenceRuntime`, `CopilotKitIntelligence`, the required
`identifyUser`, and the hosted environment values all appeared in this skill's
reference files but were wired by no step, so the skill could describe managed
Intelligence without ever producing it.

Step 2 now chooses the runtime mode before any runtime code is written, because
the mode changes how the runtime is constructed and retrofitting it means
rewriting the file. Managed Intelligence is the recommended default and now has
real wiring. Self-hosted SSE stays fully documented as a deliberate opt-out with
its prerequisites and its tradeoff stated plainly at the point of choice -- the
open-source packages are published and MIT-licensed, so obscuring the alternative
would not prevent its use and would cost credibility on everything around it.

Step 6 becomes the actual Intelligence step rather than a telemetry aside. It
separates the two credentials that setup mistakes usually conflate: the
server-side project API key, which is a secret and must never take a
NEXT_PUBLIC_/VITE_ prefix, and the public license key, which is a project
identifier meant to reach the client.

It also fixes a command that does not exist. Both this skill and
references/telemetry-setup.md instructed `npx copilotkit auth`; the command is
`login`, and `project select` is what provisions the project.

The new copilotkit-channels skill covers the code half of a managed Channel: the
declaration, the long-running host requirement, and the awaited
`listener.channels.ready()` call. Activation is lazy on every host, so a runtime
that omits that call serves HTTP, reports no error, shows an encouraging badge in
the dashboard, and answers nothing -- the failure the skill exists to prevent. It
states the managed-versus-self-hosted boundary up front, since both product
families use the words "channels" and "Slack".

A standalone skill must be registered in RESERVED_LIFECYCLE_SLUGS. Without an
entry the sync script treats it as an orphan and deletes it, so the test now pins
that requirement with the reason.
2026-08-01 14:47:36 -05:00
Tyler Slaton 289a39d00c fix(release): simplify canary dependency pins 2026-07-29 22:13:45 -04:00
Tyler Slaton ac42ca5f4c fix(release): exact-pin canary dependency sets 2026-07-29 22:05:17 -04:00
Mike Ryan 702874096e feat(channels): route delivery through live sessions (#6236)
## What changes

This replaces the managed Channels adapter and transport stack with live
sessions over Realtime Gateway.

- Channels use the standard AgentRunner and canonical AG-UI history for
each turn.
- One admitted delivery runs one prompt; multiple agent calls run in
order; concurrent calls fail with a bounded protocol error.
- Slack and Teams reuse their native renderers to emit destination-free
provider effects.
- Files, rich controls, interaction handlers, and provider cursors cross
the live-session protocol with bounded payloads.
- The old claim mapping, HTTP fallback, render batches, listener
election, in-memory transport, and legacy adapter code are removed.
- The public `@copilotkit/channels` umbrella remains limited to public
provider adapters; the managed launcher stays in
`@copilotkit/channels-intelligence`.

Companion service PR and kind proof:
https://github.com/CopilotKit/Intelligence/pull/638

## Why

Managed delivery must use the same AgentRunner path as other
Intelligence runs. SDK code emits provider-neutral effects; the trusted
Gateway owns credentials, destinations, admission, retries, and terminal
outcomes.

## Validation

- `pnpm nx run-many -t build,check-types,test -p
@copilotkit/channels-core,@copilotkit/channels-intelligence,@copilotkit/channels-slack,@copilotkit/channels-teams,@copilotkit/channels,@copilotkit/runtime`
— 31 tasks passed
- `pnpm nx test @copilotkit/channels-teams` — 89 passed
- `pnpm vitest run scripts/release/lib/channels-umbrella.test.ts` — 8
passed
- `pnpm verify:channels-umbrella` — packed snapshot, dependency
resolution, and TSX consumer passed
- affected package pre-commit tests, publint, and API type checks passed
- changed-file Prettier and `git diff --check` passed

## Known unrelated check

`pnpm nx build demo` now compiles past the prior Channels telemetry
dependency leak, then fails on the existing AG-UI 0.0.51 versus 0.0.57
private `_debug` type mismatch.
2026-07-29 18:28:49 -07:00
Benjamin Taylor 2a1a141389 perf(release): publish canary packages with bounded concurrency
After the npx fix each publish is ~4.7s and almost entirely a registry
round-trip, so a 26-package scope=all canary still spent ~125s waiting
serially. Publish 4 at a time (CANARY_PUBLISH_CONCURRENCY=1 restores
serial for debugging).

This weakens no ordering invariant. prerelease.ts's own header already
documents that the cross-scope graph has cycles (runtime ->
channels-intelligence, channels-core -> core), so no serial order avoided
publishing a package before the same-run version it pins.

Per-package output is captured and replayed as one block rather than
inherited, since a pool would otherwise interleave several npm publishes
line-by-line — and that log is the only forensic record when a canary
half-publishes. Every package is attempted even if others fail, so one
report names all of them; main() now exits non-zero on failure rather
than letting an unhandled rejection pass the step.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 19:53:05 -05:00
Benjamin Taylor 6a35e3cdbf perf(release): cut canary publish wall-clock roughly in half
The canary flow took ~11.5 min steady-state (and 20 min in an observed
run). Measured from run 30473499191, the time went to five avoidable
places rather than to real work.

1. `npx --yes npm@11.15.0 publish` ran per package, and npx re-resolves
   the spec against the registry on EVERY invocation: ~16s of each
   package's ~21s. A 9-package channels canary paid ~2.4 min of pure npx
   overhead; a 16-package monorepo release paid over 4 min. Hoist the
   pinned npm into lib/npm-cli.ts, install it once into a throwaway
   prefix, and reuse the binary.

2. publish-release.yml was the only workflow in the repo with no pnpm
   store cache, so all three jobs installed 4608 packages cold every
   time. Usually ~45s each, but registry-bandwidth bound and heavy
   tailed: the observed run spent 9m08s here on tarballs arriving at
   2-49 KiB/s. Add the same node-version-keyed cache the rest of CI uses.

3. The notify job ran for canaries only to compute "post nothing" — the
   builder already returns should_post=false for mode=prerelease and the
   self-watchdog is already gated off. ~85s of dead work on the critical
   path, since canary.yml waits for the whole run. Skip the job, keeping
   it reachable for a python_publish dispatch.

4. The build job fetched full history for canaries, which need none (no
   tag, no GH Release, no release-note commit range, and `nx run-many`
   resolves no merge base). That rode along in the 837 MiB workspace
   artifact too. Shallow-fetch prereleases; stable keeps depth 0 because
   its publish job pushes tags out of that artifact's .git.

5. Two smaller ones: the artifact was gzipped and then re-deflated into
   the artifact zip (compression-level: 0), and the orchestrator's
   run-discovery loop slept 6s before its first poll.

Verified: 143 release-script tests pass (6 new for the npm-cli helper),
actionlint + shellcheck + the scope-dropdown guard are clean, the
prerelease dry-run path still enumerates all 9 channels packages, and a
live probe confirms the helper installs npm 11.15.0 once (3.2s) and
memoizes thereafter (0ms).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 19:29:38 -05:00
Mike Ryan 6a222953a9 fix(channels): align umbrella with managed launcher 2026-07-29 16:42:02 -07:00
github-actions[bot] 5588636bd8 style: auto-fix formatting 2026-07-28 22:04:13 +00:00
copilotkit-qa-bot a0cfc60c1b Address FAC-49 review feedback 2026-07-28 14:40:24 -07:00
Benjamin Taylor 4a9837e176 fix(release): pack runtime workspace deps locally in verify-runtime-package
`verify:runtime-package` could not pass on a channels release PR. `pnpm pack`
rewrites the runtime's `workspace:` ranges to the workspace's current version,
so on a release PR the temp consumer tried to resolve the freshly-bumped
`@copilotkit/channels-intelligence` from npm — the version this very PR is
about to publish. It failed `unit (20.x)` by construction on #6185 and #6025.

Apply the fix `verify-channels-umbrella` already uses: pack the whole
first-party `workspace:` closure locally and pin it through pnpm `overrides`.
The packing helpers move to `lib/pack-workspace.ts` so both scripts share one
implementation instead of duplicating it.

The contract is unchanged: the packed runtime must still declare
channels-intelligence as a real dependency, and it must still load through
both ESM and CJS.
2026-07-27 11:10:32 -05:00
Benjamin Taylor 710b5ad783 fix(release): report literal cross-scope pins, which scope=all cannot fix
Adversarial pass on the previous commit. The warning only inspected
`workspace:` ranges, so it missed the OTHER way a cross-scope pin goes stale: a
literal version range naming a package in another scope. `bumpPackages` rewrites
literal ranges for in-scope packages only, so such a pin survives every bump —
`scope=all` publishes the canary and the artifact still resolves the dependency's
last stable release, silently, which is the exact failure this warning exists to
surface.

`findCrossScopeWorkspaceDeps` becomes `findCrossScopePins`, reporting both shapes
tagged with a `reason`, and the literal case carries its own remedy (convert to
`workspace:`) instead of the useless "re-run with scope=all".

No such pin exists in the tree today — every cross-scope edge is `workspace:` —
so this closes a latent hole rather than a live one, in the one place a future
refactor would reintroduce it.

Also documents the multi-scope partial-failure mode in prerelease.ts: the
cross-scope graph has cycles, so no publish order avoids a package shipping
before the same-run version it pins, and npm's no-republish rule means a failed
run must be retried under a new suffix.
2026-07-24 16:08:15 -05:00
Benjamin Taylor bee19e78df fix(release): make canary publishes reachable and cross-scope composable
Two release-tooling defects turned a pair of canary publishes into a broken
combination for consumers (a canary runtime resolving the last STABLE
channels-intelligence, which still called the removed `channel.addAdapter`).

1. Canary versions were prereleases of an ALREADY-PUBLISHED version. A stable
   release leaves the working tree on the version it just published, and
   computePrereleaseVersion appended `-canary.<id>` to exactly that, so the
   canary sorted BELOW its own release (`0.2.1-canary.x < 0.2.1`): the `canary`
   dist-tag pointed behind `latest`, and no dependent range could ever resolve
   it. Base the canary on the next unreleased version instead (patch bump,
   reusing computeNextStableVersion's prerelease rule).

2. A canary published one scope at a time, but the scopes are only independent
   on the version axis. `@copilotkit/runtime` carries
   `"@copilotkit/channels-intelligence": "workspace:*"`, and `pnpm pack`
   resolves that against the working tree — so a `monorepo` canary pinned the
   channels family to its last stable release even when the commit changed both
   sides of the contract. Add a prerelease-only `all` selector that bumps and
   publishes every scope from one commit under one shared canary id, and warn
   loudly when a single-scope canary leaves a cross-scope pin behind.

`all` is a selector, never a scope: stable releases stay single-scope (their
tag, release branch, and npm/Slack links all derive from one scope name), which
publish-release.yml enforces in both jobs and the dropdown guard enforces per
workflow.
2026-07-24 15:53:13 -05:00
Mike Ryan cd0b5b4061 fix(angular): address SDK review findings 2026-07-23 07:48:25 -07:00
Mike Ryan fec70d086f feat(angular): checkpoint 2 - core and package 2026-07-23 07:14:55 -07:00
Benjamin Taylor d221c03f02 fix(release): make packed Channels umbrella verify hermetic
The local `verify:channels-umbrella` check packs the Channels family and
installs a throwaway consumer, overriding only the family tarballs. The
family depends on monorepo-versioned packages (`@copilotkit/core`,
`@copilotkit/shared`) via the `workspace:` protocol, which `pnpm pack`
rewrites to the workspace's current version. On a release PR that version
is the freshly-bumped one that isn't on the registry until the release
publishes, so the consumer install fell through to npm and failed with
ERR_PNPM_NO_MATCHING_VERSION — the unit(20.x) red that blocked every
monorepo release PR (e.g. #5992, #6019) on its own not-yet-published
version.

Pack those workspace siblings locally too and pin them as consumer
overrides, so local mode never races the registry against our own
in-flight release. Siblings are discovered transitively via the
`workspace:` protocol so the list never drifts as the family's internal
dependencies change.

Verified by bumping shared+core to an unpublished version: the old script
fails with ERR_PNPM_NO_MATCHING_VERSION, the fixed script reports OK.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 13:58:02 -05:00
Benjamin Taylor 1110f18e30 fix(release): exempt first-party publishes from the release-age gate
The packed Channels umbrella (and the runtime-package verify) install
first-party packages straight from the registry, so a just-published
@copilotkit/* version fails pnpm's 24h minimumReleaseAge check — this is
what reddened `unit (20.x)` on channels PRs. The enumerated exclude lists
drift every time an internal dependency is added (main already had to bolt
on @copilotkit/channels-core, then #6012 added @copilotkit/core + shared).

Wildcard the @copilotkit/* scope (org-owned, same publish pipeline — no
outsider can inject a package, and it stops the drift). Keep @ag-ui
enumerated rather than wildcarded: it's a separate upstream org, so we don't
extend immediate-install trust to its entire scope. Third-party deps stay
fully gated. Applied to both the generated consumer workspace and the
repo-root .npmrc.

Verified: `pnpm run verify:channels-umbrella` installs the packed umbrella
with no ERR_PNPM_NO_MATURE_MATCHING_VERSION; umbrella unit tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 13:10:58 -05:00