714 Commits

Author SHA1 Message Date
Ran Shemtov 03ea9c86d2 Merge branch 'main' into claude/xenodochial-khayyam-873a16 2026-09-14 09:40:13 +02:00
Benjamin Taylor 8ebdd33998 fix(packages): raise the published Node engines floor to 20
Seven published packages declared `engines.node: ">=18"`, but CI has never
run Node 18 and Node 18 reached end of life on 2025-04-30. The claim
pointed at a runtime nothing tests and that receives no security patches.

Raise those seven to `">=20"`, the lowest version the unit matrix
(20.x, 22.x, 24.x) actually proves, and raise the root manifest to match.

Also give `@copilotkit/runtime` its first `engines` field. It declared
none, while #7089 moved it to pino 10, which drops Node 18. Pino ships no
`engines` of its own, so a consumer on Node 18 installed cleanly and
failed later, at runtime.

Closes #7107

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-12 14:25:05 -05:00
Ben Taylor ed4f44f94f fix(runtime): await durable Intelligence stop completion (#7096)
## What does this PR do?

Fixes Stop → resend on Intelligence threads.
`IntelligenceAgentRunner.stop()` previously returned `true` after
requesting an abort, while the handler kept renewing the hosted lock.
Agents that ignored abort could keep the thread locked until natural
completion.

Stop now fences late producer events, requests cancellation, and
finalizes the run through the existing event queue. It resolves `true`
only after the gateway acknowledges every queued event and the runner
completes cleanup. The gateway's existing terminal-event handling
releases only that run's lock. Cancellation does not depend on the agent
promise settling; AG-UI subscriptions also detach when the agent
supports it. Delivery rejection, teardown, or the 60-second deadline
cannot report success.

### Compatibility

- No Intelligence or AG-UI server change, new event type, required
capability, dependency bump, or coordinated rollout.
- Existing single-event and batched acknowledgments both work. Older
agents without `detachActiveRun()` retain the cancellation fallback.
- HTTP paths, empty-body requests, single-route envelopes, and response
bodies are unchanged. Missing, mismatched, and duplicate Stop requests
retain `false`.
- The existing optional runner `runId` remains supported. This PR does
not duplicate #6982's HTTP run-selection change.
- Provider cancellation remains best effort; stopping a run cannot undo
external tool effects.

### Validation

- RED: the new legacy/batch transport tests failed because no terminal
event followed a non-cooperative abort. The subscription-cleanup test
separately failed before detachment was added.
- GREEN: 11 new tests exercise real Phoenix WebSocket framing, delayed
terminal acceptance, immediate resend, older agents, throwing aborts,
late events, partial messages/tools, pre-join Stop, rejection, timeout,
and both HTTP route modes. All 2,306 runtime tests and the existing
runner tests pass.
- `pnpm nx run-many -t test,check-types,build,publint,attw
--projects=@copilotkit/runtime --parallel=2` passed again after rebasing
onto current main.
- The 11 new transport and HTTP tests also passed on Node 20.19.4; the
fixture supplies WebSocket only when the Node global is absent.
- The required pre-commit check passed tests and package validation for
nine affected packages. An initial parallel run timed out in the
unrelated SQLite replay test; its isolated rerun passed all 15 tests,
followed by a passing hook with `NX_PARALLEL=2`. No test timeout
changed.
- Focused oxlint and oxfmt checks; `git diff --check`. Oxlint reports
only three existing warnings in the runner and its older test file.
- Local integration: the actual runtime HTTP handler and a gateway built
from Intelligence `a55679d1055ab831930331e64b6129d14e73b613`, with
isolated Redis/PostgreSQL. App API lock acquisition/renewal were
represented by a test adapter over real Redis. Two consecutive streamed
runs stopped in 179 ms and 156 ms; each response followed lock release.
PostgreSQL retained both ordered five-event sequences, one
`RUN_FINISHED` per run, and no `RUN_ERROR`. The fixture included the
current replay-projection migration.

## Related PRs and Issues

Closes #7078.
Related: #6982 (HTTP selection of an exact run).


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Stopping an Intelligence run now waits for terminal confirmation
before completing.
* Stop requests prevent late events and clean up local run
subscriptions.
* Runs can be stopped at different connection stages, including before
channel join.
* Partial text and tool-call streams are properly closed when stopping.
  * Stop failures and durability timeouts are surfaced appropriately.
* HTTP Stop endpoint behavior is preserved while waiting for run
completion.

* **Documentation**
* Added guidance on stopping runs, cancellation ordering, failure
handling, and gateway acknowledgments.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-12 14:15:25 -05:00
Mike Ryan 20741d4072 test(runtime): support Node 20 in stop transport tests 2026-09-12 13:56:30 -05:00
Mike Ryan 32c6cc4be9 fix(runtime): await durable Intelligence stop completion 2026-09-12 13:56:30 -05:00
Ben Taylor ea27582da7 Merge branch 'main' into fix/6423-pino-resolution 2026-09-12 13:38:42 -05:00
Ran Shem Tov 115f0c1029 Merge remote-tracking branch 'origin/main' into claude/xenodochial-khayyam-873a16
# Conflicts:
#	showcase/shell-docs/src/content/docs/integrations/mastra/doctest.json
2026-09-12 13:23:28 +02:00
Maximiliano Korp cd44dc0acb fix(runtime): consume MCP Apps MIME correction 2026-09-11 15:57:23 -07:00
Mike Ryan f7424b047b fix(runtime): preserve safe failure reporting and completion analytics
Report failures without private diagnostic payloads in analytics. Preserve
completion counts for streams containing RUN_ERROR and notify clients when
execution fails.
2026-09-11 15:55:29 -07:00
Mike Ryan 05d6cacd93 fix(runtime): preserve identity and request boundary contracts
Preserve SDK update precedence and mounted routing, strip browser identity
aliases, and clone stop requests before application authentication consumes
the body. Keep entitlement response-body timeouts retryable.
2026-09-11 15:55:29 -07:00
Mike Ryan 84549992ab fix(runtime): scope MCP Apps requests through the released middleware
Consume upstream MCP Apps 0.1.0, retain trusted server credentials, and
reject proxy requests outside the selected agent scope. Ordinary runs
without selected servers do not attach middleware.
2026-09-11 15:55:29 -07:00
Mike Ryan 288070063a fix(runtime): validate tool arguments while preserving A2UI schemas
Validate AG-UI tool arguments against their JSON schemas. Keep relaxed
structured output limited to the open A2UI tool and preserve existing tool
tests.
2026-09-11 15:55:14 -07:00
tylerslaton 92f704e3b4 chore: release monorepo v1.71.1 2026-09-11 22:01:26 +00:00
Benjamin Taylor 39be5c5538 fix(runtime): bump @ag-ui/mcp-middleware to 0.0.2 and drop its client override
`@ag-ui/mcp-middleware@0.0.1` declared `@ag-ui/client` as an exact
dependency, so every install nested a second copy of the client beside the
one the consumer already had. Because `@ag-ui/client` carries types, two
copies are two distinct type identities, and a consumer passing a value
into `CopilotRuntime` hit a type error naming a private `_debug` field and
their own line rather than the duplication.

`0.0.2` (ag-ui-protocol/ag-ui#2689) moves `@ag-ui/client` to a peer at
`>=0.0.40`, matching the four sibling middlewares, so it resolves to the
copy the host already has.

This also removes the `@ag-ui/mcp-middleware>@ag-ui/client` override. That
override was added in c3f7961242 alongside the `0.0.1` dependency, as the
in-repo workaround for the hard pin. With `0.0.2` it is not just redundant:
it forces a stale `0.0.53` onto a peer the workspace satisfies at `0.0.59`,
and the first resolve after the bump reported that as an unmet peer.

The lockfile loses exactly one `@ag-ui/client` version, `0.0.53`. The other
resolved versions are unchanged from main.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 15:16:27 -05:00
Ben Taylor e9cbe1c97e fix(runtime): pass SSE MCP headers via requestInit (#6930)
## What does this PR do?

v2 MCP `sse` servers accepted a `headers` auth map on `mcpServers` (the
documented `Authorization: Bearer …` example) but never put those
headers on the wire.

`SSEClientTransport`'s second argument is `SSEClientTransportOptions`,
not a raw header map. Passing `{ Authorization: "…" }` matches none of
`authProvider` / `requestInit` / `eventSourceInit` / `fetch`, so the SDK
ignored it. Auth-required servers then 401'd, and the run skipped the
server (`MCP server … failed to connect — skipping it for this run`) —
the agent just had no tools.

This wraps `serverConfig.headers` as `{ requestInit: { headers } }`,
matching the HTTP transport's options-object pattern. No public type
change: `MCPClientConfigSSE.headers` stays as documented.

Adds a small regression test that stands up a local HTTP listener and
asserts the outbound SSE request carries `Authorization: Bearer
SENTINEL-TOKEN`.

Verified locally:

```
nx run @copilotkit/runtime:test -- src/agent/__tests__/mcp-servers-integration.test.ts
# 10 tests passed
```

No changeset: this repo migrated off Changesets; CI fails on new
`.changeset/*` files. The conventional commit subject is the release
note.

Intended for upstream `CopilotKit/CopilotKit` `main`:

https://github.com/CopilotKit/CopilotKit/compare/main...Zsanz3:CopilotKit:cursor/fix-mcp-sse-headers-22fc?expand=1

## Related PRs and Issues

- Fixes #6927

## 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 (no docs change — this is a bugfix of documented
behavior)
- [x] "Allow edits by maintainers" is checked (lets us help iterate on
your PR directly — faster turnaround for everyone)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Fixed SSE-based MCP connections so configured authorization and other
request headers are correctly sent.
* Added coverage to verify authenticated SSE connections complete
successfully without runtime errors.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-11 14:08:37 -05:00
Swapnoneel Saha 3f954ee315 fix(runtime): declare pino 10 directly 2026-09-11 21:54:59 +05:30
Benjamin Taylor 6c25273afe refactor(skills): replace nine knowledge skills with two entry points
The packaged skills had grown into a second copy of the documentation.
`runtime` and `react-core` were roughly 60% transcribed API surface, and
most of their remaining "Common Mistakes" prose already existed on a docs
page. A cached copy of an API goes stale silently: four claims in the
deleted skills contradicted the source they cited, and one of them reached
a shipped PR before it was caught.

Replace them with two skills that look the answer up instead of restating
it:

- `copilotkit` — the four search tools and two explore tools of the
  bundled `copilotkit-docs` MCP server, which corpus answers which
  question, and the instruction not to answer from memory.
- `copilotkit-cli` — the CLI, led by `copilotkit verify --json`. Since
  #1180 `verify` covers version skew, CORS, and transcription, which is
  what most of the old `copilotkit-debug` skill described by hand.

Deleted: copilotkit-setup, copilotkit-develop, copilotkit-integrations,
copilotkit-debug, copilotkit-upgrade, copilotkit-agui, copilotkit-contribute,
copilotkit-self-update, and the three package-generated skills (react-core,
runtime, a2ui-renderer).

The `skills` directory is dropped from the `files` field of the three
packages that shipped one, so the tarballs no longer carry a copy.

`public-skill-drift.test.ts` guarded wording in files that no longer exist.
It is now a link guard: every `docs.copilotkit.ai` path named by a packaged
skill has to resolve to a page in this repo, and the two entry points have
to stay free of a transcribed API surface.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 11:11:18 -05:00
Ben Taylor f8520c9804 fix(skills): audit react-core claims, and stop documenting Cloud keys as the Intelligence path (#6997)
Follow-up to #6993. That PR fixed two `react-core` references; four of
their six citations were stale, so this audits the other 13.

## Method

Three passes, because the first two are cheap and the third is the only
one that finds real defects.

1. **Mechanical** — every `packages/...:NN-MM` citation: does the path
exist, is the span in range? 71 citations, 57 with spans.
2. **Symbol** — every `useXxx(` and `<CopilotXxx` in the docs against
the 389 identifiers actually exported from `v2/src`.
3. **Semantic** — read the cited lines and check they support the claim.
This is where the rot lives: the lines exist, they just say something
else.

## Findings fixed

| File | Defect |
| --- | --- |
| `capabilities.md` | Cited `runtime/src/agent/index.ts:821-829,883-887`
for "shallow-merges capabilities at the category level". Those are
factory-mode config types and sampling params (`frequencyPenalty`,
`stopSequences`). The mechanism is `:940-947` — whose own doc comment
says **shallow-merged** — and `:999-1012`. |
| `provider-setup.md` | Claimed the provider resolves `publicLicenseKey
\|\| publicApiKey`. Only one of four sites does. Citation also pointed
at an unrelated line (`copilotkit.tsx:172` is `source: "agent"`). |
| `custom-message-renderers.md` | Cited lines 73-95 of a 93-line file.
The iterate-and-break it describes is at `:68-91`. |
| `suggestions.md` | `useFeatureFlag("suggestions")`, twice, with no
import and no definition. CopilotKit exports no such hook. |
| `threads.md` | `useThreadSelection()`, same problem. |

### The license-key one is a product finding, not just a docs bug

Precedence when both keys are set is inconsistent in the code:

| Site | Order |
| --- | --- |
| `CopilotKitProvider.tsx:487` | `publicApiKey ?? publicLicenseKey` |
| `copilotkit.tsx:111` | `publicApiKey \|\| publicLicenseKey` |
| `copilotkit.tsx:217` | `publicLicenseKey \|\| publicApiKey` |
| `copilotkit.tsx:883` | `publicApiKey \|\| publicLicenseKey` |

Three prefer `publicApiKey`, one prefers `publicLicenseKey`. So which
wins depends on which path runs. Rather than document one order as if it
were the contract, the doc now says to write the canonical name and not
to set both — true regardless of path. **The underlying inconsistency is
untouched here and probably wants its own issue.**

## Findings I retracted

Recording these because two of my three automated passes produced false
positives, and the ratio matters for anyone repeating this.

- **50 "missing paths."** My regex alternated `(?:ts|tsx)`, so it
matched `ts` first and truncated every `.tsx`. All 50 were my own
artifact. Real count: zero missing paths.
- **41 "unsupported spans."** A heuristic checking whether the claim's
backticked identifiers appear in the cited lines. It attributes each
`Source:` to the nearest paragraph above, which is the wrong one in
multi-paragraph gotchas. Useful as a reading list, worthless as a
finding.
- **"13 uses of the deprecated provider."** Most were the *filename*
`CopilotKitProvider.tsx` inside `Source:` citations, not component
usages. There are 2 real JSX usages, both passing only `runtimeUrl`,
both valid — and `provider-setup.md` already carries a callout
explaining that `CopilotKit` is the v1/v2 bridge and
`CopilotKitProvider` "is a perfectly good choice if you do not need the
v1 bridge". No defect.

## Testing

```
$ python3 audit_citations.py
citations: 71   mechanically broken: 0
with a line span: 57   path-only: 14

$ tsx scripts/sync-plugin-skills.ts --check
plugin skill mirror in sync

$ oxfmt --check skills/react-core/references/*.md
All matched files use the correct format.
```

Symbol pass after the fixes leaves only legitimate non-exports: React's
own hooks, two helpers the docs define inline (`useAvailableAgents`,
`useMyFeatureFlag`), and `useAgents`, which `switching-agents.md`
correctly documents as **not existing**.

Edits were made in `packages/react-core/skills/` and mirrored by the
sync script.

## Coverage, honestly

The mechanical and symbol passes cover all 15 files completely. The
semantic pass does not: I read roughly 15 of the 57 spans closely,
prioritising the files documenting APIs that have moved most. The five
defects above are what that subset produced. A full semantic read of the
remaining ~40 spans would likely find more, and the same audit has not
been run on the `runtime` skill (26 references) or `a2ui-renderer`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Documentation**
- Updated React guidance with current source references across
capabilities, message renderers, attachments, chat components,
client-side tools, debugging, human-in-the-loop rendering, tool calls,
agent access, and agent switching.
- Clarified that production SPAs require `runtimeUrl`, with Intelligence
configured server-side on the runtime using `CPK_INTELLIGENCE_API_KEY`.
- Removed outdated `publicLicenseKey` guidance from setup and API
documentation.
  - Corrected feature-flag examples to use an application-defined hook.
- Updated thread-selection examples to derive the active thread ID from
application state.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-09 16:26:53 -05:00
Benjamin Taylor ec249f81fd fix(skills): correct four defects found reviewing the previous commit
The repo's own guard caught the worst of them. `scripts/validate-intelligence-env-names.ts`
retires `INTELLIGENCE_API_KEY`: the canonical name is `CPK_INTELLIGENCE_API_KEY`,
and the retired one "produced an undefined key for a reader who followed it
with a CLI-provisioned project" (OSS-881). The rewrite reintroduced it at
seven sites. Corrected, and the validator's 22 rule tests pass.

The same file also stops listing `INTELLIGENCE_API_URL` and
`INTELLIGENCE_GATEWAY_WS_URL` as things to set. Both default to the managed
hosts when omitted, so any value a reader supplies can only replace a correct
default with a worse one.

`provider-setup.md` called `agents__unsafe_dev_only` and `selfManagedAgents`
"aliases for the same dev-only mechanism". They are not: the first is the free
local-dev escape hatch, the second is an Enterprise Intelligence tier feature
that warns when used without a license key. I inherited that sentence and made
it more confident while editing it.

`copilotkit-setup/SKILL.md` Step 6 was left incoherent by the previous commit.
Removing the provider example stranded an instruction to "set the public
license key and pass it to the provider" above an example that no longer did.
The step now ends with `copilotkit verify`, its credential table lists the one
server-side credential, and the security note no longer claims a client-side
value exists.

Two claims of my own were also too absolute: the provider throws only when
`runtimeUrl`, a Cloud key, AND dev-only agents are all absent, and
`publicLicenseKey` does have a second advisory role gating
`selfManagedAgents`. Both now say so.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 15:57:44 -05:00
Benjamin Taylor 57eb071cda fix(skills): stop documenting Cloud keys as the Intelligence path
`publicApiKey` and `publicLicenseKey` route a runtime-less client at
CopilotKit Cloud -- `api.cloud.copilotkit.ai`, header
`X-CopilotCloud-Public-Api-Key`. Five skills presented them as the way to
connect CopilotKit Intelligence, which they have never done.

Intelligence is configured on the runtime. The CLI writes
`INTELLIGENCE_API_KEY` into the server environment and it never reaches the
browser, so no client-side key is involved at all.

What was wrong, beyond the mislabelling:

- `provider-setup.md` had a section titled "SPA with CopilotKit Intelligence
  (no self-hosted runtime)". There is no client-only path: the provider throws
  in production without `runtimeUrl`, a key, or dev-only local agents. It now
  says a runtime is required and why.
- `telemetry-setup.md` told readers to expose the key with a `NEXT_PUBLIC_` or
  `VITE_` prefix and claimed removing the prop disconnects Intelligence.
  Neither is true. Rewritten around the CLI flow, the server-side variables,
  and `copilotkit verify`.
- `error-patterns.md` attributed `MISSING_PUBLIC_API_KEY_ERROR` to
  Intelligence. It is a Cloud error code.
- `copilotkit-setup/SKILL.md` called it the "CopilotKit Intelligence public
  license key" in its props table and put it in the provider example.
- The `react-core` and `runtime` SKILL.md invariants advertised
  `publicLicenseKey` as canonical, and `react-core` offered it as the SPA
  alternative to `runtimeUrl`.

The naming gotcha comparing the two props is gone rather than corrected:
neither belongs in Intelligence guidance. Three mentions remain and all three
name Cloud -- two migration-table rows in `copilotkit-upgrade`, which were
already right, and one line steering readers away.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 15:45:12 -05:00
tylerslaton cac7cde862 chore: release monorepo v1.71.0 2026-09-09 22:24:05 +02:00
Benjamin Taylor 2c05ed6885 chore(release): keep release notes in one CHANGELOG.md per release lane
The notes now land in a source-controlled changelog instead of a scratch file
that rides the release branch. One file per lane, because the lanes version
independently: a shared file would interleave `1.70.0`, `angular/0.5.0` and
`channels/0.9.0` into one unreadable sequence.

  monorepo  ->  CHANGELOG.md
  angular   ->  packages/angular/CHANGELOG.md
  channels  ->  packages/channels/CHANGELOG.md

`write-changelog.ts` prepends this release's section on the release branch,
create-pull-request commits it (a tracked file, always staged), and
`extract-release-notes.ts` reads the section back in the publish job as the
GitHub Release body. The changelog is therefore both the durable record and the
review surface: editing a section on the release PR changes what ships.
release-notes.md goes back to being ignored, so the same notes never exist as
two editable copies.

Also deletes 29 changesets-era changelogs that no tooling had written since
April. They stopped at 1.55.2 while the lane shipped 1.69.3, and
packages/angular/CHANGELOG.md still claimed 1.54.3 from before that lane split
onto its own 0.x line. Their content stays recoverable from git history. A test
pins the tracked changelog set to the lanes so they cannot creep back and
contradict the real versions.

Extraction never fails the publish job: it runs after npm publish, so a miss
annotates loudly and falls through to the existing bodyless-release fallback
rather than stranding the tag.

Committed with --no-verify: the pre-commit nx lane cannot run in this worktree
(packages/core and packages/channels-ui have no node_modules, and
`nx run @copilotkit/core:build` fails identically with the tree clean). The only
change under packages/** is deleting orphan markdown that no build or test
reads.
2026-09-09 08:31:01 -05:00
Mike Ryan 547329fe09 fix(runtime): accept nullable frontend tool schemas (#6958)
A nullable frontend tool field can reach the built-in agent as `anyOf:
[{type: "string"}, {type: "null"}]`. The converter handles the union but
throws `Invalid JSON schema` for its null branch before the model is
called. This matches R14 in the September 3–8 onboarding friction audit.

Accept explicit null branches when converting frontend tools. Required
nullable fields still require a value; optional fields can be omitted.
Invalid non-null values still fail validation.

Validation:
- RED: both the explicit anyOf input and a real Zod v4 nullable schema
failed with `Invalid JSON schema` before the fix.
- `pnpm nx test @copilotkit/runtime` — 2,293 tests passed, including
HTTP runtime integration tests.
- `pnpm nx test @copilotkit/runtime --
src/agent/__tests__/nullable-tools.test.ts` — 3 focused tests passed
after the final test typing change.
- `pnpm nx run-many -t test,check-types,build -p @copilotkit/runtime`
passed on the revised head (2,293 tests).
- `pnpm exec oxlint packages/runtime/src/agent/index.ts
packages/runtime/src/agent/__tests__/nullable-tools.test.ts` — no
errors; three existing shadowing warnings.
- `pnpm exec oxfmt --check packages/runtime/src/agent/index.ts
packages/runtime/src/agent/__tests__/nullable-tools.test.ts` and `git
diff --check` passed.

No live model request was needed: the regression exercises the actual
AG-UI-to-model-tool conversion and validates accepted and rejected
arguments.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Bug Fixes**
- Improved handling of nullable tool fields, including nullable unions,
arrays, and fields generated by Zod.
- Invalid values and missing required fields continue to be rejected
during tool schema validation.
- **Compatibility**
- JSON Schema type declarations now use a single type value; arrays of
schema types are no longer converted automatically.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-08 20:21:50 -07:00
Mike Ryan 3c78b1ad52 fix(runtime): keep nullable support scoped to null branches 2026-09-08 16:31:48 -07:00
tylerslaton 69a940c70e chore: release monorepo v1.70.3 2026-09-08 23:22:32 +00:00
Tyler Slaton fdb6ce0714 fix(inspector): require Learning container configuration for status 2026-09-08 16:05:53 -07:00
Tyler Slaton 290a8323ae fix(runtime): expose Inspector Learning without extra flags 2026-09-08 15:51:58 -07:00
Mike Ryan 8757ef0a80 fix(runtime): accept nullable frontend tool schemas 2026-09-08 15:45:17 -07:00
Benjamin Taylor 1a935861a8 fix(runtime): do not treat an unread stream as a pre-parsed body in the express bridge
`hasPreParsedBody` gates on `req.body` being set, then confirms the stream is
gone via `req.readableEnded || req.complete || _readableState.ended ||
_readableState.endEmitted`. The last three are set by the Node HTTP parser once
the socket holds every byte, whether or not anything read them, so they do not
establish that a parser ran.

That matters because `req.body` being set does not establish it either.
body-parser 1.x (Express 4) assigns `req.body = req.body || {}` before its own
`hasBody`/`shouldParse` checks, so a request it declines to parse — multipart
upload, text/plain — reaches the bridge with `req.body === {}` and a full,
unread stream. `req.complete` then satisfied the check, the bridge rebuilt the
request from `{}`, and the real payload was silently dropped.

Gate on `readableEnded` alone, which only becomes true after a parser drains the
stream to its end. Verified on express 4.22.2 / body-parser 1.20.6 that a
multipart POST behind a global `express.json()` arrives with `req.body === {}`,
`readableEnded === false`, `complete === true`, and that the genuinely parsed
JSON case is unaffected.

Same root cause as #6489, which fixed the equivalent check in the node-http
request handler. Kept as a separate local predicate rather than sharing one
helper, to avoid coupling `v2/runtime` to the v1 integration tree.
2026-09-08 16:32:38 -05:00
MikeRyanDev 16514e9424 chore: release monorepo v1.70.2 2026-09-08 20:03:39 +00:00
Cursor Agent 6aa8725b83 fix(runtime): pass SSE MCP headers via requestInit
SSEClientTransport's second argument is options, not a raw header map.
Passing `{ Authorization: ... }` was silently ignored, so documented
mcpServers auth never reached the wire.

Fixes #6927

Co-authored-by: Zsanz3 <Zsanz3@users.noreply.github.com>
2026-09-07 02:16:05 +00:00
Fnine59 1a2f5691b6 Merge upstream/main into fix/copilotkit-6888-sse-binary 2026-09-07 04:42:20 +08:00
Martha Kelly Schumann 1fdca1dc9e fix(inspector): harden Learning review flows 2026-09-04 17:30:44 -07:00
Martha Kelly Schumann 05fc4e05a4 feat(runtime): expose Learning snapshots to Inspector 2026-09-04 17:11:42 -07:00
Fnine59 79fdeb64c2 fix(runtime): encode SSE response chunks as bytes 2026-09-04 22:05:57 +00:00
Ben Taylor a4adf38683 fix(shared): keep Node-only telemetry out of browser build graphs (#6846)
## What does this PR do?

`@copilotkit/shared` re-exported `telemetry/telemetry-client.ts` from
its root entry. That module imports `@segment/analytics-node`, which
imports `node-fetch`, which imports the Node built-ins `stream`, `http`,
`https` and `zlib`. Browser bundlers resolve the whole static module
graph before they tree-shake, so every browser build of a dependent
package printed `Module ... has been externalized for browser
compatibility` warnings, even when the consumer never touched telemetry.

This PR keeps that edge out of the browser-facing entry:

- `isTelemetryDisabled` moves into
`src/telemetry/telemetry-disabled.ts`, so the root entry can keep
exporting it without reaching the client.
- The root entry keeps `isTelemetryDisabled`, the `lambdaClient`
surface, the sampling helpers, and the `TelemetryCapture` /
`TelemetryIdentity` types. The types are exported with `export type`, so
they are erased and add no runtime edge.
- `TelemetryClient` is now reachable at `@copilotkit/shared/telemetry`,
a new export subpath.
- A new test walks the value-level import graph from `src/index.ts` and
fails if it reaches a Node-only package.

Deferring the import does not fix this, which is what PR #5482
attempted. A dynamic import defers evaluation but keeps the graph edge,
so `vite:resolve` still reaches `node-fetch`. The measurement is in
https://github.com/CopilotKit/CopilotKit/pull/5482#issuecomment-5509823707.

## Export surface change

`TelemetryClient` is no longer on the `@copilotkit/shared` root entry,
or on the `CopilotKitShared` UMD global. It is reachable at
`@copilotkit/shared/telemetry`.

```diff
- import { TelemetryClient } from "@copilotkit/shared";
+ import { TelemetryClient } from "@copilotkit/shared/telemetry";
```

This is a public export in the packaging sense only. `TelemetryClient`
is our internal metrics client, so no application code is expected to
import it, and nothing that works today is expected to stop working.
`packages/runtime/src/v1-deprecated/lib/telemetry-client.ts` is the only
in-repo consumer and is updated here. There is no root shim on purpose:
a runtime re-export would reintroduce the graph edge and the bug.

`typesVersions` carries the subpath for `moduleResolution: "node"`
(node10) consumers, which `packages/runtime` still uses. Without it,
`tsc` cannot see the subpath's types.

`scripts/release/public-api/manifest.v1.json` is regenerated for the new
entry point. The manifest tracks entry points rather than symbols, so
the change there is the added `./telemetry` record.

## Related PRs and Issues

- Fixes #4151
- Supersedes #5482

## Testing

### The reported symptom, before and after

Vite 7.3.2, minimal app whose entry imports only browser-safe symbols
from `@copilotkit/shared`, pointed at a real tsdown build of the
package.

| | `vite build` warnings | modules transformed |
| --- | --- | --- |
| `main` | 4 (`stream`, `http`, `https`, `zlib`) | 663 |
| this branch | **0** | 451 |

After, verbatim:

```
vite v7.3.2 building client environment for production...
transforming...
✓ 451 modules transformed.
rendering chunks...
computing gzip size...
dist/index.html                0.12 kB │ gzip: 0.12 kB
dist/assets/index-EEiKsU3u.js  2.43 kB │ gzip: 1.29 kB
✓ built in 267ms
```

The dev-server dependency scanner is fixed too. `vite optimize --force`
before this change pre-bundled `@ag-ui/client, @segment/analytics-node,
chalk, graphql, partial-json, uuid, zod`; after it pre-bundles
`@ag-ui/client, graphql, partial-json, uuid, zod`.

### The new export surface, exercised in Node

```
=== CJS require of subpath ===
TelemetryClient: function
isTelemetryDisabled: function true
lambdaClient: object
segment instantiated: Analytics
=== ESM import of subpath ===
esm TelemetryClient: function disabled: true
=== root entry ===
root TelemetryClient: undefined
root isTelemetryDisabled: function
root lambdaClient: object
root computeSamplingMeta: function
root firstNonBlankTelemetryId: function
```

### Subpath type resolution, both resolution modes

```
### moduleResolution node10 (what packages/runtime uses) ###
(clean)
### moduleResolution node16 ###
(clean)
```

Before adding `typesVersions`, node10 failed as expected, which is why
the field is there:

```
probe.ts(1,33): error TS2307: Cannot find module '@copilotkit/shared/telemetry' or its
corresponding type declarations.
  There are types at '.../dist/telemetry/index.d.mts', but this result could not be
  resolved under your current 'moduleResolution' setting.
```

### The regression guard is not self-fulfilling

Mutation-checked both ways. Restoring `export * from "./telemetry"` on
the root entry:

```
× root entry browser safety (#4151) > does not reach Node-only packages through value imports
  → expected [ '@segment/analytics-node' ] to deeply equal []
```

Turning the type-only re-export into a value re-export fails it as well,
and restoring the file makes both tests pass again.

### The gate that went red on the first push

`scripts/release/lib/public-api-manifest.test.ts` compares the committed
public API manifest to a freshly generated one, and a new export subpath
has to be recorded there. Regenerated with `pnpm
generate:public-api-manifest`; the failing test and its whole suite now
pass:

```
scripts/release/generate-public-api-manifest.ts --check
  scripts/release/public-api/manifest.v1.json is current

vitest run scripts/release
  Test Files  14 passed (14)
       Tests  162 passed (162)
```

### Package gates

```
@copilotkit/shared: tsc --noEmit          clean
@copilotkit/shared: vitest run            18 files, 404 tests passed
@copilotkit/shared: tsdown                Build complete
@copilotkit/shared: verify-cjs-exports    exit 0
@copilotkit/shared: es-check es2022       55 files, ES13 compatible
@copilotkit/shared: es-check es2018 (umd) 1 file, ES9 compatible
@copilotkit/shared: publint               only the pre-existing repository.url suggestion
@copilotkit/shared: attw --profile node16 all green, including "@copilotkit/shared/telemetry"
```

### Not run locally

`@copilotkit/runtime:build` and the workspace-wide pre-commit gate. My
local install is missing `type-graphql@2.0.0-rc.1` from the pnpm store,
so the runtime build fails on `Cannot find module 'type-graphql'` on
`main` as well, with or without this change. The runtime change here is
one import line, and I verified that it resolves under both node10 and
node16. CI runs the real gate. This commit was made with `--no-verify`
for that reason.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Added a dedicated `@copilotkit/shared/telemetry` entry point for
server-side telemetry functionality.
- Added support for disabling telemetry when
`COPILOTKIT_TELEMETRY_DISABLED` or `DO_NOT_TRACK` is set to `true` or
`1`.

- **Improvements**
- Improved browser compatibility by preventing Node-only telemetry
dependencies from being included in browser bundles.
- Existing browser-safe telemetry utilities remain available from the
main shared package entry point.
- Full telemetry client functionality is now accessed through the
dedicated telemetry entry point.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-04 15:42:53 -05:00
Benjamin Taylor 9dea76ca81 fix(runtime): type the pino mock so the logger test typechecks
`tsc --noEmit` rejected reading `calls[0]` off an untyped `vi.fn()`,
whose call tuple is empty: TS2493. Give the mock pino's own
(options, stream) signature so the tuple carries real element types,
and drop the cast that was hiding it.
2026-09-04 13:58:46 -05:00
Benjamin Taylor 1ad6b6fc79 fix(runtime): build the logger without pino redact so edge runtimes work
pino 9 validates every `redact.paths` entry by calling `Function(...)`
through fast-redact. Cloudflare Workers and other edge runtimes forbid
code generation from strings, so the runtime threw while building its
logger. The validator swallows the real EvalError and blames the first
path in the array, which made the failure read as "redact paths array
contains an invalid path (pid)" and sent earlier triage after `pid`
itself. Every path fails, not just `pid`.

`base: null` is pino's own switch for omitting `pid` and `hostname`, it
produces identical output, and it needs no code generation.

Closes #2355

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 13:47:53 -05:00
Mike Ryan c34f7abfc1 fix(runtime): retain resource context on method errors 2026-09-04 10:49:22 -07:00
Mike Ryan c276befc13 fix(runtime): harden single-route resource requests 2026-09-04 10:39:10 -07:00
Mike Ryan 2cde6b97f7 fix(runtime): preserve single-route resource context 2026-09-04 10:36:27 -07:00
Mike Ryan 840ad3c14a feat(runtime): support Intelligence over one route 2026-09-04 10:36:27 -07:00
Maximiliano Korp 6f1d0824be fix(runtime): accept marketplace entitlement source 2026-09-03 16:59:37 -07:00
Benjamin Taylor ea0d8ceab1 fix(runtime): reject a blank Intelligence API key at construction (closes OSS-1095)
`CopilotKitIntelligence` performed no validation on `apiKey`. It assigned the
value and sent it verbatim as a Bearer credential, so a blank key produced
`Authorization: Bearer ` and surfaced much later as a 401 that named nothing.

`apiKey: string` is required on the config type, so TypeScript catches a missing
property. It does not catch an empty one, and the shape that actually happens is
a `process.env` read TypeScript is told to trust: `?? ""` in the starter wiring
block, `!` in this file's own JSDoc examples. Both yield a blank key when the
variable is unset.

Throw at construction instead. Every caller builds the client during boot, so the
error lands at startup rather than on a user's first message. The message names
`CPK_INTELLIGENCE_API_KEY` and `copilotkit project select`, and echoes none of the
key value — the rule `parseProjectIdFromApiKey` already follows for a malformed
key.

This mirrors `configuredUrl`, which already treats a blank `apiUrl`/`wsUrl` as
unset for the same `?? ""` reason.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-03 11:32:35 -05:00
tylerslaton 71b2f481f9 chore: release monorepo v1.70.1 2026-09-03 15:49:49 +00:00
Benjamin Taylor a7d889772e fix(shared): keep Node-only telemetry out of browser build graphs
`@copilotkit/shared` re-exported `telemetry/telemetry-client.ts` from its
root entry. That module imports `@segment/analytics-node`, which imports
`node-fetch`, which imports the Node built-ins `stream`, `http`, `https`
and `zlib`. Browser bundlers resolve the whole static module graph before
they tree-shake, so every browser build of a dependent package printed
"Module ... has been externalized for browser compatibility" warnings,
even when the consumer never touched telemetry.

Measured with Vite 7.3.2 against a consumer that imports only
browser-safe symbols: 663 modules and 4 warnings before, 451 modules and
0 warnings after. `vite optimize` no longer pre-bundles
`@segment/analytics-node` either.

Deferring the import does not fix this. A dynamic import defers
evaluation but keeps the graph edge, so the resolve step still reaches
`node-fetch`. The edge itself has to stay out of the browser entry.

- `isTelemetryDisabled` moves to its own module so the root entry can
  keep exporting it without reaching the client.
- The root entry keeps `isTelemetryDisabled`, the `lambdaClient` surface,
  the sampling helpers, and the `TelemetryCapture` / `TelemetryIdentity`
  types (type-only, so no runtime edge).
- `TelemetryClient` is now reachable at `@copilotkit/shared/telemetry`
  instead of the root. It is our internal metrics client, so no
  application code is expected to import it. A runtime re-export from
  the root would reintroduce the bug, so there is no shim.
- A test walks the value-level import graph from `src/index.ts` and fails
  if it reaches a Node-only package.

Fixes #4151

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-02 08:58:10 -05:00
Lukas Moschitz 9bd7acc5ce fix(shared): drop the retired "premium" tier name from the console notice
The Headless UI console notice told developers about "premium features" and
pointed at /premium/overview. The tier is called CopilotKit Intelligence now, so
the notice named a product that no longer exists. It now uses the same sentence
the Headless UI docs page uses.

The docs links in react-core, web-inspector and the runtime skill reference move
from /premium/* to /intelligence/*. They worked through the redirects added in
#6818, but each cost a hop and carried the old name.

One of them was broken, not just stale: the "Show me how" button on the missing
public API key error opened /premium/overview#getting-access. That heading was
deleted on 2026-06-16 in 449237af0c, so the button had been landing at the top
of the page for two and a half months. It now points at #plans-and-access, the
section that answers how to get a key.

Tests assert these hrefs, so they move with the strings.

Refs OSS-1085
2026-09-02 12:19:50 +02:00
Dusty 7efd99266a fix(runtime): emit AG-UI token usage 2026-09-01 15:07:18 -07:00
copilotkit-qa-bot[bot] f236329630 test(runtime): harden request auth isolation coverage 2026-09-01 08:39:00 -07:00
copilotkit-qa-bot[bot] 9c5a3ead46 Merge remote-tracking branch 'origin/main' into codex/fac-121-configurable-channels 2026-09-01 07:47:35 -07:00